Skip to content

Navigation Menu

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 2ca1f68

Browse filesBrowse files
[DI] add #[When(env: 'foo')] to disable autoconfiguring a class during autodiscovery when the env doesn't match
1 parent 9092d5b commit 2ca1f68
Copy full SHA for 2ca1f68

File tree

7 files changed

+82
-3
lines changed
Filter options

7 files changed

+82
-3
lines changed
+26Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\DependencyInjection\Attribute;
13+
14+
/**
15+
* An attribute to tell under which environement this class should be autoconfigured.
16+
*
17+
* @author Nicolas Grekas <p@tchwork.com>
18+
*/
19+
#[\Attribute(\Attribute::TARGET_CLASS | \Attribute::IS_REPEATABLE)]
20+
class When
21+
{
22+
public function __construct(
23+
public string $env,
24+
) {
25+
}
26+
}

‎src/Symfony/Component/DependencyInjection/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ CHANGELOG
1313
* Add `ContainerBuilder::willBeAvailable()` to help with conditional configuration
1414
* Add support an integer return value for default_index_method
1515
* Add `env()` and `EnvConfigurator` in the PHP-DSL
16+
* Add `#[When(env: 'foo')]` to disable autoconfiguring a class during autodiscovery when the env doesn't match
1617

1718
5.2.0
1819
-----

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Loader/FileLoader.php
+16-1Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Symfony\Component\Config\Loader\FileLoader as BaseFileLoader;
1818
use Symfony\Component\Config\Loader\Loader;
1919
use Symfony\Component\Config\Resource\GlobResource;
20+
use Symfony\Component\DependencyInjection\Attribute\When;
2021
use Symfony\Component\DependencyInjection\ChildDefinition;
2122
use Symfony\Component\DependencyInjection\Compiler\RegisterAutoconfigureAttributesPass;
2223
use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -98,7 +99,8 @@ public function registerClasses(Definition $prototype, string $namespace, string
9899
}
99100

100101
$autoconfigureAttributes = new RegisterAutoconfigureAttributesPass();
101-
$classes = $this->findClasses($namespace, $resource, (array) $exclude, $autoconfigureAttributes->accept($prototype) ? $autoconfigureAttributes : null);
102+
$autoconfigureAttributes = $autoconfigureAttributes->accept($prototype) ? $autoconfigureAttributes : null;
103+
$classes = $this->findClasses($namespace, $resource, (array) $exclude, $autoconfigureAttributes);
102104
// prepare for deep cloning
103105
$serializedPrototype = serialize($prototype);
104106

@@ -115,6 +117,19 @@ public function registerClasses(Definition $prototype, string $namespace, string
115117
foreach (class_implements($class, false) as $interface) {
116118
$this->singlyImplemented[$interface] = ($this->singlyImplemented[$interface] ?? $class) !== $class ? false : $class;
117119
}
120+
if ($autoconfigureAttributes && $this->env) {
121+
$r = $this->container->getReflectionClass($class);
122+
$attribute = null;
123+
foreach ($r->getAttributes(When::class) as $attribute) {
124+
if ($this->env === $attribute->newInstance()->env) {
125+
$attribute = null;
126+
break;
127+
}
128+
}
129+
if (null !== $attribute) {
130+
$definition->setAutoconfigured(false);
131+
}
132+
}
118133
}
119134
}
120135

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
+7-1Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,13 @@ public function load($resource, string $type = null)
5050

5151
$this->container->fileExists($path);
5252

53-
$this->loadXml($xml, $path);
53+
$env = $this->env;
54+
$this->env = null;
55+
try {
56+
$this->loadXml($xml, $path);
57+
} finally {
58+
$this->env = $env;
59+
}
5460

5561
if ($this->env) {
5662
$xpath = new \DOMXPath($xml);

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php
+7-1Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,13 @@ public function load($resource, string $type = null)
129129
return;
130130
}
131131

132-
$this->loadContent($content, $path);
132+
$env = $this->env;
133+
$this->env = null;
134+
try {
135+
$this->loadContent($content, $path);
136+
} finally {
137+
$this->env = $env;
138+
}
133139

134140
// per-env configuration
135141
if ($this->env && isset($content['when@'.$this->env])) {

‎src/Symfony/Component/DependencyInjection/Tests/Fixtures/Prototype/Foo.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Fixtures/Prototype/Foo.php
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
namespace Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype;
44

5+
use Symfony\Component\DependencyInjection\Attribute\When;
6+
7+
#[When(env: 'prod')]
8+
#[When(env: 'dev')]
59
class Foo implements FooInterface, Sub\BarInterface
610
{
711
public function __construct($bar = null)

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Loader/FileLoaderTest.php
+21Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,27 @@ public function testRegisterClassesWithIncompatibleExclude()
243243
'yaml/*'
244244
);
245245
}
246+
247+
/**
248+
* @requires PHP 8
249+
*
250+
* @testWith ["prod", true]
251+
* ["dev", true]
252+
* ["bar", false]
253+
* [null, true]
254+
*/
255+
public function testRegisterClassesWithWhenEnv(?string $env, bool $expected)
256+
{
257+
$container = new ContainerBuilder();
258+
$loader = new TestFileLoader($container, new FileLocator(self::$fixturesPath.'/Fixtures'), $env);
259+
$loader->registerClasses(
260+
(new Definition())->setAutoconfigured(true),
261+
'Symfony\Component\DependencyInjection\Tests\Fixtures\Prototype\\',
262+
'Prototype/{Foo.php}'
263+
);
264+
265+
$this->assertSame($expected, $container->getDefinition(Foo::class)->isAutoconfigured());
266+
}
246267
}
247268

248269
class TestFileLoader extends FileLoader

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.