System = &$System; $this->Database = &$System->Database; $this->Installed = false; $this->Enabled = false; $this->Running = false; $this->Dependencies = array(); $this->Type = ModuleType::Normal; } function Install() { if($this->Installed) return; $List = array(); $this->Manager->EnumDependenciesCascade($this, $List, array(ModuleCondition::NotInstalled)); $this->Manager->Perform($List, array(ModuleAction::Install), array(ModuleCondition::NotInstalled)); $this->DoInstall(); $this->Installed = true; $this->InstalledVersion = $this->Version; $this->Manager->Modules[$this->Name] = $this; } function Uninstall() { if(!$this->Installed) return; $this->Stop(); $this->Installed = false; $List = array(); $this->Manager->EnumSuperiorDependenciesCascade($this, $List, array(ModuleCondition::Installed)); $this->Manager->Perform($List, array(ModuleAction::Uninstall), array(ModuleCondition::Installed)); $this->DoUninstall(); } function Upgrade() { if(!$this->Installed) return; $List = array(); $this->Manager->EnumSuperiorDependenciesCascade($this, $List, array(ModuleCondition::Installed)); $this->Manager->Perform($List, array(ModuleAction::Upgrade), array(ModuleCondition::Installed)); $this->DoUpgrade(); } function Reinstall() { $this->Uninstall(); // TODO: Install also back dependecies $this->Install(); } function Start() { if($this->Running) return; if(!$this->Installed) return; $List = array(); $this->Manager->EnumDependenciesCascade($this, $List, array(ModuleCondition::NotRunning)); $this->Manager->Perform($List, array(ModuleAction::Start), array(ModuleCondition::NotRunning)); $this->DoStart(); $this->Running = true; } function Stop() { if(!$this->Running) return; $this->Running = false; $List = array(); $this->Manager->EnumSuperiorDependenciesCascade($this, $List, array(ModuleCondition::Running)); $this->Manager->Perform($List, array(ModuleAction::Stop), array(ModuleCondition::Running)); $this->DoStop(); } function Restart() { $this->Stop(); $this->Start(); } function Enable() { if($this->Enabled) return; if(!$this->Installed) return; $List = array(); $this->Manager->EnumDependenciesCascade($this, $List, array(ModuleCondition::NotEnabled)); $this->Manager->Perform($List, array(ModuleAction::Enable), array(ModuleCondition::NotEnabled)); $this->Enabled = true; } function Disable() { if(!$this->Enabled) return; $this->Stop(); $this->Enabled = false; $List = array(); $this->Manager->EnumSuperiorDependenciesCascade($this, $List, array(ModuleCondition::Enabled)); $this->Manager->Perform($List, array(ModuleAction::Disable), array(ModuleCondition::Enabled)); } protected function DoStart() { } protected function DoStop() { } protected function DoInstall() { } protected function DoUninstall() { } } /* Manage installed modules */ class AppModuleManager { var $Modules; var $System; var $FileName; var $OnLoadModules; function __construct(System $System) { $this->Modules = array(); $this->System = &$System; $this->FileName = 'Config/Modules.php'; } function Perform($List, $Actions, $Conditions = array(ModuleCondition::All)) { foreach($List as $Index => $Module) { if(in_array(ModuleCondition::All, $Conditions) or ($Module->Running and in_array(ModuleCondition::Running, $Conditions)) or (!$Module->Running and in_array(ModuleCondition::NotRunning, $Conditions)) or ($Module->Installed and in_array(ModuleCondition::Installed, $Conditions)) or (!$Module->Installed and in_array(ModuleCondition::NotInstalled, $Conditions)) or ($Module->Enabled and in_array(ModuleCondition::Enabled, $Conditions)) or (!$Module->Enabled and in_array(ModuleCondition::NotEnabled, $Conditions))) { foreach($Actions as $Action) { if($Action == ModuleAction::Start) $Module->Start(); if($Action == ModuleAction::Stop) $Module->Stop(); if($Action == ModuleAction::Install) $Module->Install(); if($Action == ModuleAction::Uninstall) $Module->Uninstall(); if($Action == ModuleAction::Enable) $Module->Enable(); if($Action == ModuleAction::Disable) $Module->Disable(); } } } } function EnumDependenciesCascade($Module, &$List, $Conditions = array(ModuleCondition::All)) { foreach($Module->Dependencies as $Dependency) { $DepModule = $this->Modules[$Dependency]; if(in_array(ModuleCondition::All, $Conditions) or ($Module->Running and in_array(ModuleCondition::Running, $Conditions)) or (!$Module->Running and in_array(ModuleCondition::NotRunning, $Conditions)) or ($Module->Enabled and in_array(ModuleCondition::Enabled, $Conditions)) or (!$Module->Enabled and in_array(ModuleCondition::NotEnabled, $Conditions)) or ($Module->Installed and in_array(ModuleCondition::Installed, $Conditions)) or (!$Module->Installed and in_array(ModuleCondition::NotInstalled, $Conditions))) { array_push($List, $DepModule); $this->EnumDependenciesCascade($DepModule, $List, $Conditions); } } } function EnumSuperiorDependenciesCascade($Module, &$List, $Conditions = array(ModuleCondition::All)) { foreach($this->Modules as $RefModule) { if(in_array($Module->Name, $RefModule->Dependencies) and (in_array(ModuleCondition::All, $Conditions) or ($Module->Running and in_array(ModuleCondition::Running, $Conditions)) or (!$Module->Running and in_array(ModuleCondition::NotRunning, $Conditions)) or ($Module->Enabled and in_array(ModuleCondition::Enabled, $Conditions)) or (!$Module->Enabled and in_array(ModuleCondition::NotEnabled, $Conditions)) or ($Module->Installed and in_array(ModuleCondition::Installed, $Conditions)) or (!$Module->Installed and in_array(ModuleCondition::NotInstalled, $Conditions)))) { array_push($List, $RefModule); $this->EnumSuperiorDependenciesCascade($RefModule, $List, $Conditions); } } } function Start() { $this->LoadModules(); if(file_exists($this->FileName)) $this->LoadState(); $this->StartEnabled(); } function StartAll() { $this->Perform($this->Modules, array(ModuleAction::Start)); } function StartEnabled() { $this->Perform($this->Modules, array(ModuleAction::Start), array(ModuleCondition::Enabled)); } function StopAll() { $this->Perform($this->Modules, array(ModuleAction::Stop)); } function UninstallAll() { $this->Perform($this->Modules, array(ModuleAction::Uninstall)); $this->SaveState(); } function ModulePresent($Name) { return(array_key_exists($Name, $this->Modules)); } /* @return Module */ function SearchModuleById($Id) { foreach($this->Modules as $Module) { //DebugLog($Module->Name.' '.$Module->Id); if($Module->Id == $Id) return($Module->Name); } return(''); } function LoadState() { $ConfigModules = array(); include($this->FileName); foreach($ConfigModules as $Mod) { if(array_key_exists($Mod['Name'], $this->Modules)) { $this->Modules[$Mod['Name']] = $this->Modules[$Mod['Name']]; $this->Modules[$Mod['Name']]->Enabled = $Mod['Enabled']; $this->Modules[$Mod['Name']]->Installed = $Mod['Installed']; $this->Modules[$Mod['Name']]->InstalledVersion = $Mod['Version']; } } } function SaveState() { $Data = array(); foreach($this->Modules as $Module) { $Data[] = array('Name' => $Module->Name, 'Enabled' => $Module->Enabled, 'Version' => $Module->Version, 'Installed' => $Module->Installed); } file_put_contents($this->FileName, "Modules[$Module->Name] = &$Module; $Module->Manager = &$this; $Module->OnChange = &$this->OnModuleChange; } function UnregisterModule(AppModule $Module) { unset($this->Modules[array_search($Module, $this->Modules)]); } function LoadModulesFromDir($Directory) { $List = scandir($Directory); foreach($List as $Item) { if(is_dir($Directory.'/'.$Item) and ($Item != '.') and ($Item != '..') and ($Item != '.svn')) { include_once($Directory.'/'.$Item.'/'.$Item.'.php'); $ModuleName = 'Module'.$Item; $this->RegisterModule(new $ModuleName($this->System)); } } } function LoadModules() { if(method_exists($this->OnLoadModules[0], $this->OnLoadModules[1])) $this->OnLoadModules(); else $this->LoadModulesFromDir(dirname(__FILE__).'/../Module'); } }