Przejdź do głównej treści

EventListener i EventSubscriber


Events

Różnice miedzy Listener-em a Subscriber-em

Główna różnica w stosunku do Event Listener polega na tym, że EventSubscriber zawsze zna zdarzenia, które nasłuchuje. Jeżeli różne metody EventSubscriber nasłuchują tego samego zdarzenia, ich kolejność określa parametr priorytetu. Ta wartość jest dodatnią lub ujemną liczbą całkowitą, która domyślnie wynosi 0.

Event Listener czy Event Subscriber

Listener i Subscriber mogą być wykorzystywani w tej samej aplikacji w sposób nierozróżnialny. Decyzje by użyć którąkolwiek z nich najczęściej decyduje dobry smak programisty.

Jednakże, są ważne zalety każdego typu zdarzenia:

  • Subscriber jest łatwiejszy do ponownego użycia ponieważ wiedza o zdarzeniach jest przechowywana w klasie, a nie w definicji usługi.
  • Listener jest bardziej elastyczny ponieważ pakiety mogą warunkowo włączać lub wyłączać każdy z nich w zależności od pewnej wartości konfiguracyjnej.

Event Listener

Nazwa klasy, (którą się podaje jako pierwszy parametr podczas rejestracji) musi implementować interfejs:

  • AsynchronousListenerInterface - Wykonanie kodu odbywa się w tle za pomocą kolejki BgTask, w razie niepowodzenia loguje błąd.
  • SynchronousListenerInterface - Wczytuje lisynera i przekazuje obiekt do metody onEvent.

Interface wymusza by dodać metodę onEvent(object $event): void, w której należy obsłużyć przychodzący obiekt eventu, który podaliśmy podczas rejestracji.

Przykład Listenera

Listener z przykładu jest odpowiedzialny za:

  • ustawienie pola dscrpt w tryb read only oraz dodatkowo ustawienie na tym polu disable

W listynerze sprawdzamy czy otrzymany event jest obiektem utworzonym z konkretnej klasy, w tym przypadku z \Ready\App\Processes\Event\MainFormCreated (tak jak namespace mówi obiekt event-u znajduje się w corze w folderze ./src/).

<?php

namespace ReadyApp\Projekty\Forms\Plugins;

use Ready\Component\System\Events\Listener\SynchronousListenerInterface;

final class ProcessMainGeneralFormAfterCreate implements SynchronousListenerInterface {

    public function onEvent(object $event): void {
        if ($event instanceof \Ready\App\Processes\Event\MainFormCreated) {
            $processes = $event->getProcess();
            $processes->dscrpt->disable();
            $processes->dscrpt->setReadOnly(TRUE);
        }
    }
}

Event Subscriber

Nazwa klasy, (którą się podaje jako pierwszy parametr podczas rejestracji) musi implementować interfejs:

  • AsynchronousSubscriberInterface - Dodaje subscriber do kolejki rabita. Wykonanie kodu odbywa się w tle za pomocą kolejki BgTask.
  • SynchronousSubscriberInterface - Dodaje subscriber za pomocą addSubscriber do SymfonyEventDispatcher.

Interface wymusza by dodać metodę getSubscribedEvents(): void, w której należy obsłużyć przychodzący obiekt eventu, który podaliśmy podczas rejestracji.

<?php

namespace ReadyApp\Projekty\Forms\Plugins;

use Ready\Component\System\Events\Subscriber\SynchronousSubscriberInterface;
use Ready\App\Processes\Event\MainFormCreated;

final class ProcessMainGeneralFormAfterCreate implements SynchronousSubscriberInterface {
    
    /**
     * @return array[]|\array[][]|string[]
     */
    public static function getSubscribedEvents(): array {
        return [
            MainFormCreated::class => 'onEvent',
        ];
    }

    public function onEvent(object $event): void {
        if ($event instanceof \Ready\App\Processes\Event\MainFormCreated) {
            $processes = $event->getProcess();
            $processes->dscrpt->disable();
            $processes->dscrpt->setReadOnly(TRUE);
        }
    }
}

Przykład skryptu:

ProcessMainGeneralFormAfterCreate.inc

metoda getSubscribedEvents

Posiada także możliwość zadeklarowania wielu metod:

['eventName' => 'methodName']
['eventName' => ['methodName', $priority]]
['eventName' => [['methodName1', $priority], ['methodName2']]]

Jeśli nie podamy priorytetu, deflaut - owo jest ustawiana wartość 0.