Comment permettre à un rôle utilisateur de créer un nouvel utilisateur sous un rôle inférieur à son niveau uniquement?

14

J'ai trois rôles supplémentaires dans mon site.

  1. Médecin
  2. Réceptionniste
  3. Client

ces rôles sont ajoutés par le code suivant:

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

Par défaut, le Administratorrôle crée tous les autres rôles. Mais je veux limiter ce rôle d'attribution par niveau d'utilisateur. Ce que je veux dire est:

  1. Administrateur - devrait pouvoir créer tous les utilisateurs de rôle - possible par défaut.
  2. Médecin - devrait être en mesure de créer Receptionistet de Guestrôle des utilisateurs UNIQUEMENT
  3. Réceptionniste - devrait pouvoir créer des Guestutilisateurs de rôle UNIQUEMENT
  4. Invité - Interdit de créer des utilisateurs.

Comment est-ce possible? Mieux si je peux y parvenir sans utiliser de plugins.

Riffaz Starr
la source

Réponses:

23

Tout d'abord, vous devez ajouter les fonctionnalités suivantes au rôle Doctoret Receptionist:

  • list_users
  • edit_users
  • create_users
  • delete_users

Maintenant , nous pouvons obtenir de travailler avec le contrôle qui les utilisateurs qu'ils peuvent créer / Edite / supprimer. Commençons par une fonction "d'aide" qui retournera quels rôles un utilisateur est autorisé à éditer:

/**
 * 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;
}

Et pour définir les rôles qu'ils peuvent attribuer à un utilisateur:

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

Et enfin, limitez les utilisateurs qu'ils peuvent modifier / supprimer en fonction de leur rôle:

/**
 * 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
la source
Merci beaucoup. Après avoir ajouté des fonctionnalités et votre code, cela fonctionne comme prévu. Mais Doctors, Receptionistet Guestsont également incapables de modifier leur propre profil. Je veux qu'ils modifient leur propre profil. Comment puis je faire ça?
Riffaz Starr
salut TheDeadMedic .. Êtes-vous là? J'ai voté pour votre réponse. pourriez-vous plz regarder mon commentaire ci-dessus ??
Riffaz Starr
Vérifiez ma révision.
TheDeadMedic
@TheDeadMedic Votre code m'a beaucoup aidé. Je n'ai qu'un seul problème. Je l'utilise sur un multisite. Et bien que ce code ait résolu mon problème, il en a créé un autre. Lorsque je suis connecté en tant que super administrateur, je ne peux sélectionner aucun rôle dans les pages réseau du super administrateur. Comment résoudre ce problème?
jockebq
1
C'est une brillante réponse à la question. J'ai trouvé que la documentation de Wordpress manquait totalement dans ce domaine, même pleine d'erreurs grammaticales. Il s'agit d'une solution vraiment efficace au problème.
Benji
0

La réponse ci-dessus a très bien fonctionné. Cependant, les rôles doivent être en minuscules pour

function wpse_188863_get_allowed_roles( $user ) { }

Par exemple:

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';
}
Tout graphique
la source
Le cas des rôles devrait probablement être en minuscules dans la plupart des cas. Dans l'exemple ci-dessus, le slug et le nom sont donnés en utilisant la casse du titre, c'est donc techniquement correct, bien que non recommandé.
Benji