web-dev-qa-db-fra.com

Rôle pouvant uniquement modifier les widgets, pas d'autres options de thème

Comment puis-je créer un menu d’administration des widgets d’accès aux rôles particulier (wp-admin/widgets.php), mais not accéder à d’autres éléments du menu administration du thème .

J’ai eu jusqu’à afficher Apparence un lien vers widgets.php en liant à _admin_menu événement et en modifiant la variable globale $ submenu . Bien que cela ne fonctionne manifestement pas, je vois ce code dans wp-admin/widgets.php lui-même:

    if ( ! current_user_can('edit_theme_options') )
            wp_die( __( 'Cheatin’ uh?' ));

Il est clair - vous NE SEREZ PAS autorisé à accéder à cette page, sauf si vous avez clairement edit_theme_options . Mais que faire si je ne veux pas d’autres éléments de cette capacité, en dehors des widgets, modifiables par l’utilisateur actuel (rôle)?

Il est facile de "masquer" les autres options du menu. Mais cela laisse l’utilisateur, qui sait comment WP fonctionne (comprend l’adressage, au moins), libre d’y accéder et que j’aimerais clairement éviter.

Merci d'avance pour toute aide.

3
Justas Butkus

Confirmant…

Oui, il y a actuellement (WP 3.4.1) aucun moyen de modifier les arguments d'accès pour les pages de menu d'administration. Le seul élément que vous pouvez modifier via l'API wp publique est l'élément de menu "Commentaires" . Tous les autres sont enregistrés à la main.

Mais il y a une aide venant de @scribu (plus d’informations sur le ticket trac) qui jusqu’à présent a déployé beaucoup d’efforts pour apporter quelque chose de plus utile au noyau.

Explication

Lorsque vous cherchez plus profondément dans le noyau, vous verrez alors la fonction wp_widgets_add_menu() dans ~/wp-includes/functions.php. Celui-ci ajoute l’élément de sous-menu puisque WP 2.2…

function wp_widgets_add_menu() {
    global $submenu;
    $submenu['themes.php'][7] = array( __( 'Widgets' ), 'edit_theme_options', 'widgets.php' );
    ksort( $submenu['themes.php'], SORT_NUMERIC );
}

Cette fonction est ajoutée à l'action _admin_menu par la fonction wp_maybe_load_widgets().

Contournement intermédiaire pour les éléments de menu et les widgets

Actuellement, la fonction qui charge les widgets par défaut et enregistre l'élément de sous-menu (à savoir wp_maybe_load_widgets) est appelée pendant le hook plugins_loaded avec une priorité de 0.

Cela rend difficile de le désenregistrer avec un plugin normal. Par conséquent, vous devez utiliser un plugin dans votre dossier mu-plugins.

<?php
/* Plugin Name: »Kaisers« Deny Widgets page access */
! defined( 'ABSPATH' ) AND exit;

// Init the plugin
add_action( 'muplugins_loaded', array( 'wpse6106_deny_widgets', 'init' ), 0 );

class wpse6106_deny_widgets
{
    static public $instance;

    public $required_cap = 'SET_CUSTOM_CAP_HERE';

    /**
     * Get the instance of the plugin
     * @since  2012-08-07.1505
     * @return void
     */
    static function init()
    {
        null === self :: $instance AND self :: $instance = new self;
        return self :: $instance;
    }

    /**
     * Setup
     * Removes the default function that registers the widgets.php sub menu item.
     * @since  2012-08-07.1505
     * @return void
     */
    function __construct()
    {
        // remove core function...
        remove_action( 'plugins_loaded', 'wp_maybe_load_widgets', 0 );

        // ...and add our own
        add_action( 'admin_head', array( $this, 'widgets_menu_access' ), 0 );

        // Then abort any attempt to access the widgets page
        add_action( 'load-widgets.php', array( $this, 'widgets_page_access' ), 0 );
    }

