bug #18394 [FrameworkBundle][2.7] Return the invokable service if its name is the class name (dunglas)

This PR was merged into the 2.7 branch.

Discussion
----------

[FrameworkBundle][2.7] Return the invokable service if its name is the class name

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

Backport #18289 to 2.7 as this is a bug fix.

Commits
-------

5c87d76 [FrameworkBundle] Return the invokable service if its name is the class name
This commit is contained in:
Fabien Potencier 2016-04-01 08:15:08 +02:00
commit ffb4ff3fec
2 changed files with 45 additions and 2 deletions

View File

@ -78,6 +78,10 @@ class ControllerResolver extends BaseControllerResolver
*/
protected function instantiateController($class)
{
if ($this->container->has($class)) {
return $this->container->get($class);
}
$controller = parent::instantiateController($class);
if ($controller instanceof ContainerAwareInterface) {

View File

@ -87,6 +87,8 @@ class ControllerResolverTest extends BaseControllerResolverTest
public function testGetControllerInvokableService()
{
$invokableController = new InvokableController('bar');
$container = $this->createMockContainer();
$container->expects($this->once())
->method('has')
@ -96,7 +98,7 @@ class ControllerResolverTest extends BaseControllerResolverTest
$container->expects($this->once())
->method('get')
->with('foo')
->will($this->returnValue($this))
->will($this->returnValue($invokableController))
;
$resolver = $this->createControllerResolver(null, null, $container);
@ -105,7 +107,33 @@ class ControllerResolverTest extends BaseControllerResolverTest
$controller = $resolver->getController($request);
$this->assertInstanceOf(get_class($this), $controller);
$this->assertEquals($invokableController, $controller);
}
public function testGetControllerInvokableServiceWithClassNameAsName()
{
$invokableController = new InvokableController('bar');
$className = __NAMESPACE__.'\InvokableController';
$container = $this->createMockContainer();
$container->expects($this->once())
->method('has')
->with($className)
->will($this->returnValue(true))
;
$container->expects($this->once())
->method('get')
->with($className)
->will($this->returnValue($invokableController))
;
$resolver = $this->createControllerResolver(null, null, $container);
$request = Request::create('/');
$request->attributes->set('_controller', $className);
$controller = $resolver->getController($request);
$this->assertEquals($invokableController, $controller);
}
/**
@ -178,3 +206,14 @@ class ContainerAwareController implements ContainerAwareInterface
{
}
}
class InvokableController
{
public function __construct($bar) // mandatory argument to prevent automatic instantiation
{
}
public function __invoke()
{
}
}