Modul: Datenschutz / Nutzungsvereinbarung¶
Stand
Code-Analyse vom 2026-04-22 gegen sachpool.de, WebEdition 9.2.3, PHP 8.3.
Template-ModDate: 2026-01-26.
Zweck¶
Nach dem Login muss jeder Vermittler eine Datenschutz-/Nutzungsvereinbarung akzeptieren, bevor er den internen Bereich nutzen darf. Die Zustimmung wird mit Zeitstempel und IP-Adresse persistiert — DSGVO-konforme Nachweisbarkeit der Einwilligung.
Technische Integration¶
Ein einziges Template:
| Tpl-ID | Pfad | ModDate |
|---|---|---|
| 173 | sachpool-portal/datenschutzdialog/datenschutzdialog.tmpl |
2026-01-26 |
Einbindung auf allen Seiten im Login-Bereich über den Master-Wrap:
<we:ifRegisteredUser>
<we:include type="template" id="173" comment="datenschutz-dialog.tmpl" once="true" />
</we:ifRegisteredUser>
Datenmodell: Tabelle Vereinbarung¶
| Feld | Typ | Rolle |
|---|---|---|
id |
int PK | Datensatz-ID |
art |
int | Art der Vereinbarung — hart kodiert 1 = Datenschutz |
benutzer_id |
int | Personen-ID aus $sach_persid |
benutzer |
varchar | Vermittlernummer aus $sach_user |
ip |
varchar | IP zum Zeitpunkt der Einwilligung ($_SERVER['REMOTE_ADDR']) |
datum |
varchar | Zeitstempel YYYY-MM-DD HH:MM:SS (als String!) |
exported |
int | 0 = PDF noch nicht erstellt; wird von externem Tool aktualisiert |
Keine Text-/Versions-Speicherung
Der eingewilligte Text selbst wird nicht mitgespeichert — er existiert
nur im Template (kann sich zwischen Versionen ändern, ohne dass alte Zustimmungen
ungültig werden). → HANDLUNGSEMPFEHLUNGEN.md
Mehrere Vereinbarungs-Arten möglich
Das Feld art deutet auf weitere Werte (z. B. art=2 = Courtagevereinbarung)
hin — ein ehemaliger Block für Courtagevereinbarung ist im Template als
<we:comment>START DER CORTAGEVEREINBARUNG</we:comment> (sic!) auskommentiert.
Workflow¶
1. Guard¶
ifVarEmpty invertiert genutzt
Der Tag-Name ist irreführend — der Code läuft nur wenn $sach_user gesetzt
ist. WebEdition-Eigenheit oder Bug im Include-Kontext. Funktioniert, aber
unübersichtlich.
2. Check auf bestehende Zustimmung¶
$wedb = SachPoolDB::getInstance();
$query = 'SELECT art FROM Vereinbarung WHERE benutzer = "' . $sach_user . '"';
$result = $wedb->query($query);
$rows = mysqli_fetch_assoc($result);
if (isset($rows["art"]) && $rows["art"] == 1) {
$einwilligung = true;
}
3. Dialog-Anzeige bei fehlender Zustimmung¶
Bootstrap-Modal mit dem kompletten DSGVO-Text (Vertrag zwischen Vermittler und
Sachpool), Session-Felder aus Kontakt_* werden als sach_* global gesetzt und
im Vertragstext eingesetzt (Firmenname, Adresse, IHK-Nr., etc.).
Button-Zeile:
- Abbrechen →
/_login/index.php?we_webUser_logout=1(Logout!) - Senden → POST
?(gleiche URL) mitdv-akzeptiert=on
4. Persistierung bei Zustimmung¶
if (isset($sach_akzeptiert) && $sach_akzeptiert == "on") {
$einwilligung = true;
$query = 'INSERT INTO Vereinbarung (art, benutzer_id, benutzer, ip, datum, exported)
VALUES (1, "' . $sach_persid . '", "' . $sach_user . '",
"' . $_SERVER['REMOTE_ADDR'] . '",
"' . date('Y-m-d H:i:s') . '", 0)';
$wedb->query($query);
}
exported = 0 → Signal für den externen PDF-Export-Prozess, dass dieser
Datensatz noch nicht als PDF generiert wurde.
PDF-Export (extern)¶
Der PDF-Export selbst ist nicht im Template. Das Template markiert neue
Einwilligungen nur mit exported = 0. Ein externer Prozess (Cron oder manueller
Trigger — im Code nicht sichtbar) liest diese Datensätze, generiert PDFs und
setzt exported = 1.
→ Entwicklungsroadmap aus der Word-Doku: Wunsch ist, dass Sachpool selbst PDF-Export übernimmt (statt externes Tool).
Variablen aus Session → Global¶
Aus dem eingeloggten User werden via <we:setVar from="sessionfield" ... prepareSQL="true">
übernommen:
Kontakt_Anrede→$sach_anredeKontakt_Firma→$sach_firmaKontakt_Strasse→$sach_strasseKontakt_Nr→$sach_nrKontakt_Plz→$sach_plzKontakt_Ort→$sach_ortKontakt_Registernummer→$sach_ihk_nrKontakt_IHK→$sach_ihk_ort
Vorausgesetzt (aus authorization.tmpl):
- $sach_user — Vermittlernummer
- $sach_persid — Personen-ID
- $sach_forename, $sach_surname
Bekannte Altlasten¶
→ interne Datei HANDLUNGSEMPFEHLUNGEN.md im Repo-Root
- 🟡 Kein Versions-Tracking — alte Zustimmungen gelten bei Textänderung weiter
- 🟡 Keine CSRF-Token — Zustimmung per CSRF unterschiebbar (rechtlich bedenklich)
- 🟡 SQL-Konkatenation in INSERT/SELECT,
$sach_user/$sach_persidohne expliziten Escape - 🟡 Kein Unique-Index — Doppelklick = doppelter Eintrag
- 🟡
$_SERVER['REMOTE_ADDR']ohneX-Forwarded-For-Handling (Proxy-Setup liefert falsche IP) - 🟡
ifVarEmptyinvertiert genutzt, verwirrende Semantik - 🟢 Großer auskommentierter Courtagevereinbarungs-Block im Template (toter Code, Tippfehler „CORTAGE")
- 🟢 Debug-Block mit
$debug = falseinkl.var_dump($_POST)im Produktivcode