Blog
Modernizácia modulu PrestaShop na verziu PrestaShop 9: Čo sa pokazilo a ako sme to opravili
Block Sliding Cart je jeden z najstarších modulov v našom katalógu. V roku 2013 bol po prvýkrát zaradený do ponuky na PrestaShop Addons a celé roky bez problémov fungoval. Potom prišiel PrestaShop 8, my sme s tým nestíhali držať krok a v roku 2023 bola ponuka deaktivovaná.
V roku 2026 sme to obnovili: jeden zdrojový kód pre verzie PrestaShop 1.7, 8 a 9, tému Classic a Hummingbird. Tu je zoznam toho, čo sa počas toho procesu skutočne pokazilo a ako bol každý problém vyriešený. Ak plánujete aktualizáciu na verziu PrestaShop 9, väčšina z nich sa bude týkať aj vašich vlastných modulov.
Stručná verzia: Na strane PHP bolo potrebných menej zmien, než sa očakávalo. Väčšinu času sme venovali novej predvolenej šablóne a úspešnému absolvovaniu validácie doplnkov, kde varovanie v jednej verzii PrestaShop môže spôsobiť neúspech celého posudzovania.
1. PHP: čo bolo v verzii PrestaShop 9 odstránené alebo presunuté
Tools::displayPrice() je preč
Modul formátoval ceny na sedem desatinných miest s Tools::displayPrice(). Táto metóda bola už dlho označená za zastaranú a vo verzii PrestaShop 9 bola nakoniec odstránená, takže každé takéto volanie sa stalo fatálnou chybou.
Náhradou je aktuálne národné prostredie, ktoré už pozná formát meny daného obchodu. Obe cesty sme zahrnuli do jedného pomocného modulu, takže zvyšok modulu sa už nemusí starať o to, na akej verzii PrestaShop beží:
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);
}
Šablóny využívajú ten istý pomocný prvok prostredníctvom malého modifikátora Smarty, ktorý modul zaregistroval, takže {$price|scdisplayprice} funguje vo všetkých verziách.
Triedy prezentátora majú zmenený menný priestor
Modul zobrazuje nákupný košík pomocou vlastného riešenia PrestaShop CartPresenter, takže ceny, zľavy a názvy produktov vyzerajú presne tak ako v ostatných častiach obchodu. Medzi 1.7 a 8 sa táto trieda presunula z Adapter\Cart do Adapter\Presenter\Cart. Namiesto toho, aby class_alias triky, modul vyhodnotí názov triedy len raz:
private function getCartPresenterClass()
{
return class_exists('PrestaShop\\PrestaShop\\Adapter\\Presenter\\Cart\\CartPresenter')
? 'PrestaShop\\PrestaShop\\Adapter\\Presenter\\Cart\\CartPresenter'
: 'PrestaShop\\PrestaShop\\Adapter\\Cart\\CartPresenter';
}
Ten istý vzor sa vzťahuje aj na prezentácie produktov používané na krížový predaj. Ešte jeden detail: na PrestaShop 8 a 9 present() vráti objekt typu „lazy array“, nie obyčajný poľa, takže typové špecifikácie, ktoré uvádzajú array je potrebné povoliť ArrayAccess tiež.
Statická analýza sa vykonáva na verzii PrestaShop 9
Validátor doplnkov spúšťa PHPStan na zdrojovom kóde PrestaShop 9. Volanie, ktoré je počas behu programu úplne bezpečné, pretože sa nachádza za method_exists() kontrola stále vykazuje chybu “volanie nedefinovanej metódy”. Validátor sme reprodukovali lokálne (PHPStan s bootstrapom, ktorý načíta zdrojové kódy PrestaShop 8 a 9), aby bolo možné každú opravu skontrolovať v priebehu niekoľkých minút namiesto čakania na ďalšiu revíziu.
2. Hummingbird: štyri chyby, ktoré sa objavili iba v novej téme
Hummingbird je predvolená šablóna pre PrestaShop 9 (zdroj na GitHub-e). Žiadna z nižšie uvedených položiek sa neobjavila v statickej analýze ani na stránke PrestaShop 8 s motívom Classic. Všetky štyri boli nájdené pri prehliadaní skutočného obchodu PrestaShop 9.
Kaskádové vrstvy CSS premenili zoznam košíkov na mriežku
Hummingbird upravuje štýl .products trieda ako dvojstĺpcová mriežka vnútri @layer ps-components. Náš zoznam v košíku používal z dôvodu kompatibility rovnaký názov triedy, takže v bočnom paneli sa produkty zrazu zobrazovali v dvoch úzkych stĺpcoch. Zvýšenie špecificity v tomto prípade nepomáha tak, ako je to bežné; pomôže však to, že CSS bez vrstiev má prednosť pred CSS s vrstvami. Problém sa podarilo vyriešiť krátkym pravidlom bez vrstiev v štýlovom hárku modulu:
#sclist .products,
#sclist .product_list_widget {
display: block;
grid-template-columns: none;
}
Modálne okno košíka v tejto šablóne vyžaduje vlastnú štruktúru kódu
Modul otváral svoje vyskakovacie okienko “pridané do košíka” prostredníctvom prestashop.blockcart.showModal. Hummingbird nahrádza túto funkciu svojou vlastnou verziou, ktorá vyhľadáva prvok s data-ps-ref="blockcart-modal" a v prípade, že sa mu zadá iný HTML kód, vyhodí chybu. Riešením bolo vždy používať vlastný modulový renderer namiesto renderera šablóny.
Neplatný odkaz na prvok v animácii “pridať do košíka”
Animácia uložila ikonu košíka po kliknutí na tlačidlo a o 250 ms neskôr načítala jej polohu. V prehliadači Hummingbird sa medzitým znovu vykreslí hlavička s košíkom, takže uložený prvok už na stránke nebol a offset() vrátil sa undefined. Modul teraz znovu vyhľadá ikonu v okamihu, keď ju potrebuje, a animáciu preskočí, ak téma neobsahuje žiadnu dostupnú ikonu košíka. Samotný panel sa v oboch prípadoch otvorí.
Tlačidlo s pevnou veľkosťou, ktoré presahuje rámec panelu na mobilných zariadeniach
Na mobilných telefónoch je tlačidlo na dokončenie nákupu position: fixed v spodnej časti bočného panela. Pevný prvok je umiestnený vzhľadom na najbližšieho nadradeného prvka pomocou transform — a panel má iba jedno, keď je otvorený. Keď bol panel zatvorený, tlačidlo sa pripojilo k zobrazeniu a plávalo v spodnej časti každej stránky. Obmedzenie pôsobnosti pravidla na otvorený stav (.sc-widget-panel-open) to vyriešil.
3. Overovanie doplnkov: čo sa pri kontrole skutočne overuje
Aby sa modul opäť zaradil do zoznamu, bolo potrebné prejsť procesom Validátor PrestaShop a následne kontrola súladu, pri ktorej sa modul nainštaloval na viaceré verzie PrestaShop so zapnutým režimom ladenia. Práve tieto zistenia zabrali najviac času.
Každá premenná v jazyku Smarty musí byť escapovaná
Staršie šablóny využívali automatické únikové znaky. V rámci kontroly sa teraz akýkoľvek výstup bez únikových znakov považuje za chybu brániacu spusteniu. Prešli sme všetkých sedem šablón front-office: |escape:'html':'UTF-8' pre text, URL adresy a atribúty, |intval pre identifikačné čísla a množstvá, |escape:'javascript':'UTF-8' vo vnútorných skriptoch vložených priamo do kódu.
nofilter je nahlásené ako bezpečnostný problém, aj keď je to oprávnené
Tento modul umožňuje majiteľovi obchodu vložiť vlastný HTML kód ikony (značku Font Awesome alebo súbor SVG). Tento výstup sa používa nofilter, spolu s komentárom vysvetľujúcim dôvod. Recenzent to napriek tomu označil. Akceptovaným riešením bol vlastný modifikátor Smarty, ktorý čistí HTML kód – odstraňuje <script> a <style> bloky, vstavané obslužné rutiny udalostí a javascript: URL adresy — takže šablóna už nepotrebuje nofilter vôbec.
V kóde PHP nesmie byť žiadny HTML kód
Malý panel podpory na konfiguračnej stránke bol vytvorený ako reťazec HTML v jazyku PHP. Bol presunutý do vlastnej šablóny pre správu. Jedna úskalia: vo verzii PrestaShop 8.1 bezpečnostná politika Smarty pre správu blokuje surový $this->context->smarty->fetch() súboru v priečinku modulu. Namiesto toho použite zdroj modulu:
$output .= $this->fetch('module:yourmodule/views/templates/admin/support.tpl');
Upozornenie v režime ladenia môže spôsobiť zamietnutie kontroly
Toto mi trvalo tri pokusy. Správa o súlade uvádzala, že na verziách PrestaShop 8.1 a 9.0 “nebolo možné otvoriť” konfiguračnú stránku, pričom sa nezobrazila žiadna chybová správa. Príčinou sa nakoniec ukázalo byť jedno upozornenie: Undefined array key "is_default" v šablóne HelperForm. Language::getLanguages() ak tento kľúč nevráti, šablóna formulára ho načíta pre každý jazyk a prísny režim ladenia v recenzii premení toto upozornenie na stránku s chybou. V bežnom testovacom obchode s režimom ladenia sa to zobrazuje len ako varovanie, a preto bolo ľahké to prehliadnuť.
$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;
}
Poučenie: pred odoslaním otvorte konfiguračnú stránku na PrestaShop 8 a 9 so zapnutým režimom ladenia a každé upozornenie považujte za chybu.
Štandardy kódovania, s jedným rozporom
Validátor uplatňuje pravidlá PHP-CS-Fixer. Dva detaily nás stali po jednom opätovnom odoslaní: v súbore bez menného priestoru napíšte catch (Throwable $e), nie \Throwable; a umiestnite dokumentačný blok licencie priamo za <?php, bez prázdneho riadku. Štandardná konfigurácia nástroja PHP-CS-Fixer sa bude snažiť tento prázdny riadok vložiť, preto použite pravidlá validátora, nie štandardné prednastavenie.
Kontrolný zoznam pre vaše vlastné moduly pred aktualizáciou na verziu PrestaShop 9
- Vyskúšajte našu bezplatnú Nástroj na kontrolu kompatibility PrestaShop 9 v module. Obsahuje zoznam odstránených tried, metód a hooks, ktorým sa venujú nasledujúce body, spolu s uvedením súboru a riadku.
- Vyhľadaj v kóde
Tools::displayPricea ďalšie metódy, ktoré boli v verzii 9.0 odstránené (t. j. Dokumentácia pre vývojárov PrestaShop 9 uvádza zoznam zmien). - Hľadajte triedy, na ktoré sa odkazuje prostredníctvom ich starých menných priestorov, najmä prezentéry a adaptéry.
- Nainštalujte modul na zariadenie PrestaShop 9 s zapnutým režimom ladenia a otvorte jeho konfiguračnú stránku. Prečítajte si všetky upozornenia.
- Otestujte front office na Hummingbird, a to nielen v režime Classic: vyskakovacie okná, košík v hlavičke, zoznamy produktov a mobilné rozloženie.
- Skontrolujte šablóny, či neobsahujú premenné bez únikových znakov, a
nofilter. - Skontrolujte deklarovaný rozsah kompatibility modulu. Mal by zodpovedať verziám, ktoré ste skutočne otestovali.
Kde sa modul momentálne nachádza
Block Sliding Cart beží na verziách PrestaShop 1.7, 8 a 9, prešlo validáciou doplnkov a je opäť zaradené do zoznamu, pričom jeho história a 36 recenzií (4,7★) zostali zachované. Môžete pozri si, ako to tu funguje, a dôvody pre použitie nákupného košíka s technológiou AJAX sú vysvetlené v Nákupný košík s AJAXom vs. obnovenie stránky a UX mobilného košíka v PrestaShope.
Ak vám po aktualizácii prestal fungovať nejaký modul vo vašom obchode alebo ak chcete vedieť, čo prestane fungovať ešte pred aktualizáciou, práve tým sa zaoberáme. Povedzte nám, čo sa deje a my vám odpovieme s otázkami alebo cenovou ponukou.
Najčastejšie kladené otázky
Je Tools::displayPrice() bolo to odstránené v PrestaShop 9?
Áno. Namiesto toho použite aktuálne národné nastavenie: $this->context->getCurrentLocale()->formatPrice($price, $currencyIsoCode). Ak má váš modul podporovať aj PrestaShop 1.7, zahrňte obe cesty do jednej pomocnej metódy.
Fungujú moduly PrestaShop 1.7 na zariadení PrestaShop 9?
Niektoré fungujú bez zmien. Moduly, ktoré využívajú odstránené metódy jadra, staré menné priestory tried alebo JavaScript špecifický pre danú šablónu, si vyžadujú aktualizáciu. Inštalácia modulu na verziu PrestaShop 9 s zapnutým režimom ladenia odhalí väčšinu problémov už za pár minút.
Prečo sa môj modul na Hummingbird zobrazuje nesprávne, ale na Classic nie?
Hummingbird používa odlišné značkovanie, kaskádové vrstvy CSS a vlastný JavaScript pre nákupný košík. Najviac sú týmto ovplyvnené moduly, ktoré opätovne používajú názvy tried z verzie Classic alebo volajú funkcie nákupného košíka danej šablóny.
Prečo kontrola súladu doplnkov neprešla na stránke konfigurácie?
V rámci tohto testu sa modul inštaluje na viacerých verziách PrestaShop s prísnym režimom ladenia, kde upozornenia typu “undefined array key” spôsobujú zlyhanie stránky. Otvorte si sami konfiguračnú stránku v PrestaShop 8 a 9 so zapnutým režimom ladenia a pred odoslaním odstráňte všetky upozornenia.
