2

I just found out how to create a new role on Wordpress. So, I did something like this:

function suporte_role_creation() {
    remove_role('suporte');
    add_role( 'suporte', 'Suporte', array(
        'read' => true,
        'create_users' => true,
        'delete_users' => false,
        'edit_users' => true,
        'list_users' => true,
        'promote_users' => true,
        'remove_users' => false
    ));
}

register_activation_hook( __FILE__, 'suporte_role_creation' );

Now, my intention is to let the user that belong to this new role be able to edit all users, except users with administrator role. How do I do that? Is there a filter for that?

1

Is there a filter for that?

Yup, there is, and the hook name is user_has_cap.

So try this, which worked for me in WordPress 5.6.1 (latest release as of writing):

add_filter( 'user_has_cap', 'wpse_383109', 10, 4 );
function wpse_383109( $allcaps, $caps, $args, $user ) {
    if ( empty( $args[2] ) || 'edit_user' !== $args[0] ||
        ! in_array( 'suporte', $user->roles )
    ) {
        return $allcaps;
    }

    $user2 = get_userdata( $args[2] );
    if ( $user2 && in_array( 'administrator', $user2->roles ) ) {
        $allcaps['edit_users'] = false;
    }

    return $allcaps;
}

And with that, for example on the Users → All Users admin page (wp-admin/users.php), users with the Suporte role can see the list of Administrators on the site, but the Suporte users won't be able to edit an Administrator.

And if you wonder, here's what the above code or function does:

  1. empty( $args[2] ) || 'edit_user' !== $args[0] — this ensures that the requested capability is edit_user and that a specific user ID ($args[2]) is provided. So for example, the condition is true when calling current_user_can( 'edit_user', 123 ).

  2. in_array( 'suporte', $user->roles ) — this checks if the user who is editing the specific user above has the Suporte role.

  3. $user2 && in_array( 'administrator', $user2->roles ) — this checks if the user who is being edited has the Administrator role.

  4. $allcaps['edit_users'] = false; — if all of the three conditions above are met, then this code (temporarily) disables the edit_users capability for the user said in condition #2 above. And if you want, you can also disable other capabilities.. :)

1
  • 1
    Thanks. That's what I was looking for.
    – churros
    Feb 15 at 12:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.