Blog
Modernizacja modułu PrestaShop do wersji PrestaShop 9: Co się zepsuło i jak to naprawiliśmy
Block Sliding Cart to jeden z najstarszych modułów w naszym katalogu. Po raz pierwszy pojawił się na PrestaShop Addons w 2013 roku i przez lata po prostu działał. Potem pojawił się PrestaShop 8, nie nadążaliśmy za zmianami, a w 2023 roku oferta przestała być aktywna.
W 2026 roku przywróciliśmy to rozwiązanie: jedną bazę kodu dla wersji PrestaShop 1.7, 8 i 9, motywu Classic oraz Hummingbird. Oto lista problemów, które faktycznie wystąpiły w trakcie tego procesu, oraz opis sposobu ich rozwiązania. Jeśli planujesz aktualizację do wersji PrestaShop 9, większość z tych problemów będzie miała również zastosowanie do twoich własnych modułów.
W skrócie: W części poświęconej PHP konieczne było wprowadzenie mniej zmian niż się spodziewano. Najwięcej czasu zajęło opracowanie nowego domyślnego motywu oraz przejście procesu walidacji dodatków, gdzie nawet jedno ostrzeżenie w jednej z wersji PrestaShop może spowodować odrzucenie całej weryfikacji.
1. PHP: co zostało usunięte lub przeniesione w wersji PrestaShop 9
Tools::displayPrice() zniknęło
Moduł formatował ceny z dokładnością do siedmiu miejsc, używając Tools::displayPrice(). Metoda ta od dawna była przestarzała, a w wersji PrestaShop 9 została ostatecznie usunięta, więc każde z tych wywołań stało się błędem krytycznym.
Zastępowaną wartością jest bieżąca lokalizacja, która zna już format waluty stosowany w sklepie. Umieściliśmy obie ścieżki w jednej funkcji pomocniczej, dzięki czemu pozostała część modułu nie musi się martwić, na której wersji PrestaShop działa:
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);
}
Szablony korzystają z tego samego pomocnika za pośrednictwem niewielkiego modyfikatora Smarty zarejestrowanego przez moduł, więc {$price|scdisplayprice} działa na każdej wersji.
Zmieniono przestrzeń nazw klas prezenterów
Moduł wyświetla zawartość koszyka przy użyciu własnego rozwiązania PrestaShop CartPresenter, więc ceny, rabaty i nazwy produktów wyglądają dokładnie tak samo jak w pozostałej części sklepu. W godzinach od 17:00 do 20:00 ta grupa przeniosła się z Adapter\Cart do Adapter\Presenter\Cart. Zamiast class_alias w przypadku tych sztuczek moduł rozpoznaje nazwę klasy tylko 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 sam schemat dotyczy prezentacji produktów wykorzystywanych w sprzedaży krzyżowej. Jeszcze jeden szczegół: w PrestaShop 8 i 9 present() zwraca obiekt typu „lazy array”, a nie zwykłą tablicę, więc wskazówki dotyczące typów, które mówią, że array należy zezwolić na ArrayAccess także.
Przeprowadzono analizę statyczną w oparciu o wersję PrestaShop 9
Narzędzie do sprawdzania poprawności dodatków uruchamia PHPStan na kodzie źródłowym PrestaShop 9. Wywołanie to jest całkowicie bezpieczne w czasie wykonywania, ponieważ znajduje się za method_exists() Sprawdziliśmy to, ale nadal pojawia się komunikat “wywołanie niezdefiniowanej metody”. Odtworzyliśmy walidator lokalnie (PHPStan z plikiem bootstrap ładującym źródła PrestaShop 8 i 9), dzięki czemu każdą poprawkę można było sprawdzić w ciągu kilku minut, zamiast czekać na kolejną weryfikację.
2. Hummingbird: cztery błędy, które pojawiły się wyłącznie w nowym motywie
Hummingbird to domyślny motyw w wersji PrestaShop 9 (źródło na GitHubie). Żadna z poniższych pozycji nie pojawiła się w analizie statycznej ani w serwisie PrestaShop 8 z motywem Classic. Wszystkie cztery zostały znalezione podczas przeglądania prawdziwego sklepu PrestaShop 9.
Warstwy kaskadowe CSS przekształciły listę koszyka w siatkę
Hummingbird nadaje styl elementowi .products klasa jako siatka dwukolumnowa wewnątrz @layer ps-components. Nasza lista koszyka korzystała z tej samej nazwy klasy ze względu na kompatybilność, więc w panelu bocznym produkty nagle ułożyły się w dwóch wąskich kolumnach. Zwiększenie specyficzności nie pomaga w zwalczaniu warstw w zwykły sposób; pomaga natomiast to, że CSS bez warstw ma pierwszeństwo przed CSS z warstwami. Krótka reguła bez warstw w arkuszu stylów modułu rozwiązała ten problem:
#sclist .products,
#sclist .product_list_widget {
display: block;
grid-template-columns: none;
}
Okno modalne koszyka w tym motywie wymaga własnego kodu HTML
Moduł ten wyświetlał okienko “dodano do koszyka” za pomocą prestashop.blockcart.showModal. Hummingbird zastępuje tę funkcję własną wersją, która wyszukuje element o data-ps-ref="blockcart-modal" i zgłasza błąd, gdy podany zostanie inny kod HTML. Rozwiązaniem było stosowanie zawsze własnego renderera okien modalnych modułu zamiast renderera motywu.
Nieaktualne odwołanie do elementu w animacji “przenieś do koszyka”
Animacja zapisała ikonę koszyka po kliknięciu przycisku, a 250 ms później odczytała jej położenie. W przypadku Hummingbird nagłówek koszyka jest w międzyczasie renderowany na nowo, więc zapisany element nie znajdował się już na stronie i offset() powrócił undefined. Moduł ponownie wyszukuje ikonę w momencie, gdy jest ona potrzebna, i pomija animację, jeśli motyw nie zawiera dostępnej ikony koszyka. Sam panel otwiera się w obu przypadkach.
Przycisk stały, który wykracza poza panel na urządzeniach mobilnych
W przypadku telefonów przycisk „Do kasy” to position: fixed w dolnej części panelu bocznego. Element stały jest pozycjonowany względem najbliższego elementu nadrzędnego za pomocą transform — a panel ma tylko jeden, gdy jest otwarty. Gdy panel był zamknięty, przycisk przyczepiał się do okna wyświetlania i unosił się na dole każdej strony. Ograniczenie zakresu działania reguły do stanu otwartego (.sc-widget-panel-open) rozwiązałem to.
3. Sprawdzanie dodatków: co faktycznie obejmuje weryfikacja
Aby moduł ponownie znalazł się na liście, trzeba było przejść przez Walidator PrestaShop a następnie przegląd zgodności, w ramach którego zainstalowano moduł na kilku wersjach PrestaShop z włączonym trybem debugowania. To właśnie te ustalenia zajęły najwięcej czasu.
Każda zmienna w języku Smarty musi być poddana eskapowaniu
Starsze szablony opierały się na automatycznym escapowaniu. W ramach przeglądu wszelkie dane wyjściowe bez escapowania są obecnie traktowane jako błąd uniemożliwiający dalsze działania. Przejrzeliśmy wszystkie siedem szablonów front-office: |escape:'html':'UTF-8' w przypadku tekstu, adresów URL i atrybutów, |intval w odniesieniu do numerów identyfikacyjnych i ilości, |escape:'javascript':'UTF-8' w skryptach wbudowanych.
nofilter jest zgłaszane jako problem bezpieczeństwa, nawet jeśli jest to uzasadnione
Moduł umożliwia właścicielowi sklepu wklejenie własnego kodu HTML ikony (tagu Font Awesome lub pliku SVG). Wynik ten wykorzystuje nofilter, wraz z komentarzem wyjaśniającym powód. Recenzent i tak to zgłosił. Przyjętym rozwiązaniem był niestandardowy modyfikator Smarty, który oczyszcza kod HTML — usuwa <script> oraz <style> bloki, wbudowane procedury obsługi zdarzeń oraz javascript: Adresy URL — dzięki czemu szablon nie musi już nofilter w ogóle.
W kodzie PHP nie wolno używać HTML-a
Niewielki panel pomocy technicznej na stronie konfiguracji został stworzony jako ciąg znaków HTML w języku PHP. Został on przeniesiony do osobnego szablonu panelu administracyjnego. Jedna pułapka: w wersji PrestaShop 8.1 polityka bezpieczeństwa Smarty w panelu administracyjnym blokuje surowe $this->context->smarty->fetch() pliku w folderze modułu. Zamiast tego należy skorzystać z zasobu modułu:
$output .= $this->fetch('module:yourmodule/views/templates/admin/support.tpl');
Ostrzeżenie w trybie debugowania może spowodować odrzucenie zgłoszenia
Zajęło mi to trzy próby. Raport zgodności wskazywał, że strona konfiguracyjna była “niedostępna” w wersjach PrestaShop 8.1 i 9.0, przy czym nie wyświetlał się żaden komunikat o błędzie. Okazało się, że przyczyną była jedna informacja: Undefined array key "is_default" w szablonie HelperForm. Language::getLanguages() jeśli nie zwróci tego klucza, szablon formularza odczytuje go dla każdego języka, a tryb ścisłego debugowania recenzji powoduje, że komunikat ten skutkuje wyświetleniem strony z błędem. W zwykłym sklepie testowym z włączonym trybem debugowania pojawia się on jedynie jako ostrzeżenie, dlatego łatwo było go przeoczyć.
$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;
}
Wniosek: przed przesłaniem danych należy otworzyć stronę konfiguracyjną w PrestaShop 8 i 9 z włączonym trybem debugowania i traktować każde powiadomienie jako błąd.
Standardy kodowania, z jednym rozbieżnością
Walidator stosuje reguły PHP-CS-Fixer. Dwie nieścisłości kosztowały nas po jednym ponownym zgłoszeniu: w pliku bez przestrzeni nazw należy wpisać catch (Throwable $e), a nie \Throwable; oraz umieść blok dokumentacji licencji bezpośrednio po <?php, bez pustej linii. Domyślna konfiguracja narzędzia PHP-CS-Fixer będzie próbowała wstawić tę pustą linię, dlatego należy zastosować reguły walidatora, a nie domyślne ustawienia.
Lista kontrolna dotycząca własnych modułów przed aktualizacją do wersji PrestaShop 9
- Skorzystaj z naszej bezpłatnej Narzędzie do sprawdzania zgodności PrestaShop 9 w module. Zawiera listę usuniętych klas, metod i elementów hooks, które zostały omówione w kolejnych punktach, wraz z podaniem pliku i numeru linii.
- Wyszukaj w kodzie
Tools::displayPriceoraz inne metody usunięte w wersji 9.0 (te Dokumentacja dla programistów PrestaShop 9 (zawiera listę zmian). - Poszukaj klas odwołujących się do starych przestrzeni nazw, zwłaszcza prezenterów i adapterów.
- Zainstaluj moduł w urządzeniu PrestaShop 9 z włączonym trybem debugowania i otwórz jego stronę konfiguracyjną. Zapoznaj się ze wszystkimi informacjami.
- Przetestuj front office na Hummingbird, nie tylko w wersji Classic: wyskakujące okienka, koszyk w nagłówku, listy produktów i układ mobilny.
- Sprawdź szablony pod kątem zmiennych bez znaków escape oraz
nofilter. - Sprawdź zadeklarowany zakres zgodności modułu. Powinien on odpowiadać wersjom, które faktycznie przetestowałeś.
Gdzie obecnie znajduje się moduł
Wtyczka Block Sliding Cart działa na wersjach PrestaShop 1.7, 8 i 9, przeszła proces weryfikacji w sekcji „Dodatki” i ponownie pojawiła się na liście, zachowując swoją historię oraz 36 recenzji (4,7★). Możesz zobacz, jak to działa tutaj, a przyczyny wyboru koszyka opartego na technologii AJAX zostały omówione w Koszyk AJAX a odświeżanie strony oraz UX koszyka mobilnego w PrestaShop.
Jeśli po aktualizacji jakiś moduł w Twoim sklepie przestał działać lub chcesz dowiedzieć się, co może przestać działać przed aktualizacją, właśnie tym się zajmujemy. Powiedz nam, co się stało a my skontaktujemy się z Państwem, zadając pytania lub przedstawiając wycenę.
Najczęściej zadawane pytania
Czy Tools::displayPrice() usunięto w wersji PrestaShop 9?
Tak. Zamiast tego należy użyć bieżących ustawień regionalnych: $this->context->getCurrentLocale()->formatPrice($price, $currencyIsoCode). Jeśli twój moduł musi obsługiwać również PrestaShop 1.7, umieść obie ścieżki w jednej metodzie pomocniczej.
Czy moduły PrestaShop 1.7 działają w PrestaShop 9?
Niektóre działają bez zmian. Moduły korzystające z usuniętych metod rdzenia, starych przestrzeni nazw klas lub kodu JavaScript specyficznego dla danego motywu wymagają aktualizacji. Zainstalowanie modułu na kopii PrestaShop 9 z włączonym trybem debugowania pozwala wykryć większość problemów w ciągu kilku minut.
Dlaczego mój moduł wygląda na uszkodzony w wersji Hummingbird, ale nie w wersji Classic?
Hummingbird wykorzystuje inne znaczniki, kaskadowe warstwy CSS oraz własny kod JavaScript dla koszyka. Najbardziej dotknięte tym problemem są moduły, które ponownie wykorzystują nazwy klas z wersji Classic lub wywołują funkcje koszyka tego motywu.
Dlaczego strona konfiguracji nie przechodzi kontroli zgodności w sekcji „Dodatki”?
W ramach przeglądu moduł został zainstalowany na kilku wersjach PrestaShop z włączonym trybem ścisłego debugowania, w którym komunikaty typu “undefined array key” powodują błąd wyświetlania strony. Otwórz samodzielnie stronę konfiguracyjną w wersjach PrestaShop 8 i 9 z włączonym trybem debugowania i usuń wszystkie komunikaty ostrzegawcze przed przesłaniem zmian.
