Changeset View
Changeset View
Standalone View
Standalone View
core/kernel/utility/factory.php
Show All 12 Lines | |||||
*/ | */ | ||||
use Intechnic\InPortal\Core\kernel\utility\ClassDiscovery\ClassMapBuilder; | use Intechnic\InPortal\Core\kernel\utility\ClassDiscovery\ClassMapBuilder; | ||||
defined('FULL_PATH') or die('restricted access!'); | defined('FULL_PATH') or die('restricted access!'); | ||||
class kFactory extends kBase implements kiCacheable { | class kFactory extends kBase implements kiCacheable { | ||||
const TYPE_CLASS = 1; | |||||
const TYPE_INTERFACE = 2; | |||||
const TYPE_TRAIT = 3; | |||||
const MODIFIER_ABSTRACT = 1; | |||||
const MODIFIER_FINAL = 2; | |||||
/** | /** | ||||
* Mapping between class name and file name | * Mapping between class name and file name | ||||
* where class definition can be found. | * where class definition can be found. | ||||
* File path absolute! | * File path absolute! | ||||
* | * | ||||
* @var Array | * @var Array | ||||
* @access protected | * @access protected | ||||
*/ | */ | ||||
protected $classMap = Array (); | protected $classMap = Array (); | ||||
/** | /** | ||||
* Class information. | |||||
* | |||||
* @var array | |||||
*/ | |||||
protected $classInfo = array(); | |||||
/** | |||||
* Information about class usage among other classes. | |||||
* | |||||
* @var array | |||||
*/ | |||||
protected $classTree = array(); | |||||
/** | |||||
* The PSR-4 compliant namespace-to-folder mapping. | * The PSR-4 compliant namespace-to-folder mapping. | ||||
* | * | ||||
* @var array | * @var array | ||||
*/ | */ | ||||
protected $namespaceMap = array(); | protected $namespaceMap = array(); | ||||
/** | /** | ||||
* Map class names to their pseudo | * Map class names to their pseudo | ||||
▲ Show 20 Lines • Show All 46 Lines • ▼ Show 20 Line(s) | |||||
// During installation process all modules, because unit configs from all modules are scanned too. | // During installation process all modules, because unit configs from all modules are scanned too. | ||||
$class_map_builders = ClassMapBuilder::createBuilders(); | $class_map_builders = ClassMapBuilder::createBuilders(); | ||||
} | } | ||||
else { | else { | ||||
$class_map_builders = ClassMapBuilder::createBuilders($this->Application->ModuleInfo); | $class_map_builders = ClassMapBuilder::createBuilders($this->Application->ModuleInfo); | ||||
} | } | ||||
foreach ( $class_map_builders as $class_map_builder ) { | foreach ( $class_map_builders as $class_map_builder ) { | ||||
$class_map = $class_map_builder->get(); | list($class_map, $class_info) = $class_map_builder->get(); | ||||
$class_names = array_keys($class_map); | $class_names = array_keys($class_map); | ||||
$this->classMap = array_merge($this->classMap, $class_map); | $this->classMap = array_merge($this->classMap, $class_map); | ||||
$this->classInfo = array_merge($this->classInfo, $class_info); | |||||
$this->realClasses = array_merge($this->realClasses, array_combine($class_names, $class_names)); | $this->realClasses = array_merge($this->realClasses, array_combine($class_names, $class_names)); | ||||
foreach ( $class_info as $class => $class_data ) { | |||||
if ( isset($class_data['extends']) ) { | |||||
foreach ( $class_data['extends'] as $extends_class ) { | |||||
if ( !isset($this->classTree[$extends_class]) ) { | |||||
$this->classTree[$extends_class] = array(); | |||||
} | |||||
$this->classTree[$extends_class][] = $class; | |||||
} | |||||
} | |||||
} | |||||
} | } | ||||
} | } | ||||
/** | /** | ||||
* Sets data from cache to object | * Sets data from cache to object | ||||
* | * | ||||
* @param Array $data | * @param Array $data | ||||
* @return void | * @return void | ||||
* @access public | * @access public | ||||
*/ | */ | ||||
public function setFromCache(&$data) | public function setFromCache(&$data) | ||||
{ | { | ||||
$this->classMap = $data['Factory.Files']; | $this->classMap = $data['Factory.Files']; | ||||
$this->classInfo = $data['Factory.ClassInfo']; | |||||
$this->classTree = $data['Factory.ClassTree']; | |||||
$this->namespaceMap = $data['Factory.Namespaces']; | $this->namespaceMap = $data['Factory.Namespaces']; | ||||
$this->realClasses = $data['Factory.realClasses']; | $this->realClasses = $data['Factory.realClasses']; | ||||
} | } | ||||
/** | /** | ||||
* Performs automatic loading of classes registered with the factory | * Performs automatic loading of classes registered with the factory | ||||
* | * | ||||
* @param string $class | * @param string $class | ||||
▲ Show 20 Lines • Show All 66 Lines • ▼ Show 20 Line(s) | |||||
* Gets object data for caching | * Gets object data for caching | ||||
* | * | ||||
* @return Array | * @return Array | ||||
* @access public | * @access public | ||||
*/ | */ | ||||
public function getToCache() | public function getToCache() | ||||
{ | { | ||||
ksort($this->classMap); | ksort($this->classMap); | ||||
ksort($this->classInfo); | |||||
ksort($this->classTree); | |||||
ksort($this->namespaceMap); | ksort($this->namespaceMap); | ||||
ksort($this->realClasses); | ksort($this->realClasses); | ||||
return Array ( | return Array ( | ||||
'Factory.Files' => $this->classMap, | 'Factory.Files' => $this->classMap, | ||||
'Factory.ClassInfo' => $this->classInfo, | |||||
'Factory.ClassTree' => $this->classTree, | |||||
'Factory.Namespaces' => $this->namespaceMap, | 'Factory.Namespaces' => $this->namespaceMap, | ||||
'Factory.realClasses' => $this->realClasses, | 'Factory.realClasses' => $this->realClasses, | ||||
); | ); | ||||
} | } | ||||
/** | /** | ||||
* Splits any mixing of prefix and | * Splits any mixing of prefix and | ||||
* special into correct ones | * special into correct ones | ||||
▲ Show 20 Lines • Show All 140 Lines • ▼ Show 20 Line(s) | |||||
$this->Application->Debugger->appendHTML('Factroy created <b>' . $real_class . '</b> - used ' . round($mem_used / 1024, 3) . 'Kb time: ' . round($time_used, 5)); | $this->Application->Debugger->appendHTML('Factroy created <b>' . $real_class . '</b> - used ' . round($mem_used / 1024, 3) . 'Kb time: ' . round($time_used, 5)); | ||||
$this->Application->Debugger->profilerAddTotal('objects', null, $mem_used); | $this->Application->Debugger->profilerAddTotal('objects', null, $mem_used); | ||||
} | } | ||||
return $class; | return $class; | ||||
} | } | ||||
/** | /** | ||||
* Returns sub-classes of given ancestor class. | |||||
* | |||||
* @param string $ancestor_class Ancestor class. | |||||
* @param boolean $concrete_only Return only non-abstract classes. | |||||
* | |||||
* @return array | |||||
* @throws kFactoryException When ancestor class not found. | |||||
*/ | |||||
public function getSubClasses($ancestor_class, $concrete_only = true) | |||||
{ | |||||
if ( !isset($this->classMap[$ancestor_class]) ) { | |||||
throw new kFactoryException( | |||||
'Class "<strong>' . $ancestor_class . '</strong>" is not registered in the Factory' | |||||
); | |||||
} | |||||
if ( !isset($this->classTree[$ancestor_class]) ) { | |||||
return array(); | |||||
} | |||||
$all_sub_classes = array(); | |||||
foreach ( $this->classTree[$ancestor_class] as $sub_class ) { | |||||
$real_sub_class = $this->realClasses[$sub_class]; | |||||
$all_sub_classes[$real_sub_class] = $sub_class; | |||||
$all_sub_classes = array_merge($all_sub_classes, $this->getSubClasses($sub_class, false)); | |||||
} | |||||
if ( $concrete_only ) { | |||||
$concrete_sub_classes = array(); | |||||
foreach ( $all_sub_classes as $real_sub_class => $sub_class ) { | |||||
if ( $this->classInfo[$sub_class]['type'] == self::TYPE_CLASS | |||||
&& !$this->classHasModifier($sub_class, self::MODIFIER_ABSTRACT) | |||||
) { | |||||
$concrete_sub_classes[$real_sub_class] = $sub_class; | |||||
} | |||||
} | |||||
return $concrete_sub_classes; | |||||
} | |||||
return $all_sub_classes; | |||||
} | |||||
/** | |||||
* Determines of class has modifier. | |||||
* | |||||
* @param string $class Class. | |||||
* @param integer $modifier Modifier. | |||||
* | |||||
* @return boolean | |||||
*/ | |||||
protected function classHasModifier($class, $modifier) | |||||
{ | |||||
return ($this->classInfo[$class]['modifiers'] & $modifier) == $modifier; | |||||
} | |||||
/** | |||||
* Registers new class in the factory | * Registers new class in the factory | ||||
* | * | ||||
* @param string $real_class Real name of class as in class declaration | * @param string $real_class Real name of class as in class declaration | ||||
* @param string $file Filename in what $real_class is declared | * @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 string $pseudo_class Name under this class object will be accessed using getObject method | ||||
* @return void | * @return void | ||||
* @access public | * @access public | ||||
*/ | */ | ||||
Show All 31 Lines |