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