community und dsgvo
All checks were successful
Deploy / deploy (push) Successful in 51s

This commit is contained in:
2026-07-22 21:29:50 +02:00
parent 751b6996c4
commit eb16827fdf
7 changed files with 304 additions and 45 deletions

View File

@@ -3,6 +3,7 @@
<nav class="site-footer__links" aria-label="Footer">
<a href="/impressum">Impressum</a>
<a href="/ueber-uns">Über uns</a>
<button class="site-footer__link-button" type="button" data-consent-open>Cookie-Einstellungen</button>
</nav>
<p class="site-footer__copy">© Copyright <?= date('Y') ?> - Lars Gebhardt-Kusche</p>
</div>

View File

@@ -70,8 +70,93 @@ if ($debugEnabled) {
<?php asset_scripts('header'); ?>
</head>
<body data-auth="<?= isset($_SESSION['user_id']) ? '1' : '0' ?>" data-child-gender="<?= htmlspecialchars($childGender, ENT_QUOTES) ?>" data-location-preference="<?= htmlspecialchars($locationTrackingPreference, ENT_QUOTES) ?>">
<script>
(function () {
const storageKey = 'pkt_cookie_consent';
const read = () => {
try {
const raw = localStorage.getItem(storageKey);
return raw ? JSON.parse(raw) : null;
} catch (err) {
return null;
}
};
window.PKTConsent = window.PKTConsent || {
storageKey,
get() {
return read();
},
has(category) {
if (category === 'necessary') return true;
const consent = read();
return Boolean(consent && consent[category] === true);
},
openPreferences() {
document.dispatchEvent(new CustomEvent('pkt:open-consent'));
},
};
})();
</script>
<?php tpl('matomo', 'structure'); ?>
<?php tpl('nav', 'structure'); ?>
<div class="cookie-consent" id="cookieConsentBanner" hidden>
<div class="cookie-consent__inner">
<div class="cookie-consent__copy">
<strong>Cookies, Analyse und externe Dienste</strong>
<p>Notwendige Cookies für Sitzung und Login sind immer aktiv. Analyse mit Matomo sowie Karten-, Standort- und Geocoding-Funktionen werden erst nach deiner Auswahl geladen.</p>
</div>
<div class="cookie-consent__actions">
<button class="btn ghost" type="button" data-consent-necessary>Nur notwendige</button>
<button class="btn ghost" type="button" data-consent-open>Auswahl</button>
<button class="btn" type="button" data-consent-accept-all>Alle akzeptieren</button>
</div>
</div>
</div>
<div class="modal" id="cookieConsentModal">
<div class="panel">
<div class="head flex between center-y">
<h3 style="margin:0;">Cookie- und Diensteinstellungen</h3>
<button class="btn ghost" type="button" data-consent-close>✕</button>
</div>
<div class="stack gap-12" style="margin-top:12px;">
<p class="muted" style="margin:0;">Du kannst nicht notwendige Funktionen freiwillig aktivieren oder später wieder widerrufen.</p>
<div class="card">
<strong>Notwendig</strong>
<p class="muted small">Sitzung, Login und Sicherheitsfunktionen. Immer aktiv.</p>
</div>
<label class="card" style="display:block; cursor:pointer;">
<input type="checkbox" id="consentAnalytics" style="margin-right:8px;">
<strong>Analyse mit Matomo</strong>
<p class="muted small" style="margin:8px 0 0;">Reichweitenmessung und Nutzungsanalyse.</p>
</label>
<label class="card" style="display:block; cursor:pointer;">
<input type="checkbox" id="consentExternalServices" style="margin-right:8px;">
<strong>Externe Dienste, Karten und Standort</strong>
<p class="muted small" style="margin:8px 0 0;">Browser-Geolocation, lokale Standortspeicherung, Leaflet von `unpkg.com` und Geocoding/Reverse-Geocoding über OpenStreetMap Nominatim.</p>
</label>
<div class="flex gap-12" style="flex-wrap:wrap;">
<button class="btn ghost" type="button" data-consent-necessary>Nur notwendige</button>
<button class="btn" type="button" data-consent-save>Auswahl speichern</button>
</div>
</div>
</div>
</div>
<div class="modal" id="locationPreferenceModal">
<div class="panel">
<div class="head flex between center-y">
<h3 style="margin:0;">Standortfreigabe</h3>
<button class="btn ghost" type="button" data-location-pref-close>✕</button>
</div>
<div class="stack gap-12" style="margin-top:12px;">
<p class="muted" style="margin:0;">Damit wir dir passende Treffen in deiner Nähe zeigen können, dürfen wir deinen Standort verwenden. Wie soll das gehandhabt werden?</p>
<div class="stack gap-10">
<button class="btn" type="button" data-location-pref-choice="session">Nur für diesen Besuch</button>
<button class="btn ghost" type="button" data-location-pref-choice="enabled">Immer erlauben</button>
<button class="btn ghost" type="button" data-location-pref-choice="disabled">Niemals</button>
</div>
</div>
</div>
</div>
<?php if ($debugEnabled): ?>
<style>

View File

@@ -1,40 +1,15 @@
<?php if (!defined('MATOMO_SITE_ID')) return; ?>
<?php if (!defined('MATOMO_ENABLED') || !MATOMO_ENABLED) return; ?>
<?php
$primaryDomain = app_primary_domain();
$primaryDomain = app_primary_domain();
$fakecheckDomain = app_fakecheck_domain();
// Build allowed domains for tracking (hosts only, no paths)
$matomoDomains = array_values(array_unique(array_filter([
$primaryDomain ? '*.' . $primaryDomain : null,
($fakecheckDomain && $fakecheckDomain !== $primaryDomain) ? '*.' . $fakecheckDomain : null,
])));
?>
<!-- Matomo -->
<script>
var _paq = window._paq = window._paq || [];
_paq.push(["setDomains", <?= json_encode($matomoDomains, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) ?>]);
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
var u = "<?= rtrim(MATOMO_URL, '/') ?>/";
_paq.push(['setTrackerUrl', u + 'matomo.php']);
_paq.push(['setSiteId', '<?= MATOMO_SITE_ID ?>']);
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
g.async=true;
g.src=u + 'matomo.js';
s.parentNode.insertBefore(g,s);
})();
</script>
<noscript>
<p>
<img referrerpolicy="no-referrer-when-downgrade"
src="<?= rtrim(MATOMO_URL,'/') ?>/matomo.php?idsite=<?= MATOMO_SITE_ID ?>&amp;rec=1"
style="border:0;" alt="" />
</p>
</noscript>
<!-- End Matomo -->
<script type="application/json" id="matomoConfig"><?= json_encode([
'url' => rtrim(MATOMO_URL, '/') . '/',
'siteId' => (string) MATOMO_SITE_ID,
'domains' => $matomoDomains,
], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) ?></script>