- All SKILL.md files now <500 lines (avg reduction 69%) - Detailed content extracted to references/ subdirectories - Frontmatter standardised: only name + description (Anthropic standard) - New skills: brand-guidelines, spec-coauthor, report-templates, skill-creator - Design skills: anti-slop guidelines, premium-proposals reference - Removed non-standard frontmatter fields (triggers, version, author, category) Plugins affected: infraestrutura, marketing, dev-tools, crm-ops, gestao, core-tools, negocio, perfex-dev, wordpress, design-media Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
9.4 KiB
9.4 KiB
name, description
| name | description |
|---|---|
| perfex-controllers | Controllers para módulos Perfex CRM — AdminController, ClientsController, routing e trait ValidatesContact. Baseado apenas na documentação oficial. |
/perfex-controllers - Controllers Perfex CRM
Controllers para módulos Perfex CRM. Zero assumptions, zero hallucinations - apenas documentação oficial.
Documentação Base
Estrutura de Pastas
modules/meu_modulo/
└── controllers/
├── Meu_modulo.php # Controller principal
├── Admin_controller.php # Controller admin adicional
└── Client_controller.php # Controller cliente
Classes Base Disponíveis
| Classe | Uso | Validação Automática |
|---|---|---|
AdminController |
Área admin/staff | Login staff obrigatório |
ClientsController |
Área cliente | Tema cliente aplicado |
App_Controller |
Base genérica | Nenhuma |
AdminController (Área Admin)
Para funcionalidades exclusivas de staff/administradores.
Template
<?php
defined('BASEPATH') or exit('No direct script access allowed');
class Meu_modulo extends AdminController
{
public function __construct()
{
parent::__construct();
// Carregar models, helpers, etc.
$this->load->model('meu_modulo/meu_modulo_model');
}
/**
* Página principal do módulo
* URL: /admin/meu_modulo ou /admin/meu_modulo/index
*/
public function index()
{
// Verificar permissão
if (!staff_can('view', 'meu_modulo')) {
access_denied('meu_modulo');
}
// Preparar dados
$data['items'] = $this->meu_modulo_model->get_all();
$data['title'] = _l('meu_modulo_title');
// Carregar view
$this->load->view('meu_modulo/index', $data);
}
/**
* Formulário de criação
* URL: /admin/meu_modulo/create
*/
public function create()
{
if (!staff_can('create', 'meu_modulo')) {
access_denied('meu_modulo');
}
if ($this->input->post()) {
// Processar formulário
$data = $this->input->post();
$id = $this->meu_modulo_model->add($data);
if ($id) {
set_alert('success', _l('added_successfully', _l('meu_modulo_item')));
redirect(admin_url('meu_modulo'));
}
}
$this->load->view('meu_modulo/form');
}
/**
* Editar item
* URL: /admin/meu_modulo/edit/123
*/
public function edit($id)
{
if (!staff_can('edit', 'meu_modulo')) {
access_denied('meu_modulo');
}
$data['item'] = $this->meu_modulo_model->get($id);
if (!$data['item']) {
show_404();
}
if ($this->input->post()) {
$success = $this->meu_modulo_model->update($id, $this->input->post());
if ($success) {
set_alert('success', _l('updated_successfully', _l('meu_modulo_item')));
redirect(admin_url('meu_modulo'));
}
}
$this->load->view('meu_modulo/form', $data);
}
/**
* Apagar item
* URL: /admin/meu_modulo/delete/123
*/
public function delete($id)
{
if (!staff_can('delete', 'meu_modulo')) {
access_denied('meu_modulo');
}
if ($this->meu_modulo_model->delete($id)) {
set_alert('success', _l('deleted', _l('meu_modulo_item')));
}
redirect(admin_url('meu_modulo'));
}
}
ClientsController (Área Cliente)
Para funcionalidades na área de clientes.
Template
<?php
defined('BASEPATH') or exit('No direct script access allowed');
class Meu_modulo extends ClientsController
{
public function __construct()
{
parent::__construct();
$this->load->model('meu_modulo/meu_modulo_model');
}
/**
* Página principal cliente
* URL: /meu_modulo ou /meu_modulo/index
*/
public function index()
{
// Verificar se cliente logado
if (!is_client_logged_in()) {
redirect(site_url('authentication/login'));
}
$contact_id = get_contact_user_id();
$client_id = get_client_user_id();
$data = [
'items' => $this->meu_modulo_model->get_by_client($client_id),
];
// Métodos específicos de ClientsController
$this->data($data);
$this->title(_l('meu_modulo_title'));
$this->view('meu_modulo/client_index');
$this->layout();
}
/**
* Ver detalhe
* URL: /meu_modulo/view/123
*/
public function view($id)
{
if (!is_client_logged_in()) {
redirect(site_url('authentication/login'));
}
$item = $this->meu_modulo_model->get($id);
// Verificar se pertence ao cliente
if (!$item || $item->client_id != get_client_user_id()) {
show_404();
}
$this->data(['item' => $item]);
$this->title($item->name);
$this->view('meu_modulo/client_view');
$this->layout();
}
}
ValidatesContact Trait (v2.3.3+)
Para exigir contacto autenticado com email verificado.
<?php
defined('BASEPATH') or exit('No direct script access allowed');
use app\services\ValidatesContact;
class Meu_modulo extends ClientsController
{
use ValidatesContact;
public function __construct()
{
parent::__construct();
// Todos os métodos requerem contacto validado
$this->validateContactInController();
}
public function index()
{
// Só executa se contacto logado E email verificado
// ...
}
}
URLs e Routing
Admin Controllers
| URL | Controller | Método |
|---|---|---|
/admin/meu_modulo |
Meu_modulo | index() |
/admin/meu_modulo/create |
Meu_modulo | create() |
/admin/meu_modulo/edit/123 |
Meu_modulo | edit(123) |
/admin/meu_modulo/delete/123 |
Meu_modulo | delete(123) |
Client Controllers
| URL | Controller | Método |
|---|---|---|
/meu_modulo |
Meu_modulo | index() |
/meu_modulo/view/123 |
Meu_modulo | view(123) |
Quando Nome Controller = Nome Módulo
Se o controller tem o mesmo nome do módulo, URLs simplificadas:
/admin/meu_modulo → modules/meu_modulo/controllers/Meu_modulo.php::index()
/meu_modulo → modules/meu_modulo/controllers/Meu_modulo.php::index()
Controllers com Nomes Diferentes
/admin/meu_modulo/outro_controller/metodo
→ modules/meu_modulo/controllers/Outro_controller.php::metodo()
Funções Helper Úteis
Admin URLs
// Gerar URL admin
admin_url('meu_modulo'); // /admin/meu_modulo
admin_url('meu_modulo/edit/123'); // /admin/meu_modulo/edit/123
// Redirecionar
redirect(admin_url('meu_modulo'));
Site URLs
// Gerar URL site/cliente
site_url('meu_modulo'); // /meu_modulo
site_url('meu_modulo/view/123'); // /meu_modulo/view/123
Alertas
// Definir alerta (mostra na próxima página)
set_alert('success', 'Operação concluída!');
set_alert('warning', 'Atenção!');
set_alert('danger', 'Erro!');
Verificações de Login
// Staff
is_staff_logged_in(); // bool
get_staff_user_id(); // int
// Cliente/Contacto
is_client_logged_in(); // bool
get_client_user_id(); // int (customer_id)
get_contact_user_id(); // int (contact_id)
Acesso Negado
// Redireciona com mensagem de acesso negado
access_denied('meu_modulo');
AJAX Responses
Retornar JSON
public function ajax_get_item($id)
{
if (!$this->input->is_ajax_request()) {
show_404();
}
$item = $this->meu_modulo_model->get($id);
echo json_encode([
'success' => (bool) $item,
'data' => $item,
]);
}
Com Validação CSRF
public function ajax_save()
{
if (!$this->input->is_ajax_request()) {
show_404();
}
// CSRF validado automaticamente se usar jQuery
$data = $this->input->post();
$id = $this->meu_modulo_model->add($data);
echo json_encode([
'success' => (bool) $id,
'id' => $id,
'message' => $id ? _l('added_successfully') : _l('error_occurred'),
]);
}
Anti-Patterns (NUNCA FAZER)
| Anti-Pattern | Risco | Alternativa |
|---|---|---|
| Controller sem verificar permissões | Acesso não autorizado | staff_can() sempre |
| Aceder dados de outros clientes | Data breach | Validar ownership |
| Nome ficheiro lowercase | Não carrega | Primeira letra MAIÚSCULA |
| echo em controllers admin | Output malformado | Usar views |
| Não validar AJAX requests | CSRF vulnerável | is_ajax_request() |
Checklist Controller
1. [ ] defined('BASEPATH') no topo
2. [ ] Extends classe correcta (Admin/Clients/App_Controller)
3. [ ] Nome ficheiro com primeira letra maiúscula
4. [ ] Permissões verificadas em cada método
5. [ ] Ownership validado para dados de clientes
6. [ ] Inputs via $this->input->post/get
7. [ ] Alertas definidos antes de redirect
8. [ ] AJAX methods verificam is_ajax_request()
Versão: 1.0.0 | Autor: Descomplicar® Fonte: help.perfexcrm.com/module-controllers