bug #24305 [HttpKernel] Make array vs "::" controller definitions consistent (nicolas-grekas)

This PR was merged into the 3.3 branch.

Discussion
----------

[HttpKernel] Make array vs "::" controller definitions consistent

| Q             | A
| ------------- | ---
| Branch?       | 3.3
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | -
| License       | MIT
| Doc PR        | -

Defining a controller using `[Foo::class, 'someAction']` vs `App\Controller\Foo::someAction` should end up produce the same result: a container lookup.

Commits
-------

f0f9a6691c [HttpKernel] Make array vs "::" controller definitions consistent
This commit is contained in:
Maxime Steinhausser 2017-09-24 20:01:04 +02:00
commit 3cb507ba33
2 changed files with 65 additions and 0 deletions

View File

@ -13,6 +13,7 @@ namespace Symfony\Component\HttpKernel\Controller;
use Psr\Container\ContainerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;
/**
* A controller resolver searching for a controller in a psr-11 container when using the "service:method" notation.
@ -31,6 +32,20 @@ class ContainerControllerResolver extends ControllerResolver
parent::__construct($logger);
}
/**
* {@inheritdoc}
*/
public function getController(Request $request)
{
$controller = parent::getController($request);
if (is_array($controller) && isset($controller[0]) && is_string($controller[0]) && $this->container->has($controller[0])) {
$controller[0] = $this->instantiateController($controller[0]);
}
return $controller;
}
/**
* Returns a callable for the given controller.
*

View File

@ -88,6 +88,49 @@ class ContainerControllerResolverTest extends ControllerResolverTest
$this->assertEquals($invokableController, $controller);
}
public function testNonInstantiableController()
{
$container = $this->createMockContainer();
$container->expects($this->once())
->method('has')
->with(NonInstantiableController::class)
->will($this->returnValue(false))
;
$resolver = $this->createControllerResolver(null, $container);
$request = Request::create('/');
$request->attributes->set('_controller', array(NonInstantiableController::class, 'action'));
$controller = $resolver->getController($request);
$this->assertSame(array(NonInstantiableController::class, 'action'), $controller);
}
public function testNonInstantiableControllerWithCorrespondingService()
{
$service = new \stdClass();
$container = $this->createMockContainer();
$container->expects($this->atLeastOnce())
->method('has')
->with(NonInstantiableController::class)
->will($this->returnValue(true))
;
$container->expects($this->atLeastOnce())
->method('get')
->with(NonInstantiableController::class)
->will($this->returnValue($service))
;
$resolver = $this->createControllerResolver(null, $container);
$request = Request::create('/');
$request->attributes->set('_controller', array(NonInstantiableController::class, 'action'));
$controller = $resolver->getController($request);
$this->assertSame(array($service, 'action'), $controller);
}
/**
* @dataProvider getUndefinedControllers
*/
@ -146,3 +189,10 @@ class InvokableController
{
}
}
abstract class NonInstantiableController
{
public static function action()
{
}
}