8000 [DependencyInjection] improve the deprecation features by handling pa… · symfony/symfony@9546db7 · GitHub
[go: up one dir, main page]

Skip to content

Commit 9546db7

Browse files
committed
[DependencyInjection] improve the deprecation features by handling package+version info
1 parent cde44fc commit 9546db7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+433
-108
lines changed

src/Symfony/Component/DependencyInjection/Alias.php

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ class Alias
1818
private $id;
1919
private $public;
2020
private $private;
21-
private $deprecated;
22-
private $deprecationTemplate;
21+
private $deprecation = [];
2322

2423
private static $defaultDeprecationTemplate = 'The "%alias_id%" service alias is deprecated. You should stop using it, as it will be removed in the future.';
2524

@@ -28,7 +27,6 @@ public function __construct(string $id, bool $public = true)
2827
$this->id = $id;
2928
$this->public = $public;
3029
$this->private = 2 > \func_num_args();
31-
$this->deprecated = false;
3230
}
3331

3432
/**
@@ -85,40 +83,69 @@ public function isPrivate()
8583
* Whether this alias is deprecated, that means it should not be referenced
8684
* anymore.
8785
*
88-
* @param bool $status Whether this alias is deprecated, defaults to true
89-
* @param string $template Optional template message to use if the alias is deprecated
86+
* @param string $package The name of the composer package that is triggering the deprecation
87+
* @param string $version The version of the package that introduced the deprecation
88+
* @param string $message The deprecation message to use
9089
*
9190
* @return $this
9291
*
9392
* @throws InvalidArgumentException when the message template is invalid
9493
*/
95-
public function setDeprecated(bool $status = true, string $template = null)
94+
public function setDeprecated(/* string $package, string $version, string $message */)
9695
{
97-
if (null !== $template) {
98-
if (preg_match('#[\r\n]|\*/#', $template)) {
96+
$args = func_get_args();
97+
98+
$package = $version = $message = '';
99+
$status = true;
100+
101+
if (func_num_args() < 3) {
102+
trigger_deprecation('symfony/dependency-injection', '5.1', 'The signature of "%s()" method requires 3 arguments: "string $package, string $version, string $message", not defining them is deprecated.', __METHOD__);
103+
104+
$status = $args[0] ?? true;
105+
$message = (string) ($args[1] ?? null);
106+
} else {
107+
$package = (string) $args[0];
108+
$version = (string) $args[1];
109+
$message = (string) $args[2];
110+
}
111+
112+
if ('' !== $message) {
113+
if (preg_match('#[\r\n]|\*/#', $message)) {
99114
throw new InvalidArgumentException('Invalid characters found in deprecation template.');
100115
}
101116

102-
if (false === strpos($template, '%alias_id%')) {
117+
if (false === strpos($message, '%alias_id%')) {
103118
throw new InvalidArgumentException('The deprecation template must contain the "%alias_id%" placeholder.');
104119
}
105-
106-
$this->deprecationTemplate = $template;
107120
}
108121

109-
$this->deprecated = $status;
122+
$this->deprecation = $status ? ['package' => $package, 'version' => $version, 'message' => $message ?: self::$defaultDeprecationTemplate] : [];
110123

111124
return $this;
112125
}
113126

114127
public function isDeprecated(): bool
115128
{
116-
return $this->deprecated;
129+
return (bool) $this->deprecation;
117130
}
118131

132+
/**
133+
* @deprecated since Symfony 5.1, The "getDeprecationMessage()" method is deprecated, use "getDeprecation()" instead.
134+
*/
119135
public function getDeprecationMessage(string $id): string
120136
{
121-
return str_replace('%alias_id%', $id, $this->deprecationTemplate ?: self::$defaultDeprecationTemplate);
137+
trigger_deprecation('symfony/dependency-injection', '5.1', 'The "%s()" method is deprecated, use "getDeprecation()" instead.', __METHOD__);
138+
139+
return $this->getDeprecation($id)['message'];
140+
}
141+
142+
public function getDeprecation(string $id): array
143+
{
144+
return [
145+
'package' => $this->deprecation['package'] ?? '',
146+
'version' => $this->deprecation['version'] ?? '',
147+
'message' => str_replace('%alias_id%', $id, $this->deprecation['message']),
148+
];
122149
}
123150

124151
/**

src/Symfony/Component/DependencyInjection/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ CHANGELOG
77
* added support to autowire public typed properties in php 7.4
88
* added support for defining method calls, a configurator, and property setters in `InlineServiceConfigurator`
99
* added possibility to define abstract service arguments
10+
* deprecated signature `Definition::setDeprecated(bool $status = true, string $template = null)`, use `Definition::setDeprecation(string $package, string $version, string $message)` instead
11+
* deprecated signature `Alias::setDeprecated(bool $status = true, string $template = null)`, use `Alias::setDeprecation(string $package, string $version, string $message)` instead
12+
* deprecated signature `DeprecateTrait::deprecate(string $template = null)`, use `DeprecateTrait::deprecation(string $package, string $version, string $message)` instead
1013

1114
5.0.0
1215
-----

src/Symfony/Component/DependencyInjection/Compiler/ResolveChildDefinitionsPass.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ private function doResolveDefinition(ChildDefinition $definition): Definition
102102
$def->setMethodCalls($parentDef->getMethodCalls());
103103
$def->setProperties($parentDef->getProperties());
104104
if ($parentDef->isDeprecated()) {
105-
$def->setDeprecated(true, $parentDef->getDeprecationMessage('%service_id%'));
105+
$def->setDeprecated(...array_values($parentDef->getDeprecation('%service_id%')));
106106
}
107107
$def->setFactory($parentDef->getFactory());
108108
$def->setConfigurator($parentDef->getConfigurator());
@@ -137,7 +137,11 @@ private function doResolveDefinition(ChildDefinition $definition): Definition
137137
$def->setLazy($definition->isLazy());
138138
}
139139
if (isset($changes['deprecated'])) {
140-
$def->setDeprecated($definition->isDeprecated(), $definition->getDeprecationMessage('%service_id%'));
140+
if ($definition->isDeprecated()) {
141+
$def->setDeprecated(...array_values($definition->getDeprecation('%service_id%')));
142+
} else {
143+
$def->setDeprecated(false);
144+
}
141145
}
142146
if (isset($changes['autowired'])) {
143147
$def->setAutowired($definition->isAutowired());

src/Symfony/Component/DependencyInjection/Compiler/ResolveReferencesToAliasesPass.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,9 @@ private function getDefinitionId(string $id, ContainerBuilder $container): strin
6262
$alias = $container->getAlias($id);
6363

6464
if ($alias->isDeprecated()) {
65-
trigger_deprecation('', '', '%s. It is being referenced by the "%s" %s.', rtrim($alias->getDeprecationMessage($id), '. '), $this->currentId, $container->hasDefinition($this->currentId) ? 'service' : 'alias');
65+
$deprecation = $alias->getDeprecation($id);
66+
67+
trigger_deprecation($deprecation['package'], $deprecation['version'], '%s. It is being referenced by the "%s" %s.', rtrim($deprecation['message'], '. '), $this->currentId, $container->hasDefinition($this->currentId) ? 'service' : 'alias');
6668
}
6769

6870
$seen = [];

src/Symfony/Component/DependencyInjection/ContainerBuilder.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,7 @@ private function doGet(string $id, int $invalidBehavior = ContainerInterface::EX
568568
$alias = $this->aliasDefinitions[$id];
569569

570570
if ($alias->isDeprecated()) {
571-
trigger_deprecation('', '', $alias->getDeprecationMessage($id));
571+
trigger_deprecation(...array_values($alias->getDeprecation($id)));
572572
}
573573

574574
return $this->doGet((string) $alias, $invalidBehavior, $inlineServices, $isConstructorArgument);
@@ -1037,7 +1037,7 @@ private function createService(Definition $definition, array &$inlineServices, b
10371037
}
10381038

10391039
if ($definition->isDeprecated()) {
1040-
trigger_deprecation('', '', $definition->getDeprecationMessage($id));
1040+
trigger_deprecation(...array_values($definition->getDeprecation($id)));
10411041
}
10421042

10431043
if ($tryProxy && $definition->isLazy() && !$tryProxy = !($proxy = $this->proxyInstantiator) || $proxy instanceof RealServiceInstantiator) {

src/Symfony/Component/DependencyInjection/Definition.php

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ class Definition
2626
private $file;
2727
private $factory;
2828
private $shared = true;
29-
private $deprecated = false;
30-
private $deprecationTemplate;
29+
private $deprecation = [];
3130
private $properties = [];
3231
private $calls = [];
3332
private $instanceof = [];
@@ -705,29 +704,44 @@ public function isAbstract()
705704
* Whether this definition is deprecated, that means it should not be called
706705
* anymore.
707706
*
708-
* @param string $template Template message to use if the definition is deprecated
707+
* @param string $package The name of the composer package that is triggering the deprecation
708+
* @param string $version The version of the package that introduced the deprecation
709+
* @param string $message The deprecation message to use
709710
*
710711
* @return $this
711712
*
712713
* @throws InvalidArgumentException when the message template is invalid
713714
*/
714-
public function setDeprecated(bool $status = true, string $template = null)
715+
public function setDeprecated(/* string $package, string $version, string $message */)
715716
{
716-
if (null !== $template) {
717-
if (preg_match('#[\r\n]|\*/#', $template)) {
717+
$args = func_get_args();
718+
719+
$package = $version = $message = '';
720+
$status = true;
721+
722+
if (func_num_args() < 3) {
723+
trigger_deprecation('symfony/dependency-injection', '5.1', 'The signature of "%s()" method requires 3 arguments: "string $package, string $version, string $message", not defining them is deprecated.', __METHOD__);
724+
725+
$status = $args[0] ?? true;
726+
$message = (string) ($args[1] ?? null);
727+
} else {
728+
$package = (string) $args[0];
729+
$version = (string) $args[1];
730+
$message = (string) $args[2];
731+
}
732+
733+
if ('' !== $message) {
734+
if (preg_match('#[\r\n]|\*/#', $message)) {
718735
throw new InvalidArgumentException('Invalid characters found in deprecation template.');
719736
}
720737

721-
if (false === strpos($template, '%service_id%')) {
738+
if (false === strpos($message, '%service_id%')) {
722739
throw new InvalidArgumentException('The deprecation template must contain the "%service_id%" placeholder.');
723740
}
724-
725-
$this->deprecationTemplate = $template;
726741
}
727742

728743
$this->changes['deprecated'] = true;
729-
730-
$this->deprecated = $status;
744+
$this->deprecation = $status ? ['package' => $package, 'version' => $version, 'message' => $message ?: self::$defaultDeprecationTemplate] : [];
731745

732746
return $this;
733747
}
@@ -740,19 +754,32 @@ public function setDeprecated(bool $status = true, string $template = null)
740754
*/
741755
public function isDeprecated()
742756
{
743-
return $this->deprecated;
757+
return (bool) $this->deprecation;
744758
}
745759

746760
/**
747761
* Message to use if this definition is deprecated.
748762
*
763+
* @deprecated since Symfony 5.1, The "getDeprecationMessage()" method is deprecated, use "getDeprecation()" instead.
764+
*
749765
* @param string $id Service id relying on this definition
750766
*
751767
* @return string
752768
*/
753769
public function getDeprecationMessage(string $id)
754770
{
755-
return str_replace('%service_id%', $id, $this->deprecationTemplate ?: self::$defaultDeprecationTemplate);
771+
trigger_deprecation('symfony/dependency-injection', F438 '5.1', 'The "%s()" method is deprecated, use "getDeprecation()" instead.', __METHOD__);
772+
773+
return $this->getDeprecation($id)['message'];
774+
}
775+
776+
public function getDeprecation(string $id): array
777+
{
778+
return [
779+
'package' => $this->deprecation['package'] ?? '',
780+
'version' => $this->deprecation['version'] ?? '',
781+
'message' => str_replace('%service_id%', $id, $this->deprecation['message'] ?? self::$defaultDeprecationTemplate),
782+
];
756783
}
757784

758785
/**

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -760,7 +760,8 @@ private function addService(string $id, Definition $definition): array
760760
$return[] = '';
761761
}
762762

763-
$return[] = sprintf('@deprecated %s', $definition->getDeprecationMessage($id));
763+
$deprecation = $definition->getDeprecation($id);
764+
$return[] = sprintf('@deprecated %s', ($deprecation['package'] || $deprecation['version'] ? "Since {$deprecation['package']} {$deprecation['version']}: " : '').$deprecation['message']);
764765
}
765766

766767
$return = str_replace("\n * \n", "\n *\n", implode("\n * ", $return));
@@ -803,7 +804,8 @@ protected function {$methodName}($lazyInitialization)
803804
$this->inlinedDefinitions = $this->getDefinitionsFromArguments([$definition], null, $this->serviceCalls);
804805

805806
if ($definition->isDeprecated()) {
806-
$code .= sprintf(" trigger_deprecation('', '', %s);\n\n", $this->export($definition->getDeprecationMessage($id)));
807+
$deprecation = $definition->getDeprecation($id);
808+
$code .= sprintf(" trigger_deprecation(%s, %s, %s);\n\n", $this->export($deprecation['package']), $this->export($deprecation['version']), $this->export($deprecation['message']));
807809
}
808810

809811
if ($this->getProxyDumper()->isProxyCandidate($definition)) {
@@ -1302,7 +1304,10 @@ private function addDeprecatedAliases(): string
13021304
$id = (string) $definition;
13031305
$methodNameAlias = $this->generateMethodName($alias);
13041306
$idExported = $this->export($id);
1305-
$messageExported = $this->export($definition->getDeprecationMessage($alias));
1307+
$deprecation = $definition->getDeprecation($alias);
1308+
$packageExported = $this->export($deprecation['package']);
1309+
$versionExported = $this->export($deprecation['version']);
1310+
$messageExported = $this->export($deprecation['message']);
13061311
$code .= <<<EOF
13071312
13081313
/*{$this->docStar}
@@ -1312,7 +1317,7 @@ private function addDeprecatedAliases(): string
13121317
*/
13131318
protected function {$methodNameAlias}()
13141319
{
1315-
trigger_deprecation('', '', $messageExported);
1320+
trigger_deprecation($packageExported, $versionExported, $messageExported);
13161321
13171322
return \$this->get($idExported);
13181323
}

src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,11 @@ private function addService(Definition $definition, ?string $id, \DOMElement $pa
180180

181181
if ($definition->isDeprecated()) {
182182
$deprecated = $this->document->createElement('deprecated');
183-
$deprecated->appendChild($this->document->createTextNode($definition->getDeprecationMessage('%service_id%')));
183+
$deprecation = $definition->getDeprecation('%service_id%');
184+
185+
$deprecated->appendChild($this->document->createTextNode($definition->getDeprecation('%service_id%')['message']));
186+
$deprecated->setAttribute('package', $deprecation['package']);
187+
$deprecated->setAttribute('version', $deprecation['version']);
184188

185189
$service->appendChild($deprecated);
186190
}
@@ -225,8 +229,11 @@ private function addServiceAlias(string $alias, Alias $id, \DOMElement $parent)
225229
}
226230

227231
if ($id->isDeprecated()) {
232+
$deprecation = $id->getDeprecation('%alias_id%');
228233
$deprecated = $this->document->createElement('deprecated');
229-
$deprecated->appendChild($this->document->createTextNode($id->getDeprecationMessage('%alias_id%')));
234+
$deprecated->setAttribute('message', $deprecation['message']);
235+
$deprecated->setAttribute('package', $deprecation['package']);
236+
$deprecated->setAttribute('version', $deprecation['version']);
230237

231238
$service->appendChild($deprecated);
232239
}

src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,12 @@ private function addService(string $id, Definition $definition): string
9797
}
9898

9999
if ($definition->isDeprecated()) {
100-
$code .= sprintf(" deprecated: %s\n", $this->dumper->dump($definition->getDeprecationMessage('%service_id%')));
100+
$code .= " deprecated:\n";
101+
foreach ($definition->getDeprecation('%service_id%') as $key => $value) {
102+
if ('' !== $value) {
103+
$code .= sprintf(" %s: %s\n", $key, $this->dumper->dump($value));
104+
}
105+
}
101106
}
102107

103108
if ($definition->isAutowired()) {
@@ -162,7 +167,17 @@ private function addService(string $id, Definition $definition): string
162167

163168
private function addServiceAlias(string $alias, Alias $id): string
164169
{
165-
$deprecated = $id->isDeprecated() ? sprintf(" deprecated: %s\n", $id->getDeprecationMessage('%alias_id%')) : '';
170+
$deprecated = '';
171+
172+
if ($id->isDeprecated()) {
173+
$deprecated = " deprecated:\n";
174+
175+
foreach ($id->getDeprecation('%alias_id%') as $key => $value) {
176+
if ('' !== $value) {
177+
$deprecated .= sprintf(" %s: %s\n", $key, $value);
178+
}
179+
}
180+
}
166181

167182
if ($id->isPrivate()) {
168183
return sprintf(" %s: '@%s'\n%s", $alias, $id, $deprecated);

src/Symfony/Component/DependencyInjection/Loader/Configurator/Traits/DeprecateTrait.php

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,30 @@ trait DeprecateTrait
1818
/**
1919
* Whether this definition is deprecated, that means it should not be called anymore.
2020
*
21-
* @param string $template Template message to use if the definition is deprecated
21+
* @param string $package The name of the composer package that is triggering the deprecation
22+
* @param string $version The version of the package that introduced the deprecation
23+
* @param string $message The deprecation message to use
2224
*
2325
* @return $this
2426
*
2527
* @throws InvalidArgumentException when the message template is invalid
2628
*/
27-
final public function deprecate(string $template = null): self
29+
final public function deprecate(/* string $package, string $version, string $message */): self
2830
{
29-
$this->definition->setDeprecated(true, $template);
31+
$args = func_get_args();
32+
$package = $version = $message = '';
33+
34+
if (func_num_args() < 3) {
35+
trigger_deprecation('symfony/dependency-injection', '5.1', 'The signature of "%s()" method requires 3 arguments: "string $package, string $version, string $message", not defining them is deprecated.', __METHOD__);
36+
37+
$message = (string) ($args[0] ?? null);
38+
} else {
39+
$package = (string) $args[0];
40+
$version = (string) $args[1];
41+
$message = (string) $args[2];
42+
}
43+
44+
$this->definition->setDeprecated($package, $version, $message);
3045

3146
return $this;
3247
}

0 commit comments

Comments
 (0)
0