Como permitir que uma função de usuário crie um novo usuário em uma função que seja inferior apenas ao seu nível?

14

Eu tenho três funções extras no meu site.

  1. Médico
  2. Recepcionista
  3. Hóspede

essas funções são adicionadas pelo seguinte código:

* adding Doctor role */
$doctor_role = add_role('Doctor', __('Doctor'), array('read'=>'true'));

/* adding Receptionist role */
$receptionist_role = add_role('Receptionist', __('Receptionist'), array('read'=>'true'));

/* adding Guest role */
$guest_role = add_role('Guest', __('Guest'), array('read'=>'true'));

Por Administratorfunção padrão, crie todas as outras funções. Mas quero limitar essa função de atribuição por nível de usuário. O que eu quero dizer é:

  1. Administrador - deve ser capaz de criar todos os usuários da função - possível por padrão.
  2. Médico - deve ser capaz de criar Receptioniste Guestatribuir SOMENTE usuários
  3. Recepcionista - deve poder criar SOMENTEGuest usuários da função
  4. Convidado - Não é permitido criar usuários.

Como pode fazer isso? Melhor se eu conseguir isso sem usar nenhum plug-in.

Riffaz Starr
fonte

Respostas:

23

Em primeiro lugar, você precisa adicionar os seguintes recursos à função Doctore Receptionist:

  • list_users
  • edit_users
  • create_users
  • delete_users

Agora podemos começar a controlar quais usuários eles podem criar / editar / excluir. Vamos começar com uma função "auxiliar" que retornará quais funções um usuário pode editar:

/**
 * Helper function get getting roles that the user is allowed to create/edit/delete.
 *
 * @param   WP_User $user
 * @return  array
 */
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;
}

E para definir quais funções eles podem atribuir a um usuário:

/**
 * 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' );

E, finalmente, limite quais usuários eles podem editar / excluir com base em sua função:

/**
 * Prevent users deleting/editing users with a role outside their allowance.
 */
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 );
TheDeadMedic
fonte
Perfeito, muito obrigado. Depois de adicionar recursos e seu código, ele funciona como esperávamos. Mas Doctors, Receptioniste Guesttambém não é possível editar seu próprio perfil. Quero que eles editem seu próprio perfil. Como eu posso fazer isso?
Riffaz Starr
oi TheDeadMedic .. Você está aí? Eu votei na sua resposta. u poderia plz olhar para o meu comentário acima?
Riffaz Starr #
Veja minha revisão.
TheDeadMedic
@TheDeadMedic Seu código me ajudou muito. Eu só tenho um problema. Eu uso isso em um Multisite. E enquanto esse código resolveu meu problema, ele criou outro. Quando logado como Superadministrador, não consigo selecionar nenhuma função nas Páginas de Rede do Superadministrador. Como eu resolvo isso?
jockebq
1
Esta é uma resposta brilhante para a pergunta. Achei a documentação do Wordpress totalmente inexistente nessa área, mesmo cheia de erros gramaticais. Esta é uma solução realmente eficiente para o problema.
Benji
0

A resposta acima funcionou muito bem. No entanto, as funções precisam ser minúsculas para

function wpse_188863_get_allowed_roles( $user ) { }

Por exemplo:

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';
}
Anything Graphic
fonte
O caso das funções provavelmente deve estar em minúsculas na maioria dos casos. No exemplo acima, o slug e o nome são fornecidos usando maiúsculas e minúsculas, portanto isso é tecnicamente correto, embora não seja recomendado.
Benji