The concept of WordPress roles and capabilities can be confusing, so lets take a few minutes to decipher the lingo and make sense of them. As a bonus I will also show you how to implement roles and capabilities in plugins.
Roles are what users are grouped by in WordPress. They’re a way of giving a label to various sets of users. One of the most important things to note is that roles are not hierarchical. For example, an administrator is not necessarily “higher” than an editor. Roles are merely defined by what the role can and can’t do. It’s a permissions system.
Capabilities are that permissions system. Roles are assigned capabilities that define what that role can or can’t do. These can be set up with the WordPress defaults or be completely custom, depending on the site. As a plugin developer, you can’t make too many assumptions about what certain roles have permission to do.
WordPress ships with five default roles, which work well for most installs. Although roles are not hierarchical, the default roles do set up what appears to be a hierarchical system.
Administrator — Has control over everything on the site
Editor — Has publishing permission and editing access over everyone’ s posts
Author — Has publishing access and can edit its own posts but doesn’ t have control over others’ content
Contributor — Can submit posts but not publish them
Subscriber — Enables access to edit its user profi le and the WordPress dashboard
It is important to note that while these roles each come with a pre-defined set of capabilities, they can very easily be changed through code or by using a plugin such as Members. That means we can never assume that any of these roles has particular capabilities, although it is usually safe to assume that the ‘Administrator’ role has full rights/capabilities over the website.
The Capability vs Role table on WordPress.org can help you understand better what capabilities are assigned to roles in a default installation.
Since we can never assume much about roles, it is much safer to check for capabilities when defining who has access to an area of the site or not. We’ll come to that in a moment though.
Adding Custom Roles
First of all, dig into some code to learn how we can define custom roles. These can be useful for some plugins or custom functionality for a client. For example, most e-commerce plugins define custom roles such as ‘Shop vendor’ or ‘Shop Manager’, and these would have specific capabilities related to the e-commerce functionality on the site. A similar scenario presents itself for forum plugins, with roles such as ‘Forum Administrator’ and ‘Forum Member’, both of which obviously necessitate different capabilities.
Right, so how do we add a custom role and assign it a few capabilities? Here’s the code you need:
So here we’ve created a new role called ‘Advanced contributor’ and given it two capabilities, ‘edit_posts’ and ‘read’.
That code can be used within a plugin or within your theme’s functions.php file, although I always recommend you create a plugin for custom functionality on a client site. While we’re at it, I suggest using the excellent Pluginception for creating custom functionality within a plugin on your site.
Adding Custom Capabilities
Now that we’ve learnt how to create custom roles, how about learning how to create custom capabilities? Again, it’s a simple thing:
If you want to add a capability to a particular user, rather than to a particular role, use the following code:
When adding a custom role or custom capability, the information is saved to the database (in table wp_options, field wp_user_roles), so it might be better to run this on theme/plugin activation.
Checking for Capabilities
We can check whether a particular user has been assigned a capability, like so:
https://gist.github.com/jgalea/5983390To help you get the ID of the user you want to perform the check against, you can use the Reveal IDs plugin.
The check can also be performed on the current user:
Custom Post Types and Capabilities
When registering a custom post type, you can also define capabilities that will be needed to interact with this post type.
By default, seven keys are accepted as part of the capabilities array:
- edit_post, read_post, and delete_post are meta capabilities, which are then generally mapped to corresponding primitive capabilities depending on the context, which would be the post being edited/read/deleted and the user or role being checked. Thus these capabilities would generally not be granted directly to users or roles.
- edit_posts – Controls whether objects of this post type can be edited.
- edit_others_posts – Controls whether objects of this type owned by other users can be edited. If the post type does not support an author, then this will behave like edit_posts.
- publish_posts – Controls publishing objects of this post type.
- read_private_posts – Controls whether private objects can be read.
These four primitive capabilities are checked in core in various locations.
There are also seven other primitive capabilities which are not referenced directly in core, except in map_meta_cap(), which takes the three aforementioned meta capabilities and translates them into one or more primitive capabilities that must then be checked against the user or role, depending on the context.
- read – Controls whether objects of this post type can be read.
- delete_posts – Controls whether objects of this post type can be deleted.
- delete_private_posts – Controls whether private objects can be deleted.
- delete_published_posts – Controls whether published objects can be deleted.
- delete_others_posts – Controls whether objects owned by other users can be can be deleted. If the post type does not support an author, then this will behave like delete_posts.
- edit_private_posts – Controls whether private objects can be edited.
- edit_published_posts – Controls whether published objects can be edited.
These additional capabilities are only used in map_meta_cap(). Thus, they are only assigned by default if the post type is registered with the 'map_meta_cap' argument set to true (default is false).
I guess that you might be somewhat confused after reading that. Lets try to clear things up a little bit.
The key is knowing the difference between meta capabilities and primitive capabilities.
Primitive capabilities are flags, always set to yes or no. Meta capabilities require some context, like “Is the user the author of this post?”.
Meta capabilities need to be defined with the map_meta_cap filter.
Some other facts:
- Primitive capabilities are assigned to user roles.
- Meta capabilities never should be assigned to a role.
- Primitive capabilities are generally plural, meta capabilities are singular.
Here’s a typical code snippet where we are creating a custom post type and settings its capabilities:
The capability_type and capabilities arguments for the $args array in the register_post_type() function enable you to control custom capabilities. capability_type gives you global control over the capabilities. The capabilities argument is an array that gives you specific control over individual capabilities.
When you register a custom post type, you’re not registering new capabilities, so a roles management plugin such as Members wouldn’t recognize them as such. Capabilities have to be attached to a role/user for them to “exist,” so to speak.
You won’t have access to things with custom caps unless you literally assign these caps through the role editing screen (Members plugin). That means typing them rather than checking the boxes.
If you use post for the capability_type, all is right with the world because you’re just using something that’s already set up. But, if you’re using something custom…well…it’s custom. You’ll have to do a little legwork.
Meta capabilities (the equivalent of edit_post, delete_post, and read_post) aren’t mapped for a custom capability type. You have to do the mapping for these yourself.
Essential Plugins for Roles and Capabilities
A free plugin from Justin Tadlock. Members is a plugin that extends your control over your blog. It’s a user, role, and content management plugin that was created to make WordPress a more powerful CMS.
The foundation of the plugin is its extensive role and capability management system. This is the backbone of all the current features and planned future features.
Mao Cap is ideal if you are using custom post types and want to restrict access to these types to only certain roles.
Other Interesting Reads
If you have an offending plugin that is appearing on certain roles for which it shouldn’t appear, read our previous article on how to remove menu items in admin depending on user role.
We’ve been adding roles and capabilities, but how about deleting them? It’s a bit tricky, but check out this article that explains how to delete unwanted WordPress custom capabilities.
If you enjoyed this post, make sure to subscribe to WP Mayor’s RSS feed.