芝麻web文件管理V1.00
编辑当前文件:/home/pulsehostuk9/public_html/cloud.pulsehost.co.uk/system/Module/Manager.php
'Core' ); /** * @var array */ private $_aTemplates; /** * @var array */ private $_aResults; /** * @var \Aurora\System\EventEmitter */ private $oEventEmitter; /** * @var \Aurora\System\ObjectExtender */ private $oObjectExtender; /** * @var \Aurora\System\Exceptions\Exception */ private $oLastException; /** * @var array */ private $aModulesSettings; /** * */ public function __construct() { $this->oEventEmitter = \Aurora\System\EventEmitter::getInstance(); $this->oObjectExtender = \Aurora\System\ObjectExtender::getInstance(); } /** * * @return self */ public static function createInstance() { return new self(); } /** * * @return void */ public function loadModules() { $oUser = \Aurora\System\Api::authorise(); $oCoreModule = $this->loadModule('Core'); if ($oCoreModule instanceof AbstractModule) { $oTenant = null; if ($oUser instanceof User && $oUser->Role !== \Aurora\System\Enums\UserRole::SuperAdmin) { $oTenant = \Aurora\Modules\Core\Module::Decorator()->GetTenantWithoutRoleCheck($oUser->IdTenant); } foreach ($this->GetModulesPaths() as $sModuleName => $sModulePath) { $bIsModuleDisabledForTenant = \Aurora\Modules\Core\Module::Decorator()->IsModuleDisabledForObject($oTenant, $sModuleName); $bIsModuleDisabledForUser = \Aurora\Modules\Core\Module::Decorator()->IsModuleDisabledForObject($oUser, $sModuleName); $bModuleIsDisabled = $this->getModuleConfigValue($sModuleName, 'Disabled', false); if (!($bIsModuleDisabledForUser || $bIsModuleDisabledForTenant) && !$bModuleIsDisabled) { $oLoadedModule = $this->loadModule($sModuleName, $sModulePath); $bClientModule = $this->isClientModule($sModuleName); if ($oLoadedModule instanceof AbstractModule || $bClientModule) { $this->_aAllowedModulesName[\strtolower($sModuleName)] = $sModuleName; } else { // \Aurora\System\Api::Log('Module ' . $sModuleName . ' is not allowed. $bModuleLoaded = ' . $oLoadedModule . '. $bClientModule = ' . $bClientModule . '.'); } } else { $this->FlushModuleSettings($sModuleName); // \Aurora\System\Api::Log('Module ' . $sModuleName . ' is not allowed. $bIsModuleDisabledForUser = ' . $bIsModuleDisabledForUser . '. $bModuleIsDisabled = ' . $bModuleIsDisabled . '.'); } } } else { echo "Can't load 'Core' Module"; exit; } } /** * * @param string $sModuleName * @return boolean */ protected function isClientModule($sModuleName) { $sModulePath = $this->GetModulePath($sModuleName); return \file_exists($sModulePath . $sModuleName . '/js/manager.js') || \file_exists($sModulePath . $sModuleName . '/vue/manager.js'); } /** * * @param string $sModuleName * @return boolean */ public function isModuleLoaded($sModuleName) { return \array_key_exists(\strtolower($sModuleName), $this->_aModules); } /** * * @param string $sModuleName * @param string $sConfigName * @param string $sDefaultValue * @return mixed */ public function getModuleConfigValue($sModuleName, $sConfigName, $sDefaultValue = null) { $mResult = $sDefaultValue; $oModuleConfig = $this->getModuleSettings($sModuleName); if ($oModuleConfig) { $mResult = $oModuleConfig->GetValue($sConfigName, $sDefaultValue); } return $mResult; } /** * * @param string $sModuleName * @param string $sConfigName * @param string $sValue * @return mixed */ public function setModuleConfigValue($sModuleName, $sConfigName, $sValue) { $oModuleConfig = $this->getModuleSettings($sModuleName); if ($oModuleConfig) { $oModuleConfig->SetValue($sConfigName, $sValue); } } /** * * @param string $sModuleName * @return mixed */ public function saveModuleConfigValue($sModuleName) { $oModuleConfig = $this->getModuleSettings($sModuleName); if ($oModuleConfig) { $oModuleConfig->Save(); } } /** * */ public function SyncModulesConfigs() { $sConfigFilename = 'pre-config.json'; $sConfigPath = AU_APP_ROOT_PATH . $sConfigFilename; $aModulesPreconfig = []; //getting modules pre-configuration data if (file_exists($sConfigPath)) { $sPreConfig = file_get_contents($sConfigPath); $aPreConfig = json_decode($sPreConfig, true); if (is_array($aPreConfig) && isset($aPreConfig['modules'])) { $aModulesPreconfig = $aPreConfig['modules']; } } foreach ($this->GetModulesPaths() as $sModuleName => $sModulePath) { if (!empty($sModuleName)) { $oSettings = $this->getModuleSettings($sModuleName); if ($oSettings instanceof Settings) { $oSettings->Load(); //overriding modules default configuration with pre-configuration data if (isset($aModulesPreconfig[$sModuleName])) { $aModulePreconfig = $aModulesPreconfig[$sModuleName]; foreach ($aModulePreconfig as $key => $val) { $oProp = $oSettings->GetSettingsProperty($key); if ($oProp && $oProp->IsDefault) { if (!empty($oProp->SpecType)) { $val = \Aurora\System\Enums\EnumConvert::FromXml($val, $oProp->SpecType); } $oSettings->SetValue($key, $val); } } } $oSettings->Save(); } } } } /** * * @param string $sModuleName * @return \Aurora\System\Module\AbstractModule */ protected function loadModule($sModuleName, $sModulePath = null) { $mResult = false; if (!isset($sModulePath)) { $sModulePath = $this->GetModulePath($sModuleName); } if ($sModulePath) { if (!$this->isModuleLoaded($sModuleName)) { $aArgs = array($sModuleName, $sModulePath); $this->broadcastEvent( $sModuleName, 'loadModule' . AbstractModule::$Delimiter . 'before', $aArgs ); if (@\file_exists($sModulePath . $sModuleName . '/Module.php')) { $sModuleClassName = '\\Aurora\\Modules\\' . $sModuleName . '\\Module'; $oModule = new $sModuleClassName($sModulePath); if ($oModule instanceof AbstractModule) { foreach ($oModule->GetRequireModules() as $sModule) { if (!$this->loadModule($sModule, $sModulePath)) { break; } } if ($oModule->initialize() && $oModule->isValid()) { $this->_aModules[\strtolower($sModuleName)] = $oModule; $mResult = $oModule; } } } $this->broadcastEvent( $sModuleName, 'loadModule' . AbstractModule::$Delimiter . 'after', $aArgs, $mResult ); } else { $mResult = $this->GetModule($sModuleName); } } return $mResult; } /** * @param string $sParsedTemplateID * @param string $sParsedPlace * @param string $sTemplateFileName * @param string $sModuleName */ public function includeTemplate($sParsedTemplateID, $sParsedPlace, $sTemplateFileName, $sModuleName = '') { if (!isset($this->_aTemplates[$sParsedTemplateID])) { $this->_aTemplates[$sParsedTemplateID] = array(); } $this->_aTemplates[$sParsedTemplateID][] = array( $sParsedPlace, $sTemplateFileName, $sModuleName ); } /** * * @param string $sTemplateID * @param string $sTemplateSource * @return string */ public function ParseTemplate($sTemplateID, $sTemplateSource) { if (isset($this->_aTemplates[$sTemplateID]) && \is_array($this->_aTemplates[$sTemplateID])) { foreach ($this->_aTemplates[$sTemplateID] as $aItem) { if (!empty($aItem[0]) && !empty($aItem[1]) && \file_exists($aItem[1])) { $sTemplateHtml = \file_get_contents($aItem[1]); if (!empty($aItem[2])) { $sTemplateHtml = \str_replace('%ModuleName%', $aItem[2], $sTemplateHtml); $sTemplateHtml = \str_replace('%MODULENAME%', \strtoupper($aItem[2]), $sTemplateHtml); } $sTemplateSource = \str_replace( '{%INCLUDE-START/' . $aItem[0] . '/INCLUDE-END%}', $sTemplateHtml . '{%INCLUDE-START/' . $aItem[0] . '/INCLUDE-END%}', $sTemplateSource ); } } } return $sTemplateSource; } /** * * @param string $sModule * @param string $sType * @param array $aMap */ public function extendObject($sModule, $sType, $aMap) { $this->oObjectExtender->extend($sModule, $sType, $aMap); } /** * * @param string $sType * @return array */ public function getExtendedObject($sType) { return $this->oObjectExtender->getObject($sType); } /** * * @param string $sType * @return boolean */ public function issetObject($sType) { return $this->oObjectExtender->issetObject($sType); } /** * @todo return correct path according to curent tenant * * @return string */ public function GetModulesRootPath() { return AU_APP_ROOT_PATH . 'modules/'; } /** * @todo return correct path according to curent tenant * * @return array */ public function GetModulesPaths() { if (!isset($this->_aModulesPaths)) { $sModulesPath = $this->GetModulesRootPath(); $aModulePath = [ $sModulesPath ]; $oCoreModule = $this->loadModule('Core', $sModulesPath); if ($oCoreModule instanceof \Aurora\Modules\Core\Module) { $sTenant = \trim($oCoreModule->GetTenantName()); if (!empty($sTenant)) { $sTenantModulesPath = $this->GetTenantModulesPath($sTenant); \array_unshift($aModulePath, $sTenantModulesPath); } } $this->_aModulesPaths = []; foreach ($aModulePath as $sModulesPath) { if (@\is_dir($sModulesPath)) { if (false !== ($rDirHandle = @\opendir($sModulesPath))) { while (false !== ($sFileItem = @\readdir($rDirHandle))) { if (0 < \strlen($sFileItem) && '.' !== $sFileItem[0] && \preg_match('/^[a-zA-Z0-9\-]+$/', $sFileItem)) { $this->_aModulesPaths[$sFileItem] = $sModulesPath; } } @\closedir($rDirHandle); } } } } return $this->_aModulesPaths; } /** * @todo return correct path according to curent tenant * * @return string */ public function GetModulePath($sModuleName) { $aModulesPaths = $this->GetModulesPaths(); return isset($aModulesPaths[$sModuleName]) ? $aModulesPaths[$sModuleName] : false; } /** * @todo return correct path according to curent tenant * * @return string */ public function GetModulesSettingsPath() { return \Aurora\System\Api::DataPath() . '/settings/modules/'; } /** * @return string */ public function GetTenantModulesPath($sTenant) { return AU_APP_ROOT_PATH . 'tenants/' . $sTenant . '/modules/'; } /** * @return array */ public function GetAllowedModulesName() { $aArgs = []; $mResult = $this->_aAllowedModulesName; $this->broadcastEvent('System', 'GetAllowedModulesName', $aArgs, $mResult, true); return $mResult; } /** * @param string $sModuleName * @return array */ public function IsAllowedModule($sModuleName) { $aArgs = [ 'ModuleName' => $sModuleName ]; $mResult = array_key_exists(\strtolower($sModuleName), $this->_aAllowedModulesName); $this->broadcastEvent('System', 'IsAllowedModule', $aArgs, $mResult, true); return $mResult; } /** * @return array */ public function GetModules() { return $this->_aModules; } /** * @param string $sModuleName * @return \Aurora\System\Module\Settings */ public function &getModuleSettings($sModuleName) { if (!isset($this->aModulesSettings[strtolower($sModuleName)])) { $sSettingsClassName = '\\Aurora\\Modules\\' . $sModuleName . '\\Settings'; if (class_exists($sSettingsClassName)) { $this->aModulesSettings[strtolower($sModuleName)] = new $sSettingsClassName($sModuleName); } else { $this->aModulesSettings[strtolower($sModuleName)] = new Settings($sModuleName); } } return $this->aModulesSettings[strtolower($sModuleName)]; } /** * @param string $sModuleName * @return void */ public function FlushModuleSettings($sModuleName) { if (isset($this->aModulesSettings[strtolower($sModuleName)])) { unset($this->aModulesSettings[strtolower($sModuleName)]); } } /** * @param string $sModuleName * @return \Aurora\System\Module\AbstractModule */ public function GetModule($sModuleName) { $mResult = false; $sModuleNameLower = strtolower($sModuleName); if ($this->isModuleLoaded($sModuleName)) { $mResult = $this->_aModules[$sModuleNameLower]; } return $mResult; } /** * @return \Aurora\System\Module\AbstractModule */ public function GetModuleFromRequest() { $sModule = ''; $oHttp = \MailSo\Base\Http::SingletonInstance(); if ($oHttp->IsPost()) { $sModule = $oHttp->GetPost('Module', null); } return $this->GetModule($sModule); } /** * * @param string $sEntryName * @return array */ public function GetModulesByEntry($sEntryName) { $aModules = array(); $oResult = $this->GetModuleFromRequest(); if ($oResult && !$oResult->HasEntry($sEntryName)) { $oResult = false; } if ($oResult === false) { foreach ($this->_aModules as $oModule) { if ($oModule instanceof AbstractModule && $oModule->HasEntry($sEntryName)) { $aModules[] = $oModule; } } } else { $aModules = array( $oResult ); } return $aModules; } /** * @param string $sModuleName * @return bool */ public function ModuleExists($sModuleName) { return ($this->GetModule($sModuleName)) ? true : false; } /** * * @param string $sEntryName * @return mixed */ public function RunEntry($sEntryName) { $oHttp = \MailSo\Base\Http::SingletonInstance(); $aArguments = [ 'EntryName' => $sEntryName, 'Module' => $oHttp->GetPost('Module', null), 'Method' => $oHttp->GetPost('Method', null), 'Parameters' => \json_decode($oHttp->GetPost('Parameters', ''), true) ]; $mResult = false; try { $bEventResult = $this->broadcastEvent('System', 'RunEntry' . AbstractModule::$Delimiter . 'before', $aArguments, $mResult); if ($bEventResult !== true) { if (!\Aurora\System\Router::getInstance()->hasRoute($sEntryName)) { $sEntryName = 'default'; } $mResult = \Aurora\System\Router::getInstance()->route( $sEntryName ); } $this->broadcastEvent('System', 'RunEntry' . AbstractModule::$Delimiter . 'after', $aArguments, $mResult); } catch(\Exception $oException) { $mResult = \Aurora\System\Managers\Response::GetJsonFromObject( "Json", \Aurora\System\Managers\Response::ExceptionResponse("System", $oException) ); \Aurora\System\Api::LogException($oException); } return $mResult; } /** * @return string */ public function GetModulesHash() { $sResult = md5(\Aurora\System\Api::Version()); $aModuleNames = $this->GetAllowedModulesName(); foreach ($aModuleNames as $sModuleName) { $sResult = md5($sResult . $this->GetModuleHashByName($sModuleName)); } return $sResult; } /** * @toto need to add module version to information string * @param string $sModuleName * * @return string */ public function GetModuleHashByName($sModuleName) { $sResult = ''; $sTenantName = \Aurora\System\Api::getTenantName(); $sResult .= $sTenantName !== 'Default' ? $this->GetModulesRootPath() : $this->GetTenantModulesPath($sTenantName); $sResult .= $sModuleName; return md5($sResult); } /** * @param string $oExcetpion */ public function SetLastException($oExcetpion) { $this->oLastException = $oExcetpion; } /** * */ public function GetLastException() { return $this->oLastException; } /** * * @param string $sModule * @param string $sMethod * @param mixed $mResult */ public function AddResult($sModule, $sMethod, $aParameters, $mResult, $iErrorCode = 0) { if (is_string($mResult)) { $mResult = \str_replace(\Aurora\System\Api::$aSecretWords, '*******', $mResult); } $aMapParameters = array(); if (is_array($aParameters)) { foreach ($aParameters as $sKey => $mParameter) { if (!is_resource($mParameter) && gettype($mParameter) !== 'unknown type') { $aMapParameters[$sKey] = $mParameter; } } } $aResult = array( 'Module' => $sModule, 'Method' => $sMethod, 'Parameters' => $aMapParameters, 'Result' => $mResult ); if ($iErrorCode > 0) { $aResult['ErrorCode'] = $iErrorCode; } $this->_aResults[] = $aResult; } /** * @return array */ public function GetResults() { return $this->_aResults; } /** * @param string $sModule * @param string $sMethod * @return array */ public function GetResult($sModule, $sMethod) { foreach ($this->_aResults as $aResult) { if ($aResult['Module'] === $sModule && $aResult['Method'] === $sMethod) { return [$aResult]; } } return []; } /** * Broadcasts an event * * This method will call all subscribers. If one of the subscribers returns false, the process stops. * * The arguments parameter will be sent to all subscribers * * @param string $sEvent * @param array $aArguments * @param mixed $mResult * @return boolean */ public function broadcastEvent($sModule, $sEvent, &$aArguments = [], &$mResult = null, $bSkipIsAllowedModuleCheck = false) { return $this->oEventEmitter->emit( $sModule, $sEvent, $aArguments, $mResult, function ($sModule, $aArguments, $mResult) use ($sEvent) { $this->AddResult($sModule, $sEvent, $aArguments, $mResult); }, $bSkipIsAllowedModuleCheck ); } /** * Subscribe to an event. * * When the event is triggered, we'll call all the specified callbacks. * It is possible to control the order of the callbacks through the * priority argument. * * This is for example used to make sure that the authentication plugin * is triggered before anything else. If it's not needed to change this * number, it is recommended to ommit. * * @param string $sEvent * @param callable $fCallback * @param int $iPriority * @return void */ public function subscribeEvent($sEvent, $fCallback, $iPriority = 100) { $this->oEventEmitter->on($sEvent, $fCallback, $iPriority); } public function getEvents() { return $this->oEventEmitter->getListeners(); } public function GetSubscriptionsResult() { return $this->oEventEmitter->getListenersResult(); } }