1
0
Fork 0
mirror of https://github.com/Oreolek/ifhub.club.git synced 2024-07-03 06:55:03 +03:00
ifhub.club/engine/modules/plugin/Plugin.class.php

329 lines
9.4 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?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() {
}
}
?>