Jak zbudować moduł PrestaShop 9: od szkieletu do produkcji
Moduł PrestaShop może być bardzo mały.
W najprostszej postaci katalog modułu zawiera główny plik PHP o takiej samej nazwie jak katalog.
Moduł produkcyjny często potrzebuje jednak znacznie więcej:
- usług;
- hooków;
- tabel bazy danych;
- kontrolerów Symfony;
- poleceń CLI;
- konfiguracji;
- logów;
- skryptów aktualizacji;
- kontroli bezpieczeństwa;
- testów.
PrestaShop 9 korzysta z Symfony 6.4 i kontynuuje migrację platformy do nowoczesnej architektury Symfony. Dlatego przejrzyste projektowanie modułów zorientowane na usługi jest ważniejsze niż kiedykolwiek.
Ten przewodnik przedstawia architekturę pełnoprawnego modułu PrestaShop 9, zamiast poprzestawać na „Hello World”.
Uwaga dotycząca wersji: Ten przewodnik zweryfikowano 22 września 2026 r. na podstawie aktualnej dokumentacji PrestaShop 9 dla programistów.
1. Określ odpowiedzialność modułu
Zanim utworzysz pliki, określ, za co odpowiada moduł.
Dobry moduł ma jasno określony cel biznesowy.
Przykłady:
filtrowanie stanów magazynowych
import dostawcy
monitorowanie bezpieczeństwa
reguły sprzedaży dodatkowej
eksport zamówień
Unikaj modułu, który stopniowo przejmuje odpowiedzialność za niepowiązane funkcje.
Jeśli jeden moduł obejmuje:
- SEO;
- stany magazynowe;
- bezpieczeństwo;
- wysyłkę;
- analitykę;
- import;
trudno go utrzymywać i testować.
2. Wybierz nazwę techniczną
Samouczek tworzenia modułów PrestaShop wymaga nazwy technicznej zawierającej małe litery i cyfry.
Na przykład:
mymodule
Główny plik modułu musi mieć tę samą nazwę:
/modules/mymodule/mymodule.php
Oficjalna dokumentacja odradza podkreślenia w nazwach technicznych, ponieważ nie współpracują poprawnie z domenami tłumaczeń.
3. Zacznij od przejrzystej struktury katalogów
Struktura przygotowana do produkcji może wyglądać następująco:
mymodule/
├── mymodule.php
├── composer.json
├── config/
│ ├── services.yml
│ └── routes.yml
├── src/
│ ├── Controller/
│ ├── Service/
│ ├── Repository/
│ ├── Command/
│ ├── Domain/
│ └── ApiPlatform/
├── views/
│ ├── templates/
│ ├── css/
│ └── js/
├── sql/
│ ├── install.php
│ └── uninstall.php
├── upgrade/
└── translations/
Nie potrzebujesz od razu każdego katalogu.
Dodawaj strukturę, gdy pojawi się nowa odpowiedzialność.
4. Zachowaj niewielką główną klasę modułu
Główna klasa modułu nie powinna zawierać całej logiki biznesowej.
Powinna koordynować takie elementy jak:
- metadane;
- instalację;
- rejestrację hooków;
- punkty wejścia konfiguracji.
Unikaj pisania:
2000 wierszy
wewnątrz:
class MyModule extends Module
Przenieś logikę aplikacji do usług.
5. Podstawowa główna klasa modułu
Minimalny moduł zaczyna się mniej więcej tak:
<?php
if (!defined('_PS_VERSION_')) {
exit;
}
class MyModule extends Module
{
public function __construct()
{
$this->name = 'mymodule';
$this->version = '1.0.0';
$this->author = 'Your Company';
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->l('My Module');
$this->description = $this->l('Example PrestaShop 9 module.');
}
}
Rzeczywista klasa produkcyjna zazwyczaj zawiera więcej metadanych i logiki instalacji.
6. Zaprojektuj instalację przed funkcjami
Zdecyduj, co tworzy instalacja.
Możliwe zasoby obejmują:
- hooków;
- klucze konfiguracji;
- tabel bazy danych;
- zakładki;
- uprawnienia.
Instalacja powinna kończyć się błędem w kontrolowany sposób.
Na przykład:
public function install()
{
return parent::install()
&& $this->registerHook('displayHeader')
&& $this->installDatabase();
}
Jeśli utworzenie bazy danych się nie powiedzie, nie pozostawiaj modułu częściowo zainstalowanego bez zgłoszenia problemu.
7. Rejestruj hooki świadomie
Hooki pozwalają modułom reagować na zdarzenia PrestaShop lub wyświetlać treść.
Konwencja PrestaShop rozróżnia:
actionSomething
od:
displaySomething
Hooki akcji reagują na zdarzenia.
Hooki wyświetlania renderują treść.
Rejestruj hooki podczas instalacji:
$this->registerHook('displayHeader');
Następnie zaimplementuj:
public function hookDisplayHeader(array $params)
{
// logic
}
8. Unikaj ciężkich operacji w globalnych hookach
Hook może być wykonywany na każdej stronie.
Nie umieszczaj:
- żądań do API dostawcy;
- ogromnych zapytań do bazy danych;
- skanów całego katalogu;
wewnątrz globalnego hooka wyświetlania.
Hook wyświetlania powinien w idealnym przypadku renderować już przygotowane dane.
Jeśli dane trzeba odświeżyć, użyj:
- pamięci podręcznej;
- crona;
- kolejki;
- procesu roboczego w tle.
9. Twórz usługi dla logiki biznesowej
Klasa usługi powinna reprezentować odpowiedzialność aplikacji.
Przykład:
ProductSyncService
IntegrityScanner
UpsellRuleEvaluator
StockFilterService
Kontroler powinien wywoływać usługę.
Usługa nie powinna zależeć od HTTP, chyba że wymaga tego jej odpowiedzialność.
Dzięki temu kod można ponownie wykorzystywać z:
- Back Office;
- CLI;
- crona;
- API.
10. Korzystaj ze wstrzykiwania zależności
Architektura Symfony w PrestaShop 9 obsługuje wstrzykiwanie zależności.
Zamiast:
$repo = new ProductRepository();
$logger = new Logger();
w każdej metodzie, wstrzykuj zależności.
Koncepcyjnie:
public function __construct(
ProductRepository $repository,
LoggerInterface $logger
) {
$this->repository = $repository;
$this->logger = $logger;
}
Korzyści obejmują:
- łatwość testowania;
- jasne zależności;
- łatwiejsza wymiana;
- walidacja kontenera.
11. Skonfiguruj usługi
Typowy plik usług modułu może używać:
services:
_defaults:
public: false
autowire: true
autoconfigure: true
Vendor\Module\:
resource: '../src/'
Starannie dostosuj zakres zasobów.
Nie rejestruj automatycznie klas, które nie powinny być usługami.
12. Kontrolery PrestaShop 9 muszą być usługami
Aktualna dokumentacja PrestaShop 9 wyraźnie zaznacza, że nowoczesne kontrolery muszą być definiowane jako usługi.
Kontroler można skonfigurować za pomocą:
services:
Vendor\Module\Controller\Admin\ExampleController:
autowire: true
autoconfigure: true
tags:
- { name: controller.service_arguments }
lub przez domyślne ustawienia usług.
Jeśli kontroler nie zostanie poprawnie zarejestrowany, nie zadziała.
13. Zachowaj lekkie kontrolery
Kontroler powinien:
- przyjąć żądanie;
- sprawdzić uprawnienia;
- zweryfikować dane wejściowe;
- wywołać usługę;
- zwrócić odpowiedź.
Nie pisz surowego SQL ani logiki importu bezpośrednio w metodach kontrolera.
Lekkie kontrolery ułatwiają:
- testowanie;
- ponowne wykorzystanie;
- utrzymanie.
14. Korzystaj z tras dla nowoczesnych stron
Nowoczesne strony Back Office powinny korzystać z routingu Symfony.
Koncepcyjnie plik tras może wyglądać następująco:
mymodule_dashboard:
path: /mymodule/dashboard
methods: [GET]
defaults:
_controller: 'Vendor\Module\Controller\Admin\DashboardController::index'
Używaj nazw tras konsekwentnie.
Unikaj kolizji z innymi modułami.
15. Twórz strony konfiguracji z uwzględnieniem zakresu
Prosty moduł może przechowywać ustawienia w konfiguracji PrestaShop.
Określ jednak, czy wartości są:
- globalne;
- dla grupy sklepów;
- specyficzne dla sklepu.
Błędy w trybie multistore często wynikają z ignorowania zakresu.
Ustawienie takie jak:
URL API dostawcy
może być inne dla każdego sklepu.
Inne ustawienie, takie jak:
globalny serwer licencji
może być współdzielone.
Najpierw określ znaczenie biznesowe.
16. Projektuj tabele bazy danych z myślą o skali
Jeśli moduł potrzebuje trwałego przechowywania danych, projektuj tabele wokół rzeczywistych wzorców dostępu.
Dla tabeli kolejki:
CREATE TABLE ps_mymodule_queue (
id_queue BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
id_shop INT UNSIGNED NOT NULL,
status VARCHAR(32) NOT NULL,
payload LONGTEXT NULL,
attempts INT UNSIGNED NOT NULL DEFAULT 0,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
PRIMARY KEY (id_queue)
);
Następnie zastanów się, jakie zapytania będą wykonywane.
Jeśli procesy robocze często filtrują według:
id_shop + status
dodaj odpowiedni indeks.
17. Unikaj surowych danych użytkownika w SQL
Nigdy nie sklejaj niezaufanych wartości z SQL.
Źle:
$sql = "SELECT * FROM table WHERE name = '" . $_GET['name'] . "'";
Korzystaj z narzędzi bazodanowych PrestaShop i bezpiecznego escapowania albo, gdy to właściwe, z parametryzowanych zapytań DBAL.
Dane dostawcy również są niezaufane.
Zdalny kanał XML nie powinien być uznawany za bezpieczny tylko dlatego, że pochodzi od partnera biznesowego.
18. Dodawaj skrypty aktualizacji przy zmianach schematu
Moduł produkcyjny się rozwija.
Gdy schemat się zmienia, dodaj wersjonowaną logikę aktualizacji.
Przykład:
upgrade/upgrade-1.1.0.php
Aktualizacja powinna:
- wprowadzać jedną spójną zmianę;
- jasno zwracać informację o błędzie;
- być bezpieczna przy ponownym uruchomieniu, jeśli to możliwe.
Nie ukrywaj migracji bazy danych w przypadkowym kodzie wykonywanym podczas działania aplikacji.
19. Oddziel wersję kodu od logiki migracji danych
Poprawka błędu zmieniająca wyłącznie PHP nie musi wymagać migracji bazy danych.
Zmiana schematu już tak.
Przykłady wymagające migracji:
- nowa tabela;
- nowa kolumna;
- nowy indeks;
- nowy wymagany klucz konfiguracji.
Zachowaj sensowne wersjonowanie.
20. Dodawaj polecenia CLI do ciężkich zadań
PrestaShop korzysta z komponentu Symfony Console.
Twórcy modułów mogą dodawać własne polecenia.
Korzystaj z CLI do:
- importów;
- eksportów;
- skanów integralności;
- porządkowania;
- przetwarzania obrazów;
- procesów roboczych kolejek.
Polecenie można zaplanować za pomocą crona.
To znacznie bezpieczniejsze niż wymaganie od administratora utrzymywania otwartej karty przeglądarki.
21. Zwracaj przydatne kody wyjścia
Polecenia CLI powinny zwracać:
0 = sukces
wartość niezerowa = niepowodzenie
Dzięki temu:
- crona;
- monitoring;
- CI/CD;
mogą wykrywać błędy.
Nie wyświetlaj komunikatu „niepowodzenie”, zwracając jednocześnie sukces.
22. Dodawaj blokady do długich poleceń
Uruchomienia crona mogą się nakładać.
Jeśli polecenie uruchamia się co minutę, ale trwa trzy minuty, mogą pojawić się zduplikowane procesy robocze.
Użyj:
- czasowej dzierżawy w bazie danych;
- blokady Symfony;
- blokady Redis;
- blokady systemu plików.
Blokada powinna umożliwiać odzyskanie po awarii.
23. Umożliwiaj wznawianie zadań wsadowych
Nie przetwarzaj milionów rekordów jako jednej nieprzejrzystej operacji.
Zapisuj:
kursor
przetworzone
nieudane
ponowna próba
Dzięki temu awaria nie wymusza ponownego rozpoczęcia zadania od zera.
24. Loguj uporządkowany kontekst
Logi powinny odpowiadać na pytania:
- który sklep?
- który produkt?
- które zadanie?
- który identyfikator zewnętrzny?
- który błąd?
Przykład:
[run=203]
[shop=2]
[product=119019]
Brak mapowania kategorii dostawcy
To znacznie bardziej przydatne niż:
Coś poszło nie tak
25. Nie loguj sekretów
Nigdy nie zapisuj:
- tokenu API;
- hasła;
- sekretu klienta OAuth;
- danych płatniczych;
w logach.
Oczyść kontekst wyjątku przed jego zapisaniem.
26. Dodawaj zasoby API, gdy są potrzebne
Moduły PrestaShop 9 mogą udostępniać zasoby przez nowe API administracyjne.
Konwencja jest następująca:
src/ApiPlatform/Resources
Korzystaj z tego, gdy moduł wymaga uporządkowanej integracji zewnętrznej.
Nie twórz własnego publicznego punktu końcowego PHP tylko dlatego, że szybciej można przygotować prototyp.
27. Definiuj wąskie zakresy API
Jeśli moduł udostępnia:
uruchom skan bezpieczeństwa
odczytaj raport skanowania
utwórz osobne zakresy, takie jak:
security_scan_run
security_report_read
Nie wymagaj niepowiązanych uprawnień rdzenia.
28. Weryfikuj przesyłane pliki
Jeśli moduł importuje pliki, sprawdzaj:
- rozmiar;
- rozszerzenie;
- typ MIME;
- poprawność parsowania.
Nazwa pliku kończąca się na .xml nie dowodzi, że plik zawiera poprawny XML.
Adres URL .jpg może zwrócić HTML.
Weryfikuj rzeczywistą zawartość.
29. Zabezpieczaj zdalne pobieranie
Zdalne adresy URL mogą stwarzać ryzyko fałszowania żądań po stronie serwera.
Jeśli administratorzy lub dostawcy podają adresy URL, ogranicz niebezpieczne cele.
Nie pozwalaj modułowi pobierać danych z dowolnych adresów sieci wewnętrznej bez kontroli.
Użyj:
- walidacji URL;
- list dozwolonych schematów;
- limitu czasu;
- limitów rozmiaru odpowiedzi.
30. Obsługuj multistore jawnie
Każde zapytanie powinno uwzględniać pytanie:
Czy ten rekord jest globalny, czy specyficzny dla sklepu?
Jeśli jest specyficzny dla sklepu, uwzględnij id_shop w:
- tabeli;
- indeksie;
- ograniczeniach unikalności;
- kluczach pamięci podręcznej.
Przykład:
UNIQUE(id_shop, supplier_key)
może być poprawne tam, gdzie:
UNIQUE(supplier_key)
niesłusznie blokowałoby inny sklep.
31. Testuj kontekst sklepu w cronie
Zadania CLI nie mają kontekstu sklepu wybranego przez człowieka w Back Office.
Ustawiaj lub przekazuj kontekst sklepu jawnie.
Nie polegaj na sklepie ostatnio wybranym przez pracownika.
32. Twórz przejrzyste odpowiedzi błędów
Wywołania Ajax lub API powinny zwracać uporządkowane błędy.
Przykład:
{
"success": false,
"code": "CATEGORY_MAPPING_MISSING",
"message": "Supplier category 341 is not mapped."
}
To łatwiejsze w obsłudze niż surowa strona wyjątku Symfony.
33. Testuj instalację z ZIP-a wydania
Środowiska programistyczne mogą ukrywać błędy pakowania.
Przed wydaniem:
- utwórz ZIP;
- zainstaluj go na czystej instancji PrestaShop 9;
- skonfiguruj go;
- uruchom krytyczne funkcje.
Pozwala to wykryć:
- brakujące pliki Composera;
- błędną wielkość liter w nazwach plików;
- brakujące zasoby;
- pominięte pliki kompilacji.
34. Testuj aktualizacje z poprzednich wersji
Świeża instalacja nie wystarczy.
Zainstaluj:
v1.0.0
z realistycznymi danymi.
Następnie zaktualizuj do:
v1.1.0
Sprawdź:
- schemat;
- konfiguracji;
- dane biznesowe;
- hooki.
Wiele błędów produkcyjnych występuje wyłącznie podczas aktualizacji.
35. Dodaj analizę statyczną
Używaj narzędzi takich jak:
- PHPStan;
- PHP CS Fixer;
- kontrole standardów kodowania.
Analiza statyczna wykrywa:
- błędne typy argumentów;
- brakujące klasy;
- niemożliwe gałęzie;
- problemy z wartościami dopuszczającymi null.
Jest to szczególnie przydatne przy obsłudze wielu wersji PHP.
36. Dodaj testy automatyczne
Nie wszystko wymaga pełnego testu w przeglądarce.
Użyj:
- testów jednostkowych usług;
- testów repozytoriów dla trwałego przechowywania danych;
- testów integracyjnych instalacji i aktualizacji;
- testów funkcjonalnych kontrolerów.
Najpierw skup się na przepływach pracy, które mogą uszkodzić dane biznesowe.
Przykłady:
- eksport zamówień;
- aktualizacja stanów magazynowych;
- tworzenie produktów.
37. Wspieraj tylko to, co faktycznie testujesz
Nie deklaruj:
PrestaShop 1.7–9.x
jeśli faktycznie nie testujesz tego zakresu.
Węższa obietnica kompatybilności, która działa, jest lepsza niż szeroka, która generuje zgłoszenia do pomocy technicznej.
38. Dokumentuj wymagania operacyjne
Jeśli moduł wymaga:
- crona;
- CLI;
- katalogu z prawem zapisu;
- klucza API;
- rozszerzenia PHP;
jasno to zaznacz.
Administratorzy nie powinni poznawać wymagań operacyjnych na podstawie błędów.
39. Zaplanuj zachowanie przy odinstalowaniu
Zdecyduj, co oznacza odinstalowanie.
Czy powinna usuwać:
- konfigurację?
- historię kolejki?
- rejestry audytu?
- mapowania biznesowe?
W przypadku ważnych danych rozważ osobną opcję „usuń dane”, zamiast automatycznie niszczyć wszystko.
40. Lista kontrolna modułu gotowego do produkcji
Architektura
- niewielka główna klasa modułu
- logika biznesowa w usługach
- oddzielone repozytoria
- lekkie kontrolery
- wstrzyknięte zależności
Baza danych
- schemat instalacyjny
- przydatne indeksy
- migracje aktualizacji
- ograniczenia multistore
Praca w tle
- polecenie CLI
- blokowanie
- przetwarzanie wsadowe
- stan ponownej próby
- śledzenie postępu
Bezpieczeństwo
- autoryzacja
- CSRF tam, gdzie właściwe
- bezpieczny SQL
- walidacja plików
- usuwanie sekretów z zapisywanych danych
Wydanie
- przetestowana instalacja ZIP-a na czystej instancji
- przetestowana aktualizacja
- analiza statyczna
- testy krytycznych przepływów pracy
- przetestowane odinstalowanie
Najczęściej zadawane pytania
Jaka jest minimalna struktura modułu PrestaShop?
Moduł wymaga katalogu i głównego pliku PHP o tej samej nazwie technicznej. Moduły produkcyjne zazwyczaj dodają usługi, trasy, kontrolery i inne elementy struktury.
Czy nazwa techniczna może zawierać podkreślenia?
Oficjalny samouczek PrestaShop 9 odradza podkreślenia, ponieważ nie działają poprawnie z domenami tłumaczeń.
Czy kontrolery Symfony są usługami w PrestaShop 9?
Tak. Aktualna dokumentacja stwierdza, że kontrolery PrestaShop 9 muszą być skonfigurowane jako usługi.
Czy logika biznesowa powinna znajdować się w głównej klasie modułu?
Dla rozbudowanej logiki biznesowej wybieraj usługi. Główna klasa modułu powinna skupiać się na jego cyklu życia i punktach integracji.
Czy moduł może dodawać polecenia konsoli?
Tak. PrestaShop korzysta z Symfony Console, a moduły mogą dostarczać własne polecenia.
Czy moduły mogą rozszerzać API administracyjne?
Tak. PrestaShop 9 może automatycznie wczytywać zasoby API modułu z src/ApiPlatform/Resources, gdy moduł jest zainstalowany i włączony.
Czy długie importy powinny działać w kontrolerze?
Nie. Korzystaj z CLI, crona lub procesów roboczych kolejek z przetwarzaniem wsadowym i śledzeniem postępu.
Co należy przetestować przed sprzedażą modułu?
Co najmniej: czystą instalację, konfigurację, krytyczne funkcje, aktualizację, działanie multistore, jeśli dotyczy, pakowanie i odinstalowanie.