Ограничения возможностей кастомной роли WordPress в зависимости от уровня

Создал кастомную роль, выдал уровень роли меньший уровня администратора, 'promote_users', edit_users и delete_users, но в итоге я могу удалять учетную запись администратора и назначать нового. Как ограничить возможности, чтобы можно было назначать и удалять учетные записи с уровнем не больше текущего?


Ответы (1 шт):

Автор решения: Дмитрий

Такая тема уже поднималась на англоязычном форуме, обсуждение прикрепил https://wordpress.stackexchange.com/questions/188863/how-to-allow-an-user-role-to-create-a-new-user-under-a-role-which-lower-than-his

Код решения

Now we can get to work with controlling which users they can create/edite/delete. Let's start with a "helper" function that will return which roles a user is allowed to edit:

function wpse_188863_get_allowed_roles( $user ) {
    $allowed = array();

    if ( in_array( 'administrator', $user->roles ) ) { // Admin can edit all roles
        $allowed = array_keys( $GLOBALS['wp_roles']->roles );
    } elseif ( in_array( 'Doctor', $user->roles ) ) {
        $allowed[] = 'Receptionist';
        $allowed[] = 'Guest';
    } elseif ( in_array( 'Receptionist', $user->roles ) ) {
        $allowed[] = 'Guest';
    }

    return $allowed;
}

And to set which roles they can assign a user:

/**
 * Remove roles that are not allowed for the current user role.
 */
function wpse_188863_editable_roles( $roles ) {
    if ( $user = wp_get_current_user() ) {
        $allowed = wpse_188863_get_allowed_roles( $user );

        foreach ( $roles as $role => $caps ) {
            if ( ! in_array( $role, $allowed ) )
                unset( $roles[ $role ] );
        }
    }

    return $roles;
}

add_filter( 'editable_roles', 'wpse_188863_editable_roles' );

And finally, limit which users they can edit/delete based on their role:

function wpse_188863_map_meta_cap( $caps, $cap, $user_ID, $args ) {
    if ( ( $cap === 'edit_user' || $cap === 'delete_user' ) && $args ) {
        $the_user = get_userdata( $user_ID ); // The user performing the task
        $user     = get_userdata( $args[0] ); // The user being edited/deleted

        if ( $the_user && $user && $the_user->ID != $user->ID /* User can always edit self */ ) {
            $allowed = wpse_188863_get_allowed_roles( $the_user );

            if ( array_diff( $user->roles, $allowed ) ) {
                // Target user has roles outside of our limits
                $caps[] = 'not_allowed';
            }
        }
    }

    return $caps;
}

add_filter( 'map_meta_cap', 'wpse_188863_map_meta_cap', 10, 4 );
→ Ссылка