L'editor può creare qualsiasi nuovo utente tranne l'amministratore


36

Ho creato un sito WordPress per un cliente. Il client ha il ruolo di Editor, tuttavia ho installato il plug-in Members e ho dato al client la possibilità di aggiungere nuovi utenti all'amministratore WP. Funziona bene.

La domanda che ho è che vorrei che il cliente avesse la possibilità di creare un nuovo utente come con i ruoli di Collaboratore, Abbonato, Editor e Autore, ma NON Amministratore. I nuovi utenti creati dal client non dovrebbero avere il ruolo di amministratore. È possibile nascondere questa opzione in qualche modo?

Grazie Vayu


2
Si prega di collegare il plug-in che si sta utilizzando, ho avuto problemi per scoprire a quale si sta facendo riferimento.
Hakre,

Risposte:


39

In realtà è abbastanza facile. È necessario filtrare map_meta_capse impedire agli editor di creare / modificare amministratori e rimuovere il ruolo di amministratore dall'array "ruoli modificabili". Questa classe, come plugin o nel file Functions.php del tuo tema, lo farebbe:

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

MODIFICARE

Ok, quindi ho dato un'occhiata al motivo per cui stava lasciando passare la cancellazione dell'utente. Sembra che delete_user sia gestito in modo leggermente diverso da edit_user; Ho modificato il metodo map_meta_cap per aggirare questo. Ho testato su 3.0.3 e questo impedirà a chiunque tranne gli amministratori di cancellare, modificare o creare un amministratore.

MODIFICA 2

Ho aggiornato il codice per riflettere la risposta di @ bugnumber9 di seguito. Per favore, dai un voto a quella risposta!


Qualcuno può verificare che questo codice impedisce ad altri di eliminare gli amministratori? Non riesco a riprodurre quel comportamento. Impedisce loro di modificarlo, ma il collegamento al passaggio del mouse "elimina" appare ancora e WP consente all'utente di procedere con la cancellazione ...
somatic

@somatic - sei stato perfetto. Grazie per la segnalazione. Il problema è stato risolto ora.
John P Bloch,

Ho bisogno di fare anche questo, ma non sono sicuro di dove ho inserito questo codice! Nelle funzioni.php? In caso contrario, come si potrebbe fare per funzionare da Functions.php? meglio, Dc
v3nt

@daniel leggi il primo paragrafo.
John P Bloch,

1
Ha funzionato alla grande in 3.4.1, grazie! Assicurati di aggiungere funzionalità per create_users, delete_users, add_users, remove_users, edit_users, list_users e promo_users
Jon Raasch,

8

Nonostante abbia ~ 7 anni, questa discussione può essere cercata facilmente su Google e fornisce comunque una soluzione funzionante. Intendo il codice fornito da @John P Bloch.

Detto questo, in PHP 7 produce un errore non critico (PHP deprecato) come segue:

PHP obsoleto: i metodi con lo stesso nome della loro classe non saranno costruttori in una versione futura di PHP; JPB_User_Caps ha un costruttore deprecato in ...

Per risolvere questo problema è sufficiente sostituire questo pezzo:

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

con questo:

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

Questo risolverà il problema.


1
Grazie, grazie, grazie. Apprezzo l'impegno per la qualità del codice e ho aggiornato la mia risposta in modo che anche i googler occasionali ottengano il memo. Sei forte!
John P Bloch,

3

Stavo cercando una soluzione in cui l'Editor potesse modificare solo i menu E creare / modificare utenti senza bisogno di un plug-in. Quindi ho finito per farlo per coloro che sono interessati.

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

La soluzione @John P Blochs funziona ancora bene, ma ho pensato di aggiungere anche il mio piccolo filtro per 'map_meta_cap'. Solo un po 'più corto e più pulito, almeno per i miei occhi;)

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 );
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.