Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit b14d769

Browse filesBrowse files
feature #41182 [DependencyInjection] allow PHP-DSL files to be env-conditional (nicolas-grekas)
This PR was merged into the 5.3-dev branch. Discussion ---------- [DependencyInjection] allow PHP-DSL files to be env-conditional | Q | A | ------------- | --- | Branch? | 5.x | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | - | License | MIT | Doc PR | - This PR makes config builders compatible with conditional configuration based on the $env. See fixture for an example: ```php use Symfony\Component\DependencyInjection\Tests\Fixtures\AcmeConfig; if ('prod' !== $env) { return; } return static function (AcmeConfig $config) { $config->color('blue'); }; ``` On PHP8, the PR to allow using `#[When(env: prod')]`: ```php use Symfony\Component\DependencyInjection\Attribute\When; use Symfony\Component\DependencyInjection\Tests\Fixtures\AcmeConfig; return #[When(env: 'prod')] function (AcmeConfig $config) { $config->color('blue'); }; ``` Without this patch, such a config file cannot be used if AcmeBundle is not loaded in the current $env. This is a follow up of https://symfony.com/blog/new-in-symfony-5-3-configure-multiple-environments-in-a-single-file#comment-24521 by `@a`-menshchikov Commits ------- 29173a9 [DependencyInjection] inject $env in the scope of PHP-DSL files
2 parents 1921c78 + 29173a9 commit b14d769
Copy full SHA for b14d769

File tree

7 files changed

+46
-8
lines changed
Filter options

7 files changed

+46
-8
lines changed

‎src/Symfony/Component/DependencyInjection/Attribute/When.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Attribute/When.php
+1-1Lines 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(

‎src/Symfony/Component/DependencyInjection/Loader/PhpFileLoader.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Loader/PhpFileLoader.php
+19-4Lines 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));

‎src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/config_builder.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/config_builder.php
+5-1Lines 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
};

‎src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/env_configurator.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/env_configurator.php
+1-1Lines 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

‎src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/nested_bundle_config.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Fixtures/config/nested_bundle_config.php
+1-1Lines 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
};
+7Lines 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+
};

‎src/Symfony/Component/DependencyInjection/Tests/Loader/PhpFileLoaderTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Loader/PhpFileLoaderTest.php
+12Lines 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 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.