diff --git a/.editorconfig b/.editorconfig index 2cbf3b5627..e6aef58ce1 100644 --- a/.editorconfig +++ b/.editorconfig @@ -8,7 +8,7 @@ insert_final_newline = true indent_style = space # HTML, SCSS, JS, YAML and JSON files -[{*.html,*.scss,*.js,*.json,*.yml}] +[{*.html,*.twig,*.scss,*.js,*.json,*.yml}] indent_size = 2 # PHP files diff --git a/phpmyfaq/assets/src/configuration/index.js b/phpmyfaq/assets/src/configuration/index.js new file mode 100644 index 0000000000..c2b5197423 --- /dev/null +++ b/phpmyfaq/assets/src/configuration/index.js @@ -0,0 +1,2 @@ +export * from './setup'; +export * from './update'; diff --git a/phpmyfaq/assets/src/configuration/setup.js b/phpmyfaq/assets/src/configuration/setup.js new file mode 100644 index 0000000000..affb6b1950 --- /dev/null +++ b/phpmyfaq/assets/src/configuration/setup.js @@ -0,0 +1,73 @@ +/** + * Setup functions + * + * This Source Code Form is subject to the terms of the Mozilla Public License, + * v. 2.0. If a copy of the MPL was not distributed with this file, You can + * obtain one at https://mozilla.org/MPL/2.0/. + * + * @package phpMyFAQ + * @author Thorsten Rinne + * @copyright 2015-2023 phpMyFAQ Team + * @license http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0 + * @link https://www.phpmyfaq.de + * @since 2015-12-24 + */ + +import { insertAfter } from '../utils'; + +export const selectDatabaseSetup = (event) => { + const database = document.getElementById('dbdatafull'); + const databasePort = document.getElementById('sql_port'); + const sqlite = document.getElementById('dbsqlite'); + + switch (event.target.value) { + case 'mysqli': + databasePort.value = 3306; + sqlite.className = 'd-none'; + database.className = 'd-block'; + break; + case 'pgsql': + databasePort.value = 5432; + sqlite.className = 'd-none'; + database.className = 'd-block'; + break; + case 'sqlsrv': + databasePort.value = 1433; + sqlite.className = 'd-none'; + database.className = 'd-block'; + break; + case 'sqlite3': + sqlite.className = 'd-block'; + database.className = 'd-none'; + break; + default: + sqlite.className = 'd-none'; + database.className = 'd-block'; + break; + } +}; + +export const addElasticsearchServerInput = () => { + const wrapper = document.getElementById('elasticsearch-server-wrapper'); + const input = document.createElement('input'); + + // Set attributes for input + input.className = 'form-control'; + input.className += ' mt-1'; + input.type = 'text'; + input.name = 'elasticsearch_server[]'; + input.placeholder = `127.0.0.1:9200`; + + insertAfter(wrapper, input); +}; + +export const stepIndicator = (step) => { + // This function removes the "active" class of all steps... + let i, + steps = document.getElementsByClassName('stepIndicator'); + for (i = 0; i < steps.length; i++) { + steps[i].className = steps[i].className.replace(' active', ''); + } + //... and adds the "active" class on the current step: + steps[step].className += ' active'; +}; diff --git a/phpmyfaq/assets/src/setup.test.js b/phpmyfaq/assets/src/configuration/setup.test.js similarity index 100% rename from phpmyfaq/assets/src/setup.test.js rename to phpmyfaq/assets/src/configuration/setup.test.js diff --git a/phpmyfaq/assets/src/configuration/update.js b/phpmyfaq/assets/src/configuration/update.js new file mode 100644 index 0000000000..97086dd6bc --- /dev/null +++ b/phpmyfaq/assets/src/configuration/update.js @@ -0,0 +1,25 @@ +/** + * Update functions + * + * This Source Code Form is subject to the terms of the Mozilla Public License, + * v. 2.0. If a copy of the MPL was not distributed with this file, You can + * obtain one at https://mozilla.org/MPL/2.0/. + * + * @package phpMyFAQ + * @author Thorsten Rinne + * @copyright 2023 phpMyFAQ Team + * @license http://www.mozilla.org/MPL/2.0/ Mozilla Public License Version 2.0 + * @link https://www.phpmyfaq.de + * @since 2023-10-22 + */ + +export const handleUpdateNextStepButton = () => { + const nextStepButton = document.getElementById('phpmyfaq-update-next-step'); + + if (nextStepButton) { + nextStepButton.addEventListener('click', (event) => { + event.preventDefault(); + window.location.replace('./update.php?step=2'); + }); + } +}; diff --git a/phpmyfaq/assets/src/setup.js b/phpmyfaq/assets/src/setup.js index 119cdfea48..a0b8e0c477 100644 --- a/phpmyfaq/assets/src/setup.js +++ b/phpmyfaq/assets/src/setup.js @@ -13,65 +13,8 @@ * @since 2015-12-24 */ -import { insertAfter } from './utils'; import { handlePasswordToggle } from './utils'; - -export const selectDatabaseSetup = (event) => { - const database = document.getElementById('dbdatafull'); - const databasePort = document.getElementById('sql_port'); - const sqlite = document.getElementById('dbsqlite'); - - switch (event.target.value) { - case 'mysqli': - databasePort.value = 3306; - sqlite.className = 'd-none'; - database.className = 'd-block'; - break; - case 'pgsql': - databasePort.value = 5432; - sqlite.className = 'd-none'; - database.className = 'd-block'; - break; - case 'sqlsrv': - databasePort.value = 1433; - sqlite.className = 'd-none'; - database.className = 'd-block'; - break; - case 'sqlite3': - sqlite.className = 'd-block'; - database.className = 'd-none'; - break; - default: - sqlite.className = 'd-none'; - database.className = 'd-block'; - break; - } -}; - -export const addElasticsearchServerInput = () => { - const wrapper = document.getElementById('elasticsearch-server-wrapper'); - const input = document.createElement('input'); - - // Set attributes for input - input.className = 'form-control'; - input.className += ' mt-1'; - input.type = 'text'; - input.name = 'elasticsearch_server[]'; - input.placeholder = `127.0.0.1:9200`; - - insertAfter(wrapper, input); -}; - -const stepIndicator = (step) => { - // This function removes the "active" class of all steps... - let i, - steps = document.getElementsByClassName('stepIndicator'); - for (i = 0; i < steps.length; i++) { - steps[i].className = steps[i].className.replace(' active', ''); - } - //... and adds the "active" class on the current step: - steps[step].className += ' active'; -}; +import { addElasticsearchServerInput, selectDatabaseSetup, stepIndicator } from './configuration'; document.addEventListener('DOMContentLoaded', () => { 'use strict'; @@ -112,7 +55,9 @@ document.addEventListener('DOMContentLoaded', () => { function showTab(n) { const currentStep = document.getElementsByClassName('step'); - currentStep[n].style.display = 'block'; + if (currentStep) { + currentStep[n].style.display = 'block'; + } const prevButton = document.getElementById('prevBtn'); const nextButton = document.getElementById('nextBtn'); diff --git a/phpmyfaq/assets/src/update.js b/phpmyfaq/assets/src/update.js new file mode 100644 index 0000000000..4614816b39 --- /dev/null +++ b/phpmyfaq/assets/src/update.js @@ -0,0 +1,3 @@ +import { handleUpdateNextStepButton } from './configuration'; + +handleUpdateNextStepButton(); diff --git a/phpmyfaq/assets/templates/setup/index.twig b/phpmyfaq/assets/templates/setup/index.twig new file mode 100644 index 0000000000..e69de29bb2 diff --git a/phpmyfaq/assets/templates/setup/update.twig b/phpmyfaq/assets/templates/setup/update.twig new file mode 100644 index 0000000000..a48a63a8af --- /dev/null +++ b/phpmyfaq/assets/templates/setup/update.twig @@ -0,0 +1,72 @@ + + + + + phpMyFAQ {{ newVersion }} Update + + + + + + + + + + +
+
+
+
+

