PageRenderTime 43ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/cake/cake/libs/class_registry.php

http://skygames.googlecode.com/
PHP | 347 lines | 167 code | 11 blank | 169 comment | 33 complexity | 387e7b657d818fc03122443d94e57474 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1, CC-BY-SA-3.0
  1. <?php
  2. /* SVN FILE: $Id: class_registry.php 7805 2008-10-30 17:30:26Z AD7six $ */
  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: 7805 $
  23. * @modifiedby $LastChangedBy: AD7six $
  24. * @lastmodified $Date: 2008-10-30 12:30:26 -0500 (Thu, 30 Oct 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. if (!$type) {
  97. $type = 'Model';
  98. }
  99. if (is_array($class)) {
  100. $objects = $class;
  101. if (!isset($class[0])) {
  102. $objects = array($class);
  103. }
  104. } else {
  105. $objects = array(array('class' => $class));
  106. }
  107. $defaults = isset($_this->__config[$type]) ? $_this->__config[$type] : array();
  108. $count = count($objects);
  109. foreach ($objects as $key => $settings) {
  110. if (is_array($settings)) {
  111. $plugin = $pluginPath = null;
  112. $settings = array_merge($defaults, $settings);
  113. $class = $settings['class'];
  114. if (strpos($class, '.') !== false) {
  115. list($plugin, $class) = explode('.', $class);
  116. $pluginPath = $plugin . '.';
  117. }
  118. if (empty($settings['alias'])) {
  119. $settings['alias'] = $class;
  120. }
  121. $alias = $settings['alias'];
  122. if ($model =& $_this->__duplicate($alias, $class)) {
  123. $_this->map($alias, $class);
  124. return $model;
  125. }
  126. if (class_exists($class) || App::import($type, $pluginPath . $class)) {
  127. ${$class} =& new $class($settings);
  128. } elseif ($type === 'Model') {
  129. if ($plugin && class_exists($plugin . 'AppModel')) {
  130. $appModel = $plugin . 'AppModel';
  131. } else {
  132. $appModel = 'AppModel';
  133. }
  134. $settings['name'] = $class;
  135. ${$class} =& new $appModel($settings);
  136. }
  137. if (!isset(${$class})) {
  138. trigger_error(sprintf(__('(ClassRegistry::init() could not create instance of %1$s class %2$s ', true), $class, $type), E_USER_WARNING);
  139. return $false;
  140. }
  141. if ($type !== 'Model') {
  142. $_this->addObject($alias, ${$class});
  143. } else {
  144. $_this->map($alias, $class);
  145. }
  146. } elseif (is_numeric($settings)) {
  147. trigger_error(__('(ClassRegistry::init() Attempted to create instance of a class with a numeric name', true), E_USER_WARNING);
  148. return $false;
  149. }
  150. }
  151. if ($count > 1) {
  152. return $true;
  153. }
  154. return ${$class};
  155. }
  156. /**
  157. * Add $object to the registry, associating it with the name $key.
  158. *
  159. * @param string $key Key for the object in registry
  160. * @param mixed $object Object to store
  161. * @return boolean True if the object was written, false if $key already exists
  162. * @access public
  163. * @static
  164. */
  165. function addObject($key, &$object) {
  166. $_this =& ClassRegistry::getInstance();
  167. $key = Inflector::underscore($key);
  168. if (!isset($_this->__objects[$key])) {
  169. $_this->__objects[$key] =& $object;
  170. return true;
  171. }
  172. return false;
  173. }
  174. /**
  175. * Remove object which corresponds to given key.
  176. *
  177. * @param string $key Key of object to remove from registry
  178. * @return void
  179. * @access public
  180. * @static
  181. */
  182. function removeObject($key) {
  183. $_this =& ClassRegistry::getInstance();
  184. $key = Inflector::underscore($key);
  185. if (isset($_this->__objects[$key])) {
  186. unset($_this->__objects[$key]);
  187. }
  188. }
  189. /**
  190. * Returns true if given key is present in the ClassRegistry.
  191. *
  192. * @param string $key Key to look for
  193. * @return boolean true if key exists in registry, false otherwise
  194. * @access public
  195. * @static
  196. */
  197. function isKeySet($key) {
  198. $_this =& ClassRegistry::getInstance();
  199. $key = Inflector::underscore($key);
  200. if (isset($_this->__objects[$key])) {
  201. return true;
  202. } elseif (isset($_this->__map[$key])) {
  203. return true;
  204. }
  205. return false;
  206. }
  207. /**
  208. * Get all keys from the registry.
  209. *
  210. * @return array Set of keys stored in registry
  211. * @access public
  212. * @static
  213. */
  214. function keys() {
  215. $_this =& ClassRegistry::getInstance();
  216. return array_keys($_this->__objects);
  217. }
  218. /**
  219. * Return object which corresponds to given key.
  220. *
  221. * @param string $key Key of object to look for
  222. * @return mixed Object stored in registry
  223. * @access public
  224. * @static
  225. */
  226. function &getObject($key) {
  227. $_this =& ClassRegistry::getInstance();
  228. $key = Inflector::underscore($key);
  229. $return = false;
  230. if (isset($_this->__objects[$key])) {
  231. $return =& $_this->__objects[$key];
  232. } else {
  233. $key = $_this->__getMap($key);
  234. if (isset($_this->__objects[$key])) {
  235. $return =& $_this->__objects[$key];
  236. }
  237. }
  238. return $return;
  239. }
  240. /**
  241. * Sets the default constructor parameter for an object type
  242. *
  243. * @param string $type Type of object. If this parameter is omitted, defaults to "Model"
  244. * @param array $param The parameter that will be passed to object constructors when objects
  245. * of $type are created
  246. * @return mixed Void if $param is being set. Otherwise, if only $type is passed, returns
  247. * the previously-set value of $param, or null if not set.
  248. * @access public
  249. * @static
  250. */
  251. function config($type, $param = array()) {
  252. $_this =& ClassRegistry::getInstance();
  253. if (empty($param) && is_array($type)) {
  254. $param = $type;
  255. $type = 'Model';
  256. } elseif (is_null($param)) {
  257. unset($_this->__config[$type]);
  258. } elseif (empty($param) && is_string($type)) {
  259. return isset($_this->__config[$type]) ? $_this->__config[$type] : null;
  260. }
  261. $_this->__config[$type] = $param;
  262. }
  263. /**
  264. * Checks to see if $alias is a duplicate $class Object
  265. *
  266. * @param string $alias
  267. * @param string $class
  268. * @return boolean
  269. * @access private
  270. * @static
  271. */
  272. function &__duplicate($alias, $class) {
  273. $duplicate = false;
  274. if ($this->isKeySet($alias)) {
  275. $model =& $this->getObject($alias);
  276. if (is_object($model) && (is_a($model, $class) || $model->alias === $class)) {
  277. $duplicate =& $model;
  278. }
  279. unset($model);
  280. }
  281. return $duplicate;
  282. }
  283. /**
  284. * Add a key name pair to the registry to map name to class in the registry.
  285. *
  286. * @param string $key Key to include in map
  287. * @param string $name Key that is being mapped
  288. * @access public
  289. * @static
  290. */
  291. function map($key, $name) {
  292. $_this =& ClassRegistry::getInstance();
  293. $key = Inflector::underscore($key);
  294. $name = Inflector::underscore($name);
  295. if (!isset($_this->__map[$key])) {
  296. $_this->__map[$key] = $name;
  297. }
  298. }
  299. /**
  300. * Get all keys from the map in the registry.
  301. *
  302. * @return array Keys of registry's map
  303. * @access public
  304. * @static
  305. */
  306. function mapKeys() {
  307. $_this =& ClassRegistry::getInstance();
  308. return array_keys($_this->__map);
  309. }
  310. /**
  311. * Return the name of a class in the registry.
  312. *
  313. * @param string $key Key to find in map
  314. * @return string Mapped value
  315. * @access private
  316. * @static
  317. */
  318. function __getMap($key) {
  319. if (isset($this->__map[$key])) {
  320. return $this->__map[$key];
  321. }
  322. }
  323. /**
  324. * Flushes all objects from the ClassRegistry.
  325. *
  326. * @return void
  327. * @access public
  328. * @static
  329. */
  330. function flush() {
  331. $_this =& ClassRegistry::getInstance();
  332. $_this->__objects = array();
  333. $_this->__map = array();
  334. }
  335. }
  336. ?>