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()); } } 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 +{ +}