Comment créer une fonction de rôle personnalisé?


26

Je souhaite créer une fonctionnalité personnalisée pour accéder à l'interface de mon plugin.

  • Le plugin doit-il gérer l'ajout de cette fonctionnalité à tous les comptes d'administrateur lors de l'activation?
  • Si oui: WordPress gère-t-il l'ajout de la capacité à tous les administrateurs de sous-blogs et super administrateurs dans les installations multisites, ou cette fonction doit-elle être gérée par le plugin?

Un blog détaillé: goo.gl/xNuafH
Suresh Kamrushi

Réponses:


11

Supprimez ce que vous ajoutez

Tout d'abord, assurez-vous que tout ce que vous ajoutez lors de l'activation est également supprimé lors de la désinstallation . J'ai reçu un petit tutoriel comprenant un exemple de code pour vous.

Testez avec un petit plugin:

Je ne sais vraiment pas grand-chose sur MU, mais pour autant que je sache, l'objet rôles est global sur tous les blogs. Essayez simplement ce petit plugin et voyez ce que vous pouvez obtenir:

<?php
/*
Plugin Name:    MU Roles check
Plugin URI:     https://github.com/franz-josef-kaiser/
Description:    Check roles during viewing a blog
Author:     Franz Josef Kaiser
Author URI:     https://plus.google.com/u/0/107110219316412982437
Version:        0.1
Text Domain:    murc
License:        GPL v2 - http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*/

/**
 * Show the blog data and the role names in this blog
 * Also shows if the custom capability was successfully added, or displays n/a for the role
 * 
 * @return void
 */
function wpse35165_role_check()
{
    $blog = get_current_site();
    $custom_cap = 'name_of_your_custom_capability';

    $html = "<hr /><table>";
    $html .= "<caption>List roles in (Blog) {$blog->site_name} / ID#{$blog->id}</caption>"
    $html .= "<thead><tr><th>Role Name</th><th>Capabilties</th></tr></thead><tbody>";
    foreach ( $GLOBALS['wp_roles'] as $name => $role_obj )
    {
        $cap = in_array( $custom_cap, $role_obj->caps ) ? $custom_cap : 'n/a';
        $cap = $cap OR in_array( $custom_cap, $role_obj->allcaps ) ? $custom_cap : 'n/a';
        $html .= "<tr><td>{$name}</td><td>{$cap}</td></tr>";
    }
    $html .= '</tbody></table>';

    print $html;
}
add_action( 'shutdown', 'wpse35165_role_check' );

Ajout de capacités

/**
 * Add the capability to the role objects
 * Should be in your activation function and done before you inspect with your plugin
 * 
 * @return void
 */
function wpse35165_add_cap()
{
    $custom_cap = 'name_of_your_custom_capability';
    $min_cap    = 'the_minimum_required_built_in_cap'; // Check "Roles and objects table in codex!
    $grant      = true; 

    foreach ( $GLOBALS['wp_roles'] as $role_obj )
    {
        if ( 
            ! $role_obj->has_cap( $custom_cap ) 
            AND $role_obj->has_cap( $min_cap )
        )
            $role_obj->add_cap( $custom_cap, $grant );
    }
}

Remarque: Vous pouvez ajouter la capacité au rôle sans lui accorder l'accès - définissez simplement le deuxième argument $grant = false;. Cela permet aux utilisateurs individuels de mettre sur liste blanche en ajoutant simplement le plafond, y compris le dernier argument comme vrai.


17

Pour un plugin sur lequel je travaille actuellement, je voulais accorder / restreindre l'accès aux paramètres du plugin (c'est-à-dire aux pages du menu d'administration correspondant) sur une base par rôle .
Par conséquent, j'ai dû ajouter un nouveau plugin spécifique capabilityauuser roles .

Malheureusement, la réponse de Kaiser ne semble plus fonctionner, j'ai donc passé un peu de temps à essayer de comprendre comment autoriser les fonctionnalités mentionnées ci-dessus.


L'horaire

