/library/Zend/View/Helper/Placeholder/Container/AbstractContainer.php

https://github.com/timdev/zf2 · PHP · 379 lines · 169 code · 40 blank · 170 comment · 18 complexity · 56b5358575c9a6495738fd83c412b8ce 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. */
  9. namespace Zend\View\Helper\Placeholder\Container;
  10. use ArrayObject;
  11. use Zend\View\Exception;
  12. /**
  13. * Abstract class representing container for placeholder values
  14. */
  15. abstract class AbstractContainer extends ArrayObject
  16. {
  17. /**
  18. * Whether or not to override all contents of placeholder
  19. *
  20. * @const string
  21. */
  22. const SET = 'SET';
  23. /**
  24. * Whether or not to append contents to placeholder
  25. *
  26. * @const string
  27. */
  28. const APPEND = 'APPEND';
  29. /**
  30. * Whether or not to prepend contents to placeholder
  31. *
  32. * @const string
  33. */
  34. const PREPEND = 'PREPEND';
  35. /**
  36. * Key to which to capture content
  37. *
  38. * @var string
  39. */
  40. protected $captureKey;
  41. /**
  42. * Whether or not we're already capturing for this given container
  43. *
  44. * @var bool
  45. */
  46. protected $captureLock = false;
  47. /**
  48. * What type of capture (overwrite (set), append, prepend) to use
  49. *
  50. * @var string
  51. */
  52. protected $captureType;
  53. /**
  54. * What string to use as the indentation of output, this will typically be spaces. Eg: ' '
  55. *
  56. * @var string
  57. */
  58. protected $indent = '';
  59. /**
  60. * What text to append the placeholder with when rendering
  61. *
  62. * @var string
  63. */
  64. protected $postfix = '';
  65. /**
  66. * What text to prefix the placeholder with when rendering
  67. *
  68. * @var string
  69. */
  70. protected $prefix = '';
  71. /**
  72. * What string to use between individual items in the placeholder when rendering
  73. *
  74. * @var string
  75. */
  76. protected $separator = '';
  77. /**
  78. * Constructor - This is needed so that we can attach a class member as the ArrayObject container
  79. */
  80. public function __construct()
  81. {
  82. parent::__construct(array(), parent::ARRAY_AS_PROPS);
  83. }
  84. /**
  85. * Serialize object to string
  86. *
  87. * @return string
  88. */
  89. public function __toString()
  90. {
  91. return $this->toString();
  92. }
  93. /**
  94. * Render the placeholder
  95. *
  96. * @param null|int|string $indent
  97. * @return string
  98. */
  99. public function toString($indent = null)
  100. {
  101. $indent = ($indent !== null)
  102. ? $this->getWhitespace($indent)
  103. : $this->getIndent();
  104. $items = $this->getArrayCopy();
  105. $return = $indent
  106. . $this->getPrefix()
  107. . implode($this->getSeparator(), $items)
  108. . $this->getPostfix();
  109. $return = preg_replace("/(\r\n?|\n)/", '$1' . $indent, $return);
  110. return $return;
  111. }
  112. /**
  113. * Start capturing content to push into placeholder
  114. *
  115. * @param string $type How to capture content into placeholder; append, prepend, or set
  116. * @param mixed $key Key to which to capture content
  117. * @throws Exception\RuntimeException if nested captures detected
  118. * @return void
  119. */
  120. public function captureStart($type = AbstractContainer::APPEND, $key = null)
  121. {
  122. if ($this->captureLock) {
  123. throw new Exception\RuntimeException(
  124. 'Cannot nest placeholder captures for the same placeholder'
  125. );
  126. }
  127. $this->captureLock = true;
  128. $this->captureType = $type;
  129. if ((null !== $key) && is_scalar($key)) {
  130. $this->captureKey = (string) $key;
  131. }
  132. ob_start();
  133. }
  134. /**
  135. * End content capture
  136. *
  137. * @return void
  138. */
  139. public function captureEnd()
  140. {
  141. $data = ob_get_clean();
  142. $key = null;
  143. $this->captureLock = false;
  144. if (null !== $this->captureKey) {
  145. $key = $this->captureKey;
  146. }
  147. switch ($this->captureType) {
  148. case self::SET:
  149. if (null !== $key) {
  150. $this[$key] = $data;
  151. } else {
  152. $this->exchangeArray(array($data));
  153. }
  154. break;
  155. case self::PREPEND:
  156. if (null !== $key) {
  157. $array = array($key => $data);
  158. $values = $this->getArrayCopy();
  159. $final = $array + $values;
  160. $this->exchangeArray($final);
  161. } else {
  162. $this->prepend($data);
  163. }
  164. break;
  165. case self::APPEND:
  166. default:
  167. if (null !== $key) {
  168. if (empty($this[$key])) {
  169. $this[$key] = $data;
  170. } else {
  171. $this[$key] .= $data;
  172. }
  173. } else {
  174. $this[$this->nextIndex()] = $data;
  175. }
  176. break;
  177. }
  178. }
  179. /**
  180. * Get keys
  181. *
  182. * @return array
  183. */
  184. public function getKeys()
  185. {
  186. $array = $this->getArrayCopy();
  187. return array_keys($array);
  188. }
  189. /**
  190. * Retrieve container value
  191. *
  192. * If single element registered, returns that element; otherwise,
  193. * serializes to array.
  194. *
  195. * @return mixed
  196. */
  197. public function getValue()
  198. {
  199. if (1 == count($this)) {
  200. $keys = $this->getKeys();
  201. $key = array_shift($keys);
  202. return $this[$key];
  203. }
  204. return $this->getArrayCopy();
  205. }
  206. /**
  207. * Retrieve whitespace representation of $indent
  208. *
  209. * @param int|string $indent
  210. * @return string
  211. */
  212. public function getWhitespace($indent)
  213. {
  214. if (is_int($indent)) {
  215. $indent = str_repeat(' ', $indent);
  216. }
  217. return (string) $indent;
  218. }
  219. /**
  220. * Set a single value
  221. *
  222. * @param mixed $value
  223. * @return void
  224. */
  225. public function set($value)
  226. {
  227. $this->exchangeArray(array($value));
  228. return $this;
  229. }
  230. /**
  231. * Prepend a value to the top of the container
  232. *
  233. * @param mixed $value
  234. * @return void
  235. */
  236. public function prepend($value)
  237. {
  238. $values = $this->getArrayCopy();
  239. array_unshift($values, $value);
  240. $this->exchangeArray($values);
  241. return $this;
  242. }
  243. /**
  244. * Next Index as defined by the PHP manual
  245. *
  246. * @return int
  247. */
  248. public function nextIndex()
  249. {
  250. $keys = $this->getKeys();
  251. if (0 == count($keys)) {
  252. return 0;
  253. }
  254. return $nextIndex = max($keys) + 1;
  255. }
  256. /**
  257. * Set the indentation string for __toString() serialization,
  258. * optionally, if a number is passed, it will be the number of spaces
  259. *
  260. * @param string|int $indent
  261. * @return AbstractContainer
  262. */
  263. public function setIndent($indent)
  264. {
  265. $this->indent = $this->getWhitespace($indent);
  266. return $this;
  267. }
  268. /**
  269. * Retrieve indentation
  270. *
  271. * @return string
  272. */
  273. public function getIndent()
  274. {
  275. return $this->indent;
  276. }
  277. /**
  278. * Set postfix for __toString() serialization
  279. *
  280. * @param string $postfix
  281. * @return AbstractContainer
  282. */
  283. public function setPostfix($postfix)
  284. {
  285. $this->postfix = (string) $postfix;
  286. return $this;
  287. }
  288. /**
  289. * Retrieve postfix
  290. *
  291. * @return string
  292. */
  293. public function getPostfix()
  294. {
  295. return $this->postfix;
  296. }
  297. /**
  298. * Set prefix for __toString() serialization
  299. *
  300. * @param string $prefix
  301. * @return AbstractContainer
  302. */
  303. public function setPrefix($prefix)
  304. {
  305. $this->prefix = (string) $prefix;
  306. return $this;
  307. }
  308. /**
  309. * Retrieve prefix
  310. *
  311. * @return string
  312. */
  313. public function getPrefix()
  314. {
  315. return $this->prefix;
  316. }
  317. /**
  318. * Set separator for __toString() serialization
  319. *
  320. * Used to implode elements in container
  321. *
  322. * @param string $separator
  323. * @return AbstractContainer
  324. */
  325. public function setSeparator($separator)
  326. {
  327. $this->separator = (string) $separator;
  328. return $this;
  329. }
  330. /**
  331. * Retrieve separator
  332. *
  333. * @return string
  334. */
  335. public function getSeparator()
  336. {
  337. return $this->separator;
  338. }
  339. }