Skip to content

Commit

Permalink
First draft of refactoring install process with a progress display sy…
Browse files Browse the repository at this point in the history
…stem
  • Loading branch information
Pierstoval committed Nov 13, 2024
1 parent 608ec96 commit 1894444
Show file tree
Hide file tree
Showing 14 changed files with 588 additions and 102 deletions.
2 changes: 2 additions & 0 deletions dependency_injection/legacyConfigProviders.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
use Glpi\Config\LegacyConfigurators\CustomObjectsAutoloader;
use Glpi\Config\LegacyConfigurators\CustomObjectsBootstrap;
use Glpi\Config\LegacyConfigurators\InitializePlugins;
use Glpi\Config\LegacyConfigurators\InstallTweaks;
use Glpi\Config\LegacyConfigurators\ProfilerStart;
use Glpi\Config\LegacyConfigurators\SessionConfig;
use Glpi\Config\LegacyConfigurators\SessionStart;
Expand All @@ -65,6 +66,7 @@

$services->set(ProfilerStart::class)->tag($tagName, ['priority' => 180]);
$services->set(SessionStart::class)->tag($tagName, ['priority' => 170]);
$services->set(InstallTweaks::class)->tag($tagName, ['priority' => 165]);
$services->set(StandardIncludes::class)->tag($tagName, ['priority' => 160]);
$services->set(CleanPHPSelfParam::class)->tag($tagName, ['priority' => 150]);
$services->set(SessionConfig::class)->tag($tagName, ['priority' => 130]);
Expand Down
1 change: 1 addition & 0 deletions dependency_injection/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
$services->load('Glpi\Controller\\', $projectDir . '/src/Glpi/Controller');
$services->load('Glpi\Http\\', $projectDir . '/src/Glpi/Http');
$services->load('Glpi\DependencyInjection\\', $projectDir . '/src/Glpi/DependencyInjection');
$services->load('Glpi\Progress\\', $projectDir . '/src/Glpi/Progress');

/**
* Override Symfony's logger.
Expand Down
44 changes: 26 additions & 18 deletions install/install.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ function header_html($etape)
echo Html::script("lib/fuzzy.js");
echo Html::script("js/common.js");
echo Html::script("js/glpi_dialog.js");
echo Html::script("js/glpi_install.js");

// CSS
echo Html::css('lib/tabler.css');
Expand Down Expand Up @@ -227,7 +228,6 @@ public function __construct($dbh)
//Step 4 Create and fill database.
function step4($databasename, $newdatabasename)
{

$host = $_SESSION['db_access']['host'];
$user = $_SESSION['db_access']['user'];
$password = $_SESSION['db_access']['password'];
Expand Down Expand Up @@ -297,7 +297,7 @@ public function __construct($dbh)

if (
!$link->select_db($databasename)
&& !$link->query("CREATE DATABASE IF NOT EXISTS `" . $databasename . "`")
&& !$link->query("CREATE DATABASE IF NOT EXISTS `" . $databasename . "`;")
) {
echo __s('Error in creating database!');
echo "<br>" . sprintf(__s('The server answered: %s'), htmlescape($link->error));
Expand Down Expand Up @@ -328,23 +328,21 @@ public function __construct($dbh)
);

if ($success) {
echo "<p>" . __s('Initializing database tables and default data...') . "</p>";
try {
Toolbox::createSchema($_SESSION["glpilanguage"]);
} catch (\Throwable $e) {
echo "<p>"
. sprintf(
__s('An error occurred during the database initialization. The error was: %s'),
'<br />' . htmlescape($e->getMessage())
)
. "</p>";
@unlink(GLPI_CONFIG_DIR . '/config_db.php'); // try to remove the config file, to be able to restart the process
$prev_form($host, $user, $password);
return;
}
echo "<p>" . __s('OK - database was initialized') . "</p>";
echo "<p>" . __('Initializing database tables and default data...') . "</p>";

$alert_name = 'glpi_install_messages_container';
ob_start();
$next_form();
$next = ob_get_clean();

echo \sprintf('<div id="%s"></div>', $alert_name);
echo \sprintf(
'<script defer>startDatabaseInstall("%s", "%s");</script>',
$alert_name,
str_replace(["\n", '"'], ['', '\\"'], $next),
);

$prev_form($host, $user, $password);
} else { // can't create config_db file
echo "<p>" . __s('Impossible to write the database setup file') . "</p>";
$prev_form($host, $user, $password);
Expand Down Expand Up @@ -416,6 +414,7 @@ function step8()
]
);

$_SESSION['is_installing'] = false;
Session::destroy(); // Remove session data (debug mode for instance) set by web installation

TemplateRenderer::getInstance()->display('install/step8.html.twig');
Expand All @@ -424,6 +423,7 @@ function step8()

function update1($dbname)
{
$_SESSION['is_installing'] = false;

$host = $_SESSION['db_access']['host'];
$user = $_SESSION['db_access']['user'];
Expand Down Expand Up @@ -478,11 +478,17 @@ function update1($dbname)
Session::start();
error_reporting(0); // we want to check system before affraid the user.

/** @var array $CFG_GLPI */
global $CFG_GLPI;

if (isset($_POST["language"]) && isset($CFG_GLPI["languages"][$_POST["language"]])) {
$_SESSION["glpilanguage"] = $_POST["language"];
}

Session::loadLanguage('', false);
if (!isset($_SESSION["glpilanguage"])) {
$_SESSION["glpilanguage"] = Session::getPreferredLanguage();
}
Session::loadLanguage(Session::getLanguage(), false);

