Adds initial support for maintenance mode
parent
315b68f928
commit
08953c6272
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
|
||||
namespace App\Core;
|
||||
|
||||
class Maintenance
|
||||
{
|
||||
public const FLAG_PATH = __DIR__ . '/../../storage/maintenance.flag';
|
||||
|
||||
public static function isEnabled(): bool
|
||||
{
|
||||
return file_exists(self::FLAG_PATH);
|
||||
}
|
||||
|
||||
public static function enable(string $message = ''): bool
|
||||
{
|
||||
$dir = dirname(self::FLAG_PATH);
|
||||
if (!is_dir($dir)) {
|
||||
mkdir($dir, 0755, true);
|
||||
}
|
||||
$content = $message !== '' ? $message : 'Site is under maintenance';
|
||||
return file_put_contents(self::FLAG_PATH, $content) !== false;
|
||||
}
|
||||
|
||||
public static function disable(): bool
|
||||
{
|
||||
if (file_exists(self::FLAG_PATH)) {
|
||||
return unlink(self::FLAG_PATH);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static function getMessage(): string
|
||||
{
|
||||
if (!self::isEnabled()) {
|
||||
return '';
|
||||
}
|
||||
$msg = @file_get_contents(self::FLAG_PATH);
|
||||
return is_string($msg) ? trim($msg) : '';
|
||||
}
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
<?php
|
||||
/**
|
||||
* Maintenance mode page
|
||||
*/
|
||||
?>
|
||||
<div class="container mt-5">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-md-8">
|
||||
<div class="card border-warning">
|
||||
<div class="card-header bg-warning text-dark">
|
||||
<strong>Maintenance mode</strong>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="lead">The site is temporarily unavailable due to maintenance.</p>
|
||||
<p class="text-muted">Please try again later.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -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.:
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
require_once __DIR__ . '/../app/core/Maintenance.php';
|
||||
|
||||
use App\Core\Maintenance;
|
||||
|
||||
function usage()
|
||||
{
|
||||
echo "\nJilo Web - Maintenance Mode\n";
|
||||
echo "Usage:\n";
|
||||
echo " php scripts/maintenance.php on [message] # Enable maintenance mode with optional message\n";
|
||||
echo " php scripts/maintenance.php off # Disable maintenance mode\n";
|
||||
echo " php scripts/maintenance.php status # Show maintenance status\n\n";
|
||||
}
|
||||
|
||||
$cmd = $argv[1] ?? 'status';
|
||||
|
||||
try {
|
||||
switch ($cmd) {
|
||||
case 'on':
|
||||
$message = $argv[2] ?? '';
|
||||
if (Maintenance::enable($message)) {
|
||||
echo "Maintenance mode ENABLED" . ($message ? ": $message" : '') . "\n";
|
||||
exit(0);
|
||||
}
|
||||
fwrite(STDERR, "Failed to enable maintenance mode\n");
|
||||
exit(1);
|
||||
case 'off':
|
||||
if (Maintenance::disable()) {
|
||||
echo "Maintenance mode DISABLED\n";
|
||||
exit(0);
|
||||
}
|
||||
fwrite(STDERR, "Failed to disable maintenance mode\n");
|
||||
exit(1);
|
||||
case 'status':
|
||||
default:
|
||||
if (Maintenance::isEnabled()) {
|
||||
$msg = Maintenance::getMessage();
|
||||
echo "Maintenance: ON" . ($msg ? " - $msg" : '') . "\n";
|
||||
} else {
|
||||
echo "Maintenance: OFF\n";
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
} catch (Throwable $e) {
|
||||
fwrite(STDERR, "Error: " . $e->getMessage() . "\n");
|
||||
exit(1);
|
||||
}
|
Loading…
Reference in New Issue