Editor สามารถสร้างผู้ใช้ใหม่ยกเว้นผู้ดูแลระบบ


36

ฉันตั้งค่าเว็บไซต์ WordPress สำหรับลูกค้าแล้ว ลูกค้ามีบทบาท Editor แต่ฉันได้ติดตั้งปลั๊กอินสมาชิกและให้ความสามารถแก่ลูกค้าในการเพิ่มผู้ใช้ใหม่ในผู้ดูแลระบบ WP มันใช้งานได้ดี

คำถามที่ฉันมีคือฉันต้องการให้ลูกค้ามีความสามารถในการสร้างผู้ใช้ใหม่เช่นเดียวกับบทบาทของผู้สนับสนุนสมาชิกผู้แก้ไขและผู้แต่ง แต่ไม่ใช่ผู้ดูแลระบบ ผู้ใช้ใหม่ที่ลูกค้าสร้างไม่ควรมีบทบาทผู้ดูแลระบบ เป็นไปได้หรือไม่ที่จะซ่อนตัวเลือกนี้

ขอบคุณ Vayu


2
โปรดลิงก์ปลั๊กอินที่คุณใช้ฉันมีปัญหาในการค้นหาว่าคุณกำลังอ้างอิงถึงอันไหน
hakre

คำตอบ:


39

จริงๆแล้วมันง่ายมาก คุณต้องกรองmap_meta_capsและหยุดไม่ให้ผู้แก้ไขสร้าง / แก้ไขผู้ดูแลระบบและลบบทบาทผู้ดูแลระบบออกจากอาร์เรย์ 'บทบาทที่แก้ไขได้' คลาสนี้เป็นปลั๊กอินหรือในไฟล์ functions.php ของชุดรูปแบบของคุณ:

class JPB_User_Caps {

  // Add our filters
  function __construct(){
    add_filter( 'editable_roles', array($this, 'editable_roles'));
    add_filter( 'map_meta_cap', array($this, 'map_meta_cap'), 10, 4);
  }

  // Remove 'Administrator' from the list of roles if the current user is not an admin
  function editable_roles( $roles ){
    if( isset( $roles['administrator'] ) && !current_user_can('administrator') ){
      unset( $roles['administrator']);
    }
    return $roles;
  }

  // If someone is trying to edit or delete and admin and that user isn't an admin, don't allow it
  function map_meta_cap( $caps, $cap, $user_id, $args ){

    switch( $cap ){
        case 'edit_user':
        case 'remove_user':
        case 'promote_user':
            if( isset($args[0]) && $args[0] == $user_id )
                break;
            elseif( !isset($args[0]) )
                $caps[] = 'do_not_allow';
            $other = new WP_User( absint($args[0]) );
            if( $other->has_cap( 'administrator' ) ){
                if(!current_user_can('administrator')){
                    $caps[] = 'do_not_allow';
                }
            }
            break;
        case 'delete_user':
        case 'delete_users':
            if( !isset($args[0]) )
                break;
            $other = new WP_User( absint($args[0]) );
            if( $other->has_cap( 'administrator' ) ){
                if(!current_user_can('administrator')){
                    $caps[] = 'do_not_allow';
                }
            }
            break;
        default:
            break;
    }
    return $caps;
  }

}

$jpb_user_caps = new JPB_User_Caps();

แก้ไข

ตกลงดังนั้นฉันจึงดูว่าทำไมมันถึงทำให้ผู้ใช้ลบข้อมูลไม่ได้ ดูเหมือนว่า delete_user จะถูกจัดการแตกต่างจาก edit_user เล็กน้อย ฉันได้ปรับเปลี่ยนวิธี map_meta_cap เพื่อแก้ไขปัญหานี้ ฉันได้ทดสอบกับ 3.0.3 แล้วและนี่จะเป็นการป้องกันไม่ให้ใครนอกจากผู้ดูแลระบบลบจริงๆแก้ไขหรือสร้างผู้ดูแลระบบ

แก้ไข 2

