Jak utworzyć niestandardową funkcję roli?

26

Chcę stworzyć niestandardową możliwość dostępu do interfejsu mojej wtyczki.

  • Czy wtyczka powinna poradzić sobie z dodaniem tej możliwości do wszystkich kont administratora podczas aktywacji?
  • Jeśli tak: czy WordPress zarządza dodaniem możliwości wszystkim administratorom pod blogów i superadministratorów w instalacjach na wielu stronach, czy też ta funkcja musi być obsługiwana przez wtyczkę?
rsman
źródło
Szczegółowy blog: goo.gl/xNuafH
Suresh Kamrushi

Odpowiedzi:

11

Usuń to, co dodajesz

Najpierw upewnij się, że wszystko, co dodasz podczas aktywacji, zostanie również usunięte podczas odinstalowywania . Mam krótki samouczek zawierający przykładowy kod dla ciebie .

Przetestuj za pomocą małej wtyczki:

Naprawdę niewiele wiem o MU, ale o ile mogę stwierdzić, obiekt ról jest globalny we wszystkich blogach. Po prostu wypróbuj tę małą wtyczkę i zobacz, co możesz uzyskać:

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

Dodawanie możliwości

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

Uwaga: Możesz dodać możliwość do roli bez udzielania dostępu do niej - wystarczy ustawić drugi argument $grant = false;. Pozwala to dodawać pojedynczych użytkowników do białej listy po prostu dodając limit, w tym ostatni argument jako prawdziwy.

kajzer
źródło
17

W przypadku wtyczki, nad którą obecnie pracuję, chciałem udzielić / ograniczyć dostęp do ustawień wtyczki (tj. Odpowiednich stron menu administratora) dla poszczególnych ról .
Dlatego musiałem dodać nową wtyczkę capabilitydouser roles .

Niestety, odpowiedź kaisera wydaje się już nie działać, więc spędziłem trochę czasu próbując wymyślić, jak zezwolić na wyżej wspomnianą funkcjonalność.


Harmonogram

Zanim podzielę się z tobą moim kodem, oto o co chodzi, w postaci zwykłego tekstu:

  1. Po aktywacji wtyczki dodaj nową funkcję THE_NEW_CAPdo ról mających pewne wbudowane możliwości BUILT_IN_CAP(w moim przypadku:edit_pages :).
  2. Przy każdym ładowaniu strony wykonaj 1. (tj. Ponownie dodaj możliwość). Jest to konieczne tylko wtedy, gdy chcesz uwzględnić możliwe nowe role, które zostały utworzone po aktywacji wtyczki. Dlatego te nowe role nie mają funkcji specyficznych dla wtyczek, nawet jeśli mają wymagane wbudowane funkcje.
  3. Skorzystaj z nowej funkcji do wszystkiego, czego chcesz. Jak wyjaśniono wcześniej, używam go do przyznawania / ograniczania dostępu do stron menu administratora wtyczki, tak to jest zrobione w poniższym przykładzie kodu.
  4. Po dezaktywacji wtyczki usuń tę możliwość. Oczywiście możesz to zrobić również podczas odinstalowywania wtyczki. Tak czy inaczej, zrób to w końcu.

Kod

A oto powyższa lista przekonwertowana na kod:

»Konfiguracja

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

" Użyj tego

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

»Sprzątanie

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

}

Uwaga: Nie używaj wielkich liter. To tylko dla czytelności.

tfrommen
źródło
1
Zawsze używaj get_editable_roles()do pobierania ról, które chcesz edytować. Państwo będzie złamać wtyczek inaczej.
fuxia
1
@toscho Dobrze, dobrze, przypuszczam, że to jedna z tych funkcji nawet Codex nie wie ...;) Oczywiście, ta funkcja ma prawo do istnienia, jednak nie widzę za pomocą globalnej WP_Roles tablicy łamanie wszelkie wtyczki w moim przypadku.
tfrommen
2
Niektóre wtyczki tworzą wyspecjalizowane role użytkowników i polegają na dokładnym zestawie możliwości. W niektórych przypadkach jedna funkcja wyklucza użycie innej w logice programu. Nie możesz wiedzieć, kiedy tak jest.
fuxia
0

To działa dla mnie:

    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 );
                }
            }
        }
    }
Witalij Konurin
źródło
Nigdy nie modyfikuj globalnych ról! Nigdy. Nie! Nie uruchomisz żadnych haczyków i odmówisz filtrów, a Twój kod stanie się ruchomym celem. Nikt nigdy nie będzie wiedział, kiedy i gdzie zarejestrowałeś tę rolę (nie zrobiłeś tego, po prostu gdzieś ją gdzieś, gdzieś gdzieś). Proszę: nigdy tego nie rób. Zwłaszcza nie z rolami.
kaiser