Ticket #132: Engine.class.php

File Engine.class.php, 23.5 KB (added by 1d1ot, 21 months ago)

Engine with GetClassInfo

Line 
1<?php
2/*-------------------------------------------------------
3*
4*   LiveStreet Engine Social Networking
5*   Copyright © 2008 Mzhelskiy Maxim
6*
7*--------------------------------------------------------
8*
9*   Official site: www.livestreet.ru
10*   Contact e-mail: rus.engine@gmail.com
11*
12*   GNU General Public License, version 2:
13*   http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
14*
15---------------------------------------------------------
16*/
17
18set_include_path(get_include_path().PATH_SEPARATOR.dirname(__FILE__));
19require_once(Config::Get('path.root.engine').'/lib/internal/ProfilerSimple/Profiler.class.php');
20
21require_once("Object.class.php");
22require_once("Plugin.class.php");
23require_once("Block.class.php");
24require_once("Hook.class.php");
25require_once("Module.class.php");
26require_once("Router.class.php");
27
28require_once("Entity.class.php");
29require_once("Mapper.class.php");
30
31// ORM
32require_once("ModuleORM.class.php");
33require_once("EntityORM.class.php");
34require_once("MapperORM.class.php");
35
36/**
37 * Основной класс движка, который позволяет напрямую обращаться к любому модулю
38 *
39 */
40class Engine extends Object {
41       
42        /**
43         * Имя плагина
44         * @var int
45         */
46        const CI_PLUGIN = 1;
47       
48        /**
49         * Имя экшна
50         * @var int
51         */
52        const CI_ACTION = 2;
53       
54        /**
55         * Имя модуля
56         * @var int
57         */
58        const CI_MODULE = 4;
59       
60        /**
61         * Имя сущности
62         * @var int
63         */
64        const CI_ENTITY = 8;
65       
66        /**
67         * Имя маппера
68         * @var int
69         */
70        const CI_MAPPER = 16;
71       
72        /**
73         * Имя метода
74         * @var int
75         */
76        const CI_METHOD = 32;
77       
78        /**
79         * Имя хука
80         * @var int
81         */
82        const CI_HOOK = 64;
83       
84        /**
85         * Имя класс наследования
86         * @var int
87         */
88        const CI_INHERIT = 128;
89       
90        /**
91         * Префикс плагина
92         * @var int
93         */
94        const CI_PPREFIX = 8192;
95       
96        /**
97         * Разобранный класс наследования
98         * @var int
99         */
100        const CI_INHERITS = 16384;
101       
102        /**
103         * Путь к файлу класса
104         * @var int
105         */
106        const CI_CLASSPATH = 32768;
107       
108        /**
109         * Все свойства класса
110         * @var int
111         */
112        const CI_ALL = 65535;
113       
114        /**
115         * Свойства по-умолчанию
116         * CI_ALL ^ (CI_CLASSPATH | CI_INHERITS | CI_PPREFIX)
117         * @var int
118         */
119        const CI_DEFAULT = 8191;
120       
121        /**
122         * Объекты
123         * CI_ACTION | CI_MAPPER | CI_HOOK | CI_PLUGIN | CI_ACTION | CI_MODULE | CI_ENTITY
124         * @var int
125         */
126        const CI_OBJECT = 95;
127       
128        static protected $oInstance=null;
129       
130        protected $aModules=array();
131        protected $aPlugins=array();
132        protected $aConfigModule;
133        public $iTimeLoadModule=0;
134        protected $iTimeInit=null;
135       
136               
137        /**
138         * При создании объекта делаем инициализацию
139         *
140         */
141        protected function __construct() {
142                $this->iTimeInit=microtime(true);
143                if (get_magic_quotes_gpc()) {
144                        func_stripslashes($_REQUEST);
145                        func_stripslashes($_GET);
146                        func_stripslashes($_POST);
147                        func_stripslashes($_COOKIE);
148                }
149        }
150       
151        /**
152         * Ограничиваем объект только одним экземпляром
153         *
154         * @return Engine
155         */
156        static public function getInstance() {
157                if (isset(self::$oInstance) and (self::$oInstance instanceof self)) {
158                        return self::$oInstance;
159                } else {
160                        self::$oInstance= new self();
161                        return self::$oInstance;
162                }
163        }
164       
165        /**
166         * Инициализация
167         *
168         */
169        public function Init() {
170                /**
171                 * Загружаем плагины
172                 */
173                $this->LoadPlugins();
174                /**
175                 * Инициализируем хуки
176                 */
177                $this->InitHooks();
178                /**
179                 * Загружаем модули автозагрузки
180                 */
181                $this->LoadModules();
182                /**
183                 * Инициализируем загруженные модули
184                 */
185                $this->InitModules();
186                /**
187                 * Инициализируем загруженные плагины
188                 */
189                $this->InitPlugins();
190                /**
191                 * Запускаем хуки для события завершения инициализации Engine
192                 */
193                $this->Hook_Run('engine_init_complete');
194        }
195        /**
196         * Завершение работы модуля
197         *
198         */
199        public function Shutdown() {
200                $this->ShutdownModules();
201        }
202        /**
203         * Производит инициализацию всех модулей
204         *
205         */
206        protected function InitModules() {
207                foreach ($this->aModules as $oModule) {
208                        if(!$oModule->isInit()) {
209                                /**
210                                * Замеряем время инициализации модуля
211                                */
212                                $oProfiler=ProfilerSimple::getInstance();
213                                $iTimeId=$oProfiler->Start('InitModule',get_class($oModule));
214                               
215                                $this->InitModule($oModule);
216
217                                $oProfiler->Stop($iTimeId);
218                        }
219                }
220        }
221       
222        /**
223         * Инициализирует модуль
224         *
225         * @param unknown_type $oModule
226         * @param unknown_type $bHookParent
227         */
228        protected function InitModule($oModule, $bHookParent = true){
229                $sOrigClassName = $sClassName = get_class($oModule);
230                $bRunHooks = false;
231               
232                if($this->isInitModule('ModuleHook')){
233                        $bRunHooks = true;
234                        if($bHookParent){
235                                while(self::GetPluginName($sClassName)){
236                                        $sParentClassName = get_parent_class($sClassName);
237                                        if(!self::GetClassInfo($sParentClassName, self::CI_MODULE, true)){
238                                                break;
239                                        }
240                                        $sClassName = $sParentClassName;
241                                }
242                        }
243                }
244                if($bRunHooks || $sClassName == 'ModuleHook'){
245                        $sHookPrefix = 'module_';
246                        if($sPluginName = self::GetPluginName($sClassName)){
247                                $sHookPrefix .= "plugin{$sPluginName}_";
248                        }
249                        $sHookPrefix .= self::GetModuleName($sClassName).'_init_';
250                }
251                if($bRunHooks){
252                        $this->Hook_Run($sHookPrefix.'before');
253                }
254                $oModule->Init();
255                $oModule->SetInit();
256                if($bRunHooks || $sClassName == 'ModuleHook'){
257                        $this->Hook_Run($sHookPrefix.'after');
258                }
259        }
260       
261        /**
262         * Проверяет модуль на инициализацию
263         *
264         * @param unknown_type $sModuleClass
265         * @return unknown
266         */
267        public function isInitModule($sModuleClass) {
268                if(!in_array($sModuleClass,array('ModulePlugin','ModuleHook'))) {
269                        $sModuleClass=$this->Plugin_GetDelegate('module',$sModuleClass);
270                }
271                if(isset($this->aModules[$sModuleClass]) and $this->aModules[$sModuleClass]->isInit()){
272                        return true;
273                }
274                return false;
275        }
276       
277        /**
278         * Завершаем работу всех модулей
279         *
280         */
281        protected function ShutdownModules() {
282                foreach ($this->aModules as $sKey => $oModule) {
283                        /**
284                         * Замеряем время shutdown`a модуля
285                         */
286                        $oProfiler=ProfilerSimple::getInstance();
287                        $iTimeId=$oProfiler->Start('ShutdownModule',get_class($oModule));
288
289                        $oModule->Shutdown();
290
291                        $oProfiler->Stop($iTimeId);
292                }
293        }
294       
295        /**
296         * Выполняет загрузку модуля по его названию
297         *
298         * @param  string $sModuleClass
299         * @param  bool $bInit - инициализировать модуль или нет
300         * @return Module
301         */
302        public function LoadModule($sModuleClass,$bInit=false) {
303                $tm1=microtime(true);
304               
305                /**             
306                 * Создаем объект модуля
307                 */             
308                $oModule=new $sModuleClass($this);
309                $this->aModules[$sModuleClass]=$oModule;
310                if ($bInit or $sModuleClass=='ModuleCache') {
311                        $this->InitModule($oModule);
312                }               
313                $tm2=microtime(true);
314                $this->iTimeLoadModule+=$tm2-$tm1;
315                dump("load $sModuleClass - \t\t".($tm2-$tm1)."");
316                return $oModule;
317        }
318       
319        /**
320         * Загружает все используемые модули и передает им в конструктор ядро
321         *
322         */
323        protected function LoadModules() {
324                $this->LoadConfig();
325                foreach ($this->aConfigModule['autoLoad'] as $sModuleName) {
326                        $sModuleClass='Module'.$sModuleName;
327                        if(!in_array($sModuleName,array('Plugin','Hook'))) $sModuleClass=$this->Plugin_GetDelegate('module',$sModuleClass);
328                       
329                        if (!isset($this->aModules[$sModuleClass])) {
330                                $this->LoadModule($sModuleClass);
331                        }
332                }
333        }
334        /**
335         * Выполняет загрузку конфигов
336         *
337         */
338        protected function LoadConfig() {
339                $this->aConfigModule = Config::Get('module');
340        }
341        /**
342         * Регистрирует хуки из /classes/hooks/
343         *
344         */
345        protected function InitHooks() {
346                $sDirHooks=Config::Get('path.root.server').'/classes/hooks/';
347                $aFiles=glob($sDirHooks.'Hook*.class.php');
348               
349                if($aFiles and count($aFiles)) {
350                        foreach ($aFiles as $sFile) {
351                                if (preg_match("/Hook([^_]+)\.class\.php$/i",basename($sFile),$aMatch)) {
352                                        //require_once($sFile);
353                                        $sClassName='Hook'.$aMatch[1];
354                                        $oHook=new $sClassName;
355                                        $oHook->RegisterHook();
356                                }
357                        }
358                }
359               
360                /**
361                 * Подгружаем хуки активных плагинов
362                 */
363                $this->InitPluginHooks();
364        }
365       
366        /**
367         * Инициализация хуков активированных плагинов
368         *
369         */
370        protected function InitPluginHooks() {
371                if($aPluginList = func_list_plugins()) {
372                       
373                        $aFiles=array();
374                        $sDirHooks=Config::Get('path.root.server').'/plugins/';
375                       
376                        foreach ($aPluginList as $sPluginName) {
377                                $aFiles=glob($sDirHooks.$sPluginName.'/classes/hooks/Hook*.class.php');
378                                if($aFiles and count($aFiles)) {
379                                        foreach ($aFiles as $sFile) {
380                                                if (preg_match("/Hook([^_]+)\.class\.php$/i",basename($sFile),$aMatch)) {
381                                                        //require_once($sFile);
382                                                        $sPluginName = ucfirst($sPluginName);
383                                                        $sClassName="Plugin{$sPluginName}_Hook{$aMatch[1]}";
384                                                        $oHook=new $sClassName;
385                                                        $oHook->RegisterHook();
386                                                }
387                                        }
388                                }
389                        }
390                }
391        }
392
393        /**
394         * Загрузка плагинов и делегирование
395         *
396         */
397        protected function LoadPlugins() {
398                if($aPluginList = func_list_plugins()) {
399                        foreach ($aPluginList as $sPluginName) {
400                                $sClassName='Plugin'.ucfirst($sPluginName);
401                                $oPlugin=new $sClassName;
402                                $oPlugin->Delegate();
403                                $this->aPlugins[$sPluginName]=$oPlugin;
404                        }
405                }
406        }
407       
408        /**
409         * Инициализация активированных плагинов
410         *
411         */
412        protected function InitPlugins() {
413                foreach ($this->aPlugins as $oPlugin) {                 
414                        $oPlugin->Init();
415                }
416        }
417       
418        /**
419         * Возвращает список активных плагинов
420         *
421         * @return unknown
422         */
423        public function GetPlugins() {
424                return $this->aPlugins;
425        }
426       
427        /**
428         * Проверяет файл на существование, если используется кеширование memcache то кеширует результат работы
429         *
430         * @param  string $sFile
431         * @return mixed
432         */
433        public function isFileExists($sFile,$iTime=3600) {
434                if(
435                   !$this->isInit('cache')
436                || !Config::Get('sys.cache.use')
437                || Config::Get('sys.cache.type') != 'memory'
438                ){
439                        return file_exists($sFile);     
440                }
441                if (false === ($data = $this->Cache_Get("file_exists_{$sFile}"))) {
442                        $data=file_exists($sFile);
443                        $this->Cache_Set((int)$data, "file_exists_{$sFile}", array(), $iTime);
444                }
445                return $data;
446        }
447        /**
448         * Вызывает метод нужного модуля
449         *
450         * @param string $sName
451         * @param array $aArgs
452         * @return unknown
453         */
454        public function _CallModule($sName,$aArgs) {
455                list($oModule,$sModuleName,$sMethod)=$this->GetModule($sName);
456               
457                if (!method_exists($oModule,$sMethod)) {
458                        throw new Exception("The module has no required method: ".$sModuleName.'->'.$sMethod.'()');
459                }
460                               
461                $oProfiler=ProfilerSimple::getInstance();
462                $iTimeId=$oProfiler->Start('callModule',$sModuleName.'->'.$sMethod.'()');
463               
464                $sModuleName=strtolower($sModuleName);
465                $aResultHook=array();
466                if (!in_array($sModuleName,array('plugin','hook'))) {
467                        $aResultHook=$this->_CallModule('Hook_Run',array('module_'.$sModuleName.'_'.strtolower($sMethod).'_before',&$aArgs));
468                }               
469               
470                if (array_key_exists('delegate_result',$aResultHook)) {                 
471                        $result=$aResultHook['delegate_result'];
472                } else {
473                        $aArgsRef=array();
474                        foreach ($aArgs as $key=>$v) {
475                                $aArgsRef[]=&$aArgs[$key];
476                        }
477                        $result=call_user_func_array(array($oModule,$sMethod),$aArgsRef);
478                }
479                               
480                if (!in_array($sModuleName,array('plugin','hook'))) {
481                        $this->Hook_Run('module_'.$sModuleName.'_'.strtolower($sMethod).'_after',array('result'=>&$result,'params'=>$aArgs));
482                }
483                               
484                $oProfiler->Stop($iTimeId);
485                return $result;
486        }
487
488        /**
489         * Возвращает объект модуля, имя модуля и имя вызванного метода
490         *
491         * @param  string $sName
492         * @return array
493         */
494        public function GetModule($sName) {
495                /**
496                 * Поддержка полного синтаксиса при вызове метода модуля
497                 */
498                $aInfo = self::GetClassInfo(
499                        $sName,
500                        self::CI_MODULE
501                        |self::CI_PPREFIX
502                        |self::CI_METHOD
503                );
504                if($aInfo[self::CI_MODULE] && $aInfo[self::CI_METHOD]){
505                        $sName = $aInfo[self::CI_MODULE].'_'.$aInfo[self::CI_METHOD];
506                        if($aInfo[self::CI_PPREFIX]){
507                                $sName = $aInfo[self::CI_PPREFIX].$sName;
508                        }
509                }
510                //var_dump($sName);
511                $aName=explode("_",$sName);
512               
513                if(count($aName)==2) {
514                        $sModuleName=$aName[0];
515                        $sModuleClass='Module'.$aName[0];
516                        $sMethod=$aName[1];
517                } else {
518                        $sModuleName=$aName[0].'_'.$aName[1];
519                        $sModuleClass=$aName[0].'_Module'.$aName[1];
520                        $sMethod=$aName[2];
521                }
522                /**
523                 * Подхватыем делегат модуля (в случае наличия такового)
524                 */
525                if(!in_array($sModuleName,array('Plugin','Hook'))){
526                        $sModuleClass=$this->Plugin_GetDelegate('module',$sModuleClass);
527                }
528
529                if (isset($this->aModules[$sModuleClass])) {
530                        $oModule=$this->aModules[$sModuleClass];
531                } else {
532                        $oModule=$this->LoadModule($sModuleClass,true);
533                }
534               
535                return array($oModule,$sModuleName,$sMethod);
536        }
537       
538        public function getStats() {
539                return array('sql'=>$this->Database_GetStats(),'cache'=>$this->Cache_GetStats(),'engine'=>array('time_load_module'=>round($this->iTimeLoadModule,3)));
540        }
541       
542        public function GetTimeInit() {
543                return $this->iTimeInit;
544        }
545
546        /**
547         * Ставим хук на вызов неизвестного метода и считаем что хотели вызвать метод какого либо модуля
548         *
549         * @param string $sName
550         * @param array $aArgs
551         * @return unknown
552         */
553        public function __call($sName,$aArgs) {
554                return $this->_CallModule($sName,$aArgs);
555        }
556       
557        /**
558         * Блокируем копирование/клонирование объекта ядра
559         *
560         */
561        protected function __clone() {
562               
563        }
564       
565        /**
566         * Получает объект маппера
567         *
568         * @param string $sClassName
569         * @param string $sName
570         * @return mixed
571         */
572        public static function GetMapper($sClassName,$sName=null,$oConnect=null) {             
573                $sModuleName = self::GetClassInfo(
574                        $sClassName,
575                        self::CI_MODULE,
576                        true
577                );
578                if ($sModuleName) {
579                        if (!$sName) {
580                                $sName=$sModuleName;
581                        }
582                        $sClass=$sClassName.'_Mapper'.$sName;
583                        if (!$oConnect) {                       
584                                $oConnect=Engine::getInstance()->Database_GetConnect();
585                        }
586                        $sClass=self::getInstance()->Plugin_GetDelegate('mapper',$sClass);
587                        return new $sClass($oConnect);
588                }               
589                return null;
590        }
591       
592        /**
593         * Создает объект сущности, контролируя варианты кастомизации
594         *
595         * @param  string $sName
596         * @param  mixed  $aParams
597         * @return mixed
598         */
599        public static function GetEntity($sName,$aParams=array()) {
600                /**
601                 * Сущности, имеющие такое же название как модуль,
602                 * можно вызывать сокращенно. Например, вместо User_User -> User
603                 */
604                switch (substr_count($sName,'_')) {
605                        case 0:
606                                $sEntity = $sModule = $sName;
607                                break;
608                       
609                        case 1:
610                                /**
611                                 * Поддержка полного синтаксиса при вызове сущности
612                                 */
613                                $aInfo = self::GetClassInfo(
614                                        $sName,
615                                        self::CI_ENTITY
616                                        |self::CI_MODULE
617                                        |self::CI_PLUGIN
618                                );
619                                if ($aInfo[self::CI_MODULE]
620                                && $aInfo[self::CI_ENTITY]) {
621                                        $sName=$aInfo[self::CI_MODULE].'_'.$aInfo[self::CI_ENTITY];
622                                }
623                               
624                                list($sModule,$sEntity) = explode('_',$sName,2);
625                                /**
626                                 * Обслуживание короткой записи сущностей плагинов
627                                 * PluginTest_Test -> PluginTest_ModuleTest_EntityTest
628                                 */
629                                if($aInfo[self::CI_PLUGIN]) {
630                                        $sPlugin = $aInfo[self::CI_PLUGIN];
631                                        $sModule = $sEntity;
632                                }
633                                break;
634                               
635                        case 2:
636                                /**
637                                 * Поддержка полного синтаксиса при вызове сущности плагина
638                                 */
639                                $aInfo = self::GetClassInfo(
640                                        $sName,
641                                        self::CI_ENTITY
642                                        |self::CI_MODULE
643                                        |self::CI_PLUGIN
644                                );
645                                if ($aInfo[self::CI_PLUGIN]
646                                && $aInfo[self::CI_MODULE]
647                                && $aInfo[self::CI_ENTITY]) {
648                                        $sName='Plugin'.$aInfo[self::CI_PLUGIN]
649                                                .'_'.$aInfo[self::CI_MODULE]
650                                                .'_'.$aInfo[self::CI_ENTITY]
651                                        ;
652                                }
653                                /**
654                                 * Entity плагина
655                                 */
656                                if($aInfo[self::CI_PLUGIN]) { 
657                                        list(,$sModule,$sEntity)=explode('_',$sName);
658                                        $sPlugin = $aInfo[self::CI_PLUGIN];
659                                } else {
660                                        throw new Exception("Unknown entity '{$sName}' given.");
661                                }
662                                break;
663                               
664                        default:
665                                throw new Exception("Unknown entity '{$sName}' given.");
666                }
667                                               
668                $sClass=isset($sPlugin)
669                        ? 'Plugin'.$sPlugin.'_Module'.$sModule.'_Entity'.$sEntity
670                        : 'Module'.$sModule.'_Entity'.$sEntity;
671                /**
672                 * Определяем наличие делегата сущности
673                 * Делегирование указывается только в полной форме!
674                 */
675                $sClass=self::getInstance()->Plugin_GetDelegate('entity',$sClass);             
676               
677                $oEntity=new $sClass($aParams);
678                return $oEntity;
679        }       
680       
681       
682        public static function GetPluginName($oModule) {
683                return self::GetClassInfo($oModule, self::CI_PLUGIN, true);
684        }
685
686        public static function GetPluginPrefix($oModule) {
687                return self::GetClassInfo($oModule, self::CI_PPREFIX, true);
688        }
689
690        public static function GetModuleName($oModule) {
691                return self::GetClassInfo($oModule, self::CI_MODULE, true);
692        }       
693       
694        public static function GetEntityName($oEntity) {
695                return self::GetClassInfo($oEntity, self::CI_ENTITY, true);
696        }
697       
698        public static function GetActionName($oAction) {
699                return self::GetClassInfo($oAction, self::CI_ACTION, true);
700        }
701       
702        public static function GetClassInfo($oObject,$iFlag=self::CI_DEFAULT,$bSingle=false){
703                $sClassName = is_string($oObject) ? $oObject : get_class($oObject);
704                $aResult = array();
705                if($iFlag & self::CI_PLUGIN){
706                        $aResult[self::CI_PLUGIN] = preg_match('/^Plugin([^_]+)/',$sClassName,$aMatches)
707                                ? $aMatches[1]
708                                : null
709                        ;
710                }
711                if($iFlag & self::CI_ACTION){
712                        $aResult[self::CI_ACTION] = preg_match('/^(?:Plugin[^_]+_|)Action([^_]+)/',$sClassName,$aMatches)
713                                ? $aMatches[1]
714                                : null
715                        ;
716                }
717                if($iFlag & self::CI_MODULE){
718                        $aResult[self::CI_MODULE] = preg_match('/^(?:Plugin[^_]+_|)Module(?:ORM|)([^_]+)/',$sClassName,$aMatches)
719                                ? $aMatches[1]
720                                : null
721                        ;
722                }
723                if($iFlag & self::CI_ENTITY){
724                        $aResult[self::CI_ENTITY] = preg_match('/_Entity(?:ORM|)([^_]+)/',$sClassName,$aMatches)
725                                ? $aMatches[1]
726                                : null
727                        ;
728                }
729                if($iFlag & self::CI_MAPPER){
730                        $aResult[self::CI_MAPPER] = preg_match('/_Mapper(?:ORM|)([^_]+)/',$sClassName,$aMatches)
731                                ? $aMatches[1]
732                                : null
733                        ;
734                }
735                if($iFlag & self::CI_HOOK){
736                        $aResult[self::CI_HOOK] = preg_match('/^(?:Plugin[^_]+_|)Hook([^_]+)$/',$sClassName,$aMatches)
737                                ? $aMatches[1]
738                                : null
739                        ;
740                }
741                if($iFlag & self::CI_METHOD){
742                        $sModuleName = isset($aResult[self::CI_MODULE])
743                                ? $aResult[self::CI_MODULE]
744                                : self::GetClassInfo($sClassName, self::CI_MODULE, true)
745                        ;
746                        $aResult[self::CI_METHOD] = preg_match('/_([^_]+)$/',$sClassName,$aMatches)
747                                ? ($sModuleName && strtolower($aMatches[1]) == strtolower('module'.$sModuleName)
748                                        ? null
749                                        : $aMatches[1]
750                                )
751                                : null
752                        ;
753                }
754                if($iFlag & self::CI_PPREFIX){
755                        $sPluginName = isset($aResult[self::CI_PLUGIN])
756                                ? $aResult[self::CI_PLUGIN]
757                                : self::GetClassInfo($sClassName, self::CI_PLUGIN, true)
758                        ;
759                        $aResult[self::CI_PPREFIX] = $sPluginName
760                                ? "Plugin{$sPluginName}_"
761                                : ''
762                        ;
763                }
764                if($iFlag & self::CI_INHERIT){
765                        $aResult[self::CI_INHERIT] = preg_match('/_Inherits?_(\w+)$/',$sClassName,$aMatches)
766                                ? $aMatches[1]
767                                : null
768                        ;
769                }
770                if($iFlag & self::CI_INHERITS){
771                        $sInherit = isset($aResult[self::CI_INHERIT])
772                                ? $aResult[self::CI_INHERIT]
773                                : self::GetClassInfo($sClassName, self::CI_INHERIT, true)
774                        ;
775                        $aResult[self::CI_INHERITS] = $sInherit
776                                ? self::GetClassInfo(
777                                        $sClassName,
778                                        self::CI_OBJECT,
779                                        false)
780                                : null
781                        ;
782                }
783                if($iFlag & self::CI_CLASSPATH){
784                        $aResult[self::CI_CLASSPATH] = self::GetClassPath($sClassName);
785                }
786               
787                return $bSingle ? array_pop($aResult) : $aResult;
788        }
789       
790       
791        public static function GetClassPath($oObject){
792                $aInfo = self::GetClassInfo(
793                        $oObject,
794                        self::CI_OBJECT
795                );
796                $sPath = Config::get('path.root.server').'/';
797                if($aInfo[self::CI_ENTITY]){
798                        // Сущность
799                        if($aInfo[self::CI_PLUGIN]){
800                                // Сущность модуля плагина
801                                $sPath .= 'plugins/'.strtolower($aInfo[self::CI_PLUGIN])
802                                        .'/classes/modules/'.strtolower($aInfo[self::CI_MODULE])
803                                        .'/entity/'.$aInfo[self::CI_ENTITY].'.entity.class.php'
804                                ;
805                        }else{
806                                // Сущность модуля ядра
807                                $sPath .= 'classes/modules/'.strtolower($aInfo[self::CI_MODULE])
808                                        .'/entity/'.$aInfo[self::CI_ENTITY].'.entity.class.php'
809                                ;
810                        }
811                }elseif($aInfo[self::CI_MAPPER]){
812                        // Маппер
813                        if($aInfo[self::CI_PLUGIN]){
814                                // Маппер модуля плагина
815                                $sPath .= 'plugins/'.strtolower($aInfo[self::CI_PLUGIN])
816                                        .'/classes/modules/'.strtolower($aInfo[self::CI_MODULE])
817                                        .'/mapper/'.$aInfo[self::CI_MAPPER].'.mapper.class.php'
818                                ;
819                        }else{
820                                // Маппер модуля ядра
821                                $sPath .= 'classes/modules/'.strtolower($aInfo[self::CI_MODULE])
822                                        .'/mapper/'.$aInfo[self::CI_MAPPER].'.mapper.class.php'
823                                ;
824                        }
825                }elseif($aInfo[self::CI_ACTION]){
826                        // Экшн
827                        if($aInfo[self::CI_PLUGIN]){
828                                // Экшн плагина
829                                $sPath .= 'plugins/'.strtolower($aInfo[self::CI_PLUGIN])
830                                        .'/classes/actions/Action'.$aInfo[self::CI_ACTION].'.class.php'
831                                ;
832                        }else{
833                                // Экшн ядра
834                                $sPath .= 'classes/actions/Action'
835                                        .$aInfo[self::CI_ACTION].'.class.php'
836                                ;
837                        }
838                }elseif($aInfo[self::CI_MODULE]){
839                        // Модуль
840                        if($aInfo[self::CI_PLUGIN]){
841                                // Модуль плагина
842                                $sPath .= 'plugins/'.strtolower($aInfo[self::CI_PLUGIN])
843                                        .'/classes/modules/'.strtolower($aInfo[self::CI_MODULE])
844                                        .'/'.$aInfo[self::CI_MODULE].'.class.php';
845                                ;
846                        }else{
847                                // Модуль ядра
848                                $sPath .= 'classes/modules/'.strtolower($aInfo[self::CI_MODULE])
849                                        .'/'.$aInfo[self::CI_MODULE].'.class.php'
850                                ;
851                                if(!is_file($sPath)){
852                                        $sPath = str_replace('/classes/modules/','/engine/modules/',$sPath);
853                                }
854                        }
855                }elseif($aInfo[self::CI_HOOK]){
856                        // Хук
857                        if($aInfo[self::CI_PLUGIN]){
858                                // Хук плагина
859                                $sPath .= 'plugins/'.strtolower($aInfo[self::CI_PLUGIN])
860                                        .'/classes/hooks/Hook'.$aInfo[self::CI_HOOK]
861                                        .'.class.php';
862                                ;
863                        }else{
864                                // Хук ядра
865                                $sPath .= 'classes/hooks/Hook'.$aInfo[self::CI_HOOK].'.class.php';
866                        }
867                }elseif($aInfo[self::CI_PLUGIN]){
868                        // Плагин
869                        $sPath .= 'plugins/'.strtolower($aInfo[self::CI_PLUGIN])
870                                .'/Plugin'.$aInfo[self::CI_PLUGIN]
871                                .'.class.php';
872                        ;
873                }else{
874                        $sClassName = is_string($oObject) ? $oObject : get_class($oObject);
875                        $sPath .= 'engine/classes/'.$sClassName.'.class.php';
876                }
877                return is_file($sPath) ? $sPath : null;
878        }
879       
880       
881}
882
883/**
884 * Автозагрузка классов
885 *
886 * @param unknown_type $sClassName
887 */
888function __autoload($sClassName) {
889        $aInfo = Engine::GetClassInfo(
890                $sClassName,
891                Engine::CI_CLASSPATH|Engine::CI_INHERIT
892        );
893        if($aInfo[Engine::CI_INHERIT]){
894                $sInheritClass = $aInfo[Engine::CI_INHERIT];
895                $sParentClass = Engine::getInstance()->Plugin_GetParentInherit($sInheritClass);
896                class_alias($sParentClass,$sClassName);
897        }elseif($aInfo[Engine::CI_CLASSPATH]){
898                require_once $aInfo[Engine::CI_CLASSPATH];
899        }elseif(!class_exists($sClassName)){
900                dump("(autoload $sClassName) Can not load CLASS-file");
901                dump($aInfo);
902                //throw new Exception("(autoload '$sClassName') Can not load CLASS-file");
903        }
904}
905?>