How to update role capabilities

add_role() will not do anything if the role already exists, so it can’t be used to modify capabilities. To modify capabilities use the add_cap() and remove_cap() method of the WP_Role object. You can get a WP_Role for your role using get_role():

$role = get_role( 'event-planner' );
$role->add_cap( 'edit_others_events' );

Here’s the thing though, roles are stored in the database, so adding roles or capabilities are things that shouldn’t be happening on every page load. If you want to modify an existing role, you’ll need to do it just once. So that means you’ll need to do it on theme or plugin activation, or when saving an options page. The same goes for creating the role to begin with.

Given that, if this is just a plugin/role that exists on just on your site, you’re probably better of just using a plugin like User Role Editor.

If it’s a distributed plugin, you could do it in a hook that loads on every page, but just check an option to see if the update has already been done:

function wpse_289293_update_role() {
    // Get current version of user role.
    $version = get_option( 'wpse_289293_roles_version' )

    // Define version number that represents this change.
    $new_version = 2;

    // If current version is lower than new version.
    if ( $version < $new_version ) {
        // Update the role.
        $role = get_role( 'event-planner' );
        $role->add_cap( 'edit_others_events' );

        // Update db to indicate role has been updated.
        update_option( 'wpse_289293_db_version', $new_version );
    }
}
add_action( 'plugins_loaded', 'wpse_289293_update_role' );

Because the role’s capabilities aren’t being forced on every page reload this also has the advantage of allowing users to use a user role editor plugin to modify the capabilities themselves. If add_cap() was being run on every page load it would overwrite any changes they would make.

Leave a Comment