ฉันอัปเดตรหัสเพื่อให้สะท้อนถึงคำตอบของ @ bugnumber9 ด้านล่าง โปรดตอบคำถามนั้นด้วยการ upvote!


บางคนสามารถยืนยันว่ารหัสนี้ป้องกันไม่ให้ผู้อื่นลบผู้ดูแลระบบหรือไม่ ฉันทำซ้ำพฤติกรรมนั้นไม่ได้ มันจะป้องกันไม่ให้พวกเขาแก้ไข แต่ลิงก์โฮเวอร์ "ลบ" ยังคงปรากฏและ WP ช่วยให้ผู้ใช้ผ่านการลบ ...
somatic

@somatic - คุณได้เห็น ขอบคุณสำหรับการชี้ให้เห็นว่า ปัญหาได้รับการแก้ไขแล้ว
John P Bloch

ฉันต้องทำยัง แต่ไม่แน่ใจที่ฉันใส่รหัสนี้! ในส่วนของฟังก์ชั่น php? ถ้าไม่ใช่วิธีการที่จะใช้งานได้จากฟังก์ชั่น ดีที่สุด, Dc
v3nt

@daniel อ่านย่อหน้าแรก
John P Bloch

1
ทำงานได้ดีใน 3.4.1 ขอบคุณ! ตรวจสอบให้แน่ใจว่าได้เพิ่มความสามารถสำหรับ create_users, delete_users, add_users, remove_users, edit_users, list_users และ Promot_users
Jon Raasch

8

แม้จะมีอายุตั้งแต่ 7 ปีขึ้นไป แต่หัวข้อนี้สามารถ googled ได้อย่างง่ายดายและยังคงมีวิธีแก้ปัญหาการทำงาน ฉันหมายถึงรหัสที่ให้โดย @John P Bloch

ที่กล่าวว่าภายใต้ PHP 7 จะสร้างข้อผิดพลาดที่ไม่สำคัญ (PHP Deprecated) ดังต่อไปนี้:

PHP เลิกใช้: วิธีการที่มีชื่อเดียวกันกับคลาสจะไม่เป็นตัวสร้างใน PHP เวอร์ชันอนาคต JPB_User_Caps มีตัวสร้างที่คัดค้านใน ...

เพื่อแก้ไขปัญหานี้เพียงแทนที่ชิ้นส่วนนี้:

// Add our filters
  function JPB_User_Caps(){
    add_filter( 'editable_roles', array(&$this, 'editable_roles'));
    add_filter( 'map_meta_cap', array(&$this, 'map_meta_cap'),10,4);
  }

ด้วยสิ่งนี้:

// Add our filters
  function __construct() {
    add_filter( 'editable_roles', array(&$this, 'editable_roles') );
    add_filter( 'map_meta_cap', array(&$this, 'map_meta_cap'), 10, 4 );
  }

สิ่งนี้จะแก้ไขปัญหา


1
ขอบคุณขอบคุณขอบคุณ. ฉันซาบซึ้งในความทุ่มเทต่อคุณภาพของรหัสและได้อัปเดตคำตอบของฉันเพื่อที่ผู้ใช้งานทั่วไปจะได้รับบันทึกช่วยจำ คุณร็อค!
John P Bloch

3

ฉันกำลังมองหาโซลูชันที่ Editor สามารถแก้ไขได้เฉพาะเมนูและสร้าง / แก้ไขผู้ใช้โดยไม่ต้องใช้ปลั๊กอิน ดังนั้นฉันจึงตัดสินใจทำเพื่อผู้ที่สนใจ

// Customizes 'Editor' role to have the ability to modify menus, add new users
// and more.
class Custom_Admin {
    // Add our filters
    public function __construct(){
        // Allow editor to edit theme options (ie Menu)
        add_action('init', array($this, 'init'));
        add_filter('editable_roles', array($this, 'editable_roles'));
        add_filter('map_meta_cap', array($this, 'map_meta_cap'), 10, 4);
    }

