diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
index e2e8a84163859..7685c6472aeb5 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php
@@ -153,6 +153,10 @@ public function load(array $configs, ContainerBuilder $container)
$definition->replaceArgument(2, E_COMPILE_ERROR | E_PARSE | E_ERROR | E_CORE_ERROR);
}
+ if (interface_exists('Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface')) {
+ $loader->load('psr-http-message.xml');
+ }
+
$this->addClassesToCompile(array(
'Symfony\\Component\\Config\\FileLocator',
diff --git a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php
index 499f39c6c95c0..6a1c8baf7f9dd 100644
--- a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php
+++ b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php
@@ -36,6 +36,7 @@
use Symfony\Component\HttpKernel\DependencyInjection\FragmentRendererPass;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Bundle\Bundle;
+use Symfony\Component\HttpKernel\DependencyInjection\RegisterArgumentResolversPass;
/**
* Bundle.
@@ -88,6 +89,7 @@ public function build(ContainerBuilder $container)
$container->addCompilerPass(new TranslationDumperPass());
$container->addCompilerPass(new FragmentRendererPass(), PassConfig::TYPE_AFTER_REMOVING);
$container->addCompilerPass(new SerializerPass());
+ $container->addCompilerPass(new RegisterArgumentResolversPass());
if ($container->getParameter('kernel.debug')) {
$container->addCompilerPass(new ContainerBuilderDebugDumpPass(), PassConfig::TYPE_AFTER_REMOVING);
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/psr-http-message.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/psr-http-message.xml
new file mode 100644
index 0000000000000..ffb2eab4f7e77
--- /dev/null
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/psr-http-message.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml
index 2021505726fef..f816ce38d37e5 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml
@@ -25,6 +25,7 @@
+
false
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml
index 9b2f3cb3a4373..74e8899cb36ab 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml
@@ -25,6 +25,16 @@
+
+
+
+
+
+
+
+
+
+
%kernel.charset%
diff --git a/src/Symfony/Bundle/SecurityBundle/ArgumentResolver/UserArgumentResolver.php b/src/Symfony/Bundle/SecurityBundle/ArgumentResolver/UserArgumentResolver.php
new file mode 100644
index 0000000000000..6c0c885020d07
--- /dev/null
+++ b/src/Symfony/Bundle/SecurityBundle/ArgumentResolver/UserArgumentResolver.php
@@ -0,0 +1,63 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\SecurityBundle\ArgumentResolver;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpKernel\Controller\ArgumentResolver\ArgumentResolverInterface;
+use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
+
+/**
+ * Resolves a typehint for UserInterface in a controller to the current user.
+ *
+ * @author Wouter J
+ */
+class UserArgumentResolver implements ArgumentResolverInterface
+{
+ /**
+ * @var TokenStorageInterface
+ */
+ private $tokenStorage;
+
+ public function __construct(TokenStorageInterface $tokenStorage)
+ {
+ $this->tokenStorage = $tokenStorage;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supports(Request $request, \ReflectionParameter $parameter)
+ {
+ $class = $parameter->getClass();
+ $userInterface = 'Symfony\Component\Security\Core\User\UserInterface';
+ $userImplementation = 'Symfony\Component\Security\Core\User\User';
+
+ return null !== $class && ($userInterface === $class->getName() || $userImplementation === $class->getName());
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function resolve(Request $request, \ReflectionParameter $parameter)
+ {
+ if (null === $token = $this->tokenStorage->getToken()) {
+ return;
+ }
+
+ if (!is_object($user = $token->getUser())) {
+ // e.g. anonymous authentication
+ return;
+ }
+
+ return $user;
+ }
+}
diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml
index b7c1407c1cc56..ad08b4bd05726 100644
--- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml
+++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml
@@ -50,6 +50,12 @@
+
+
+
+
+
+
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/ArgumentResolver/UserArgumentResolverTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/ArgumentResolver/UserArgumentResolverTest.php
new file mode 100644
index 0000000000000..608065ef101eb
--- /dev/null
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/ArgumentResolver/UserArgumentResolverTest.php
@@ -0,0 +1,96 @@
+
+ */
+class UserArgumentResolverTest extends \PHPUnit_Framework_TestCase
+{
+ private $resolver;
+ private $tokenStorage;
+
+ protected function setUp()
+ {
+ $this->tokenStorage = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface');
+ $this->resolver = new UserArgumentResolver($this->tokenStorage);
+ }
+
+ /**
+ * @dataProvider provideClasses
+ */
+ public function testSupports($class, $supported = true)
+ {
+ $this->assertEquals($supported, $this->resolver->supports($this->getRequestMock(), $this->getReflectionParameterMock($class)));
+ }
+
+ public function provideClasses()
+ {
+ return array(
+ array('Symfony\Component\Security\Core\User\UserInterface'),
+ array('Symfony\Component\Security\Core\User\User'),
+ array('Symfony\Bundle\SecurityBundle\Tests\ArgumentResolver\UserFixture', false),
+ array('\stdClass', false),
+ );
+ }
+
+ public function testResolvesToNullWhenNoUserIsAvailable()
+ {
+ $this->tokenStorage->expects($this->any())->method('getToken')->willReturn(null);
+
+ $this->assertNull($this->resolver->resolve($this->getRequestMock(), $this->getReflectionParameterMock()));
+ }
+
+ public function testResolvesToNullWhenUserIsAnonymous()
+ {
+ $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
+ $token->expects($this->any())->method('getUser')->willReturn('anon.');
+
+ $this->tokenStorage->expects($this->any())->method('getToken')->willReturn($token);
+
+ $this->assertNull($this->resolver->resolve($this->getRequestMock(), $this->getReflectionParameterMock()));
+ }
+
+ public function testResolvesToUser()
+ {
+ $user = $this->getMock('Symfony\component\Security\Core\User\User');
+
+ $token = $this->getMock('Symfony\Component\Security\Core\Authentication\Token\TokenInterface');
+ $token->expects($this->any())->method('getUser')->willReturn($user);
+
+ $this->tokenStorage->expects($this->any())->method('getToken')->willReturn($token);
+
+ $this->assertEquals($user, $this->resolver->resolve($this->getRequestMock(), $this->getReflectionParameterMock()));
+ }
+
+ private function getRequestMock()
+ {
+ return $this->getMock('Symfony\Component\HttpFoundation\Request');
+ }
+
+ private function getReflectionParameterMock($class = null)
+ {
+ $reflectionParameter = $this->getMockBuilder('\ReflectionParameter')->disableOriginalConstructor()->getMock();
+
+ if (null !== $class) {
+ $reflectionClass = $this->getMockBuilder('\ReflectionClass')->disableOriginalConstructor()->getMock();
+ $reflectionClass->expects($this->any())->method('getName')->willReturn($class);
+ $reflectionParameter->expects($this->any())->method('getClass')->willReturn($reflectionClass);
+ }
+
+ return $reflectionParameter;
+ }
+}
+
+class UserFixture implements UserInterface
+{
+ public function getRoles() {}
+ public function getPassword() {}
+ public function getSalt() {}
+ public function getUsername() {}
+ public function eraseCredentials() {}
+}
diff --git a/src/Symfony/Component/HttpKernel/CHANGELOG.md b/src/Symfony/Component/HttpKernel/CHANGELOG.md
index ad27886ac8738..e8d60ff309a10 100644
--- a/src/Symfony/Component/HttpKernel/CHANGELOG.md
+++ b/src/Symfony/Component/HttpKernel/CHANGELOG.md
@@ -1,6 +1,12 @@
CHANGELOG
=========
+2.8.0
+-----
+
+ * added argument resolvers
+ * deprecated `Symfony\Component\HttpKernel\Controller\ControllerResolver::getArguments()` and `doGetArguments()` in favor of argument resolvers
+
2.7.0
-----
diff --git a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/ArgumentResolverInterface.php b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/ArgumentResolverInterface.php
new file mode 100644
index 0000000000000..9fa90de09e360
--- /dev/null
+++ b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/ArgumentResolverInterface.php
@@ -0,0 +1,44 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpKernel\Controller\ArgumentResolver;
+
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * An ArgumentResolverInterface implementation resolves the arguments of
+ * controllers.
+ *
+ * @author Wouter J
+ */
+interface ArgumentResolverInterface
+{
+ /**
+ * Checks if the current pameter can be esolved by this argument
+ * resolver.
+ *
+ * @param Request $request
+ * @param \ReflectionParameter $parameter
+ *
+ * @return bool
+ */
+ public function supports(Request $request, \ReflectionParameter $parameter);
+
+ /**
+ * Resolves the current parameter into an argument.
+ *
+ * @param Request $request
+ * @param \ReflectionParameter $parameter
+ *
+ * @return mixed The resolved argument
+ */
+ public function resolve(Request $request, \ReflectionParameter $parameter);
+}
diff --git a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/PsrServerRequestArgumentResolver.php b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/PsrServerRequestArgumentResolver.php
new file mode 100644
index 0000000000000..35233a08422b6
--- /dev/null
+++ b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/PsrServerRequestArgumentResolver.php
@@ -0,0 +1,52 @@
+
+ * @author Wouter J
+ */
+class PsrServerRequestArgumentResolver implements ArgumentResolverInterface
+{
+ /**
+ * @var array
+ */
+ private static $supportedTypes = array(
+ 'Psr\Http\Message\ServerRequestInterface' => true,
+ 'Psr\Http\Message\RequestInterface' => true,
+ 'Psr\Http\Message\MessageInterface' => true,
+ );
+
+ /**
+ * @var HttpMessageFactoryInterface
+ */
+ private $httpMessageFactory;
+
+ public function __construct(HttpMessageFactoryInterface $httpMessageFactory)
+ {
+ $this->httpMessageFactory = $httpMessageFactory;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function supports(Request $request, \ReflectionParameter $parameter)
+ {
+ $class = $parameter->getClass();
+
+ return null !== $class && isset(self::$supportedTypes[$class->getName()]);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function resolve(Request $request, \ReflectionParameter $parameter)
+ {
+ return $this->httpMessageFactory->createRequest($request);
+ }
+}
diff --git a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestArgumentResolver.php b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestArgumentResolver.php
new file mode 100644
index 0000000000000..f80d7b4ce31a2
--- /dev/null
+++ b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestArgumentResolver.php
@@ -0,0 +1,40 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpKernel\Controller\ArgumentResolver;
+
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Resolves arguments typehinting for the HttpFoundation Request object.
+ *
+ * @author Wouter J
+ */
+class RequestArgumentResolver implements ArgumentResolverInterface
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function supports(Request $request, \ReflectionParameter $parameter)
+ {
+ $class = $parameter->getClass();
+
+ return $class && $class->isInstance($request);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function resolve(Request $request, \ReflectionParameter $parameter)
+ {
+ return $request;
+ }
+}
diff --git a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestAttributesArgumentResolver.php b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestAttributesArgumentResolver.php
new file mode 100644
index 0000000000000..e6c23ceec5d7c
--- /dev/null
+++ b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestAttributesArgumentResolver.php
@@ -0,0 +1,38 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpKernel\Controller\ArgumentResolver;
+
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Resolves arguments which names are equal to the name of a request attribute.
+ *
+ * @author Wouter J
+ */
+class RequestAttributesArgumentResolver implements ArgumentResolverInterface
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function supports(Request $request, \ReflectionParameter $parameter)
+ {
+ return $request->attributes->has($parameter->getName());
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function resolve(Request $request, \ReflectionParameter $parameter)
+ {
+ return $request->attributes->get($parameter->getName());
+ }
+}
diff --git a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolverManager.php b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolverManager.php
new file mode 100644
index 0000000000000..46bfb003da7ae
--- /dev/null
+++ b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolverManager.php
@@ -0,0 +1,102 @@
+
+ *
+ * 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;
+use Symfony\Component\HttpKernel\Controller\ArgumentResolver\ArgumentResolverInterface;
+
+/**
+ * The ArgumentResolverManager chains over the registered argument resolvers to
+ * resolve all controller arguments.
+ *
+ * @author Wouter J
+ */
+class ArgumentResolverManager
+{
+ /**
+ * @var ArgumentResolverInterface[]
+ */
+ private $resolvers;
+
+ /**
+ * @param ArgumentResolverInterface[] $resolvers
+ */
+ public function __construct(array $resolvers = array())
+ {
+ $this->resolvers = $resolvers;
+ }
+
+ /**
+ * Adds an argument resolver to the chain.
+ *
+ * The order in which the resolvers will be chained is equal
+ * to the order in which this method is called.
+ *
+ * @param ArgumentResolverInterface $resolver
+ */
+ public function add(ArgumentResolverInterface $resolver)
+ {
+ $this->resolvers[] = $resolver;
+ }
+
+ /**
+ * Resolves the constructor arguments of the passed controller.
+ *
+ * @param Request $request
+ * @param callable $controller
+ *
+ * @return array
+ */
+ public function getArguments(Request $request, $controller)
+ {
+ if (!is_callable($controller)) {
+ throw new \InvalidArgumentException(sprintf('Expected a callable as second parameter, got "%s".', is_object($controller) ? get_class($controller) : gettype($controller)));
+ }
+
+ if (is_array($controller)) {
+ $controllerReflection = new \ReflectionMethod($controller[0], $controller[1]);
+ } elseif (is_object($controller) && !$controller instanceof \Closure) {
+ $controllerReflection = new \ReflectionObject($controller);
+ $controllerReflection = $controllerReflection->getMethod('__invoke');
+ } else {
+ $controllerReflection = new \ReflectionFunction($controller);
+ }
+
+ $parameters = $controllerReflection->getParameters();
+ $arguments = array();
+
+ foreach ($parameters as $parameter) {
+ foreach ($this->resolvers as $argumentResolver) {
+ if ($argumentResolver->supports($request, $parameter)) {
+ $arguments[] = $argumentResolver->resolve($request, $parameter);
+ continue 2;
+ }
+ }
+
+ if ($parameter->isDefaultValueAvailable()) {
+ $arguments[] = $parameter->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 and none of the argument resolvers could resolve its value).', $repr, $parameter->name));
+ }
+ }
+
+ return $arguments;
+ }
+}
diff --git a/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php b/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php
index 94df05eee415f..f1dfdcfc21c8f 100644
--- a/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php
+++ b/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php
@@ -13,6 +13,8 @@
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpKernel\Controller\ArgumentResolver\RequestArgumentResolver;
+use Symfony\Component\HttpKernel\Controller\ArgumentResolver\RequestAttributesArgumentResolver;
/**
* ControllerResolver.
@@ -29,6 +31,11 @@ class ControllerResolver implements ControllerResolverInterface
{
private $logger;
+ /**
+ * @var ArgumentResolverManager
+ */
+ private $argumentResolverManager;
+
/**
* Constructor.
*
@@ -39,6 +46,14 @@ public function __construct(LoggerInterface $logger = null)
$this->logger = $logger;
}
+ /**
+ * @internal
+ */
+ public function setArgumentResolverManager(ArgumentResolverManager $argumentResolverManager)
+ {
+ $this->argumentResolverManager = $argumentResolverManager;
+ }
+
/**
* {@inheritdoc}
*
@@ -102,34 +117,20 @@ public function getArguments(Request $request, $controller)
$r = new \ReflectionFunction($controller);
}
+ $reflector = new \ReflectionMethod($this, 'doGetArguments');
+ if ($reflector->getDeclaringClass()->getName() !== __CLASS__) {
+ @trigger_error('The ControllerResolverInterface::doGetArguments() method is deprecated since version 2.8 and will be removed in 3.0. Use the ArgumentResolverManager and custom ArgumentResolverInterface implementations instead.', E_USER_DEPRECATED);
+ }
+
return $this->doGetArguments($request, $controller, $r->getParameters());
}
+ /**
+ * @deprecated As of Symfony 2.8, to be removed in Symfony 3.0. Create a custom ArgumentResolverInterface implementation instead.
+ */
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)) {
- $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;
+ return $this->getArgumentResolverManager()->getArguments($request, $controller);
}
/**
@@ -157,7 +158,7 @@ protected function createController($controller)
}
/**
- * Returns an instantiated controller
+ * Returns an instantiated controller.
*
* @param string $class A class name
*
@@ -167,4 +168,16 @@ protected function instantiateController($class)
{
return new $class();
}
+
+ private function getArgumentResolverManager()
+ {
+ if (null === $this->argumentResolverManager) {
+ $this->argumentResolverManager = new ArgumentResolverManager(array(
+ new RequestArgumentResolver(),
+ new RequestAttributesArgumentResolver(),
+ ));
+ }
+
+ return $this->argumentResolverManager;
+ }
}
diff --git a/src/Symfony/Component/HttpKernel/Controller/ControllerResolverInterface.php b/src/Symfony/Component/HttpKernel/Controller/ControllerResolverInterface.php
index 6f805ed2dab77..4cf398b6ae3dd 100644
--- a/src/Symfony/Component/HttpKernel/Controller/ControllerResolverInterface.php
+++ b/src/Symfony/Component/HttpKernel/Controller/ControllerResolverInterface.php
@@ -57,6 +57,8 @@ public function getController(Request $request);
*
* @throws \RuntimeException When value for argument given is not provided
*
+ * @deprecated As of Symfony 2.8, to be removed in Symfony 3.0. Use the ArgumentResolverManager instead.
+ *
* @api
*/
public function getArguments(Request $request, $controller);
diff --git a/src/Symfony/Component/HttpKernel/DependencyInjection/ContainerAwareHttpKernel.php b/src/Symfony/Component/HttpKernel/DependencyInjection/ContainerAwareHttpKernel.php
index c64c4c3939981..7b3d4b44479c9 100644
--- a/src/Symfony/Component/HttpKernel/DependencyInjection/ContainerAwareHttpKernel.php
+++ b/src/Symfony/Component/HttpKernel/DependencyInjection/ContainerAwareHttpKernel.php
@@ -13,6 +13,7 @@
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
+use Symfony\Component\HttpKernel\Controller\ArgumentResolverManager;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\HttpKernel;
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
@@ -35,15 +36,16 @@ class ContainerAwareHttpKernel extends HttpKernel
/**
* Constructor.
*
- * @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance
- * @param ContainerInterface $container A ContainerInterface instance
- * @param ControllerResolverInterface $controllerResolver A ControllerResolverInterface instance
- * @param RequestStack $requestStack A stack for master/sub requests
- * @param bool $triggerDeprecation Whether or not to trigger the deprecation warning for the ContainerAwareHttpKernel
+ * @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance
+ * @param ContainerInterface $container A ContainerInterface instance
+ * @param ControllerResolverInterface $controllerResolver A ControllerResolverInterface instance
+ * @param RequestStack $requestStack A stack for master/sub requests
+ * @param ArgumentResolverManager $argumentResolverManager A manager to resolve arguments
+ * @param bool $triggerDeprecation Whether or not to trigger the deprecation warning for the ContainerAwareHttpKernel
*/
- public function __construct(EventDispatcherInterface $dispatcher, ContainerInterface $container, ControllerResolverInterface $controllerResolver, RequestStack $requestStack = null, $triggerDeprecation = true)
+ public function __construct(EventDispatcherInterface $dispatcher, ContainerInterface $container, ControllerResolverInterface $controllerResolver, RequestStack $requestStack = null, ArgumentResolverManager $argumentResolverManager = null, $triggerDeprecation = true)
{
- parent::__construct($dispatcher, $controllerResolver, $requestStack);
+ parent::__construct($dispatcher, $controllerResolver, $requestStack, $argumentResolverManager);
if ($triggerDeprecation) {
trigger_error('The '.__CLASS__.' class is deprecated since version 2.7 and will be removed in 3.0. Use the Symfony\Component\HttpKernel\HttpKernel class instead.', E_USER_DEPRECATED);
diff --git a/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterArgumentResolversPass.php b/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterArgumentResolversPass.php
new file mode 100644
index 0000000000000..21c61f1829be9
--- /dev/null
+++ b/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterArgumentResolversPass.php
@@ -0,0 +1,45 @@
+
+ */
+class RegisterArgumentResolversPass implements CompilerPassInterface
+{
+ private $managerService;
+ private $resolverTag;
+
+ public function __construct($managerService = 'argument_resolver.manager', $resolverTag = 'kernel.argument_resolver')
+ {
+ $this->managerService = $managerService;
+ $this->resolverTag = $resolverTag;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function process(ContainerBuilder $container)
+ {
+ if (!$container->hasDefinition($this->managerService) && !$container->hasAlias($this->managerService)) {
+ return;
+ }
+
+ $definition = $container->findDefinition($this->managerService);
+ $resolvers = array();
+
+ foreach ($container->findTaggedServiceIds($this->resolverTag) as $id => $tags) {
+ $priority = isset($tags[0]['priority']) ? $tags[0]['priority'] : 0;
+ $resolvers[$priority][] = new Reference($id);
+ }
+
+ ksort($resolvers);
+ $resolvers = call_user_func_array('array_merge', $resolvers);
+
+ $definition->replaceArgument(1, $resolvers);
+ }
+}
diff --git a/src/Symfony/Component/HttpKernel/HttpKernel.php b/src/Symfony/Component/HttpKernel/HttpKernel.php
index 473f780ca3cb6..d63259927305e 100644
--- a/src/Symfony/Component/HttpKernel/HttpKernel.php
+++ b/src/Symfony/Component/HttpKernel/HttpKernel.php
@@ -11,6 +11,9 @@
namespace Symfony\Component\HttpKernel;
+use Symfony\Component\HttpKernel\Controller\ArgumentResolver\RequestArgumentResolver;
+use Symfony\Component\HttpKernel\Controller\ArgumentResolver\RequestAttributesArgumentResolver;
+use Symfony\Component\HttpKernel\Controller\ArgumentResolverManager;
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
@@ -42,17 +45,29 @@ class HttpKernel implements HttpKernelInterface, TerminableInterface
/**
* Constructor.
*
- * @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance
- * @param ControllerResolverInterface $resolver A ControllerResolverInterface instance
- * @param RequestStack $requestStack A stack for master/sub requests
+ * @param EventDispatcherInterface $dispatcher An EventDispatcherInterface instance
+ * @param ControllerResolverInterface $resolver A ControllerResolverInterface instance
+ * @param RequestStack $requestStack A stack for master/sub requests
+ * @param ArgumentResolverManager $argumentResolverManager A manager to resolve the controller arguments
*
* @api
*/
- public function __construct(EventDispatcherInterface $dispatcher, ControllerResolverInterface $resolver, RequestStack $requestStack = null)
+ public function __construct(EventDispatcherInterface $dispatcher, ControllerResolverInterface $resolver, RequestStack $requestStack = null, ArgumentResolverManager $argumentResolverManager = null)
{
$this->dispatcher = $dispatcher;
$this->resolver = $resolver;
$this->requestStack = $requestStack ?: new RequestStack();
+
+ if (null === $argumentResolverManager) {
+ $argumentResolverManager = new ArgumentResolverManager(array(
+ new RequestArgumentResolver(),
+ new RequestAttributesArgumentResolver(),
+ ));
+ }
+
+ if (method_exists($resolver, 'setArgumentResolverManager')) {
+ $resolver->setArgumentResolverManager($argumentResolverManager);
+ }
}
/**
@@ -141,6 +156,11 @@ private function handleRaw(Request $request, $type = self::MASTER_REQUEST)
$controller = $event->getController();
// controller arguments
+ $reflector = new \ReflectionMethod($this->resolver, 'getArguments');
+ if (0 !== strpos($reflector->getDeclaringClass()->getName(), 'Symfony\Component\HttpKernel\Controller\\')) {
+ @trigger_error('The ControllerResolverInterface::getArguments() method is deprecated since version 2.8 and will be removed in 3.0. Use the ArgumentResolverManager and custom ArgumentResolverInterface implementations instead.', E_USER_DEPRECATED);
+ }
+
$arguments = $this->resolver->getArguments($request, $controller);
// call controller
diff --git a/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/PsrServerRequestArgumentResolverTest.php b/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/PsrServerRequestArgumentResolverTest.php
new file mode 100644
index 0000000000000..49b53abe1aa57
--- /dev/null
+++ b/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/PsrServerRequestArgumentResolverTest.php
@@ -0,0 +1,67 @@
+
+ */
+class PsrServerRequestArgumentResolverTest extends \PHPUnit_Framework_TestCase
+{
+ private $httpMessageFactory;
+ private $resolver;
+
+ protected function setUp()
+ {
+ $this->httpMessageFactory = $this->getMock('Symfony\Bridge\PsrHttpMessage\HttpMessageFactoryInterface', array('createRequest'));
+ $this->resolver = new PsrServerRequestArgumentResolver($this->httpMessageFactory);
+ }
+
+ /**
+ * @dataProvider provideClasses
+ */
+ public function testSupports($class, $supported = true)
+ {
+ $this->assertEquals($supported, $this->resolver->supports($this->getRequestMock(), $this->getReflectionParameterMock($class)));
+ }
+
+ public function provideClasses()
+ {
+ return array(
+ array('Psr\Http\Message\ServerRequestInterface'),
+ array('Psr\Http\Message\RequestInterface'),
+ array('Psr\Http\Message\MessageInterface'),
+ array('\stdClass', false),
+ array('Symfony\Component\HttpFoundation\Request', false),
+ );
+ }
+
+ public function testResolvesUsingHttpMessageFactory()
+ {
+ $request = $this->getRequestMock();
+
+ $this->httpMessageFactory->expects($this->once())->method('createRequest')->with($request);
+
+ $this->resolver->resolve($request, $this->getReflectionParameterMock());
+ }
+
+ private function getRequestMock()
+ {
+ return $this->getMock('Symfony\Component\HttpFoundation\Request');
+ }
+
+ private function getReflectionParameterMock($class = null)
+ {
+ $reflectionParameter = $this->getMockBuilder('ReflectionParameter')->disableOriginalConstructor()->getMock();
+
+ if (null !== $class) {
+ $reflectionClass = $this->getMockBuilder('ReflectionClass')->disableOriginalConstructor()->getMock();
+ $reflectionClass->expects($this->any())->method('getName')->willReturn($class);
+
+ $reflectionParameter->expects($this->any())->method('getClass')->will($this->returnValue($reflectionClass));
+ }
+
+ return $reflectionParameter;
+ }
+}
diff --git a/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/RequestArgumentResolverTest.php b/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/RequestArgumentResolverTest.php
new file mode 100644
index 0000000000000..ae6917829df91
--- /dev/null
+++ b/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/RequestArgumentResolverTest.php
@@ -0,0 +1,63 @@
+
+ */
+class RequestArgumentResolverTest extends \PHPUnit_Framework_TestCase
+{
+ private $resolver;
+
+ protected function setUp()
+ {
+ $this->resolver = new RequestArgumentResolver();
+ }
+
+ /**
+ * @dataProvider provideClasses
+ */
+ public function testSupports($class, $supported = true)
+ {
+ $this->assertEquals($supported, $this->resolver->supports($this->getRequestMock(), $this->getReflectionParameterMock($class)));
+ }
+
+ public function provideClasses()
+ {
+ return array(
+ array('Symfony\Component\HttpFoundation\Request'),
+ array('Symfony\Component\BrowerKit\Request', false),
+ array('\stdClass', false),
+ );
+ }
+
+ public function testResolvesToRequest()
+ {
+ $request = $this->getRequestMock();
+
+ $this->assertEquals($request, $this->resolver->resolve($request, $this->getReflectionParameterMock()));
+ }
+
+ private function getRequestMock()
+ {
+ return $this->getMock('Symfony\Component\HttpFoundation\Request');
+ }
+
+ private function getReflectionParameterMock($class = null)
+ {
+ $reflectionParameter = $this->getMockBuilder('ReflectionParameter')->disableOriginalConstructor()->getMock();
+
+ if (null !== $class) {
+ $reflectionClass = $this->getMockBuilder('ReflectionClass')->disableOriginalConstructor()->getMock();
+ $reflectionClass->expects($this->any())->method('isInstance')->will($this->returnCallback(function ($obj) use ($class) {
+ return is_a($obj, $class);
+ }));
+
+ $reflectionParameter->expects($this->any())->method('getClass')->will($this->returnValue($reflectionClass));
+ }
+
+ return $reflectionParameter;
+ }
+}
diff --git a/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/RequestAttributesArgumentResolverTest.php b/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/RequestAttributesArgumentResolverTest.php
new file mode 100644
index 0000000000000..55c3d38fb3d66
--- /dev/null
+++ b/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/RequestAttributesArgumentResolverTest.php
@@ -0,0 +1,60 @@
+
+ */
+class RequestAttributesArgumentResolverTest extends \PHPUnit_Framework_TestCase
+{
+ private $resolver;
+
+ public function setUp()
+ {
+ $this->resolver = new RequestAttributesArgumentResolver();
+ }
+
+ /**
+ * @dataProvider provideParameters
+ */
+ public function testSupports($parameterName, $supported = true)
+ {
+ $this->assertEquals($supported, $this->resolver->supports($this->getRequestMock(), $this->getReflectionParameterMock($parameterName)));
+ }
+
+ public function provideParameters()
+ {
+ return array(
+ array('exists'),
+ array('not_exists', false),
+ );
+ }
+
+ public function testResolvesToRequestAttributeValues()
+ {
+ $this->assertEquals('value_of_exists', $this->resolver->resolve($this->getRequestMock(), $this->getReflectionParameterMock('exists')));
+ }
+
+ private function getRequestMock()
+ {
+ $request = $this->getMock('Symfony\Component\HttpFoundation\Request');
+ $request->attributes = $this->getMock('Symfony\Component\HttpFoundation\ParameterBag');
+ $request->attributes->expects($this->any())->method('has')->will($this->returnValueMap(array(
+ array('exists', true),
+ array('not_exists', false),
+ )));
+ $request->attributes->expects($this->any())->method('get')->with('exists')->willReturn('value_of_exists');
+
+ return $request;
+ }
+
+ private function getReflectionParameterMock($name)
+ {
+ $reflectionParameter = $this->getMockBuilder('ReflectionParameter')->disableOriginalConstructor()->getMock();
+ $reflectionParameter->expects($this->any())->method('getName')->willReturn($name);
+
+ return $reflectionParameter;
+ }
+}
diff --git a/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolverManagerTest.php b/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolverManagerTest.php
new file mode 100644
index 0000000000000..e5e7087e73692
--- /dev/null
+++ b/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolverManagerTest.php
@@ -0,0 +1,133 @@
+
+ *
+ * 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\ArgumentResolverManager;
+
+class ArgumentResolverManagerTest extends \PHPUnit_Framework_TestCase
+{
+ private $manager;
+ private $resolver1;
+ private $resolver2;
+ private $request;
+
+ public function setUp()
+ {
+ $this->resolver1 = $this->getMock('Symfony\Component\HttpKernel\Controller\ArgumentResolver\ArgumentResolverInterface');
+ $this->resolver2 = $this->getMock('Symfony\Component\HttpKernel\Controller\ArgumentResolver\ArgumentResolverInterface');
+
+ $this->manager = new ArgumentResolverManager(array(
+ $this->resolver1,
+ $this->resolver2,
+ ));
+
+ $this->request = $this->getMock('Symfony\Component\HttpFoundation\Request');
+ }
+
+ public function testGetArgumentsWithoutControllerParameters()
+ {
+ $this->assertArguments(array(), function () { });
+ }
+
+ public function testGetArgumentsFirstResolverAccepts()
+ {
+ $this->promiseResolverToMatch($this->resolver1, 'resolved_value');
+
+ $this->assertArguments(array('resolved_value'), $this->getControllerWithOneParameter());
+ }
+
+ public function testGetArgumentsSecondResolverAccepts()
+ {
+ $this->promiseResolverToNotMatch($this->resolver1);
+ $this->promiseResolverToMatch($this->resolver2, 'resolved_value');
+
+ $this->assertArguments(array('resolved_value'), $this->getControllerWithOneParameter());
+ }
+
+ /**
+ * @expectedException RuntimeException
+ */
+ public function testGetArgumentsFailsIfNoResolverAccepts()
+ {
+ $this->promiseResolverToNotMatch($this->resolver1);
+ $this->promiseResolverToNotMatch($this->resolver2);
+
+ $this->manager->getArguments($this->request, $this->getControllerWithOneParameter());
+ }
+
+ public function testGetArgumentResolvingMultipleParameters()
+ {
+ $this->resolver1->expects($this->any())
+ ->method('supports')
+ ->will($this->onConsecutiveCalls(false, true, true));
+ $this->resolver1->expects($this->any())
+ ->method('resolve')
+ ->will($this->onConsecutiveCalls('1st resolved by 1', '2nd resolved by 1'));
+
+ $this->resolver2->expects($this->any())
+ ->method('supports')
+ ->will($this->onConsecutiveCalls(true, false, true));
+ $this->resolver2->expects($this->any())
+ ->method('resolve')
+ ->will($this->onConsecutiveCalls('1st resolved by 2', '2nd resolved by 2'));
+
+ $this->assertArguments(
+ array('1st resolved by 2', '1st resolved by 1', '2nd resolved by 1'),
+ function ($a, $b, $c) { }
+ );
+ }
+
+ public function testControllerWithOneOptionalParameterWhichDoesNotMatch()
+ {
+ $this->promiseResolverToNotMatch($this->resolver1);
+ $this->promiseResolverToNotMatch($this->resolver2);
+
+ $this->assertArguments(array('default'), function ($a = 'default') { });
+ }
+
+ public function testControllerWithOneOptionalParameterWhichDoesMatch()
+ {
+ $this->promiseResolverToMatch($this->resolver1, 'resolved by 1');
+ $this->promiseResolverToNotMatch($this->resolver2);
+
+ $this->assertArguments(array('resolved by 1'), function ($a = 'default') { });
+ }
+
+ public function testControllerWithOneParameterWithNullDefault()
+ {
+ $this->promiseResolverToNotMatch($this->resolver1);
+ $this->promiseResolverToNotMatch($this->resolver2);
+
+ $this->assertArguments(array(null), function ($a = null) { });
+ }
+
+ private function assertArguments(array $expected, $controller)
+ {
+ $this->assertEquals($expected, $this->manager->getArguments($this->request, $controller));
+ }
+
+ private function promiseResolverToMatch($resolver, $return)
+ {
+ $resolver->expects($this->any())->method('supports')->will($this->returnValue(true));
+ $resolver->expects($this->any())->method('resolve')->will($this->returnValue($return));
+ }
+
+ private function promiseResolverToNotMatch($resolver)
+ {
+ $resolver->expects($this->any())->method('supports')->will($this->returnValue(false));
+ }
+
+ private function getControllerWithOneParameter()
+ {
+ return function ($a) { };
+ }
+}
diff --git a/src/Symfony/Component/HttpKernel/Tests/Controller/ControllerResolverTest.php b/src/Symfony/Component/HttpKernel/Tests/Controller/ControllerResolverTest.php
index 32db4e47adc5a..ee5b7a8dc90e7 100644
--- a/src/Symfony/Component/HttpKernel/Tests/Controller/ControllerResolverTest.php
+++ b/src/Symfony/Component/HttpKernel/Tests/Controller/ControllerResolverTest.php
@@ -220,19 +220,19 @@ public function controllerMethod1($foo)
{
}
- protected function controllerMethod2($foo, $bar = null)
+ public function controllerMethod2($foo, $bar = null)
{
}
- protected function controllerMethod3($foo, $bar = null, $foobar)
+ public function controllerMethod3($foo, $bar = null, $foobar)
{
}
- protected static function controllerMethod4()
+ public static function controllerMethod4()
{
}
- protected function controllerMethod5(Request $request)
+ public function controllerMethod5(Request $request)
{
}
}
diff --git a/src/Symfony/Component/HttpKernel/Tests/Debug/TraceableEventDispatcherTest.php b/src/Symfony/Component/HttpKernel/Tests/Debug/TraceableEventDispatcherTest.php
index f64d7247c0b48..bcf7449de96ab 100644
--- a/src/Symfony/Component/HttpKernel/Tests/Debug/TraceableEventDispatcherTest.php
+++ b/src/Symfony/Component/HttpKernel/Tests/Debug/TraceableEventDispatcherTest.php
@@ -20,6 +20,11 @@
class TraceableEventDispatcherTest extends \PHPUnit_Framework_TestCase
{
+ /**
+ * Tagged as legacy because of the usage of the deprecated ControllerResolver#getArguments().
+ *
+ * @group legacy
+ */
public function testStopwatchSections()
{
$dispatcher = new TraceableEventDispatcher(new EventDispatcher(), $stopwatch = new Stopwatch());
@@ -39,6 +44,11 @@ public function testStopwatchSections()
), array_keys($events));
}
+ /**
+ * Tagged as legacy because of the usage of the deprecated ControllerResolver#getArguments().
+ *
+ * @group legacy
+ */
public function testStopwatchCheckControllerOnRequestEvent()
{
$stopwatch = $this->getMockBuilder('Symfony\Component\Stopwatch\Stopwatch')
@@ -55,6 +65,11 @@ public function testStopwatchCheckControllerOnRequestEvent()
$kernel->handle($request);
}
+ /**
+ * Tagged as legacy because of the usage of the deprecated ControllerResolver#getArguments().
+ *
+ * @group legacy
+ */
public function testStopwatchStopControllerOnRequestEvent()
{
$stopwatch = $this->getMockBuilder('Symfony\Component\Stopwatch\Stopwatch')
diff --git a/src/Symfony/Component/HttpKernel/Tests/Fragment/InlineFragmentRendererTest.php b/src/Symfony/Component/HttpKernel/Tests/Fragment/InlineFragmentRendererTest.php
index 4e487a478a600..bd2ef30a0da7d 100644
--- a/src/Symfony/Component/HttpKernel/Tests/Fragment/InlineFragmentRendererTest.php
+++ b/src/Symfony/Component/HttpKernel/Tests/Fragment/InlineFragmentRendererTest.php
@@ -140,6 +140,11 @@ private function getKernelExpectingRequest(Request $request)
return $kernel;
}
+ /**
+ * Tagged as legacy because of the usage of the deprecated ControllerResolver#getArguments().
+ *
+ * @group legacy
+ */
public function testExceptionInSubRequestsDoesNotMangleOutputBuffers()
{
$resolver = $this->getMock('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface');
diff --git a/src/Symfony/Component/HttpKernel/Tests/HttpCache/TestHttpKernel.php b/src/Symfony/Component/HttpKernel/Tests/HttpCache/TestHttpKernel.php
index 5546ba2ed830e..a3b62b34272df 100644
--- a/src/Symfony/Component/HttpKernel/Tests/HttpCache/TestHttpKernel.php
+++ b/src/Symfony/Component/HttpKernel/Tests/HttpCache/TestHttpKernel.php
@@ -15,10 +15,11 @@
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
-use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
use Symfony\Component\EventDispatcher\EventDispatcher;
+use Symfony\Component\HttpKernel\Tests\TestArgumentResolverManager;
+use Symfony\Component\HttpKernel\Tests\TestControllerResolver;
-class TestHttpKernel extends HttpKernel implements ControllerResolverInterface
+class TestHttpKernel extends HttpKernel
{
protected $body;
protected $status;
@@ -35,7 +36,7 @@ public function __construct($body, $status, $headers, \Closure $customizer = nul
$this->headers = $headers;
$this->customizer = $customizer;
- parent::__construct(new EventDispatcher(), $this);
+ parent::__construct(new EventDispatcher(), new TestControllerResolver($this), null, new TestArgumentResolverManager());
}
public function getBackendRequest()
@@ -56,16 +57,6 @@ public function isCatchingExceptions()
return $this->catch;
}
- public function getController(Request $request)
- {
- return array($this, 'callController');
- }
-
- public function getArguments(Request $request, $controller)
- {
- return array($request);
- }
-
public function callController(Request $request)
{
$this->called = true;
diff --git a/src/Symfony/Component/HttpKernel/Tests/HttpCache/TestMultipleHttpKernel.php b/src/Symfony/Component/HttpKernel/Tests/HttpCache/TestMultipleHttpKernel.php
index 773e221482bed..19de6269aaae2 100644
--- a/src/Symfony/Component/HttpKernel/Tests/HttpCache/TestMultipleHttpKernel.php
+++ b/src/Symfony/Component/HttpKernel/Tests/HttpCache/TestMultipleHttpKernel.php
@@ -15,10 +15,11 @@
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
-use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
use Symfony\Component\EventDispatcher\EventDispatcher;
+use Symfony\Component\HttpKernel\Tests\TestArgumentResolverManager;
+use Symfony\Component\HttpKernel\Tests\TestControllerResolver;
-class TestMultipleHttpKernel extends HttpKernel implements ControllerResolverInterface
+class TestMultipleHttpKernel extends HttpKernel
{
protected $bodies = array();
protected $statuses = array();
@@ -34,7 +35,7 @@ public function __construct($responses)
$this->headers[] = $response['headers'];
}
- parent::__construct(new EventDispatcher(), $this);
+ parent::__construct(new EventDispatcher(), new TestControllerResolver($this), null, new TestArgumentResolverManager());
}
public function getBackendRequest()
@@ -49,16 +50,6 @@ public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQ
return parent::handle($request, $type, $catch);
}
- public function getController(Request $request)
- {
- return array($this, 'callController');
- }
-
- public function getArguments(Request $request, $controller)
- {
- return array($request);
- }
-
public function callController(Request $request)
{
$this->called = true;
diff --git a/src/Symfony/Component/HttpKernel/Tests/HttpKernelTest.php b/src/Symfony/Component/HttpKernel/Tests/HttpKernelTest.php
index 97e68f66f979a..573d670574dc2 100644
--- a/src/Symfony/Component/HttpKernel/Tests/HttpKernelTest.php
+++ b/src/Symfony/Component/HttpKernel/Tests/HttpKernelTest.php
@@ -21,6 +21,11 @@
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\EventDispatcher\EventDispatcher;
+/**
+ * Tagged as legacy because of the usage of the deprecated ControllerResolver#getArguments().
+ *
+ * @group legacy
+ */
class HttpKernelTest extends \PHPUnit_Framework_TestCase
{
/**
diff --git a/src/Symfony/Component/HttpKernel/Tests/TestArgumentResolverManager.php b/src/Symfony/Component/HttpKernel/Tests/TestArgumentResolverManager.php
new file mode 100644
index 0000000000000..093548cd5d979
--- /dev/null
+++ b/src/Symfony/Component/HttpKernel/Tests/TestArgumentResolverManager.php
@@ -0,0 +1,26 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpKernel\Tests;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpKernel\Controller\ArgumentResolverManager;
+
+/**
+ * @author Wouter J
+ */
+class TestArgumentResolverManager extends ArgumentResolverManager
+{
+ public function getArguments(Request $request, $controller)
+ {
+ return array($request);
+ }
+}
diff --git a/src/Symfony/Component/HttpKernel/Tests/TestControllerResolver.php b/src/Symfony/Component/HttpKernel/Tests/TestControllerResolver.php
new file mode 100644
index 0000000000000..828b3ca36f2a7
--- /dev/null
+++ b/src/Symfony/Component/HttpKernel/Tests/TestControllerResolver.php
@@ -0,0 +1,26 @@
+
+ */
+class TestControllerResolver extends ControllerResolver
+{
+ private $controller;
+
+ public function __construct($controller, LoggerInterface $logger = null)
+ {
+ parent::__construct($logger);
+ $this->controller = $controller;
+ }
+
+ public function getController(Request $request)
+ {
+ return array($this->controller, 'callController');
+ }
+}
diff --git a/src/Symfony/Component/HttpKernel/Tests/TestHttpKernel.php b/src/Symfony/Component/HttpKernel/Tests/TestHttpKernel.php
index d526c4de80c36..6330505102160 100644
--- a/src/Symfony/Component/HttpKernel/Tests/TestHttpKernel.php
+++ b/src/Symfony/Component/HttpKernel/Tests/TestHttpKernel.php
@@ -14,24 +14,13 @@
use Symfony\Component\HttpKernel\HttpKernel;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
-use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
use Symfony\Component\EventDispatcher\EventDispatcher;
-class TestHttpKernel extends HttpKernel implements ControllerResolverInterface
+class TestHttpKernel extends HttpKernel
{
public function __construct()
{
- parent::__construct(new EventDispatcher(), $this);
- }
-
- public function getController(Request $request)
- {
- return array($this, 'callController');
- }
-
- public function getArguments(Request $request, $controller)
- {
- return array($request);
+ parent::__construct(new EventDispatcher(), new TestControllerResolver($this), null, new TestArgumentResolverManager());
}
public function callController(Request $request)