/** * @param $nodeName * * @return \Symfony\Component\Config\Definition\ArrayNode */ private function getChildNode($nodeName) { /** @var ArrayNode[] $childs */ $childs = $this->tree->getChildren(); self::assertArrayHasKey($nodeName, $childs); return $childs[$nodeName]; }
/** * 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'); }
/** * Tests the opposite of the testMappedAttributeKeyIsRemoved because * the removal can be toggled with an option. */ public function testMappedAttributeKeyNotRemoved() { $node = new PrototypedArrayNode('root'); $node->setKeyAttribute('id', false); // 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(); $children[] = array('id' => 'item_name', 'foo' => 'bar'); $normalized = $node->normalize($children); $expected = array(); $expected['item_name'] = array('id' => 'item_name', 'foo' => 'bar'); $this->assertEquals($expected, $normalized); }
/** * Processes an array of configurations. * * @param array $validated merged and validated array * @param array $validating merging and validating array * @param ArrayNode $node merging node * @param ArrayNode $masterNode merged node (master node) * * @return array list of (validated array, merged node) */ public function process(array $validated, array $validating, ArrayNode $node, ArrayNode $masterNode = null) { // no setting master node if (is_null($masterNode)) { // set a node to master node $masterNode = $node; // has setting } else { // merge a node to master node // enabled master node setting when exists the same key validation // check existence for avoid exception trying to set a key that already set $childrenAll = $masterNode->getChildren(); foreach ($node->getChildren() as $name => $child) { if (!isset($childrenAll[$name])) { $masterNode->addChild($child); } } } // validate root node name, target is merging/validating array foreach ($validating as $name => $config) { if ($masterNode->getName() !== $name || $node->getName() !== $name) { throw new \Exception(sprintf('Settings root[%s] is different from Configuration root[%s] or part[%s].', $name, $masterNode->getName(), $node->getName())); } } // directly set validated array without normalize/merge/finalize $currentConfig = $validated; // loop a validating array foreach ($validating as $config) { // execute a node's normalize to validate key $config = $node->normalize($config); // execute a master node's merge to reflect cannotBeOverwritten key setting and so on $currentConfig = $masterNode->merge($currentConfig, $config); } // execute a master node's finalize $finalized = $masterNode->finalize($currentConfig); return array($finalized, $masterNode); }
/** * Creates an array node. * * @param NodeBuilder $node The builder of the node * * @return Symfony\Component\Config\Definition\ArrayNode */ protected function createArrayConfigNode(NodeBuilder $node) { $configNode = new ArrayNode($node->name, $node->parent); $configNode->setAddIfNotSet($node->addDefaults); $configNode->setAllowNewKeys($node->allowNewKeys); $configNode->addEquivalentValue(null, $node->nullEquivalent); $configNode->addEquivalentValue(true, $node->trueEquivalent); $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); } if (true === $node->atLeastOne) { $configNode->setMinNumberOfElements(1); } if (null !== $node->normalization) { $configNode->setNormalizationClosures( $this->buildExpressions($node->normalization->before) ); $configNode->setXmlRemappings($node->normalization->remappings); } if (null !== $node->merge) { $configNode->setAllowOverwrite($node->merge->allowOverwrite); $configNode->setAllowFalse($node->merge->allowFalse); } foreach ($node->children as $child) { $child->parent = $configNode; $configNode->addChild($this->createConfigNode($child)); } if (null !== $node->prototype) { $node->prototype->parent = $configNode; $configNode->setPrototype($this->createConfigNode($node->prototype)); } if (null !== $node->defaultValue) { $configNode->setDefaultValue($node->defaultValue); } if (null !== $node->validation) { $configNode->setFinalValidationClosures( $this->buildExpressions($node->validation->rules) ); } return $configNode; }
/** * @param PrototypedArrayNode $node * * @return array */ private function getPrototypeChildren(PrototypedArrayNode $node) { $prototype = $node->getPrototype(); $key = $node->getKeyAttribute(); // Do not expand prototype if it isn't an array node nor uses attribute as key if (!$key && !$prototype instanceof ArrayNode) { return $node->getChildren(); } if ($prototype instanceof ArrayNode) { $keyNode = new ArrayNode($key, $node); $children = $prototype->getChildren(); if ($prototype instanceof PrototypedArrayNode && $prototype->getKeyAttribute()) { $children = $this->getPrototypeChildren($prototype); } // add children foreach ($children as $childNode) { $keyNode->addChild($childNode); } } else { $keyNode = new ScalarNode($key, $node); } $info = 'Prototype'; if (null !== $prototype->getInfo()) { $info .= ': ' . $prototype->getInfo(); } $keyNode->setInfo($info); return array($key => $keyNode); }
protected function validateConcreteNode(ArrayNode $node) { $path = $node->getPath(); if (null !== $this->key) { throw new InvalidDefinitionException(sprintf('->useAttributeAsKey() is not applicable to concrete nodes at path "%s"', $path)); } if (true === $this->atLeastOne) { throw new InvalidDefinitionException(sprintf('->requiresAtLeastOneElement() is not applicable to concrete nodes at path "%s"', $path)); } if ($this->default) { throw new InvalidDefinitionException(sprintf('->defaultValue() is not applicable to concrete nodes at path "%s"', $path)); } if (false !== $this->addDefaultChildren) { throw new InvalidDefinitionException(sprintf('->addDefaultChildrenIfNoneSet() is not applicable to concrete nodes at path "%s"', $path)); } }
/** * @dataProvider getPreNormalizedNormalizedOrderedData */ public function testChildrenOrderIsMaintainedOnNormalizeValue($prenormalized, $normalized) { $scalar1 = new ScalarNode('1'); $scalar2 = new ScalarNode('2'); $scalar3 = new ScalarNode('3'); $node = new ArrayNode('foo'); $node->addChild($scalar1); $node->addChild($scalar3); $node->addChild($scalar2); $r = new \ReflectionMethod($node, 'normalizeValue'); $r->setAccessible(true); $this->assertSame($normalized, $r->invoke($node, $prenormalized)); }
/** * @param NodeInterface $node * @param int $depth */ private function outputNode(NodeInterface $node, $depth = 0) { $comments = array(); $default = ''; $defaultArray = null; $children = null; $example = $node->getExample(); // defaults if ($node instanceof ArrayNode) { $children = $node->getChildren(); if ($node instanceof PrototypedArrayNode) { $prototype = $node->getPrototype(); if ($prototype instanceof ArrayNode) { $children = $prototype->getChildren(); } // check for attribute as key if ($key = $node->getKeyAttribute()) { $keyNode = new ArrayNode($key, $node); $keyNode->setInfo('Prototype'); // add children foreach ($children as $childNode) { $keyNode->addChild($childNode); } $children = array($key => $keyNode); } } if (!$children) { if ($node->hasDefaultValue() && count($defaultArray = $node->getDefaultValue())) { $default = ''; } elseif (!is_array($example)) { $default = '[]'; } } } else { $default = '~'; if ($node->hasDefaultValue()) { $default = $node->getDefaultValue(); if (true === $default) { $default = 'true'; } elseif (false === $default) { $default = 'false'; } elseif (null === $default) { $default = '~'; } } } // required? if ($node->isRequired()) { $comments[] = 'Required'; } // example if ($example && !is_array($example)) { $comments[] = 'Example: ' . $example; } $default = (string) $default != '' ? ' ' . $default : ''; $comments = count($comments) ? '# ' . implode(', ', $comments) : ''; $text = sprintf('%-20s %s %s', $node->getName() . ':', $default, $comments); if ($info = $node->getInfo()) { $this->outputLine(''); $this->outputLine('# ' . $info, $depth * 4); } $this->outputLine($text, $depth * 4); // output defaults if ($defaultArray) { $this->outputLine(''); $message = count($defaultArray) > 1 ? 'Defaults' : 'Default'; $this->outputLine('# ' . $message . ':', $depth * 4 + 4); $this->outputArray($defaultArray, $depth + 1); } if (is_array($example)) { $this->outputLine(''); $message = count($example) > 1 ? 'Examples' : 'Example'; $this->outputLine('# ' . $message . ':', $depth * 4 + 4); $this->outputArray($example, $depth + 1); } if ($children) { foreach ($children as $childNode) { $this->outputNode($childNode, $depth + 1); } } }
/** * We hook into the validateType method, this * gets called form the normalize method. * * @param mixed $value * * @throws InvalidTypeException */ protected function validateType($value) { if (isset($value['type'])) { $this->prepareChildren($value['type']); } else { // ignore extra keys so the error message will be // focused on the missing type field $this->setIgnoreExtraKeys(true); } parent::validateType($value); }
/** * Constructor. * * @param string $name The Node's name * @param NodeInterface $parent The node parent */ public function __construct($name, NodeInterface $parent = null) { parent::__construct($name, $parent); $this->minNumberOfElements = 0; $this->defaultValue = array(); }
protected function getPrototypeNodeWithDefaultChildren() { $node = new PrototypedArrayNode('root'); $prototype = new ArrayNode(null, $node); $child = new ScalarNode('foo'); $child->setDefaultValue('bar'); $prototype->addChild($child); $prototype->setAddIfNotSet(true); $node->setPrototype($prototype); return $node; }
/** * Constructor. * * @param string $name The Node's name * @param NodeInterface $parent The node parent */ public function __construct($name, NodeInterface $parent = null) { parent::__construct($name, $parent); $this->minNumberOfElements = 0; }
/** * @expectedException \RuntimeException * @expectedExceptionMessage The node at path "foo" has no default value. */ public function testGetDefaultValueWithoutDefaultValue() { $node = new ArrayNode('foo'); $node->getDefaultValue(); }
public function getDefaultValue() { if ($this->children['type']->getDefaultValue()) { $this->prepareChildren($this->children['type']->getDefaultValue()); } return parent::getDefaultValue(); }
public function getDataForKeyRemovedLeftValueOnly() { $scalarValue = new ScalarNode('value'); $arrayValue = new ArrayNode('value'); $arrayValue->addChild(new ScalarNode('foo')); $arrayValue->addChild(new ScalarNode('bar')); $variableValue = new VariableNode('value'); return array(array($scalarValue, array(array('id' => 'option1', 'value' => 'value1')), array('option1' => 'value1')), array($scalarValue, array(array('id' => 'option1', 'value' => 'value1'), array('id' => 'option2', 'value' => 'value2', 'foo' => 'foo2')), array('option1' => 'value1', 'option2' => array('value' => 'value2', 'foo' => 'foo2'))), array($arrayValue, array(array('id' => 'option1', 'value' => array('foo' => 'foo1', 'bar' => 'bar1'))), array('option1' => array('foo' => 'foo1', 'bar' => 'bar1'))), array($variableValue, array(array('id' => 'option1', 'value' => array('foo' => 'foo1', 'bar' => 'bar1')), array('id' => 'option2', 'value' => 'value2')), array('option1' => array('foo' => 'foo1', 'bar' => 'bar1'), 'option2' => 'value2'))); }