* @license PHP License * @package WB * @subpackage base */ // load WBStdClass, it it is not there yet if (!class_exists('WBStdClass', false)) { include dirname(__FILE__) . '/StdClass.php'; } /** * Class utilities * * Allows to load classes etc. * * @version 0.2.1 * @package WB * @subpackage base */ class WBClass extends WBStdClass { /** * List of loaded classes * * Each entry is corresponds to a class and tells how often it was * reqested to load. * * @var array */ static protected $_loaded = array( 'WBClass' => 1, 'WBStdClass' => 1 ); /** * List of local class folders * * The default list contains WB (of course) and pat * which is linked into the wombat * * @var array */ static protected $_locals = array( 'WB' => 'Wombat::WB/', 'pat' => 'Pat::pat/pat' ); /** * Local include dirs * * @var array */ static protected $_incDir = array(); /** * class loader * @var array WBClass_Loader */ static protected $loaders = array(); /** * load class and instantiate it * * Handy function and generic replacement of "new" * * @param string $clazz the class name of the class to be created * @param array $parameter associative array of options * @return WBStdClass */ static public function create($clazz, $parameter = array() ) { if (!self::includeClass( $clazz)) { self::includeClass('WBException_Class'); throw new WBException_Class('Could not create instance of "'. $clazz . '" because class does not exist.', 1, __CLASS__ ); } $creatorClazz = 'WBClass_Creator_' . $clazz; if (self::includeClass($creatorClazz)) { $creator = new $creatorClazz(); $obj = $creator->instantiate($parameter); return $obj; } $obj = new $clazz($parameter); return $obj; } /** * Load class or classes * * @see includeClass() * @param string $class the class name to be loaded or many class names * @return bool true if last include was successful */ static public function load() { // load all classes $clazzes = func_get_args(); $result = true; foreach ($clazzes as $clazz) { $result = self::includeClass($clazz); } return $result; } /** * Load class or classes * * Fancy replacement of require_once, include_once. This also makes sure the * static-constructor is called * * @param string $class the class name to be loaded or many class names * @return bool always true */ protected static function includeClass($clazz) { // check whether this class is loaded already if (isset(self::$_loaded[$clazz])) { if (0 < self::$_loaded[$clazz]) { ++self::$_loaded[$clazz]; return true; } return false; } else if (class_exists($clazz, false)) { self::$_loaded[$clazz] = 1; return true; } $loaded = false; $local = false; foreach (self::$_locals as $prefix => $param) { $length = strlen($prefix); if (strncmp($prefix, $clazz, $length) != 0) { continue; } $local = true; $loaded = self::$loaders[$prefix]->load($clazz, $param); break; } // load "non-local" classes (like PEAR classes etc.) if (!$local) { $file = str_replace('_', '/', $clazz) . '.php'; // avoid double include for non-local classes if (class_exists($clazz, false)) { self::$_loaded[$clazz] = 1; return true; } // avoid ugly warning $loaded = include $file; } if (!$loaded) { self::$_loaded[$clazz] = -1; return false; } // created counter bofore static constructor is called self::$_loaded[$clazz] = 1; // call static constructor if (method_exists($clazz, 'staticConstruct')) { call_user_func(array($clazz, 'staticConstruct')); } return true; } /** * Static constructor * * Starts the configurator helper object */ static public function staticConstruct() { // basic include folder self::$_incDir[] = realpath(dirname(__FILE__) . '/..'); // load standard class loader if (!class_exists('WBClass_Loader', false)) { include dirname(__FILE__) . '/Class/Loader.php'; self::$_loaded['WBClass_Loader'] = 1; } if (!class_exists('WBClass_Loader_Wombat', false)) { include dirname(__FILE__) . '/Class/Loader/Wombat.php'; self::$_loaded['WBClass_Loader_Wombat'] = 1; } // create the hen to produce eggs self::$loaders['WB'] = new WBClass_Loader_Wombat(); self::$loaders['WB']->setIncDir(self::$_incDir); $param = explode('::', self::$_locals['WB'], 2); if (1 == count($param)) { $param = array('Wombat', $param[0]); } self::$loaders['WB']->setParameter('WB', $param); // load some basic classes WBClass::load('WBException' , 'WBParam' , 'WBParam_Observer' , 'WBErrorHandler' , 'WBErrorHandler_Php' , 'WBErrorHandler_Exception' , 'WBClass_Configurator' , 'WBClass_Creator' , 'WBEvent' ); $tmp = self::$_locals; unset(self::$_locals['pat']); self::updateLocals($tmp); // observe parameter WBClass_Configurator::start(); } /** * update list of local prefixes * * Configure class loader according to prefixes and parameter * * @param array $locals */ static protected function updateLocals($locals) { krsort($locals); $loaders = array(); foreach ($locals as $prefix => $param) { // remember list of prefixes $loaders[] = $prefix; // no changes if (isset(self::$_locals[$prefix]) && self::$_locals[$prefix] == $param) { continue; } // extract loader from parameter $param = explode('::', $param, 2); if (1 == count($param)) { $param = array('Wombat', $param[0]); } $obj = self::create('WBClass_Loader_' . $param[0]); $obj->setIncDir(self::$_incDir); $obj->setParameter($prefix, $param); self::$loaders[$prefix] = $obj; } // remove "old" loaders foreach (self::$loaders as $prefix => &$obj) { if (in_array($prefix, $loaders)) { continue; } $obj = null; } self::$_locals = $locals; } /** * update list of include folders * * Tell all loaders about new list of include dirs * * @param array $dirs */ static protected function updateIncDir($dirs) { self::$_incDir = $dirs; foreach (self::$loaders as $loader) { $loader->setIncDir(self::$_incDir); } } /** * Register or unregister autoload function * * @param bool $register whether to register WBClass * @return bool true on success */ static public function registerAutoload($register = true) { if (empty($register)) { spl_autoload_unregister(array('WBClass', 'load')); return true; } spl_autoload_register(array('WBClass', 'load')); return true; } /** * receive list of all loaded classes * * @return array associative array of loaded classes * @see $_loaded */ static public function getLoaded() { return self::$_loaded; } } // execute static constructor :-) WBClass::staticConstruct();