mirror of
https://github.com/Oreolek/ifhub.club.git
synced 2024-07-03 06:55:03 +03:00
329 lines
9.4 KiB
PHP
329 lines
9.4 KiB
PHP
<?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
|
||
*
|
||
---------------------------------------------------------
|
||
*/
|
||
|
||
/**
|
||
* Модуль управления плагинами сообщений
|
||
*
|
||
*/
|
||
class LsPlugin extends Module {
|
||
/**
|
||
* Файл содержащий информацию об активированных плагинах
|
||
*
|
||
* @var string
|
||
*/
|
||
const PLUGIN_ACTIVATION_FILE = 'plugins.dat';
|
||
/**
|
||
* Файл описания плагина
|
||
*
|
||
* @var string
|
||
*/
|
||
const PLUGIN_README_FILE = 'plugin.xml';
|
||
/**
|
||
* Путь к директории с плагинами
|
||
*
|
||
* @var string
|
||
*/
|
||
protected $sPluginsDir;
|
||
|
||
/**
|
||
* Список плагинов
|
||
*
|
||
* @var unknown_type
|
||
*/
|
||
protected $aPluginsList=array();
|
||
|
||
/**
|
||
* Список engine-rewrite`ов (модули, экшены, сущности, шаблоны)
|
||
*
|
||
* @var array
|
||
*/
|
||
protected $aDelegates=array(
|
||
'module' => array(),
|
||
'action' => array(),
|
||
'entity' => array(),
|
||
'template' => array()
|
||
);
|
||
|
||
/**
|
||
* Инициализация модуля
|
||
*
|
||
*/
|
||
public function Init() {
|
||
$this->sPluginsDir=Config::Get('path.root.server').'/plugins/';
|
||
}
|
||
|
||
/**
|
||
* Получает список информации о всех плагинах, загруженных в plugin-директорию
|
||
*
|
||
* @return array
|
||
*/
|
||
public function GetList() {
|
||
$aList=array_map('basename',glob($this->sPluginsDir.'*',GLOB_ONLYDIR));
|
||
$aActivePlugins=$this->GetActivePlugins();
|
||
|
||
foreach($aList as $sPlugin) {
|
||
$this->aPluginsList[$sPlugin] = array(
|
||
'code' => $sPlugin,
|
||
'is_active' => in_array($sPlugin,$aActivePlugins)
|
||
);
|
||
|
||
/**
|
||
* Считываем данные из XML файла описания
|
||
*/
|
||
$sPluginXML = $this->sPluginsDir.$sPlugin.'/'.self::PLUGIN_README_FILE;
|
||
if($this->aPluginsList[$sPlugin]['property'] = @simplexml_load_file($sPluginXML)) {
|
||
$this->aPluginsList[$sPlugin]['property']->homepage=$this->Text_Parser($this->aPluginsList[$sPlugin]['property']->homepage);
|
||
}
|
||
}
|
||
|
||
return $this->aPluginsList;
|
||
}
|
||
|
||
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;
|
||
|
||
if($sAction=='Activate') {
|
||
/**
|
||
* Проверяем совместимость с версией LS
|
||
*/
|
||
if(defined('LS_VERSION')
|
||
and version_compare(LS_VERSION,$aPlugins[$sPlugin]['property']->requires->livestreet,'=<')) {
|
||
$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; }
|
||
}
|
||
|
||
/**
|
||
* Проверяем, не вступает ли данный плагин в конфликт с уже активированными
|
||
* (по поводу объявленных делегатов)
|
||
*/
|
||
$aPluginDelegates=$oPlugin->GetDelegates();
|
||
$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;
|
||
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
|
||
);
|
||
}
|
||
}
|
||
if($iCount){ return; }
|
||
}
|
||
}
|
||
|
||
$bResult=$oPlugin->$sAction();
|
||
} else {
|
||
/**
|
||
* Исполняемый файл плагина не найден
|
||
*/
|
||
$this->Message_AddError($this->Lang_Get('plugins_activation_file_not_found'),$this->Lang_Get('error'),true);
|
||
return;
|
||
}
|
||
|
||
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)]);
|
||
}
|
||
}
|
||
$this->SetActivePlugins($aActivePlugins);
|
||
}
|
||
return $bResult;
|
||
|
||
default:
|
||
return null;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Возвращает список активированных плагинов в системе
|
||
*
|
||
* @return array
|
||
*/
|
||
public function GetActivePlugins() {
|
||
/**
|
||
* Читаем данные из файла PLUGINS.DAT
|
||
*/
|
||
$aPlugins=@file($this->sPluginsDir.self::PLUGIN_ACTIVATION_FILE);
|
||
$aPlugins =(is_array($aPlugins))?array_unique(array_map('trim',$aPlugins)):array();
|
||
|
||
return $aPlugins;
|
||
}
|
||
|
||
/**
|
||
* Записывает список активных плагинов в файл PLUGINS.DAT
|
||
*
|
||
* @param array|string $aPlugins
|
||
*/
|
||
public function SetActivePlugins($aPlugins) {
|
||
if(!is_array($aPlugins)) $aPlugins = array($aPlugins);
|
||
$aPlugins=array_unique(array_map('trim',$aPlugins));
|
||
|
||
/**
|
||
* Записываем данные в файл PLUGINS.DAT
|
||
*/
|
||
file_put_contents($this->sPluginsDir.self::PLUGIN_ACTIVATION_FILE, implode(PHP_EOL,$aPlugins));
|
||
}
|
||
|
||
|
||
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);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Перенаправление вызовов на модули, экшены, сущности
|
||
*
|
||
* @param string $sType
|
||
* @param string $sFrom
|
||
* @param string $sTo
|
||
* @param string $sSign
|
||
*/
|
||
public function Delegate($sType,$sFrom,$sTo,$sSign=__CLASS__) {
|
||
/**
|
||
* Запрещаем неподписанные делегаты
|
||
*/
|
||
if(!is_string($sSign) or !strlen($sSign)) return null;
|
||
if(!in_array($sType,array_keys($this->aDelegates)) or !$sFrom or !$sTo) return null;
|
||
|
||
$this->aDelegates[$sType][trim($sFrom)]=array(
|
||
'delegate'=>trim($sTo),
|
||
'sign'=>$sSign
|
||
);
|
||
}
|
||
|
||
/**
|
||
* Возвращает делегат модуля, экшена, сущности.
|
||
* Если делегат не определен, отдает переданный в качестве sender`a параметр
|
||
*
|
||
* @param string $sType
|
||
* @param string $sFrom
|
||
* @return string
|
||
*/
|
||
public function GetDelegate($sType,$sFrom) {
|
||
return $this->isDelegated($sType,$sFrom)?$this->aDelegates[$sType][$sFrom]['delegate']:$sFrom;
|
||
}
|
||
|
||
/**
|
||
* Возвращает подпись делегата модуля, экшена, сущности.
|
||
*
|
||
* @param string $sType
|
||
* @param string $sFrom
|
||
* @return string|null
|
||
*/
|
||
public function GetDelegateSign($sType,$sFrom) {
|
||
return $this->isDelegated($sType,$sFrom)?$this->aDelegates[$sType][$sFrom]['sign']:null;
|
||
}
|
||
|
||
/**
|
||
* Возвращает true, если установлено правило делегирования
|
||
*
|
||
* @param string $sType
|
||
* @param string $sFrom
|
||
* @return bool
|
||
*/
|
||
public function isDelegated($sType,$sFrom) {
|
||
if(!in_array($sType,array_keys($this->aDelegates)) or !$sFrom) return false;
|
||
return isset($this->aDelegates[$sType][$sFrom]['delegate']);
|
||
}
|
||
|
||
/**
|
||
* При завершении работы модуля
|
||
*
|
||
*/
|
||
public function Shutdown() {
|
||
}
|
||
}
|
||
?>
|