Як дозволити ролі користувача створити нового користувача в ролі, нижчій лише за його рівень?


14

У мене на сайті три додаткові ролі.

  1. Лікар
  2. Ресепшн
  3. Гість

ці ролі додаються наступним кодом:

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

За замовчуванням Administratorролі створюйте всі інші ролі. Але я хочу обмежити цю призначену роль за рівнем користувача. Що я маю на увазі:

  1. Адміністратор - повинен мати змогу створювати всіх рольових користувачів - можливо за замовчуванням.
  2. Лікар - повинен бути в змозі створити Receptionistі Guestролі користувачів ТІЛЬКИ
  3. Ресепшн - повинен мати можливість створювати Guestкористувач ролей ТІЛЬКИ
  4. Гість - заборонено створювати користувачів.

Як це можна зробити? Краще, якщо я можу досягти цього, не використовуючи ніяких плагінів.

Відповіді:


23

По-перше, вам потрібно додати наступні можливості до Doctorта Receptionistроль:

  • list_users
  • edit_users
  • create_users
  • delete_users

Тепер ми можемо працювати над контролем, яких користувачів вони можуть створювати / редагувати / видаляти. Почнемо з функції "помічник", яка повертає, які ролі користувачеві дозволено редагувати:

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

І щоб встановити, які ролі вони можуть призначити користувачеві:

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

І нарешті, обмежте, яких користувачів вони можуть редагувати / видаляти, виходячи з їх ролі:

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

Ідеально дякую .. Після того, як я додав можливості та ваш код, він працює як ми очікували. Але Doctors, Receptionistі GuestНЕ в змозі змінити свій власний профіль теж. Я хочу, щоб вони редагували власний профіль. Як я можу це зробити?
Ріффаз Старр

привіт TheDeadMedic .. Ти там? Я підтримав відповідь ури. Ви можете PLZ заглянути в мій вище коментар ??
Ріффаз Старр

Перевірте мою редакцію.
TheDeadMedic

@TheDeadMedic Ваш код мені дуже допоміг. У мене тільки одна біда. Я використовую це на Multisite. І хоча цей код вирішив мою проблему, він створив ще один. Коли ви ввійшли як адміністратор Super, я взагалі не можу вибирати жодних ролей із мережевих сторінок Super Admin. Як я це вирішую?
jockebq

1
Це геніальна відповідь на запитання. Я знайшов власну документацію Wordpress, якої повністю не вистачає в цій галузі, навіть повну граматичних помилок. Це дійсно ефективне рішення проблеми.
Бенджі

0

Наведена відповідь спрацювала чудово. Однак ролі повинні бути малі

function wpse_188863_get_allowed_roles( $user ) { }

Наприклад:

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';
}

Випадки ролей, швидше за все, мають бути малими літерами в більшості випадків. У наведеному вище прикладі і slug, і ім'я вказані з використанням регістру заголовків, тому це технічно правильно, хоча і не рекомендується.
Бенджі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.