Cytat
Jeśli chcę sobie podpiąć Listener pod zdarzenie, które wykonuje się na samym początku, zaraz po uruchomieniu aplikacji, to muszę zdefiniować service i poinformować w tej definicji DIC, że ma go podpiąć pod takie a nie inne zdarzenie?
Nie musisz, a możesz - to tylko jeden z możliwych sposobów, aczkolwiek najczęściej właśnie tak będziesz chciał to robić.
Zdefiniuj dokładniej co masz dokładnie na myśli pisząc "zaraz po uruchomieniu aplikacji". Aplikacja uruchamia się na linii nr 1 w pliku app.php, ale Tobie zapewne chodzi o jakiś moment, w którym cały framework już działa i masz dostęp do pewnych zasobów. Napisz co dokładnie chciałbyś uzyskać to podpowiem Ci, kiedy i jak powinieneś to uruchomić.
Cytat
Po prostu nie umiałem sobie wyobrazić, jak podpiąć Listener z Bundle'a, który byłby informowany o zdarzeniu jeszcze przed tym, jak wywoływany jest kontroler tego Bundle.
Symfony ma tutaj bardzo prostą architekturę. Musisz to zrobić po prostu zanim zostanie wywołana akcja z kontrolera. A co się dzieje zanim akcja zostanie wywołana? (w uproszczeniu)
1. Jeżeli jeszcze nie istnieje budowany jest kontener zależności (m. in. na podstawie plików XML). W ostatnim etapie jego budowania obsługiwane są TAG-i
kernel.event_listener oraz
kernel.event_subscriber, które powodują, że wygenerowany kod tworzący obiekt EventDispatchera od razu będzie miał dodane coś na kształt poniższego:
// pseudokod
function getEventDispatcherService() {
$obj = new EventDispatcher(); // definicja <service ...> z XML-a
// to zostanie dodane dzięki tagom:
$obj->addListener('kernel.request', getMyCustomKernelRequestListenerService());
$obj->addListener('kernel.request', getMyAnotherCustomKernelRequestListenerService());
$obj->addSubscriber('kernel.response', getMyCustomKernelResponseListenerService());
return $obj;
}
Dzięki temu, gdy albo Ty, albo samo Symfony wywoła
$container->get('event_dispatcher') wywołana zostanie ta funkcja (tylko raz w obrębie całego życia aplikacji - w kontekście żądania HTTP) i zwrócony zostanie EventDispatcher z już podpiętymi listenerami.
2. Następnie wszystko jest inicjalizowane, tj. odpalane są wszystkie bundle, tj. metoda boot() z MojProjekt\Abcdef\MojProjektAbcdefBundle. Tam możesz na dobrą sprawę zrobić co chcesz - masz dostęp do DIC-a więc możesz odwołać się do wszystkiego. Czyli możesz też dodać kolejnego listenera do EventDispatchera.
3. Następnie odpalane jest serce całego systemu, czyli
Symfony\Component\HttpKernelHttpKernel::handleRaw(). Metoda ta przy pomocy EventDispatchera rzuca następującymi zdarzeniami
kernel.request - to prawodpodobnie właśnie pod to chcesz się podpiąć,
kernel.controller - tutaj wiadomo już jaki konkertnie kontroler i jaka akcja będą miały zostać odpalone, dopiero po tych dwóch zdarzeniach faktycznie odpalana jest akcja z kontrolera.