@@ -67,9 +67,9 @@ parameters key:
6767 Tag Controllers to Be Checked
6868~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
6969
70- A ``kernel.controller `` listener gets notified on * every * request, right before
71- the controller is executed. So, first, you need some way to identify if the
72- controller that matches the request needs token validation.
70+ A ``kernel.controller `` (aka `` KernelEvents::CONTROLLER ``) listener gets notified
71+ on * every * request, right before the controller is executed. So, first, you need
72+ some way to identify if the controller that matches the request needs token validation.
7373
7474A clean and easy way is to create an empty interface and make the controllers
7575implement it::
@@ -97,21 +97,23 @@ A controller that implements this interface simply looks like this::
9797 }
9898 }
9999
100- Creating an Event Listener
101- ~~~~~~~~~~~~~~~~~~~~~~~~~~
100+ Creating an Event Subscriber
101+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
102102
103103Next, you'll need to create an event listener, which will hold the logic
104104that you want to be executed before your controllers. If you're not familiar with
105105event listeners, you can learn more about them at :doc: `/event_dispatcher `::
106106
107- // src/AppBundle/EventListener/TokenListener .php
108- namespace AppBundle\EventListener ;
107+ // src/AppBundle/EventSubscriber/TokenSubscriber .php
108+ namespace AppBundle\EventSubscriber ;
109109
110110 use AppBundle\Controller\TokenAuthenticatedController;
111111 use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
112112 use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
113+ use Symfony\Component\EventDispatcher\EventSubscriberInterface;
114+ use Symfony\Component\HttpKernel\KernelEvents;
113115
114- class TokenListener
116+ class TokenSubscriber implements EventSubscriberInterface
115117 {
116118 private $tokens;
117119
@@ -140,52 +142,28 @@ event listeners, you can learn more about them at :doc:`/event_dispatcher`::
140142 }
141143 }
142144 }
143- }
144-
145- Registering the Listener
146- ~~~~~~~~~~~~~~~~~~~~~~~~
147-
148- Finally, register your listener as a service and tag it as an event listener.
149- By listening on ``kernel.controller ``, you're telling Symfony that you want
150- your listener to be called just before any controller is executed.
151-
152- .. configuration-block ::
153-
154- .. code-block :: yaml
155145
156- # app/config/services.yml
157- services :
158- app.tokens.action_listener :
159- class : AppBundle\EventListener\TokenListener
160- arguments : ['%tokens%']
161- tags :
162- - { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
163-
164- .. code-block :: xml
165-
166- <!-- app/config/services.xml -->
167- <service id =" app.tokens.action_listener" class =" AppBundle\EventListener\TokenListener" >
168- <argument >%tokens%</argument >
169- <tag name =" kernel.event_listener" event =" kernel.controller" method =" onKernelController" />
170- </service >
171-
172- .. code-block :: php
146+ public static function getSubscribedEvents()
147+ {
148+ return array(
149+ KernelEvents::CONTROLLER => 'onKernelController',
150+ );
151+ }
152+ }
173153
174- // app/config/services.php
175- use AppBundle\EventListener\TokenListener;
154+ That's it! Your ``services.yml `` file should already be setup to load services from
155+ the ``EventSubscriber `` directory. Symfony takes care of the rest. Your
156+ ``TokenSubscriber `` ``onKernelController() `` method will be executed on each request.
157+ If the controller that is about to be executed implements ``TokenAuthenticatedController ``,
158+ token authentication is applied. This lets you have a "before" filter on any controller
159+ you want.
176160
177- $container->register('app.tokens.action_listener', TokenListener::class)
178- ->addArgument('%tokens%')
179- ->addTag('kernel.event_listener', array(
180- 'event' => 'kernel.controller',
181- 'method' => 'onKernelController',
182- ));
161+ .. tip ::
183162
184- With this configuration, your ``TokenListener `` ``onKernelController() `` method
185- will be executed on each request. If the controller that is about to be executed
186- implements ``TokenAuthenticatedController ``, token authentication is
187- applied. This lets you have a "before" filter on any controller that you
188- want.
163+ If your subscriber is *not * called on each request, double-check that
164+ you're :ref: `loading services <service-container-services-load-example >` from
165+ the ``EventSubscriber `` directory and have :ref: `autoconfigure <services-autoconfigure >`
166+ enabled. You can also manually add the ``kernel.event_subscriber `` tag.
189167
190168After Filters with the ``kernel.response `` Event
191169------------------------------------------------
@@ -195,12 +173,12 @@ can also add a hook that's executed *after* your controller. For this example,
195173imagine that you want to add a sha1 hash (with a salt using that token) to
196174all responses that have passed this token authentication.
197175
198- Another core Symfony event - called ``kernel.response `` - is notified on
199- every request, but after the controller returns a Response object. Creating
200- an "after" listener is as easy as creating a listener class and registering
176+ Another core Symfony event - called ``kernel.response `` (aka `` KernelEvents::RESPONSE ``) -
177+ is notified on every request, but after the controller returns a Response object.
178+ Creating an "after" listener is as easy as creating a listener class and registering
201179it as a service on this event.
202180
203- For example, take the ``TokenListener `` from the previous example and first
181+ For example, take the ``TokenSubscriber `` from the previous example and first
204182record the authentication token inside the request attributes. This will
205183serve as a basic flag that this request underwent token authentication::
206184
@@ -219,9 +197,9 @@ serve as a basic flag that this request underwent token authentication::
219197 }
220198 }
221199
222- Now, add another method to this class - ``onKernelResponse() `` - that looks
223- for this flag on the request object and sets a custom header on the response
224- if it's found::
200+ Now, configure the subscriber to listen to another event and add ``onKernelResponse() ``.
201+ This will look for the `` auth_token `` flag on the request object and set a custom
202+ header on the response if it's found::
225203
226204 // add the new use statement at the top of your file
227205 use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
@@ -240,49 +218,16 @@ if it's found::
240218 $response->headers->set('X-CONTENT-HASH', $hash);
241219 }
242220
243- Finally, a second "tag" is needed in the service definition to notify Symfony
244- that the ``onKernelResponse `` event should be notified for the ``kernel.response ``
245- event:
246-
247- .. configuration-block ::
248-
249- .. code-block :: yaml
250-
251- # app/config/services.yml
252- services :
253- app.tokens.action_listener :
254- class : AppBundle\EventListener\TokenListener
255- arguments : ['%tokens%']
256- tags :
257- - { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
258- - { name: kernel.event_listener, event: kernel.response, method: onKernelResponse }
259-
260- .. code-block :: xml
261-
262- <!-- app/config/services.xml -->
263- <service id =" app.tokens.action_listener" class =" AppBundle\EventListener\TokenListener" >
264- <argument >%tokens%</argument >
265- <tag name =" kernel.event_listener" event =" kernel.controller" method =" onKernelController" />
266- <tag name =" kernel.event_listener" event =" kernel.response" method =" onKernelResponse" />
267- </service >
221+ public static function getSubscribedEvents()
222+ {
223+ return array(
224+ KernelEvents::CONTROLLER => 'onKernelController',
225+ KernelEvents::RESPONSE => 'onKernelResponse',
226+ );
227+ }
268228
269- .. code-block :: php
270229
271- // app/config/services.php
272- use AppBundle\EventListener\TokenListener;
273-
274- $container->register('app.tokens.action_listener', TokenListener::class)
275- ->addArgument('%tokens%')
276- ->addTag('kernel.event_listener', array(
277- 'event' => 'kernel.controller',
278- 'method' => 'onKernelController',
279- ))
280- ->addTag('kernel.event_listener', array(
281- 'event' => 'kernel.response',
282- 'method' => 'onKernelResponse',
283- ));
284-
285- That's it! The ``TokenListener `` is now notified before every controller is
230+ That's it! The ``TokenSubscriber `` is now notified before every controller is
286231executed (``onKernelController() ``) and after every controller returns a response
287232(``onKernelResponse() ``). By making specific controllers implement the ``TokenAuthenticatedController ``
288233interface, your listener knows which controllers it should take action on.
0 commit comments