diff --git a/src/Glpi/Config/LegacyConfigurators/StandardIncludes.php b/src/Glpi/Config/LegacyConfigurators/StandardIncludes.php index 6be0bc80f14..b90de6fa79e 100644 --- a/src/Glpi/Config/LegacyConfigurators/StandardIncludes.php +++ b/src/Glpi/Config/LegacyConfigurators/StandardIncludes.php @@ -34,19 +34,11 @@ namespace Glpi\Config\LegacyConfigurators; -use Config; use Glpi\Application\View\TemplateRenderer; 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 Toolbox; -use Update; final class StandardIncludes implements LegacyConfigProviderInterface, ConfigProviderWithRequestInterface { @@ -62,10 +54,10 @@ public function execute(): void // Check maintenance mode if ( - !$this->isFrontEndAssetEndpoint($this->getRequest()) - && !$this->isSymfonyProfilerEndpoint($this->getRequest()) - && isset($CFG_GLPI["maintenance_mode"]) + isset($CFG_GLPI["maintenance_mode"]) && $CFG_GLPI["maintenance_mode"] + && !$this->isFrontEndAssetEndpoint($this->getRequest()) + && !$this->isSymfonyProfilerEndpoint($this->getRequest()) ) { if (isset($_GET['skipMaintenance']) && $_GET['skipMaintenance']) { $_SESSION["glpiskipMaintenance"] = 1; @@ -79,77 +71,5 @@ public function execute(): void exit(); } } - - // Check version - 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); - - /** @var \DBmysql $DB */ - global $DB; - - $requirements = (new RequirementsManager())->getCoreRequirementList($DB); - $requirements->add(new DatabaseTablesEngine($DB)); - - $twig_params = [ - 'core_requirements' => $requirements, - 'try_again' => __('Try again'), - 'update_needed' => __('The GLPI codebase has been updated. The update of the GLPI database is necessary.'), - 'upgrade' => _sx('button', 'Upgrade'), - 'outdated_files' => __('You are trying to use GLPI with outdated files compared to the version of the database. Please install the correct GLPI files corresponding to the version of your database.'), - 'stable_release' => VersionParser::isStableRelease(GLPI_VERSION), - 'agree_unstable' => Config::agreeUnstableMessage(VersionParser::isDevVersion(GLPI_VERSION)), - 'outdated' => version_compare( - VersionParser::getNormalizedVersion($CFG_GLPI['version'] ?? '0.0.0-dev'), - VersionParser::getNormalizedVersion(GLPI_VERSION), - '>' - ) - ]; - - Html::nullHeader(__('Update needed'), $CFG_GLPI["root_doc"]); - // language=Twig - echo TemplateRenderer::getInstance()->renderFromStringTemplate(<< -
-
-
- {% include 'install/blocks/requirements_table.html.twig' with {'requirements': core_requirements} %} - {% if core_requirements.hasMissingMandatoryRequirements() or core_requirements.hasMissingOptionalRequirements() %} -
- -
- {% endif %} - {% if not core_requirements.hasMissingMandatoryRequirements() %} - {% if not outdated %} -
- - {% if not stable_release %} - {{ agree_unstable|raw }} - {% endif %} -

- {{ update_needed }} -

- -
- {% else %} -

- {{ outdated_files }} -

- {% endif %} - {% endif %} -
-
-
- -TWIG, $twig_params); - Html::nullFooter(); - $_SESSION['glpi_use_mode'] = $debug_mode; - exit(); - } } } diff --git a/src/Glpi/Controller/NeedsUpdateController.php b/src/Glpi/Controller/NeedsUpdateController.php new file mode 100644 index 00000000000..8cf4a01653f --- /dev/null +++ b/src/Glpi/Controller/NeedsUpdateController.php @@ -0,0 +1,129 @@ +. + * + * --------------------------------------------------------------------- + */ + +namespace Glpi\Controller; + +use Config; +use DBmysql; +use Glpi\Application\View\TemplateRenderer; +use Glpi\System\Requirement\DatabaseTablesEngine; +use Glpi\System\RequirementsManager; +use Glpi\Toolbox\VersionParser; +use Html; +use Session; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpFoundation\StreamedResponse; +use Toolbox; + +class NeedsUpdateController extends AbstractController +{ + public function __invoke(string $key): Response + { + return new StreamedResponse($this->display(...)); + } + + public function display(): void + { + // 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); + + /** @var DBmysql $DB */ + global $DB; + + /** @var array $CFG_GLPI */ + global $CFG_GLPI; + + $requirements = (new RequirementsManager())->getCoreRequirementList($DB); + $requirements->add(new DatabaseTablesEngine($DB)); + + $twig_params = [ + 'core_requirements' => $requirements, + 'try_again' => __('Try again'), + 'update_needed' => __('The GLPI codebase has been updated. The update of the GLPI database is necessary.'), + 'upgrade' => _sx('button', 'Upgrade'), + 'outdated_files' => __('You are trying to use GLPI with outdated files compared to the version of the database. Please install the correct GLPI files corresponding to the version of your database.'), + 'stable_release' => VersionParser::isStableRelease(GLPI_VERSION), + 'agree_unstable' => Config::agreeUnstableMessage(VersionParser::isDevVersion(GLPI_VERSION)), + 'outdated' => version_compare( + VersionParser::getNormalizedVersion($CFG_GLPI['version'] ?? '0.0.0-dev'), + VersionParser::getNormalizedVersion(GLPI_VERSION), + '>' + ) + ]; + + Html::nullHeader(__('Update needed')); + // language=Twig + echo TemplateRenderer::getInstance()->renderFromStringTemplate(<< +
+
+
+ {% include 'install/blocks/requirements_table.html.twig' with {'requirements': core_requirements} %} + {% if core_requirements.hasMissingMandatoryRequirements() or core_requirements.hasMissingOptionalRequirements() %} +
+ +
+ {% endif %} + {% if not core_requirements.hasMissingMandatoryRequirements() %} + {% if not outdated %} +
+ + {% if not stable_release %} + {{ agree_unstable|raw }} + {% endif %} +

+ {{ update_needed }} +

+ +
+ {% else %} +

+ {{ outdated_files }} +

+ {% endif %} + {% endif %} +
+
+
+ +TWIG, $twig_params); + Html::nullFooter(); + $_SESSION['glpi_use_mode'] = $debug_mode; + } +} diff --git a/src/Glpi/Http/Listener/CheckIfUpdateNeededListener.php b/src/Glpi/Http/Listener/CheckIfUpdateNeededListener.php new file mode 100644 index 00000000000..62d82700b01 --- /dev/null +++ b/src/Glpi/Http/Listener/CheckIfUpdateNeededListener.php @@ -0,0 +1,74 @@ +. + * + * --------------------------------------------------------------------- + */ + +namespace Glpi\Http\Listener; + +use Glpi\Controller\NeedsUpdateController; +use Glpi\Http\RequestPoliciesTrait; +use Glpi\Kernel\ListenersPriority; +use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\HttpKernel\Event\RequestEvent; +use Symfony\Component\HttpKernel\KernelEvents; +use Update; + +class CheckIfUpdateNeededListener 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 ( + \defined('SKIP_UPDATES') + || Update::isDbUpToDate() + || !$this->shouldCheckDbStatus($event->getRequest()) + ) { + return; + } + + $event->getRequest()->attributes->set('_controller', NeedsUpdateController::class); + } +} diff --git a/src/Glpi/Kernel/ListenersPriority.php b/src/Glpi/Kernel/ListenersPriority.php index 2553a7c23b2..b36c249421b 100644 --- a/src/Glpi/Kernel/ListenersPriority.php +++ b/src/Glpi/Kernel/ListenersPriority.php @@ -66,6 +66,10 @@ final class ListenersPriority // It must be executed before executing any controller (except controllers related to front-end assets). HttpListener\CheckDatabaseStatusListener::class => 450, + // This listener will ensure that GLPI is not being updated, or does not need a database update. + // Must also be executed before other controllers, since it defines its own controller. + HttpListener\CheckIfUpdateNeededListener::class => 440, + // Legacy config providers. // FIXME: Reorganize them and transform them into HTTP request listeners to register them here directly. LegacyConfigProviderListener::class => 425,