PrestaShop module generator tworzy szkielet modułu: plik główny, strukturę katalogów, podstawowe hooki i prosty panel konfiguracji. Nie napisze za Ciebie logiki biznesowej, integracji z ERP czy płatnościami — to nadal praca dewelopera. Poniżej znajdziesz część organizacyjną: najczęstsze błędy popełniane po wygenerowaniu szkieletu, checklistę wdrożenia od stagingu do produkcji i odpowiedzi na pytania, które najczęściej dostajemy od klientów. Warto zestawić to z oficjalną dokumentacją dla deweloperów PrestaShop: devdocs.prestashop-project.org.
PrestaShop module generator to narzędzie, które na podstawie kilku danych wejściowych — nazwy modułu, wersji PrestaShop, listy hooków i informacji o autorze — tworzy gotowy szkielet modułu. Efektem jest paczka ZIP z plikiem głównym (np. mojmodul.php), klasą dziedziczącą po Module, metodami install() i uninstall(), pustymi szablonami oraz — jeśli zaznaczysz taką opcję — prostym panelem konfiguracji w zapleczu. Generator nie wymyśla funkcji, którą moduł ma realizować. To szkielet, nie produkt.
W praktyce spotkasz trzy typy generatorów:
Dla kogo to jest. Początkujący deweloper nauczy się na szkieletcie konwencji PrestaShop: nazewnictwa plików, rejestracji hooków, struktury kontrolerów. Agencja skróci czas do pierwszego commita z godzin do minut. Właściciel sklepu zamawiający moduł zrozumie, co realnie dostaje w pierwszym etapie i dlaczego wycena nie kończy się na wygenerowanej paczce.
Czego generator nie zrobi. Nie napisze logiki biznesowej (np. własnego algorytmu rabatowego czy mapowania danych z ERP), nie zintegruje płatności ani kurierów, nie doda testów, nie przeprowadzi Cię przez aktualizacje pod kolejne wersje PrestaShop i nie przejmie utrzymania. Te elementy to nadal praca dewelopera — dlatego warto najpierw uporządkować wybór i wdrożenie modułów PrestaShop, a dopiero potem pisać własny.
Proces jest krótki: wypełniasz formularz, dostajesz ZIP. Warto wiedzieć, co dokładnie ląduje w paczce, żeby nie zgubić się przy pierwszej modyfikacji.
Wejście. Typowy generator prosi o: nazwę modułu, autora, wersję PrestaShop (1.7 lub 8.x), listę hooków oraz przełącznik odpowiedzialny za panel konfiguracji. Część narzędzi pozwala też wybrać, czy chcesz kontroler frontowy, adminowy, czy oba.
Wyjście. W katalogu /modules/mojmodul/ znajdziesz plik główny z klasą dziedziczącą po Module:
class Mojmodul extends Module
{
public function __construct()
{
$this->name = 'mojmodul';
$this->version = '1.0.0';
$this->author = 'Twoja firma';
$this->ps_versions_compliancy = ['min' => '1.7.0.0', 'max' => _PS_VERSION_];
parent::__construct();
}
public function install()
{
return parent::install()
&& $this->registerHook('displayHeader')
&& $this->registerHook('displayHome')
&& $this->registerHook('actionCartSave');
}
}Metoda uninstall() wygląda analogicznie, ale pamiętaj o usunięciu własnych wpisów z tabeli configuration — inaczej po reinstalacji zostaną stare ustawienia. Pełny opis konwencji znajdziesz w oficjalnej dokumentacji dla deweloperów PrestaShop.
config.xml to metadane modułu: nazwa, wersja, autor, zgodność wersji i lista hooków. PrestaShop czyta go przy instalacji i przy walidacji. Jeśli podbijesz wersję w kodzie, a zapomnisz o XML, dostaniesz rozjazd. logo.png (32×32 px) to ikona na liście modułów — bez niej wyświetla się domyślna grafika, co u klienta wygląda na niedokończoną pracę. Tłumaczenia trzymaj w katalogu translations/; w PrestaShop 8 to pliki XLIFF generowane z panelu Międzynarodowe > Tłumaczenia, starsze moduły używają plików PHP. W szablonach używaj {l s='Tekst' mod='mojmodul'} — bez mod= string trafi do słownika core, nie modułu.
| Element | Do czego służy | Na co uważać |
|---|---|---|
| mojmodul.php | klasa Module: konstruktor, install(), uninstall(), hooki | nazwa pliku i klasy muszą być identyczne |
| config.xml | metadane: nazwa, wersja, autor, zgodność, lista hooków | rozjazd z kodem przy podbijaniu wersji |
| logo.png | ikona modułu na liście w zapleczu | 32×32 px, inaczej się rozjedzie |
| controllers/ | kontrolery frontowe i adminowe (własne URL-e) | nazwa klasy i pliku zgodna z konwencją |
| views/templates/ | szablony front i back, pliki CSS/JS | nie duplikuj stylów core |
| translations/ | słowniki .xlf lub .php | w szablonach zawsze mod='mojmodul' |
| upgrade/ | skrypty migracji między wersjami | przy 1.0.0 puste, ale katalogu nie usuwaj |
| classes/ | własne klasy pomocnicze | autoloader ładuje je po nazwie pliku |
Załóż, że masz działający lokalny PrestaShop i chcesz zobaczyć efekt bez ryzyka dla sklepu klienta.
define('_PS_MODE_DEV_', true) w config/defines.inc.php, potem wyczyść cache — Parametry zaawansowane > Wydajność > Wyczyść pamięć podręczną lub usuń zawartość var/cache.mojmodul: małe litery, bez spacji, myślników i polskich znaków. Nazwa modułu, katalogu i klasy muszą być identyczne — inaczej PrestaShop go nie rozpozna.displayHeader (dołączenie CSS/JS), displayHome (blok na stronie głównej) i actionCartSave (reakcja na zmiany w koszyku). Włącz panel konfiguracji, jeśli moduł ma mieć ustawienia./modules/mojmodul/. Uprawnienia: 644 dla plików, 755 dla katalogów, właściciel taki sam jak proces PHP.actionCartSave), wejdź na stronę główną (displayHome), a w źródle strony poszukaj plików CSS/JS modułu (displayHeader). W trybie dev błędy PHP zobaczysz od razu na ekranie.Pułapka, która kosztuje najwięcej. actionCartSave odpala się przy każdym zapisie koszyka, także przy zmianie ilości. Jeśli wstawisz tam odwołanie do zewnętrznego API, każde kliknięcie plusa przy produkcie generuje żądanie sieciowe. Przy 200 aktywnych koszykach w godzinie szczytu zablokujesz sklep. Trzymaj tam możliwie lekką logikę, a cięższe operacje przenieś do kolejki lub zadania cron.
Zanim wdrożysz moduł na produkcję, przećwicz cały scenariusz na kopii sklepu — usługi PrestaShop dla sklepów w praktyce zaczynają się od stagingu, nie od wgrania paczki na żywy serwer.
| Krok | Czas | Efekt |
|---|---|---|
| Środowisko lokalne: PHP 8.1+, MySQL, PrestaShop 8 | 5–10 min (jednorazowo) | działający sklep na localhost |
| Generowanie szkieletu pod nazwą mojmodul | 2 min | paczka ZIP |
| Wgranie do /modules/ i instalacja w panelu | 2 min | moduł widoczny w Menedżerze modułów |
| Test trzech hooków i panelu konfiguracji | 3 min | potwierdzenie, że szkielet działa |
Wygenerowany szkielet to katalog modules/mojmodul/ z plikiem głównym mojmodul.php i klasą Mojmodul extends Module. Nazwa klasy to nazwa modułu w CamelCase, nazwa katalogu — małymi literami: minimum 3 znaki, tylko litery, cyfry i podkreślenia, bez myślników i bez cyfry na początku. Złamiesz konwencję — instalator odrzuci moduł, zanim cokolwiek się uruchomi.
W __construct() ustawiasz metadane, od których zależy całe życie modułu: name, version, author, ps_versions_compliancy (zakres min–max), kategorię w panelu (tab) i bootstrap = true, jeśli chcesz korzystać z komponentów PrestaShop w widokach. install() wykonuje się raz: rejestruje hooki przez registerHook(), tworzy tabele z prefiksem _DB_PREFIX_ i zapisuje wartości domyślne przez Configuration::updateValue(). uninstall() jest jego lustrem i musi sprzątać dokładnie to samo.
Hooki mają sztywną konwencję nazw: hookDisplayHeader(), hookDisplayHome(), hookActionCartSave(). Metoda musi być publiczna, a hook zarejestrowany — inaczej PrestaShop nigdy jej nie wywoła. Kontrolery frontowe leżą w controllers/front/, dziedziczą po ModuleFrontController, a link generujesz przez getModuleLink(). Kontrolery administracyjne (ModuleAdminController) obsługują listy, filtry i formularze w back office. Widoki to Twig w views/templates/front/, hook/ i admin/. Teksty wyciągaj do domen tłumaczeń, np. Modules.Mojmodul.Shop, pliki trzymaj w translations/.
Własną logikę — ERP, płatności, eksport — trzymaj poza plikiem głównym: klasa modułu ma tylko spinać hooki z serwisami. Od 1.7 możesz w module uruchomić Composer i autoloadować klasy z src/. Wtedy zmiana logiki nie rozjeżdża instalatora. Zobacz też nasz materiał o tym, jak wybierać i wdrażać moduły PrestaShop.
| Element | Do czego służy | Gdzie dopisujesz logikę |
|---|---|---|
| mojmodul.php / __construct() | nazwa, wersja, zgodność, kategoria w panelu | nigdzie — to metadane |
| install() / uninstall() | rejestracja hooków, tabele, konfiguracja domyślna | sprzątanie, migracje, dane startowe |
| hookDisplay* / hookAction* | wpięcie w szablon i zdarzenia sklepu | wywołanie serwisu z src/ |
| controllers/front/ | własny adres URL modułu | przepływ: formularz, koszyk, webhook |
| views/templates/*.twig | warstwa prezentacji | tylko dane — zero zapytań do bazy |
| translations/ | teksty widoczne dla użytkownika | kolejne języki sklepu |
Generator nie zna Twojego sklepu, więc produkuje szkielet, który działa przy pierwszym uruchomieniu i sypie się przy pierwszej aktualizacji, jeśli nie poprawisz pięciu rzeczy.
install() tworzy tabele i zapisuje konfigurację, uninstall() musi je usunąć: DROP TABLE, Configuration::deleteByName(), unregisterHook(), usunięcie zakładki w panelu. Objaw zaniedbania: druga instalacja wywala się na CREATE TABLE, w bazie zostają tabele z prefiksem sklepu, a w panelu wisi martwa zakładka. Test: odinstaluj moduł na stagingu i przeszukaj bazę po fragmencie nazwy.Tools::getValue() zwraca surowy ciąg z żądania. Wstawiony do zapytania daje SQL injection, wypisany w szablonie daje XSS — a XSS w panelu administratora pozwala przejąć sesję. Stosuj castowanie ((int)), Validate::isInt(), Validate::isEmail(), a w zapytaniach pSQL() dla stringów. W Twig nie używaj |raw na danych użytkownika, w Smarty pisz |escape:'htmlall':'UTF-8'.ps_versions_compliancy ma odzwierciedlać realnie przetestowane wersje, nie życzenia. Wymagania PHP dla konkretnego wydania PrestaShop sprawdzisz w dokumentacji dla deweloperów PrestaShop.var/cache/. W trybie deweloperskim włącz wymuszanie kompilacji, po wdrożeniu wyczyść cache raz, celowo. Hook nie działa też, gdy nie jest zarejestrowany albo szablon nie wywołuje {hook h='displayX'} — weryfikujesz to w zakładce Pozycje.Gorzej, gdy moduł gada z zewnętrznym systemem — wtedy walidacja po obu stronach jest warunkiem koniecznym. Więcej o tym w tekście o integracji modułu z PrestaShop API.
Standardy sprowadzają się do trzech poziomów: dane, dostęp, dystrybucja.
Dane. Walidacja po stronie serwera jest obowiązkowa — atrybut required w HTML to tylko wygoda dla użytkownika. W kontrolerze administracyjnym zbieraj komunikaty do tablicy $this->errors i nie zapisuj nic, dopóki jest niepusta. W Twig escapowanie HTML jest domyślnie włączone, ale tracisz je przy |raw i w blokach literal; w Smarty pamiętaj o |escape:'htmlall':'UTF-8'. Dane wstawiane do skryptu escapuj w kontekście JS, a wstawiane do adresu — w kontekście URL. To trzy różne mechanizmy, nie jeden.
Dostęp. Token CSRF: kontrolery administracyjne mają wbudowaną weryfikację, formularze frontowe potrzebują własnego pola ukrytego sprawdzanego przy każdej akcji zmieniającej stan. Uprawnienia plików: 644 dla plików, 755 dla katalogów, właściciel to użytkownik, spod którego działa PHP — nie root. Katalogu nie ustawiaj na 777, bo to otwarte drzwi do wstrzyknięcia kodu. Klucze API trzymaj poza katalogiem publicznym, a jeśli muszą leżeć w module, dołóż blokadę dostępu i nie nadpisuj zabezpieczeń, które PrestaShop sam wstawia w kluczowych katalogach.
Dystrybucja. PrestaShop Addons sprawdza deklarowaną kompatybilność, licencję, obecność tłumaczeń i brak błędów z walidatora. Teksty wpisane na sztywno w szablonach to niemal pewny problem — używaj domen i plików w translations/. Biblioteki osób trzecich: dołącz ich licencje i nie usuwaj nagłówków. Aktualną checklistę i opis wymagań znajdziesz w dokumentacji deweloperskiej PrestaShop. Przed publikacją przejdź pełny test na kopii sklepu — tak samo jak przy każdym wdrożeniu i migracji PrestaShop.
| Obszar | Standard | Gdzie sprawdzasz |
|---|---|---|
| Walidacja | typy, Validate::isInt/isEmail, brak zapisu przy błędach | kontroler + logi PHP |
| Escaping | Twig bez |raw, Smarty |escape:'htmlall':'UTF-8' | przegląd szablonów |
| CSRF | token w każdym formularzu zmieniającym stan, metoda POST | kod kontrolera i szablon formularza |
| Uprawnienia | 644 pliki, 755 katalogi, właściciel = user PHP | SSH / panel hostingu |
| Addons | kompatybilność, licencja, tłumaczenia | checklista walidatora |
Nie ma jednej dobrej odpowiedzi. Są trzy drogi i każda ma inny próg wejścia oraz inne ryzyko po stronie sklepu.
Generator plus Twoja praca. Szkielet powstaje w 0–2 godziny. Ale generator nie napisze logiki: mapowania pól z ERP, obsługi webhooków płatności, reguł rabatowych czy zapisu do własnych tabel. Realnie 20–80 godzin pracy dewelopera, zależnie od liczby hooków i integracji. Rozliczasz stawkę godzinową, więc koszt rośnie razem z zakresem. Zaleta: kod jest Twój i można go dowolnie rozwijać. Wada: nie ma gwarancji, że ktoś go później utrzyma.
Gotowy moduł z marketplace. Instalacja to 30 minut do 2 godzin, jeśli funkcja jest standardowa. Płacisz za licencję, często też za roczny abonament na aktualizacje. Ryzyko: konflikt z dodatkami, które już masz — dwa moduły nadpisujące ten sam hook potrafią wyłączyć koszyk albo podmienić cennik. Przed zakupem sprawdź zgodność z Twoją wersją PrestaShop i wersją PHP, a nie tylko z opisem na stronie sprzedawcy.
Moduł na zamówienie. Wycena wychodzi z liczby godzin, typowo 20–80 h dla średniego zakresu. Przy integracji z ERP, płatnościami i kurierami to często 80–200 h plus testy i dokumentacja. Dostajesz kod dopasowany do procesów i kogoś, kto odpowiada za wdrożenie.
Praktyczna podpowiedź: policz godziny, zanim wybierzesz. Jeśli szkielet ma obsłużyć jeden dodatkowy przycisk w panelu, wystarczy generator. Jeśli moduł ma wysyłać stany magazynowe do ERP co 15 minut, to projekt wdrożeniowy. Sposób wyboru i wdrażania rozszerzeń opisujemy szerzej w materiale o modułach PrestaShop, a sam generator najlepiej poznać z oficjalnej dokumentacji dla deweloperów PrestaShop.
| Wariant | Czas do działającej wersji | Koszt | Kiedy ma sens | Główne ryzyko |
|---|---|---|---|---|
| Generator + własna praca | 0–2 h szkielet, 20–80 h logika | stawka godzinowa × godziny | masz dewelopera znającego hooki | brak testów, dług techniczny |
| Gotowy moduł | 30 min – 2 h na instalację i konfigurację | licencja + ewentualny abonament | funkcja jest standardowa | konflikt z innymi modułami, brak dostępu do kodu |
| Moduł na zamówienie | 20–80 h, więcej przy integracjach | wycena godzinowa po zebraniu wymagań | ERP, płatności, kurierzy, procesy niestandardowe | źle zebrane wymagania, zmiany w trakcie |
Po wygenerowaniu szkieletu najważniejsza jest dyscyplina wdrożeniowa. Kolejność poniżej oszczędza godziny nerwów i chroni dane klientów.
Na produkcję wchodzisz dopiero po zamknięciu wszystkich punktów: wyłączasz tryb dev, włączasz cache, instalujesz moduł przez panel i robisz jedno zamówienie kontrolne po wdrożeniu.
| Etap | Co sprawdzić | Gdzie |
|---|---|---|
| Backup | baza, /modules, /themes, parameters.php | panel hostingu lub mysqldump |
| Staging | zgodność wersji PS, PHP, MySQL, szablonu | config/defines.inc.php, _PS_MODE_DEV_ |
| Logi | błędy PHP, deprecated, wyjątki | var/logs, error_log |
| Testy | hooki, koszyk, zamówienie, mail | front i back office |
| Odinstalowanie | tabele w bazie i tabela configuration | phpMyAdmin |
Generator robi szkielet. Są projekty, w których lepiej od razu zamówić usługę wdrożeniową, bo sam szkielet tylko odsuwa problem w czasie.
W takich przypadkach sensowniej zacząć od rozmowy o zakresie niż od generatora. Zobacz, jak prowadzimy wdrożenia i migracje PrestaShop oraz jakie usługi PrestaShop realizujemy. Prosty test decyzyjny: jeśli nie potrafisz w jednym zdaniu powiedzieć, kto dokończy moduł i kto go zaktualizuje po premierze nowej wersji sklepu, to nie jest projekt na generator.
Brak implementacji uninstall() lub pozostawione tabele i wpisy w konfiguracji po odinstalowaniu modułu.
Jak wykryć: Zainstaluj i odinstaluj moduł na kopii bazy, a potem wykonaj SHOW TABLES LIKE 'ps_twojmodul%' oraz przejrzyj tabelę ps_configuration pod kątem nazw powiązanych z modułem.
Jak naprawić: Dopisz w uninstall() usuwanie własnych tabel (Db::getInstance()->execute('DROP TABLE ...')) oraz Configuration::deleteByName() dla każdego klucza zapisanego w install(). Sprawdź też, czy nie usuwasz tabel, których moduł nie tworzył.
Brak walidacji danych wejściowych i escapowania wyjścia — ryzyko XSS oraz SQL injection.
Jak wykryć: Wpisz w pola formularza modułu wartości testowe: oraz ' OR 1=1 -- i sprawdź, czy skrypt się wykona, a zapytanie zwróci nieoczekiwane dane.
Jak naprawić: Rzutuj dane na typ ((int), (float), (string)), filtruj przez Tools::getValue() z walidacją, a zapytania buduj z parametrami zamiast sklejania stringów. W Twig domyślne {{ }} escapuje treść — używaj |raw tylko wtedy, gdy wiesz, co wypuszczasz.
Brak tokena CSRF w formularzach i akcjach administracyjnych modułu.
Jak wykryć: Podejrzyj wygenerowany HTML lub URL akcji w panelu — jeśli nie ma parametru token, zabezpieczenia nie ma.
Jak naprawić: Dodaj token do formularza (np. przez Tools::getAdminTokenLite()) i zweryfikuj go po stronie kontrolera przed wykonaniem operacji. Dotyczy to także akcji wykonywanych przez AJAX.
Niezgodność wersji PHP i PrestaShop — moduł działa lokalnie, a wysypuje się na produkcji.
Jak wykryć: Porównaj wersje PHP (php -v) i PrestaShop na obu środowiskach, przejrzyj logi serwera pod kątem błędów deprecated i fatal error.
Jak naprawić: Ustaw w pliku głównym tablicę $this->ps_versions_compliancy z zakresem wspieranych wersji i deklaruj minimalną wersję PHP. Testuj na tej samej wersji PHP, na której stoi sklep.
Cache i hooki, które nie odświeżają się po zmianach — moduł wygląda na niedziałający.
Jak wykryć: Sprawdź, czy hook jest zarejestrowany w install() i wywoływany w szablonie, a potem wyczyść cache PrestaShop i odśwież stronę z pominięciem cache przeglądarki.
Jak naprawić: Zarejestruj hook jawnie w install(), wyczyść cache po każdej zmianie szablonów i plików tłumaczeń. Jeśli korzystasz z cache serwera (np. Varnish, CDN), dodaj wyjątek dla panelu administracyjnego.
Złe uprawnienia plików i właściciel katalogu modułu.
Jak wykryć: Sprawdź uprawnienia po wgraniu paczki na serwer (ls -la w katalogu /modules/) i spróbuj zapisać konfigurację w panelu — błąd zapisu oznacza problem z prawami.
Jak naprawić: Ustaw 644 dla plików i 755 dla katalogów, właścicielem powinien być użytkownik, pod którym działa PHP. Nie zostawiaj 777 ani plików wgranych z lokalnego konta administratora.
Generator modułów PrestaShop skraca start, ale nie zdejmuje z Ciebie odpowiedzialności za bezpieczeństwo, zgodność wersji i utrzymanie. Najczęstsze problemy to brak uninstall(), brak walidacji i tokena CSRF oraz różnice między środowiskiem lokalnym a produkcją. Checklista wdrożenia jest krótka, ale każdy punkt z niej wynika z realnego błędu, który gdzieś już wystąpił. Przejdź ją w całości na stagingu, zanim cokolwiek trafi na produkcję.
Nie. Generator daje szkielet: strukturę katalogów, plik główny, rejestrację hooków i podstawowy panel konfiguracji. Cała logika biznesowa — integracja, obliczenia, obsługa błędów, testy — to nadal praca dewelopera. Traktuj generator jako skrócenie pierwszych kilkudziesięciu minut, a nie jako gotowe rozwiązanie.
Dla PrestaShop 8 typowe, wspierane środowisko to PHP 8.1 lub nowsze, ale dokładna macierz zależy od konkretnej wersji sklepu i zmienia się między wydaniami. Zanim wdrożysz moduł, sprawdź aktualne wymagania w dokumentacji deweloperskiej PrestaShop i upewnij się, że staging ma identyczną wersję PHP co produkcja.
Zmiernąć czas generowania strony przed i po włączeniu modułu, na tym samym środowisku i przy tej samej zawartości. Jeśli w logach widzisz dodatkowe zapytania SQL wykonywane przy każdym wejściu, sprawdź, czy da się je ograniczyć lub objąć cache. Nie oceniaj wydajności na podstawie odczucia — potrzebny jest pomiar.
Sam szkielet nie wystarczy — marketplace sprawdza m.in. licencję, kompletność tłumaczeń, kompatybilność z deklarowanymi wersjami PrestaShop i jakość kodu. Jeśli planujesz sprzedaż modułu, zaplanuj czas na doprowadzenie go do tych wymagań, zanim złożysz zgłoszenie.
Realistyczny zakres dla niestandardowego modułu to zwykle 20–80 godzin pracy, zależnie od liczby integracji, hooków i scenariuszy brzegowych. Prosty moduł wyświetlający treść to dolna granica, integracja z ERP, płatnościami lub kurierem — górna. Wycena powinna być oparta na liczbie godzin, nie na jednej kwocie z sufitu.
Najpierw sprawdź, czy oba moduły nie nadpisują tego samego hooka lub szablonu — to najczęstsza przyczyna konfliktów. Testy wykonaj na stagingu, wyłączając moduły pojedynczo. Jeśli konflikt dotyczy tego samego mechanizmu, np. koszyka czy checkoutu, czasem taniej jest napisać jedną spójną integrację niż utrzymywać dwie walczące ze sobą.
Jeśli moduł ma robić coś więcej niż wyświetlać treść — integrować się z ERP, płatnościami czy kurierami — zapraszamy do rozmowy. Zajrzyj na PrestaShop moduły: jak wybrać, wdrożyć i nie zepsuć sklepu i opisz, co ma działać.