bug #29995 [DI] add id of referencing service when a deprecated alias is found (nicolas-grekas)
This PR was merged into the 4.3-dev branch.
Discussion
----------
[DI] add id of referencing service when a deprecated alias is found
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | -
| License | MIT
| Doc PR | -
Improves #29968 a bit for DX.
Commits
-------
b124fb7271
[DI] add id of referencing service when a deprecated alias is found
This commit is contained in:
commit
dca09750ed
@ -21,7 +21,7 @@ class Alias
|
||||
private $deprecated;
|
||||
private $deprecationTemplate;
|
||||
|
||||
private static $defaultDeprecationTemplate = 'The "%service_id%" service alias is deprecated. You should stop using it, as it will soon be removed.';
|
||||
private static $defaultDeprecationTemplate = 'The "%alias_id%" service alias is deprecated. You should stop using it, as it will be removed in the future.';
|
||||
|
||||
public function __construct(string $id, bool $public = true)
|
||||
{
|
||||
@ -103,8 +103,8 @@ class Alias
|
||||
throw new InvalidArgumentException('Invalid characters found in deprecation template.');
|
||||
}
|
||||
|
||||
if (false === strpos($template, '%service_id%')) {
|
||||
throw new InvalidArgumentException('The deprecation template must contain the "%service_id%" placeholder.');
|
||||
if (false === strpos($template, '%alias_id%')) {
|
||||
throw new InvalidArgumentException('The deprecation template must contain the "%alias_id%" placeholder.');
|
||||
}
|
||||
|
||||
$this->deprecationTemplate = $template;
|
||||
@ -122,7 +122,7 @@ class Alias
|
||||
|
||||
public function getDeprecationMessage(string $id): string
|
||||
{
|
||||
return str_replace('%service_id%', $id, $this->deprecationTemplate ?: self::$defaultDeprecationTemplate);
|
||||
return str_replace('%alias_id%', $id, $this->deprecationTemplate ?: self::$defaultDeprecationTemplate);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -86,7 +86,7 @@ class RemoveUnusedDefinitionsPass extends AbstractRecursivePass implements Repea
|
||||
protected function processValue($value, $isRoot = false)
|
||||
{
|
||||
if (!$value instanceof Reference) {
|
||||
return parent::processValue($value);
|
||||
return parent::processValue($value, $isRoot);
|
||||
}
|
||||
|
||||
if (ContainerBuilder::IGNORE_ON_UNINITIALIZED_REFERENCE !== $value->getInvalidBehavior()) {
|
||||
|
@ -31,6 +31,7 @@ class ResolveReferencesToAliasesPass extends AbstractRecursivePass
|
||||
|
||||
foreach ($container->getAliases() as $id => $alias) {
|
||||
$aliasId = (string) $alias;
|
||||
$this->currentId = $id;
|
||||
|
||||
if ($aliasId !== $defId = $this->getDefinitionId($aliasId, $container)) {
|
||||
$container->setAlias($id, $defId)->setPublic($alias->isPublic())->setPrivate($alias->isPrivate());
|
||||
@ -43,34 +44,36 @@ class ResolveReferencesToAliasesPass extends AbstractRecursivePass
|
||||
*/
|
||||
protected function processValue($value, $isRoot = false)
|
||||
{
|
||||
if ($value instanceof Reference) {
|
||||
$defId = $this->getDefinitionId($id = (string) $value, $this->container);
|
||||
|
||||
if ($defId !== $id) {
|
||||
return new Reference($defId, $value->getInvalidBehavior());
|
||||
}
|
||||
if (!$value instanceof Reference) {
|
||||
return parent::processValue($value, $isRoot);
|
||||
}
|
||||
|
||||
return parent::processValue($value);
|
||||
$defId = $this->getDefinitionId($id = (string) $value, $this->container);
|
||||
|
||||
return $defId !== $id ? new Reference($defId, $value->getInvalidBehavior()) : $value;
|
||||
}
|
||||
|
||||
private function getDefinitionId(string $id, ContainerBuilder $container): string
|
||||
{
|
||||
if (!$container->hasAlias($id)) {
|
||||
return $id;
|
||||
}
|
||||
|
||||
$alias = $container->getAlias($id);
|
||||
|
||||
if ($alias->isDeprecated()) {
|
||||
@trigger_error(sprintf('%s. It is being referenced by the "%s" %s.', rtrim($alias->getDeprecationMessage($id), '. '), $this->currentId, $container->hasDefinition($this->currentId) ? 'service' : 'alias'), E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
$seen = [];
|
||||
while ($container->hasAlias($id)) {
|
||||
do {
|
||||
if (isset($seen[$id])) {
|
||||
throw new ServiceCircularReferenceException($id, array_merge(array_keys($seen), [$id]));
|
||||
}
|
||||
|
||||
$seen[$id] = true;
|
||||
$alias = $container->getAlias($id);
|
||||
|
||||
if ($alias->isDeprecated()) {
|
||||
@trigger_error($alias->getDeprecationMessage($id), E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
$id = (string) $alias;
|
||||
}
|
||||
$id = (string) $container->getAlias($id);
|
||||
} while ($container->hasAlias($id));
|
||||
|
||||
return $id;
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ class Definition
|
||||
|
||||
protected $arguments = [];
|
||||
|
||||
private static $defaultDeprecationTemplate = 'The "%service_id%" service is deprecated. You should stop using it, as it will soon be removed.';
|
||||
private static $defaultDeprecationTemplate = 'The "%service_id%" service is deprecated. You should stop using it, as it will be removed in the future.';
|
||||
|
||||
/**
|
||||
* @internal
|
||||
|
@ -52,7 +52,7 @@ class AliasTest extends TestCase
|
||||
public function testCanDeprecateAnAlias()
|
||||
{
|
||||
$alias = new Alias('foo', false);
|
||||
$alias->setDeprecated(true, 'The %service_id% service is deprecated.');
|
||||
$alias->setDeprecated(true, 'The %alias_id% service is deprecated.');
|
||||
|
||||
$this->assertTrue($alias->isDeprecated());
|
||||
}
|
||||
@ -62,14 +62,14 @@ class AliasTest extends TestCase
|
||||
$alias = new Alias('foo', false);
|
||||
$alias->setDeprecated();
|
||||
|
||||
$expectedMessage = 'The "foo" service alias is deprecated. You should stop using it, as it will soon be removed.';
|
||||
$expectedMessage = 'The "foo" service alias is deprecated. You should stop using it, as it will be removed in the future.';
|
||||
$this->assertEquals($expectedMessage, $alias->getDeprecationMessage('foo'));
|
||||
}
|
||||
|
||||
public function testReturnsCorrectDeprecationMessage()
|
||||
{
|
||||
$alias = new Alias('foo', false);
|
||||
$alias->setDeprecated(true, 'The "%service_id%" is deprecated.');
|
||||
$alias->setDeprecated(true, 'The "%alias_id%" is deprecated.');
|
||||
|
||||
$expectedMessage = 'The "foo" is deprecated.';
|
||||
$this->assertEquals($expectedMessage, $alias->getDeprecationMessage('foo'));
|
||||
@ -101,10 +101,10 @@ class AliasTest extends TestCase
|
||||
public function invalidDeprecationMessageProvider()
|
||||
{
|
||||
return [
|
||||
"With \rs" => ["invalid \r message %service_id%"],
|
||||
"With \ns" => ["invalid \n message %service_id%"],
|
||||
'With */s' => ['invalid */ message %service_id%'],
|
||||
'message not containing required %service_id% variable' => ['this is deprecated'],
|
||||
"With \rs" => ["invalid \r message %alias_id%"],
|
||||
"With \ns" => ["invalid \n message %alias_id%"],
|
||||
'With */s' => ['invalid */ message %alias_id%'],
|
||||
'message not containing required %alias_id% variable' => ['this is deprecated'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ class ResolveReferencesToAliasesPassTest extends TestCase
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
* @expectedDeprecation The "deprecated_foo_alias" service alias is deprecated. You should stop using it, as it will soon be removed.
|
||||
* @expectedDeprecation The "deprecated_foo_alias" service alias is deprecated. You should stop using it, as it will be removed in the future. It is being referenced by the "alias" alias.
|
||||
*/
|
||||
public function testDeprecationNoticeWhenReferencedByAlias()
|
||||
{
|
||||
@ -105,7 +105,7 @@ class ResolveReferencesToAliasesPassTest extends TestCase
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
* @expectedDeprecation The "foo_aliased" service alias is deprecated. You should stop using it, as it will soon be removed.
|
||||
* @expectedDeprecation The "foo_aliased" service alias is deprecated. You should stop using it, as it will be removed in the future. It is being referenced by the "definition" service.
|
||||
*/
|
||||
public function testDeprecationNoticeWhenReferencedByDefinition()
|
||||
{
|
||||
|
@ -88,7 +88,7 @@ class ContainerBuilderTest extends TestCase
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
* @expectedDeprecation The "deprecated_foo" service is deprecated. You should stop using it, as it will soon be removed.
|
||||
* @expectedDeprecation The "deprecated_foo" service is deprecated. You should stop using it, as it will be removed in the future.
|
||||
*/
|
||||
public function testCreateDeprecatedService()
|
||||
{
|
||||
@ -261,7 +261,7 @@ class ContainerBuilderTest extends TestCase
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
* @expectedDeprecation The "foobar" service alias is deprecated. You should stop using it, as it will soon be removed.
|
||||
* @expectedDeprecation The "foobar" service alias is deprecated. You should stop using it, as it will be removed in the future.
|
||||
*/
|
||||
public function testDeprecatedAlias()
|
||||
{
|
||||
|
@ -164,7 +164,7 @@ class DefinitionTest extends TestCase
|
||||
$this->assertFalse($def->isDeprecated(), '->isDeprecated() returns false by default');
|
||||
$this->assertSame($def, $def->setDeprecated(true), '->setDeprecated() implements a fluent interface');
|
||||
$this->assertTrue($def->isDeprecated(), '->isDeprecated() returns true if the instance should not be used anymore.');
|
||||
$this->assertSame('The "deprecated_service" service is deprecated. You should stop using it, as it will soon be removed.', $def->getDeprecationMessage('deprecated_service'), '->getDeprecationMessage() should return a formatted message template');
|
||||
$this->assertSame('The "deprecated_service" service is deprecated. You should stop using it, as it will be removed in the future.', $def->getDeprecationMessage('deprecated_service'), '->getDeprecationMessage() should return a formatted message template');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -327,7 +327,7 @@ class PhpDumperTest extends TestCase
|
||||
|
||||
/**
|
||||
* @group legacy
|
||||
* @expectedDeprecation The "alias_for_foo_deprecated" service alias is deprecated. You should stop using it, as it will soon be removed.
|
||||
* @expectedDeprecation The "alias_for_foo_deprecated" service alias is deprecated. You should stop using it, as it will be removed in the future.
|
||||
*/
|
||||
public function testAliasesDeprecation()
|
||||
{
|
||||
@ -1067,7 +1067,7 @@ class PhpDumperTest extends TestCase
|
||||
* This test checks the trigger of a deprecation note and should not be removed in major releases.
|
||||
*
|
||||
* @group legacy
|
||||
* @expectedDeprecation The "foo" service is deprecated. You should stop using it, as it will soon be removed.
|
||||
* @expectedDeprecation The "foo" service is deprecated. You should stop using it, as it will be removed in the future.
|
||||
*/
|
||||
public function testPrivateServiceTriggersDeprecation()
|
||||
{
|
||||
|
@ -66,7 +66,7 @@ class Symfony_DI_PhpDumper_Test_Aliases_Deprecation extends Container
|
||||
*/
|
||||
protected function getAliasForFooDeprecatedService()
|
||||
{
|
||||
@trigger_error('The "alias_for_foo_deprecated" service alias is deprecated. You should stop using it, as it will soon be removed.', E_USER_DEPRECATED);
|
||||
@trigger_error('The "alias_for_foo_deprecated" service alias is deprecated. You should stop using it, as it will be removed in the future.', E_USER_DEPRECATED);
|
||||
|
||||
return $this->get('foo');
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
// This file has been auto-generated by the Symfony Dependency Injection Component for internal use.
|
||||
// Returns the public 'deprecated_service' shared service.
|
||||
|
||||
@trigger_error('The "deprecated_service" service is deprecated. You should stop using it, as it will soon be removed.', E_USER_DEPRECATED);
|
||||
@trigger_error('The "deprecated_service" service is deprecated. You should stop using it, as it will be removed in the future.', E_USER_DEPRECATED);
|
||||
|
||||
return $this->services['deprecated_service'] = new \stdClass();
|
||||
|
||||
@ -156,7 +156,7 @@ use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
// This file has been auto-generated by the Symfony Dependency Injection Component for internal use.
|
||||
// Returns the private 'factory_simple' shared service.
|
||||
|
||||
@trigger_error('The "factory_simple" service is deprecated. You should stop using it, as it will soon be removed.', E_USER_DEPRECATED);
|
||||
@trigger_error('The "factory_simple" service is deprecated. You should stop using it, as it will be removed in the future.', E_USER_DEPRECATED);
|
||||
|
||||
return new \SimpleFactoryClass('foo');
|
||||
|
||||
|
@ -206,11 +206,11 @@ class ProjectServiceContainer extends Container
|
||||
*
|
||||
* @return \stdClass
|
||||
*
|
||||
* @deprecated The "deprecated_service" service is deprecated. You should stop using it, as it will soon be removed.
|
||||
* @deprecated The "deprecated_service" service is deprecated. You should stop using it, as it will be removed in the future.
|
||||
*/
|
||||
protected function getDeprecatedServiceService()
|
||||
{
|
||||
@trigger_error('The "deprecated_service" service is deprecated. You should stop using it, as it will soon be removed.', E_USER_DEPRECATED);
|
||||
@trigger_error('The "deprecated_service" service is deprecated. You should stop using it, as it will be removed in the future.', E_USER_DEPRECATED);
|
||||
|
||||
return $this->services['deprecated_service'] = new \stdClass();
|
||||
}
|
||||
@ -400,11 +400,11 @@ class ProjectServiceContainer extends Container
|
||||
*
|
||||
* @return \SimpleFactoryClass
|
||||
*
|
||||
* @deprecated The "factory_simple" service is deprecated. You should stop using it, as it will soon be removed.
|
||||
* @deprecated The "factory_simple" service is deprecated. You should stop using it, as it will be removed in the future.
|
||||
*/
|
||||
protected function getFactorySimpleService()
|
||||
{
|
||||
@trigger_error('The "factory_simple" service is deprecated. You should stop using it, as it will soon be removed.', E_USER_DEPRECATED);
|
||||
@trigger_error('The "factory_simple" service is deprecated. You should stop using it, as it will be removed in the future.', E_USER_DEPRECATED);
|
||||
|
||||
return new \SimpleFactoryClass('foo');
|
||||
}
|
||||
|
@ -206,11 +206,11 @@ class Symfony_DI_PhpDumper_Errored_Definition extends Container
|
||||
*
|
||||
* @return \stdClass
|
||||
*
|
||||
* @deprecated The "deprecated_service" service is deprecated. You should stop using it, as it will soon be removed.
|
||||
* @deprecated The "deprecated_service" service is deprecated. You should stop using it, as it will be removed in the future.
|
||||
*/
|
||||
protected function getDeprecatedServiceService()
|
||||
{
|
||||
@trigger_error('The "deprecated_service" service is deprecated. You should stop using it, as it will soon be removed.', E_USER_DEPRECATED);
|
||||
@trigger_error('The "deprecated_service" service is deprecated. You should stop using it, as it will be removed in the future.', E_USER_DEPRECATED);
|
||||
|
||||
return $this->services['deprecated_service'] = new \stdClass();
|
||||
}
|
||||
@ -400,11 +400,11 @@ class Symfony_DI_PhpDumper_Errored_Definition extends Container
|
||||
*
|
||||
* @return \SimpleFactoryClass
|
||||
*
|
||||
* @deprecated The "factory_simple" service is deprecated. You should stop using it, as it will soon be removed.
|
||||
* @deprecated The "factory_simple" service is deprecated. You should stop using it, as it will be removed in the future.
|
||||
*/
|
||||
protected function getFactorySimpleService()
|
||||
{
|
||||
@trigger_error('The "factory_simple" service is deprecated. You should stop using it, as it will soon be removed.', E_USER_DEPRECATED);
|
||||
@trigger_error('The "factory_simple" service is deprecated. You should stop using it, as it will be removed in the future.', E_USER_DEPRECATED);
|
||||
|
||||
return new \SimpleFactoryClass('foo');
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
<deprecated />
|
||||
</service>
|
||||
<service id="alias_for_foobar" alias="foobar">
|
||||
<deprecated>The "%service_id%" service alias is deprecated.</deprecated>
|
||||
<deprecated>The "%alias_id%" service alias is deprecated.</deprecated>
|
||||
</service>
|
||||
</services>
|
||||
</container>
|
||||
|
@ -97,7 +97,7 @@
|
||||
<service id="decorator_service" class="stdClass" public="true" decorates="decorated"/>
|
||||
<service id="decorator_service_with_name" class="stdClass" public="true" decorates="decorated" decoration-inner-name="decorated.pif-pouf"/>
|
||||
<service id="deprecated_service" class="stdClass" public="true">
|
||||
<deprecated>The "%service_id%" service is deprecated. You should stop using it, as it will soon be removed.</deprecated>
|
||||
<deprecated>The "%service_id%" service is deprecated. You should stop using it, as it will be removed in the future.</deprecated>
|
||||
</service>
|
||||
<service id="new_factory" class="FactoryClass" public="false">
|
||||
<property name="foo">bar</property>
|
||||
@ -114,7 +114,7 @@
|
||||
</service>
|
||||
<service id="factory_simple" class="SimpleFactoryClass" public="false">
|
||||
<argument>foo</argument>
|
||||
<deprecated>The "%service_id%" service is deprecated. You should stop using it, as it will soon be removed.</deprecated>
|
||||
<deprecated>The "%service_id%" service is deprecated. You should stop using it, as it will be removed in the future.</deprecated>
|
||||
</service>
|
||||
<service id="factory_service_simple" class="Bar" public="true">
|
||||
<factory service="factory_simple" method="getInstance"/>
|
||||
|
@ -1,4 +1,4 @@
|
||||
services:
|
||||
alias_for_foobar:
|
||||
alias: foobar
|
||||
deprecated: The "%service_id%" service alias is deprecated.
|
||||
deprecated: The "%alias_id%" service alias is deprecated.
|
||||
|
@ -103,7 +103,7 @@ services:
|
||||
public: true
|
||||
deprecated_service:
|
||||
class: stdClass
|
||||
deprecated: The "%service_id%" service is deprecated. You should stop using it, as it will soon be removed.
|
||||
deprecated: The "%service_id%" service is deprecated. You should stop using it, as it will be removed in the future.
|
||||
public: true
|
||||
new_factory:
|
||||
class: FactoryClass
|
||||
@ -124,7 +124,7 @@ services:
|
||||
public: true
|
||||
factory_simple:
|
||||
class: SimpleFactoryClass
|
||||
deprecated: The "%service_id%" service is deprecated. You should stop using it, as it will soon be removed.
|
||||
deprecated: The "%service_id%" service is deprecated. You should stop using it, as it will be removed in the future.
|
||||
public: false
|
||||
arguments: ['foo']
|
||||
factory_service_simple:
|
||||
|
@ -343,7 +343,7 @@ class XmlFileLoaderTest extends TestCase
|
||||
$loader->load('services_deprecated.xml');
|
||||
|
||||
$this->assertTrue($container->getDefinition('foo')->isDeprecated());
|
||||
$message = 'The "foo" service is deprecated. You should stop using it, as it will soon be removed.';
|
||||
$message = 'The "foo" service is deprecated. You should stop using it, as it will be removed in the future.';
|
||||
$this->assertSame($message, $container->getDefinition('foo')->getDeprecationMessage('foo'));
|
||||
|
||||
$this->assertTrue($container->getDefinition('bar')->isDeprecated());
|
||||
@ -358,7 +358,7 @@ class XmlFileLoaderTest extends TestCase
|
||||
$loader->load('deprecated_alias_definitions.xml');
|
||||
|
||||
$this->assertTrue($container->getAlias('alias_for_foo')->isDeprecated());
|
||||
$message = 'The "alias_for_foo" service alias is deprecated. You should stop using it, as it will soon be removed.';
|
||||
$message = 'The "alias_for_foo" service alias is deprecated. You should stop using it, as it will be removed in the future.';
|
||||
$this->assertSame($message, $container->getAlias('alias_for_foo')->getDeprecationMessage('alias_for_foo'));
|
||||
|
||||
$this->assertTrue($container->getAlias('alias_for_foobar')->isDeprecated());
|
||||
|
Reference in New Issue
Block a user