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 0eb071b

Browse filesBrowse files
j92Renan
authored and
Renan
committed
Added support for deprecating an alias
1 parent a9f8ca5 commit 0eb071b
Copy full SHA for 0eb071b

10 files changed

+249
-3
lines changed

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Alias.php
+59Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,24 @@
1111

1212
namespace Symfony\Component\DependencyInjection;
1313

14+
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
15+
1416
class Alias
1517
{
1618
private $id;
1719
private $public;
1820
private $private;
21+
private $deprecated;
22+
private $deprecationTemplate;
23+
24+
private static $defaultDeprecationTemplate = 'The "%service_id%" service alias is deprecated. You should stop using it, as it will soon be removed.';
1925

2026
public function __construct(string $id, bool $public = true)
2127
{
2228
$this->id = $id;
2329
$this->public = $public;
2430
$this->private = 2 > \func_num_args();
31+
$this->deprecated = false;
2532
}
2633

2734
/**
@@ -78,6 +85,58 @@ public function isPrivate()
7885
return $this->private;
7986
}
8087

88+
/**
89+
* Whether this alias is deprecated, that means it should not be called
90+
* anymore.
91+
*
92+
* @param bool $status Defaults to true
93+
* @param string $template Optional template message to use if the alias is deprecated
94+
*
95+
* @return $this
96+
*
97+
* @throws InvalidArgumentException when the message template is invalid
98+
*/
99+
public function setDeprecated($status = true, $template = null)
100+
{
101+
if (null !== $template) {
102+
if (preg_match('#[\r\n]|\*/#', $template)) {
103+
throw new InvalidArgumentException('Invalid characters found in deprecation template.');
104+
}
105+
106+
if (false === strpos($template, '%service_id%')) {
107+
throw new InvalidArgumentException('The deprecation template must contain the "%service_id%" placeholder.');
108+
}
109+
110+
$this->deprecationTemplate = $template;
111+
}
112+
113+
$this->deprecated = (bool) $status;
114+
115+
return $this;
116+
}
117+
118+
/**
119+
* Returns whether this alias is deprecated.
120+
*
121+
* @return bool
122+
*/
123+
public function isDeprecated()
124+
{
125+
return $this->deprecated;
126+
}
127+
128+
/**
129+
* Message to use if this alias is deprecated.
130+
*
131+
* @param string $id Service id relying on this alias
132+
*
133+
* @return string
134+
*/
135+
public function getDeprecationMessage($id)
136+
{
137+
return str_replace('%service_id%', $id, $this->deprecationTemplate ?: self::$defaultDeprecationTemplate);
138+
}
139+
81140
/**
82141
* Returns the Id of this alias.
83142
*

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/ContainerBuilder.php
+6-1Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,12 @@ private function doGet($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_
579579
}
580580

581581
if (!isset($this->definitions[$id]) && isset($this->aliasDefinitions[$id])) {
582-
return $this->doGet((string) $this->aliasDefinitions[$id], $invalidBehavior, $inlineServices, $isConstructorArgument);
582+
$aliasDefinition = $this->aliasDefinitions[$id];
583+
if ($aliasDefinition->isDeprecated()) {
584+
@trigger_error($aliasDefinition->getDeprecationMessage($id), E_USER_DEPRECATED);
585+
}
586+
587+
return $this->doGet((string) $aliasDefinition, $invalidBehavior, $inlineServices, $isConstructorArgument);
583588
}
584589

585590
try {

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
+9-1Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,10 @@ private function parseDefinition(\DOMElement $service, $file, array $defaults)
220220
$alias->setPublic($defaults['public']);
221221
}
222222

223+
if ($deprecated = $this->getChildren($service, 'deprecated')) {
224+
$alias->setDeprecated(true, $deprecated[0]->nodeValue ?: null);
225+
}
226+
223227
return;
224228
}
225229

@@ -667,8 +671,12 @@ private function validateAlias(\DOMElement $alias, $file)
667671
}
668672
}
669673

674+
$allowedTags = array('deprecated');
670675
foreach ($alias->childNodes as $child) {
671-
if ($child instanceof \DOMElement && self::NS === $child->namespaceURI) {
676+
if (!$child instanceof \DOMElement && self::NS !== $child->namespaceURI) {
677+
continue;
678+
}
679+
if (!in_array($child->localName, $allowedTags, true)) {
672680
throw new InvalidArgumentException(sprintf('Invalid child element "%s" defined for alias "%s" in "%s".', $child->localName, $alias->getAttribute('id'), $file));
673681
}
674682
}

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php
+6-1Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,8 +349,13 @@ private function parseDefinition($id, $service, $file, array $defaults)
349349
}
350350

351351
foreach ($service as $key => $value) {
352-
if (!\in_array($key, ['alias', 'public'])) {
352+
if (!\in_array($key, ['alias', 'public', 'deprecated'])) {
353353
throw new InvalidArgumentException(sprintf('The configuration key "%s" is unsupported for the service "%s" which is defined as an alias in "%s". Allowed configuration keys for service aliases are "alias" and "public".', $key, $id, $file));
354+
continue;
355+
}
356+
357+
if ('deprecated' === $key) {
358+
$alias->setDeprecated(true, $value);
354359
}
355360
}
356361

+110Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
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\Tests;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\DependencyInjection\Alias;
16+
17+
class AliasTest extends TestCase
18+
{
19+
public function testConstructor()
20+
{
21+
$alias = new Alias('foo');
22+
23+
$this->assertEquals('foo', (string) $alias);
24+
$this->assertTrue($alias->isPublic());
25+
}
26+
27+
public function testCanConstructANonPublicAlias()
28+
{
29+
$alias = new Alias('foo', false);
30+
31+
$this->assertEquals('foo', (string) $alias);
32+
$this->assertFalse($alias->isPublic());
33+
}
34+
35+
public function testCanConstructAPrivateAlias()
36+
{
37+
$alias = new Alias('foo', false, false);
38+
39+
$this->assertEquals('foo', (string) $alias);
40+
$this->assertFalse($alias->isPublic());
41+
$this->assertFalse($alias->isPrivate());
42+
}
43+
44+
public function testCanSetPublic()
45+
{
46+
$alias = new Alias('foo', false);
47+
$alias->setPublic(true);
48+
49+
$this->assertTrue($alias->isPublic());
50+
}
51+
52+
public function testCanDeprecateAnAlias()
53+
{
54+
$alias = new Alias('foo', false);
55+
$alias->setDeprecated(true, 'The %service_id% service is deprecated.');
56+
57+
$this->assertTrue($alias->isDeprecated());
58+
}
59+
60+
public function testItHasADefaultDeprecationMessage()
61+
{
62+
$alias = new Alias('foo', false);
63+
$alias->setDeprecated();
64+
65+
$expectedMessage = 'The "foo" service alias is deprecated. You should stop using it, as it will soon be removed.';
66+
$this->assertEquals($expectedMessage, $alias->getDeprecationMessage('foo'));
67+
}
68+
69+
public function testReturnsCorrectDeprecationMessage()
70+
{
71+
$alias = new Alias('foo', false);
72+
$alias->setDeprecated(true, 'The "%service_id%" is deprecated.');
73+
74+
$expectedMessage = 'The "foo" is deprecated.';
75+
$this->assertEquals($expectedMessage, $alias->getDeprecationMessage('foo'));
76+
}
77+
78+
public function testCanOverrideDeprecation()
79+
{
80+
$alias = new Alias('foo', false);
81+
$alias->setDeprecated();
82+
83+
$initial = $alias->isDeprecated();
84+
$alias->setDeprecated(false);
85+
$final = $alias->isDeprecated();
86+
87+
$this->assertTrue($initial);
88+
$this->assertFalse($final);
89+
}
90+
91+
/**
92+
* @dataProvider invalidDeprecationMessageProvider
93+
* @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
94+
*/
95+
public function testCannotDeprecateWithAnInvalidTemplate($message)
96+
{
97+
$def = new Alias('foo');
98+
$def->setDeprecated(true, $message);
99+
}
100+
101+
public function invalidDeprecationMessageProvider()
102+
{
103+
return array(
104+
"With \rs" => array("invalid \r message %service_id%"),
105+
"With \ns" => array("invalid \n message %service_id%"),
106+
'With */s' => array('invalid */ message %service_id%'),
107+
'message not containing required %service_id% variable' => array('this is deprecated'),
108+
);
109+
}
110+
}

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php
+16Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,22 @@ public function testAliases()
259259
}
260260
}
261261

