Files
kaffeekasse-saas/app/plan-watermark.php
T
clemensandClaude Opus 5 9b309bb942 Hinweis auf die Kaffeeliste auch im PDF-Ausdruck
Die Marke stand bisher nur in der Web-Ansicht; auf dem Ausdruck, den die
Mitglieder taeglich vor sich haben, fehlte sie. Sie erscheint jetzt unten
rechts im Seitenfuss - nach derselben Regel wie im Web: im kostenlosen
Tarif fest, sonst nach Mandant-Einstellung.

Die Tasse wird mit TCPDFs Zeichenbefehlen gemalt statt als SVG oder Bild
eingebettet: ImageSVG braucht die XML-Extension, ein Rasterbild GD - beides
ist auf einem Webspace nicht garantiert.

Der Schriftzug sitzt in einer Cell() statt in Text(): dessen y-Bezug haengt
an Schriftmetriken und ergab in der Probe einen um Millimeter versetzten
Schriftzug. Steht die Marke, reserviert export_page_row_budget_mm() 6 mm am
Seitenfuss, damit die Tabelle nicht hineinlaeuft.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 00:46:52 +02:00

121 lines
4.1 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
require_once __DIR__ . '/bootstrap.php';
/**
* Wasserzeichen des kostenlosen Tarifs: eine kleine Marke unten rechts, die
* auf die Kaffeeliste verweist. Sie erscheint nur im Tarif "free" - wer
* zahlt, bekommt seine Oberflaeche ohne fremdes Logo.
*
* Bewusst getrennt von app/branding.php: dort geht es um das Logo *des
* Mandanten*, hier um das Logo *des Anbieters*. Beide koennen gleichzeitig
* sichtbar sein (Kopfzeile oben, Wasserzeichen unten rechts).
*/
/**
* Tarif eines Mandanten, ohne Seiteneffekt. Absichtlich nicht
* billing_fetch_or_init(): das Wasserzeichen wird auf jeder Seite geprueft
* und darf dabei keine Zeile anlegen. Fehlt der Datensatz, gilt - wie beim
* Anlegen - "free".
*/
function plan_watermark_plan_code(PDO $pdo, int $tenantId): string
{
static $cache = [];
if (array_key_exists($tenantId, $cache)) {
return $cache[$tenantId];
}
try {
$stmt = $pdo->prepare('SELECT plan_code FROM tenant_billing WHERE tenant_id = ?');
$stmt->execute([$tenantId]);
$planCode = $stmt->fetchColumn();
$cache[$tenantId] = $planCode === false ? 'free' : (string)$planCode;
} catch (Throwable $e) {
// Laesst sich der Tarif nicht lesen, bleibt die Oberflaeche sauber -
// ein Wasserzeichen bei einem zahlenden Kunden waere der schlimmere
// Fehler als ein fehlendes bei einem kostenlosen.
$cache[$tenantId] = 'unknown';
}
return $cache[$tenantId];
}
/**
* Zeigt dieser Mandant das Wasserzeichen? Im kostenlosen Tarif immer - es ist
* der Gegenwert fuer die kostenlose Nutzung und deshalb nicht abschaltbar.
* Alle anderen entscheiden ueber die Mandant-Einstellung
* `watermark_enabled` (Standard: an).
*/
function plan_watermark_visible(PDO $pdo, int $tenantId): bool
{
if ($tenantId <= 0) {
return false;
}
$planCode = plan_watermark_plan_code($pdo, $tenantId);
if ($planCode === 'free') {
return true;
}
if ($planCode === 'unknown') {
return false;
}
require_once __DIR__ . '/features.php';
return app_tenant_switch_enabled($pdo, $tenantId, 'watermark_enabled');
}
/**
* Wortmarke der Kaffeeliste als Inline-SVG. Als Inline-Grafik statt als
* Bilddatei, damit das Wasserzeichen ohne zusaetzlichen Request auskommt,
* auf jedem Bildschirm scharf bleibt und die Farbe der Umgebung uebernimmt.
*/
function plan_watermark_logo_svg(): string
{
return '<svg class="plan-watermark-logo" viewBox="0 0 24 24" width="18" height="18" '
. 'aria-hidden="true" focusable="false" fill="none" stroke="currentColor" '
. 'stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">'
. '<path d="M4 9h13v6a4 4 0 0 1-4 4H8a4 4 0 0 1-4-4V9Z"/>'
. '<path d="M17 10.5h1.5a2.5 2.5 0 0 1 0 5H17"/>'
. '<path d="M8 5.5c0-1 1-1.4 1-2.5M12 5.5c0-1 1-1.4 1-2.5"/>'
. '</svg>';
}
/**
* Beschriftung des Wasserzeichens: die Marketing-Domain ohne Schema
* ("kaffeeliste.de"). Laesst sie sich nicht ermitteln, bleibt der Name der
* App uebrig. Wird von der Web-Ansicht und vom PDF-Ausdruck gemeinsam
* genutzt, damit beide dieselbe Adresse nennen.
*/
function plan_watermark_label(): string
{
$url = app_marketing_url();
return $url !== '' ? (string)preg_replace('#^https?://#i', '', $url) : 'Kaffeeliste';
}
/**
* Markup des Wasserzeichens. Ohne erreichbare Marketing-Domain (CLI,
* ungewoehnliche Hosts) bleibt es bei Logo und Namen ohne Link - ein
* Verweis ins Leere waere schlechter als keiner.
*/
function plan_watermark_html(): string
{
$url = app_marketing_url();
$label = plan_watermark_label();
$inner = plan_watermark_logo_svg()
. '<span class="plan-watermark-text">' . htmlspecialchars($label, ENT_QUOTES, 'UTF-8') . '</span>';
if ($url === '') {
return '<div class="plan-watermark" title="Kaffeeliste die digitale Kaffeekasse">' . $inner . '</div>';
}
return '<a class="plan-watermark" href="' . htmlspecialchars($url, ENT_QUOTES, 'UTF-8') . '"'
. ' target="_blank" rel="noopener noreferrer"'
. ' title="Kaffeeliste die digitale Kaffeekasse">' . $inner . '</a>';
}