Pārlūkot izejas kodu

[DependencyInjection] Being sure to remove XML-remapped singular options and key attribute options after processing.

This prevents these keys from being validated as extra fields.
Ryan Weaver 14 gadi atpakaļ
vecāks
revīzija
fd5cdfc18f

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

@@ -358,6 +358,7 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
             }
 
             $value[$plural] = Extension::normalizeConfig($value, $singular, $plural);
+            unset($value[$singular]);
         }
 
         if (null !== $this->prototype) {
@@ -372,6 +373,7 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
                         ));
                     } else if (isset($v[$this->keyAttribute])) {
                         $k = $v[$this->keyAttribute];
+                        unset($v[$this->keyAttribute]);
                     }
 
                     if (array_key_exists($k, $normalized)) {

+ 50 - 1
tests/Symfony/Tests/Component/Config/Definition/ArrayNodeTest.php

@@ -3,6 +3,7 @@
 namespace Symfony\Tests\Component\Config\Definition;
 
 use Symfony\Component\Config\Definition\ArrayNode;
+use Symfony\Component\Config\Definition\ScalarNode;
 
 class ArrayNodeTest extends \PHPUnit_Framework_TestCase
 {
@@ -78,4 +79,52 @@ class ArrayNodeTest extends \PHPUnit_Framework_TestCase
         $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');
+
+        $remappings = array();
+        $remappings[] = array('mapping', 'mappings');
+        $node->setXmlRemappings($remappings);
+
+        $normalized = $node->normalize(array('mapping' => array('foo', 'bar')));
+        $this->assertEquals(array('mappings' => array('foo', 'bar')), $normalized);
+    }
+
+    /**
+     * Tests that when a key attribute is mapped, that key is removed from the array:
+     *
+     *     <things>
+     *         <option id="option1" value="foo">
+     *         <option id="option2" value="bar">
+     *     </things>
+     *
+     * The above should finally be mapped to an array that looks like this
+     * (because "id" is the key attribute).
+     *
+     *     array(
+     *         'things' => array(
+     *             'option1' => 'foo',
+     *             'option2' => 'bar',
+     *         )
+     *     )
+     */
+    public function testMappedAttributeKeyIsRemoved()
+    {
+        $node = new ArrayNode('root');
+        $node->setKeyAttribute('id');
+
+        $prototype = new ArrayNode(null);
+        $node->setPrototype($prototype);
+
+        $children = array();
+        $children[] = array('id' => 'item_name', 'foo' => 'bar');
+        $normalized = $node->normalize($children);
+
+        $expected = array();
+        $expected['item_name'] = array('foo' => 'bar');
+        $this->assertEquals($expected, $normalized);
+    }
+}