[Config] Fix YamlReferenceDumper prototyped array support

This commit is contained in:
Maxime Steinhausser 2016-08-08 18:48:03 +02:00 committed by Maxime STEINHAUSSER
parent 5129c4cf7e
commit 063a98040c
5 changed files with 56 additions and 29 deletions

View File

@ -16,6 +16,7 @@ use Symfony\Component\Config\Definition\NodeInterface;
use Symfony\Component\Config\Definition\ArrayNode; use Symfony\Component\Config\Definition\ArrayNode;
use Symfony\Component\Config\Definition\EnumNode; use Symfony\Component\Config\Definition\EnumNode;
use Symfony\Component\Config\Definition\PrototypedArrayNode; use Symfony\Component\Config\Definition\PrototypedArrayNode;
use Symfony\Component\Config\Definition\ScalarNode;
use Symfony\Component\Yaml\Inline; use Symfony\Component\Yaml\Inline;
/** /**
@ -45,8 +46,9 @@ class YamlReferenceDumper
/** /**
* @param NodeInterface $node * @param NodeInterface $node
* @param int $depth * @param int $depth
* @param bool $prototypedArray
*/ */
private function writeNode(NodeInterface $node, $depth = 0) private function writeNode(NodeInterface $node, $depth = 0, $prototypedArray = false)
{ {
$comments = array(); $comments = array();
$default = ''; $default = '';
@ -59,29 +61,7 @@ class YamlReferenceDumper
$children = $node->getChildren(); $children = $node->getChildren();
if ($node instanceof PrototypedArrayNode) { if ($node instanceof PrototypedArrayNode) {
$prototype = $node->getPrototype(); $children = $this->getPrototypeChildren($node);
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);
}
} }
if (!$children) { if (!$children) {
@ -125,7 +105,8 @@ class YamlReferenceDumper
$default = (string) $default != '' ? ' '.$default : ''; $default = (string) $default != '' ? ' '.$default : '';
$comments = count($comments) ? '# '.implode(', ', $comments) : ''; $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()) { if ($info = $node->getInfo()) {
$this->writeLine(''); $this->writeLine('');
@ -159,7 +140,7 @@ class YamlReferenceDumper
if ($children) { if ($children) {
foreach ($children as $childNode) { foreach ($children as $childNode) {
$this->writeNode($childNode, $depth + 1); $this->writeNode($childNode, $depth + 1, $node instanceof PrototypedArrayNode && !$node->getKeyAttribute());
} }
} }
} }
@ -200,4 +181,38 @@ class YamlReferenceDumper
} }
} }
} }
/**
* @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);
}
} }

View File

@ -66,6 +66,9 @@ class XmlReferenceDumperTest extends \PHPUnit_Framework_TestCase
child3="" child3=""
/> />
<!-- prototype -->
<scalar-prototyped>scalar value</scalar-prototyped>
<!-- prototype: Parameter name --> <!-- prototype: Parameter name -->
<parameter name="parameter name">scalar value</parameter> <parameter name="parameter name">scalar value</parameter>

View File

@ -22,7 +22,6 @@ class YamlReferenceDumperTest extends \PHPUnit_Framework_TestCase
$dumper = new YamlReferenceDumper(); $dumper = new YamlReferenceDumper();
$this->markTestIncomplete('The Yaml Dumper currently does not support prototyped arrays');
$this->assertEquals($this->getConfigurationAsString(), $dumper->dump($configuration)); $this->assertEquals($this->getConfigurationAsString(), $dumper->dump($configuration));
} }
@ -32,7 +31,7 @@ class YamlReferenceDumperTest extends \PHPUnit_Framework_TestCase
acme_root: acme_root:
boolean: true boolean: true
scalar_empty: ~ scalar_empty: ~
scalar_null: ~ scalar_null: null
scalar_true: true scalar_true: true
scalar_false: false scalar_false: false
scalar_default: default scalar_default: default
@ -55,13 +54,17 @@ acme_root:
# multi-line info text # multi-line info text
# which should be indented # which should be indented
child3: ~ # Example: example setting child3: ~ # Example: example setting
scalar_prototyped: []
parameters: parameters:
# Prototype: Parameter name # Prototype: Parameter name
name: ~ name: ~
connections: connections:
# Prototype # Prototype
- { user: ~, pass: ~ } -
user: ~
pass: ~
EOL; EOL;
} }

View File

@ -52,6 +52,9 @@ class ExampleConfiguration implements ConfigurationInterface
->end() ->end()
->end() ->end()
->end() ->end()
->arrayNode('scalar_prototyped')
->prototype('scalar')->end()
->end()
->arrayNode('parameters') ->arrayNode('parameters')
->useAttributeAsKey('name') ->useAttributeAsKey('name')
->prototype('scalar')->info('Parameter name')->end() ->prototype('scalar')->info('Parameter name')->end()

View File

@ -19,6 +19,9 @@
"php": ">=5.5.9", "php": ">=5.5.9",
"symfony/filesystem": "~2.8|~3.0" "symfony/filesystem": "~2.8|~3.0"
}, },
"require-dev": {
"symfony/yaml": "~3.0"
},
"suggest": { "suggest": {
"symfony/yaml": "To use the yaml reference dumper" "symfony/yaml": "To use the yaml reference dumper"
}, },