Jak zezwolić roli użytkownika na utworzenie nowego użytkownika na podstawie roli niższej niż jego poziom?

14

Mam trzy dodatkowe role w mojej witrynie.

  1. Lekarz
  2. Recepcjonista
  3. Gość

role te są dodawane przez następujący kod:

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

Domyślnie Administratorrola tworzy wszystkie inne role. Ale chcę ograniczyć tę rolę przypisującą według poziomu użytkownika. Chodzi mi o to że:

  1. Administrator - powinien być w stanie utworzyć wszystkich użytkowników roli - domyślnie możliwe.
  2. Lekarz - powinien być w stanie tworzyć Receptionisti przypisywać WYŁĄCZNIEGuest użytkownikom
  3. Recepcjonista - powinien móc tworzyć TYLKOGuest użytkowników
  4. Gość - nie można tworzyć żadnych użytkowników.

Jak to zrobić? Lepiej, jeśli uda mi się to osiągnąć bez użycia wtyczek.

Riffaz Starr
źródło

Odpowiedzi:

23

Po pierwsze, musisz dodać następujące funkcje do Doctori Receptionistroli:

  • list_users
  • edit_users
  • create_users
  • delete_users

Teraz możemy zabrać się do kontrolowania, którzy użytkownicy mogą tworzyć / edytować / usuwać. Zacznijmy od funkcji „pomocnika”, która zwróci role, które użytkownik może edytować:

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

Aby ustawić role, które mogą przypisać użytkownikowi:

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

Na koniec ogranicz użytkowników, których mogą edytować / usuwać w zależności od ich roli:

/**
 * 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
źródło
Idealnie dziękuję bardzo. Po dodaniu możliwości i kodu działa on zgodnie z oczekiwaniami. Ale Doctors, Receptionisti Guestnie są w stanie zmieniać swój profil też. Chcę, żeby edytowali własny profil. Jak mogę to zrobić?
Riffaz Starr
cześć TheDeadMedic .. Jesteś tam? Poparłem twoją odpowiedź. czy mógłbyś zajrzeć do mojego powyższego komentarza?
Riffaz Starr
Sprawdź moją wersję.
TheDeadMedic
@TheDeadMedic Twój kod bardzo mi pomógł. Mam tylko jeden problem. Używam tego na wielu stronach. I chociaż ten kod rozwiązał mój problem, stworzył inny. Po zalogowaniu się jako superadministrator nie mogę w ogóle wybierać ról ze stron sieciowych superadministratora. Jak to rozwiązać?
jockebq
1
To znakomita odpowiedź na pytanie. Odkryłem, że własnej dokumentacji Wordpress całkowicie brakuje w tej dziedzinie, nawet pełnej błędów gramatycznych. To jest naprawdę skuteczne rozwiązanie problemu.
Benji
0

Powyższa odpowiedź działała świetnie. Jednak role muszą być pisane małymi literami

function wpse_188863_get_allowed_roles( $user ) { }

Na przykład:

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';
}
Coś graficznego
źródło
W większości przypadków przypadek ról powinien być pisany małymi literami. W powyższym przykładzie zarówno ślimak, jak i nazwa zostały podane przy użyciu tytułu, więc jest to technicznie poprawne, chociaż nie jest zalecane.
Benji