Skip to content

Commit

Permalink
Move db update check out of StandardIncludes to its own listener+cont…
Browse files Browse the repository at this point in the history
…roller
  • Loading branch information
Pierstoval committed Dec 20, 2024
1 parent 6344e60 commit 8553b32
Show file tree
Hide file tree
Showing 4 changed files with 210 additions and 83 deletions.
86 changes: 3 additions & 83 deletions src/Glpi/Config/LegacyConfigurators/StandardIncludes.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand All @@ -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;
Expand All @@ -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(<<<TWIG
<div class="container-fluid mb-4">
<div class="row justify-content-evenly">
<div class="col-12 col-xxl-6">
<div class="card text-center mb-4">
{% include 'install/blocks/requirements_table.html.twig' with {'requirements': core_requirements} %}
{% if core_requirements.hasMissingMandatoryRequirements() or core_requirements.hasMissingOptionalRequirements() %}
<form action="{{ path('index.php') }}" method="post">
<button type="submit" class="btn btn-primary">
<i class="fas fa-redo"></i>{{ try_again }}
</button>
</form>
{% endif %}
{% if not core_requirements.hasMissingMandatoryRequirements() %}
{% if not outdated %}
<form method="post" action="{{ path('install/update.php') }}">
<input type="hidden" name="_glpi_csrf_token" value="{{ csrf_token() }}">
{% if not stable_release %}
{{ agree_unstable|raw }}
{% endif %}
<p class="mt-2 mb-n2 alert alert-important alert-warning">
{{ update_needed }}
</p>
<button type="submit" name="from_update" class="btn btn-primary">
<i class="fas fa-check"></i>{{ upgrade }}
</button>
</form>
{% else %}
<p class="mt-2 mb-n2 alert alert-important alert-warning">
{{ outdated_files }}
</p>
{% endif %}
{% endif %}
</div>
</div>
</div>
</div>
TWIG, $twig_params);
Html::nullFooter();
$_SESSION['glpi_use_mode'] = $debug_mode;
exit();
}
}
}
129 changes: 129 additions & 0 deletions src/Glpi/Controller/NeedsUpdateController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
<?php

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

namespace Glpi\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(<<<TWIG
<div class="container-fluid mb-4">
<div class="row justify-content-evenly">
<div class="col-12 col-xxl-6">
<div class="card text-center mb-4">
{% include 'install/blocks/requirements_table.html.twig' with {'requirements': core_requirements} %}
{% if core_requirements.hasMissingMandatoryRequirements() or core_requirements.hasMissingOptionalRequirements() %}
<form action="{{ path('index.php') }}" method="post">
<button type="submit" class="btn btn-primary">
<i class="fas fa-redo"></i>{{ try_again }}
</button>
</form>
{% endif %}
{% if not core_requirements.hasMissingMandatoryRequirements() %}
{% if not outdated %}
<form method="post" action="{{ path('install/update.php') }}">
<input type="hidden" name="_glpi_csrf_token" value="{{ csrf_token() }}">
{% if not stable_release %}
{{ agree_unstable|raw }}
{% endif %}
<p class="mt-2 mb-n2 alert alert-important alert-warning">
{{ update_needed }}
</p>
<button type="submit" name="from_update" class="btn btn-primary">
<i class="fas fa-check"></i>{{ upgrade }}
</button>
</form>
{% else %}
<p class="mt-2 mb-n2 alert alert-important alert-warning">
{{ outdated_files }}
</p>
{% endif %}
{% endif %}
</div>
</div>
</div>
</div>
TWIG, $twig_params);
Html::nullFooter();
$_SESSION['glpi_use_mode'] = $debug_mode;
}
}
74 changes: 74 additions & 0 deletions src/Glpi/Http/Listener/CheckIfUpdateNeededListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

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

namespace Glpi\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);
}
}
4 changes: 4 additions & 0 deletions src/Glpi/Kernel/ListenersPriority.php
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit 8553b32

Please sign in to comment.