feature #35560 [HttpKernel] allow using public aliases to reference controllers (nicolas-grekas)

This PR was merged into the 5.1-dev branch.

Discussion
----------

[HttpKernel] allow using public aliases to reference controllers

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| Deprecations? | no
| Tickets       | -
| License       | MIT
| Doc PR        | -

This PR allows referencing a controller with an alias when needed. The use case I'm targetting is using `@Route` annotations on methods of the `App\Kernel` and have them work. This PR allows it.

Sidekick of https://github.com/symfony/recipes/pull/735

Commits
-------

94bc1f7d3b [HttpKernel] allow using public aliases to reference controllers
This commit is contained in:
Fabien Potencier 2020-02-03 17:34:59 +01:00
commit 59f0980fd9
5 changed files with 39 additions and 1 deletions

View File

@ -141,7 +141,7 @@ trait MicroKernelTrait
AbstractConfigurator::$valuePreProcessor = $valuePreProcessor;
}
$container->setAlias(static::class, 'kernel');
$container->setAlias(static::class, 'kernel')->setPublic(true);
});
}

View File

@ -1,6 +1,11 @@
CHANGELOG
=========
5.1.0
-----
* allowed using public aliases to reference controllers
5.0.0
-----

View File

@ -53,6 +53,13 @@ class RegisterControllerArgumentLocatorsPass implements CompilerPassInterface
$parameterBag = $container->getParameterBag();
$controllers = [];
$publicAliases = [];
foreach ($container->getAliases() as $id => $alias) {
if ($alias->isPublic()) {
$publicAliases[(string) $alias][] = $id;
}
}
foreach ($container->findTaggedServiceIds($this->controllerTag, true) as $id => $tags) {
$def = $container->getDefinition($id);
$def->setPublic(true);
@ -182,6 +189,10 @@ class RegisterControllerArgumentLocatorsPass implements CompilerPassInterface
// register the maps as a per-method service-locators
if ($args) {
$controllers[$id.'::'.$r->name] = ServiceLocatorTagPass::register($container, $args);
foreach ($publicAliases[$id] ?? [] as $alias) {
$controllers[$alias.'::'.$r->name] = clone $controllers[$id.'::'.$r->name];
}
}
}
}

View File

@ -43,6 +43,11 @@ class RemoveEmptyControllerArgumentLocatorsPass implements CompilerPassInterface
// any methods listed for call-at-instantiation cannot be actions
$reason = false;
list($id, $action) = explode('::', $controller);
if ($container->hasAlias($id)) {
continue;
}
$controllerDef = $container->getDefinition($id);
foreach ($controllerDef->getMethodCalls() as list($method)) {
if (0 === strcasecmp($action, $method)) {

View File

@ -379,6 +379,23 @@ class RegisterControllerArgumentLocatorsPassTest extends TestCase
$this->assertInstanceOf(Reference::class, $locatorArgument);
}
public function testAlias()
{
$container = new ContainerBuilder();
$resolver = $container->register('argument_resolver.service')->addArgument([]);
$container->register('foo', RegisterTestController::class)
->addTag('controller.service_arguments');
$container->setAlias(RegisterTestController::class, 'foo')->setPublic(true);
$pass = new RegisterControllerArgumentLocatorsPass();
$pass->process($container);
$locator = $container->getDefinition((string) $resolver->getArgument(0))->getArgument(0);
$this->assertSame([RegisterTestController::class.'::fooAction', 'foo::fooAction'], array_keys($locator));
}
}
class RegisterTestController