Blog
Modernizace modulu PrestaShop na verzi PrestaShop 9: Co se pokazilo a jak jsme to opravili
Block Sliding Cart je jedním z nejstarších modulů v našem katalogu. Poprvé byl uveden na PrestaShop Addons v roce 2013 a po celá léta prostě fungoval. Poté přišel PrestaShop 8, my jsme s ním nestačili držet krok a v roce 2023 byl záznam deaktivován.
V roce 2026 jsme se k tomu vrátili: jedna kódová základna pro PrestaShop 1.7, 8 a 9, téma Classic a Hummingbird. Zde je seznam toho, co se při tom skutečně pokazilo, a jak byl každý problém opraven. Pokud plánujete upgrade na verzi PrestaShop 9, většina z těchto problémů se bude týkat i vašich vlastních modulů.
Zkrácená verze: Na straně PHP bylo zapotřebí méně změn, než se očekávalo. Většinu času zabralo vytvoření nového výchozího motivu a splnění požadavků validace doplňků, kde i jedno varování u jedné verze PrestaShop může způsobit neúspěch celého posouzení.
1. PHP: co bylo v verzi PrestaShop 9 odstraněno nebo přesunuto
Tools::displayPrice() je pryč
Modul formátoval ceny na sedm míst s Tools::displayPrice(). Tato metoda byla již dlouho označena za zastaralou a ve verzi PrestaShop 9 byla nakonec odstraněna, takže každé z těchto volání se stalo fatální chybou.
Náhradou je aktuální locale, které již zná formát měny daného obchodu. Obě cesty jsme sjednotili do jedné pomocné funkce, takže zbytek modulu se nemusí vůbec starat o to, na jaké verzi PrestaShop běží:
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);
}
Šablony využívají stejný pomocný prvek prostřednictvím malého modifikátoru Smarty, který modul zaregistroval, takže {$price|scdisplayprice} funguje na všech verzích.
Třídy prezentátorů mají změněný jmenný prostor
Modul zobrazuje nákupní košík pomocí vlastního řešení PrestaShop CartPresenter, takže ceny, slevy a názvy produktů vypadají přesně stejně jako ve zbytku obchodu. Mezi 1.7 a 8 se tato třída přesunula z Adapter\Cart do Adapter\Presenter\Cart. Místo toho class_alias triky, modul vyhodnotí název třídy pouze jednou:
private function getCartPresenterClass()
{
return class_exists('PrestaShop\\PrestaShop\\Adapter\\Presenter\\Cart\\CartPresenter')
? 'PrestaShop\\PrestaShop\\Adapter\\Presenter\\Cart\\CartPresenter'
: 'PrestaShop\\PrestaShop\\Adapter\\Cart\\CartPresenter';
}
Stejný vzor se vztahuje i na prezentace produktů používané pro křížový prodej. Ještě jeden detail: na PrestaShop 8 a 9 present() vrací objekt typu „lazy array“, nikoli prosté pole, takže typové náznaky, které uvádějí array je třeba povolit ArrayAccess také.
Provádí se statická analýza na verzi PrestaShop 9
Validátor doplňků spouští PHPStan na zdrojovém kódu PrestaShop 9. Volání, které je za běhu naprosto bezpečné, protože se nachází za method_exists() kontrola stále vykazuje chybu “volání nedefinované metody”. Validátor jsme si zprovoznili lokálně (PHPStan s bootstrapem, který načítá zdrojové kódy PrestaShop 8 a 9), aby bylo možné každou opravu zkontrolovat během několika minut, místo abychom museli čekat na další revizi.
2. Hummingbird: čtyři chyby, které se objevily pouze v novém motivu
Hummingbird je výchozí šablona systému PrestaShop 9 (zdroj na GitHubu). Žádný z níže uvedených prvků se neobjevil při statické analýze ani na verzi PrestaShop 8 s motivem Classic. Všechny čtyři byly nalezeny při procházení skutečného obchodu ve verzi PrestaShop 9.
Kaskádové vrstvy CSS proměnily seznam položek v košíku v mřížku
Hummingbird upravuje vzhled .products třída jako dvou sloupcová mřížka uvnitř @layer ps-components. Náš seznam v nákupním košíku používal ze důvodu kompatibility stejný název třídy, takže se produkty v postranním panelu najednou zobrazovaly ve dvou úzkých sloupcích. Zvýšení specificity v tomto případě nepomáhá proti vrstvám obvyklým způsobem; pomáhá však to, že CSS bez vrstev má přednost před CSS s vrstvami. Problém se podařilo vyřešit krátkým pravidlem bez vrstev v stylu modulu:
#sclist .products,
#sclist .product_list_widget {
display: block;
grid-template-columns: none;
}
Modální okno košíku tohoto motivu vyžaduje vlastní kód HTML
Modul otevíral vyskakovací okno “přidáno do košíku” prostřednictvím prestashop.blockcart.showModal. Hummingbird nahrazuje tuto funkci svou vlastní verzí, která vyhledává prvek s data-ps-ref="blockcart-modal" a při zadání jiného HTML vyhodí chybu. Řešením bylo vždy používat vlastní modální renderer modulu namísto rendereru šablony.
Neplatný odkaz na prvek v animaci “přidat do košíku”
Animace uložila ikonu košíku po kliknutí na tlačítko a o 250 ms později načítala její pozici. V prohlížeči Hummingbird se mezitím znovu vykreslila hlavička s košíkem, takže uložený prvek již na stránce nebyl a offset() vrátil se undefined. Modul nyní ikonu vyhledá znovu v okamžiku, kdy ji potřebuje, a animaci přeskočí, pokud téma neobsahuje žádnou dostupnou ikonu košíku. Samotný panel se v každém případě otevře.
Tlačítko, které na mobilních zařízeních vybočuje z panelu
Na mobilních telefonech je tlačítko pro dokončení objednávky position: fixed ve spodní části bočního panelu. Pevný prvek je umístěn vzhledem k nejbližšímu nadřazenému prvku s transform — a panel má pouze jedno, když je otevřený. Když byl panel zavřený, tlačítko se připojilo k oknu zobrazení a plavalo ve spodní části každé stránky. Omezení pravidla na otevřený stav (.sc-widget-panel-open) to vyřešil.
3. Ověření doplňků: co se při kontrole vlastně prověřuje
Aby byl modul znovu zařazen do seznamu, bylo třeba projít procesem Validátor PrestaShop a následně kontrola shody, při které byl modul nainstalován na několik verzí PrestaShop se zapnutým ladicím režimem. Právě tato zjištění zabrala nejvíce času.
Každá proměnná jazyka Smarty musí být escapována
Starší šablony využívaly automatické escapování. V rámci revize je nyní jakýkoli neeskapovaný výstup považován za závažnou chybu. Prošli jsme všech sedm šablon front-office: |escape:'html':'UTF-8' pro text, URL adresy a atributy, |intval pro identifikační čísla a množství, |escape:'javascript':'UTF-8' uvnitř skriptů vložených přímo do kódu.
nofilter je nahlášeno jako bezpečnostní problém, i když je to oprávněné
Tento modul umožňuje majiteli obchodu vložit vlastní HTML kód ikony (značku Font Awesome nebo soubor SVG). Tento výstup se použije nofilter, spolu s komentářem vysvětlujícím důvod. Recenzent to přesto označil. Přijatým řešením byl vlastní modifikátor Smarty, který čistí HTML – odstraňuje <script> a <style> bloky, inline obslužné rutiny událostí a javascript: URL adresy — takže šablona již nepotřebuje nofilter vůbec.
V kódu PHP nesmí být žádný HTML kód
Malý panel podpory na stránce konfigurace byl vytvořen jako HTML řetězec v PHP. Byl přesunut do vlastní šablony pro správu. Jedna úskalí: ve verzi PrestaShop 8.1 blokují bezpečnostní zásady Smarty pro správu nezpracovaný $this->context->smarty->fetch() souboru ve složce modulu. Místo toho použijte zdroj modulu:
$output .= $this->fetch('module:yourmodule/views/templates/admin/support.tpl');
Varování v ladicím režimu může vést k zamítnutí revize
Tohle mi trvalo tři pokusy. Zpráva o shodě uváděla, že na verzích PrestaShop 8.1 a 9.0 “nebylo možné otevřít” stránku konfigurace, aniž by se zobrazila chybová zpráva. Příčinou se nakonec ukázalo být jediné upozornění: Undefined array key "is_default" v šabloně HelperForm. Language::getLanguages() pokud tento klíč nevrátí, šablona formuláře jej načte pro každý jazyk a přísný ladicí režim recenze způsobí, že se z tohoto upozornění stane stránka s chybou. V běžném testovacím obchodě s ladicím režimem se to zobrazí pouze jako varování, a proto bylo snadné si toho nevšimnout.
$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čení: Před odesláním otevřete konfigurační stránku na PrestaShop 8 a 9 se zapnutým ladicím režimem a každé upozornění považujte za chybu.
Standardy kódování, s jedním rozporem
Validátor uplatňuje pravidla PHP-CS-Fixer. Dvě drobnosti nás stály vždy jedno opětovné odeslání: v souboru bez jmenného prostoru napište catch (Throwable $e), nikoli \Throwable; a ponechte dokumentační blok licence přímo za <?php, bez prázdného řádku. Obecná konfigurace nástroje PHP-CS-Fixer se bude snažit tento prázdný řádek vložit, proto použijte pravidla validátoru, nikoli obecné přednastavení.
Kontrolní seznam pro vaše vlastní moduly před aktualizací na verzi PrestaShop 9
- Vyzkoušejte naši bezplatnou Nástroj pro kontrolu kompatibility PrestaShop 9 v modulu. Obsahuje seznam odstraněných tříd, metod a hooks, kterým se věnují následující body, včetně uvedení souboru a řádku.
- Vyhledej v kódu
Tools::displayPricea další metody odstraněné ve verzi 9.0 (ty PrestaShop 9 – dokumentace pro vývojáře (uvádí seznam změn). - Hledejte třídy, na které se odkazuje pomocí jejich starých jmenných prostorů, zejména prezentéry a adaptéry.
- Nainstalujte modul na kopii PrestaShop 9 se zapnutým ladicím režimem a otevřete jeho konfigurační stránku. Přečtěte si všechna upozornění.
- Otestujte front office na Hummingbird, a to nejen v režimu Classic: vyskakovací okna, záhlaví s košíkem, seznamy produktů a mobilní rozvržení.
- Zkontrolujte šablony, zda neobsahují neeskapované proměnné a
nofilter. - Zkontrolujte deklarovaný rozsah kompatibility modulu. Měl by odpovídat verzím, které jste skutečně otestovali.
Kde se modul nyní nachází
Block Sliding Cart běží na PrestaShop 1.7, 8 a 9, prošlo ověřením v sekci Addons a je opět uvedeno v seznamu, přičemž jeho historie a 36 recenzí (4,7★) zůstaly beze změny. Můžete podívejte se, jak to funguje tady, a důvody pro použití košíku založeného na AJAXu jsou popsány v Nákupní košík s AJAXem vs. obnovení stránky a UX mobilního košíku v PrestaShopu.
Pokud vám po aktualizaci přestal fungovat nějaký modul v obchodě, nebo pokud chcete před aktualizací zjistit, co přestane fungovat, právě tím se zabýváme. Řekněte nám, co se děje a my vám odpovíme s dotazy nebo cenovou nabídkou.
Často kladené otázky
Je Tools::displayPrice() bylo odstraněno v PrestaShop 9?
Ano. Místo toho použijte aktuální národní prostředí: $this->context->getCurrentLocale()->formatPrice($price, $currencyIsoCode). Pokud musí váš modul podporovat i PrestaShop 1.7, zahrňte obě cesty do jedné pomocné metody.
Fungují moduly PrestaShop 1.7 na zařízení PrestaShop 9?
Některé fungují beze změn. Moduly, které využívají odstraněné metody jádra, staré jmenné prostory tříd nebo JavaScript specifický pro dané téma, vyžadují aktualizaci. Instalace modulu na kopii PrestaShop 9 se zapnutým ladicím režimem odhalí většinu problémů během několika minut.
Proč se můj modul na Hummingbird zobrazuje nefunkčně, ale na Classicu ne?
Hummingbird využívá pro nákupní košík odlišné značkování, kaskádové vrstvy CSS a vlastní JavaScript. Nejvíce jsou tím ovlivněny moduly, které znovu používají názvy tříd z Classic nebo volají funkce nákupního košíku daného motivu.
Proč kontrola shody doplňků vykazuje chybu na stránce konfigurace?
V rámci této recenze byl modul nainstalován na několik verzí PrestaShop s přísným ladicím režimem, kde hlášení typu “undefined array key” způsobují selhání stránky. Otevřete si sami konfigurační stránku ve verzích PrestaShop 8 a 9 se zapnutým ladicím režimem a před odesláním opravte všechna hlášení.
