99 lines
4.5 KiB
PHP
99 lines
4.5 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
declare(strict_types=1);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Druckfassung einer Stadionzeitung-Ausgabe (Route ?druck=1, siehe
|
||
|
|
* app/pages/stadionzeitung-ausgabe.php) — die Seiten in BROSCHÜREN-Reihenfolge
|
||
|
|
* statt Lesereihenfolge: das Heft wird als A4 quer beidseitig gedruckt, die
|
||
|
|
* Blätter werden gestapelt und mittig gefaltet. Damit dabei vorn das Cover
|
||
|
|
* und innen die richtige Abfolge liegt, trägt Blatt 1 vorne [letzte Seite |
|
||
|
|
* Seite 1], hinten [Seite 2 | vorletzte Seite] usw. — die klassische
|
||
|
|
* Sattelheftungs-Montage. Deshalb liegt die Montage HIER im PHP (die
|
||
|
|
* DOM-Reihenfolge selbst ist die Druckreihenfolge), nicht in Druck-CSS:
|
||
|
|
* CSS kann Seiten nicht über Blattgrenzen hinweg umsortieren.
|
||
|
|
*
|
||
|
|
* Die Seitenzahl wird dafür auf ein Vielfaches von 4 gebracht: fehlende
|
||
|
|
* Seiten füllt eine weiße Leerseite VOR der Rückseite auf (die Rückseite
|
||
|
|
* bleibt immer außen). Die Regel fürs Heft bleibt trotzdem: Lücken beim
|
||
|
|
* Erzeugen gemeinsam sauber lösen, Leerseiten sind der Notnagel.
|
||
|
|
*
|
||
|
|
* Auf dem Bildschirm zeigt die Route eine Blatt-Vorschau (jedes Blatt als
|
||
|
|
* A4-quer-Fläche mit Beschriftung „Blatt 1 · Vorderseite") plus
|
||
|
|
* Druck-Anleitung; assets/js/stadionzeitung-druck.js liefert den
|
||
|
|
* „Jetzt drucken"-Button (progressive enhancement — ohne JS druckt der
|
||
|
|
* Browser-Dialog dieselbe Ansicht).
|
||
|
|
*
|
||
|
|
* Props: $issue Eintrag aus data/stadionzeitung.json
|
||
|
|
*/
|
||
|
|
$issue = $issue ?? [];
|
||
|
|
$pages = $issue['images'] ?? [];
|
||
|
|
if ($pages === []) {
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
|
||
|
|
$hasLive = false;
|
||
|
|
foreach ($pages as $entry) {
|
||
|
|
if (($entry['type'] ?? 'image') === 'live') {
|
||
|
|
$hasLive = true;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
$liveData = $hasLive ? stadionzeitung_live_data($issue) : [];
|
||
|
|
|
||
|
|
// Auf Vielfaches von 4 auffüllen — Leerseiten direkt vor der letzten Seite,
|
||
|
|
// damit die gelieferte Rückseite die äußere Rückseite des Hefts bleibt.
|
||
|
|
$fill = (4 - count($pages) % 4) % 4;
|
||
|
|
if ($fill > 0) {
|
||
|
|
array_splice($pages, count($pages) - 1, 0, array_fill(0, $fill, ['type' => 'leer']));
|
||
|
|
}
|
||
|
|
$n = count($pages);
|
||
|
|
|
||
|
|
// Sattelheftung: Blatt k (0-basiert) trägt vorne [n-1-2k | 2k] und hinten
|
||
|
|
// [2k+1 | n-2-2k] (0-basierte Seitenindizes). Beim beidseitigen Druck an der
|
||
|
|
// KURZEN Kante spiegeln, sonst steht jede Rückseite kopf.
|
||
|
|
$sides = [];
|
||
|
|
for ($k = 0; $k < intdiv($n, 4); $k++) {
|
||
|
|
$sides[] = ['label' => 'Blatt ' . ($k + 1) . ' · Vorderseite', 'pages' => [$n - 1 - 2 * $k, 2 * $k]];
|
||
|
|
$sides[] = ['label' => 'Blatt ' . ($k + 1) . ' · Rückseite', 'pages' => [2 * $k + 1, $n - 2 - 2 * $k]];
|
||
|
|
}
|
||
|
|
?>
|
||
|
|
<section class="stadionzeitung-druck">
|
||
|
|
<ol class="stadionzeitung-druck__blaetter">
|
||
|
|
<?php foreach ($sides as $side): ?>
|
||
|
|
<li class="stadionzeitung-druck__blatt">
|
||
|
|
<p class="stadionzeitung-druck__blatt-label" aria-hidden="true"><?= e($side['label']) ?></p>
|
||
|
|
<div class="stadionzeitung-druck__flaeche">
|
||
|
|
<?php foreach ($side['pages'] as $pageIndex): ?>
|
||
|
|
<div class="stadionzeitung-druck__slot">
|
||
|
|
<?php component('stadionzeitung-seite', [
|
||
|
|
'entry' => $pages[$pageIndex],
|
||
|
|
'issue' => $issue,
|
||
|
|
'data' => $liveData,
|
||
|
|
// In der Druckfassung wird JEDE Seite sofort geladen:
|
||
|
|
// lazy geladene Bilder, die nie im Sichtfeld waren,
|
||
|
|
// druckt Chrome sonst als leere Flächen.
|
||
|
|
'eager' => true,
|
||
|
|
]); ?>
|
||
|
|
</div>
|
||
|
|
<?php endforeach; ?>
|
||
|
|
</div>
|
||
|
|
</li>
|
||
|
|
<?php endforeach; ?>
|
||
|
|
</ol>
|
||
|
|
<?php /* Anleitung + Druck-Button bewusst UNTER den Blättern (Wunsch Felix,
|
||
|
|
29.07.2026): erst die Vorschau komplett durchsehen, ganz unten
|
||
|
|
drucken. */ ?>
|
||
|
|
<div class="stadionzeitung-druck__hilfe">
|
||
|
|
<h2 class="stadionzeitung-druck__hilfe-title">Drucken</h2>
|
||
|
|
<p>
|
||
|
|
<?= intdiv($n, 4) ?> Blätter A4 quer<?= $fill > 0 ? ', mit ' . $fill . ' weißen Füllseiten auf ' . $n . ' Seiten aufgefüllt' : ' (' . $n . ' Seiten)' ?>.
|
||
|
|
Beidseitig drucken und dabei <strong>an der kurzen Kante spiegeln</strong>,
|
||
|
|
danach alle Blätter aufeinanderlegen und mittig falten — fertig ist das Heft.
|
||
|
|
</p>
|
||
|
|
<button class="btn stadionzeitung-druck__print-btn" type="button" data-druck-print hidden>
|
||
|
|
<?= icon('printer') ?> Jetzt drucken
|
||
|
|
</button>
|
||
|
|
</div>
|
||
|
|
</section>
|