Blog
Mise à niveau d'un module PrestaShop vers la version PrestaShop 9 : ce qui n'a pas fonctionné et comment nous y avons remédié
Block Sliding Cart est l'un des modules les plus anciens de notre catalogue. Il a été mis en vente pour la première fois sur PrestaShop Addons en 2013, et pendant des années, il a tout simplement fonctionné. Puis PrestaShop 8 est arrivé, nous n'avons pas su suivre le rythme, et en 2023, l'annonce a été désactivée.
En 2026, nous avons réintroduit cette solution : une base de code unique pour les versions 1.7, 8 et 9 de PrestaShop, le thème Classic et Hummingbird. Voici la liste des problèmes qui sont effectivement apparus au cours du processus et la manière dont chacun d'entre eux a été résolu. Si vous prévoyez de passer à la version 9 de PrestaShop, la plupart de ces points s'appliqueront également à vos propres modules.
En bref : Le côté PHP a nécessité moins de modifications que prévu. La majeure partie du temps a été consacrée au nouveau thème par défaut et à la validation des modules complémentaires, car un simple avertissement sur une version de PrestaShop peut entraîner l'échec de l'ensemble de la validation.
1. PHP : ce qui a été supprimé ou déplacé dans la version PrestaShop 9
Tools::displayPrice() n'est plus là
Le module affichait les prix avec sept décimales, en utilisant Tools::displayPrice(). Cette méthode était obsolète depuis longtemps et a finalement été supprimée dans la version PrestaShop 9 ; par conséquent, chacun de ces appels a généré une erreur fatale.
La valeur de remplacement correspond aux paramètres régionaux actuels, qui connaissent déjà le format de devise de la boutique. Nous avons regroupé ces deux chemins dans une seule fonction d'aide, de sorte que le reste du module n'ait jamais à se soucier de la version de PrestaShop sur laquelle il s'exécute :
public function formatPrice($price)
{
if (method_exists('Tools', 'displayPrice')) {
// PrestaShop 1.7 / 8: keep the old behaviour
return Tools::displayPrice((float) $price);
}
$locale = $this->context->getCurrentLocale();
$isoCode = isset($this->context->currency) ? $this->context->currency->iso_code : '';
return $locale->formatPrice((float) $price, $isoCode);
}
Les modèles utilisent la même fonction d'aide via un petit modificateur Smarty enregistré par le module, donc {$price|scdisplayprice} fonctionne avec toutes les versions.
Les classes de présentateur ont changé d'espace de noms
Le module affiche le panier avec le style propre à PrestaShop CartPresenter, de sorte que les prix, les réductions et les noms de produits sont exactement les mêmes que dans le reste de la boutique. Entre 1.7 et 8, cette classe est passée de Adapter\Cart à Adapter\Presenter\Cart. Au lieu de class_alias Grâce à ces astuces, le module ne résout le nom de la classe qu'une seule fois :
private function getCartPresenterClass()
{
return class_exists('PrestaShop\\PrestaShop\\Adapter\\Presenter\\Cart\\CartPresenter')
? 'PrestaShop\\PrestaShop\\Adapter\\Presenter\\Cart\\CartPresenter'
: 'PrestaShop\\PrestaShop\\Adapter\\Cart\\CartPresenter';
}
Le même modèle s'applique aux présentateurs de produits utilisés pour la vente croisée. Un détail supplémentaire : sur les pages 8 et 9 de PrestaShop present() renvoie un objet tableau « paresseux », et non un tableau classique ; par conséquent, les indications de type du type array il faut autoriser ArrayAccess aussi.
Analyses statiques effectuées sur la version PrestaShop 9
Le validateur d'extensions exécute PHPStan sur le code source de PrestaShop 9. Un appel qui est parfaitement sûr lors de l'exécution, car il se trouve derrière un method_exists() vérification, est toujours signalée comme “ appel à une méthode non définie ”. Nous avons reproduit le validateur en local (PHPStan avec un fichier bootstrap chargeant les sources PrestaShop 8 et 9) afin que chaque correction puisse être vérifiée en quelques minutes, sans avoir à attendre une nouvelle révision.
2. Hummingbird : quatre bugs qui n'apparaissaient que sur le nouveau thème
Hummingbird est le thème par défaut de PrestaShop 9 (source sur GitHub). Aucun des éléments ci-dessous n'est apparu lors de l'analyse statique ni sur la version PrestaShop 8 avec le thème Classic. Les quatre ont été découverts en parcourant une véritable boutique PrestaShop 9.
Les couches en cascade du CSS ont transformé la liste des articles en une grille
Hummingbird met en forme le .products classe sous la forme d'une grille à deux colonnes à l'intérieur @layer ps-components. Notre liste de panier utilisait le même nom de classe pour des raisons de compatibilité, si bien que, dans le panneau latéral, les produits se retrouvaient soudainement disposés sur deux colonnes étroites. Augmenter la spécificité ne résout pas ce problème de superposition de la manière habituelle ; ce qui fonctionne, c’est que le CSS non superposé l’emporte sur le CSS superposé. Une courte règle non superposée dans la feuille de style du module a permis de résoudre le problème :
#sclist .products,
#sclist .product_list_widget {
display: block;
grid-template-columns: none;
}
La fenêtre contextuelle du panier du thème nécessite son propre balisage
Le module ouvrait sa fenêtre contextuelle “ Ajouté au panier ” via prestashop.blockcart.showModal. Hummingbird remplace cette fonction par sa propre version, qui recherche un élément avec data-ps-ref="blockcart-modal" et génère une erreur lorsqu'on lui fournit un code HTML différent. La solution consistait à toujours utiliser le moteur de rendu modal propre au module plutôt que celui du thème.
Une référence à un élément obsolète dans l'animation “ Ajouter au panier ”
L'animation enregistrait l'icône du panier lorsque l'on cliquait sur le bouton, puis récupérait sa position 250 ms plus tard. Sur Hummingbird, l'en-tête du panier est rafraîchi entre-temps, de sorte que l'élément enregistré ne figurait plus sur la page et offset() de retour undefined. Le module recherche désormais l'icône au moment où il en a besoin et ignore l'animation si le thème ne dispose pas d'une icône de panier accessible. Le panneau s'ouvre quant à lui dans tous les cas.
Un bouton fixe qui sort du cadre sur mobile
Sur les téléphones, le bouton « Passer à la caisse » est position: fixed au bas du panneau latéral. Un élément fixe est positionné par rapport à son ancêtre le plus proche à l'aide d'un transform — et le panneau n'en comporte qu'un seul lorsqu'il est ouvert. Lorsque le panneau était fermé, le bouton se fixait à la fenêtre d'affichage et flottait au bas de chaque page. Limiter la portée de la règle à l'état « ouvert » (.sc-widget-panel-open) a trouvé la solution.
3. Validation des extensions : ce que vérifie réellement le contrôle
Pour qu’un module soit à nouveau référencé, il fallait passer par la Validateur PrestaShop puis un contrôle de conformité consistant à installer le module sur plusieurs versions de PrestaShop avec le mode débogage activé. Ce sont ces vérifications qui ont pris le plus de temps.
Chaque variable Smarty doit être échappée
Les anciens modèles reposaient sur l'échappement automatique. Désormais, la révision considère toute sortie non échappée comme un blocage. Nous avons passé en revue les sept modèles du front-office : |escape:'html':'UTF-8' pour le texte, les URL et les attributs, |intval pour les références et les quantités, |escape:'javascript':'UTF-8' à l'intérieur des scripts intégrés.
nofilter est signalé comme un problème de sécurité, même lorsque cela se justifie
Ce module permet au propriétaire de la boutique d'insérer son propre code HTML d'icône (une balise Font Awesome ou un fichier SVG). Ce code génère nofilter, accompagnée d'un commentaire expliquant pourquoi. Le modérateur l'a tout de même signalée. La solution retenue consistait en un modificateur Smarty personnalisé qui assainit le code HTML — en supprimant <script> et <style> blocs, gestionnaires d'événements intégrés et javascript: URL — le modèle n'a donc plus besoin de nofilter pas du tout.
Pas de code HTML dans le PHP
Un petit panneau d'assistance sur la page de configuration avait été créé sous forme de chaîne HTML en PHP. Il a été déplacé vers son propre modèle d'administration. Un piège : sur PrestaShop 8.1, la politique de sécurité Smarty de l'administration bloque un élément brut $this->context->smarty->fetch() d'un fichier situé dans le dossier du module. Utilisez plutôt la ressource du module :
$output .= $this->fetch('module:yourmodule/views/templates/admin/support.tpl');
Un avertissement en mode débogage peut entraîner l'échec de la révision
Il a fallu trois tentatives pour y parvenir. Le rapport de conformité indiquait que la page de configuration était “ inaccessible ” sur les versions PrestaShop 8.1 et 9.0, sans message d'erreur. La cause s'est avérée être une simple notification : Undefined array key "is_default" dans le modèle HelperForm. Language::getLanguages() Si cette clé n'est pas renvoyée, le modèle de formulaire la lit pour chaque langue, et le mode de débogage strict de la révision transforme cette notification en une page d'erreur. Sur une boutique de test normale avec le mode de débogage activé, cela s'affiche uniquement comme un avertissement, ce qui explique pourquoi il était facile de passer à côté.
$languages = Language::getLanguages(false);
$idDefaultLang = (int) Configuration::get('PS_LANG_DEFAULT');
foreach ($languages as $k => $lang) {
$languages[$k]['is_default'] = ((int) $lang['id_lang'] === $idDefaultLang) ? 1 : 0;
}
La leçon à retenir : avant de valider, ouvrez la page de configuration sur les versions PrestaShop 8 et 9 en mode débogage et considérez chaque avertissement comme une erreur.
Normes de codage, avec un conflit
Le validateur applique les règles de PHP-CS-Fixer. Deux détails nous ont chacun coûté une nouvelle soumission : dans un fichier sans espace de noms, écrivez catch (Throwable $e), et non \Throwable; et conservez le bloc de documentation relatif à la licence juste après <?php, sans ligne vide. Une configuration générique de PHP-CS-Fixer tentera d'insérer cette ligne vide ; il faut donc appliquer les règles du validateur, et non un préréglage générique.
Liste de contrôle à effectuer sur vos propres modules avant la mise à niveau vers la version PrestaShop 9
- Essayez notre application gratuite Outil de vérification de la compatibilité PrestaShop 9 dans le module. Il répertorie les classes, méthodes et hooks supprimées, qui feront l'objet des points suivants, en indiquant le fichier et la ligne correspondants.
- Rechercher dans le code les éléments suivants :
Tools::displayPriceet d'autres méthodes supprimées dans la version 9.0 (la Documentation pour les développeurs PrestaShop 9 (énumère les modifications). - Recherchez les classes référencées par leurs anciens espaces de noms, en particulier les présentateurs et les adaptateurs.
- Installez le module sur une version PrestaShop 9 avec le mode débogage activé, puis ouvrez sa page de configuration. Lisez toutes les remarques.
- Testez le front office sur le Hummingbird, et pas seulement en mode « Classic » : fenêtres contextuelles, panier dans l'en-tête, listes de produits et mise en page mobile.
- Vérifiez que les modèles ne contiennent pas de variables non échappées et
nofilter. - Vérifiez la plage de compatibilité indiquée pour le module. Elle doit correspondre aux versions que vous avez effectivement testées.
Où en est le module actuellement ?
Block Sliding Cart fonctionne sur les versions PrestaShop 1.7, 8 et 9, a passé avec succès la validation des extensions et figure à nouveau dans la liste, avec son historique et ses 36 avis (4,7★) intacts. Vous pouvez regarde ce que ça fait ici, et les raisons qui justifient l'utilisation d'un panier AJAX sont abordées dans Panier AJAX ou actualisation de la page ? et UX du panier mobile pour PrestaShop.
Si un module de votre boutique a cessé de fonctionner après une mise à jour, ou si vous souhaitez savoir quels modules risquent de ne plus fonctionner avant de procéder à la mise à jour, c'est exactement ce à quoi nous nous consacrons. Dites-nous ce qui ne va pas et nous vous répondrons en vous posant des questions ou en vous proposant un devis.
Foire aux questions
Est-ce que Tools::displayPrice() Supprimé dans la version PrestaShop 9 ?
Oui. Utilisez plutôt les paramètres régionaux actuels : $this->context->getCurrentLocale()->formatPrice($price, $currencyIsoCode). Si votre module doit également prendre en charge la version 1.7 de PrestaShop, regroupez ces deux chemins dans une seule méthode d'aide.
Les modules PrestaShop 1.7 fonctionnent-ils sur le PrestaShop 9 ?
Certains fonctionnent sans modification. Les modules qui utilisent des méthodes du noyau supprimées, d'anciens espaces de noms de classes ou du code JavaScript spécifique à un thème doivent être mis à jour. L'installation du module sur une copie de PrestaShop 9 avec le mode débogage activé permet de mettre en évidence la plupart des problèmes en quelques minutes.
Pourquoi mon module semble-t-il ne pas fonctionner correctement sur Hummingbird, mais fonctionne-t-il normalement sur Classic ?
Hummingbird utilise un balisage différent, des couches CSS en cascade et son propre code JavaScript pour le panier. Les modules qui réutilisent les noms de classes de Classic ou qui appellent les fonctions du panier du thème sont les plus touchés.
Pourquoi la page de configuration échoue-t-elle au contrôle de conformité des extensions ?
Ce test consiste à installer le module sur plusieurs versions de PrestaShop en mode débogage strict, où des avertissements tels que “ clé de tableau non définie ” provoquent une erreur sur la page. Ouvrez vous-même la page de configuration sur les versions 8 et 9 de PrestaShop avec le mode débogage activé et corrigez chaque avertissement avant de valider.
