class_registry.php

Go to the documentation of this file.
00001 <?php
00002 /* SVN FILE: $Id: class_registry.php 8015 2009-02-04 05:00:59Z mark_story $ */
00003 /**
00004  * Class collections.
00005  *
00006  * A repository for class objects, each registered with a key.
00007  *
00008  * PHP versions 4 and 5
00009  *
00010  * CakePHP(tm) :  Rapid Development Framework (http://www.cakephp.org)
00011  * Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
00012  *
00013  * Licensed under The MIT License
00014  * Redistributions of files must retain the above copyright notice.
00015  *
00016  * @filesource
00017  * @copyright     Copyright 2005-2008, Cake Software Foundation, Inc. (http://www.cakefoundation.org)
00018  * @link          http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
00019  * @package       cake
00020  * @subpackage    cake.cake.libs
00021  * @since         CakePHP(tm) v 0.9.2
00022  * @version       $Revision: 8015 $
00023  * @modifiedby    $LastChangedBy: mark_story $
00024  * @lastmodified  $Date: 2009-02-04 00:00:59 -0500 (Wed, 04 Feb 2009) $
00025  * @license       http://www.opensource.org/licenses/mit-license.php The MIT License
00026  */
00027 /**
00028  * Class Collections.
00029  *
00030  * A repository for class objects, each registered with a key.
00031  * If you try to add an object with the same key twice, nothing will come of it.
00032  * If you need a second instance of an object, give it another key.
00033  *
00034  * @package       cake
00035  * @subpackage    cake.cake.libs
00036  */
00037 class ClassRegistry {
00038 /**
00039  * Names of classes with their objects.
00040  *
00041  * @var array
00042  * @access private
00043  */
00044     var $__objects = array();
00045 /**
00046  * Names of class names mapped to the object in the registry.
00047  *
00048  * @var array
00049  * @access private
00050  */
00051     var $__map = array();
00052 /**
00053  * Default constructor parameter settings, indexed by type
00054  *
00055  * @var array
00056  * @access private
00057  */
00058     var $__config = array();
00059 /**
00060  * Return a singleton instance of the ClassRegistry.
00061  *
00062  * @return ClassRegistry instance
00063  * @access public
00064  */
00065     function &getInstance() {
00066         static $instance = array();
00067         if (!$instance) {
00068             $instance[0] =& new ClassRegistry();
00069         }
00070         return $instance[0];
00071     }
00072 /**
00073  * Loads a class, registers the object in the registry and returns instance of the object.
00074  *
00075  * Examples
00076  * Simple Use: Get a Post model instance ```ClassRegistry::init('Post');```
00077  * 
00078  * Exapanded: ```array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'TypeOfClass');```
00079  * 
00080  * Model Classes can accept optional ```array('id' => $id, 'table' => $table, 'ds' => $ds, 'alias' => $alias);```
00081  * 
00082  * When $class is a numeric keyed array, multiple class instances will be stored in the registry,
00083  *  no instance of the object will be returned
00084  * {{{
00085  * array(
00086  *      array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'TypeOfClass'),
00087  *      array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'TypeOfClass'),
00088  *      array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'TypeOfClass')
00089  * );
00090  * }}}
00091  * @param mixed $class as a string or a single key => value array instance will be created,
00092  *  stored in the registry and returned.
00093  * @param string $type TypeOfClass
00094  * @return object instance of ClassName
00095  * @access public
00096  * @static
00097  */
00098     function &init($class, $type = null) {
00099         $_this =& ClassRegistry::getInstance();
00100         $id = $false = false;
00101         $true = true;
00102 
00103         if (!$type) {
00104             $type = 'Model';
00105         }
00106 
00107         if (is_array($class)) {
00108             $objects = $class;
00109             if (!isset($class[0])) {
00110                 $objects = array($class);
00111             }
00112         } else {
00113             $objects = array(array('class' => $class));
00114         }
00115         $defaults = isset($_this->__config[$type]) ? $_this->__config[$type] : array();
00116         $count = count($objects);
00117 
00118         foreach ($objects as $key => $settings) {
00119             if (is_array($settings)) {
00120                 $plugin = $pluginPath = null;
00121                 $settings = array_merge($defaults, $settings);
00122                 $class = $settings['class'];
00123 
00124                 if (strpos($class, '.') !== false) {
00125                     list($plugin, $class) = explode('.', $class);
00126                     $pluginPath = $plugin . '.';
00127                 }
00128 
00129                 if (empty($settings['alias'])) {
00130                     $settings['alias'] = $class;
00131                 }
00132                 $alias = $settings['alias'];
00133 
00134                 if ($model =& $_this->__duplicate($alias, $class)) {
00135                     $_this->map($alias, $class);
00136                     return $model;
00137                 }
00138 
00139                 if (class_exists($class) || App::import($type, $pluginPath . $class)) {
00140                     ${$class} =& new $class($settings);
00141                 } elseif ($type === 'Model') {
00142                     if ($plugin && class_exists($plugin . 'AppModel')) {
00143                         $appModel = $plugin . 'AppModel';
00144                     } else {
00145                         $appModel = 'AppModel';
00146                     }
00147                     $settings['name'] = $class;
00148                     ${$class} =& new $appModel($settings);
00149                 }
00150 
00151                 if (!isset(${$class})) {
00152                     trigger_error(sprintf(__('(ClassRegistry::init() could not create instance of %1$s class %2$s ', true), $class, $type), E_USER_WARNING);
00153                     return $false;
00154                 }
00155 
00156                 if ($type !== 'Model') {
00157                     $_this->addObject($alias, ${$class});
00158                 } else {
00159                     $_this->map($alias, $class);
00160                 }
00161             } elseif (is_numeric($settings)) {
00162                 trigger_error(__('(ClassRegistry::init() Attempted to create instance of a class with a numeric name', true), E_USER_WARNING);
00163                 return $false;
00164             }
00165         }
00166 
00167         if ($count > 1) {
00168             return $true;
00169         }
00170         return ${$class};
00171     }
00172 /**
00173  * Add $object to the registry, associating it with the name $key.
00174  *
00175  * @param string $key   Key for the object in registry
00176  * @param mixed $object Object to store
00177  * @return boolean True if the object was written, false if $key already exists
00178  * @access public
00179  * @static
00180  */
00181     function addObject($key, &$object) {
00182         $_this =& ClassRegistry::getInstance();
00183         $key = Inflector::underscore($key);
00184         if (!isset($_this->__objects[$key])) {
00185             $_this->__objects[$key] =& $object;
00186             return true;
00187         }
00188         return false;
00189     }
00190 /**
00191  * Remove object which corresponds to given key.
00192  *
00193  * @param string $key   Key of object to remove from registry
00194  * @return void
00195  * @access public
00196  * @static
00197  */
00198     function removeObject($key) {
00199         $_this =& ClassRegistry::getInstance();
00200         $key = Inflector::underscore($key);
00201         if (isset($_this->__objects[$key])) {
00202             unset($_this->__objects[$key]);
00203         }
00204     }
00205 /**
00206  * Returns true if given key is present in the ClassRegistry.
00207  *
00208  * @param string $key Key to look for
00209  * @return boolean true if key exists in registry, false otherwise
00210  * @access public
00211  * @static
00212  */
00213     function isKeySet($key) {
00214         $_this =& ClassRegistry::getInstance();
00215         $key = Inflector::underscore($key);
00216         if (isset($_this->__objects[$key])) {
00217             return true;
00218         } elseif (isset($_this->__map[$key])) {
00219             return true;
00220         }
00221         return false;
00222     }
00223 /**
00224  * Get all keys from the registry.
00225  *
00226  * @return array Set of keys stored in registry
00227  * @access public
00228  * @static
00229  */
00230     function keys() {
00231         $_this =& ClassRegistry::getInstance();
00232         return array_keys($_this->__objects);
00233     }
00234 /**
00235  * Return object which corresponds to given key.
00236  *
00237  * @param string $key Key of object to look for
00238  * @return mixed Object stored in registry
00239  * @access public
00240  * @static
00241  */
00242     function &getObject($key) {
00243         $_this =& ClassRegistry::getInstance();
00244         $key = Inflector::underscore($key);
00245         $return = false;
00246         if (isset($_this->__objects[$key])) {
00247             $return =& $_this->__objects[$key];
00248         } else {
00249             $key = $_this->__getMap($key);
00250             if (isset($_this->__objects[$key])) {
00251                 $return =& $_this->__objects[$key];
00252             }
00253         }
00254         return $return;
00255     }
00256 /**
00257  * Sets the default constructor parameter for an object type
00258  *
00259  * @param string $type Type of object.  If this parameter is omitted, defaults to "Model"
00260  * @param array $param The parameter that will be passed to object constructors when objects
00261  *                      of $type are created
00262  * @return mixed Void if $param is being set.  Otherwise, if only $type is passed, returns
00263  *               the previously-set value of $param, or null if not set.
00264  * @access public
00265  * @static
00266  */
00267     function config($type, $param = array()) {
00268         $_this =& ClassRegistry::getInstance();
00269 
00270         if (empty($param) && is_array($type)) {
00271             $param = $type;
00272             $type = 'Model';
00273         } elseif (is_null($param)) {
00274             unset($_this->__config[$type]);
00275         } elseif (empty($param) && is_string($type)) {
00276             return isset($_this->__config[$type]) ? $_this->__config[$type] : null;
00277         }
00278         $_this->__config[$type] = $param;
00279     }
00280 /**
00281  * Checks to see if $alias is a duplicate $class Object
00282  *
00283  * @param string $alias
00284  * @param string $class
00285  * @return boolean
00286  * @access private
00287  * @static
00288  */
00289     function &__duplicate($alias,  $class) {
00290         $duplicate = false;
00291         if ($this->isKeySet($alias)) {
00292             $model =& $this->getObject($alias);
00293             if (is_object($model) && (is_a($model, $class) || $model->alias === $class)) {
00294                 $duplicate =& $model;
00295             }
00296             unset($model);
00297         }
00298         return $duplicate;
00299     }
00300 /**
00301  * Add a key name pair to the registry to map name to class in the registry.
00302  *
00303  * @param string $key Key to include in map
00304  * @param string $name Key that is being mapped
00305  * @access public
00306  * @static
00307  */
00308     function map($key, $name) {
00309         $_this =& ClassRegistry::getInstance();
00310         $key = Inflector::underscore($key);
00311         $name = Inflector::underscore($name);
00312         if (!isset($_this->__map[$key])) {
00313             $_this->__map[$key] = $name;
00314         }
00315     }
00316 /**
00317  * Get all keys from the map in the registry.
00318  *
00319  * @return array Keys of registry's map
00320  * @access public
00321  * @static
00322  */
00323     function mapKeys() {
00324         $_this =& ClassRegistry::getInstance();
00325         return array_keys($_this->__map);
00326     }
00327 /**
00328  * Return the name of a class in the registry.
00329  *
00330  * @param string $key Key to find in map
00331  * @return string Mapped value
00332  * @access private
00333  * @static
00334  */
00335     function __getMap($key) {
00336         if (isset($this->__map[$key])) {
00337             return $this->__map[$key];
00338         }
00339     }
00340 /**
00341  * Flushes all objects from the ClassRegistry.
00342  *
00343  * @return void
00344  * @access public
00345  * @static
00346  */
00347     function flush() {
00348         $_this =& ClassRegistry::getInstance();
00349         $_this->__objects = array();
00350         $_this->__map = array();
00351     }
00352 }
00353 ?>

Generated on Sun Nov 22 00:30:52 2009 for CakePHP 1.2.x.x (v1.2.4.8284) by doxygen 1.4.7