bug #27214 [HttpKernel] Fix services are no longer injected into __invoke controllers method (ogizanagi)
This PR was merged into the 4.1 branch.
Discussion
----------
[HttpKernel] Fix services are no longer injected into __invoke controllers method
| Q | A
| ------------- | ---
| Branch? | 4.1 <!-- see below -->
| Bug fix? | yes
| New feature? | no <!-- don't forget to update src/**/CHANGELOG.md files -->
| BC breaks? | no <!-- see https://symfony.com/bc -->
| Deprecations? | no <!-- don't forget to update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tests pass? | yes <!-- please add some, will be required by reviewers -->
| Fixed tickets | #27208 <!-- #-prefixed issue number(s), if any -->
| License | MIT
| Doc PR | N/A
_TL;DR:_ The `RemoveEmptyControllerArgumentLocatorsPass` is the one adding the `Controller::_invoke` => `Controller` shortcut missing from the service locator. It isn't properly executed on some cases. This fixes it.
Since https://github.com/symfony/symfony/pull/26833, the resolvers are decorated by a `TraceableValueResolver`, which usually isn't much an issue to deal within passes. But the `RemoveEmptyControllerArgumentLocatorsPass` happens late (`TYPE_BEFORE_REMOVING`), when decoration inheritance is already resolved, so accessing `$controllerLocator = $container->getDefinition((string) $serviceResolver->getArgument(0));` isn't accessing the controller locator, but the decorated service instead.
Commits
-------
ee44903fd0
[HttpKernel] Fix services are no longer injected into __invoke controllers method
This commit is contained in:
commit
5f0e2d6671
@ -33,11 +33,13 @@ class RegisterControllerArgumentLocatorsPass implements CompilerPassInterface
|
|||||||
{
|
{
|
||||||
private $resolverServiceId;
|
private $resolverServiceId;
|
||||||
private $controllerTag;
|
private $controllerTag;
|
||||||
|
private $controllerLocator;
|
||||||
|
|
||||||
public function __construct(string $resolverServiceId = 'argument_resolver.service', string $controllerTag = 'controller.service_arguments')
|
public function __construct(string $resolverServiceId = 'argument_resolver.service', string $controllerTag = 'controller.service_arguments', string $controllerLocator = 'argument_resolver.controller_locator')
|
||||||
{
|
{
|
||||||
$this->resolverServiceId = $resolverServiceId;
|
$this->resolverServiceId = $resolverServiceId;
|
||||||
$this->controllerTag = $controllerTag;
|
$this->controllerTag = $controllerTag;
|
||||||
|
$this->controllerLocator = $controllerLocator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function process(ContainerBuilder $container)
|
public function process(ContainerBuilder $container)
|
||||||
@ -179,6 +181,8 @@ class RegisterControllerArgumentLocatorsPass implements CompilerPassInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
$container->getDefinition($this->resolverServiceId)
|
$container->getDefinition($this->resolverServiceId)
|
||||||
->replaceArgument(0, ServiceLocatorTagPass::register($container, $controllers));
|
->replaceArgument(0, $controllerLocatorRef = ServiceLocatorTagPass::register($container, $controllers));
|
||||||
|
|
||||||
|
$container->setAlias($this->controllerLocator, (string) $controllerLocatorRef);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,21 +21,16 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
|
|||||||
*/
|
*/
|
||||||
class RemoveEmptyControllerArgumentLocatorsPass implements CompilerPassInterface
|
class RemoveEmptyControllerArgumentLocatorsPass implements CompilerPassInterface
|
||||||
{
|
{
|
||||||
private $resolverServiceId;
|
private $controllerLocator;
|
||||||
|
|
||||||
public function __construct(string $resolverServiceId = 'argument_resolver.service')
|
public function __construct(string $controllerLocator = 'argument_resolver.controller_locator')
|
||||||
{
|
{
|
||||||
$this->resolverServiceId = $resolverServiceId;
|
$this->controllerLocator = $controllerLocator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function process(ContainerBuilder $container)
|
public function process(ContainerBuilder $container)
|
||||||
{
|
{
|
||||||
if (false === $container->hasDefinition($this->resolverServiceId)) {
|
$controllerLocator = $container->findDefinition($this->controllerLocator);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$serviceResolver = $container->getDefinition($this->resolverServiceId);
|
|
||||||
$controllerLocator = $container->getDefinition((string) $serviceResolver->getArgument(0));
|
|
||||||
$controllers = $controllerLocator->getArgument(0);
|
$controllers = $controllerLocator->getArgument(0);
|
||||||
|
|
||||||
foreach ($controllers as $controller => $argumentRef) {
|
foreach ($controllers as $controller => $argumentRef) {
|
||||||
|
Reference in New Issue
Block a user