From a3fd512271b05cf522111ec6fe1cce8e2f7eb784 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 29 Jan 2017 19:27:06 +0100 Subject: [PATCH] [DI] ContainerBuilder::compile() can optionally resolve env vars in parameter bag --- .../DependencyInjection/ContainerBuilder.php | 27 +++++++++++++++++-- .../Tests/ContainerBuilderTest.php | 27 +++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php index d68688c6029c1..5386944a13a3b 100644 --- a/src/Symfony/Component/DependencyInjection/ContainerBuilder.php +++ b/src/Symfony/Component/DependencyInjection/ContainerBuilder.php @@ -25,6 +25,7 @@ use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; use Symfony\Component\Config\Resource\ClassExistenceResource; use Symfony\Component\Config\Resource\DirectoryResource; use Symfony\Component\Config\Resource\FileExistenceResource; @@ -657,9 +658,25 @@ public function prependExtensionConfig($name, array $config) * * Parameter values are resolved; * * The parameter bag is frozen; * * Extension loading is disabled. + * + * @param bool $resolveEnvPlaceholders Whether %env()% parameters should be resolved using the current + * env vars or be replaced by uniquely identifiable placeholders. + * Set to "true" when you want to use the current ContainerBuilder + * directly, keep to "false" when the container is dumped instead. */ - public function compile() + public function compile(/*$resolveEnvPlaceholders = false*/) { + if (1 <= func_num_args()) { + $resolveEnvPlaceholders = func_get_arg(0); + } else { + if (__CLASS__ !== static::class) { + $r = new \ReflectionMethod($this, __FUNCTION__); + if (__CLASS__ !== $r->getDeclaringClass()->getName() && (1 > $r->getNumberOfParameters() || 'resolveEnvPlaceholders' !== $r->getParameters()[0]->name)) { + @trigger_error(sprintf('The %s::compile() method expects a first "$resolveEnvPlaceholders" argument since version 3.3. It will be made mandatory in 4.0.', static::class), E_USER_DEPRECATED); + } + } + $resolveEnvPlaceholders = false; + } $compiler = $this->getCompiler(); if ($this->trackResources) { @@ -667,6 +684,13 @@ public function compile() $this->addObjectResource($pass); } } + $bag = $this->getParameterBag(); + + if ($resolveEnvPlaceholders && $bag instanceof EnvPlaceholderParameterBag) { + $this->parameterBag = new ParameterBag($this->resolveEnvPlaceholders($bag->all(), true)); + $this->envPlaceholders = $bag->getEnvPlaceholders(); + $this->parameterBag = $bag = new ParameterBag($this->resolveEnvPlaceholders($this->parameterBag->all())); + } $compiler->compile($this); @@ -680,7 +704,6 @@ public function compile() } $this->extensionConfigs = array(); - $bag = $this->getParameterBag(); parent::compile(); diff --git a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php index 41a5702549a35..b6301b9712cbc 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php @@ -550,6 +550,33 @@ public function testResolveEnvValues() unset($_ENV['DUMMY_ENV_VAR']); } + public function testCompileWithResolveEnv() + { + $_ENV['DUMMY_ENV_VAR'] = 'du%%y'; + + $container = new ContainerBuilder(); + $container->setParameter('env(FOO)', 'Foo'); + $container->setParameter('bar', '%% %env(DUMMY_ENV_VAR)%'); + $container->setParameter('foo', '%env(FOO)%'); + $container->compile(true); + + $this->assertSame('% du%%y', $container->getParameter('bar')); + $this->assertSame('Foo', $container->getParameter('foo')); + + unset($_ENV['DUMMY_ENV_VAR']); + } + + /** + * @expectedException \Symfony\Component\DependencyInjection\Exception\EnvNotFoundException + * @expectedExceptionMessage Environment variable not found: "FOO". + */ + public function testCompileWithResolveMissingEnv() + { + $container = new ContainerBuilder(); + $container->setParameter('foo', '%env(FOO)%'); + $container->compile(true); + } + /** * @expectedException \LogicException */