8000 Add the kernel.controller_arguments event · symfony/symfony@af02e2a · GitHub
[go: up one dir, main page]

Skip to content

Commit af02e2a

Browse files
committed
Add the kernel.controller_arguments event
1 parent 45b557a commit af02e2a

8 files changed

+118
-7
lines changed

src/Symfony/Component/HttpKernel/CHANGELOG.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ CHANGELOG
1010
* added `Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface`
1111
* added `Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface` as argument to `HttpKernel`
1212
* added `Symfony\Component\HttpKernel\Controller\ArgumentResolver`
13+
* added the `kernel.controller_arguments` event, triggered after controller arguments have been resolved
1314

1415
3.0.0
1516
-----
@@ -22,8 +23,8 @@ CHANGELOG
2223
* removed `Symfony\Component\HttpKernel\EventListener\RouterListener::setRequest()`
2324
* removed `Symfony\Component\HttpKernel\EventListener\ProfilerListener::onKernelRequest()`
2425
* removed `Symfony\Component\HttpKernel\Fragment\FragmentHandler::setRequest()`
25-
* removed `Symfony\Component\HttpKernel\HttpCache\Esi::hasSurrogateEsiCapability()`
26-
* removed `Symfony\Component\HttpKernel\HttpCache\Esi::addSurrogateEsiCapability()`
26+
* removed `Symfony\Component\HttpKernel\HttpCache\Esi::hasSurrogateEsiCapability()`
27+
* removed `Symfony\Component\HttpKernel\HttpCache\Esi::addSurrogateEsiCapability()`
2728
* removed `Symfony\Component\HttpKernel\HttpCache\Esi::needsEsiParsing()`
2829
* removed `Symfony\Component\HttpKernel\HttpCache\HttpCache::getEsi()`
2930
* removed `Symfony\Component\HttpKernel\DependencyInjection\ContainerAwareHttpKernel`

