1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
15:
16: 17: 18:
19: App::uses('Model', 'Model');
20: App::uses('AppModel', 'Model');
21: App::uses('ConnectionManager', 'Model');
22:
23: 24: 25: 26: 27: 28: 29: 30: 31:
32: class ClassRegistry {
33:
34: 35: 36: 37: 38:
39: protected $_objects = array();
40:
41: 42: 43: 44: 45:
46: protected $_map = array();
47:
48: 49: 50: 51: 52:
53: protected $_config = array();
54:
55: 56: 57: 58: 59:
60: public static function &getInstance() {
61: static $instance = array();
62: if (!$instance) {
63: $instance[0] = new ClassRegistry();
64: }
65: return $instance[0];
66: }
67:
68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94:
95: public static function init($class, $strict = false) {
96: $_this = ClassRegistry::getInstance();
97: $false = false;
98: $true = true;
99:
100: if (is_array($class)) {
101: $objects = $class;
102: if (!isset($class[0])) {
103: $objects = array($class);
104: }
105: } else {
106: $objects = array(array('class' => $class));
107: }
108: $defaults = isset($_this->_config['Model']) ? $_this->_config['Model'] : array();
109: $count = count($objects);
110: $availableDs = array_keys(ConnectionManager::enumConnectionObjects());
111:
112: foreach ($objects as $key => $settings) {
113: if (is_array($settings)) {
114: $pluginPath = null;
115: $settings = array_merge($defaults, $settings);
116: $class = $settings['class'];
117:
118: list($plugin, $class) = pluginSplit($class);
119: if ($plugin) {
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: App::uses($plugin . 'AppModel', $pluginPath . 'Model');
134: App::uses($class, $pluginPath . 'Model');
135:
136: if (class_exists($class) || interface_exists($class)) {
137: $reflection = new ReflectionClass($class);
138: if ($reflection->isAbstract() || $reflection->isInterface()) {
139: throw new CakeException(__d('cake_dev', 'Cannot create instance of %s, as it is abstract or is an interface', $class));
140: }
141: $testing = isset($settings['testing']) ? $settings['testing'] : false;
142: if ($testing) {
143: $settings['ds'] = 'test';
144: $defaultProperties = $reflection->getDefaultProperties();
145: if (isset($defaultProperties['useDbConfig'])) {
146: $useDbConfig = $defaultProperties['useDbConfig'];
147: if (in_array('test_' . $useDbConfig, $availableDs)) {
148: $useDbConfig = 'test_' . $useDbConfig;
149: }
150: if (strpos($useDbConfig, 'test') === 0) {
151: $settings['ds'] = $useDbConfig;
152: }
153: }
154: }
155: if ($reflection->getConstructor()) {
156: $instance = $reflection->newInstance($settings);
157: } else {
158: $instance = $reflection->newInstance();
159: }
160: if ($strict) {
161: $instance = ($instance instanceof Model) ? $instance : null;
162: }
163: }
164: if (!isset($instance)) {
165: if ($strict) {
166: return false;
167: } elseif ($plugin && class_exists($plugin . 'AppModel')) {
168: $appModel = $plugin . 'AppModel';
169: } else {
170: $appModel = 'AppModel';
171: }
172: if (!empty($appModel)) {
173: $settings['name'] = $class;
174: $instance = new $appModel($settings);
175: }
176:
177: if (!isset($instance)) {
178: trigger_error(__d('cake_dev', '(ClassRegistry::init() could not create instance of %1$s class %2$s ', $class, $type), E_USER_WARNING);
179: return $false;
180: }
181: }
182: $_this->map($alias, $class);
183: } elseif (is_numeric($settings)) {
184: trigger_error(__d('cake_dev', '(ClassRegistry::init() Attempted to create instance of a class with a numeric name'), E_USER_WARNING);
185: return $false;
186: }
187: }
188:
189: if ($count > 1) {
190: return $true;
191: }
192: return $instance;
193: }
194:
195: 196: 197: 198: 199: 200: 201:
202: public static function addObject($key, $object) {
203: $_this = ClassRegistry::getInstance();
204: $key = Inflector::underscore($key);
205: if (!isset($_this->_objects[$key])) {
206: $_this->_objects[$key] = $object;
207: return true;
208: }
209: return false;
210: }
211:
212: 213: 214: 215: 216: 217:
218: public static function removeObject($key) {
219: $_this = ClassRegistry::getInstance();
220: $key = Inflector::underscore($key);
221: if (isset($_this->_objects[$key])) {
222: unset($_this->_objects[$key]);
223: }
224: }
225:
226: 227: 228: 229: 230: 231:
232: public static function isKeySet($key) {
233: $_this = ClassRegistry::getInstance();
234: $key = Inflector::underscore($key);
235: if (isset($_this->_objects[$key])) {
236: return true;
237: } elseif (isset($_this->_map[$key])) {
238: return true;
239: }
240: return false;
241: }
242:
243: 244: 245: 246: 247:
248: public static function keys() {
249: $_this = ClassRegistry::getInstance();
250: return array_keys($_this->_objects);
251: }
252:
253: 254: 255: 256: 257: 258:
259: public static function &getObject($key) {
260: $_this = ClassRegistry::getInstance();
261: $key = Inflector::underscore($key);
262: $return = false;
263: if (isset($_this->_objects[$key])) {
264: $return = $_this->_objects[$key];
265: } else {
266: $key = $_this->_getMap($key);
267: if (isset($_this->_objects[$key])) {
268: $return = $_this->_objects[$key];
269: }
270: }
271: return $return;
272: }
273:
274: 275: 276: 277: 278: 279: 280: 281: 282:
283: public static function config($type, $param = array()) {
284: $_this = ClassRegistry::getInstance();
285:
286: if (empty($param) && is_array($type)) {
287: $param = $type;
288: $type = 'Model';
289: } elseif (is_null($param)) {
290: unset($_this->_config[$type]);
291: } elseif (empty($param) && is_string($type)) {
292: return isset($_this->_config[$type]) ? $_this->_config[$type] : null;
293: }
294: if (isset($_this->_config[$type]['testing'])) {
295: $param['testing'] = true;
296: }
297: $_this->_config[$type] = $param;
298: }
299:
300: 301: 302: 303: 304: 305: 306:
307: protected function &_duplicate($alias, $class) {
308: $duplicate = false;
309: if ($this->isKeySet($alias)) {
310: $model = $this->getObject($alias);
311: if (is_object($model) && (is_a($model, $class) || $model->alias === $class)) {
312: $duplicate = $model;
313: }
314: unset($model);
315: }
316: return $duplicate;
317: }
318:
319: 320: 321: 322: 323: 324: 325:
326: public static function map($key, $name) {
327: $_this = ClassRegistry::getInstance();
328: $key = Inflector::underscore($key);
329: $name = Inflector::underscore($name);
330: if (!isset($_this->_map[$key])) {
331: $_this->_map[$key] = $name;
332: }
333: }
334:
335: 336: 337: 338: 339:
340: public static function mapKeys() {
341: $_this = ClassRegistry::getInstance();
342: return array_keys($_this->_map);
343: }
344:
345: 346: 347: 348: 349: 350:
351: protected function _getMap($key) {
352: if (isset($this->_map[$key])) {
353: return $this->_map[$key];
354: }
355: }
356:
357: 358: 359: 360: 361:
362: public static function flush() {
363: $_this = ClassRegistry::getInstance();
364: $_this->_objects = array();
365: $_this->_map = array();
366: }
367:
368: }
369: