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.
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. register_activation_hook()
function. Another way is to bypass the WordPress database by setting the $wp_user_roles
global variable. 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.
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>
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
and plugins_loaded
hooks. init
stored in the wp_usermeta
table to link users to their roles. meta_key
After deserialization, the metadata is as follows:
<code>array( 'administrator' => true )</code>
Also, remember
is the prefix of the current blog. wp_
function). $GLOBALS['wpdb']->get_blog_prefix()
wp_capabilities
a:1:{s:13:"administrator";b:1;}
wp_10_capabilities
a:1:{s:11:"contributor";b:1;}
wp_15_capabilities
a:1:{s:10:"subscriber";b:1;}
[...]
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.
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>
Roles are never hardcoded; roles are just permission wrappers, which only exist in the database.
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>
WP_User::has_cap
Check whether a specific user has permission.
<code>if (!current_user_can('activate_plugins')) { wp_die(__('您没有足够的权限来管理此站点的插件。')); }</code>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
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>
function runs once and then does nothing. add_role
<code>add_action('init', function() { $user = get_user_by('slug', 'admin'); if ($user->has_cap('install_plugins')) { echo '管理员可以安装插件'; } else { echo '管理员不能安装插件'; } });</code>
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>
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.
There are several ways to avoid these database problems.
WordPress allows plugin authors to use the
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>
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.
object loads the role from the database when WordPress starts:
WP_Roles
WordPress checks for the
<code>add_action('init', function() { $role = get_role('administrator'); var_dump($role->has_cap('install_plugins')); // 打印 TRUE });</code>
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:
This solution solves the database problem, but may introduce some other issues:
However, this may be a viable solution when building a custom WordPress application that requires a custom list of static roles:
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!
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.
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, // 可以编辑帖子 ) );
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');
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);
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');
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.
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.
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.
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);
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!