phpMyFAQ {{ newVersion }} Update

+
+

+ Did you already read our documentation + carefully before starting the phpMyFAQ setup? +

+
+
+ +
+ Update information + File backups + Database updates +
+ + {{ include('setup/update/step1.twig') }} + +
+
+
+ + + + + + + diff --git a/phpmyfaq/assets/templates/setup/update/step1.twig b/phpmyfaq/assets/templates/setup/update/step1.twig new file mode 100644 index 0000000000..f78ef9ad9f --- /dev/null +++ b/phpmyfaq/assets/templates/setup/update/step1.twig @@ -0,0 +1,80 @@ +
+ + + +
+
+ +
+
+ +
+
+

This update script will work only for the following versions:

+
    +
  • phpMyFAQ 3.0.x
  • +
  • phpMyFAQ 3.1.x
  • +
  • phpMyFAQ 3.2.x
  • +
+
+
+

This update script will not work for the following versions:

+
    +
  • phpMyFAQ 0.x
  • +
  • phpMyFAQ 1.x
  • +
  • phpMyFAQ 2.x
  • +
+
+
+ +
+
+ + {% if errorCheckPreUpgrade %} + + {% endif %} + + {% if configTableNotAvailable %} + + {% endif %} + + {% if installedVersionTooOld %} + + {% endif %} + + {% if isMaintenanceModeEnabled %} + + {% endif %} + +
+
+ +
+
+ +
+
+
diff --git a/phpmyfaq/setup/update.php b/phpmyfaq/setup/update.php index e09ef1fd51..4ef19bdd15 100644 --- a/phpmyfaq/setup/update.php +++ b/phpmyfaq/setup/update.php @@ -17,7 +17,6 @@ * @since 2002-01-10 */ -use phpMyFAQ\Component\Alert; use phpMyFAQ\Configuration; use phpMyFAQ\Configuration\DatabaseConfiguration; use phpMyFAQ\Database; @@ -26,6 +25,7 @@ use phpMyFAQ\Setup\Update; use phpMyFAQ\Strings; use phpMyFAQ\System; +use phpMyFAQ\Template\TwigWrapper; use Symfony\Component\HttpFoundation\RedirectResponse; const COPYRIGHT = '© 2001-2023 phpMyFAQ Team'; @@ -43,13 +43,16 @@ Strings::init(); -$step = Filter::filterInput(INPUT_GET, 'step', FILTER_VALIDATE_INT, 1); -$version = Filter::filterInput(INPUT_POST, 'version', FILTER_SANITIZE_SPECIAL_CHARS); -$query = []; +$step = Filter::filterInput(INPUT_GET, 'next-step', FILTER_VALIDATE_INT, 1); +$version = Filter::filterInput(INPUT_POST, 'installed-version', FILTER_SANITIZE_SPECIAL_CHARS); $system = new System(); $faqConfig = Configuration::getConfigurationInstance(); + $update = new Update($system, $faqConfig); +$update->setVersion(System::getVersion()); + +$installedVersion = $faqConfig->getVersion(); if (!$update->checkDatabaseFile()) { $redirect = new RedirectResponse('./index.php'); @@ -62,153 +65,48 @@ $dbConfig = new DatabaseConfiguration(PMF_ROOT_DIR . '/content/core/config/database.php'); } -?> - - - - - phpMyFAQ <?= System::getVersion(); ?> Update - - - - - - - - - - - -
-
-
-
-

