Contao escapes the descriptions in BackendUser::navigation() and the menu template escapes the title attribute again, so "W&K" showed as "W&K". Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
W&K-Sync Bundle
Verbindet Contao 5.7 mit der Seminarverwaltung W&K (Windows-Software ohne Schnittstelle) über CSV-Dateien:
- Import: Die Redaktion exportiert in W&K die Seminarliste als CSV und lädt sie im Contao-Backend hoch. Vor dem Schreiben zeigt eine Vorschau, was sich ändert (neu, geändert, storniert, unverändert, übersprungen, Warnungen). Erst nach Bestätigung werden die Veranstaltungen im Kalender angelegt bzw. aktualisiert.
- Online-Anmeldung: Besucher melden sich über ein Formular des Formulargenerators zu einer Veranstaltung an. Das Bundle blendet je nach Veranstaltung Felder ein und aus, prüft Plätze und Anmeldeschluss, speichert die Anmeldung, verschickt die passende Benachrichtigung (Notification Center 2) und leitet auf die Bestätigungsseite weiter.
- Posteingang: Anmeldungen und Kontaktanfragen werden in Ordnern bearbeitet (Neu, Download-Liste, Bereits bearbeitet, Ignoriert/Spam, Exportiert).
- Export: Die Download-Liste wird als CSV für den W&K-Import erzeugt (ISO-8859-1, Semikolon, feste Spalten), die Datensätze werden als exportiert markiert und die freien Plätze der Veranstaltungen reduziert.
- Contao 5.7, PHP 8.5, Doctrine DBAL 4
- Keine Abhängigkeiten außer dem Contao-Core und dem Kalender-Bundle
- Notification Center 2 wird für Benachrichtigungen empfohlen (Typ „W&K-Anmeldung“), ist aber nicht erforderlich
- Newsletter-Anmeldung (Double-Opt-in) mit dem Newsletter-Bundle, optional
Installation
composer require mummert/wk-sync-bundle
Das Paket liegt nicht auf Packagist; das Repository in der composer.json des Projekts eintragen:
"repositories": [
{ "type": "vcs", "url": "ssh://git@git.mummert.media:3245/mummert/wk-sync-bundle.git" }
]
Danach die Datenbank aktualisieren:
vendor/bin/contao-console contao:migrate
Einrichtung
-
Kategorien anlegen – Backend „W&K-Tools → Kategorien“ oder die Standardkategorien des TPI Moritzburg per Befehl:
vendor/bin/contao-console wk-sync:categories:seedJede Kategorie hat eine Art (Schule, Evangelische Schulen, Elementarbereich, Gemeinde, Gottesdienst mit Kindern, Tagungen, Ausbildung, Mentoring, Sonstiges) und die W&K-Bezeichnungen (Werte des Felds
kbsgebiet, eine pro Zeile). Beim Import zählen genaue Treffer zuerst (alle Kategorien mit dieser Bezeichnung, z. B. „Alle Schularten“ für Grundschule und weiterführende Schule), sonst der erste Teilstring-Treffer in Sortierreihenfolge. Die erste zugeordnete Kategorie wird Hauptkategorie und steuert die Formularregeln und die Benachrichtigung. -
Anmeldeformular anlegen – im Formulargenerator, am einfachsten per Befehl (legt alle Felder mit passenden Namen, Optionen und CSS-Klassen an und trägt es im Kalender ein):
vendor/bin/contao-console wk-sync:form:create --calendar=1Die Feldnamen entsprechen den Spalten von
tl_wk_booking(gender,firstname,lastname,street,postal,city,email,phone,position,birthday,teacherPosition,schoolName,schoolCity,vegetarian,overnightStay,addDifferentInvoiceAddress,invoice…,addNotes,notes,newsletter,privacyAccepted,agbAccepted). Spamschutz über das ALTCHA-Feld des Contao-Kerns. Das Formular braucht keine Weiterleitungsseite und kein „Daten in Tabelle speichern“ – beides übernimmt das Bundle. -
Einstellungen anlegen – Backend „W&K-Tools → Einstellungen → Neu“, ein Eintrag je Kalender:
- Kalender, in den importiert wird und dessen Veranstaltungen buchbar sind
- Anmeldeformular, Seite mit dem Anmeldeformular, Bestätigungsseite, Seite mit dem Anfrageformular
- Anmeldeschluss (Tage vor Beginn, Standard 1) und angezeigter Anmeldeschluss (Standard 31)
- Eigene Veranstaltungsorte (Standard „TPI Moritzburg“; Orte, die so beginnen, gelten als „im eigenen Haus“)
- Autor importierter Veranstaltungen, Mitgliedergruppen für Kursleitung und Referenten (leer = keine Mitglieder anlegen)
- Newsletter-Verteiler und Aktivierungsseite (optional)
- Benachrichtigungen: Standard sowie je Bedingung 1–12 (siehe unten); die Auswahl zeigt den Titel mit ID
wk-sync:form:create --calendar=1legt den Eintrag bei Bedarf mit an. Am Kalender selbst wird nichts konfiguriert. -
Seiten und Module
- Seite Kurs (
kurs): Modul Event-Reader des Kerns plus Modul W&K-Anmeldestatus (freie Plätze, Anmeldeschluss, Link „Jetzt anmelden“, Hinweis bei externer Anmeldung, geschlossenem Teilnehmerkreis usw.) - Seite Anmeldung (
kurs/anmeldung): Modul W&K-Anmeldeformular – wird wie der Event-Reader mit dem Alias der Veranstaltung aufgerufen (/kurs/anmeldung/<alias>) - Seite Anmeldung eingegangen: Text; der Link enthält
?booking=<Token>, damit Folgeformulare (z. B. Workshop-Auswahl) die Anmeldung kennen (siehe unten) - Seite Anfrage: Formular des Formulargenerators mit „Daten in Tabelle speichern“ →
tl_wk_inquiry(Feldnamengender,academicTitle,firstname,lastname,street,postal,city,email,phone,subject,notes,newsletter,privacy). Der Link vom Anmeldestatus hängt?event=<ID>an; das Bundle trägt die Veranstaltung automatisch ein. - Kalender-Module des Kerns (Eventliste, Kalender, Eventmenü) erhalten das Feld W&K-Kategorien, um nur Veranstaltungen bestimmter Kategorien zu zeigen.
- Seite Kurs (
-
Benachrichtigungen (Notification Center 2): Benachrichtigungen vom Typ W&K-Anmeldung anlegen (System → Benachrichtigungen) und unter W&K-Tools → Einstellungen den Bedingungen zuordnen. Ohne zugeordnete Benachrichtigung wird die Anmeldung gespeichert, aber keine Mail verschickt (Warnung im Systemprotokoll). Tokens:
##recipient_email##,##subscription_*##(alle Felder der Anmeldung, Auswahlfelder zusätzlich als##subscription_gender_label##usw., Ja/Nein-Felder als##subscription_vegetarian_label##),##event_*##(alle Felder der Veranstaltung, Datumsfelder formatiert),##event_datetime##,##event_link##,##event_categories##,##event_speakers##,##subscription_event_wk_id##,##subscription_confirmation_page_url##,##calendar_*##,##admin_email##. Die bisherigen Token-Namenevent_organizerCityundevent_internalEventNumberbleiben erhalten. -
Benutzergruppen: Zugriff auf die Module des Bereichs „W&K-Tools“ (Import, Posteingang, Anmeldungen, Kontaktanfragen, Exporte, Kategorien, Einstellungen, Protokoll) freigeben. Anmeldungen werden ausschließlich dort bearbeitet, nicht am Event im Kalender.
Import aus W&K
Backend → W&K-Tools → Import → Datei hochladen. Erwartet wird der Seminarexport aus W&K (Semikolon, Anführungszeichen, Windows-1252 oder UTF-8, mehrzeilige Felder). Wichtig: in W&K das größtmögliche Zeitintervall exportieren – Seminare, die nicht in der Datei stehen, werden storniert und ausgeblendet (nur Veranstaltungen des Kalenders, die eine W&K-Nummer tragen; manuell angelegte Veranstaltungen ohne W&K-Nummer bleiben unberührt).
Regeln beim Import:
| W&K | Contao | Bemerkung |
|---|---|---|
kbnr |
wkId |
Muss mit einer führenden Null beginnen, sonst wird der Datensatz übersprungen |
kbvsnr |
wkInternalEventNumber |
Leer = nicht veröffentlichen (übersprungen); „keine“ wird zu leer |
kbtitel, kbutitel, kbrtitel |
title, wkSubTitle, wkSubTitleAdditional |
Titel ist Pflicht |
kbanreise, kbabreise, kbuanreise, kbuabreise |
startDate, endDate, startTime, endTime, addTime |
Datum TT.MM.JJJJ, Uhrzeit HH.MM; wie im Contao-Kern (ganztägig bis 23:59:59) |
kbstatus1 |
wkState |
1–5; 5 (Storno) blendet aus. Manuelles Ausblenden bleibt erhalten, bis sich der W&K-Status ändert |
kbsgebiet |
wkCategoryText, wkCategories, wkCategoryPrimary |
Keine Zuordnung möglich → Storno + Hinweis |
kbpmemo, kbzusatz |
teaser, wkTopics |
Text wird HTML-sicher in Absätze bzw. Listen (- ) umgewandelt |
kbwmemo |
wkTags |
Kommagetrennt, dedupliziert |
kbkln1, kbmref |
wkInstructor, wkSpeakers |
Mitglieder nach Nachname; werden nur angelegt, wenn im Kalender Mitgliedergruppen gesetzt sind. „N.N.“ wird ignoriert |
kbanzmax, kbanztat |
wkMaxPlaces, wkPlacesLeft |
Freie Plätze = max − belegt |
kbkp1–kbkp6, kbktxp1–kbktxp6 |
wkPrice1–6, wkPriceType1–6 |
Dezimalzahlen |
kbkd* |
wkOrganizer* |
Straße und Landeskennzahl richtig zugeordnet (war vertauscht) |
kbkdemail |
wkOrganizerEmail |
E-Mail oder URL (Veranstaltungsart 3: Anmeldung beim Veranstalter) |
kbvort, kbgruppe, kbvsart, kbztermin |
location, wkAudience, wkEventType, wkAdditionalDates |
„geschlossener Teilnehmerkreis“ verhindert die Online-Anmeldung |
Das Euro-Zeichen, das W&K als „Ç“ exportiert, wird im Umfeld von Zahlen korrigiert. Aliase werden nur beim Anlegen erzeugt und bleiben danach stabil. Jeder Import wird protokolliert (W&K-Tools → Protokoll); die Datei liegt unter var/wk-sync/imports/.
Auf der Konsole:
vendor/bin/contao-console wk-sync:import files/Import/stva.csv 1 # Vorschau
vendor/bin/contao-console wk-sync:import files/Import/stva.csv 1 --apply # anwenden
Formularregeln
Welche Felder das Anmeldeformular zeigt, hängt von der Hauptkategorie (Art), dem Veranstaltungsort und der Veranstaltungsnummer ab:
- Lehrertätigkeit (
teacherPosition,schoolName,schoolCity): nur bei den Arten Schule und Evangelische Schulen. - Abweichende Rechnungsanschrift: bei Schulkursen nur, wenn „Ich unterrichte an einer Schule in sonstiger Trägerschaft“ gewählt ist; sonst immer.
- Übernachtung: nur bei mehrtägigen Veranstaltungen. Bei EXTP-Kursen und Elementarkursen im eigenen Haus erscheint stattdessen der Hinweis, dass Übernachtung und Verpflegung direkt im Gästehaus gebucht werden (Erklärungsfeld mit CSS-Klasse
wk-slot-no-overnight-stay). Ausnahme: Lehrerkurse außer Haus zeigen das Feld. - Vegetarisch: nicht bei Online-Kursen und nicht bei mehrtägigen EXTP-Kursen oder Elementarkursen (außer Tagungen); Lehrerkurse außer Haus zeigen das Feld.
- Abhängige Felder (Schule, Rechnungsanschrift, Nachricht) werden serverseitig nur validiert und gespeichert, wenn ihr steuerndes Feld sichtbar ist und den passenden Wert hat; ein kleines Skript (
bundles/contaowksync/wk-sync.js) blendet sie im Browser ein und aus.
Zusätzlich prüft das Bundle vor dem Anzeigen und noch einmal beim Absenden: veröffentlicht, nicht storniert, kein geschlossener Teilnehmerkreis, keine externe Anmeldung (Veranstaltungsart 3 mit E-Mail/URL), Anmeldeschluss, freie Plätze (W&K-Stand minus offene Anmeldungen, zusätzlich maximale Plätze).
Benachrichtigungs-Bedingungen
Vorrang: Benachrichtigung an der Veranstaltung (Legende „Anmeldung“) → erste erfüllte Bedingung in den Einstellungen → Standard-Benachrichtigung der Einstellungen. Eine zutreffende Bedingung ohne Zuordnung wird übersprungen.
| Nr. | Bedingung |
|---|---|
| 1 | Online-Kurs (Veranstaltungsort „Online“) |
| 2 / 5 | Tages- / Mehrtagesveranstaltung, Art Schule, Nummer beginnt mit EXTP |
| 3 / 7 | Tages- / Mehrtagesveranstaltung, Art Gemeinde, Gottesdienst mit Kindern oder Tagungen |
| 4 / 6 | Tages- / Mehrtagesveranstaltung, Art Elementarbereich |
| 8 / 9 | Tages- / Mehrtagesveranstaltung, Art Evangelische Schulen |
| 10 / 11 | Tages- / Mehrtagesveranstaltung, Art Mentoring |
| 12 | Mehrtägige Ausbildung |
Ohne Notification Center werden Anmeldungen gespeichert, aber keine Mails verschickt (Warnung im Systemprotokoll).
Folgeformulare (z. B. Workshop-Auswahl)
Die Bestätigungsseite wird mit ?booking=<Token> aufgerufen. Formulare des Formulargenerators auf dieser Seite erhalten beim Absenden automatisch die Felder subscription (ID der Anmeldung), subscription_email, subscription_firstname, subscription_lastname, event, event_title und event_wk_id – in Benachrichtigungen als ##form_subscription_email## usw. verwendbar. Eine eigene Bestätigungsseite lässt sich je Veranstaltung hinterlegen.
Posteingang und Export
W&K-Tools → Posteingang. Neue Anmeldungen und Kontaktanfragen werden gesichtet und einzeln oder gesammelt verschoben. Doppelte Anmeldungen (gleiche E-Mail-Adresse, gleiche Veranstaltung) werden markiert. „Bearbeiten“ öffnet den Datensatz unter W&K-Tools → Anmeldungen bzw. W&K-Tools → Kontaktanfragen; dort lassen sich alle Angaben korrigieren (Liste mit Filter nach Veranstaltung und Ordner, Suche nach Name/E-Mail). Beim Löschen einer Veranstaltung werden ihre Anmeldungen mitgelöscht.
Export: In der Download-Liste erzeugt „Download-Liste für W&K exportieren“ die Datei JJJJ-MM-TT_website_kontaktanfragen_wk.csv mit den Spalten KBNR;KNKDAN;KNKDTITEL;KNKDN2;KNKDN1;KNKDSTR;KNKDPLZ;KNKDORT;KNGEBDAT;KDEMAIL;KDTEL1;KDFREI01;KDFREI02;KDFREI03;KDFREI04;KNUKAT;KNVEG;schoolName;schoolCity. Kontaktanfragen stehen ohne Kursnummer in der Datei. Die Datensätze werden als „Exportiert“ markiert, die freien Plätze der Veranstaltungen um die Zahl der Anmeldungen reduziert (bis zum nächsten W&K-Import), und die Datei bleibt unter W&K-Tools → Exporte zum erneuten Download.
Berechtigungen
Alle Unterpunkte von „W&K-Tools“ sind normale Contao-Backend-Module und werden je Benutzergruppe unter Benutzergruppen → Erlaubte Module freigeschaltet oder ausgeblendet (Gruppe „W&K-Tools“: Import, Posteingang, Anmeldungen, Kontaktanfragen, Exporte, Kategorien, Einstellungen, Protokoll). Was nicht freigeschaltet ist, erscheint nicht in der linken Spalte und ist auch per URL nicht aufrufbar. Wie bei den Tabellen des Contao-Kerns gilt darüber hinaus: Unter Tabellenrechte (Spalten „Anlegen“, „Bearbeiten“, „Löschen“) legt die Gruppe fest, ob sie Datensätze der Tabellen tl_wk_booking, tl_wk_inquiry, tl_wk_category und tl_wk_config anlegen, bearbeiten und löschen darf, und unter Erlaubte Felder sind alle Felder dieser Tabellen sowie die W&K-Felder der Veranstaltungen einzeln freigebbar. Zum Bearbeiten von Anmeldungen braucht eine Gruppe also das Modul „Anmeldungen“, unter Tabellenrechte „Bearbeiten“ für tl_wk_booking und die gewünschten Felder; ein Zugriff auf den Kalender ist nicht nötig (die Anmeldungen hängen bewusst nicht als Untertabelle an den Veranstaltungen). Eine typische Redaktionsgruppe erhält Posteingang, Anmeldungen, Kontaktanfragen und Exporte plus die Felder von tl_wk_booking und tl_wk_inquiry; Import, Kategorien und Einstellungen bleiben der Leitung bzw. Administratoren vorbehalten.
Eigene Templates
- Frontend-Module:
frontend_module/wk_booking_form.html.twigundfrontend_module/wk_booking_status.html.twig(Blöckebooking_header,booking_status,booking_formbzw.status,inquiry). - Twig-Funktionen für eigene Event-Templates:
wk_booking_info(event.id)(Verfügbarkeit, freie Plätze, Anmeldeschluss, Links),wk_event_categories(event)(Kategorien),wk_event_people(event)(Kursleitung, Referenten).
Sicherheit und Robustheit
- Alle schreibenden Backend-Aktionen laufen über POST mit Request-Token; Ausgaben sind escaped.
- Upload nur
.csv/.txt, Dateien liegen außerhalb des Web-Roots (var/wk-sync/). - Import in einer Transaktion; fehlerhafte Zeilen brechen den Import nicht ab, sondern werden gemeldet.
- Verfügbarkeit wird beim Absenden erneut geprüft (Wettlauf um den letzten Platz).
- Anmeldungen und Anfragen werden nur mit bekannten Spalten gespeichert.
Entwicklung
composer install
vendor/bin/phpunit
Die Tests decken CSV-Parsing, Zeilen-Zuordnung, Kategorie-Auflösung, Formularregeln, Benachrichtigungs-Routing, Textaufbereitung und den W&K-Export ab.