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 be5fbce

Browse filesBrowse files
HeahDudechalasr
authored andcommitted
[DependencyInjection] Enable deprecating parameters
1 parent d5c800f commit be5fbce
Copy full SHA for be5fbce
Expand file treeCollapse file tree

18 files changed

+671
-40
lines changed

‎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
@@ -10,6 +10,7 @@ CHANGELOG
1010
* Add support for nesting autowiring-related attributes into `#[Autowire(...)]`
1111
* Deprecate undefined and numeric keys with `service_locator` config
1212
* Fail if Target attribute does not exist during compilation
13+
* Enable deprecating parameters with `ContainerBuilder::deprecateParameter()`
1314

1415
6.2
1516
---

‎src/Symfony/Component/DependencyInjection/Container.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Container.php
+5-1Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
2323
use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag;
2424
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
25+
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
2526
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
2627
use Symfony\Contracts\Service\ResetInterface;
2728

@@ -82,7 +83,10 @@ public function compile()
8283
{
8384
$this->parameterBag->resolve();
8485

85-
$this->parameterBag = new FrozenParameterBag($this->parameterBag->all());
86+
$this->parameterBag = new FrozenParameterBag(
87+
$this->parameterBag->all(),
88+
$this->parameterBag instanceof ParameterBag ? $this->parameterBag->allDeprecated() : []
89+
);
8690

8791
$this->compiled = true;
8892
}

‎src/Symfony/Component/DependencyInjection/ContainerBuilder.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/ContainerBuilder.php
+27-4Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
use Symfony\Component\DependencyInjection\Exception\BadMethodCallException;
3535
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
3636
use Symfony\Component\DependencyInjection\Exception\LogicException;
37+
use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
3738
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
3839
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
3940
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
@@ -610,7 +611,15 @@ public function merge(self $container)
610611
}
611612
}
612613
$this->addAliases($container->getAliases());
613-
$this->getParameterBag()->add($container->getParameterBag()->all());
614+
$parameterBag = $this->getParameterBag();
615+
$otherBag = $container->getParameterBag();
616+
$parameterBag->add($otherBag->all());
617+
618+
if ($parameterBag instanceof ParameterBag && $otherBag instanceof ParameterBag) {
619+
foreach ($otherBag->allDeprecated() as $name => $deprecated) {
620+
$parameterBag->deprecate($name, ...$deprecated);
621+
}
622+
}
614623