phpMyFAQ

-
-

- Did you already read our documentation - carefully before starting the phpMyFAQ setup? -

-
-
- -
- Update information - File backups - Database updates -
-getVersion(); +$twig = new TwigWrapper('../assets/templates'); +$template = $twig->loadTemplate('./setup/update.twig'); -$update = new Update($system, $faqConfig); -$update->setVersion(System::getVersion()); +$templateVars = [ + 'newVersion' => System::getVersion(), + 'installedVersion' => $installedVersion, + 'currentYear' => date('Y'), + 'documentationUrl' => System::getDocumentationUrl(), + 'configTableNotAvailable' => $update->isConfigTableAvailable($faqConfig->getDb()), + 'nextStepButtonEnabled' => $update->checkMaintenanceMode() ? '' : 'disabled', +]; +// Check hard requirements try { $update->checkPreUpgrade($dbConfig->getType()); } catch (Exception $e) { - echo Alert::danger('ad_entryins_fail', $e->getMessage()); + $templateVars = [ + ...$templateVars, + 'errorCheckPreUpgrade' => true, + 'errorMessagePreUpgrade' => $e->getMessage(), + ]; } -if ($update->isConfigTableAvailable($faqConfig->getDb())) { - echo Alert::danger('ad_entryins_fail'); -} -/**************************** STEP 1 OF 3 ***************************/ -if ($step === 1) { ?> -
- - -
-
- -
-
- -
-
-

