Editorul poate crea orice utilizator nou, cu excepția administratorului

24 nov. 2010, 12:34:04
Vizualizări: 21.8K
Voturi: 42

Am configurat un site WordPress pentru un client. Clientul are rolul de Editor, însă am instalat pluginul Members și i-am acordat clientului capacitatea de a adăuga utilizatori noi în administrarea WordPress. Acest lucru funcționează foarte bine.

Întrebarea mea este că aș dori ca clientul să aibă posibilitatea de a crea utilizatori noi cu rolurile de Contributor, Subscriber, Editor și Author, dar NU Administrator. Utilizatorii noi pe care îi creează clientul nu ar trebui să aibă rolul de Administrator. Este posibil să ascund cumva această opțiune?

Mulțumesc Vayu

1
Comentarii

Te rog să menționezi pluginul pe care îl folosești, am avut probleme să înțeleg la care te referi.

hakre hakre
24 nov. 2010 14:22:02
Toate răspunsurile la întrebare 4
8
45

Este de fapt destul de ușor. Trebuie să filtrezi în map_meta_caps și să împiedici editorii să creeze/editeze administratori, precum și să elimini rolul de administrator din array-ul 'editable roles'. Această clasă, ca un plugin sau în fișierul functions.php al temei tale, ar face asta:

class JPB_User_Caps {

  // Adăugăm filtrele noastre
  function __construct(){
    add_filter( 'editable_roles', array($this, 'editable_roles'));
    add_filter( 'map_meta_cap', array($this, 'map_meta_cap'), 10, 4);
  }

  // Elimină 'Administrator' din lista de roluri dacă utilizatorul curent nu este admin
  function editable_roles( $roles ){
    if( isset( $roles['administrator'] ) && !current_user_can('administrator') ){
      unset( $roles['administrator']);
    }
    return $roles;
  }

  // Dacă cineva încearcă să editeze sau să șteargă un admin și acel utilizator nu este admin, nu permite
  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();

EDITARE

Ok, am analizat de ce permitea ștergerea utilizatorilor. Se pare că delete_user este tratat ușor diferit față de edit_user; am modificat metoda map_meta_cap pentru a rezolva acest lucru. Am testat pe versiunea 3.0.3 și acest cod va împiedica pe oricine, în afară de administratori, să șteargă, editeze sau creeze un administrator.

EDITARE 2

Am actualizat codul pentru a reflecta răspunsul lui @bugnumber9 de mai jos. Te rog să îi dai un upvote acelui răspuns!

25 nov. 2010 00:07:34
Comentarii

Poate cineva să verifice dacă acest cod împiedică ștergerea administratorilor de către alții? Nu reușesc să reproduc acest comportament. Împiedică editarea, dar link-ul de "ștergere" apare la hover, iar WP permite utilizatorului să finalizeze ștergerea...

somatic somatic
15 dec. 2010 14:47:17

@somatic - ai avut perfectă dreptate. Mulțumesc pentru observație. Problema este rezolvată acum.

John P Bloch John P Bloch
20 dec. 2010 19:24:34

Am nevoie să fac și eu asta, dar nu sunt sigur unde să pun acest cod! În functions.php? Dacă nu, cum ar putea fi făcut să funcționeze din functions.php? Cu stimă, Dc

v3nt v3nt
27 iul. 2011 15:16:42

@daniel citește primul paragraf.

John P Bloch John P Bloch
27 iul. 2011 17:02:44

dacă cineva dorește să restrângă roluri suplimentare, trebuie doar să adăugați o linie suplimentară pentru fiecare rol sub această linie: unset( $roles['administrator']); ... deci după această linie puteți adăuga de exemplu: unset( $roles['editor']);

User User
4 nov. 2011 05:32:32

Funcționează perfect în 3.4.1, mulțumesc! Asigurați-vă că adăugați capabilități pentru create_users, delete_users, add_users, remove_users, edit_users, list_users și promote_users

Jon Raasch Jon Raasch
14 sept. 2012 02:11:39

Cod excelent. Pentru cei care folosesc acest lucru, asigurați-vă că vedeți mica ajustare de mai jos de la @bugnumber9. (Poate John P Block își va edita codul?)

Eric Eric
11 iul. 2017 09:40:24

Asta nu a funcționat pentru mine.

avia avia
2 aug. 2021 05:33:42
Arată celelalte 3 comentarii
1
11

În ciuda faptului că are aproximativ 7 ani, acest fir de discuție poate fi găsit ușor prin Google și încă oferă o soluție funcțională. Mă refer la codul furnizat de @John P Bloch.

Totuși, sub PHP 7, acesta produce o eroare necritică (PHP Deprecated) după cum urmează:

PHP Deprecated: Methods with the same name as their class will not be constructors in a future version of PHP; JPB_User_Caps has a deprecated constructor in ...

Pentru a remedia această problemă, pur și simplu înlocuiți acest fragment:

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

cu acesta:

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

Aceasta va rezolva problema.

2 iul. 2017 12:51:59
Comentarii

Mulțumesc, mulțumesc, mulțumesc. Apreciez dedicarea pentru calitatea codului și am actualizat răspunsul meu, astfel încât și cei care caută ocazional pe Google să primească memo-ul. Ești fantastic!

John P Bloch John P Bloch
18 iul. 2017 06:04:09
0

Căutam o soluție prin care Editorul să poată edita doar meniuri ȘI să poată crea/edita utilizatori fără a avea nevoie de un plugin. Așa că am realizat acest cod pentru cei care sunt interesați.

// Personalizează rolul de 'Editor' pentru a avea capacitatea de a modifica meniuri, adăuga utilizatori noi
// și altele.
class Custom_Admin {
    // Adaugă filtrele noastre
    public function __construct(){
        // Permite editorului să editeze opțiunile temei (ex. Meniu)
        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()) {
            // Dezactivează accesul la paginile de teme/widget-uri dacă nu e 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(__('Nu aveți permisiuni suficiente pentru a accesa această pagină.'));
    }

    public function modify_menus() 
    {
        remove_submenu_page( 'themes.php', 'themes.php' ); // ascunde submeniul de selectare teme
        remove_submenu_page( 'themes.php', 'widgets.php' ); // ascunde submeniul de widget-uri

        // Meniul Aspect
        global $menu;
        global $submenu;
        if (isset($menu[60][0])) {
            $menu[60][0] = "Meniuri"; // Redenumește Aspect în Meniuri
        }
        unset($submenu['themes.php'][6]); // Personalizează
    }

    // Elimină 'Administrator' din lista de roluri dacă utilizatorul curent nu este 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;
    }

    // Dacă cineva încearcă să editeze sau să șteargă un admin și acel utilizator nu este admin, nu permite
    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';
                    }
                    // Nu permite non-admin să editeze 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;
                    }
                    // Nu permite non-admin să șteargă 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;
    }

    // Dacă utilizatorul curent se numește admin sau administrative și este 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();
14 nov. 2014 01:47:53
0

Soluția lui @John P Bloch încă funcționează bine, dar am vrut să adaug și eu micul meu filtru pentru 'map_meta_cap'. Doar un pic mai scurt și mai curat, cel puțin pentru ochii mei ;)

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 ); // Verificare PHP 7 pentru variabilă în $args...
  if( $other && $other->has_cap('administrator') ) {
    $caps[] = 'do_not_allow';
  }
  return $caps;
}
add_filter('map_meta_cap', 'my_map_meta_cap', 10, 4 );
26 apr. 2019 00:56:59