1 | <?php |
---|
2 | /** |
---|
3 | * |
---|
4 | * PHP versions 4 and 5 |
---|
5 | * |
---|
6 | * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) |
---|
7 | * Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org) |
---|
8 | * |
---|
9 | * Licensed under The MIT License |
---|
10 | * Redistributions of files must retain the above copyright notice. |
---|
11 | * |
---|
12 | * @copyright Copyright 2005-2011, Cake Software Foundation, Inc. (http://cakefoundation.org) |
---|
13 | * @link http://cakephp.org CakePHP(tm) Project |
---|
14 | * @package cake |
---|
15 | * @subpackage cake.cake.libs.controller |
---|
16 | * @since CakePHP(tm) v TBD |
---|
17 | * @license MIT License (http://www.opensource.org/licenses/mit-license.php) |
---|
18 | */ |
---|
19 | |
---|
20 | /** |
---|
21 | * Handler for Controller::$components |
---|
22 | * |
---|
23 | * @package cake |
---|
24 | * @subpackage cake.cake.libs.controller |
---|
25 | * @link http://book.cakephp.org/view/993/Components |
---|
26 | */ |
---|
27 | class Component extends Object { |
---|
28 | |
---|
29 | /** |
---|
30 | * Contains various controller variable information (plugin, name, base). |
---|
31 | * |
---|
32 | * @var object |
---|
33 | * @access private |
---|
34 | */ |
---|
35 | var $__controllerVars = array('plugin' => null, 'name' => null, 'base' => null); |
---|
36 | |
---|
37 | /** |
---|
38 | * List of loaded components. |
---|
39 | * |
---|
40 | * @var object |
---|
41 | * @access protected |
---|
42 | */ |
---|
43 | var $_loaded = array(); |
---|
44 | |
---|
45 | /** |
---|
46 | * List of components attached directly to the controller, which callbacks |
---|
47 | * should be executed on. |
---|
48 | * |
---|
49 | * @var object |
---|
50 | * @access protected |
---|
51 | */ |
---|
52 | var $_primary = array(); |
---|
53 | |
---|
54 | /** |
---|
55 | * Settings for loaded components. |
---|
56 | * |
---|
57 | * @var array |
---|
58 | * @access private |
---|
59 | */ |
---|
60 | var $__settings = array(); |
---|
61 | |
---|
62 | /** |
---|
63 | * Used to initialize the components for current controller. |
---|
64 | * |
---|
65 | * @param object $controller Controller with components to load |
---|
66 | * @return void |
---|
67 | * @access public |
---|
68 | */ |
---|
69 | function init(&$controller) { |
---|
70 | if (!is_array($controller->components)) { |
---|
71 | return; |
---|
72 | } |
---|
73 | $this->__controllerVars = array( |
---|
74 | 'plugin' => $controller->plugin, 'name' => $controller->name, |
---|
75 | 'base' => $controller->base |
---|
76 | ); |
---|
77 | |
---|
78 | $this->_loadComponents($controller); |
---|
79 | } |
---|
80 | |
---|
81 | /** |
---|
82 | * Called before the Controller::beforeFilter(). |
---|
83 | * |
---|
84 | * @param object $controller Controller with components to initialize |
---|
85 | * @return void |
---|
86 | * @access public |
---|
87 | * @link http://book.cakephp.org/view/998/MVC-Class-Access-Within-Components |
---|
88 | */ |
---|
89 | function initialize(&$controller) { |
---|
90 | foreach (array_keys($this->_loaded) as $name) { |
---|
91 | $component =& $this->_loaded[$name]; |
---|
92 | |
---|
93 | if (method_exists($component,'initialize') && $component->enabled === true) { |
---|
94 | $settings = array(); |
---|
95 | if (isset($this->__settings[$name])) { |
---|
96 | $settings = $this->__settings[$name]; |
---|
97 | } |
---|
98 | $component->initialize($controller, $settings); |
---|
99 | } |
---|
100 | } |
---|
101 | } |
---|
102 | |
---|
103 | /** |
---|
104 | * Called after the Controller::beforeFilter() and before the controller action |
---|
105 | * |
---|
106 | * @param object $controller Controller with components to startup |
---|
107 | * @return void |
---|
108 | * @access public |
---|
109 | * @link http://book.cakephp.org/view/998/MVC-Class-Access-Within-Components |
---|
110 | * @deprecated See Component::triggerCallback() |
---|
111 | */ |
---|
112 | function startup(&$controller) { |
---|
113 | $this->triggerCallback('startup', $controller); |
---|
114 | } |
---|
115 | |
---|
116 | /** |
---|
117 | * Called after the Controller::beforeRender(), after the view class is loaded, and before the |
---|
118 | * Controller::render() |
---|
119 | * |
---|
120 | * @param object $controller Controller with components to beforeRender |
---|
121 | * @return void |
---|
122 | * @access public |
---|
123 | * @deprecated See Component::triggerCallback() |
---|
124 | */ |
---|
125 | function beforeRender(&$controller) { |
---|
126 | $this->triggerCallback('beforeRender', $controller); |
---|
127 | } |
---|
128 | |
---|
129 | /** |
---|
130 | * Called before Controller::redirect(). |
---|
131 | * |
---|
132 | * @param object $controller Controller with components to beforeRedirect |
---|
133 | * @return void |
---|
134 | * @access public |
---|
135 | */ |
---|
136 | function beforeRedirect(&$controller, $url, $status = null, $exit = true) { |
---|
137 | $response = array(); |
---|
138 | |
---|
139 | foreach ($this->_primary as $name) { |
---|
140 | $component =& $this->_loaded[$name]; |
---|
141 | |
---|
142 | if ($component->enabled === true && method_exists($component, 'beforeRedirect')) { |
---|
143 | $resp = $component->beforeRedirect($controller, $url, $status, $exit); |
---|
144 | if ($resp === false) { |
---|
145 | return false; |
---|
146 | } |
---|
147 | $response[] = $resp; |
---|
148 | } |
---|
149 | } |
---|
150 | return $response; |
---|
151 | } |
---|
152 | |
---|
153 | /** |
---|
154 | * Called after Controller::render() and before the output is printed to the browser. |
---|
155 | * |
---|
156 | * @param object $controller Controller with components to shutdown |
---|
157 | * @return void |
---|
158 | * @access public |
---|
159 | * @deprecated See Component::triggerCallback() |
---|
160 | */ |
---|
161 | function shutdown(&$controller) { |
---|
162 | $this->triggerCallback('shutdown', $controller); |
---|
163 | } |
---|
164 | |
---|
165 | /** |
---|
166 | * Trigger a callback on all primary components. Will fire $callback on all components |
---|
167 | * that have such a method. You can implement and fire custom callbacks in addition to the |
---|
168 | * standard ones. |
---|
169 | * |
---|
170 | * example use, from inside a controller: |
---|
171 | * |
---|
172 | * `$this->Component->triggerCallback('beforeFilter', $this);` |
---|
173 | * |
---|
174 | * will trigger the beforeFilter callback on all components that have implemented one. You |
---|
175 | * can trigger any method in this fashion. |
---|
176 | * |
---|
177 | * @param Controller $controller Controller instance |
---|
178 | * @param string $callback Callback to trigger. |
---|
179 | * @return void |
---|
180 | * @access public |
---|
181 | */ |
---|
182 | function triggerCallback($callback, &$controller) { |
---|
183 | foreach ($this->_primary as $name) { |
---|
184 | $component =& $this->_loaded[$name]; |
---|
185 | if (method_exists($component, $callback) && $component->enabled === true) { |
---|
186 | $component->{$callback}($controller); |
---|
187 | } |
---|
188 | } |
---|
189 | } |
---|
190 | |
---|
191 | /** |
---|
192 | * Loads components used by this component. |
---|
193 | * |
---|
194 | * @param object $object Object with a Components array |
---|
195 | * @param object $parent the parent of the current object |
---|
196 | * @return void |
---|
197 | * @access protected |
---|
198 | */ |
---|
199 | function _loadComponents(&$object, $parent = null) { |
---|
200 | $base = $this->__controllerVars['base']; |
---|
201 | $normal = Set::normalize($object->components); |
---|
202 | foreach ((array)$normal as $component => $config) { |
---|
203 | $plugin = isset($this->__controllerVars['plugin']) ? $this->__controllerVars['plugin'] . '.' : null; |
---|
204 | list($plugin, $component) = pluginSplit($component, true, $plugin); |
---|
205 | $componentCn = $component . 'Component'; |
---|
206 | |
---|
207 | if (!class_exists($componentCn)) { |
---|
208 | if (is_null($plugin) || !App::import('Component', $plugin . $component)) { |
---|
209 | if (!App::import('Component', $component)) { |
---|
210 | $this->cakeError('missingComponentFile', array(array( |
---|
211 | 'className' => $this->__controllerVars['name'], |
---|
212 | 'component' => $component, |
---|
213 | 'file' => Inflector::underscore($component) . '.php', |
---|
214 | 'base' => $base, |
---|
215 | 'code' => 500 |
---|
216 | ))); |
---|
217 | return false; |
---|
218 | } |
---|
219 | } |
---|
220 | |
---|
221 | if (!class_exists($componentCn)) { |
---|
222 | $this->cakeError('missingComponentClass', array(array( |
---|
223 | 'className' => $this->__controllerVars['name'], |
---|
224 | 'component' => $component, |
---|
225 | 'file' => Inflector::underscore($component) . '.php', |
---|
226 | 'base' => $base, |
---|
227 | 'code' => 500 |
---|
228 | ))); |
---|
229 | return false; |
---|
230 | } |
---|
231 | } |
---|
232 | |
---|
233 | if ($parent === null) { |
---|
234 | $this->_primary[] = $component; |
---|
235 | } |
---|
236 | |
---|
237 | if (isset($this->_loaded[$component])) { |
---|
238 | $object->{$component} =& $this->_loaded[$component]; |
---|
239 | |
---|
240 | if (!empty($config) && isset($this->__settings[$component])) { |
---|
241 | $this->__settings[$component] = array_merge($this->__settings[$component], $config); |
---|
242 | } elseif (!empty($config)) { |
---|
243 | $this->__settings[$component] = $config; |
---|
244 | } |
---|
245 | } else { |
---|
246 | if ($componentCn === 'SessionComponent') { |
---|
247 | $object->{$component} =& new $componentCn($base); |
---|
248 | } else { |
---|
249 | if (PHP5) { |
---|
250 | $object->{$component} = new $componentCn(); |
---|
251 | } else { |
---|
252 | $object->{$component} =& new $componentCn(); |
---|
253 | } |
---|
254 | } |
---|
255 | $object->{$component}->enabled = true; |
---|
256 | $this->_loaded[$component] =& $object->{$component}; |
---|
257 | if (!empty($config)) { |
---|
258 | $this->__settings[$component] = $config; |
---|
259 | } |
---|
260 | } |
---|
261 | |
---|
262 | if (isset($object->{$component}->components) && is_array($object->{$component}->components) && (!isset($object->{$component}->{$parent}))) { |
---|
263 | $this->_loadComponents($object->{$component}, $component); |
---|
264 | } |
---|
265 | } |
---|
266 | } |
---|
267 | } |
---|