From cdc7446051a0e2c80bab68751f4ecd3d1c8420fd Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 1 Oct 2019 09:48:14 +0200 Subject: [PATCH] [DI] enable improved syntax for defining method calls in Yaml --- .../DependencyInjection/CHANGELOG.md | 1 + .../Loader/YamlFileLoader.php | 38 ++++++++++++++++--- .../Tests/Fixtures/yaml/alt_call.yaml | 5 +++ .../Tests/Loader/YamlFileLoaderTest.php | 15 ++++++++ 4 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/alt_call.yaml diff --git a/src/Symfony/Component/DependencyInjection/CHANGELOG.md b/src/Symfony/Component/DependencyInjection/CHANGELOG.md index 7171cb882d91..c90cfa747128 100644 --- a/src/Symfony/Component/DependencyInjection/CHANGELOG.md +++ b/src/Symfony/Component/DependencyInjection/CHANGELOG.md @@ -12,6 +12,7 @@ CHANGELOG * added support for binding iterable and tagged services * made singly-implemented interfaces detection be scoped by file * added ability to define a static priority method for tagged service + * added support for improved syntax to define method calls in Yaml 4.3.0 ----- diff --git a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php index 8a47fae60bc1..b219fcc80107 100644 --- a/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php +++ b/src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php @@ -459,20 +459,48 @@ private function parseDefinition(string $id, $service, string $file, array $defa throw new InvalidArgumentException(sprintf('Parameter "calls" must be an array for service "%s" in %s. Check your YAML syntax.', $id, $file)); } - foreach ($service['calls'] as $call) { + foreach ($service['calls'] as $k => $call) { + if (!\is_array($call) && (!\is_string($k) || !$call instanceof TaggedValue)) { + throw new InvalidArgumentException(sprintf('Invalid method call for service "%s": expected map or array, %s given in %s.', $id, $call instanceof TaggedValue ? '!'.$call->getTag() : \gettype($call), $file)); + } + + if (\is_string($k)) { + throw new InvalidArgumentException(sprintf('Invalid method call for service "%s", did you forgot a leading dash before "%s: ..." in %s?', $id, $k, $file)); + } + if (isset($call['method'])) { $method = $call['method']; - $args = isset($call['arguments']) ? $this->resolveServices($call['arguments'], $file) : []; + $args = $call['arguments'] ?? []; $returnsClone = $call['returns_clone'] ?? false; } else { - $method = $call[0]; - $args = isset($call[1]) ? $this->resolveServices($call[1], $file) : []; - $returnsClone = $call[2] ?? false; + if (1 === \count($call) && \is_string(key($call))) { + $method = key($call); + $args = $call[$method]; + + if ($args instanceof TaggedValue) { + if ('returns_clone' !== $args->getTag()) { + throw new InvalidArgumentException(sprintf('Unsupported tag "!%s", did you mean "!returns_clone" for service "%s" in %s?', $args->getTag(), $id, $file)); + } + + $returnsClone = true; + $args = $args->getValue(); + } else { + $returnsClone = false; + } + } elseif (empty($call[0])) { + throw new InvalidArgumentException(sprintf('Invalid call for service "%s": the method must be defined as the first index of an array or as the only key of a map in %s.', $id, $file)); + } else { + $method = $call[0]; + $args = $call[1] ?? []; + $returnsClone = $call[2] ?? false; + } } if (!\is_array($args)) { throw new InvalidArgumentException(sprintf('The second parameter for function call "%s" must be an array of its arguments for service "%s" in %s. Check your YAML syntax.', $method, $id, $file)); } + + $args = $this->resolveServices($args, $file); $definition->addMethodCall($method, $args, $returnsClone); } } diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/alt_call.yaml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/alt_call.yaml new file mode 100644 index 000000000000..26cf9e628c6f --- /dev/null +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/alt_call.yaml @@ -0,0 +1,5 @@ +services: + foo: + calls: + - foo: [1, 2, 3] + - bar: !returns_clone [1, 2, 3] diff --git a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php index 2e116132a35d..e01f41d139fe 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php +++ b/src/Symfony/Component/DependencyInjection/Tests/Loader/YamlFileLoaderTest.php @@ -900,4 +900,19 @@ public function testNotSinglyImplementedInterfacesInMultipleResourcesWithPreviou $this->assertSame(Prototype\SinglyImplementedInterface\Adapter\Adapter::class, (string) $alias); } + + public function testAlternativeMethodCalls() + { + $container = new ContainerBuilder(); + + $loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml')); + $loader->load('alt_call.yaml'); + + $expected = [ + ['foo', [1, 2, 3]], + ['bar', [1, 2, 3], true], + ]; + + $this->assertSame($expected, $container->getDefinition('foo')->getMethodCalls()); + } } pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy