123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 |
- <?php
- /*
- * This file is part of the Symfony package.
- *
- * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
- namespace Symfony\Component\Config\Definition\Builder;
- use Symfony\Component\Config\Definition\BaseNode;
- use Symfony\Component\Config\Definition\BooleanNode;
- use Symfony\Component\Config\Definition\ArrayNode;
- use Symfony\Component\Config\Definition\ScalarNode;
- use Symfony\Component\Config\Definition\VariableNode;
- /**
- * This is the entry class for building your own config tree.
- *
- * @author Johannes M. Schmitt <schmittjoh@gmail.com>
- */
- class TreeBuilder
- {
- protected $root;
- protected $tree;
- /**
- * Creates the NodeBuilder for the root node
- *
- * @param string $name The name of the node
- * @param string $type The type of the node
- *
- * @return Symfony\Component\Config\Definition\Builder\NodeBuilder
- */
- public function root($name, $type)
- {
- $this->tree = null;
- return $this->root = new NodeBuilder($name, $type, $this);
- }
- /**
- * Builds the tree.
- *
- * @return Symfony\Component\Config\Definition\NodeInterface
- */
- public function buildTree()
- {
- if (null === $this->root) {
- throw new \RuntimeException('You haven\'t added a root node.');
- }
- if (null !== $this->tree) {
- return $this->tree;
- }
- $this->root->parent = null;
- return $this->tree = $this->createConfigNode($this->root);
- }
- /**
- * Creates a node.
- *
- * @param NodeBuilder $node The builder of the node
- *
- * @return Symfony\Component\Config\Definition\NodeInterface
- */
- protected function createConfigNode(NodeBuilder $node)
- {
- $method = 'create'.$node->type.'ConfigNode';
- if (!method_exists($this, $method)) {
- throw new \RuntimeException(sprintf('Unknown node type: "%s"', $node->type));
- }
- return $this->$method($node);
- }
- /**
- * Creates a boolean node.
- *
- * @param NodeBuilder $node The builder of the node
- *
- * @return Symfony\Component\Config\Definition\BooleanNode
- */
- protected function createBooleanConfigNode(NodeBuilder $node)
- {
- $configNode = new BooleanNode($node->name, $node->parent);
- $this->configureVariableNode($configNode, $node);
- return $configNode;
- }
- /**
- * Creates a scalar node.
- *
- * @param NodeBuilder $node the builder of the node
- *
- * @return Symfony\Component\Config\Definition\ScalarNode
- */
- protected function createScalarConfigNode(NodeBuilder $node)
- {
- $configNode = new ScalarNode($node->name, $node->parent);
- $this->configureVariableNode($configNode, $node);
- return $configNode;
- }
- /**
- * Configures a variable node.
- *
- * @param VariableNode $configNode The node to configure
- * @param NodeBuilder $node The builder of the node
- */
- protected function configureVariableNode(VariableNode $configNode, NodeBuilder $node)
- {
- if (null !== $node->normalization) {
- $configNode->setNormalizationClosures(
- $this->buildExpressions($node->normalization->before)
- );
- }
- if (null !== $node->merge) {
- $configNode->setAllowOverwrite($node->merge->allowOverwrite);
- }
- if (true === $node->default) {
- $configNode->setDefaultValue($node->defaultValue);
- }
- if (false === $node->allowEmptyValue) {
- $configNode->setAllowEmptyValue($node->allowEmptyValue);
- }
- $configNode->addEquivalentValue(null, $node->nullEquivalent);
- $configNode->addEquivalentValue(true, $node->trueEquivalent);
- $configNode->addEquivalentValue(false, $node->falseEquivalent);
- $configNode->setRequired($node->required);
- if (null !== $node->validation) {
- $configNode->setFinalValidationClosures(
- $this->buildExpressions($node->validation->rules)
- );
- }
- }
- /**
- * Creates a variable node.
- *
- * @param NodeBuilder $node the builder of the node
- *
- * @return Symfony\Component\Config\Definition\VariableNode
- */
- protected function createVariableConfigNode(NodeBuilder $node)
- {
- $configNode = new VariableNode($node->name, $node->parent);
- $this->configureVariableNode($configNode, $node);
- return $configNode;
- }
- /**
- * 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;
- }
- /**
- * Builds the expressions.
- *
- * @param array $expressions An array of ExprBuilder instances to build
- *
- * @return array
- */
- protected function buildExpressions(array $expressions)
- {
- foreach ($expressions as $k => $expr) {
- if (!$expr instanceof ExprBuilder) {
- continue;
- }
- $expressions[$k] = function($v) use($expr) {
- $ifPart = $expr->ifPart;
- if (true !== $ifPart($v)) {
- return $v;
- }
- $thenPart = $expr->thenPart;
- return $thenPart($v);
- };
- }
- return $expressions;
- }
- }
|