Gedruckte Adressen aus club.website statt base_url
QR-Codes und Adresszeilen trugen `http://localhost:8000` ins Druckmaterial, weil sie über abs_url() liefen. Nach dem Produktivgang hätten alle zehn Codes neu erzeugt werden müssen — und ein gedruckter Code mit localhost darin ist Altpapier. Die öffentliche Domain ist Vereinsidentität, keine Umgebungseinstellung: neues Feld `club.website` in data/club.json plus club_url()/club_domain(). base_url bleibt umgebungsabhängig, weil Canonical, OG, Sitemap und JSON-LD zur ausliefernden Adresse passen müssen. Umgestellt: Cover-QR und die acht geteilten CTA-QRs, die Internet-Zeile im Heft-Impressum, die Cover-Zeile neben dem QR, die acht Linkzeilen unter den CTA-QRs der Live-Seiten (die hatte ich beim ersten Durchgang übersehen), das Web-Feld im Website-Impressum und bin/qr.php. Nebenbei: club_domain() ohne Pfad hängte einen Wurzel-Slash an („tsv08kulmbach.de/"), und der Kopf-Kommentar von stadionzeitung-add.php beschrieb noch die alten vier Anzeigen-Gruppen. Nicht verifizierbar und deshalb dokumentiert: die vendorte QR-Bibliothek arbeitet nicht reproduzierbar (gleiche URL, andere Pixel — anderes Maskenmuster, beides gültig). Ein PNG-Vergleich beweist nichts, nachweisbar ist nur der Code-Pfad. Jeden Druck-QR einmal scannen. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NzeVVgMCrzCDJAKeLEdKr7
This commit is contained in:
22
bin/qr.php
22
bin/qr.php
@@ -18,11 +18,11 @@ declare(strict_types=1);
|
||||
* 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.
|
||||
* Ein QR-Code hat die URL fest eingebacken — gegen die Entwicklungs-Config erzeugt
|
||||
* stünde `http://localhost:8000/…` darin und das gedruckte Plakat wäre Altpapier.
|
||||
* Deshalb läuft ein interner Pfad durch club_url(): die öffentliche Vereinsadresse
|
||||
* aus data/club.json, unabhängig von der Umgebung. Der Code stimmt damit schon vor
|
||||
* dem Produktivgang und muss danach nicht neu erzeugt werden.
|
||||
*/
|
||||
if (PHP_SAPI !== 'cli') {
|
||||
exit(1);
|
||||
@@ -45,7 +45,7 @@ if ($args === []) {
|
||||
|
||||
$target = $args[0];
|
||||
$isAbsolute = str_starts_with($target, 'http://') || str_starts_with($target, 'https://');
|
||||
$url = $isAbsolute ? $target : abs_url(trim($target, '/'));
|
||||
$url = $isAbsolute ? $target : club_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.
|
||||
@@ -59,11 +59,11 @@ if ($dest === null) {
|
||||
$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");
|
||||
// Der Riegel bleibt, nur zeigt er jetzt auf das richtige Feld: ohne saubere
|
||||
// club.website wäre der gedruckte Code wieder unbrauchbar.
|
||||
if (!$isAbsolute && !str_starts_with($url, 'https://')) {
|
||||
fwrite(STDERR, "WARNUNG club.website in data/club.json ist nicht https ('{$url}') — dieser QR-Code\n");
|
||||
fwrite(STDERR, " führt nicht auf die echte Seite und ist als Druckvorlage unbrauchbar.\n\n");
|
||||
}
|
||||
|
||||
if (!generate_qr_png($url, $dest, $scale)) {
|
||||
|
||||
@@ -19,18 +19,20 @@ declare(strict_types=1);
|
||||
* <ordner>/spieler.* optional, freigestelltes Spielerfoto (PNG mit Transparenz)
|
||||
* fürs Cover — wird unverändert kopiert, nie über GD neu kodiert
|
||||
* <ordner>/verfasser.* optional, Porträtfoto für die Vorwort-Signatur
|
||||
* <ordner>/anzeigen/* Sponsoren-Seiten (fertige Vollseiten — ob im Sponsoring
|
||||
* halbe oder ganze Seite verkauft wurde, ist hier egal,
|
||||
* geliefert wird immer eine fertige Seite), natürlich sortiert
|
||||
*
|
||||
* Feste Vorlage (Interview-Beschluss 29.07.2026): Cover (live) → Vorwort →
|
||||
* Ergebnis-Rückblick (live) → Anzeigen A → je Mannschaft eine Tabelle (live,
|
||||
* Reihenfolge = data/matchcenter.json) → Vorschau (live) → Anzeigen B →
|
||||
* Termine (live) → Anzeigen C → News (live) → Ansprechpartner (live) →
|
||||
* Anzeigen D → Rückseite. Das Cover wird automatisch generiert (siehe
|
||||
* app/components/stadionzeitung-cover.php) — kein Canva-Bild mehr nötig. Der
|
||||
* gesamte Anzeigen-Pool (in gelieferter Reihenfolge) wird zu möglichst
|
||||
* gleichen Teilen auf die vier Gruppen verteilt.
|
||||
* KEINE Anzeigen im Ordner (seit 31.07.2026): die kommen aus dem dauerhaften
|
||||
* Bestand data/anzeigen.json, gepflegt mit bin/anzeige-add.php. Sponsorenmotive
|
||||
* ändern sich selten, das Heft erscheint oft — vorher lag jede Anzeige als Kopie
|
||||
* unter jeder Ausgabe und ihr Alt-Text musste jedes Mal neu geschrieben werden.
|
||||
*
|
||||
* Feste Vorlage (Interview-Beschluss 29.07.2026, Anzeigen 31.07.2026 überarbeitet):
|
||||
* Der Inhalt ist eine Liste von BLÖCKEN, die Anzeigen werden gleichmäßig in die
|
||||
* Lücken dazwischen verteilt — nie mehr als zwei hintereinander (vorher vier
|
||||
* Blöcke à fünf, das las sich wie „Heft zu Ende"). Anzeigenfrei bleiben: nach dem
|
||||
* Cover, im Aufschlag Vorwort+Interview, zwischen den Tabellenseiten und zwischen
|
||||
* Impressum und Rückseite. Die Doppelseiten-Regel (erste Tabelle auf gerader
|
||||
* Seite) rechnet das Skript selbst und verschiebt dafür eine Anzeige.
|
||||
* Das Cover wird automatisch generiert (app/components/stadionzeitung-cover.php).
|
||||
*
|
||||
* Neue Ausgaben entstehen als ENTWURF (status: entwurf): unsichtbar in
|
||||
* Archiv/Sitemap, Live-Seiten rechnen bei jedem Aufruf frisch. Erst
|
||||
@@ -500,10 +502,13 @@ if ($spieler !== null) {
|
||||
}
|
||||
|
||||
// --- QR-Code zur digitalen Ausgabe fürs Cover: einmalig, Ziel-URL ändert sich nie.
|
||||
// club_url() statt abs_url(): der Code landet auf Papier und muss auf die echte
|
||||
// Domain zeigen, auch wenn er hier lokal erzeugt wird (vorher stand
|
||||
// http://localhost:8000 darin).
|
||||
// QR ist "nice to have" — schlägt die Erzeugung fehl, läuft die Ausgabe ohne weiter. ---
|
||||
$qrImage = null;
|
||||
$qrDest = "{$destDir}/qr.png";
|
||||
if (generate_qr_png(abs_url('stadionzeitung/' . $slug), $qrDest)) {
|
||||
if (generate_qr_png(club_url('stadionzeitung/' . $slug), $qrDest)) {
|
||||
$qrImage = "img/stadionzeitung/{$slug}/qr.png";
|
||||
$log('QR-Code erzeugt.');
|
||||
} else {
|
||||
@@ -511,11 +516,11 @@ if (generate_qr_png(abs_url('stadionzeitung/' . $slug), $qrDest)) {
|
||||
}
|
||||
|
||||
// Geteilte QRs der CTA-Füße (Kontakt → /mitmachen, News → /news, Termine →
|
||||
// /termine, Vorschau → /matchcenter, für alle Ausgaben gleich) — werden bei
|
||||
// jedem Lauf mit der aktuellen base_url neu geschrieben, damit sie nach dem
|
||||
// Produktivgang automatisch auf die echte Domain zeigen.
|
||||
// /termine, Vorschau → /matchcenter, für alle Ausgaben gleich) — ebenfalls über
|
||||
// club_url(), damit sie unabhängig von der Umgebung stimmen und nach dem
|
||||
// Produktivgang nicht neu erzeugt werden müssen.
|
||||
foreach (['mitmachen', 'news', 'termine', 'matchcenter', 'mitglied-werden', 'historie', 'sportheimbuchung', 'partner-werden'] as $ctaTarget) {
|
||||
if (generate_qr_png(abs_url($ctaTarget), PUBLIC_PATH . "/assets/img/stadionzeitung/qr-{$ctaTarget}.png")) {
|
||||
if (generate_qr_png(club_url($ctaTarget), PUBLIC_PATH . "/assets/img/stadionzeitung/qr-{$ctaTarget}.png")) {
|
||||
$log("QR-Code für /{$ctaTarget} erzeugt.");
|
||||
} else {
|
||||
$log("QR-Code für /{$ctaTarget} konnte nicht erzeugt werden — die Seite rendert ohne QR.", 'WARN');
|
||||
|
||||
Reference in New Issue
Block a user