Verzeichnisstruktur phpBB-3.3.15


Veröffentlicht
28.08.2024

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

ValueGenerator.php

Zuletzt modifiziert: 02.04.2025, 15:03 - Dateigröße: 12.72 KiB


001  <?php
002  /**
003   * Zend Framework (http://framework.zend.com/)
004   *
005   * @link      http://github.com/zendframework/zf2 for the canonical source repository
006   * @copyright Copyright (c) 2005-2016 Zend Technologies USA Inc. (http://www.zend.com)
007   * @license   http://framework.zend.com/license/new-bsd New BSD License
008   */
009   
010  namespace Zend\Code\Generator;
011   
012  use ArrayObject as SplArrayObject;
013  use Zend\Code\Exception\InvalidArgumentException;
014  use Zend\Stdlib\ArrayObject as StdlibArrayObject;
015   
016  use function addcslashes;
017  use function array_keys;
018  use function array_merge;
019  use function array_search;
020  use function count;
021  use function get_class;
022  use function get_defined_constants;
023  use function gettype;
024  use function implode;
025  use function in_array;
026  use function is_array;
027  use function is_int;
028  use function is_object;
029  use function max;
030  use function sprintf;
031  use function str_repeat;
032  use function strpos;
033   
034  class ValueGenerator extends AbstractGenerator
035  {
036      /**#@+
037       * Constant values
038       */
039      const TYPE_AUTO        = 'auto';
040      const TYPE_BOOLEAN     = 'boolean';
041      const TYPE_BOOL        = 'bool';
042      const TYPE_NUMBER      = 'number';
043      const TYPE_INTEGER     = 'integer';
044      const TYPE_INT         = 'int';
045      const TYPE_FLOAT       = 'float';
046      const TYPE_DOUBLE      = 'double';
047      const TYPE_STRING      = 'string';
048      const TYPE_ARRAY       = 'array';
049      const TYPE_ARRAY_SHORT = 'array_short';
050      const TYPE_ARRAY_LONG  = 'array_long';
051      const TYPE_CONSTANT    = 'constant';
052      const TYPE_NULL        = 'null';
053      const TYPE_OBJECT      = 'object';
054      const TYPE_OTHER       = 'other';
055      /**#@-*/
056   
057      const OUTPUT_MULTIPLE_LINE = 'multipleLine';
058      const OUTPUT_SINGLE_LINE   = 'singleLine';
059   
060      /**
061       * @var mixed
062       */
063      protected $value;
064   
065      /**
066       * @var string
067       */
068      protected $type = self::TYPE_AUTO;
069   
070      /**
071       * @var int
072       */
073      protected $arrayDepth = 0;
074   
075      /**
076       * @var string
077       */
078      protected $outputMode = self::OUTPUT_MULTIPLE_LINE;
079   
080      /**
081       * @var array
082       */
083      protected $allowedTypes;
084   
085      /**
086       * Autodetectable constants
087       *
088       * @var SplArrayObject|StdlibArrayObject
089       */
090      protected $constants;
091   
092      /**
093       * @param mixed       $value
094       * @param string      $type
095       * @param string      $outputMode
096       * @param null|SplArrayObject|StdlibArrayObject $constants
097       */
098      public function __construct(
099          $value = null,
100          $type = self::TYPE_AUTO,
101          $outputMode = self::OUTPUT_MULTIPLE_LINE,
102          $constants = null
103      ) {
104          // strict check is important here if $type = AUTO
105          if ($value !== null) {
106              $this->setValue($value);
107          }
108          if ($type !== self::TYPE_AUTO) {
109              $this->setType($type);
110          }
111          if ($outputMode !== self::OUTPUT_MULTIPLE_LINE) {
112              $this->setOutputMode($outputMode);
113          }
114          if ($constants === null) {
115              $constants = new SplArrayObject();
116          } elseif (! ($constants instanceof SplArrayObject || $constants instanceof StdlibArrayObject)) {
117              throw new InvalidArgumentException(
118                  '$constants must be an instance of ArrayObject or Zend\Stdlib\ArrayObject'
119              );
120          }
121          $this->constants = $constants;
122      }
123   
124      /**
125       * Init constant list by defined and magic constants
126       */
127      public function initEnvironmentConstants()
128      {
129          $constants   = [
130              '__DIR__',
131              '__FILE__',
132              '__LINE__',
133              '__CLASS__',
134              '__TRAIT__',
135              '__METHOD__',
136              '__FUNCTION__',
137              '__NAMESPACE__',
138              '::',
139          ];
140          $constants = array_merge($constants, array_keys(get_defined_constants()), $this->constants->getArrayCopy());
141          $this->constants->exchangeArray($constants);
142      }
143   
144      /**
145       * Add constant to list
146       *
147       * @param string $constant
148       *
149       * @return $this
150       */
151      public function addConstant($constant)
152      {
153          $this->constants->append($constant);
154   
155          return $this;
156      }
157   
158      /**
159       * Delete constant from constant list
160       *
161       * @param string $constant
162       *
163       * @return bool
164       */
165      public function deleteConstant($constant)
166      {
167          if (($index = array_search($constant, $this->constants->getArrayCopy())) !== false) {
168              $this->constants->offsetUnset($index);
169          }
170   
171          return $index !== false;
172      }
173   
174      /**
175       * Return constant list
176       *
177       * @return SplArrayObject|StdlibArrayObject
178       */
179      public function getConstants()
180      {
181          return $this->constants;
182      }
183   
184      /**
185       * @return bool
186       */
187      public function isValidConstantType()
188      {
189          if ($this->type === self::TYPE_AUTO) {
190              $type = $this->getAutoDeterminedType($this->value);
191          } else {
192              $type = $this->type;
193          }
194   
195          $validConstantTypes = [
196              self::TYPE_ARRAY,
197              self::TYPE_ARRAY_LONG,
198              self::TYPE_ARRAY_SHORT,
199              self::TYPE_BOOLEAN,
200              self::TYPE_BOOL,
201              self::TYPE_NUMBER,
202              self::TYPE_INTEGER,
203              self::TYPE_INT,
204              self::TYPE_FLOAT,
205              self::TYPE_DOUBLE,
206              self::TYPE_STRING,
207              self::TYPE_CONSTANT,
208              self::TYPE_NULL,
209          ];
210   
211          return in_array($type, $validConstantTypes);
212      }
213   
214      /**
215       * @param  mixed $value
216       * @return ValueGenerator
217       */
218      public function setValue($value)
219      {
220          $this->value = $value;
221          return $this;
222      }
223   
224      /**
225       * @return mixed
226       */
227      public function getValue()
228      {
229          return $this->value;
230      }
231   
232      /**
233       * @param  string $type
234       * @return ValueGenerator
235       */
236      public function setType($type)
237      {
238          $this->type = (string) $type;
239          return $this;
240      }
241   
242      /**
243       * @return string
244       */
245      public function getType()
246      {
247          return $this->type;
248      }
249   
250      /**
251       * @param  int $arrayDepth
252       * @return ValueGenerator
253       */
254      public function setArrayDepth($arrayDepth)
255      {
256          $this->arrayDepth = (int) $arrayDepth;
257          return $this;
258      }
259   
260      /**
261       * @return int
262       */
263      public function getArrayDepth()
264      {
265          return $this->arrayDepth;
266      }
267   
268      /**
269       * @param  string $type
270       * @return string
271       */
272      protected function getValidatedType($type)
273      {
274          $types = [
275              self::TYPE_AUTO,
276              self::TYPE_BOOLEAN,
277              self::TYPE_BOOL,
278              self::TYPE_NUMBER,
279              self::TYPE_INTEGER,
280              self::TYPE_INT,
281              self::TYPE_FLOAT,
282              self::TYPE_DOUBLE,
283              self::TYPE_STRING,
284              self::TYPE_ARRAY,
285              self::TYPE_ARRAY_SHORT,
286              self::TYPE_ARRAY_LONG,
287              self::TYPE_CONSTANT,
288              self::TYPE_NULL,
289              self::TYPE_OBJECT,
290              self::TYPE_OTHER,
291          ];
292   
293          if (in_array($type, $types)) {
294              return $type;
295          }
296   
297          return self::TYPE_AUTO;
298      }
299   
300      /**
301       * @param  mixed $value
302       * @return string
303       */
304      public function getAutoDeterminedType($value)
305      {
306          switch (gettype($value)) {
307              case 'boolean':
308                  return self::TYPE_BOOLEAN;
309              case 'string':
310                  foreach ($this->constants as $constant) {
311                      if (strpos($value, $constant) !== false) {
312                          return self::TYPE_CONSTANT;
313                      }
314                  }
315                  return self::TYPE_STRING;
316              case 'double':
317              case 'float':
318              case 'integer':
319                  return self::TYPE_NUMBER;
320              case 'array':
321                  return self::TYPE_ARRAY;
322              case 'NULL':
323                  return self::TYPE_NULL;
324              case 'object':
325              case 'resource':
326              case 'unknown type':
327              default:
328                  return self::TYPE_OTHER;
329          }
330      }
331   
332      /**
333       * @throws Exception\RuntimeException
334       * @return string
335       */
336      public function generate()
337      {
338          $type = $this->type;
339   
340          if ($type !== self::TYPE_AUTO) {
341              $type = $this->getValidatedType($type);
342          }
343   
344          $value = $this->value;
345   
346          if ($type === self::TYPE_AUTO) {
347              $type = $this->getAutoDeterminedType($value);
348          }
349   
350          $isArrayType = in_array($type, [self::TYPE_ARRAY, self::TYPE_ARRAY_LONG, self::TYPE_ARRAY_SHORT]);
351   
352          if ($isArrayType) {
353              foreach ($value as &$curValue) {
354                  if ($curValue instanceof self) {
355                      continue;
356                  }
357   
358                  if (is_array($curValue)) {
359                      $newType = $type;
360                  } else {
361                      $newType = self::TYPE_AUTO;
362                  }
363   
364                  $curValue = new self($curValue, $newType, self::OUTPUT_MULTIPLE_LINE, $this->getConstants());
365                  $curValue->setIndentation($this->indentation);
366              }
367          }
368   
369          $output = '';
370   
371          switch ($type) {
372              case self::TYPE_BOOLEAN:
373              case self::TYPE_BOOL:
374                  $output .= $value ? 'true' : 'false';
375                  break;
376              case self::TYPE_STRING:
377                  $output .= self::escape($value);
378                  break;
379              case self::TYPE_NULL:
380                  $output .= 'null';
381                  break;
382              case self::TYPE_NUMBER:
383              case self::TYPE_INTEGER:
384              case self::TYPE_INT:
385              case self::TYPE_FLOAT:
386              case self::TYPE_DOUBLE:
387              case self::TYPE_CONSTANT:
388                  $output .= $value;
389                  break;
390              case self::TYPE_ARRAY:
391              case self::TYPE_ARRAY_LONG:
392              case self::TYPE_ARRAY_SHORT:
393                  if ($type === self::TYPE_ARRAY_LONG) {
394                      $startArray = 'array(';
395                      $endArray   = ')';
396                  } else {
397                      $startArray = '[';
398                      $endArray = ']';
399                  }
400   
401                  $output .= $startArray;
402                  if ($this->outputMode == self::OUTPUT_MULTIPLE_LINE) {
403                      $output .= self::LINE_FEED . str_repeat($this->indentation, $this->arrayDepth + 1);
404                  }
405                  $outputParts = [];
406                  $noKeyIndex  = 0;
407                  foreach ($value as $n => $v) {
408                      /* @var $v ValueGenerator */
409                      $v->setArrayDepth($this->arrayDepth + 1);
410                      $partV = $v->generate();
411                      $short = false;
412                      if (is_int($n)) {
413                          if ($n === $noKeyIndex) {
414                              $short = true;
415                              $noKeyIndex++;
416                          } else {
417                              $noKeyIndex = max($n + 1, $noKeyIndex);
418                          }
419                      }
420   
421                      if ($short) {
422                          $outputParts[] = $partV;
423                      } else {
424                          $outputParts[] = (is_int($n) ? $n : self::escape($n)) . ' => ' . $partV;
425                      }
426                  }
427                  $padding = $this->outputMode == self::OUTPUT_MULTIPLE_LINE
428                      ? self::LINE_FEED . str_repeat($this->indentation, $this->arrayDepth + 1)
429                      : ' ';
430                  $output .= implode(',' . $padding, $outputParts);
431                  if ($this->outputMode == self::OUTPUT_MULTIPLE_LINE) {
432                      if (count($outputParts) > 0) {
433                          $output .= ',';
434                      }
435                      $output .= self::LINE_FEED . str_repeat($this->indentation, $this->arrayDepth);
436                  }
437                  $output .= $endArray;
438                  break;
439              case self::TYPE_OTHER:
440              default:
441                  throw new Exception\RuntimeException(sprintf(
442                      'Type "%s" is unknown or cannot be used as property default value.',
443                      is_object($value) ? get_class($value) : gettype($value)
444                  ));
445          }
446   
447          return $output;
448      }
449   
450      /**
451       * Quotes value for PHP code.
452       *
453       * @param  string $input Raw string.
454       * @param  bool $quote Whether add surrounding quotes or not.
455       * @return string PHP-ready code.
456       */
457      public static function escape($input, $quote = true)
458      {
459          $output = addcslashes($input, "\\'");
460   
461          // adds quoting strings
462          if ($quote) {
463              $output = "'" . $output . "'";
464          }
465   
466          return $output;
467      }
468   
469      /**
470       * @param  string $outputMode
471       * @return ValueGenerator
472       */
473      public function setOutputMode($outputMode)
474      {
475          $this->outputMode = (string) $outputMode;
476          return $this;
477      }
478   
479      /**
480       * @return string
481       */
482      public function getOutputMode()
483      {
484          return $this->outputMode;
485      }
486   
487      public function __toString()
488      {
489          return $this->generate();
490      }
491  }
492