Les défis du développement de modules PrestaShop
Cet article couvre la compatibilité réelle de nos modules, de PrestaShop 1.6 à 9.0, PHP 7.1+, y compris les API supprimées par PrestaShop 9 (noyau Symfony 6.4) dont un même module doit désormais compenser la disparition.
public function install()
{
return parent::install()
&& $this->registerHook('displayHeader')
&& $this->registerHook('actionFrontControllerSetMedia')
&& $this->registerHook('actionOutputHTMLBefore');
}
Développer des modules pour PrestaShop ne consiste pas simplement à écrire du code : il faut assurer un fonctionnement fluide entre différentes versions, configurations et environnements. Au fil des années, nous avons rencontré d’innombrables défis qui ont exigé une planification rigoureuse, des tests approfondis et une vraie résolution de problèmes. Voici les principaux obstacles auxquels nous sommes confrontés, ainsi que la façon dont nous les traitons.
Différentes versions de PrestaShop, Suivre le rythme d’un écosystème en constante évolution

Un module fiable se teste comme un produit installable, pas seulement comme du code source.
PrestaShop évolue en permanence et, à chaque version, des fonctions peuvent être ajoutées, modifiées ou supprimées. Certaines fonctionnalités essentielles dans les anciennes versions peuvent devenir obsolètes dans les plus récentes, tandis que des fonctionnalités auparavant supprimées peuvent parfois revenir. Un module doit être prêt à gérer toutes ces variations.
Pour garantir la compatibilité, nos modules mettent en place des contrôles de version appropriés et adaptent dynamiquement leur comportement selon la version de PrestaShop installée. Cela évite les problèmes de compatibilité et assure un fonctionnement fluide sur plusieurs versions.
Concrètement, des « contrôles de version appropriés » signifient utiliser version_compare() avec la version de PrestaShop en cours d’exécution, et non deviner à partir de l’existence d’une classe. Voici la structure exacte que nous utilisons pour séparer le comportement entre la branche historique et la branche 1.7+ :
if (version_compare(_PS_VERSION_, '1.7.0.0', '<')) {
// 1.6 path: legacy asset API, $smarty->assign + addCSS/addJS
$this->context->controller->addCSS($this->_path . 'views/css/front.css');
} else {
// 1.7+ path: registerStylesheet via the SetMedia hook
$this->context->controller->registerStylesheet(
'mymodule-front',
'modules/' . $this->name . '/views/css/front.css',
['media' => 'all', 'priority' => 150]
);
}
La raison pour laquelle nous testons la chaîne de version plutôt que method_exists(), c’est que le comportement, et pas seulement la disponibilité, change d’une version à l’autre. Une méthode peut exister dans deux versions et faire des choses subtilement différentes. _PS_VERSION_ est la source de vérité utilisée par PrestaShop lui-même.
Compatibilité avec les versions de PHP, Trouver l’équilibre entre l’ancien et le nouveau
Comme PrestaShop, les versions de PHP évoluent elles aussi, avec de nouvelles fonctionnalités, de meilleures performances et des mises à jour de sécurité. Cependant, de nombreux marchands utilisent encore d’anciennes versions de PHP en raison des limites de leur hébergement ou de la crainte de casser leur boutique. Les modules doivent donc rester compatibles avec un large éventail de versions de PHP.
Nous développons en gardant les anciennes versions de PHP à l’esprit afin d’assurer une large compatibilité, tout en veillant à ce que notre code fonctionne efficacement sur les dernières versions de PHP. Cette approche permet aux marchands de continuer à utiliser nos modules même s’ils ne peuvent pas mettre à niveau leur environnement d’hébergement immédiatement. Notre plancher est PHP 7.1 : nous évitons donc la syntaxe (propriétés typées, arguments nommés, énumérations, match) qui provoquerait une erreur fatale en 7.1, même si elle se lit plus proprement en 8.x.
API supprimées, Quand le même code doit fonctionner sur 1.6 et 9
Le problème de version le plus difficile n’est pas l’ajout d’une fonctionnalité : c’est la suppression d’une fonctionnalité existante. PrestaShop 9 fonctionne avec Symfony 6.4 et a supprimé des API sur lesquelles le code de l’époque 1.6 s’appuyait. Deux cas reviennent constamment chez nous : Tools::displayPrice() (supprimé en 9.0 ; les prix se formatent désormais via l’objet Locale) et AdminController::ajaxDie(). Appelez l’une ou l’autre directement et votre module provoque une erreur fatale sur 9 tout en fonctionnant parfaitement sur 1.6, le pire type de bogue, parce qu’il n’apparaît que sur les boutiques les plus récentes.
Ce problème ne se règle pas avec un drapeau dispersé au point d’appel dans trente fichiers. Nous faisons passer chaque appel supprimé ou déprécié par un seul adaptateur de compatibilité, qui détecte la version en cours d’exécution et délègue à la bonne API. Pour le formatage des prix, cet adaptateur est MyPrestaRocks\Compat\PriceFormatter :
namespace MyPrestaRocks\Compat;
class PriceFormatter
{
public static function format(float $price, $currency = null): string
{
// PS 9 removed Tools::displayPrice() – go through the Locale object.
if (version_compare(_PS_VERSION_, '9.0.0', '>=')) {
$context = \Context::getContext();
$iso = $currency ? $currency->iso_code : $context->currency->iso_code;
return $context->getCurrentLocale()->formatPrice($price, $iso);
}
// 1.6 / 1.7 / 8.x still have the old helper.
return \Tools::displayPrice($price, $currency);
}
}
Ensuite, le reste du module appelle PriceFormatter::format($price, $currency) partout et ne touche jamais à l’API brute. Quand PrestaShop supprimera le prochain helper, il y aura un seul fichier à mettre à jour, au lieu d’un « grep et on espère » sur toute la base de code. C’est aussi pour cette raison que nous gardons cet adaptateur dans un package partagé plutôt que de le copier-coller module par module : on corrige la détection de version une seule fois, et tous les modules en héritent.
Environnements serveur variés. Chaque configuration est unique
Aucune boutique PrestaShop ne fonctionne dans un environnement strictement identique à une autre. Les différences de systèmes d’exploitation, de types de serveurs (Apache, Nginx, LiteSpeed), de configurations PHP et même de versions précises d’Apache ou de Nginx peuvent influencer le comportement d’un module.
Pour anticiper ces problèmes potentiels, nous testons nos modules dans plusieurs environnements. En tenant compte de différentes configurations d’hébergement, des extensions PHP activées et de diverses configurations de serveurs web, nous nous assurons que nos modules restent stables quelle que soit l’infrastructure sous-jacente.
Adaptation aux configurations de boutique, Gérer correctement chaque réglage
Chaque boutique PrestaShop possède sa propre configuration. Certaines activent les groupes de clients, le multiboutique ou des règles de prix spécifiques, tandis que d’autres utilisent des configurations plus simples. Un module doit détecter ces réglages et s’y adapter pour fonctionner correctement.
Nos modules vérifient dynamiquement les configurations de boutique afin de se comporter correctement quels que soient les réglages du marchand. Qu’il s’agisse de détecter si les groupes de clients sont activés ou d’identifier les configurations multiboutiques, nous veillons à ce que les modules s’intègrent proprement à la configuration propre à chaque boutique.
Compatibilité avec les autres modules, Éviter les conflits
Une boutique PrestaShop fonctionne rarement avec les seules fonctionnalités natives : les marchands installent plusieurs modules pour enrichir leur boutique. Malheureusement, certains modules peuvent remplacer des fonctionnalités clés ou interférer avec d’autres, ce qui crée des conflits. Pour obtenir des conseils sur la construction d’une base stable, consultez notre guide sur les bases du SEO PrestaShop.
Pour prévenir ce type de problème, nous concevons nos modules pour fonctionner dans des zones isolées, en réduisant au minimum le risque de conflit. Notre approche garantit que, même si un module est désinstallé, la boutique continue de fonctionner comme s’il n’avait jamais été installé.
Lacunes de connaissance des marchands, Combler l’écart de compréhension
Tous les marchands ne connaissent pas en profondeur le fonctionnement interne de PrestaShop. Certains utilisateurs s’attendent à ce qu’un module fonctionne parfaitement sans aucune configuration, ce qui peut créer de la confusion lorsque des réglages avancés entrent en jeu.
Pour y remédier, nous misons sur une documentation claire, des interfaces conviviales et des infobulles utiles dans les réglages des modules. Notre objectif est de rendre chaque module aussi intuitif que possible tout en proposant des options de personnalisation avancées aux utilisateurs expérimentés.
Fichiers du cœur modifiés, Le cauchemar d’un développeur
Certains propriétaires de boutiques ou développeurs précédents modifient directement les fichiers du cœur de PrestaShop au lieu d’utiliser des surcharges ou des hooks. Cela peut casser le fonctionnement attendu et rendre difficile, pour un module, le fait de s’appuyer sur le comportement standard de PrestaShop.
Nous concevons nos modules pour gérer ce type de cas limite avec élégance, en mettant en place des mécanismes de repli chaque fois que c’est possible afin de maintenir des performances stables, même dans des environnements modifiés.
Malgré ces défis, nous livrons des modules fiables
Même face à tous ces défis, nous restons confiants dans notre capacité à livrer des modules fiables et de haute qualité. Grâce à des tests rigoureux, à des contrôles de version et aux bonnes pratiques de développement, nous veillons à ce que nos modules fonctionnent avec différentes versions de PrestaShop, différents environnements PHP et diverses configurations de boutique. Découvrez notre module Performance Revolution pour une optimisation avancée.
En comprenant ces défis et en les traitant de façon proactive, nous fournissons aux propriétaires de boutiques des modules qui améliorent leur activité sans ajouter de complexité ni de risque.
FAQ
Comment prenez-vous en charge PrestaShop 1.6 et 9 depuis une seule base de code ?
Nous créons des branches avec version_compare(_PS_VERSION_, …) pour les comportements qui diffèrent réellement, et nous faisons passer chaque appel d’API supprimé ou déprécié par un adaptateur de compatibilité afin que la logique de version reste au même endroit. Le reste du module demeure indépendant de la version. La discipline qui rend cela durable consiste aussi à rester honnête sur le plancher de syntaxe : si vous ciblez PHP 7.1, vous n’écrivez pas de syntaxe PHP 8 qui y provoquera silencieusement une erreur fatale.
Pourquoi ne pas simplement utiliser method_exists() pour détecter ce qui est disponible ?
method_exists() indique qu’une méthode est présente, pas qu’elle se comporte de la même manière. PrestaShop a modifié le comportement de méthodes existantes entre certaines versions ; la présence ne suffit donc pas. La chaîne de version est ce que le cœur de PrestaShop utilise lui-même pour ses embranchements, nous nous appuyons donc sur la même chose.
Qu’est-ce qui casse réellement un module de l’époque 1.6 sur PrestaShop 9 ?
Le plus souvent, c’est un helper supprimé plutôt que le framework lui-même. Les deux que nous rencontrons le plus sont Tools::displayPrice() et AdminController::ajaxDie(), tous deux supprimés en 9.0. Le code qui les appelle fonctionne très bien partout jusqu’à 8.x et ne provoque une erreur fatale que sur 9, ce qui explique pourquoi il passe entre les mailles des tests lorsqu’ils n’incluent pas une véritable installation en 9. Un adaptateur de compatibilité autour de chaque appel supprimé corrige le problème sans forker le module.
Dois-je utiliser des surcharges ou des hooks pour les travaux sensibles à la compatibilité ?
Des hooks, presque toujours. Les surcharges remplacent un fichier de classe du cœur et cassent dès que deux modules veulent remplacer le même, en plus d’être liées à des mécanismes internes qui changent d’une version à l’autre. Les hooks font partie de l’API de module publiée et résistent bien mieux aux mises à niveau. Nous réservons les surcharges aux rares cas où il n’existe réellement aucun hook dans le chemin de code, et nous les documentons très clairement lorsque nous y recourons. Notre guide pratique des hooks explique où chacun trouve sa place.
Comment testez-vous autant de versions sans que cela prenne une éternité ?
Nous installons le module comme un vrai ZIP dans une boutique propre de chaque version cible, au lieu de nous contenter de vérifier le code source avec un linter. Un module qui réussit l’analyse statique peut tout de même échouer à l’installation sur une version où le nom d’un hook a changé ou où une API supprimée est appelée. Nous considérons que la véritable condition de réussite est : « s’installe et fonctionne sur une installation fraîche en 1.6, 8.x et 9 », parce que c’est exactement ce que le marchand vit.
Si vous voulez le complément pratique à cet article, du vrai code de hooks que nous livrons, avec les pièges dans lesquels nous sommes tombés, consultez PrestaShop Hooks in Practice. Et si vous vous demandez s’il vaut encore la peine de maintenir une ancienne boutique, notre analyse sur la pertinence de conserver PrestaShop 1.6 couvre l’aspect business.