Como crio um recurso de função personalizado?

26

Desejo criar um recurso personalizado para acessar a interface do meu plugin.

  • O plug-in deve gerenciar adicionar esse recurso a todas as contas de administrador na ativação?
  • Em caso afirmativo: o WordPress gerencia adicionar a capacidade a todos os administradores de sub-blogs e superusuários em instalações multisite, ou essa função precisa ser tratada pelo plug-in?
rsman
fonte
Um blog de detalhes: goo.gl/xNuafH
Suresh Kamrushi

Respostas:

11

Remova o que você adiciona

Primeiro, verifique se tudo o que você adiciona na ativação também é removido na desinstalação . Eu recebi um breve tutorial, incluindo código de exemplo para você.

Teste com um pequeno plugin:

Realmente não sei muito sobre o MU, mas, até onde sei, o objeto role é global em todos os blogs. Apenas tente este pequeno plugin e veja o que você pode obter:

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

Adicionando recursos

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

Nota: Você pode adicionar o recurso à função sem conceder acesso a ela - basta definir o segundo argumento $grant = false;. Isso permite que usuários únicos da lista de permissões adicionem simplesmente o limite incluindo o último argumento como verdadeiro.

kaiser
fonte
17

Para um plug-in no qual estou trabalhando, eu queria conceder / restringir o acesso às configurações do plug-in (ou seja, as páginas do menu de administração) de acordo com a função .
Portanto, tive que adicionar um novo plugin específico capabilityao arquivouser roles .

Infelizmente, a resposta do kaiser parece não estar mais funcionando, então passei algum tempo tentando descobrir como permitir a funcionalidade mencionada acima.


O horário

Antes de compartilhar meu código com você, aqui está o que se trata, em texto simples:

  1. Na ativação do plug-in, adicione o novo recurso THE_NEW_CAPa funções com um determinado recurso interno BUILT_IN_CAP(no meu caso edit_pages:).
  2. Em cada carregamento de página, faça 1. (por exemplo, adicione o recurso novamente). Isso é necessário apenas se você desejar contabilizar possíveis novas funções que foram criadas após a ativação do plug-in. Portanto, essas novas funções não têm o recurso específico do plug-in, mesmo que tenham o recurso interno necessário.
  3. Use o novo recurso para o que você quiser. Como explicado anteriormente, eu o uso para conceder / restringir o acesso às páginas do menu de administração do plug-in, e é assim que é feito no exemplo de código a seguir.
  4. Na desativação do plug-in, remova o recurso. Obviamente, você também pode fazer isso quando o plug-in estiver sendo desinstalado. De qualquer maneira, faça-o eventualmente.

O código

E aqui está a lista acima convertida em código:

»Configurando

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

" Usando isso

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

»Limpando

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

}

Nota: Por favor, não use recursos em maiúsculas. Isso é apenas para facilitar a leitura.

tfrommen
fonte
11
Sempre use get_editable_roles()para buscar as funções que deseja editar. Você irá quebrar os plugins caso contrário.
Fuxia
11
@toscho Bem, ok, suponho que seja uma dessas funções que nem o Codex desconheça ...;) Obviamente, essa função tem o direito de existir, no entanto, não vejo o uso da quebra global da matriz WP_Roles quaisquer plugins no meu caso.
tfrommen
2
Alguns plug-ins criam funções de usuário especializadas e contam com o conjunto exato de recursos. Em alguns casos, um recurso exclui o uso de outro na lógica do programa. Você não pode saber quando é esse o caso.
fuxia
0

Isso funciona para mim:

    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
fonte
Nunca modifique os globais de papéis! Nunca. Não! Você não acionará nenhum gancho, negará filtros e fará do seu código um alvo em movimento. Ninguém nunca saberá quando e onde você registrou esse papel (você não o fez, apenas o colocou lá em algum lugar, de alguma maneira, de alguma maneira). Por favor: nunca faça isso. Especialmente com papéis.
kaiser