PageRenderTime 52ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/cake/libs/class_registry.php

https://github.com/msadouni/cakephp2x
PHP | 348 lines | 152 code | 25 blank | 171 comment | 32 complexity | ed9e6c42b9ca14bac9a78998e5979e2b MD5 | raw file
  1. <?php
  2. /**
  3. * Class collections.
  4. *
  5. * A repository for class objects, each registered with a key.
  6. *
  7. * PHP Version 5.x
  8. *
  9. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  10. * Copyright 2005-2009, 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-2009, 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. * Class Collections.
  24. *
  25. * A repository for class objects, each registered with a key.
  26. * If you try to add an object with the same key twice, nothing will come of it.
  27. * If you need a second instance of an object, give it another key.
  28. *
  29. * @package cake
  30. * @subpackage cake.cake.libs
  31. */
  32. final class ClassRegistry {
  33. /**
  34. * Names of classes with their objects.
  35. *
  36. * @var array
  37. * @access private
  38. */
  39. private static $__objects = array();
  40. /**
  41. * Names of class names mapped to the object in the registry.
  42. *
  43. * @var array
  44. * @access private
  45. */
  46. private static $__map = array();
  47. /**
  48. * Default constructor parameter settings, indexed by type
  49. *
  50. * @var array
  51. * @access private
  52. */
  53. private static $__config = array();
  54. /**
  55. * Loads a class, registers the object in the registry and returns instance of the object.
  56. *
  57. * Examples
  58. * Simple Use: Get a Post model instance ```ClassRegistry::init('Post');```
  59. *
  60. * Exapanded: ```array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'TypeOfClass');```
  61. *
  62. * Model Classes can accept optional ```array('id' => $id, 'table' => $table, 'ds' => $ds, 'alias' => $alias);```
  63. *
  64. * When $class is a numeric keyed array, multiple class instances will be stored in the registry,
  65. * no instance of the object will be returned
  66. * {{{
  67. * array(
  68. * array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'TypeOfClass'),
  69. * array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'TypeOfClass'),
  70. * array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'TypeOfClass')
  71. * );
  72. * }}}
  73. * @param mixed $class as a string or a single key => value array instance will be created,
  74. * stored in the registry and returned.
  75. * @param string $type TypeOfClass
  76. * @return object instance of ClassName
  77. * @access public
  78. * @static
  79. */
  80. public static function &init($class, $type = null) {
  81. $id = $false = false;
  82. $true = true;
  83. if (!$type) {
  84. $type = 'Model';
  85. }
  86. if (is_array($class)) {
  87. $objects = $class;
  88. if (!isset($class[0])) {
  89. $objects = array($class);
  90. }
  91. } else {
  92. $objects = array(array('class' => $class));
  93. }
  94. $defaults = isset(self::$__config[$type]) ? self::$__config[$type] : array();
  95. $count = count($objects);
  96. foreach ($objects as $key => $settings) {
  97. if (is_array($settings)) {
  98. $pluginPath = null;
  99. $settings = array_merge($defaults, $settings);
  100. $class = $settings['class'];
  101. list($plugin, $class) = pluginSplit($class);
  102. if ($plugin) {
  103. $pluginPath = $plugin . '.';
  104. }
  105. if (empty($settings['alias'])) {
  106. $settings['alias'] = $class;
  107. }
  108. $alias = $settings['alias'];
  109. if ($model = self::__duplicate($alias, $class)) {
  110. self::map($alias, $class);
  111. return $model;
  112. }
  113. if (class_exists($class) || App::import($type, $pluginPath . $class)) {
  114. ${$class} = new $class($settings);
  115. } elseif ($type === 'Model') {
  116. if ($plugin && class_exists($plugin . 'AppModel')) {
  117. $appModel = $plugin . 'AppModel';
  118. } else {
  119. $appModel = 'AppModel';
  120. }
  121. $settings['name'] = $class;
  122. ${$class} = new $appModel($settings);
  123. }
  124. if (!isset(${$class})) {
  125. trigger_error(sprintf(__('(ClassRegistry::init() could not create instance of %1$s class %2$s ', true), $class, $type), E_USER_WARNING);
  126. return $false;
  127. }
  128. if ($type !== 'Model') {
  129. self::addObject($alias, ${$class});
  130. } else {
  131. self::map($alias, $class);
  132. }
  133. } elseif (is_numeric($settings)) {
  134. trigger_error(__('(ClassRegistry::init() Attempted to create instance of a class with a numeric name', true), E_USER_WARNING);
  135. return $false;
  136. }
  137. }
  138. if ($count > 1) {
  139. return $true;
  140. }
  141. return ${$class};
  142. }
  143. /**
  144. * Add $object to the registry, associating it with the name $key.
  145. *
  146. * @param string $key Key for the object in registry
  147. * @param mixed $object Object to store
  148. * @return boolean True if the object was written, false if $key already exists
  149. * @access public
  150. * @static
  151. */
  152. public static function addObject($key, &$object) {
  153. $key = Inflector::underscore($key);
  154. if (!isset(self::$__objects[$key])) {
  155. self::$__objects[$key] = $object;
  156. return true;
  157. }
  158. return false;
  159. }
  160. /**
  161. * Remove object which corresponds to given key.
  162. *
  163. * @param string $key Key of object to remove from registry
  164. * @return void
  165. * @access public
  166. * @static
  167. */
  168. public static function removeObject($key) {
  169. $key = Inflector::underscore($key);
  170. if (isset(self::$__objects[$key])) {
  171. unset(self::$__objects[$key]);
  172. }
  173. }
  174. /**
  175. * Returns true if given key is present in the ClassRegistry.
  176. *
  177. * @param string $key Key to look for
  178. * @return boolean true if key exists in registry, false otherwise
  179. * @access public
  180. * @static
  181. */
  182. public static function isKeySet($key) {
  183. $key = Inflector::underscore($key);
  184. if (isset(self::$__objects[$key])) {
  185. return true;
  186. } elseif (isset(self::$__map[$key])) {
  187. return true;
  188. }
  189. return false;
  190. }
  191. /**
  192. * Get all keys from the registry.
  193. *
  194. * @return array Set of keys stored in registry
  195. * @access public
  196. * @static
  197. */
  198. public static function keys() {
  199. return array_keys(self::$__objects);
  200. }
  201. /**
  202. * Return object which corresponds to given key.
  203. *
  204. * @param string $key Key of object to look for
  205. * @return mixed Object stored in registry or boolean false if the object does not exist.
  206. * @access public
  207. * @static
  208. */
  209. public static function getObject($key) {
  210. $key = Inflector::underscore($key);
  211. if (isset(self::$__objects[$key])) {
  212. return self::$__objects[$key];
  213. } else {
  214. $key = self::__getMap($key);
  215. if (isset(self::$__objects[$key])) {
  216. return self::$__objects[$key];
  217. }
  218. }
  219. return false;
  220. }
  221. /**
  222. * Return array of objects
  223. *
  224. * @deprecated Remove it later when we've got the visibility fixed
  225. * @return array
  226. * @access public
  227. */
  228. public static function objects() {
  229. return self::$__objects;
  230. }
  231. /**
  232. * Sets the default constructor parameter for an object type
  233. *
  234. * @param string $type Type of object. If this parameter is omitted, defaults to "Model"
  235. * @param array $param The parameter that will be passed to object constructors when objects
  236. * of $type are created
  237. * @return mixed Void if $param is being set. Otherwise, if only $type is passed, returns
  238. * the previously-set value of $param, or null if not set.
  239. * @access public
  240. * @static
  241. */
  242. public static function config($type, $param = array()) {
  243. if (empty($param) && is_array($type)) {
  244. $param = $type;
  245. $type = 'Model';
  246. } elseif (is_null($param)) {
  247. unset(self::$__config[$type]);
  248. } elseif (empty($param) && is_string($type)) {
  249. return isset(self::$__config[$type]) ? self::$__config[$type] : null;
  250. }
  251. self::$__config[$type] = $param;
  252. }
  253. /**
  254. * Add a key name pair to the registry to map name to class in the registry.
  255. *
  256. * @param string $key Key to include in map
  257. * @param string $name Key that is being mapped
  258. * @access public
  259. * @static
  260. */
  261. public static function map($key, $name) {
  262. $key = Inflector::underscore($key);
  263. $name = Inflector::underscore($name);
  264. if (!isset(self::$__map[$key])) {
  265. self::$__map[$key] = $name;
  266. }
  267. }
  268. /**
  269. * Get all keys from the map in the registry.
  270. *
  271. * @return array Keys of registry's map
  272. * @access public
  273. * @static
  274. */
  275. public static function mapKeys() {
  276. return array_keys(self::$__map);
  277. }
  278. /**
  279. * Flushes all objects from the ClassRegistry.
  280. *
  281. * @return void
  282. * @access public
  283. * @static
  284. */
  285. public static function flush() {
  286. self::$__objects = array();
  287. self::$__map = array();
  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. private static function __duplicate($alias, $class) {
  299. $duplicate = false;
  300. if (self::isKeySet($alias)) {
  301. $model = self::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. * Return the name of a class in the registry.
  311. *
  312. * @param string $key Key to find in map
  313. * @return string Mapped value
  314. * @access private
  315. * @static
  316. */
  317. private static function __getMap($key) {
  318. if (isset(self::$__map[$key])) {
  319. return self::$__map[$key];
  320. }
  321. }
  322. }
  323. ?>