Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Users, roles and capabilities

A site may have several people with different duties: one writes articles, another reviews them, a third configures the site. WordPress separates them by roles, and each role is a set of capabilities for particular actions.

The built-in roles

RoleWhat it can do
Subscriber (subscriber)Read and edit their own profile
Contributor (contributor)Write posts but not publish them
Author (author)Publish and edit their own posts
Editor (editor)Manage all posts and pages
Administrator (administrator)Everything, including settings, themes and plugins

Checking capabilities

You check not the role but the capability for an action:

if (current_user_can('edit_posts')) {
    echo '<a href="' . esc_url(admin_url('post-new.php')) . '">Write a post</a>';
}
 
if (current_user_can('edit_post', $postId)) {
    edit_post_link('Edit', '', '', $postId);
}
CapabilityWhat it allows
readEntering the dashboard and one's own profile
edit_postsCreating posts
publish_postsPublishing
edit_others_postsChanging other people's posts
upload_filesUploading files
manage_optionsChanging site settings

The edit_post capability with a post number is special: WordPress itself decides whether the text is yours or someone else's and whether it is published.

The current user

<?php
// header.php
 
if (is_user_logged_in()) {
    $user = wp_get_current_user();
 
    printf(
        'Hello, %s! <a href="%s">Log out</a>',
        esc_html($user->display_name),
        esc_url(wp_logout_url(home_url('/'))),
    );
} else {
    printf('<a href="%s">Log in</a>', esc_url(wp_login_url(get_permalink())));
}

A custom role

Roles are stored in the database, so they are created once — on plugin activation:

// books.php
 
register_activation_hook(__FILE__, function () {
    add_role('librarian', 'Librarian', [
        'read' => true,
        'edit_posts' => true,
        'upload_files' => true,
    ]);
});
 
register_deactivation_hook(__FILE__, function () {
    remove_role('librarian');
});

A custom capability

A new capability can be added to an existing role:

register_activation_hook(__FILE__, function () {
    get_role('editor')?->add_cap('manage_books');
    get_role('administrator')?->add_cap('manage_books');
});
if (!current_user_can('manage_books')) {
    wp_die('You do not have permission.', 403);
}

User data

Extra details are kept in user metadata:

update_user_meta($userId, 'favorite_genre', 'fantasy');
 
$genre = get_user_meta($userId, 'favorite_genre', true);

Creating a user

$userId = wp_insert_user([
    'user_login' => 'anna',
    'user_email' => 'anna@example.com',
    'user_pass' => wp_generate_password(),
    'role' => 'author',
]);
 
if (is_wp_error($userId)) {
    error_log($userId->get_error_message());
}

WordPress hashes the password itself.

Restricted content

add_filter('the_content', function (string $content): string {
    if (is_singular('book') && !is_user_logged_in()) {
        return '<p>Log in to read the book.</p>';
    }
 
    return $content;
});

Common mistake

A role check — in_array('editor', $user->roles) — breaks as soon as the site gets a custom role or a plugin changes the set of capabilities. Ask about the action: current_user_can('edit_others_posts'). And do not call add_role() on every load of the site: that is an extra database write on each request.

Thanks for reading!

Donate to the site — we work hard for you.