Subversion-Projekte lars-tiefland.cakephp

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

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