[ Index ]

PHP Cross Reference of phpBB-3.3.11-deutsch

title

Body

[close]

/vendor/symfony/config/Definition/ -> ArrayNode.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;
  13  
  14  use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
  15  use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
  16  use Symfony\Component\Config\Definition\Exception\UnsetKeyException;
  17  
  18  /**
  19   * Represents an Array node in the config tree.
  20   *
  21   * @author Johannes M. Schmitt <schmittjoh@gmail.com>
  22   */
  23  class ArrayNode extends BaseNode implements PrototypeNodeInterface
  24  {
  25      protected $xmlRemappings = [];
  26      protected $children = [];
  27      protected $allowFalse = false;
  28      protected $allowNewKeys = true;
  29      protected $addIfNotSet = false;
  30      protected $performDeepMerging = true;
  31      protected $ignoreExtraKeys = false;
  32      protected $removeExtraKeys = true;
  33      protected $normalizeKeys = true;
  34  
  35      public function setNormalizeKeys($normalizeKeys)
  36      {
  37          $this->normalizeKeys = (bool) $normalizeKeys;
  38      }
  39  
  40      /**
  41       * {@inheritdoc}
  42       *
  43       * Namely, you mostly have foo_bar in YAML while you have foo-bar in XML.
  44       * After running this method, all keys are normalized to foo_bar.
  45       *
  46       * If you have a mixed key like foo-bar_moo, it will not be altered.
  47       * The key will also not be altered if the target key already exists.
  48       */
  49      protected function preNormalize($value)
  50      {
  51          if (!$this->normalizeKeys || !\is_array($value)) {
  52              return $value;
  53          }
  54  
  55          $normalized = [];
  56  
  57          foreach ($value as $k => $v) {
  58              if (false !== strpos($k, '-') && false === strpos($k, '_') && !\array_key_exists($normalizedKey = str_replace('-', '_', $k), $value)) {
  59                  $normalized[$normalizedKey] = $v;
  60              } else {
  61                  $normalized[$k] = $v;
  62              }
  63          }
  64  
  65          return $normalized;
  66      }
  67  
  68      /**
  69       * Retrieves the children of this node.
  70       *
  71       * @return array The children
  72       */
  73      public function getChildren()
  74      {
  75          return $this->children;
  76      }
  77  
  78      /**
  79       * Sets the xml remappings that should be performed.
  80       *
  81       * @param array $remappings An array of the form [[string, string]]
  82       */
  83      public function setXmlRemappings(array $remappings)
  84      {
  85          $this->xmlRemappings = $remappings;
  86      }
  87  
  88      /**
  89       * Gets the xml remappings that should be performed.
  90       *
  91       * @return array an array of the form [[string, string]]
  92       */
  93      public function getXmlRemappings()
  94      {
  95          return $this->xmlRemappings;
  96      }
  97  
  98      /**
  99       * Sets whether to add default values for this array if it has not been
 100       * defined in any of the configuration files.
 101       *
 102       * @param bool $boolean
 103       */
 104      public function setAddIfNotSet($boolean)
 105      {
 106          $this->addIfNotSet = (bool) $boolean;
 107      }
 108  
 109      /**
 110       * Sets whether false is allowed as value indicating that the array should be unset.
 111       *
 112       * @param bool $allow
 113       */
 114      public function setAllowFalse($allow)
 115      {
 116          $this->allowFalse = (bool) $allow;
 117      }
 118  
 119      /**
 120       * Sets whether new keys can be defined in subsequent configurations.
 121       *
 122       * @param bool $allow
 123       */
 124      public function setAllowNewKeys($allow)
 125      {
 126          $this->allowNewKeys = (bool) $allow;
 127      }
 128  
 129      /**
 130       * Sets if deep merging should occur.
 131       *
 132       * @param bool $boolean
 133       */
 134      public function setPerformDeepMerging($boolean)
 135      {
 136          $this->performDeepMerging = (bool) $boolean;
 137      }
 138  
 139      /**
 140       * Whether extra keys should just be ignored without an exception.
 141       *
 142       * @param bool $boolean To allow extra keys
 143       * @param bool $remove  To remove extra keys
 144       */
 145      public function setIgnoreExtraKeys($boolean, $remove = true)
 146      {
 147          $this->ignoreExtraKeys = (bool) $boolean;
 148          $this->removeExtraKeys = $this->ignoreExtraKeys && $remove;
 149      }
 150  
 151      /**
 152       * {@inheritdoc}
 153       */
 154      public function setName($name)
 155      {
 156          $this->name = $name;
 157      }
 158  
 159      /**
 160       * {@inheritdoc}
 161       */
 162      public function hasDefaultValue()
 163      {
 164          return $this->addIfNotSet;
 165      }
 166  
 167      /**
 168       * {@inheritdoc}
 169       */
 170      public function getDefaultValue()
 171      {
 172          if (!$this->hasDefaultValue()) {
 173              throw new \RuntimeException(sprintf('The node at path "%s" has no default value.', $this->getPath()));
 174          }
 175  
 176          $defaults = [];
 177          foreach ($this->children as $name => $child) {
 178              if ($child->hasDefaultValue()) {
 179                  $defaults[$name] = $child->getDefaultValue();
 180              }
 181          }
 182  
 183          return $defaults;
 184      }
 185  
 186      /**
 187       * Adds a child node.
 188       *
 189       * @throws \InvalidArgumentException when the child node has no name
 190       * @throws \InvalidArgumentException when the child node's name is not unique
 191       */
 192      public function addChild(NodeInterface $node)
 193      {
 194          $name = $node->getName();
 195          if (!\strlen($name)) {
 196              throw new \InvalidArgumentException('Child nodes must be named.');
 197          }
 198          if (isset($this->children[$name])) {
 199              throw new \InvalidArgumentException(sprintf('A child node named "%s" already exists.', $name));
 200          }
 201  
 202          $this->children[$name] = $node;
 203      }
 204  
 205      /**
 206       * Finalizes the value of this node.
 207       *
 208       * @param mixed $value
 209       *
 210       * @return mixed The finalised value
 211       *
 212       * @throws UnsetKeyException
 213       * @throws InvalidConfigurationException if the node doesn't have enough children
 214       */
 215      protected function finalizeValue($value)
 216      {
 217          if (false === $value) {
 218              throw new UnsetKeyException(sprintf('Unsetting key for path "%s", value: "%s".', $this->getPath(), json_encode($value)));
 219          }
 220  
 221          foreach ($this->children as $name => $child) {
 222              if (!\array_key_exists($name, $value)) {
 223                  if ($child->isRequired()) {
 224                      $ex = new InvalidConfigurationException(sprintf('The child node "%s" at path "%s" must be configured.', $name, $this->getPath()));
 225                      $ex->setPath($this->getPath());
 226  
 227                      throw $ex;
 228                  }
 229  
 230                  if ($child->hasDefaultValue()) {
 231                      $value[$name] = $child->getDefaultValue();
 232                  }
 233  
 234                  continue;
 235              }
 236  
 237              if ($child->isDeprecated()) {
 238                  @trigger_error($child->getDeprecationMessage($name, $this->getPath()), \E_USER_DEPRECATED);
 239              }
 240  
 241              try {
 242                  $value[$name] = $child->finalize($value[$name]);
 243              } catch (UnsetKeyException $e) {
 244                  unset($value[$name]);
 245              }
 246          }
 247  
 248          return $value;
 249      }
 250  
 251      /**
 252       * Validates the type of the value.
 253       *
 254       * @param mixed $value
 255       *
 256       * @throws InvalidTypeException
 257       */
 258      protected function validateType($value)
 259      {
 260          if (!\is_array($value) && (!$this->allowFalse || false !== $value)) {
 261              $ex = new InvalidTypeException(sprintf('Invalid type for path "%s". Expected array, but got %s', $this->getPath(), \gettype($value)));
 262              if ($hint = $this->getInfo()) {
 263                  $ex->addHint($hint);
 264              }
 265              $ex->setPath($this->getPath());
 266  
 267              throw $ex;
 268          }
 269      }
 270  
 271      /**
 272       * Normalizes the value.
 273       *
 274       * @param mixed $value The value to normalize
 275       *
 276       * @return mixed The normalized value
 277       *
 278       * @throws InvalidConfigurationException
 279       */
 280      protected function normalizeValue($value)
 281      {
 282          if (false === $value) {
 283              return $value;
 284          }
 285  
 286          $value = $this->remapXml($value);
 287  
 288          $normalized = [];
 289          foreach ($value as $name => $val) {
 290              if (isset($this->children[$name])) {
 291                  try {
 292                      $normalized[$name] = $this->children[$name]->normalize($val);
 293                  } catch (UnsetKeyException $e) {
 294                  }
 295                  unset($value[$name]);
 296              } elseif (!$this->removeExtraKeys) {
 297                  $normalized[$name] = $val;
 298              }
 299          }
 300  
 301          // if extra fields are present, throw exception
 302          if (\count($value) && !$this->ignoreExtraKeys) {
 303              $ex = new InvalidConfigurationException(sprintf('Unrecognized option%s "%s" under "%s"', 1 === \count($value) ? '' : 's', implode(', ', array_keys($value)), $this->getPath()));
 304              $ex->setPath($this->getPath());
 305  
 306              throw $ex;
 307          }
 308  
 309          return $normalized;
 310      }
 311  
 312      /**
 313       * Remaps multiple singular values to a single plural value.
 314       *
 315       * @param array $value The source values
 316       *
 317       * @return array The remapped values
 318       */
 319      protected function remapXml($value)
 320      {
 321          foreach ($this->xmlRemappings as list($singular, $plural)) {
 322              if (!isset($value[$singular])) {
 323                  continue;
 324              }
 325  
 326              $value[$plural] = Processor::normalizeConfig($value, $singular, $plural);
 327              unset($value[$singular]);
 328          }
 329  
 330          return $value;
 331      }
 332  
 333      /**
 334       * Merges values together.
 335       *
 336       * @param mixed $leftSide  The left side to merge
 337       * @param mixed $rightSide The right side to merge
 338       *
 339       * @return mixed The merged values
 340       *
 341       * @throws InvalidConfigurationException
 342       * @throws \RuntimeException
 343       */
 344      protected function mergeValues($leftSide, $rightSide)
 345      {
 346          if (false === $rightSide) {
 347              // if this is still false after the last config has been merged the
 348              // finalization pass will take care of removing this key entirely
 349              return false;
 350          }
 351  
 352          if (false === $leftSide || !$this->performDeepMerging) {
 353              return $rightSide;
 354          }
 355  
 356          foreach ($rightSide as $k => $v) {
 357              // no conflict
 358              if (!\array_key_exists($k, $leftSide)) {
 359                  if (!$this->allowNewKeys) {
 360                      $ex = new InvalidConfigurationException(sprintf('You are not allowed to define new elements for path "%s". Please define all elements for this path in one config file. If you are trying to overwrite an element, make sure you redefine it with the same name.', $this->getPath()));
 361                      $ex->setPath($this->getPath());
 362  
 363                      throw $ex;
 364                  }
 365  
 366                  $leftSide[$k] = $v;
 367                  continue;
 368              }
 369  
 370              if (!isset($this->children[$k])) {
 371                  throw new \RuntimeException('merge() expects a normalized config array.');
 372              }
 373  
 374              $leftSide[$k] = $this->children[$k]->merge($leftSide[$k], $v);
 375          }
 376  
 377          return $leftSide;
 378      }
 379  }


Generated: Sat Nov 4 14:26:03 2023 Cross-referenced by PHPXref 0.7.1