--- name: perfex-controllers description: Perfex CRM module controllers. AdminController, ClientsController, routing, ValidatesContact trait. Based on official documentation only. Use when user mentions "perfex controller", "AdminController", "ClientsController", "routing perfex". author: Descomplicar® Crescimento Digital version: 1.0.0 quality_score: 70 user_invocable: true desk_task: null --- # /perfex-controllers - Controllers Perfex CRM Controllers para módulos Perfex CRM. **Zero assumptions, zero hallucinations** - apenas documentação oficial. --- ## Documentação Base - [Module Controllers](https://help.perfexcrm.com/module-controllers/) - [CodeIgniter Controllers](https://codeigniter.com/userguide3/general/controllers.html) --- ## 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 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 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 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 ```php // 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 ```php // Gerar URL site/cliente site_url('meu_modulo'); // /meu_modulo site_url('meu_modulo/view/123'); // /meu_modulo/view/123 ``` ### Alertas ```php // 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 ```php // 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 ```php // Redireciona com mensagem de acesso negado access_denied('meu_modulo'); ``` --- ## AJAX Responses ### Retornar JSON ```php 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 ```php 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