This update script will work only for the following versions:

-
    -
  • phpMyFAQ 3.0.x
  • -
  • phpMyFAQ 3.1.x
  • -
  • phpMyFAQ 3.2.x
  • -
-
-
-

This update script will not work for the following versions:

-
    -
  • phpMyFAQ 0.x
  • -
  • phpMyFAQ 1.x
  • -
  • phpMyFAQ 2.x
  • -
-
-
- -
-
- checkMinimumUpdateVersion($installedVersion)) { + $templateVars = [ + ...$templateVars, + 'installedVersionTooOld' => true, + ]; +} - // - // We only support updates from 3.0+ - // - if (!version_compare($version, '3.0.0', '>')) { - echo ''; - } - - // - // Updates only possible if maintenance mode is enabled - // - if (!$faqConfig->get('main.maintenanceMode')) { - echo ''; - $updateDisabled = 'disabled'; - } else { - $updateDisabled = ''; - } - ?> -

- -

-
-
-
- checkMaintenanceMode()) { + $templateVars = [ + ...$templateVars, + 'isMaintenanceModeEnabled' => true, + ]; } +echo $template->render($templateVars); + /**************************** STEP 2 OF 3 ***************************/ if ($step == 2) { $checkDatabaseSetupFile = $checkLdapSetupFile = $checkElasticsearchSetupFile = true; diff --git a/phpmyfaq/src/phpMyFAQ/Setup.php b/phpmyfaq/src/phpMyFAQ/Setup.php index f9a13c4db5..2dc105203f 100644 --- a/phpmyfaq/src/phpMyFAQ/Setup.php +++ b/phpmyfaq/src/phpMyFAQ/Setup.php @@ -34,8 +34,30 @@ public function checkMinimumPhpVersion(): bool return version_compare(PHP_VERSION, System::VERSION_MINIMUM_PHP) > 0; } + /** + * We only support updates from 3.0.0 and later. + * + * @param string $version + * @return bool + */ + public function checkMinimumUpdateVersion(string $version): bool + { + return version_compare($version, '3.0.0', '>'); + } + + /** + * Updates only possible if maintenance mode is enabled. + * + * @return bool + */ + public function checkMaintenanceMode(): bool + { + return Configuration::getConfigurationInstance()->get('main.maintenanceMode'); + } + /** * Checks if the database file exists. + * * @return bool */ public function checkDatabaseFile(): bool diff --git a/webpack.config.js b/webpack.config.js index 2e703f3657..c62811db7a 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -8,6 +8,7 @@ module.exports = { backend: './phpmyfaq/admin/assets/src/index.js', frontend: './phpmyfaq/assets/src/frontend.js', setup: './phpmyfaq/assets/src/setup.js', + update: './phpmyfaq/assets/src/update.js', styles: './phpmyfaq/assets/themes/default/scss/style.scss', admin: './phpmyfaq/admin/assets/scss/style.scss', },