2009-12-30 00:15:25 +02:00
|
|
|
|
<?php
|
|
|
|
|
/*-------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* LiveStreet Engine Social Networking
|
|
|
|
|
* Copyright © 2008 Mzhelskiy Maxim
|
|
|
|
|
*
|
|
|
|
|
*--------------------------------------------------------
|
|
|
|
|
*
|
|
|
|
|
* Official site: www.livestreet.ru
|
|
|
|
|
* Contact e-mail: rus.engine@gmail.com
|
|
|
|
|
*
|
|
|
|
|
* GNU General Public License, version 2:
|
|
|
|
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
|
|
|
*
|
|
|
|
|
---------------------------------------------------------
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Модуль управления плагинами сообщений
|
|
|
|
|
*
|
|
|
|
|
*/
|
2010-05-27 17:02:43 +03:00
|
|
|
|
class ModulePlugin extends Module {
|
2009-12-30 01:53:10 +02:00
|
|
|
|
/**
|
|
|
|
|
* Файл описания плагина
|
|
|
|
|
*
|
|
|
|
|
* @var string
|
|
|
|
|
*/
|
2010-04-04 12:37:04 +03:00
|
|
|
|
const PLUGIN_XML_FILE = 'plugin.xml';
|
2009-12-30 00:15:25 +02:00
|
|
|
|
/**
|
|
|
|
|
* Путь к директории с плагинами
|
|
|
|
|
*
|
|
|
|
|
* @var string
|
|
|
|
|
*/
|
|
|
|
|
protected $sPluginsDir;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Список плагинов
|
|
|
|
|
*
|
|
|
|
|
* @var unknown_type
|
|
|
|
|
*/
|
|
|
|
|
protected $aPluginsList=array();
|
|
|
|
|
|
2010-01-10 16:26:44 +02:00
|
|
|
|
/**
|
2010-01-11 15:22:29 +02:00
|
|
|
|
* Список engine-rewrite`ов (модули, экшены, сущности, шаблоны)
|
2010-01-10 16:26:44 +02:00
|
|
|
|
*
|
|
|
|
|
* @var array
|
|
|
|
|
*/
|
2010-01-12 21:02:29 +02:00
|
|
|
|
protected $aDelegates=array(
|
2010-01-10 16:26:44 +02:00
|
|
|
|
'module' => array(),
|
2010-06-06 17:09:21 +03:00
|
|
|
|
'mapper' => array(),
|
2010-01-10 16:26:44 +02:00
|
|
|
|
'action' => array(),
|
2010-01-11 15:22:29 +02:00
|
|
|
|
'entity' => array(),
|
2011-07-05 16:33:59 +03:00
|
|
|
|
'template' => array(),
|
|
|
|
|
'block' => array(),
|
2010-01-10 16:26:44 +02:00
|
|
|
|
);
|
|
|
|
|
|
2010-05-28 18:20:55 +03:00
|
|
|
|
/**
|
|
|
|
|
* Стек наследований
|
|
|
|
|
*
|
|
|
|
|
* @var array
|
|
|
|
|
*/
|
|
|
|
|
protected $aInherits=array();
|
|
|
|
|
|
2009-12-30 00:15:25 +02:00
|
|
|
|
/**
|
|
|
|
|
* Инициализация модуля
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
public function Init() {
|
2010-01-08 22:01:40 +02:00
|
|
|
|
$this->sPluginsDir=Config::Get('path.root.server').'/plugins/';
|
2009-12-30 00:15:25 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Получает список информации о всех плагинах, загруженных в plugin-директорию
|
|
|
|
|
*
|
|
|
|
|
* @return array
|
|
|
|
|
*/
|
|
|
|
|
public function GetList() {
|
2010-04-17 18:12:10 +03:00
|
|
|
|
if ($aPaths=glob($this->sPluginsDir.'*',GLOB_ONLYDIR)) {
|
|
|
|
|
$aList=array_map('basename',$aPaths);
|
|
|
|
|
$aActivePlugins=$this->GetActivePlugins();
|
|
|
|
|
foreach($aList as $sPlugin) {
|
|
|
|
|
$this->aPluginsList[$sPlugin] = array(
|
2010-02-07 19:01:38 +02:00
|
|
|
|
'code' => $sPlugin,
|
2010-04-17 18:12:10 +03:00
|
|
|
|
'is_active' => in_array($sPlugin,$aActivePlugins)
|
|
|
|
|
);
|
2010-01-09 21:49:34 +02:00
|
|
|
|
|
2010-02-08 20:07:28 +02:00
|
|
|
|
/**
|
2010-04-17 18:12:10 +03:00
|
|
|
|
* Считываем данные из XML файла описания
|
|
|
|
|
*/
|
|
|
|
|
$sPluginXML = $this->sPluginsDir.$sPlugin.'/'.self::PLUGIN_XML_FILE;
|
|
|
|
|
if($oXml = @simplexml_load_file($sPluginXML)) {
|
|
|
|
|
/**
|
|
|
|
|
* Обрабатываем данные, считанные из XML-описания
|
|
|
|
|
*/
|
|
|
|
|
$sLang=$this->Lang_GetLang();
|
2010-02-08 20:07:28 +02:00
|
|
|
|
|
2010-04-17 18:12:10 +03:00
|
|
|
|
$this->Xlang($oXml,'name',$sLang);
|
|
|
|
|
$this->Xlang($oXml,'author',$sLang);
|
|
|
|
|
$this->Xlang($oXml,'description',$sLang);
|
|
|
|
|
$oXml->homepage=$this->Text_Parser($oXml->homepage);
|
2011-07-07 10:03:00 +03:00
|
|
|
|
$oXml->settings=preg_replace('/{([^}]+)}/',Router::GetPath('$1'),$oXml->settings);
|
|
|
|
|
|
2010-04-17 18:12:10 +03:00
|
|
|
|
$this->aPluginsList[$sPlugin]['property']=$oXml;
|
|
|
|
|
} else {
|
|
|
|
|
/**
|
|
|
|
|
* Если XML-файл описания отсутствует, или не является валидным XML,
|
|
|
|
|
* удаляем плагин из списка
|
|
|
|
|
*/
|
|
|
|
|
unset($this->aPluginsList[$sPlugin]);
|
|
|
|
|
}
|
2009-12-30 01:53:10 +02:00
|
|
|
|
}
|
2009-12-30 00:15:25 +02:00
|
|
|
|
}
|
|
|
|
|
return $this->aPluginsList;
|
|
|
|
|
}
|
|
|
|
|
|
2010-02-09 17:53:06 +02:00
|
|
|
|
/**
|
|
|
|
|
* Получает значение параметра из XML на основе языковой разметки
|
|
|
|
|
*
|
|
|
|
|
* @param SimpleXMLElement $oXml
|
|
|
|
|
* @param string $sProperty
|
|
|
|
|
* @param string $sLang
|
|
|
|
|
*/
|
|
|
|
|
protected function Xlang($oXml,$sProperty,$sLang) {
|
|
|
|
|
$sProperty=trim($sProperty);
|
|
|
|
|
|
|
|
|
|
$oXml->$sProperty->data = count($data=$oXml->xpath("{$sProperty}/lang[@name='{$sLang}']"))
|
|
|
|
|
? $this->Text_Parser(trim((string)array_shift($data)))
|
|
|
|
|
: $this->Text_Parser(trim((string)array_shift($oXml->xpath("{$sProperty}/lang[@name='default']"))));
|
|
|
|
|
}
|
|
|
|
|
|
2009-12-30 00:15:25 +02:00
|
|
|
|
public function Toggle($sPlugin,$sAction) {
|
|
|
|
|
$aPlugins=$this->GetList();
|
|
|
|
|
if(!isset($aPlugins[$sPlugin])) return null;
|
|
|
|
|
|
|
|
|
|
$sPluginName=ucfirst($sPlugin);
|
|
|
|
|
|
|
|
|
|
switch ($sAction) {
|
|
|
|
|
case 'activate':
|
|
|
|
|
case 'deactivate':
|
|
|
|
|
$sAction=ucfirst($sAction);
|
|
|
|
|
|
|
|
|
|
$sFile="{$this->sPluginsDir}{$sPlugin}/Plugin{$sPluginName}.class.php";
|
|
|
|
|
if(is_file($sFile)) {
|
|
|
|
|
require_once($sFile);
|
|
|
|
|
|
|
|
|
|
$sClassName="Plugin{$sPluginName}";
|
|
|
|
|
$oPlugin=new $sClassName;
|
2010-01-12 21:02:29 +02:00
|
|
|
|
|
|
|
|
|
if($sAction=='Activate') {
|
2010-02-07 20:01:12 +02:00
|
|
|
|
/**
|
|
|
|
|
* Проверяем совместимость с версией LS
|
|
|
|
|
*/
|
|
|
|
|
if(defined('LS_VERSION')
|
2010-06-23 11:23:59 +03:00
|
|
|
|
and version_compare(LS_VERSION,(string)$aPlugins[$sPlugin]['property']->requires->livestreet,'<')) {
|
2010-02-07 20:01:12 +02:00
|
|
|
|
$this->Message_AddError(
|
|
|
|
|
$this->Lang_Get(
|
|
|
|
|
'plugins_activation_version_error',
|
|
|
|
|
array(
|
|
|
|
|
'version'=>$aPlugins[$sPlugin]['property']->requires->livestreet)
|
|
|
|
|
),
|
|
|
|
|
$this->Lang_Get('error'),
|
|
|
|
|
true
|
|
|
|
|
);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
/**
|
|
|
|
|
* Проверяем наличие require-плагинов
|
|
|
|
|
*/
|
|
|
|
|
if($aPlugins[$sPlugin]['property']->requires->plugins) {
|
|
|
|
|
$aActivePlugins=$this->GetActivePlugins();
|
|
|
|
|
$iConflict=0;
|
|
|
|
|
foreach ($aPlugins[$sPlugin]['property']->requires->plugins->children() as $sReqPlugin) {
|
|
|
|
|
if(!in_array($sReqPlugin,$aActivePlugins)) {
|
|
|
|
|
$iConflict++;
|
|
|
|
|
$this->Message_AddError(
|
|
|
|
|
$this->Lang_Get('plugins_activation_requires_error',
|
|
|
|
|
array(
|
|
|
|
|
'plugin'=>ucfirst($sReqPlugin)
|
|
|
|
|
)
|
|
|
|
|
),
|
|
|
|
|
$this->Lang_Get('error'),
|
|
|
|
|
true
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if($iConflict) { return; }
|
|
|
|
|
}
|
|
|
|
|
|
2010-01-12 21:02:29 +02:00
|
|
|
|
/**
|
|
|
|
|
* Проверяем, не вступает ли данный плагин в конфликт с уже активированными
|
|
|
|
|
* (по поводу объявленных делегатов)
|
|
|
|
|
*/
|
|
|
|
|
$aPluginDelegates=$oPlugin->GetDelegates();
|
2010-05-30 22:00:58 +03:00
|
|
|
|
$aPluginInherits=$oPlugin->GetInherits();
|
2010-01-12 21:02:29 +02:00
|
|
|
|
$iConflict=0;
|
|
|
|
|
foreach ($this->aDelegates as $sGroup=>$aReplaceList) {
|
|
|
|
|
$iCount=0;
|
|
|
|
|
if(isset($aPluginDelegates[$sGroup])
|
|
|
|
|
and is_array($aPluginDelegates[$sGroup])
|
|
|
|
|
and $iCount=count($aOverlap=array_intersect_key($aReplaceList,$aPluginDelegates[$sGroup]))) {
|
|
|
|
|
$iConflict+=$iCount;
|
2010-01-14 17:45:47 +02:00
|
|
|
|
foreach ($aOverlap as $sResource=>$aConflict) {
|
|
|
|
|
$this->Message_AddError(
|
|
|
|
|
$this->Lang_Get('plugins_activation_overlap', array(
|
|
|
|
|
'resource'=>$sResource,
|
|
|
|
|
'delegate'=>$aConflict['delegate'],
|
|
|
|
|
'plugin' =>$aConflict['sign']
|
|
|
|
|
)),
|
|
|
|
|
$this->Lang_Get('error'), true
|
|
|
|
|
);
|
|
|
|
|
}
|
2010-01-12 21:02:29 +02:00
|
|
|
|
}
|
2010-05-30 22:00:58 +03:00
|
|
|
|
if(isset($aPluginInherits[$sGroup])
|
|
|
|
|
and is_array($aPluginInherits[$sGroup])
|
|
|
|
|
and $iCount=count($aOverlap=array_intersect_key($aReplaceList,$aPluginInherits[$sGroup]))) {
|
|
|
|
|
$iConflict+=$iCount;
|
|
|
|
|
foreach ($aOverlap as $sResource=>$aConflict) {
|
|
|
|
|
$this->Message_AddError(
|
|
|
|
|
$this->Lang_Get('plugins_activation_overlap', array(
|
|
|
|
|
'resource'=>$sResource,
|
|
|
|
|
'delegate'=>$aConflict['delegate'],
|
|
|
|
|
'plugin' =>$aConflict['sign']
|
|
|
|
|
)),
|
|
|
|
|
$this->Lang_Get('error'), true
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
2010-01-14 17:45:47 +02:00
|
|
|
|
if($iCount){ return; }
|
2010-01-12 21:02:29 +02:00
|
|
|
|
}
|
2010-05-30 22:00:58 +03:00
|
|
|
|
/**
|
|
|
|
|
* Проверяем на конфликт с наследуемыми классами
|
|
|
|
|
*/
|
|
|
|
|
$iConflict=0;
|
|
|
|
|
foreach ($aPluginDelegates as $sGroup=>$aReplaceList) {
|
|
|
|
|
foreach ($aReplaceList as $sResource=>$aConflict) {
|
2010-06-03 23:39:27 +03:00
|
|
|
|
if (isset($this->aInherits[$sResource])) {
|
|
|
|
|
$iConflict+=count($this->aInherits[$sResource]['items']);
|
|
|
|
|
foreach ($this->aInherits[$sResource]['items'] as $aItem) {
|
2010-05-30 22:00:58 +03:00
|
|
|
|
$this->Message_AddError(
|
|
|
|
|
$this->Lang_Get('plugins_activation_overlap_inherit', array(
|
|
|
|
|
'resource'=>$sResource,
|
|
|
|
|
'plugin' =>$aItem['sign']
|
|
|
|
|
)),
|
|
|
|
|
$this->Lang_Get('error'), true
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if($iConflict){ return; }
|
2010-01-12 21:02:29 +02:00
|
|
|
|
}
|
|
|
|
|
|
2009-12-30 00:15:25 +02:00
|
|
|
|
$bResult=$oPlugin->$sAction();
|
2010-02-08 17:49:15 +02:00
|
|
|
|
} else {
|
|
|
|
|
/**
|
|
|
|
|
* Исполняемый файл плагина не найден
|
|
|
|
|
*/
|
|
|
|
|
$this->Message_AddError($this->Lang_Get('plugins_activation_file_not_found'),$this->Lang_Get('error'),true);
|
|
|
|
|
return;
|
2009-12-30 00:15:25 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if($bResult) {
|
|
|
|
|
/**
|
|
|
|
|
* Переопределяем список активированных пользователем плагинов
|
|
|
|
|
*/
|
|
|
|
|
$aActivePlugins=$this->GetActivePlugins();
|
|
|
|
|
if($sAction=='Activate') {
|
|
|
|
|
/**
|
|
|
|
|
* Вносим данные в файл об активации плагина
|
|
|
|
|
*/
|
|
|
|
|
$aActivePlugins[] = $sPlugin;
|
|
|
|
|
} else {
|
|
|
|
|
/**
|
|
|
|
|
* Вносим данные в файл о деактивации плагина
|
|
|
|
|
*/
|
|
|
|
|
$aIndex=array_keys($aActivePlugins,$sPlugin);
|
|
|
|
|
if(is_array($aIndex)) {
|
|
|
|
|
unset($aActivePlugins[array_shift($aIndex)]);
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-08-02 18:52:52 +03:00
|
|
|
|
/**
|
|
|
|
|
* Сбрасываем весь кеш, т.к. могут быть закешированы унаследованые плагинами сущности
|
|
|
|
|
*/
|
|
|
|
|
$this->Cache_Clean();
|
2011-04-25 22:18:59 +03:00
|
|
|
|
if (!$this->SetActivePlugins($aActivePlugins)) {
|
|
|
|
|
$this->Message_AddError($this->Lang_Get('plugins_activation_file_write_error'),$this->Lang_Get('error'),true);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2009-12-30 00:15:25 +02:00
|
|
|
|
}
|
|
|
|
|
return $bResult;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Возвращает список активированных плагинов в системе
|
|
|
|
|
*
|
|
|
|
|
* @return array
|
|
|
|
|
*/
|
|
|
|
|
public function GetActivePlugins() {
|
|
|
|
|
/**
|
|
|
|
|
* Читаем данные из файла PLUGINS.DAT
|
|
|
|
|
*/
|
2011-04-25 23:01:55 +03:00
|
|
|
|
$aPlugins=@file($this->sPluginsDir.Config::Get('sys.plugins.activation_file'));
|
2010-01-09 21:49:34 +02:00
|
|
|
|
$aPlugins =(is_array($aPlugins))?array_unique(array_map('trim',$aPlugins)):array();
|
2009-12-30 00:15:25 +02:00
|
|
|
|
|
|
|
|
|
return $aPlugins;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Записывает список активных плагинов в файл PLUGINS.DAT
|
|
|
|
|
*
|
|
|
|
|
* @param array|string $aPlugins
|
|
|
|
|
*/
|
|
|
|
|
public function SetActivePlugins($aPlugins) {
|
|
|
|
|
if(!is_array($aPlugins)) $aPlugins = array($aPlugins);
|
2010-01-09 21:49:34 +02:00
|
|
|
|
$aPlugins=array_unique(array_map('trim',$aPlugins));
|
2009-12-30 00:15:25 +02:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Записываем данные в файл PLUGINS.DAT
|
|
|
|
|
*/
|
2011-08-03 10:56:28 +03:00
|
|
|
|
if (@file_put_contents($this->sPluginsDir.Config::Get('sys.plugins.activation_file'), implode(PHP_EOL,$aPlugins))!==false) {
|
2011-04-25 22:18:59 +03:00
|
|
|
|
return true;
|
2011-08-03 10:56:28 +03:00
|
|
|
|
}
|
2011-04-25 22:18:59 +03:00
|
|
|
|
return false;
|
2009-12-30 00:15:25 +02:00
|
|
|
|
}
|
|
|
|
|
|
2010-02-20 00:44:44 +02:00
|
|
|
|
/**
|
|
|
|
|
* Удаляет плагины с сервера
|
|
|
|
|
*
|
|
|
|
|
* @param array $aPlugins
|
|
|
|
|
*/
|
2009-12-30 16:54:56 +02:00
|
|
|
|
public function Delete($aPlugins) {
|
|
|
|
|
if(!is_array($aPlugins)) $aPlugins=array($aPlugins);
|
|
|
|
|
|
|
|
|
|
$aActivePlugins=$this->GetActivePlugins();
|
|
|
|
|
foreach ($aPlugins as $sPluginCode) {
|
|
|
|
|
/**
|
|
|
|
|
* Если плагин активен, деактивируем его
|
|
|
|
|
*/
|
|
|
|
|
if(in_array($sPluginCode,$aActivePlugins)) $this->Toggle($sPluginCode,'deactivate');
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Удаляем директорию с плагином
|
|
|
|
|
*/
|
|
|
|
|
func_rmdir($this->sPluginsDir.$sPluginCode);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2010-01-10 16:26:44 +02:00
|
|
|
|
/**
|
|
|
|
|
* Перенаправление вызовов на модули, экшены, сущности
|
|
|
|
|
*
|
|
|
|
|
* @param string $sType
|
|
|
|
|
* @param string $sFrom
|
|
|
|
|
* @param string $sTo
|
2010-01-14 17:45:47 +02:00
|
|
|
|
* @param string $sSign
|
2010-01-10 16:26:44 +02:00
|
|
|
|
*/
|
2010-01-14 17:45:47 +02:00
|
|
|
|
public function Delegate($sType,$sFrom,$sTo,$sSign=__CLASS__) {
|
|
|
|
|
/**
|
|
|
|
|
* Запрещаем неподписанные делегаты
|
|
|
|
|
*/
|
|
|
|
|
if(!is_string($sSign) or !strlen($sSign)) return null;
|
2010-01-12 21:02:29 +02:00
|
|
|
|
if(!in_array($sType,array_keys($this->aDelegates)) or !$sFrom or !$sTo) return null;
|
2010-01-14 17:45:47 +02:00
|
|
|
|
|
|
|
|
|
$this->aDelegates[$sType][trim($sFrom)]=array(
|
|
|
|
|
'delegate'=>trim($sTo),
|
|
|
|
|
'sign'=>$sSign
|
|
|
|
|
);
|
2010-01-10 16:26:44 +02:00
|
|
|
|
}
|
2010-03-12 00:57:30 +02:00
|
|
|
|
|
2010-05-28 18:20:55 +03:00
|
|
|
|
/**
|
|
|
|
|
* Добавляет в стек наследника класса
|
|
|
|
|
*
|
|
|
|
|
* @param string $sFrom
|
|
|
|
|
* @param string $sTo
|
|
|
|
|
* @param string $sSign
|
|
|
|
|
*/
|
|
|
|
|
public function Inherit($sFrom,$sTo,$sSign=__CLASS__) {
|
|
|
|
|
if(!is_string($sSign) or !strlen($sSign)) return null;
|
|
|
|
|
if(!$sFrom or !$sTo) return null;
|
|
|
|
|
|
2010-06-03 23:39:27 +03:00
|
|
|
|
$this->aInherits[trim($sFrom)]['items'][]=array(
|
2010-05-28 18:20:55 +03:00
|
|
|
|
'inherit'=>trim($sTo),
|
|
|
|
|
'sign'=>$sSign
|
|
|
|
|
);
|
2010-06-03 23:39:27 +03:00
|
|
|
|
$this->aInherits[trim($sFrom)]['position']=count($this->aInherits[trim($sFrom)]['items'])-1;
|
2010-05-28 18:20:55 +03:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Получает следующего родителя у наследника.
|
|
|
|
|
* ВНИМАНИЕ! Данный метод нужно вызвать только из __autoload()
|
|
|
|
|
*
|
|
|
|
|
* @param unknown_type $sFrom
|
|
|
|
|
* @return unknown
|
|
|
|
|
*/
|
2010-06-03 23:39:27 +03:00
|
|
|
|
public function GetParentInherit($sFrom) {
|
|
|
|
|
if (!isset($this->aInherits[$sFrom]['items']) or count($this->aInherits[$sFrom]['items'])<=1 or $this->aInherits[$sFrom]['position']<1) {
|
2010-05-28 18:20:55 +03:00
|
|
|
|
return $sFrom;
|
|
|
|
|
}
|
2010-06-03 23:39:27 +03:00
|
|
|
|
$this->aInherits[$sFrom]['position']--;
|
|
|
|
|
return $this->aInherits[$sFrom]['items'][$this->aInherits[$sFrom]['position']]['inherit'];
|
2010-05-28 18:20:55 +03:00
|
|
|
|
}
|
|
|
|
|
|
2010-11-13 07:34:39 +02:00
|
|
|
|
public function GetInherits($sFrom) {
|
|
|
|
|
if (isset($this->aInherits[trim($sFrom)])) {
|
|
|
|
|
return $this->aInherits[trim($sFrom)]['items'];
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2010-05-30 22:00:58 +03:00
|
|
|
|
public function GetLastInherit($sFrom) {
|
2010-06-03 23:39:27 +03:00
|
|
|
|
if (isset($this->aInherits[trim($sFrom)])) {
|
|
|
|
|
return $this->aInherits[trim($sFrom)]['items'][count($this->aInherits[trim($sFrom)]['items'])-1];
|
2010-05-30 22:00:58 +03:00
|
|
|
|
}
|
|
|
|
|
return null;
|
2010-11-13 07:34:39 +02:00
|
|
|
|
}
|
2010-01-10 16:26:44 +02:00
|
|
|
|
/**
|
|
|
|
|
* Возвращает делегат модуля, экшена, сущности.
|
2010-05-30 22:00:58 +03:00
|
|
|
|
* Если делегат не определен, пытается найти наследника, иначе отдает переданный в качестве sender`a параметр
|
2010-01-10 16:26:44 +02:00
|
|
|
|
*
|
|
|
|
|
* @param string $sType
|
|
|
|
|
* @param string $sFrom
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
2011-07-05 16:33:59 +03:00
|
|
|
|
public function GetDelegate($sType,$sFrom) {
|
2010-05-30 22:00:58 +03:00
|
|
|
|
if (isset($this->aDelegates[$sType][$sFrom]['delegate'])) {
|
|
|
|
|
return $this->aDelegates[$sType][$sFrom]['delegate'];
|
2011-07-05 16:33:59 +03:00
|
|
|
|
} elseif ($aInherit=$this->GetLastInherit($sFrom)) {
|
2010-05-30 22:00:58 +03:00
|
|
|
|
return $aInherit['inherit'];
|
|
|
|
|
}
|
|
|
|
|
return $sFrom;
|
2010-01-14 17:45:47 +02:00
|
|
|
|
}
|
|
|
|
|
|
2010-11-13 07:34:39 +02:00
|
|
|
|
public function GetDelegates($sType,$sFrom) {
|
|
|
|
|
if (isset($this->aDelegates[$sType][$sFrom]['delegate'])) {
|
|
|
|
|
return array($this->aDelegates[$sType][$sFrom]['delegate']);
|
|
|
|
|
} else if($aInherits=$this->GetInherits($sFrom)) {
|
|
|
|
|
return array_map(create_function('$aInherit','return $aInherit["inherit"];'),array_reverse($aInherits));
|
|
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2010-11-16 18:24:57 +02:00
|
|
|
|
public function GetDelegationChain($sType,$sTo) {
|
|
|
|
|
$sRootDelegater = $this->GetRootDelegater($sType,$sTo);
|
|
|
|
|
return $this->collectAllDelegatesRecursive($sType,array($sRootDelegater));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function GetRootDelegater($sType,$sTo) {
|
|
|
|
|
$sItem = $sTo;
|
|
|
|
|
$sItemDelegater = $this->GetDelegater($sType,$sTo);
|
|
|
|
|
while(empty($sRootDelegater)) {
|
|
|
|
|
if($sItem==$sItemDelegater) {
|
|
|
|
|
$sRootDelegater = $sItem;
|
|
|
|
|
}
|
|
|
|
|
$sItem = $sItemDelegater;
|
|
|
|
|
$sItemDelegater = $this->GetDelegater($sType,$sItemDelegater);
|
|
|
|
|
}
|
|
|
|
|
return $sRootDelegater;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function collectAllDelegatesRecursive($sType,$aDelegates) {
|
2010-11-13 07:34:39 +02:00
|
|
|
|
foreach($aDelegates as $sClass) {
|
|
|
|
|
if($aNewDelegates=$this->GetDelegates($sType,$sClass)) {
|
2010-11-16 18:24:57 +02:00
|
|
|
|
$aDelegates = array_merge($this->collectAllDelegatesRecursive($sType,$aNewDelegates),$aDelegates);
|
2010-11-13 07:34:39 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return $aDelegates;
|
2010-11-16 18:24:57 +02:00
|
|
|
|
}
|
|
|
|
|
|
2010-03-14 21:01:02 +02:00
|
|
|
|
/**
|
|
|
|
|
* Возвращает делегирующий объект по имени делегата
|
|
|
|
|
*
|
|
|
|
|
* @param string $sType Объект
|
|
|
|
|
* @param string $sTo Делегат
|
|
|
|
|
* @return string
|
|
|
|
|
*/
|
|
|
|
|
public function GetDelegater($sType,$sTo) {
|
|
|
|
|
$aDelegateMapper=array_filter(
|
|
|
|
|
$this->aDelegates[$sType],
|
|
|
|
|
create_function('$item','return $item["delegate"]=="'.$sTo.'";')
|
|
|
|
|
);
|
2010-05-30 22:00:58 +03:00
|
|
|
|
if (is_array($aDelegateMapper) and count($aDelegateMapper)) {
|
|
|
|
|
return array_shift(array_keys($aDelegateMapper));
|
|
|
|
|
}
|
|
|
|
|
foreach ($this->aInherits as $k=>$v) {
|
|
|
|
|
$aInheritMapper=array_filter(
|
|
|
|
|
$v['items'],
|
|
|
|
|
create_function('$item','return $item["inherit"]=="'.$sTo.'";')
|
|
|
|
|
);
|
|
|
|
|
if (is_array($aInheritMapper) and count($aInheritMapper)) {
|
|
|
|
|
return $k;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return $sTo;
|
2010-03-14 21:01:02 +02:00
|
|
|
|
}
|
|
|
|
|
|
2010-01-14 17:45:47 +02:00
|
|
|
|
/**
|
|
|
|
|
* Возвращает подпись делегата модуля, экшена, сущности.
|
|
|
|
|
*
|
|
|
|
|
* @param string $sType
|
|
|
|
|
* @param string $sFrom
|
|
|
|
|
* @return string|null
|
|
|
|
|
*/
|
|
|
|
|
public function GetDelegateSign($sType,$sFrom) {
|
2010-05-30 22:00:58 +03:00
|
|
|
|
if (isset($this->aDelegates[$sType][$sFrom]['sign'])) {
|
|
|
|
|
return $this->aDelegates[$sType][$sFrom]['sign'];
|
|
|
|
|
}
|
|
|
|
|
if ($aInherit=$this->GetLastInherit($sFrom)) {
|
|
|
|
|
return $aInherit['sign'];
|
|
|
|
|
}
|
|
|
|
|
return null;
|
2010-01-10 16:26:44 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
2010-03-14 21:01:02 +02:00
|
|
|
|
* Возвращает true, если установлено правило делегирования
|
|
|
|
|
* и класс является базовым в данном правиле
|
2010-01-10 16:26:44 +02:00
|
|
|
|
*
|
|
|
|
|
* @param string $sType
|
|
|
|
|
* @param string $sFrom
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
2010-03-14 21:01:02 +02:00
|
|
|
|
public function isDelegater($sType,$sFrom) {
|
2010-05-30 22:00:58 +03:00
|
|
|
|
if (isset($this->aDelegates[$sType][$sFrom]['delegate'])) {
|
|
|
|
|
return true;
|
|
|
|
|
} elseif ($aInherit=$this->GetLastInherit($sFrom)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
2010-01-10 16:26:44 +02:00
|
|
|
|
}
|
|
|
|
|
|
2010-03-14 21:01:02 +02:00
|
|
|
|
/**
|
|
|
|
|
* Возвращает true, если устано
|
|
|
|
|
*
|
|
|
|
|
* @param string $sType
|
|
|
|
|
* @param string $sTo
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
|
|
|
|
public function isDelegated($sType,$sTo) {
|
|
|
|
|
/**
|
2010-05-30 22:00:58 +03:00
|
|
|
|
* Фильтруем меппер делегатов/наследников
|
2010-03-14 21:01:02 +02:00
|
|
|
|
* @var array
|
|
|
|
|
*/
|
|
|
|
|
$aDelegateMapper=array_filter(
|
|
|
|
|
$this->aDelegates[$sType],
|
|
|
|
|
create_function('$item','return $item["delegate"]=="'.$sTo.'";')
|
|
|
|
|
);
|
2010-05-30 22:00:58 +03:00
|
|
|
|
if (is_array($aDelegateMapper) and count($aDelegateMapper)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
foreach ($this->aInherits as $k=>$v) {
|
|
|
|
|
$aInheritMapper=array_filter(
|
|
|
|
|
$v['items'],
|
|
|
|
|
create_function('$item','return $item["inherit"]=="'.$sTo.'";')
|
|
|
|
|
);
|
|
|
|
|
if (is_array($aInheritMapper) and count($aInheritMapper)) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
2010-03-14 21:01:02 +02:00
|
|
|
|
}
|
|
|
|
|
|
2010-03-12 00:57:30 +02:00
|
|
|
|
/**
|
|
|
|
|
* Возвращает список объектов, доступных для делегирования
|
|
|
|
|
*
|
|
|
|
|
* @return array
|
|
|
|
|
*/
|
|
|
|
|
public function GetDelegateObjectList() {
|
|
|
|
|
return array_keys($this->aDelegates);
|
|
|
|
|
}
|
|
|
|
|
|
2009-12-30 00:15:25 +02:00
|
|
|
|
/**
|
|
|
|
|
* При завершении работы модуля
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
public function Shutdown() {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
?>
|