Skip to content

Commit a3f2273

Browse files
[DependencyInjection] inject $env in the scope of PHP-DSL files
1 parent b39781a commit a3f2273

File tree

7 files changed

+46
-8
lines changed

7 files changed

+46
-8
lines changed

Attribute/When.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
*
1717
* @author Nicolas Grekas <p@tchwork.com>
1818
*/
19-
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::IS_REPEATABLE)]
19+
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::TARGET_METHOD | \Attribute::IS_REPEATABLE)]
2020
class When
2121
{
2222
public function __construct(

Loader/PhpFileLoader.php

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\Config\Builder\ConfigBuilderGeneratorInterface;
1616
use Symfony\Component\Config\Builder\ConfigBuilderInterface;
1717
use Symfony\Component\Config\FileLocatorInterface;
18+
use Symfony\Component\DependencyInjection\Attribute\When;
1819
use Symfony\Component\DependencyInjection\Container;
1920
use Symfony\Component\DependencyInjection\ContainerBuilder;
2021
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
@@ -55,12 +56,12 @@ public function load($resource, string $type = null)
5556
$this->container->fileExists($path);
5657

5758
// the closure forbids access to the private scope in the included file
58-
$load = \Closure::bind(function ($path) use ($container, $loader, $resource, $type) {
59+
$load = \Closure::bind(function ($path, $env) use ($container, $loader, $resource, $type) {
5960
return include $path;
6061
}, $this, ProtectedPhpFileLoader::class);
6162

6263
try {
63-
$callback = $load($path);
64+
$callback = $load($path, $this->env);
6465

6566
if (\is_object($callback) && \is_callable($callback)) {
6667
$this->executeCallback($callback, new ContainerConfigurator($this->container, $this, $this->instanceof, $path, $resource, $this->env), $path);
@@ -98,8 +99,22 @@ private function executeCallback(callable $callback, ContainerConfigurator $cont
9899

99100
$arguments = [];
100101
$configBuilders = [];
101-
$parameters = (new \ReflectionFunction($callback))->getParameters();
102-
foreach ($parameters as $parameter) {
102+
$r = new \ReflectionFunction($callback);
103+
104+
if (\PHP_VERSION_ID >= 80000) {
105+
$attribute = null;
106+
foreach ($r->getAttributes(When::class) as $attribute) {
107+
if ($this->env === $attribute->newInstance()->env) {
108+
$attribute = null;
109+
break;
110+
}
111+
}
112+
if (null !== $attribute) {
113+
return;
114+
}
115+
}
116+
117+
foreach ($r->getParameters() as $parameter) {
103118
$reflectionType = $parameter->getType();
104119
if (!$reflectionType instanceof \ReflectionNamedType) {
105120
throw new \InvalidArgumentException(sprintf('Could not resolve argument "$%s" for "%s". You must typehint it (for example with "%s" or "%s").', $parameter->getName(), $path, ContainerConfigurator::class, ContainerBuilder::class));

Tests/Fixtures/config/config_builder.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
use Symfony\Component\DependencyInjection\Tests\Fixtures\AcmeConfig;
44

5-
return static function (AcmeConfig $config) {
5+
if ('prod' !== $env) {
6+
return;
7+
}
8+
9+
return function (AcmeConfig $config) {
610
$config->color('blue');
711
};

Tests/Fixtures/config/env_configurator.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
44

5-
return static function (ContainerConfigurator $configurator): void {
5+
return function (ContainerConfigurator $configurator): void {
66
$services = $configurator->services();
77

88
$services

Tests/Fixtures/config/nested_bundle_config.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22

33
use Symfony\Config\AcmeConfig\NestedConfig;
44

5-
return static function (NestedConfig $config) {
5+
return function (NestedConfig $config) {
66
throw new RuntimeException('This code should not be run.');
77
};

Tests/Fixtures/config/when_env.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
use Symfony\Component\DependencyInjection\Attribute\When;
4+
5+
return #[When(env: 'prod')] function () {
6+
throw new RuntimeException('This code should not be run.');
7+
};

Tests/Loader/PhpFileLoaderTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,4 +176,16 @@ public function testNestedBundleConfigNotAllowed()
176176

177177
$loader->load($fixtures.'/config/nested_bundle_config.php');
178178
}
179+
180+
/**
181+
* @requires PHP 8
182+
*/
183+
public function testWhenEnv()
184+
{
185+
$fixtures = realpath(__DIR__.'/../Fixtures');
186+
$container = new ContainerBuilder();
187+
$loader = new PhpFileLoader($container, new FileLocator(), 'dev', new ConfigBuilderGenerator(sys_get_temp_dir()));
188+
189+
$loader->load($fixtures.'/config/when_env.php');
190+
}
179191
}

0 commit comments

Comments
 (0)