This is a four-part series tutorial covering the WordPress users, roles and capabilities topic. The series will cover the architecture and design of user roles in WordPress; highlight the most important functions for interacting with users and managing roles and capabilities; and in the last tutorial, we are going to build a real-life example that demonstrates the usefulness of this API.
Introduction
In the first part, we covered only theory about users, roles and capabilities. This part will focus on code and the functions WordPress offers to interact with this system. Obviously, we are not going to cover all the functions WordPress has, but I tried to go over the most important and useful ones.
As WordPress changes and updates are pushed frequently, you should always return to the Codex documentation and check if something changed. I'll provide a link to the Codex page for every function we'll cover here for your convenience.
Managing Users
Users in WordPress are different from visitors. They are people who have registered an account with a unique username on your site. You can enable the registration of new users on your site from the Settings -> General panel by checking the "Membership -> Anyone can register" checkbox.
In this section, we'll cover some of the useful functions to interact with registered users in WordPress. Your fresh WordPress setup should have at least one user: the one who setup the WordPress install. In older versions, this was the "admin"; however, now you can pick the username when installing WordPress.
-
Creating, Updating and Deleting Users
WordPress has a visual interface to create, update and delete users. You should use it most of the time. However, there are cases when you want to do that with programming: For example, when importing users from another framework or if you are building your own custom registration form.
WordPress has four functions to perform these activities:
At first, it can be a bit confusing. All of the first 3 functions can create new users, and both "
wp_insert_user
" and "wp_update_user
" can update existing users. But there is a reason for that.There are two ways to create a new user:
- By passing only the minimal information required to create the user (username, password and email). In this case, you should use the
wp_create_user
function. - By passing an array of the user's data. In this case, you should use the
wp_insert_user
function. This gives the ability to set any user data for your user before adding it.
To update an existing user, you should use
wp_update_user
. It's possible to use the samewp_insert_user
; however, this function doesn't hash the user password and thus can fail. Therefore, it's better to use the right function for the right job.Below, I'm outlining a sample snippet of usage for each function. You should, however, refer to the Codex if you are looking for more detailed documentation.
Usage of
wp_create_user
add_action( 'init', 'wpttuts_createuser' ); function wpttuts_createuser() { // User Data $user_name = 'new_user'; $user_password = 'new_user_password'; $user_email = '[email protected]'; // Create the user $user_id = wp_create_user( $user_name, $user_password, $user_email ); // Checks if the function returned a WP Error Object if ( is_wp_error ($user_id) ) { $user_id->get_error_message(); } else { // user created successfully } }
Usage of
wp_insert_user
add_action( 'init', 'wpttuts_insertuser' ); function wpttuts_insertuser() { // Prepare the user data $user_data = array ( 'user_login' => 'new_user', 'user_password' => 'new_user_password' 'user_email' => '[email protected]', 'role' => 'administrator' ); // Create the user $user_id = wp_insert_user( $user_data ); // Checks if the function returned a WP Error Object if ( is_wp_error( $user_id ) ) { $user_id->get_error_message(); } else { // user created successfully } }
Usage of
wp_update_user
add_action( 'init', 'wpttuts_updateuser' ); function wpttuts_updateuser() { // Prepare the user data $user_data = array ( 'user_id' => 3, 'description' => ' Our newly created user' ); // Updates the user description $user_id = wp_update_user( $user_data ); // Checks if the function returned a WP Error Object if ( is_wp_error( $user_id ) ) { $user_id->get_error_message(); } else { // user updated successfully } }
Usage of
wp_delete_user
add_action( 'init', 'wpttuts_deleteuser' ); function wpttuts_deleteuser() { if ( wp_delete_user( 3, 1 ) ) { // User removed successfully } }
- By passing only the minimal information required to create the user (username, password and email). In this case, you should use the
-
Getting the List of Users
WordPress used to offer two functions to retrieve the list of users, so you don't have to query the database. The first function "
get_users_of_blog()
" returns an array of all the users in the current blog (or you can pass a blog ID if you are running a MultiSite install). The second function "get_users()
" returns a list of users based on the arguments passed to the function. This eliminates the need to do custom SQL queries to the database.Both functions return an array of user data objects. (Except for
get_users()
where you can specify to return only a particular field.) The user object will be covered in more details in the next section.The "
get_users_of_blog()
" function is now deprecated, so you should no longer use it, and use "get_users()
" instead. The following is an example of usage for "get_users()
".add_action( 'init', 'wpttuts_getusers' ); function wpttuts_getusers() { // Query criteria $args = array ( 'orderby' => 'url', 'order' => 'ASC' ); // Get the users array $users = get_users( $args ); // Loop through users, and display their home page foreach( $users as $user) { echo '<a href="' . $user->user_url . '">' . $user->user_url . '</a>'; } }
The function argument accepts more options. You can find the complete list of these options in the function Codex page.
-
blog_id
Only useful for multisite installs. The default value is the current blog ID. -
role
Limit the returned users to the role specified. -
include
An array of user IDs to include in the returned query. -
exclude
An array of user IDs to exclude from the returned query.
-
-
The
WP_User
ClassThe
WP_User
class allows accessing properties, capabilities and methods relative for a particular user. To create a new instance of the class you need the user ID or username; and if you are on a multisite install, you'll need also the blog ID.You can initiate the class for a particular user, and dump the class content. This will display only the properties, but it's still useful if you want to read inside the user class.
add_action( 'init', 'wptuts_wpuserclass' ); function wptuts_wpuserclass() { $user = new WP_User( 1 ); var_dump( $user ); }
The following is a summary of the properties and methods of the
WP_User
class:WP_User
Properties-
data
(Object with the user details such as the username, password, URL...) -
ID
(Integer The user ID) -
caps
(Array) -
roles
(Array Roles assigned to the user) -
cap_key
(String) -
allcaps
(Array All the capabilities the user has) -
filter
(Null)
WP_User
Public Methods-
get_role_caps()
Sets the roles and allcaps properties. -
add_role()
Add a role to the user. -
remove_role()
Remove a role from the user. -
set_role()
Set a role to the user. This will remove previously assigned roles. -
add_cap()
Add capability to the user. -
remove_cap()
Remove capability from user. -
remove_all_caps()
Remove all of the capabilities of the user. -
has_cap()
Checks if the user has a capability or role name.
-
-
Users' Meta-Data
As pointed out in the previous article, users' meta-data is data about the user saved in the
wp_usermeta
table. It's saved as key/pair values, and the meta value can be any type of data. The pair is not necessarily unique. You can store multiple pairs with the same key.Adding a User Meta-Data
The function
add_user_meta()
adds new user metadata. The function returns true when the data is successfully added and false if it fails. As mentioned earlier, it's possible to add many meta values with the same key. If you want to make meta keys unique, set the fourth argument to true.add_action('init', 'wptuts_addusermeta'); function wptuts_addusermeta() { // Add multiple meta values with the same meta key add_user_meta( 1, 'bookmarks', 'http://site1.com', false ); add_user_meta( 1, 'bookmarks', 'http://site2.com', false ); add_user_meta( 1, 'bookmarks', 'http://site3.com', false ); }
Retrieving a User Meta-Data
The function
get_user_meta()
returns the meta value based on the user ID and meta key passed to it.add_action('init', 'wptuts_getusermeta'); function wptuts_getusermeta() { // Retrieves the user bookmarks $bookmarks = get_user_meta( 1, 'bookmarks', false ); echo '<ul>'; foreach ( $bookmarks as $bookmark ) { echo '<li><a href="' . $bookmark . '">' . $bookmark . '</a></li>'; } echo '</ul>'; }
Updating a User Meta-Data
The function
update_user_meta()
updates a single meta value. If there are multiple values for the same meta key, and no previous meta value was specified, then the new value will overwrite all the previous meta values.add_action('init', 'wptuts_updateusermeta'); function wptuts_updateusermeta() { // Updates a user bookmark update_user_meta( 1, 'bookmarks', 'https://site2.com', 'http://site2.com' ); }
Removing a User Meta-Data
The function
delete_user_data()
removes a single or all meta key/pairs for a given meta key. If you want to remove a single value, then you should specify it in the third argument.add_action('init', 'wptuts_removeusermeta'); function wptuts_removeusermeta() { // Updates a user bookmark delete_user_meta( 1, 'bookmarks', 'https://site2.com' ); }
Managing Roles and Capabilities
-
Creating, and Removing Roles
WordPress roles are extensible. You can add and remove roles. Adding a role is pretty simple, you need a role slug name, a display name for the role; and the capabilities the role has.
add_action( 'init', 'wptuts_addrole' ); function wptuts_addrole() { add_role( 'uploader', 'Uploader', array('upload_files') ); add_role( 'link_manager', 'Link Manager', array('manage_links') ); }
If you check a user settings page ( User->Pick Any User->Edit ), you'll find that your newly added roles are available. They are displayed with the display name you entered.
It's important to mention that role creation needs to be done only once. So if you are hooking to the "
init
" action like in the code above, you are re-creating the role every time the code fires. This is not a good thing; in practice, you want to create it only once. You can then hook it to the plugin activation hook, and make sure to remove it when the plugin is deactivated.Removing roles is pretty straightforward too. You just need the role slug name.
add_action( 'init', 'wptuts_removerole' ); function wptuts_removerole() { remove_role( 'uploader' ); remove_role( 'link_manager' ); }
-
Adding Capabilities to Roles
Similarly to users, roles have a special class:
WP_Role
. However, initializing this class requires both the role name and also the role capabilities; which is not quite so useful.WordPress offers another function
get_role()
which requires only the role name and initializes the class for you.add_action('init', 'wptuts_getrole'); function wptuts_getrole() { $role = get_role('editor'); var_dump($role); }
The returned object has two properties, and three methods.
WP_Role
Properties-
capabilities
An array of the capabilities the role has. -
name
The role name.
WP_Role
Methods-
add_cap()
Add the capability to the role object -
has_cap()
Verify whether the role has the capability -
remove_cap()
Remove the capability from the role
-
-
Checking for Permissions
Roles and capabilities are there, they do nothing. You should enforce them in your plugin or theme by checking them before executing code. You should always check for capabilities instead of roles. A user with a role of "editor" doesn't guarantee that he has the default capabilities that WordPress assign to this role since they can be changed by another plugin or the blog owner himself.
WordPress has 3 functions for checking permissions, which are interchangeable to some degree.
current_user_can()
checks if the current user has the specified capability. It also accepts a post or object to check for meta-capabilities.user_can()
works in the same fashion but you can specify the user ID. It doesn't check for meta-capabilities, though. So it is a little lacking if you want to check for a meta-capability for a user different than the current user. For that, you can use theauthor_can()
function which checks if a post author can perform a specific task based on a capability and post ID.// checks if the post author of the first post can publish the post if ( author_can( 1, 'publish_posts') ) { publish_post_function(); // publish the post } else { echo "You don't have the right to publish the post"; }
Conclusion
In this part, I tried to cover as much functions WordPress has as possible, and also explain when you should use each function. Now, you should be able to create a plugin or theme which uses the capability system. In the next part, I'm going to show you how to build a plugin that uses this system.
Comments