Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork9.6k
Description
Symfony version(s) affected
6.4.16
Description
WithSymfony\Component\DependencyInjection\Compiler\ResolveParameterPlaceHoldersPass::$skipScalars
set totrue
(via patching),#[Autowire(param: 'app.root')]
and#[Autowire('%app.root%')]
behave differently.
a. (wrong)#[Autowire(param: 'app.root')]
resolves the parameter at compile time, not taking$skipScalars === true
into account, breaking Drupal sites.
b. (Correct)#[Autowire('%app.root%')]
works as expected, taking$skipScalars === true
into account and resolves the parameter on service resolution.
How to reproduce
ChangeSymfony\Component\DependencyInjection\Compiler\ResolveParameterPlaceHoldersPass::$skipScalars
to betrue
.
Create the following class and configure as autowired service:
class ParameterAutowireTestService {publicfunction__construct( #[Autowire(param:'test')]string$param1, #[Autowire('%test%')]string$param2, ) {if ($param1 !==$param2) {thrownew \Exception('$param1 and $param2 must be equal.'); } }}
Create a Symfony application with atest
parameter, which gets explicitly set with different values from a controller and a CLI command on every request.
Then retrieve the service from the container after the parameter has been set. The service should not throw the exception.
Possible Solution
No response
Additional Context
Drupal 10/11 has one parameter which can change between two single requests, especially between HTTP requests and CLI calls. This parameterapp.root
holds the absolute path of the Drupal installation and this value is different onchrooted environments withopen_basedir restrictions. For a detailed explanation why the path changes seeDrupal Core 33482733 - Stop caching app.root and site.path in DI containter. Due to this, Drupal sets this parameter on the container on every request with the current value.
The problem is that parameters are resolved during container compilation and the compiled container definition gets cached by Drupal. As consequence when rebuilding the caches via CLI the HTTP requests use an invalid/unresolvable application root path path and vice versa causing lots of problems. After a long analysis and debugging session I found out that I can fix this by patching theSymfony\Component\DependencyInjection\Compiler\ResolveParameterPlaceHoldersPass
by enabling the$skipScalars
option.
When refactoring my module from function based hooks to OOP hooks (for upgrading to Drupal 11) I observed this patch not working anymore.