'datetime', 'certificate_checked_at' => 'datetime', ]; } /** * Wofür der Name da ist — und damit, was er darf. * * `public` — Website, Portal, Status, Dateien. Vom offenen Internet * erreichbar, Zertifikat über die HTTP-Prüfung. * `console` — der Adminbereich. Er bekommt die Netzsperre und ist NICHT * öffentlich; ein Zertifikat holt er trotzdem. * * Getrennt, weil ein Name mit dem falschen Zweck genau die Sorte Fehler * ist, die niemand sieht: die Konsole öffentlich zu stellen sieht aus wie * eine funktionierende Seite. */ public const PURPOSES = ['public', 'console']; public function isConsole(): bool { return $this->purpose === 'console'; } /** Tage bis zum Ablauf, oder null wenn nichts gemessen wurde. */ public function daysLeft(): ?int { if ($this->certificate_expires_at === null) { return null; } // Aufgerundet auf ganze Tage und nie negativ dargestellt: „noch -3 Tage" // ist keine Auskunft, „abgelaufen" ist eine. return max(0, (int) now()->diffInDays($this->certificate_expires_at, false)); } /** * Läuft es bald ab? * * Dreißig Tage, weil Let's Encrypt bei neunzig Tagen Laufzeit nach dreißig * verbleibenden längst hätte erneuern müssen. Was darunter steht, ist kein * knappes Zertifikat mehr, sondern eine Erneuerung, die nicht stattfindet. */ public function isExpiringSoon(): bool { $days = $this->daysLeft(); return $days !== null && $days <= 30; } }