/**
* @since 0.84.2
Expand Down Expand Up @@ -525,6 +531,8 @@ function checkConfigFile()
$_POST["db_pass"] = rawurldecode($_POST["db_pass"]);
}

$_SESSION['is_installing'] = true;

switch ($_POST["install"]) {
case "lang_select": // lang ok, go accept licence
checkConfigFile();
Expand Down
133 changes: 133 additions & 0 deletions js/glpi_install.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/**
* ---------------------------------------------------------------------
*
* GLPI - Gestionnaire Libre de Parc Informatique
*
* http://glpi-project.org
*
* @copyright 2015-2024 Teclib' and contributors.
* @licence https://www.gnu.org/licenses/gpl-3.0.html
*
* ---------------------------------------------------------------------
*
* LICENSE
*
* This file is part of GLPI.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* ---------------------------------------------------------------------
*/

let request_running = false;

function startDatabaseInstall(message_element_id, success_html)
{
const message_element = document.getElementById(message_element_id);
if (!message_element) {
const alert = document.createElement('p');
alert.innerText = 'Could not load HtmlElement to append messages to.';
document.body.appendChild(alert);
throw new Error(alert.innerText);
}

const single_message_element = document.createElement('p');
const msg_list_element = document.createElement('div');
message_element.appendChild(msg_list_element);
msg_list_element.appendChild(single_message_element);

function message(text) {
const alert = document.createElement('p');
alert.innerHTML = text;
msg_list_element.appendChild(alert);
}
function queries_message(amount) {
single_message_element.innerHTML = `Process: ${amount}`;
}

request_running = true;

setTimeout(() => {
checkProgress(queries_message);
}, 1500);


fetch("/install/step7/start_db_inserts", {
method: 'POST',
headers: {
'Content-Type': 'text/plain'
},
})
.then((res) => res.text())
.then((text) => {
if (text && text.trim().length) {
message(`Error:\n${text}`);
} else {
message(success_html);
queries_message('✅');
}
})
.finally(() => request_running = false);
}

let previous_count = 0;
let previous_state_commutator = 1;

function checkProgress(message_fn)
{
if (!request_running) {
return;
}

setTimeout(() => {

fetch("/install/step7/check_progress", {
method: 'POST',
})
.then((res) => {
if (res.status >= 300) {
throw new Error('Invalid response from progress check.');
}
return res.json();
})
.then((json) => {
if (!request_running) {
return;
}

if (json && json.current) {
message_fn("Data received:");
let msg = json.current.toString();

msg += (new Array(previous_state_commutator)).fill('.').join('');
previous_state_commutator ++;
if (previous_state_commutator >= 4) {
previous_state_commutator = 1;
}

previous_count = json.current;

message_fn(msg);

return checkProgress(message_fn);
} else {
message_fn(`Error:\n${json}`);
}
})
.catch((err) => {
return message_fn(err.message || err.toString());
});

}, 500);
}
32 changes: 20 additions & 12 deletions src/DBmysql.php
Original file line number Diff line number Diff line change
Expand Up @@ -1013,18 +1013,7 @@ public function isSlave()
*/
public function runFile($path)
{
$script = fopen($path, 'r');
if (!$script) {
return false;
}
$sql_query = @fread(
$script,
@filesize($path)
) . "\n";
$sql_query = html_entity_decode($sql_query, ENT_COMPAT, 'UTF-8');

$sql_query = $this->removeSqlRemarks($sql_query);
$queries = preg_split('/;\s*$/m', $sql_query);
$queries = $this->getQueriesFromFile($path);

foreach ($queries as $query) {
$query = trim($query);
Expand All @@ -1044,6 +1033,25 @@ public function runFile($path)
return true;
}

/**
* @internal
*
* @return array<string>
*/
public function getQueriesFromFile(string $path): array
{
$script = fopen($path, 'r');
if (!$script) {
return [];
}
$sql_query = @fread($script, @filesize($path)) . "\n";
$sql_query = html_entity_decode($sql_query, ENT_COMPAT, 'UTF-8');

$sql_query = $this->removeSqlRemarks($sql_query);

return preg_split('/;\s*$/m', $sql_query);
}

/**
* Instanciate a Simple DBIterator
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
{
public function execute(): void
{
if (!DBConnection::isDbAvailable()) {
if (isset($_SESSION['is_installing']) || !DBConnection::isDbAvailable()) {
// Requires the database to be available.
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
{
public function execute(): void
{
if (!DBConnection::isDbAvailable()) {
if (isset($_SESSION['is_installing']) || !DBConnection::isDbAvailable()) {
// Requires the database to be available.
return;
}
Expand Down
61 changes: 61 additions & 0 deletions src/Glpi/Config/LegacyConfigurators/InstallTweaks.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

/**
* ---------------------------------------------------------------------
*
* GLPI - Gestionnaire Libre de Parc Informatique
*
* http://glpi-project.org
*
* @copyright 2015-2024 Teclib' and contributors.
* @licence https://www.gnu.org/licenses/gpl-3.0.html
*
* ---------------------------------------------------------------------
*
* LICENSE
*
* This file is part of GLPI.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* ---------------------------------------------------------------------
*/

namespace Glpi\Config\LegacyConfigurators;

use Glpi\Config\ConfigProviderHasRequestTrait;
use Glpi\Config\ConfigProviderWithRequestInterface;
use Glpi\Config\LegacyConfigProviderInterface;

final class InstallTweaks implements LegacyConfigProviderInterface, ConfigProviderWithRequestInterface
{
use ConfigProviderHasRequestTrait;

public function execute(): void
{
$request = $this->getRequest();

if (!str_starts_with($request->getPathInfo(), '/install/')) {
return;
}

/**
* @var array $CFG_GLPI
*/
global $CFG_GLPI;

$CFG_GLPI['url_base'] = $request->getBasePath();
\Config::detectRootDoc();
}
}
Loading

0 comments on commit 1894444

Please sign in to comment.