Ultimate Guide to Roles and Capabilities

What are Roles and Capabilities?
In other CMS and web applications, WordPress has a built-in system to verify whether a particular user has enough privilege to take a certain action. Users are divided into Roles, and each Role is assigned certain capabilities (or permissions).

Here is a summary of WordPress default roles:img_03

  • Administrator – Somebody who has access to all the administration features
  • Editor – Somebody who can publish posts, manage posts as well as manage other people’s posts, etc.
  • Author – Somebody who can publish and manage their own posts
  • Contributor – Somebody who can write and manage their posts but not publish posts
  • Subscriber – Somebody who can read comments/comment/receive news letters, etc.

Roles and Capabilities is much more flexible than User Level, since it enables you to add, remove or re-assign capabilities among roles.

You can even add more roles to the system without destroying the default setup.

Capabilities and administration menus

Almost every plugin needs to have at least one page in the admin area to let users customize how the plugin is used.

In order to do this, you need to add your own administration menu items. There are a number of WordPress functions which let you do this:

// add top level menu
add_menu_page(page_title, menu_title, capability, handle, [function], [icon_url]);
// add sub-menu pages
add_submenu_page(parent, page_title, menu_title, capability, file/handle, [function]);
// add Options sub-menu
add_options_page(page_title, menu_title, capability, handle, [function]);
// add Management sub-menu
add_management_page(page_title, menu_title, capability, handle, [function]);
// add Pages sub-menu
add_pages_page( page_title, menu_title, capability, handle, [function]);
// add Posts sub-menu
add_posts_page( page_title, menu_title, capability, handle, [function]);
// add Appearances sub-menu
add_theme_page( page_title, menu_title, capability, handle, [function]);

There’s always a required parameter called capability for each of those functions. This essentially means the user who logs in to the administration area needs to have a certain capability to see the menu item.

You can either use a user level (which is deprecated and not recommended), or a string representing a certain capability (for example, edit_posts).

Many plugins still use user levels (numeric representation of a user’s privilege, from 0 to 10).

However, this is deprecated and should not be used anymore. By using capabilities, you won’t have to worry when user levels are not supported by WordPress, and if you want to add and use your custom capabilities, this is the way to go.

If you use the functions above to add menu items to the admin area, only the users who have the specified capability can see the menu items and access the pages associated with those items. If your theme or plugin has an option page, it’s important that you restrict access to that page properly. For example, if it’s a theme option page, you should use edit_themes capability, while if it’s a plugin option, edit_plugins. Another way is to use manage_options for both plugin and theme option pages.
Remember, sometimes the blog administrator wants to share and divide responsibilities among several other users. As a result, using capabilities make your themes and plugins much more customizable.

Checking a user’s capability

If your plugin or theme involves the user making changes to the blog’s data (adding new or editing existing content etc.), it’s very important that you check whether the current user has enough capability to make a certain action.

The current_user_can() function lets you do this:

