Home > CMS Tutorial > WordPress > Mastering WordPress Roles and Capabilities

Mastering WordPress Roles and Capabilities

Christopher Nolan
Release: 2025-02-16 11:49:08
Original
413 people have browsed it

WordPress User Management: In-depth Analysis of Roles and Permissions

WordPress's user management system is based on roles and permissions. A role is an entity that contains a unique name and a set of permissions, each of which defines the level of access to platform-specific features of that role. Let's dig into the working mechanisms of WordPress roles and permissions.

Key Points

  • WordPress's user management is based on roles and permissions. A role has a unique name and a set of permissions that define the level of access to different features of the platform by a role.
  • WordPress provides a comprehensive API to customize roles and their permissions. Functions such as add_role(), remove_role(), add_cap(), and remove_cap() can be used to manage roles and permissions. However, you must pay attention to database access and performance when using these functions.
  • There are several ways to avoid database issues when dealing with roles and permissions. One way is to trigger the code only when the plugin is enabled, you can use the register_activation_hook() function. Another way is to bypass the WordPress database by setting the $wp_user_roles global variable.

Back to the scenes mechanism

Role storage

The default role and permission list is available on WordPress Codex.

The

database stores this list in the wp_options table.

It uses the serialized wp_user_roles key.

Mastering WordPress Roles and Capabilities The deserialized data is as follows:

<code>array(
    'administrator' => array(
        'name'         => '管理员',
        'capabilities' => array(
            'switch_themes'          => true,
            'edit_themes'            => true,
            'activate_plugins'       => true,
            'edit_plugins'           => true,
            'edit_users'             => true,
            // [...]
        )
    ),
    'contributor' => array(
        'name'         => '投稿者',
        'capabilities' => array(
            'delete_pages'           => true,
            'delete_others_pages'    => true,
            'delete_published_pages' => true,
            'delete_posts'           => true,
            // [...]
        )
    ),
    // [...]
);</code>
Copy after login
Copy after login
Copy after login

This metadata is automatically set when a new WordPress site is installed.

When WordPress starts, the

class loads the list from the database. WP_Roles

This happens between

and plugins_loaded hooks. init

Link user to role

WordPress uses

stored in the wp_usermeta table to link users to their roles. meta_key

After deserialization, the metadata is as follows: Mastering WordPress Roles and Capabilities

<code>array(
    'administrator' => true
)</code>
Copy after login
Copy after login
Copy after login
Note that WordPress uses arrays, although users can only have one role at a time, we will see why later.

Also, remember

is the prefix of the current blog. wp_

(We can get it using the

function). $GLOBALS['wpdb']->get_blog_prefix()

In a multi-site installation, this allows users to use different roles in different instances:

  • => wp_capabilitiesa:1:{s:13:"administrator";b:1;}
  • => wp_10_capabilitiesa:1:{s:11:"contributor";b:1;}
  • => wp_15_capabilitiesa:1:{s:10:"subscriber";b:1;}
  • [...]
This rule also applies to the

entry we saw in the wp_options table. wp_user_roles

Finally, we can see the wp_user_level metadata as well as the role.

It is used to deal with characters in older versions of WordPress and is now deprecated.

Use permissions in core code

We have learned how roles are loaded and linked to users; from there, WordPress is able to get permissions for a given user when needed.

Some default permissions are hardcoded in WordPress core code.

For example, when the plugin screen is loaded, it will check if the current user can manage the plugin by running the following code:

<code>array(
    'administrator' => array(
        'name'         => '管理员',
        'capabilities' => array(
            'switch_themes'          => true,
            'edit_themes'            => true,
            'activate_plugins'       => true,
            'edit_plugins'           => true,
            'edit_users'             => true,
            // [...]
        )
    ),
    'contributor' => array(
        'name'         => '投稿者',
        'capabilities' => array(
            'delete_pages'           => true,
            'delete_others_pages'    => true,
            'delete_published_pages' => true,
            'delete_posts'           => true,
            // [...]
        )
    ),
    // [...]
);</code>
Copy after login
Copy after login
Copy after login

Roles are never hardcoded; roles are just permission wrappers, which only exist in the database.

Using roles and permissions: WordPress API

Access API

WordPress provides the following global functions to help us handle roles.

current_user_can()

Check whether the current user has the required permissions.

<code>array(
    'administrator' => true
)</code>
Copy after login
Copy after login
Copy after login

WP_User::has_cap

Check whether a specific user has permission.

<code>if (!current_user_can('activate_plugins'))
{
    wp_die(__('您没有足够的权限来管理此站点的插件。'));
}</code>
Copy after login
Copy after login

We can notice that current_user_can uses this function.

get_editable_roles()

Returns to editable roles.

<code>add_action('init', function()
{
    if (current_user_can('install_plugins'))
    {
        echo '您可以安装插件';
    }
    else
    {
        echo '您不能安装插件';
    }
});</code>
Copy after login
Copy after login

This list may be overwritten by editable_roles filters, so we should not rely on this function to get the full list of roles on the website.

Please note the use of the admin_init hook, because the function has not been loaded in the init hook yet.

get_role()

