source: trunk/Packages/Common/AppModule.php

Last change on this file was 3, checked in by chronos, 8 years ago
  • Modified: Updated to work with PHP7. Old database class replaced by Common package.
File size: 11.0 KB
Line 
1<?php
2
3/* This implementation will not support installation from remote source. Just
4 * installation of already presented modules mainly to persistence preparation.
5 */
6
7class ModuleType
8{
9 const System = 0;
10 const Normal = 1;
11 const Application = 2;
12}
13
14class ModuleAction
15{
16 const Start = 0;
17 const Stop = 1;
18 const Install = 2;
19 const Uninstall = 3;
20 const Upgrade = 4;
21 const Enable = 5;
22 const Disable = 6;
23}
24
25class ModuleCondition
26{
27 const All = 0;
28 const Enabled = 1;
29 const NotEnabled = 2;
30 const Installed = 3;
31 const NotInstalled = 4;
32 const Running = 5;
33 const NotRunning = 6;
34}
35
36class AppModule
37{
38 var $Id;
39 var $Name;
40 var $Title;
41 var $Version;
42 var $License;
43 var $Creator;
44 var $HomePage;
45 var $Description;
46 var $Running;
47 var $Enabled;
48 var $Installed;
49 var $InstalledVersion;
50 /** @var ModuleType */
51 var $Type;
52 var $Dependencies;
53 /** @var Database */
54 var $Database;
55 /** @var System */
56 var $System;
57 /** @var AppModuleManager */
58 var $Manager;
59 var $OnChange;
60
61 function __construct(System $System)
62 {
63 $this->System = &$System;
64 $this->Database = &$System->Database;
65 $this->Installed = false;
66 $this->Enabled = false;
67 $this->Running = false;
68 $this->HomePage = '';
69 $this->License = '';
70 $this->Version = '';
71 $this->Creator = '';
72 $this->Description = '';
73 $this->Dependencies = array();
74 $this->Type = ModuleType::Normal;
75 }
76
77 function Install()
78 {
79 if($this->Installed) return;
80 $List = array();
81 $this->Manager->EnumDependenciesCascade($this, $List, array(ModuleCondition::NotInstalled));
82 $this->Manager->Perform($List, array(ModuleAction::Install), array(ModuleCondition::NotInstalled));
83 $this->DoInstall();
84 $this->Installed = true;
85 $this->InstalledVersion = $this->Version;
86 $this->Manager->Modules[$this->Name] = $this;
87 }
88
89 function Uninstall()
90 {
91 if(!$this->Installed) return;
92 $this->Stop();
93 $this->Installed = false;
94 $List = array();
95 $this->Manager->EnumSuperiorDependenciesCascade($this, $List, array(ModuleCondition::Installed));
96 $this->Manager->Perform($List, array(ModuleAction::Uninstall), array(ModuleCondition::Installed));
97 $this->DoUninstall();
98 }
99
100 function Upgrade()
101 {
102 if(!$this->Installed) return;
103 if($this->InstalledVersion == $this->Version) return;
104 $List = array();
105 $this->Manager->EnumSuperiorDependenciesCascade($this, $List, array(ModuleCondition::Installed));
106 $this->Manager->Perform($List, array(ModuleAction::Upgrade), array(ModuleCondition::Installed));
107 $this->DoUpgrade();
108 }
109
110 function Reinstall()
111 {
112 $this->Uninstall();
113 // TODO: Install also back dependecies
114 $this->Install();
115 }
116
117 function Start()
118 {
119 if($this->Running) return;
120 if(!$this->Installed) return;
121 $List = array();
122 $this->Manager->EnumDependenciesCascade($this, $List, array(ModuleCondition::NotRunning));
123 $this->Manager->Perform($List, array(ModuleAction::Start), array(ModuleCondition::NotRunning));
124 $this->DoStart();
125 $this->Running = true;
126 }
127
128 function Stop()
129 {
130 if(!$this->Running) return;
131 $this->Running = false;
132 $List = array();
133 $this->Manager->EnumSuperiorDependenciesCascade($this, $List, array(ModuleCondition::Running));
134 $this->Manager->Perform($List, array(ModuleAction::Stop), array(ModuleCondition::Running));
135 $this->DoStop();
136 }
137
138 function Restart()
139 {
140 $this->Stop();
141 $this->Start();
142 }
143
144 function Enable()
145 {
146 if($this->Enabled) return;
147 if(!$this->Installed) return;
148 $List = array();
149 $this->Manager->EnumDependenciesCascade($this, $List, array(ModuleCondition::NotEnabled));
150 $this->Manager->Perform($List, array(ModuleAction::Enable), array(ModuleCondition::NotEnabled));
151 $this->Enabled = true;
152 }
153
154 function Disable()
155 {
156 if(!$this->Enabled) return;
157 $this->Stop();
158 $this->Enabled = false;
159 $List = array();
160 $this->Manager->EnumSuperiorDependenciesCascade($this, $List, array(ModuleCondition::Enabled));
161 $this->Manager->Perform($List, array(ModuleAction::Disable), array(ModuleCondition::Enabled));
162 }
163
164 protected function DoStart()
165 {
166 }
167
168 protected function DoStop()
169 {
170 }
171
172 protected function DoInstall()
173 {
174 }
175
176 protected function DoUninstall()
177 {
178 }
179
180 protected function DoUpgrade()
181 {
182
183 }
184}
185
186/* Manage installed modules */
187class AppModuleManager
188{
189 var $Modules;
190 var $System;
191 var $FileName;
192 var $ModulesDir;
193 var $OnLoadModules;
194
195 function __construct(System $System)
196 {
197 $this->Modules = array();
198 $this->System = &$System;
199 $this->FileName = dirname(__FILE__).'/../../Config/ModulesConfig.php';
200 $this->ModulesDir = dirname(__FILE__).'/../../Modules';
201 }
202
203 function Perform($List, $Actions, $Conditions = array(ModuleCondition::All))
204 {
205 foreach($List as $Index => $Module)
206 {
207 if(in_array(ModuleCondition::All, $Conditions) or
208 ($Module->Running and in_array(ModuleCondition::Running, $Conditions)) or
209 (!$Module->Running and in_array(ModuleCondition::NotRunning, $Conditions)) or
210 ($Module->Installed and in_array(ModuleCondition::Installed, $Conditions)) or
211 (!$Module->Installed and in_array(ModuleCondition::NotInstalled, $Conditions)) or
212 ($Module->Enabled and in_array(ModuleCondition::Enabled, $Conditions)) or
213 (!$Module->Enabled and in_array(ModuleCondition::NotEnabled, $Conditions)))
214 {
215 foreach($Actions as $Action)
216 {
217 if($Action == ModuleAction::Start) $Module->Start();
218 if($Action == ModuleAction::Stop) $Module->Stop();
219 if($Action == ModuleAction::Install) $Module->Install();
220 if($Action == ModuleAction::Uninstall) $Module->Uninstall();
221 if($Action == ModuleAction::Enable) $Module->Enable();
222 if($Action == ModuleAction::Disable) $Module->Disable();
223 if($Action == ModuleAction::Upgrade) $Module->Upgrade();
224 }
225 }
226 }
227 }
228
229 function EnumDependenciesCascade($Module, &$List, $Conditions = array(ModuleCondition::All))
230 {
231 foreach($Module->Dependencies as $Dependency)
232 {
233 if(!array_key_exists($Dependency, $this->Modules))
234 throw new Exception(sprintf(T('Module "%s" dependency "%s" not found'), $Module->Name, $Dependency));
235 $DepModule = $this->Modules[$Dependency];
236 if(in_array(ModuleCondition::All, $Conditions) or
237 ($Module->Running and in_array(ModuleCondition::Running, $Conditions)) or
238 (!$Module->Running and in_array(ModuleCondition::NotRunning, $Conditions)) or
239 ($Module->Enabled and in_array(ModuleCondition::Enabled, $Conditions)) or
240 (!$Module->Enabled and in_array(ModuleCondition::NotEnabled, $Conditions)) or
241 ($Module->Installed and in_array(ModuleCondition::Installed, $Conditions)) or
242 (!$Module->Installed and in_array(ModuleCondition::NotInstalled, $Conditions)))
243 {
244 array_push($List, $DepModule);
245 $this->EnumDependenciesCascade($DepModule, $List, $Conditions);
246 }
247 }
248 }
249
250 function EnumSuperiorDependenciesCascade($Module, &$List, $Conditions = array(ModuleCondition::All))
251 {
252 foreach($this->Modules as $RefModule)
253 {
254 if(in_array($Module->Name, $RefModule->Dependencies) and
255 (in_array(ModuleCondition::All, $Conditions) or
256 ($Module->Running and in_array(ModuleCondition::Running, $Conditions)) or
257 (!$Module->Running and in_array(ModuleCondition::NotRunning, $Conditions)) or
258 ($Module->Enabled and in_array(ModuleCondition::Enabled, $Conditions)) or
259 (!$Module->Enabled and in_array(ModuleCondition::NotEnabled, $Conditions)) or
260 ($Module->Installed and in_array(ModuleCondition::Installed, $Conditions)) or
261 (!$Module->Installed and in_array(ModuleCondition::NotInstalled, $Conditions))))
262 {
263 array_push($List, $RefModule);
264 $this->EnumSuperiorDependenciesCascade($RefModule, $List, $Conditions);
265 }
266 }
267 }
268
269 function Start()
270 {
271 $this->LoadModules();
272 if(file_exists($this->FileName)) $this->LoadState();
273 $this->StartEnabled();
274 }
275
276 function StartAll()
277 {
278 $this->Perform($this->Modules, array(ModuleAction::Start));
279 }
280
281 function StartEnabled()
282 {
283 $this->Perform($this->Modules, array(ModuleAction::Start), array(ModuleCondition::Enabled));
284 }
285
286 function StopAll()
287 {
288 $this->Perform($this->Modules, array(ModuleAction::Stop));
289 }
290
291 function InstallAll()
292 {
293 $this->Perform($this->Modules, array(ModuleAction::Install));
294 $this->SaveState();
295 }
296
297 function UninstallAll()
298 {
299 $this->Perform($this->Modules, array(ModuleAction::Uninstall));
300 $this->SaveState();
301 }
302
303 function EnableAll()
304 {
305 $this->Perform($this->Modules, array(ModuleAction::Enable));
306 $this->SaveState();
307 }
308
309 function DisableAll()
310 {
311 $this->Perform($this->Modules, array(ModuleAction::Disable));
312 $this->SaveState();
313 }
314
315 function ModulePresent($Name)
316 {
317 return(array_key_exists($Name, $this->Modules));
318 }
319
320 function ModuleEnabled($Name)
321 {
322 return(array_key_exists($Name, $this->Modules) and $this->Modules[$Name]->Enabled);
323 }
324
325 function ModuleRunning($Name)
326 {
327 return(array_key_exists($Name, $this->Modules) and $this->Modules[$Name]->Running);
328 }
329
330 /* @return Module */
331 function SearchModuleById($Id)
332 {
333 foreach($this->Modules as $Module)
334 {
335 //DebugLog($Module->Name.' '.$Module->Id);
336 if($Module->Id == $Id) return($Module->Name);
337 }
338 return('');
339 }
340
341 function LoadState()
342 {
343 $ConfigModules = array();
344 include($this->FileName);
345 foreach($ConfigModules as $Mod)
346 {
347 if(array_key_exists($Mod['Name'], $this->Modules))
348 {
349 $this->Modules[$Mod['Name']] = $this->Modules[$Mod['Name']];
350 $this->Modules[$Mod['Name']]->Enabled = $Mod['Enabled'];
351 $this->Modules[$Mod['Name']]->Installed = $Mod['Installed'];
352 $this->Modules[$Mod['Name']]->InstalledVersion = $Mod['Version'];
353 }
354 }
355 }
356
357 function SaveState()
358 {
359 $Data = array();
360 foreach($this->Modules as $Module)
361 {
362 $Data[] = array('Name' => $Module->Name, 'Enabled' => $Module->Enabled,
363 'Version' => $Module->Version, 'Installed' => $Module->Installed);
364 }
365 file_put_contents($this->FileName, "<?php \n\n\$ConfigModules = ".var_export($Data, true).";\n");
366 }
367
368 function RegisterModule(AppModule $Module)
369 {
370 $this->Modules[$Module->Name] = &$Module;
371 $Module->Manager = &$this;
372 $Module->OnChange = &$this->OnModuleChange;
373 }
374
375 function UnregisterModule(AppModule $Module)
376 {
377 unset($this->Modules[array_search($Module, $this->Modules)]);
378 }
379
380 function LoadModulesFromDir($Directory)
381 {
382 $List = scandir($Directory);
383 foreach($List as $Item)
384 {
385 if(is_dir($Directory.'/'.$Item) and ($Item != '.') and ($Item != '..') and ($Item != '.svn'))
386 {
387 include_once($Directory.'/'.$Item.'/'.$Item.'.php');
388 $ModuleName = 'Module'.$Item;
389 $this->RegisterModule(new $ModuleName($this->System));
390 }
391 }
392 }
393
394 function LoadModules()
395 {
396 if(method_exists($this->OnLoadModules[0], $this->OnLoadModules[1]))
397 $this->OnLoadModules();
398 else $this->LoadModulesFromDir($this->ModulesDir);
399 }
400}
Note: See TracBrowser for help on using the repository browser.