Sin impuesto Con impuesto

Structure d'un module moderne pour PrestaShop 8 et 9

Un module de 2026 n'est pas un fichier PHP géant. Nous vous montrons la structure que nous utilisons pour qu'il soit maintenable, passe le validateur d'Addons et survive aux mises à jour.

Jesús Meilán
Updated: 26/09/2026 110
Structure d'un module moderne pour PrestaShop 8 et 9
Share:

Beaucoup de modules sont encore écrits comme sous PrestaShop 1.6 : un fichier principal de milliers de lignes, du SQL écrit à la main et des formulaires HelperForm. Ils fonctionnent, mais ils coûtent cher à maintenir. Voici la structure que nous suivons dans nos modules pour PrestaShop 8 et 9.

L'arborescence des dossiers

mimodulo/
├── mimodulo.php          # classe principale : installation, hooks, guère plus
├── composer.json         # autoload PSR-4 de l'espace de noms
├── config/
│   ├── services.yml      # services Symfony
│   └── routes.yml        # routes du back-office
├── src/
│   ├── Controller/Admin/ # contrôleurs Symfony
│   ├── Entity/ ou Repository/
│   └── Service/          # logique métier, testable
├── views/
│   ├── templates/hook/   # templates Smarty du front
│   ├── templates/admin/  # templates Twig du back-office
│   ├── css/ js/ img/
├── upgrade/              # upgrade-1.1.0.php, upgrade-1.2.0.php…
├── translations/
└── logo.png

Une classe principale légère

Le fichier mimodulo.php devrait se limiter à déclarer le module, l'installer et déléguer. La vraie logique va dans des classes de src/ que l'on peut tester séparément :

public function hookActionValidateOrder(array $params)
{
    $this->get('mimodulo.order_notifier')->notify($params['order']);
}

Composer et espace de noms

{
  "name": "rekire/mimodulo",
  "autoload": { "psr-4": { "Rekire\\MiModulo\\": "src/" } },
  "config": { "prepend-autoloader": false },
  "type": "prestashop-module"
}

L'option prepend-autoloader: false empêche votre autoloader de passer devant celui de PrestaShop, ce qui peut provoquer des conflits de versions avec des bibliothèques que le cœur embarque déjà.

Attention aux bibliothèques partagées : si deux modules incluent chacun leur copie d'un SDK (celui de Stripe est le cas classique) et que les deux sont chargés dans la même requête, PHP échoue avec « Cannot declare class ». Chargez les dépendances uniquement si la classe n'existe pas déjà, ou isolez-la avec un préfixe d'espace de noms.

Back-office avec Symfony

Dans PrestaShop 8 et 9, les écrans de configuration peuvent être des contrôleurs Symfony avec des formulaires Symfony et des templates Twig, déclarés dans config/routes.yml. Ils s'intègrent ainsi au menu, aux permissions et aux jetons CSRF du back-office sans avoir à les réinventer.

Des upgrades dès le premier jour

Chaque version qui modifie la base de données, enregistre de nouveaux hooks ou crée des onglets a son upgrade/upgrade-X.Y.Z.php. Et ce script doit être idempotent : s'il s'exécute deux fois, il ne duplique rien. C'est ce qui évite les onglets en double dans le menu ou les colonnes dont la création échoue.

Validation avant publication

  • En-tête de licence dans tous les fichiers.
  • Échappement des variables dans Smarty (|escape:'html':'UTF-8').
  • Aucune fonction interdite par le validateur d'Addons.
  • index.php dans chaque dossier.
  • Tests sur au moins deux versions de PrestaShop et avec le mode debug activé : les avertissements invisibles en production comptent bel et bien dans le rapport de compatibilité.

Avec cette structure, un module peut évoluer pendant des années sans devenir un fichier que personne n'ose toucher.

Chargement...
Consentement aux cookies
Retour en haut