web-dev-qa-db-fra.com

Comment créer une fonctionnalité de rôle personnalisée?

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 tel est le cas: WordPress gère-t-il l'ajout de la possibilité à tous les administrateurs de sous-blogs et de super administrateurs dans les installations multisites, ou cette fonction doit-elle être gérée par le plugin?
25
rsman

Enlevez ce que vous ajoutez

Tout d’abord, assurez-vous que tout ce que vous ajoutez à l’activation obtient également supprimé lors de la désinstallation. J'ai eu un court tutoriel incluant un exemple de code pour vous.

Testez avec un petit plugin:

Je ne connais vraiment pas grand chose à MU, mais pour autant que je sache, l'objet de rôles est global dans tous les blogs. Essayez juste 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 fonctionnalité au rôle sans lui donner accès. Définissez simplement le deuxième argument $grant = false;. Cela permet d’inscrire en liste blanche des utilisateurs uniques en ajoutant simplement le plafond, y compris le dernier argument, à la valeur true.

10
kaiser

Pour un plug-in sur lequel je travaille actuellement, je souhaitais accorder/restreindre l'accès aux paramètres du plug-in (c'est-à-dire les pages de menu d'administration correspondantes) sur une base par rôle.
Par conséquent, je devais ajouter une nouvelle variable capability propre au plugin au user roles.

Malheureusement, la réponse de kaiser semble ne plus fonctionner, alors j'ai passé un certain temps à essayer de comprendre comment permettre la fonctionnalité mentionnée ci-dessus.


L'horaire

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

  1. Lors de l'activation du plug-in, ajoutez la nouvelle fonctionnalité THE_NEW_CAP aux rôles ayant une certaine fonctionnalité intégrée BUILT_IN_CAP (dans mon cas: edit_pages).
  2. À chaque chargement de page, faites 1. (c’est-à-dire, ajoutez à nouveau la capacité). Cela n'est nécessaire que si vous souhaitez prendre en compte d'éventuels nouveaux rôles créés après l'activation du plug-in. Par conséquent, ces nouveaux rôles n'ont pas la capacité spécifique au plug-in, même s'ils possèdent la capacité intégrée requise.
  3. Utilisez la nouvelle fonctionnalité pour tout ce que vous voulez. Comme expliqué précédemment, je l'utilise pour octroyer/restreindre l'accès aux pages de menu d'administration du plug-in. C'est ainsi que cela se passe dans l'exemple de code suivant.
  4. Sur la désactivation du plugin, supprimez la capacité. Bien sûr, vous pouvez également le faire lors de la désinstallation du plug-in. Quoi qu'il en soit, faites-le éventuellement.

Le code

Et voici la liste ci-dessus convertie en code:

"Mise en place

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 nettoyage

    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 fonctions majuscules. Ceci est juste pour des raisons de lisibilité.

17
tfrommen

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 );
                }
            }
        }
    }
0
Vitaly Konurin