From bb5f1185559e376f7c9ec8870bb08840039e8ca0 Mon Sep 17 00:00:00 2001 From: Hugo Hamon Date: Thu, 24 Dec 2015 16:17:45 +0100 Subject: [PATCH] [DependencyInjection] make YamlFileLoader raise a deprecation notice if a service definition contains unsupported keywords. --- .../Loader/YamlFileLoader.php | 46 +++++++++++++++++++ .../yaml/legacy_invalid_definition.yml | 10 ++++ .../Tests/Loader/YamlFileLoaderTest.php | 10 ++++ 3 files changed, 66 insertions(+) create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/legacy_invalid_definition.yml diff --git a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php index 7fb8c1751f..59f59b0b70 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php @@ -32,6 +32,30 @@ use Symfony\Component\ExpressionLanguage\Expression; */ class YamlFileLoader extends FileLoader { + private static $keywords = array( + 'alias' => 'alias', + 'parent' => 'parent', + 'class' => 'class', + 'shared' => 'shared', + 'synthetic' => 'synthetic', + 'lazy' => 'lazy', + 'public' => 'public', + 'abstract' => 'abstract', + 'deprecated' => 'deprecated', + 'factory' => 'factory', + 'file' => 'file', + 'arguments' => 'arguments', + 'properties' => 'properties', + 'configurator' => 'configurator', + 'calls' => 'calls', + 'tags' => 'tags', + 'decorates' => 'decorates', + 'decoration_inner_name' => 'decoration_inner_name', + 'decoration_priority' => 'decoration_priority', + 'autowire' => 'autowire', + 'autowiring_types' => 'autowiring_types', + ); + private $yamlParser; /** @@ -147,6 +171,8 @@ class YamlFileLoader extends FileLoader throw new InvalidArgumentException(sprintf('A service definition must be an array or a string starting with "@" but %s found for service "%s" in %s. Check your YAML syntax.', gettype($service), $id, $file)); } + static::checkDefinition($id, $service, $file); + if (isset($service['alias'])) { $public = !array_key_exists('public', $service) || (bool) $service['public']; $this->container->setAlias($id, new Alias($service['alias'], $public)); @@ -432,4 +458,24 @@ class YamlFileLoader extends FileLoader $this->container->loadFromExtension($namespace, $values); } } + + /** + * Checks the keywords used to define a service. + * + * @param string $id The service name + * @param array $definition The service definition to check + * @param string $file The loaded YAML file + */ + private static function checkDefinition($id, array $definition, $file) + { + foreach ($definition as $key => $value) { + if (!isset(static::$keywords[$key])) { + @trigger_error(sprintf('The configuration key "%s" is unsupported for service definition "%s" in "%s". Allowed configuration keys are "%s". The YamlFileLoader object will raise an exception instead in Symfony 4.0 when detecting an unsupported service configuration key.', $key, $id, $file, implode('", "', static::$keywords)), E_USER_DEPRECATED); + // @deprecated Uncomment the following statement in Symfony 4.0 + // and also update the corresponding unit test to make it expect + // an InvalidArgumentException exception. + //throw new InvalidArgumentException(sprintf('The configuration key "%s" is unsupported for service definition "%s" in "%s". Allowed configuration keys are "%s".', $key, $id, $file, implode('", "', static::$keywords))); + } + } + } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/legacy_invalid_definition.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/legacy_invalid_definition.yml new file mode 100644 index 0000000000..8487e854d4 --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/legacy_invalid_definition.yml @@ -0,0 +1,10 @@ +services: + # This definition is valid and should not raise any deprecation notice + foo: + class: stdClass + arguments: [ 'foo', 'bar' ] + + # This definition is invalid and must raise a deprecation notice + bar: + class: stdClass + private: true # the "private" keyword is invalid diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php index baa0cddd76..feca4d1fd4 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php @@ -293,4 +293,14 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase $this->assertTrue($container->getDefinition('bar_service')->isAutowired()); } + + /** + * @group legacy + */ + public function testServiceDefinitionContainsUnsupportedKeywords() + { + $container = new ContainerBuilder(); + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('legacy_invalid_definition.yml'); + } }