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: /**
27: * Block content. An array of blocks indexed by name.
28: *
29: * @var array
30: */
31: protected $_blocks = array();
32:
33: /**
34: * The active blocks being captured.
35: *
36: * @var array
37: */
38: protected $_active = array();
39:
40: /**
41: * Start capturing output for a 'block'
42: *
43: * Blocks allow you to create slots or blocks of dynamic content in the layout.
44: * view files can implement some or all of a layout's slots.
45: *
46: * You can end capturing blocks using View::end(). Blocks can be output
47: * using View::get();
48: *
49: * @param string $name The name of the block to capture for.
50: * @return void
51: */
52: public function start($name) {
53: $this->_active[] = $name;
54: ob_start();
55: }
56:
57: /**
58: * End a capturing block. The compliment to ViewBlock::start()
59: *
60: * @return void
61: * @see ViewBlock::start()
62: */
63: public function end() {
64: if (!empty($this->_active)) {
65: $active = end($this->_active);
66: $content = ob_get_clean();
67: if (!isset($this->_blocks[$active])) {
68: $this->_blocks[$active] = '';
69: }
70: $this->_blocks[$active] .= $content;
71: array_pop($this->_active);
72: }
73: }
74:
75: /**
76: * Append to an existing or new block. Appending to a new
77: * block will create the block.
78: *
79: * Calling append() without a value will create a new capturing
80: * block that needs to be finished with View::end(). The content
81: * of the new capturing context will be added to the existing block context.
82: *
83: * @param string $name Name of the block
84: * @param string $value The content for the block.
85: * @return void
86: * @throws CakeException when you use non-string values.
87: */
88: public function append($name, $value = null) {
89: if (isset($value)) {
90: if (!is_string($value)) {
91: throw new CakeException(__d('cake_dev', '$value must be a string.'));
92: }
93: if (!isset($this->_blocks[$name])) {
94: $this->_blocks[$name] = '';
95: }
96: $this->_blocks[$name] .= $value;
97: } else {
98: $this->start($name);
99: }
100: }
101:
102: /**
103: * Set the content for a block. This will overwrite any
104: * existing content.
105: *
106: * @param string $name Name of the block
107: * @param string $value The content for the block.
108: * @return void
109: * @throws CakeException when you use non-string values.
110: */
111: public function set($name, $value) {
112: if (!is_string($value)) {
113: throw new CakeException(__d('cake_dev', 'Blocks can only contain strings.'));
114: }
115: $this->_blocks[$name] = $value;
116: }
117:
118: /**
119: * Get the content for a block.
120: *
121: * @param string $name Name of the block
122: * @return The block content or '' if the block does not exist.
123: */
124: public function get($name) {
125: if (!isset($this->_blocks[$name])) {
126: return '';
127: }
128: return $this->_blocks[$name];
129: }
130:
131: /**
132: * Get the names of all the existing blocks.
133: *
134: * @return array An array containing the blocks.
135: */
136: public function keys() {
137: return array_keys($this->_blocks);
138: }
139:
140: /**
141: * Get the name of the currently open block.
142: *
143: * @return mixed Either null or the name of the last open block.
144: */
145: public function active() {
146: return end($this->_active);
147: }
148:
149: /**
150: * Get the names of the unclosed/active blocks.
151: *
152: * @return array An array of unclosed blocks.
153: */
154: public function unclosed() {
155: return $this->_active;
156: }
157:
158: }
159: