diff --git a/.phpstan-baseline.php b/.phpstan-baseline.php
index 0e2f15916a4..96896ab728f 100644
--- a/.phpstan-baseline.php
+++ b/.phpstan-baseline.php
@@ -2437,18 +2437,6 @@
'count' => 1,
'path' => __DIR__ . '/src/Glpi/Console/Application.php',
];
-$ignoreErrors[] = [
- 'message' => '#^Call to function property_exists\\(\\) with \\$this\\(Glpi\\\\Console\\\\Application\\) and \'db\' will always evaluate to true\\.$#',
- 'identifier' => 'function.alreadyNarrowedType',
- 'count' => 1,
- 'path' => __DIR__ . '/src/Glpi/Console/Application.php',
-];
-$ignoreErrors[] = [
- 'message' => '#^Property Glpi\\\\Console\\\\Application\\:\\:\\$error_handler is unused\\.$#',
- 'identifier' => 'property.unused',
- 'count' => 1,
- 'path' => __DIR__ . '/src/Glpi/Console/Application.php',
-];
$ignoreErrors[] = [
'message' => '#^Strict comparison using \\!\\=\\= between null and \'development\' will always evaluate to true\\.$#',
'identifier' => 'notIdentical.alwaysTrue',
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 60d19da3ba1..505afcf813e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -370,6 +370,7 @@ The present file will list all changes made to the project; according to the
- `Contract::showShort()`
- `DbUtils::closeDBConnections()`
- `DbUtils::regenerateTreeCompleteName()`
+- `DBConnection::displayMySQLError()`
- `DBmysql::error` property.
- `Document::getImage()`
- `Document::showUploadedFilesDropdown()`
@@ -388,6 +389,7 @@ The present file will list all changes made to the project; according to the
- `Glpi\Api\API::showDebug()`
- `Glpi\Api\API::returnSanitizedContent()`
- `Glpi\Application\ErrorHandler::handleSqlError()`
+- `Glpi\Console\Command\ForceNoPluginsOptionCommandInterface` class
- `Glpi\Dashboard\Filter::dates()`
- `Glpi\Dashboard\Filter::dates_mod()`
- `Glpi\Dashboard\Filter::itilcategory()`
diff --git a/bin/console b/bin/console
index 160c61e14f1..785e008e7a7 100755
--- a/bin/console
+++ b/bin/console
@@ -153,11 +153,5 @@ if (array_key_exists('config-dir', $options)) {
require_once dirname(__DIR__) . '/vendor/autoload.php';
$kernel = new \Glpi\Kernel\Kernel($options['env'] ?? null);
-$kernel->loadCliConsoleOnlyConfig();
-
-if (file_exists(GLPI_CONFIG_DIR . '/config_db.php')) {
- include_once GLPI_CONFIG_DIR . '/config_db.php';
-}
-
-$application = new \Glpi\Console\Application();
+$application = new \Glpi\Console\Application($kernel);
$application->run();
diff --git a/dependency_injection/legacyConfigProviders.php b/dependency_injection/legacyConfigProviders.php
index 5f8fc1ff2b9..f3156877b45 100644
--- a/dependency_injection/legacyConfigProviders.php
+++ b/dependency_injection/legacyConfigProviders.php
@@ -35,17 +35,7 @@
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
use Glpi\Config\LegacyConfigProviderInterface;
-use Glpi\Config\LegacyConfigurators\CleanPHPSelfParam;
-use Glpi\Config\LegacyConfigurators\ConfigRest;
-use Glpi\Config\LegacyConfigurators\CustomObjectsAutoloader;
-use Glpi\Config\LegacyConfigurators\CustomObjectsBootstrap;
-use Glpi\Config\LegacyConfigurators\InitializeDbConnection;
-use Glpi\Config\LegacyConfigurators\InitializePlugins;
-use Glpi\Config\LegacyConfigurators\LoadLegacyConfiguration;
-use Glpi\Config\LegacyConfigurators\ProfilerStart;
-use Glpi\Config\LegacyConfigurators\SessionConfig;
-use Glpi\Config\LegacyConfigurators\SessionStart;
-use Glpi\Config\LegacyConfigurators\StandardIncludes;
+use Glpi\Config\LegacyConfigurators;
return static function (ContainerConfigurator $container): void {
$services = $container->services();
@@ -65,22 +55,10 @@
* ⚠ Here, ORDER of definition matters!
*/
- $services->set(ProfilerStart::class)->tag($tagName, ['priority' => 200]);
- $services->set(InitializeDbConnection::class)->tag($tagName, ['priority' => 190]);
- $services->set(LoadLegacyConfiguration::class)->tag($tagName, ['priority' => 180]);
- $services->set(SessionStart::class)->tag($tagName, ['priority' => 170]);
- $services->set(StandardIncludes::class)->tag($tagName, ['priority' => 160]);
- $services->set(CleanPHPSelfParam::class)->tag($tagName, ['priority' => 150]);
- $services->set(SessionConfig::class)->tag($tagName, ['priority' => 130]);
-
- // Must be done before plugins initialization, to allow plugin to work with concrete class names.
- $services->set(CustomObjectsAutoloader::class)->tag($tagName, ['priority' => 120]);
-
- $services->set(InitializePlugins::class)->tag($tagName, ['priority' => 110]);
-
- // Must be done after plugins initialization, to allow plugin to register new capacities.
- $services->set(CustomObjectsBootstrap::class)->tag($tagName, ['priority' => 100]);
+ $services->set(LegacyConfigurators\StandardIncludes::class)->tag($tagName, ['priority' => 160]);
+ $services->set(LegacyConfigurators\CleanPHPSelfParam::class)->tag($tagName, ['priority' => 150]);
+ $services->set(LegacyConfigurators\SessionConfig::class)->tag($tagName, ['priority' => 130]);
// FIXME: This class MUST stay at the end until the entire config is revamped.
- $services->set(ConfigRest::class)->tag($tagName, ['priority' => 10]);
+ $services->set(LegacyConfigurators\ConfigRest::class)->tag($tagName, ['priority' => 10]);
};
diff --git a/dependency_injection/services.php b/dependency_injection/services.php
index a7df2ee87a0..4aaeb34e507 100644
--- a/dependency_injection/services.php
+++ b/dependency_injection/services.php
@@ -57,6 +57,7 @@
$services->load('Glpi\Config\\', $projectDir . '/src/Glpi/Config');
$services->load('Glpi\Controller\\', $projectDir . '/src/Glpi/Controller');
$services->load('Glpi\Http\\', $projectDir . '/src/Glpi/Http');
+ $services->load('Glpi\Kernel\\Listener\\', $projectDir . '/src/Glpi/Kernel/Listener');
$services->load('Glpi\DependencyInjection\\', $projectDir . '/src/Glpi/DependencyInjection');
$services->load('Glpi\Progress\\', $projectDir . '/src/Glpi/Progress')->exclude($projectDir . '/src/Glpi/Progress/SessionProgress.php');
diff --git a/front/cron.php b/front/cron.php
index bb53cca0a9f..b1ebd677f0a 100644
--- a/front/cron.php
+++ b/front/cron.php
@@ -33,6 +33,12 @@
* ---------------------------------------------------------------------
*/
+/**
+ * @var \DBmysql|null $DB
+ * @var array $CFG_GLPI
+ */
+global $DB, $CFG_GLPI;
+
if (PHP_SAPI === 'cli') {
// Check the resources state before trying to instanciate the Kernel.
// It must be done here as this check must be done even when the Kernel
@@ -43,13 +49,45 @@
require_once dirname(__DIR__) . '/vendor/autoload.php';
$kernel = new \Glpi\Kernel\Kernel();
- $kernel->loadCommonGlobalConfig();
-}
+ $kernel->boot();
-/**
- * @var array $CFG_GLPI
- */
-global $CFG_GLPI;
+ // Handle the `--debug` argument
+ $debug = array_search('--debug', $_SERVER['argv']);
+ if ($debug) {
+ $_SESSION['glpi_use_mode'] = Session::DEBUG_MODE;
+ unset($_SERVER['argv'][$debug]);
+ $_SERVER['argv'] = array_values($_SERVER['argv']);
+ $_SERVER['argc']--;
+ }
+
+ if ($CFG_GLPI['maintenance_mode'] ?? false) {
+ echo 'Service is down for maintenance. It will be back shortly.' . PHP_EOL;
+ exit();
+ }
+
+ if (!($DB instanceof DBmysql)) {
+ echo sprintf(
+ 'ERROR: The database configuration file "%s" is missing or is corrupted. You have to either restart the install process, or restore this file.',
+ GLPI_CONFIG_DIR . '/config_db.php'
+ ) . PHP_EOL;
+ exit();
+ }
+
+ if (!$DB->connected) {
+ echo 'ERROR: The connection to the SQL server could not be established. Please check your configuration.' . PHP_EOL;
+ exit();
+ }
+
+ if (!Config::isLegacyConfigurationLoaded()) {
+ echo 'ERROR: Unable to load the GLPI configuration from the database.' . PHP_EOL;
+ exit();
+ }
+
+ if (!defined('SKIP_UPDATES') && !Update::isDbUpToDate()) {
+ echo 'The GLPI codebase has been updated. The update of the GLPI database is necessary.' . PHP_EOL;
+ exit();
+ }
+}
// Ensure current directory when run from crontab
chdir(__DIR__);
diff --git a/install/install.php b/install/install.php
index 4a853a04b80..b76ed902bf3 100644
--- a/install/install.php
+++ b/install/install.php
@@ -54,8 +54,6 @@
Session::loadLanguage(with_plugins: false);
}
-Session::checkCookieSecureConfig();
-
//Print a correct Html header for application
function header_html($etape)
{
@@ -518,11 +516,12 @@ function checkConfigFile()
checkConfigFile();
- // Add a flag that will be used to validate that installation can be processed.
- // This flag is put here just after checking that DB config file does not exist yet.
- // It is mandatory to validate that `Etape_4` to `Etape_6` are not used outside installation process
- // to change GLPI base URL without even being authenticated.
+ // Add a flag that will be used to validate that installation can be processed.
+ // This flag is put here just after checking that DB config file does not exist yet.
+ // It is mandatory to validate that installation endpoints are not used outside installation process
+ // to alter the GLPI database or configuration.
$_SESSION['can_process_install'] = true;
+ $_SESSION['is_installing'] = true;
header_html(__("Select your language"));
choose_language();
@@ -532,8 +531,6 @@ 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();
diff --git a/install/update.php b/install/update.php
index 24e6372d583..f64c97e07b4 100644
--- a/install/update.php
+++ b/install/update.php
@@ -37,8 +37,6 @@
use Glpi\Cache\CacheManager;
use Glpi\Toolbox\VersionParser;
-include_once(GLPI_CONFIG_DIR . "/config_db.php");
-
/**
* @var \DBmysql|null $DB
* @var \Psr\SimpleCache\CacheInterface $GLPI_CACHE
@@ -46,21 +44,14 @@
* @var bool $HEADER_LOADED
*/
global $DB,
- $GLPI_CACHE,
- $update,
- $HEADER_LOADED;
+ $GLPI_CACHE,
+ $update,
+ $HEADER_LOADED;
$GLPI_CACHE = (new CacheManager())->getInstallerCacheInstance();
-Session::checkCookieSecureConfig();
-
-if (!($DB instanceof DBmysql)) { // $DB can have already been init in install.php script
- $DB = new DB();
-}
$DB->disableTableCaching(); //prevents issues on fieldExists upgrading from old versions
-Config::loadLegacyConfiguration();
-
$update = new Update($DB);
if (isset($_POST['update_end'])) {
@@ -146,10 +137,6 @@ function showSecurityKeyCheckForm()
//Debut du script
$HEADER_LOADED = true;
-Session::start();
-
-Session::loadLanguage('', false);
-
// Send UTF8 Headers
header("Content-Type: text/html; charset=UTF-8");
@@ -229,6 +216,8 @@ function showSecurityKeyCheckForm()
doUpdateDb();
echo "";
+ Session::destroy(); // Remove session data set by web installation
+
$_SESSION['telemetry_from_install'] = true;
TemplateRenderer::getInstance()->display('install/update.html.twig', [
diff --git a/phpunit/bootstrap.php b/phpunit/bootstrap.php
index ae4c0ba0911..112a2f170cf 100644
--- a/phpunit/bootstrap.php
+++ b/phpunit/bootstrap.php
@@ -50,17 +50,21 @@
define('FIXTURE_DIR', __DIR__ . "/../tests/fixtures");
-global $CFG_GLPI, $GLPI_CACHE;
+global $GLPI_CACHE;
require_once dirname(__DIR__) . '/vendor/autoload.php';
$kernel = new Kernel('testing');
-$kernel->loadCommonGlobalConfig();
+$kernel->boot();
if (!file_exists(GLPI_CONFIG_DIR . '/config_db.php')) {
echo("\nConfiguration file for tests not found\n\nrun: php bin/console database:install --env=testing ...\n\n");
exit(1);
}
+if (!defined('SKIP_UPDATES') && !Update::isDbUpToDate()) {
+ echo 'The GLPI codebase has been updated. The update of the GLPI database is necessary.' . PHP_EOL;
+ exit(1);
+}
//init cache
if (file_exists(GLPI_CONFIG_DIR . DIRECTORY_SEPARATOR . CacheManager::CONFIG_FILENAME)) {
diff --git a/src/DBConnection.php b/src/DBConnection.php
index 04974fc6293..f0b1f24ba9b 100644
--- a/src/DBConnection.php
+++ b/src/DBConnection.php
@@ -646,29 +646,6 @@ public static function getHistoryMaxDate($DBconnection)
}
- /**
- * Display a common mysql connection error
- **/
- public static function displayMySQLError()
- {
- /** @var \DBmysql $DB */
- global $DB;
-
- $fr_msg = "Le serveur Mysql est inaccessible. Vérifiez votre configuration.";
- $en_msg = "A link to the SQL server could not be established. Please check your configuration.";
-
- if (!isCommandLine()) {
- Html::nullHeader("Mysql Error", '');
- echo "
";
- Html::nullFooter();
- } else {
- echo "$en_msg\n$fr_msg\n";
- }
-
- exit(1);
- }
-
-
/**
* @param $name
**/
diff --git a/src/Glpi/Config/LegacyConfigurators/CleanPHPSelfParam.php b/src/Glpi/Config/LegacyConfigurators/CleanPHPSelfParam.php
index 21116a8ef75..ee637eaa77d 100644
--- a/src/Glpi/Config/LegacyConfigurators/CleanPHPSelfParam.php
+++ b/src/Glpi/Config/LegacyConfigurators/CleanPHPSelfParam.php
@@ -37,7 +37,6 @@
use Glpi\Config\ConfigProviderHasRequestTrait;
use Glpi\Config\ConfigProviderWithRequestInterface;
use Glpi\Config\LegacyConfigProviderInterface;
-use Glpi\Debug\Profiler;
final class CleanPHPSelfParam implements LegacyConfigProviderInterface, ConfigProviderWithRequestInterface
{
@@ -45,12 +44,10 @@ final class CleanPHPSelfParam implements LegacyConfigProviderInterface, ConfigPr
public function execute(): void
{
- Profiler::getInstance()->start('CleanPHPSelfParam::execute', Profiler::CATEGORY_BOOT);
// Security of PHP_SELF
$self = \Html::cleanParametersURL($this->getRequest()->server->get('PHP_SELF'));
$_SERVER['PHP_SELF'] = $self;
$this->getRequest()->server->set('PHP_SELF', $self);
- Profiler::getInstance()->stop('CleanPHPSelfParam::execute');
}
}
diff --git a/src/Glpi/Config/LegacyConfigurators/ConfigRest.php b/src/Glpi/Config/LegacyConfigurators/ConfigRest.php
index 9ab7c469f93..98b38223f0a 100644
--- a/src/Glpi/Config/LegacyConfigurators/ConfigRest.php
+++ b/src/Glpi/Config/LegacyConfigurators/ConfigRest.php
@@ -35,7 +35,6 @@
namespace Glpi\Config\LegacyConfigurators;
use Glpi\Config\LegacyConfigProviderInterface;
-use Glpi\Debug\Profiler;
use Session;
final readonly class ConfigRest implements LegacyConfigProviderInterface
@@ -45,21 +44,9 @@ public function execute(): void
/**
* @var array $CFG_GLPI
* @var \Psr\SimpleCache\CacheInterface $GLPI_CACHE
- * @var bool $FOOTER_LOADED
- * @var bool $HEADER_LOADED
- * @var string $CURRENTCSRFTOKEN
*/
- global $CFG_GLPI,
- $GLPI_CACHE,
- $FOOTER_LOADED, $HEADER_LOADED,
- $CURRENTCSRFTOKEN
- ;
+ global $CFG_GLPI, $GLPI_CACHE;
- // Mark if Header is loaded or not :
- $HEADER_LOADED = false;
- $FOOTER_LOADED = false;
-
- Profiler::getInstance()->start('ConfigRest::execute', Profiler::CATEGORY_BOOT);
// Security : check CSRF token
if (!isAPI() && count($_POST) > 0) {
if (preg_match(':' . $CFG_GLPI['root_doc'] . '(/(plugins|marketplace)/[^/]*|)/ajax/:', $_SERVER['REQUEST_URI']) === 1) {
@@ -73,8 +60,6 @@ public function execute(): void
Session::checkCSRF($_POST);
}
}
- // SET new global Token
- $CURRENTCSRFTOKEN = '';
// Manage profile change
if (isset($_REQUEST["force_profile"]) && ($_SESSION['glpiactiveprofile']['id'] ?? -1) != $_REQUEST["force_profile"]) {
@@ -105,6 +90,5 @@ public function execute(): void
) {
Session::loadGroups();
}
- Profiler::getInstance()->stop('ConfigRest::execute');
}
}
diff --git a/src/Glpi/Config/LegacyConfigurators/SessionConfig.php b/src/Glpi/Config/LegacyConfigurators/SessionConfig.php
index 55f177374da..81386e103dc 100644
--- a/src/Glpi/Config/LegacyConfigurators/SessionConfig.php
+++ b/src/Glpi/Config/LegacyConfigurators/SessionConfig.php
@@ -37,8 +37,6 @@
use Glpi\Config\ConfigProviderHasRequestTrait;
use Glpi\Config\ConfigProviderWithRequestInterface;
use Glpi\Config\LegacyConfigProviderInterface;
-use Glpi\Debug\Profile;
-use Glpi\Debug\Profiler;
use Glpi\Toolbox\URL;
use Session;
@@ -48,15 +46,6 @@ final class SessionConfig implements LegacyConfigProviderInterface, ConfigProvid
public function execute(): void
{
- Profiler::getInstance()->start('SessionConfig::execute', Profiler::CATEGORY_BOOT);
- if (
- isset($_SESSION['glpi_use_mode'])
- && ($_SESSION['glpi_use_mode'] == Session::DEBUG_MODE)
- ) {
- // Start the debug profile
- Profile::getCurrent();
- }
-
if (!isset($_SESSION["MESSAGE_AFTER_REDIRECT"])) {
$_SESSION["MESSAGE_AFTER_REDIRECT"] = [];
}
@@ -79,6 +68,5 @@ public function execute(): void
if (isset($_REQUEST['glpilist_limit'])) {
$_SESSION['glpilist_limit'] = $_REQUEST['glpilist_limit'];
}
- Profiler::getInstance()->stop('SessionConfig::execute');
}
}
diff --git a/src/Glpi/Config/LegacyConfigurators/StandardIncludes.php b/src/Glpi/Config/LegacyConfigurators/StandardIncludes.php
index ede5c76807c..6be0bc80f14 100644
--- a/src/Glpi/Config/LegacyConfigurators/StandardIncludes.php
+++ b/src/Glpi/Config/LegacyConfigurators/StandardIncludes.php
@@ -34,155 +34,36 @@
namespace Glpi\Config\LegacyConfigurators;
-use Auth;
-use DBConnection;
-use DBmysql;
use Config;
use Glpi\Application\View\TemplateRenderer;
-use Glpi\Cache\CacheManager;
+use Glpi\Config\ConfigProviderHasRequestTrait;
+use Glpi\Config\ConfigProviderWithRequestInterface;
use Glpi\Config\LegacyConfigProviderInterface;
+use Glpi\Http\RequestPoliciesTrait;
use Glpi\System\Requirement\DatabaseTablesEngine;
use Glpi\System\RequirementsManager;
use Glpi\Toolbox\VersionParser;
use Html;
use Session;
-use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Toolbox;
use Update;
-final readonly class StandardIncludes implements LegacyConfigProviderInterface
+final class StandardIncludes implements LegacyConfigProviderInterface, ConfigProviderWithRequestInterface
{
- public function __construct(
- #[Autowire('%kernel.project_dir%')] private string $projectDir,
- ) {
- }
+ use ConfigProviderHasRequestTrait;
+ use RequestPoliciesTrait;
public function execute(): void
{
/**
- * @var \DBmysql|null $DB
* @var array $CFG_GLPI
- * @var \Psr\SimpleCache\CacheInterface $GLPI_CACHE
*/
- global $DB,
- $CFG_GLPI,
- $GLPI_CACHE
- ;
-
- if (isset($_SESSION['is_installing'])) {
- $GLPI_CACHE = (new CacheManager())->getInstallerCacheInstance();
-
- Session::loadLanguage(with_plugins: false);
- return;
- }
-
- $skip_db_checks = false;
- $skip_maintenance_checks = false;
- if (array_key_exists('REQUEST_URI', $_SERVER)) {
- if (preg_match('#^' . $CFG_GLPI['root_doc'] . '/front/(css|locale).php#', $_SERVER['REQUEST_URI']) === 1) {
- $skip_db_checks = true;
- $skip_maintenance_checks = true;
- }
-
- $no_db_checks_scripts = [
- '#^' . $CFG_GLPI['root_doc'] . '/$#',
- '#^' . $CFG_GLPI['root_doc'] . '/index.php#',
- '#^' . $CFG_GLPI['root_doc'] . '/install/install.php#',
- '#^' . $CFG_GLPI['root_doc'] . '/install/update.php#',
- ];
- foreach ($no_db_checks_scripts as $pattern) {
- if (preg_match($pattern, $_SERVER['REQUEST_URI']) === 1) {
- $skip_db_checks = true;
- break;
- }
- }
- }
-
- //init cache
- $cache_manager = new CacheManager();
- $GLPI_CACHE = $cache_manager->getCoreCacheInstance();
-
- // Check if the DB is configured properly
- if (!$skip_db_checks) {
- if ($DB instanceof DBmysql) {
- //Database connection
- if (!$DB->connected) {
- DBConnection::displayMySQLError();
- exit(1);
- }
-
- //Options from DB, do not touch this part.
- if (!Config::isLegacyConfigurationLoaded()) {
- echo "Error accessing config table";
- exit(1);
- }
- } else {
- Session::loadLanguage('', false);
-
- if (!isCommandLine()) {
- // Prevent inclusion of debug information in footer, as they are based on vars that are not initialized here.
- $debug_mode = $_SESSION['glpi_use_mode'];
- $_SESSION['glpi_use_mode'] = Session::NORMAL_MODE;
-
- Html::nullHeader('Missing configuration', $CFG_GLPI["root_doc"]);
- $twig_params = [
- 'config_db' => GLPI_CONFIG_DIR . '/config_db.php',
- 'install_exists' => file_exists($this->projectDir . '/install/install.php'),
- ];
- // language=Twig
- echo TemplateRenderer::getInstance()->renderFromStringTemplate(<<
-
-
-
GLPI seems to not be configured properly.
-
- Database configuration file "{{ config_db }}" is missing or is corrupted.
- You have to either restart the install process, either restore this file.
-
-
- {% if install_exists %}
- Go to install page
- {% endif %}
-
-
-
-
- TWIG, $twig_params);
- Html::nullFooter();
- $_SESSION['glpi_use_mode'] = $debug_mode;
- } else {
- echo "GLPI seems to not be configured properly.\n";
- echo sprintf('Database configuration file "%s" is missing or is corrupted.', GLPI_CONFIG_DIR . '/config_db.php') . "\n";
- echo "You have to either restart the install process, either restore this file.\n";
- }
- exit(1);
- }
- }
-
- if (
- isCommandLine()
- && !defined('TU_USER') // In test suite context, used --debug option is the atoum one
- && isset($_SERVER['argv'])
- ) {
- $key = array_search('--debug', $_SERVER['argv']);
- if ($key) {
- $_SESSION['glpi_use_mode'] = Session::DEBUG_MODE;
- unset($_SERVER['argv'][$key]);
- $_SERVER['argv'] = array_values($_SERVER['argv']);
- $_SERVER['argc']--;
- }
- }
-
- // Override cfg_features by session value
- foreach ($CFG_GLPI['user_pref_field'] as $field) {
- if (!isset($_SESSION["glpi$field"]) && isset($CFG_GLPI[$field])) {
- $_SESSION["glpi$field"] = $CFG_GLPI[$field];
- }
- }
+ global $CFG_GLPI;
// Check maintenance mode
if (
- !$skip_maintenance_checks
+ !$this->isFrontEndAssetEndpoint($this->getRequest())
+ && !$this->isSymfonyProfilerEndpoint($this->getRequest())
&& isset($CFG_GLPI["maintenance_mode"])
&& $CFG_GLPI["maintenance_mode"]
) {
@@ -191,36 +72,20 @@ public function execute(): void
}
if (!isset($_SESSION["glpiskipMaintenance"]) || !$_SESSION["glpiskipMaintenance"]) {
- Session::loadLanguage('', false);
- if (isCommandLine()) {
- echo __('Service is down for maintenance. It will be back shortly.');
- echo "\n";
- } else {
- TemplateRenderer::getInstance()->display('maintenance.html.twig', [
- 'title' => "MAINTENANCE MODE",
- 'maintenance_text' => $CFG_GLPI["maintenance_text"] ?? "",
- ]);
- }
+ TemplateRenderer::getInstance()->display('maintenance.html.twig', [
+ 'title' => "MAINTENANCE MODE",
+ 'maintenance_text' => $CFG_GLPI["maintenance_text"] ?? "",
+ ]);
exit();
}
}
// Check version
- if (!$skip_db_checks && !defined('SKIP_UPDATES') && !Update::isDbUpToDate()) {
- Session::checkCookieSecureConfig();
-
+ if ($this->shouldCheckDbStatus($this->getRequest()) && !defined('SKIP_UPDATES') && !Update::isDbUpToDate()) {
// Prevent debug bar to be displayed when an admin user was connected with debug mode when codebase was updated.
$debug_mode = $_SESSION['glpi_use_mode'];
Toolbox::setDebugMode(Session::NORMAL_MODE);
- Session::loadLanguage('', false);
-
- if (isCommandLine()) {
- echo __('The GLPI codebase has been updated. The update of the GLPI database is necessary.');
- echo "\n";
- exit();
- }
-
/** @var \DBmysql $DB */
global $DB;
@@ -286,8 +151,5 @@ public function execute(): void
$_SESSION['glpi_use_mode'] = $debug_mode;
exit();
}
-
- // Load Language file
- Session::loadLanguage();
}
}
diff --git a/src/Glpi/Console/Application.php b/src/Glpi/Console/Application.php
index 790068c3a3c..f67719bff81 100644
--- a/src/Glpi/Console/Application.php
+++ b/src/Glpi/Console/Application.php
@@ -35,19 +35,15 @@
namespace Glpi\Console;
-use Config;
-use DB;
use DBmysql;
use GLPI;
use Glpi\Application\ErrorHandler;
-use Glpi\Cache\CacheManager;
use Glpi\Console\Command\ConfigurationCommandInterface;
-use Glpi\Console\Command\ForceNoPluginsOptionCommandInterface;
use Glpi\Console\Command\GlpiCommandInterface;
+use Glpi\Kernel\Kernel;
use Glpi\System\Requirement\RequirementInterface;
use Glpi\System\RequirementsManager;
use Glpi\Toolbox\Filesystem;
-use Plugin;
use Session;
use Symfony\Component\Console\Application as BaseApplication;
use Symfony\Component\Console\Command\Command;
@@ -92,44 +88,35 @@ class Application extends BaseApplication
*/
private $config;
- /**
- * @var ErrorHandler
- */
- private $error_handler;
-
- /**
- * @var DBmysql|null
- */
- private $db;
+ private ?DBmysql $db = null;
/**
* @var OutputInterface
*/
private $output;
- public function __construct()
+ public function __construct(private Kernel $kernel)
{
+ /**
+ * @var \DBmysql $DB
+ * @var array $CFG_GLPI
+ */
+ global $DB, $CFG_GLPI;
parent::__construct('GLPI CLI', GLPI_VERSION);
- $this->initApplication();
- $this->initCache();
- $this->initDb();
- $this->initSession();
- $this->initConfig();
+ $this->kernel->boot();
+
+ $this->db = $DB;
+ $this->config = &$CFG_GLPI;
+
+ // Force the current "username"
+ $_SESSION['glpiname'] = 'cli';
$this->computeAndLoadOutputLang();
- // Load core commands only to check if called command prevent or not usage of plugins
- // Plugin commands will be loaded later
- $loader = new CommandLoader(false);
+ $loader = new CommandLoader(include_plugins: $this->db instanceof DBmysql && $this->db->connected);
$this->setCommandLoader($loader);
-
- if ($this->usePlugins()) {
- $plugin = new Plugin();
- $plugin->init(true);
- $loader->setIncludePlugins(true);
- }
}
protected function getDefaultInputDefinition(): InputDefinition
@@ -199,12 +186,6 @@ protected function getDefaultInputDefinition(): InputDefinition
InputOption::VALUE_OPTIONAL,
__('Configuration directory to use. Deprecated option')
),
- new InputOption(
- '--no-plugins',
- null,
- InputOption::VALUE_NONE,
- __('Disable GLPI plugins (unless commands forces plugins loading)')
- ),
new InputOption(
'--lang',
null,
@@ -336,106 +317,6 @@ protected function doRunCommand(Command $command, InputInterface $input, OutputI
return $result;
}
- /**
- * Initalize GLPI.
- *
- * @return void
- */
- private function initApplication()
- {
- }
-
- /**
- * Initialize database connection.
- *
- * @global DBmysql $DB
- *
- * @return void
- *
- * @throws RuntimeException
- */
- private function initDb()
- {
-
- if (!class_exists('DB', false) || !class_exists('mysqli', false)) {
- return;
- }
-
- /** @var \DBmysql $DB */
- global $DB;
- $DB = @new DB();
- $this->db = $DB;
-
- if (!$this->db->connected) {
- return;
- }
-
- ob_start();
- $checkdb = Config::displayCheckDbEngine();
- $message = ob_get_clean();
- if ($checkdb > 0) {
- throw new \Symfony\Component\Console\Exception\RuntimeException($message);
- }
- }
-
- /**
- * Initialize GLPI session.
- * This is mandatory to init cache and load languages.
- *
- * @TODO Do not use session for console.
- *
- * @return void
- */
- private function initSession()
- {
-
- if (!Session::canWriteSessionFiles()) {
- throw new \Symfony\Component\Console\Exception\RuntimeException(
- sprintf(__('Cannot write in "%s" directory.'), GLPI_SESSION_DIR)
- );
- }
-
- Session::setPath();
- Session::start();
-
- // Default value for use mode
- $_SESSION['glpi_use_mode'] = Session::NORMAL_MODE;
- $_SESSION['glpiname'] = 'cli';
- }
-
- /**
- * Initialize GLPI cache.
- *
- * @global \Psr\SimpleCache\CacheInterface $GLPI_CACHE
- *
- * @return void
- */
- private function initCache()
- {
-
- /** @var \Psr\SimpleCache\CacheInterface $GLPI_CACHE */
- global $GLPI_CACHE;
- $cache_manager = new CacheManager();
- $GLPI_CACHE = $cache_manager->getCoreCacheInstance();
- }
-
- /**
- * Initialize GLPI configuration.
- *
- * @global array $CFG_GLPI
- *
- * @return void
- */
- private function initConfig()
- {
-
- /** @var array $CFG_GLPI */
- global $CFG_GLPI;
- $this->config = &$CFG_GLPI;
-
- Config::loadLegacyConfiguration();
- }
-
/**
* Compute and load output language.
*
@@ -468,9 +349,11 @@ private function computeAndLoadOutputLang()
$lang = 'en_GB';
}
- $_SESSION['glpilanguage'] = $lang;
+ if ($lang !== $_SESSION['glpilanguage']) {
+ $_SESSION['glpilanguage'] = $lang;
- Session::loadLanguage('', $this->usePlugins());
+ Session::loadLanguage();
+ }
}
/**
@@ -487,32 +370,6 @@ private function isLanguageValid($language)
&& array_key_exists($language, $this->config['languages']);
}
- /**
- * Whether or not plugins have to be used.
- *
- * @return boolean
- */
- private function usePlugins()
- {
- if (!($this->db instanceof DBmysql) || !$this->db->connected) {
- return false;
- }
-
- $input = new ArgvInput();
-
- try {
- $command = $this->find($this->getCommandName($input) ?? '');
- if ($command instanceof ForceNoPluginsOptionCommandInterface) {
- return !$command->getNoPluginsOptionValue();
- }
- } catch (\Symfony\Component\Console\Exception\CommandNotFoundException $e) {
- // Command will not be found at this point if it is a plugin command
- $command = null; // Say hello to CS checker
- }
-
- return !$input->hasParameterOption('--no-plugins', true);
- }
-
/**
* Check if core mandatory requirements are OK.
*
@@ -523,11 +380,9 @@ private function usePlugins()
private function checkCoreMandatoryRequirements(
array $command_specific_requirements
): bool {
- $db = property_exists($this, 'db') ? $this->db : null;
-
$requirements_manager = new RequirementsManager();
$core_requirements = $requirements_manager->getCoreRequirementList(
- $db instanceof DBmysql && $db->connected ? $db : null
+ $this->db instanceof DBmysql && $this->db->connected ? $this->db : null
);
// Some commands might specify some extra requirements
@@ -614,13 +469,11 @@ public function extractNamespace(string $name, ?int $limit = null): string
* Gets the Kernel associated with this Console.
*
* This method is required by most of the commands provided by the `symfony/framework-bundle`.
+ *
* @see \Symfony\Bundle\FrameworkBundle\Console\Application::getKernel()
*/
- public function getKernel(): ?KernelInterface
+ public function getKernel(): KernelInterface
{
- /** @var KernelInterface|null $kernel */
- global $kernel;
-
- return $kernel;
+ return $this->kernel;
}
}
diff --git a/src/Glpi/Console/Command/ForceNoPluginsOptionCommandInterface.php b/src/Glpi/Console/Command/ForceNoPluginsOptionCommandInterface.php
deleted file mode 100644
index 7c8c0ff8cf5..00000000000
--- a/src/Glpi/Console/Command/ForceNoPluginsOptionCommandInterface.php
+++ /dev/null
@@ -1,46 +0,0 @@
-.
- *
- * ---------------------------------------------------------------------
- */
-
-namespace Glpi\Console\Command;
-
-interface ForceNoPluginsOptionCommandInterface
-{
- /**
- * Defines whether or not command prevents plugins to be loaded.
- *
- * @return boolean
- */
- public function getNoPluginsOptionValue();
-}
diff --git a/src/Glpi/Console/Database/AbstractConfigureCommand.php b/src/Glpi/Console/Database/AbstractConfigureCommand.php
index 255ca02a8f1..4c7b0fff457 100644
--- a/src/Glpi/Console/Database/AbstractConfigureCommand.php
+++ b/src/Glpi/Console/Database/AbstractConfigureCommand.php
@@ -39,7 +39,6 @@
use DBConnection;
use DBmysql;
use Glpi\Console\AbstractCommand;
-use Glpi\Console\Command\ForceNoPluginsOptionCommandInterface;
use Glpi\System\Requirement\DbTimezones;
use mysqli;
use Symfony\Component\Console\Exception\InvalidArgumentException;
@@ -49,7 +48,7 @@
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\Question;
-abstract class AbstractConfigureCommand extends AbstractCommand implements ForceNoPluginsOptionCommandInterface
+abstract class AbstractConfigureCommand extends AbstractCommand
{
/**
* Error code returned if DB configuration succeed.
@@ -351,12 +350,6 @@ public function __construct(
};
}
- public function getNoPluginsOptionValue()
- {
-
- return true;
- }
-
/**
* Check if DB is already configured.
*
diff --git a/src/Glpi/Console/Database/UpdateCommand.php b/src/Glpi/Console/Database/UpdateCommand.php
index 835121f86a0..50ccfdeb138 100644
--- a/src/Glpi/Console/Database/UpdateCommand.php
+++ b/src/Glpi/Console/Database/UpdateCommand.php
@@ -39,7 +39,6 @@
use Glpi\Cache\CacheManager;
use Glpi\Console\AbstractCommand;
use Glpi\Console\Command\ConfigurationCommandInterface;
-use Glpi\Console\Command\ForceNoPluginsOptionCommandInterface;
use Glpi\Console\Traits\TelemetryActivationTrait;
use Glpi\System\Diagnostic\DatabaseSchemaIntegrityChecker;
use Glpi\System\Requirement\DatabaseTablesEngine;
@@ -55,7 +54,7 @@
use Symfony\Component\Console\Output\OutputInterface;
use Update;
-class UpdateCommand extends AbstractCommand implements ConfigurationCommandInterface, ForceNoPluginsOptionCommandInterface
+class UpdateCommand extends AbstractCommand implements ConfigurationCommandInterface
{
use TelemetryActivationTrait;
@@ -266,12 +265,6 @@ protected function execute(InputInterface $input, OutputInterface $output)
return 0; // Success
}
- public function getNoPluginsOptionValue()
- {
-
- return true;
- }
-
/**
* Check schema integrity of installed database.
*
diff --git a/src/Glpi/Console/Plugin/AbstractPluginCommand.php b/src/Glpi/Console/Plugin/AbstractPluginCommand.php
index 230a168679e..ab95c5df426 100644
--- a/src/Glpi/Console/Plugin/AbstractPluginCommand.php
+++ b/src/Glpi/Console/Plugin/AbstractPluginCommand.php
@@ -36,14 +36,13 @@
namespace Glpi\Console\Plugin;
use Glpi\Console\AbstractCommand;
-use Glpi\Console\Command\ForceNoPluginsOptionCommandInterface;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ChoiceQuestion;
-abstract class AbstractPluginCommand extends AbstractCommand implements ForceNoPluginsOptionCommandInterface
+abstract class AbstractPluginCommand extends AbstractCommand
{
/**
* Wildcard value to target all directories.
@@ -113,13 +112,6 @@ protected function interact(InputInterface $input, OutputInterface $output)
}
}
- public function getNoPluginsOptionValue()
- {
-
- // Force no loading on plugins in plugin install process
- return true;
- }
-
/**
* Normalize input to symplify handling of specific arguments/options values.
*
diff --git a/src/Glpi/Console/Plugin/ListCommand.php b/src/Glpi/Console/Plugin/ListCommand.php
index 6d44894c796..7b261d3cb0a 100644
--- a/src/Glpi/Console/Plugin/ListCommand.php
+++ b/src/Glpi/Console/Plugin/ListCommand.php
@@ -36,7 +36,6 @@
namespace Glpi\Console\Plugin;
use Glpi\Console\AbstractCommand;
-use Glpi\Console\Command\ForceNoPluginsOptionCommandInterface;
use Glpi\Marketplace\Controller;
use Plugin;
use Symfony\Component\Console\Helper\Table;
@@ -45,7 +44,7 @@
use Symfony\Component\Console\Output\OutputInterface;
use Toolbox;
-class ListCommand extends AbstractCommand implements ForceNoPluginsOptionCommandInterface
+class ListCommand extends AbstractCommand
{
protected function configure()
{
@@ -107,9 +106,4 @@ protected function execute(InputInterface $input, OutputInterface $output)
}
return 0;
}
-
- public function getNoPluginsOptionValue()
- {
- return true;
- }
}
diff --git a/src/Glpi/Controller/ErrorController.php b/src/Glpi/Controller/ErrorController.php
index 62ec3611937..4eff32fbc52 100644
--- a/src/Glpi/Controller/ErrorController.php
+++ b/src/Glpi/Controller/ErrorController.php
@@ -34,6 +34,8 @@
namespace Glpi\Controller;
+use Config;
+use DBConnection;
use Glpi\Application\ErrorHandler;
use Html;
use Session;
@@ -127,8 +129,10 @@ private function getErrorResponse(\Throwable $exception, Request $request): Resp
{
$status_code = $exception instanceof HttpExceptionInterface ? $exception->getStatusCode() : 500;
- $title = _n('Error', 'Errors', 1);
- $message = __('An unexpected error has occurred.');
+ $title = _n('Error', 'Errors', 1);
+ $message = __('An unexpected error has occurred.');
+ $link_text = null;
+ $link_url = null;
if ($exception instanceof HttpExceptionInterface) {
// Default messages.
@@ -158,6 +162,10 @@ private function getErrorResponse(\Throwable $exception, Request $request): Resp
) {
$message = $custom_message;
}
+ if ($exception instanceof \Glpi\Exception\Http\HttpExceptionInterface) {
+ $link_text = $exception->getLinktext();
+ $link_url = $exception->getLinkUrl();
+ }
}
$trace = null;
@@ -210,6 +218,11 @@ private function getErrorResponse(\Throwable $exception, Request $request): Resp
$header_method = match (true) {
// A minimal page is displayed as we do not have enough memory available to display the full page.
$exception instanceof OutOfMemoryError => 'simpleHeader',
+
+ // Only the error message should be shown if the DB is ot available or the config not loaded.
+ // Trying to display a full header is not possible.
+ !DBConnection::isDbAvailable() || !Config::isLegacyConfigurationLoaded() => 'nullHeader',
+
Session::getCurrentInterface() === 'central' => 'header',
Session::getCurrentInterface() === 'helpdesk' => 'helpHeader',
default => 'nullHeader',
@@ -220,8 +233,8 @@ private function getErrorResponse(\Throwable $exception, Request $request): Resp
[
'header_method' => $header_method,
'page_title' => $title,
- 'link_url' => Html::getBackUrl(),
- 'link_text' => __('Return to previous page'),
+ 'link_url' => $link_url ?? Html::getBackUrl(),
+ 'link_text' => $link_text ?? __('Return to previous page'),
] + $error_block_params,
new Response(status: $status_code)
);
diff --git a/src/Glpi/Controller/IndexController.php b/src/Glpi/Controller/IndexController.php
index 611d5988d01..8c3f3092986 100644
--- a/src/Glpi/Controller/IndexController.php
+++ b/src/Glpi/Controller/IndexController.php
@@ -85,45 +85,10 @@ public function __invoke(Request $request): Response
private function call(): void
{
/**
- * @var \DBmysql|null $DB
* @var array $CFG_GLPI
* @var array $PLUGIN_HOOKS
*/
- global $DB, $CFG_GLPI, $PLUGIN_HOOKS;
-
- // If config_db doesn't exist -> start installation
- if (!file_exists(GLPI_CONFIG_DIR . "/config_db.php") || !class_exists('DB', false)) {
- if (file_exists(GLPI_ROOT . '/install/install.php')) {
- Html::redirect("install/install.php");
- } else {
- Session::loadLanguage('', false);
- // Prevent inclusion of debug information in footer, as they are based on vars that are not initialized here.
- $_SESSION['glpi_use_mode'] = Session::NORMAL_MODE;
-
- // no translation
- $title_text = 'GLPI seems to not be configured properly.';
- $missing_conf_text = sprintf('Database configuration file "%s" is missing.', GLPI_CONFIG_DIR . '/config_db.php');
- $hint_text = 'You have to either restart the install process, either restore this file.';
-
- Html::nullHeader('Missing configuration');
- echo '';
- echo '
';
- echo '
';
- echo '
' . $title_text . '
';
- echo '
';
- echo $missing_conf_text;
- echo ' ';
- echo $hint_text;
- echo '
';
- echo '
';
- echo '
';
- echo '
';
- Html::nullFooter();
- return;
- }
- }
-
- Session::checkCookieSecureConfig();
+ global $CFG_GLPI, $PLUGIN_HOOKS;
$_SESSION["glpicookietest"] = 'testcookie';
diff --git a/src/Glpi/Controller/InstallController.php b/src/Glpi/Controller/InstallController.php
index e5b2b02d926..0d99546e8a9 100644
--- a/src/Glpi/Controller/InstallController.php
+++ b/src/Glpi/Controller/InstallController.php
@@ -56,7 +56,7 @@ public function __construct(
#[SecurityStrategy(Firewall::STRATEGY_NO_CHECK)]
public function start_inserts(): Response
{
- if (!isset($_SESSION['is_installing'])) {
+ if (!isset($_SESSION['can_process_install'])) {
throw new AccessDeniedHttpException();
}
diff --git a/src/Glpi/Exception/Http/HttpExceptionInterface.php b/src/Glpi/Exception/Http/HttpExceptionInterface.php
index 51b5236f1e2..92e167817ae 100644
--- a/src/Glpi/Exception/Http/HttpExceptionInterface.php
+++ b/src/Glpi/Exception/Http/HttpExceptionInterface.php
@@ -40,4 +40,14 @@ interface HttpExceptionInterface extends \Symfony\Component\HttpKernel\Exception
* Get the message to display.
*/
public function getMessageToDisplay(): ?string;
+
+ /**
+ * Get the specific link text.
+ */
+ public function getLinkText(): ?string;
+
+ /**
+ * Get the specific link URL.
+ */
+ public function getLinkUrl(): ?string;
}
diff --git a/src/Glpi/Exception/Http/HttpExceptionTrait.php b/src/Glpi/Exception/Http/HttpExceptionTrait.php
index b324b4d27af..6712921c548 100644
--- a/src/Glpi/Exception/Http/HttpExceptionTrait.php
+++ b/src/Glpi/Exception/Http/HttpExceptionTrait.php
@@ -38,6 +38,10 @@ trait HttpExceptionTrait
{
private ?string $message_to_display = null;
+ private ?string $link_text = null;
+
+ private ?string $link_url = null;
+
/**
* Get the message to display.
*/
@@ -53,4 +57,36 @@ public function setMessageToDisplay(?string $message): void
{
$this->message_to_display = $message;
}
+
+ /**
+ * Get the specific link text.
+ */
+ public function getLinkText(): ?string
+ {
+ return $this->link_text;
+ }
+
+ /**
+ * Define the specific link text.
+ */
+ public function setLinkText(?string $text): void
+ {
+ $this->link_text = $text;
+ }
+
+ /**
+ * Get the specific link URL.
+ */
+ public function getLinkUrl(): ?string
+ {
+ return $this->link_url;
+ }
+
+ /**
+ * Define the specific link URL.
+ */
+ public function setLinkUrl(?string $url): void
+ {
+ $this->link_url = $url;
+ }
}
diff --git a/src/Glpi/Http/Listener/AccessErrorListener.php b/src/Glpi/Http/Listener/AccessErrorListener.php
index 02624d94e5a..9340032cc86 100644
--- a/src/Glpi/Http/Listener/AccessErrorListener.php
+++ b/src/Glpi/Http/Listener/AccessErrorListener.php
@@ -45,12 +45,11 @@
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\KernelEvents;
-final class AccessErrorListener implements EventSubscriberInterface
+final readonly class AccessErrorListener implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [
- // priority = 1 to be executed before the default Symfony listeners
KernelEvents::EXCEPTION => ['onKernelException', 1],
];
}
diff --git a/src/Glpi/Http/Listener/CheckDatabaseStatusListener.php b/src/Glpi/Http/Listener/CheckDatabaseStatusListener.php
new file mode 100644
index 00000000000..541b566be10
--- /dev/null
+++ b/src/Glpi/Http/Listener/CheckDatabaseStatusListener.php
@@ -0,0 +1,109 @@
+.
+ *
+ * ---------------------------------------------------------------------
+ */
+
+namespace Glpi\Http\Listener;
+
+use Config;
+use DBmysql;
+use Glpi\Http\RequestPoliciesTrait;
+use Glpi\Kernel\ListenersPriority;
+use Symfony\Component\DependencyInjection\Attribute\Autowire;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Symfony\Component\HttpKernel\Event\RequestEvent;
+use Symfony\Component\HttpKernel\KernelEvents;
+
+final class CheckDatabaseStatusListener implements EventSubscriberInterface
+{
+ use RequestPoliciesTrait;
+
+ public function __construct(
+ #[Autowire('%kernel.project_dir%')] private readonly string $projectDir,
+ ) {
+ }
+
+ public static function getSubscribedEvents(): array
+ {
+ return [
+ KernelEvents::REQUEST => [
+ ['onKernelRequest', ListenersPriority::REQUEST_LISTENERS_PRIORITIES[self::class]],
+ ],
+ ];
+ }
+
+ public function onKernelRequest(RequestEvent $event): void
+ {
+ /** @var ?DBmysql $DB */
+ global $DB;
+
+ if (!$event->isMainRequest()) {
+ return;
+ }
+
+ if (!$this->shouldCheckDbStatus($event->getRequest())) {
+ return;
+ }
+
+ if (!($DB instanceof DBmysql)) {
+ $exception = new \Glpi\Exception\Http\HttpException(500);
+ $exception->setMessageToDisplay(
+ __('The database configuration file is missing or is corrupted. You have to either restart the install process, or restore this file.')
+ );
+ if (file_exists($this->projectDir . '/install/install.php')) {
+ $exception->setLinkText(__('Go to install page'));
+ $exception->setLinkUrl($event->getRequest()->getBasePath() . '/install/install.php');
+ }
+ throw $exception;
+ }
+
+ if (!$DB->connected) {
+ $exception = new \Glpi\Exception\Http\HttpException(500);
+ $exception->setMessageToDisplay(
+ __('The connection to the SQL server could not be established. Please check your configuration.')
+ );
+ $exception->setLinkText(__('Try again'));
+ $exception->setLinkUrl($event->getRequest()->getRequestUri());
+ throw $exception;
+ }
+
+ if (!Config::isLegacyConfigurationLoaded()) {
+ $exception = new \Glpi\Exception\Http\HttpException(500);
+ $exception->setMessageToDisplay(
+ __('Unable to load the GLPI configuration from the database.')
+ );
+ $exception->setLinkText(__('Try again'));
+ $exception->setLinkUrl($event->getRequest()->getRequestUri());
+ throw $exception;
+ }
+ }
+}
diff --git a/src/Glpi/Http/Listener/LegacyAssetsListener.php b/src/Glpi/Http/Listener/LegacyAssetsListener.php
index 54040b60229..6440bf20ac2 100644
--- a/src/Glpi/Http/Listener/LegacyAssetsListener.php
+++ b/src/Glpi/Http/Listener/LegacyAssetsListener.php
@@ -35,7 +35,7 @@
namespace Glpi\Http\Listener;
use Glpi\Http\LegacyRouterTrait;
-use Glpi\Http\ListenersPriority;
+use Glpi\Kernel\ListenersPriority;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
@@ -59,7 +59,7 @@ public function __construct(
public static function getSubscribedEvents(): array
{
return [
- KernelEvents::REQUEST => ['onKernelRequest', ListenersPriority::LEGACY_LISTENERS_PRIORITIES[self::class]],
+ KernelEvents::REQUEST => ['onKernelRequest', ListenersPriority::REQUEST_LISTENERS_PRIORITIES[self::class]],
];
}
diff --git a/src/Glpi/Config/LegacyConfigProviderListener.php b/src/Glpi/Http/Listener/LegacyConfigProviderListener.php
similarity index 91%
rename from src/Glpi/Config/LegacyConfigProviderListener.php
rename to src/Glpi/Http/Listener/LegacyConfigProviderListener.php
index ba1452a3d35..f4900fc073e 100644
--- a/src/Glpi/Config/LegacyConfigProviderListener.php
+++ b/src/Glpi/Http/Listener/LegacyConfigProviderListener.php
@@ -32,9 +32,11 @@
* ---------------------------------------------------------------------
*/
-namespace Glpi\Config;
+namespace Glpi\Http\Listener;
-use Glpi\Http\ListenersPriority;
+use Glpi\Config\ConfigProviderWithRequestInterface;
+use Glpi\Config\LegacyConfigProviders;
+use Glpi\Kernel\ListenersPriority;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
@@ -50,7 +52,7 @@ public static function getSubscribedEvents(): array
{
return [
// Has to be executed before anything else!
- KernelEvents::REQUEST => ['onKernelRequest', ListenersPriority::LEGACY_LISTENERS_PRIORITIES[self::class]],
+ KernelEvents::REQUEST => ['onKernelRequest', ListenersPriority::REQUEST_LISTENERS_PRIORITIES[self::class]],
];
}
diff --git a/src/Glpi/Http/Listener/LegacyItemtypeRouteListener.php b/src/Glpi/Http/Listener/LegacyItemtypeRouteListener.php
index 86b6d8416d6..d6c0284bfca 100644
--- a/src/Glpi/Http/Listener/LegacyItemtypeRouteListener.php
+++ b/src/Glpi/Http/Listener/LegacyItemtypeRouteListener.php
@@ -46,7 +46,7 @@
use Glpi\Controller\DropdownFormController;
use Glpi\Dropdown\Dropdown;
use Glpi\Dropdown\DropdownDefinition;
-use Glpi\Http\ListenersPriority;
+use Glpi\Kernel\ListenersPriority;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\RequestEvent;
@@ -62,7 +62,7 @@ public function __construct(private UrlMatcherInterface $url_matcher)
public static function getSubscribedEvents(): array
{
return [
- KernelEvents::REQUEST => ['onKernelRequest', ListenersPriority::LEGACY_LISTENERS_PRIORITIES[self::class]],
+ KernelEvents::REQUEST => ['onKernelRequest', ListenersPriority::REQUEST_LISTENERS_PRIORITIES[self::class]],
];
}
diff --git a/src/Glpi/Http/Listener/LegacyPostRequestActionsListener.php b/src/Glpi/Http/Listener/LegacyPostRequestActionsListener.php
index cff43cdba17..228cba38a11 100644
--- a/src/Glpi/Http/Listener/LegacyPostRequestActionsListener.php
+++ b/src/Glpi/Http/Listener/LegacyPostRequestActionsListener.php
@@ -37,7 +37,7 @@
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\KernelEvents;
-class LegacyPostRequestActionsListener implements EventSubscriberInterface
+final readonly class LegacyPostRequestActionsListener implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
diff --git a/src/Glpi/Http/Listener/LegacyRouterListener.php b/src/Glpi/Http/Listener/LegacyRouterListener.php
index ffedd0e6f20..58deadd5ab9 100644
--- a/src/Glpi/Http/Listener/LegacyRouterListener.php
+++ b/src/Glpi/Http/Listener/LegacyRouterListener.php
@@ -36,7 +36,7 @@
use Glpi\Controller\LegacyFileLoadController;
use Glpi\Http\LegacyRouterTrait;
-use Glpi\Http\ListenersPriority;
+use Glpi\Kernel\ListenersPriority;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
@@ -57,7 +57,7 @@ public function __construct(
public static function getSubscribedEvents(): array
{
return [
- KernelEvents::REQUEST => ['onKernelRequest', ListenersPriority::LEGACY_LISTENERS_PRIORITIES[self::class]],
+ KernelEvents::REQUEST => ['onKernelRequest', ListenersPriority::REQUEST_LISTENERS_PRIORITIES[self::class]],
];
}
diff --git a/src/Glpi/Http/Listener/PluginsRouterListener.php b/src/Glpi/Http/Listener/PluginsRouterListener.php
index 56e369d3a0c..d98d79a32ea 100644
--- a/src/Glpi/Http/Listener/PluginsRouterListener.php
+++ b/src/Glpi/Http/Listener/PluginsRouterListener.php
@@ -37,7 +37,7 @@
use Glpi\Controller\AbstractController;
use Glpi\DependencyInjection\PluginContainer;
use Glpi\DependencyInjection\PublicService;
-use Glpi\Http\ListenersPriority;
+use Glpi\Kernel\ListenersPriority;
use Plugin;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
@@ -46,19 +46,19 @@
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Component\Routing\Router;
-class PluginsRouterListener implements EventSubscriberInterface
+final readonly class PluginsRouterListener implements EventSubscriberInterface
{
public const ROUTE_NAME = 'glpi_plugin';
public function __construct(
- private readonly PluginContainer $plugin_container,
+ private PluginContainer $plugin_container,
) {
}
public static function getSubscribedEvents(): array
{
return [
- KernelEvents::REQUEST => ['onKernelRequest', ListenersPriority::LEGACY_LISTENERS_PRIORITIES[self::class]],
+ KernelEvents::REQUEST => ['onKernelRequest', ListenersPriority::REQUEST_LISTENERS_PRIORITIES[self::class]],
];
}
diff --git a/src/Glpi/Http/Listener/RedirectExceptionListener.php b/src/Glpi/Http/Listener/RedirectExceptionListener.php
index 1cef7cc5af0..c9c358d4d6b 100644
--- a/src/Glpi/Http/Listener/RedirectExceptionListener.php
+++ b/src/Glpi/Http/Listener/RedirectExceptionListener.php
@@ -39,7 +39,7 @@
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\KernelEvents;
-final class RedirectExceptionListener implements EventSubscriberInterface
+final readonly class RedirectExceptionListener implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
diff --git a/src/Glpi/Http/Listener/RedirectLegacyRouteListener.php b/src/Glpi/Http/Listener/RedirectLegacyRouteListener.php
index 32620826600..08cd46764ea 100644
--- a/src/Glpi/Http/Listener/RedirectLegacyRouteListener.php
+++ b/src/Glpi/Http/Listener/RedirectLegacyRouteListener.php
@@ -34,7 +34,7 @@
namespace Glpi\Http\Listener;
-use Glpi\Http\ListenersPriority;
+use Glpi\Kernel\ListenersPriority;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpKernel\Event\RequestEvent;
@@ -49,7 +49,7 @@
public static function getSubscribedEvents(): array
{
return [
- KernelEvents::REQUEST => ['onKernelRequest', ListenersPriority::LEGACY_LISTENERS_PRIORITIES[self::class]],
+ KernelEvents::REQUEST => ['onKernelRequest', ListenersPriority::REQUEST_LISTENERS_PRIORITIES[self::class]],
];
}
diff --git a/src/Glpi/Http/Listener/SessionCheckCookieListener.php b/src/Glpi/Http/Listener/SessionCheckCookieListener.php
new file mode 100644
index 00000000000..61ffcf6d726
--- /dev/null
+++ b/src/Glpi/Http/Listener/SessionCheckCookieListener.php
@@ -0,0 +1,74 @@
+.
+ *
+ * ---------------------------------------------------------------------
+ */
+
+namespace Glpi\Http\Listener;
+
+use Glpi\Exception\Http\BadRequestHttpException;
+use Glpi\Http\RequestPoliciesTrait;
+use Glpi\Kernel\ListenersPriority;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Symfony\Component\HttpKernel\Event\RequestEvent;
+use Symfony\Component\HttpKernel\KernelEvents;
+
+class SessionCheckCookieListener implements EventSubscriberInterface
+{
+ use RequestPoliciesTrait;
+
+ public static function getSubscribedEvents(): array
+ {
+ return [
+ KernelEvents::REQUEST => ['onKernelRequest', ListenersPriority::REQUEST_LISTENERS_PRIORITIES[self::class]],
+ ];
+ }
+
+ public function onKernelRequest(RequestEvent $event): void
+ {
+ if (!$event->isMainRequest()) {
+ return;
+ }
+
+ if ($this->isFrontEndAssetEndpoint($event->getRequest())) {
+ return;
+ }
+
+ // If session cookie is only available on a secure HTTPS context but request is made on an unsecured HTTP context,
+ // throw an exception
+ $cookie_secure = filter_var(ini_get('session.cookie_secure'), FILTER_VALIDATE_BOOLEAN);
+ if ($event->getRequest()->isSecure() === false && $cookie_secure === true) {
+ $exception = new BadRequestHttpException();
+ $exception->setMessageToDisplay(__('The web server is configured to allow session cookies only on secured context (https). Therefore, you must access GLPI on a secured context to be able to use it.'));
+ throw $exception;
+ }
+ }
+}
diff --git a/src/Glpi/Http/ListenersPriority.php b/src/Glpi/Http/ListenersPriority.php
deleted file mode 100644
index b2f99e4bf13..00000000000
--- a/src/Glpi/Http/ListenersPriority.php
+++ /dev/null
@@ -1,78 +0,0 @@
-.
- *
- * ---------------------------------------------------------------------
- */
-
-namespace Glpi\Http;
-
-use Glpi\Config\LegacyConfigProviderListener;
-use Glpi\Http\Listener\LegacyAssetsListener;
-use Glpi\Http\Listener\LegacyItemtypeRouteListener;
-use Glpi\Http\Listener\LegacyRouterListener;
-use Glpi\Http\Listener\PluginsRouterListener;
-use Glpi\Http\Listener\RedirectLegacyRouteListener;
-
-final class ListenersPriority
-{
- public const LEGACY_LISTENERS_PRIORITIES = [
- // Static assets must be served without executing anything else.
- // Keep them on top priority.
- LegacyAssetsListener::class => 500,
-
- LegacyRouterListener::class => 400,
-
- // Legacy URLs redirections does not require any complex logic. It can be done prior to
- // GLPI config and plugins initialization.
- RedirectLegacyRouteListener::class => 375,
-
- // Config providers may still expect some `$_SERVER` variables to be redefined.
- // They must therefore be executed after the `LegacyRouterListener`.
- LegacyConfigProviderListener::class => 350,
-
- // Plugins itemtypes requires plugins to be initialized, therefore config must be already set.
- // Also, keep it after the `LegacyRouterListener` to not map to the generic controller if a
- // legacy script exists for the requested URI.
- LegacyItemtypeRouteListener::class => 300,
-
- // This listener allows matching plugins routes at runtime,
- // that's why it's executed right after Symfony's Router,
- // and also after GLPI's config is set.
- //
- // Symfony's Router priority is 32.
- // @see \Symfony\Component\HttpKernel\EventListener\RouterListener::getSubscribedEvents()
- PluginsRouterListener::class => 31,
- ];
-
- private function __construct()
- {
- }
-}
diff --git a/src/Glpi/Http/RequestPoliciesTrait.php b/src/Glpi/Http/RequestPoliciesTrait.php
new file mode 100644
index 00000000000..c2c867876db
--- /dev/null
+++ b/src/Glpi/Http/RequestPoliciesTrait.php
@@ -0,0 +1,86 @@
+.
+ *
+ * ---------------------------------------------------------------------
+ */
+
+namespace Glpi\Http;
+
+use Symfony\Component\HttpFoundation\Request;
+
+trait RequestPoliciesTrait
+{
+ /**
+ * Indicates the requested resource is made on a front-end asset endpoint.
+ */
+ protected function isFrontEndAssetEndpoint(Request $request): bool
+ {
+ $path = $request->getPathInfo();
+
+ return \str_starts_with($path, '/js/')
+ || \str_starts_with($path, '/front/css.php')
+ || \str_starts_with($path, '/front/locale.php');
+ }
+
+ /**
+ * Indicates the requested resource is made on the Symfony profiler resources.
+ */
+ protected function isSymfonyProfilerEndpoint(Request $request): bool
+ {
+ $path = $request->getPathInfo();
+
+ return \str_starts_with($path, '/_profiler/')
+ || \str_starts_with($path, '/_wdt/');
+ }
+
+ /**
+ * Indicates whether the DB status should be checked for the given request.
+ */
+ protected function shouldCheckDbStatus(Request $request): bool
+ {
+ $path = $request->getPathInfo();
+
+ if ($this->isFrontEndAssetEndpoint($request) || $this->isSymfonyProfilerEndpoint($request)) {
+ // These resources should always be available.
+ return false;
+ }
+
+ if (
+ \str_starts_with($path, '/install/')
+ || ($_SESSION['is_installing'] ?? false)
+ ) {
+ // DB status should never be checked when the requested endpoint is part of the install process.
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/src/Glpi/Kernel/Kernel.php b/src/Glpi/Kernel/Kernel.php
index 99717ab5f3e..b8c8254d20b 100644
--- a/src/Glpi/Kernel/Kernel.php
+++ b/src/Glpi/Kernel/Kernel.php
@@ -36,9 +36,6 @@
use GLPI;
use Glpi\Application\SystemConfigurator;
-use Glpi\Config\ConfigProviderConsoleExclusiveInterface;
-use Glpi\Config\ConfigProviderWithRequestInterface;
-use Glpi\Config\LegacyConfigProviders;
use Glpi\Http\Listener\PluginsRouterListener;
use Symfony\Bundle\FrameworkBundle\FrameworkBundle;
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
@@ -111,30 +108,14 @@ public function registerBundles(): iterable
return $bundles;
}
- public function loadCommonGlobalConfig(): void
+ public function boot(): void
{
- $this->boot();
+ $dispatch_postboot = !$this->booted;
- /** @var LegacyConfigProviders $providers */
- $providers = $this->container->get(LegacyConfigProviders::class);
- foreach ($providers->getProviders() as $provider) {
- if ($provider instanceof ConfigProviderWithRequestInterface) {
- continue;
- }
- $provider->execute();
- }
- }
+ parent::boot();
- public function loadCliConsoleOnlyConfig(): void
- {
- $this->boot();
-
- /** @var LegacyConfigProviders $providers */
- $providers = $this->container->get(LegacyConfigProviders::class);
- foreach ($providers->getProviders() as $provider) {
- if ($provider instanceof ConfigProviderConsoleExclusiveInterface) {
- $provider->execute();
- }
+ if ($dispatch_postboot) {
+ $this->container->get('event_dispatcher')->dispatch(new PostBootEvent());
}
}
diff --git a/src/Glpi/Config/LegacyConfigurators/CustomObjectsAutoloader.php b/src/Glpi/Kernel/Listener/CustomObjectsAutoloaderRegistration.php
similarity index 64%
rename from src/Glpi/Config/LegacyConfigurators/CustomObjectsAutoloader.php
rename to src/Glpi/Kernel/Listener/CustomObjectsAutoloaderRegistration.php
index 6b2ac629e05..fd1afcf036d 100644
--- a/src/Glpi/Config/LegacyConfigurators/CustomObjectsAutoloader.php
+++ b/src/Glpi/Kernel/Listener/CustomObjectsAutoloaderRegistration.php
@@ -32,26 +32,38 @@
* ---------------------------------------------------------------------
*/
-namespace Glpi\Config\LegacyConfigurators;
+namespace Glpi\Kernel\Listener;
use DBConnection;
use Glpi\Asset\AssetDefinitionManager;
-use Glpi\Config\LegacyConfigProviderInterface;
use Glpi\Debug\Profiler;
use Glpi\Dropdown\DropdownDefinitionManager;
+use Glpi\Kernel\ListenersPriority;
+use Glpi\Kernel\PostBootEvent;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Update;
-final readonly class CustomObjectsAutoloader implements LegacyConfigProviderInterface
+final readonly class CustomObjectsAutoloaderRegistration implements EventSubscriberInterface
{
- public function execute(): void
+ public static function getSubscribedEvents(): array
{
- if (isset($_SESSION['is_installing']) || !DBConnection::isDbAvailable()) {
+ return [
+ PostBootEvent::class => ['onPostBoot', ListenersPriority::POST_BOOT_LISTENERS_PRIORITIES[self::class]],
+ ];
+ }
+
+ public function onPostBoot(): void
+ {
+ if (!DBConnection::isDbAvailable() || (!defined('SKIP_UPDATES') && !Update::isDbUpToDate())) {
// Requires the database to be available.
return;
}
- Profiler::getInstance()->start('CustomObjectsAutoloader::execute', Profiler::CATEGORY_BOOT);
+ Profiler::getInstance()->start('CustomObjectsAutoloaderRegistration::execute', Profiler::CATEGORY_BOOT);
+
AssetDefinitionManager::getInstance()->registerAutoload();
DropdownDefinitionManager::getInstance()->registerAutoload();
- Profiler::getInstance()->stop('CustomObjectsAutoloader::execute');
+
+ Profiler::getInstance()->stop('CustomObjectsAutoloaderRegistration::execute');
}
}
diff --git a/src/Glpi/Config/LegacyConfigurators/CustomObjectsBootstrap.php b/src/Glpi/Kernel/Listener/CustomObjectsBootstrap.php
similarity index 73%
rename from src/Glpi/Config/LegacyConfigurators/CustomObjectsBootstrap.php
rename to src/Glpi/Kernel/Listener/CustomObjectsBootstrap.php
index fda3f7144af..0c92e12f1a2 100644
--- a/src/Glpi/Config/LegacyConfigurators/CustomObjectsBootstrap.php
+++ b/src/Glpi/Kernel/Listener/CustomObjectsBootstrap.php
@@ -32,26 +32,38 @@
* ---------------------------------------------------------------------
*/
-namespace Glpi\Config\LegacyConfigurators;
+namespace Glpi\Kernel\Listener;
use DBConnection;
use Glpi\Asset\AssetDefinitionManager;
-use Glpi\Config\LegacyConfigProviderInterface;
use Glpi\Debug\Profiler;
use Glpi\Dropdown\DropdownDefinitionManager;
+use Glpi\Kernel\ListenersPriority;
+use Glpi\Kernel\PostBootEvent;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Update;
-final readonly class CustomObjectsBootstrap implements LegacyConfigProviderInterface
+final readonly class CustomObjectsBootstrap implements EventSubscriberInterface
{
- public function execute(): void
+ public static function getSubscribedEvents(): array
{
- if (isset($_SESSION['is_installing']) || !DBConnection::isDbAvailable()) {
+ return [
+ PostBootEvent::class => ['onPostBoot', ListenersPriority::POST_BOOT_LISTENERS_PRIORITIES[self::class]],
+ ];
+ }
+
+ public function onPostBoot(): void
+ {
+ if (!DBConnection::isDbAvailable() || (!defined('SKIP_UPDATES') && !Update::isDbUpToDate())) {
// Requires the database to be available.
return;
}
Profiler::getInstance()->start('CustomObjectsBootstrap::execute', Profiler::CATEGORY_BOOT);
+
AssetDefinitionManager::getInstance()->bootstrapDefinitions();
DropdownDefinitionManager::getInstance()->bootstrapDefinitions();
+
Profiler::getInstance()->stop('CustomObjectsBootstrap::execute');
}
}
diff --git a/src/Glpi/Kernel/Listener/InitializeCache.php b/src/Glpi/Kernel/Listener/InitializeCache.php
new file mode 100644
index 00000000000..d06934206ed
--- /dev/null
+++ b/src/Glpi/Kernel/Listener/InitializeCache.php
@@ -0,0 +1,65 @@
+.
+ *
+ * ---------------------------------------------------------------------
+ */
+
+namespace Glpi\Kernel\Listener;
+
+use Glpi\Cache\CacheManager;
+use Glpi\Debug\Profiler;
+use Glpi\Kernel\ListenersPriority;
+use Glpi\Kernel\PostBootEvent;
+use Psr\SimpleCache\CacheInterface;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+final readonly class InitializeCache implements EventSubscriberInterface
+{
+ public static function getSubscribedEvents(): array
+ {
+ return [
+ PostBootEvent::class => ['onPostBoot', ListenersPriority::POST_BOOT_LISTENERS_PRIORITIES[self::class]],
+ ];
+ }
+
+ public function onPostBoot(): void
+ {
+ /** @var CacheInterface|null $GLPI_CACHE */
+ global $GLPI_CACHE;
+
+ Profiler::getInstance()->start('InitializeCache::execute', Profiler::CATEGORY_BOOT);
+
+ $cache_manager = new CacheManager();
+ $GLPI_CACHE = $cache_manager->getCoreCacheInstance();
+
+ Profiler::getInstance()->stop('InitializeCache::execute');
+ }
+}
diff --git a/src/Glpi/Kernel/Listener/InitializeDbConnection.php b/src/Glpi/Kernel/Listener/InitializeDbConnection.php
new file mode 100644
index 00000000000..cb4aa58c8a0
--- /dev/null
+++ b/src/Glpi/Kernel/Listener/InitializeDbConnection.php
@@ -0,0 +1,66 @@
+.
+ *
+ * ---------------------------------------------------------------------
+ */
+
+namespace Glpi\Kernel\Listener;
+
+use DBConnection;
+use Glpi\Debug\Profiler;
+use Glpi\Kernel\ListenersPriority;
+use Glpi\Kernel\PostBootEvent;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+final readonly class InitializeDbConnection implements EventSubscriberInterface
+{
+ public static function getSubscribedEvents(): array
+ {
+ return [
+ PostBootEvent::class => ['onPostBoot', ListenersPriority::POST_BOOT_LISTENERS_PRIORITIES[self::class]],
+ ];
+ }
+
+ public function onPostBoot(): void
+ {
+ Profiler::getInstance()->start('InitializeDbConnection::execute', Profiler::CATEGORY_BOOT);
+
+ if (file_exists(GLPI_CONFIG_DIR . '/config_db.php')) {
+ include_once(GLPI_CONFIG_DIR . '/config_db.php');
+
+ if (\class_exists('DB', false)) {
+ DBConnection::establishDBConnection(false, false);
+ }
+ }
+
+ Profiler::getInstance()->stop('InitializeDbConnection::execute');
+ }
+}
diff --git a/src/Glpi/Config/LegacyConfigurators/InitializePlugins.php b/src/Glpi/Kernel/Listener/InitializePlugins.php
similarity index 71%
rename from src/Glpi/Config/LegacyConfigurators/InitializePlugins.php
rename to src/Glpi/Kernel/Listener/InitializePlugins.php
index 74161aecd24..cea75168bd7 100644
--- a/src/Glpi/Config/LegacyConfigurators/InitializePlugins.php
+++ b/src/Glpi/Kernel/Listener/InitializePlugins.php
@@ -32,35 +32,44 @@
* ---------------------------------------------------------------------
*/
-namespace Glpi\Config\LegacyConfigurators;
+namespace Glpi\Kernel\Listener;
-use Glpi\Config\LegacyConfigProviderInterface;
+use DBConnection;
use Glpi\Debug\Profiler;
use Glpi\DependencyInjection\PluginContainer;
+use Glpi\Kernel\ListenersPriority;
+use Glpi\Kernel\PostBootEvent;
use Plugin;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Update;
-final readonly class InitializePlugins implements LegacyConfigProviderInterface
+final readonly class InitializePlugins implements EventSubscriberInterface
{
public function __construct(private PluginContainer $pluginContainer)
{
}
- public function execute(): void
+ public static function getSubscribedEvents(): array
{
- /*
- * On startup, register all plugins configured for use,
- * except during the database install/update process.
- */
- if (isset($_SESSION['is_installing']) || (!defined('SKIP_UPDATES') && !Update::isDbUpToDate())) {
+ return [
+ PostBootEvent::class => ['onPostBoot', ListenersPriority::POST_BOOT_LISTENERS_PRIORITIES[self::class]],
+ ];
+ }
+
+ public function onPostBoot(): void
+ {
+ if (!DBConnection::isDbAvailable() || (!defined('SKIP_UPDATES') && !Update::isDbUpToDate())) {
+ // Requires the database to be available.
return;
}
Profiler::getInstance()->start('InitializePlugins::execute', Profiler::CATEGORY_BOOT);
+
$plugin = new Plugin();
$plugin->init(true);
$this->pluginContainer->initializeContainer();
+
Profiler::getInstance()->stop('InitializePlugins::execute');
}
}
diff --git a/src/Glpi/Config/LegacyConfigurators/InitializeDbConnection.php b/src/Glpi/Kernel/Listener/LoadLanguage.php
similarity index 61%
rename from src/Glpi/Config/LegacyConfigurators/InitializeDbConnection.php
rename to src/Glpi/Kernel/Listener/LoadLanguage.php
index 09316e97d3b..553f717016a 100644
--- a/src/Glpi/Config/LegacyConfigurators/InitializeDbConnection.php
+++ b/src/Glpi/Kernel/Listener/LoadLanguage.php
@@ -32,29 +32,29 @@
* ---------------------------------------------------------------------
*/
-namespace Glpi\Config\LegacyConfigurators;
+namespace Glpi\Kernel\Listener;
-use DBConnection;
-use Glpi\Config\LegacyConfigProviderInterface;
+use Glpi\Debug\Profiler;
+use Glpi\Kernel\ListenersPriority;
+use Glpi\Kernel\PostBootEvent;
+use Session;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
-final readonly class InitializeDbConnection implements LegacyConfigProviderInterface
+final readonly class LoadLanguage implements EventSubscriberInterface
{
- public function execute(): void
+ public static function getSubscribedEvents(): array
{
- if (isset($_SESSION['is_installing'])) {
- return;
- }
-
- if (!file_exists(GLPI_CONFIG_DIR . '/config_db.php')) {
- return;
- }
+ return [
+ PostBootEvent::class => ['onPostBoot', ListenersPriority::POST_BOOT_LISTENERS_PRIORITIES[self::class]],
+ ];
+ }
- include_once(GLPI_CONFIG_DIR . '/config_db.php');
+ public function onPostBoot(): void
+ {
+ Profiler::getInstance()->start('LoadLanguage::execute', Profiler::CATEGORY_BOOT);
- if (!\class_exists('DB', false)) {
- return;
- }
+ Session::loadLanguage();
- DBConnection::establishDBConnection(false, false);
+ Profiler::getInstance()->stop('LoadLanguage::execute');
}
}
diff --git a/src/Glpi/Config/LegacyConfigurators/LoadLegacyConfiguration.php b/src/Glpi/Kernel/Listener/LoadLegacyConfiguration.php
similarity index 57%
rename from src/Glpi/Config/LegacyConfigurators/LoadLegacyConfiguration.php
rename to src/Glpi/Kernel/Listener/LoadLegacyConfiguration.php
index d2a59f1caf3..55941d098fc 100644
--- a/src/Glpi/Config/LegacyConfigurators/LoadLegacyConfiguration.php
+++ b/src/Glpi/Kernel/Listener/LoadLegacyConfiguration.php
@@ -32,27 +32,41 @@
* ---------------------------------------------------------------------
*/
-namespace Glpi\Config\LegacyConfigurators;
+namespace Glpi\Kernel\Listener;
use Config;
-use Glpi\Config\LegacyConfigProviderInterface;
+use Glpi\Debug\Profiler;
+use Glpi\Kernel\ListenersPriority;
+use Glpi\Kernel\PostBootEvent;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
-final readonly class LoadLegacyConfiguration implements LegacyConfigProviderInterface
+final readonly class LoadLegacyConfiguration implements EventSubscriberInterface
{
- public function execute(): void
+ public static function getSubscribedEvents(): array
+ {
+ return [
+ PostBootEvent::class => ['onPostBoot', ListenersPriority::POST_BOOT_LISTENERS_PRIORITIES[self::class]],
+ ];
+ }
+
+ public function onPostBoot(): void
{
/**
* @var array $CFG_GLPI
*/
global $CFG_GLPI;
- if (isset($_SESSION['is_installing'])) {
- // Force `root_doc` value
- $request = \Symfony\Component\HttpFoundation\Request::createFromGlobals();
- $CFG_GLPI['root_doc'] = $request->getBasePath();
- return;
- }
+ Profiler::getInstance()->start('LoadLegacyConfiguration::execute', Profiler::CATEGORY_BOOT);
Config::loadLegacyConfiguration();
+
+ // Copy the configuration defaults to the session
+ foreach ($CFG_GLPI['user_pref_field'] as $field) {
+ if (!isset($_SESSION["glpi$field"]) && isset($CFG_GLPI[$field])) {
+ $_SESSION["glpi$field"] = $CFG_GLPI[$field];
+ }
+ }
+
+ Profiler::getInstance()->stop('LoadLegacyConfiguration::execute');
}
}
diff --git a/src/Glpi/Config/LegacyConfigurators/ProfilerStart.php b/src/Glpi/Kernel/Listener/ProfilerStart.php
similarity index 64%
rename from src/Glpi/Config/LegacyConfigurators/ProfilerStart.php
rename to src/Glpi/Kernel/Listener/ProfilerStart.php
index 710589882e9..43da95394c7 100644
--- a/src/Glpi/Config/LegacyConfigurators/ProfilerStart.php
+++ b/src/Glpi/Kernel/Listener/ProfilerStart.php
@@ -32,19 +32,38 @@
* ---------------------------------------------------------------------
*/
-namespace Glpi\Config\LegacyConfigurators;
+namespace Glpi\Kernel\Listener;
-use Glpi\Config\LegacyConfigProviderInterface;
+use Session;
+use Glpi\Debug\Profile;
use Glpi\Debug\Profiler;
+use Glpi\Kernel\ListenersPriority;
+use Glpi\Kernel\PostBootEvent;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
-final readonly class ProfilerStart implements LegacyConfigProviderInterface
+final readonly class ProfilerStart implements EventSubscriberInterface
{
- public function execute(): void
+ public static function getSubscribedEvents(): array
+ {
+ return [
+ PostBootEvent::class => ['onPostBoot', ListenersPriority::POST_BOOT_LISTENERS_PRIORITIES[self::class]],
+ ];
+ }
+
+ public function onPostBoot(): void
{
if (isCommandLine()) {
Profiler::getInstance()->disable();
} else {
Profiler::getInstance()->start('php_request');
}
+
+ if (
+ isset($_SESSION['glpi_use_mode'])
+ && ($_SESSION['glpi_use_mode'] == Session::DEBUG_MODE)
+ ) {
+ // Start the debug profile
+ Profile::getCurrent();
+ }
}
}
diff --git a/src/Glpi/Config/LegacyConfigurators/SessionStart.php b/src/Glpi/Kernel/Listener/SessionStart.php
similarity index 85%
rename from src/Glpi/Config/LegacyConfigurators/SessionStart.php
rename to src/Glpi/Kernel/Listener/SessionStart.php
index 35d790114f2..a2f754b8db3 100644
--- a/src/Glpi/Config/LegacyConfigurators/SessionStart.php
+++ b/src/Glpi/Kernel/Listener/SessionStart.php
@@ -32,15 +32,24 @@
* ---------------------------------------------------------------------
*/
-namespace Glpi\Config\LegacyConfigurators;
+namespace Glpi\Kernel\Listener;
+use Glpi\Kernel\ListenersPriority;
+use Glpi\Kernel\PostBootEvent;
use Session;
-use Glpi\Config\LegacyConfigProviderInterface;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
-final class SessionStart implements LegacyConfigProviderInterface
+final readonly class SessionStart implements EventSubscriberInterface
{
- public function execute(): void
+ public static function getSubscribedEvents(): array
+ {
+ return [
+ PostBootEvent::class => ['onPostBoot', ListenersPriority::POST_BOOT_LISTENERS_PRIORITIES[self::class]],
+ ];
+ }
+
+ public function onPostBoot(): void
{
// The session must be started even in CLI context.
// The GLPI code refers to the session in many places
@@ -57,7 +66,7 @@ public function execute(): void
if (\str_starts_with($path, '/api.php') || \str_starts_with($path, '/apirest.php')) {
// API clients must not use cookies, as the session token is expected to be passed in headers.
$use_cookies = false;
- // The API endpoint is strating the session manually.
+ // The API endpoint is starting the session manually.
$start_session = false;
} elseif (\str_starts_with($path, '/caldav.php')) {
// CalDAV clients must not use cookies, as the authentication is expected to be passed in headers.
diff --git a/src/Glpi/Kernel/ListenersPriority.php b/src/Glpi/Kernel/ListenersPriority.php
new file mode 100644
index 00000000000..2553a7c23b2
--- /dev/null
+++ b/src/Glpi/Kernel/ListenersPriority.php
@@ -0,0 +1,96 @@
+.
+ *
+ * ---------------------------------------------------------------------
+ */
+
+namespace Glpi\Kernel;
+
+use Glpi\Http\Listener\LegacyConfigProviderListener;
+use Glpi\Kernel\Listener as KernelListener;
+use Glpi\Http\Listener as HttpListener;
+
+final class ListenersPriority
+{
+ public const POST_BOOT_LISTENERS_PRIORITIES = [
+ KernelListener\SessionStart::class => 200,
+ KernelListener\ProfilerStart::class => 190,
+ KernelListener\InitializeDbConnection::class => 180,
+ KernelListener\InitializeCache::class => 170,
+ KernelListener\LoadLegacyConfiguration::class => 160,
+ KernelListener\CustomObjectsAutoloaderRegistration::class => 150,
+ KernelListener\InitializePlugins::class => 140,
+ KernelListener\CustomObjectsBootstrap::class => 130,
+ KernelListener\LoadLanguage::class => 120,
+ ];
+
+ public const REQUEST_LISTENERS_PRIORITIES = [
+ // Static assets must be served without executing anything else.
+ // Keep them on top priority.
+ HttpListener\LegacyAssetsListener::class => 500,
+
+ // This listener will ensure that the request is made on a secure context (HTTPS) when the
+ // cookies are available only on a secure context (`session.cookie_secure=on`).
+ // It must be executed before trying to serve any statefull endpoint.
+ HttpListener\SessionCheckCookieListener::class => 475,
+
+ // This listener will ensure that the database connection is configured and available.
+ // It must be executed before executing any controller (except controllers related to front-end assets).
+ HttpListener\CheckDatabaseStatusListener::class => 450,
+
+ // Legacy config providers.
+ // FIXME: Reorganize them and transform them into HTTP request listeners to register them here directly.
+ LegacyConfigProviderListener::class => 425,
+
+ // Executes the legacy controller scripts (`/ajax/*.php` or `/front/*.php` scripts) whenever the
+ // requested URI matches an existing file.
+ HttpListener\LegacyRouterListener::class => 400,
+
+ // Map legacy scripts URLS (e.g. `/front/computer.php`) to modern controllers.
+ // Must be executed after the `LegacyRouterListener` to ensure to use the legacy script if it exists.
+ HttpListener\LegacyItemtypeRouteListener::class => 375,
+
+ // Legacy URLs redirections.
+ HttpListener\RedirectLegacyRouteListener::class => 350,
+
+ // This listener allows matching plugins routes at runtime,
+ // that's why it's executed right after Symfony's Router,
+ // and also after GLPI's config is set.
+ //
+ // Symfony's Router priority is 32.
+ // @see \Symfony\Component\HttpKernel\EventListener\RouterListener::getSubscribedEvents()
+ HttpListener\PluginsRouterListener::class => 31,
+ ];
+
+ private function __construct()
+ {
+ }
+}
diff --git a/src/Glpi/Config/ConfigProviderConsoleExclusiveInterface.php b/src/Glpi/Kernel/PostBootEvent.php
similarity index 93%
rename from src/Glpi/Config/ConfigProviderConsoleExclusiveInterface.php
rename to src/Glpi/Kernel/PostBootEvent.php
index ffcf06822da..bc839e160ee 100644
--- a/src/Glpi/Config/ConfigProviderConsoleExclusiveInterface.php
+++ b/src/Glpi/Kernel/PostBootEvent.php
@@ -32,8 +32,8 @@
* ---------------------------------------------------------------------
*/
-namespace Glpi\Config;
+namespace Glpi\Kernel;
-interface ConfigProviderConsoleExclusiveInterface
+class PostBootEvent
{
}
diff --git a/src/Session.php b/src/Session.php
index 7838f8ee49d..0db48d8ad4a 100644
--- a/src/Session.php
+++ b/src/Session.php
@@ -38,7 +38,6 @@
use Glpi\Controller\InventoryController;
use Glpi\Event;
use Glpi\Exception\Http\AccessDeniedHttpException;
-use Glpi\Exception\Http\BadRequestHttpException;
use Glpi\Exception\SessionExpiredException;
use Glpi\Plugin\Hooks;
use Glpi\Session\SessionInfo;
@@ -268,6 +267,11 @@ public static function start()
if (!isset($_SESSION['glpi_use_mode'])) {
$_SESSION['glpi_use_mode'] = Session::NORMAL_MODE;
}
+
+ // Define default language
+ if (!isset($_SESSION['glpilanguage'])) {
+ $_SESSION['glpilanguage'] = Session::getPreferredLanguage();
+ }
}
@@ -1004,23 +1008,6 @@ public static function redirectIfNotLoggedIn()
}
}
- /**
- * Check the `session.cookie_secure` configuration and throw an exception if the
- * current request context is not allowed to use session cookies.
- */
- public static function checkCookieSecureConfig(): void
- {
- // If session cookie is only available on a secure HTTPS context but request is made on an unsecured HTTP context,
- // throw an exception
- $cookie_secure = filter_var(ini_get('session.cookie_secure'), FILTER_VALIDATE_BOOLEAN);
- $is_https_request = ($_SERVER['HTTPS'] ?? 'off') === 'on' || (int)($_SERVER['SERVER_PORT'] ?? null) == 443;
- if ($is_https_request === false && $cookie_secure === true) {
- $exception = new BadRequestHttpException();
- $exception->setMessageToDisplay(__('The web server is configured to allow session cookies only on secured context (https). Therefore, you must access GLPI on a secured context to be able to use it.'));
- throw $exception;
- }
- }
-
/**
* Global check of session to prevent PHP vulnerability
*
diff --git a/templates/error_block.html.twig b/templates/error_block.html.twig
index 2d3a4eaa701..4a92cb39513 100644
--- a/templates/error_block.html.twig
+++ b/templates/error_block.html.twig
@@ -41,7 +41,7 @@
{{ message }}
{% if link_url is not empty %}
- {{ link_text }}
+ {{ link_text }}
{% endif %}
diff --git a/tests/bin/test-updated-data b/tests/bin/test-updated-data
index 12d70ea4e62..2b34913c018 100755
--- a/tests/bin/test-updated-data
+++ b/tests/bin/test-updated-data
@@ -37,7 +37,7 @@
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
$kernel = new \Glpi\Kernel\Kernel('testing');
-$kernel->loadCommonGlobalConfig();
+$kernel->boot();
$command = new \Glpi\Tests\Command\TestUpdatedDataCommand();
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
index 82b4d3a44bf..75e8ffd1620 100644
--- a/tests/bootstrap.php
+++ b/tests/bootstrap.php
@@ -48,17 +48,21 @@
define('TU_USER', '_test_user');
define('TU_PASS', 'PhpUnit_4');
-global $CFG_GLPI, $GLPI_CACHE;
+global $GLPI_CACHE;
require_once dirname(__DIR__) . '/vendor/autoload.php';
$kernel = new Kernel('testing');
-$kernel->loadCommonGlobalConfig();
+$kernel->boot();
if (!file_exists(GLPI_CONFIG_DIR . '/config_db.php')) {
echo("\nConfiguration file for tests not found\n\nrun: php bin/console database:install --env=testing ...\n\n");
exit(1);
}
+if (!defined('SKIP_UPDATES') && !Update::isDbUpToDate()) {
+ echo 'The GLPI codebase has been updated. The update of the GLPI database is necessary.' . PHP_EOL;
+ exit(1);
+}
//init cache
if (file_exists(GLPI_CONFIG_DIR . DIRECTORY_SEPARATOR . CacheManager::CONFIG_FILENAME)) {
diff --git a/tests/cypress/e2e/form/question_types/dropdown.cy.js b/tests/cypress/e2e/form/question_types/dropdown.cy.js
index 19730bf01b4..958a1656359 100644
--- a/tests/cypress/e2e/form/question_types/dropdown.cy.js
+++ b/tests/cypress/e2e/form/question_types/dropdown.cy.js
@@ -147,6 +147,10 @@ describe('Dropdown form question type', () => {
// Click on the question
cy.get("@question").click('top');
+ // TODO: Investigate why this 'wait' is needed and fix it.
+ // eslint-disable-next-line cypress/no-unnecessary-waiting
+ cy.wait(200);
+
// Check selected options and option labels
checkSelectedOptions([2]);
checkOptionLabels(["Option 1", "Option 2", "Option 3"]);
diff --git a/tests/cypress/e2e/search/display_preferences.cy.js b/tests/cypress/e2e/search/display_preferences.cy.js
index 1b6559579bc..b5c334a5488 100644
--- a/tests/cypress/e2e/search/display_preferences.cy.js
+++ b/tests/cypress/e2e/search/display_preferences.cy.js
@@ -30,7 +30,7 @@
* ---------------------------------------------------------------------
*/
-describe('Display preferences', {retries: {runMode: 5}}, () => {
+describe('Display preferences', () => {
before(() => {
// Create at least one ticket as we will be displaying the ticket list
// to validate that the right columns are displayed
@@ -47,7 +47,7 @@ describe('Display preferences', {retries: {runMode: 5}}, () => {
openDisplayPreferences();
// Add a new column to the global view
- goToTab('Global View');
+ goToTab('Global View', true);
addDisplayPeference('Pending reason');
// Refresh page
@@ -86,7 +86,7 @@ describe('Display preferences', {retries: {runMode: 5}}, () => {
openDisplayPreferences();
// Add a new column to the global view
- goToTab('Helpdesk View');
+ goToTab('Helpdesk View', true);
addDisplayPeference('Pending reason');
// Refresh page
@@ -135,11 +135,23 @@ describe('Display preferences', {retries: {runMode: 5}}, () => {
;
}
- function goToTab(name) {
+ function goToTab(name, wait = false) {
+ if (wait) {
+ // When changing tabs for the first time, we must wait for the
+ // js hanlder to be loaded.
+ // Sadly, there is no easy way to determine this without waiting
+ // an arbitrary amount of time.
+ // eslint-disable-next-line cypress/no-unnecessary-waiting
+ cy.wait(250);
+ }
+
+ cy.intercept('GET', '/ajax/common.tabs.php?*').as('refresh_tab_request');
cy.get('@iframeBody').find('#tabspanel-select').select(name);
+ cy.wait('@refresh_tab_request');
}
function addDisplayPeference(name) {
+ cy.intercept('POST', '/ajax/displaypreference.php').as('update_request');
cy.get('@iframeBody')
.getDropdownByLabelText('Select an option to add')
.click()
@@ -152,15 +164,18 @@ describe('Display preferences', {retries: {runMode: 5}}, () => {
.findByRole('button', {'name': 'Add'})
.click()
;
+ cy.wait('@update_request');
}
function deletePreference(name) {
+ cy.intercept('POST', '/ajax/displaypreference.php').as('update_request');
cy.get('@iframeBody')
.findByRole('list')
.findByRole('option', {'name': name}) // Should be listitem instead of option, our DOM is wrong
.findByRole('button', {'name': "Delete permanently"})
.click()
;
+ cy.wait('@update_request');
}
function validateThatDisplayPreferenceExist(name) {
diff --git a/tools/bin/check-twig-templates-syntax b/tools/bin/check-twig-templates-syntax
index a127d0c6821..285ab0821f7 100755
--- a/tools/bin/check-twig-templates-syntax
+++ b/tools/bin/check-twig-templates-syntax
@@ -37,7 +37,7 @@
require_once dirname(__DIR__, 2) . '/vendor/autoload.php';
$kernel = new \Glpi\Kernel\Kernel('testing');
-$kernel->loadCliConsoleOnlyConfig();
+$kernel->boot();
$command = new \Glpi\Tools\Command\CheckTwigTemplatesSyntaxCommand();
diff --git a/tools/cachebench.php b/tools/cachebench.php
index fa62847371d..69871efac86 100644
--- a/tools/cachebench.php
+++ b/tools/cachebench.php
@@ -41,7 +41,7 @@
require dirname(__DIR__) . '/vendor/autoload.php';
$kernel = new \Glpi\Kernel\Kernel();
-$kernel->loadCommonGlobalConfig();
+$kernel->boot();
define('PER_LEVEL', 8);
define('COUNT', 1024);
diff --git a/tools/fake_metrics.php b/tools/fake_metrics.php
index 58ad9a60fb7..9e5f6ced6dd 100644
--- a/tools/fake_metrics.php
+++ b/tools/fake_metrics.php
@@ -41,7 +41,7 @@
require dirname(__DIR__) . '/vendor/autoload.php';
$kernel = new \Glpi\Kernel\Kernel();
-$kernel->loadCommonGlobalConfig();
+$kernel->boot();
$printers_id = false;
$networkports_id = false;
diff --git a/tools/fk_generate.php b/tools/fk_generate.php
index 4f9c73cba9e..66bf52fbb05 100644
--- a/tools/fk_generate.php
+++ b/tools/fk_generate.php
@@ -41,7 +41,7 @@
require dirname(__DIR__) . '/vendor/autoload.php';
$kernel = new \Glpi\Kernel\Kernel();
-$kernel->loadCommonGlobalConfig();
+$kernel->boot();
$DB->query("SET FOREIGN_KEY_CHECKS = '0';");
$result = $DB->list_tables();
diff --git a/tools/getsearchoptions.php b/tools/getsearchoptions.php
index 5e4bf273f1a..53ebcd4c218 100644
--- a/tools/getsearchoptions.php
+++ b/tools/getsearchoptions.php
@@ -43,7 +43,7 @@
require dirname(__DIR__) . '/vendor/autoload.php';
$kernel = new \Glpi\Kernel\Kernel();
-$kernel->loadCommonGlobalConfig();
+$kernel->boot();
if (isset($_SERVER['argv'])) {
for ($i = 1; $i < $_SERVER['argc']; $i++) {
diff --git a/tools/inventory.php b/tools/inventory.php
index a81b48d43cf..52781c2c743 100644
--- a/tools/inventory.php
+++ b/tools/inventory.php
@@ -39,7 +39,7 @@
require dirname(__DIR__) . '/vendor/autoload.php';
$kernel = new Kernel('testing');
-$kernel->loadCommonGlobalConfig();
+$kernel->boot();
$conf = new Conf();
if ($conf->enabled_inventory != 1) {
diff --git a/tools/testmail.php b/tools/testmail.php
index 1e63cbc67ea..5a20f5e42ad 100644
--- a/tools/testmail.php
+++ b/tools/testmail.php
@@ -41,7 +41,7 @@
require dirname(__DIR__) . '/vendor/autoload.php';
$kernel = new \Glpi\Kernel\Kernel();
-$kernel->loadCommonGlobalConfig();
+$kernel->boot();
if (isset($_SERVER['argc'])) {
for ($i = 1; $i < $_SERVER['argc']; $i++) {
diff --git a/tools/update_registered_ids.php b/tools/update_registered_ids.php
index b13d3d5ce95..6f5749d09cd 100644
--- a/tools/update_registered_ids.php
+++ b/tools/update_registered_ids.php
@@ -41,7 +41,7 @@
require dirname(__DIR__) . '/vendor/autoload.php';
$kernel = new \Glpi\Kernel\Kernel();
-$kernel->loadCommonGlobalConfig();
+$kernel->boot();
$registeredid = new RegisteredID();
$manufacturer = new Manufacturer();