From 063a98040cca33ffb890617fe86c279a5cb24c87 Mon Sep 17 00:00:00 2001 From: Maxime Steinhausser Date: Mon, 8 Aug 2016 18:48:03 +0200 Subject: [PATCH] [Config] Fix YamlReferenceDumper prototyped array support --- .../Definition/Dumper/YamlReferenceDumper.php | 67 ++++++++++++------- .../Dumper/XmlReferenceDumperTest.php | 3 + .../Dumper/YamlReferenceDumperTest.php | 9 ++- .../Configuration/ExampleConfiguration.php | 3 + src/Symfony/Component/Config/composer.json | 3 + 5 files changed, 56 insertions(+), 29 deletions(-) diff --git a/src/Symfony/Component/Config/Definition/Dumper/YamlReferenceDumper.php b/src/Symfony/Component/Config/Definition/Dumper/YamlReferenceDumper.php index d38e6ebeff82..9d00a898709b 100644 --- a/src/Symfony/Component/Config/Definition/Dumper/YamlReferenceDumper.php +++ b/src/Symfony/Component/Config/Definition/Dumper/YamlReferenceDumper.php @@ -16,6 +16,7 @@ use Symfony\Component\Config\Definition\ArrayNode; use Symfony\Component\Config\Definition\EnumNode; use Symfony\Component\Config\Definition\PrototypedArrayNode; +use Symfony\Component\Config\Definition\ScalarNode; use Symfony\Component\Yaml\Inline; /** @@ -45,8 +46,9 @@ public function dumpNode(NodeInterface $node) /** * @param NodeInterface $node * @param int $depth + * @param bool $prototypedArray */ - private function writeNode(NodeInterface $node, $depth = 0) + private function writeNode(NodeInterface $node, $depth = 0, $prototypedArray = false) { $comments = array(); $default = ''; @@ -59,29 +61,7 @@ private function writeNode(NodeInterface $node, $depth = 0) $children = $node->getChildren(); if ($node instanceof PrototypedArrayNode) { - $prototype = $node->getPrototype(); - - if ($prototype instanceof ArrayNode) { - $children = $prototype->getChildren(); - } - - // check for attribute as key - if ($key = $node->getKeyAttribute()) { - $keyNodeClass = 'Symfony\Component\Config\Definition\\'.($prototype instanceof ArrayNode ? 'ArrayNode' : 'ScalarNode'); - $keyNode = new $keyNodeClass($key, $node); - - $info = 'Prototype'; - if (null !== $prototype->getInfo()) { - $info .= ': '.$prototype->getInfo(); - } - $keyNode->setInfo($info); - - // add children - foreach ($children as $childNode) { - $keyNode->addChild($childNode); - } - $children = array($key => $keyNode); - } + $children = $this->getPrototypeChildren($node); } if (!$children) { @@ -125,7 +105,8 @@ private function writeNode(NodeInterface $node, $depth = 0) $default = (string) $default != '' ? ' '.$default : ''; $comments = count($comments) ? '# '.implode(', ', $comments) : ''; - $text = rtrim(sprintf('%-20s %s %s', $node->getName().':', $default, $comments), ' '); + $key = $prototypedArray ? '-' : $node->getName().':'; + $text = rtrim(sprintf('%-20s %s %s', $key, $default, $comments), ' '); if ($info = $node->getInfo()) { $this->writeLine(''); @@ -159,7 +140,7 @@ private function writeNode(NodeInterface $node, $depth = 0) if ($children) { foreach ($children as $childNode) { - $this->writeNode($childNode, $depth + 1); + $this->writeNode($childNode, $depth + 1, $node instanceof PrototypedArrayNode && !$node->getKeyAttribute()); } } } @@ -200,4 +181,38 @@ private function writeArray(array $array, $depth) } } } + + /** + * @param PrototypedArrayNode $node + * + * @return array + */ + private function getPrototypeChildren(PrototypedArrayNode $node) + { + $prototype = $node->getPrototype(); + $key = $node->getKeyAttribute(); + + // Do not expand prototype if it isn't an array node nor uses attribute as key + if (!$key && !$prototype instanceof ArrayNode) { + return $node->getChildren(); + } + + if ($prototype instanceof ArrayNode) { + $keyNode = new ArrayNode($key, $node); + // add children + foreach ($prototype->getChildren() as $childNode) { + $keyNode->addChild($childNode); + } + } else { + $keyNode = new ScalarNode($key, $node); + } + + $info = 'Prototype'; + if (null !== $prototype->getInfo()) { + $info .= ': '.$prototype->getInfo(); + } + $keyNode->setInfo($info); + + return array($key => $keyNode); + } } diff --git a/src/Symfony/Component/Config/Tests/Definition/Dumper/XmlReferenceDumperTest.php b/src/Symfony/Component/Config/Tests/Definition/Dumper/XmlReferenceDumperTest.php index 6d9d52dd3a25..de7b6324936b 100644 --- a/src/Symfony/Component/Config/Tests/Definition/Dumper/XmlReferenceDumperTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/Dumper/XmlReferenceDumperTest.php @@ -66,6 +66,9 @@ enum="" child3="" /> + + scalar value + scalar value diff --git a/src/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php b/src/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php index 28d0cd6ad2e6..efc608d9b9b7 100644 --- a/src/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php @@ -22,7 +22,6 @@ public function testDumper() $dumper = new YamlReferenceDumper(); - $this->markTestIncomplete('The Yaml Dumper currently does not support prototyped arrays'); $this->assertEquals($this->getConfigurationAsString(), $dumper->dump($configuration)); } @@ -32,7 +31,7 @@ private function getConfigurationAsString() acme_root: boolean: true scalar_empty: ~ - scalar_null: ~ + scalar_null: null scalar_true: true scalar_false: false scalar_default: default @@ -55,13 +54,17 @@ enum: ~ # One of "this"; "that" # multi-line info text # which should be indented child3: ~ # Example: example setting + scalar_prototyped: [] parameters: # Prototype: Parameter name name: ~ connections: + # Prototype - - { user: ~, pass: ~ } + - + user: ~ + pass: ~ EOL; } diff --git a/src/Symfony/Component/Config/Tests/Fixtures/Configuration/ExampleConfiguration.php b/src/Symfony/Component/Config/Tests/Fixtures/Configuration/ExampleConfiguration.php index 7125dc491e72..87d40430a3b8 100644 --- a/src/Symfony/Component/Config/Tests/Fixtures/Configuration/ExampleConfiguration.php +++ b/src/Symfony/Component/Config/Tests/Fixtures/Configuration/ExampleConfiguration.php @@ -52,6 +52,9 @@ public function getConfigTreeBuilder() ->end() ->end() ->end() + ->arrayNode('scalar_prototyped') + ->prototype('scalar')->end() + ->end() ->arrayNode('parameters') ->useAttributeAsKey('name') ->prototype('scalar')->info('Parameter name')->end() diff --git a/src/Symfony/Component/Config/composer.json b/src/Symfony/Component/Config/composer.json index 3631f4f16624..2de34d92e937 100644 --- a/src/Symfony/Component/Config/composer.json +++ b/src/Symfony/Component/Config/composer.json @@ -19,6 +19,9 @@ "php": ">=5.5.9", "symfony/filesystem": "~2.8|~3.0" }, + "require-dev": { + "symfony/yaml": "~3.0" + }, "suggest": { "symfony/yaml": "To use the yaml reference dumper" },