Extracting arg resolving from ControllerResolver
This commit is contained in:
parent
8e1c60af3c
commit
360fc5fc4b
@ -65,6 +65,10 @@ HttpKernel
|
|||||||
* Passing objects as URI attributes to the ESI and SSI renderers has been
|
* Passing objects as URI attributes to the ESI and SSI renderers has been
|
||||||
deprecated and will be removed in Symfony 4.0. The inline fragment
|
deprecated and will be removed in Symfony 4.0. The inline fragment
|
||||||
renderer should be used with object attributes.
|
renderer should be used with object attributes.
|
||||||
|
* The `ControllerResolver::getArguments()` method is deprecated and will be
|
||||||
|
removed in 4.0. If you have your own `ControllerResolverInterface`
|
||||||
|
implementation, you should replace this method by implementing the
|
||||||
|
`ArgumentResolverInterface` and injecting it in the HttpKernel.
|
||||||
|
|
||||||
Serializer
|
Serializer
|
||||||
----------
|
----------
|
||||||
|
@ -150,9 +150,6 @@ class FrameworkExtension extends Extension
|
|||||||
|
|
||||||
$loader->load('debug.xml');
|
$loader->load('debug.xml');
|
||||||
|
|
||||||
$definition = $container->findDefinition('http_kernel');
|
|
||||||
$definition->replaceArgument(1, new Reference('debug.controller_resolver'));
|
|
||||||
|
|
||||||
// replace the regular event_dispatcher service with the debug one
|
// replace the regular event_dispatcher service with the debug one
|
||||||
$definition = $container->findDefinition('event_dispatcher');
|
$definition = $container->findDefinition('event_dispatcher');
|
||||||
$definition->setPublic(false);
|
$definition->setPublic(false);
|
||||||
@ -173,6 +170,7 @@ class FrameworkExtension extends Extension
|
|||||||
'Symfony\\Component\\HttpKernel\\EventListener\\ResponseListener',
|
'Symfony\\Component\\HttpKernel\\EventListener\\ResponseListener',
|
||||||
'Symfony\\Component\\HttpKernel\\EventListener\\RouterListener',
|
'Symfony\\Component\\HttpKernel\\EventListener\\RouterListener',
|
||||||
'Symfony\\Component\\HttpKernel\\Controller\\ControllerResolver',
|
'Symfony\\Component\\HttpKernel\\Controller\\ControllerResolver',
|
||||||
|
'Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolver',
|
||||||
'Symfony\\Component\\HttpKernel\\Event\\KernelEvent',
|
'Symfony\\Component\\HttpKernel\\Event\\KernelEvent',
|
||||||
'Symfony\\Component\\HttpKernel\\Event\\FilterControllerEvent',
|
'Symfony\\Component\\HttpKernel\\Event\\FilterControllerEvent',
|
||||||
'Symfony\\Component\\HttpKernel\\Event\\FilterResponseEvent',
|
'Symfony\\Component\\HttpKernel\\Event\\FilterResponseEvent',
|
||||||
|
@ -17,8 +17,14 @@
|
|||||||
<argument type="service" id="logger" on-invalid="null" />
|
<argument type="service" id="logger" on-invalid="null" />
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
<service id="debug.controller_resolver" class="Symfony\Component\HttpKernel\Controller\TraceableControllerResolver">
|
<service id="debug.controller_resolver" decorates="controller_resolver" class="Symfony\Component\HttpKernel\Controller\TraceableControllerResolver">
|
||||||
<argument type="service" id="controller_resolver" />
|
<argument type="service" id="debug.controller_resolver.inner" />
|
||||||
|
<argument type="service" id="debug.stopwatch" />
|
||||||
|
<argument type="service" id="argument_resolver" />
|
||||||
|
</service>
|
||||||
|
|
||||||
|
<service id="debug.argument_resolver" decorates="argument_resolver" class="Symfony\Component\HttpKernel\Controller\TraceableArgumentResolver">
|
||||||
|
<argument type="service" id="debug.argument_resolver.inner" />
|
||||||
<argument type="service" id="debug.stopwatch" />
|
<argument type="service" id="debug.stopwatch" />
|
||||||
</service>
|
</service>
|
||||||
</services>
|
</services>
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
<argument type="service" id="event_dispatcher" />
|
<argument type="service" id="event_dispatcher" />
|
||||||
<argument type="service" id="controller_resolver" />
|
<argument type="service" id="controller_resolver" />
|
||||||
<argument type="service" id="request_stack" />
|
<argument type="service" id="request_stack" />
|
||||||
|
<argument type="service" id="argument_resolver" />
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
<service id="request_stack" class="Symfony\Component\HttpFoundation\RequestStack" />
|
<service id="request_stack" class="Symfony\Component\HttpFoundation\RequestStack" />
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
<argument type="service" id="logger" on-invalid="ignore" />
|
<argument type="service" id="logger" on-invalid="ignore" />
|
||||||
</service>
|
</service>
|
||||||
|
|
||||||
|
<service id="argument_resolver" class="Symfony\Component\HttpKernel\Controller\ArgumentResolver" public="false" />
|
||||||
|
|
||||||
<service id="response_listener" class="Symfony\Component\HttpKernel\EventListener\ResponseListener">
|
<service id="response_listener" class="Symfony\Component\HttpKernel\EventListener\ResponseListener">
|
||||||
<tag name="kernel.event_subscriber" />
|
<tag name="kernel.event_subscriber" />
|
||||||
<argument>%kernel.charset%</argument>
|
<argument>%kernel.charset%</argument>
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
"symfony/config": "~2.8|~3.0",
|
"symfony/config": "~2.8|~3.0",
|
||||||
"symfony/event-dispatcher": "~2.8|~3.0",
|
"symfony/event-dispatcher": "~2.8|~3.0",
|
||||||
"symfony/http-foundation": "~3.1",
|
"symfony/http-foundation": "~3.1",
|
||||||
"symfony/http-kernel": "~2.8|~3.0",
|
"symfony/http-kernel": "~3.1",
|
||||||
"symfony/polyfill-mbstring": "~1.0",
|
"symfony/polyfill-mbstring": "~1.0",
|
||||||
"symfony/filesystem": "~2.8|~3.0",
|
"symfony/filesystem": "~2.8|~3.0",
|
||||||
"symfony/finder": "~2.8|~3.0",
|
"symfony/finder": "~2.8|~3.0",
|
||||||
|
@ -4,6 +4,9 @@ CHANGELOG
|
|||||||
3.1.0
|
3.1.0
|
||||||
-----
|
-----
|
||||||
* deprecated passing objects as URI attributes to the ESI and SSI renderers
|
* deprecated passing objects as URI attributes to the ESI and SSI renderers
|
||||||
|
* Added an `ArgumentResolver` with `getArguments()` and the respective interface `ArgumentResolverInterface`
|
||||||
|
* Deprecated `ControllerResolver::getArguments()`, which uses the `ArgumentResolver` as BC layer by extending it
|
||||||
|
* The `HttpKernel` now accepts an additional argument for an `ArgumentResolver`
|
||||||
|
|
||||||
3.0.0
|
3.0.0
|
||||||
-----
|
-----
|
||||||
|
@ -0,0 +1,70 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\HttpKernel\Controller;
|
||||||
|
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Responsible for the creation of the action arguments.
|
||||||
|
*
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*/
|
||||||
|
class ArgumentResolver implements ArgumentResolverInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getArguments(Request $request, $controller)
|
||||||
|
{
|
||||||
|
if (is_array($controller)) {
|
||||||
|
$r = new \ReflectionMethod($controller[0], $controller[1]);
|
||||||
|
} elseif (is_object($controller) && !$controller instanceof \Closure) {
|
||||||
|
$r = new \ReflectionObject($controller);
|
||||||
|
$r = $r->getMethod('__invoke');
|
||||||
|
} else {
|
||||||
|
$r = new \ReflectionFunction($controller);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->doGetArguments($request, $controller, $r->getParameters());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function doGetArguments(Request $request, $controller, array $parameters)
|
||||||
|
{
|
||||||
|
$attributes = $request->attributes->all();
|
||||||
|
$arguments = array();
|
||||||
|
foreach ($parameters as $param) {
|
||||||
|
if (array_key_exists($param->name, $attributes)) {
|
||||||
|
if (PHP_VERSION_ID >= 50600 && $param->isVariadic() && is_array($attributes[$param->name])) {
|
||||||
|
$arguments = array_merge($arguments, array_values($attributes[$param->name]));
|
||||||
|
} else {
|
||||||
|
$arguments[] = $attributes[$param->name];
|
||||||
|
}
|
||||||
|
} elseif ($param->getClass() && $param->getClass()->isInstance($request)) {
|
||||||
|
$arguments[] = $request;
|
||||||
|
} elseif ($param->isDefaultValueAvailable()) {
|
||||||
|
$arguments[] = $param->getDefaultValue();
|
||||||
|
} else {
|
||||||
|
if (is_array($controller)) {
|
||||||
|
$repr = sprintf('%s::%s()', get_class($controller[0]), $controller[1]);
|
||||||
|
} elseif (is_object($controller)) {
|
||||||
|
$repr = get_class($controller);
|
||||||
|
} else {
|
||||||
|
$repr = $controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new \RuntimeException(sprintf('Controller "%s" requires that you provide a value for the "$%s" argument (because there is no default value or because there is a non optional argument after this one).', $repr, $param->name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $arguments;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\HttpKernel\Controller;
|
||||||
|
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An ArgumentResolverInterface implementation knows how to determine the
|
||||||
|
* arguments for a specific action.
|
||||||
|
*
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*/
|
||||||
|
interface ArgumentResolverInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Returns the arguments to pass to the controller.
|
||||||
|
*
|
||||||
|
* @param Request $request A Request instance
|
||||||
|
* @param callable $controller A PHP callable
|
||||||
|
*
|
||||||
|
* @return array An array of arguments to pass to the controller
|
||||||
|
*
|
||||||
|
* @throws \RuntimeException When value for argument given is not provided
|
||||||
|
*/
|
||||||
|
public function getArguments(Request $request, $controller);
|
||||||
|
}
|
@ -23,7 +23,7 @@ use Symfony\Component\HttpFoundation\Request;
|
|||||||
*
|
*
|
||||||
* @author Fabien Potencier <fabien@symfony.com>
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
*/
|
*/
|
||||||
class ControllerResolver implements ControllerResolverInterface
|
class ControllerResolver extends ArgumentResolver implements ControllerResolverInterface
|
||||||
{
|
{
|
||||||
private $logger;
|
private $logger;
|
||||||
|
|
||||||
@ -84,50 +84,24 @@ class ControllerResolver implements ControllerResolverInterface
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
|
*
|
||||||
|
* @deprecated this method is deprecated as of 3.1 and will be removed in 4.0. Implement the ArgumentResolverInterface or extend the ArgumentResolver instead.
|
||||||
*/
|
*/
|
||||||
public function getArguments(Request $request, $controller)
|
public function getArguments(Request $request, $controller)
|
||||||
{
|
{
|
||||||
if (is_array($controller)) {
|
@trigger_error(sprintf('%s is deprecated as of 3.1 and will be removed in 4.0. Implement the %s or extend the %s and inject it in the HttpKernel instead.', __METHOD__, ArgumentResolverInterface::class, ArgumentResolver::class), E_USER_DEPRECATED);
|
||||||
$r = new \ReflectionMethod($controller[0], $controller[1]);
|
|
||||||
} elseif (is_object($controller) && !$controller instanceof \Closure) {
|
|
||||||
$r = new \ReflectionObject($controller);
|
|
||||||
$r = $r->getMethod('__invoke');
|
|
||||||
} else {
|
|
||||||
$r = new \ReflectionFunction($controller);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->doGetArguments($request, $controller, $r->getParameters());
|
return parent::getArguments($request, $controller);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated this method is deprecated as of 3.1 and will be removed in 4.0. Implement the ArgumentResolverInterface or extend the ArgumentResolver instead.
|
||||||
|
*/
|
||||||
protected function doGetArguments(Request $request, $controller, array $parameters)
|
protected function doGetArguments(Request $request, $controller, array $parameters)
|
||||||
{
|
{
|
||||||
$attributes = $request->attributes->all();
|
@trigger_error(sprintf('%s is deprecated as of 3.1 and will be removed in 4.0. Implement the %s or extend the %s and inject it in the HttpKernel instead.', __METHOD__, ArgumentResolverInterface::class, ArgumentResolver::class), E_USER_DEPRECATED);
|
||||||
$arguments = array();
|
|
||||||
foreach ($parameters as $param) {
|
|
||||||
if (array_key_exists($param->name, $attributes)) {
|
|
||||||
if (PHP_VERSION_ID >= 50600 && $param->isVariadic() && is_array($attributes[$param->name])) {
|
|
||||||
$arguments = array_merge($arguments, array_values($attributes[$param->name]));
|
|
||||||
} else {
|
|
||||||
$arguments[] = $attributes[$param->name];
|
|
||||||
}
|
|
||||||
} elseif ($param->getClass() && $param->getClass()->isInstance($request)) {
|
|
||||||
$arguments[] = $request;
|
|
||||||
} elseif ($param->isDefaultValueAvailable()) {
|
|
||||||
$arguments[] = $param->getDefaultValue();
|
|
||||||
} else {
|
|
||||||
if (is_array($controller)) {
|
|
||||||
$repr = sprintf('%s::%s()', get_class($controller[0]), $controller[1]);
|
|
||||||
} elseif (is_object($controller)) {
|
|
||||||
$repr = get_class($controller);
|
|
||||||
} else {
|
|
||||||
$repr = $controller;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new \RuntimeException(sprintf('Controller "%s" requires that you provide a value for the "$%s" argument (because there is no default value or because there is a non optional argument after this one).', $repr, $param->name));
|
return parent::doGetArguments($request, $controller, $parameters);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $arguments;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -52,6 +52,8 @@ interface ControllerResolverInterface
|
|||||||
* @return array An array of arguments to pass to the controller
|
* @return array An array of arguments to pass to the controller
|
||||||
*
|
*
|
||||||
* @throws \RuntimeException When value for argument given is not provided
|
* @throws \RuntimeException When value for argument given is not provided
|
||||||
|
*
|
||||||
|
* @deprecated This method is deprecated as of 3.1 and will be removed in 4.0. Please use the {@see ArgumentResolverInterface} instead.
|
||||||
*/
|
*/
|
||||||
public function getArguments(Request $request, $controller);
|
public function getArguments(Request $request, $controller);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\HttpKernel\Controller;
|
||||||
|
|
||||||
|
use Symfony\Component\Stopwatch\Stopwatch;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
|
*/
|
||||||
|
class TraceableArgumentResolver implements ArgumentResolverInterface
|
||||||
|
{
|
||||||
|
private $resolver;
|
||||||
|
private $stopwatch;
|
||||||
|
|
||||||
|
public function __construct(ArgumentResolverInterface $resolver, Stopwatch $stopwatch)
|
||||||
|
{
|
||||||
|
$this->resolver = $resolver;
|
||||||
|
$this->stopwatch = $stopwatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function getArguments(Request $request, $controller)
|
||||||
|
{
|
||||||
|
$e = $this->stopwatch->start('controller.get_arguments');
|
||||||
|
|
||||||
|
$ret = $this->resolver->getArguments($request, $controller);
|
||||||
|
|
||||||
|
$e->stop();
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
}
|
@ -19,21 +19,28 @@ use Symfony\Component\HttpFoundation\Request;
|
|||||||
*
|
*
|
||||||
* @author Fabien Potencier <fabien@symfony.com>
|
* @author Fabien Potencier <fabien@symfony.com>
|
||||||
*/
|
*/
|
||||||
class TraceableControllerResolver implements ControllerResolverInterface
|
class TraceableControllerResolver implements ControllerResolverInterface, ArgumentResolverInterface
|
||||||
{
|
{
|
||||||
private $resolver;
|
private $resolver;
|
||||||
private $stopwatch;
|
private $stopwatch;
|
||||||
|
private $argumentResolver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @param ControllerResolverInterface $resolver A ControllerResolverInterface instance
|
* @param ControllerResolverInterface $resolver A ControllerResolverInterface instance
|
||||||
* @param Stopwatch $stopwatch A Stopwatch instance
|
* @param Stopwatch $stopwatch A Stopwatch instance
|
||||||
|
* @param ArgumentResolverInterface $argumentResolver Only required for BC
|
||||||
*/
|
*/
|
||||||
public function __construct(ControllerResolverInterface $resolver, Stopwatch $stopwatch)
|
public function __construct(ControllerResolverInterface $resolver, Stopwatch $stopwatch, ArgumentResolverInterface $argumentResolver = null)
|
||||||
{
|
{
|
||||||
$this->resolver = $resolver;
|
$this->resolver = $resolver;
|
||||||
$this->stopwatch = $stopwatch;
|
$this->stopwatch = $stopwatch;
|
||||||
|
$this->argumentResolver = $argumentResolver;
|
||||||
|
|
||||||
|
if (null === $this->argumentResolver) {
|
||||||
|
$this->argumentResolver = $resolver;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -52,12 +59,20 @@ class TraceableControllerResolver implements ControllerResolverInterface
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
|
*
|
||||||
|
* @deprecated This method is deprecated as of 3.1 and will be removed in 4.0.
|
||||||
*/
|
*/
|
||||||
public function getArguments(Request $request, $controller)
|
public function getArguments(Request $request, $controller)
|
||||||
{
|
{
|
||||||
|
@trigger_error(sprintf('This %s method is deprecated as of 3.1 and will be removed in 4.0. Please use the %s instead.', __METHOD__, TraceableArgumentResolver::class), E_USER_DEPRECATED);
|
||||||
|
|
||||||
|
if ($this->argumentResolver instanceof TraceableArgumentResolver) {
|
||||||
|
return $this->argumentResolver->getArguments($request, $controller);
|
||||||
|
}
|
||||||
|
|
||||||
$e = $this->stopwatch->start('controller.get_arguments');
|
$e = $this->stopwatch->start('controller.get_arguments');
|
||||||
|
|
||||||
$ret = $this->resolver->getArguments($request, $controller);
|
$ret = $this->argumentResolver->getArguments($request, $controller);
|
||||||
|
|
||||||
$e->stop();
|
$e->stop();
|
||||||
|
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\HttpKernel;
|
namespace Symfony\Component\HttpKernel;
|
||||||
|
|
||||||
|
use Symfony\Component\HttpKernel\Controller\ArgumentResolver;
|
||||||
|
use Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface;
|
||||||
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
|
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
|
||||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||||
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
|
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
|
||||||
@ -36,19 +38,28 @@ class HttpKernel implements HttpKernelInterface, TerminableInterface
|
|||||||
protected $dispatcher;
|
protected $dispatcher;
|
||||||
protected $resolver;
|
protected $resolver;
|
||||||
protected $requestStack;
|
protected $requestStack;
|
||||||
|
private $argumentResolver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
*
|
*
|
||||||
* @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance
|
* @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance
|
||||||
* @param ControllerResolverInterface $resolver A ControllerResolverInterface instance
|
* @param ControllerResolverInterface $resolver A ControllerResolverInterface instance
|
||||||
* @param RequestStack $requestStack A stack for master/sub requests
|
* @param RequestStack $requestStack A stack for master/sub requests
|
||||||
|
* @param ArgumentResolverInterface $argumentResolver An ArgumentResolverInterface instance
|
||||||
*/
|
*/
|
||||||
public function __construct(EventDispatcherInterface $dispatcher, ControllerResolverInterface $resolver, RequestStack $requestStack = null)
|
public function __construct(EventDispatcherInterface $dispatcher, ControllerResolverInterface $resolver, RequestStack $requestStack = null, ArgumentResolverInterface $argumentResolver = null)
|
||||||
{
|
{
|
||||||
$this->dispatcher = $dispatcher;
|
$this->dispatcher = $dispatcher;
|
||||||
$this->resolver = $resolver;
|
$this->resolver = $resolver;
|
||||||
$this->requestStack = $requestStack ?: new RequestStack();
|
$this->requestStack = $requestStack ?: new RequestStack();
|
||||||
|
$this->argumentResolver = $argumentResolver;
|
||||||
|
|
||||||
|
if (null === $this->argumentResolver) {
|
||||||
|
@trigger_error(sprintf('As of 3.1 an %s is used to resolve arguments. In 4.0 the $argumentResolver becomes mandatory and the %s can no longer be used to resolve arguments.', ArgumentResolverInterface::class, ControllerResolverInterface::class), E_USER_DEPRECATED);
|
||||||
|
// fallback in case of deprecations
|
||||||
|
$this->argumentResolver = $resolver;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -133,7 +144,7 @@ class HttpKernel implements HttpKernelInterface, TerminableInterface
|
|||||||
$controller = $event->getController();
|
$controller = $event->getController();
|
||||||
|
|
||||||
// controller arguments
|
// controller arguments
|
||||||
$arguments = $this->resolver->getArguments($request, $controller);
|
$arguments = $this->argumentResolver->getArguments($request, $controller);
|
||||||
|
|
||||||
// call controller
|
// call controller
|
||||||
$response = call_user_func_array($controller, $arguments);
|
$response = call_user_func_array($controller, $arguments);
|
||||||
|
@ -0,0 +1,137 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\HttpKernel\Tests\Controller;
|
||||||
|
|
||||||
|
use Symfony\Component\HttpKernel\Controller\ArgumentResolver;
|
||||||
|
use Symfony\Component\HttpKernel\Controller\ControllerResolver;
|
||||||
|
use Symfony\Component\HttpKernel\Tests\Fixtures\Controller\VariadicController;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
||||||
|
class ArgumentResolverTest extends \PHPUnit_Framework_TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
|
public function testGetArguments()
|
||||||
|
{
|
||||||
|
$resolver = new ArgumentResolver();
|
||||||
|
|
||||||
|
$request = Request::create('/');
|
||||||
|
$controller = array(new self(), 'testGetArguments');
|
||||||
|
$this->assertEquals(array(), $resolver->getArguments($request, $controller), '->getArguments() returns an empty array if the method takes no arguments');
|
||||||
|
|
||||||
|
$request = Request::create('/');
|
||||||
|
$request->attributes->set('foo', 'foo');
|
||||||
|
$controller = array(new self(), 'controllerMethod1');
|
||||||
|
$this->assertEquals(array('foo'), $resolver->getArguments($request, $controller), '->getArguments() returns an array of arguments for the controller method');
|
||||||
|
|
||||||
|
$request = Request::create('/');
|
||||||
|
$request->attributes->set('foo', 'foo');
|
||||||
|
$controller = array(new self(), 'controllerMethod2');
|
||||||
|
$this->assertEquals(array('foo', null), $resolver->getArguments($request, $controller), '->getArguments() uses default values if present');
|
||||||
|
|
||||||
|
$request->attributes->set('bar', 'bar');
|
||||||
|
$this->assertEquals(array('foo', 'bar'), $resolver->getArguments($request, $controller), '->getArguments() overrides default values if provided in the request attributes');
|
||||||
|
|
||||||
|
$request = Request::create('/');
|
||||||
|
$request->attributes->set('foo', 'foo');
|
||||||
|
$controller = function ($foo) {};
|
||||||
|
$this->assertEquals(array('foo'), $resolver->getArguments($request, $controller));
|
||||||
|
|
||||||
|
$request = Request::create('/');
|
||||||
|
$request->attributes->set('foo', 'foo');
|
||||||
|
$controller = function ($foo, $bar = 'bar') {};
|
||||||
|
$this->assertEquals(array('foo', 'bar'), $resolver->getArguments($request, $controller));
|
||||||
|
|
||||||
|
$request = Request::create('/');
|
||||||
|
$request->attributes->set('foo', 'foo');
|
||||||
|
$controller = new self();
|
||||||
|
$this->assertEquals(array('foo', null), $resolver->getArguments($request, $controller));
|
||||||
|
$request->attributes->set('bar', 'bar');
|
||||||
|
$this->assertEquals(array('foo', 'bar'), $resolver->getArguments($request, $controller));
|
||||||
|
|
||||||
|
$request = Request::create('/');
|
||||||
|
$request->attributes->set('foo', 'foo');
|
||||||
|
$request->attributes->set('foobar', 'foobar');
|
||||||
|
$controller = 'Symfony\Component\HttpKernel\Tests\Controller\another_controller_function';
|
||||||
|
$this->assertEquals(array('foo', 'foobar'), $resolver->getArguments($request, $controller));
|
||||||
|
|
||||||
|
$request = Request::create('/');
|
||||||
|
$request->attributes->set('foo', 'foo');
|
||||||
|
$request->attributes->set('foobar', 'foobar');
|
||||||
|
$controller = array(new self(), 'controllerMethod3');
|
||||||
|
|
||||||
|
try {
|
||||||
|
$resolver->getArguments($request, $controller);
|
||||||
|
$this->fail('->getArguments() throws a \RuntimeException exception if it cannot determine the argument value');
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
$this->assertInstanceOf('\RuntimeException', $e, '->getArguments() throws a \RuntimeException exception if it cannot determine the argument value');
|
||||||
|
}
|
||||||
|
|
||||||
|
$request = Request::create('/');
|
||||||
|
$controller = array(new self(), 'controllerMethod5');
|
||||||
|
$this->assertEquals(array($request), $resolver->getArguments($request, $controller), '->getArguments() injects the request');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires PHP 5.6
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
|
public function testGetVariadicArguments()
|
||||||
|
{
|
||||||
|
$resolver = new ControllerResolver();
|
||||||
|
|
||||||
|
$request = Request::create('/');
|
||||||
|
$request->attributes->set('foo', 'foo');
|
||||||
|
$request->attributes->set('bar', array('foo', 'bar'));
|
||||||
|
$controller = array(new VariadicController(), 'action');
|
||||||
|
$this->assertEquals(array('foo', 'foo', 'bar'), $resolver->getArguments($request, $controller));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testCreateControllerCanReturnAnyCallable()
|
||||||
|
{
|
||||||
|
$mock = $this->getMock('Symfony\Component\HttpKernel\Controller\ControllerResolver', array('createController'));
|
||||||
|
$mock->expects($this->once())->method('createController')->will($this->returnValue('Symfony\Component\HttpKernel\Tests\Controller\another_controller_function'));
|
||||||
|
|
||||||
|
$request = Request::create('/');
|
||||||
|
$request->attributes->set('_controller', 'foobar');
|
||||||
|
$mock->getController($request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __invoke($foo, $bar = null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function controllerMethod1($foo)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function controllerMethod2($foo, $bar = null)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function controllerMethod3($foo, $bar, $foobar)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static function controllerMethod4()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function controllerMethod5(Request $request)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function another_controller_function($foo, $foobar)
|
||||||
|
{
|
||||||
|
}
|
@ -137,6 +137,9 @@ class ControllerResolverTest extends \PHPUnit_Framework_TestCase
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
public function testGetArguments()
|
public function testGetArguments()
|
||||||
{
|
{
|
||||||
$resolver = $this->createControllerResolver();
|
$resolver = $this->createControllerResolver();
|
||||||
@ -200,6 +203,7 @@ class ControllerResolverTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @requires PHP 5.6
|
* @requires PHP 5.6
|
||||||
|
* @group legacy
|
||||||
*/
|
*/
|
||||||
public function testGetVariadicArguments()
|
public function testGetVariadicArguments()
|
||||||
{
|
{
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace Symfony\Component\HttpKernel\Tests\Debug;
|
namespace Symfony\Component\HttpKernel\Tests\Debug;
|
||||||
|
|
||||||
use Symfony\Component\EventDispatcher\EventDispatcher;
|
use Symfony\Component\EventDispatcher\EventDispatcher;
|
||||||
|
use Symfony\Component\HttpFoundation\RequestStack;
|
||||||
use Symfony\Component\HttpKernel\Debug\TraceableEventDispatcher;
|
use Symfony\Component\HttpKernel\Debug\TraceableEventDispatcher;
|
||||||
use Symfony\Component\HttpKernel\HttpKernel;
|
use Symfony\Component\HttpKernel\HttpKernel;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
@ -108,10 +109,11 @@ class TraceableEventDispatcherTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
protected function getHttpKernel($dispatcher, $controller)
|
protected function getHttpKernel($dispatcher, $controller)
|
||||||
{
|
{
|
||||||
$resolver = $this->getMock('Symfony\Component\HttpKernel\Controller\ControllerResolverInterface');
|
$controllerResolver = $this->getMock('Symfony\Component\HttpKernel\Controller\ControllerResolverInterface');
|
||||||
$resolver->expects($this->once())->method('getController')->will($this->returnValue($controller));
|
$controllerResolver->expects($this->once())->method('getController')->will($this->returnValue($controller));
|
||||||
$resolver->expects($this->once())->method('getArguments')->will($this->returnValue(array()));
|
$argumentResolver = $this->getMock('Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface');
|
||||||
|
$argumentResolver->expects($this->once())->method('getArguments')->will($this->returnValue(array()));
|
||||||
|
|
||||||
return new HttpKernel($dispatcher, $resolver);
|
return new HttpKernel($dispatcher, $controllerResolver, new RequestStack(), $argumentResolver);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\HttpKernel\Tests\Fragment;
|
namespace Symfony\Component\HttpKernel\Tests\Fragment;
|
||||||
|
|
||||||
|
use Symfony\Component\HttpFoundation\RequestStack;
|
||||||
|
use Symfony\Component\HttpKernel\Controller\ArgumentResolver;
|
||||||
use Symfony\Component\HttpKernel\Controller\ControllerReference;
|
use Symfony\Component\HttpKernel\Controller\ControllerReference;
|
||||||
use Symfony\Component\HttpKernel\HttpKernel;
|
use Symfony\Component\HttpKernel\HttpKernel;
|
||||||
use Symfony\Component\HttpKernel\Fragment\InlineFragmentRenderer;
|
use Symfony\Component\HttpKernel\Fragment\InlineFragmentRenderer;
|
||||||
@ -60,7 +62,7 @@ class InlineFragmentRendererTest extends \PHPUnit_Framework_TestCase
|
|||||||
}))
|
}))
|
||||||
;
|
;
|
||||||
|
|
||||||
$kernel = new HttpKernel(new EventDispatcher(), $resolver);
|
$kernel = new HttpKernel(new EventDispatcher(), $resolver, new RequestStack(), new ArgumentResolver());
|
||||||
$renderer = new InlineFragmentRenderer($kernel);
|
$renderer = new InlineFragmentRenderer($kernel);
|
||||||
|
|
||||||
$response = $renderer->render(new ControllerReference('main_controller', array('object' => new \stdClass(), 'object1' => new Bar()), array()), Request::create('/'));
|
$response = $renderer->render(new ControllerReference('main_controller', array('object' => new \stdClass(), 'object1' => new Bar()), array()), Request::create('/'));
|
||||||
@ -142,8 +144,8 @@ class InlineFragmentRendererTest extends \PHPUnit_Framework_TestCase
|
|||||||
|
|
||||||
public function testExceptionInSubRequestsDoesNotMangleOutputBuffers()
|
public function testExceptionInSubRequestsDoesNotMangleOutputBuffers()
|
||||||
{
|
{
|
||||||
$resolver = $this->getMock('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface');
|
$controllerResolver = $this->getMock('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface');
|
||||||
$resolver
|
$controllerResolver
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('getController')
|
->method('getController')
|
||||||
->will($this->returnValue(function () {
|
->will($this->returnValue(function () {
|
||||||
@ -152,13 +154,15 @@ class InlineFragmentRendererTest extends \PHPUnit_Framework_TestCase
|
|||||||
throw new \RuntimeException();
|
throw new \RuntimeException();
|
||||||
}))
|
}))
|
||||||
;
|
;
|
||||||
$resolver
|
|
||||||
|
$argumentResolver = $this->getMock('Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolverInterface');
|
||||||
|
$argumentResolver
|
||||||
->expects($this->once())
|
->expects($this->once())
|
||||||
->method('getArguments')
|
->method('getArguments')
|
||||||
->will($this->returnValue(array()))
|
->will($this->returnValue(array()))
|
||||||
;
|
;
|
||||||
|
|
||||||
$kernel = new HttpKernel(new EventDispatcher(), $resolver);
|
$kernel = new HttpKernel(new EventDispatcher(), $controllerResolver, new RequestStack(), $argumentResolver);
|
||||||
$renderer = new InlineFragmentRenderer($kernel);
|
$renderer = new InlineFragmentRenderer($kernel);
|
||||||
|
|
||||||
// simulate a main request with output buffering
|
// simulate a main request with output buffering
|
||||||
|
Reference in New Issue
Block a user