[ Index ]

PHP Cross Reference of phpBB-3.2.11-deutsch

title

Body

[close]

/vendor/symfony/config/Definition/Builder/ -> ArrayNodeDefinition.php (source)

   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\Exception\InvalidDefinitionException;
  16  use Symfony\Component\Config\Definition\PrototypedArrayNode;
  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 = true;
  26      protected $ignoreExtraKeys = false;
  27      protected $removeExtraKeys = true;
  28      protected $children = array();
  29      protected $prototype;
  30      protected $atLeastOne = false;
  31      protected $allowNewKeys = true;
  32      protected $key;
  33      protected $removeKeyItem;
  34      protected $addDefaults = false;
  35      protected $addDefaultChildren = false;
  36      protected $nodeBuilder;
  37      protected $normalizeKeys = true;
  38  
  39      /**
  40       * {@inheritdoc}
  41       */
  42      public function __construct($name, NodeParentInterface $parent = null)
  43      {
  44          parent::__construct($name, $parent);
  45  
  46          $this->nullEquivalent = array();
  47          $this->trueEquivalent = array();
  48      }
  49  
  50      /**
  51       * {@inheritdoc}
  52       */
  53      public function setBuilder(NodeBuilder $builder)
  54      {
  55          $this->nodeBuilder = $builder;
  56      }
  57  
  58      /**
  59       * {@inheritdoc}
  60       */
  61      public function children()
  62      {
  63          return $this->getNodeBuilder();
  64      }
  65  
  66      /**
  67       * Sets a prototype for child nodes.
  68       *
  69       * @param string $type The type of node
  70       *
  71       * @return NodeDefinition
  72       */
  73      public function prototype($type)
  74      {
  75          return $this->prototype = $this->getNodeBuilder()->node(null, $type)->setParent($this);
  76      }
  77  
  78      /**
  79       * Adds the default value if the node is not set in the configuration.
  80       *
  81       * This method is applicable to concrete nodes only (not to prototype nodes).
  82       * If this function has been called and the node is not set during the finalization
  83       * phase, it's default value will be derived from its children default values.
  84       *
  85       * @return $this
  86       */
  87      public function addDefaultsIfNotSet()
  88      {
  89          $this->addDefaults = true;
  90  
  91          return $this;
  92      }
  93  
  94      /**
  95       * Adds children with a default value when none are defined.
  96       *
  97       * This method is applicable to prototype nodes only.
  98       *
  99       * @param int|string|array|null $children The number of children|The child name|The children names to be added
 100       *
 101       * @return $this
 102       */
 103      public function addDefaultChildrenIfNoneSet($children = null)
 104      {
 105          $this->addDefaultChildren = $children;
 106  
 107          return $this;
 108      }
 109  
 110      /**
 111       * Requires the node to have at least one element.
 112       *
 113       * This method is applicable to prototype nodes only.
 114       *
 115       * @return $this
 116       */
 117      public function requiresAtLeastOneElement()
 118      {
 119          $this->atLeastOne = true;
 120  
 121          return $this;
 122      }
 123  
 124      /**
 125       * Disallows adding news keys in a subsequent configuration.
 126       *
 127       * If used all keys have to be defined in the same configuration file.
 128       *
 129       * @return $this
 130       */
 131      public function disallowNewKeysInSubsequentConfigs()
 132      {
 133          $this->allowNewKeys = false;
 134  
 135          return $this;
 136      }
 137  
 138      /**
 139       * Sets a normalization rule for XML configurations.
 140       *
 141       * @param string $singular The key to remap
 142       * @param string $plural   The plural of the key for irregular plurals
 143       *
 144       * @return $this
 145       */
 146      public function fixXmlConfig($singular, $plural = null)
 147      {
 148          $this->normalization()->remap($singular, $plural);
 149  
 150          return $this;
 151      }
 152  
 153      /**
 154       * Sets the attribute which value is to be used as key.
 155       *
 156       * This is useful when you have an indexed array that should be an
 157       * associative array. You can select an item from within the array
 158       * to be the key of the particular item. For example, if "id" is the
 159       * "key", then:
 160       *
 161       *     array(
 162       *         array('id' => 'my_name', 'foo' => 'bar'),
 163       *     );
 164       *
 165       *   becomes
 166       *
 167       *     array(
 168       *         'my_name' => array('foo' => 'bar'),
 169       *     );
 170       *
 171       * If you'd like "'id' => 'my_name'" to still be present in the resulting
 172       * array, then you can set the second argument of this method to false.
 173       *
 174       * This method is applicable to prototype nodes only.
 175       *
 176       * @param string $name          The name of the key
 177       * @param bool   $removeKeyItem Whether or not the key item should be removed
 178       *
 179       * @return $this
 180       */
 181      public function useAttributeAsKey($name, $removeKeyItem = true)
 182      {
 183          $this->key = $name;
 184          $this->removeKeyItem = $removeKeyItem;
 185  
 186          return $this;
 187      }
 188  
 189      /**
 190       * Sets whether the node can be unset.
 191       *
 192       * @param bool $allow
 193       *
 194       * @return $this
 195       */
 196      public function canBeUnset($allow = true)
 197      {
 198          $this->merge()->allowUnset($allow);
 199  
 200          return $this;
 201      }
 202  
 203      /**
 204       * Adds an "enabled" boolean to enable the current section.
 205       *
 206       * By default, the section is disabled. If any configuration is specified then
 207       * the node will be automatically enabled:
 208       *
 209       * enableableArrayNode: {enabled: true, ...}   # The config is enabled & default values get overridden
 210       * enableableArrayNode: ~                      # The config is enabled & use the default values
 211       * enableableArrayNode: true                   # The config is enabled & use the default values
 212       * enableableArrayNode: {other: value, ...}    # The config is enabled & default values get overridden
 213       * enableableArrayNode: {enabled: false, ...}  # The config is disabled
 214       * enableableArrayNode: false                  # The config is disabled
 215       *
 216       * @return $this
 217       */
 218      public function canBeEnabled()
 219      {
 220          $this
 221              ->addDefaultsIfNotSet()
 222              ->treatFalseLike(array('enabled' => false))
 223              ->treatTrueLike(array('enabled' => true))
 224              ->treatNullLike(array('enabled' => true))
 225              ->beforeNormalization()
 226                  ->ifArray()
 227                  ->then(function ($v) {
 228                      $v['enabled'] = isset($v['enabled']) ? $v['enabled'] : true;
 229  
 230                      return $v;
 231                  })
 232              ->end()
 233              ->children()
 234                  ->booleanNode('enabled')
 235                      ->defaultFalse()
 236          ;
 237  
 238          return $this;
 239      }
 240  
 241      /**
 242       * Adds an "enabled" boolean to enable the current section.
 243       *
 244       * By default, the section is enabled.
 245       *
 246       * @return $this
 247       */
 248      public function canBeDisabled()
 249      {
 250          $this
 251              ->addDefaultsIfNotSet()
 252              ->treatFalseLike(array('enabled' => false))
 253              ->treatTrueLike(array('enabled' => true))
 254              ->treatNullLike(array('enabled' => true))
 255              ->children()
 256                  ->booleanNode('enabled')
 257                      ->defaultTrue()
 258          ;
 259  
 260          return $this;
 261      }
 262  
 263      /**
 264       * Disables the deep merging of the node.
 265       *
 266       * @return $this
 267       */
 268      public function performNoDeepMerging()
 269      {
 270          $this->performDeepMerging = false;
 271  
 272          return $this;
 273      }
 274  
 275      /**
 276       * Allows extra config keys to be specified under an array without
 277       * throwing an exception.
 278       *
 279       * Those config values are simply ignored and removed from the
 280       * resulting array. This should be used only in special cases where
 281       * you want to send an entire configuration array through a special
 282       * tree that processes only part of the array.
 283       *
 284       * @param bool $remove Whether to remove the extra keys
 285       *
 286       * @return $this
 287       */
 288      public function ignoreExtraKeys($remove = true)
 289      {
 290          $this->ignoreExtraKeys = true;
 291          $this->removeExtraKeys = $remove;
 292  
 293          return $this;
 294      }
 295  
 296      /**
 297       * Sets key normalization.
 298       *
 299       * @param bool $bool Whether to enable key normalization
 300       *
 301       * @return $this
 302       */
 303      public function normalizeKeys($bool)
 304      {
 305          $this->normalizeKeys = (bool) $bool;
 306  
 307          return $this;
 308      }
 309  
 310      /**
 311       * {@inheritdoc}
 312       */
 313      public function append(NodeDefinition $node)
 314      {
 315          $this->children[$node->name] = $node->setParent($this);
 316  
 317          return $this;
 318      }
 319  
 320      /**
 321       * Returns a node builder to be used to add children and prototype.
 322       *
 323       * @return NodeBuilder The node builder
 324       */
 325      protected function getNodeBuilder()
 326      {
 327          if (null === $this->nodeBuilder) {
 328              $this->nodeBuilder = new NodeBuilder();
 329          }
 330  
 331          return $this->nodeBuilder->setParent($this);
 332      }
 333  
 334      /**
 335       * {@inheritdoc}
 336       */
 337      protected function createNode()
 338      {
 339          if (null === $this->prototype) {
 340              $node = new ArrayNode($this->name, $this->parent);
 341  
 342              $this->validateConcreteNode($node);
 343  
 344              $node->setAddIfNotSet($this->addDefaults);
 345  
 346              foreach ($this->children as $child) {
 347                  $child->parent = $node;
 348                  $node->addChild($child->getNode());
 349              }
 350          } else {
 351              $node = new PrototypedArrayNode($this->name, $this->parent);
 352  
 353              $this->validatePrototypeNode($node);
 354  
 355              if (null !== $this->key) {
 356                  $node->setKeyAttribute($this->key, $this->removeKeyItem);
 357              }
 358  
 359              if (true === $this->atLeastOne) {
 360                  $node->setMinNumberOfElements(1);
 361              }
 362  
 363              if ($this->default) {
 364                  $node->setDefaultValue($this->defaultValue);
 365              }
 366  
 367              if (false !== $this->addDefaultChildren) {
 368                  $node->setAddChildrenIfNoneSet($this->addDefaultChildren);
 369                  if ($this->prototype instanceof static && null === $this->prototype->prototype) {
 370                      $this->prototype->addDefaultsIfNotSet();
 371                  }
 372              }
 373  
 374              $this->prototype->parent = $node;
 375              $node->setPrototype($this->prototype->getNode());
 376          }
 377  
 378          $node->setAllowNewKeys($this->allowNewKeys);
 379          $node->addEquivalentValue(null, $this->nullEquivalent);
 380          $node->addEquivalentValue(true, $this->trueEquivalent);
 381          $node->addEquivalentValue(false, $this->falseEquivalent);
 382          $node->setPerformDeepMerging($this->performDeepMerging);
 383          $node->setRequired($this->required);
 384          $node->setIgnoreExtraKeys($this->ignoreExtraKeys, $this->removeExtraKeys);
 385          $node->setNormalizeKeys($this->normalizeKeys);
 386  
 387          if (null !== $this->normalization) {
 388              $node->setNormalizationClosures($this->normalization->before);
 389              $node->setXmlRemappings($this->normalization->remappings);
 390          }
 391  
 392          if (null !== $this->merge) {
 393              $node->setAllowOverwrite($this->merge->allowOverwrite);
 394              $node->setAllowFalse($this->merge->allowFalse);
 395          }
 396  
 397          if (null !== $this->validation) {
 398              $node->setFinalValidationClosures($this->validation->rules);
 399          }
 400  
 401          return $node;
 402      }
 403  
 404      /**
 405       * Validate the configuration of a concrete node.
 406       *
 407       * @throws InvalidDefinitionException
 408       */
 409      protected function validateConcreteNode(ArrayNode $node)
 410      {
 411          $path = $node->getPath();
 412  
 413          if (null !== $this->key) {
 414              throw new InvalidDefinitionException(sprintf('->useAttributeAsKey() is not applicable to concrete nodes at path "%s"', $path));
 415          }
 416  
 417          if (true === $this->atLeastOne) {
 418              throw new InvalidDefinitionException(sprintf('->requiresAtLeastOneElement() is not applicable to concrete nodes at path "%s"', $path));
 419          }
 420  
 421          if ($this->default) {
 422              throw new InvalidDefinitionException(sprintf('->defaultValue() is not applicable to concrete nodes at path "%s"', $path));
 423          }
 424  
 425          if (false !== $this->addDefaultChildren) {
 426              throw new InvalidDefinitionException(sprintf('->addDefaultChildrenIfNoneSet() is not applicable to concrete nodes at path "%s"', $path));
 427          }
 428      }
 429  
 430      /**
 431       * Validate the configuration of a prototype node.
 432       *
 433       * @throws InvalidDefinitionException
 434       */
 435      protected function validatePrototypeNode(PrototypedArrayNode $node)
 436      {
 437          $path = $node->getPath();
 438  
 439          if ($this->addDefaults) {
 440              throw new InvalidDefinitionException(sprintf('->addDefaultsIfNotSet() is not applicable to prototype nodes at path "%s"', $path));
 441          }
 442  
 443          if (false !== $this->addDefaultChildren) {
 444              if ($this->default) {
 445                  throw new InvalidDefinitionException(sprintf('A default value and default children might not be used together at path "%s"', $path));
 446              }
 447  
 448              if (null !== $this->key && (null === $this->addDefaultChildren || \is_int($this->addDefaultChildren) && $this->addDefaultChildren > 0)) {
 449                  throw new InvalidDefinitionException(sprintf('->addDefaultChildrenIfNoneSet() should set default children names as ->useAttributeAsKey() is used at path "%s"', $path));
 450              }
 451  
 452              if (null === $this->key && (\is_string($this->addDefaultChildren) || \is_array($this->addDefaultChildren))) {
 453                  throw new InvalidDefinitionException(sprintf('->addDefaultChildrenIfNoneSet() might not set default children names as ->useAttributeAsKey() is not used at path "%s"', $path));
 454              }
 455          }
 456      }
 457  }


Generated: Wed Nov 11 20:33:01 2020 Cross-referenced by PHPXref 0.7.1