Skip to content

Commit 2c54257

Browse files
committed
Merge branch '2.0' of git://github.com/ricardclau/symfony-docs into ricardclau-2.0
2 parents d041dca + 723d9b3 commit 2c54257

File tree

1 file changed

+70
-14
lines changed

1 file changed

+70
-14
lines changed

cookbook/event_dispatcher/before_after_filters.rst

+70-14
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,16 @@ token.
3030
in config and neither database setup nor authentication via
3131
the Security component will be used.
3232

33-
Creating a before filter with a controller.request event
34-
--------------------------------------------------------
33+
Adding a hash to a JSON Response
34+
--------------------------------
35+
36+
In the same context as the token example imagine that we want to add a sha1
37+
hash (with a salt using that token) to all our responses.
38+
39+
So, after generating a JSON response, this hash has to be added to the response.
40+
41+
Before and after filters with ``kernel.controller`` / ``kernel.response`` events
42+
--------------------------------------------------------------------------------
3543

3644
Basic Setup
3745
~~~~~~~~~~~
@@ -67,11 +75,15 @@ You can add basic token configuration using ``config.yml`` and the parameters ke
6775
));
6876
6977
Tag Controllers to be checked
70-
-----------------------------
78+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
7179

7280
A ``kernel.controller`` listener gets notified on every request, right before
73-
the controller is executed. First, you need some way to identify if the controller
74-
that matches the request needs token validation.
81+
the controller is executed. Same happens to ``kernel.response`` listeners
82+
after the controller returns a Response object.
83+
84+
So, first, you need some way to identify if the controller that matches the
85+
request needs token validation. Regarding the response, you will also need
86+
some way to identify that the response needs to be hashed.
7587

7688
A clean and easy way is to create an empty interface and make the controllers
7789
implement it::
@@ -80,18 +92,36 @@ implement it::
8092

8193
interface TokenAuthenticatedController
8294
{
83-
// Nothing here
95+
// ...
96+
}
97+
98+
And also create a ``HashedResponse`` object extending ``Response``
99+
100+
namespace Acme\DemoBundle\Response;
101+
102+
use Symfony\Component\HttpFoundation\Response;
103+
104+
class HashedResponse extends Response
105+
{
106+
// ...
84107
}
85108

86109
A controller that implements this interface simply looks like this::
87110

111+
use Acme\DemoBundle\Controller\TokenAuthenticatedController;
112+
use Acme\DemoBundle\Response\HashedResponse;
113+
88114
class FooController implements TokenAuthenticatedController
89115
{
90-
// ... Your actions that need authentication
116+
// An action that needs authentication and signature
117+
public function barAction()
118+
{
119+
return new HashedResponse('Hello world');
120+
}
91121
}
92122

93123
Creating an Event Listener
94-
--------------------------
124+
~~~~~~~~~~~~~~~~~~~~~~~~~~
95125

96126
Next, you'll need to create an event listener, which will hold the logic
97127
that you want executed before your controllers. If you're not familiar with
@@ -101,10 +131,12 @@ event listeners, you can learn more about them at :doc:`/cookbook/service_contai
101131
namespace Acme\DemoBundle\EventListener;
102132

103133
use Acme\DemoBundle\Controller\TokenAuthenticatedController;
134+
use Acme\DemoBundle\Response\HashedResponse;
135+
104136
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
105137
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
106138

107-
class BeforeListener
139+
class BeforeAndAfterListener
108140
{
109141
private $tokens;
110142

@@ -132,14 +164,34 @@ event listeners, you can learn more about them at :doc:`/cookbook/service_contai
132164
}
133165
}
134166
}
167+
168+
public function onKernelResponse(FilterResponseEvent $event)
169+
{
170+
$response = $event->getResponse();
171+
172+
if ($response instanceof HashedResponse) {
173+
$token = $event->getRequest()->get('token');
174+
175+
$hash = sha1($response->getContent().$token);
176+
177+
$response->setContent(
178+
json_encode(array(
179+
'hash' => $hash,
180+
'content' => $response->getContent(),
181+
))
182+
);
183+
}
184+
}
135185
}
136186

137187
Registering the Listener
138-
------------------------
188+
~~~~~~~~~~~~~~~~~~~~~~~~
139189

140190
Finally, register your listener as a service and tag it as an event listener.
141191
By listening on ``kernel.controller``, you're telling Symfony that you want
142-
your listener to be called just before any controller is executed:
192+
your listener to be called just before any controller is executed. And by
193+
listening on ``kernel.response``, your listener will be called after returning
194+
a Response:
143195

144196
.. configuration-block::
145197

@@ -148,25 +200,29 @@ your listener to be called just before any controller is executed:
148200
# app/config/config.yml (or inside your services.yml)
149201
services:
150202
demo.tokens.action_listener:
151-
class: Acme\DemoBundle\EventListener\BeforeListener
203+
class: Acme\DemoBundle\EventListener\BeforeAndAfterListener
152204
arguments: [ %tokens% ]
153205
tags:
154206
- { name: kernel.event_listener, event: kernel.controller, method: onKernelController }
207+
- { name: kernel.event_listener, event: kernel.response, method: onKernelResponse }
155208
156209
.. code-block:: xml
157210
158211
<!-- app/config/config.xml (or inside your services.xml) -->
159-
<service id="demo.tokens.action_listener" class="Acme\DemoBundle\EventListener\BeforeListener">
212+
<service id="demo.tokens.action_listener" class="Acme\DemoBundle\EventListener\BeforeAndAfterListener">
160213
<argument>%tokens%</argument>
161214
<tag name="kernel.event_listener" event="kernel.controller" method="onKernelController" />
215+
<tag name="kernel.event_listener" event="kernel.response" method="onKernelResponse" />
162216
</service>
163217
164218
.. code-block:: php
165219
166220
// app/config/config.php (or inside your services.php)
167221
use Symfony\Component\DependencyInjection\Definition;
168222
169-
$listener = new Definition('Acme\DemoBundle\EventListener\BeforeListener', array('%tokens%'));
223+
$listener = new Definition('Acme\DemoBundle\EventListener\BeforeAndAfterListener', array('%tokens%'));
170224
$listener->addTag('kernel.event_listener', array('event' => 'kernel.controller', 'method' => 'onKernelController'));
225+
$listener->addTag('kernel.event_listener', array('event' => 'kernel.response', 'method' => 'onKernelResponse'));
171226
$container->setDefinition('demo.tokens.action_listener', $listener);
172227
228+

0 commit comments

Comments
 (0)