/library/Zend/View/Model/ViewModel.php

https://github.com/christeredvartsen/zf2 · PHP · 439 lines · 183 code · 48 blank · 208 comment · 14 complexity · 7d431ed0657cd3ff5236a97a5eb9e782 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-2013 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. * @package Zend_View
  9. */
  10. namespace Zend\View\Model;
  11. use ArrayAccess;
  12. use ArrayIterator;
  13. use Traversable;
  14. use Zend\Stdlib\ArrayUtils;
  15. use Zend\View\Exception;
  16. use Zend\View\Model;
  17. use Zend\View\Variables as ViewVariables;
  18. /**
  19. * @category Zend
  20. * @package Zend_View
  21. * @subpackage Model
  22. */
  23. class ViewModel implements ModelInterface
  24. {
  25. /**
  26. * What variable a parent model should capture this model to
  27. *
  28. * @var string
  29. */
  30. protected $captureTo = 'content';
  31. /**
  32. * Child models
  33. * @var array
  34. */
  35. protected $children = array();
  36. /**
  37. * Renderer options
  38. * @var array
  39. */
  40. protected $options = array();
  41. /**
  42. * Template to use when rendering this model
  43. *
  44. * @var string
  45. */
  46. protected $template = '';
  47. /**
  48. * Is this a standalone, or terminal, model?
  49. *
  50. * @var bool
  51. */
  52. protected $terminate = false;
  53. /**
  54. * View variables
  55. * @var array|ArrayAccess&Traversable
  56. */
  57. protected $variables = array();
  58. /**
  59. * Is this append to child with the same capture?
  60. *
  61. * @var bool
  62. */
  63. protected $append = false;
  64. /**
  65. * Constructor
  66. *
  67. * @param null|array|Traversable $variables
  68. * @param array|Traversable $options
  69. */
  70. public function __construct($variables = null, $options = null)
  71. {
  72. if (null === $variables) {
  73. $variables = new ViewVariables();
  74. }
  75. // Initializing the variables container
  76. $this->setVariables($variables, true);
  77. if (null !== $options) {
  78. $this->setOptions($options);
  79. }
  80. }
  81. /**
  82. * Property overloading: set variable value
  83. *
  84. * @param string $name
  85. * @param mixed $value
  86. * @return void
  87. */
  88. public function __set($name, $value)
  89. {
  90. $this->setVariable($name, $value);
  91. }
  92. /**
  93. * Property overloading: get variable value
  94. *
  95. * @param string $name
  96. * @return mixed
  97. */
  98. public function __get($name)
  99. {
  100. if (!$this->__isset($name)) {
  101. return null;
  102. }
  103. $variables = $this->getVariables();
  104. return $variables[$name];
  105. }
  106. /**
  107. * Property overloading: do we have the requested variable value?
  108. *
  109. * @param string $name
  110. * @return bool
  111. */
  112. public function __isset($name)
  113. {
  114. $variables = $this->getVariables();
  115. return isset($variables[$name]);
  116. }
  117. /**
  118. * Property overloading: unset the requested variable
  119. *
  120. * @param string $name
  121. * @return void
  122. */
  123. public function __unset($name)
  124. {
  125. if (!$this->__isset($name)) {
  126. return null;
  127. }
  128. unset($this->variables[$name]);
  129. }
  130. /**
  131. * Set a single option
  132. *
  133. * @param string $name
  134. * @param mixed $value
  135. * @return ViewModel
  136. */
  137. public function setOption($name, $value)
  138. {
  139. $this->options[(string) $name] = $value;
  140. return $this;
  141. }
  142. /**
  143. * Get a single option
  144. *
  145. * @param string $name The option to get.
  146. * @param mixed|null $default (optional) A default value if the option is not yet set.
  147. * @return mixed
  148. */
  149. public function getOption($name, $default = null)
  150. {
  151. $name = (string) $name;
  152. return array_key_exists($name, $this->options) ? $this->options[$name] : $default;
  153. }
  154. /**
  155. * Set renderer options/hints en masse
  156. *
  157. * @param array|\Traversable $options
  158. * @throws \Zend\View\Exception\InvalidArgumentException
  159. * @return ViewModel
  160. */
  161. public function setOptions($options)
  162. {
  163. // Assumption is that lowest common denominator for renderer configuration
  164. // is an array
  165. if ($options instanceof Traversable) {
  166. $options = ArrayUtils::iteratorToArray($options);
  167. }
  168. if (!is_array($options)) {
  169. throw new Exception\InvalidArgumentException(sprintf(
  170. '%s: expects an array, or Traversable argument; received "%s"',
  171. __METHOD__,
  172. (is_object($options) ? get_class($options) : gettype($options))
  173. ));
  174. }
  175. $this->options = $options;
  176. return $this;
  177. }
  178. /**
  179. * Get renderer options/hints
  180. *
  181. * @return array
  182. */
  183. public function getOptions()
  184. {
  185. return $this->options;
  186. }
  187. /**
  188. * Get a single view variable
  189. *
  190. * @param string $name
  191. * @param mixed|null $default (optional) default value if the variable is not present.
  192. * @return mixed
  193. */
  194. public function getVariable($name, $default = null)
  195. {
  196. $name = (string) $name;
  197. if (array_key_exists($name, $this->variables)) {
  198. return $this->variables[$name];
  199. }
  200. return $default;
  201. }
  202. /**
  203. * Set view variable
  204. *
  205. * @param string $name
  206. * @param mixed $value
  207. * @return ViewModel
  208. */
  209. public function setVariable($name, $value)
  210. {
  211. $this->variables[(string) $name] = $value;
  212. return $this;
  213. }
  214. /**
  215. * Set view variables en masse
  216. *
  217. * Can be an array or a Traversable + ArrayAccess object.
  218. *
  219. * @param array|ArrayAccess|Traversable $variables
  220. * @param bool $overwrite Whether or not to overwrite the internal container with $variables
  221. * @throws Exception\InvalidArgumentException
  222. * @return ViewModel
  223. */
  224. public function setVariables($variables, $overwrite = false)
  225. {
  226. if (!is_array($variables) && !$variables instanceof Traversable) {
  227. throw new Exception\InvalidArgumentException(sprintf(
  228. '%s: expects an array, or Traversable argument; received "%s"',
  229. __METHOD__,
  230. (is_object($variables) ? get_class($variables) : gettype($variables))
  231. ));
  232. }
  233. if ($overwrite) {
  234. if (is_object($variables) && !$variables instanceof ArrayAccess) {
  235. $variables = ArrayUtils::iteratorToArray($variables);
  236. }
  237. $this->variables = $variables;
  238. return $this;
  239. }
  240. foreach ($variables as $key => $value) {
  241. $this->setVariable($key, $value);
  242. }
  243. return $this;
  244. }
  245. /**
  246. * Get view variables
  247. *
  248. * @return array|ArrayAccess|Traversable
  249. */
  250. public function getVariables()
  251. {
  252. return $this->variables;
  253. }
  254. /**
  255. * Set the template to be used by this model
  256. *
  257. * @param string $template
  258. * @return ViewModel
  259. */
  260. public function setTemplate($template)
  261. {
  262. $this->template = (string) $template;
  263. return $this;
  264. }
  265. /**
  266. * Get the template to be used by this model
  267. *
  268. * @return string
  269. */
  270. public function getTemplate()
  271. {
  272. return $this->template;
  273. }
  274. /**
  275. * Add a child model
  276. *
  277. * @param ModelInterface $child
  278. * @param null|string $captureTo Optional; if specified, the "capture to" value to set on the child
  279. * @param null|bool $append Optional; if specified, append to child with the same capture
  280. * @return ViewModel
  281. */
  282. public function addChild(ModelInterface $child, $captureTo = null, $append = null)
  283. {
  284. $this->children[] = $child;
  285. if (null !== $captureTo) {
  286. $child->setCaptureTo($captureTo);
  287. }
  288. if (null !== $captureTo) {
  289. $child->setAppend($append);
  290. }
  291. return $this;
  292. }
  293. /**
  294. * Return all children.
  295. *
  296. * Return specifies an array, but may be any iterable object.
  297. *
  298. * @return array
  299. */
  300. public function getChildren()
  301. {
  302. return $this->children;
  303. }
  304. /**
  305. * Does the model have any children?
  306. *
  307. * @return bool
  308. */
  309. public function hasChildren()
  310. {
  311. return (0 < count($this->children));
  312. }
  313. /**
  314. * Set the name of the variable to capture this model to, if it is a child model
  315. *
  316. * @param string $capture
  317. * @return ViewModel
  318. */
  319. public function setCaptureTo($capture)
  320. {
  321. $this->captureTo = (string) $capture;
  322. return $this;
  323. }
  324. /**
  325. * Get the name of the variable to which to capture this model
  326. *
  327. * @return string
  328. */
  329. public function captureTo()
  330. {
  331. return $this->captureTo;
  332. }
  333. /**
  334. * Set flag indicating whether or not this is considered a terminal or standalone model
  335. *
  336. * @param bool $terminate
  337. * @return ViewModel
  338. */
  339. public function setTerminal($terminate)
  340. {
  341. $this->terminate = (bool) $terminate;
  342. return $this;
  343. }
  344. /**
  345. * Is this considered a terminal or standalone model?
  346. *
  347. * @return bool
  348. */
  349. public function terminate()
  350. {
  351. return $this->terminate;
  352. }
  353. /**
  354. * Set flag indicating whether or not append to child with the same capture
  355. *
  356. * @param bool $append
  357. * @return ViewModel
  358. */
  359. public function setAppend($append)
  360. {
  361. $this->append = (bool) $append;
  362. return $this;
  363. }
  364. /**
  365. * Is this append to child with the same capture?
  366. *
  367. * @return bool
  368. */
  369. public function isAppend()
  370. {
  371. return $this->append;
  372. }
  373. /**
  374. * Return count of children
  375. *
  376. * @return int
  377. */
  378. public function count()
  379. {
  380. return count($this->children);
  381. }
  382. /**
  383. * Get iterator of children
  384. *
  385. * @return ArrayIterator
  386. */
  387. public function getIterator()
  388. {
  389. return new ArrayIterator($this->children);
  390. }
  391. }