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