Własne Moduły: Rozszerz Magento Bezpiecznie
Modyfikacja core Magento 2 to pewna droga do katastrofy przy każdej aktualizacji. Dowiedz się, jak tworzyć własne moduły z Plugins, DI i Declarative Schema, które przetrwają każdy upgrade i działają niezawodnie na produkcji.
0
modyfikacji core – wszystko przez Plugins i Preferences
DI
Dependency Injection – podstawa testowalnego i elastycznego kodu
PSR-12
Magento Coding Standard – wymagany do przejścia code review
Magento 2 zostało zaprojektowane tak, żeby można je było rozszerzać bez ingerencji w kod źródłowy. Każda zmiana zachowania platformy powinna odbywać się przez dedykowany mechanizm rozszerzeń: Plugins do metod, Preferences do podmienienia klas, Observers do zdarzeń i Declarative Schema do zmian w bazie danych. To gwarantuje, że Twój moduł będzie działał po każdej aktualizacji Magento.
Struktura i rejestracja modułu
Każdy moduł Magento 2 to katalog w app/code/Vendor/ModuleName/ z minimalnymi plikami rejestracyjnymi. Bez nich Magento nie rozpozna Twojego kodu. Sekcja <sequence> w module.xml kontroluje kolejność ładowania – jeśli Twój moduł nadpisuje moduł bazowy, musi się ładować po nim.
Minimalna struktura modułu + rejestracja
Dwa pliki wymagane do rejestracji modułu oraz komendy aktywacji. Bez setup:upgrade Magento nie wykryje zmian w schemacie bazy danych.
// app/code/Vendor/ModuleName/registration.php
use Magento\Framework\Component\ComponentRegistrar;
ComponentRegistrar::register(
ComponentRegistrar::MODULE,
'Vendor_ModuleName',
__DIR__
);
<!-- app/code/Vendor/ModuleName/etc/module.xml -->
<config>
<module name="Vendor_ModuleName" setup_version="1.0.0">
<sequence><module name="Magento_Catalog"/></sequence>
</module>
</config>
# Aktywacja modułu:
php bin/magento module:enable Vendor_ModuleName
php bin/magento setup:upgrade && php bin/magento setup:di:compile
Plugins (Interceptors) – najważniejszy mechanizm rozszerzeń
Plugins to podstawowy sposób rozszerzania zachowania klas Magento 2 bez ich modyfikacji. Pozwalają na uruchomienie kodu przed (before), po (after) lub zamiast (around) oryginalnej metody. Są bezpieczne, łatwe w testowaniu i nie kolidują z innymi modułami (kilka Pluginów może działać jednocześnie na tej samej metodzie).
Pro Tip: Plugin after vs around – kiedy użyć czego?
Użwaj around tylko gdy musisz warunkowo zapobiec wywołaniu oryginalnej metody. We wszystkich innych przypadkach before lub after są lepsze – są szybsze i nie blokują innych Pluginów w łańcuchu wywołań.
<!-- etc/di.xml -->
<type name="Magento\Catalog\Model\Product">
<plugin name="vendor_module_product_plugin"
type="Vendor\ModuleName\Plugin\ProductPlugin"/>
</type>
// Plugin/ProductPlugin.php
public function afterGetName(Product $subject, string $result): string {
return $result . ' [OUTLET]'; // dołącz tekst po nazwie
}
public function beforeSetPrice(Product $subject, float $price): array {
return [$price * 0.9]; // rabat 10% przed zapisem
}
Declarative Schema – zmiany w bazie bez Install Scripts
Od Magento 2.3 migracje bazy danych powinny być deklarowane w pliku etc/db_schema.xml. To lepsze podejście niż stare InstallSchema/UpgradeSchema – Magento sam wykrywa różnice i stosuje tylko niezbędne ALTER TABLE. Nie musisz się martwić o wersjonowanie skryptów.
db_schema.xml + wygenerowanie whitelist
Przykład dodania nowej tabeli z kluczem obcym do produktu. Po każdej zmianie db_schema.xml musisz wygenerować plik db_schema_whitelist.json.
<!-- etc/db_schema.xml -->
<schema>
<table name="vendor_custom_data" resource="default" engine="innodb">
<column name="entity_id" xsi:type="int" unsigned="true" nullable="false" identity="true"/>
<column name="product_id" xsi:type="int" unsigned="true" nullable="false"/>
<column name="custom_value" xsi:type="varchar" length="255" nullable="true"/>
<constraint xsi:type="primary" referenceId="PRIMARY">
<column name="entity_id"/>
</constraint>
</table>
</schema>
# Wygeneruj whitelist po każdej zmianie schematu:
php bin/magento setup:db-declaration:generate-whitelist --module-name=Vendor_ModuleName
# Zastosuj zmiany w bazie:
php bin/magento setup:upgrade
Kiedy użyć jakiego mechanizmu?
Plugin – modyfikacja metody klasy
Zmień zachowanie przed/po/zamiast konkretnej metody publicznej. Nie wymaga nadpisywania całej klasy. Preferowany mechanizm rozszerzeń.
Preference – podmiana całej klasy
Używaj tylko gdy Plugin nie wystarczy (np. zmiana prywatnych metod). Twoja klasa dziedziczy z oryginalnej i nadpisuje wybrane metody.
Observer – reakcja na zdarzenie
Niezbędny gdy chcesz reagować na eventy Magento (np. sales_order_place_after). Nie blokuje wywołania oryginalnego kodu.
Cron Job – zadania cykliczne
Zdefiniuj w etc/crontab.xml. Magento zarządza kolejką crona niezależnie od systemu – sprawdzaj tabelę cron_schedule.
API REST/GraphQL – nowy endpoint
Zdefiniuj w etc/webapi.xml i etc/schema.graphqls. Dostęp kontrolowany przez ACL (etc/acl.xml).
UI Component – rozszerzenie panelu Admin
Dodaj kolumny do gridów, nowe pola w formularzach lub całkowicie nowe sekcje w Adminie przy użyciu XML i knockout.js binding.
Najczęstsze błędy przy tworzeniu modułów
Modyfikacja plików w vendor/
Każdy composer update nadpisze zmiany. Zawsze użwaj Plugins lub Preferences zamiast edytować kod core Magento.
Brak setup:di:compile po zmianie DI
Zmiany w etc/di.xml lub nowe klasy nie działają w trybie production bez rekompilacji kontenera DI.
ObjectManager użyty bezpośrednio
Używanie ObjectManager::getInstance() w kodzie to antywzorzec. Wstrzykuj zależności przez konstruktor – kod będzie testowalny i czytelny.
Błędna kolejność w sequence
Plugin lub Preference ładuje się przed modułem bazowym i nie działa. Sprawdź sekcję <sequence> w module.xml.
Brak whitelist dla db_schema
Po dodaniu kolumny do db_schema.xml bez regeneracji whitelist.json Magento nie zastosuje zmian lub zgłosi błąd przy setup:upgrade.
Naruszenie Magento Coding Standard
Moduł nie przechodzi code review. Uruchom vendor/bin/phpcs --standard=Magento2 app/code/Vendor/ przed każdym commitem.
Przydatne komendy deweloperskie
Zestaw komend, które przyspieszą development i debugging modułów Magento 2.
# Włącz tryb deweloperski (szybsze iteracje, widoczne błędy):
php bin/magento deploy:mode:set developer
# Wyczyść wygenerowane pliki DI i cache:
rm -rf generated/code/* generated/metadata/* var/cache/* var/page_cache/*
php bin/magento cache:flush
# Sprawdź zależności modułu (co zależy od twojego modułu):
php bin/magento module:status Vendor_ModuleName
# Analiza statyczna PHPCS ze standardem Magento2:
vendor/bin/phpcs --standard=Magento2 app/code/Vendor/ModuleName/ --extensions=php
# Wygeneruj interfejs Data Object (Value Object):
php bin/magento dev:generate:api:data-object --module=Vendor_ModuleName
# Debugowanie pluginu – lista wszystkich pluginów na metodzie:
php bin/magento dev:di:info "Magento\Catalog\Model\Product"
Tworzenie modułów Magento 2 to rzemiosło wymagające znajomości architektury platformy. W Mage24.pl każdy nasz moduł przechodzi przez code review, testy PHPUnit i analizę PHPCS – zanim trafi na produkcję klienta.
Potrzebujesz dedykowanego modułu Magento 2?
Zaprojektujemy i wdrożymy moduł zgodny z najlepszymi praktykami Magento – z testami, dokumentacją i gwarancją kompatybilności z przyszłymi wersjami.