3 * Zend Framework (http://framework.zend.com/)
5 * @link http://github.com/zendframework/zf2 for the canonical source repository
6 * @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
7 * @license http://framework.zend.com/license/new-bsd New BSD License
10 namespace Zend\Code\Generator
;
12 use Zend\Stdlib\ArrayObject
;
14 class ValueGenerator
extends AbstractGenerator
19 const TYPE_AUTO
= 'auto';
20 const TYPE_BOOLEAN
= 'boolean';
21 const TYPE_BOOL
= 'bool';
22 const TYPE_NUMBER
= 'number';
23 const TYPE_INTEGER
= 'integer';
24 const TYPE_INT
= 'int';
25 const TYPE_FLOAT
= 'float';
26 const TYPE_DOUBLE
= 'double';
27 const TYPE_STRING
= 'string';
28 const TYPE_ARRAY
= 'array';
29 const TYPE_CONSTANT
= 'constant';
30 const TYPE_NULL
= 'null';
31 const TYPE_OBJECT
= 'object';
32 const TYPE_OTHER
= 'other';
35 const OUTPUT_MULTIPLE_LINE
= 'multipleLine';
36 const OUTPUT_SINGLE_LINE
= 'singleLine';
41 protected $value = null;
46 protected $type = self
::TYPE_AUTO
;
51 protected $arrayDepth = 1;
56 protected $outputMode = self
::OUTPUT_MULTIPLE_LINE
;
61 protected $allowedTypes = null;
63 * Autodetectable constants
66 protected $constants = null;
71 * @param string $outputMode
72 * @param ArrayObject $constants
74 public function __construct($value = null, $type = self
::TYPE_AUTO
, $outputMode = self
::OUTPUT_MULTIPLE_LINE
, ArrayObject
$constants = null)
76 if ($value !== null) { // strict check is important here if $type = AUTO
77 $this->setValue($value);
79 if ($type !== self
::TYPE_AUTO
) {
80 $this->setType($type);
82 if ($outputMode !== self
::OUTPUT_MULTIPLE_LINE
) {
83 $this->setOutputMode($outputMode);
85 if ($constants !== null) {
86 $this->constants
= $constants;
88 $this->constants
= new ArrayObject();
94 * Init constant list by defined and magic constants
96 public function initEnvironmentConstants()
109 $constants = array_merge($constants, array_keys(get_defined_constants()), $this->constants
->getArrayCopy());
110 $this->constants
->exchangeArray($constants);
114 * Add constant to list
116 * @param string $constant
120 public function addConstant($constant)
122 $this->constants
->append($constant);
128 * Delete constant from constant list
130 * @param string $constant
134 public function deleteConstant($constant)
136 if (($index = array_search($constant, $this->constants
->getArrayCopy())) !== false) {
137 $this->constants
->offsetUnset($index);
140 return $index !== false;
144 * Return constant list
146 * @return ArrayObject
148 public function getConstants()
150 return $this->constants
;
156 public function isValidConstantType()
158 if ($this->type
== self
::TYPE_AUTO
) {
159 $type = $this->getAutoDeterminedType($this->value
);
164 // valid types for constants
165 $scalarTypes = array(
178 return in_array($type, $scalarTypes);
182 * @param mixed $value
183 * @return ValueGenerator
185 public function setValue($value)
187 $this->value
= $value;
194 public function getValue()
200 * @param string $type
201 * @return ValueGenerator
203 public function setType($type)
205 $this->type
= (string) $type;
212 public function getType()
218 * @param int $arrayDepth
219 * @return ValueGenerator
221 public function setArrayDepth($arrayDepth)
223 $this->arrayDepth
= (int) $arrayDepth;
230 public function getArrayDepth()
232 return $this->arrayDepth
;
236 * @param string $type
239 protected function getValidatedType($type)
258 if (in_array($type, $types)) {
262 return self
::TYPE_AUTO
;
266 * @param mixed $value
269 public function getAutoDeterminedType($value)
271 switch (gettype($value)) {
273 return self
::TYPE_BOOLEAN
;
275 foreach ($this->constants
as $constant) {
276 if (strpos($value, $constant) !== false) {
277 return self
::TYPE_CONSTANT
;
280 return self
::TYPE_STRING
;
284 return self
::TYPE_NUMBER
;
286 return self
::TYPE_ARRAY
;
288 return self
::TYPE_NULL
;
293 return self
::TYPE_OTHER
;
298 * @throws Exception\RuntimeException
301 public function generate()
305 if ($type != self
::TYPE_AUTO
) {
306 $type = $this->getValidatedType($type);
309 $value = $this->value
;
311 if ($type == self
::TYPE_AUTO
) {
312 $type = $this->getAutoDeterminedType($value);
314 if ($type == self
::TYPE_ARRAY
) {
315 $rii = new \
RecursiveIteratorIterator(
316 $it = new \
RecursiveArrayIterator($value),
317 \RecursiveIteratorIterator
::SELF_FIRST
319 foreach ($rii as $curKey => $curValue) {
320 if (!$curValue instanceof ValueGenerator
) {
321 $curValue = new self($curValue, self
::TYPE_AUTO
, self
::OUTPUT_MULTIPLE_LINE
, $this->getConstants());
322 $rii->getSubIterator()->offsetSet($curKey, $curValue);
324 $curValue->setArrayDepth($rii->getDepth());
326 $value = $rii->getSubIterator()->getArrayCopy();
334 case self
::TYPE_BOOLEAN
:
335 case self
::TYPE_BOOL
:
336 $output .= ($value ?
'true' : 'false');
338 case self
::TYPE_STRING
:
339 $output .= self
::escape($value);
341 case self
::TYPE_NULL
:
344 case self
::TYPE_NUMBER
:
345 case self
::TYPE_INTEGER
:
347 case self
::TYPE_FLOAT
:
348 case self
::TYPE_DOUBLE
:
349 case self
::TYPE_CONSTANT
:
352 case self
::TYPE_ARRAY
:
354 $curArrayMultiblock = false;
355 if (count($value) > 1) {
356 $curArrayMultiblock = true;
357 if ($this->outputMode
== self
::OUTPUT_MULTIPLE_LINE
) {
358 $output .= self
::LINE_FEED
. str_repeat($this->indentation
, $this->arrayDepth +
1);
361 $outputParts = array();
363 foreach ($value as $n => $v) {
364 /* @var $v ValueGenerator */
365 $v->setArrayDepth($this->arrayDepth +
1);
366 $partV = $v->generate();
369 if ($n === $noKeyIndex) {
373 $noKeyIndex = max($n +
1, $noKeyIndex);
378 $outputParts[] = $partV;
380 $outputParts[] = (is_int($n) ?
$n : self
::escape($n)) . ' => ' . $partV;
383 $padding = ($this->outputMode
== self
::OUTPUT_MULTIPLE_LINE
)
384 ? self
::LINE_FEED
. str_repeat($this->indentation
, $this->arrayDepth +
1)
386 $output .= implode(',' . $padding, $outputParts);
387 if ($curArrayMultiblock == true && $this->outputMode
== self
::OUTPUT_MULTIPLE_LINE
) {
388 $output .= self
::LINE_FEED
. str_repeat($this->indentation
, $this->arrayDepth +
1);
392 case self
::TYPE_OTHER
:
394 throw new Exception\
RuntimeException(sprintf(
395 'Type "%s" is unknown or cannot be used as property default value.',
404 * Quotes value for PHP code.
406 * @param string $input Raw string.
407 * @param bool $quote Whether add surrounding quotes or not.
408 * @return string PHP-ready code.
410 public static function escape($input, $quote = true)
412 $output = addcslashes($input, "'");
414 // adds quoting strings
416 $output = "'" . $output . "'";
423 * @param string $outputMode
424 * @return ValueGenerator
426 public function setOutputMode($outputMode)
428 $this->outputMode
= (string) $outputMode;
435 public function getOutputMode()
437 return $this->outputMode
;
440 public function __toString()
442 return $this->generate();