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. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
ValueGenerator.php
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