diff --git a/src/Symfony/Component/Config/Definition/BaseNode.php b/src/Symfony/Component/Config/Definition/BaseNode.php index a49e0b0bdc86e..00aa212bdc404 100644 --- a/src/Symfony/Component/Config/Definition/BaseNode.php +++ b/src/Symfony/Component/Config/Definition/BaseNode.php @@ -507,35 +507,21 @@ private static function resolvePlaceholderValue($value) return $value; } - private static function getType($value): string - { - switch ($type = \gettype($value)) { - case 'boolean': - return 'bool'; - case 'double': - return 'float'; - case 'integer': - return 'int'; - } - - return $type; - } - private function doValidateType($value): void { - if (null === $this->handlingPlaceholder || null === $value) { - $this->validateType($value); - - return; - } - - if (!$this->allowPlaceholders()) { + if (null !== $this->handlingPlaceholder && !$this->allowPlaceholders()) { $e = new InvalidTypeException(sprintf('A dynamic value is not compatible with a "%s" node type at path "%s".', get_class($this), $this->getPath())); $e->setPath($this->getPath()); throw $e; } + if (null === $this->handlingPlaceholder || null === $value) { + $this->validateType($value); + + return; + } + $knownTypes = array_keys(self::$placeholders[$this->handlingPlaceholder]); $validTypes = $this->getValidPlaceholderTypes(); diff --git a/src/Symfony/Component/DependencyInjection/Compiler/ValidateEnvPlaceholdersPass.php b/src/Symfony/Component/DependencyInjection/Compiler/ValidateEnvPlaceholdersPass.php index 1fe57f9db6cfb..09c83ce3bf2ee 100644 --- a/src/Symfony/Component/DependencyInjection/Compiler/ValidateEnvPlaceholdersPass.php +++ b/src/Symfony/Component/DependencyInjection/Compiler/ValidateEnvPlaceholdersPass.php @@ -14,7 +14,6 @@ use Symfony\Component\Config\Definition\BaseNode; use Symfony\Component\Config\Definition\Processor; use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Exception\LogicException; use Symfony\Component\DependencyInjection\Extension\ConfigurationExtensionInterface; use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; @@ -42,21 +41,20 @@ public function process(ContainerBuilder $container) return; } - $defaultBag = new ParameterBag($container->getParameterBag()->all()); + $defaultBag = new ParameterBag($resolvingBag->all()); $envTypes = $resolvingBag->getProvidedTypes(); try { foreach ($resolvingBag->getEnvPlaceholders() + $resolvingBag->getUnusedEnvPlaceholders() as $env => $placeholders) { - $prefix = (false === $i = strpos($env, ':')) ? 'string' : substr($env, 0, $i); - $types = $envTypes[$prefix] ?? array('string'); - $default = ($hasEnv = (false === $i && $defaultBag->has("env($env)"))) ? $defaultBag->get("env($env)") : null; - - if (null !== $default && !in_array($type = self::getType($default), $types, true)) { - throw new LogicException(sprintf('Invalid type for env parameter "env(%s)". Expected "%s", but got "%s".', $env, implode('", "', $types), $type)); - } - $values = array(); - foreach ($types as $type) { - $values[$type] = $hasEnv ? $default : self::$typeFixtures[$type] ?? null; + if (false === $i = strpos($env, ':')) { + $default = $defaultBag->has("env($env)") ? $defaultBag->get("env($env)") : null; + $defaultType = null !== $default ? self::getType($default) : 'string'; + $values[$defaultType] = $default; + } else { + $prefix = substr($env, 0, $i); + foreach ($envTypes[$prefix] ?? array('string') as $type) { + $values[$type] = self::$typeFixtures[$type] ?? null; + } } foreach ($placeholders as $placeholder) { BaseNode::setPlaceholder($placeholder, $values); diff --git a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ValidateEnvPlaceholdersPassTest.php b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ValidateEnvPlaceholdersPassTest.php index bd554cd285901..9534b11a90bb2 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Compiler/ValidateEnvPlaceholdersPassTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Compiler/ValidateEnvPlaceholdersPassTest.php @@ -22,31 +22,31 @@ class ValidateEnvPlaceholdersPassTest extends TestCase { - /** - * @expectedException \Symfony\Component\DependencyInjection\Exception\LogicException - * @expectedExceptionMessage Invalid type for env parameter "env(FOO)". Expected "string", but got "bool". - */ - public function testDefaultEnvIsValidatedByType() + public function testEnvsAreValidatedInConfig() { $container = new ContainerBuilder(); - $container->setParameter('env(FOO)', true); - $container->registerExtension(new EnvExtension()); - $container->prependExtensionConfig('env_extension', array( - 'scalar_node' => '%env(FOO)%', + $container->setParameter('env(NULLED)', null); + $container->setParameter('env(FLOATISH)', 3.2); + $container->registerExtension($ext = new EnvExtension()); + $container->prependExtensionConfig('env_extension', $expected = array( + 'scalar_node' => '%env(NULLED)%', + 'scalar_node_not_empty' => '%env(FLOATISH)%', + 'int_node' => '%env(int:FOO)%', + 'float_node' => '%env(float:BAR)%', )); $this->doProcess($container); + + $this->assertSame($expected, $container->resolveEnvPlaceholders($ext->getConfig())); } - public function testEnvsAreValidatedInConfig() + public function testDefaultEnvWithoutPrefixIsValidatedInConfig() { $container = new ContainerBuilder(); - $container->setParameter('env(NULLED)', null); + $container->setParameter('env(FLOATISH)', 3.2); $container->registerExtension($ext = new EnvExtension()); $container->prependExtensionConfig('env_extension', $expected = array( - 'scalar_node' => '%env(NULLED)%', - 'int_node' => '%env(int:FOO)%', - 'float_node' => '%env(float:BAR)%', + 'float_node' => '%env(FLOATISH)%', )); $this->doProcess($container); diff --git a/src/Symfony/Component/DependencyInjection/composer.json b/src/Symfony/Component/DependencyInjection/composer.json index 8230395645c7c..12758018f22da 100644 --- a/src/Symfony/Component/DependencyInjection/composer.json +++ b/src/Symfony/Component/DependencyInjection/composer.json @@ -32,7 +32,7 @@ "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them" }, "conflict": { - "symfony/config": "<4.1", + "symfony/config": "<4.1.1", "symfony/finder": "<3.4", "symfony/proxy-manager-bridge": "<3.4", "symfony/yaml": "<3.4"