class_registry.php

Go to the documentation of this file.
00001 <?php
00002 /* SVN FILE: $Id: class__registry_8php-source.html 580 2008-07-01 14:45:49Z gwoo $ */
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.
00012  *                              1785 E. Sahara Avenue, Suite 490-204
00013  *                              Las Vegas, Nevada 89104
00014  *
00015  * Licensed under The MIT License
00016  * Redistributions of files must retain the above copyright notice.
00017  *
00018  * @filesource
00019  * @copyright       Copyright 2005-2008, Cake Software Foundation, Inc.
00020  * @link                http://www.cakefoundation.org/projects/info/cakephp CakePHP(tm) Project
00021  * @package         cake
00022  * @subpackage      cake.cake.libs
00023  * @since           CakePHP(tm) v 0.9.2
00024  * @version         $Revision: 580 $
00025  * @modifiedby      $LastChangedBy: gwoo $
00026  * @lastmodified    $Date: 2008-07-01 09:45:49 -0500 (Tue, 01 Jul 2008) $
00027  * @license         http://www.opensource.org/licenses/mit-license.php The MIT License
00028  */
00029 /**
00030  * Class Collections.
00031  *
00032  * A repository for class objects, each registered with a key.
00033  * If you try to add an object with the same key twice, nothing will come of it.
00034  * If you need a second instance of an object, give it another key.
00035  *
00036  * @package     cake
00037  * @subpackage  cake.cake.libs
00038  */
00039 class ClassRegistry {
00040 /**
00041  * Names of classes with their objects.
00042  *
00043  * @var array
00044  * @access private
00045  */
00046     var $__objects = array();
00047 /**
00048  * Names of class names mapped to the object in the registry.
00049  *
00050  * @var array
00051  * @access private
00052  */
00053     var $__map = array();
00054 /**
00055  * Return a singleton instance of the ClassRegistry.
00056  *
00057  * @return ClassRegistry instance
00058  * @access public
00059  */
00060     function &getInstance() {
00061         static $instance = array();
00062         if (!$instance) {
00063             $instance[0] =& new ClassRegistry();
00064         }
00065         return $instance[0];
00066     }
00067 /**
00068  * Loads a class, registers the object in the registry and returns instance of the object.
00069  *
00070  *
00071  * @param mixed $class as a string or a single key => value array instance will be created, stored in the registry and returned.
00072  *   Required: array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'TypeOfClass');
00073  *   Model Classes can accept optional array('id' => $id, 'table' => $table, 'ds' => $ds, 'alias' => $alias);
00074  * When $class is a numeric keyed array, multiple class instances will be stored in the registry, no instance of the object will be returned
00075  *   array(
00076  *  array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'TypeOfClass'),
00077  *  array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'TypeOfClass'),
00078  *  array('class' => 'ClassName', 'alias' => 'AliasNameStoredInTheRegistry', 'type' => 'TypeOfClass'));
00079  *
00080  * @param string $type TypeOfClass
00081  * @return object intance of ClassName
00082  */
00083     function &init($class, $type = null) {
00084         $_this =& ClassRegistry::getInstance();
00085         $id = $false = false;
00086         $table = $ds = $alias = $plugin = null;
00087         $options = null;
00088         $true = true;
00089         if (!$type) {
00090             $type = 'Model';
00091         }
00092 
00093         if (is_array($class)) {
00094             $objects = $class;
00095             if (!isset($class[0])) {
00096                 $objects = array($class);
00097             }
00098         } else {
00099             $objects = array(array('class' => $class));
00100         }
00101 
00102         $count = count($objects);
00103         foreach ($objects as $key => $settings) {
00104             if (is_array($settings)) {
00105                 $plugin = null;
00106                 $settings = array_merge(array('id' => false, 'table' => null, 'ds' => null, 'alias' => null, 'name' => null), $settings);
00107 
00108                 extract($settings, EXTR_OVERWRITE);
00109 
00110                 if (strpos($class, '.') !== false) {
00111                     list($plugin, $class) = explode('.', $class);
00112                     $plugin = $plugin . '.';
00113                 }
00114 
00115                 if (empty($alias)) {
00116                     $alias = $class;
00117                 }
00118 
00119                 if ($_this->_duplicate($alias, $class) && $count == 1) {
00120                     $_this->map($alias, $class);
00121                     return $_this->getObject($alias);
00122                 }
00123 
00124                 if ($type === 'Model') {
00125                     $options = array('id' => $id, 'table' => $table, 'ds' => $ds, 'alias' => $alias, 'name' => $class);
00126                 }
00127                 if (App::import($type, $plugin . $class)) {
00128                     ${$class} =& new $class($options);
00129                 } elseif ($type === 'Model') {
00130                     if ($plugin && class_exists($plugin .'AppModel')) {
00131                         $appModel = $plugin .'AppModel';
00132                     } else {
00133                         $appModel = 'AppModel';
00134                     }
00135                     ${$class} =& new $appModel($options);
00136                 }
00137 
00138                 if (!isset(${$class})) {
00139                     trigger_error(sprintf(__('(ClassRegistry::init() could not create instance of %1$s class %2$s ', true), $class, $type), E_USER_WARNING);
00140                     return $false;
00141                 }
00142 
00143                 if ($type !== 'Model') {
00144                     $_this->addObject($alias, ${$class});
00145                 } else {
00146                     $_this->map($alias, $class);
00147                 }
00148             } elseif (is_numeric($settings)) {
00149                 trigger_error(__('(ClassRegistry::init() Attempted to create instance of a class with a numeric name', true), E_USER_WARNING);
00150                 return $false;
00151             }
00152         }
00153 
00154         if ($count > 1) {
00155             return $true;
00156         }
00157 
00158         return ${$class};
00159     }
00160 /**
00161  * Add $object to the registry, associating it with the name $key.
00162  *
00163  * @param string $key   Key for the object in registry
00164  * @param mixed $object Object to store
00165  * @return boolean True if the object was written, false if $key already exists
00166  * @access public
00167  */
00168     function addObject($key, &$object) {
00169         $_this =& ClassRegistry::getInstance();
00170         $key = Inflector::underscore($key);
00171         if (array_key_exists($key, $_this->__objects) === false) {
00172             $_this->__objects[$key] = &$object;
00173             return true;
00174         }
00175         return false;
00176     }
00177 /**
00178  * Remove object which corresponds to given key.
00179  *
00180  * @param string $key   Key of object to remove from registry
00181  * @access public
00182  */
00183     function removeObject($key) {
00184         $_this =& ClassRegistry::getInstance();
00185         $key = Inflector::underscore($key);
00186         if (array_key_exists($key, $_this->__objects) === true) {
00187             unset($_this->__objects[$key]);
00188         }
00189     }
00190 /**
00191  * Returns true if given key is present in the ClassRegistry.
00192  *
00193  * @param string $key Key to look for
00194  * @return boolean true if key exists in registry, false otherwise
00195  * @access public
00196  */
00197     function isKeySet($key) {
00198         $_this =& ClassRegistry::getInstance();
00199         $key = Inflector::underscore($key);
00200         if (array_key_exists($key, $_this->__objects)) {
00201             return true;
00202         } elseif (array_key_exists($key, $_this->__map)) {
00203             return true;
00204         }
00205         return false;
00206     }
00207 /**
00208  * Get all keys from the regisrty.
00209  *
00210  * @return array Set of keys stored in registry
00211  * @access public
00212  */
00213     function keys() {
00214         $_this =& ClassRegistry::getInstance();
00215         return array_keys($_this->__objects);
00216     }
00217 /**
00218  * Return object which corresponds to given key.
00219  *
00220  * @param string $key Key of object to look for
00221  * @return mixed Object stored in registry
00222  * @access public
00223  */
00224     function &getObject($key) {
00225         $_this =& ClassRegistry::getInstance();
00226         $key = Inflector::underscore($key);
00227 
00228         if (isset($_this->__objects[$key])) {
00229             return $_this->__objects[$key];
00230         } else {
00231             $key = $_this->__getMap($key);
00232             if (isset($_this->__objects[$key])) {
00233                 return $_this->__objects[$key];
00234             }
00235         }
00236 
00237         $return = false;
00238         return $return;
00239     }
00240 /**
00241  * Checks to see if $alias is a duplicate $class Object
00242  *
00243  * @param string $alias
00244  * @param string $class
00245  * @return boolean
00246  */
00247     function _duplicate($alias,  $class) {
00248         $_this =& ClassRegistry::getInstance();
00249         $duplicate = false;
00250 
00251         if ($_this->isKeySet($alias)) {
00252             $model = $_this->getObject($alias);
00253             if (is_a($model, $class)) {
00254                 $duplicate = true;
00255             }
00256             unset($model);
00257         }
00258         return $duplicate;
00259     }
00260 /**
00261  * Add a key name pair to the registry to map name to class in the regisrty.
00262  *
00263  * @param string $key Key to include in map
00264  * @param string $name Key that is being mapped
00265  * @access public
00266  */
00267     function map($key, $name) {
00268         $_this =& ClassRegistry::getInstance();
00269         $key = Inflector::underscore($key);
00270         $name = Inflector::underscore($name);
00271         if (array_key_exists($key, $_this->__map) === false) {
00272             $_this->__map[$key] = $name;
00273         }
00274     }
00275 /**
00276  * Get all keys from the map in the regisrty.
00277  *
00278  * @return array Keys of registry's map
00279  * @access public
00280  */
00281     function mapKeys() {
00282         $_this =& ClassRegistry::getInstance();
00283         return array_keys($_this->__map);
00284     }
00285 /**
00286  * Return the name of a class in the registry.
00287  *
00288  * @param string $key Key to find in map
00289  * @return string Mapped value
00290  * @access private
00291  */
00292     function __getMap($key) {
00293         $_this =& ClassRegistry::getInstance();
00294         if (array_key_exists($key, $_this->__map)) {
00295             return $_this->__map[$key];
00296         }
00297     }
00298 /**
00299  * Flushes all objects from the ClassRegistry.
00300  *
00301  * @access public
00302  */
00303     function flush() {
00304         $_this =& ClassRegistry::getInstance();
00305         $_this->__objects = array();
00306         $_this->__map = array();
00307     }
00308 }
00309 ?>