Files
claude-plugins/perfex-dev/skills/perfex-permissions/SKILL.md
Emanuel Almeida 2cb3210962 feat: adiciona 12 plugins Descomplicar ao marketplace
Plugins: automacao, crm-ops, design-media, dev-tools, gestao,
infraestrutura, marketing, negocio, perfex-dev, project-manager,
wordpress + hello-plugin (existente).

Totais: 83 skills, 44 agents, 12 datasets.json

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 21:41:24 +00:00

11 KiB

name, description, author, version, quality_score, user_invocable, desk_task
name description author version quality_score user_invocable desk_task
perfex-permissions Perfex CRM permissions system. staff_can(), register_staff_capabilities(), access control. Based on official documentation only. Use when user mentions "perfex permissions", "staff_can", "access control", "capabilities perfex". Descomplicar® Crescimento Digital 1.0.0 70 true null

/perfex-permissions - Permissões Perfex CRM

Sistema de permissões e controlo de acesso. Zero assumptions, zero hallucinations - apenas documentação oficial.


Documentação Base


Conceitos Fundamentais

Conceito Descrição
Feature Área funcional (invoices, projects, meu_modulo)
Capability Permissão específica (view, create, edit, delete)
Role Conjunto de permissões pré-definido

Registar Permissões do Módulo

No Init File

hooks()->add_action('admin_init', 'meu_modulo_register_permissions');

function meu_modulo_register_permissions()
{
    $capabilities = [];

    $capabilities['capabilities'] = [
        'view'   => _l('permission_view'),    // Ver
        'create' => _l('permission_create'),  // Criar
        'edit'   => _l('permission_edit'),    // Editar
        'delete' => _l('permission_delete'),  // Apagar
    ];

    register_staff_capabilities(
        'meu_modulo',           // Feature ID (único)
        $capabilities,          // Array de capabilities
        _l('meu_modulo_title')  // Nome do módulo (mostrado em Settings)
    );
}

Parâmetros register_staff_capabilities()

Parâmetro Tipo Descrição
$feature string ID único da feature
$capabilities array Array com key 'capabilities'
$name string Nome mostrado na UI

Verificar Permissões: staff_can()

Sintaxe

staff_can($capability, $feature = null, $staff_id = '');

Parâmetros

Parâmetro Tipo Descrição
$capability string Nome da capability (view, create, etc.)
$feature string Feature ID (recomendado SEMPRE passar)
$staff_id int ID do staff (default: staff logado)

Retorno

  • true - Staff tem permissão
  • false - Staff não tem permissão

NOTA: Administradores SEMPRE retornam true (bypass total).


Exemplos de Uso

No Controller

class Meu_modulo extends AdminController
{
    public function index()
    {
        // Verificar permissão de ver
        if (!staff_can('view', 'meu_modulo')) {
            access_denied('meu_modulo');
        }

        // ... código
    }

    public function create()
    {
        // Verificar permissão de criar
        if (!staff_can('create', 'meu_modulo')) {
            access_denied('meu_modulo');
        }

        // ... código
    }

    public function edit($id)
    {
        // Verificar permissão de editar
        if (!staff_can('edit', 'meu_modulo')) {
            access_denied('meu_modulo');
        }

        // ... código
    }

    public function delete($id)
    {
        // Verificar permissão de apagar
        if (!staff_can('delete', 'meu_modulo')) {
            access_denied('meu_modulo');
        }

        // ... código
    }
}

Na View

<!-- Mostrar botão apenas se tem permissão -->
<?php if (staff_can('create', 'meu_modulo')): ?>
    <a href="<?php echo admin_url('meu_modulo/create'); ?>" class="btn btn-primary">
        <i class="fa fa-plus"></i> <?php echo _l('create'); ?>
    </a>
<?php endif; ?>

<!-- Botões de acção condicionais -->
<td>
    <?php if (staff_can('edit', 'meu_modulo')): ?>
        <a href="<?php echo admin_url('meu_modulo/edit/' . $item->id); ?>"
           class="btn btn-default btn-icon">
            <i class="fa fa-pencil"></i>
        </a>
    <?php endif; ?>

    <?php if (staff_can('delete', 'meu_modulo')): ?>
        <a href="<?php echo admin_url('meu_modulo/delete/' . $item->id); ?>"
           class="btn btn-danger btn-icon _delete">
            <i class="fa fa-trash"></i>
        </a>
    <?php endif; ?>
</td>

No Menu

function meu_modulo_init_menu()
{
    // Só mostrar menu se tem permissão
    if (!staff_can('view', 'meu_modulo')) {
        return;
    }

    $CI = &get_instance();
    $CI->app_menu->add_sidebar_menu_item('meu-modulo', [
        'name'     => _l('meu_modulo'),
        'href'     => admin_url('meu_modulo'),
        'position' => 25,
        'icon'     => 'fa fa-cube',
    ]);
}

Capabilities Padrão

Recomendadas para CRUD

Capability Descrição Uso
view Ver registos Listar, ver detalhes
create Criar novos Formulário de criação
edit Editar existentes Formulário de edição
delete Apagar registos Botão de eliminar

Adicionar Capabilities Custom

$capabilities['capabilities'] = [
    // CRUD básico
    'view'   => _l('permission_view'),
    'create' => _l('permission_create'),
    'edit'   => _l('permission_edit'),
    'delete' => _l('permission_delete'),

    // Custom
    'export'     => _l('permission_export'),      // Exportar dados
    'import'     => _l('permission_import'),      // Importar dados
    'send_email' => _l('permission_send_email'),  // Enviar emails
    'view_all'   => _l('permission_view_all'),    // Ver todos (não só próprios)
    'approve'    => _l('permission_approve'),     // Aprovar items
];

