source: trunk/Packages/Common/Modules/Setup.php

Last change on this file was 981, checked in by chronos, 4 days ago
  • Fixed: Check if system user is logged in modules page.
File size: 13.7 KB
Line 
1<?php
2
3class ModuleSetup extends Module
4{
5 public UpdateManager $UpdateManager;
6
7 function __construct(System $System)
8 {
9 global $DatabaseRevision;
10
11 parent::__construct($System);
12 $this->Name = 'Setup';
13 $this->Version = '1.0';
14 $this->Creator = 'Chronos';
15 $this->License = 'GNU/GPLv3';
16 $this->Description = 'Base setup module';
17 $this->Type = ModuleType::System;
18
19 // Check database persistence structure
20 $this->UpdateManager = new UpdateManager();
21 $this->UpdateManager->Database = &$this->Database;
22 $this->UpdateManager->Revision = $DatabaseRevision;
23 $this->UpdateManager->InstallMethod = 'FullInstall';
24 }
25
26 static function Cast(Module $Module): ModuleSetup
27 {
28 if ($Module instanceof ModuleSetup)
29 {
30 return $Module;
31 }
32 throw new Exception('Expected ModuleSetup type but '.gettype($Module));
33 }
34
35 function DoStart(): void
36 {
37 Core::Cast($this->System)->RegisterPage([''], 'PageSetupRedirect');
38 Core::Cast($this->System)->RegisterPage(['setup'], 'PageSetup');
39 }
40
41 function DoStop(): void
42 {
43 unset($this->UpdateManager);
44 Core::Cast($this->System)->UnregisterPage(['']);
45 Core::Cast($this->System)->UnregisterPage(['setup']);
46 }
47
48 function CheckState(): bool
49 {
50 return $this->Database->Connected() and $this->UpdateManager->IsInstalled() and
51 $this->UpdateManager->IsUpToDate();
52 }
53
54 function DoUpgrade(): string
55 {
56 $Updates = new Updates();
57 $this->UpdateManager->Trace = $Updates->Get();
58 $Output = $this->UpdateManager->Upgrade();
59 return $Output;
60 }
61
62 function UserLogged(): bool
63 {
64 if (!array_key_exists('SystemPassword', $_SESSION)) $_SESSION['SystemPassword'] = '';
65 if (array_key_exists('login', $_POST)) $_SESSION['SystemPassword'] = $_POST['SystemPassword'];
66 return sha1($_SESSION['SystemPassword']) == Core::Cast($this->System)->Config['SystemPassword'];
67 }
68}
69
70class PageSetup extends Page
71{
72 public UpdateManager $UpdateManager;
73 public array $ConfigDefinition;
74 public array $Config;
75 public int $DatabaseRevision;
76 public int $Revision;
77 public string $ConfigDir;
78 public array $YesNo;
79
80 function __construct(System $System)
81 {
82 parent::__construct($System);
83 $this->Title = T('Application setup');
84 //$this->ParentClass = 'PageSetupRedirect';
85 $this->ConfigDir = dirname(dirname(dirname(__FILE__))).'/Config';
86 $this->YesNo = array(false => T('No'), true => T('Yes'));
87 }
88
89 function LoginPanel(): string
90 {
91 $Output = '<h3>Přihlášení k instalaci</h3>'.
92 '<form action="?" method="post">'.
93 '<table>'.
94 '<tr><td>Systémové heslo:</td><td> <input type="password" name="SystemPassword" value=""/></td></tr>'.
95 '</table>'.
96 '<input type="submit" name="login" value="'.T('Login').'"/>'.
97 '</form>';
98 return $Output;
99 }
100
101 function ControlPanel(): string
102 {
103 $Output = '<h3>'.T('Instance management').'</h3>';
104
105 $Output .= 'Je připojení k databázi: '.$this->YesNo[$this->UpdateManager->Database->Connected()].'<br/>';
106 if ($this->UpdateManager->Database->Connected())
107 {
108 $Output .= 'Je instalováno: '.$this->YesNo[$this->UpdateManager->IsInstalled()].'<br/>';
109 if ($this->UpdateManager->IsInstalled())
110 $Output .= 'Je aktuální: '.$this->YesNo[$this->UpdateManager->IsUpToDate()].'<br/>'.
111 'Verze databáze: '.$this->UpdateManager->GetDbVersion().'<br/>';
112 $Output .= 'Verze databáze kódu: '.$this->UpdateManager->Revision.'<br/>';
113 if ($this->UpdateManager->IsInstalled())
114 {
115 if (!$this->UpdateManager->IsUpToDate())
116 $Output .= '<a href="?action=upgrade">'.T('Upgrade').'</a> ';
117 $Output .= '<a href="?action=insert_sample_data">Vložit vzorová data</a> ';
118 $Output .= '<a href="?action=reload-modules">Obnovit seznam modulů</a> ';
119 $Output .= '<a href="?action=uninstall">Odinstalovat</a> ';
120 $Output .= '<a href="'.$this->System->Link('/modules/').'">Správa modulů</a> ';
121 $Output .= '<a href="?action=models">Přegenerovat modely</a> ';
122 } else $Output .= '<a href="?action=install">Instalovat</a> ';
123 }
124 $Output .= '<a href="?action=configure">Nastavit</a> ';
125 $Output .= '<a href="?action=logout">Odhlásit</a> ';
126 $Output .= '<a href="'.$this->System->Link('/').'">'.T('Go to main page').'</a> ';
127 $Output .= '';
128 return $Output;
129 }
130
131 function Show(): string
132 {
133 global $DatabaseRevision, $Config;
134
135 $this->UpdateManager = ModuleSetup::Cast($this->System->GetModule('Setup'))->UpdateManager;
136 $DefaultConfig = new DefaultConfig();
137 $this->ConfigDefinition = $DefaultConfig->Get();
138 $this->DatabaseRevision = $DatabaseRevision;
139 $this->Config = &$Config;
140
141 $Output = '';
142 if (isset($this->Config))
143 {
144 if (!ModuleSetup::Cast($this->System->GetModule('Setup'))->UserLogged())
145 {
146 $Output .= $this->LoginPanel();
147 } else
148 {
149 if (array_key_exists('action', $_GET)) $Action = $_GET['action'];
150 else $Action = '';
151 if ($Action == 'logout')
152 {
153 $_SESSION['SystemPassword'] = '';
154 $Output .= 'Odhlášen';
155 $Output .= $this->LoginPanel();
156 }
157 else if ($Action == 'models')
158 {
159 Core::Cast($this->System)->FormManager->UpdateSQLMeta();
160 }
161 else if ($Action == 'upgrade')
162 {
163 $Output .= '<h3>Povýšení</h3>';
164 try
165 {
166 $Output .= ModuleSetup::Cast($this->System->GetModule('Setup'))->DoUpgrade();
167 $this->System->ModuleManager->UpgradeAll(array(ModuleCondition::System));
168 } catch (Exception $E)
169 {
170 $Output .= $this->SystemMessage('Chyba aktualizace',
171 'Došlo k chybě v SQL dotazu při aktualizaci: <br/>'.$E->getMessage());
172 }
173 $Output .= $this->ControlPanel();
174 }
175 else if ($Action == 'install')
176 {
177 $Output .= '<h3>Instalace systém</h3>';
178 global $DatabaseRevision;
179
180 $this->Database->query("CREATE TABLE IF NOT EXISTS `".$this->UpdateManager->VersionTable."` (".
181 '`Id` int(11) NOT NULL AUTO_INCREMENT, '.
182 '`Revision` int(11) NOT NULL, '.
183 'PRIMARY KEY (`Id`) '.
184 ') ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;');
185 $DbResult = $this->Database->select($this->UpdateManager->VersionTable, 'Id');
186 if ($DbResult->num_rows == 0)
187 {
188 $this->Database->query("INSERT INTO `".$this->UpdateManager->VersionTable.
189 "` (`Id`, `Revision`) VALUES (1, ".$DatabaseRevision.");");
190 }
191 $this->System->ModuleManager->InstallAll(array(ModuleCondition::System));
192 $this->System->ModuleManager->LoadModules();
193 $this->System->ModuleManager->SaveState();
194 //$Output .= ModuleSetup::Cast($this->System->GetModule('Setup'))->Upgrade();
195 $Output .= $this->ControlPanel();
196 }
197 else if ($Action == 'uninstall')
198 {
199 $Output .= '<h3>Odinstalace vše</h3>';
200 $this->System->ModuleManager->UninstallAll(array(ModuleCondition::All));
201 $this->Database->query('DROP TABLE IF EXISTS `'.$this->UpdateManager->VersionTable.'`');
202 $Output .= $this->ControlPanel();
203 }
204 else if ($Action == 'reload-modules')
205 {
206 $Output .= '<h3>Znovunačtení seznamu modulů</h3>';
207 $this->System->ModuleManager->LoadModules();
208 $this->System->ModuleManager->SaveState();
209 $Output .= $this->ControlPanel();
210 }
211 else if ($Action == 'insert_sample_data')
212 {
213 $Output .= '<h3>Vložení vzorových dat</h3>';
214 $this->System->ModuleManager->Perform(array(ModuleAction::InsertSampleData), array(ModuleCondition::Installed));
215 $Output .= $this->ControlPanel();
216 }
217 else if ($Action == 'configure_save')
218 {
219 $Output .= $this->ConfigSave($this->Config);
220 $Output .= $this->ControlPanel();
221 }
222 else if ($Action == 'configure')
223 {
224 $Output .= $this->PrepareConfig($this->Config);
225 }
226 else
227 {
228 $Output .= $this->ControlPanel();
229 }
230 }
231 } else
232 {
233 if (array_key_exists('configure_save', $_POST))
234 {
235 $Output .= $this->ConfigSave(array());
236 $Output .= 'Pokračujte k přihlášení <a href="">zde</a>';
237 } else {
238 $Output .= $this->PrepareConfig(array());
239 }
240 }
241 return $Output;
242 }
243
244 function PrepareConfig($Config): string
245 {
246 $Output = '';
247 if (!file_exists($this->ConfigDir.'/Config.php') and !is_writable($this->ConfigDir))
248 $Output .= 'Varování: Konfigurační soubor nebude možné zapsat, protože složka "'.$this->ConfigDir.'" není povolená pro zápis!';
249 if (file_exists($this->ConfigDir.'/Config.php') and !is_writable($this->ConfigDir.'/Config.php'))
250 $Output .= 'Varování: Konfigurační soubor nebude možné zapsat, protože soubor "'.$this->ConfigDir.'/Config.php" není povolen pro zápis!';
251 $Output .= '<h3>Nastavení systému</h3>'.
252 '<form action="?action=configure_save" method="post">'.
253 '<table>';
254 foreach ($this->ConfigDefinition as $Def)
255 {
256 $PathParts = explode('/', $Def['Name']);
257 $TempConfig = &$Config;
258 foreach ($PathParts as $Part)
259 if (array_key_exists($Part, $TempConfig))
260 {
261 $TempConfig = &$TempConfig[$Part];
262 }
263 if (!is_array($TempConfig)) $Value = $TempConfig;
264 else $Value = $Def['Default'];
265 $Output .= '<tr><td>'.$Def['Title'].'</td><td>';
266 if ($Def['Type'] == 'String') $Output .= '<input type="text" name="'.$Def['Name'].'" value="'.$Value.'"/>';
267 if ($Def['Type'] == 'Password') $Output .= '<input type="password" name="'.$Def['Name'].'"/>';
268 if ($Def['Type'] == 'PasswordEncoded') $Output .= '<input type="password" name="'.$Def['Name'].'"/>';
269 if ($Def['Type'] == 'Integer') $Output .= '<input type="text" name="'.$Def['Name'].'" value="'.$Value.'"/>';
270 if ($Def['Type'] == 'Float') $Output .= '<input type="text" name="'.$Def['Name'].'" value="'.$Value.'"/>';
271 if ($Def['Type'] == 'Boolean') $Output .= '<input type="text" name="'.$Def['Name'].'" value="'.$Value.'"/>';
272 if ($Def['Type'] == 'Array') $Output .= '<input type="text" name="'.$Def['Name'].'" value="'.implode(',', $Value).'"/>';
273 }
274 $Output .= '</td></tr>'.
275 '<tr><td colspan="2"><input type="submit" name="configure_save" value="'.T('Save').'"/></td></tr>'.
276 '</table>'.
277 '</form>';
278 return $Output;
279 }
280
281 function ConfigSave($DefaultConfig)
282 {
283 $Config = $DefaultConfig;
284 foreach ($this->ConfigDefinition as $Def)
285 {
286 $Value = null;
287 if ($Def['Type'] == 'String') if (array_key_exists($Def['Name'], $_POST))
288 $Value = $_POST[$Def['Name']];
289 if ($Def['Type'] == 'Password') if (array_key_exists($Def['Name'], $_POST) and ($_POST[$Def['Name']] != ''))
290 $Value = $_POST[$Def['Name']];
291 if ($Def['Type'] == 'PasswordEncoded') if (array_key_exists($Def['Name'], $_POST) and ($_POST[$Def['Name']] != ''))
292 $Value = sha1($_POST[$Def['Name']]);
293 if ($Def['Type'] == 'Integer') if (array_key_exists($Def['Name'], $_POST))
294 $Value = $_POST[$Def['Name']];
295 if ($Def['Type'] == 'Float') if (array_key_exists($Def['Name'], $_POST))
296 $Value = $_POST[$Def['Name']];
297 if ($Def['Type'] == 'Boolean') if (array_key_exists($Def['Name'], $_POST))
298 $Value = $_POST[$Def['Name']];
299 if ($Def['Type'] == 'Array') if (array_key_exists($Def['Name'], $_POST))
300 $Value = explode(',', $_POST[$Def['Name']]);
301 if (!is_null($Value))
302 {
303 $PathParts = explode('/', $Def['Name']);
304 $TempConfig = &$Config;
305 foreach ($PathParts as $Part)
306 {
307 $TempConfig = &$TempConfig[$Part];
308 }
309 if (!is_array($TempConfig)) $TempConfig = $Value;
310 else $Value = $Def['Default'];
311 }
312 }
313 $ConfigText = $this->CreateConfig($Config);
314 file_put_contents($this->ConfigDir.'/Config.php', $ConfigText);
315 $Output = 'Konfigurace nastavena<br/>';
316 return $Output;
317 }
318
319 function CreateConfig($Config): string
320 {
321 $Output = "<?php\n\n".
322 "\$IsDeveloper = array_key_exists('REMOTE_ADDR', \$_SERVER) and in_array(\$_SERVER['REMOTE_ADDR'], array('127.0.0.1'));\n\n";
323
324 foreach ($this->ConfigDefinition as $Def)
325 {
326 $PathParts = explode('/', $Def['Name']);
327 $Output .= "\$Config";
328 foreach ($PathParts as $Part)
329 $Output .= "['".$Part."']";
330 $TempConfig = &$Config;
331 $Output .= ' = ';
332 foreach ($PathParts as $Part)
333 if (array_key_exists($Part, $TempConfig))
334 {
335 $TempConfig = &$TempConfig[$Part];
336 }
337 if (!is_array($TempConfig)) $Value = $TempConfig;
338 else $Value = $Def['Default'];
339 if ($Def['Type'] == 'Array')
340 {
341 $Output .= ' array(';
342 foreach ($Value as $Index => $Item)
343 $Output .= '\''.$Item.'\', ';
344 $Output .= ')';
345 }
346 else $Output .= "'".$Value."'";
347 $Output .= ";\n";
348 }
349 $Output .= "\n\n";
350 return $Output;
351 }
352}
353
354class PageSetupRedirect extends Page
355{
356 function Show(): string
357 {
358 $Output = '';
359 if (!$this->Database->Connected())
360 {
361 $Output .= T('Can\'t connect to database.').'<br>';
362 } else
363 {
364 if (!ModuleSetup::Cast($this->System->GetModule('Setup'))->UpdateManager->IsInstalled())
365 {
366 $Output .= T('System requires database initialization.').'<br>';
367 } else
368 if (!ModuleSetup::Cast($this->System->GetModule('Setup'))->UpdateManager->IsUpToDate())
369 {
370 $Output .= T('System requires database upgrade.').'<br>';
371 }
372 }
373 $Output .= sprintf(T('Front page was not configured. Continue to %s.'), '<a href="'.$this->System->Link('/setup/').'">'.T('setup').'</a>');
374 return $Output;
375 }
376}
Note: See TracBrowser for help on using the repository browser.