bug #40603 [Config] Fixed support for nodes not extending BaseNode (Nyholm)
This PR was merged into the 4.4 branch.
Discussion
----------
[Config] Fixed support for nodes not extending BaseNode
| Q | A
| ------------- | ---
| Branch? | 4.4
| Bug fix? | yes
| New feature? | no
| Deprecations? | no
| Tickets |
| License | MIT
| Doc PR |
Too many times we assume that a `NodeInterface` extends `BaseNode`. This PR adds a small test with a new `CustomNodeDefinition` and `CustomNode` that implements `NodeInterface`.
Commits
-------
68276562c3
Fixed support for nodes not extending BaseNode
This commit is contained in:
commit
bd90627814
|
@ -68,7 +68,7 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
|
|||
/**
|
||||
* Retrieves the children of this node.
|
||||
*
|
||||
* @return array The children
|
||||
* @return array<string, NodeInterface>
|
||||
*/
|
||||
public function getChildren()
|
||||
{
|
||||
|
|
|
@ -127,7 +127,9 @@ abstract class NodeDefinition implements NodeParentInterface
|
|||
}
|
||||
|
||||
$node = $this->createNode();
|
||||
$node->setAttributes($this->attributes);
|
||||
if ($node instanceof BaseNode) {
|
||||
$node->setAttributes($this->attributes);
|
||||
}
|
||||
|
||||
return $node;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
namespace Symfony\Component\Config\Definition\Dumper;
|
||||
|
||||
use Symfony\Component\Config\Definition\ArrayNode;
|
||||
use Symfony\Component\Config\Definition\BaseNode;
|
||||
use Symfony\Component\Config\Definition\ConfigurationInterface;
|
||||
use Symfony\Component\Config\Definition\EnumNode;
|
||||
use Symfony\Component\Config\Definition\NodeInterface;
|
||||
|
@ -126,50 +127,52 @@ class XmlReferenceDumper
|
|||
|
||||
// get attributes and elements
|
||||
foreach ($children as $child) {
|
||||
if (!$child instanceof ArrayNode) {
|
||||
// get attributes
|
||||
|
||||
// metadata
|
||||
$name = str_replace('_', '-', $child->getName());
|
||||
$value = '%%%%not_defined%%%%'; // use a string which isn't used in the normal world
|
||||
|
||||
// comments
|
||||
$comments = [];
|
||||
if ($info = $child->getInfo()) {
|
||||
$comments[] = $info;
|
||||
}
|
||||
|
||||
if ($example = $child->getExample()) {
|
||||
$comments[] = 'Example: '.$example;
|
||||
}
|
||||
|
||||
if ($child->isRequired()) {
|
||||
$comments[] = 'Required';
|
||||
}
|
||||
|
||||
if ($child->isDeprecated()) {
|
||||
$comments[] = sprintf('Deprecated (%s)', $child->getDeprecationMessage($child->getName(), $node->getPath()));
|
||||
}
|
||||
|
||||
if ($child instanceof EnumNode) {
|
||||
$comments[] = 'One of '.implode('; ', array_map('json_encode', $child->getValues()));
|
||||
}
|
||||
|
||||
if (\count($comments)) {
|
||||
$rootAttributeComments[$name] = implode(";\n", $comments);
|
||||
}
|
||||
|
||||
// default values
|
||||
if ($child->hasDefaultValue()) {
|
||||
$value = $child->getDefaultValue();
|
||||
}
|
||||
|
||||
// append attribute
|
||||
$rootAttributes[$name] = $value;
|
||||
} else {
|
||||
if ($child instanceof ArrayNode) {
|
||||
// get elements
|
||||
$rootChildren[] = $child;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// get attributes
|
||||
|
||||
// metadata
|
||||
$name = str_replace('_', '-', $child->getName());
|
||||
$value = '%%%%not_defined%%%%'; // use a string which isn't used in the normal world
|
||||
|
||||
// comments
|
||||
$comments = [];
|
||||
if ($child instanceof BaseNode && $info = $child->getInfo()) {
|
||||
$comments[] = $info;
|
||||
}
|
||||
|
||||
if ($child instanceof BaseNode && $example = $child->getExample()) {
|
||||
$comments[] = 'Example: '.$example;
|
||||
}
|
||||
|
||||
if ($child->isRequired()) {
|
||||
$comments[] = 'Required';
|
||||
}
|
||||
|
||||
if ($child instanceof BaseNode && $child->isDeprecated()) {
|
||||
$comments[] = sprintf('Deprecated (%s)', $child->getDeprecationMessage($child->getName(), $node->getPath()));
|
||||
}
|
||||
|
||||
if ($child instanceof EnumNode) {
|
||||
$comments[] = 'One of '.implode('; ', array_map('json_encode', $child->getValues()));
|
||||
}
|
||||
|
||||
if (\count($comments)) {
|
||||
$rootAttributeComments[$name] = implode(";\n", $comments);
|
||||
}
|
||||
|
||||
// default values
|
||||
if ($child->hasDefaultValue()) {
|
||||
$value = $child->getDefaultValue();
|
||||
}
|
||||
|
||||
// append attribute
|
||||
$rootAttributes[$name] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
namespace Symfony\Component\Config\Definition\Dumper;
|
||||
|
||||
use Symfony\Component\Config\Definition\ArrayNode;
|
||||
use Symfony\Component\Config\Definition\BaseNode;
|
||||
use Symfony\Component\Config\Definition\ConfigurationInterface;
|
||||
use Symfony\Component\Config\Definition\EnumNode;
|
||||
use Symfony\Component\Config\Definition\NodeInterface;
|
||||
|
@ -76,7 +77,10 @@ class YamlReferenceDumper
|
|||
$default = '';
|
||||
$defaultArray = null;
|
||||
$children = null;
|
||||
$example = $node->getExample();
|
||||
$example = null;
|
||||
if ($node instanceof BaseNode) {
|
||||
$example = $node->getExample();
|
||||
}
|
||||
|
||||
// defaults
|
||||
if ($node instanceof ArrayNode) {
|
||||
|
@ -123,7 +127,7 @@ class YamlReferenceDumper
|
|||
}
|
||||
|
||||
// deprecated?
|
||||
if ($node->isDeprecated()) {
|
||||
if ($node instanceof BaseNode && $node->isDeprecated()) {
|
||||
$comments[] = sprintf('Deprecated (%s)', $node->getDeprecationMessage($node->getName(), $parentNode ? $parentNode->getPath() : $node->getPath()));
|
||||
}
|
||||
|
||||
|
@ -138,7 +142,7 @@ class YamlReferenceDumper
|
|||
$key = $prototypedArray ? '-' : $node->getName().':';
|
||||
$text = rtrim(sprintf('%-21s%s %s', $key, $default, $comments), ' ');
|
||||
|
||||
if ($info = $node->getInfo()) {
|
||||
if ($node instanceof BaseNode && $info = $node->getInfo()) {
|
||||
$this->writeLine('');
|
||||
// indenting multi-line info
|
||||
$info = str_replace("\n", sprintf("\n%".($depth * 4).'s# ', ' '), $info);
|
||||
|
|
|
@ -57,6 +57,7 @@ class XmlReferenceDumperTest extends TestCase
|
|||
node-with-a-looong-name=""
|
||||
enum-with-default="this"
|
||||
enum=""
|
||||
custom-node="true"
|
||||
>
|
||||
|
||||
<!-- some info -->
|
||||
|
|
|
@ -137,6 +137,7 @@ acme_root:
|
|||
|
||||
# Prototype
|
||||
name: []
|
||||
custom_node: true
|
||||
|
||||
EOL;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Symfony\Component\Config\Tests\Fixtures\Configuration;
|
||||
|
||||
use Symfony\Component\Config\Definition\NodeInterface;
|
||||
|
||||
class CustomNode implements NodeInterface
|
||||
{
|
||||
public function getName()
|
||||
{
|
||||
return 'custom_node';
|
||||
}
|
||||
|
||||
public function getPath()
|
||||
{
|
||||
return 'custom';
|
||||
}
|
||||
|
||||
public function isRequired()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function hasDefaultValue()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getDefaultValue()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function normalize($value)
|
||||
{
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function merge($leftSide, $rightSide)
|
||||
{
|
||||
return array_merge($leftSide, $rightSide);
|
||||
}
|
||||
|
||||
public function finalize($value)
|
||||
{
|
||||
return $value;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Symfony\Component\Config\Tests\Fixtures\Configuration;
|
||||
|
||||
use Symfony\Component\Config\Definition\Builder\NodeDefinition;
|
||||
|
||||
class CustomNodeDefinition extends NodeDefinition
|
||||
{
|
||||
protected function createNode()
|
||||
{
|
||||
return new CustomNode();
|
||||
}
|
||||
}
|
|
@ -93,6 +93,7 @@ class ExampleConfiguration implements ConfigurationInterface
|
|||
->end()
|
||||
->end()
|
||||
->end()
|
||||
->append(new CustomNodeDefinition('acme'))
|
||||
->end()
|
||||
;
|
||||
|
||||
|
|
Reference in New Issue