Add the central site registry and remote updates
Every installation now reports address and version to sites.kant-it.de every 15 minutes and picks up update orders there (ADR 123). Reports and answers are HMAC-signed with a per-installation key sent on first contact; an order can only install a published release with checksum. The next request after the file swap runs the migrations, so a remote update finishes without anyone in the admin. The platform itself lives in zentrale/ (plain PHP + SQLite, not part of the release archive): overview with outdated, silent and unassigned installations, single and bulk updates, per-site detail and history. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
32cb77b72e
commit
723680b7de
39 files changed
+2355
-27
No files matched your search
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Zentrale;
|
||||
|
||||
/**
|
||||
* Vorlagen als PHP-Dateien. Alles, was ausgegeben wird, geht durch e().
|
||||
*/
|
||||
final class Ansicht
|
||||
{
|
||||
public function __construct(private string $csrf)
|
||||
{
|
||||
}
|
||||
|
||||
/** @param array<string, mixed> $daten */
|
||||
public function vorlage(string $datei, array $daten): string
|
||||
{
|
||||
$v = $this;
|
||||
extract($daten, EXTR_SKIP);
|
||||
ob_start();
|
||||
require $datei;
|
||||
|
||||
return (string) ob_get_clean();
|
||||
}
|
||||
|
||||
public function e(mixed $wert): string
|
||||
{
|
||||
return htmlspecialchars((string) $wert, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
|
||||
}
|
||||
|
||||
public function csrf(): string
|
||||
{
|
||||
return '<input type="hidden" name="_csrf" value="'.$this->e($this->csrf).'">';
|
||||
}
|
||||
|
||||
/** Ein Zeitpunkt in deutscher Ortszeit. */
|
||||
public function zeit(?string $iso): string
|
||||
{
|
||||
if (null === $iso || '' === $iso || false === strtotime($iso)) {
|
||||
return '–';
|
||||
}
|
||||
|
||||
return (new \DateTimeImmutable($iso))->setTimezone(new \DateTimeZone('Europe/Berlin'))->format('d.m.Y, H:i');
|
||||
}
|
||||
|
||||
/** „vor 5 Minuten“ - für die letzte Meldung. */
|
||||
public function vor(int $sekunden): string
|
||||
{
|
||||
return match (true) {
|
||||
$sekunden < 90 => 'gerade eben',
|
||||
$sekunden < 5400 => sprintf('vor %d Minuten', (int) round($sekunden / 60)),
|
||||
$sekunden < 129600 => sprintf('vor %d Stunden', (int) round($sekunden / 3600)),
|
||||
default => sprintf('vor %d Tagen', (int) round($sekunden / 86400)),
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user