    /**
     * Adds an action, that re-registers the sub menu item with a custom capability.
     * @since  2012-08-07.1505
     * @return void
     */
    function widgets_menu_access()
    {
        global $submenu;

        // Call default widgets file
        require_once( ABSPATH . WPINC . '/default-widgets.php' );

        $submenu['themes.php'][7] = array( 
             __( 'Widgets' )
            ,$this->required_cap
            ,'widgets.php'
        );
        ksort( $submenu['themes.php'], SORT_NUMERIC );
    }

    /**
     * Does a second check if someone without the custom cap entered the widgets page and dies.
     * @since  2012-08-07.1505
     * @return void
     */
    function widgets_page_access()
    {
        get_currentuserinfo();
        global $current_user;

        if ( ! current_user_can( $this->required_cap ) )
            wp_die( __( 'Cheatin&#8217; uh?' ) );
    }
}

Déposez-le simplement dans votre dossier MU-Plugins, ajustez la chaîne SET_CUSTOM_CAP_HERE à l'intérieur du plug-in (variable de classe en haut ↑) et vous êtes prêt. Assurez-vous que vous utilisez un gestionnaire de rôle (tel que Membres , qui vous permet de ne donner ce rôle qu'à ceux qui sont censés accéder à la page des widgets. Ou ajoutez-le manuellement à l'aide d'un plugin propre/personnalisé.

Veillez également à ce que les utilisateurs ne disposent pas de capacités restantes. Si c'est not fonctionne, désactivez all plugins, revenez à TwentyTen/Eleven et réinitialisez votre base de données locale avec un plugin comme "WordPress Reset" .

Résultat prouvé

enter image description here

Remarque: le plug-in est testé et fonctionne dans une installation plain Vanilla.


Désactiver les widgets par défaut et les éléments de sous-menu

Note: Ceci est seulement pour les lecteurs ultérieurs, qui veulent se débarrasser de tout cela.

Si vous voulez vous débarrasser complètement de tous les widgets par défaut, il existe un filtre simple, que vous pouvez appeler, qui arrête d'inclure le fichier ~/wp-includes/default-widgets.php et désactive l'enregistrement de la page:

add_filter( 'load_default_widgets', '__return_false' );
3
kaiser

VUE D'ENSEMBLE

Bien que la question portait sur la limitation des rôles d'éditeur pour l'accès uniquement aux widgets, l'exemple suivant montre comment limiter l'accès aux menus uniquement. Cependant, comme vous le verrez, il peut facilement être modifié pour autoriser uniquement les widgets ou plus!

J'ai ajouté l'étape 3 parce que j'avais oublié la barre d'administration. Oops! Alors maintenant, que vous soyez connecté au tableau de bord ou connecté et sur le site Web WP, vous avez le contrôle total sur les possibilités d'un éditeur pour les sous-menus 'edit_theme_capablity'.

Si aucun plug-in Roles & Capabilities n'est installé sur votre ordinateur, vous pouvez le faire:

(Si vous le faites, sautez le n ° 1 et passez au n ° 2 puis au n ° 3)

(1) Ajoutez ceci au functions.php de votre thème:

// Add all Editors the privilege to edit Themes, Widgets, Menus, Backgrounds

// get the the role object - editor, author, etc. (or those specially created)
$role_object = get_role( 'editor' );

// add $cap capability to this role object
// 'edit_theme_options' enables Dashboard APPEARANCE sub-menus
// for Themes, Widgets, Menus, and Backgrounds for users with that role
$role_object->add_cap( 'edit_theme_options' );


(2) Ajoutez ceci à admin-footer.php: (situé dans le répertoire wp-admin)
Cela vous permet de choisir l’option que vous voulez que les éditeurs aient sur leur tableau de bord.
LIRE CECI pour plus d’informations de l’auteur de l’extrait de code jQuery.

