编辑者可以创建除管理员之外的任何新用户

时间:2010-11-24 作者:Vayu

我已经为客户建立了WordPress网站。客户端具有编辑器角色,但我已安装Members plugin 并赋予客户端向WP管理员添加新用户的能力。这很好用。

我的问题是,我希望客户端能够像贡献者、订阅者、编辑和作者一样创建新用户,而不是管理员。客户端创建的新用户不应具有管理员角色。是否有可能以某种方式隐藏此选项?

ThanksVayu谢谢

4 个回复
SO网友:John P Bloch

这其实很简单。您需要过滤到map_meta_caps 阻止编辑器创建/编辑管理员,并从“可编辑角色”数组中删除管理员角色。此类,作为插件或主题函数。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\\u user的处理方式与edit\\u user略有不同;我修改了map\\u meta\\u cap方法来解决这个问题。我已经在3.0.3上进行了测试,这将阻止除管理员以外的任何人实际删除、编辑或创建管理员。

编辑2我更新了代码以反映下面@bugnumber9的答案。请把那个答案投赞成票!

SO网友:bugnumber9

尽管该线程已有7年的历史,但它可以很容易地在谷歌上搜索,并且仍然提供了一个有效的解决方案。我是指由@johnp Bloch提供的代码。

也就是说,在PHP 7下,它会产生一个非关键错误(PHP已弃用),如下所示:

PHP已弃用:在PHP的未来版本中,与类同名的方法将不会是构造函数;JPB\\u User\\u 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 );
  }
这将解决问题。

SO网友:SilbinaryWolf

我在寻找一种解决方案,编辑器可以只编辑菜单,创建/编辑用户,而不需要插件。所以我最终为那些感兴趣的人制作了它。

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

SO网友:rassoh

@John P Blochs的解决方案仍然可以很好地工作,但我想我也会加入“map\\u meta\\u 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 );

结束

相关推荐