Estrutura de um módulo moderno para PrestaShop 8 e 9
Um módulo de 2026 não é um ficheiro PHP gigante. Mostramos-lhe a estrutura que usamos para que seja fácil de manter, passe no validador do Addons e sobreviva às atualizações.
Muitos módulos continuam escritos como no PrestaShop 1.6: um ficheiro principal com milhares de linhas, SQL à mão e formulários de HelperForm. Funcionam, mas custam muito a manter. Esta é a estrutura que seguimos nos nossos módulos para PrestaShop 8 e 9.
A árvore de pastas
mimodulo/
├── mimodulo.php # clase principal: instalación, hooks, poco más
├── composer.json # autoload PSR-4 del espacio de nombres
├── config/
│ ├── services.yml # servicios de Symfony
│ └── routes.yml # rutas del back office
├── src/
│ ├── Controller/Admin/ # controladores Symfony
│ ├── Entity/ o Repository/
│ └── Service/ # lógica de negocio, testeable
├── views/
│ ├── templates/hook/ # plantillas Smarty del front
│ ├── templates/admin/ # plantillas Twig del back office
│ ├── css/ js/ img/
├── upgrade/ # upgrade-1.1.0.php, upgrade-1.2.0.php…
├── translations/
└── logo.png
A classe principal, magra
O ficheiro mimodulo.php deve limitar-se a declarar o módulo, instalá-lo e delegar. A lógica real vai em classes de src/ que podem ser testadas em separado:
public function hookActionValidateOrder(array $params)
{
$this->get('mimodulo.order_notifier')->notify($params['order']);
}
Composer e namespace
{
"name": "rekire/mimodulo",
"autoload": { "psr-4": { "Rekire\\MiModulo\\": "src/" } },
"config": { "prepend-autoloader": false },
"type": "prestashop-module"
}
A opção prepend-autoloader: false evita que o seu autoloader se coloque à frente do do PrestaShop, o que pode provocar conflitos de versões com bibliotecas que o núcleo já traz.
Back office com Symfony
No PrestaShop 8 e 9 os ecrãs de configuração podem ser controladores Symfony com formulários Symfony e templates Twig, declarados em config/routes.yml. Assim integram-se com o menu, as permissões e os tokens CSRF do back office sem os reinventar.
Upgrades desde o primeiro dia
Cada versão que altera a base de dados, regista hooks novos ou cria separadores leva o seu upgrade/upgrade-X.Y.Z.php. E esse script tem de ser idempotente: se for executado duas vezes, não duplica nada. É o que evita separadores duplicados no menu ou colunas que falham ao ser criadas.
Validação antes de publicar
- Cabeçalho de licença em todos os ficheiros.
- Escape de variáveis no Smarty (
|escape:'html':'UTF-8'). - Nada de funções proibidas pelo validador do Addons.
index.phpem cada pasta.- Testes em pelo menos duas versões do PrestaShop e com o modo de depuração ativo: os avisos que em produção não se veem contam no relatório de compatibilidade.
Com esta estrutura, um módulo pode crescer durante anos sem se transformar num ficheiro em que ninguém se atreve a mexer.