Files = $data['Factory.Files']; $this->realClasses = $data['Factory.realClasses']; } /** * Performs automatic loading of classes registered with the factory * * @param string $class_name * @return void * @throws Exception * @access public */ public function autoload($class_name) { if ( !isset($this->Files[$class_name]) ) { // class not from our factory -> let other autoloaders handle it return; } if ( !file_exists(FULL_PATH . $this->Files[$class_name]) ) { throw new Exception('File ' . FULL_PATH . $this->Files[$class_name] . ' containing class ' . $class_name . ' definition not found'); } kUtil::includeOnce(FULL_PATH . $this->Files[$class_name]); } /** * Gets object data for caching * * @return Array * @access public */ public function getToCache() { return Array ( 'Factory.Files' => $this->Files, 'Factory.realClasses' => $this->realClasses, ); } /** * Splits any mixing of prefix and * special into correct ones * * @param string $prefix_special * @return Array * @access public */ public function processPrefix($prefix_special) { // l.pick, l, m.test_TagProcessor //preg_match("/(.*)\.*(.*)(_*)(.*)/", $prefix_special, $regs); //return Array('prefix'=>$regs[1].$regs[3].$regs[4], 'special'=>$regs[2]); $tmp = explode('_', $prefix_special, 2); $tmp[0] = explode('.', $tmp[0]); $prefix = $tmp[0][0]; $prefix_special = $prefix; // new1 if ( isset($tmp[1]) ) { $prefix .= '_' . $tmp[1]; } $special = isset($tmp[0][1]) ? $tmp[0][1] : ''; $prefix_special .= '.' . $special; // new2 return Array ('prefix' => $prefix, 'special' => $special, 'prefix_special' => $prefix_special); } /** * Returns object using params specified, creates it if is required * * @param string $name * @param string $pseudo_class * @param Array $event_params * @param Array $arguments * @return kBase * @access public */ public function getObject($name, $pseudo_class = '', $event_params = Array (), $arguments = Array ()) { $name = rtrim($name, '.'); if ( isset($this->Storage[$name]) ) { return $this->Storage[$name]; } $ret = $this->processPrefix($name); if ( !$pseudo_class ) { $pseudo_class = $ret['prefix']; } if ( !isset($this->realClasses[$pseudo_class]) ) { $error_msg = 'RealClass not defined for pseudo_class ' . $pseudo_class . ''; if ( $this->Application->isInstalled() ) { throw new Exception($error_msg); } else { if ( $this->Application->isDebugMode() ) { $this->Application->Debugger->appendTrace(); } trigger_error($error_msg, E_USER_WARNING); } return false; } if ( defined('DEBUG_MODE') && defined('DBG_FACTORY') && DBG_FACTORY && $this->Application->isDebugMode() ) { $this->Application->Debugger->appendHTML('Creating object: Pseudo class: ' . $pseudo_class . ' Prefix: ' . $name); $this->Application->Debugger->appendTrace(); } $this->Storage[$name] = $this->makeClass($pseudo_class, $arguments); $this->Storage[$name]->Init($ret['prefix'], $ret['special']); $this->Application->EventManager->runBuildEvent($ret['prefix_special'], $pseudo_class, $event_params); return $this->Storage[$name]; } /** * Removes object from storage, so next time it could be created from scratch * * @param string $name Object's name in the Storage * @return void * @access public */ public function DestroyObject($name) { unset($this->Storage[$name]); } /** * Checks if object with prefix passes was already created in factory * * @param string $name object pseudo_class, prefix * @return bool * @access public */ public function hasObject($name) { return isset($this->Storage[$name]); } /** * Get's real class name for pseudo class, * includes class file and creates class * instance. * All parameters except first one are passed to object constuctor * through mediator method makeClass that creates instance of class * * Pattern: Factory Method * * @param string $pseudo_class * @param Array $arguments * @return kBase * @access public */ public function makeClass($pseudo_class, $arguments = Array ()) { $real_class = $this->realClasses[$pseudo_class]; $mem_before = memory_get_usage(); $time_before = microtime(true); $arguments = (array)$arguments; if ( !$arguments ) { $class = new $real_class(); } else { $reflection = new ReflectionClass($real_class); $class = $reflection->newInstanceArgs($arguments); } if ( defined('DEBUG_MODE') && DEBUG_MODE && defined('DBG_PROFILE_MEMORY') && DBG_PROFILE_MEMORY && $this->Application->isDebugMode() ) { $mem_after = memory_get_usage(); $time_after = microtime(true); $mem_used = $mem_after - $mem_before; $time_used = $time_after - $time_before; $this->Application->Debugger->appendHTML('Factroy created ' . $real_class . ' - used ' . round($mem_used / 1024, 3) . 'Kb time: ' . round($time_used, 5)); $this->Application->Debugger->profilerAddTotal('objects', null, $mem_used); } return $class; } /** * Registers new class in the factory * * @param string $real_class Real name of class as in class declaration * @param string $file Filename in what $real_class is declared * @param string $pseudo_class Name under this class object will be accessed using getObject method * @return void * @access public */ public function registerClass($real_class, $file, $pseudo_class = null) { if ( !isset($pseudo_class) ) { $pseudo_class = $real_class; } if ( !isset($this->Files[$real_class]) ) { $this->Files[$real_class] = preg_replace('/^' . preg_quote(FULL_PATH, '/') . '/', '', $file, 1); } $this->realClasses[$pseudo_class] = $real_class; } /** * Unregisters existing class from factory * * @param string $real_class Real name of class as in class declaration * @param string $pseudo_class Name under this class object is accessed using getObject method * @return void * @access public */ public function unregisterClass($real_class, $pseudo_class = null) { unset($this->Files[$real_class]); } }