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:

RoleDescription
Super AdminFull control over a multisite network
AdministratorComplete control of a single site
EditorCan publish and manage posts including others’ posts
AuthorCan publish and manage their own posts
ContributorCan write posts but cannot publish them
SubscriberCan only manage their profile

Default Capabilities Examples

Common capabilities provided by WordPress include:

CapabilityPurpose
edit_postsAllows editing of own posts
edit_others_postsAllows editing posts written by other users
publish_postsAllows publishing posts
delete_postsAllows deleting own posts
delete_others_postsAllows deleting posts from other users
manage_optionsAllows changing site settings
install_pluginsAllows installing plugins
activate_pluginsAllows activating plugins
update_pluginsAllows updating plugins
delete_pluginsAllows deleting plugins
edit_usersAllows editing other user accounts
create_usersAllows creating new users
delete_usersAllows 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_capabilities

  • wp_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_allow

  • Access 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.