#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 ); }