Adicionar Permissões a Features Existentes

Para adicionar capabilities a módulos do core (invoices, projects, etc.):

hooks()->add_action('admin_init', 'meu_modulo_extend_permissions');

function meu_modulo_extend_permissions()
{
    $capabilities = [];

    $capabilities['capabilities'] = [
        'meu_modulo_custom_action' => _l('meu_modulo_custom_action_label'),
    ];

    // Adicionar à feature "invoices"
    register_staff_capabilities('invoices', $capabilities);
}

Uso:

if (staff_can('meu_modulo_custom_action', 'invoices')) {
    // Acção custom em facturas
}

Verificar Administrador

// Verificar se é admin (tem todas as permissões)
if (is_admin()) {
    // Utilizador é administrador
}

// Verificar se é admin específico (ID 1)
if (is_admin(1)) {
    // Staff com ID 1 é admin
}

Funções Auxiliares

Acesso Negado

// Redireciona com mensagem de acesso negado
access_denied('meu_modulo');

Verificar Staff Logado

// ID do staff actual
$staff_id = get_staff_user_id();

// Verificar se está logado
if (is_staff_logged_in()) {
    // Staff autenticado
}

Verificar Permissão de Outro Staff

// Verificar se staff ID 5 pode editar
$can_edit = staff_can('edit', 'meu_modulo', 5);

Exemplo Completo

Init File

<?php
defined('BASEPATH') or exit('No direct script access allowed');

/*
Module Name: Gestão de Inventário
Description: Sistema de inventário com controlo de acesso
Version: 1.0.0
Requires at least: 2.3.*
*/

// Registar permissões
hooks()->add_action('admin_init', 'inventario_register_permissions');
hooks()->add_action('admin_init', 'inventario_init_menu');

function inventario_register_permissions()
{
    $capabilities = [
        'capabilities' => [
            'view'       => _l('permission_view'),
            'create'     => _l('permission_create'),
            'edit'       => _l('permission_edit'),
            'delete'     => _l('permission_delete'),
            'export'     => _l('inventory_permission_export'),
            'adjust'     => _l('inventory_permission_adjust'),  // Ajustar stock
            'view_costs' => _l('inventory_permission_view_costs'),  // Ver custos
        ],
    ];

    register_staff_capabilities(
        'inventario',
        $capabilities,
        _l('inventory_module')
    );
}

function inventario_init_menu()
{
    if (!staff_can('view', 'inventario')) {
        return;
    }

    $CI = &get_instance();

    $CI->app_menu->add_sidebar_menu_item('inventario', [
        'name'     => _l('inventory'),
        'collapse' => true,
        'position' => 22,
        'icon'     => 'fa fa-cubes',
    ]);

    $CI->app_menu->add_sidebar_children_item('inventario', [
        'slug'     => 'inventario-lista',
        'name'     => _l('products'),
        'href'     => admin_url('inventario'),
        'position' => 1,
        'icon'     => 'fa fa-list',
    ]);

    if (staff_can('adjust', 'inventario')) {
        $CI->app_menu->add_sidebar_children_item('inventario', [
            'slug'     => 'inventario-ajustes',
            'name'     => _l('adjustments'),
            'href'     => admin_url('inventario/adjustments'),
            'position' => 2,
            'icon'     => 'fa fa-exchange',
        ]);
    }

    if (staff_can('export', 'inventario')) {
        $CI->app_menu->add_sidebar_children_item('inventario', [
            'slug'     => 'inventario-export',
            'name'     => _l('export'),
            'href'     => admin_url('inventario/export'),
            'position' => 3,
            'icon'     => 'fa fa-download',
        ]);
    }
}

Controller

<?php
defined('BASEPATH') or exit('No direct script access allowed');

class Inventario extends AdminController
{
    public function __construct()
    {
        parent::__construct();
        $this->load->model('inventario/inventario_model');
    }

    public function index()
    {
        if (!staff_can('view', 'inventario')) {
            access_denied('inventario');
        }

        $data['products'] = $this->inventario_model->get_all();

        // Se pode ver custos, incluir
        if (staff_can('view_costs', 'inventario')) {
            $data['show_costs'] = true;
        }

        $this->load->view('inventario/index', $data);
    }

    public function adjustments()
    {
        if (!staff_can('adjust', 'inventario')) {
            access_denied('inventario');
        }

        // ... lógica de ajustes
    }

    public function export()
    {
        if (!staff_can('export', 'inventario')) {
            access_denied('inventario');
        }

        // ... lógica de exportação
    }
}

Anti-Patterns (NUNCA FAZER)

Anti-Pattern Risco Alternativa
Não verificar permissões no controller Acesso não autorizado staff_can() sempre
Confiar apenas na UI Bypass via URL Verificar em backend
Feature ID duplicado Conflitos Prefixar com nome módulo
Capability sem _l() Não traduzível Usar traduções
Assumir que view esconde acção Vulnerável Verificar em ambos

Checklist Permissões

1. [ ] register_staff_capabilities no init file
2. [ ] Feature ID único
3. [ ] Capabilities com traduções (_l)
4. [ ] staff_can() em TODOS os métodos do controller
5. [ ] staff_can() nas views para UI condicional
6. [ ] staff_can() antes de mostrar menus
7. [ ] access_denied() para rejeitar acesso
8. [ ] Testado com utilizador não-admin

Versão: 1.0.0 | Autor: Descomplicar® Fonte: help.perfexcrm.com/staff-capabilities-and-access