From 49eb65c63e763229128bcb6473dc81a26f2fa2f1 Mon Sep 17 00:00:00 2001 From: Ener-Getick Date: Sat, 9 Jan 2016 19:39:03 +0100 Subject: [PATCH] [DependencyInjection] Deprecate unsupported attributes/elements for alias --- .../Loader/XmlFileLoader.php | 23 ++++++++++++++++ .../Loader/YamlFileLoader.php | 6 +++++ .../xml/legacy_invalid_alias_definition.xml | 11 ++++++++ .../yaml/legacy_invalid_alias_definition.yml | 5 ++++ .../Tests/Loader/XmlFileLoaderTest.php | 27 +++++++++++++++++++ .../Tests/Loader/YamlFileLoaderTest.php | 26 ++++++++++++++++++ 6 files changed, 98 insertions(+) create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/legacy_invalid_alias_definition.xml create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/legacy_invalid_alias_definition.yml diff --git a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php index dad46786d91f..46ca2921f6a9 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php @@ -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); @@ -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. * diff --git a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php index 59f59b0b70b7..df8e4e7d9fe0 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php @@ -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; } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/legacy_invalid_alias_definition.xml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/legacy_invalid_alias_definition.xml new file mode 100644 index 000000000000..52386e5bf52d --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/legacy_invalid_alias_definition.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/legacy_invalid_alias_definition.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/legacy_invalid_alias_definition.yml new file mode 100644 index 000000000000..00c011c1ddd0 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/legacy_invalid_alias_definition.yml @@ -0,0 +1,5 @@ +services: + foo: + alias: bar + factory: foo + parent: quz diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php index 7057d4400952..7860379fd597 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php @@ -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'); + + $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(); + } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php index feca4d1fd434..a85dacf9a839 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php @@ -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(); + } }