From 0743526e2f2b67fe65f9e7802cb8e941de083ffd Mon Sep 17 00:00:00 2001 From: WouterJ Date: Fri, 28 Feb 2014 13:25:25 +0100 Subject: [PATCH 1/5] Refactored argument resolving out of the ControllerResolver --- .../FrameworkBundle/FrameworkBundle.php | 2 + .../Resources/config/services.xml | 1 + .../FrameworkBundle/Resources/config/web.xml | 10 ++ src/Symfony/Component/HttpKernel/CHANGELOG.md | 2 + .../RequestArgumentResolver.php | 41 ++++++ .../RequestAttributesArgumentResolver.php | 41 ++++++ .../Controller/ArgumentResolverInterface.php | 44 +++++++ .../Controller/ArgumentResolverManager.php | 88 +++++++++++++ .../Controller/ControllerResolver.php | 5 + .../ContainerAwareHttpKernel.php | 6 +- .../RegisterArgumentResolversPass.php | 56 +++++++++ .../Component/HttpKernel/HttpKernel.php | 30 ++++- .../ArgumentResolverManagerTest.php | 118 ++++++++++++++++++ .../Debug/TraceableEventDispatcherTest.php | 8 +- .../ContainerAwareHttpKernelTest.php | 19 +-- .../Fragment/InlineFragmentRendererTest.php | 10 +- 16 files changed, 460 insertions(+), 21 deletions(-) create mode 100644 src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestArgumentResolver.php create mode 100644 src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestAttributesArgumentResolver.php create mode 100644 src/Symfony/Component/HttpKernel/Controller/ArgumentResolverInterface.php create mode 100644 src/Symfony/Component/HttpKernel/Controller/ArgumentResolverManager.php create mode 100644 src/Symfony/Component/HttpKernel/DependencyInjection/RegisterArgumentResolversPass.php create mode 100644 src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolverManagerTest.php 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/services.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml index 63cbe6b00d682..09d60727bdb87 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml @@ -14,6 +14,7 @@ + diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml index af7d37449a6cb..b75b810d97e11 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml @@ -17,6 +17,16 @@ + + + + + + + + + + %kernel.charset% diff --git a/src/Symfony/Component/HttpKernel/CHANGELOG.md b/src/Symfony/Component/HttpKernel/CHANGELOG.md index 088e1803f4d11..b533cf3d32d5f 100644 --- a/src/Symfony/Component/HttpKernel/CHANGELOG.md +++ b/src/Symfony/Component/HttpKernel/CHANGELOG.md @@ -4,6 +4,8 @@ CHANGELOG 3.0.0 ----- + * added argument resolvers + * deprecated `Symfony\Component\HttpKernel\Controller\ControllerResolver#getArguments()` and `doGetArguments()`, use argument resolvers instead * removed `Symfony\Component\HttpKernel\Kernel::init()` * removed `Symfony\Component\HttpKernel\Kernel::isClassInActiveBundle()` and `Symfony\Component\HttpKernel\KernelInterface::isClassInActiveBundle()` 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..7f89d7fa2d329 --- /dev/null +++ b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestArgumentResolver.php @@ -0,0 +1,41 @@ + + * + * 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\HttpKernel\Controller\ArgumentResolverInterface; +use Symfony\Component\HttpFoundation\Request; + +/** + * Resolves arguments typehinting for the Request object. + * + * @author Wouter J + */ +class RequestArgumentResolver implements ArgumentResolverInterface +{ + /** + * {@inheritDoc} + */ + public function accepts(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..ce1af652c59a6 --- /dev/null +++ b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestAttributesArgumentResolver.php @@ -0,0 +1,41 @@ + + * + * 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\HttpKernel\Controller\ArgumentResolverInterface; +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 accepts(Request $request, \ReflectionParameter $parameter) + { + return array_key_exists($parameter->name, $request->attributes->all()); + } + + /** + * {@inheritDoc} + */ + public function resolve(Request $request, \ReflectionParameter $parameter) + { + $attributes = $request->attributes->all(); + + return $attributes[$parameter->name]; + } +} diff --git a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolverInterface.php b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolverInterface.php new file mode 100644 index 0000000000000..a58256568d536 --- /dev/null +++ b/src/Symfony/Component/HttpKernel/Controller/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; + +use Symfony\Component\HttpFoundation\Request; + +/** + * An ArgumentResolverInterface implementation resolves the arguments of + * controllers. + * + * @author Wouter J + */ +interface ArgumentResolverInterface +{ + /** + * Checks if the current parameter can be resolved by this argument + * resolver. + * + * @param Request $request + * @param \ReflectionParameter $parameter + * + * @return Boolean + */ + public function accepts(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/ArgumentResolverManager.php b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolverManager.php new file mode 100644 index 0000000000000..5c4e394ebb295 --- /dev/null +++ b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolverManager.php @@ -0,0 +1,88 @@ + + * + * 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; + +/** + * The ArgumentResolverManager chains over the registered argument resolvers to + * resolve all controller arguments. + * + * @author Wouter J + */ +class ArgumentResolverManager +{ + /** + * @var ArgumentResolverInterface[] + */ + protected $resolvers = array(); + + /** + * Adds an argument resolver. + * + * @param ArgumentResolverInterface $resolver + */ + public function addResolver(ArgumentResolverInterface $resolver) + { + $this->resolvers[] = $resolver; + } + + /** + * 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 a parameter cannot be resolved + */ + public function getArguments(Request $request, $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->accepts($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..03561fb3f1c5c 100644 --- a/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php +++ b/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php @@ -90,6 +90,8 @@ public function getController(Request $request) * {@inheritdoc} * * @api + * + * @deprecated Deprecated since Symfony 2.6, will be removed in Symfony 3.0. Use ArgumentResolvers instead */ public function getArguments(Request $request, $controller) { @@ -105,6 +107,9 @@ public function getArguments(Request $request, $controller) return $this->doGetArguments($request, $controller, $r->getParameters()); } + /** + * @deprecated Deprecated since Symfony 2.6, will be removed in Symfony 3.0. Use ArgumentResolvers instead + */ protected function doGetArguments(Request $request, $controller, array $parameters) { $attributes = $request->attributes->all(); diff --git a/src/Symfony/Component/HttpKernel/DependencyInjection/ContainerAwareHttpKernel.php b/src/Symfony/Component/HttpKernel/DependencyInjection/ContainerAwareHttpKernel.php index 4d249f69ef7ac..6dd0b61e0cba1 100644 --- a/src/Symfony/Component/HttpKernel/DependencyInjection/ContainerAwareHttpKernel.php +++ b/src/Symfony/Component/HttpKernel/DependencyInjection/ContainerAwareHttpKernel.php @@ -15,6 +15,7 @@ use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\HttpKernel\HttpKernel; +use Symfony\Component\HttpKernel\Controller\ArgumentResolverManager; use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -39,10 +40,11 @@ class ContainerAwareHttpKernel extends HttpKernel * @param ContainerInterface $container A ContainerInterface instance * @param ControllerResolverInterface $controllerResolver A ControllerResolverInterface instance * @param RequestStack $requestStack A stack for master/sub requests + * @param ArgumentResolverManager $argumentResolver An ArgumentResolverManager instance */ - public function __construct(EventDispatcherInterface $dispatcher, ContainerInterface $container, ControllerResolverInterface $controllerResolver, RequestStack $requestStack = null) + public function __construct(EventDispatcherInterface $dispatcher, ContainerInterface $container, ControllerResolverInterface $controllerResolver, RequestStack $requestStack = null, ArgumentResolverManager $argumentResolver = null) { - parent::__construct($dispatcher, $controllerResolver, $requestStack); + parent::__construct($dispatcher, $controllerResolver, $requestStack, $argumentResolver); $this->container = $container; diff --git a/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterArgumentResolversPass.php b/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterArgumentResolversPass.php new file mode 100644 index 0000000000000..e80a1593684bb --- /dev/null +++ b/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterArgumentResolversPass.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\HttpKernel\DependencyInjection; + +use Symfony\Component\DependencyInjection\Reference; +use Symfony\Component\DependencyInjection\ContainerBuilder; +use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; + +/** + * Compiler pass to register argument resolvers. + * + * @author Wouter J + */ +class RegisterArgumentResolversPass implements CompilerPassInterface +{ + /** + * @var string + */ + protected $managerService; + + /** + * @var string + */ + protected $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); + + foreach ($container->findTaggedServiceIds($this->resolverTag) as $id => $resolvers) { + $definition->addMethodCall('addResolver', array(new Reference($id))); + } + } +} diff --git a/src/Symfony/Component/HttpKernel/HttpKernel.php b/src/Symfony/Component/HttpKernel/HttpKernel.php index 82ffa95d71208..e465da9f28684 100644 --- a/src/Symfony/Component/HttpKernel/HttpKernel.php +++ b/src/Symfony/Component/HttpKernel/HttpKernel.php @@ -11,6 +11,8 @@ namespace Symfony\Component\HttpKernel; +use Symfony\Component\HttpKernel\Controller\ArgumentResolver; +use Symfony\Component\HttpKernel\Controller\ArgumentResolverManager; use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; @@ -37,22 +39,25 @@ class HttpKernel implements HttpKernelInterface, TerminableInterface { protected $dispatcher; protected $resolver; + protected $argumentResolver; protected $requestStack; /** * 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 $argumentResolver An ArgumentResolverManager instance * * @api */ - public function __construct(EventDispatcherInterface $dispatcher, ControllerResolverInterface $resolver, RequestStack $requestStack = null) + public function __construct(EventDispatcherInterface $dispatcher, ControllerResolverInterface $resolver, RequestStack $requestStack = null, ArgumentResolverManager $argumentResolver = null) { $this->dispatcher = $dispatcher; $this->resolver = $resolver; $this->requestStack = $requestStack ?: new RequestStack(); + $this->argumentResolver = $argumentResolver; } /** @@ -141,7 +146,7 @@ private function handleRaw(Request $request, $type = self::MASTER_REQUEST) $controller = $event->getController(); // controller arguments - $arguments = $this->resolver->getArguments($request, $controller); + $arguments = $this->getArgumentResolver()->getArguments($request, $controller); // call controller $response = call_user_func_array($controller, $arguments); @@ -290,4 +295,19 @@ private function varToString($var) return (string) $var; } + + /** + * @return ArgumentResolverManager + */ + protected function getArgumentResolver() + { + if (null === $this->argumentResolver) { + // to keep BC + $this->argumentResolver = new ArgumentResolverManager(); + $this->argumentResolver->addResolver(new ArgumentResolver\RequestArgumentResolver()); + $this->argumentResolver->addResolver(new ArgumentResolver\RequestAttributesArgumentResolver()); + } + + return $this->argumentResolver; + } } 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..fb1514edcfaa9 --- /dev/null +++ b/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolverManagerTest.php @@ -0,0 +1,118 @@ + + * + * 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 +{ + protected $manager; + protected $resolver1; + protected $resolver2; + protected $request; + + public function setUp() + { + $this->manager = new ArgumentResolverManager(); + $this->resolver1 = $this->getMock('Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface'); + $this->resolver2 = $this->getMock('Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface'); + $this->manager->addResolver($this->resolver1); + $this->manager->addResolver($this->resolver2); + + $this->request = $this->getMock('Symfony\Component\HttpFoundation\Request'); + } + + public function testGetArgumentsFirstResolverAccepts() + { + $this->resolver1->expects($this->any())->method('accepts')->will($this->returnValue(true)); + $this->resolver1->expects($this->any()) + ->method('resolve') + ->will($this->returnValue('resolved_value')); + + $controller = $this->getControllerWithOneArgument(); + + $arguments = $this->manager->getArguments($this->request, $controller); + $this->assertEquals(array('resolved_value'), $arguments); + } + + public function testGetArgumentsSecondResolverAccepts() + { + $this->resolver1->expects($this->any())->method('accepts')->will($this->returnValue(false)); + $this->resolver2->expects($this->any())->method('accepts')->will($this->returnValue(true)); + $this->resolver2->expects($this->any()) + ->method('resolve') + ->will($this->returnValue('resolved_value')); + + $controller = $this->getControllerWithOneArgument(); + + $arguments = $this->manager->getArguments($this->request, $controller); + $this->assertEquals(array('resolved_value'), $arguments); + } + + /** + * @expectedException RuntimeException + */ + public function testGetArgumentsFailsIfNoResolverAccepts() + { + $this->resolver1->expects($this->any())->method('accepts')->will($this->returnValue(false)); + $this->resolver2->expects($this->any())->method('accepts')->will($this->returnValue(false)); + + $controller = $this->getControllerWithOneArgument(); + $this->manager->getArguments($this->request, $controller); + } + + public function testGetArgumentResolvingMultipleArguments() + { + $this->resolver1->expects($this->any()) + ->method('accepts') + ->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('accepts') + ->will($this->onConsecutiveCalls(true, false, true)); + $this->resolver2->expects($this->any()) + ->method('resolve') + ->will($this->onConsecutiveCalls('1st resolved by 2', '2nd resolved by 2')); + + $controller = function ($a, $b, $c) { }; + + $arguments = $this->manager->getArguments($this->request, $controller); + $this->assertEquals(array('1st resolved by 2', '1st resolved by 1', '2nd resolved by 1'), $arguments); + } + + public function testControllerWithOneOptionalArgumentWhichDoesNotMatch() + { + $this->resolver1->expects($this->any())->method('accepts')->will($this->returnValue(false)); + $this->resolver2->expects($this->any())->method('accepts')->will($this->returnValue(false)); + + $arguments = $this->manager->getArguments($this->request, function ($a = 'default') { }); + $this->assertEquals(array('default'), $arguments); + } + + public function testControllerWithOneOptionalArgumentWhichDoMatch() + { + $this->resolver1->expects($this->any())->method('accepts')->will($this->returnValue(true)); + $this->resolver1->expects($this->any())->method('resolve')->will($this->returnValue('resolved by 1')); + $this->resolver2->expects($this->any())->method('accepts')->will($this->returnValue(false)); + + $arguments = $this->manager->getArguments($this->request, function ($a = 'default') { }); + $this->assertEquals(array('resolved by 1'), $arguments); + } + + protected function getControllerWithOneArgument() + { + return function ($a) { }; + } +} diff --git a/src/Symfony/Component/HttpKernel/Tests/Debug/TraceableEventDispatcherTest.php b/src/Symfony/Component/HttpKernel/Tests/Debug/TraceableEventDispatcherTest.php index c2cafc37b8cfa..5931086c60ea7 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Debug/TraceableEventDispatcherTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Debug/TraceableEventDispatcherTest.php @@ -96,9 +96,11 @@ public function testAddListenerNested() protected function getHttpKernel($dispatcher, $controller) { $resolver = $this->getMock('Symfony\Component\HttpKernel\Controller\ControllerResolverInterface'); - $resolver->expects($this->once())->method('getController')->will($this->returnValue($controller)); - $resolver->expects($this->once())->method('getArguments')->will($this->returnValue(array())); + $resolver->expects($this->any())->method('getController')->will($this->returnValue($controller)); - return new HttpKernel($dispatcher, $resolver); + $argumentResolver = $this->getMock('Symfony\Component\HttpKernel\Controller\ArgumentResolverManager'); + $argumentResolver->expects($this->any())->method('getArguments')->will($this->returnValue(array())); + + return new HttpKernel($dispatcher, $resolver, null, $argumentResolver); } } diff --git a/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/ContainerAwareHttpKernelTest.php b/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/ContainerAwareHttpKernelTest.php index 0b110d4a21b2f..73416da86132f 100644 --- a/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/ContainerAwareHttpKernelTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/DependencyInjection/ContainerAwareHttpKernelTest.php @@ -42,7 +42,7 @@ public function testHandle($type) $dispatcher = new EventDispatcher(); $resolver = $this->getResolverMockFor($controller, $request); $stack = new RequestStack(); - $kernel = new ContainerAwareHttpKernel($dispatcher, $container, $resolver, $stack); + $kernel = new ContainerAwareHttpKernel($dispatcher, $container, $resolver, $stack, $this->getArgumentsResolverMockFor($controller, $request)); $actual = $kernel->handle($request, $type); @@ -67,7 +67,7 @@ public function testVerifyRequestStackPushPopDuringHandle($type) $container = $this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'); $dispatcher = new EventDispatcher(); $resolver = $this->getResolverMockFor($controller, $request); - $kernel = new ContainerAwareHttpKernel($dispatcher, $container, $resolver, $stack); + $kernel = new ContainerAwareHttpKernel($dispatcher, $container, $resolver, $stack, $this->getArgumentsResolverMockFor($controller, $request)); $kernel->handle($request, $type); } @@ -95,7 +95,7 @@ public function testHandleRestoresThePreviousRequestOnException($type) $resolver = $this->getMock('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface'); $resolver = $this->getResolverMockFor($controller, $request); $stack = new RequestStack(); - $kernel = new ContainerAwareHttpKernel($dispatcher, $container, $resolver, $stack); + $kernel = new ContainerAwareHttpKernel($dispatcher, $container, $resolver, $stack, $this->getArgumentsResolverMockFor($controller, $request)); try { $kernel->handle($request, $type); @@ -118,16 +118,21 @@ public function getProviderTypes() private function getResolverMockFor($controller, $request) { $resolver = $this->getMock('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface'); - $resolver->expects($this->once()) + $resolver->expects($this->any()) ->method('getController') ->with($request) ->will($this->returnValue($controller)); - $resolver->expects($this->once()) + + return $resolver; + } + + private function getArgumentsResolverMockFor($controller, $request) + { + $resolver = $this->getMock('Symfony\\Component\\HttpKernel\\Controller\\ArgumentsResolverManager'); + $resolver->expects($this->any()) ->method('getArguments') ->with($request, $controller) ->will($this->returnValue(array())); - - return $resolver; } private function expectsSetRequestWithAt($container, $with, $at) diff --git a/src/Symfony/Component/HttpKernel/Tests/Fragment/InlineFragmentRendererTest.php b/src/Symfony/Component/HttpKernel/Tests/Fragment/InlineFragmentRendererTest.php index 4e487a478a600..cddda31189e4f 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Fragment/InlineFragmentRendererTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Fragment/InlineFragmentRendererTest.php @@ -144,7 +144,7 @@ public function testExceptionInSubRequestsDoesNotMangleOutputBuffers() { $resolver = $this->getMock('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface'); $resolver - ->expects($this->once()) + ->expects($this->any()) ->method('getController') ->will($this->returnValue(function () { ob_start(); @@ -152,13 +152,15 @@ public function testExceptionInSubRequestsDoesNotMangleOutputBuffers() throw new \RuntimeException(); })) ; - $resolver - ->expects($this->once()) + + $argumentResolver = $this->getMock('Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolverManager'); + $argumentResolver + ->expects($this->any()) ->method('getArguments') ->will($this->returnValue(array())) ; - $kernel = new HttpKernel(new EventDispatcher(), $resolver); + $kernel = new HttpKernel(new EventDispatcher(), $resolver, null, $argumentResolver); $renderer = new InlineFragmentRenderer($kernel); // simulate a main request with output buffering From 667e141bc79be83fa926228b691031daa630fddf Mon Sep 17 00:00:00 2001 From: WouterJ Date: Thu, 19 Feb 2015 19:56:57 +0100 Subject: [PATCH 2/5] Revisit PR --- .../RequestArgumentResolver.php | 4 +- .../RequestAttributesArgumentResolver.php | 8 ++- .../Controller/ArgumentResolverInterface.php | 8 +-- .../Controller/ArgumentResolverManager.php | 8 ++- .../Controller/ControllerResolver.php | 51 ------------------- .../ControllerResolverInterface.php | 14 ----- .../RegisterArgumentResolversPass.php | 6 +-- .../Component/HttpKernel/HttpKernel.php | 4 +- .../ArgumentResolverManagerTest.php | 6 +-- 9 files changed, 23 insertions(+), 86 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestArgumentResolver.php b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestArgumentResolver.php index 7f89d7fa2d329..105f835654620 100644 --- a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestArgumentResolver.php +++ b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestArgumentResolver.php @@ -24,10 +24,10 @@ class RequestArgumentResolver implements ArgumentResolverInterface /** * {@inheritDoc} */ - public function accepts(Request $request, \ReflectionParameter $parameter) + public function supports(Request $request, \ReflectionParameter $parameter) { $class = $parameter->getClass(); - + return $class && $class->isInstance($request); } diff --git a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestAttributesArgumentResolver.php b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestAttributesArgumentResolver.php index ce1af652c59a6..67269e0a4a893 100644 --- a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestAttributesArgumentResolver.php +++ b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestAttributesArgumentResolver.php @@ -24,9 +24,9 @@ class RequestAttributesArgumentResolver implements ArgumentResolverInterface /** * {@inheritDoc} */ - public function accepts(Request $request, \ReflectionParameter $parameter) + public function supports(Request $request, \ReflectionParameter $parameter) { - return array_key_exists($parameter->name, $request->attributes->all()); + return $request->attributes->has($parameter->name); } /** @@ -34,8 +34,6 @@ public function accepts(Request $request, \ReflectionParameter $parameter) */ public function resolve(Request $request, \ReflectionParameter $parameter) { - $attributes = $request->attributes->all(); - - return $attributes[$parameter->name]; + return $request->attributes->get($parameter->name); } } diff --git a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolverInterface.php b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolverInterface.php index a58256568d536..92ef9a0920a43 100644 --- a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolverInterface.php +++ b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolverInterface.php @@ -14,7 +14,7 @@ use Symfony\Component\HttpFoundation\Request; /** - * An ArgumentResolverInterface implementation resolves the arguments of + * An ArgumentResolverInterface implementation resolves the arguments of * controllers. * * @author Wouter J @@ -22,7 +22,7 @@ interface ArgumentResolverInterface { /** - * Checks if the current parameter can be resolved by this argument + * Checks if the current parameter can be resolved by this argument * resolver. * * @param Request $request @@ -30,14 +30,14 @@ interface ArgumentResolverInterface * * @return Boolean */ - public function accepts(Request $request, \ReflectionParameter $parameter); + 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/ArgumentResolverManager.php b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolverManager.php index 5c4e394ebb295..dd1cd4bd2a186 100644 --- a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolverManager.php +++ b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolverManager.php @@ -31,7 +31,7 @@ class ArgumentResolverManager * * @param ArgumentResolverInterface $resolver */ - public function addResolver(ArgumentResolverInterface $resolver) + public function add(ArgumentResolverInterface $resolver) { $this->resolvers[] = $resolver; } @@ -48,6 +48,10 @@ public function addResolver(ArgumentResolverInterface $resolver) */ 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) { @@ -62,7 +66,7 @@ public function getArguments(Request $request, $controller) foreach ($parameters as $parameter) { foreach ($this->resolvers as $argumentResolver) { - if ($argumentResolver->accepts($request, $parameter)) { + if ($argumentResolver->supports($request, $parameter)) { $arguments[] = $argumentResolver->resolve($request, $parameter); continue 2; } diff --git a/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php b/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php index 03561fb3f1c5c..5e4f2d0c9404c 100644 --- a/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php +++ b/src/Symfony/Component/HttpKernel/Controller/ControllerResolver.php @@ -86,57 +86,6 @@ public function getController(Request $request) return $callable; } - /** - * {@inheritdoc} - * - * @api - * - * @deprecated Deprecated since Symfony 2.6, will be removed in Symfony 3.0. Use ArgumentResolvers instead - */ - 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()); - } - - /** - * @deprecated Deprecated since Symfony 2.6, will be removed in Symfony 3.0. Use ArgumentResolvers 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; - } - /** * Returns a callable for the given controller. * diff --git a/src/Symfony/Component/HttpKernel/Controller/ControllerResolverInterface.php b/src/Symfony/Component/HttpKernel/Controller/ControllerResolverInterface.php index 6f805ed2dab77..c643e29daef22 100644 --- a/src/Symfony/Component/HttpKernel/Controller/ControllerResolverInterface.php +++ b/src/Symfony/Component/HttpKernel/Controller/ControllerResolverInterface.php @@ -46,18 +46,4 @@ interface ControllerResolverInterface * @api */ public function getController(Request $request); - - /** - * 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 - * - * @api - */ - public function getArguments(Request $request, $controller); } diff --git a/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterArgumentResolversPass.php b/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterArgumentResolversPass.php index e80a1593684bb..0e2f7baa69878 100644 --- a/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterArgumentResolversPass.php +++ b/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterArgumentResolversPass.php @@ -25,12 +25,12 @@ class RegisterArgumentResolversPass implements CompilerPassInterface /** * @var string */ - protected $managerService; + private $managerService; /** * @var string */ - protected $resolverTag; + private $resolverTag; public function __construct($managerService = 'argument_resolver.manager', $resolverTag = 'kernel.argument_resolver') { @@ -50,7 +50,7 @@ public function process(ContainerBuilder $container) $definition = $container->findDefinition($this->managerService); foreach ($container->findTaggedServiceIds($this->resolverTag) as $id => $resolvers) { - $definition->addMethodCall('addResolver', array(new Reference($id))); + $definition->addMethodCall('add', array(new Reference($id))); } } } diff --git a/src/Symfony/Component/HttpKernel/HttpKernel.php b/src/Symfony/Component/HttpKernel/HttpKernel.php index e465da9f28684..12b81149acc0e 100644 --- a/src/Symfony/Component/HttpKernel/HttpKernel.php +++ b/src/Symfony/Component/HttpKernel/HttpKernel.php @@ -304,8 +304,8 @@ protected function getArgumentResolver() if (null === $this->argumentResolver) { // to keep BC $this->argumentResolver = new ArgumentResolverManager(); - $this->argumentResolver->addResolver(new ArgumentResolver\RequestArgumentResolver()); - $this->argumentResolver->addResolver(new ArgumentResolver\RequestAttributesArgumentResolver()); + $this->argumentResolver->add(new ArgumentResolver\RequestArgumentResolver()); + $this->argumentResolver->add(new ArgumentResolver\RequestAttributesArgumentResolver()); } return $this->argumentResolver; diff --git a/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolverManagerTest.php b/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolverManagerTest.php index fb1514edcfaa9..a18794b573aad 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolverManagerTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolverManagerTest.php @@ -25,15 +25,15 @@ public function setUp() $this->manager = new ArgumentResolverManager(); $this->resolver1 = $this->getMock('Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface'); $this->resolver2 = $this->getMock('Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface'); - $this->manager->addResolver($this->resolver1); - $this->manager->addResolver($this->resolver2); + $this->manager->add($this->resolver1); + $this->manager->add($this->resolver2); $this->request = $this->getMock('Symfony\Component\HttpFoundation\Request'); } public function testGetArgumentsFirstResolverAccepts() { - $this->resolver1->expects($this->any())->method('accepts')->will($this->returnValue(true)); + $this->resolver1->expects($this->any())->method('accepts')->will($this->returnValue(true)); $this->resolver1->expects($this->any()) ->method('resolve') ->will($this->returnValue('resolved_value')); From 966ffe620f47261a1900b45eebc19a649012ab22 Mon Sep 17 00:00:00 2001 From: WouterJ Date: Thu, 19 Feb 2015 20:01:23 +0100 Subject: [PATCH 3/5] Make fabbot happy --- .../Controller/ArgumentResolver/RequestArgumentResolver.php | 4 ++-- .../ArgumentResolver/RequestAttributesArgumentResolver.php | 4 ++-- .../HttpKernel/Controller/ArgumentResolverInterface.php | 2 +- .../DependencyInjection/RegisterArgumentResolversPass.php | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestArgumentResolver.php b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestArgumentResolver.php index 105f835654620..ba4815a1d8af8 100644 --- a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestArgumentResolver.php +++ b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestArgumentResolver.php @@ -22,7 +22,7 @@ class RequestArgumentResolver implements ArgumentResolverInterface { /** - * {@inheritDoc} + * {@inheritdoc} */ public function supports(Request $request, \ReflectionParameter $parameter) { @@ -32,7 +32,7 @@ public function supports(Request $request, \ReflectionParameter $parameter) } /** - * {@inheritDoc} + * {@inheritdoc} */ public function resolve(Request $request, \ReflectionParameter $parameter) { diff --git a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestAttributesArgumentResolver.php b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestAttributesArgumentResolver.php index 67269e0a4a893..9f5c84f81a15a 100644 --- a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestAttributesArgumentResolver.php +++ b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestAttributesArgumentResolver.php @@ -22,7 +22,7 @@ class RequestAttributesArgumentResolver implements ArgumentResolverInterface { /** - * {@inheritDoc} + * {@inheritdoc} */ public function supports(Request $request, \ReflectionParameter $parameter) { @@ -30,7 +30,7 @@ public function supports(Request $request, \ReflectionParameter $parameter) } /** - * {@inheritDoc} + * {@inheritdoc} */ public function resolve(Request $request, \ReflectionParameter $parameter) { diff --git a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolverInterface.php b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolverInterface.php index 92ef9a0920a43..766c9f3666256 100644 --- a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolverInterface.php +++ b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolverInterface.php @@ -28,7 +28,7 @@ interface ArgumentResolverInterface * @param Request $request * @param \ReflectionParameter $parameter * - * @return Boolean + * @return bool */ public function supports(Request $request, \ReflectionParameter $parameter); diff --git a/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterArgumentResolversPass.php b/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterArgumentResolversPass.php index 0e2f7baa69878..b4f72a012ff2b 100644 --- a/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterArgumentResolversPass.php +++ b/src/Symfony/Component/HttpKernel/DependencyInjection/RegisterArgumentResolversPass.php @@ -39,8 +39,8 @@ public function __construct($managerService = 'argument_resolver.manager', $reso } /** - * {@inheritDoc} - */ + * {@inheritdoc} + */ public function process(ContainerBuilder $container) { if (!$container->hasDefinition($this->managerService) && !$container->hasAlias($this->managerService)) { From 416a33edff373c52020f7de583b45e1a34cf7fd2 Mon Sep 17 00:00:00 2001 From: WouterJ Date: Mon, 6 Apr 2015 18:08:11 +0200 Subject: [PATCH 4/5] Cleanup tests --- .../Controller/ControllerResolverTest.php | 4 +- .../ArgumentResolverManagerTest.php | 94 +++++++++++-------- .../Controller/ControllerResolverTest.php | 87 ++--------------- 3 files changed, 63 insertions(+), 122 deletions(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerResolverTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerResolverTest.php index 4e804bf079701..c444aff651645 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerResolverTest.php +++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerResolverTest.php @@ -65,12 +65,12 @@ public function testGetControllerService() $resolver = $this->createControllerResolver(null, null, $container); $request = Request::create('/'); - $request->attributes->set('_controller', 'foo:controllerMethod1'); + $request->attributes->set('_controller', 'foo:controllerMethod'); $controller = $resolver->getController($request); $this->assertInstanceOf(get_class($this), $controller[0]); - $this->assertSame('controllerMethod1', $controller[1]); + $this->assertSame('controllerMethod', $controller[1]); } public function testGetControllerInvokableService() diff --git a/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolverManagerTest.php b/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolverManagerTest.php index a18794b573aad..0ad048c551e78 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolverManagerTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolverManagerTest.php @@ -22,40 +22,34 @@ class ArgumentResolverManagerTest extends \PHPUnit_Framework_TestCase public function setUp() { - $this->manager = new ArgumentResolverManager(); $this->resolver1 = $this->getMock('Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface'); $this->resolver2 = $this->getMock('Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface'); + + $this->manager = new ArgumentResolverManager(); $this->manager->add($this->resolver1); $this->manager->add($this->resolver2); $this->request = $this->getMock('Symfony\Component\HttpFoundation\Request'); } - public function testGetArgumentsFirstResolverAccepts() + public function testGetArgumentsWithoutControllerParameters() { - $this->resolver1->expects($this->any())->method('accepts')->will($this->returnValue(true)); - $this->resolver1->expects($this->any()) - ->method('resolve') - ->will($this->returnValue('resolved_value')); + $this->assertArguments(array(), function () { }); + } - $controller = $this->getControllerWithOneArgument(); + public function testGetArgumentsFirstResolverAccepts() + { + $this->promiseResolverToMatch($this->resolver1, 'resolved_value'); - $arguments = $this->manager->getArguments($this->request, $controller); - $this->assertEquals(array('resolved_value'), $arguments); + $this->assertArguments(array('resolved_value'), $this->getControllerWithOneParameter()); } public function testGetArgumentsSecondResolverAccepts() { - $this->resolver1->expects($this->any())->method('accepts')->will($this->returnValue(false)); - $this->resolver2->expects($this->any())->method('accepts')->will($this->returnValue(true)); - $this->resolver2->expects($this->any()) - ->method('resolve') - ->will($this->returnValue('resolved_value')); - - $controller = $this->getControllerWithOneArgument(); + $this->promiseResolverToNotMatch($this->resolver1); + $this->promiseResolverToMatch($this->resolver2, 'resolved_value'); - $arguments = $this->manager->getArguments($this->request, $controller); - $this->assertEquals(array('resolved_value'), $arguments); + $this->assertArguments(array('resolved_value'), $this->getControllerWithOneParameter()); } /** @@ -63,55 +57,75 @@ public function testGetArgumentsSecondResolverAccepts() */ public function testGetArgumentsFailsIfNoResolverAccepts() { - $this->resolver1->expects($this->any())->method('accepts')->will($this->returnValue(false)); - $this->resolver2->expects($this->any())->method('accepts')->will($this->returnValue(false)); + $this->promiseResolverToNotMatch($this->resolver1); + $this->promiseResolverToNotMatch($this->resolver2); - $controller = $this->getControllerWithOneArgument(); - $this->manager->getArguments($this->request, $controller); + $this->manager->getArguments($this->request, $this->getControllerWithOneParameter()); } - public function testGetArgumentResolvingMultipleArguments() + public function testGetArgumentResolvingMultipleParameters() { $this->resolver1->expects($this->any()) - ->method('accepts') + ->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('accepts') + ->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')); - $controller = function ($a, $b, $c) { }; + $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); - $arguments = $this->manager->getArguments($this->request, $controller); - $this->assertEquals(array('1st resolved by 2', '1st resolved by 1', '2nd resolved by 1'), $arguments); + $this->assertArguments(array('resolved by 1'), function ($a = 'default') { }); } - public function testControllerWithOneOptionalArgumentWhichDoesNotMatch() + public function testControllerWithOneParameterWithNullDefault() { - $this->resolver1->expects($this->any())->method('accepts')->will($this->returnValue(false)); - $this->resolver2->expects($this->any())->method('accepts')->will($this->returnValue(false)); + $this->promiseResolverToNotMatch($this->resolver1); + $this->promiseResolverToNotMatch($this->resolver2); + + $this->assertArguments(array(null), function ($a = null) { }); + } - $arguments = $this->manager->getArguments($this->request, function ($a = 'default') { }); - $this->assertEquals(array('default'), $arguments); + private function assertArguments(array $expected, $controller) + { + $this->assertEquals($expected, $this->manager->getArguments($this->request, $controller)); } - public function testControllerWithOneOptionalArgumentWhichDoMatch() + private function promiseResolverToMatch($resolver, $return) { - $this->resolver1->expects($this->any())->method('accepts')->will($this->returnValue(true)); - $this->resolver1->expects($this->any())->method('resolve')->will($this->returnValue('resolved by 1')); - $this->resolver2->expects($this->any())->method('accepts')->will($this->returnValue(false)); + $resolver->expects($this->any())->method('supports')->will($this->returnValue(true)); + $resolver->expects($this->any())->method('resolve')->will($this->returnValue($return)); + } - $arguments = $this->manager->getArguments($this->request, function ($a = 'default') { }); - $this->assertEquals(array('resolved by 1'), $arguments); + private function promiseResolverToNotMatch($resolver) + { + $resolver->expects($this->any())->method('supports')->will($this->returnValue(false)); } - protected function getControllerWithOneArgument() + 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 4b886ee10977d..ba78109af9cb0 100644 --- a/src/Symfony/Component/HttpKernel/Tests/Controller/ControllerResolverTest.php +++ b/src/Symfony/Component/HttpKernel/Tests/Controller/ControllerResolverTest.php @@ -52,9 +52,9 @@ public function testGetControllerWithObjectAndMethod() $resolver = $this->createControllerResolver(); $request = Request::create('/'); - $request->attributes->set('_controller', array($this, 'controllerMethod1')); + $request->attributes->set('_controller', array($this, 'controllerMethod')); $controller = $resolver->getController($request); - $this->assertSame(array($this, 'controllerMethod1'), $controller); + $this->assertSame(array($this, 'controllerMethod'), $controller); } public function testGetControllerWithClassAndMethod() @@ -62,9 +62,9 @@ public function testGetControllerWithClassAndMethod() $resolver = $this->createControllerResolver(); $request = Request::create('/'); - $request->attributes->set('_controller', array('Symfony\Component\HttpKernel\Tests\Controller\ControllerResolverTest', 'controllerMethod4')); + $request->attributes->set('_controller', array('Symfony\Component\HttpKernel\Tests\Controller\ControllerResolverTest', 'staticControllerMethod')); $controller = $resolver->getController($request); - $this->assertSame(array('Symfony\Component\HttpKernel\Tests\Controller\ControllerResolverTest', 'controllerMethod4'), $controller); + $this->assertSame(array('Symfony\Component\HttpKernel\Tests\Controller\ControllerResolverTest', 'staticControllerMethod'), $controller); } public function testGetControllerWithObjectAndMethodAsString() @@ -72,7 +72,7 @@ public function testGetControllerWithObjectAndMethodAsString() $resolver = $this->createControllerResolver(); $request = Request::create('/'); - $request->attributes->set('_controller', 'Symfony\Component\HttpKernel\Tests\Controller\ControllerResolverTest::controllerMethod1'); + $request->attributes->set('_controller', 'Symfony\Component\HttpKernel\Tests\Controller\ControllerResolverTest::controllerMethod'); $controller = $resolver->getController($request); $this->assertInstanceOf('Symfony\Component\HttpKernel\Tests\Controller\ControllerResolverTest', $controller[0], '->getController() returns a PHP callable'); } @@ -132,67 +132,6 @@ public function getUndefinedControllers() ); } - public function testGetArguments() - { - $resolver = $this->createControllerResolver(); - - $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\some_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'); - } - public function testCreateControllerCanReturnAnyCallable() { $mock = $this->getMock('Symfony\Component\HttpKernel\Controller\ControllerResolver', array('createController')); @@ -212,23 +151,11 @@ public function __invoke($foo, $bar = null) { } - public function controllerMethod1($foo) - { - } - - protected function controllerMethod2($foo, $bar = null) - { - } - - protected function controllerMethod3($foo, $bar = null, $foobar) - { - } - - protected static function controllerMethod4() + public function controllerMethod($foo) { } - protected function controllerMethod5(Request $request) + protected static function staticControllerMethod() { } } From 1a34c3390950cf6661fd32c631164ff99330b13d Mon Sep 17 00:00:00 2001 From: WouterJ Date: Fri, 8 May 2015 16:01:16 +0200 Subject: [PATCH 5/5] Fix dep version --- src/Symfony/Bundle/FrameworkBundle/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json index db09b59b9cd6e..0dd47ac13d342 100644 --- a/src/Symfony/Bundle/FrameworkBundle/composer.json +++ b/src/Symfony/Bundle/FrameworkBundle/composer.json @@ -18,7 +18,7 @@ "require": { "php": ">=5.5.9", "symfony/asset": "~2.7|~3.0", - "symfony/dependency-injection" : "~2.7|~3.0", + "symfony/dependency-injection" : "~3.0", "symfony/config" : "~2.7|~3.0", "symfony/event-dispatcher": "~2.7|~3.0", "symfony/http-foundation": "~2.7|~3.0", pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy