vendor/symfony/src/Symfony/Component/Config/Definition/Builder/ArrayNodeDefinition.php
changeset 0 7f95f8617b0b
equal deleted inserted replaced
-1:000000000000 0:7f95f8617b0b
       
     1 <?php
       
     2 
       
     3 /*
       
     4  * This file is part of the Symfony package.
       
     5  *
       
     6  * (c) Fabien Potencier <fabien@symfony.com>
       
     7  *
       
     8  * For the full copyright and license information, please view the LICENSE
       
     9  * file that was distributed with this source code.
       
    10  */
       
    11 
       
    12 namespace Symfony\Component\Config\Definition\Builder;
       
    13 
       
    14 use Symfony\Component\Config\Definition\ArrayNode;
       
    15 use Symfony\Component\Config\Definition\PrototypedArrayNode;
       
    16 use Symfony\Component\Config\Definition\NodeInterface;
       
    17 
       
    18 /**
       
    19  * This class provides a fluent interface for defining an array node.
       
    20  *
       
    21  * @author Johannes M. Schmitt <schmittjoh@gmail.com>
       
    22  */
       
    23 class ArrayNodeDefinition extends NodeDefinition implements ParentNodeDefinitionInterface
       
    24 {
       
    25     protected $performDeepMerging;
       
    26     protected $ignoreExtraKeys;
       
    27     protected $children;
       
    28     protected $prototype;
       
    29     protected $atLeastOne;
       
    30     protected $allowNewKeys;
       
    31     protected $key;
       
    32     protected $removeKeyItem;
       
    33     protected $addDefaults;
       
    34     protected $nodeBuilder;
       
    35 
       
    36     /**
       
    37      * {@inheritDoc}
       
    38      */
       
    39     public function __construct($name, NodeParentInterface $parent = null)
       
    40     {
       
    41         parent::__construct($name, $parent);
       
    42 
       
    43         $this->children = array();
       
    44         $this->addDefaults = false;
       
    45         $this->allowNewKeys = true;
       
    46         $this->atLeastOne = false;
       
    47         $this->allowEmptyValue = true;
       
    48         $this->performDeepMerging = true;
       
    49         $this->nullEquivalent = array();
       
    50         $this->trueEquivalent = array();
       
    51     }
       
    52 
       
    53     /**
       
    54      * Set a custom children builder
       
    55      *
       
    56      * @param NodeBuilder $builder A custom NodeBuilder
       
    57      */
       
    58     public function setBuilder(NodeBuilder $builder)
       
    59     {
       
    60         $this->nodeBuilder = $builder;
       
    61     }
       
    62 
       
    63     /**
       
    64      * Returns a builder to add children nodes
       
    65      *
       
    66      * @return NodeBuilder
       
    67      */
       
    68     public function children()
       
    69     {
       
    70         return $this->getNodeBuilder();
       
    71     }
       
    72 
       
    73     /**
       
    74      * Sets a prototype for child nodes.
       
    75      *
       
    76      * @param string $type the type of node
       
    77      *
       
    78      * @return NodeDefinition
       
    79      */
       
    80     public function prototype($type)
       
    81     {
       
    82         $builder = $this->getNodeBuilder();
       
    83         $this->prototype = $builder->node(null, $type);
       
    84         $this->prototype->parent = $this;
       
    85 
       
    86         return $this->prototype;
       
    87     }
       
    88 
       
    89     /**
       
    90      * Adds the default value if the node is not set in the configuration.
       
    91      *
       
    92      * @return ArrayNodeDefinition
       
    93      */
       
    94     public function addDefaultsIfNotSet()
       
    95     {
       
    96         $this->addDefaults = true;
       
    97 
       
    98         return $this;
       
    99     }
       
   100 
       
   101     /**
       
   102      * Requires the node to have at least one element.
       
   103      *
       
   104      * @return ArrayNodeDefinition
       
   105      */
       
   106     public function requiresAtLeastOneElement()
       
   107     {
       
   108         $this->atLeastOne = true;
       
   109 
       
   110         return $this;
       
   111     }
       
   112 
       
   113     /**
       
   114      * Disallows adding news keys in a subsequent configuration.
       
   115      *
       
   116      * If used all keys have to be defined in the same configuration file.
       
   117      *
       
   118      * @return ArrayNodeDefinition
       
   119      */
       
   120     public function disallowNewKeysInSubsequentConfigs()
       
   121     {
       
   122         $this->allowNewKeys = false;
       
   123 
       
   124         return $this;
       
   125     }
       
   126 
       
   127     /**
       
   128      * Sets a normalization rule for XML configurations.
       
   129      *
       
   130      * @param string $singular The key to remap
       
   131      * @param string $plural   The plural of the key for irregular plurals
       
   132      *
       
   133      * @return ArrayNodeDefinition
       
   134      */
       
   135     public function fixXmlConfig($singular, $plural = null)
       
   136     {
       
   137         $this->normalization()->remap($singular, $plural);
       
   138 
       
   139         return $this;
       
   140     }
       
   141 
       
   142     /**
       
   143      * Set the attribute which value is to be used as key.
       
   144      *
       
   145      * This is useful when you have an indexed array that should be an
       
   146      * associative array. You can select an item from within the array
       
   147      * to be the key of the particular item. For example, if "id" is the
       
   148      * "key", then:
       
   149      *
       
   150      *     array(
       
   151      *         array('id' => 'my_name', 'foo' => 'bar'),
       
   152      *     )
       
   153      *
       
   154      * becomes
       
   155      *
       
   156      *     array(
       
   157      *         'my_name' => array('foo' => 'bar'),
       
   158      *     )
       
   159      *
       
   160      * If you'd like "'id' => 'my_name'" to still be present in the resulting
       
   161      * array, then you can set the second argument of this method to false.
       
   162      *
       
   163      * @param string  $name          The name of the key
       
   164      * @param Boolean $removeKeyItem Whether or not the key item should be removed.
       
   165      *
       
   166      * @return ArrayNodeDefinition
       
   167      */
       
   168     public function useAttributeAsKey($name, $removeKeyItem = true)
       
   169     {
       
   170         $this->key = $name;
       
   171         $this->removeKeyItem = $removeKeyItem;
       
   172 
       
   173         return $this;
       
   174     }
       
   175 
       
   176     /**
       
   177      * Sets whether the node can be unset.
       
   178      *
       
   179      * @param Boolean $allow
       
   180      *
       
   181      * @return ArrayNodeDefinition
       
   182      */
       
   183     public function canBeUnset($allow = true)
       
   184     {
       
   185         $this->merge()->allowUnset($allow);
       
   186 
       
   187         return $this;
       
   188     }
       
   189 
       
   190     /**
       
   191      * Disables the deep merging of the node.
       
   192      *
       
   193      * @return ArrayNodeDefinition
       
   194      */
       
   195     public function performNoDeepMerging()
       
   196     {
       
   197         $this->performDeepMerging = false;
       
   198 
       
   199         return $this;
       
   200     }
       
   201 
       
   202     /**
       
   203      * Allows extra config keys to be specified under an array without
       
   204      * throwing an exception.
       
   205      *
       
   206      * Those config values are simply ignored. This should be used only
       
   207      * in special cases where you want to send an entire configuration
       
   208      * array through a special tree that processes only part of the array.
       
   209      *
       
   210      * @return ArrayNodeDefinition
       
   211      */
       
   212     public function ignoreExtraKeys()
       
   213     {
       
   214         $this->ignoreExtraKeys = true;
       
   215 
       
   216         return $this;
       
   217     }
       
   218 
       
   219     /**
       
   220      * Append a node definition.
       
   221      *
       
   222      *     $node = new ArrayNodeDefinition()
       
   223      *         ->children()
       
   224      *             ->scalarNode('foo')
       
   225      *             ->scalarNode('baz')
       
   226      *         ->end()
       
   227      *         ->append($this->getBarNodeDefinition())
       
   228      *     ;
       
   229      *
       
   230      * @return ArrayNodeDefinition This node
       
   231      */
       
   232     public function append(NodeDefinition $node)
       
   233     {
       
   234         $this->children[$node->name] = $node->setParent($this);
       
   235 
       
   236         return $this;
       
   237     }
       
   238 
       
   239     /**
       
   240      * Returns a node builder to be used to add children and prototype
       
   241      *
       
   242      * @return NodeBuilder The node builder
       
   243      */
       
   244     protected function getNodeBuilder()
       
   245     {
       
   246         if (null === $this->nodeBuilder) {
       
   247             $this->nodeBuilder = new NodeBuilder();
       
   248         }
       
   249 
       
   250         return $this->nodeBuilder->setParent($this);
       
   251     }
       
   252 
       
   253     /**
       
   254      * {@inheritDoc}
       
   255      */
       
   256     protected function createNode()
       
   257     {
       
   258         if (null == $this->prototype) {
       
   259             $node = new ArrayNode($this->name, $this->parent);
       
   260         } else {
       
   261             $node = new PrototypedArrayNode($this->name, $this->parent);
       
   262         }
       
   263 
       
   264         $node->setAddIfNotSet($this->addDefaults);
       
   265         $node->setAllowNewKeys($this->allowNewKeys);
       
   266         $node->addEquivalentValue(null, $this->nullEquivalent);
       
   267         $node->addEquivalentValue(true, $this->trueEquivalent);
       
   268         $node->addEquivalentValue(false, $this->falseEquivalent);
       
   269         $node->setPerformDeepMerging($this->performDeepMerging);
       
   270         $node->setRequired($this->required);
       
   271         $node->setIgnoreExtraKeys($this->ignoreExtraKeys);
       
   272 
       
   273         if (null !== $this->normalization) {
       
   274             $node->setNormalizationClosures($this->normalization->before);
       
   275             $node->setXmlRemappings($this->normalization->remappings);
       
   276         }
       
   277 
       
   278         if (null !== $this->merge) {
       
   279             $node->setAllowOverwrite($this->merge->allowOverwrite);
       
   280             $node->setAllowFalse($this->merge->allowFalse);
       
   281         }
       
   282 
       
   283         if (null !== $this->validation) {
       
   284             $node->setFinalValidationClosures($this->validation->rules);
       
   285         }
       
   286 
       
   287         if (null == $this->prototype) {
       
   288             foreach ($this->children as $child) {
       
   289                 $child->parent = $node;
       
   290                 $node->addChild($child->getNode());
       
   291             }
       
   292         } else {
       
   293             if (null !== $this->key) {
       
   294                 $node->setKeyAttribute($this->key, $this->removeKeyItem);
       
   295             }
       
   296 
       
   297             if (true === $this->atLeastOne) {
       
   298                 $node->setMinNumberOfElements(1);
       
   299             }
       
   300 
       
   301             if (null !== $this->defaultValue) {
       
   302                 $node->setDefaultValue($this->defaultValue);
       
   303             }
       
   304 
       
   305             $this->prototype->parent = $node;
       
   306             $node->setPrototype($this->prototype->getNode());
       
   307         }
       
   308 
       
   309         return $node;
       
   310     }
       
   311 
       
   312 }