From 0184e0f0ece5a1e9841440325e8cade181390582 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jes=C3=BAs=20Miguel=20Benito=20Calzada?= Date: Mon, 1 Dec 2014 20:24:37 +0100 Subject: [PATCH 1/9] Added a note about the priority meaning in event subscribers Conflicts: cookbook/service_container/event_listener.rst --- cookbook/event_dispatcher/event_listener.rst | 160 ++++++++++++++++--- 1 file changed, 139 insertions(+), 21 deletions(-) diff --git a/cookbook/event_dispatcher/event_listener.rst b/cookbook/event_dispatcher/event_listener.rst index 3dd9987266c..41d2578b1c7 100644 --- a/cookbook/event_dispatcher/event_listener.rst +++ b/cookbook/event_dispatcher/event_listener.rst @@ -1,27 +1,34 @@ .. index:: single: Events; Create listener + single: Create subscriber -How to Create an Event Listener -=============================== +How to Create Event Listeners and Subscribers +============================================= Symfony has various events and hooks that can be used to trigger custom behavior in your application. Those events are thrown by the HttpKernel component and can be viewed in the :class:`Symfony\\Component\\HttpKernel\\KernelEvents` class. To hook into an event and add your own custom logic, you have to create -a service that will act as an event listener on that event. In this entry, -you will create a service that will act as an exception listener, allowing -you to modify how exceptions are shown by your application. The ``KernelEvents::EXCEPTION`` -event is just one of the core kernel events:: +a service that listens to that event. You can do that in two different ways, +creating an event listener or an event subscriber instead. In this entry, +you will see the two ways of creating a service that will act as an exception +listener, allowing you to modify how exceptions are shown by your application. +The ``KernelEvents::EXCEPTION`` event is just one of the core kernel events. - // src/AppBundle/EventListener/AcmeExceptionListener.php +Creating an Event Listener +-------------------------- + +The most common way to listen to an event is to register an event listener:: + + // src/AppBundle/EventListener/ExceptionListener.php namespace AppBundle\EventListener; use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; - class AcmeExceptionListener + class ExceptionListener { public function onKernelException(GetResponseForExceptionEvent $event) { @@ -43,7 +50,7 @@ event is just one of the core kernel events:: $response->setStatusCode($exception->getStatusCode()); $response->headers->replace($exception->getHeaders()); } else { - $response->setStatusCode(500); + $response->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR); } // Send the modified response object to the event @@ -51,18 +58,15 @@ event is just one of the core kernel events:: } } +.. versionadded:: 2.4 + Support for HTTP status code constants was introduced in Symfony 2.4. + .. tip:: Each event receives a slightly different type of ``$event`` object. For the ``kernel.exception`` event, it is :class:`Symfony\\Component\\HttpKernel\\Event\\GetResponseForExceptionEvent`. To see what type of object each event listener receives, see :class:`Symfony\\Component\\HttpKernel\\KernelEvents`. -.. note:: - - When setting a response for the ``kernel.request``, ``kernel.view`` or - ``kernel.exception`` events, the propagation is stopped, so the lower - priority listeners on that event don't get called. - Now that the class is created, you just need to register it as a service and notify Symfony that it is a "listener" on the ``kernel.exception`` event by using a special "tag": @@ -71,7 +75,7 @@ using a special "tag": .. code-block:: yaml - # app/config/services.yml + # app/config/config.yml services: kernel.listener.your_listener_name: class: AppBundle\EventListener\AcmeExceptionListener @@ -80,14 +84,14 @@ using a special "tag": .. code-block:: xml - + .. code-block:: php - // app/config/services.php + // app/config/config.php $container ->register('kernel.listener.your_listener_name', 'AppBundle\EventListener\AcmeExceptionListener') ->addTag('kernel.event_listener', array('event' => 'kernel.exception', 'method' => 'onKernelException')) @@ -96,12 +100,124 @@ using a special "tag": .. note:: There is an additional tag option ``priority`` that is optional and defaults - to 0. The listeners will be executed in the order of their priority (highest to lowest). - This is useful when you need to guarantee that one listener is executed before another. + to 0. This value can be from -255 to 255, and the listeners will be executed + in the order of their priority (highest to lowest). This is useful when + you need to guarantee that one listener is executed before another. + +Creating an Event Subscriber +---------------------------- + +Another way to listen to events is via an event subscriber. An event subscriber +can define one or various methods that listen to one or various events, +and can set a priority for each method. The higher the priority, the earlier +the method is called. To learn more about event subscribers, see :doc:`/components/event_dispatcher/introduction`. +The following example shows a subscriber that subscribes various methods +to the ``kernel.exception`` event:: + + // src/AppBundle/EventListener/ExceptionSubscriber.php + namespace AppBundle\EventSubscriber; + + use Symfony\Component\EventDispatcher\EventSubscriberInterface; + use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; + use Symfony\Component\HttpFoundation\Response; + use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; + + class ExceptionSubscriber implements EventSubscriberInterface + { + public static function getSubscribedEvents() + { + // Return the events it is subscribed to, the methods that listen each event and the + // priority of each method + return array( + 'kernel.exception' => array( + array('onKernelExceptionPre', 10), + array('onKernelExceptionMid', 5), + array('onKernelExceptionPost', 0), + ) + ); + } + + public function onKernelExceptionPre(GetResponseForExceptionEvent $event) + { + $exception = $event->getException(); + $message = sprintf( + 'My Error says: %s with code: %s', + $exception->getMessage(), + $exception->getCode() + ); + + $response = new Response(); + $response->setContent($message); + + if ($exception instanceof HttpExceptionInterface) { + $response->setStatusCode($exception->getStatusCode()); + $response->headers->replace($exception->getHeaders()); + } else { + $response->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR); + } + + $event->setResponse($response); + } + + public function onKernerlExceptionMid(GetResponseForExceptionEvent $event) + { + // ... + } + + public function onKernerlExceptionPost(GetResponseForExceptionEvent $event) + { + // ... + } + } + +Now, you just need to register the class as a service and notify Symfony that it +is an event subscriber: + +.. configuration-block:: + + .. code-block:: yaml + + # app/config/config.yml + services: + kernel.listener.your_subscriber_name: + class: AppBundle\EventSubscriber\AcmeExceptionSubscriber + tags: + - { name: kernel.event_subscriber } + + .. code-block:: xml + + + + + + + + + + + + + + + .. code-block:: php + + // app/config/config.php + $container + ->register( + 'acme_exception_subscriber', + 'AppBundle\EventSubscriber\AcmeExceptionSubscriber' + ) + ->addTag('kernel.event_subscriber') + ; Request Events, Checking Types ------------------------------ +.. versionadded:: 2.4 + The ``isMasterRequest()`` method was introduced in Symfony 2.4. + Prior, the ``getRequestType()`` method must be used. + A single page can make several requests (one master request, and then multiple sub-requests), which is why when working with the ``KernelEvents::REQUEST`` event, you might need to check the type of the request. This can be easily @@ -117,7 +233,7 @@ done as follow:: { public function onKernelRequest(GetResponseEvent $event) { - if (HttpKernel::MASTER_REQUEST != $event->getRequestType()) { + if (!$event->isMasterRequest()) { // don't do anything if it's not the master request return; } @@ -131,3 +247,5 @@ done as follow:: Two types of request are available in the :class:`Symfony\\Component\\HttpKernel\\HttpKernelInterface` interface: ``HttpKernelInterface::MASTER_REQUEST`` and ``HttpKernelInterface::SUB_REQUEST``. + +.. _`The EventDispatcher component`: http://symfony.com/doc/current/components/event_dispatcher/index.html From 9a6dab70bc297650b4874ee33d1fe8f7cd007297 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Wed, 10 Jun 2015 20:04:41 +0200 Subject: [PATCH 2/9] Completed the cookbook about the event subscriber --- cookbook/event_dispatcher/event_listener.rst | 112 +++++++++---------- 1 file changed, 51 insertions(+), 61 deletions(-) diff --git a/cookbook/event_dispatcher/event_listener.rst b/cookbook/event_dispatcher/event_listener.rst index 41d2578b1c7..43089685cd6 100644 --- a/cookbook/event_dispatcher/event_listener.rst +++ b/cookbook/event_dispatcher/event_listener.rst @@ -6,23 +6,25 @@ How to Create Event Listeners and Subscribers ============================================= Symfony has various events and hooks that can be used to trigger custom -behavior in your application. Those events are thrown by the HttpKernel -component and can be viewed in the :class:`Symfony\\Component\\HttpKernel\\KernelEvents` class. +actions in your application. Those events are thrown by the HttpKernel +component and they are defined in the :class:`Symfony\\Component\\HttpKernel\\KernelEvents` +class. -To hook into an event and add your own custom logic, you have to create -a service that listens to that event. You can do that in two different ways, -creating an event listener or an event subscriber instead. In this entry, -you will see the two ways of creating a service that will act as an exception -listener, allowing you to modify how exceptions are shown by your application. -The ``KernelEvents::EXCEPTION`` event is just one of the core kernel events. +To hook into an event and execute your own custom logic, you have to create +a service that listens to that event. As explained in this article, you can do +that in two different ways: creating an event listener or an event subscriber. + +The examples of this article only use the ``KernelEvents::EXCEPTION`` event for +consistency purposes. In your own application you can use any event and even mix +several of them in the same subscriber. Creating an Event Listener -------------------------- -The most common way to listen to an event is to register an event listener:: +The most common way to listen to an event is to register an **event listener**:: - // src/AppBundle/EventListener/ExceptionListener.php - namespace AppBundle\EventListener; + // src/AppBundle/Listener/ExceptionListener.php + namespace AppBundle\Listener; use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; use Symfony\Component\HttpFoundation\Response; @@ -78,44 +80,50 @@ using a special "tag": # app/config/config.yml services: kernel.listener.your_listener_name: - class: AppBundle\EventListener\AcmeExceptionListener + class: AppBundle\Listener\ExceptionListener tags: - - { name: kernel.event_listener, event: kernel.exception, method: onKernelException } + - { name: kernel.event_listener, event: kernel.exception } .. code-block:: xml - - + + .. code-block:: php // app/config/config.php $container - ->register('kernel.listener.your_listener_name', 'AppBundle\EventListener\AcmeExceptionListener') - ->addTag('kernel.event_listener', array('event' => 'kernel.exception', 'method' => 'onKernelException')) + ->register('kernel.listener.your_listener_name', 'AppBundle\Listener\ExceptionListener') + ->addTag('kernel.event_listener', array('event' => 'kernel.exception')) ; .. note:: - There is an additional tag option ``priority`` that is optional and defaults - to 0. This value can be from -255 to 255, and the listeners will be executed - in the order of their priority (highest to lowest). This is useful when - you need to guarantee that one listener is executed before another. + There is an optional tag option called ``method`` which defines which method + to execute when the event is triggered. By default the name of the method is + ``on`` + "camel-cased event name". If the event is ``kernel.exception`` the + method executed by default is ``onKernelException()``. + + The other optional tag option is called ``priority`` and it defaults to ``0``. + This value ranges from ``-255`` to ``255`` and it controls the order in which + listeners are executed (the highest the priority, the earlier a listener is + executed). This is useful when you need to guarantee that one listener is + executed before another. Creating an Event Subscriber ---------------------------- -Another way to listen to events is via an event subscriber. An event subscriber -can define one or various methods that listen to one or various events, -and can set a priority for each method. The higher the priority, the earlier -the method is called. To learn more about event subscribers, see :doc:`/components/event_dispatcher/introduction`. -The following example shows a subscriber that subscribes various methods -to the ``kernel.exception`` event:: +Another way to listen to events is via an **event subscriber**, which is a class +that can define one or more methods that listen to one or various events. The +event priority can be defined for each method (the higher the priority, the earlier +the method is called). To learn more about event subscribers, read :doc:`/components/event_dispatcher/introduction`. +The following example shows an event subscriber that defines several methods which +listen to the same ``kernel.exception`` event:: - // src/AppBundle/EventListener/ExceptionSubscriber.php - namespace AppBundle\EventSubscriber; + // src/AppBundle/Subscriber/ExceptionSubscriber.php + namespace AppBundle\Subscriber; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; @@ -126,45 +134,27 @@ to the ``kernel.exception`` event:: { public static function getSubscribedEvents() { - // Return the events it is subscribed to, the methods that listen each event and the - // priority of each method + // return the subscribed events, their methods and priorities return array( 'kernel.exception' => array( - array('onKernelExceptionPre', 10), - array('onKernelExceptionMid', 5), - array('onKernelExceptionPost', 0), + array('processException', 10), + array('logException', 0), + array('notifyException', -10), ) ); } - public function onKernelExceptionPre(GetResponseForExceptionEvent $event) + public function processException(GetResponseForExceptionEvent $event) { - $exception = $event->getException(); - $message = sprintf( - 'My Error says: %s with code: %s', - $exception->getMessage(), - $exception->getCode() - ); - - $response = new Response(); - $response->setContent($message); - - if ($exception instanceof HttpExceptionInterface) { - $response->setStatusCode($exception->getStatusCode()); - $response->headers->replace($exception->getHeaders()); - } else { - $response->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR); - } - - $event->setResponse($response); + // ... } - public function onKernerlExceptionMid(GetResponseForExceptionEvent $event) + public function logException(GetResponseForExceptionEvent $event) { // ... } - public function onKernerlExceptionPost(GetResponseForExceptionEvent $event) + public function notifyException(GetResponseForExceptionEvent $event) { // ... } @@ -180,7 +170,7 @@ is an event subscriber: # app/config/config.yml services: kernel.listener.your_subscriber_name: - class: AppBundle\EventSubscriber\AcmeExceptionSubscriber + class: AppBundle\Subscriber\ExceptionSubscriber tags: - { name: kernel.event_subscriber } @@ -192,7 +182,7 @@ is an event subscriber: + class="AppBundle\Subscriber\ExceptionSubscriber"> @@ -206,7 +196,7 @@ is an event subscriber: $container ->register( 'acme_exception_subscriber', - 'AppBundle\EventSubscriber\AcmeExceptionSubscriber' + 'AppBundle\Subscriber\ExceptionSubscriber' ) ->addTag('kernel.event_subscriber') ; @@ -223,13 +213,13 @@ sub-requests), which is why when working with the ``KernelEvents::REQUEST`` event, you might need to check the type of the request. This can be easily done as follow:: - // src/AppBundle/EventListener/AcmeRequestListener.php - namespace AppBundle\EventListener; + // src/AppBundle/Listener/RequestListener.php + namespace AppBundle\Listener; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\HttpKernel; - class AcmeRequestListener + class RequestListener { public function onKernelRequest(GetResponseEvent $event) { From a44495115428ac959f4acc948266199a26762d5d Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 12 Jun 2015 22:11:01 +0200 Subject: [PATCH 3/9] Implemented the suggestions made by @xabbuh --- cookbook/event_dispatcher/event_listener.rst | 38 ++++++++------------ 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/cookbook/event_dispatcher/event_listener.rst b/cookbook/event_dispatcher/event_listener.rst index 43089685cd6..19c1a4c3ae7 100644 --- a/cookbook/event_dispatcher/event_listener.rst +++ b/cookbook/event_dispatcher/event_listener.rst @@ -5,8 +5,8 @@ How to Create Event Listeners and Subscribers ============================================= -Symfony has various events and hooks that can be used to trigger custom -actions in your application. Those events are thrown by the HttpKernel +Symfony has various events and hooks that can be used to perform custom +actions in your application. Those events are triggered by the HttpKernel component and they are defined in the :class:`Symfony\\Component\\HttpKernel\\KernelEvents` class. @@ -15,7 +15,7 @@ a service that listens to that event. As explained in this article, you can do that in two different ways: creating an event listener or an event subscriber. The examples of this article only use the ``KernelEvents::EXCEPTION`` event for -consistency purposes. In your own application you can use any event and even mix +consistency purposes. In your own application, you can use any event and even mix several of them in the same subscriber. Creating an Event Listener @@ -52,7 +52,7 @@ The most common way to listen to an event is to register an **event listener**:: $response->setStatusCode($exception->getStatusCode()); $response->headers->replace($exception->getHeaders()); } else { - $response->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR); + $response->setStatusCode(500); } // Send the modified response object to the event @@ -60,9 +60,6 @@ The most common way to listen to an event is to register an **event listener**:: } } -.. versionadded:: 2.4 - Support for HTTP status code constants was introduced in Symfony 2.4. - .. tip:: Each event receives a slightly different type of ``$event`` object. For @@ -77,7 +74,7 @@ using a special "tag": .. code-block:: yaml - # app/config/config.yml + # app/config/services.yml services: kernel.listener.your_listener_name: class: AppBundle\Listener\ExceptionListener @@ -86,14 +83,14 @@ using a special "tag": .. code-block:: xml - + .. code-block:: php - // app/config/config.php + // app/config/services.php $container ->register('kernel.listener.your_listener_name', 'AppBundle\Listener\ExceptionListener') ->addTag('kernel.event_listener', array('event' => 'kernel.exception')) @@ -101,12 +98,12 @@ using a special "tag": .. note:: - There is an optional tag option called ``method`` which defines which method + There is an optional tag attribute called ``method`` which defines which method to execute when the event is triggered. By default the name of the method is ``on`` + "camel-cased event name". If the event is ``kernel.exception`` the method executed by default is ``onKernelException()``. - The other optional tag option is called ``priority`` and it defaults to ``0``. + The other optional tag attribute is called ``priority`` which defaults to ``0``. This value ranges from ``-255`` to ``255`` and it controls the order in which listeners are executed (the highest the priority, the earlier a listener is executed). This is useful when you need to guarantee that one listener is @@ -126,8 +123,8 @@ listen to the same ``kernel.exception`` event:: namespace AppBundle\Subscriber; use Symfony\Component\EventDispatcher\EventSubscriberInterface; - use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; use Symfony\Component\HttpFoundation\Response; + use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; class ExceptionSubscriber implements EventSubscriberInterface @@ -169,7 +166,7 @@ is an event subscriber: # app/config/config.yml services: - kernel.listener.your_subscriber_name: + app.exception_subscriber: class: AppBundle\Subscriber\ExceptionSubscriber tags: - { name: kernel.event_subscriber } @@ -181,7 +178,7 @@ is an event subscriber: - @@ -195,7 +192,7 @@ is an event subscriber: // app/config/config.php $container ->register( - 'acme_exception_subscriber', + 'app.exception_subscriber', 'AppBundle\Subscriber\ExceptionSubscriber' ) ->addTag('kernel.event_subscriber') @@ -204,10 +201,6 @@ is an event subscriber: Request Events, Checking Types ------------------------------ -.. versionadded:: 2.4 - The ``isMasterRequest()`` method was introduced in Symfony 2.4. - Prior, the ``getRequestType()`` method must be used. - A single page can make several requests (one master request, and then multiple sub-requests), which is why when working with the ``KernelEvents::REQUEST`` event, you might need to check the type of the request. This can be easily @@ -218,12 +211,13 @@ done as follow:: use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\HttpKernel; + use Symfony\Component\HttpKernel\HttpKernelInterface; class RequestListener { public function onKernelRequest(GetResponseEvent $event) { - if (!$event->isMasterRequest()) { + if ($event->getRequestType() !== HttpKernelInterface::MASTER_REQUEST) { // don't do anything if it's not the master request return; } @@ -237,5 +231,3 @@ done as follow:: Two types of request are available in the :class:`Symfony\\Component\\HttpKernel\\HttpKernelInterface` interface: ``HttpKernelInterface::MASTER_REQUEST`` and ``HttpKernelInterface::SUB_REQUEST``. - -.. _`The EventDispatcher component`: http://symfony.com/doc/current/components/event_dispatcher/index.html From 36b1d106a83ca94c56420335768d148269a34322 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Wed, 17 Jun 2015 15:01:58 +0200 Subject: [PATCH 4/9] Fixed the name of the services file --- cookbook/event_dispatcher/event_listener.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cookbook/event_dispatcher/event_listener.rst b/cookbook/event_dispatcher/event_listener.rst index 19c1a4c3ae7..6ef9f399026 100644 --- a/cookbook/event_dispatcher/event_listener.rst +++ b/cookbook/event_dispatcher/event_listener.rst @@ -164,7 +164,7 @@ is an event subscriber: .. code-block:: yaml - # app/config/config.yml + # app/config/services.yml services: app.exception_subscriber: class: AppBundle\Subscriber\ExceptionSubscriber @@ -173,7 +173,7 @@ is an event subscriber: .. code-block:: xml - + @@ -189,7 +189,7 @@ is an event subscriber: .. code-block:: php - // app/config/config.php + // app/config/services.php $container ->register( 'app.exception_subscriber', From c8c8bf8497333a4414646a1787ea85e80c76d6a0 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Wed, 17 Jun 2015 15:06:10 +0200 Subject: [PATCH 5/9] Reworded the subscriber introduction --- cookbook/event_dispatcher/event_listener.rst | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/cookbook/event_dispatcher/event_listener.rst b/cookbook/event_dispatcher/event_listener.rst index 6ef9f399026..f736b9208a6 100644 --- a/cookbook/event_dispatcher/event_listener.rst +++ b/cookbook/event_dispatcher/event_listener.rst @@ -113,9 +113,15 @@ Creating an Event Subscriber ---------------------------- Another way to listen to events is via an **event subscriber**, which is a class -that can define one or more methods that listen to one or various events. The -event priority can be defined for each method (the higher the priority, the earlier -the method is called). To learn more about event subscribers, read :doc:`/components/event_dispatcher/introduction`. +that defines one or more methods that listen to one or various events. The main +difference with the event listeners is that subscribers always know which events +they are listening to. + +In a given subscriber, different methods can listen to the same event. The order +in which methods are executed is defined by the ``priority`` parameter of each +method (the higher the priority, the earlier the method is called). To learn more +about event subscribers, read :doc:`/components/event_dispatcher/introduction`. + The following example shows an event subscriber that defines several methods which listen to the same ``kernel.exception`` event:: From e56fed8cd4f11b3a711209aa5df64fc5ecd9bee8 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Wed, 24 Jun 2015 08:56:08 +0200 Subject: [PATCH 6/9] Fixed minor issues --- cookbook/event_dispatcher/event_listener.rst | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/cookbook/event_dispatcher/event_listener.rst b/cookbook/event_dispatcher/event_listener.rst index f736b9208a6..a52732b8c75 100644 --- a/cookbook/event_dispatcher/event_listener.rst +++ b/cookbook/event_dispatcher/event_listener.rst @@ -103,11 +103,12 @@ using a special "tag": ``on`` + "camel-cased event name". If the event is ``kernel.exception`` the method executed by default is ``onKernelException()``. - The other optional tag attribute is called ``priority`` which defaults to ``0``. - This value ranges from ``-255`` to ``255`` and it controls the order in which - listeners are executed (the highest the priority, the earlier a listener is - executed). This is useful when you need to guarantee that one listener is - executed before another. + The other optional tag attribute is called ``priority``, which defaults to + ``0`` and it controls the order in which listeners are executed (the highest + the priority, the earlier a listener is executed). This is useful when you + need to guarantee that one listener is executed before another. The priorities + of the internal Symfony events range from ``-255`` to ``255`` but your own + events can use any positive or negative integer. Creating an Event Subscriber ---------------------------- @@ -119,7 +120,7 @@ they are listening to. In a given subscriber, different methods can listen to the same event. The order in which methods are executed is defined by the ``priority`` parameter of each -method (the higher the priority, the earlier the method is called). To learn more +method (the higher the priority the earlier the method is called). To learn more about event subscribers, read :doc:`/components/event_dispatcher/introduction`. The following example shows an event subscriber that defines several methods which From 483f029433ce9bc8b9b6a8bab849de5069e58f67 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 7 Jul 2015 16:46:03 +0200 Subject: [PATCH 7/9] Added a note about the advantages/drawbacks of listeners/subscribers --- cookbook/event_dispatcher/event_listener.rst | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/cookbook/event_dispatcher/event_listener.rst b/cookbook/event_dispatcher/event_listener.rst index a52732b8c75..8c7ba323791 100644 --- a/cookbook/event_dispatcher/event_listener.rst +++ b/cookbook/event_dispatcher/event_listener.rst @@ -238,3 +238,16 @@ done as follow:: Two types of request are available in the :class:`Symfony\\Component\\HttpKernel\\HttpKernelInterface` interface: ``HttpKernelInterface::MASTER_REQUEST`` and ``HttpKernelInterface::SUB_REQUEST``. + +Events or Subscribers +--------------------- + +Listeners and subscribers can be used in the same application indistinctly. The +decision to use either of them is usually a matter of personal taste. However, +there are some minor advantages for each of them: + +* **Subscribers are easier to reuse** because the knowledge of the events is kept + in the class rather than in the service definition. This is the reason why + Symfony uses subscribers internally; +* **Listeners are more flexible** because bundles can enable or disable each of + them conditionally depending on some configuration value. From ba9ec6b1acc5aa3a55d79fc24b8001375fba57ba Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Wed, 2 Sep 2015 16:37:53 +0200 Subject: [PATCH 8/9] Reworded the introduction and other minor fixes --- cookbook/event_dispatcher/event_listener.rst | 29 ++++++++++---------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/cookbook/event_dispatcher/event_listener.rst b/cookbook/event_dispatcher/event_listener.rst index 8c7ba323791..681862986e4 100644 --- a/cookbook/event_dispatcher/event_listener.rst +++ b/cookbook/event_dispatcher/event_listener.rst @@ -5,18 +5,18 @@ How to Create Event Listeners and Subscribers ============================================= -Symfony has various events and hooks that can be used to perform custom -actions in your application. Those events are triggered by the HttpKernel -component and they are defined in the :class:`Symfony\\Component\\HttpKernel\\KernelEvents` -class. +During the execution of a Symfony application, lots of event notifications are +triggered. Your application can listen to these notifications and respond to +them by executing any piece of code. -To hook into an event and execute your own custom logic, you have to create -a service that listens to that event. As explained in this article, you can do -that in two different ways: creating an event listener or an event subscriber. +Internal events provided by Symfony itself are defined in the +:class:`Symfony\\Component\\HttpKernel\\KernelEvents` class. Third-party bundles +and libraries also trigger lots of events and your own application can trigger +:doc:`custom events `. -The examples of this article only use the ``KernelEvents::EXCEPTION`` event for -consistency purposes. In your own application, you can use any event and even mix -several of them in the same subscriber. +All the examples shown in this article use the same ``KernelEvents::EXCEPTION`` +event for consistency purposes. In your own application, you can use any event +and even mix several of them in the same subscriber. Creating an Event Listener -------------------------- @@ -107,8 +107,8 @@ using a special "tag": ``0`` and it controls the order in which listeners are executed (the highest the priority, the earlier a listener is executed). This is useful when you need to guarantee that one listener is executed before another. The priorities - of the internal Symfony events range from ``-255`` to ``255`` but your own - events can use any positive or negative integer. + of the internal Symfony listeners usually range from ``-255`` to ``255`` but + your own listeners can use any positive or negative integer. Creating an Event Subscriber ---------------------------- @@ -182,14 +182,15 @@ is an event subscriber: - + - From b5a82ca4eab8bf2982f7b39dc5346e321efac3ce Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Sat, 5 Sep 2015 15:54:14 +0200 Subject: [PATCH 9/9] Final changes --- cookbook/event_dispatcher/event_listener.rst | 44 ++++++++++++-------- 1 file changed, 27 insertions(+), 17 deletions(-) diff --git a/cookbook/event_dispatcher/event_listener.rst b/cookbook/event_dispatcher/event_listener.rst index 681862986e4..939646339a9 100644 --- a/cookbook/event_dispatcher/event_listener.rst +++ b/cookbook/event_dispatcher/event_listener.rst @@ -23,8 +23,8 @@ Creating an Event Listener The most common way to listen to an event is to register an **event listener**:: - // src/AppBundle/Listener/ExceptionListener.php - namespace AppBundle\Listener; + // src/AppBundle/EventListener/ExceptionListener.php + namespace AppBundle\EventListener; use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent; use Symfony\Component\HttpFoundation\Response; @@ -76,23 +76,33 @@ using a special "tag": # app/config/services.yml services: - kernel.listener.your_listener_name: - class: AppBundle\Listener\ExceptionListener + app.exception_listener: + class: AppBundle\EventListener\ExceptionListener tags: - { name: kernel.event_listener, event: kernel.exception } .. code-block:: xml - - - + + + + + + + + + + .. code-block:: php // app/config/services.php $container - ->register('kernel.listener.your_listener_name', 'AppBundle\Listener\ExceptionListener') + ->register('app.exception_listener', 'AppBundle\EventListener\ExceptionListener') ->addTag('kernel.event_listener', array('event' => 'kernel.exception')) ; @@ -126,8 +136,8 @@ about event subscribers, read :doc:`/components/event_dispatcher/introduction`. The following example shows an event subscriber that defines several methods which listen to the same ``kernel.exception`` event:: - // src/AppBundle/Subscriber/ExceptionSubscriber.php - namespace AppBundle\Subscriber; + // src/AppBundle/EventSubscriber/ExceptionSubscriber.php + namespace AppBundle\EventSubscriber; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\HttpFoundation\Response; @@ -164,8 +174,8 @@ listen to the same ``kernel.exception`` event:: } } -Now, you just need to register the class as a service and notify Symfony that it -is an event subscriber: +Now, you just need to register the class as a service and add the +``kernel.event_subscriber`` tag to tell Symfony that this is an event subscriber: .. configuration-block:: @@ -174,7 +184,7 @@ is an event subscriber: # app/config/services.yml services: app.exception_subscriber: - class: AppBundle\Subscriber\ExceptionSubscriber + class: AppBundle\EventSubscriber\ExceptionSubscriber tags: - { name: kernel.event_subscriber } @@ -188,7 +198,7 @@ is an event subscriber: + class="AppBundle\EventSubscriber\ExceptionSubscriber"> @@ -201,7 +211,7 @@ is an event subscriber: $container ->register( 'app.exception_subscriber', - 'AppBundle\Subscriber\ExceptionSubscriber' + 'AppBundle\EventSubscriber\ExceptionSubscriber' ) ->addTag('kernel.event_subscriber') ; @@ -214,8 +224,8 @@ sub-requests), which is why when working with the ``KernelEvents::REQUEST`` event, you might need to check the type of the request. This can be easily done as follow:: - // src/AppBundle/Listener/RequestListener.php - namespace AppBundle\Listener; + // src/AppBundle/EventListener/RequestListener.php + namespace AppBundle\EventListener; use Symfony\Component\HttpKernel\Event\GetResponseEvent; use Symfony\Component\HttpKernel\HttpKernel;