ViewBlock.php 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. <?php
  2. /**
  3. * PHP 5
  4. *
  5. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  6. * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
  7. *
  8. * Licensed under The MIT License
  9. * Redistributions of files must retain the above copyright notice.
  10. *
  11. * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
  12. * @link http://cakephp.org CakePHP(tm) Project
  13. * @since CakePHP(tm) v2.1
  14. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  15. */
  16. /**
  17. * ViewBlock implements the concept of Blocks or Slots in the View layer.
  18. * Slots or blocks are combined with extending views and layouts to afford slots
  19. * of content that are present in a layout or parent view, but are defined by the child
  20. * view or elements used in the view.
  21. *
  22. * @package Cake.View
  23. */
  24. class ViewBlock {
  25. /**
  26. * Append content
  27. *
  28. * @constant APPEND
  29. */
  30. const APPEND = 'append';
  31. /**
  32. * Prepend content
  33. *
  34. * @constant PREPEND
  35. */
  36. const PREPEND = 'prepend';
  37. /**
  38. * Block content. An array of blocks indexed by name.
  39. *
  40. * @var array
  41. */
  42. protected $_blocks = array();
  43. /**
  44. * The active blocks being captured.
  45. *
  46. * @var array
  47. */
  48. protected $_active = array();
  49. /**
  50. * Start capturing output for a 'block'
  51. *
  52. * Blocks allow you to create slots or blocks of dynamic content in the layout.
  53. * view files can implement some or all of a layout's slots.
  54. *
  55. * You can end capturing blocks using View::end(). Blocks can be output
  56. * using View::get();
  57. *
  58. * @param string $name The name of the block to capture for.
  59. * @return void
  60. */
  61. public function start($name) {
  62. $this->_active[] = $name;
  63. ob_start();
  64. }
  65. /**
  66. * End a capturing block. The compliment to ViewBlock::start()
  67. *
  68. * @return void
  69. * @see ViewBlock::start()
  70. */
  71. public function end() {
  72. if (!empty($this->_active)) {
  73. $active = end($this->_active);
  74. $content = ob_get_clean();
  75. if (!isset($this->_blocks[$active])) {
  76. $this->_blocks[$active] = '';
  77. }
  78. $this->_blocks[$active] .= $content;
  79. array_pop($this->_active);
  80. }
  81. }
  82. /**
  83. * Concat content to an existing or new block.
  84. * Concating to a new block will create the block.
  85. *
  86. * Calling concat() without a value will create a new capturing
  87. * block that needs to be finished with View::end(). The content
  88. * of the new capturing context will be added to the existing block context.
  89. *
  90. * @param string $name Name of the block
  91. * @param string $value The content for the block
  92. * @param string $mode If ViewBlock::APPEND content will be appended to existing content.
  93. * If ViewBlock::PREPEND it will be prepended.
  94. * @return void
  95. * @throws CakeException when you use non-string values.
  96. */
  97. public function concat($name, $value = null, $mode = ViewBlock::APPEND) {
  98. if (isset($value)) {
  99. if (!is_string($value)) {
  100. throw new CakeException(__d('cake_dev', '$value must be a string.'));
  101. }
  102. if (!isset($this->_blocks[$name])) {
  103. $this->_blocks[$name] = '';
  104. }
  105. if ($mode === ViewBlock::PREPEND) {
  106. $this->_blocks[$name] = $value . $this->_blocks[$name];
  107. } else {
  108. $this->_blocks[$name] .= $value;
  109. }
  110. } else {
  111. $this->start($name);
  112. }
  113. }
  114. /**
  115. * Append to an existing or new block. Appending to a new
  116. * block will create the block.
  117. *
  118. * Calling append() without a value will create a new capturing
  119. * block that needs to be finished with View::end(). The content
  120. * of the new capturing context will be added to the existing block context.
  121. *
  122. * @param string $name Name of the block
  123. * @param string $value The content for the block.
  124. * @return void
  125. * @throws CakeException when you use non-string values.
  126. * @deprecated As of 2.3 use ViewBlock::concat() instead.
  127. */
  128. public function append($name, $value = null) {
  129. $this->concat($name, $value);
  130. }
  131. /**
  132. * Set the content for a block. This will overwrite any
  133. * existing content.
  134. *
  135. * @param string $name Name of the block
  136. * @param string $value The content for the block.
  137. * @return void
  138. * @throws CakeException when you use non-string values.
  139. */
  140. public function set($name, $value) {
  141. if (!is_string($value)) {
  142. throw new CakeException(__d('cake_dev', 'Blocks can only contain strings.'));
  143. }
  144. $this->_blocks[$name] = $value;
  145. }
  146. /**
  147. * Get the content for a block.
  148. *
  149. * @param string $name Name of the block
  150. * @return string The block content or $default if the block does not exist.
  151. */
  152. public function get($name, $default = '') {
  153. if (!isset($this->_blocks[$name])) {
  154. return $default;
  155. }
  156. return $this->_blocks[$name];
  157. }
  158. /**
  159. * Get the names of all the existing blocks.
  160. *
  161. * @return array An array containing the blocks.
  162. */
  163. public function keys() {
  164. return array_keys($this->_blocks);
  165. }
  166. /**
  167. * Get the name of the currently open block.
  168. *
  169. * @return mixed Either null or the name of the last open block.
  170. */
  171. public function active() {
  172. return end($this->_active);
  173. }
  174. /**
  175. * Get the names of the unclosed/active blocks.
  176. *
  177. * @return array An array of unclosed blocks.
  178. */
  179. public function unclosed() {
  180. return $this->_active;
  181. }
  182. }