Stadionzeitung: Live-Seiten (Tabellen, Ergebnisse, Vorschau, Termine, News, Kontakt, Historie, Sportheim, Partner, Momente, Impressum), automatisches Cover, Swipe-Viewer mit Vollbildmodus und die Druckfassung als Falt-Heft. Anzeigen kommen jetzt aus dem Bestand und werden gleichmäßig verteilt, nie mehr als zwei hintereinander (vorher vier Blöcke à fünf). Die Doppelseiten-Regel rechnet das Skript selbst, statt sie von Hand zu prüfen. Veranstaltungen: Bereich /veranstaltungen mit Detailseite pro Fest, Lebenszyklus über das Datum (Ankündigung vor dem Fest, Rückblick danach), Galerie mit Lightbox. veranstaltungen.json ist dritte Termin-Quelle, damit ein Fest nie doppelt gepflegt wird. News-Artikel als dritte dynamische Prefix-Route, gemeinsamer detail-head. Behobene Fehler: - Wappen-Kontexte setzten Zeilen-Layout auf .crest statt auf die Zeile; das Wappen wurde zum Grid, Vereinsname und Tore rutschten darunter zusammen (Ergebnis-Rückblick, Vorschau, Cover). - --header-h (60px) unterschätzt die Kopfleiste um 32px (Logo 72px + 20px Versatz): neues abgeleitetes --header-space, sonst klebten Zurück-Links unter dem Logo. - base_url in der Produktions-Config ohne www, während .htaccess auf www umleitet; preflight prüft das jetzt. - .lightbox brauchte display:none mit (0,2,0), sonst lag das Overlay offen. Neue Werkzeuge: bin/anzeige-add.php (Anzeigen-Bestand), bin/veranstaltung-bilder.php (Plakate und Galerien, Alt-Texte folgen der Quelldatei), bin/qr.php (Druck-QR mit Warnung, wenn base_url nicht auf die echte Domain zeigt). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NzeVVgMCrzCDJAKeLEdKr7
79 lines
3.1 KiB
PHP
79 lines
3.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
/**
|
|
* QR-Code für DRUCKSACHEN erzeugen (nur CLI).
|
|
*
|
|
* php bin/qr.php <pfad|url> [ziel.png] [--scale=24]
|
|
*
|
|
* Beispiele:
|
|
* php bin/qr.php stadionzeitung/aktuell
|
|
* php bin/qr.php stadionzeitung/aktuell ~/Desktop/qr-plakat.png --scale=30
|
|
* php bin/qr.php https://tsv08kulmbach.de/stadionzeitung/aktuell
|
|
*
|
|
* Abgrenzung zu den QR-Codes der Stadionzeitung: die erzeugt
|
|
* bin/stadionzeitung-add.php selbst, klein und für die A5-Seiten
|
|
* (generate_qr_png() Default-Skalierung, gut 200px). Dieses Skript ist für
|
|
* Plakate und Aushänge, die in Canva zusammengebaut werden — dort braucht es
|
|
* ein Vielfaches an Pixeln, sonst franst der Code im Druck aus.
|
|
*
|
|
* DIE EIGENTLICHE AUFGABE DIESES SKRIPTS IST DIE WARNUNG: ein QR-Code enthält
|
|
* die URL fest eingebacken. Wird er gegen die Entwicklungs-Config erzeugt, steht
|
|
* `http://localhost:8000/…` darin und das gedruckte Plakat ist Altpapier. Ein
|
|
* interner Pfad läuft deshalb durch abs_url() (Single Source: config base_url),
|
|
* und wenn die nicht auf https zeigt, sagt das Skript es laut.
|
|
*/
|
|
if (PHP_SAPI !== 'cli') {
|
|
exit(1);
|
|
}
|
|
|
|
require dirname(__DIR__) . '/app/bootstrap.php';
|
|
|
|
$args = array_values(array_filter(array_slice($argv, 1), static fn (string $a): bool => !str_starts_with($a, '--')));
|
|
$scale = 24;
|
|
foreach ($argv as $arg) {
|
|
if (str_starts_with($arg, '--scale=')) {
|
|
$scale = max(1, (int) substr($arg, 8));
|
|
}
|
|
}
|
|
|
|
if ($args === []) {
|
|
fwrite(STDERR, "Nutzung: php bin/qr.php <pfad|url> [ziel.png] [--scale=24]\n");
|
|
exit(1);
|
|
}
|
|
|
|
$target = $args[0];
|
|
$isAbsolute = str_starts_with($target, 'http://') || str_starts_with($target, 'https://');
|
|
$url = $isAbsolute ? $target : abs_url(trim($target, '/'));
|
|
|
|
// Zielpfad: ohne Angabe neben das Skript-Verzeichnis in storage/qr/ ablegen —
|
|
// Druckmaterial ist kein Website-Asset und hat unter public/ nichts zu suchen.
|
|
$dest = $args[1] ?? null;
|
|
if ($dest === null) {
|
|
$dir = STORAGE_PATH . '/qr';
|
|
if (!is_dir($dir)) {
|
|
mkdir($dir, 0755, true);
|
|
}
|
|
$name = preg_replace('/[^a-z0-9]+/', '-', strtolower($isAbsolute ? (string) parse_url($url, PHP_URL_PATH) : $target)) ?? 'qr';
|
|
$dest = $dir . '/qr-' . trim($name, '-') . '.png';
|
|
}
|
|
|
|
if (!$isAbsolute && !str_starts_with((string) config('base_url'), 'https://')) {
|
|
fwrite(STDERR, "WARNUNG base_url ist '" . (string) config('base_url') . "' — dieser QR-Code führt NICHT auf die echte Seite\n");
|
|
fwrite(STDERR, " und ist als Druckvorlage unbrauchbar. Entweder die Produktions-Config verwenden\n");
|
|
fwrite(STDERR, " oder die vollständige URL direkt übergeben:\n");
|
|
fwrite(STDERR, " php bin/qr.php https://tsv08kulmbach.de/{$target}\n\n");
|
|
}
|
|
|
|
if (!generate_qr_png($url, $dest, $scale)) {
|
|
fwrite(STDERR, "FEHLER QR-Code konnte nicht erzeugt werden (vendor-manual/phpqrcode vorhanden?)\n");
|
|
exit(1);
|
|
}
|
|
|
|
[$w, $h] = getimagesize($dest) ?: [0, 0];
|
|
echo "QR-Code erzeugt\n";
|
|
echo " Ziel-URL : {$url}\n";
|
|
echo " Datei : {$dest}\n";
|
|
echo " Größe : {$w}x{$h} px (bei 300 dpi etwa " . round($w / 300 * 2.54, 1) . " cm)\n";
|