feature #14238 [config] added remove option to ignoreExtraKeys (twifty)

This PR was submitted for the 2.7 branch but it was merged into the 2.8 branch instead (closes #14238).

Discussion
----------

[config] added remove option to ignoreExtraKeys

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets |
| License       | MIT
| Doc PR        |

I have added a remove option to the `ignoreExtraKeys()` method of `Config/Definition/Builder/ArrayNodeDefinition`. The current implementation removes all such keys from the resulting array. This can at times be an inconvenience as we have to write extra methods to remove them before the validation then add them back again when done. Passing a boolean to the method now leaves them in place.

Commits
-------

1df4ebe added remove option to ignoreExtraKeys
This commit is contained in:
Fabien Potencier 2015-06-28 20:28:03 +02:00
commit 674b124b59
3 changed files with 28 additions and 3 deletions

View File

@ -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]);
}
}

View File

@ -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) {

View File

@ -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
*/