diff --git a/src/Symfony/Component/DependencyInjection/CHANGELOG.md b/src/Symfony/Component/DependencyInjection/CHANGELOG.md index a27d6f32032e5..aa1ff13314352 100644 --- a/src/Symfony/Component/DependencyInjection/CHANGELOG.md +++ b/src/Symfony/Component/DependencyInjection/CHANGELOG.md @@ -12,6 +12,7 @@ CHANGELOG * Add support for per-env configuration in loaders * Add `ContainerBuilder::willBeAvailable()` to help with conditional configuration * Add support an integer return value for default_index_method + * Add `env()` and `EnvConfigurator` in the PHP-DSL 5.2.0 ----- diff --git a/src/Symfony/Component/DependencyInjection/Loader/Configurator/AbstractConfigurator.php b/src/Symfony/Component/DependencyInjection/Loader/Configurator/AbstractConfigurator.php index d9e936fc49df9..93d84337d0f26 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/Configurator/AbstractConfigurator.php +++ b/src/Symfony/Component/DependencyInjection/Loader/Configurator/AbstractConfigurator.php @@ -83,6 +83,10 @@ public static function processValue($value, $allowServices = false) return $def; } + if ($value instanceof EnvConfigurator) { + return (string) $value; + } + if ($value instanceof self) { throw new InvalidArgumentException(sprintf('"%s()" can be used only at the root of service configuration files.', $value::FACTORY)); } diff --git a/src/Symfony/Component/DependencyInjection/Loader/Configurator/ContainerConfigurator.php b/src/Symfony/Component/DependencyInjection/Loader/Configurator/ContainerConfigurator.php index 5fc8f5b6c803d..fdc042fbfa4b6 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/Configurator/ContainerConfigurator.php +++ b/src/Symfony/Component/DependencyInjection/Loader/Configurator/ContainerConfigurator.php @@ -201,3 +201,11 @@ function abstract_arg(string $description): AbstractArgument { return new AbstractArgument($description); } + +/** + * Creates an environment variable reference. + */ +function env(string $name): EnvConfigurator +{ + return new EnvConfigurator($name); +} diff --git a/src/Symfony/Component/DependencyInjection/Loader/Configurator/EnvConfigurator.php b/src/Symfony/Component/DependencyInjection/Loader/Configurator/EnvConfigurator.php new file mode 100644 index 0000000000000..c41b2814451c6 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Loader/Configurator/EnvConfigurator.php @@ -0,0 +1,213 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Loader\Configurator; + +class EnvConfigurator +{ + /** + * @var string[] + */ + private $stack; + + public function __construct(string $name) + { + $this->stack = explode(':', $name); + } + + /** + * @return string + */ + public function __toString() + { + return '%env('.implode(':', $this->stack).')%'; + } + + /** + * @return $this + */ + public function custom(string $processor, ...$args): self + { + array_unshift($this->stack, $processor, ...$args); + + return $this; + } + + /** + * @return $this + */ + public function base64(): self + { + array_unshift($this->stack, 'base64'); + + return $this; + } + + /** + * @return $this + */ + public function bool(): self + { + array_unshift($this->stack, 'bool'); + + return $this; + } + + /** + * @return $this + */ + public function not(): self + { + array_unshift($this->stack, 'not'); + + return $this; + } + + /** + * @return $this + */ + public function const(): self + { + array_unshift($this->stack, 'const'); + + return $this; + } + + /** + * @return $this + */ + public function csv(): self + { + array_unshift($this->stack, 'csv'); + + return $this; + } + + /** + * @return $this + */ + public function file(): self + { + array_unshift($this->stack, 'file'); + + return $this; + } + + /** + * @return $this + */ + public function float(): self + { + array_unshift($this->stack, 'float'); + + return $this; + } + + /** + * @return $this + */ + public function int(): self + { + array_unshift($this->stack, 'int'); + + return $this; + } + + /** + * @return $this + */ + public function json(): self + { + array_unshift($this->stack, 'json'); + + return $this; + } + + /** + * @return $this + */ + public function key(string $key): self + { + array_unshift($this->stack, 'key', $key); + + return $this; + } + + /** + * @return $this + */ + public function url(): self + { + array_unshift($this->stack, 'url'); + + return $this; + } + + /** + * @return $this + */ + public function queryString(): self + { + array_unshift($this->stack, 'query_string'); + + return $this; + } + + /** + * @return $this + */ + public function resolve(): self + { + array_unshift($this->stack, 'resolve'); + + return $this; + } + + /** + * @return $this + */ + public function default(string $fallbackParam): self + { + array_unshift($this->stack, 'default', $fallbackParam); + + return $this; + } + + /** + * @return $this + */ + public function string(): self + { + array_unshift($this->stack, 'string'); + + return $this; + } + + /** + * @return $this + */ + public function trim(): self + { + array_unshift($this->stack, 'trim'); + + return $this; + } + + /** + * @return $this + */ + public function require(): self + { + array_unshift($this->stack, 'require'); + + return $this; + } +} diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/env_configurator.php b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/env_configurator.php new file mode 100644 index 0000000000000..1c6a3b9038467 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/env_configurator.php @@ -0,0 +1,14 @@ +services(); + + $services + ->set('foo', \stdClass::class) + ->public() + ->args([ + env('CCC')->int() + ]); +}; diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/Configurator/EnvConfiguratorTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/Configurator/EnvConfiguratorTest.php new file mode 100644 index 0000000000000..d866752798501 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/Configurator/EnvConfiguratorTest.php @@ -0,0 +1,35 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DependencyInjection\Tests\Loader\Configurator; + +use PHPUnit\Framework\TestCase; +use Symfony\Component\DependencyInjection\Loader\Configurator\EnvConfigurator; + +final class EnvConfiguratorTest extends TestCase +{ + /** + * @dataProvider provide + */ + public function test(string $expected, EnvConfigurator $envConfigurator) + { + $this->assertSame($expected, (string) $envConfigurator); + } + + public function provide() + { + yield ['%env(FOO)%', new EnvConfigurator('FOO')]; + yield ['%env(string:FOO)%', new EnvConfigurator('string:FOO')]; + yield ['%env(string:FOO)%', (new EnvConfigurator('FOO'))->string()]; + yield ['%env(key:path:url:FOO)%', (new EnvConfigurator('FOO'))->url()->key('path')]; + yield ['%env(default:fallback:bar:arg1:FOO)%', (new EnvConfigurator('FOO'))->custom('bar', 'arg1')->default('fallback')]; + } +} diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/PhpFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/PhpFileLoaderTest.php index 50f3c58dd89e3..23b7111582207 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/PhpFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/PhpFileLoaderTest.php @@ -147,6 +147,15 @@ public function testWhenEnv() $this->assertSame(['foo' => 234, 'bar' => 345], $container->getParameterBag()->all()); } + public function testEnvConfigurator() + { + $container = new ContainerBuilder(); + $loader = new PhpFileLoader($container, new FileLocator(realpath(__DIR__.'/../Fixtures').'/config'), 'some-env'); + $loader->load('env_configurator.php'); + + $this->assertSame('%env(int:CCC)%', $container->getDefinition('foo')->getArgument(0)); + } + /** * @group legacy */