615624
if ($this->trackResources) {
616625
foreach ($container->getResources() as $resource) {
@@ -626,9 +635,9 @@ public function merge(self $container)
626635
$this->extensionConfigs[$name] = array_merge($this->extensionConfigs[$name], $container->getExtensionConfig($name));
627636
}
628637

629-
if ($this->getParameterBag() instanceof EnvPlaceholderParameterBag && $container->getParameterBag() instanceof EnvPlaceholderParameterBag) {
630-
$envPlaceholders = $container->getParameterBag()->getEnvPlaceholders();
631-
$this->getParameterBag()->mergeEnvPlaceholders($container->getParameterBag());
638+
if ($parameterBag instanceof EnvPlaceholderParameterBag && $otherBag instanceof EnvPlaceholderParameterBag) {
639+
$envPlaceholders = $otherBag->getEnvPlaceholders();
640+
$parameterBag->mergeEnvPlaceholders($otherBag);
632641
} else {
633642
$envPlaceholders = [];
634643
}
@@ -689,6 +698,20 @@ public function prependExtensionConfig(string $name, array $config)
689698
array_unshift($this->extensionConfigs[$name], $config);
690699
}
691700

701+
/**
702+
* Deprecates a service container parameter.
703+
*
704+
* @throws ParameterNotFoundException if the parameter is not defined
705+
*/
706+
public function deprecateParameter(string $name, string $package, string $version, string $message = 'The parameter "%s" is deprecated.'): void
707+
{
708+
if (!$this->parameterBag instanceof ParameterBag) {
709+
throw new BadMethodCallException(sprintf('The parameter bag must be an instance of "%s" to call "%s".', ParameterBag::class, __METHOD__));
710+
}
711+
712+
$this->parameterBag->deprecate($name, $package, $version, $message);
713+
}
714+
692715
/**
693716
* Compiles the container.
694717
*

‎src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Dumper/PhpDumper.php
+34-5Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\NullDumper;
3636
use Symfony\Component\DependencyInjection\Loader\FileLoader;
3737
use Symfony\Component\DependencyInjection\Parameter;
38+
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
3839
use Symfony\Component\DependencyInjection\Reference;
3940
use Symfony\Component\DependencyInjection\ServiceLocator as BaseServiceLocator;
4041
use Symfony\Component\DependencyInjection\TypedReference;
@@ -1234,6 +1235,8 @@ private function startClass(string $class, string $baseClass, bool $hasProxyClas
12341235
*/
12351236
class $class extends $baseClass
12361237
{
1238+
private const DEPRECATED_PARAMETERS = [];
1239+
12371240
protected \$parameters = [];
12381241
protected readonly \WeakReference \$ref;
12391242
@@ -1242,11 +1245,9 @@ public function __construct()
12421245
\$this->ref = \WeakReference::create(\$this);
12431246
12441247
EOF;
1248+
$code = str_replace(" private const DEPRECATED_PARAMETERS = [];\n\n", $this->addDeprecatedParameters(), $code);
12451249
if ($this->asFiles) {
1246-
$code = str_replace('$parameters = []', "\$containerDir;\n protected \$parameters = [];\n private \$buildParameters", $code);
1247-
$code = str_replace('__construct()', '__construct(array $buildParameters = [], $containerDir = __DIR__)', $code);
1248-
$code .= " \$this->buildParameters = \$buildParameters;\n";
1249-
$code .= " \$this->containerDir = \$containerDir;\n";
1250+
$code = str_replace('__construct()', '__construct(private array $buildParameters = [], protected string $containerDir = __DIR__)', $code);
12501251

12511252
if (null !== $this->targetDirRegex) {
12521253
$code = str_replace('$parameters = []', "\$targetDir;\n protected \$parameters = []", $code);
@@ -1391,6 +1392,24 @@ public function getRemovedIds(): array
13911392
EOF;
13921393
}
13931394

1395+
private function addDeprecatedParameters(): string
1396+
{
1397+
if (!($bag = $this->container->getParameterBag()) instanceof ParameterBag) {
1398+
return '';
1399+
}
1400+
1401+
if (!$deprecated = $bag->allDeprecated()) {
1402+
return '';
1403+
}
1404+
$code = '';
1405+
ksort($deprecated);
1406+
foreach ($deprecated as $param => $deprecation) {
1407+
$code .= ' '.$this->doExport($param).' => ['.implode(', ', array_map($this->doExport(...), $deprecation))."],\n";
1408+
}
1409+
1410+
return " private const DEPRECATED_PARAMETERS = [\n{$code} ];\n\n";
1411+
}
1412+
13941413
private function addMethodMap(): string
13951414
{
13961415
$code = '';
@@ -1552,6 +1571,10 @@ private function addDefaultParametersMethod(): string
15521571
15531572
public function getParameter(string $name): array|bool|string|int|float|\UnitEnum|null
15541573
{
1574+
if (isset(self::DEPRECATED_PARAMETERS[$name])) {
1575+
trigger_deprecation(...self::DEPRECATED_PARAMETERS[$name]);
1576+
}
1577+
15551578
if (isset($this->buildParameters[$name])) {
15561579
return $this->buildParameters[$name];
15571580
}
@@ -1590,17 +1613,23 @@ public function getParameterBag(): ParameterBagInterface
15901613
foreach ($this->buildParameters as $name => $value) {
15911614
$parameters[$name] = $value;
15921615
}
1593-
$this->parameterBag = new FrozenParameterBag($parameters);
1616+
$this->parameterBag = new FrozenParameterBag($parameters, self::DEPRECATED_PARAMETERS);
15941617
}
15951618
15961619
return $this->parameterBag;
15971620
}
15981621

15991622
EOF;
1623+
16001624
if (!$this->asFiles) {
16011625
$code = preg_replace('/^.*buildParameters.*\n.*\n.*\n\n?/m', '', $code);
16021626
}
16031627

1628+
if (!($bag = $this->container->getParameterBag()) instanceof ParameterBag || !$bag->allDeprecated()) {
1629+
$code = preg_replace("/\n.*DEPRECATED_PARAMETERS.*\n.*\n.*\n/m", '', $code, 1);
1630+
$code = str_replace(', self::DEPRECATED_PARAMETERS', '', $code);
1631+
}
1632+
16041633
if ($dynamicPhp) {
16051634
$loadedDynamicParameters = $this->exportParameters(array_combine(array_keys($dynamicPhp), array_fill(0, \count($dynamicPhp), false)), '', 8);
16061635
$getDynamicParameter = <<<'EOF'

‎src/Symfony/Component/DependencyInjection/ParameterBag/FrozenParameterBag.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/ParameterBag/FrozenParameterBag.php
+9-4Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,11 +25,11 @@ class FrozenParameterBag extends ParameterBag
2525
* all keys are already lowercased.
2626
*
2727
* This is always the case when used internally.
28-
*
29-
* @param array $parameters An array of parameters
3028
*/
31-
public function __construct(array $parameters = [])
32-
{
29+
public function __construct(
30+
array $parameters = [],
31+
protected array $deprecatedParameters = [],
32+
) {
3333
$this->parameters = $parameters;
3434
$this->resolved = true;
3535
}
@@ -49,6 +49,11 @@ public function set(string $name, array|bool|string|int|float|\UnitEnum|null $va
4949
throw new LogicException('Impossible to call set() on a frozen ParameterBag.');
5050
}
5151

52+
public function deprecate(string $name, string $package, string $version, string $message = 'The parameter "%s" is deprecated.')
53+
{
54+
throw new LogicException('Impossible to call deprecate() on a frozen ParameterBag.');
55+
}
56+
5257
public function remove(string $name)
5358
{
5459
throw new LogicException('Impossible to call remove() on a frozen ParameterBag.');

‎src/Symfony/Component/DependencyInjection/ParameterBag/ParameterBag.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/ParameterBag/ParameterBag.php
+25-1Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ class ParameterBag implements ParameterBagInterface
2424
{
2525
protected $parameters = [];
2626
protected $resolved = false;
27+
protected array $deprecatedParameters = [];
2728

2829
public function __construct(array $parameters = [])
2930
{
@@ -47,6 +48,11 @@ public function all(): array
4748
return $this->parameters;
4849
}
4950

51+
public function allDeprecated(): array
52+
{
53+
return $this->deprecatedParameters;
54+
}
55+
5056
public function get(string $name): array|bool|string|int|float|\UnitEnum|null
5157
{
5258
if (!\array_key_exists($name, $this->parameters)) {
@@ -81,6 +87,10 @@ public function get(string $name): array|bool|string|int|float|\UnitEnum|null
8187
throw new ParameterNotFoundException($name, null, null, null, $alternatives, $nonNestedAlternative);
8288
}
8389

90+
if (isset($this->deprecatedParameters[$name])) {
91+
trigger_deprecation(...$this->deprecatedParameters[$name]);
92+
}
93+
8494
return $this->parameters[$name];
8595
}
8696

@@ -95,14 +105,28 @@ public function set(string $name, array|bool|string|int|float|\UnitEnum|null $va
95105
$this->parameters[$name] = $value;
96106
}
97107

108+
/**
109+
* Deprecates a service container parameter.
110+
*
111+
* @throws ParameterNotFoundException if the parameter is not defined
112+
*/
113+
public function deprecate(string $name, string $package, string $version, string $message = 'The parameter "%s" is deprecated.')
114+
{
115+
if (!\array_key_exists($name, $this->parameters)) {
116+
throw new ParameterNotFoundException($name);
117+
}
118+
119+
$this->deprecatedParameters[$name] = [$package, $version, $message, $name];
120+
}
121+
98122
public function has(string $name): bool
99123
{
100124
return \array_key_exists($name, $this->parameters);
101125
}
102126

103127
public function remove(string $name)
104128
{
105-
unset($this->parameters[$name]);
129+
unset($this->parameters[$name], $this->deprecatedParameters[$name]);
106130
}
107131

108132
public function resolve()

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php
+106Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,11 @@
3131
use Symfony\Component\DependencyInjection\ContainerBuilder;
3232
use Symfony\Component\DependencyInjection\ContainerInterface;
3333
use Symfony\Component\DependencyInjection\Definition;
34+
use Symfony\Component\DependencyInjection\Exception\BadMethodCallException;
3435
use Symfony\Component\DependencyInjection\Exception\EnvNotFoundException;
3536
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
3637
use Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException;
38+
use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
3739
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
3840
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
3941
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
@@ -42,6 +44,7 @@
4244
use Symfony\Component\DependencyInjection\Loader\ClosureLoader;
4345
use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag;
4446
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
47+
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
4548
use Symfony\Component\DependencyInjection\Reference;
4649
use Symfony\Component\DependencyInjection\ServiceLocator;
4750
use Symfony\Component\DependencyInjection\Tests\Compiler\Foo;
@@ -100,6 +103,109 @@ public function testDefinitions()
100103
}
101104
}
102105

106+
/**
107+
* The test should be kept in the group as it always expects a deprecation.
108+
*
109+
* @group legacy
110+
*/
111+
public function testDeprecateParameter()
112+
{
113+
$builder = new ContainerBuilder();
114+
$builder->setParameter('foo', 'bar');
115+
116+
$builder->deprecateParameter('foo', 'symfony/test', '6.3');
117+
118+
$this->expectDeprecation('Since symfony/test 6.3: The parameter "foo" is deprecated.');
119+
120+
$builder->getParameter('foo');
121+
}
122+
123+
/**
124+
* The test should be kept in the group as it always expects a deprecation.
125+
*
126+
* @group legacy
127+
*/
128+
public function testParameterDeprecationIsTrgiggeredWhenCompiled()
129+
{
130+
$builder = new ContainerBuilder();
131+
$builder->setParameter('foo', '%bar%');
132+
$builder->setParameter('bar', 'baz');
133+
134+
$builder->deprecateParameter('bar', 'symfony/test', '6.3');
135+
136+
$this->expectDeprecation('Since symfony/test 6.3: The parameter "bar" is deprecated.');
137+
138+
$builder->compile();
139+
}
140+
141+
public function testDeprecateParameterThrowsWhenParameterIsUndefined()
142+
{
143+
$builder = new ContainerBuilder();
144+
145+
$this->expectException(ParameterNotFoundException::class);
146+
$this->expectExceptionMessage('You have requested a non-existent parameter "foo".');
147+
148+
$builder->deprecateParameter('foo', 'symfony/test', '6.3');
149+
}
150+
151+
public function testDeprecateParameterThrowsWhenParameterBagIsNotInternal()
152+
{
153+
$builder = new ContainerBuilder(new class() implements ParameterBagInterface {
154+
public function clear()
155+
{
156+
}
157+
158+
public function add(array $parameters)
159+
{
160+
}
161+
162+
public function all(): array
163+
{
164+
return [];
165+
}
166+
167+
public function get(string $name): array|bool|string|int|float|\UnitEnum|null
168+
{
169+
return null;
170+
}
171+
172+
public function remove(string $name)
173+
{
174+
}
175+
176+
public function set(string $name, \UnitEnum|float|int|bool|array|string|null $value)
177+
{
178+
}
179+
180+
public function has(string $name): bool
181+
{
182+
return false;
183+
}
184+
185+
public function resolve()
186+
{
187+
}
188+
189+
public function resolveValue(mixed $value)
190+
{
191+
}
192+
193+
public function escapeValue(mixed $value): mixed
194+
{
195+
return null;
196+
}
197+
198+
public function unescapeValue(mixed $value): mixed
199+
{
200+
return null;
201+
}
202+
});
203+
204+
$this->expectException(BadMethodCallException::class);
205+
206+
$builder->deprecateParameter('foo', 'symfony/test', '6.3');
207+
}
208+
103209
public function testRegister()
104210
{
105211
$builder = new ContainerBuilder();

0 commit comments

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