Files = $data['Factory.Files']; $this->realClasses = $data['Factory.realClasses']; $this->Dependencies = $data['Factory.Dependencies']; } /** * Gets object data for caching * * @access public * @return Array */ public function getToCache() { return Array ( 'Factory.Files' => $this->Files, 'Factory.realClasses' => $this->realClasses, 'Factory.Dependencies' => $this->Dependencies, ); } /** * Splits any mixing of prefix and * special into correct ones * * @param string $prefix_special * @return Array * @access 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 */ 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); } $false = false; 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 */ function DestroyObject($name) { unset($this->Storage[$name]); } /** * Includes file containing class * definition for real class name * * @param string $real_class * @access private */ function includeClassFile($real_class, $pseudo_class = null) { if ( class_exists($real_class) ) { return; } if( !isset($this->Files[$real_class]) ) { throw new Exception('Real Class ' . $real_class . ' (for pseudo class ' . $pseudo_class . ') is not registered with the Factory'); } if( !file_exists(FULL_PATH . $this->Files[$real_class]) ) { throw new Exception('Include file for class ' . $real_class . ' (' . FULL_PATH . $this->Files[$real_class] . ') does not exists'); } if( isset( $this->Dependencies[$real_class] ) ) { foreach($this->Dependencies[$real_class] as $dep_class_name) { $this->includeClassFile($dep_class_name, $pseudo_class); } } kUtil::includeOnce(FULL_PATH.$this->Files[$real_class]); } /** * 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]; if ( !class_exists($real_class) ) { $this->includeClassFile($real_class, $pseudo_class); } $mem_before = memory_get_usage(); $time_before = microtime(true); if ( !is_array($arguments) ) { // fallback for code, that doesn't know how to pass arguments $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 * @param Array $dependecies List of classes required for this class functioning * @access public */ function registerClass($real_class, $file, $pseudo_class=null, $dependecies = Array() ) { 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); } if ( isset($this->realClasses[$pseudo_class]) ) { $this->registerDependency($real_class, $pseudo_class); } if ($dependecies) { if ( !is_array($dependecies) ) { $dependecies = Array ($dependecies); } foreach ($dependecies as $required_class) { $this->registerDependency($real_class, $required_class); } } $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 */ function unregisterClass($real_class, $pseudo_class = null) { if ( !isset($pseudo_class) ) { $pseudo_class = $real_class; } unset($this->Files[$real_class]); if ( !array_key_exists($real_class, $this->Dependencies) ) { return ; } $this->realClasses[$pseudo_class] = $this->Dependencies[$real_class][0]; unset( $this->Dependencies[$real_class] ); } /** * Add $class_name to required classes list for $depended_class class. * All required class files are included before $depended_class file is included * * @param string $depended_class * @param string $class_name * @author Alex */ function registerDependency($depended_class, $class_name) { if ($this->realClasses[$class_name] == $depended_class) { // same class return ; } $dependencies =& $this->Dependencies[$depended_class]; $dependency_exists = is_array($dependencies) && in_array($this->realClasses[$class_name], $dependencies); if ( !$dependency_exists ) { $dependencies[] = $this->realClasses[$class_name]; } } }