8000 [DependencyInjection] Fix env default processor with scalar node · symfony/symfony@c707435 · GitHub
[go: up one dir, main page]

Skip to content

Commit c707435

Browse files
committed
[DependencyInjection] Fix env default processor with scalar node
1 parent c427887 commit c707435

File tree

2 files changed

+79
-12
lines changed

2 files changed

+79
-12
lines changed

src/Symfony/Component/DependencyInjection/Compiler/ValidateEnvPlaceholdersPass.php

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,9 @@ public function process(ContainerBuilder $container)
4747
}
4848

4949
$defaultBag = new ParameterBag($resolvingBag->all());
50-
$envTypes = $resolvingBag->getProvidedTypes();
5150
foreach ($resolvingBag->getEnvPlaceholders() + $resolvingBag->getUnusedEnvPlaceholders() as $env => $placeholders) {
52-
$values = [];
53-
if (false === $i = strpos($env, ':')) {
54-
$default = $defaultBag->has("env($env)") ? $defaultBag->get("env($env)") : self::TYPE_FIXTURES['string'];
55-
$defaultType = null !== $default ? get_debug_type($default) : 'string';
56-
$values[$defaultType] = $default;
57-
} else {
58-
$prefix = substr($env, 0, $i);
59-
foreach ($envTypes[$prefix] ?? ['string'] as $type) {
60-
$values[$type] = self::TYPE_FIXTURES[$type] ?? null;
61-
}
62-
}
51+
$values = $this->getPlaceholderValues($env, $defaultBag, $resolvingBag->getProvidedTypes());
52+
6353
foreach ($placeholders as $placeholder) {
6454
BaseNode::setPlaceholder($placeholder, $values);
6555
}
@@ -100,4 +90,50 @@ public function getExtensionConfig(): array
10090
$this->extensionConfig = [];
10191
}
10292
}
93+
94+
/**
95+
* @param array<string, list<string>> $envTypes
96+
*
97+
* @return array<string, mixed>
98+
*/
99+
private function getPlaceholderValues(string $env, ParameterBag $defaultBag, array $envTypes): array
100+
{
101+
if (false === $i = strpos($env, ':')) {
102+
[$default, $defaultType] = $this->getParameterDefaultAndDefaultType("env($env)", $defaultBag);
103+
104+
return [$defaultType => $default];
105+
}
106+
107+
$prefix = substr($env, 0, $i);
108+
if ('default' === $prefix) {
109+
$parts = explode(':', $env);
110+
array_shift($parts); // Remove 'default' prefix
111+
$parameter = array_shift($parts); // Retrieve and remove parameter
112+
113+
[$defaultParameter, $defaultParameterType] = $this->getParameterDefaultAndDefaultType($parameter, $defaultBag);
114+
115+
return [
116+
$defaultParameterType => $defaultParameter,
117+
...$this->getPlaceholderValues(implode(':', $parts), $defaultBag, $envTypes),
118+
];
119+
}
120+
121+
$values = [];
122+
foreach ($envTypes[$prefix] ?? ['string'] as $type) {
123+
$values[$type] = self::TYPE_FIXTURES[$type] ?? null;
124+
}
125+
126+
return $values;
127+
}
128+
129+
/**
130+
* @return array{0: string, 1: string}
131+
*/
132+
private function getParameterDefaultAndDefaultType(string $name, ParameterBag $defaultBag): array
133+
{
134+
$default = $defaultBag->has($name) ? $defaultBag->get($name) : self::TYPE_FIXTURES['string'];
135+
$defaultType = null !== $default ? get_debug_type($default) : 'string';
136+
137+
return [$default, $defaultType];
138+
}
103139
}

src/Symfony/Component/DependencyInjection/Tests/Compiler/ValidateEnvPlaceholdersPassTest.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,37 @@ public function testDefaultEnvWithoutPrefixIsValidatedInConfig()
7373
$this->doProcess($container);
7474
}
7575

76+
public function testDefaultProcessorWithScalarNode()
77+
{
78+
$container = new ContainerBuilder();
79+
$container->setParameter('parameter_int', 12134);
80+
$container->setParameter('env(FLOATISH)', 4.2);
81+
$container->registerExtension($ext = new EnvExtension());
82+
$container->prependExtensionConfig('env_extension', $expected = [
83+
'scalar_node' => '%env(default:parameter_int:FLOATISH)%',
84+
]);
85+
86+
$this->doProcess($container);
87+
$this->assertSame($expected, $container->resolveEnvPlaceholders($ext->getConfig()));
88+
}
89+
90+
public function testDefaultProcessorAndAnotherProcessorWithScalarNode()
91+
{
92+
$this->expectException(InvalidTypeException::class);
93+
$this->expectExceptionMessageMatches('/^Invalid type for path "env_extension\.scalar_node"\. Expected one of "bool", "int", "float", "string", but got one of "int", "array"\.$/');
94+
95+
$container = new ContainerBuilder();
96+
$container->setParameter('parameter_int', 12134);
97+
$container->setParameter('env(JSON)', '{ "foo": "bar" }');
98+
$container->registerExtension($ext = new EnvExtension());
99+
$container->prependExtensionConfig('env_extension', $expected = [
100+
'scalar_node' => '%env(default:parameter_int:json:JSON)%',
101+
]);
102+
103+
$this->doProcess($container);
104+
dump($container->resolveEnvPlaceholders($ext->getConfig()));
105+
}
106+
76107
public function testEnvsAreValidatedInConfigWithInvalidPlaceholder()
77108
{
78109
$this->expectException(InvalidTypeException::class);

0 commit comments

Comments
 (0)
0