8000 [DependencyInjection] Deprecate unsupported attributes/elements for alias by GuilhemN · Pull Request #17323 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[DependencyInjection] Deprecate unsupported attributes/elements for alias #17323

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,8 @@ private function parseDefinitions(\DOMDocument $xml, $file)
private function parseDefinition(\DOMElement $service, $file)
{
if ($alias = $service->getAttribute('alias')) {
$this->validateAlias($service, $file);

$public = true;
if ($publicAttr = $service->getAttribute('public')) {
$public = XmlUtils::phpize($publicAttr);
Expand Down Expand Up @@ -490,6 +492,27 @@ public function validateSchema(\DOMDocument $dom)
return $valid;
}

/**
* Validates an alias.
*
* @param \DOMElement $alias
* @param string $file
*/
private function validateAlias(\DOMElement $alias, $file)
{
foreach ($alias->attributes as $name => $node) {
if (!in_array($name, array('alias', 'id', 'public'))) {
@trigger_error(sprintf('Using the attribute "%s" is deprecated for alias definition "%s" in "%s". Allowed attributes are "alias", "id" and "public". The XmlFileLoader will raise an exception in Symfony 4.0, instead of silently ignoring unsupported attributes.', $name, $alias->getAttribute('id'), $file), E_USER_DEPRECATED);
}
}

foreach ($alias->childNodes as $child) {
if ($child instanceof \DOMElement && $child->namespaceURI === self::NS) {
@trigger_error(sprintf('Using the element "%s" is deprecated for alias definition "%s" in "%s". The XmlFileLoader will raise an exception in Symfony 4.0, instead of silently ignoring unsupported elements.', $child->localName, $alias->getAttribute('id'), $file), E_USER_DEPRECATED);
}
}
}

/**
* Validates an extension.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,12 @@ private function parseDefinition($id, $service, $file)
$public = !array_key_exists('public', $service) || (bool) $service['public'];
$this->container->setAlias($id, new Alias($service['alias'], $public));

foreach ($service as $key => $value) {
if (!in_array($key, array('alias', 'public'))) {
@trigger_error(sprintf('The configuration key "%s" is unsupported for alias definition "%s" in "%s". Allowed configuration keys are "alias" and "public". The YamlFileLoader will raise an exception in Symfony 4.0, instead of silently ignoring unsupported attributes.', $key, $id, $file), E_USER_DEPRECATED);
}
}

return;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<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">
<services>
<service id="foo" class="Foo" />

<service id="bar" alias="foo" class="Foo">
<tag name="foo.bar" />
<factory service="foobar" method="getBar" />
</service>
</services>
</container>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
services:
foo:
alias: bar
factory: foo
parent: quz
Original file line number Diff line number Diff line change
Expand Up @@ -486,4 +486,31 @@ public function testAutowire()

$this->assertTrue($container->getDefinition('bar')->isAutowired());
}

/**
* @group legacy
*/
public function testAliasDefinitionContainsUnsupportedElements()
{
$container = new ContainerBuilder();
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));

$deprecations = array();
set_error_handler(function ($type, $msg) use (&$deprecations) {
if (E_USER_DEPRECATED === $type) {
$deprecations[] = $msg;
}
});

$loader->load('legacy_invalid_alias_definition.xml');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test does not test anything (there are no assertions)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It tests that loading this deprecated options doesn't throw an error yet.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It still needs an assertion to not be marked as risky.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure @Tobion? They are not marked as risky on my computer.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd also prefer to have an assertion. There's always an expected outcome. Not throwing an exception is not really the one. The fact that alias is registered in the container might be a better idea.

Can we at least verify the alias was registered in the container please?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not adding a test that the deprecation is actually triggered (we did something similar in the Yaml component)?


$this->assertTrue($container->has('bar'));

$this->assertCount(3, $deprecations);
$this->assertContains('Using the attribute "class" is deprecated for alias definition "bar"', $deprecations[0]);
$this->assertContains('Using the element "tag" is deprecated for alias definition "bar"', $deprecations[1]);
$this->assertContains('Using the element "factory" is deprecated for alias definition "bar"', $deprecations[2]);

restore_error_handler();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -303,4 +303,30 @@ public function testServiceDefinitionContainsUnsupportedKeywords()
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
$loader->load('legacy_invalid_definition.yml');
}

/**
* @group legacy
*/
public function testAliasDefinitionContainsUnsupportedKeywords()
{
$container = new ContainerBuilder();
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));

$deprecations = array();
set_error_handler(function ($type, $msg) use (&$deprecations) {
if (E_USER_DEPRECATED === $type) {
$deprecations[] = $msg;
}
});

$loader->load('legacy_invalid_alias_definition.yml');

$this->assertTrue($container->has('foo'));

$this->assertCount(2, $deprecations);
$this->assertContains('The configuration key "factory" is unsupported for alias definition "foo"', $deprecations[0]);
$this->assertContains('The configuration key "parent" is unsupported for alias definition "foo"', $deprecations[1]);

restore_error_handler();
}
}
0