_fileInfo[$className] = array( 'filename' => $fileName, 'path' => $relativePath, 'instance' => null); } /** * Here we should do all the factory stuff. * The classes instatiated here will be stored * into our private object cache. If there is no * object of the given type into the cache, 'newInstance' * will be called. * * @access public * @return object */ public function &getInstance(){ /* at least the class name */ if (func_num_args() <= 0) return null; $args = func_get_args(); /* recovering class data */ if ($entry = $this->_getEntry($args[0])) { if (is_null($entry['instance'])) { /* must instantiate it */ if (($obj = call_user_func_array(array($this, "newInstance"), $args)) == null) throw new Exception("Unable to instantiate '".$args[0]."'"); /* saving the object reference */ $this->_setEntryInstance($args[0], $obj); return $obj; } return $entry['instance']; } /* class not allowed */ else throw new Exception("You are not allowed to instantiate class '".$args[0]."'."); } /** * Instantiate classes. * * @todo I think that we don't need to use the reflection * class here. Future work... * @access public * @return object */ public function &newInstance(){ /* at least the class name */ if (func_num_args() <= 0) return null; $args = func_get_args(); $className = array_shift($args); if(!$this->_import($className)) return null; /* I dont know.. maybe we could do better here.. */ $reflectionObj = new ReflectionClass($className); if (count($args) == 0) return $reflectionObj->newInstance(); return $reflectionObj->newInstanceArgs($args); } /** * Private stuff. Handles the cache and information * '$_fileInfo' array. * * @access private * @return array */ private function _getEntry($className){ return $this->_fileInfo[$className]; } /** * Stores the given object into the internal cache * for upcoming requests. * * @access private * @return boolean */ private function _setEntryInstance($className, $obj){ if (is_array($this->_fileInfo[$className])) { $this->_fileInfo[$className]['instance'] = $obj; return true; } return false; } /** * Including (requiring_once ;P ) the file(s) itself. Ideally, * it could be the only place to include files. * * @access private * @return boolean */ private function _import($className){ /* not found */ if (!($entry = $this->_getEntry($className))) throw new Exception('You are not allowed to instantiate '.$className.' class.'); $fullPath = WF_SERVER_ROOT . $entry['path'] . SEP . $entry['filename']; /* file not found */ if (!file_exists($fullPath)) throw new Exception("File '".$fullPath."' not found."); /* including file */ require_once $fullPath; return true; } } ?>