if ( current_user_can( $capability ) ) {
// do something if the current user has $capability

This function also accepts an optional argument for a certain post ID, in case you want to check whether the current user can do something to that post:

// check whether the current can edit a post with the ID $post_id
current_user_can( ‘edit_post’, $post_id );

There’s another function you can use to check whether the author of a certain post has a certain capability:

if ( author_can( $post, $capability ) ) {
// do something if the author of the post $post has $capability

The first argument can be either a post object, or a post ID. Although this function is rarely used, it’s helpful to know it’s there. I personally never had to use that function, but if you have an interesting example, let me know in the comment!

Adding custom user rolesuser-role-editor

Sometimes it’s necessary for your plugin to add new roles to the system. Let’s say you’re coding a new gallery plugin where users can register to upload photos to your site, but that’s it – these registered users can’t add or modify any other type of content to your blog (such as posts or pages). The best way to do this, is to add a new custom role:

add_role( $role_name, $display_name, $capabilities );
// for example:
add_role( ‘photo_uploader’, ‘Photo Uploader’, array( ‘organize_gallery’ ) );

What this function does is add a new role to the system with a set of capabilities. The example aboves add a role called “photo_uploader”, with a display name and an array containing a list of default capabilities for that role (in this case, organize_gallery ).

When you process a request to create, edit or upload galleries, you should use current_user_can() to check whether the current user are permitted to take these actions.

if ( current_user_can( ‘organize_gallery’ ) ) {
// do something

The users who are assigned this role can only organize_gallery, but cannot edit_posts or publish_posts.
To remove a role, you can use remove_role():

remove_role( ‘photo_uploader’ );

You should have an option somewhere for your plugin users to remove this custom role when they decide to uninstall your plugin.
But what if you want to add capabilities to existing users?

Adding custom user capabilities

This is useful when you develop a plugin that allows users to take actions other than manipulating post contents. Let’s come back to our gallery plugin example above. Say, if you also want to assign organize_gallery capability to existing roles (administrator, editor, author, contributor etc. ), what would you do?

// get the “author” role object
$role = get_role( ‘author’ );
// add “organize_gallery” to this role object
$role->add_cap( ‘organize_gallery’ );

WordPress Capability Classes

We’ve covered checking and adding capabilities, as well as adding roles. These are the most frequent used functions for managing user permissions in WordPress. However, as the title of this post contains the word “ultimate”, I’d like to also cover the three WordPress classes that work behind the scene and the API these classes provide, which you can use for advanced permission management in your plugin. These three classes are:
WP_Roles
WP_Role
WP_User
The source code of these three classes can be found in wp-includes/capabilities.php. The source code is documented in great details and I’m sure you can understand it easily, but I’d like to sum up what you can do with these classes.

The WP_Roles Class

This class, as its name suggests, is for managing roles in general. When you use it in your plugin, you actually don’t have to initiate a new object, but use a global object which has been created by WordPress:

global $wp_roles;

The $wp_roles is available as a global object, and can be used anywhere in your functions, as long as it’s declared beforehand in your functions with the global keyword.
As covered before, you can add and remove roles using add_role() and remove_role(). These functions are actually wrappers for $wp_roles->add_role(), and $wp_roles->remove_role. Therefore you can add and remove roles using the $wp_roles object as well:

global $wp_roles;
// add a new role, same arguments as add_role()
$wp_roles->add_role( $role, $display_name, $capabilities )
// remove a role, same arguments as remove_role()
$wp_roles->remove_role( $role );

Likewise, you can also get a role using this method:

global $wp_roles;
// get a role based on role name, does the same thing as get_role()
$wp_roles->get_role( $role );

You can also get a list of available roles, containing pair of role names and role display names. This is useful when you want to provide an interface for the user to change capability assignment.

global $wp_roles;
// get a list of values, containing pairs of: $role_name => $display_name
$roles = $wp_roles->get_names();

Finally, you can add and remove capabilities using $wp_roles too, making this object versatile for almost all roles and capabilities operations.

global $wp_roles;
// add capability $cap to role $role
$wp_roles->add_cap( $role, $cap );
// remove capability $cap from role $role
$wp_roles->remove_cap( $role, $cap );
// for example
$wp_roles->add_cap( ‘administrator’, ‘manage_galleries’ );
$wp_roles->remove_cap( ‘subscriber’, ‘view_galleries’ );

WP_Role Class

This is a very simple class. All it does is adding and removing capabilities.

// get the the role object
$role_object = get_role( $role_name );
// add $cap capability to this role object
$role_object->add_cap( $capability_name );
// remove $cap capability from this role object
$role_object->remove_cap( $capability_name );

WP_User class

This class lets you manage roles and capabilities per user, which means you can assign multiple roles to a particular user, or add a capability to a certain user regardless of his current role.
First of all, you need to get the user object before manipulating its roles and capabilities:

// get user by user ID
$user = new WP_User( $id );
// or get user by username
$user = new WP_User( null, $name );

As you can see, you can get a user object based on either his user ID or username. With the latter, the first parameter must be empty (either null or an empty string). Examples:

// get the administrator by ID
$admin = new WP_User( 1 );
// get the administrator by username
$admin = new WP_User( null, ‘admin’ );

Once you have the user object, you can add another role to this user without modifying his current role (which means the user can have as many roles as you want):

$user->add_role( $role_name );

Or you can remove a role from this user, using remove_role():

$user->remove_role( $role_name );

You can also set a role to this user, which means removing all the current roles of this user and assign a new one:

$user->set_role( $role_name );

For manipulating capabilities, you have a bunch of methods that allow you to do various things:

// check whether the user has a certain capability or role name
if ( $user->has_cap( $cap_name ) ) {
// do something
// add a capability to the user and grant access to that capability
$user->add_cap( $cap_name );
// remove a capability from the user
$user->remove_cap( $cap_name );
// remove all capabilities from the user
$user->remove_all_caps();

In Summary

There, that’s all there is to know about Roles and Capabilities. You may not need to grasp all of this, but it’s definitely helpful to know WordPress has a full-fledged user and role management system, which you can always use for complicated projects.

If you have any comment or suggestion, please leave it below!