편집자는 관리자를 제외한 새로운 사용자를 만들 수 있습니다


36

클라이언트를위한 WordPress 사이트를 설정했습니다. 클라이언트에는 편집자 역할이 있지만 멤버 플러그인 을 설치 하고 클라이언트에게 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 답변을 반영하도록 코드를 업데이트했습니다. 그 답을 공감하십시오!


누군가이 코드가 다른 사람이 관리자를 삭제하지 못하도록 막을 수 있습니까? 나는 그 행동을 재현 할 수 없습니다. 그것들은 편집 할 수 없지만 "삭제"호버 링크는 여전히 나타나고 WP는 사용자가 삭제를 진행할 수 있도록합니다.
somatic

@ somatic-당신은 자리에 있었다. 지적 해 주셔서 감사합니다. 이제 문제가 해결되었습니다.
John P Bloch

이 작업을 수행해야하지만이 코드를 어디에 넣었는지 확실하지 않습니다! functions.php에서? 그렇지 않다면 functions.php에서 어떻게 작업 할 수 있습니까? 가장 좋은, Dc
v3nt

@daniel은 첫 번째 단락을 읽었습니다.
John P Bloch

1
감사합니다. 3.4.1에서 훌륭했습니다. create_users, delete_users, add_users, remove_users, edit_users, list_users 및 promote_users에 대한 기능을 추가해야합니다
존 Raasch에게

8

~ 7 세 임에도 불구하고이 스레드는 쉽게 구글 검색이 가능하며 여전히 효과적인 솔루션을 제공합니다. @ 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
감사합니다 감사합니다 코드 품질에 대한 헌신에 감사 드리며 캐주얼 Google 직원들도 메모를 받도록 답변을 업데이트했습니다. 당신은 바위!
John P Bloch

3

에디터가 플러그인없이 메뉴 만 편집하고 사용자를 생성 / 편집 할 수있는 솔루션을 찾고있었습니다. 그래서 나는 관심있는 사람들을 위해 그것을 만들었습니다.

// 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.