Remove Ability for Administrators to Delete Administrators

The question:

I’ve been studying roles and capabilities and have worked with and worked up a bunch of awesome code for creating unique capabilities and roles. I have created a “Master Editor” role to maintain users with almost every capability…
However, edit_users & delete_users obviously allows for an editor to CUD users, including the existing administrators…

At the moment I’m to new at coding to be confident editing users.php but I have to be close to the solution:

if ( ! current_user_can( 'delete_users' ) ) 
// or is trying to delete an admin's $userids 
wp_die(__('You can’t delete users.')); // or administrators

$update = 'del';
$delete_count = 0;

foreach ( $userids as $id ) {
    if ( ! current_user_can( 'delete_user', $id ) )
        wp_die(__( 'You can’t delete that user.' ) );

    if ( $id == $current_user->ID ) {
        $update = 'err_admin_del';
        continue;
    }
    switch ( $_REQUEST['delete_option'] ) {
    case 'delete':
        wp_delete_user( $id );
        break;
    case 'reassign':
        wp_delete_user( $id, $_REQUEST['reassign_user'] );
        break;
    }
    ++$delete_count;
}

I can’t figure out how to check that the $userids in question are an administrators user ID. Because if I can I could add that to the die… Am I on the right track?
Thanks in advance.

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

Your question seems to boil down to this

I can’t figure out how to check that the $userids in question are an
administrators user ID.

Try

user_can($id,'administrator')

http://codex.wordpress.org/Function_Reference/user_can

The Codex has a warning about using role names with the current_user_can function and it is very similar to user_can so I suppose caution is order until the conflicting instructions are sorted.

Do not pass a role name to current_user_can(), as this is not
guaranteed to work correctly.

The same page also says:

$capability
(string) (required) capability or role name
Default: None

As does the source:

  • @param string $capability Capability or role name.

Are you hacking core file? The users.php isn’t this users.php is it? That is a high maintenance path your are going down if it is.

Method 2

Very nice write-up by @s_ha_dum. I’ll just extend his answer regarding the contradiction in the documentation.

Recently I was dealing with current_user_can, investigated a bit and came up with this function:

/**
 * Function name grabbed from: http://core.trac.wordpress.org/ticket/22624
 * 2 lines of code from TutPlus: http://goo.gl/X4lmf
 */
if( !function_exists( 'current_user_has_role' ) )
{
    function current_user_has_role( $role )
    {
        $current_user = new WP_User( wp_get_current_user()->ID );
        $user_roles = $current_user->roles;
        $is_or_not = in_array( $role, $user_roles );
        return $is_or_not;
    }
}


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment