Wie erstelle ich eine benutzerdefinierte Rollenfunktion?

26

Ich möchte eine benutzerdefinierte Funktion für den Zugriff auf die Benutzeroberfläche meines Plugins erstellen.

  • Sollte das Plugin es schaffen, diese Funktion bei der Aktivierung allen Administratorkonten hinzuzufügen?
  • Wenn ja: Schafft es WordPress, allen Administratoren von Subblogs und Superadministratoren in Installationen mit mehreren Standorten die Funktionen hinzuzufügen, oder muss diese Funktion vom Plug-in übernommen werden?
rsman
quelle
Ein detaillierter Blog: goo.gl/xNuafH
Suresh Kamrushi

Antworten:

11

Entfernen Sie, was Sie hinzufügen

Stellen Sie zunächst sicher, dass alles, was Sie bei der Aktivierung hinzufügen, auch bei der Deinstallation entfernt wird . Ich habe ein kurzes Tutorial mit Beispielcode für Sie.

Test mit einem kleinen Plugin:

Ich weiß wirklich nicht viel über MU, aber soweit ich das beurteilen kann, ist das Rollenobjekt in allen Blogs global. Probieren Sie einfach dieses kleine Plugin aus und sehen Sie, was Sie bekommen können:

<?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' );

Funktionen hinzufügen

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

Hinweis: Sie können die Funktion der Rolle hinzufügen, ohne Zugriff darauf zu gewähren. Setzen Sie einfach das zweite Argument $grant = false;. Dies ermöglicht die Whitelist einzelner Benutzer durch einfaches Hinzufügen der Obergrenze einschließlich des letzten Arguments als wahr.

Kaiser
quelle
17

Für ein Plugin bin auf mich zur Zeit wollte ich gewähren / beschränken Sie den Zugriff auf die Plugin - Einstellungen (dh die nach Admin - Menü Seiten) auf einer pro Rolle Basis.
Deshalb musste ich ein neues Plugin-spezifische hinzufügen capabilityzu deruser roles .

Leider scheint die Antwort von kaiser nicht mehr zu funktionieren, daher habe ich einige Zeit damit verbracht, herauszufinden, wie die oben genannte Funktionalität berücksichtigt werden kann.


Der Stundenplan

Bevor ich meinen Code mit Ihnen teile, geht es um Folgendes im Klartext:

  1. Fügen Sie bei der Aktivierung des Plugins die neue Funktion THE_NEW_CAPzu Rollen mit einer bestimmten integrierten Funktion hinzu BUILT_IN_CAP(in meinem Fall:) edit_pages.
  2. Führen Sie bei jedem Laden der Seite 1. aus (dh fügen Sie die Funktion erneut hinzu). Dies ist nur erforderlich, wenn Sie mögliche neue Rollen berücksichtigen möchten, die nach der Aktivierung des Plugins erstellt wurden. Daher verfügen diese neuen Rollen nicht über die Plug-in-spezifischen Funktionen, selbst wenn sie über die erforderlichen integrierten Funktionen verfügen.
  3. Nutzen Sie die neue Funktion für alles, was Sie wollen. Wie bereits erläutert, verwende ich es, um den Zugriff auf die Admin-Menüseiten des Plugins zu gewähren / einzuschränken. So wird es im folgenden Codebeispiel gemacht.
  4. Entfernen Sie bei Deaktivierung des Plugins die Funktion. Natürlich können Sie dies auch tun, wenn das Plugin deinstalliert wird. So oder so, mach es irgendwann.

Der Code

Und hier ist die obige Liste in Code umgewandelt:

»Einrichten

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

" Es benutzen

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

»Aufräumen

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

}

Hinweis: Bitte verwenden Sie keine Großbuchstaben. Dies dient nur der Lesbarkeit.

tfrommen
quelle
1
Immer get_editable_roles()zum Abrufen von Rollen verwenden, die Sie bearbeiten möchten. Sie werden sonst Plugins brechen.
Fuxia
1
@toscho Na ja, okay, ich nehme an, dass eine dieser Funktionen auch der Codex nicht kennt ...;) Natürlich ist diese Funktion sein Recht hat, jedoch zu existieren, sehe ich nicht den globalen WP_Roles Array Bruch irgendwelche Plugins in meinem Fall.
Beginn am
2
Einige Plugins erstellen spezielle Benutzerrollen und stützen sich auf die genauen Funktionen. In einigen Fällen schließt eine Funktion die Verwendung einer anderen in der Programmlogik aus. Sie können nicht wissen, wann dies der Fall ist.
Fuxia
0

Das funktioniert bei mir:

    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 );
                }
            }
        }
    }
Vitaly Konurin
quelle
Verändern Sie niemals die Globalen von Rollen! Noch nie. Nicht! Sie werden keine Hooks auslösen und Filter ablehnen und Ihren Code zu einem sich bewegenden Ziel machen. Niemand wird jemals erfahren, wann und wo Sie diese Rolle registriert haben (das haben Sie nicht getan, Sie haben sie einfach irgendwo, irgendwann, irgendwie hineingesteckt). Bitte: Tu das niemals. Vor allem nicht mit Rollen.
Kaiser