Skip to content

Commit 50d7ce0

Browse files
committed
feature symfony#53971 Cast env vars to null or bool when referencing them using #[Autowire(env: '...')] depending on the signature of the corresponding parameter (ruudk)
This PR was merged into the 7.1 branch. Discussion ---------- Cast env vars to null or bool when referencing them using `#[Autowire(env: '...')]` depending on the signature of the corresponding parameter | Q | A | ------------- | --- | Branch? | 7.1 | Bug fix? | no | New feature? | yes | Deprecations? | no | Issues | Fix symfony#53918 | License | MIT See symfony#53918 This PR automatically adds `bool` [Environment Variable Processors](https://symfony.com/doc/current/configuration/env_var_processors.html#built-in-environment-variable-processors) on `#[Autowire(env: 'KEY')] bool $key` arguments. The idea behind this, is to prevent mistakes being made. If you omit the `bool` env var processor, passing `KEY=false` will become true-ish and thus mark `$key` as `true`. With the `bool` env processor, `KEY=false` becomes `false`. It also automatically adds the `default::` prefix if the default value of an argument is `null`. Commits ------- 5890327 [DependencyInjection] Cast env vars to null or bool when referencing them using `#[Autowire(env: '...')]` depending on the signature of the corresponding parameter
2 parents 0a9cba3 + 5890327 commit 50d7ce0

File tree

4 files changed

+37
-0
lines changed

4 files changed

+37
-0
lines changed

src/Symfony/Component/DependencyInjection/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
---

src/Symfony/Component/DependencyInjection/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 {

src/Symfony/Component/DependencyInjection/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
}

src/Symfony/Component/DependencyInjection/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)