Index: branches/5.2.x/core/kernel/utility/factory.php
===================================================================
diff -u -N -r13840 -r14095
--- branches/5.2.x/core/kernel/utility/factory.php (.../factory.php) (revision 13840)
+++ branches/5.2.x/core/kernel/utility/factory.php (.../factory.php) (revision 14095)
@@ -1,6 +1,6 @@
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
*
@@ -83,115 +111,58 @@
/**
- * Returns object using params specified,
- * creates it if is required
+ * Returns object using params specified, creates it if is required
*
* @param string $name
* @param string $pseudo_class
* @param Array $event_params
- * @return Object
+ * @param Array $arguments
+ * @return kBase
*/
- function &getObject($name,$pseudo_class='',$event_params=Array())
+ 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'];
+ $name = rtrim($name, '.');
- if (!isset($this->realClasses[$pseudo_class]))
- {
- if( $this->Application->isDebugMode() ) $this->Application->Debugger->appendTrace();
- $error_level = $this->Application->isInstalled() ? E_USER_ERROR : E_USER_WARNING;
- trigger_error('RealClass not defined for pseudo_class '.$pseudo_class.'', $error_level);
- $false = false;
- return $false;
+ if ( isset($this->Storage[$name]) ) {
+ return $this->Storage[$name];
}
- if (defined('DEBUG_MODE') && defined('DBG_FACTORY') && DBG_FACTORY && $this->Application->isDebugMode()) {
- global $debugger;
+ $ret = $this->processPrefix($name);
- $debugger->appendHTML('Creating object: Pseudo class: '.$pseudo_class.' Prefix: '.$name);
- $debugger->appendTrace();
+ if (!$pseudo_class) {
+ $pseudo_class = $ret['prefix'];
}
- $this->Storage[$name] =& $this->makeClass($pseudo_class);
- $this->Storage[$name]->Init($ret['prefix'],$ret['special'],$event_params);
+ if ( !isset($this->realClasses[$pseudo_class]) ) {
+ $error_msg = 'RealClass not defined for pseudo_class ' . $pseudo_class . '';
- $prefix=$this->Storage[$name]->Prefix;
- $special=$this->Storage[$name]->Special;
+ if ( $this->Application->isInstalled() ) {
+ throw new Exception($error_msg);
+ }
+ else {
+ if ( $this->Application->isDebugMode() ) {
+ $this->Application->Debugger->appendTrace();
+ }
-// $event_manager =& $this->Storage['EventManager'];
- $event =& $this->Application->EventManager->getBuildEvent($pseudo_class);
- if($event)
- {
- $event->Init($prefix,$special);
- foreach($event_params as $param_name=>$param_value)
- {
- $event->setEventParam($param_name,$param_value);
+ trigger_error($error_msg, E_USER_WARNING);
}
- $this->Application->HandleEvent($event);
- }
- return $this->Storage[$name];
- }
-
- /**
- * Returns object using Variable number of params specified,
- * creates it if is required
- * all params after 4th are passed to object constructor
- *
- * @param string $name
- * @param string $pseudo_class
- * @param Array $event_params
- * @return Object
- */
- function &getObjectP($name,$pseudo_class='',$event_params=Array())
- {
- $ret=$this->processPrefix($name);
- if (!$pseudo_class) $pseudo_class = $ret['prefix'];
- $name=rtrim($name,'.');
- if( isset($this->Storage[$name]) ) return $this->Storage[$name];
-
- if (!isset($this->realClasses[$pseudo_class]))
- {
- if( $this->Application->isDebugMode() ) $this->Application->Debugger->appendTrace();
- $error_level = $this->Application->isInstalled() ? E_USER_ERROR : E_USER_WARNING;
- trigger_error('RealClass not defined for pseudo_class '.$pseudo_class.'', $error_level);
$false = false;
return $false;
}
- if (defined('DEBUG_MODE') && defined('DBG_FACTORY') && DBG_FACTORY && $this->Application->isDebugMode()) {
- global $debugger;
- $debugger->appendHTML('Creating object: Pseudo class: '.$pseudo_class.' Prefix: '.$name);
- $debugger->appendTrace();
+ 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();
}
- $funs_args = func_get_args();
- array_splice($funs_args, 0, 3, Array($pseudo_class) );
+ $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);
- $this->Storage[$name] =& ref_call_user_func_array( Array(&$this,'makeClass'), $funs_args);
- $this->Storage[$name]->Init($ret['prefix'],$ret['special'],$event_params);
-
- $prefix=$this->Storage[$name]->Prefix;
- $special=$this->Storage[$name]->Special;
-
- $event_manager =& $this->getObject('EventManager');
- $event =& $event_manager->getBuildEvent($pseudo_class);
- if($event)
- {
- $event->Init($prefix,$special);
- foreach($event_params as $param_name=>$param_value)
- {
- $event->setEventParam($param_name,$param_value);
- }
- $this->Application->HandleEvent($event);
- }
-
return $this->Storage[$name];
}
-
/**
* Removes object from storage, so next time it could be created from scratch
*
@@ -211,18 +182,18 @@
*/
function includeClassFile($real_class)
{
- if (class_exists($real_class)) return;
- if(!isset($this->Files[$real_class])) {
- trigger_error('Real Class '.$real_class.' is not registered with the Factory', E_USER_ERROR);
+ if ( class_exists($real_class) ) {
+ return;
}
- if(!file_exists(FULL_PATH.$this->Files[$real_class])) {
- if ($this->Application->isDebugMode()) {
- $this->Application->Debugger->appendTrace();
- }
- trigger_error('Include file for class '.$real_class.' ('.FULL_PATH.$this->Files[$real_class].') does not exists', E_USER_ERROR);
+ if( !isset($this->Files[$real_class]) ) {
+ throw new Exception('Real Class ' . $real_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)
@@ -231,7 +202,7 @@
}
}
- k4_include_once(FULL_PATH.$this->Files[$real_class]);
+ kUtil::includeOnce(FULL_PATH.$this->Files[$real_class]);
}
/**
@@ -242,37 +213,44 @@
* through mediator method makeClass that creates instance of class
*
* @param string $pseudo_class
- * @return Object
- * @access private
+ * @param Array $arguments
+ * @return kBase
+ * @access public
*/
- function &makeClass($pseudo_class)
+ public function &makeClass($pseudo_class, $arguments = Array ())
{
$real_class = $this->realClasses[$pseudo_class];
- if (!class_exists($real_class)) $this->includeClassFile($real_class);
+ if ( !class_exists($real_class) ) {
+ $this->includeClassFile($real_class);
+ }
+
$mem_before = memory_get_usage();
- $time_before = getmicrotime();
+ $time_before = microtime(true);
- if( func_num_args() == 1 )
- {
+ 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
- {
- $func_args = func_get_args();
- $pseudo_class = array_shift($func_args);
- $class =& ref_call_user_func_array( Array($real_class,'makeClass'), $func_args );
+ else {
+ $reflection = new ReflectionClass($real_class);
+ $class = $reflection->newInstanceArgs($arguments);
}
- if( defined('DEBUG_MODE') && DEBUG_MODE && constOn('DBG_PROFILE_MEMORY') )
- {
+
+ if ( defined('DEBUG_MODE') && DEBUG_MODE && defined('DBG_PROFILE_MEMORY') && DBG_PROFILE_MEMORY && $this->Application->isDebugMode() ) {
$mem_after = memory_get_usage();
- $time_after = getmicrotime();
+ $time_after = microtime(true);
$mem_used = $mem_after - $mem_before;
$time_used = $time_after - $time_before;
- global $debugger;
- $debugger->appendHTML('Factroy created '.$real_class.' - used '.round($mem_used/1024, 3).'Kb time: '.round($time_used, 5));
- $debugger->profilerAddTotal('objects', null, $mem_used);
+
+ $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;
}
@@ -287,27 +265,54 @@
*/
function registerClass($real_class, $file, $pseudo_class=null, $dependecies = Array() )
{
- if(!isset($pseudo_class)) $pseudo_class = $real_class;
- if (!isset($this->Files[$real_class])) {
+ 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])) {
+ if ( isset($this->realClasses[$pseudo_class]) ) {
$this->registerDependency($real_class, $pseudo_class);
}
- if($dependecies)
- {
- if (!is_array($dependecies)) $dependecies = array($dependecies);
+ 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;
+ $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
*
@@ -317,15 +322,16 @@
*/
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);
- $conditions = Array();
- $conditions['exists'] = is_array($dependencies) && in_array($this->realClasses[$class_name], $dependencies);
- $conditions['same_class'] = $this->realClasses[$class_name] == $depended_class;
-
- if (!$conditions['exists'] && !$conditions['same_class']) {
+ if ( !$dependency_exists ) {
$dependencies[] = $this->realClasses[$class_name];
}
}
-
}
\ No newline at end of file