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

11

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

  1. Médico
  2. Recepcionista
  3. Convidado

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 padrão, Administrator role cria todas as outras funções. Mas quero limitar essa função de atribuição por nível de usuário. O que 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 Receptionist e Guest usuários da função SOMENTE
  3. Recepcionista - deve ser capaz de criar Guest usuários da função SOMENTE
  4. Convidado - Não permitido para criar usuários.

Como pode fazer isso? Melhor se eu conseguir isso sem usar plugins.

    
por Riffaz Starr 20.05.2015 / 13:45

2 respostas

20

Primeiramente, você precisa adicionar os seguintes recursos à função Doctor e Receptionist :

  • list_users
  • edit_users
  • create_users
  • delete_users

Agora podemos trabalhar com o controle de quais usuários 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' );

Por fim, limite os usuários que 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 );
    
por TheDeadMedic 20.05.2015 / 17:35
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';
}
    
por Anything Graphic 27.10.2016 / 18:41