PageRenderTime 49ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/zendframework/zendframework/library/Zend/Code/Generator/ValueGenerator.php

https://bitbucket.org/pcelta/zf2
PHP | 375 lines | 250 code | 33 blank | 92 comment | 26 complexity | fec91c1508b4b4c91fa5384897daba8d MD5 | raw file
  1. <?php
  2. /**
  3. * Zend Framework (http://framework.zend.com/)
  4. *
  5. * @link http://github.com/zendframework/zf2 for the canonical source repository
  6. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. * @package Zend_Code
  9. */
  10. namespace Zend\Code\Generator;
  11. class ValueGenerator extends AbstractGenerator
  12. {
  13. /**#@+
  14. * Constant values
  15. */
  16. const TYPE_AUTO = 'auto';
  17. const TYPE_BOOLEAN = 'boolean';
  18. const TYPE_BOOL = 'bool';
  19. const TYPE_NUMBER = 'number';
  20. const TYPE_INTEGER = 'integer';
  21. const TYPE_INT = 'int';
  22. const TYPE_FLOAT = 'float';
  23. const TYPE_DOUBLE = 'double';
  24. const TYPE_STRING = 'string';
  25. const TYPE_ARRAY = 'array';
  26. const TYPE_CONSTANT = 'constant';
  27. const TYPE_NULL = 'null';
  28. const TYPE_OBJECT = 'object';
  29. const TYPE_OTHER = 'other';
  30. /**#@-*/
  31. const OUTPUT_MULTIPLE_LINE = 'multipleLine';
  32. const OUTPUT_SINGLE_LINE = 'singleLine';
  33. /**
  34. * @var mixed
  35. */
  36. protected $value = null;
  37. /**
  38. * @var string
  39. */
  40. protected $type = self::TYPE_AUTO;
  41. /**
  42. * @var int
  43. */
  44. protected $arrayDepth = 1;
  45. /**
  46. * @var string
  47. */
  48. protected $outputMode = self::OUTPUT_MULTIPLE_LINE;
  49. /**
  50. * @var array
  51. */
  52. protected $allowedTypes = null;
  53. public function __construct($value = null, $type = self::TYPE_AUTO, $outputMode = self::OUTPUT_MULTIPLE_LINE)
  54. {
  55. if ($value !== null) { // strict check is important here if $type = AUTO
  56. $this->setValue($value);
  57. }
  58. if ($type !== self::TYPE_AUTO) {
  59. $this->setType($type);
  60. }
  61. if ($outputMode !== self::OUTPUT_MULTIPLE_LINE) {
  62. $this->setOutputMode($outputMode);
  63. }
  64. }
  65. /**
  66. * isValidConstantType()
  67. *
  68. * @return bool
  69. */
  70. public function isValidConstantType()
  71. {
  72. if ($this->type == self::TYPE_AUTO) {
  73. $type = $this->getAutoDeterminedType($this->value);
  74. } else {
  75. $type = $this->type;
  76. }
  77. // valid types for constants
  78. $scalarTypes = array(
  79. self::TYPE_BOOLEAN,
  80. self::TYPE_BOOL,
  81. self::TYPE_NUMBER,
  82. self::TYPE_INTEGER,
  83. self::TYPE_INT,
  84. self::TYPE_FLOAT,
  85. self::TYPE_DOUBLE,
  86. self::TYPE_STRING,
  87. self::TYPE_CONSTANT,
  88. self::TYPE_NULL
  89. );
  90. return in_array($type, $scalarTypes);
  91. }
  92. /**
  93. * setValue()
  94. *
  95. * @param mixed $value
  96. * @return ValueGenerator
  97. */
  98. public function setValue($value)
  99. {
  100. $this->value = $value;
  101. return $this;
  102. }
  103. /**
  104. * getValue()
  105. *
  106. * @return mixed
  107. */
  108. public function getValue()
  109. {
  110. return $this->value;
  111. }
  112. /**
  113. * setType()
  114. *
  115. * @param string $type
  116. * @return ValueGenerator
  117. */
  118. public function setType($type)
  119. {
  120. $this->type = $type;
  121. return $this;
  122. }
  123. /**
  124. * getType()
  125. *
  126. * @return string
  127. */
  128. public function getType()
  129. {
  130. return $this->type;
  131. }
  132. /**
  133. * setArrayDepth()
  134. *
  135. * @param int $arrayDepth
  136. * @return ValueGenerator
  137. */
  138. public function setArrayDepth($arrayDepth)
  139. {
  140. $this->arrayDepth = $arrayDepth;
  141. return $this;
  142. }
  143. /**
  144. * getArrayDepth()
  145. *
  146. * @return int
  147. */
  148. public function getArrayDepth()
  149. {
  150. return $this->arrayDepth;
  151. }
  152. /**
  153. * _getValidatedType()
  154. *
  155. * @param string $type
  156. * @return string
  157. */
  158. protected function getValidatedType($type)
  159. {
  160. $types = array(
  161. self::TYPE_AUTO,
  162. self::TYPE_BOOLEAN,
  163. self::TYPE_BOOL,
  164. self::TYPE_NUMBER,
  165. self::TYPE_INTEGER,
  166. self::TYPE_INT,
  167. self::TYPE_FLOAT,
  168. self::TYPE_DOUBLE,
  169. self::TYPE_STRING,
  170. self::TYPE_ARRAY,
  171. self::TYPE_CONSTANT,
  172. self::TYPE_NULL,
  173. self::TYPE_OBJECT,
  174. self::TYPE_OTHER
  175. );
  176. if (in_array($type, $types)) {
  177. return $type;
  178. }
  179. return self::TYPE_AUTO;
  180. }
  181. /**
  182. * _getAutoDeterminedType()
  183. *
  184. * @param mixed $value
  185. * @return string
  186. */
  187. public function getAutoDeterminedType($value)
  188. {
  189. switch (gettype($value)) {
  190. case 'boolean':
  191. return self::TYPE_BOOLEAN;
  192. case 'integer':
  193. return self::TYPE_INT;
  194. case 'string':
  195. return self::TYPE_STRING;
  196. case 'double':
  197. case 'float':
  198. case 'integer':
  199. return self::TYPE_NUMBER;
  200. case 'array':
  201. return self::TYPE_ARRAY;
  202. case 'NULL':
  203. return self::TYPE_NULL;
  204. case 'object':
  205. case 'resource':
  206. case 'unknown type':
  207. default:
  208. return self::TYPE_OTHER;
  209. }
  210. }
  211. /**
  212. * generate()
  213. *
  214. * @throws Exception\RuntimeException
  215. * @return string
  216. */
  217. public function generate()
  218. {
  219. $type = $this->type;
  220. if ($type != self::TYPE_AUTO) {
  221. $type = $this->getValidatedType($type);
  222. }
  223. $value = $this->value;
  224. if ($type == self::TYPE_AUTO) {
  225. $type = $this->getAutoDeterminedType($value);
  226. if ($type == self::TYPE_ARRAY) {
  227. $rii = new \RecursiveIteratorIterator(
  228. $it = new \RecursiveArrayIterator($value),
  229. \RecursiveIteratorIterator::SELF_FIRST
  230. );
  231. foreach ($rii as $curKey => $curValue) {
  232. if (!$curValue instanceof ValueGenerator) {
  233. $curValue = new self($curValue);
  234. $rii->getSubIterator()->offsetSet($curKey, $curValue);
  235. }
  236. $curValue->setArrayDepth($rii->getDepth());
  237. }
  238. $value = $rii->getSubIterator()->getArrayCopy();
  239. }
  240. }
  241. $output = '';
  242. switch ($type) {
  243. case self::TYPE_BOOLEAN:
  244. case self::TYPE_BOOL:
  245. $output .= ($value ? 'true' : 'false');
  246. break;
  247. case self::TYPE_STRING:
  248. $output .= self::escape($value);
  249. break;
  250. case self::TYPE_NULL:
  251. $output .= 'null';
  252. break;
  253. case self::TYPE_NUMBER:
  254. case self::TYPE_INTEGER:
  255. case self::TYPE_INT:
  256. case self::TYPE_FLOAT:
  257. case self::TYPE_DOUBLE:
  258. case self::TYPE_CONSTANT:
  259. $output .= $value;
  260. break;
  261. case self::TYPE_ARRAY:
  262. $output .= 'array(';
  263. $curArrayMultiblock = false;
  264. if (count($value) > 1) {
  265. $curArrayMultiblock = true;
  266. if ($this->outputMode == self::OUTPUT_MULTIPLE_LINE) {
  267. $output .= self::LINE_FEED . str_repeat($this->indentation, $this->arrayDepth + 1);
  268. }
  269. }
  270. $outputParts = array();
  271. $noKeyIndex = 0;
  272. foreach ($value as $n => $v) {
  273. /* @var $v ValueGenerator */
  274. $v->setArrayDepth($this->arrayDepth + 1);
  275. $partV = $v->generate();
  276. if ($n === $noKeyIndex) {
  277. $outputParts[] = $partV;
  278. $noKeyIndex++;
  279. } else {
  280. $outputParts[] = (is_int($n) ? $n : self::escape($n)) . ' => ' . $partV;
  281. }
  282. }
  283. $padding = ($this->outputMode == self::OUTPUT_MULTIPLE_LINE)
  284. ? self::LINE_FEED . str_repeat($this->indentation, $this->arrayDepth + 1)
  285. : ' ';
  286. $output .= implode(',' . $padding, $outputParts);
  287. if ($curArrayMultiblock == true && $this->outputMode == self::OUTPUT_MULTIPLE_LINE) {
  288. $output .= self::LINE_FEED . str_repeat($this->indentation, $this->arrayDepth + 1);
  289. }
  290. $output .= ')';
  291. break;
  292. case self::TYPE_OTHER:
  293. default:
  294. throw new Exception\RuntimeException(
  295. "Type '" . get_class($value) . "' is unknown or cannot be used as property default value."
  296. );
  297. }
  298. return $output;
  299. }
  300. /**
  301. * Quotes value for PHP code.
  302. *
  303. * @param string $input Raw string.
  304. * @param bool $quote Whether add surrounding quotes or not.
  305. * @return string PHP-ready code.
  306. */
  307. public static function escape($input, $quote = true)
  308. {
  309. $output = addcslashes($input, "'");
  310. // adds quoting strings
  311. if ($quote) {
  312. $output = "'" . $output . "'";
  313. }
  314. return $output;
  315. }
  316. /**
  317. * @param string $outputMode
  318. * @return ValueGenerator
  319. */
  320. public function setOutputMode($outputMode)
  321. {
  322. $this->outputMode = $outputMode;
  323. return $this;
  324. }
  325. /**
  326. * @return string
  327. */
  328. public function getOutputMode()
  329. {
  330. return $this->outputMode;
  331. }
  332. public function __toString()
  333. {
  334. return $this->generate();
  335. }
  336. }