70 lines
1.9 KiB
PHP
70 lines
1.9 KiB
PHP
<?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).'">';
|
||
}
|
||
|
||
/**
|
||
* Eine Adresse der Übersicht; leere Werte und Seite 1 fallen weg.
|
||
*
|
||
* @param array<string, mixed> $werte
|
||
*/
|
||
public function adresse(array $werte): string
|
||
{
|
||
$werte = array_filter($werte, static fn (mixed $wert): bool => null !== $wert && '' !== $wert && 1 !== $wert);
|
||
|
||
return '/'.([] === $werte ? '' : '?'.http_build_query($werte));
|
||
}
|
||
|
||
/** 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)),
|
||
};
|
||
}
|
||
}
|