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>
This commit is contained in:
467
perfex-dev/skills/perfex-permissions/SKILL.md
Normal file
467
perfex-dev/skills/perfex-permissions/SKILL.md
Normal file
@@ -0,0 +1,467 @@
|
||||
---
|
||||
name: perfex-permissions
|
||||
description: 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".
|
||||
author: Descomplicar® Crescimento Digital
|
||||
version: 1.0.0
|
||||
quality_score: 70
|
||||
user_invocable: true
|
||||
desk_task: 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
|
||||
|
||||
- [Staff Capabilities and Access](https://help.perfexcrm.com/staff-capabilities-and-access/)
|
||||
- [Roles](https://help.perfexcrm.com/roles/)
|
||||
|
||||
---
|
||||
|
||||
## 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
|
||||
|
||||
```php
|
||||
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
|
||||
|
||||
```php
|
||||
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
|
||||
|
||||
```php
|
||||
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
|
||||
|
||||
```php
|
||||
<!-- 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
|
||||
|
||||
```php
|
||||
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
|
||||
|
||||
```php
|
||||
$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.):
|
||||
|
||||
```php
|
||||
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:**
|
||||
|
||||
```php
|
||||
if (staff_can('meu_modulo_custom_action', 'invoices')) {
|
||||
// Acção custom em facturas
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Verificar Administrador
|
||||
|
||||
```php
|
||||
// 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
|
||||
|
||||
```php
|
||||
// Redireciona com mensagem de acesso negado
|
||||
access_denied('meu_modulo');
|
||||
```
|
||||
|
||||
### Verificar Staff Logado
|
||||
|
||||
```php
|
||||
// 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
|
||||
|
||||
```php
|
||||
// Verificar se staff ID 5 pode editar
|
||||
$can_edit = staff_can('edit', 'meu_modulo', 5);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Exemplo Completo
|
||||
|
||||
### Init File
|
||||
|
||||
```php
|
||||
<?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
|
||||
<?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
|
||||
Reference in New Issue
Block a user