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.pdf_show_empty_rows,
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
LEFT JOIN tenant_settings ts ON ts.tenant_id = 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_split_mode' => (string)$settings['pdf_split_mode'],
'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'] ?? ''));
$pdfSplitMode = trim((string)($input['pdf_split_mode'] ?? 'drinking_behavior'));
$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 = [];
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)) {
$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) {
$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
(tenant_id, mark_price_cents, self_entry_enabled, paypal_enabled,
paypal_url_template, sheet_window_days, negative_warning_cents,
pdf_show_empty_rows, pdf_split_mode, pdf_row_height_px)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
pdf_show_empty_rows, pdf_split_mode, pdf_row_height_px,
pdf_watermark_text, pdf_footer_text)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON DUPLICATE KEY UPDATE
mark_price_cents = VALUES(mark_price_cents),
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),
pdf_show_empty_rows = VALUES(pdf_show_empty_rows),
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([
$tenantId,
@@ -406,6 +421,8 @@ function saas_update_tenant_settings(PDO $pdo, int $tenantId, array $input): arr
$pdfShowEmptyRows,
$pdfSplitMode,
(int)$pdfRowHeightPx,
$pdfWatermarkText,
$pdfFooterText,
]);
$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;
$splitMode = (string)($settings['pdf_split_mode'] ?? 'drinking_behavior');
$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
// einer einzelnen Seite gedruckt.
define('EXPORT_MULTI_PAGE_THRESHOLD', 50);
// Platzbudget in TCPDF-HTML-"px" fuer die Datenzeilen einer Seite, kalibriert
// an der bisherigen Ausgabe (63 Zeilen a 16px auf einer vollen A4-Seite).
define('EXPORT_PAGE_ROW_BUDGET_PX', 63 * 16);
// an der bisherigen Ausgabe (63 Zeilen a 16px auf einer vollen A4-Seite). Ist
// 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
// absurd hohen Teilnehmerzahlen - kein gestalterisches Minimum.
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');
class MyCustomPDFWithWatermark extends TCPDF {
public string $watermarkText = '';
public string $footerText = '';
public function Header() {
if (trim($this->watermarkText) === '') {
return;
}
$bMargin = $this->getBreakMargin();
$auto_page_break = $this->AutoPageBreak;
$this->SetAutoPageBreak(false, 0);
$img_file = __DIR__ . '/watermark.jpg';
$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->SetFont('helvetica', '', 9.5);
$this->SetAutoPageBreak($auto_page_break, $bMargin);
$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->watermarkText = $watermarkText;
$pdf->footerText = $footerText;
$pdf->SetHeaderData("", 0, "Kaffeestrichliste", "");
$pdf->SetPrintFooter(false);
$pdf->SetPrintFooter(true);
$pdf->SetMargins('5', '5', '5');
$pdf->SetAutoPageBreak(true, 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_split_mode' => $_POST['pdf_split_mode'] ?? 'drinking_behavior',
'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 {
@@ -132,6 +134,14 @@ include 'nav.php';
<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>
</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>
<ul class="actions">
<li><button type="submit">Speichern</button></li>