admin管理员组

文章数量:1289506

In a plugin, i create a dedicated user role along with some capabilities. These capabilities also need to be assigned to other roles, such as editor and admin.

As the addition of roles and capabilities involves database writes, these operations are commonly considered "expensive" and recommended to be performed only in the plugin activation hook. In my case, there is no activation hook, as the plugin needs to be loaded as mu-plugin. Therefore, i want to check if the admin and editor roles already have my custom capabilities, before attempting to add them.

How can i check if a specific role has a specific capability? Or, alternatively: Is it even less "expensive" to make the check? Or should i just make the call to add_cap() from the init hook without prior checks?

In a plugin, i create a dedicated user role along with some capabilities. These capabilities also need to be assigned to other roles, such as editor and admin.

As the addition of roles and capabilities involves database writes, these operations are commonly considered "expensive" and recommended to be performed only in the plugin activation hook. In my case, there is no activation hook, as the plugin needs to be loaded as mu-plugin. Therefore, i want to check if the admin and editor roles already have my custom capabilities, before attempting to add them.

How can i check if a specific role has a specific capability? Or, alternatively: Is it even less "expensive" to make the check? Or should i just make the call to add_cap() from the init hook without prior checks?

Share Improve this question asked Mar 14, 2018 at 16:40 jsphpljsphpl 2432 silver badges7 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 3

#Update: Wow, I feel like such a buffoon... haha. WP_Role::has_cap

I can't (role) my eyes hard enough.

$caps  = array( 'cap_1', 'cap_2', 'cap_3' );
$roles = array( 'administrator', 'editor' );

foreach( $roles as $role ) {
    if( $role_object = get_role( $role ) ) {
        foreach( $caps as $cap ) {
            if( !$role_object->has_cap( $cap ) ) {
                $role_object->add_cap( $cap );
            }
        }
    }
}

#Disregard this nonesense: I apologize, my other answer was per user not per role.

What you can do is check to see if the role has the capability using get_role()

You can see that get_role( 'administrator' ) will return an Object that has an array of capabilities in it.

$administrator = get_role( 'administrator' );

// Make sure role object was retrieved
if( $administrator ){
    //See if it's got our capability or not
    if( !in_array( 'my-custom-cap', $administrator->capabilities ) ){
        // Wasn't there, so add it here
        $administrator->add_cap( 'my-custom-cap' );
    }
}

If for some reason you don't want to run the $role object comparison each time, you can define it once and then set a flag in the database with update_option() and check it with get_option()

if( get_option( 'manually_set_add_cap_admin' ) != true ){
    $administrator = get_role( 'administrator' );

    // Make sure role object was retrieved
    if( $administrator ){
        //See if it's got our capability or not
        if( !in_array( 'my-custom-cap', $administrator->capabilities ) ){
            // Wasn't there, so add it here
            $administrator->add_cap( 'my-custom-cap' );
            update_option( 'manually_set_add_cap_admin', true );
        }
    }
}

Here's a bit more lengthy solution that will loop through any roles you add, and give them all the appropriate capabilities. After the loops are completed, it will set a flag that's checked, so there won't be any WP_Role object fetching after it's ran the first time.

// Define flag as a variable to prevent typos, in update/get_option
// or it will constantly run (I know from experience...)
$flag = 'manually_added_my_custom_caps';

if( !get_option( $flag ) ){
    // Our flag option wasn't set, that means this code hasn't run yet.

    $roles        = array( 'administrator', 'editor' );
    $capabilities = array( 'custom-cap-1', 'custom-cap-2' );

    // Loop through each role
    foreach( $roles as $role ){
        // Make sure we got a WP_Role object back
        if( $role_object = get_role( $role ) ){
            // Loop through our custom capabilities
            foreach( $capabilities as $cap ){
                // Our option flag wasn't set, but let's confirm
                // that the role doesn't have the cap
                if( !in_array( $cap, $role_object->capabilities ) ){
                    // Confirmed not there, add it here
                    $role_object->add_cap( $cap );
                }
            }
        }
    }

    // Our function ran, it should have set all caps to all the roles
    // so now our code will skip this entirely next time
    update_option( $flag, true );
}

本文标签: capabilitiesHow to check if a role has a specific capability