Augmentation vers version 3.3.0

This commit is contained in:
Gauvain Boiché
2020-03-31 15:31:03 +02:00
parent d926806907
commit a1864c0414
2618 changed files with 406015 additions and 31377 deletions

View File

@@ -22,8 +22,8 @@ use Symfony\Component\Config\Definition\Exception\UnsetKeyException;
*/
class ArrayNode extends BaseNode implements PrototypeNodeInterface
{
protected $xmlRemappings = array();
protected $children = array();
protected $xmlRemappings = [];
protected $children = [];
protected $allowFalse = false;
protected $allowNewKeys = true;
protected $addIfNotSet = false;
@@ -38,17 +38,13 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
}
/**
* Normalizes keys between the different configuration formats.
* {@inheritdoc}
*
* Namely, you mostly have foo_bar in YAML while you have foo-bar in XML.
* After running this method, all keys are normalized to foo_bar.
*
* If you have a mixed key like foo-bar_moo, it will not be altered.
* The key will also not be altered if the target key already exists.
*
* @param mixed $value
*
* @return array The value with normalized keys
*/
protected function preNormalize($value)
{
@@ -56,10 +52,10 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
return $value;
}
$normalized = array();
$normalized = [];
foreach ($value as $k => $v) {
if (false !== strpos($k, '-') && false === strpos($k, '_') && !array_key_exists($normalizedKey = str_replace('-', '_', $k), $value)) {
if (false !== strpos($k, '-') && false === strpos($k, '_') && !\array_key_exists($normalizedKey = str_replace('-', '_', $k), $value)) {
$normalized[$normalizedKey] = $v;
} else {
$normalized[$k] = $v;
@@ -82,7 +78,7 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
/**
* Sets the xml remappings that should be performed.
*
* @param array $remappings An array of the form array(array(string, string))
* @param array $remappings An array of the form [[string, string]]
*/
public function setXmlRemappings(array $remappings)
{
@@ -92,7 +88,7 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
/**
* Gets the xml remappings that should be performed.
*
* @return array an array of the form array(array(string, string))
* @return array an array of the form [[string, string]]
*/
public function getXmlRemappings()
{
@@ -141,7 +137,7 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
}
/**
* Whether extra keys should just be ignore without an exception.
* Whether extra keys should just be ignored without an exception.
*
* @param bool $boolean To allow extra keys
* @param bool $remove To remove extra keys
@@ -177,7 +173,7 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
throw new \RuntimeException(sprintf('The node at path "%s" has no default value.', $this->getPath()));
}
$defaults = array();
$defaults = [];
foreach ($this->children as $name => $child) {
if ($child->hasDefaultValue()) {
$defaults[$name] = $child->getDefaultValue();
@@ -223,7 +219,7 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
}
foreach ($this->children as $name => $child) {
if (!array_key_exists($name, $value)) {
if (!\array_key_exists($name, $value)) {
if ($child->isRequired()) {
$ex = new InvalidConfigurationException(sprintf('The child node "%s" at path "%s" must be configured.', $name, $this->getPath()));
$ex->setPath($this->getPath());
@@ -238,6 +234,10 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
continue;
}
if ($child->isDeprecated()) {
@trigger_error($child->getDeprecationMessage($name, $this->getPath()), E_USER_DEPRECATED);
}
try {
$value[$name] = $child->finalize($value[$name]);
} catch (UnsetKeyException $e) {
@@ -285,7 +285,7 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
$value = $this->remapXml($value);
$normalized = array();
$normalized = [];
foreach ($value as $name => $val) {
if (isset($this->children[$name])) {
try {
@@ -318,9 +318,7 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
*/
protected function remapXml($value)
{
foreach ($this->xmlRemappings as $transformation) {
list($singular, $plural) = $transformation;
foreach ($this->xmlRemappings as list($singular, $plural)) {
if (!isset($value[$singular])) {
continue;
}
@@ -357,7 +355,7 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
foreach ($rightSide as $k => $v) {
// no conflict
if (!array_key_exists($k, $leftSide)) {
if (!\array_key_exists($k, $leftSide)) {
if (!$this->allowNewKeys) {
$ex = new InvalidConfigurationException(sprintf('You are not allowed to define new elements for path "%s". Please define all elements for this path in one config file. If you are trying to overwrite an element, make sure you redefine it with the same name.', $this->getPath()));
$ex->setPath($this->getPath());

View File

@@ -25,12 +25,13 @@ abstract class BaseNode implements NodeInterface
{
protected $name;
protected $parent;
protected $normalizationClosures = array();
protected $finalValidationClosures = array();
protected $normalizationClosures = [];
protected $finalValidationClosures = [];
protected $allowOverwrite = true;
protected $required = false;
protected $equivalentValues = array();
protected $attributes = array();
protected $deprecationMessage = null;
protected $equivalentValues = [];
protected $attributes = [];
/**
* @param string|null $name The name of the node
@@ -48,21 +49,37 @@ abstract class BaseNode implements NodeInterface
$this->parent = $parent;
}
/**
* @param string $key
*/
public function setAttribute($key, $value)
{
$this->attributes[$key] = $value;
}
/**
* @param string $key
*
* @return mixed
*/
public function getAttribute($key, $default = null)
{
return isset($this->attributes[$key]) ? $this->attributes[$key] : $default;
}
/**
* @param string $key
*
* @return bool
*/
public function hasAttribute($key)
{
return isset($this->attributes[$key]);
}
/**
* @return array
*/
public function getAttributes()
{
return $this->attributes;
@@ -73,6 +90,9 @@ abstract class BaseNode implements NodeInterface
$this->attributes = $attributes;
}
/**
* @param string $key
*/
public function removeAttribute($key)
{
unset($this->attributes[$key]);
@@ -91,7 +111,7 @@ abstract class BaseNode implements NodeInterface
/**
* Returns info message.
*
* @return string The info text
* @return string|null The info text
*/
public function getInfo()
{
@@ -111,7 +131,7 @@ abstract class BaseNode implements NodeInterface
/**
* Retrieves the example configuration for this node.
*
* @return string|array The example
* @return string|array|null The example
*/
public function getExample()
{
@@ -126,7 +146,7 @@ abstract class BaseNode implements NodeInterface
*/
public function addEquivalentValue($originalValue, $equivalentValue)
{
$this->equivalentValues[] = array($originalValue, $equivalentValue);
$this->equivalentValues[] = [$originalValue, $equivalentValue];
}
/**
@@ -139,6 +159,19 @@ abstract class BaseNode implements NodeInterface
$this->required = (bool) $boolean;
}
/**
* Sets this node as deprecated.
*
* You can use %node% and %path% placeholders in your message to display,
* respectively, the node name and its complete path.
*
* @param string|null $message Deprecated message
*/
public function setDeprecated($message)
{
$this->deprecationMessage = $message;
}
/**
* Sets if this node can be overridden.
*
@@ -177,6 +210,29 @@ abstract class BaseNode implements NodeInterface
return $this->required;
}
/**
* Checks if this node is deprecated.
*
* @return bool
*/
public function isDeprecated()
{
return null !== $this->deprecationMessage;
}
/**
* Returns the deprecated message.
*
* @param string $node the configuration node name
* @param string $path the path of the node
*
* @return string
*/
public function getDeprecationMessage($node, $path)
{
return strtr($this->deprecationMessage, ['%node%' => $node, '%path%' => $path]);
}
/**
* {@inheritdoc}
*/
@@ -243,9 +299,9 @@ abstract class BaseNode implements NodeInterface
/**
* Normalizes the value before any other normalization is applied.
*
* @param $value
* @param mixed $value
*
* @return The normalized array value
* @return mixed The normalized array value
*/
protected function preNormalize($value)
{

View File

@@ -25,7 +25,7 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
protected $performDeepMerging = true;
protected $ignoreExtraKeys = false;
protected $removeExtraKeys = true;
protected $children = array();
protected $children = [];
protected $prototype;
protected $atLeastOne = false;
protected $allowNewKeys = true;
@@ -43,8 +43,8 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
{
parent::__construct($name, $parent);
$this->nullEquivalent = array();
$this->trueEquivalent = array();
$this->nullEquivalent = [];
$this->trueEquivalent = [];
}
/**
@@ -75,6 +75,62 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
return $this->prototype = $this->getNodeBuilder()->node(null, $type)->setParent($this);
}
/**
* @return VariableNodeDefinition
*/
public function variablePrototype()
{
return $this->prototype('variable');
}
/**
* @return ScalarNodeDefinition
*/
public function scalarPrototype()
{
return $this->prototype('scalar');
}
/**
* @return BooleanNodeDefinition
*/
public function booleanPrototype()
{
return $this->prototype('boolean');
}
/**
* @return IntegerNodeDefinition
*/
public function integerPrototype()
{
return $this->prototype('integer');
}
/**
* @return FloatNodeDefinition
*/
public function floatPrototype()
{
return $this->prototype('float');
}
/**
* @return ArrayNodeDefinition
*/
public function arrayPrototype()
{
return $this->prototype('array');
}
/**
* @return EnumNodeDefinition
*/
public function enumPrototype()
{
return $this->prototype('enum');
}
/**
* Adds the default value if the node is not set in the configuration.
*
@@ -158,15 +214,15 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
* to be the key of the particular item. For example, if "id" is the
* "key", then:
*
* array(
* array('id' => 'my_name', 'foo' => 'bar'),
* );
* [
* ['id' => 'my_name', 'foo' => 'bar'],
* ];
*
* becomes
*
* array(
* 'my_name' => array('foo' => 'bar'),
* );
* [
* 'my_name' => ['foo' => 'bar'],
* ];
*
* If you'd like "'id' => 'my_name'" to still be present in the resulting
* array, then you can set the second argument of this method to false.
@@ -219,9 +275,9 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
{
$this
->addDefaultsIfNotSet()
->treatFalseLike(array('enabled' => false))
->treatTrueLike(array('enabled' => true))
->treatNullLike(array('enabled' => true))
->treatFalseLike(['enabled' => false])
->treatTrueLike(['enabled' => true])
->treatNullLike(['enabled' => true])
->beforeNormalization()
->ifArray()
->then(function ($v) {
@@ -249,9 +305,9 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
{
$this
->addDefaultsIfNotSet()
->treatFalseLike(array('enabled' => false))
->treatTrueLike(array('enabled' => true))
->treatNullLike(array('enabled' => true))
->treatFalseLike(['enabled' => false])
->treatTrueLike(['enabled' => true])
->treatNullLike(['enabled' => true])
->children()
->booleanNode('enabled')
->defaultTrue()
@@ -276,10 +332,10 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
* Allows extra config keys to be specified under an array without
* throwing an exception.
*
* Those config values are simply ignored and removed from the
* resulting array. This should be used only in special cases where
* you want to send an entire configuration array through a special
* tree that processes only part of the array.
* Those config values are ignored and removed from the resulting
* array. This should be used only in special cases where you want
* to send an entire configuration array through a special tree that
* processes only part of the array.
*
* @param bool $remove Whether to remove the extra keys
*
@@ -356,6 +412,10 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
$node->setKeyAttribute($this->key, $this->removeKeyItem);
}
if (false === $this->allowEmptyValue) {
@trigger_error(sprintf('Using %s::cannotBeEmpty() at path "%s" has no effect, consider requiresAtLeastOneElement() instead. In 4.0 both methods will behave the same.', __CLASS__, $node->getPath()), E_USER_DEPRECATED);
}
if (true === $this->atLeastOne) {
$node->setMinNumberOfElements(1);
}
@@ -381,6 +441,7 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
$node->addEquivalentValue(false, $this->falseEquivalent);
$node->setPerformDeepMerging($this->performDeepMerging);
$node->setRequired($this->required);
$node->setDeprecated($this->deprecationMessage);
$node->setIgnoreExtraKeys($this->ignoreExtraKeys, $this->removeExtraKeys);
$node->setNormalizeKeys($this->normalizeKeys);
@@ -414,6 +475,10 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition
throw new InvalidDefinitionException(sprintf('->useAttributeAsKey() is not applicable to concrete nodes at path "%s"', $path));
}
if (false === $this->allowEmptyValue) {
@trigger_error(sprintf('->cannotBeEmpty() is not applicable to concrete nodes at path "%s". In 4.0 it will throw an exception.', $path), E_USER_DEPRECATED);
}
if (true === $this->atLeastOne) {
throw new InvalidDefinitionException(sprintf('->requiresAtLeastOneElement() is not applicable to concrete nodes at path "%s"', $path));
}

View File

@@ -12,6 +12,7 @@
namespace Symfony\Component\Config\Definition\Builder;
use Symfony\Component\Config\Definition\BooleanNode;
use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException;
/**
* This class provides a fluent interface for defining a node.
@@ -30,18 +31,6 @@ class BooleanNodeDefinition extends ScalarNodeDefinition
$this->nullEquivalent = true;
}
/**
* {@inheritdoc}
*
* @deprecated Deprecated since version 2.8, to be removed in 3.0.
*/
public function cannotBeEmpty()
{
@trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
return parent::cannotBeEmpty();
}
/**
* Instantiate a Node.
*
@@ -51,4 +40,14 @@ class BooleanNodeDefinition extends ScalarNodeDefinition
{
return new BooleanNode($this->name, $this->parent);
}
/**
* {@inheritdoc}
*
* @throws InvalidDefinitionException
*/
public function cannotBeEmpty()
{
throw new InvalidDefinitionException('->cannotBeEmpty() is not applicable to BooleanNodeDefinition.');
}
}

View File

@@ -88,6 +88,18 @@ class ExprBuilder
return $this;
}
/**
* Tests if the value is empty.
*
* @return ExprBuilder
*/
public function ifEmpty()
{
$this->ifPart = function ($v) { return empty($v); };
return $this;
}
/**
* Tests if the value is an array.
*
@@ -124,6 +136,19 @@ class ExprBuilder
return $this;
}
/**
* Transforms variables of any type into an array.
*
* @return $this
*/
public function castToArray()
{
$this->ifPart = function ($v) { return !\is_array($v); };
$this->thenPart = function ($v) { return [$v]; };
return $this;
}
/**
* Sets the closure to run if the test pass.
*
@@ -143,7 +168,7 @@ class ExprBuilder
*/
public function thenEmptyArray()
{
$this->thenPart = function ($v) { return array(); };
$this->thenPart = function ($v) { return []; };
return $this;
}

View File

@@ -23,7 +23,7 @@ class NodeBuilder implements NodeParentInterface
public function __construct()
{
$this->nodeMapping = array(
$this->nodeMapping = [
'variable' => __NAMESPACE__.'\\VariableNodeDefinition',
'scalar' => __NAMESPACE__.'\\ScalarNodeDefinition',
'boolean' => __NAMESPACE__.'\\BooleanNodeDefinition',
@@ -31,7 +31,7 @@ class NodeBuilder implements NodeParentInterface
'float' => __NAMESPACE__.'\\FloatNodeDefinition',
'array' => __NAMESPACE__.'\\ArrayNodeDefinition',
'enum' => __NAMESPACE__.'\\EnumNodeDefinition',
);
];
}
/**

View File

@@ -27,13 +27,14 @@ abstract class NodeDefinition implements NodeParentInterface
protected $defaultValue;
protected $default = false;
protected $required = false;
protected $deprecationMessage = null;
protected $merge;
protected $allowEmptyValue = true;
protected $nullEquivalent;
protected $trueEquivalent = true;
protected $falseEquivalent = false;
protected $parent;
protected $attributes = array();
protected $attributes = [];
/**
* @param string|null $name The name of the node
@@ -160,6 +161,23 @@ abstract class NodeDefinition implements NodeParentInterface
return $this;
}
/**
* Sets the node as deprecated.
*
* You can use %node% and %path% placeholders in your message to display,
* respectively, the node name and its complete path.
*
* @param string $message Deprecation message
*
* @return $this
*/
public function setDeprecated($message = 'The child node "%node%" at path "%path%" is deprecated.')
{
$this->deprecationMessage = $message;
return $this;
}
/**
* Sets the equivalent value used when the node contains null.
*

View File

@@ -19,8 +19,8 @@ namespace Symfony\Component\Config\Definition\Builder;
class NormalizationBuilder
{
protected $node;
public $before = array();
public $remappings = array();
public $before = [];
public $remappings = [];
public function __construct(NodeDefinition $node)
{
@@ -37,7 +37,7 @@ class NormalizationBuilder
*/
public function remap($key, $plural = null)
{
$this->remappings[] = array($key, null === $plural ? $key.'s' : $plural);
$this->remappings[] = [$key, null === $plural ? $key.'s' : $plural];
return $this;
}

View File

@@ -11,6 +11,8 @@
namespace Symfony\Component\Config\Definition\Builder;
use Symfony\Component\Config\Definition\Exception\InvalidDefinitionException;
/**
* Abstract class that contains common code of integer and float node definitions.
*
@@ -62,12 +64,10 @@ abstract class NumericNodeDefinition extends ScalarNodeDefinition
/**
* {@inheritdoc}
*
* @deprecated Deprecated since version 2.8, to be removed in 3.0.
* @throws InvalidDefinitionException
*/
public function cannotBeEmpty()
{
@trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
return parent::cannotBeEmpty();
throw new InvalidDefinitionException('->cannotBeEmpty() is not applicable to NumericNodeDefinition.');
}
}

View File

@@ -22,6 +22,10 @@ class TreeBuilder implements NodeParentInterface
{
protected $tree;
protected $root;
/**
* @deprecated since 3.4. To be removed in 4.0
*/
protected $builder;
/**

View File

@@ -19,7 +19,7 @@ namespace Symfony\Component\Config\Definition\Builder;
class ValidationBuilder
{
protected $node;
public $rules = array();
public $rules = [];
public function __construct(NodeDefinition $node)
{

View File

@@ -54,6 +54,7 @@ class VariableNodeDefinition extends NodeDefinition
$node->addEquivalentValue(true, $this->trueEquivalent);
$node->addEquivalentValue(false, $this->falseEquivalent);
$node->setRequired($this->required);
$node->setDeprecated($this->deprecationMessage);
if (null !== $this->validation) {
$node->setFinalValidationClosures($this->validation->rules);

View File

@@ -42,10 +42,9 @@ class XmlReferenceDumper
}
/**
* @param NodeInterface $node
* @param int $depth
* @param bool $root If the node is the root node
* @param string $namespace The namespace of the node
* @param int $depth
* @param bool $root If the node is the root node
* @param string $namespace The namespace of the node
*/
private function writeNode(NodeInterface $node, $depth = 0, $root = false, $namespace = null)
{
@@ -65,10 +64,10 @@ class XmlReferenceDumper
}
$rootName = str_replace('_', '-', $rootName);
$rootAttributes = array();
$rootAttributeComments = array();
$rootChildren = array();
$rootComments = array();
$rootAttributes = [];
$rootAttributeComments = [];
$rootChildren = [];
$rootComments = [];
if ($node instanceof ArrayNode) {
$children = $node->getChildren();
@@ -96,7 +95,10 @@ class XmlReferenceDumper
$rootAttributes[$key] = str_replace('-', ' ', $rootName).' '.$key;
}
if ($prototype instanceof ArrayNode) {
if ($prototype instanceof PrototypedArrayNode) {
$prototype->setName($key);
$children = [$key => $prototype];
} elseif ($prototype instanceof ArrayNode) {
$children = $prototype->getChildren();
} else {
if ($prototype->hasDefaultValue()) {
@@ -137,7 +139,7 @@ class XmlReferenceDumper
$value = '%%%%not_defined%%%%'; // use a string which isn't used in the normal world
// comments
$comments = array();
$comments = [];
if ($info = $child->getInfo()) {
$comments[] = $info;
}
@@ -150,6 +152,10 @@ class XmlReferenceDumper
$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()));
}
@@ -300,5 +306,7 @@ class XmlReferenceDumper
if (\is_array($value)) {
return implode(',', $value);
}
return '';
}
}

View File

@@ -16,6 +16,7 @@ use Symfony\Component\Config\Definition\ConfigurationInterface;
use Symfony\Component\Config\Definition\EnumNode;
use Symfony\Component\Config\Definition\NodeInterface;
use Symfony\Component\Config\Definition\PrototypedArrayNode;
use Symfony\Component\Config\Definition\ScalarNode;
use Symfony\Component\Yaml\Inline;
/**
@@ -32,6 +33,32 @@ class YamlReferenceDumper
return $this->dumpNode($configuration->getConfigTreeBuilder()->buildTree());
}
public function dumpAtPath(ConfigurationInterface $configuration, $path)
{
$rootNode = $node = $configuration->getConfigTreeBuilder()->buildTree();
foreach (explode('.', $path) as $step) {
if (!$node instanceof ArrayNode) {
throw new \UnexpectedValueException(sprintf('Unable to find node at path "%s.%s"', $rootNode->getName(), $path));
}
/** @var NodeInterface[] $children */
$children = $node instanceof PrototypedArrayNode ? $this->getPrototypeChildren($node) : $node->getChildren();
foreach ($children as $child) {
if ($child->getName() === $step) {
$node = $child;
continue 2;
}
}
throw new \UnexpectedValueException(sprintf('Unable to find node at path "%s.%s"', $rootNode->getName(), $path));
}
return $this->dumpNode($node);
}
public function dumpNode(NodeInterface $node)
{
$this->reference = '';
@@ -43,12 +70,12 @@ class YamlReferenceDumper
}
/**
* @param NodeInterface $node
* @param int $depth
* @param int $depth
* @param bool $prototypedArray
*/
private function writeNode(NodeInterface $node, $depth = 0)
private function writeNode(NodeInterface $node, NodeInterface $parentNode = null, $depth = 0, $prototypedArray = false)
{
$comments = array();
$comments = [];
$default = '';
$defaultArray = null;
$children = null;
@@ -59,29 +86,7 @@ class YamlReferenceDumper
$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) {
@@ -117,6 +122,11 @@ class YamlReferenceDumper
$comments[] = 'Required';
}
// deprecated?
if ($node->isDeprecated()) {
$comments[] = sprintf('Deprecated (%s)', $node->getDeprecationMessage($node->getName(), $parentNode ? $parentNode->getPath() : $node->getPath()));
}
// example
if ($example && !\is_array($example)) {
$comments[] = 'Example: '.$example;
@@ -125,7 +135,8 @@ class YamlReferenceDumper
$default = '' != (string) $default ? ' '.$default : '';
$comments = \count($comments) ? '# '.implode(', ', $comments) : '';
$text = rtrim(sprintf('%-21s%s %s', $node->getName().':', $default, $comments), ' ');
$key = $prototypedArray ? '-' : $node->getName().':';
$text = rtrim(sprintf('%-21s%s %s', $key, $default, $comments), ' ');
if ($info = $node->getInfo()) {
$this->writeLine('');
@@ -159,7 +170,7 @@ class YamlReferenceDumper
if ($children) {
foreach ($children as $childNode) {
$this->writeNode($childNode, $depth + 1);
$this->writeNode($childNode, $node, $depth + 1, $node instanceof PrototypedArrayNode && !$node->getKeyAttribute());
}
}
}
@@ -200,4 +211,42 @@ class YamlReferenceDumper
}
}
}
/**
* @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);
$children = $prototype->getChildren();
if ($prototype instanceof PrototypedArrayNode && $prototype->getKeyAttribute()) {
$children = $this->getPrototypeChildren($prototype);
}
// add children
foreach ($children as $childNode) {
$keyNode->addChild($childNode);
}
} else {
$keyNode = new ScalarNode($key, $node);
}
$info = 'Prototype';
if (null !== $prototype->getInfo()) {
$info .= ': '.$prototype->getInfo();
}
$keyNode->setInfo($info);
return [$key => $keyNode];
}
}

View File

@@ -22,7 +22,7 @@ class EnumNode extends ScalarNode
{
private $values;
public function __construct($name, NodeInterface $parent = null, array $values = array())
public function __construct($name, NodeInterface $parent = null, array $values = [])
{
$values = array_unique($values);
if (empty($values)) {

View File

@@ -28,7 +28,7 @@ class Processor
*/
public function process(NodeInterface $configTree, array $configs)
{
$currentConfig = array();
$currentConfig = [];
foreach ($configs as $config) {
$config = $configTree->normalize($config);
$currentConfig = $configTree->merge($currentConfig, $config);
@@ -86,12 +86,12 @@ class Processor
if (isset($config[$key])) {
if (\is_string($config[$key]) || !\is_int(key($config[$key]))) {
// only one
return array($config[$key]);
return [$config[$key]];
}
return $config[$key];
}
return array();
return [];
}
}

View File

@@ -27,12 +27,12 @@ class PrototypedArrayNode extends ArrayNode
protected $keyAttribute;
protected $removeKeyAttribute = false;
protected $minNumberOfElements = 0;
protected $defaultValue = array();
protected $defaultValue = [];
protected $defaultChildren;
/**
* @var NodeInterface[] An array of the prototypes of the simplified value children
*/
private $valuePrototypes = array();
private $valuePrototypes = [];
/**
* Sets the minimum number of elements that a prototype based node must
@@ -53,15 +53,15 @@ class PrototypedArrayNode extends ArrayNode
* to be the key of the particular item. For example, if "id" is the
* "key", then:
*
* array(
* array('id' => 'my_name', 'foo' => 'bar'),
* );
* [
* ['id' => 'my_name', 'foo' => 'bar'],
* ];
*
* becomes
*
* array(
* 'my_name' => array('foo' => 'bar'),
* );
* [
* 'my_name' => ['foo' => 'bar'],
* ];
*
* If you'd like "'id' => 'my_name'" to still be present in the resulting
* array, then you can set the second argument of this method to false.
@@ -78,7 +78,7 @@ class PrototypedArrayNode extends ArrayNode
/**
* Retrieves the name of the attribute which value should be used as key.
*
* @return string The name of the attribute
* @return string|null The name of the attribute
*/
public function getKeyAttribute()
{
@@ -114,10 +114,10 @@ class PrototypedArrayNode extends ArrayNode
*
* @param int|string|array|null $children The number of children|The child name|The children names to be added
*/
public function setAddChildrenIfNoneSet($children = array('defaults'))
public function setAddChildrenIfNoneSet($children = ['defaults'])
{
if (null === $children) {
$this->defaultChildren = array('defaults');
$this->defaultChildren = ['defaults'];
} else {
$this->defaultChildren = \is_int($children) && $children > 0 ? range(1, $children) : (array) $children;
}
@@ -132,8 +132,8 @@ class PrototypedArrayNode extends ArrayNode
public function getDefaultValue()
{
if (null !== $this->defaultChildren) {
$default = $this->prototype->hasDefaultValue() ? $this->prototype->getDefaultValue() : array();
$defaults = array();
$default = $this->prototype->hasDefaultValue() ? $this->prototype->getDefaultValue() : [];
$defaults = [];
foreach (array_values($this->defaultChildren) as $i => $name) {
$defaults[null === $this->keyAttribute ? $i : $name] = $default;
}
@@ -226,7 +226,7 @@ class PrototypedArrayNode extends ArrayNode
$value = $this->remapXml($value);
$isAssoc = array_keys($value) !== range(0, \count($value) - 1);
$normalized = array();
$normalized = [];
foreach ($value as $k => $v) {
if (null !== $this->keyAttribute && \is_array($v)) {
if (!isset($v[$this->keyAttribute]) && \is_int($k) && !$isAssoc) {
@@ -243,9 +243,9 @@ class PrototypedArrayNode extends ArrayNode
}
// if only "value" is left
if (array_keys($v) === array('value')) {
if (array_keys($v) === ['value']) {
$v = $v['value'];
if ($this->prototype instanceof ArrayNode && ($children = $this->prototype->getChildren()) && array_key_exists('value', $children)) {
if ($this->prototype instanceof ArrayNode && ($children = $this->prototype->getChildren()) && \array_key_exists('value', $children)) {
$valuePrototype = current($this->valuePrototypes) ?: clone $children['value'];
$valuePrototype->parent = $this;
$originalClosures = $this->prototype->normalizationClosures;
@@ -258,7 +258,7 @@ class PrototypedArrayNode extends ArrayNode
}
}
if (array_key_exists($k, $normalized)) {
if (\array_key_exists($k, $normalized)) {
$ex = new DuplicateKeyException(sprintf('Duplicate key "%s" for path "%s".', $k, $this->getPath()));
$ex->setPath($this->getPath());
@@ -301,14 +301,14 @@ class PrototypedArrayNode extends ArrayNode
}
foreach ($rightSide as $k => $v) {
// prototype, and key is irrelevant, so simply append the element
// prototype, and key is irrelevant, append the element
if (null === $this->keyAttribute) {
$leftSide[] = $v;
continue;
}
// no conflict
if (!array_key_exists($k, $leftSide)) {
if (!\array_key_exists($k, $leftSide)) {
if (!$this->allowNewKeys) {
$ex = new InvalidConfigurationException(sprintf('You are not allowed to define new elements for path "%s". Please define all elements for this path in one config file.', $this->getPath()));
$ex->setPath($this->getPath());
@@ -335,30 +335,30 @@ class PrototypedArrayNode extends ArrayNode
*
* For example, assume $this->keyAttribute is 'name' and the value array is as follows:
*
* array(
* array(
* [
* [
* 'name' => 'name001',
* 'value' => 'value001'
* )
* )
* ]
* ]
*
* Now, the key is 0 and the child node is:
*
* array(
* [
* 'name' => 'name001',
* 'value' => 'value001'
* )
* ]
*
* When normalizing the value array, the 'name' element will removed from the child node
* and its value becomes the new key of the child node:
*
* array(
* 'name001' => array('value' => 'value001')
* )
* [
* 'name001' => ['value' => 'value001']
* ]
*
* Now only 'value' element is left in the child node which can be further simplified into a string:
*
* array('name001' => 'value001')
* ['name001' => 'value001']
*
* Now, the key becomes 'name001' and the child node becomes 'value001' and
* the prototype of child node 'name001' should be a ScalarNode instead of an ArrayNode instance.