Переглянути джерело

[Config] Reverting the preventExtraKeys option. This is a revert of functionality that would have allowed "unnamed" children to be added to an array node.

We decided that this is not necessary and that it's leaving too many things wide open. Instead, in these cases where we have an array with unknown items, a prototype should be used.

Further functionality will need to be added later to allow you to specify a few nodes that you *do* know about under an array and then also specify a prototype to catch everything else.
Ryan Weaver 14 роки тому
батько
коміт
6f17b6d58e

+ 2 - 23
src/Symfony/Component/Config/Definition/ArrayNode.php

@@ -35,7 +35,6 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
     protected $minNumberOfElements;
     protected $performDeepMerging;
     protected $defaultValue;
-    protected $preventExtraKeys;
 
     /**
      * Constructor.
@@ -55,7 +54,6 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
         $this->allowNewKeys = true;
         $this->performDeepMerging = true;
         $this->minNumberOfElements = 0;
-        $this->preventExtraKeys = true;
     }
 
     /**
@@ -417,8 +415,8 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
             $value[$name] = $child->normalize($value[$name]);
         }
 
-        // if extra fields are present and preventExtraKeys is true, throw exception
-        if ($this->preventExtraKeys && $diff = array_diff(array_keys($value), array_keys($this->children))) {
+        // if extra fields are present, throw exception
+        if ($diff = array_diff(array_keys($value), array_keys($this->children))) {
             $msg = sprintf('Unrecognized options "%s" under "%s"', implode(', ', $diff), $this->getPath());
 
             throw new InvalidConfigurationException($msg);
@@ -483,23 +481,4 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
 
         return $leftSide;
     }
-
-    /**
-     * Set whether or not this array should just prevent child values from
-     * keys that have no corresponding child nodes.
-     *
-     * If true (default), an exception will be thrown if unrecognized options
-     * are introduced. If false, extra keys are allowed in and included in
-     * the final array.
-     *
-     * An example would be an "options" array node, where its children
-     * could be any key of any form. In this case, no children are placed
-     * on the node, but child values must be allowed.
-     *
-     * @param  Boolean $v Whether to allow unnamed children
-     */
-    public function setPreventExtraKeys($v)
-    {
-        $this->preventExtraKeys = $v;
-    }
 }

+ 0 - 22
src/Symfony/Component/Config/Definition/Builder/NodeBuilder.php

@@ -43,7 +43,6 @@ class NodeBuilder
     public $trueEquivalent;
     public $falseEquivalent;
     public $performDeepMerging;
-    public $preventExtraKeys;
 
     /**
      * Constructor
@@ -66,7 +65,6 @@ class NodeBuilder
         $this->allowEmptyValue = true;
         $this->children = array();
         $this->performDeepMerging = true;
-        $this->preventExtraKeys = true;
 
         if ('boolean' === $type) {
             $this->nullEquivalent = true;
@@ -486,24 +484,4 @@ class NodeBuilder
     {
         return $this->parent;
     }
-
-    /**
-     * Allow un-named child values to be set into an array node.
-     *
-     * By default, any values under an array node must be represented by
-     * a child node. This allows an array node to accept any values set
-     * on it, regardless of whether or not a node is present to normalize it.
-     *
-     * An example would be an "options" array node, where its children
-     * could be any key of any form. In this case, no children are placed
-     * on the node, but child values must be allowed.
-     *
-     * @return Symfony\Component\DependencyInjection\Configuration\Builder\NodeBuilder
-     */
-    public function allowExtraKeys()
-    {
-        $this->preventExtraKeys = false;
-
-        return $this;
-    }
 }

+ 0 - 1
src/Symfony/Component/Config/Definition/Builder/TreeBuilder.php

@@ -163,7 +163,6 @@ class TreeBuilder
         $configNode->addEquivalentValue(false, $node->falseEquivalent);
         $configNode->setPerformDeepMerging($node->performDeepMerging);
         $configNode->setRequired($node->required);
-        $configNode->setPreventExtraKeys($node->preventExtraKeys);
 
         if (null !== $node->key) {
             $configNode->setKeyAttribute($node->key, $node->removeKeyItem);

+ 11 - 15
tests/Symfony/Tests/Component/Config/Definition/ArrayNodeTest.php

@@ -59,24 +59,17 @@ class ArrayNodeTest extends \PHPUnit_Framework_TestCase
         $node->normalize(array('foo' => 'bar'));
     }
 
-    // if prevent extra keys is false, normalize allows them
-    public function textNoExceptionForUnrecognizedChildWithUnnamedChildren()
-    {
-        $node = new ArrayNode('root');
-        $node->setPreventExtraKeys(false);
-        $normalized = $node->normalize(array('foo' => 'bar'));
-
-        $this->assertEquals(array('foo' => 'bar'), $normalized);
-    }
-
     // a remapped key (e.g. "mapping" -> "mappings") should be unset after being used
     public function testRemappedKeysAreUnset()
     {
         $node = new ArrayNode('root');
         $mappingsNode = new ArrayNode('mappings');
-        $mappingsNode->setPreventExtraKeys(false); // just so we can add anything to it
         $node->addChild($mappingsNode);
 
+        // each item under mappings is just a scalar
+        $prototype= new ScalarNode(null, $mappingsNode);
+        $mappingsNode->setPrototype($prototype);
+
         $remappings = array();
         $remappings[] = array('mapping', 'mappings');
         $node->setXmlRemappings($remappings);
@@ -108,8 +101,9 @@ class ArrayNodeTest extends \PHPUnit_Framework_TestCase
         $node = new ArrayNode('root');
         $node->setKeyAttribute('id', true);
 
-        $prototype = new ArrayNode(null);
-        $prototype->setPreventExtraKeys(false); // just so it allows anything
+        // each item under the root is an array, with one scalar item
+        $prototype= new ArrayNode(null, $node);
+        $prototype->addChild(new ScalarNode('foo'));
         $node->setPrototype($prototype);
 
         $children = array();
@@ -130,8 +124,10 @@ class ArrayNodeTest extends \PHPUnit_Framework_TestCase
         $node = new ArrayNode('root');
         $node->setKeyAttribute('id', false);
 
-        $prototype = new ArrayNode(null);
-        $prototype->setPreventExtraKeys(false); // just so it allows anything
+        // each item under the root is an array, with two scalar items
+        $prototype= new ArrayNode(null, $node);
+        $prototype->addChild(new ScalarNode('foo'));
+        $prototype->addChild(new ScalarNode('id')); // the key attribute will remain
         $node->setPrototype($prototype);
 
         $children = array();