Concept of Roles and Capabilities
WordPress provides a role-based permission system that controls what actions a user can perform on a website. Instead of granting every user full administrative access, WordPress assigns each user a role, and each role contains a set of capabilities.
A capability is a specific permission such as:
editing posts
publishing posts
installing plugins
managing options
deleting users
A role is simply a collection of capabilities.
Example: the Editor role has permissions to edit and publish posts, but cannot install plugins or change site settings.
This system helps maintain security and prevents unauthorized access to sensitive administrative functions.
Default WordPress Roles
WordPress includes several built-in roles:
| Role | Description |
|---|---|
| Super Admin | Full control over a multisite network |
| Administrator | Complete control of a single site |
| Editor | Can publish and manage posts including others’ posts |
| Author | Can publish and manage their own posts |
| Contributor | Can write posts but cannot publish them |
| Subscriber | Can only manage their profile |
Default Capabilities Examples
Common capabilities provided by WordPress include:
| Capability | Purpose |
|---|---|
| edit_posts | Allows editing of own posts |
| edit_others_posts | Allows editing posts written by other users |
| publish_posts | Allows publishing posts |
| delete_posts | Allows deleting own posts |
| delete_others_posts | Allows deleting posts from other users |
| manage_options | Allows changing site settings |
| install_plugins | Allows installing plugins |
| activate_plugins | Allows activating plugins |
| update_plugins | Allows updating plugins |
| delete_plugins | Allows deleting plugins |
| edit_users | Allows editing other user accounts |
| create_users | Allows creating new users |
| delete_users | Allows deleting users |
Capabilities are checked using the current_user_can() function.
Checking Capabilities
if ( current_user_can( 'edit_posts' ) ) {
echo 'User can edit posts';
}
if ( current_user_can( 'manage_options' ) ) {
echo 'User is likely an administrator';
}
Role API
WordPress provides a Role API to manage roles programmatically.
Key functions include:
add_role()remove_role()get_role()add_cap()remove_cap()
Retrieving a Role Object
$role = get_role( 'editor' );
if ( ! empty( $role ) ) {
$role->add_cap( 'edit_private_posts' );
}
Removing a Capability
$role = get_role( 'author' );
if ( $role ) {
$role->remove_cap( 'publish_posts' );
}
Adding a Custom Role
A custom role can be created using add_role().
Example: creating a role similar to administrator but without post editing capabilities.
function create_custom_admin_role() {
$admin = get_role( 'administrator' );
if ( $admin ) {
add_role(
'restricted_admin',
'Restricted Admin',
$admin->capabilities
);
$role = get_role( 'restricted_admin' );
$role->remove_cap( 'edit_posts' );
$role->remove_cap( 'edit_others_posts' );
$role->remove_cap( 'delete_posts' );
$role->remove_cap( 'delete_others_posts' );
}
}
add_action( 'init', 'create_custom_admin_role' );
Removing a Role
remove_role( 'restricted_admin' );
Adding Custom Capabilities
Developers can create their own capabilities to control access to specific plugin functionality.
function add_custom_capability() {
$role = get_role( 'administrator' );
if ( $role ) {
$role->add_cap( 'access_custom_admin_page' );
}
}
add_action( 'init', 'add_custom_capability' );
Restricting Access Using a Custom Capability
function register_custom_menu_page() {
add_menu_page(
'Custom Page',
'Custom Page',
'access_custom_admin_page',
'custom-admin-page',
'custom_admin_page_callback'
);
}
add_action( 'admin_menu', 'register_custom_menu_page' );
function custom_admin_page_callback() {
echo '<h1>Custom Admin Page</h1>';
}
Only users with the access_custom_admin_page capability will be able to access the menu.
Plugins for Exploring Roles and Capabilities
Common tools used during development:
User Role Editor – allows editing roles and capabilities through the UI
Members – powerful role management plugin
User Switching – allows switching between users for testing permissions
Users Role and User Metadata
Every WordPress user is assigned a role and additional information stored in the user metadata table (wp_usermeta).
User metadata stores extra details such as:
roles
capabilities
first name
last name
nickname
preferences
plugin-specific user data
Structure of wp_usermeta Table
|Column|Description| enquir |—|—| |umeta_id|Unique identifier| |user_id|ID of the user| |meta_key|Name of metadata| |meta_value|Stored value|
Roles and capabilities are stored using meta keys such as:
wp_capabilitieswp_user_level
Retrieving User Metadata
The function get_user_meta() is used to retrieve metadata.
$user_id = get_current_user_id();
$first_name = get_user_meta( $user_id, 'first_name', true );
echo $first_name;
If the $single parameter is set to false, the function returns an array.
$meta = get_user_meta( $user_id, 'favorite_color' );
print_r( $meta );
Updating User Metadata
update_user_meta( $user_id, 'favorite_color', 'blue' );
Adding User Metadata
add_user_meta( $user_id, 'membership_level', 'gold' );
Deleting User Metadata
delete_user_meta( $user_id, 'membership_level' );
map_meta_cap() Function
The map_meta_cap() function maps meta capabilities to primitive capabilities.
Meta capabilities represent high-level permissions such as:
edit_post
delete_post
edit_user
These are mapped internally to primitive capabilities like:
edit_posts
edit_others_posts
delete_posts
Example Usage
$user_id = get_current_user_id();
$post_id = 10;
$caps = map_meta_cap( 'edit_post', $user_id, $post_id );
print_r( $caps );
Output example:
Array
(
[0] => edit_posts
)
WordPress then checks whether the user has the required primitive capability.
map_meta_cap Filter
The map_meta_cap filter allows developers to customize how capabilities are mapped.
This is useful for implementing advanced permission logic.
Example: Restrict Editing a Specific Post
function restrict_editing_special_post( $caps, $cap, $user_id, $args ) {
if ( $cap === 'edit_post' ) {
$post_id = $args[0];
if ( $post_id == 50 ) {
$caps = array( 'do_not_allow' );
}
}
return $caps;
}
add_filter( 'map_meta_cap', 'restrict_editing_special_post', 10, 4 );
In this example:
If a user attempts to edit post ID 50
WordPress maps the capability to
do_not_allowAccess is denied regardless of user role
Example: Allow Custom Capability for Editing a Post
function custom_capability_for_editing( $caps, $cap, $user_id, $args ) {
if ( $cap === 'edit_post' ) {
$post_id = $args[0];
if ( get_post_type( $post_id ) === 'product' ) {
$caps = array( 'edit_products' );
}
}
return $caps;
}
add_filter( 'map_meta_cap', 'custom_capability_for_editing', 10, 4 );
This allows developers to create advanced permission systems for custom post types or plugin features.