diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cake/libs/class_registry.php	Sun Jul 24 21:08:31 2011 +0900
@@ -0,0 +1,365 @@
+<?php
+/**
+ * Class collections.
+ *
+ * A repository for class objects, each registered with a key.
+ *
+ * PHP versions 4 and 5
+ *
+ * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
+ * Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ *
+ * Licensed under The MIT License
+ * Redistributions of files must retain the above copyright notice.
+ *
+ * @copyright     Copyright 2005-2010, Cake Software Foundation, Inc. (http://cakefoundation.org)
+ * @link          http://cakephp.org CakePHP(tm) Project
+ * @package       cake
+ * @subpackage    cake.cake.libs
+ * @since         CakePHP(tm) v 0.9.2
+ * @license       MIT License (http://www.opensource.org/licenses/mit-license.php)
+ */
+
+/**
+ * Class Collections.
+ *
+ * A repository for class objects, each registered with a key.
+ * If you try to add an object with the same key twice, nothing will come of it.
+ * If you need a second instance of an object, give it another key.
+ *
+ * @package       cake
+ * @subpackage    cake.cake.libs
+ */
+class ClassRegistry {
+
+/**
+ * Names of classes with their objects.
+ *
+ * @var array
+ * @access private
+ */
+	var $__objects = array();
+
+/**
+ * Names of class names mapped to the object in the registry.
+ *
+ * @var array
+ * @access private
+ */
+	var $__map = array();
+
+/**
+ * Default constructor parameter settings, indexed by type
+ *
+ * @var array
+ * @access private
+ */
+	var $__config = array();
+
+/**
+ * Return a singleton instance of the ClassRegistry.
+ *
+ * @return ClassRegistry instance
+ * @access public
+ */
+	function &getInstance() {
+		static $instance = array();
+		if (!$instance) {
+			$instance[0] =& new ClassRegistry();
+		}
+		return $instance[0];
+	}
+
+/**
+ * Loads a class, registers the object in the registry and returns instance of the object. ClassRegistry::init()
+ * is used as a factory for models, and handle correct injecting of settings, that assist in testing.
+ *
+ * Examples
+ * Simple Use: Get a Post model instance ```ClassRegistry::init('Post');```
+ *
+ * Exapanded: ```array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'Model');```
+ *
+ * Model Classes can accept optional ```array('id' => $id, 'table' => $table, 'ds' => $ds, 'alias' => $alias);```
+ *
+ * When $class is a numeric keyed array, multiple class instances will be stored in the registry,
+ *  no instance of the object will be returned
+ * {{{
+ * array(
+ *		array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'Model'),
+ *		array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'Model'),
+ *		array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'Model')
+ * );
+ * }}}
+ * @param mixed $class as a string or a single key => value array instance will be created,
+ *  stored in the registry and returned.
+ * @param string $type Only model is accepted as a valid value for $type.
+ * @return object instance of ClassName
+ * @access public
+ * @static
+ */
+	function &init($class, $type = null) {
+		$_this =& ClassRegistry::getInstance();
+		$id = $false = false;
+		$true = true;
+
+		if (!$type) {
+			$type = 'Model';
+		}
+
+		if (is_array($class)) {
+			$objects = $class;
+			if (!isset($class[0])) {
+				$objects = array($class);
+			}
+		} else {
+			$objects = array(array('class' => $class));
+		}
+		$defaults = isset($_this->__config[$type]) ? $_this->__config[$type] : array();
+		$count = count($objects);
+
+		foreach ($objects as $key => $settings) {
+			if (is_array($settings)) {
+				$pluginPath = null;
+				$settings = array_merge($defaults, $settings);
+				$class = $settings['class'];
+				
+				list($plugin, $class) = pluginSplit($class);
+				if ($plugin) {
+					$pluginPath = $plugin . '.';
+				}
+
+				if (empty($settings['alias'])) {
+					$settings['alias'] = $class;
+				}
+				$alias = $settings['alias'];
+
+				if ($model =& $_this->__duplicate($alias, $class)) {
+					$_this->map($alias, $class);
+					return $model;
+				}
+
+				if (class_exists($class) || App::import($type, $pluginPath . $class)) {
+					${$class} =& new $class($settings);
+				} elseif ($type === 'Model') {
+					if ($plugin && class_exists($plugin . 'AppModel')) {
+						$appModel = $plugin . 'AppModel';
+					} else {
+						$appModel = 'AppModel';
+					}
+					$settings['name'] = $class;
+					${$class} =& new $appModel($settings);
+				}
+
+				if (!isset(${$class})) {
+					trigger_error(sprintf(__('(ClassRegistry::init() could not create instance of %1$s class %2$s ', true), $class, $type), E_USER_WARNING);
+					return $false;
+				}
+
+				if ($type !== 'Model') {
+					$_this->addObject($alias, ${$class});
+				} else {
+					$_this->map($alias, $class);
+				}
+			} elseif (is_numeric($settings)) {
+				trigger_error(__('(ClassRegistry::init() Attempted to create instance of a class with a numeric name', true), E_USER_WARNING);
+				return $false;
+			}
+		}
+
+		if ($count > 1) {
+			return $true;
+		}
+		return ${$class};
+	}
+
+/**
+ * Add $object to the registry, associating it with the name $key.
+ *
+ * @param string $key	Key for the object in registry
+ * @param mixed $object	Object to store
+ * @return boolean True if the object was written, false if $key already exists
+ * @access public
+ * @static
+ */
+	function addObject($key, &$object) {
+		$_this =& ClassRegistry::getInstance();
+		$key = Inflector::underscore($key);
+		if (!isset($_this->__objects[$key])) {
+			$_this->__objects[$key] =& $object;
+			return true;
+		}
+		return false;
+	}
+
+/**
+ * Remove object which corresponds to given key.
+ *
+ * @param string $key	Key of object to remove from registry
+ * @return void
+ * @access public
+ * @static
+ */
+	function removeObject($key) {
+		$_this =& ClassRegistry::getInstance();
+		$key = Inflector::underscore($key);
+		if (isset($_this->__objects[$key])) {
+			unset($_this->__objects[$key]);
+		}
+	}
+
+/**
+ * Returns true if given key is present in the ClassRegistry.
+ *
+ * @param string $key Key to look for
+ * @return boolean true if key exists in registry, false otherwise
+ * @access public
+ * @static
+ */
+	function isKeySet($key) {
+		$_this =& ClassRegistry::getInstance();
+		$key = Inflector::underscore($key);
+		if (isset($_this->__objects[$key])) {
+			return true;
+		} elseif (isset($_this->__map[$key])) {
+			return true;
+		}
+		return false;
+	}
+
+/**
+ * Get all keys from the registry.
+ *
+ * @return array Set of keys stored in registry
+ * @access public
+ * @static
+ */
+	function keys() {
+		$_this =& ClassRegistry::getInstance();
+		return array_keys($_this->__objects);
+	}
+
+/**
+ * Return object which corresponds to given key.
+ *
+ * @param string $key Key of object to look for
+ * @return mixed Object stored in registry or boolean false if the object does not exist.
+ * @access public
+ * @static
+ */
+	function &getObject($key) {
+		$_this =& ClassRegistry::getInstance();
+		$key = Inflector::underscore($key);
+		$return = false;
+		if (isset($_this->__objects[$key])) {
+			$return =& $_this->__objects[$key];
+		} else {
+			$key = $_this->__getMap($key);
+			if (isset($_this->__objects[$key])) {
+				$return =& $_this->__objects[$key];
+			}
+		}
+		return $return;
+	}
+
+/**
+ * Sets the default constructor parameter for an object type
+ *
+ * @param string $type Type of object.  If this parameter is omitted, defaults to "Model"
+ * @param array $param The parameter that will be passed to object constructors when objects
+ *                      of $type are created
+ * @return mixed Void if $param is being set.  Otherwise, if only $type is passed, returns
+ *               the previously-set value of $param, or null if not set.
+ * @access public
+ * @static
+ */
+	function config($type, $param = array()) {
+		$_this =& ClassRegistry::getInstance();
+
+		if (empty($param) && is_array($type)) {
+			$param = $type;
+			$type = 'Model';
+		} elseif (is_null($param)) {
+			unset($_this->__config[$type]);
+		} elseif (empty($param) && is_string($type)) {
+			return isset($_this->__config[$type]) ? $_this->__config[$type] : null;
+		}
+		$_this->__config[$type] = $param;
+	}
+
+/**
+ * Checks to see if $alias is a duplicate $class Object
+ *
+ * @param string $alias
+ * @param string $class
+ * @return boolean
+ * @access private
+ * @static
+ */
+	function &__duplicate($alias,  $class) {
+		$duplicate = false;
+		if ($this->isKeySet($alias)) {
+			$model =& $this->getObject($alias);
+			if (is_object($model) && (is_a($model, $class) || $model->alias === $class)) {
+				$duplicate =& $model;
+			}
+			unset($model);
+		}
+		return $duplicate;
+	}
+
+/**
+ * Add a key name pair to the registry to map name to class in the registry.
+ *
+ * @param string $key Key to include in map
+ * @param string $name Key that is being mapped
+ * @access public
+ * @static
+ */
+	function map($key, $name) {
+		$_this =& ClassRegistry::getInstance();
+		$key = Inflector::underscore($key);
+		$name = Inflector::underscore($name);
+		if (!isset($_this->__map[$key])) {
+			$_this->__map[$key] = $name;
+		}
+	}
+
+/**
+ * Get all keys from the map in the registry.
+ *
+ * @return array Keys of registry's map
+ * @access public
+ * @static
+ */
+	function mapKeys() {
+		$_this =& ClassRegistry::getInstance();
+		return array_keys($_this->__map);
+	}
+
+/**
+ * Return the name of a class in the registry.
+ *
+ * @param string $key Key to find in map
+ * @return string Mapped value
+ * @access private
+ * @static
+ */
+	function __getMap($key) {
+		if (isset($this->__map[$key])) {
+			return $this->__map[$key];
+		}
+	}
+
+/**
+ * Flushes all objects from the ClassRegistry.
+ *
+ * @return void
+ * @access public
+ * @static
+ */
+	function flush() {
+		$_this =& ClassRegistry::getInstance();
+		$_this->__objects = array();
+		$_this->__map = array();
+	}
+}