262+
/**
263+
* @group legacy
264+
* @expectedDeprecation The "foobar" service alias is deprecated. You should stop using it, as it will soon be removed.
265+
*/
266+
public function testDeprecatedAlias()
267+
{
268+
$builder = new ContainerBuilder();
269+
$builder->register('foo', 'stdClass');
270+
271+
$alias = new Alias('foo');
272+
$alias->setDeprecated();
273+
$builder->setAlias('foobar', $alias);
274+
275+
$builder->get('foobar');
276+
}
277+
262278
public function testGetAliases()
263279
{
264280
$builder = new ContainerBuilder();
+13Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
3+
<services>
4+
<service id="foo" class="Foo">
5+
</service>
6+
<service id="alias_for_foo" alias="foo">
7+
<deprecated />
8+
</service>
9+
<service id="alias_for_foobar" alias="foobar">
10+
<deprecated>The "%service_id%" service alias is deprecated.</deprecated>
11+
</service>
12+
</services>
13+
</container>
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
services:
2+
alias_for_foobar:
3+
alias: foobar
4+
deprecated: The "%service_id%" service alias is deprecated.

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php
+15Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,21 @@ public function testDeprecated()
351351
$this->assertSame($message, $container->getDefinition('bar')->getDeprecationMessage('bar'));
352352
}
353353

