- 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>
296 lines
7.2 KiB
Markdown
296 lines
7.2 KiB
Markdown
---
|
|
name: perfex-module-basics
|
|
description: Fundamentos de desenvolvimento de módulos Perfex CRM — estrutura de pastas, ficheiro init, headers e integração CodeIgniter. Baseado apenas na documentação oficial.
|
|
---
|
|
|
|
# /perfex-module-basics - Estrutura Base Módulos Perfex CRM
|
|
|
|
Fundamentos para desenvolvimento de módulos Perfex CRM. **Zero assumptions, zero hallucinations** - apenas documentação oficial.
|
|
|
|
---
|
|
|
|
## Documentação Base
|
|
|
|
- [Module Basics](https://help.perfexcrm.com/module-basics/)
|
|
- [Introduction to Modules](https://help.perfexcrm.com/introduction-to-perfex-crm-modules/)
|
|
- [Module File Headers](https://help.perfexcrm.com/module-file-headers/)
|
|
|
|
---
|
|
|
|
## Estrutura de Pastas (Obrigatória)
|
|
|
|
```
|
|
modules/
|
|
└── meu_modulo/
|
|
├── meu_modulo.php # Init file (OBRIGATÓRIO - mesmo nome da pasta)
|
|
├── controllers/
|
|
│ └── Meu_modulo.php
|
|
├── models/
|
|
│ └── Meu_modulo_model.php
|
|
├── views/
|
|
│ ├── index.php
|
|
│ └── form.php
|
|
├── libraries/
|
|
├── helpers/
|
|
├── language/
|
|
│ └── english/
|
|
│ └── meu_modulo_lang.php
|
|
├── migrations/
|
|
│ └── 001_version_100.php
|
|
├── config/
|
|
└── index.html # SEGURANÇA - prevenir directory listing
|
|
```
|
|
|
|
---
|
|
|
|
## Init File (Obrigatório)
|
|
|
|
O ficheiro init é o ponto de entrada do módulo. **DEVE ter o mesmo nome da pasta.**
|
|
|
|
### Template Mínimo
|
|
|
|
```php
|
|
<?php
|
|
|
|
defined('BASEPATH') or exit('No direct script access allowed');
|
|
|
|
/*
|
|
Module Name: Meu Módulo
|
|
Description: Descrição do módulo
|
|
Version: 1.0.0
|
|
Requires at least: 2.3.*
|
|
Author: Descomplicar
|
|
Author URI: https://descomplicar.pt
|
|
*/
|
|
|
|
// Registar hooks de activação/desactivação
|
|
register_activation_hook('meu_modulo', 'meu_modulo_activation_hook');
|
|
register_deactivation_hook('meu_modulo', 'meu_modulo_deactivation_hook');
|
|
register_uninstall_hook('meu_modulo', 'meu_modulo_uninstall_hook');
|
|
|
|
/**
|
|
* Executado quando o módulo é activado
|
|
*/
|
|
function meu_modulo_activation_hook()
|
|
{
|
|
$CI = &get_instance();
|
|
|
|
// Criar tabelas
|
|
if (!$CI->db->table_exists(db_prefix() . 'meu_modulo')) {
|
|
$CI->db->query('CREATE TABLE `' . db_prefix() . 'meu_modulo` (
|
|
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
|
`name` VARCHAR(255) NOT NULL,
|
|
`created_at` DATETIME NOT NULL,
|
|
PRIMARY KEY (`id`)
|
|
) ENGINE=InnoDB DEFAULT CHARSET=' . $CI->db->char_set . ';');
|
|
}
|
|
|
|
// Adicionar opções
|
|
add_option('meu_modulo_version', '1.0.0');
|
|
}
|
|
|
|
/**
|
|
* Executado quando o módulo é desactivado
|
|
*/
|
|
function meu_modulo_deactivation_hook()
|
|
{
|
|
// Limpeza temporária (não apagar dados)
|
|
}
|
|
|
|
/**
|
|
* Executado quando o módulo é removido
|
|
*/
|
|
function meu_modulo_uninstall_hook()
|
|
{
|
|
$CI = &get_instance();
|
|
|
|
// Remover tabelas
|
|
$CI->db->query('DROP TABLE IF EXISTS `' . db_prefix() . 'meu_modulo`');
|
|
|
|
// Remover opções
|
|
delete_option('meu_modulo_version');
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## File Headers (Meta-Informação)
|
|
|
|
### Headers Obrigatórios
|
|
|
|
| Header | Descrição |
|
|
|--------|-----------|
|
|
| `Module Name` | **ÚNICO OBRIGATÓRIO** - Nome do módulo |
|
|
|
|
### Headers Opcionais (Recomendados)
|
|
|
|
| Header | Descrição | Exemplo |
|
|
|--------|-----------|---------|
|
|
| `Description` | Descrição funcional | `CRM integration module` |
|
|
| `Version` | Versão semântica | `1.0.0` |
|
|
| `Requires at least` | Versão mínima Perfex | `2.3.*` |
|
|
| `Author` | Nome do autor | `Descomplicar` |
|
|
| `Author URI` | Website do autor | `https://descomplicar.pt` |
|
|
| `Module URI` | Página do módulo | `https://...` |
|
|
|
|
### Exemplo Completo
|
|
|
|
```php
|
|
/*
|
|
Module Name: Customer Portal
|
|
Description: Extended customer self-service portal
|
|
Version: 2.1.0
|
|
Requires at least: 2.3.*
|
|
Author: Descomplicar
|
|
Author URI: https://descomplicar.pt
|
|
Module URI: https://descomplicar.pt/modules/customer-portal
|
|
*/
|
|
```
|
|
|
|
---
|
|
|
|
## Aceder ao CodeIgniter
|
|
|
|
Fora de controllers/models, usar `get_instance()`:
|
|
|
|
```php
|
|
$CI = &get_instance();
|
|
|
|
// Carregar helper
|
|
$CI->load->helper('meu_modulo/meu_helper');
|
|
|
|
// Carregar library
|
|
$CI->load->library('meu_modulo/minha_library');
|
|
|
|
// Carregar model
|
|
$CI->load->model('meu_modulo/meu_modulo_model');
|
|
|
|
// Aceder à BD
|
|
$CI->db->get(db_prefix() . 'meu_modulo');
|
|
```
|
|
|
|
---
|
|
|
|
## Funções de Módulo Essenciais
|
|
|
|
### Paths e URLs
|
|
|
|
```php
|
|
// URL do módulo
|
|
$url = module_dir_url('meu_modulo');
|
|
// Resultado: https://crm.exemplo.pt/modules/meu_modulo/
|
|
|
|
// Path absoluto
|
|
$path = module_dir_path('meu_modulo');
|
|
// Resultado: /var/www/html/modules/meu_modulo/
|
|
|
|
// Path das libraries
|
|
$libs_path = module_libs_path('meu_modulo');
|
|
// Resultado: /var/www/html/modules/meu_modulo/libraries/
|
|
```
|
|
|
|
### Opções (Persistência)
|
|
|
|
```php
|
|
// Criar opção (não sobrescreve se existir)
|
|
add_option('meu_modulo_setting', 'valor', 0);
|
|
|
|
// Ler opção
|
|
$valor = get_option('meu_modulo_setting');
|
|
|
|
// Actualizar opção (cria se não existir - v2.3.3+)
|
|
update_option('meu_modulo_setting', 'novo_valor');
|
|
|
|
// Apagar opção
|
|
delete_option('meu_modulo_setting');
|
|
```
|
|
|
|
### Database Prefix
|
|
|
|
**SEMPRE usar `db_prefix()` em queries:**
|
|
|
|
```php
|
|
// CORRECTO
|
|
$CI->db->get(db_prefix() . 'meu_modulo');
|
|
$CI->db->query('SELECT * FROM ' . db_prefix() . 'meu_modulo');
|
|
|
|
// ERRADO - vai falhar se prefix não for "tbl"
|
|
$CI->db->get('tblmeu_modulo');
|
|
```
|
|
|
|
---
|
|
|
|
## Convenções de Nomenclatura
|
|
|
|
### Prefixos (OBRIGATÓRIO)
|
|
|
|
Todas as funções e classes devem ter prefixo único para evitar conflitos:
|
|
|
|
```php
|
|
// CORRECTO
|
|
function meu_modulo_get_data() { }
|
|
class Meu_modulo_helper { }
|
|
|
|
// ERRADO - pode conflitar com outros módulos/core
|
|
function get_data() { }
|
|
class Helper { }
|
|
```
|
|
|
|
### Nomes de Ficheiros
|
|
|
|
| Tipo | Convenção | Exemplo |
|
|
|------|-----------|---------|
|
|
| Controller | Primeira letra maiúscula | `Meu_modulo.php` |
|
|
| Model | Sufixo `_model` | `Meu_modulo_model.php` |
|
|
| Helper | Sufixo `_helper` | `meu_modulo_helper.php` |
|
|
| Language | Sufixo `_lang` | `meu_modulo_lang.php` |
|
|
|
|
---
|
|
|
|
## Modo de Desenvolvimento
|
|
|
|
**SEMPRE activar durante desenvolvimento:**
|
|
|
|
1. Abrir `application/config/config.php`
|
|
2. Definir: `$config['development_mode'] = true;`
|
|
|
|
Isto mostra:
|
|
- Erros PHP
|
|
- Warnings de depreciação
|
|
- Stack traces
|
|
|
|
---
|
|
|
|
## Anti-Patterns (NUNCA FAZER)
|
|
|
|
| Anti-Pattern | Risco | Alternativa |
|
|
|--------------|-------|-------------|
|
|
| Modificar ficheiros core do Perfex | Quebra em updates | Usar hooks |
|
|
| Hardcode database prefix `tbl` | Falha em instalações custom | `db_prefix()` |
|
|
| Funções sem prefixo | Conflitos | Prefixar tudo |
|
|
| Init file com nome diferente da pasta | Módulo não detectado | Nomes iguais |
|
|
| Desenvolver sem development mode | Erros silenciosos | Activar sempre |
|
|
| Não incluir index.html nas pastas | Directory listing | Incluir sempre |
|
|
|
|
---
|
|
|
|
## Checklist Novo Módulo
|
|
|
|
```
|
|
1. [ ] Pasta em /modules/ com nome único
|
|
2. [ ] Init file com mesmo nome da pasta
|
|
3. [ ] Header "Module Name" presente
|
|
4. [ ] defined('BASEPATH') em todos os ficheiros PHP
|
|
5. [ ] index.html em todas as pastas
|
|
6. [ ] Funções com prefixo único
|
|
7. [ ] db_prefix() em todas as queries
|
|
8. [ ] Development mode activado para testes
|
|
9. [ ] Hooks de activation/deactivation/uninstall
|
|
10. [ ] Testado em ambiente staging
|
|
```
|
|
|
|
---
|
|
|
|
**Versão:** 1.0.0 | **Autor:** Descomplicar®
|
|
**Fonte:** help.perfexcrm.com/module-basics
|