diff --git a/src/Symfony/Component/DependencyInjection/CHANGELOG.md b/src/Symfony/Component/DependencyInjection/CHANGELOG.md index 0e2870bb38e81..f314f4c66fad8 100644 --- a/src/Symfony/Component/DependencyInjection/CHANGELOG.md +++ b/src/Symfony/Component/DependencyInjection/CHANGELOG.md @@ -5,6 +5,7 @@ CHANGELOG --- * Deprecate `ContainerAwareInterface` and `ContainerAwareTrait`, use dependency injection instead + * Add `defined` env var processor that returns `true` for defined and neither null nor empty env vars 6.3 --- diff --git a/src/Symfony/Component/DependencyInjection/EnvVarProcessor.php b/src/Symfony/Component/DependencyInjection/EnvVarProcessor.php index b7633c0fea8a9..1b4eb10fe3c39 100644 --- a/src/Symfony/Component/DependencyInjection/EnvVarProcessor.php +++ b/src/Symfony/Component/DependencyInjection/EnvVarProcessor.php @@ -56,6 +56,7 @@ public static function getProvidedTypes(): array 'require' => 'bool|int|float|string|array', 'enum' => \BackedEnum::class, 'shuffle' => 'array', + 'defined' => 'bool', ]; } @@ -103,6 +104,14 @@ public function getEnv(string $prefix, string $name, \Closure $getEnv): mixed return $backedEnumClassName::tryFrom($backedEnumValue) ?? throw new RuntimeException(sprintf('Enum value "%s" is not backed by "%s".', $backedEnumValue, $backedEnumClassName)); } + if ('defined' === $prefix) { + try { + return '' !== ($getEnv($name) ?? ''); + } catch (EnvNotFoundException) { + return false; + } + } + if ('default' === $prefix) { if (false === $i) { throw new RuntimeException(sprintf('Invalid env "default:%s": a fallback parameter should be provided.', $name)); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/RegisterEnvVarProcessorsPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/RegisterEnvVarProcessorsPassTest.php index ebf6c82b6e7ec..d23073c850bf8 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/RegisterEnvVarProcessorsPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/RegisterEnvVarProcessorsPassTest.php @@ -50,6 +50,7 @@ public function testSimpleProcessor() 'require' => ['bool', 'int', 'float', 'string', 'array'], 'enum' => [\BackedEnum::class], 'shuffle' => ['array'], + 'defined' => ['bool'], ]; $this->assertSame($expected, $container->getParameterBag()->getProvidedTypes()); diff --git a/src/Symfony/Component/DependencyInjection/Tests/EnvVarProcessorTest.php b/src/Symfony/Component/DependencyInjection/Tests/EnvVarProcessorTest.php index ac4ca68b10f26..98b02b598581e 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/EnvVarProcessorTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/EnvVarProcessorTest.php @@ -925,4 +925,21 @@ public function testGetEnvCastsNull($expected, string $prefix) }); })); } + + /** + * @dataProvider provideGetEnvDefined + */ + public function testGetEnvDefined(bool $expected, callable $callback) + { + $this->assertSame($expected, (new EnvVarProcessor(new Container()))->getEnv('defined', 'NO_SOMETHING', $callback)); + } + + public static function provideGetEnvDefined(): iterable + { + yield 'Defined' => [true, fn () => 'foo']; + yield 'Falsy but defined' => [true, fn () => '0']; + yield 'Empty string' => [false, fn () => '']; + yield 'Null' => [false, fn () => null]; + yield 'Env var not defined' => [false, fn () => throw new EnvNotFoundException()]; + } }