Verzeichnisstruktur phpBB-3.2.0


Veröffentlicht
06.01.2017

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

      (Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

ArrayNode.php

Zuletzt modifiziert: 09.10.2024, 12:56 - Dateigröße: 11.13 KiB


 001  <?php
 002   
 003  /*
 004   * This file is part of the Symfony package.
 005   *
 006   * (c) Fabien Potencier <fabien@symfony.com>
 007   *
 008   * For the full copyright and license information, please view the LICENSE
 009   * file that was distributed with this source code.
 010   */
 011   
 012  namespace Symfony\Component\Config\Definition;
 013   
 014  use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
 015  use Symfony\Component\Config\Definition\Exception\InvalidTypeException;
 016  use Symfony\Component\Config\Definition\Exception\UnsetKeyException;
 017   
 018  /**
 019   * Represents an Array node in the config tree.
 020   *
 021   * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 022   */
 023  class ArrayNode extends BaseNode implements PrototypeNodeInterface
 024  {
 025      protected $xmlRemappings = array();
 026      protected $children = array();
 027      protected $allowFalse = false;
 028      protected $allowNewKeys = true;
 029      protected $addIfNotSet = false;
 030      protected $performDeepMerging = true;
 031      protected $ignoreExtraKeys = false;
 032      protected $removeExtraKeys = true;
 033      protected $normalizeKeys = true;
 034   
 035      public function setNormalizeKeys($normalizeKeys)
 036      {
 037          $this->normalizeKeys = (bool) $normalizeKeys;
 038      }
 039   
 040      /**
 041       * Normalizes keys between the different configuration formats.
 042       *
 043       * Namely, you mostly have foo_bar in YAML while you have foo-bar in XML.
 044       * After running this method, all keys are normalized to foo_bar.
 045       *
 046       * If you have a mixed key like foo-bar_moo, it will not be altered.
 047       * The key will also not be altered if the target key already exists.
 048       *
 049       * @param mixed $value
 050       *
 051       * @return array The value with normalized keys
 052       */
 053      protected function preNormalize($value)
 054      {
 055          if (!$this->normalizeKeys || !is_array($value)) {
 056              return $value;
 057          }
 058   
 059          $normalized = array();
 060   
 061          foreach ($value as $k => $v) {
 062              if (false !== strpos($k, '-') && false === strpos($k, '_') && !array_key_exists($normalizedKey = str_replace('-', '_', $k), $value)) {
 063                  $normalized[$normalizedKey] = $v;
 064              } else {
 065                  $normalized[$k] = $v;
 066              }
 067          }
 068   
 069          return $normalized;
 070      }
 071   
 072      /**
 073       * Retrieves the children of this node.
 074       *
 075       * @return array The children
 076       */
 077      public function getChildren()
 078      {
 079          return $this->children;
 080      }
 081   
 082      /**
 083       * Sets the xml remappings that should be performed.
 084       *
 085       * @param array $remappings an array of the form array(array(string, string))
 086       */
 087      public function setXmlRemappings(array $remappings)
 088      {
 089          $this->xmlRemappings = $remappings;
 090      }
 091   
 092      /**
 093       * Gets the xml remappings that should be performed.
 094       *
 095       * @return array $remappings an array of the form array(array(string, string))
 096       */
 097      public function getXmlRemappings()
 098      {
 099          return $this->xmlRemappings;
 100      }
 101   
 102      /**
 103       * Sets whether to add default values for this array if it has not been
 104       * defined in any of the configuration files.
 105       *
 106       * @param bool $boolean
 107       */
 108      public function setAddIfNotSet($boolean)
 109      {
 110          $this->addIfNotSet = (bool) $boolean;
 111      }
 112   
 113      /**
 114       * Sets whether false is allowed as value indicating that the array should be unset.
 115       *
 116       * @param bool $allow
 117       */
 118      public function setAllowFalse($allow)
 119      {
 120          $this->allowFalse = (bool) $allow;
 121      }
 122   
 123      /**
 124       * Sets whether new keys can be defined in subsequent configurations.
 125       *
 126       * @param bool $allow
 127       */
 128      public function setAllowNewKeys($allow)
 129      {
 130          $this->allowNewKeys = (bool) $allow;
 131      }
 132   
 133      /**
 134       * Sets if deep merging should occur.
 135       *
 136       * @param bool $boolean
 137       */
 138      public function setPerformDeepMerging($boolean)
 139      {
 140          $this->performDeepMerging = (bool) $boolean;
 141      }
 142   
 143      /**
 144       * Whether extra keys should just be ignore without an exception.
 145       *
 146       * @param bool $boolean To allow extra keys
 147       * @param bool $remove  To remove extra keys
 148       */
 149      public function setIgnoreExtraKeys($boolean, $remove = true)
 150      {
 151          $this->ignoreExtraKeys = (bool) $boolean;
 152          $this->removeExtraKeys = $this->ignoreExtraKeys && $remove;
 153      }
 154   
 155      /**
 156       * Sets the node Name.
 157       *
 158       * @param string $name The node's name
 159       */
 160      public function setName($name)
 161      {
 162          $this->name = $name;
 163      }
 164   
 165      /**
 166       * Checks if the node has a default value.
 167       *
 168       * @return bool
 169       */
 170      public function hasDefaultValue()
 171      {
 172          return $this->addIfNotSet;
 173      }
 174   
 175      /**
 176       * Retrieves the default value.
 177       *
 178       * @return array The default value
 179       *
 180       * @throws \RuntimeException if the node has no default value
 181       */
 182      public function getDefaultValue()
 183      {
 184          if (!$this->hasDefaultValue()) {
 185              throw new \RuntimeException(sprintf('The node at path "%s" has no default value.', $this->getPath()));
 186          }
 187   
 188          $defaults = array();
 189          foreach ($this->children as $name => $child) {
 190              if ($child->hasDefaultValue()) {
 191                  $defaults[$name] = $child->getDefaultValue();
 192              }
 193          }
 194   
 195          return $defaults;
 196      }
 197   
 198      /**
 199       * Adds a child node.
 200       *
 201       * @param NodeInterface $node The child node to add
 202       *
 203       * @throws \InvalidArgumentException when the child node has no name
 204       * @throws \InvalidArgumentException when the child node's name is not unique
 205       */
 206      public function addChild(NodeInterface $node)
 207      {
 208          $name = $node->getName();
 209          if (!strlen($name)) {
 210              throw new \InvalidArgumentException('Child nodes must be named.');
 211          }
 212          if (isset($this->children[$name])) {
 213              throw new \InvalidArgumentException(sprintf('A child node named "%s" already exists.', $name));
 214          }
 215   
 216          $this->children[$name] = $node;
 217      }
 218   
 219      /**
 220       * Finalizes the value of this node.
 221       *
 222       * @param mixed $value
 223       *
 224       * @return mixed The finalised value
 225       *
 226       * @throws UnsetKeyException
 227       * @throws InvalidConfigurationException if the node doesn't have enough children
 228       */
 229      protected function finalizeValue($value)
 230      {
 231          if (false === $value) {
 232              $msg = sprintf('Unsetting key for path "%s", value: %s', $this->getPath(), json_encode($value));
 233              throw new UnsetKeyException($msg);
 234          }
 235   
 236          foreach ($this->children as $name => $child) {
 237              if (!array_key_exists($name, $value)) {
 238                  if ($child->isRequired()) {
 239                      $msg = sprintf('The child node "%s" at path "%s" must be configured.', $name, $this->getPath());
 240                      $ex = new InvalidConfigurationException($msg);
 241                      $ex->setPath($this->getPath());
 242   
 243                      throw $ex;
 244                  }
 245   
 246                  if ($child->hasDefaultValue()) {
 247                      $value[$name] = $child->getDefaultValue();
 248                  }
 249   
 250                  continue;
 251              }
 252   
 253              try {
 254                  $value[$name] = $child->finalize($value[$name]);
 255              } catch (UnsetKeyException $e) {
 256                  unset($value[$name]);
 257              }
 258          }
 259   
 260          return $value;
 261      }
 262   
 263      /**
 264       * Validates the type of the value.
 265       *
 266       * @param mixed $value
 267       *
 268       * @throws InvalidTypeException
 269       */
 270      protected function validateType($value)
 271      {
 272          if (!is_array($value) && (!$this->allowFalse || false !== $value)) {
 273              $ex = new InvalidTypeException(sprintf(
 274                  'Invalid type for path "%s". Expected array, but got %s',
 275                  $this->getPath(),
 276                  gettype($value)
 277              ));
 278              if ($hint = $this->getInfo()) {
 279                  $ex->addHint($hint);
 280              }
 281              $ex->setPath($this->getPath());
 282   
 283              throw $ex;
 284          }
 285      }
 286   
 287      /**
 288       * Normalizes the value.
 289       *
 290       * @param mixed $value The value to normalize
 291       *
 292       * @return mixed The normalized value
 293       *
 294       * @throws InvalidConfigurationException
 295       */
 296      protected function normalizeValue($value)
 297      {
 298          if (false === $value) {
 299              return $value;
 300          }
 301   
 302          $value = $this->remapXml($value);
 303   
 304          $normalized = array();
 305          foreach ($value as $name => $val) {
 306              if (isset($this->children[$name])) {
 307                  $normalized[$name] = $this->children[$name]->normalize($val);
 308                  unset($value[$name]);
 309              } elseif (!$this->removeExtraKeys) {
 310                  $normalized[$name] = $val;
 311              }
 312          }
 313   
 314          // if extra fields are present, throw exception
 315          if (count($value) && !$this->ignoreExtraKeys) {
 316              $msg = sprintf('Unrecognized option%s "%s" under "%s"', 1 === count($value) ? '' : 's', implode(', ', array_keys($value)), $this->getPath());
 317              $ex = new InvalidConfigurationException($msg);
 318              $ex->setPath($this->getPath());
 319   
 320              throw $ex;
 321          }
 322   
 323          return $normalized;
 324      }
 325   
 326      /**
 327       * Remaps multiple singular values to a single plural value.
 328       *
 329       * @param array $value The source values
 330       *
 331       * @return array The remapped values
 332       */
 333      protected function remapXml($value)
 334      {
 335          foreach ($this->xmlRemappings as $transformation) {
 336              list($singular, $plural) = $transformation;
 337   
 338              if (!isset($value[$singular])) {
 339                  continue;
 340              }
 341   
 342              $value[$plural] = Processor::normalizeConfig($value, $singular, $plural);
 343              unset($value[$singular]);
 344          }
 345   
 346          return $value;
 347      }
 348   
 349      /**
 350       * Merges values together.
 351       *
 352       * @param mixed $leftSide  The left side to merge
 353       * @param mixed $rightSide The right side to merge
 354       *
 355       * @return mixed The merged values
 356       *
 357       * @throws InvalidConfigurationException
 358       * @throws \RuntimeException
 359       */
 360      protected function mergeValues($leftSide, $rightSide)
 361      {
 362          if (false === $rightSide) {
 363              // if this is still false after the last config has been merged the
 364              // finalization pass will take care of removing this key entirely
 365              return false;
 366          }
 367   
 368          if (false === $leftSide || !$this->performDeepMerging) {
 369              return $rightSide;
 370          }
 371   
 372          foreach ($rightSide as $k => $v) {
 373              // no conflict
 374              if (!array_key_exists($k, $leftSide)) {
 375                  if (!$this->allowNewKeys) {
 376                      $ex = new InvalidConfigurationException(sprintf(
 377                          'You are not allowed to define new elements for path "%s". '
 378                         .'Please define all elements for this path in one config file. '
 379                         .'If you are trying to overwrite an element, make sure you redefine it '
 380                         .'with the same name.',
 381                          $this->getPath()
 382                      ));
 383                      $ex->setPath($this->getPath());
 384   
 385                      throw $ex;
 386                  }
 387   
 388                  $leftSide[$k] = $v;
 389                  continue;
 390              }
 391   
 392              if (!isset($this->children[$k])) {
 393                  throw new \RuntimeException('merge() expects a normalized config array.');
 394              }
 395   
 396              $leftSide[$k] = $this->children[$k]->merge($leftSide[$k], $v);
 397          }
 398   
 399          return $leftSide;
 400      }
 401  }
 402