Files
KantSites/src/EventSubscriber/MaintenanceSubscriber.php
T
kantarciandClaude Opus 5.5 b982cb8944 Give mail delivery its own admin page and move the origin probe off /.well-known
The mail page under System tries SMTP, PHP mail() and both sendmail
modes one by one or all at once, and saves the chosen way to .env
without ever showing the password. IONOS answers everything under
/.well-known/ itself with 403, so the address and HTTPS checks never
reached the installation; the probe now lives at /kantsites-origin
(ADR 122).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 21:07:27 +02:00

55 lines
2.1 KiB
PHP

<?php
namespace App\EventSubscriber;
use App\Ops\Updater;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Twig\Environment;
/**
* While an update runs, the website answers with 503 and the administration stays open.
*
* 503 and not 200 with a notice: a search engine reads 503 with Retry-After as "come back later"
* and keeps the page in its index, while a 200 would teach it that the page now contains an
* excuse. The administration has to stay reachable, because otherwise nobody could finish or
* undo the update.
*/
final class MaintenanceSubscriber implements EventSubscriberInterface
{
public function __construct(private Environment $twig, private string $projectDir, private string $adminPath)
{
}
public static function getSubscribedEvents(): array
{
// Before the router: during maintenance no controller should run at all.
return [KernelEvents::REQUEST => ['onRequest', 40]];
}
public function onRequest(RequestEvent $event): void
{
if (!$event->isMainRequest() || !is_file($this->projectDir.'/'.Updater::MAINTENANCE_FILE)) {
return;
}
$path = $event->getRequest()->getPathInfo();
if (preg_match('#^/('.preg_quote($this->adminPath, '#').'|assets/|media/|favicon|kantsites-origin$)#', $path)) {
return;
}
$since = @file_get_contents($this->projectDir.'/'.Updater::MAINTENANCE_FILE);
$response = new Response(
$this->twig->render('maintenance.html.twig', ['since' => trim((string) $since)]),
Response::HTTP_SERVICE_UNAVAILABLE,
[
'Retry-After' => '600',
'Cache-Control' => 'no-store',
'Content-Type' => 'text/html; charset=UTF-8',
'Content-Security-Policy' => "default-src 'self'; script-src 'none'; style-src 'self'; img-src 'self'; object-src 'none'; base-uri 'none'; frame-ancestors 'none'",
],
);
$event->setResponse($response);
}
}