Jak zbudować moduł PrestaShop 9: od szkieletu do produkcji

63 Views

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:

  1. przyjąć żądanie;
  2. sprawdzić uprawnienia;
  3. zweryfikować dane wejściowe;
  4. wywołać usługę;
  5. 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:

  1. utwórz ZIP;
  2. zainstaluj go na czystej instancji PrestaShop 9;
  3. skonfiguruj go;
  4. 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.

Powiązane przewodniki i zasoby PrestaShop 9