<?php
  //  Using jQuery: How to allow Editors to edit only Menus (or more!)
  //  Placed in admin-footer.php as Dashboard comes from the wp-admin files

  if ( is_user_logged_in() ) { // This IF may be redundant, but safe is better than sorry...
    if ( current_user_can('edit_theme_options') && !current_user_can('manage_options') ) { // Check if non-Admin
?>
      <script>
    jQuery.noConflict();
    jQuery(document).ready(function() {
      //  Comment out the line you WANT to enable, so it displays (is NOT removed).
      //  For example, the jQuery line for MENUS is commented out below so it's not removed.

      // THEMES:  If you want to allow THEMES, also comment out APPEARANCE if you want it to display Themes when clicked. (Default behaviour)
      jQuery('li#menu-appearance.wp-has-submenu li a[href="themes.php"]').remove();
      jQuery('li#menu-appearance.wp-has-submenu a.wp-has-submenu').removeAttr("href");

      // WIDGETS:
      jQuery('li#menu-appearance.wp-has-submenu li a[href="widgets.php"]').remove();

      // MENUS:
      // jQuery('li#menu-appearance.wp-has-submenu li a[href="nav-menus.php"]').remove();

      // BACKGROUND:
      jQuery('li#menu-appearance.wp-has-submenu li a[href="themes.php?page=custom-background"]').remove();
    });
      </script>
<?php
    } // End IF current_user_can...
  } // End IF is_user_logged_in...
?>


(3) Ajoutez ceci au footer.php du thème:
Cela vous permet de choisir l’option que vous voulez que les éditeurs aient dans leur barre d’administration.

<?php
  //  Using jQuery: How to allow Editors to edit only Menus (or more!)
  //  Placed in THEME's footer.php as the Admin Bar is added when a user is logged in

  if ( is_user_logged_in() ) { // This IF may be redundant, but safe is better than sorry...
    if ( current_user_can('edit_theme_options') && !current_user_can('manage_options') ) { // Check if non-Admin
?>
      <script>
    jQuery.noConflict();
    jQuery(document).ready(function() {
      //  Comment out the line you WANT to enable, so it displays (is NOT removed).
      //  For example, the jQuery line for MENUS is commented out below so it's not removed.

      // THEMES:
      jQuery('li#wp-admin-bar-themes').remove();

      // CUSTOMIZE:
      jQuery('li#wp-admin-bar-customize').remove();

      // WIDGETS:
      jQuery('li#wp-admin-bar-widgets').remove();

      // MENUS:
      // jQuery('li#wp-admin-bar-menus').remove();

      // BACKGROUND:
      jQuery('li#wp-admin-bar-background').remove();
    });
      </script>
<?php
    } // End IF current_user_can...
  } // End IF is_user_logged_in...
?>
1
Chris Lemke

J'ai trouvé une solution partielle à ce problème.

Actions contraignantes

J'ajoute la méthode tardive (priorité = 10) à l'action user_has_cap. Dans la méthode liée, je vérifie la page utilisée (assurez-vous qu'il s'agit bien de wp-admin/widgets.php) et, le cas échéant, si l'autorisation est vérifiée edit_theme_options- J'accorde cette permission return $all_caps + array('edit_theme_options' => true);.

De plus, j'ai lié la méthode très tardive (priorité = 999) à admin_menuaction. Cette méthode, étant donné que l'utilisateur actuel a ma propre capacité définie à accéder uniquement au menu des widgets (n'a pas de sens - pourrait être user_can_customize_themes_widgets_only) J'itération sur global $ submenu section de tableau liée à l'apparence ($ submenu ['themes.php']) et supprime les éléments qui n'ont pas 'widgets.php' comme élément de chemin d'accès (index pour chemin est 2). Et enfin, je rajoute widgets.php), au cas où il manquerait.

Choses à considérer

Pourquoi je dis que c'est partiel?

Parce que c'est un contournement. J'accorde à l'utilisateur edit_theme_optionsright, même si pendant un court laps de temps et après s'être assuré que l'utilisateur accède à widgets.phpet pas à une autre page.

Et aussi - je ne peux pas compter sur cela pour travailler avec les futures versions de WP, car je modifie la variable globale $ submenu, qui peut changer de n'importe quelle manière à tout moment.

Compte tenu de cela - il est facile de mettre en œuvre la solution, mais ce n'est pas Nice en aucune façon.

0
Justas Butkus