354+
public function testDeprecatedAliases()
355+
{
356+
$container = new ContainerBuilder();
357+
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
358+
$loader->load('deprecated_alias_definitions.xml');
359+
360+
$this->assertTrue($container->getAlias('alias_for_foo')->isDeprecated());
361+
$message = 'The "alias_for_foo" service alias is deprecated. You should stop using it, as it will soon be removed.';
362+
$this->assertSame($message, $container->getAlias('alias_for_foo')->getDeprecationMessage('alias_for_foo'));
363+
364+
$this->assertTrue($container->getAlias('alias_for_foobar')->isDeprecated());
365+
$message = 'The "alias_for_foobar" service alias is deprecated.';
366+
$this->assertSame($message, $container->getAlias('alias_for_foobar')->getDeprecationMessage('alias_for_foobar'));
367+
}
368+
354369
public function testConvertDomElementToArray()
355370
{
356371
$doc = new \DOMDocument('1.0');

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

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php
+11Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,17 @@ public function testLoadServices()
175175
$this->assertEquals(['decorated', 'decorated.pif-pouf', 5], $services['decorator_service_with_name_and_priority']->getDecoratedService());
176176
}
177177

178+
public function testDeprecatedAliases()
179+
{
180+
$container = new ContainerBuilder();
181+
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
182+
$loader->load('deprecated_alias_definitions.yml');
183+
184+
$this->assertTrue($container->getAlias('alias_for_foobar')->isDeprecated());
185+
$message = 'The "alias_for_foobar" service alias is deprecated.';
186+
$this->assertSame($message, $container->getAlias('alias_for_foobar')->getDeprecationMessage('alias_for_foobar'));
187+
}
188+
178189
public function testLoadFactoryShortSyntax()
179190
{
180191
$container = new ContainerBuilder();

0 commit comments

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