Skip to content

Commit 6094d2c

Browse files
committed
[DependencyInjection] Fix env default processor with scalar node
1 parent 7a379d8 commit 6094d2c

File tree

2 files changed

+78
-11
lines changed

2 files changed

+78
-11
lines changed

Compiler/ValidateEnvPlaceholdersPass.php

Lines changed: 48 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,8 @@ public function process(ContainerBuilder $container)
4949
$defaultBag = new ParameterBag($resolvingBag->all());
5050
$envTypes = $resolvingBag->getProvidedTypes();
5151
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-
}
52+
$values = $this->getPlaceholderValues($env, $defaultBag, $envTypes);
53+
6354
foreach ($placeholders as $placeholder) {
6455
BaseNode::setPlaceholder($placeholder, $values);
6556
}
@@ -100,4 +91,50 @@ public function getExtensionConfig(): array
10091
$this->extensionConfig = [];
10192
}
10293
}
94+
95+
/**
96+
* @param array<string, list<string>> $envTypes
97+
*
98+
* @return array<string, mixed>
99+
*/
100+
private function getPlaceholderValues(string $env, ParameterBag $defaultBag, array $envTypes): array
101+
{
102+
if (false === $i = strpos($env, ':')) {
103+
[$default, $defaultType] = $this->getParameterDefaultAndDefaultType("env($env)", $defaultBag);
104+
105+
return [$defaultType => $default];
106+
}
107+
108+
$prefix = substr($env, 0, $i);
109+
if ('default' === $prefix) {
110+
$parts = explode(':', $env);
111+
array_shift($parts); // Remove 'default' prefix
112+
$parameter = array_shift($parts); // Retrieve and remove parameter
113+
114+
[$defaultParameter, $defaultParameterType] = $this->getParameterDefaultAndDefaultType($parameter, $defaultBag);
115+
116+
return [
117+
$defaultParameterType => $defaultParameter,
118+
...$this->getPlaceholderValues(implode(':', $parts), $defaultBag, $envTypes),
119+
];
120+
}
121+
122+
$values = [];
123+
foreach ($envTypes[$prefix] ?? ['string'] as $type) {
124+
$values[$type] = self::TYPE_FIXTURES[$type] ?? null;
125+
}
126+
127+
return $values;
128+
}
129+
130+
/**
131+
* @return array{0: string, 1: string}
132+
*/
133+
private function getParameterDefaultAndDefaultType(string $name, ParameterBag $defaultBag): array
134+
{
135+
$default = $defaultBag->has($name) ? $defaultBag->get($name) : self::TYPE_FIXTURES['string'];
136+
$defaultType = null !== $default ? get_debug_type($default) : 'string';
137+
138+
return [$default, $defaultType];
139+
}
103140
}

Tests/Compiler/ValidateEnvPlaceholdersPassTest.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,36 @@ 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', [
100+
'scalar_node' => '%env(default:parameter_int:json:JSON)%',
101+
]);
102+
103+
$this->doProcess($container);
104+
}
105+
76106
public function testEnvsAreValidatedInConfigWithInvalidPlaceholder()
77107
{
78108
$this->expectException(InvalidTypeException::class);

0 commit comments

Comments
 (0)