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