Mercurial > hg > Members > shoshi > webvirt
comparison cake/libs/class_registry.php @ 0:261e66bd5a0c
hg init
author | Shoshi TAMAKI <shoshi@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 24 Jul 2011 21:08:31 +0900 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:261e66bd5a0c |
---|---|
1 <?php | |
2 /** | |
3 * Class collections. | |
4 * | |
5 * A repository for class objects, each registered with a key. | |
6 * | |
7 * PHP versions 4 and 5 | |
8 * | |
9 * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) | |
10 * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org) | |
11 * | |
12 * Licensed under The MIT License | |
13 * Redistributions of files must retain the above copyright notice. | |
14 * | |
15 * @copyright Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org) | |
16 * @link http://cakephp.org CakePHP(tm) Project | |
17 * @package cake | |
18 * @subpackage cake.cake.libs | |
19 * @since CakePHP(tm) v 0.9.2 | |
20 * @license MIT License (http://www.opensource.org/licenses/mit-license.php) | |
21 */ | |
22 | |
23 /** | |
24 * Class Collections. | |
25 * | |
26 * A repository for class objects, each registered with a key. | |
27 * If you try to add an object with the same key twice, nothing will come of it. | |
28 * If you need a second instance of an object, give it another key. | |
29 * | |
30 * @package cake | |
31 * @subpackage cake.cake.libs | |
32 */ | |
33 class ClassRegistry { | |
34 | |
35 /** | |
36 * Names of classes with their objects. | |
37 * | |
38 * @var array | |
39 * @access private | |
40 */ | |
41 var $__objects = array(); | |
42 | |
43 /** | |
44 * Names of class names mapped to the object in the registry. | |
45 * | |
46 * @var array | |
47 * @access private | |
48 */ | |
49 var $__map = array(); | |
50 | |
51 /** | |
52 * Default constructor parameter settings, indexed by type | |
53 * | |
54 * @var array | |
55 * @access private | |
56 */ | |
57 var $__config = array(); | |
58 | |
59 /** | |
60 * Return a singleton instance of the ClassRegistry. | |
61 * | |
62 * @return ClassRegistry instance | |
63 * @access public | |
64 */ | |
65 function &getInstance() { | |
66 static $instance = array(); | |
67 if (!$instance) { | |
68 $instance[0] =& new ClassRegistry(); | |
69 } | |
70 return $instance[0]; | |
71 } | |
72 | |
73 /** | |
74 * Loads a class, registers the object in the registry and returns instance of the object. ClassRegistry::init() | |
75 * is used as a factory for models, and handle correct injecting of settings, that assist in testing. | |
76 * | |
77 * Examples | |
78 * Simple Use: Get a Post model instance ```ClassRegistry::init('Post');``` | |
79 * | |
80 * Exapanded: ```array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'Model');``` | |
81 * | |
82 * Model Classes can accept optional ```array('id' => $id, 'table' => $table, 'ds' => $ds, 'alias' => $alias);``` | |
83 * | |
84 * When $class is a numeric keyed array, multiple class instances will be stored in the registry, | |
85 * no instance of the object will be returned | |
86 * {{{ | |
87 * array( | |
88 * array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'Model'), | |
89 * array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'Model'), | |
90 * array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'Model') | |
91 * ); | |
92 * }}} | |
93 * @param mixed $class as a string or a single key => value array instance will be created, | |
94 * stored in the registry and returned. | |
95 * @param string $type Only model is accepted as a valid value for $type. | |
96 * @return object instance of ClassName | |
97 * @access public | |
98 * @static | |
99 */ | |
100 function &init($class, $type = null) { | |
101 $_this =& ClassRegistry::getInstance(); | |
102 $id = $false = false; | |
103 $true = true; | |
104 | |
105 if (!$type) { | |
106 $type = 'Model'; | |
107 } | |
108 | |
109 if (is_array($class)) { | |
110 $objects = $class; | |
111 if (!isset($class[0])) { | |
112 $objects = array($class); | |
113 } | |
114 } else { | |
115 $objects = array(array('class' => $class)); | |
116 } | |
117 $defaults = isset($_this->__config[$type]) ? $_this->__config[$type] : array(); | |
118 $count = count($objects); | |
119 | |
120 foreach ($objects as $key => $settings) { | |
121 if (is_array($settings)) { | |
122 $pluginPath = null; | |
123 $settings = array_merge($defaults, $settings); | |
124 $class = $settings['class']; | |
125 | |
126 list($plugin, $class) = pluginSplit($class); | |
127 if ($plugin) { | |
128 $pluginPath = $plugin . '.'; | |
129 } | |
130 | |
131 if (empty($settings['alias'])) { | |
132 $settings['alias'] = $class; | |
133 } | |
134 $alias = $settings['alias']; | |
135 | |
136 if ($model =& $_this->__duplicate($alias, $class)) { | |
137 $_this->map($alias, $class); | |
138 return $model; | |
139 } | |
140 | |
141 if (class_exists($class) || App::import($type, $pluginPath . $class)) { | |
142 ${$class} =& new $class($settings); | |
143 } elseif ($type === 'Model') { | |
144 if ($plugin && class_exists($plugin . 'AppModel')) { | |
145 $appModel = $plugin . 'AppModel'; | |
146 } else { | |
147 $appModel = 'AppModel'; | |
148 } | |
149 $settings['name'] = $class; | |
150 ${$class} =& new $appModel($settings); | |
151 } | |
152 | |
153 if (!isset(${$class})) { | |
154 trigger_error(sprintf(__('(ClassRegistry::init() could not create instance of %1$s class %2$s ', true), $class, $type), E_USER_WARNING); | |
155 return $false; | |
156 } | |
157 | |
158 if ($type !== 'Model') { | |
159 $_this->addObject($alias, ${$class}); | |
160 } else { | |
161 $_this->map($alias, $class); | |
162 } | |
163 } elseif (is_numeric($settings)) { | |
164 trigger_error(__('(ClassRegistry::init() Attempted to create instance of a class with a numeric name', true), E_USER_WARNING); | |
165 return $false; | |
166 } | |
167 } | |
168 | |
169 if ($count > 1) { | |
170 return $true; | |
171 } | |
172 return ${$class}; | |
173 } | |
174 | |
175 /** | |
176 * Add $object to the registry, associating it with the name $key. | |
177 * | |
178 * @param string $key Key for the object in registry | |
179 * @param mixed $object Object to store | |
180 * @return boolean True if the object was written, false if $key already exists | |
181 * @access public | |
182 * @static | |
183 */ | |
184 function addObject($key, &$object) { | |
185 $_this =& ClassRegistry::getInstance(); | |
186 $key = Inflector::underscore($key); | |
187 if (!isset($_this->__objects[$key])) { | |
188 $_this->__objects[$key] =& $object; | |
189 return true; | |
190 } | |
191 return false; | |
192 } | |
193 | |
194 /** | |
195 * Remove object which corresponds to given key. | |
196 * | |
197 * @param string $key Key of object to remove from registry | |
198 * @return void | |
199 * @access public | |
200 * @static | |
201 */ | |
202 function removeObject($key) { | |
203 $_this =& ClassRegistry::getInstance(); | |
204 $key = Inflector::underscore($key); | |
205 if (isset($_this->__objects[$key])) { | |
206 unset($_this->__objects[$key]); | |
207 } | |
208 } | |
209 | |
210 /** | |
211 * Returns true if given key is present in the ClassRegistry. | |
212 * | |
213 * @param string $key Key to look for | |
214 * @return boolean true if key exists in registry, false otherwise | |
215 * @access public | |
216 * @static | |
217 */ | |
218 function isKeySet($key) { | |
219 $_this =& ClassRegistry::getInstance(); | |
220 $key = Inflector::underscore($key); | |
221 if (isset($_this->__objects[$key])) { | |
222 return true; | |
223 } elseif (isset($_this->__map[$key])) { | |
224 return true; | |
225 } | |
226 return false; | |
227 } | |
228 | |
229 /** | |
230 * Get all keys from the registry. | |
231 * | |
232 * @return array Set of keys stored in registry | |
233 * @access public | |
234 * @static | |
235 */ | |
236 function keys() { | |
237 $_this =& ClassRegistry::getInstance(); | |
238 return array_keys($_this->__objects); | |
239 } | |
240 | |
241 /** | |
242 * Return object which corresponds to given key. | |
243 * | |
244 * @param string $key Key of object to look for | |
245 * @return mixed Object stored in registry or boolean false if the object does not exist. | |
246 * @access public | |
247 * @static | |
248 */ | |
249 function &getObject($key) { | |
250 $_this =& ClassRegistry::getInstance(); | |
251 $key = Inflector::underscore($key); | |
252 $return = false; | |
253 if (isset($_this->__objects[$key])) { | |
254 $return =& $_this->__objects[$key]; | |
255 } else { | |
256 $key = $_this->__getMap($key); | |
257 if (isset($_this->__objects[$key])) { | |
258 $return =& $_this->__objects[$key]; | |
259 } | |
260 } | |
261 return $return; | |
262 } | |
263 | |
264 /** | |
265 * Sets the default constructor parameter for an object type | |
266 * | |
267 * @param string $type Type of object. If this parameter is omitted, defaults to "Model" | |
268 * @param array $param The parameter that will be passed to object constructors when objects | |
269 * of $type are created | |
270 * @return mixed Void if $param is being set. Otherwise, if only $type is passed, returns | |
271 * the previously-set value of $param, or null if not set. | |
272 * @access public | |
273 * @static | |
274 */ | |
275 function config($type, $param = array()) { | |
276 $_this =& ClassRegistry::getInstance(); | |
277 | |
278 if (empty($param) && is_array($type)) { | |
279 $param = $type; | |
280 $type = 'Model'; | |
281 } elseif (is_null($param)) { | |
282 unset($_this->__config[$type]); | |
283 } elseif (empty($param) && is_string($type)) { | |
284 return isset($_this->__config[$type]) ? $_this->__config[$type] : null; | |
285 } | |
286 $_this->__config[$type] = $param; | |
287 } | |
288 | |
289 /** | |
290 * Checks to see if $alias is a duplicate $class Object | |
291 * | |
292 * @param string $alias | |
293 * @param string $class | |
294 * @return boolean | |
295 * @access private | |
296 * @static | |
297 */ | |
298 function &__duplicate($alias, $class) { | |
299 $duplicate = false; | |
300 if ($this->isKeySet($alias)) { | |
301 $model =& $this->getObject($alias); | |
302 if (is_object($model) && (is_a($model, $class) || $model->alias === $class)) { | |
303 $duplicate =& $model; | |
304 } | |
305 unset($model); | |
306 } | |
307 return $duplicate; | |
308 } | |
309 | |
310 /** | |
311 * Add a key name pair to the registry to map name to class in the registry. | |
312 * | |
313 * @param string $key Key to include in map | |
314 * @param string $name Key that is being mapped | |
315 * @access public | |
316 * @static | |
317 */ | |
318 function map($key, $name) { | |
319 $_this =& ClassRegistry::getInstance(); | |
320 $key = Inflector::underscore($key); | |
321 $name = Inflector::underscore($name); | |
322 if (!isset($_this->__map[$key])) { | |
323 $_this->__map[$key] = $name; | |
324 } | |
325 } | |
326 | |
327 /** | |
328 * Get all keys from the map in the registry. | |
329 * | |
330 * @return array Keys of registry's map | |
331 * @access public | |
332 * @static | |
333 */ | |
334 function mapKeys() { | |
335 $_this =& ClassRegistry::getInstance(); | |
336 return array_keys($_this->__map); | |
337 } | |
338 | |
339 /** | |
340 * Return the name of a class in the registry. | |
341 * | |
342 * @param string $key Key to find in map | |
343 * @return string Mapped value | |
344 * @access private | |
345 * @static | |
346 */ | |
347 function __getMap($key) { | |
348 if (isset($this->__map[$key])) { | |
349 return $this->__map[$key]; | |
350 } | |
351 } | |
352 | |
353 /** | |
354 * Flushes all objects from the ClassRegistry. | |
355 * | |
356 * @return void | |
357 * @access public | |
358 * @static | |
359 */ | |
360 function flush() { | |
361 $_this =& ClassRegistry::getInstance(); | |
362 $_this->__objects = array(); | |
363 $_this->__map = array(); | |
364 } | |
365 } |