coding 699318 1920

Pluginy w Magento 2 – tworzenie i typy

Magento Handbook

Jednym z największych problemów w Magento 1 dla osób, które chciały dostosowywać ten system do swoich potrzeb była konieczność nadpisywania klas jeśli nie można było zastosować eventów. Powodowało to wiele problemów, i konfliktów w czasie gdy kilka modułów próbowało nadpisać tą samą klasę bazową.

W Magento 2 wyeliminowano tą niedogodność poprzez wprowadzenie systemu pluginów. Zgodnie z dokumentacją jaką można znaleźć na stronie http://devdocs.magento.com/guides/v2.2/extension-dev-guide/plugins.html pluginy to klasy, które modyfikują działanie metod publicznych znajdujących się w innych klasach lub interfejsach.

Dzięki temu mechanizmowi większość modyfikacji na sklepie możemy wykonać bez nadpisywania oryginalnych klas.

Za pomocą pluginów możemy zmienić wartość parametrów przekazywanych do danej metody, zwracany przez nią wynik, lub wykonać dodatkowe operacje podczas wywołania danej funkcji.

Deklaracja Pluginów

Poza klasą, która zawiera kod pluginu, musimy też dokonać jego deklaracji – robimy to w pliku di.xml, który znajduje się w folderze etc naszego modułu.

Listing 1. Ogólna deklaracja pluginu w pliku di.xml /app/code/Vendor/Module/etc/di.xml

<?xml version="1.0"?>
<config>
    <type name="{obserwowana_klasa}">
        <plugin name="{nazwa_pluginu}" type="{klasa_pluginu}" sortOrder="1"
               disabled="false"/>
    </type>
</config>

Parametry wymagane:

  • obserwowana_klasa – klasa na której ma działać plugin
  • nazwa_pluginu – nazwa pluginu
  • klasa_pluginu – klasa ze stworzonym pluginem

Parametry opcjonalne:

  • sortOrder – kolejność wywołania pluginu
  • disabled – wyłączenie pluginu (domyślnie wartość false)

Typy pluginów

Magento 2 oferuje trzy typy pluginów. Umożliwiają one uruchomienie naszego kodu przed daną metodą, po niej lub na zewnątrz.
Deklarując klasę z pluginem należy pamiętać o tym, że metoda pluginu musi mieć taką samą nazwę jak nazwa oryginalnej metody i powinna być poprzedzona odpowiednim prefixem (before, after lub around).

Plugin Before

Uruchamiany jest przed daną metodą. Umożliwia nam zmodyfikowanie parametrów jakie są przekazywane do metody, oraz wykonanie kodu przed jej uruchomieniem. Nazwa pluginu powinna być taka sama jak nazwa metody i posiadać prefix „before”. Rezultat wykonania tego pluginu powinien być tablicą argumentów.

Listing 2. Deklaracja pluginu „before” /app/code/Vendor/Module/etc/di.xml

<?xml version="1.0"?>
<config>
    <type name="Magento\Catalog\Model\Product">
        <plugin name="before_set_sku" type="Vendor\Module\Plugin\BeforePlugin"/>
    </type>
</config>

Listing 3. Klasa z pluginem „before” /app/code/Vendor/Module/Plugin/BeforePlugin

namespace Vendor\Module\Plugin;

class BeforePlugin
{
    public function beforeSetSku(
        \Magento\Catalog\Model\Product $subject,
        $sku    
    ) {
        $sku = ‘PRODUCT_’ . $sku;
        return [$sku];
    }
}

Plugin After

Wywoływany po wykonaniu danej metody. Używany jest do modyfikacji wyników zwracanych przez daną metodę, oraz do uruchomienia kodu bezpośrednio po jej wykonaniu. Nazwa pluginu powinna być taka sama jak nazwa metody i posiadać prefix „after”

Listing 4. Deklaracja pluginu „after” /app/code/Vendor/Module/etc/di.xml

<?xml version="1.0"?>
<config>
    <type name="Magento\Catalog\Model\Product">
        <plugin name="after_get_name" type="Vendor\Module\Plugin\AfterPlugin"/>
    </type>
</config>

Listing 5. Klasa z pluginem „after” /app/code/Vendor/Module/Plugin/AfterPlugin

namespace Vendor\Module\Plugin;

class AfterPlugin
{
    public function afterGetName(
        \Magento\Catalog\Model\Product $subject,
        $result
    ) {
        return ‘Product’ . $result;
    }
}

Plugin Around

Wywoływany zarówno przed, jak i po danej metodzie. Może służyć także do jej całkowitego nadpisania. Nazwa pluginu powinna być taka sama jak nazwa metody i posiadać prefix „around”

Listing 6. Deklaracja pluginu „around” /app/code/Vendor/Module/etc/di.xml

<?xml version="1.0"?>
<config>
    <type name="Magento\Catalog\Model\Product">
        <plugin name="around_get_name" type="Vendor\Module\Plugin\AroundPlugin"/>
    </type>
</config>

Listing 7. Klasa z pluginem „around” /app/code/Vendor/Module/Plugin/AroundPlugin

namespace Vendor\Module\Plugin;

class AroundPlugin
{
    public function aroundGetName(
        \Magento\Catalog\Model\Product $subject,
        callable $proceed
    ) {
        $status = $subject→getStatus();
        $name = $proceed();

        if ($status == 1) {
            $returnValue = ‘Enabled: ’ . $name;
        } else {
            $returnValue = ‘Disabled: ’ . $name;
        }
        return $returnValue;
    }
}

Ograniczenia przy stosowaniu pluginów.

Pluginów możemy używać tylko i wyłącznie dla publicznych metod. Oznacza to, że nie będą one działać dla:

  • Finalnych metod
  • Finalnych klas
  • Konstruktorów klas
  • Klas inicjowanych przed klasą do obsługi pluginów
  • Wirtualnych typach
  • Nie publicznych metodach
  • Statycznych metodach

Podsumowanie

Stosowanie pluginów przy pisaniu modułów i modyfikacji funkcjonalności Magento 2 minimalizuje konflikty między rozszerzeniami. Kod pisany przy ich użyciu jest czytelniejszy i łatwiejszy w utrzymaniu, ponieważ nie zmieniamy samej klasy, lecz modyfikujemy zachowania funkcji. Jeśli dodamy do tego możliwość ustawienia kolejności w jakiej pluginy będą się uruchamiać, otrzymujemy bardzo przydatne narzędzie, które warto stosować we własnych projektach opartych o Magento 2.

Dodaj komentarz

Twój adres email nie zostanie opublikowany.