Skip to content

Commit 7db5f8a

Browse files
ruudknicolas-grekas
authored andcommitted
[DependencyInjection] Cast env vars to null or bool when referencing them using #[Autowire(env: '...')] depending on the signature of the corresponding parameter
1 parent d9dc33e commit 7db5f8a

File tree

4 files changed

+37
-0
lines changed

4 files changed

+37
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ CHANGELOG
1212
* Make `ContainerBuilder::registerAttributeForAutoconfiguration()` propagate to attribute classes that extend the registered class
1313
* Add argument `$prepend` to `FileLoader::construct()` to prepend loaded configuration instead of appending it
1414
* [BC BREAK] When used in the `prependExtension()` method, the `ContainerConfigurator::import()` method now prepends the configuration instead of appending it
15+
* Cast env vars to null or bool when referencing them using `#[Autowire(env: '...')]` depending on the signature of the corresponding parameter
1516

1617
7.0
1718
---

Compiler/AutowirePass.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,17 @@ private function autowireMethod(\ReflectionFunctionAbstract $reflectionMethod, a
306306

307307
foreach ($attributes as $attribute) {
308308
$attribute = $attribute->newInstance();
309+
$value = $attribute instanceof Autowire ? $attribute->value : null;
310+
311+
if (\is_string($value) && str_starts_with($value, '%env(') && str_ends_with($value, ')%')) {
312+
if ($parameter->getType() instanceof \ReflectionNamedType && 'bool' === $parameter->getType()->getName() && !str_starts_with($value, '%env(bool:')) {
313+
$attribute = new Autowire(substr_replace($value, 'bool:', 5, 0));
314+
}
315+
if ($parameter->isDefaultValueAvailable() && $parameter->allowsNull() && null === $parameter->getDefaultValue() && !preg_match('/(^|:)default:/', $value)) {
316+
$attribute = new Autowire(substr_replace($value, 'default::', 5, 0));
317+
}
318+
}
319+
309320
$invalidBehavior = $parameter->allowsNull() ? ContainerInterface::NULL_ON_INVALID_REFERENCE : ContainerBuilder::EXCEPTION_ON_INVALID_REFERENCE;
310321

311322
try {

Tests/Compiler/AutowirePassTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1397,4 +1397,18 @@ public function testLazyNotCompatibleWithAutowire()
13971397
$this->assertSame('Using both attributes #[Lazy] and #[Autowire] on an argument is not allowed; use the "lazy" parameter of #[Autowire] instead.', $e->getMessage());
13981398
}
13991399
}
1400+
1401+
public function testAutowireAttributeWithEnvVar()
1402+
{
1403+
$container = new ContainerBuilder();
1404+
1405+
$container->register('foo', AutowireAttributeEnv::class)->setAutowired(true);
1406+
1407+
(new AutowirePass())->process($container);
1408+
1409+
$definition = $container->getDefinition('foo');
1410+
1411+
$this->assertSame('%env(bool:ENABLED)%', $container->resolveEnvPlaceholders($definition->getArguments()[0]));
1412+
$this->assertSame('%env(default::OPTIONAL)%', $container->resolveEnvPlaceholders($definition->getArguments()[1]));
1413+
}
14001414
}

Tests/Fixtures/includes/autowiring_classes_80.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,17 @@ public function __construct(
8181
}
8282
}
8383

84+
class AutowireAttributeEnv
85+
{
86+
public function __construct(
87+
#[Autowire(env: 'ENABLED')]
88+
public bool $enabled,
89+
#[Autowire(env: 'OPTIONAL')]
90+
public ?string $optional = null,
91+
) {
92+
}
93+
}
94+
8495
interface AsDecoratorInterface
8596
{
8697
}

0 commit comments

Comments
 (0)