Get WP_Role object based on its slug.

<code>add_action('init', function()   
{
    $user = get_user_by('slug', 'admin');
    if ($user->has_cap('install_plugins'))
    {
        echo '管理员可以安装插件';
    }
    else
    {
        echo '管理员不能安装插件';
    }
});</code>
Copy after login
Copy after login

WP_Role::has_cap()

Check whether the role has the required permissions.

<code>add_action('admin_init', function()
{
    $roles = get_editable_roles();
    var_dump($roles);
});</code>
Copy after login
Copy after login

Custom API

WordPress also provides a complete API to customize roles and their permissions.

add_role()

Register a new role in the database.

<code>add_action('init', function()
{
    $role = get_role('administrator');
    var_dump($role);
});

// 这将打印:
// WP_Role 对象
// (
//     [name] => administrator
//     [capabilities] => Array
//         (
//             [switch_themes] => 1
//             [edit_themes] => 1
//             [activate_plugins] => 1
//             [edit_plugins] => 1
//             [...]</code>
Copy after login
Copy after login

remove_role()

If present, delete the required role from the database.

<code>add_action('init', function()
{
    $role = get_role('administrator');
    var_dump($role->has_cap('install_plugins')); // 打印 TRUE
});</code>
Copy after login
Copy after login

WP_Role::add_cap()

Add permissions to the role.

<code>add_action('init', function()
{
    add_role('plugins_manager', '插件管理员', array(
        'install_plugins',
        'activate_plugins',
        'edit_plugins'
    ));
});</code>
Copy after login

This can be core permissions (install_plugins, edit_posts…) or any custom string (my_awesome_plugin_cap).

It allows us to register as many custom permissions as possible for our plugin.

WP_Role::remove_cap()

If it exists, delete permissions from the role.

<code>add_action('init', function()
{
    remove_role('plugins_manager');
});</code>
Copy after login

WP_User::add_role()

Add roles to a given user.

<code>add_action('init', function()
{
    $role = get_role('contributor');
    $role->add_cap('install_plugins');
});</code>
Copy after login

This function allows you to theoretically set multiple roles for the same user.

Since the WordPress backend only displays and manages one role per user, we should not add multiple roles for users and should always use WP_User::remove_role() before adding a new role.

WP_User::remove_role()

Remove roles from the given user.

<code>add_action('init', function()
{
    $role = get_role('contributor');
    $role->remove_cap('install_plugins');
});</code>
Copy after login

WP_User::add_cap()

Add permissions to a given user.

<code>array(
    'administrator' => array(
        'name'         => '管理员',
        'capabilities' => array(
            'switch_themes'          => true,
            'edit_themes'            => true,
            'activate_plugins'       => true,
            'edit_plugins'           => true,
            'edit_users'             => true,
            // [...]
        )
    ),
    'contributor' => array(
        'name'         => '投稿者',
        'capabilities' => array(
            'delete_pages'           => true,
            'delete_others_pages'    => true,
            'delete_published_pages' => true,
            'delete_posts'           => true,
            // [...]
        )
    ),
    // [...]
);</code>
Copy after login
Copy after login
Copy after login

Mastering WordPress Roles and Capabilities This is very useful if we want to add a single permission to the user without having to create a full role.

WP_User::remove_cap()

Remove permissions from the given user.

<code>array(
    'administrator' => true
)</code>
Copy after login
Copy after login
Copy after login

Some issues with WordPress API

Apart from one question, the functions we see look good: database access and performance.

What we mainly focus on when dealing with roles and permissions is when should our code be triggered?

To explain this, let's take a look at WordPress core code.

First, we want to add a new empty character:

<code>if (!current_user_can('activate_plugins'))
{
    wp_die(__('您没有足够的权限来管理此站点的插件。'));
}</code>
Copy after login
Copy after login
The following are the first few lines of the

function (actually redirected to add_role): WP_Roles::add_role

<code>add_action('init', function()
{
    if (current_user_can('install_plugins'))
    {
        echo '您可以安装插件';
    }
    else
    {
        echo '您不能安装插件';
    }
});</code>
Copy after login
Copy after login
If we add a new role, the

function runs once and then does nothing. add_role

Next, suppose we want to add permissions to our newly created role:

<code>add_action('init', function()   
{
    $user = get_user_by('slug', 'admin');
    if ($user->has_cap('install_plugins'))
    {
        echo '管理员可以安装插件';
    }
    else
    {
        echo '管理员不能安装插件';
    }
});</code>
Copy after login
Copy after login
The

function in WordPress 4.2.2 is as follows: WP_Role::add_cap()

<code>add_action('admin_init', function()
{
    $roles = get_editable_roles();
    var_dump($roles);
});</code>
Copy after login
Copy after login
It updates the

object, but we can also see that the database will update every time our code runs, even if our new permissions are already registered! $this->roles This means that if we care about performance, all the code we write for custom roles and permissions should not run when each page is loading.

Solution

There are several ways to avoid these database problems.

Activate with plug-in

WordPress allows plugin authors to use the

function to trigger code when the plugin is enabled in the backend.

Let's create a sample plugin: register_activation_hook()

