Skip to content

Commit 875b04e

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

30 files changed

+257
-41
lines changed

src/Symfony/Component/DependencyInjection/Alias.php

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class Alias
1919
private $public;
2020
private $private;
2121
private $deprecated;
22-
private $deprecationTemplate;
22+
private $deprecation = [];
2323

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

@@ -92,7 +92,7 @@ public function isPrivate()
9292
*
9393
* @throws InvalidArgumentException when the message template is invalid
9494
*/
95-
public function setDeprecated(bool $status = true, string $template = null)
95+
public function setDeprecated(bool $status = true, string $template = null, string $package = null, string $sinceVersion = null)
9696
{
9797
if (null !== $template) {
9898
if (preg_match('#[\r\n]|\*/#', $template)) {
@@ -103,7 +103,15 @@ public function setDeprecated(bool $status = true, string $template = null)
103103
throw new InvalidArgumentException('The deprecation template must contain the "%alias_id%" placeholder.');
104104
}
105105

106-
$this->deprecationTemplate = $template;
106+
$this->deprecation['message'] = $template;
107+
}
108+
109+
if (null !== $package) {
110+
$this->deprecation['package'] = $package;
111+
}
112+
113+
if (null !== $sinceVersion) {
114+
$this->deprecation['since_version'] = $sinceVersion;
107115
}
108116

109117
$this->deprecated = $status;
@@ -118,7 +126,21 @@ public function isDeprecated(): bool
118126

119127
public function getDeprecationMessage(string $id): string
120128
{
121-
return str_replace('%alias_id%', $id, $this->deprecationTemplate ?: self::$defaultDeprecationTemplate);
129+
trigger_deprecation('symfony/dependency-injection', '5.1', 'The "%s()" method is deprecated, use "getDeprecation()" instead.', __METHOD__);
130+
131+
return $this->getDeprecation($id)['message'];
132+
}
133+
134+
/**
135+
* @param string $id Service id relying on this definition
136+
*/
137+
public function getDeprecation(string $id): array
138+
{
139+
return [
140+
'message' => str_replace('%alias_id%', $id, $this->deprecation['message'] ?? self::$defaultDeprecationTemplate),
141+
'since_version' => $this->deprecation['since_version'] ?? '',
142+
'package' => $this->deprecation['package'] ?? '',
143+
];
122144
}
123145

124146
/**

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+
* added support for `package` and `since_version` in service/alias deprecations
11+
* deprecated using `Definition::getDeprecationMessage` and `Alias::getDeprecationMessage()`
12+
* deprecated using service/alias deprecation message as xml node content, use `message` attribute instead.
1013

1114
5.0.0
1215
-----

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,8 @@ 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+
$parentDeprecation = $parentDef->getDeprecation('%service_id%');
106+
$def->setDeprecated(true, $parentDeprecation['message'], $parentDeprecation['package'], $parentDeprecation['since_version']);
106107
}
107108
$def->setFactory($parentDef->getFactory());
108109
$def->setConfigurator($parentDef->getConfigurator());

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['since_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: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -568,7 +568,9 @@ 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+
$deprecation = $alias->getDeprecation($id);
572+
573+
trigger_deprecation($deprecation['package'], $deprecation['since_version'], $deprecation['message']);
572574
}
573575

574576
return $this->doGet((string) $alias, $invalidBehavior, $inlineServices, $isConstructorArgument);
@@ -1037,7 +1039,8 @@ private function createService(Definition $definition, array &$inlineServices, b
10371039
}
10381040

10391041
if ($definition->isDeprecated()) {
1040-
trigger_deprecation('', '', $definition->getDeprecationMessage($id));
1042+
$deprecation = $definition->getDeprecation($id);
1043+
trigger_deprecation($deprecation['package'], $deprecation['since_version'], $deprecation['message']);
10411044
}
10421045

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

src/Symfony/Component/DependencyInjection/Definition.php

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class Definition
2727
private $factory;
2828
private $shared = true;
2929
private $deprecated = false;
30-
private $deprecationTemplate;
30+
private $deprecation = [];
3131
private $properties = [];
3232
private $calls = [];
3333
private $instanceof = [];
@@ -711,7 +711,7 @@ public function isAbstract()
711711
*
712712
* @throws InvalidArgumentException when the message template is invalid
713713
*/
714-
public function setDeprecated(bool $status = true, string $template = null)
714+
public function setDeprecated(bool $status = true, string $template = null, string $package = null, string $sinceVersion = null)
715715
{
716716
if (null !== $template) {
717717
if (preg_match('#[\r\n]|\*/#', $template)) {
@@ -722,7 +722,15 @@ public function setDeprecated(bool $status = true, string $template = null)
722722
throw new InvalidArgumentException('The deprecation template must contain the "%service_id%" placeholder.');
723723
}
724724

725-
$this->deprecationTemplate = $template;
725+
$this->deprecation['message'] = $template;
726+
}
727+
728+
if (null !== $package) {
729+
$this->deprecation['package'] = $package;
730+
}
731+
732+
if (null !== $sinceVersion) {
733+
$this->deprecation['since_version'] = $sinceVersion;
726734
}
727735

728736
$this->changes['deprecated'] = true;
@@ -752,7 +760,21 @@ public function isDeprecated()
752760
*/
753761
public function getDeprecationMessage(string $id)
754762
{
755-
return str_replace('%service_id%', $id, $this->deprecationTemplate ?: self::$defaultDeprecationTemplate);
763+
trigger_deprecation('symfony/dependency-injection', '5.1', 'The "%s()" method is deprecated, use "getDeprecation()" instead.', __METHOD__);
764+
765+
return $this->getDeprecation($id)['message'];
766+
}
767+
768+
/**
769+
* @param string $id Service id relying on this definition
770+
*/
771+
public function getDeprecation(string $id): array
772+
{
773+
return [
774+
'message' => str_replace('%service_id%', $id, $this->deprecation['message'] ?? self::$defaultDeprecationTemplate),
775+
'since_version' => $this->deprecation['since_version'] ?? '',
776+
'package' => $this->deprecation['package'] ?? '',
777+
];
756778
}
757779

758780
/**

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%s', $deprecation['message'], $deprecation['since_version'] ? (' since version '.$deprecation['since_version']) : '');
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['since_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+
$sinceVersionExported = $this->export($deprecation['since_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, $sinceVersionExported, $messageExported);
13161321
13171322
return \$this->get($idExported);
13181323
}

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,12 @@ 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+
184+
foreach ($definition->getDeprecation('%service_id%') as $key => $value) {
185+
if (!empty($value)) {
186+
$deprecated->setAttribute(str_replace('_', '-', $key), $value);
187+
}
188+
}
184189

185190
$service->appendChild($deprecated);
186191
}
@@ -225,8 +230,11 @@ private function addServiceAlias(string $alias, Alias $id, \DOMElement $parent)
225230
}
226231

227232
if ($id->isDeprecated()) {
233+
$deprecation = $id->getDeprecation('%alias_id%');
228234
$deprecated = $this->document->createElement('deprecated');
229-
$deprecated->appendChild($this->document->createTextNode($id->getDeprecationMessage('%alias_id%')));
235+
$deprecated->setAttribute('message', $deprecation['message']);
236+
$deprecated->setAttribute('package', $deprecation['package']);
237+
$deprecated->setAttribute('since_version', $deprecation['since_version']);
230238

231239
$service->appendChild($deprecated);
232240
}

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 (!empty($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: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,17 @@ 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 $template Template message to use if the definition is deprecated
22+
* @param string $package The name of the Composer package that is triggering the deprecation
23+
* @param string $sinceVersion The version of the package that introduced the deprecation
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 $template = null, string $package = null, string $sinceVersion = null): self
2830
{
29-
$this->definition->setDeprecated(true, $template);
31+
$this->definition->setDeprecated(true, $template, $package, $sinceVersion);
3032

3133
return $this;
3234
}

0 commit comments

Comments
 (0)