Skip to content

Commit

Permalink
bug #18289 [FrameworkBundle] Return the invokable service if its name…
Browse files Browse the repository at this point in the history
… is the class name (dunglas)

This PR was squashed before being merged into the 3.1-dev branch (closes #18289).

Discussion
----------

[FrameworkBundle] 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

 if a service is invokable and has the same name than its class name, the controller resolver of FrameworkBundle doesn't retrieve the service and tries to construct a new instance of the class instead.

This is a very rare edge case, but this fix is useful for dunglas/DunglasActionBundle#36: referencing auto-registered controllers following the ADR style in YAML and XML routing files will be more intuitive.

Currently: `defaults:  { _controller: 'Your\Action\FQN:__invoke' }`, after this fix: `defaults:  { _controller: 'Your\Action\FQN' }`.

This PR also fix a currently useless test.

Commits
-------

70b9309 [FrameworkBundle] Return the invokable service if its name is the class name
  • Loading branch information
fabpot committed Mar 25, 2016
2 parents 3c75c48 + 70b9309 commit f9b0aaa
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 2 deletions.
Expand Up @@ -78,6 +78,10 @@ protected function createController($controller)
*/
protected function instantiateController($class)
{
if ($this->container->has($class)) {
return $this->container->get($class);
}

$controller = parent::instantiateController($class);

if ($controller instanceof ContainerAwareInterface) {
Expand Down
Expand Up @@ -87,6 +87,8 @@ public function testGetControllerService()

public function testGetControllerInvokableService()
{
$invokableController = new InvokableController('bar');

$container = $this->createMockContainer();
$container->expects($this->once())
->method('has')
Expand All @@ -96,7 +98,7 @@ public function testGetControllerInvokableService()
$container->expects($this->once())
->method('get')
->with('foo')
->will($this->returnValue($this))
->will($this->returnValue($invokableController))
;

$resolver = $this->createControllerResolver(null, null, $container);
Expand All @@ -105,7 +107,33 @@ public function testGetControllerInvokableService()

$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);
}

/**
Expand Down Expand Up @@ -182,3 +210,14 @@ public function __invoke()
{
}
}

class InvokableController
{
public function __construct($bar) // mandatory argument to prevent automatic instantiation
{
}

public function __invoke()
{
}
}

0 comments on commit f9b0aaa

Please sign in to comment.