CluPilotCloud/app/Support/Settings.php

61 lines
2.1 KiB
PHP

<?php
namespace App\Support;
use Illuminate\Support\Facades\Cache;
use Illuminate\Database\QueryException;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
/**
* Runtime settings an operator can change from the console.
*
* Cached because the public-site gate reads one of these on every single
* request; the cache is dropped on write, so a flip takes effect immediately
* rather than "within a minute".
*/
final class Settings
{
private const CACHE_PREFIX = 'app_setting:';
public static function get(string $key, mixed $default = null): mixed
{
$raw = Cache::rememberForever(self::CACHE_PREFIX.$key, function () use ($key) {
try {
$row = DB::table('app_settings')->where('key', $key)->value('value');
} catch (QueryException $e) {
// The gate reads a setting on every request, so an unreachable
// or not-yet-migrated table would take the whole site down —
// including during a deploy where new code runs before migrate.
// Fall back to the caller's default instead, and say so.
Log::warning('app_settings unavailable, using default', [
'key' => $key, 'error' => $e->getMessage(),
]);
return '__missing__';
}
// Sentinel: distinguishes "stored null" from "never stored", so a
// missing row does not get re-queried on every request.
return $row === null ? '__missing__' : $row;
});
return $raw === '__missing__' ? $default : json_decode($raw, true);
}
public static function set(string $key, mixed $value): void
{
DB::table('app_settings')->updateOrInsert(
['key' => $key],
['value' => json_encode($value), 'updated_at' => now(), 'created_at' => now()],
);
Cache::forget(self::CACHE_PREFIX.$key);
}
public static function bool(string $key, bool $default = false): bool
{
return (bool) self::get($key, $default);
}
}