    public function init() {
        if ($this->is_client_admin()) {
            // Disable access to the theme/widget pages if not admin
            add_action('admin_head', array($this, 'modify_menus'));
            add_action('load-themes.php', array($this, 'wp_die'));
            add_action('load-widgets.php', array($this, 'wp_die'));
            add_action('load-customize.php', array($this, 'wp_die'));

            add_filter('user_has_cap', array($this, 'user_has_cap'));
        }
    }

    public function wp_die() {
        _default_wp_die_handler(__('You do not have sufficient permissions to access this page.'));
    }

    public function modify_menus() 
    {
        remove_submenu_page( 'themes.php', 'themes.php' ); // hide the theme selection submenu
        remove_submenu_page( 'themes.php', 'widgets.php' ); // hide the widgets submenu

        // Appearance Menu
        global $menu;
        global $submenu;
        if (isset($menu[60][0])) {
            $menu[60][0] = "Menus"; // Rename Appearance to Menus
        }
        unset($submenu['themes.php'][6]); // Customize
    }

    // Remove 'Administrator' from the list of roles if the current user is not an admin
    public function editable_roles( $roles ){
        if( isset( $roles['administrator'] ) && !current_user_can('administrator') ){
            unset( $roles['administrator']);
        }
        return $roles;
    }

    public function user_has_cap( $caps ){
        $caps['list_users'] = true;
        $caps['create_users'] = true;

        $caps['edit_users'] = true;
        $caps['promote_users'] = true;

        $caps['delete_users'] = true;
        $caps['remove_users'] = true;

        $caps['edit_theme_options'] = true;
        return $caps;
    }

    // If someone is trying to edit or delete and admin and that user isn't an admin, don't allow it
    public function map_meta_cap( $caps, $cap, $user_id, $args ){
        // $args[0] == other_user_id
        foreach($caps as $key => $capability)
        {
            switch ($cap)
            {
                case 'edit_user':
                case 'remove_user':
                case 'promote_user':
                    if(isset($args[0]) && $args[0] == $user_id) {
                        break;
                    }
                    else if(!isset($args[0])) {
                        $caps[] = 'do_not_allow';
                    }
                    // Do not allow non-admin to edit admin
                    $other = new WP_User( absint($args[0]) );
                    if( $other->has_cap( 'administrator' ) ){
                        if(!current_user_can('administrator')){
                            $caps[] = 'do_not_allow';
                        }
                    }
                    break;
                case 'delete_user':
                case 'delete_users':
                    if( !isset($args[0])) {
                        break;
                    }
                    // Do not allow non-admin to delete admin
                    $other = new WP_User(absint($args[0]));
                    if( $other->has_cap( 'administrator' ) ){
                        if(!current_user_can('administrator')){
                            $caps[] = 'do_not_allow';
                        }
                    }
                    break;
                break;
            }
        }
        return $caps;
    }

    // If current user is called admin or administrative and is an editor
    protected function is_client_admin() {
        $current_user = wp_get_current_user();
        $is_editor = isset($current_user->caps['editor']) ? $current_user->caps['editor'] : false;
        return ($is_editor);
    }
}
new Custom_Admin();

1

@John P Blochs ยังคงใช้งานได้ดี แต่ฉันคิดว่าฉันจะใช้ฟิลเตอร์เล็ก ๆ สำหรับ 'map_meta_cap' ได้เช่นกัน เพียงเล็กน้อยสั้นและสะอาดตาอย่างน้อยสำหรับฉัน;)

function my_map_meta_cap( $caps, $cap, $user_id, $args ) {
  $check_caps = [
    'edit_user',
    'remove_user',
    'promote_user',
    'delete_user',
    'delete_users'
  ];
  if( !in_array( $cap, $check_caps ) || current_user_can('administrator') ) {
    return $caps;
  }
  $other = get_user_by( 'id', $args[0] ?? false ); // PHP 7 check for variable in $args... 
  if( $other && $other->has_cap('administrator') ) {
    $caps[] = 'do_not_allow';
  }
  return $caps;
}
add_filter('map_meta_cap', 'my_map_meta_cap', 10, 4 );
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.