One of the most criticized aspects of WordPress is the user privilege system. Versions 1.5.x and prior assign privileges using user levels. Each user has a zero through ten level, with level ten being an all powerful administrator and level zero having no powers. The levels are hierarchical. A higher level user can edit the posts of a lower level user. This sounds like a pretty simple scheme, but in practice it creates a lot of confusion. The privileges associated with each level are not clear. What is the difference between level ten and level five? Who can edit who? Can a level five edit another level five? What exactly can each of those eleven levels do?
For 2.0, we decided that the privilege system was ready for an overhaul. After researching the way other weblog and CMS applications handled privileges, we decided to go with a Role and Capability model. After some debate about the workflow we wanted to establish, we settled on creating five roles: Subscriber, Contributor, Author, Editor, and Administrator. Each of these roles has a set of associated capabilites. A Subscriber has very limited capabilities. A Subscriber can see the Dashboard and edit his own profile. That is all. A Contributor can draft posts but cannot publish them. An Author can publish posts. An Editor can edit other people’s posts and can manage categories, links, comments, and pages. An Administrator can do everyting. An Admin can switch themes, activate plugins, edit files, and run importers.
Although these roles seem hierarchical, they are not. Each role is simply a set of capabilities. The Editor and Administrator roles have the capability to edit posts that do not belong to them. They can edit anyone’s posts, including each other’s. For those used to the old user level hierarchy, allowing Editors to modify posts made by Administrators may seem odd. Avoiding the hierarchy was a purposeful decision, however. You either have the capability to edit other’s posts, or you don’t. We’re trying to keep it simple.
Users can belong to one or more roles and can have individual capabilities assigned to them outside of the context of a role. In the default UI, only one role per user is exposed. You select which of the five roles you want a user to be in, and that is that. You can’t edit roles or assign individual capabilities to users. Again, this is a purposeful design decision that is intended to keep things simple. More advanced role and capability management will be available through a plugin.
Currently, about twenty capabilities are defined. In the code, capabilities are simply keywords that can be assigned to users and roles. Here is our full capability set.
- switch_themes
- edit_themes
- activate_plugins
- edit_plugins
- edit_users
- edit_files
- manage_options
- moderate_comments
- manage_categories
- manage_links
- upload_files
- import
- unfiltered_html
- edit_posts
- edit_others_posts
- edit_published_posts
- publish_posts
- edit_pages
- read
For backward compatiblity with the user level system, we also have capabilities that correspond to levels: level_0, level_1, … , level_10. A Subscriber has the level_0 capability. A Contributor has level_0 and level_1. An Author has level_0, level_1, and level_2. An Editor has level_0 through level_7, and an Administrator has level_0 through level_10. When upgrading from a previous version of WP, all users are mapped to roles based on their user level. A level seven user will be mapped into the Editor role, for example.
For plugin authors, an API is available for retrieving and manipulating roles and capabilities. A plugin can create a new capability called ‘do_foo’ and give that capability to the Adminstrator role with the following code.
$role = get_role('administrator');
$role->add_cap('do_foo');
To check if the currently logged in user has this capability, plugins can make use of the current_user_can() function.
if ( current_user_can('do_foo') ) ...
To check the capabilities for a certain user ID, instantiate a WP_User object.
$user_id = 1;
$user = new WP_User($user_id);
if ( $user->has_cap('do_foo') ) ...
If a brand new role is needed, one can be created using add_role() and add_cap().
$role = add_role('foo_doer', 'Foo Doer');
$role->add_cap('do_foo');
$role->add_cap('do_bar');
Those are the basics. Consult capabilities.php for the full API. The most commonly used bit of API is current_user_can(). Whenever you need to determine if the logged-in user can do something, use current_user_can().
For more information on roles and capabilities, take a look at Owen’s overview. If you are a plugin author with questions regarding use of the API, visit the Hackers list. If you are a user wondering what this means to you, visit the Support Forums.
What’s the best time to add caps? Plugins are loaded before $wp_roles is defined, so you can’t use get_role() etc. unless it’s hooked into a function.
The init action?
Ryan: Great stuff. I’ve always meant to clarify what levels signified. Now I don’t need to!
This is a fantastic development for WordPress, and I’m wondering if you think this might lead to more collaborative blogs appearing out there?
So a bunch of nonsensical user levels with numeric names have been replaced with a bunch of nonsensical user levels with textual names? Big deal. Why not just let site administrators define their own ‘roles’ phpbb-style?
Hmm, Why can’t users edit their own coments? I didn’t see the option in this post, and that is the most used user permission on my blog. I use a plug-in for allowing editting of comments, but it should be built into wordpress.
Hey Ryan, this post was a nice kick off to bring me on the right track with roles and capabilies but because the strings for the roles are localized, could you please edit your examples to
$role = get_role(__(‘Administrator’));
One suggestion. I would love to have a “Commentator” Role/Capability. On my new blog I feel compelled to turn off comment capability, but if a “Commentator” Role was created then I could assign rights to team members who would have the ability to comment on stories and no one else.
True, I could just turn comments on and then moderate them so that only team members were posted; however, then I risk upsetting those who leave a comment and are rejected out of hand.
It’s just a thought
Challen
I finally found what many of you said you were looking for…just like me. The ability to moderate authors.
I used this plugin successfully. It saved my life…
It’s a plugin for WordPress2.0 called Role Manager.
http://redalt.com/Resources/Plugins/Role+Manager