From 1df4ebecfd36b5103915b1c001a7068aeaddaa51 Mon Sep 17 00:00:00 2001 From: twifty Date: Tue, 7 Apr 2015 03:31:40 +0800 Subject: [PATCH] added remove option to ignoreExtraKeys --- .../Component/Config/Definition/ArrayNode.php | 8 +++++++- .../Definition/Builder/ArrayNodeDefinition.php | 8 ++++++-- .../Config/Tests/Definition/ArrayNodeTest.php | 15 +++++++++++++++ 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/Symfony/Component/Config/Definition/ArrayNode.php b/src/Symfony/Component/Config/Definition/ArrayNode.php index 05ae1fdcd9..c88552dcda 100644 --- a/src/Symfony/Component/Config/Definition/ArrayNode.php +++ b/src/Symfony/Component/Config/Definition/ArrayNode.php @@ -29,6 +29,7 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface protected $addIfNotSet = false; protected $performDeepMerging = true; protected $ignoreExtraKeys = false; + protected $removeExtraKeys = true; protected $normalizeKeys = true; public function setNormalizeKeys($normalizeKeys) @@ -140,10 +141,12 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface * Whether extra keys should just be ignore without an exception. * * @param bool $boolean To allow extra keys + * @param bool $remove To remove extra keys */ - public function setIgnoreExtraKeys($boolean) + public function setIgnoreExtraKeys($boolean, $remove = true) { $this->ignoreExtraKeys = (bool) $boolean; + $this->removeExtraKeys = $this->ignoreExtraKeys && $remove; } /** @@ -300,6 +303,9 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface if (isset($this->children[$name])) { $normalized[$name] = $this->children[$name]->normalize($val); unset($value[$name]); + } elseif (false === $this->removeExtraKeys) { + $normalized[$name] = $val; + unset($value[$name]); } } diff --git a/src/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php b/src/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php index c64b2ecfdb..fb34cfa8f7 100644 --- a/src/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php +++ b/src/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php @@ -24,6 +24,7 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition { protected $performDeepMerging = true; protected $ignoreExtraKeys = false; + protected $removeExtraKeys = true; protected $children = array(); protected $prototype; protected $atLeastOne = false; @@ -284,11 +285,14 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition * 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 + * * @return ArrayNodeDefinition */ - public function ignoreExtraKeys() + public function ignoreExtraKeys($remove = true) { $this->ignoreExtraKeys = true; + $this->removeExtraKeys = $remove; return $this; } @@ -393,7 +397,7 @@ class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinition $node->addEquivalentValue(false, $this->falseEquivalent); $node->setPerformDeepMerging($this->performDeepMerging); $node->setRequired($this->required); - $node->setIgnoreExtraKeys($this->ignoreExtraKeys); + $node->setIgnoreExtraKeys($this->ignoreExtraKeys, $this->removeExtraKeys); $node->setNormalizeKeys($this->normalizeKeys); if (null !== $this->normalization) { diff --git a/src/Symfony/Component/Config/Tests/Definition/ArrayNodeTest.php b/src/Symfony/Component/Config/Tests/Definition/ArrayNodeTest.php index 291c2fd2cc..c88fc13f07 100644 --- a/src/Symfony/Component/Config/Tests/Definition/ArrayNodeTest.php +++ b/src/Symfony/Component/Config/Tests/Definition/ArrayNodeTest.php @@ -50,6 +50,21 @@ class ArrayNodeTest extends \PHPUnit_Framework_TestCase $this->assertTrue(true, 'No exception was thrown when setIgnoreExtraKeys is true'); } + /** + * Tests that extra keys are not removed when + * ignoreExtraKeys second option is set to false. + * + * Related to testExceptionThrownOnUnrecognizedChild + */ + public function testIgnoreExtraKeysNotRemoved() + { + $node = new ArrayNode('roo'); + $node->setIgnoreExtraKeys(true, false); + + $data = array('foo' => 'bar'); + $this->assertSame($data, $node->normalize($data)); + } + /** * @dataProvider getPreNormalizationTests */