src/Symfony/Component/HttpKernel/Debug/TraceableEventDispatcher.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ protected function preDispatch($eventName, Event $event)
6161
protected function postDispatch($eventName, Event $event)
6262
{
6363
switch ($eventName) {
64-
case KernelEvents::CONTROLLER:
64+
case KernelEvents::CONTROLLER_ARGUMENTS:
6565
$this->stopwatch->start('controller', 'section');
6666
break;
6767
case KernelEvents::RESPONSE:
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\HttpKernel\Event;
13+
14+
use Symfony\Component\HttpKernel\HttpKernelInterface;
15+
use Symfony\Component\HttpFoundation\Request;
16+
17+
/**
18+
* Allows filtering of controller arguments.
19+
*
20+
* You can call getController() to retrieve the controller and getArguments
21+
* to retrieve the current arguments. With setArguments() you can replace
22+
* arguments that are used to call the controller.
23+
*
24+
* Arguments set in the event must be compatible with the signature of the
25+
* controller.
26+
*
27+
* @author Christophe Coevoet <stof@notk.org>
28+
*/
29+
class FilterControllerArgumentsEvent extends FilterControllerEvent
30+
{
31+
private $arguments;
32+
33+
public function __construct(HttpKernelInterface $kernel, callable $controller, array $arguments, Request $request, $requestType)
34+
{
35+
parent::__construct($kernel, $controller, $request, $requestType);
36+
37+
$this->arguments = $arguments;
38+
}
39+
40+
/**
41+
* @return array
42+
*/
43+
public function getArguments()
44+
{
45+
return $this->arguments;
46+
}
47+
48+
/**
49+
* @param array $arguments
50+
*/
51+
public function setArguments(array $arguments)
52+
{
53+
$this->arguments = $arguments;
54+
}
55+
}

src/Symfony/Component/HttpKernel/Event/FilterControllerEvent.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,6 @@ public function getController()
5353
* Sets a new controller.
5454
*
5555
* @param callable $controller
56-
*
57-
* @throws \LogicException
5856
*/
5957
public function setController(callable $controller)
6058
{

src/Symfony/Component/HttpKernel/HttpKernel.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Symfony\Component\HttpKernel\Controller\ArgumentResolver;
1515
use Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface;
1616
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
17+
use Symfony\Component\HttpKernel\Event\FilterControllerArgumentsEvent;
1718
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
1819
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
1920
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
@@ -138,6 +139,11 @@ private function handleRaw(Request $request, $type = self::MASTER_REQUEST)
138139
// controller arguments
139140
$arguments = $this->argumentResolver->getArguments($request, $controller);
140141

142+
$event = new FilterControllerArgumentsEvent($this, $controller, $arguments, $request, $type);
143+
$this->dispatcher->dispatch(KernelEvents::CONTROLLER_ARGUMENTS, $event);
144+
$controller = $event->getController();
145+
$arguments = $event->getArguments();
146+
141147
// call controller
142148
$response = call_user_func_array($controller, $arguments);
143149

src/Symfony/Component/HttpKernel/KernelEvents.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,19 @@ final class KernelEvents
7676
*/
7777
const CONTROLLER = 'kernel.controller';
7878

79+
/**
80+
* The CONTROLLER_ARGUMENTS event occurs once controller arguments have been resolved.
81+
*
82+
* This event allows you to change the arguments that will be passed to
83+
* the controller. The event listener method receives a
84+
* Symfony\Component\HttpKernel\Event\FilterControllerArgumentsEvent instance.
85+
*
86+
* @Event
87+
*
88+
* @var string
89+
*/
90+
const CONTROLLER_ARGUMENTS = 'kernel.controller_arguments';
91+
7992
/**
8093
* The RESPONSE event occurs once a response was created for
8194
* replying to a request.

src/Symfony/Component/HttpKernel/Tests/Debug/TraceableEventDispatcherTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public function testStopwatchSections()
3434
'__section__',
3535
'kernel.request',
3636
'kernel.controller',
37+
'kernel.controller_arguments',
3738
'controller',
3839
'kernel.response',
3940
'kernel.terminate',

src/Symfony/Component/HttpKernel/Tests/HttpKernelTest.php

Lines changed: 39 additions & 2 deletions
F438
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\HttpFoundation\RequestStack;
1616
use Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface;
1717
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
18+
use Symfony\Component\HttpKernel\Event\FilterControllerArgumentsEvent;
1819
use Symfony\Component\HttpKernel\HttpKernel;
1920
use Symfony\Component\HttpKernel\HttpKernelInterface;
2021
use Symfony\Component\HttpKernel\KernelEvents;
@@ -233,6 +234,42 @@ public function testHandleWithAResponseListener()
233234
$this->assertEquals('foo', $kernel->handle(new Request())->getContent());
234235
}
235236

237+
public function testHandleAllowChangingControllerArguments()
238+
{
239+
$dispatcher = new EventDispatcher();
240+
$dispatcher->addListener(KernelEvents::CONTROLLER_ARGUMENTS, function (FilterControllerArgumentsEvent $event) {
241+
$event->setArguments(array('foo'));
242+
});
243+
244+
$kernel = $this->getHttpKernel($dispatcher, function ($content) { return new Response($content); });
245+
246+
$this->assertResponseEquals(new Response('foo'), $kernel->handle(new Request()));
247+
}
248+
249+
public function testHandleAllowChangingControllerAndArguments()
250+
{
251+
$dispatcher = new EventDispatcher();
252+
$dispatcher->addListener(KernelEvents::CONTROLLER_ARGUMENTS, function (FilterControllerArgumentsEvent $event) {
253+
$oldController = $event->getController();
254+
$oldArguments = $event->getArguments();
255+
256+
$newController = function ($id) use ($oldController, $oldArguments) {
257+
$response = call_user_func_array($oldController, $oldArguments);
258+
259+
$response->headers->set('X-Id', $id);
260+
261+
return $response;
262+
};
263+
264+
$event->setController($newController);
265+
$event->setArguments(array('bar'));
266+
});
267+
268+
$kernel = $this->getHttpKernel($dispatcher, function ($content) { return new Response($content); }, null, array('foo'));
269+
270+
$this->assertResponseEquals(new Response('foo', 200, array('X-Id' => 'bar')), $kernel->handle(new Request()));
271+
}
272+
236273
public function testTerminate()
237274
{
238275
$dispatcher = new EventDispatcher();
@@ -265,7 +302,7 @@ public function testVerifyRequestStackPushPopDuringHandle()
265302
$kernel->handle($request, HttpKernelInterface::MASTER_REQUEST);
266303
}
267304

268-
private function getHttpKernel(EventDispatcherInterface $eventDispatcher, $controller = null, RequestStack $requestStack = null)
305+
private function getHttpKernel(EventDispatcherInterface $eventDispatcher, $controller = null, RequestStack $requestStack = null, array $arguments = array())
269306
{
270307
if (null === $controller) {
271308
$controller = function () { return new Response('Hello'); };
@@ -281,7 +318,7 @@ private function getHttpKernel(EventDispatcherInterface $eventDispatcher, $contr
281318
$argumentResolver
282319
->expects($this->any())
283320
->method('getArguments')
284-
->will($this->returnValue(array()));
321+
->will($this->returnValue($arguments));
285322

286323
return new HttpKernel($eventDispatcher, $controllerResolver, $requestStack, $argumentResolver);
287324
}

0 commit comments

Comments
 (0)
0