This code will only run once when the plugin is enabled on the website.

<code>add_action('init', function()
{
    $role = get_role('administrator');
    var_dump($role);
});

// 这将打印:
// WP_Role 对象
// (
//     [name] => administrator
//     [capabilities] => Array
//         (
//             [switch_themes] => 1
//             [edit_themes] => 1
//             [activate_plugins] => 1
//             [edit_plugins] => 1
//             [...]</code>
Copy after login
Copy after login
Now, we must remember that this solution depends on the activation and deactivation of the plugin.

What happens if the plugin is already in production, or if the reactivate is omitted when the update is pushed?

In fact, this solution also relies on the database and requires an extra step when pushing the code.

Bypass WordPress database

There is also an undisclosed solution that works well in some cases.

Let's look at the WordPress core code at the end, when the

object loads the role from the database when WordPress starts:

WP_RolesWordPress checks for the

global variables before getting data from the database.
<code>add_action('init', function()
{
    $role = get_role('administrator');
    var_dump($role->has_cap('install_plugins')); // 打印 TRUE
});</code>
Copy after login
Copy after login

If set, WordPress will use its contents and block the database usage by setting the $wp_user_roles variable to false.

Let's try it out, keeping only a new, restricted administrator role: $this->use_db

When loading the backend, we can see that it retains the definition of our custom role:

Mastering WordPress Roles and Capabilities This solution solves the database problem, but may introduce some other issues:

  • Plugins using native APIs may not work properly.
  • We have to manually set the definition of each role, even for the role we don't want to change.

However, this may be a viable solution when building a custom WordPress application that requires a custom list of static roles:

  • Role definitions can be versioned with the code.
  • Pusing new code to the environment will automatically update the definition.
  • No need to consider database issues anymore.

Conclusion

In this article, I introduce an overview of roles and permissions usage in WordPress.

Although its complete API allows us to do almost anything we want, relationships with databases are still the main problem.

We must keep this in mind when developing our plugins and themes.

What do you think about the way WordPress manages roles? Looking forward to your feedback!

Frequently Asked Questions about Mastering WordPress Roles and Permissions

What is the default user role in WordPress? What are their permissions?

WordPress has six default user roles: Super Administrator, Administrator, Editor, Author, Contributor, and Subscriber. Each role has a specific set of permissions. For example, a super administrator can access all administrative features of multiple sites. Administrators can perform all administrative tasks on a single site. Editors can publish and manage posts, including those of other users. Authors can post and manage their own posts. Contributors can write and manage their own posts, but they cannot be posted. Subscribers can only manage their profile.

How to add new user roles in WordPress?

To add a new user role in WordPress, you can use the add_role() function. This function accepts three parameters: role, display name, and permission array. For example, to add a new role called "custom_role" and have permission to read and edit posts, you can use the following code:

add_role( 'custom_role', __('自定义角色'), array( 'read' => true, // 可以读取帖子 'edit_posts' => true, // 可以编辑帖子 ) );

How to delete user roles in WordPress?

To delete a user role in WordPress, you can use the remove_role() function. This function accepts one parameter: role. For example, to delete the previously added "custom_role", you can use the following code:

remove_role('custom_role');

How to add permissions to user roles in WordPress?

To add permissions to user roles in WordPress, you can use the add_cap() function. This function accepts two parameters: permission and a Boolean value indicating whether the role has the permission. For example, to add "publish_posts" permission to "custom_role", you can use the following code:

$role = get_role('custom_role'); $role->add_cap('publish_posts', true);

How to remove permissions from user roles in WordPress?

To remove permissions from user roles in WordPress, you can use the remove_cap() function. This function accepts a parameter: permission. For example, to remove the "publish_posts" permission from "custom_role", you can use the following code:

$role = get_role('custom_role'); $role->remove_cap('publish_posts');

How to change the default user role in WordPress?

To change the default user role in WordPress, navigate to Settings > General in the WordPress dashboard. Under New User Default Roles, select the role you want to set as default from the drop-down menu.

How to assign multiple roles to users in WordPress?

WordPress does not support assigning multiple roles to users by default. However, you can do this using plugins like Multiple Roles. After you install and activate the plugin, you can assign multiple roles to the user from the user's profile page.

How to limit content access based on user roles in WordPress?

To restrict content access based on user roles in WordPress, you can use plugins like Members. This plugin allows you to control which roles can access specific content on your website.

How to create custom permissions in WordPress?

To create custom permissions in WordPress, you can use the add_cap() function. This function accepts two parameters: permission and a Boolean value indicating whether the role has the permission. For example, to add a custom permission named "manage_custom" to "custom_role", you can use the following code:

$role = get_role('custom_role'); $role->add_cap('manage_custom', true);

How to check if a user in WordPress has specific permissions?

To check if a user in WordPress has specific permissions, you can use the current_user_can() function. This function accepts a parameter: permission. For example, to check if the current user has "manage_custom" permission, you can use the following code:

if (current_user_can('manage_custom')) { // 当前用户具有“manage_custom”权限 }

All pictures retain their original format and location.

The above is the detailed content of Mastering WordPress Roles and Capabilities. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template