PDF Fusszeile und watermak mandantenfähig gemacht.

This commit is contained in:
2026-07-19 23:39:52 +02:00
parent 0551b13a86
commit 6127d84d11
4 changed files with 69 additions and 9 deletions
+21 -4
View File
@@ -276,7 +276,9 @@ function saas_fetch_tenant_settings(PDO $pdo, int $tenantId): ?array
ts.negative_warning_cents, ts.negative_warning_cents,
ts.pdf_show_empty_rows, ts.pdf_show_empty_rows,
ts.pdf_split_mode, ts.pdf_split_mode,
ts.pdf_row_height_px ts.pdf_row_height_px,
ts.pdf_watermark_text,
ts.pdf_footer_text
FROM tenants t FROM tenants t
LEFT JOIN tenant_settings ts ON ts.tenant_id = t.id LEFT JOIN tenant_settings ts ON ts.tenant_id = t.id
WHERE t.id = ? WHERE t.id = ?
@@ -312,6 +314,8 @@ function saas_fetch_tenant_settings(PDO $pdo, int $tenantId): ?array
'pdf_show_empty_rows' => (int)$settings['pdf_show_empty_rows'], 'pdf_show_empty_rows' => (int)$settings['pdf_show_empty_rows'],
'pdf_split_mode' => (string)$settings['pdf_split_mode'], 'pdf_split_mode' => (string)$settings['pdf_split_mode'],
'pdf_row_height_px' => (int)$settings['pdf_row_height_px'], 'pdf_row_height_px' => (int)$settings['pdf_row_height_px'],
'pdf_watermark_text' => (string)$settings['pdf_watermark_text'],
'pdf_footer_text' => (string)$settings['pdf_footer_text'],
]; ];
} }
@@ -327,6 +331,8 @@ function saas_update_tenant_settings(PDO $pdo, int $tenantId, array $input): arr
$paypalUrlTemplate = trim((string)($input['paypal_url_template'] ?? '')); $paypalUrlTemplate = trim((string)($input['paypal_url_template'] ?? ''));
$pdfSplitMode = trim((string)($input['pdf_split_mode'] ?? 'drinking_behavior')); $pdfSplitMode = trim((string)($input['pdf_split_mode'] ?? 'drinking_behavior'));
$pdfRowHeightPx = filter_var($input['pdf_row_height_px'] ?? null, FILTER_VALIDATE_INT); $pdfRowHeightPx = filter_var($input['pdf_row_height_px'] ?? null, FILTER_VALIDATE_INT);
$pdfWatermarkText = trim((string)($input['pdf_watermark_text'] ?? ''));
$pdfFooterText = trim((string)($input['pdf_footer_text'] ?? ''));
$errors = []; $errors = [];
if (strlen($tenantName) < 3 || strlen($tenantName) > 255) { if (strlen($tenantName) < 3 || strlen($tenantName) > 255) {
@@ -356,6 +362,12 @@ function saas_update_tenant_settings(PDO $pdo, int $tenantId, array $input): arr
if (!in_array($pdfSplitMode, ['drinking_behavior', 'alphabetical'], true)) { if (!in_array($pdfSplitMode, ['drinking_behavior', 'alphabetical'], true)) {
$errors[] = 'Die Sortierung für den Ausdruck ist ungültig.'; $errors[] = 'Die Sortierung für den Ausdruck ist ungültig.';
} }
if (strlen($pdfWatermarkText) > 500) {
$errors[] = 'Der Wasserzeichen-Text im Ausdruck ist zu lang (max. 500 Zeichen).';
}
if (strlen($pdfFooterText) > 500) {
$errors[] = 'Der Fußzeilen-Hinweis im Ausdruck ist zu lang (max. 500 Zeichen).';
}
if ($pdfRowHeightPx === false || $pdfRowHeightPx < 10 || $pdfRowHeightPx > 60) { if ($pdfRowHeightPx === false || $pdfRowHeightPx < 10 || $pdfRowHeightPx > 60) {
$errors[] = 'Die Zeilenhöhe im Ausdruck muss zwischen 10 und 60 Pixel liegen.'; $errors[] = 'Die Zeilenhöhe im Ausdruck muss zwischen 10 und 60 Pixel liegen.';
} }
@@ -382,8 +394,9 @@ function saas_update_tenant_settings(PDO $pdo, int $tenantId, array $input): arr
'INSERT INTO tenant_settings 'INSERT INTO tenant_settings
(tenant_id, mark_price_cents, self_entry_enabled, paypal_enabled, (tenant_id, mark_price_cents, self_entry_enabled, paypal_enabled,
paypal_url_template, sheet_window_days, negative_warning_cents, paypal_url_template, sheet_window_days, negative_warning_cents,
pdf_show_empty_rows, pdf_split_mode, pdf_row_height_px) pdf_show_empty_rows, pdf_split_mode, pdf_row_height_px,
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) pdf_watermark_text, pdf_footer_text)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE ON DUPLICATE KEY UPDATE
mark_price_cents = VALUES(mark_price_cents), mark_price_cents = VALUES(mark_price_cents),
self_entry_enabled = VALUES(self_entry_enabled), self_entry_enabled = VALUES(self_entry_enabled),
@@ -393,7 +406,9 @@ function saas_update_tenant_settings(PDO $pdo, int $tenantId, array $input): arr
negative_warning_cents = VALUES(negative_warning_cents), negative_warning_cents = VALUES(negative_warning_cents),
pdf_show_empty_rows = VALUES(pdf_show_empty_rows), pdf_show_empty_rows = VALUES(pdf_show_empty_rows),
pdf_split_mode = VALUES(pdf_split_mode), pdf_split_mode = VALUES(pdf_split_mode),
pdf_row_height_px = VALUES(pdf_row_height_px)' pdf_row_height_px = VALUES(pdf_row_height_px),
pdf_watermark_text = VALUES(pdf_watermark_text),
pdf_footer_text = VALUES(pdf_footer_text)'
); );
$stmt->execute([ $stmt->execute([
$tenantId, $tenantId,
@@ -406,6 +421,8 @@ function saas_update_tenant_settings(PDO $pdo, int $tenantId, array $input): arr
$pdfShowEmptyRows, $pdfShowEmptyRows,
$pdfSplitMode, $pdfSplitMode,
(int)$pdfRowHeightPx, (int)$pdfRowHeightPx,
$pdfWatermarkText,
$pdfFooterText,
]); ]);
$pdo->commit(); $pdo->commit();
@@ -0,0 +1,3 @@
ALTER TABLE tenant_settings
ADD COLUMN pdf_watermark_text VARCHAR(500) NOT NULL DEFAULT 'Fragen oder Unklarheiten? Bitte lies zuerst die FAQs hinter dieser Liste!' AFTER pdf_row_height_px,
ADD COLUMN pdf_footer_text VARCHAR(500) NOT NULL DEFAULT '' AFTER pdf_watermark_text;
+35 -5
View File
@@ -32,13 +32,18 @@ $markPrice = number_format(($settings['mark_price_cents'] ?? 20) / 100, 2, ',',
$showEmptyRows = (int)($settings['pdf_show_empty_rows'] ?? 1) === 1; $showEmptyRows = (int)($settings['pdf_show_empty_rows'] ?? 1) === 1;
$splitMode = (string)($settings['pdf_split_mode'] ?? 'drinking_behavior'); $splitMode = (string)($settings['pdf_split_mode'] ?? 'drinking_behavior');
$adminRowHeightPx = (int)($settings['pdf_row_height_px'] ?? 16); $adminRowHeightPx = (int)($settings['pdf_row_height_px'] ?? 16);
$watermarkText = trim((string)($settings['pdf_watermark_text'] ?? ''));
$footerText = trim((string)($settings['pdf_footer_text'] ?? ''));
// Ab dieser Mitgliederzahl wird auf zwei Seiten (Vorder-/Rueckseite) statt // Ab dieser Mitgliederzahl wird auf zwei Seiten (Vorder-/Rueckseite) statt
// einer einzelnen Seite gedruckt. // einer einzelnen Seite gedruckt.
define('EXPORT_MULTI_PAGE_THRESHOLD', 50); define('EXPORT_MULTI_PAGE_THRESHOLD', 50);
// Platzbudget in TCPDF-HTML-"px" fuer die Datenzeilen einer Seite, kalibriert // Platzbudget in TCPDF-HTML-"px" fuer die Datenzeilen einer Seite, kalibriert
// an der bisherigen Ausgabe (63 Zeilen a 16px auf einer vollen A4-Seite). // an der bisherigen Ausgabe (63 Zeilen a 16px auf einer vollen A4-Seite). Ist
define('EXPORT_PAGE_ROW_BUDGET_PX', 63 * 16); // eine Fusszeile konfiguriert, wird ihr reservierter Platz abgezogen, damit
// die letzte Tabellenzeile sie nicht ueberlappt.
define('EXPORT_FOOTER_RESERVE_PX', 40);
define('EXPORT_PAGE_ROW_BUDGET_PX', (63 * 16) - ($footerText !== '' ? EXPORT_FOOTER_RESERVE_PX : 0));
// Technischer Mindestwert, nur als letzte Bremse gegen 0/negative Hoehen bei // Technischer Mindestwert, nur als letzte Bremse gegen 0/negative Hoehen bei
// absurd hohen Teilnehmerzahlen - kein gestalterisches Minimum. // absurd hohen Teilnehmerzahlen - kein gestalterisches Minimum.
define('EXPORT_HARD_MIN_ROW_HEIGHT_PX', 6); define('EXPORT_HARD_MIN_ROW_HEIGHT_PX', 6);
@@ -130,24 +135,49 @@ function export_render_page_html(array $teilnehmer, string $titel, string $hinwe
require_once(__DIR__ . '/TCPDF/tcpdf.php'); require_once(__DIR__ . '/TCPDF/tcpdf.php');
class MyCustomPDFWithWatermark extends TCPDF { class MyCustomPDFWithWatermark extends TCPDF {
public string $watermarkText = '';
public string $footerText = '';
public function Header() { public function Header() {
if (trim($this->watermarkText) === '') {
return;
}
$bMargin = $this->getBreakMargin(); $bMargin = $this->getBreakMargin();
$auto_page_break = $this->AutoPageBreak; $auto_page_break = $this->AutoPageBreak;
$this->SetAutoPageBreak(false, 0); $this->SetAutoPageBreak(false, 0);
$img_file = __DIR__ . '/watermark.jpg';
$this->SetAlpha(0.35); $this->SetAlpha(0.35);
$this->Image($img_file, 0, 0, 223, 280, '', '', '', false, 300, '', false, false, 0); $this->SetFont('helvetica', '', 14);
$this->SetTextColor(0, 0, 0);
foreach ([40, 140, 240] as $y) {
$this->MultiCell(90, 0, $this->watermarkText, 0, 'L', false, 1, 110, $y);
}
$this->SetAlpha(1); $this->SetAlpha(1);
$this->SetFont('helvetica', '', 9.5);
$this->SetAutoPageBreak($auto_page_break, $bMargin); $this->SetAutoPageBreak($auto_page_break, $bMargin);
$this->setPageMark(); $this->setPageMark();
} }
public function Footer() {
if (trim($this->footerText) === '') {
return;
}
$this->SetY(-15);
$this->SetFont('helvetica', '', 8);
$this->SetTextColor(120, 120, 120);
$this->Cell(0, 10, $this->footerText, 0, 0, 'C');
$this->SetTextColor(0, 0, 0);
}
} }
$pdf = new MyCustomPDFWithWatermark(PDF_PAGE_ORIENTATION, 'mm', 'A4', true, 'UTF-8', false); $pdf = new MyCustomPDFWithWatermark(PDF_PAGE_ORIENTATION, 'mm', 'A4', true, 'UTF-8', false);
$pdf->watermarkText = $watermarkText;
$pdf->footerText = $footerText;
$pdf->SetHeaderData("", 0, "Kaffeestrichliste", ""); $pdf->SetHeaderData("", 0, "Kaffeestrichliste", "");
$pdf->SetPrintFooter(false); $pdf->SetPrintFooter(true);
$pdf->SetMargins('5', '5', '5'); $pdf->SetMargins('5', '5', '5');
$pdf->SetAutoPageBreak(true, 5); $pdf->SetAutoPageBreak(true, 5);
$pdf->SetFont('helvetica', '', 9.5); $pdf->SetFont('helvetica', '', 9.5);
+10
View File
@@ -35,6 +35,8 @@ if ($canManageSettings) {
'pdf_show_empty_rows' => !empty($_POST['pdf_show_empty_rows']) ? 1 : 0, 'pdf_show_empty_rows' => !empty($_POST['pdf_show_empty_rows']) ? 1 : 0,
'pdf_split_mode' => $_POST['pdf_split_mode'] ?? 'drinking_behavior', 'pdf_split_mode' => $_POST['pdf_split_mode'] ?? 'drinking_behavior',
'pdf_row_height_px' => $_POST['pdf_row_height_px'] ?? 16, 'pdf_row_height_px' => $_POST['pdf_row_height_px'] ?? 16,
'pdf_watermark_text' => $_POST['pdf_watermark_text'] ?? '',
'pdf_footer_text' => $_POST['pdf_footer_text'] ?? '',
]; ];
} }
} else { } else {
@@ -132,6 +134,14 @@ include 'nav.php';
<label for="pdf_row_height_px">Zeilenhöhe im Ausdruck (1060px)</label> <label for="pdf_row_height_px">Zeilenhöhe im Ausdruck (1060px)</label>
<input type="number" name="pdf_row_height_px" id="pdf_row_height_px" min="10" max="60" value="<?php echo saas_html($settings['pdf_row_height_px']); ?>" required> <input type="number" name="pdf_row_height_px" id="pdf_row_height_px" min="10" max="60" value="<?php echo saas_html($settings['pdf_row_height_px']); ?>" required>
</div> </div>
<div class="col-12">
<label for="pdf_watermark_text">Wasserzeichen-Text im Ausdruck (leer = kein Wasserzeichen)</label>
<input type="text" name="pdf_watermark_text" id="pdf_watermark_text" maxlength="500" value="<?php echo saas_html($settings['pdf_watermark_text']); ?>">
</div>
<div class="col-12">
<label for="pdf_footer_text">Hinweis in der Fußzeile des Ausdrucks (leer = keine Fußzeile)</label>
<input type="text" name="pdf_footer_text" id="pdf_footer_text" maxlength="500" value="<?php echo saas_html($settings['pdf_footer_text']); ?>">
</div>
</div> </div>
<ul class="actions"> <ul class="actions">
<li><button type="submit">Speichern</button></li> <li><button type="submit">Speichern</button></li>