Engine
Package | framework.engine |
---|---|
Inheritance | class Engine |
Since | 1.0 |
Source Code | /framework/classes/engine/Engine.class.php |
Производит инициализацию плагинов, модулей, хуков. Через этот класс происходит выполнение методов всех модулей, которые вызываются как
$this->Module_Method();Также отвечает за автозагрузку остальных классов движка.
В произвольном месте (не в классах движка у которых нет обработки метода __call() на выполнение модулей) метод модуля можно вызвать так:
Engine::getInstance()->Module_Method();
Public Properties
Property | Type | Description | Defined By |
---|---|---|---|
iTimeLoadModule | int | Время загрузки модулей в микросекундах | Engine |
Protected Properties
Property | Type | Description | Defined By |
---|---|---|---|
aModuleAutoload | array | Содержит список модулей для автозагрузки. | Engine |
aModules | array | Список загруженных модулей | Engine |
aPlugins | array | Список загруженных плагинов | Engine |
iTimeInit | int|null | Текущее время в микросекундах на момент инициализации ядра(движка). | Engine |
oInstance | Engine | Текущий экземпляр движка, используется для синглтона. | Engine |
sEnvironment | string | Текущее окружение | Engine |
Public Methods
Method | Description | Defined By |
---|---|---|
DetectEnvironment() | Запускает определение текущего окружения на основе параметров | Engine |
GetActionName() | Возвращает имя экшена | Engine |
GetBehavior() | Создает объект поведения | Engine |
GetBehaviorClass() | Возвращает класс поведения, контролируя варианты кастомизации | Engine |
GetBehaviorName() | Возвращает имя поведения | Engine |
GetClassInfo() | Возвращает информацию об объекта или классе | Engine |
GetClassPath() | Возвращает информацию о пути до файла класса. | Engine |
GetEntity() | Создает объект сущности | Engine |
GetEntityClass() | Возвращает класс сущности, контролируя варианты кастомизации | Engine |
GetEntityItems() | Создает набор сущностей | Engine |
GetEntityName() | Возвращает имя сущности | Engine |
GetEnvironment() | Возвращает текущее окружение | Engine |
GetMapper() | Получает объект маппера | Engine |
GetModule() | Возвращает объект модуля, имя модуля и имя вызванного метода | Engine |
GetModuleName() | Возвращает имя модуля | Engine |
GetModuleObject() | Возвращает объект модуля | Engine |
GetPluginName() | Возвращает имя плагина моудля если модул принадлежит плагину. | Engine |
GetPluginPrefix() | Возвращает префикс плагина | Engine |
GetPlugins() | Возвращает список активных плагинов | Engine |
GetTimeInit() | Возвращает время старта выполнения движка в микросекундах | Engine |
Init() | Инициализация ядра движка | Engine |
LoadModule() | Выполняет загрузку модуля по его названию | Engine |
SetEnvironment() | Устанавливает текущее окружение | Engine |
Shutdown() | Завершение работы движка | Engine |
_CallModule() | Вызывает метод нужного модуля | Engine |
__call() | Ставим хук на вызов неизвестного метода и считаем что хотели вызвать метод какого либо модуля | Engine |
autoload() | Автозагрузка классов | Engine |
getInstance() | Ограничиваем объект только одним экземпляром. | Engine |
getStats() | Возвращает статистику выполнения | Engine |
isFileExists() | Проверяет файл на существование, если используется кеширование memcache то кеширует результат работы | Engine |
isInitModule() | Проверяет модуль на инициализацию | Engine |
Protected Methods
Method | Description | Defined By |
---|---|---|
AutoloadRegister() | Регистрация автозагрузки классов | Engine |
DetectEnvironmentConsole() | Определяет окружение на основе запуска через cli | Engine |
DetectEnvironmentWeb() | Определяет окружение на основе WEB-запроса к странице | Engine |
InitHooks() | Регистрирует хуки из /classes/hooks/ | Engine |
InitModule() | Инициализирует модуль | Engine |
InitModules() | Производит инициализацию всех модулей | Engine |
InitPluginHooks() | Инициализация хуков активированных плагинов | Engine |
InitPlugins() | Инициализация активированных(загруженных) плагинов | Engine |
LoadConfig() | Выполняет загрузку конфигов | Engine |
LoadModules() | Загружает модули из авто-загрузки и передает им в конструктор ядро | Engine |
LoadPlugins() | Загрузка плагинов и делегирование | Engine |
ShutdownModules() | Завершаем работу всех модулей | Engine |
__clone() | Блокируем копирование/клонирование объекта ядра | Engine |
__construct() | Вызывается при создании объекта ядра. | Engine |
Property Details
Содержит список модулей для автозагрузки. Используется для получания списка модулей для авто-загрузки. Остальные модули загружаются при первом обращении. В конфиге определен так:
$config['module']['autoLoad'] = array('Hook','Cache','Security','Session','Lang','Message','User');
Список загруженных модулей
Список загруженных плагинов
Текущее время в микросекундах на момент инициализации ядра(движка). Определается так:
$this->iTimeInit=microtime(true);
Время загрузки модулей в микросекундах
Текущий экземпляр движка, используется для синглтона.
See Also
Текущее окружение
Method Details
protected void AutoloadRegister()
|
protected function AutoloadRegister()
{
spl_autoload_register(array('Engine', 'autoload'));
}
Регистрация автозагрузки классов
public static int|mixed|null|string DetectEnvironment(array|Closure $aEnvironments)
| ||
$aEnvironments | array|Closure | |
{return} | int|mixed|null|string |
static public function DetectEnvironment($aEnvironments)
{
$aConsoleArgs = isset($_SERVER['argv']) ? $_SERVER['argv'] : null;
/**
* Если запуск из консоли и переданы параметры
*/
if ($aConsoleArgs) {
$sEnv = self::DetectEnvironmentConsole($aEnvironments, $aConsoleArgs);
} else {
$sEnv = self::DetectEnvironmentWeb($aEnvironments);
}
if ($sEnv) {
self::$sEnvironment = $sEnv;
}
return self::$sEnvironment;
}
Запускает определение текущего окружения на основе параметров
protected static int|mixed|null|string DetectEnvironmentConsole(array|Closure $aEnvironments, array $aConsoleArgs)
| ||
$aEnvironments | array|Closure | |
$aConsoleArgs | array | |
{return} | int|mixed|null|string |
static protected function DetectEnvironmentConsole($aEnvironments, $aConsoleArgs)
{
$aArgs = array_filter($aConsoleArgs, function ($sItem) {
return strpos($sItem, '--env') === 0;
});
if ($sArg = reset($aArgs)) {
return reset(array_slice(explode('=', $sArg), 1));
} else {
return self::DetectEnvironmentWeb($aEnvironments);
}
}
Определяет окружение на основе запуска через cli Окружение передается как параметр --env=production
protected static int|mixed|null|string DetectEnvironmentWeb(array|Closure $aEnvironments)
| ||
$aEnvironments | array|Closure | |
{return} | int|mixed|null|string |
static protected function DetectEnvironmentWeb($aEnvironments)
{
if ($aEnvironments instanceof Closure) {
return call_user_func($aEnvironments);
}
foreach ($aEnvironments as $sEnvironment => $aHosts) {
foreach ((array)$aHosts as $sHost) {
if ($sHost == gethostname()) {
return $sEnvironment;
}
}
}
return null;
}
Определяет окружение на основе WEB-запроса к странице
public static string|null GetActionName($oAction $oAction)
| ||
$oAction | $oAction | Объект экшена |
{return} | string|null |
public static function GetActionName($oAction)
{
return self::GetClassInfo($oAction, self::CI_ACTION, true);
}
Возвращает имя экшена
public static Behavior GetBehavior(string $sName, array $aParams=array (
))
| ||
$sName | string | Имя поведения, возможны сокращенные варианты.
Например ModuleUser_BehaviorUserэквивалентно User_Userи эквивалентно Userт.к. имя поведения совпадает с именем модуля |
$aParams | array | |
{return} | Behavior |
public static function GetBehavior($sName, $aParams = array())
{
$sClass = self::GetBehaviorClass($sName);
return new $sClass($aParams);
}
Создает объект поведения
public static mixed GetBehaviorClass($sName $sName)
| ||
$sName | $sName | |
{return} | mixed |
public static function GetBehaviorClass($sName)
{
/**
* Поведения, имеющие такое же название как модуль,
* можно вызывать сокращенно. Например, вместо User_User -> User
*/
switch (substr_count($sName, '_')) {
case 0:
$sEntity = $sModule = $sName;
break;
case 1:
/**
* Поддержка полного синтаксиса при вызове сущности
*/
$aInfo = self::GetClassInfo(
$sName,
self::CI_BEHAVIOR
| self::CI_MODULE
| self::CI_PLUGIN
);
if ($aInfo[self::CI_MODULE]
&& $aInfo[self::CI_BEHAVIOR]
) {
$sName = $aInfo[self::CI_MODULE] . '_' . $aInfo[self::CI_BEHAVIOR];
}
list($sModule, $sEntity) = explode('_', $sName, 2);
/**
* Обслуживание короткой записи сущностей плагинов
* PluginTest_Test -> PluginTest_ModuleTest_EntityTest
*/
if ($aInfo[self::CI_PLUGIN]) {
$sPlugin = $aInfo[self::CI_PLUGIN];
$sModule = $sEntity;
}
break;
case 2:
/**
* Поддержка полного синтаксиса при вызове сущности плагина
*/
$aInfo = self::GetClassInfo(
$sName,
self::CI_BEHAVIOR
| self::CI_MODULE
| self::CI_PLUGIN
);
if ($aInfo[self::CI_PLUGIN]
&& $aInfo[self::CI_MODULE]
&& $aInfo[self::CI_BEHAVIOR]
) {
$sName = 'Plugin' . $aInfo[self::CI_PLUGIN]
. '_' . $aInfo[self::CI_MODULE]
. '_' . $aInfo[self::CI_BEHAVIOR];
}
/**
* Entity плагина
*/
if ($aInfo[self::CI_PLUGIN]) {
list(, $sModule, $sEntity) = explode('_', $sName);
$sPlugin = $aInfo[self::CI_PLUGIN];
} else {
throw new Exception("Unknown behavior '{$sName}' given.");
}
break;
default:
throw new Exception("Unknown behavior '{$sName}' given.");
}
$sClass = isset($sPlugin)
? 'Plugin' . $sPlugin . '_Module' . $sModule . '_Behavior' . $sEntity
: 'Module' . $sModule . '_Behavior' . $sEntity;
/**
* If Plugin Entity doesn't exist, search among it's Module delegates
*/
if (isset($sPlugin) && !self::GetClassPath($sClass)) {
$aModulesChain = Engine::GetInstance()->Plugin_GetDelegationChain('module',
'Plugin' . $sPlugin . '_Module' . $sModule);
foreach ($aModulesChain as $sModuleName) {
$sClassTest = $sModuleName . '_Behavior' . $sEntity;
if (self::GetClassPath($sClassTest)) {
$sClass = $sClassTest;
break;
}
}
if (!self::GetClassPath($sClass)) {
$sClass = 'Module' . $sModule . '_Behavior' . $sEntity;
}
}
/**
* Определяем наличие делегата сущности
* Делегирование указывается только в полной форме!
*/
$sClass = self::getInstance()->Plugin_GetDelegate('behavior', $sClass);
return $sClass;
}
Возвращает класс поведения, контролируя варианты кастомизации
public static string|null GetBehaviorName(Behavior $oBehavior)
| ||
$oBehavior | Behavior | Объект сущности |
{return} | string|null |
public static function GetBehaviorName($oBehavior)
{
return self::GetClassInfo($oBehavior, self::CI_BEHAVIOR, true);
}
Возвращает имя поведения
public static array|string|null GetClassInfo(LsObject|string $oObject, int $iFlag=8191, bool $bSingle=false)
| ||
$oObject | LsObject|string | Объект или имя класса |
$iFlag | int | Маска по которой нужно вернуть рузультат. Доступные маски определены в константах CI_*
Например, получить информацию о плагине и модуле:
Engine::GetClassInfo($oObject,Engine::CI_PLUGIN | Engine::CI_MODULE); |
$bSingle | bool | Возвращать полный результат или только первый элемент |
{return} | array|string|null |
public static function GetClassInfo($oObject, $iFlag = self::CI_DEFAULT, $bSingle = false)
{
$sClassName = is_string($oObject) ? $oObject : get_class($oObject);
$aResult = array();
if ($iFlag & self::CI_PLUGIN) {
$aResult[self::CI_PLUGIN] = preg_match('/^Plugin([^_]+)/', $sClassName, $aMatches)
? $aMatches[1]
: null;
}
if ($iFlag & self::CI_ACTION) {
$aResult[self::CI_ACTION] = preg_match('/^(?:Plugin[^_]+_|)Action([^_]+)/', $sClassName, $aMatches)
? $aMatches[1]
: null;
}
if ($iFlag & self::CI_MODULE) {
$aResult[self::CI_MODULE] = preg_match('/^(?:Plugin[^_]+_|)Module(?:ORM|)([^_]+)/', $sClassName, $aMatches)
? $aMatches[1]
: null;
}
if ($iFlag & self::CI_ENTITY) {
$aResult[self::CI_ENTITY] = preg_match('/_Entity(?:ORM|)([^_]+)/', $sClassName, $aMatches)
? $aMatches[1]
: null;
}
if ($iFlag & self::CI_BEHAVIOR) {
$aResult[self::CI_BEHAVIOR] = preg_match('/_Behavior([^_]+)/', $sClassName, $aMatches)
? $aMatches[1]
: null;
}
if ($iFlag & self::CI_MAPPER) {
$aResult[self::CI_MAPPER] = preg_match('/_Mapper(?:ORM|)([^_]+)/', $sClassName, $aMatches)
? $aMatches[1]
: null;
}
if ($iFlag & self::CI_HOOK) {
$aResult[self::CI_HOOK] = preg_match('/^(?:Plugin[^_]+_|)Hook([^_]+)$/', $sClassName, $aMatches)
? $aMatches[1]
: null;
}
if ($iFlag & self::CI_BLOCK) {
$aResult[self::CI_BLOCK] = preg_match('/^(?:Plugin[^_]+_|)Block([^_]+)$/', $sClassName, $aMatches)
? $aMatches[1]
: null;
}
if ($iFlag & self::CI_EVENT) {
$aResult[self::CI_EVENT] = preg_match('/_Event([^_]+)/', $sClassName, $aMatches)
? $aMatches[1]
: null;
}
if ($iFlag & self::CI_METHOD) {
$sModuleName = isset($aResult[self::CI_MODULE])
? $aResult[self::CI_MODULE]
: self::GetClassInfo($sClassName, self::CI_MODULE, true);
$aResult[self::CI_METHOD] = preg_match('/_([^_]+)$/', $sClassName, $aMatches)
? ($sModuleName && strtolower($aMatches[1]) == strtolower('module' . $sModuleName)
? null
: $aMatches[1]
)
: null;
}
if ($iFlag & self::CI_PPREFIX) {
$sPluginName = isset($aResult[self::CI_PLUGIN])
? $aResult[self::CI_PLUGIN]
: self::GetClassInfo($sClassName, self::CI_PLUGIN, true);
$aResult[self::CI_PPREFIX] = $sPluginName
? "Plugin{$sPluginName}_"
: '';
}
if ($iFlag & self::CI_INHERIT) {
$aResult[self::CI_INHERIT] = preg_match('/_Inherits?_(\w+)$/', $sClassName, $aMatches)
? $aMatches[1]
: null;
}
if ($iFlag & self::CI_INHERITS) {
$sInherit = isset($aResult[self::CI_INHERIT])
? $aResult[self::CI_INHERIT]
: self::GetClassInfo($sClassName, self::CI_INHERIT, true);
$aResult[self::CI_INHERITS] = $sInherit
? self::GetClassInfo(
$sInherit,
self::CI_OBJECT,
false)
: null;
}
if ($iFlag & self::CI_CLASSPATH) {
$aResult[self::CI_CLASSPATH] = self::GetClassPath($sClassName);
}
return $bSingle ? array_pop($aResult) : $aResult;
}
Возвращает информацию об объекта или классе
public static null|string GetClassPath(LsObject $oObject)
| ||
$oObject | LsObject | Объект - модуль, экшен, плагин, хук, сущность |
{return} | null|string |
public static function GetClassPath($oObject)
{
$aInfo = self::GetClassInfo(
$oObject,
self::CI_OBJECT
);
$sPath = Config::get('path.application.server') . '/';
$sPathFramework = Config::get('path.framework.server') . '/';
if ($aInfo[self::CI_ENTITY]) {
// Сущность
if ($aInfo[self::CI_PLUGIN]) {
// Сущность модуля плагина
$sPath .= 'plugins/' . func_underscore($aInfo[self::CI_PLUGIN])
. '/classes/modules/' . func_underscore($aInfo[self::CI_MODULE])
. '/entity/' . $aInfo[self::CI_ENTITY] . '.entity.class.php';
} else {
// Сущность модуля ядра
$sFile = 'classes/modules/' . func_underscore($aInfo[self::CI_MODULE])
. '/entity/' . $aInfo[self::CI_ENTITY] . '.entity.class.php';
$sPath .= $sFile;
if (!is_file($sPath)) {
$sPath = $sPathFramework . $sFile;
}
}
} elseif ($aInfo[self::CI_BEHAVIOR]) {
// Поведение
if ($aInfo[self::CI_PLUGIN]) {
// Поведение модуля плагина
$sPath .= 'plugins/' . func_underscore($aInfo[self::CI_PLUGIN])
. '/classes/modules/' . func_underscore($aInfo[self::CI_MODULE])
. '/behavior/' . $aInfo[self::CI_BEHAVIOR] . '.behavior.class.php';
} else {
// Поведение модуля ядра
$sFile = 'classes/modules/' . func_underscore($aInfo[self::CI_MODULE])
. '/behavior/' . $aInfo[self::CI_BEHAVIOR] . '.behavior.class.php';
$sPath .= $sFile;
if (!is_file($sPath)) {
$sPath = $sPathFramework . $sFile;
}
}
} elseif ($aInfo[self::CI_MAPPER]) {
// Маппер
if ($aInfo[self::CI_PLUGIN]) {
// Маппер модуля плагина
$sPath .= 'plugins/' . func_underscore($aInfo[self::CI_PLUGIN])
. '/classes/modules/' . func_underscore($aInfo[self::CI_MODULE])
. '/mapper/' . $aInfo[self::CI_MAPPER] . '.mapper.class.php';
} else {
// Маппер модуля ядра
$sFile = 'classes/modules/' . func_underscore($aInfo[self::CI_MODULE])
. '/mapper/' . $aInfo[self::CI_MAPPER] . '.mapper.class.php';
$sPath .= $sFile;
if (!is_file($sPath)) {
$sPath = $sPathFramework . $sFile;
}
}
} elseif ($aInfo[self::CI_EVENT]) {
// Евент
if ($aInfo[self::CI_PLUGIN]) {
// Евент плагина
$sPath .= 'plugins/' . func_underscore($aInfo[self::CI_PLUGIN])
. '/classes/actions/' . lcfirst($aInfo[self::CI_ACTION]) . '/Event' . $aInfo[self::CI_EVENT] . '.class.php';
} else {
// Евент ядра
$sPath .= 'classes/actions/' . lcfirst($aInfo[self::CI_ACTION]) . '/Event'
. $aInfo[self::CI_EVENT] . '.class.php';
}
} elseif ($aInfo[self::CI_ACTION]) {
// Экшн
if ($aInfo[self::CI_PLUGIN]) {
// Экшн плагина
$sPath .= 'plugins/' . func_underscore($aInfo[self::CI_PLUGIN])
. '/classes/actions/Action' . $aInfo[self::CI_ACTION] . '.class.php';
} else {
// Экшн ядра
$sPath .= 'classes/actions/Action'
. $aInfo[self::CI_ACTION] . '.class.php';
}
} elseif ($aInfo[self::CI_MODULE]) {
// Модуль
if ($aInfo[self::CI_PLUGIN]) {
// Модуль плагина
$sPath .= 'plugins/' . func_underscore($aInfo[self::CI_PLUGIN])
. '/classes/modules/' . func_underscore($aInfo[self::CI_MODULE])
. '/' . $aInfo[self::CI_MODULE] . '.class.php';;
} else {
// Модуль ядра
$sFile = 'classes/modules/' . func_underscore($aInfo[self::CI_MODULE])
. '/' . $aInfo[self::CI_MODULE] . '.class.php';
$sPath .= $sFile;
if (!is_file($sPath)) {
$sPath = $sPathFramework . $sFile;
}
}
} elseif ($aInfo[self::CI_HOOK]) {
// Хук
if ($aInfo[self::CI_PLUGIN]) {
// Хук плагина
$sPath .= 'plugins/' . func_underscore($aInfo[self::CI_PLUGIN])
. '/classes/hooks/Hook' . $aInfo[self::CI_HOOK]
. '.class.php';;
} else {
// Хук ядра
$sPath .= 'classes/hooks/Hook' . $aInfo[self::CI_HOOK] . '.class.php';
}
} elseif ($aInfo[self::CI_BLOCK]) {
// Блок
if ($aInfo[self::CI_PLUGIN]) {
// Блок плагина
$sPath .= 'plugins/' . func_underscore($aInfo[self::CI_PLUGIN])
. '/classes/blocks/Block' . $aInfo[self::CI_BLOCK]
. '.class.php';;
} else {
// Блок ядра
$sPath .= 'classes/blocks/Block' . $aInfo[self::CI_BLOCK] . '.class.php';
}
} elseif ($aInfo[self::CI_PLUGIN]) {
// Плагин
$sPath .= 'plugins/' . func_underscore($aInfo[self::CI_PLUGIN])
. '/Plugin' . $aInfo[self::CI_PLUGIN]
. '.class.php';;
} else {
$sClassName = is_string($oObject) ? $oObject : get_class($oObject);
$sPath = $sPathFramework . 'classes/engine/' . $sClassName . '.class.php';
}
return is_file($sPath) ? $sPath : null;
}
Возвращает информацию о пути до файла класса. Используется в автозагрузке
public static Entity GetEntity(string $sName, array $aParams=array (
))
| ||
$sName | string | Имя сущности, возможны сокращенные варианты.
Например ModuleUser_EntityUserэквивалентно User_Userи эквивалентно Userт.к. имя сущности совпадает с именем модуля |
$aParams | array | |
{return} | Entity |
public static function GetEntity($sName, $aParams = array())
{
$sClass = self::GetEntityClass($sName);
$oEntity = new $sClass($aParams);
return $oEntity;
}
Создает объект сущности
public static mixed GetEntityClass($sName $sName)
| ||
$sName | $sName | |
{return} | mixed |
public static function GetEntityClass($sName)
{
/**
* Сущности, имеющие такое же название как модуль,
* можно вызывать сокращенно. Например, вместо User_User -> User
*/
switch (substr_count($sName, '_')) {
case 0:
$sEntity = $sModule = $sName;
break;
case 1:
/**
* Поддержка полного синтаксиса при вызове сущности
*/
$aInfo = self::GetClassInfo(
$sName,
self::CI_ENTITY
| self::CI_MODULE
| self::CI_PLUGIN
);
if ($aInfo[self::CI_MODULE]
&& $aInfo[self::CI_ENTITY]
) {
$sName = $aInfo[self::CI_MODULE] . '_' . $aInfo[self::CI_ENTITY];
}
list($sModule, $sEntity) = explode('_', $sName, 2);
/**
* Обслуживание короткой записи сущностей плагинов
* PluginTest_Test -> PluginTest_ModuleTest_EntityTest
*/
if ($aInfo[self::CI_PLUGIN]) {
$sPlugin = $aInfo[self::CI_PLUGIN];
$sModule = $sEntity;
}
break;
case 2:
/**
* Поддержка полного синтаксиса при вызове сущности плагина
*/
$aInfo = self::GetClassInfo(
$sName,
self::CI_ENTITY
| self::CI_MODULE
| self::CI_PLUGIN
);
if ($aInfo[self::CI_PLUGIN]
&& $aInfo[self::CI_MODULE]
&& $aInfo[self::CI_ENTITY]
) {
$sName = 'Plugin' . $aInfo[self::CI_PLUGIN]
. '_' . $aInfo[self::CI_MODULE]
. '_' . $aInfo[self::CI_ENTITY];
}
/**
* Entity плагина
*/
if ($aInfo[self::CI_PLUGIN]) {
list(, $sModule, $sEntity) = explode('_', $sName);
$sPlugin = $aInfo[self::CI_PLUGIN];
} else {
throw new Exception("Unknown entity '{$sName}' given.");
}
break;
default:
throw new Exception("Unknown entity '{$sName}' given.");
}
$sClass = isset($sPlugin)
? 'Plugin' . $sPlugin . '_Module' . $sModule . '_Entity' . $sEntity
: 'Module' . $sModule . '_Entity' . $sEntity;
/**
* If Plugin Entity doesn't exist, search among it's Module delegates
*/
if (isset($sPlugin) && !self::GetClassPath($sClass)) {
$aModulesChain = Engine::GetInstance()->Plugin_GetDelegationChain('module',
'Plugin' . $sPlugin . '_Module' . $sModule);
foreach ($aModulesChain as $sModuleName) {
$sClassTest = $sModuleName . '_Entity' . $sEntity;
if (self::GetClassPath($sClassTest)) {
$sClass = $sClassTest;
break;
}
}
if (!self::GetClassPath($sClass)) {
$sClass = 'Module' . $sModule . '_Entity' . $sEntity;
}
}
/**
* Определяем наличие делегата сущности
* Делегирование указывается только в полной форме!
*/
$sClass = self::getInstance()->Plugin_GetDelegate('entity', $sClass);
return $sClass;
}
Возвращает класс сущности, контролируя варианты кастомизации
public static array GetEntityItems(string $sName, array $aItems, null|string $sIndexKey=NULL)
| ||
$sName | string | Имя сущности, возможны сокращенные варианты |
$aItems | array | Двумерный массив набора данных сущностей |
$sIndexKey | null|string | Ключ массива из набора данных, по которому будут формироваться ключи результирующего набора сущностей |
{return} | array |
public static function GetEntityItems($sName, $aItems, $sIndexKey = null)
{
$aReturn = array();
foreach ($aItems as $aRow) {
if (is_null($sIndexKey)) {
$aReturn[] = self::GetEntity($sName, $aRow);
} else {
$aReturn[$aRow[$sIndexKey]] = self::GetEntity($sName, $aRow);
}
}
return $aReturn;
}
Создает набор сущностей
public static string|null GetEntityName(Entity $oEntity)
| ||
$oEntity | Entity | Объект сущности |
{return} | string|null |
public static function GetEntityName($oEntity)
{
return self::GetClassInfo($oEntity, self::CI_ENTITY, true);
}
Возвращает имя сущности
public static string GetEnvironment()
| ||
{return} | string |
static public function GetEnvironment()
{
return self::$sEnvironment;
}
Возвращает текущее окружение
public static mixed GetMapper(string $sClassName, string|null $sName=NULL, DbSimple_Mysql|null $oConnect=NULL)
| ||
$sClassName | string | Класс модуля маппера |
$sName | string|null | Имя маппера |
$oConnect | DbSimple_Mysql|null | Объект коннекта к БД
Можно получить так:
Engine::getInstance()->Database_GetConnect($aConfig); |
{return} | mixed |
public static function GetMapper($sClassName, $sName = null, $oConnect = null)
{
$sModuleName = self::GetClassInfo(
$sClassName,
self::CI_MODULE,
true
);
if ($sModuleName) {
if (!$sName) {
$sName = $sModuleName;
}
$sClass = $sClassName . '_Mapper' . $sName;
if (!$oConnect) {
$oConnect = Engine::getInstance()->Database_GetConnect();
}
$sClass = self::getInstance()->Plugin_GetDelegate('mapper', $sClass);
return new $sClass($oConnect);
}
return null;
}
Получает объект маппера
public array GetModule(string $sName)
| ||
$sName | string | Имя метода модуля в полном виде
Например Module_Method |
{return} | array |
public function GetModule($sName)
{
/**
* Поддержка полного синтаксиса при вызове метода модуля
*/
$aInfo = self::GetClassInfo(
$sName,
self::CI_MODULE
| self::CI_PPREFIX
| self::CI_METHOD
);
if ($aInfo[self::CI_MODULE] && $aInfo[self::CI_METHOD]) {
$sName = $aInfo[self::CI_MODULE] . '_' . $aInfo[self::CI_METHOD];
if ($aInfo[self::CI_PPREFIX]) {
$sName = $aInfo[self::CI_PPREFIX] . $sName;
}
}
$aName = explode("_", $sName);
if (count($aName) == 2) {
$sModuleName = $aName[0];
$sModuleClass = 'Module' . $aName[0];
$sMethod = $aName[1];
} elseif (count($aName) == 3) {
$sModuleName = $aName[0] . '_' . $aName[1];
$sModuleClass = $aName[0] . '_Module' . $aName[1];
$sMethod = $aName[2];
} else {
throw new Exception("Undefined method module: " . $sName);
}
/**
* Подхватыем делегат модуля (в случае наличия такового)
*/
if (!in_array($sModuleName, array('Plugin', 'Hook'))) {
$sModuleClass = $this->Plugin_GetDelegate('module', $sModuleClass);
}
if (isset($this->aModules[$sModuleClass])) {
$oModule = $this->aModules[$sModuleClass];
} else {
$oModule = $this->LoadModule($sModuleClass, true);
}
return array($oModule, $sModuleName, $sMethod);
}
Возвращает объект модуля, имя модуля и имя вызванного метода
public static string|null GetModuleName(Module $oModule)
| ||
$oModule | Module | Объект модуля |
{return} | string|null |
public static function GetModuleName($oModule)
{
return self::GetClassInfo($oModule, self::CI_MODULE, true);
}
Возвращает имя модуля
public void GetModuleObject(string $sName)
| ||
$sName | string | Имя модуля |
public function GetModuleObject($sName)
{
if (self::GetPluginPrefix($sName)) {
if (substr_count($sName, '_') < 2) {
$sName .= '_x';
}
} else {
if (substr_count($sName, '_') < 1) {
$sName .= '_x';
}
}
$aCallArray = $this->GetModule($sName);
return $aCallArray[0];
}
Возвращает объект модуля
public static string|null GetPluginName(Module $oModule)
| ||
$oModule | Module | Объект модуля |
{return} | string|null |
public static function GetPluginName($oModule)
{
return self::GetClassInfo($oModule, self::CI_PLUGIN, true);
}
Возвращает имя плагина моудля если модул принадлежит плагину. Например
Openid
public static string GetPluginPrefix(Module $oModule)
| ||
$oModule | Module | Объект модуля |
{return} | string | Если плагина нет, возвращает пустую строку |
public static function GetPluginPrefix($oModule)
{
return self::GetClassInfo($oModule, self::CI_PPREFIX, true);
}
Возвращает префикс плагина Например
PluginOpenid_
public array GetPlugins()
| ||
{return} | array |
public function GetPlugins()
{
return $this->aPlugins;
}
Возвращает список активных плагинов
public int GetTimeInit()
| ||
{return} | int |
public function GetTimeInit()
{
return $this->iTimeInit;
}
Возвращает время старта выполнения движка в микросекундах
public void Init()
|
public function Init()
{
/**
* Загружаем плагины
*/
$this->LoadPlugins();
/**
* Инициализируем хуки
*/
$this->InitHooks();
/**
* Загружаем модули автозагрузки
*/
$this->LoadModules();
/**
* Инициализируем загруженные модули
*/
$this->InitModules();
/**
* Инициализируем загруженные плагины
*/
$this->InitPlugins();
/**
* Запускаем хуки для события завершения инициализации Engine
*/
$this->Hook_Run('engine_init_complete');
}
Инициализация ядра движка todo: запретить выполнять повторную инициализацию
protected void InitHooks()
|
protected function InitHooks()
{
$sDirHooks = Config::Get('path.application.server') . '/classes/hooks/';
$aFiles = glob($sDirHooks . 'Hook*.class.php');
if ($aFiles and count($aFiles)) {
foreach ($aFiles as $sFile) {
if (preg_match("/Hook([^_]+)\.class\.php$/i", basename($sFile), $aMatch)) {
//require_once($sFile);
$sClassName = 'Hook' . $aMatch[1];
$oHook = new $sClassName;
$oHook->RegisterHook();
}
}
}
/**
* Подгружаем хуки активных плагинов
*/
$this->InitPluginHooks();
}
Регистрирует хуки из /classes/hooks/
protected void InitModule(Module $oModule, bool $bHookParent=true)
| ||
$oModule | Module | Объект модуля |
$bHookParent | bool | Вызывает хук на родительском модуле, от которого наследуется текущий |
protected function InitModule($oModule, $bHookParent = true)
{
$sOrigClassName = $sClassName = get_class($oModule);
$bRunHooks = false;
if ($this->isInitModule('ModuleHook')) {
$bRunHooks = true;
if ($bHookParent) {
while (self::GetPluginName($sClassName)) {
$sParentClassName = get_parent_class($sClassName);
if (!self::GetClassInfo($sParentClassName, self::CI_MODULE, true)) {
break;
}
$sClassName = $sParentClassName;
}
}
}
if ($bRunHooks || $sClassName == 'ModuleHook') {
$sHookPrefix = 'module_';
if ($sPluginName = self::GetPluginName($sClassName)) {
$sHookPrefix .= "plugin{$sPluginName}_";
}
$sHookPrefix .= self::GetModuleName($sClassName) . '_init_';
$sHookPrefix = strtolower($sHookPrefix);
}
if ($bRunHooks) {
$this->Hook_Run($sHookPrefix . 'before');
}
$oModule->Init();
$oModule->SetInit();
if ($bRunHooks || $sClassName == 'ModuleHook') {
$this->Hook_Run($sHookPrefix . 'after');
}
}
Инициализирует модуль
protected void InitModules()
|
protected function InitModules()
{
foreach ($this->aModules as $oModule) {
if (!$oModule->isInit()) {
$this->InitModule($oModule);
}
}
}
Производит инициализацию всех модулей
protected void InitPluginHooks()
|
protected function InitPluginHooks()
{
if ($aPluginList = func_list_plugins()) {
$sDirHooks = Config::Get('path.application.plugins.server') . '/';
foreach ($aPluginList as $sPluginName) {
$aFiles = glob($sDirHooks . $sPluginName . '/classes/hooks/Hook*.class.php');
if ($aFiles and count($aFiles)) {
foreach ($aFiles as $sFile) {
if (preg_match("/Hook([^_]+)\.class\.php$/i", basename($sFile), $aMatch)) {
//require_once($sFile);
$sPluginName = func_camelize($sPluginName);
$sClassName = "Plugin{$sPluginName}_Hook{$aMatch[1]}";
$oHook = new $sClassName;
$oHook->RegisterHook();
}
}
}
}
}
}
Инициализация хуков активированных плагинов
protected void InitPlugins()
|
protected function InitPlugins()
{
foreach ($this->aPlugins as $oPlugin) {
$oPlugin->Init();
}
}
Инициализация активированных(загруженных) плагинов
protected void LoadConfig()
|
protected function LoadConfig()
{
$this->aModuleAutoload = Config::Get('module.autoLoad');
}
Выполняет загрузку конфигов
public Module LoadModule(string $sModuleClass, bool $bInit=false)
| ||
$sModuleClass | string | Класс модуля |
$bInit | bool | Инициализировать модуль или нет |
{return} | Module |
public function LoadModule($sModuleClass, $bInit = false)
{
$tm1 = microtime(true);
if (!class_exists($sModuleClass)) {
throw new RuntimeException(sprintf('Class "%s" not found!', $sModuleClass));
}
/**
* Создаем объект модуля
*/
$oModule = new $sModuleClass();
$this->aModules[$sModuleClass] = $oModule;
if ($bInit or $sModuleClass == 'ModuleCache') {
$this->InitModule($oModule);
}
$tm2 = microtime(true);
$this->iTimeLoadModule += $tm2 - $tm1;
return $oModule;
}
Выполняет загрузку модуля по его названию
protected void LoadModules()
|
protected function LoadModules()
{
$this->LoadConfig();
foreach ($this->aModuleAutoload as $sModuleName) {
$sModuleClass = 'Module' . $sModuleName;
if (!in_array($sModuleName, array('Plugin', 'Hook'))) {
$sModuleClass = $this->Plugin_GetDelegate('module', $sModuleClass);
}
if (!isset($this->aModules[$sModuleClass])) {
$this->LoadModule($sModuleClass);
}
}
}
Загружает модули из авто-загрузки и передает им в конструктор ядро
protected void LoadPlugins()
|
protected function LoadPlugins()
{
if ($aPluginList = func_list_plugins()) {
foreach ($aPluginList as $sPluginName) {
$sClassName = 'Plugin' . func_camelize($sPluginName);
$oPlugin = new $sClassName;
$oPlugin->Delegate();
$this->aPlugins[$sPluginName] = $oPlugin;
}
}
}
Загрузка плагинов и делегирование
public static void SetEnvironment(string $sEnvironment)
| ||
$sEnvironment | string |
static public function SetEnvironment($sEnvironment)
{
self::$sEnvironment = $sEnvironment;
}
Устанавливает текущее окружение
public void Shutdown()
|
public function Shutdown()
{
$this->ShutdownModules();
/**
* Запускаем хуки для события завершения работы Engine
*/
$this->Hook_Run('engine_shutdown_complete');
}
Завершение работы движка Завершает все модули.
protected void ShutdownModules()
|
protected function ShutdownModules()
{
foreach ($this->aModules as $sKey => $oModule) {
$oModule->Shutdown();
}
}
Завершаем работу всех модулей
public mixed _CallModule(string $sName, array $aArgs)
| ||
$sName | string | Название метода в полном виде.
Например Module_Method |
$aArgs | array | Список аргументов |
{return} | mixed |
public function _CallModule($sName, $aArgs)
{
list($oModule, $sModuleName, $sMethod) = $this->GetModule($sName);
if (!method_exists($oModule, $sMethod)) {
// comment for ORM testing
//throw new Exception("The module has no required method: ".$sModuleName.'->'.$sMethod.'()');
}
$sModuleName = strtolower($sModuleName);
$aResultHook = array();
if (!in_array($sModuleName, array('plugin', 'hook'))) {
$aResultHook = $this->_CallModule('Hook_Run',
array('module_' . $sModuleName . '_' . strtolower($sMethod) . '_before', &$aArgs));
}
/**
* Хук может делегировать результат выполнения метода модуля, сам метод при этом не выполняется, происходит только подмена результата
*/
if (array_key_exists('delegate_result', $aResultHook)) {
$result = $aResultHook['delegate_result'];
} else {
$aArgsRef = array();
foreach ($aArgs as $key => $v) {
$aArgsRef[] =& $aArgs[$key];
}
$result = call_user_func_array(array($oModule, $sMethod), $aArgsRef);
}
if (!in_array($sModuleName, array('plugin', 'hook'))) {
$this->Hook_Run('module_' . $sModuleName . '_' . strtolower($sMethod) . '_after',
array('result' => &$result, 'params' => $aArgs));
}
return $result;
}
Вызывает метод нужного модуля
public mixed __call(string $sName, array $aArgs)
| ||
$sName | string | Имя метода |
$aArgs | array | Аргументы |
{return} | mixed |
public function __call($sName, $aArgs)
{
return $this->_CallModule($sName, $aArgs);
}
Ставим хук на вызов неизвестного метода и считаем что хотели вызвать метод какого либо модуля
protected void __clone()
|
protected function __clone()
{
}
Блокируем копирование/клонирование объекта ядра
protected void __construct()
|
protected function __construct()
{
$this->iTimeInit = microtime(true);
$this->AutoloadRegister();
if (get_magic_quotes_gpc()) {
func_stripslashes($_REQUEST);
func_stripslashes($_GET);
func_stripslashes($_POST);
func_stripslashes($_COOKIE);
}
}
Вызывается при создании объекта ядра. Устанавливает время старта инициализации и обрабатывает входные параметры PHP
public static bool autoload(string $sClassName)
| ||
$sClassName | string | Название класса |
{return} | bool |
public static function autoload($sClassName)
{
$aInfo = Engine::GetClassInfo(
$sClassName,
Engine::CI_CLASSPATH | Engine::CI_INHERIT
);
if ($aInfo[Engine::CI_INHERIT]) {
$sInheritClass = $aInfo[Engine::CI_INHERIT];
$sParentClass = Engine::getInstance()->Plugin_GetParentInherit($sInheritClass);
if (class_alias($sParentClass, $sClassName)) {
return true;
}
} elseif ($aInfo[Engine::CI_CLASSPATH]) {
require_once $aInfo[Engine::CI_CLASSPATH];
return true;
} elseif (!class_exists($sClassName)) {
/**
* Проверяем соответствие PSR-0
*/
$sClassName = ltrim($sClassName, '\\');
$sFileName = '';
$sNameSpace = '';
if ($iLastNsPos = strrpos($sClassName, '\\')) {
$sNameSpace = substr($sClassName, 0, $iLastNsPos);
$sClassName = substr($sClassName, $iLastNsPos + 1);
$sFileName = str_replace('\\', DIRECTORY_SEPARATOR, $sNameSpace) . DIRECTORY_SEPARATOR;
}
$sFileName .= str_replace('_', DIRECTORY_SEPARATOR, $sClassName) . '.php';
$sFileName = Config::Get('path.framework.libs_vendor.server') . DIRECTORY_SEPARATOR . $sFileName;
if (file_exists($sFileName)) {
require_once($sFileName);
return true;
}
//throw new Exception("(autoload '$sClassName') Can not load CLASS-file");
}
return false;
}
Автозагрузка классов
public static Engine getInstance()
| ||
{return} | Engine |
static public function getInstance()
{
if (isset(self::$oInstance) and (self::$oInstance instanceof self)) {
return self::$oInstance;
} else {
self::$oInstance = new self();
return self::$oInstance;
}
}
Ограничиваем объект только одним экземпляром.
Функционал синглтона.
Используется так:
Engine::getInstance()->Module_Method();
public array getStats()
| ||
{return} | array |
public function getStats()
{
return array('sql' => $this->Database_GetStats(),
'cache' => $this->Cache_GetStats(),
'engine' => array('time_load_module' => round($this->iTimeLoadModule, 3))
);
}
Возвращает статистику выполнения
public bool isFileExists(string $sFile, int $iTime=3600)
| ||
$sFile | string | Полный путь до файла |
$iTime | int | Время жизни кеша |
{return} | bool |
public function isFileExists($sFile, $iTime = 3600)
{
// пока так
return file_exists($sFile);
if (
!$this->isInit('cache')
|| !Config::Get('sys.cache.use')
|| Config::Get('sys.cache.type') != 'memory'
) {
return file_exists($sFile);
}
if (false === ($data = $this->Cache_Get("file_exists_{$sFile}"))) {
$data = file_exists($sFile);
$this->Cache_Set((int)$data, "file_exists_{$sFile}", array(), $iTime);
}
return $data;
}
Проверяет файл на существование, если используется кеширование memcache то кеширует результат работы
public bool isInitModule(string $sModuleClass)
| ||
$sModuleClass | string | Класс модуля |
{return} | bool |
public function isInitModule($sModuleClass)
{
if (!in_array($sModuleClass, array('ModulePlugin', 'ModuleHook'))) {
$sModuleClass = $this->Plugin_GetDelegate('module', $sModuleClass);
}
if (isset($this->aModules[$sModuleClass]) and $this->aModules[$sModuleClass]->isInit()) {
return true;
}
return false;
}
Проверяет модуль на инициализацию