Avant de partager mon code avec vous, voici de quoi il s'agit, en texte clair:

  1. Lors de l'activation du plugin, ajoutez la nouvelle capacité THE_NEW_CAPaux rôles ayant une certaine capacité intégrée BUILT_IN_CAP(dans mon cas:) edit_pages.
  2. À chaque chargement de page, faites 1. (c.-à-d., Ajoutez la capacité, encore une fois). Cela n'est nécessaire que si vous souhaitez tenir compte des nouveaux rôles possibles qui ont été créés après l'activation du plugin. Par conséquent, ces nouveaux rôles n'ont pas la capacité spécifique au plugin, même s'ils ont la capacité intégrée requise.
  3. Utilisez la nouvelle capacité pour tout ce que vous voulez. Comme expliqué précédemment, je l'utilise pour accorder / restreindre l'accès aux pages du menu d'administration du plugin, c'est ainsi que cela se fait dans l'exemple de code suivant.
  4. Lors de la désactivation du plugin, supprimez la capacité. Bien sûr, vous pouvez également le faire lors de la désinstallation du plugin. Quoi qu'il en soit, faites-le finalement.

Le code

Et voici la liste ci-dessus convertie en code:

»Configuration

class WPSE35165Plugin {

    public function __construct() {
        // Register hooks
        register_activation_hook(__FILE__, array(__CLASS__, 'activation'));
        register_deactivation_hook(__FILE__, array(__CLASS__, 'deactivation'));

        // Add actions
        add_action('admin_menu', array(__CLASS__, 'admin_menu'));
    }

    public function activation() {
        self::add_cap();
    }

    // Add the new capability to all roles having a certain built-in capability
    private static function add_cap() {
        $roles = get_editable_roles();
        foreach ($GLOBALS['wp_roles']->role_objects as $key => $role) {
            if (isset($roles[$key]) && $role->has_cap('BUILT_IN_CAP')) {
                $role->add_cap('THE_NEW_CAP');
            }
        }
    }

" En l'utilisant

    // Add plugin menu pages to admin menu
    public function admin_menu() {
        // Remove the following line if you don't care about new roles
        // that have been created after plugin activation
        self::add_cap();

        // Set up the plugin admin menu
        add_menu_page('Menu', 'Menu', 'THE_NEW_CAP', …);
        add_submenu_page('wpse35165', 'Submenu', 'Submenu', 'THE_NEW_CAP', ...);
    }

»Le nettoyer

    public function deactivation() {
        self::remove_cap();
    }

    // Remove the plugin-specific custom capability
    private static function remove_cap() {
        $roles = get_editable_roles();
        foreach ($GLOBALS['wp_roles']->role_objects as $key => $role) {
            if (isset($roles[$key]) && $role->has_cap('THE_NEW_CAP')) {
                $role->remove_cap('THE_NEW_CAP');
            }
        }
    }

}

Remarque: veuillez ne pas utiliser les capacités en majuscules. C'est juste pour la lisibilité.


1
Utilisez toujours get_editable_roles()pour récupérer les rôles que vous souhaitez modifier. Vous allez casser les plugins autrement.
fuxia

1
@toscho Bon, d' accord, je suppose que c'est une de ces fonctions même le Codex ne connaît pas ...;) Bien sûr, cette fonction a son droit d'exister, cependant, je ne vois pas en utilisant le tableau global WP_Roles rupture tous les plugins dans mon cas.
tfrommen

2
Certains plugins créent des rôles d'utilisateur spécialisés et s'appuient sur l'ensemble exact de capacités. Dans certains cas, une capacité exclut l'utilisation d'une autre dans la logique du programme. Vous ne pouvez pas savoir quand c'est le cas.
fuxia

0

Cela fonctionne pour moi:

    add_action('admin_init', 'add_custom_cap');
    function add_custom_cap()
    {
        $custom_cap = 'test_cap';
        $min_cap    = 'read';
        $grant      = true;
        $to_role = 'your_user_role';
        $role = 'user_role';

        foreach ( $GLOBALS['wp_roles'] as $role_obj )
        {
            if (is_object($role_obj[$role])) {
                if (!$role_obj[$role]->has_cap( $custom_cap ) && $role_obj[$role]->has_cap( $min_cap )) {
                    $role_obj[$role]->add_cap( $custom_cap, $grant );
                }
            }
        }
    }

Ne modifiez jamais les globales des rôles! Jamais. Non! Vous ne déclencherez aucun hook et refuserez les filtres et ferez de votre code une cible mobile. Personne ne saura jamais quand et où vous avez enregistré ce rôle (vous ne l'avez pas fait, vous l'avez simplement inséré quelque part, quelque part, d'une manière ou d'une autre). S'il vous plaît: ne faites jamais ça. Surtout pas avec les rôles.
kaiser
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.