From a9e9f3679945b8eb5651ea0a18feb6c085663a1e Mon Sep 17 00:00:00 2001 From: Samuel ROZE Date: Wed, 15 Nov 2017 11:35:30 +0200 Subject: [PATCH 1/2] Add service value resolver tests Prove that the service value resolver will not work with the array notation --- .../ServiceValueResolverTest.php | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/ServiceValueResolverTest.php diff --git a/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/ServiceValueResolverTest.php b/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/ServiceValueResolverTest.php new file mode 100644 index 0000000000..b05828f5bf --- /dev/null +++ b/src/Symfony/Component/HttpKernel/Tests/Controller/ArgumentResolver/ServiceValueResolverTest.php @@ -0,0 +1,93 @@ + + * + * 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\ArgumentResolver; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\ServiceLocator; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\Controller\ArgumentResolver\ServiceValueResolver; +use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata; + +class ServiceValueResolverTest extends TestCase +{ + public function testDoNotSupportWhenControllerDoNotExists() + { + $resolver = new ServiceValueResolver(new ServiceLocator(array())); + $argument = new ArgumentMetadata('dummy', DummyService::class, false, false, null); + $request = $this->requestWithAttributes(array('_controller' => 'my_controller')); + + $this->assertFalse($resolver->supports($request, $argument)); + } + + public function testExistingController() + { + $resolver = new ServiceValueResolver(new ServiceLocator(array( + 'App\\Controller\\Mine::method' => function () { + return new ServiceLocator(array( + 'dummy' => function () { + return new DummyService(); + }, + )); + }, + ))); + + $request = $this->requestWithAttributes(array('_controller' => 'App\\Controller\\Mine::method')); + $argument = new ArgumentMetadata('dummy', DummyService::class, false, false, null); + + $this->assertTrue($resolver->supports($request, $argument)); + $this->assertYieldEquals(array(new DummyService()), $resolver->resolve($request, $argument)); + } + + public function testControllerNameIsAnArray() + { + $resolver = new ServiceValueResolver(new ServiceLocator(array( + 'App\\Controller\\Mine::method' => function () { + return new ServiceLocator(array( + 'dummy' => function () { + return new DummyService(); + }, + )); + }, + ))); + + $request = $this->requestWithAttributes(array('_controller' => array('App\\Controller\\Mine', 'method'))); + $argument = new ArgumentMetadata('dummy', DummyService::class, false, false, null); + + $this->assertTrue($resolver->supports($request, $argument)); + $this->assertYieldEquals(array(new DummyService()), $resolver->resolve($request, $argument)); + } + + private function requestWithAttributes(array $attributes) + { + $request = Request::create('/'); + + foreach ($attributes as $name => $value) { + $request->attributes->set($name, $value); + } + + return $request; + } + + private function assertYieldEquals(array $expected, \Generator $generator) + { + $args = array(); + foreach ($generator as $arg) { + $args[] = $arg; + } + + $this->assertEquals($expected, $args); + } +} + +class DummyService +{ +} From fc3d3bbf60617be6f76b8463ac6f24755d15d107 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 14 Nov 2017 23:29:28 +0200 Subject: [PATCH 2/2] [HttpKernel] Fix service arg resolver for controllers as array callables --- .../ArgumentResolver/ServiceValueResolver.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/ServiceValueResolver.php b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/ServiceValueResolver.php index b1da6a9a75..c55564c046 100644 --- a/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/ServiceValueResolver.php +++ b/src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/ServiceValueResolver.php @@ -35,7 +35,13 @@ final class ServiceValueResolver implements ArgumentValueResolverInterface */ public function supports(Request $request, ArgumentMetadata $argument) { - return is_string($controller = $request->attributes->get('_controller')) && $this->container->has($controller) && $this->container->get($controller)->has($argument->getName()); + $controller = $request->attributes->get('_controller'); + + if (\is_array($controller) && \is_callable($controller, true) && \is_string($controller[0])) { + $controller = $controller[0].'::'.$controller[1]; + } + + return \is_string($controller) && $this->container->has($controller) && $this->container->get($controller)->has($argument->getName()); } /** @@ -43,6 +49,10 @@ final class ServiceValueResolver implements ArgumentValueResolverInterface */ public function resolve(Request $request, ArgumentMetadata $argument) { - yield $this->container->get($request->attributes->get('_controller'))->get($argument->getName()); + if (\is_array($controller = $request->attributes->get('_controller'))) { + $controller = $controller[0].'::'.$controller[1]; + } + + yield $this->container->get($controller)->get($argument->getName()); } }