source: trunk/Packages/Common/ModuleManager.php

Last change on this file was 8, checked in by chronos, 19 months ago
  • Modified: Updated Common package.
  • Modified: Form types made as separate FormManager package.
  • Fixed: PHP 8.1 support.
File size: 10.1 KB
Line 
1<?php
2
3/* Manage installed modules */
4class ModuleManager
5{
6 public array $Modules; // Module
7 public System $System;
8 public string $FileName;
9 public string $ModulesDir;
10 public $OnLoadModules;
11 public $OnInstallModel;
12 public $OnUninstallModel;
13 public $OnInstallModule;
14 public $OnUninstallModule;
15 public $OnModuleChange;
16 private int $NewModuleId;
17
18 function __construct(System $System)
19 {
20 $this->Modules = array();
21 $this->System = &$System;
22 $this->FileName = dirname(__FILE__).'/../../Config/ModulesConfig.php';
23 $this->ModulesDir = dirname(__FILE__).'/../../Modules';
24 $this->OnInstallModel = null;
25 $this->OnUninstallModel = null;
26 $this->OnInstallModule = null;
27 $this->OnUninstallModule = null;
28 $this->OnModuleChange = null;
29 $this->NewModuleId = 1;
30 }
31
32 function Perform(array $Actions, array $Conditions = array(ModuleCondition::All)): void
33 {
34 $this->PerformList($this->Modules, $Actions, $Conditions);
35 }
36
37 function PerformList(array $List, array $Actions, array $Conditions = array(ModuleCondition::All)): void
38 {
39 foreach ($List as $Module)
40 {
41 if (in_array(ModuleCondition::All, $Conditions) or
42 ($Module->Running and in_array(ModuleCondition::Running, $Conditions)) or
43 (!$Module->Running and in_array(ModuleCondition::NotRunning, $Conditions)) or
44 ($Module->Installed and in_array(ModuleCondition::Installed, $Conditions)) or
45 (!$Module->Installed and in_array(ModuleCondition::NotInstalled, $Conditions)) or
46 ($Module->Enabled and in_array(ModuleCondition::Enabled, $Conditions)) or
47 (!$Module->Enabled and in_array(ModuleCondition::NotEnabled, $Conditions)) or
48 (($Module->Type == ModuleType::System) and in_array(ModuleCondition::System, $Conditions)) or
49 (($Module->Type == ModuleType::Application) and in_array(ModuleCondition::Application, $Conditions)) or
50 (($Module->Type == ModuleType::Library) and in_array(ModuleCondition::Library, $Conditions)))
51 {
52 foreach ($Actions as $Action)
53 {
54 if ($Action == ModuleAction::Start) $Module->Start();
55 if ($Action == ModuleAction::Stop) $Module->Stop();
56 if ($Action == ModuleAction::Install) $Module->Install();
57 if ($Action == ModuleAction::Uninstall) $Module->Uninstall();
58 if ($Action == ModuleAction::Enable) $Module->Enable();
59 if ($Action == ModuleAction::Disable) $Module->Disable();
60 if ($Action == ModuleAction::Upgrade) $Module->Upgrade();
61 if ($Action == ModuleAction::InsertSampleData) $Module->InsertSampleData();
62 }
63 }
64 }
65 }
66
67 function EnumDependenciesCascade(Module $Module, array &$List, array $Conditions = array(ModuleCondition::All))
68 {
69 foreach ($Module->Dependencies as $Dependency)
70 {
71 if (!array_key_exists($Dependency, $this->Modules))
72 throw new Exception(sprintf(T('Module "%s" dependency "%s" not found'), $Module->Name, $Dependency));
73 $DepModule = $this->Modules[$Dependency];
74 if (in_array(ModuleCondition::All, $Conditions) or
75 ($DepModule->Running and in_array(ModuleCondition::Running, $Conditions)) or
76 (!$DepModule->Running and in_array(ModuleCondition::NotRunning, $Conditions)) or
77 ($DepModule->Enabled and in_array(ModuleCondition::Enabled, $Conditions)) or
78 (!$DepModule->Enabled and in_array(ModuleCondition::NotEnabled, $Conditions)) or
79 ($DepModule->Installed and in_array(ModuleCondition::Installed, $Conditions)) or
80 (!$DepModule->Installed and in_array(ModuleCondition::NotInstalled, $Conditions)) or
81 (($DepModule->Type == ModuleType::System) and in_array(ModuleCondition::System, $Conditions)) or
82 (($DepModule->Type == ModuleType::Application) and in_array(ModuleCondition::Application, $Conditions)) or
83 (($DepModule->Type == ModuleType::Library) and in_array(ModuleCondition::Library, $Conditions)))
84 {
85 array_push($List, $DepModule);
86 $this->EnumDependenciesCascade($DepModule, $List, $Conditions);
87 }
88 }
89 }
90
91 function EnumSuperiorDependenciesCascade(Module $Module, array &$List, array $Conditions = array(ModuleCondition::All))
92 {
93 foreach ($this->Modules as $RefModule)
94 {
95 if (in_array($Module->Name, $RefModule->Dependencies) and
96 (in_array(ModuleCondition::All, $Conditions) or
97 ($RefModule->Running and in_array(ModuleCondition::Running, $Conditions)) or
98 (!$RefModule->Running and in_array(ModuleCondition::NotRunning, $Conditions)) or
99 ($RefModule->Enabled and in_array(ModuleCondition::Enabled, $Conditions)) or
100 (!$RefModule->Enabled and in_array(ModuleCondition::NotEnabled, $Conditions)) or
101 ($RefModule->Installed and in_array(ModuleCondition::Installed, $Conditions)) or
102 (!$RefModule->Installed and in_array(ModuleCondition::NotInstalled, $Conditions)) or
103 (($RefModule->Type == ModuleType::System) and in_array(ModuleCondition::System, $Conditions)) or
104 (($RefModule->Type == ModuleType::Application) and in_array(ModuleCondition::Application, $Conditions)) or
105 (($RefModule->Type == ModuleType::Library) and in_array(ModuleCondition::Library, $Conditions))))
106 {
107 array_push($List, $RefModule);
108 $this->EnumSuperiorDependenciesCascade($RefModule, $List, $Conditions);
109 }
110 }
111 }
112
113 function StartAll(array $Conditions = array(ModuleCondition::All)): void
114 {
115 $this->Perform(array(ModuleAction::Start), $Conditions);
116 }
117
118 function StopAll(array $Conditions = array(ModuleCondition::All)): void
119 {
120 $this->Perform(array(ModuleAction::Stop), $Conditions);
121 }
122
123 function InstallAll(array $Conditions = array(ModuleCondition::All)): void
124 {
125 $this->Perform(array(ModuleAction::Install), $Conditions);
126 $this->SaveState();
127 }
128
129 function UninstallAll(array $Conditions = array(ModuleCondition::All)): void
130 {
131 $this->Perform(array(ModuleAction::Uninstall), $Conditions);
132 $this->SaveState();
133 }
134
135 function EnableAll(array $Conditions = array(ModuleCondition::All)): void
136 {
137 $this->Perform(array(ModuleAction::Enable), $Conditions);
138 $this->SaveState();
139 }
140
141 function DisableAll(array $Conditions = array(ModuleCondition::All)): void
142 {
143 $this->Perform(array(ModuleAction::Disable), $Conditions);
144 $this->SaveState();
145 }
146
147 function UpgradeAll(array $Conditions = array(ModuleCondition::All)): void
148 {
149 $this->Perform(array(ModuleAction::Upgrade), $Conditions);
150 $this->SaveState();
151 }
152
153 function ModulePresent(string $Name): bool
154 {
155 return array_key_exists($Name, $this->Modules);
156 }
157
158 function ModuleEnabled(string $Name): bool
159 {
160 return array_key_exists($Name, $this->Modules) and $this->Modules[$Name]->Enabled;
161 }
162
163 function ModuleRunning(string $Name): bool
164 {
165 return array_key_exists($Name, $this->Modules) and $this->Modules[$Name]->Running;
166 }
167
168 function GetModule(string $Name): Module
169 {
170 return $this->Modules[$Name];
171 }
172
173 function SearchModuleById(int $Id): string
174 {
175 foreach ($this->Modules as $Module)
176 {
177 if ($Module->Id == $Id) return $Module->Name;
178 }
179 return '';
180 }
181
182 function LoadState(): void
183 {
184 $ConfigModules = array();
185 include $this->FileName;
186 foreach ($ConfigModules as $Mod)
187 {
188 $ModuleName = $Mod['Name'];
189 if (array_key_exists($ModuleName, $this->Modules))
190 {
191 if (array_key_exists('Id', $Mod))
192 {
193 $this->Modules[$ModuleName]->Id = $Mod['Id'];
194 }
195 if (array_key_exists('Enabled', $Mod))
196 {
197 $this->Modules[$ModuleName]->Enabled = $Mod['Enabled'];
198 }
199 if (array_key_exists('Installed', $Mod))
200 {
201 $this->Modules[$ModuleName]->Installed = $Mod['Installed'];
202 }
203 if (array_key_exists('InstalledVersion', $Mod))
204 {
205 $this->Modules[$ModuleName]->InstalledVersion = $Mod['InstalledVersion'];
206 }
207 }
208 }
209 }
210
211 function SaveState(): void
212 {
213 $Data = array();
214 foreach ($this->Modules as $Module)
215 {
216 $Data[] = array(
217 'Id' => $Module->Id,
218 'Name' => $Module->Name,
219 'Enabled' => $Module->Enabled,
220 'InstalledVersion' => $Module->InstalledVersion,
221 'Installed' => $Module->Installed
222 );
223 }
224 if (file_put_contents($this->FileName, "<?php \n\n\$ConfigModules = ".var_export($Data, true).";\n") === FALSE)
225 {
226 echo($this->FileName.' is not writeable.');
227 }
228 }
229
230 function RegisterModule(Module $Module): void
231 {
232 if (array_key_exists($Module->Name, $this->Modules))
233 die('Can\'t register module '.$Module->Name.' because it already exists.');
234 $this->Modules[$Module->Name] = &$Module;
235 $Module->Manager = &$this;
236 $Module->OnChange = &$this->OnModuleChange;
237 }
238
239 function UnregisterModule(Module $Module): void
240 {
241 unset($this->Modules[array_search($Module, $this->Modules)]);
242 }
243
244 function GetUniqueModuleId()
245 {
246 $this->NewModuleId++;
247 return $this->NewModuleId - 1;
248 }
249
250 function LoadModule(string $FileName): Module
251 {
252 $ClassName = pathinfo($FileName, PATHINFO_FILENAME);
253 if (!array_key_exists($ClassName::GetName(), $this->Modules))
254 {
255 $Module = new $ClassName($this->System);
256 $Module->Id = $this->GetUniqueModuleId();
257 $this->RegisterModule($Module);
258 return $Module;
259 } else
260 {
261 $Module = $this->Modules[$ClassName::GetName()];
262 return $Module;
263 }
264 }
265
266 function LoadModulesFromDir(string $Directory): void
267 {
268 $FileNames = array();
269 $List = scandir($Directory);
270 foreach ($List as $Item)
271 {
272 if (is_dir($Directory.'/'.$Item) and ($Item != '.') and ($Item != '..') and ($Item != '.svn'))
273 {
274 $FileName = $Directory.'/'.$Item.'/Module'.$Item.'.php';
275 $FileNames[] = $FileName;
276 include_once($FileName);
277 }
278 }
279 foreach ($FileNames as $FileName)
280 {
281 $this->LoadModule($FileName);
282 }
283 }
284
285 function LoadModules(): void
286 {
287 if (is_array($this->OnLoadModules) and (count($this->OnLoadModules) == 2) and method_exists($this->OnLoadModules[0], $this->OnLoadModules[1]))
288 call_user_func($this->OnLoadModules);
289 else $this->LoadModulesFromDir($this->ModulesDir);
290 }
291}
Note: See TracBrowser for help on using the repository browser.