Skip to content

Commit

Permalink
[Config] Adding an ignoreExtraKeys options, which allows you to let o…
Browse files Browse the repository at this point in the history
…ptions simply be ignore without throwing a validation exception.

I had thought that this was unnecessary - when would you ever want to just let "extra" options fail silently?

But, the SecurityExtension takes advantage of this by creating two separate config trees. The first tree looks for just one particular value on the configuration array and ignores the rest. So, there *is* a use-case for allowing all extra fields to simply be ignored, though this should not be the norm.
  • Loading branch information
weaverryan committed Feb 18, 2011
1 parent d2971e0 commit 026ab6c
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 2 deletions.
15 changes: 13 additions & 2 deletions src/Symfony/Component/Config/Definition/ArrayNode.php
Expand Up @@ -35,6 +35,7 @@ class ArrayNode extends BaseNode implements PrototypeNodeInterface
protected $minNumberOfElements;
protected $performDeepMerging;
protected $defaultValue;
protected $ignoreExtraKeys;

/**
* Constructor.
Expand Down Expand Up @@ -144,13 +145,23 @@ public function setAllowNewKeys($allow)
/**
* Sets if deep merging should occur.
*
* @param boolean $boolean
* @param Boolean $boolean
*/
public function setPerformDeepMerging($boolean)
{
$this->performDeepMerging = (Boolean) $boolean;
}

/**
* Whether extra keys should just be ignore without an exception.
*
* @param Boolean $boolean To allow extra keys
*/
public function setIgnoreExtraKeys($boolean)
{
$this->ignoreExtraKeys = (Boolean) $boolean;
}

/**
* Sets the node Name.
*
Expand Down Expand Up @@ -416,7 +427,7 @@ protected function normalizeValue($value)
}

// if extra fields are present, throw exception
if (count($value)) {
if (count($value) && !$this->ignoreExtraKeys) {
$msg = sprintf('Unrecognized options "%s" under "%s"', implode(', ', array_keys($value)), $this->getPath());

throw new InvalidConfigurationException($msg);
Expand Down
18 changes: 18 additions & 0 deletions src/Symfony/Component/Config/Definition/Builder/NodeBuilder.php
Expand Up @@ -43,6 +43,7 @@ class NodeBuilder
public $trueEquivalent;
public $falseEquivalent;
public $performDeepMerging;
public $ignoreExtraKeys;

/**
* Constructor
Expand Down Expand Up @@ -484,4 +485,21 @@ public function end()
{
return $this->parent;
}

/**
* Allows extra config keys to be specified under an array without
* throwing an exception.
*
* Those config values are simply ignored. 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.
*
* @return Symfony\Component\Config\Definition\Builder\NodeBuilder
*/
public function ignoreExtraKeys()
{
$this->ignoreExtraKeys = true;

return $this;
}
}
Expand Up @@ -163,6 +163,7 @@ protected function createArrayConfigNode(NodeBuilder $node)
$configNode->addEquivalentValue(false, $node->falseEquivalent);
$configNode->setPerformDeepMerging($node->performDeepMerging);
$configNode->setRequired($node->required);
$configNode->setIgnoreExtraKeys($node->ignoreExtraKeys);

if (null !== $node->key) {
$configNode->setKeyAttribute($node->key, $node->removeKeyItem);
Expand Down
15 changes: 15 additions & 0 deletions tests/Symfony/Tests/Component/Config/Definition/ArrayNodeTest.php
Expand Up @@ -68,6 +68,21 @@ public function testExceptionThrownOnUnrecognizedChild()
}
}

/**
* Tests that no exception is thrown for an unrecognized child if the
* ignoreExtraKeys option is set to true.
*
* Related to testExceptionThrownOnUnrecognizedChild
*/
public function testIgnoreExtraKeysNoException()
{
$node = new ArrayNode('roo');
$node->setIgnoreExtraKeys(true);

$node->normalize(array('foo' => 'bar'));
$this->assertTrue(true, 'No exception was thrown when setIgnoreExtraKeys is true');
}

// a remapped key (e.g. "mapping" -> "mappings") should be unset after being used
public function testRemappedKeysAreUnset()
{
Expand Down

0 comments on commit 026ab6c

Please sign in to comment.