<?php class ModuleSetup extends Module { public UpdateManager $UpdateManager; function __construct(System $System) { global $DatabaseRevision; parent::__construct($System); $this->Name = 'Setup'; $this->Version = '1.0'; $this->Creator = 'Chronos'; $this->License = 'GNU/GPLv3'; $this->Description = 'Base setup module'; $this->Revision = 1; $this->Type = ModuleType::System; // Check database persistence structure $this->UpdateManager = new UpdateManager(); $this->UpdateManager->Database = &$this->Database; $this->UpdateManager->Revision = $DatabaseRevision; $this->UpdateManager->InstallMethod = 'FullInstall'; } static function Cast(Module $Module): ModuleSetup { if ($Module instanceof ModuleSetup) { return $Module; } throw new Exception('Expected ModuleSetup type but '.gettype($Module)); } function DoStart(): void { Core::Cast($this->System)->RegisterPage([''], 'PageSetupRedirect'); Core::Cast($this->System)->RegisterPage(['setup'], 'PageSetup'); } function DoStop(): void { unset($this->UpdateManager); Core::Cast($this->System)->UnregisterPage(['']); Core::Cast($this->System)->UnregisterPage(['setup']); } function CheckState(): bool { return $this->Database->Connected() and $this->UpdateManager->IsInstalled() and $this->UpdateManager->IsUpToDate(); } function DoUpgrade(): string { $Updates = new Updates(); $this->UpdateManager->Trace = $Updates->Get(); $Output = $this->UpdateManager->Upgrade(); return $Output; } } class PageSetup extends Page { public UpdateManager $UpdateManager; public array $ConfigDefinition; public array $Config; public int $DatabaseRevision; public int $Revision; public string $ConfigDir; public array $YesNo; function __construct(System $System) { parent::__construct($System); $this->Title = T('Application setup'); //$this->ParentClass = 'PageSetupRedirect'; $this->ConfigDir = dirname(dirname(dirname(__FILE__))).'/Config'; $this->YesNo = array(false => T('No'), true => T('Yes')); } function LoginPanel(): string { $Output = '<h3>PÅ™ihlášenà k instalaci</h3>'. '<form action="?" method="post">'. '<table>'. '<tr><td>Systémové heslo:</td><td> <input type="password" name="SystemPassword" value=""/></td></tr>'. '</table>'. '<input type="submit" name="login" value="'.T('Login').'"/>'. '</form>'; return $Output; } function ControlPanel(): string { $Output = '<h3>'.T('Instance management').'</h3>'; $Output .= 'Je pÅ™ipojenà k databázi: '.$this->YesNo[$this->UpdateManager->Database->Connected()].'<br/>'; if ($this->UpdateManager->Database->Connected()) { $Output .= 'Je instalováno: '.$this->YesNo[$this->UpdateManager->IsInstalled()].'<br/>'; if ($this->UpdateManager->IsInstalled()) $Output .= 'Je aktuálnÃ: '.$this->YesNo[$this->UpdateManager->IsUpToDate()].'<br/>'. 'Verze databáze: '.$this->UpdateManager->GetDbVersion().'<br/>'; $Output .= 'Verze databáze kódu: '.$this->UpdateManager->Revision.'<br/>'; if ($this->UpdateManager->IsInstalled()) { if (!$this->UpdateManager->IsUpToDate()) $Output .= '<a href="?action=upgrade">'.T('Upgrade').'</a> '; $Output .= '<a href="?action=insert_sample_data">Vložit vzorová data</a> '; $Output .= '<a href="?action=reload-modules">Obnovit seznam modulů</a> '; $Output .= '<a href="?action=uninstall">Odinstalovat</a> '; $Output .= '<a href="'.$this->System->Link('/modules/').'">Správa modulů</a> '; $Output .= '<a href="?action=models">PÅ™egenerovat modely</a> '; } else $Output .= '<a href="?action=install">Instalovat</a> '; } $Output .= '<a href="?action=configure">Nastavit</a> '; $Output .= '<a href="?action=logout">Odhlásit</a> '; $Output .= '<a href="'.$this->System->Link('/').'">'.T('Go to main page').'</a> '; $Output .= ''; return $Output; } function Show(): string { global $ConfigDefinition, $DatabaseRevision, $Config, $Updates; $this->UpdateManager = ModuleSetup::Cast($this->System->GetModule('Setup'))->UpdateManager; $DefaultConfig = new DefaultConfig(); $this->ConfigDefinition = $DefaultConfig->Get(); $this->DatabaseRevision = $DatabaseRevision; $this->Config = &$Config; $Output = ''; if (isset($this->Config)) { if (!array_key_exists('SystemPassword', $_SESSION)) $_SESSION['SystemPassword'] = ''; if (array_key_exists('login', $_POST)) $_SESSION['SystemPassword'] = $_POST['SystemPassword']; if (sha1($_SESSION['SystemPassword']) != $this->Config['SystemPassword']) { $Output .= $this->LoginPanel(); } else { if (array_key_exists('action', $_GET)) $Action = $_GET['action']; else $Action = ''; if ($Action == 'logout') { $_SESSION['SystemPassword'] = ''; $Output .= 'Odhlášen'; $Output .= $this->LoginPanel(); } else if ($Action == 'models') { $this->System->FormManager->UpdateSQLMeta(); } else if ($Action == 'upgrade') { $Output .= '<h3>PovýšenÃ</h3>'; try { $Output .= ModuleSetup::Cast($this->System->GetModule('Setup'))->DoUpgrade(); $this->System->ModuleManager->UpgradeAll(array(ModuleCondition::System)); } catch (Exception $E) { $Output .= $this->SystemMessage('Chyba aktualizace', 'DoÅ¡lo k chybÄ› v SQL dotazu pÅ™i aktualizaci: <br/>'.$E->getMessage()); } $Output .= $this->ControlPanel(); } else if ($Action == 'install') { $Output .= '<h3>Instalace systém</h3>'; global $DatabaseRevision; $this->Database->query("CREATE TABLE IF NOT EXISTS `".$this->UpdateManager->VersionTable."` (". '`Id` int(11) NOT NULL AUTO_INCREMENT, '. '`Revision` int(11) NOT NULL, '. 'PRIMARY KEY (`Id`) '. ') ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;'); $DbResult = $this->Database->select($this->UpdateManager->VersionTable, 'Id'); if ($DbResult->num_rows == 0) { $this->Database->query("INSERT INTO `".$this->UpdateManager->VersionTable. "` (`Id`, `Revision`) VALUES (1, ".$DatabaseRevision.");"); } $this->System->ModuleManager->InstallAll(array(ModuleCondition::System)); $this->System->ModuleManager->LoadModules(); $this->System->ModuleManager->SaveState(); //$Output .= ModuleSetup::Cast($this->System->GetModule('Setup'))->Upgrade(); $Output .= $this->ControlPanel(); } else if ($Action == 'uninstall') { $Output .= '<h3>Odinstalace vÅ¡e</h3>'; $this->System->ModuleManager->UninstallAll(array(ModuleCondition::All)); $this->Database->query('DROP TABLE IF EXISTS `'.$this->UpdateManager->VersionTable.'`'); $Output .= $this->ControlPanel(); } else if ($Action == 'reload-modules') { $Output .= '<h3>ZnovunaÄtenà seznamu modulů</h3>'; $this->System->ModuleManager->LoadModules(); $this->System->ModuleManager->SaveState(); $Output .= $this->ControlPanel(); } else if ($Action == 'insert_sample_data') { $Output .= '<h3>Vloženà vzorových dat</h3>'; $this->System->ModuleManager->Perform(array(ModuleAction::InsertSampleData), array(ModuleCondition::Installed)); $Output .= $this->ControlPanel(); } else if ($Action == 'configure_save') { $Output .= $this->ConfigSave($this->Config); $Output .= $this->ControlPanel(); } else if ($Action == 'configure') { $Output .= $this->PrepareConfig($this->Config); } else { $Output .= $this->ControlPanel(); } } } else { if (array_key_exists('configure_save', $_POST)) { $Output .= $this->ConfigSave(array()); $Output .= 'PokraÄujte k pÅ™ihlášenà <a href="">zde</a>'; } else { $Output .= $this->PrepareConfig(array()); } } return $Output; } function PrepareConfig($Config): string { $Output = ''; if (!file_exists($this->ConfigDir.'/Config.php') and !is_writable($this->ConfigDir)) $Output .= 'VarovánÃ: KonfiguraÄnà soubor nebude možné zapsat, protože složka "'.$this->ConfigDir.'" nenà povolená pro zápis!'; if (file_exists($this->ConfigDir.'/Config.php') and !is_writable($this->ConfigDir.'/Config.php')) $Output .= 'VarovánÃ: KonfiguraÄnà soubor nebude možné zapsat, protože soubor "'.$this->ConfigDir.'/Config.php" nenà povolen pro zápis!'; $Output .= '<h3>Nastavenà systému</h3>'. '<form action="?action=configure_save" method="post">'. '<table>'; foreach ($this->ConfigDefinition as $Def) { $PathParts = explode('/', $Def['Name']); $TempConfig = &$Config; foreach ($PathParts as $Part) if (array_key_exists($Part, $TempConfig)) { $TempConfig = &$TempConfig[$Part]; } if (!is_array($TempConfig)) $Value = $TempConfig; else $Value = $Def['Default']; $Output .= '<tr><td>'.$Def['Title'].'</td><td>'; if ($Def['Type'] == 'String') $Output .= '<input type="text" name="'.$Def['Name'].'" value="'.$Value.'"/>'; if ($Def['Type'] == 'Password') $Output .= '<input type="password" name="'.$Def['Name'].'"/>'; if ($Def['Type'] == 'PasswordEncoded') $Output .= '<input type="password" name="'.$Def['Name'].'"/>'; if ($Def['Type'] == 'Integer') $Output .= '<input type="text" name="'.$Def['Name'].'" value="'.$Value.'"/>'; if ($Def['Type'] == 'Float') $Output .= '<input type="text" name="'.$Def['Name'].'" value="'.$Value.'"/>'; if ($Def['Type'] == 'Boolean') $Output .= '<input type="text" name="'.$Def['Name'].'" value="'.$Value.'"/>'; if ($Def['Type'] == 'Array') $Output .= '<input type="text" name="'.$Def['Name'].'" value="'.implode(',', $Value).'"/>'; } $Output .= '</td></tr>'. '<tr><td colspan="2"><input type="submit" name="configure_save" value="'.T('Save').'"/></td></tr>'. '</table>'. '</form>'; return $Output; } function ConfigSave($DefaultConfig) { $Config = $DefaultConfig; foreach ($this->ConfigDefinition as $Def) { $Value = null; if ($Def['Type'] == 'String') if (array_key_exists($Def['Name'], $_POST)) $Value = $_POST[$Def['Name']]; if ($Def['Type'] == 'Password') if (array_key_exists($Def['Name'], $_POST) and ($_POST[$Def['Name']] != '')) $Value = $_POST[$Def['Name']]; if ($Def['Type'] == 'PasswordEncoded') if (array_key_exists($Def['Name'], $_POST) and ($_POST[$Def['Name']] != '')) $Value = sha1($_POST[$Def['Name']]); if ($Def['Type'] == 'Integer') if (array_key_exists($Def['Name'], $_POST)) $Value = $_POST[$Def['Name']]; if ($Def['Type'] == 'Float') if (array_key_exists($Def['Name'], $_POST)) $Value = $_POST[$Def['Name']]; if ($Def['Type'] == 'Boolean') if (array_key_exists($Def['Name'], $_POST)) $Value = $_POST[$Def['Name']]; if ($Def['Type'] == 'Array') if (array_key_exists($Def['Name'], $_POST)) $Value = explode(',', $_POST[$Def['Name']]); if (!is_null($Value)) { $PathParts = explode('/', $Def['Name']); $TempConfig = &$Config; foreach ($PathParts as $Part) { $TempConfig = &$TempConfig[$Part]; } if (!is_array($TempConfig)) $TempConfig = $Value; else $Value = $Def['Default']; } } $ConfigText = $this->CreateConfig($Config); file_put_contents($this->ConfigDir.'/Config.php', $ConfigText); $Output = 'Konfigurace nastavena<br/>'; return $Output; } function CreateConfig($Config): string { $Output = "<?php\n\n". "\$IsDeveloper = array_key_exists('REMOTE_ADDR', \$_SERVER) and in_array(\$_SERVER['REMOTE_ADDR'], array('127.0.0.1'));\n\n"; foreach ($this->ConfigDefinition as $Def) { $PathParts = explode('/', $Def['Name']); $Output .= "\$Config"; foreach ($PathParts as $Part) $Output .= "['".$Part."']"; $TempConfig = &$Config; $Output .= ' = '; foreach ($PathParts as $Part) if (array_key_exists($Part, $TempConfig)) { $TempConfig = &$TempConfig[$Part]; } if (!is_array($TempConfig)) $Value = $TempConfig; else $Value = $Def['Default']; if ($Def['Type'] == 'Array') { $Output .= ' array('; foreach ($Value as $Index => $Item) $Output .= '\''.$Item.'\', '; $Output .= ')'; } else $Output .= "'".$Value."'"; $Output .= ";\n"; } $Output .= "\n\n"; return $Output; } } class PageSetupRedirect extends Page { function Show(): string { $Output = ''; if (!$this->Database->Connected()) { $Output .= T('Can\'t connect to database.').'<br>'; } else { if (!ModuleSetup::Cast($this->System->GetModule('Setup'))->UpdateManager->IsInstalled()) { $Output .= T('System requires database initialization.').'<br>'; } else if (!ModuleSetup::Cast($this->System->GetModule('Setup'))->UpdateManager->IsUpToDate()) { $Output .= T('System requires database upgrade.').'<br>'; } } $Output .= sprintf(T('Front page was not configured. Continue to %s.'), '<a href="'.$this->System->Link('/setup/').'">'.T('setup').'</a>'); return $Output; } }