¿Cómo permitir que un rol de usuario cree un nuevo usuario bajo un rol que sea inferior a su nivel solamente?

14

Tengo tres roles adicionales en mi sitio.

  1. Médico
  2. Recepcionista
  3. Invitado

esos roles se agregan mediante el siguiente 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 defecto, el Administratorrol crea todos los otros roles. Pero quiero limitar esta función de asignación por nivel de usuario. Lo que quiero decir es:

  1. Administrador: debe ser capaz de crear todos los usuarios de roles, posible de forma predeterminada
  2. Doctor - debe ser capaz de crear Receptionisty Guestde roles a los usuarios SOLAMENTE
  3. Recepcionista: debe ser capaz de crear Guestusuarios de roles SOLAMENTE
  4. Invitado: no se permite crear ningún usuario.

¿Cómo puede hacer esto? Mejor si puedo lograr esto sin usar ningún complemento.

Riffaz Starr
fuente

Respuestas:

23

En primer lugar, debe agregar las siguientes capacidades al rol Doctory Receptionist:

  • list_users
  • edit_users
  • create_users
  • delete_users

Ahora podemos trabajar para controlar qué usuarios pueden crear / editar / eliminar. Comencemos con una función "auxiliar" que devolverá los roles que un usuario puede 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;
}

Y para establecer qué roles pueden asignar a un usuario:

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

Y, por último, limite qué usuarios pueden editar / eliminar según su función:

/**
 * 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
fuente
Perfecto, muchas gracias. Después de agregar capacidades y su código, funciona como esperábamos. Pero Doctors, Receptionisty Guestno pueden editar su propio perfil también. Quiero que editen su propio perfil. ¿Cómo puedo hacer eso?
Riffaz Starr
hola TheDeadMedic .. ¿Estás ahí? He votado tu respuesta. ¿podrías mirar mi comentario anterior?
Riffaz Starr
Mira mi revisión.
TheDeadMedic
@TheDeadMedic Tu código me ayudó mucho. Solo tengo un problema. Lo uso en un sitio múltiple. Y aunque este código resolvió mi problema, creó otro. Cuando inicie sesión como Súper Administrador, no puedo seleccionar ningún rol de las Páginas de Red del Súper Administrador. ¿Cómo puedo solucionar esto?
jockebq
1
Esta es una respuesta brillante a la pregunta. Encontré que la propia documentación de Wordpress carecía por completo en esta área, incluso llena de errores gramaticales. Esta es una solución realmente eficiente al problema.
Benji
0

La respuesta anterior funcionó muy bien. Sin embargo, los roles deben estar en minúsculas para

function wpse_188863_get_allowed_roles( $user ) { }

Por ejemplo:

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';
}
Cualquier cosa gráfica
fuente
El caso de los roles probablemente debería estar en minúsculas en la mayoría de los casos. En el ejemplo anterior, tanto el slug como el nombre se dan usando el caso del título, por lo que esto es técnicamente correcto, aunque no se recomienda.
Benji