Skip to content

Commit 9a20024

Browse files
committed
Add an env function to DI expression language
1 parent 44db49f commit 9a20024

File tree

6 files changed

+51
-4
lines changed

6 files changed

+51
-4
lines changed

src/Symfony/Component/DependencyInjection/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ CHANGELOG
66

77
* Add `$exclude` to `TaggedIterator` and `TaggedLocator` attributes
88
* Add `$exclude` to `tagged_iterator` and `tagged_locator` configurator
9+
* Add an `env` function to the expression language provider
910

1011
6.0
1112
---

src/Symfony/Component/DependencyInjection/ContainerBuilder.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1586,7 +1586,7 @@ private function getExpressionLanguage(): ExpressionLanguage
15861586
if (!class_exists(\Symfony\Component\ExpressionLanguage\ExpressionLanguage::class)) {
15871587
throw new LogicException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.');
15881588
}
1589-
$this->expressionLanguage = new ExpressionLanguage(null, $this->expressionLanguageProviders);
1589+
$this->expressionLanguage = new ExpressionLanguage(null, $this->expressionLanguageProviders, null, \Closure::fromCallable([$this, 'getEnv']));
15901590
}
15911591

15921592
return $this->expressionLanguage;

src/Symfony/Component/DependencyInjection/ExpressionLanguage.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,10 @@ class ExpressionLanguage extends BaseExpressionLanguage
3030
/**
3131
* {@inheritdoc}
3232
*/
33-
public function __construct(CacheItemPoolInterface $cache = null, array $providers = [], callable $serviceCompiler = null)
33+
public function __construct(CacheItemPoolInterface $cache = null, array $providers = [], callable $serviceCompiler = null, \Closure $getEnv = null)
3434
{
3535
// prepend the default provider to let users override it easily
36-
array_unshift($providers, new ExpressionLanguageProvider($serviceCompiler));
36+
array_unshift($providers, new ExpressionLanguageProvider($serviceCompiler, $getEnv));
3737

3838
parent::__construct($cache, $providers);
3939
}

src/Symfony/Component/DependencyInjection/ExpressionLanguageProvider.php

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\DependencyInjection;
1313

14+
use Symfony\Component\DependencyInjection\Exception\LogicException;
1415
use Symfony\Component\ExpressionLanguage\ExpressionFunction;
1516
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
1617

@@ -19,16 +20,20 @@
1920
*
2021
* To get a service, use service('request').
2122
* To get a parameter, use parameter('kernel.debug').
23+
* To get an env variable, use env('SOME_VARIABLE').
2224
*
2325
* @author Fabien Potencier <[email protected]>
2426
*/
2527
class ExpressionLanguageProvider implements ExpressionFunctionProviderInterface
2628
{
2729
private ?\Closure $serviceCompiler;
2830

29-
public function __construct(callable $serviceCompiler = null)
31+
private ?\Closure $getEnv;
32+
33+
public function __construct(callable $serviceCompiler = null, \Closure $getEnv = null)
3034
{
3135
$this->serviceCompiler = null !== $serviceCompiler && !$serviceCompiler instanceof \Closure ? \Closure::fromCallable($serviceCompiler) : $serviceCompiler;
36+
$this->getEnv = $getEnv;
3237
}
3338

3439
public function getFunctions(): array
@@ -45,6 +50,16 @@ public function getFunctions(): array
4550
}, function (array $variables, $value) {
4651
return $variables['container']->getParameter($value);
4752
}),
53+
54+
new ExpressionFunction('env', function ($arg) {
55+
return sprintf('$this->getEnv(%s)', $arg);
56+
}, function (array $variables, $value) {
57+
if (!$this->getEnv) {
58+
throw new LogicException('You need to pass a getEnv closure to the expression langage provider to use the "env" function.');
59+
}
60+
61+
return ($this->getEnv)($value);
62+
}),
4863
];
4964
}
5065
}

src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,19 @@ public function testCreateServiceWithExpression()
517517
$this->assertEquals('foobar', $builder->get('foo')->arguments['foo']);
518518
}
519519

520+
public function testEnvExpressionFunction()
521+
{
522+
$container = new ContainerBuilder();
523+
$container->register('bar', 'BarClass')
524+
->setPublic(true)
525+
->setProperty('foo', new Expression('env("BAR_FOO")'));
526+
$container->compile(true);
527+
528+
$_ENV['BAR_FOO'] = 'Foo value';
529+
530+
$this->assertEquals('Foo value', $container->get('bar')->foo);
531+
}
532+
520533
public function testCreateServiceWithAbstractArgument()
521534
{
522535
$this->expectException(RuntimeException::class);

src/Symfony/Component/DependencyInjection/Tests/Dumper/PhpDumperTest.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -961,6 +961,24 @@ public function testPrivateWithIgnoreOnInvalidReference()
961961
$this->assertInstanceOf(\BazClass::class, $container->get('bar')->getBaz());
962962
}
963963

964+
public function testEnvExpressionFunction()
965+
{
966+
$container = new ContainerBuilder();
967+
$container->register('bar', 'BarClass')
968+
->setPublic(true)
969+
->setProperty('foo', new Expression('env("BAR_FOO")'));
970+
$container->compile();
971+
972+
$dumper = new PhpDumper($container);
973+
eval('?>'.$dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_Env_Expression_Function']));
974+
975+
$container = new \Symfony_DI_PhpDumper_Test_Env_Expression_Function();
976+
977+
$_ENV['BAR_FOO'] = 'Foo value';
978+
979+
$this->assertEquals('Foo value', $container->get('bar')->foo);
980+
}
981+
964982
public function testArrayParameters()
965983
{
966984
$container = new ContainerBuilder();

0 commit comments

Comments
 (0)