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];
}
}
}