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

https://github.com/leerbag/zf2 · PHP · 385 lines · 166 code · 36 blank · 183 comment · 18 complexity · 14b9334f554d755375bdc802727e4e36 MD5 · raw file

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