Der Editor kann jeden neuen Benutzer mit Ausnahme des Administrators erstellen

36

Ich habe eine WordPress-Site für einen Kunden eingerichtet. Der Client hat die Rolle des Editors, ich habe jedoch das Members-Plugin installiert und dem Client die Möglichkeit gegeben, dem WP-Administrator neue Benutzer hinzuzufügen. Das funktioniert gut.

Die Frage, die ich habe, ist, dass ich möchte, dass der Kunde die Möglichkeit hat, einen neuen Benutzer wie in den Rollen eines Mitwirkenden, Abonnenten, Herausgebers und Autors, aber NICHT eines Administrators, zu erstellen. Die neuen Benutzer, die der Client erstellt, sollten nicht die Administratorrolle haben. Ist es möglich, diese Option irgendwie zu verbergen?

Vielen Dank, Vayu

Vayu
quelle
2
Bitte verlinken Sie das von Ihnen verwendete Plugin. Ich hatte Probleme herauszufinden, auf welches Sie sich beziehen.
Hakre

Antworten:

39

Das ist eigentlich ganz einfach. Sie müssen das map_meta_capsErstellen / Bearbeiten von Administratoren durch Editoren filtern und verhindern und die Administratorrolle aus dem Array "Bearbeitbare Rollen" entfernen. Diese Klasse würde es als Plugin oder in der Datei functions.php Ihres Themas tun:

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

BEARBEITEN

Ok, also habe ich mir angesehen, warum die Löschung durch den Benutzer passiert. Es sieht so aus, als würde delete_user etwas anders behandelt als edit_user. Ich habe die map_meta_cap-Methode geändert, um dies zu umgehen. Ich habe 3.0.3 getestet und dies hindert nur Administratoren daran, einen Administrator zu löschen, zu bearbeiten oder zu erstellen.

BEARBEITEN 2

Ich habe den Code aktualisiert, um die Antwort von @ bugnumber9 unten wiederzugeben. Bitte gib dieser Antwort eine positive Bewertung!

John P Bloch
quelle
Kann jemand überprüfen, ob dieser Code verhindert, dass andere Administratoren gelöscht werden? Ich kann dieses Verhalten nicht reproduzieren. Es verhindert, dass sie bearbeitet werden, aber der Hover-Link "Löschen" wird weiterhin angezeigt, und WP ermöglicht dem Benutzer, den Löschvorgang durchzuführen ...
somatic
@somatic - Sie waren genau richtig. Vielen Dank für den Hinweis. Das Problem ist jetzt behoben.
John P Bloch
Ich muss dies auch tun, aber nicht sicher, wo ich diesen Code setzen! In der functions.php? Wenn nicht, wie könnte es gemacht werden, um von der functions.php aus zu arbeiten? best, Dc
v3nt
@ Daniel las den ersten Absatz.
John P Bloch
1
Hat in 3.4.1 super funktioniert, danke! Stellen Sie sicher , hinzuzufügen Fähigkeiten für create_users, delete_users, add_users, remove_users, edit_users, list_users und promote_users
Jon Raasch
8

Obwohl dieser Thread ~ 7 Jahre alt ist, kann er leicht gegoogelt werden und bietet dennoch eine funktionierende Lösung. Ich meine den Code von @John P Bloch.

Das heißt, unter PHP 7 erzeugt es einen nicht kritischen Fehler (PHP veraltet) wie folgt:

PHP veraltet: Methoden mit demselben Namen wie ihre Klasse werden in einer zukünftigen Version von PHP keine Konstruktoren mehr sein. JPB_User_Caps hat einen veralteten Konstruktor in ...

Um dies zu beheben, ersetzen Sie einfach dieses Stück:

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

mit diesem:

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

Dies wird das Problem beheben.

Fehlernummer9
quelle
1
Danke danke danke. Ich schätze die Hingabe zur Codequalität und habe meine Antwort aktualisiert, damit auch Gelegenheits-Googler das Memo erhalten. Du rockst!
John P Bloch
3

Ich suchte nach einer Lösung, bei der der Editor nur Menüs bearbeiten UND Benutzer erstellen / bearbeiten konnte, ohne ein Plugin zu benötigen. Also habe ich es für diejenigen gemacht, die interessiert sind.

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

@ John P Blochs Lösung funktioniert immer noch einwandfrei, aber ich dachte, ich würde meinen kleinen Filter auch für 'map_meta_cap' einsetzen. Nur ein bisschen kürzer und sauberer, zumindest für meine Augen;)

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 );
rassoh
quelle