Bagaimana cara memungkinkan peran pengguna untuk membuat pengguna baru di bawah peran yang lebih rendah dari levelnya saja?

14

Saya memiliki tiga peran tambahan di situs saya.

  1. Dokter
  2. Resepsionis
  3. Tamu

peran-peran itu ditambahkan dengan kode berikut:

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

Secara default Administratorperan membuat semua peran lainnya. Tapi saya ingin membatasi peran penugasan ini berdasarkan level pengguna. Yang saya maksud:

  1. Administrator - harus dapat membuat semua pengguna peran - dimungkinkan secara default.
  2. Dokter - harus dapat membuat Receptionistdan Guestperan pengguna SAJA
  3. Resepsionis - harus mampu menciptakan Guestperan pengguna SAJA
  4. Tamu - Tidak diizinkan membuat pengguna apa pun.

Bagaimana ini bisa dilakukan? Lebih baik jika saya dapat mencapai ini tanpa menggunakan plugin apa pun.

Riffaz Starr
sumber

Jawaban:

23

Pertama, Anda perlu menambahkan kapabilitas Doctordan Receptionistperan berikut:

  • list_users
  • edit_users
  • create_users
  • delete_users

Sekarang kita bisa mulai bekerja dengan mengendalikan pengguna mana yang dapat mereka buat / edit / hapus. Mari kita mulai dengan fungsi "pembantu" yang akan mengembalikan peran mana yang boleh diedit pengguna:

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

Dan untuk mengatur peran mana yang dapat mereka berikan kepada pengguna:

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

Dan akhirnya, batasi pengguna mana yang dapat mereka edit / hapus berdasarkan peran mereka:

/**
 * 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
sumber
Sempurna terima kasih banyak .. Setelah saya menambahkan kemampuan dan kode Anda berfungsi seperti yang kami harapkan. Tetapi Doctors, Receptionistdan Guesttidak dapat mengedit profil mereka sendiri juga. Saya ingin mereka mengedit profil mereka sendiri. Bagaimana saya bisa melakukan itu?
Riffaz Starr
hai TheDeadMedic .. Apakah kamu di sana? Saya telah mengangkat jawaban Anda. bisakah kamu melihat komentar saya di atas ??
Riffaz Starr
Periksa revisi saya.
TheDeadMedic
@TheDeadMedic Kode Anda banyak membantu saya. Saya hanya punya satu masalah. Saya menggunakan ini pada Multisite. Dan sementara kode ini memecahkan masalah saya, itu membuat masalah lain. Ketika masuk sebagai Super Administrator saya tidak dapat memilih peran sama sekali dari Halaman Jaringan Super Admin. Bagaimana saya mengatasi ini?
jockebq
1
Ini adalah jawaban yang cemerlang untuk pertanyaan itu. Saya menemukan dokumentasi Wordpress sendiri sepenuhnya kurang dalam bidang ini, bahkan penuh dengan kesalahan tata bahasa. Ini adalah solusi yang sangat efisien untuk masalah ini.
Benji
0

Jawaban di atas bekerja dengan baik. Namun, perannya harus huruf kecil

function wpse_188863_get_allowed_roles( $user ) { }

Contohnya:

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';
}
Grafis Apa Pun
sumber
Kasus peran seharusnya huruf kecil di sebagian besar kasus. Dalam contoh di atas, siput dan nama diberikan menggunakan judul case, jadi ini benar secara teknis, meskipun tidak direkomendasikan.
Benji