From 08953c627267ff7f8a9f7e95e6f49ecc7b99f2f6 Mon Sep 17 00:00:00 2001 From: Yasen Pramatarov Date: Wed, 24 Sep 2025 20:27:17 +0300 Subject: [PATCH] Adds initial support for maintenance mode --- app/core/Maintenance.php | 40 ++++++++++++++++++++++++++++ app/templates/maintenance.php | 20 ++++++++++++++ doc/database/README.md | 20 +++++++++++++- public_html/index.php | 24 +++++++++++++++++ scripts/maintenance.php | 49 +++++++++++++++++++++++++++++++++++ 5 files changed, 152 insertions(+), 1 deletion(-) create mode 100644 app/core/Maintenance.php create mode 100644 app/templates/maintenance.php create mode 100644 scripts/maintenance.php diff --git a/app/core/Maintenance.php b/app/core/Maintenance.php new file mode 100644 index 0000000..253f9db --- /dev/null +++ b/app/core/Maintenance.php @@ -0,0 +1,40 @@ + +
+
+
+
+
+ Maintenance mode +
+
+

The site is temporarily unavailable due to maintenance.

+

Please try again later.

+
+
+
+
+
diff --git a/doc/database/README.md b/doc/database/README.md index 87e0a24..2bbc03a 100644 --- a/doc/database/README.md +++ b/doc/database/README.md @@ -26,11 +26,29 @@ php scripts/migrate.php up 3. Typical deployment steps - Pull new code from git. -- Put the site in maintenance mode (optional, recommended for sensitive changes). +- Put the site in maintenance mode (recommended): `php scripts/maintenance.php on "Upgrading database"`. - Run `php scripts/migrate.php status`. - If there are pending migrations, run `php scripts/migrate.php up`. +- Disable maintenance mode: `php scripts/maintenance.php off`. - Clear opcache if applicable and resume traffic. +## Maintenance mode + +Enable maintenance mode to temporarily block non-admin traffic during upgrades. Superusers (user ID 1 or with `superuser` right) can still access the site. + +Commands: + +```bash +# Turn on with optional message +php scripts/maintenance.php on "Upgrading database" + +# Turn off +php scripts/maintenance.php off + +# Status +php scripts/maintenance.php status +``` + ## Authoring new migrations 1. Create a new SQL file in `doc/database/migrations/`, e.g.: diff --git a/public_html/index.php b/public_html/index.php index 771c7bf..d69559b 100644 --- a/public_html/index.php +++ b/public_html/index.php @@ -229,6 +229,30 @@ if (!$pipeline->run()) { exit; } +// Maintenance mode: show maintenance page to non-superusers +try { + require_once __DIR__ . '/../app/core/Maintenance.php'; + if (\App\Core\Maintenance::isEnabled()) { + $isSuperuser = false; + if ($validSession && isset($userId) && isset($userObject) && method_exists($userObject, 'hasRight')) { + // user 1 is always superuser per implementation, but also check explicit right + $isSuperuser = ($userId === 1) || (bool)$userObject->hasRight($userId, 'superuser'); + } + if (!$isSuperuser) { + http_response_code(503); + // Show themed maintenance page + \App\Helpers\Theme::include('page-header'); + \App\Helpers\Theme::include('page-menu'); + include __DIR__ . '/../app/templates/maintenance.php'; + \App\Helpers\Theme::include('page-footer'); + ob_end_flush(); + exit; + } + } +} catch (\Throwable $e) { + // Do not break app if maintenance check fails +} + // Apply per-user theme from DB into session (without persisting) once user is known if ($validSession && isset($userId) && isset($userObject) && is_object($userObject) && method_exists($userObject, 'getUserTheme')) { try { diff --git a/scripts/maintenance.php b/scripts/maintenance.php new file mode 100644 index 0000000..ce58c89 --- /dev/null +++ b/scripts/maintenance.php @@ -0,0 +1,49 @@ +#!/usr/bin/env php +getMessage() . "\n"); + exit(1); +}