isPast(); } return true; } /** * @param array|null $message Locale => message. */ public static function enable(?array $message = null, ?CarbonImmutable $until = null): void { Setting::set(self::KEY, [ 'enabled' => true, 'message' => $message ?? self::state()['message'] ?? null, 'until' => $until?->toIso8601String(), 'started_at' => now()->toIso8601String(), ]); } public static function disable(): void { Setting::set(self::KEY, [ ...self::state(), 'enabled' => false, 'until' => null, ]); } /** * The message shown to visitors, resolved to the request's language and * falling back to a translated default when none was written. */ public static function message(?string $locale = null): string { $locale ??= app()->getLocale(); $messages = self::state()['message'] ?? []; if (is_array($messages)) { $written = $messages[$locale] ?? $messages[config('locales.fallback')] ?? null; if (filled($written)) { return (string) $written; } } return __('maintenance.default_message'); } public static function until(): ?CarbonImmutable { $until = self::state()['until'] ?? null; return filled($until) ? CarbonImmutable::parse($until) : null; } public static function startedAt(): ?CarbonImmutable { $started = self::state()['started_at'] ?? null; return filled($started) ? CarbonImmutable::parse($started) : null; } /** * Seconds a caller should wait before retrying, for the `Retry-After` * header. Capped so a distant end date does not tell a CDN to stop asking * for a day. */ public static function retryAfter(): int { $until = self::until(); if ($until === null || $until->isPast()) { return 300; } return min(3600, max(60, (int) now()->diffInSeconds($until))); } /** * Every locale's message, for editing in the panel. * * @return array */ public static function messages(): array { $messages = self::state()['message'] ?? []; return is_array($messages) ? $messages : []; } /** * @return array */ public static function state(): array { $state = Setting::get(self::KEY, []); return is_array($state) ? $state : []; } }