Backend group W&K-Tools with settings module instead of calendar fields
All W&K configuration moves from tl_calendar into the new table tl_wk_config (one entry per calendar), edited under W&K-Tools → Einstellungen. The backend group now has separate entries for import, inbox, bookings, inquiries, exports, categories, settings and log. Notification selects show the notification ID. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
efce662b4f
commit
c976f47e9c
26 files changed
+492
-360
No files matched your search
@@ -38,7 +38,7 @@ vendor/bin/contao-console contao:migrate
|
||||
|
||||
## Einrichtung
|
||||
|
||||
1. **Kategorien anlegen** – Backend „W&K-Sync → Kategorien“ oder die Standardkategorien des TPI Moritzburg per Befehl:
|
||||
1. **Kategorien anlegen** – Backend „W&K-Tools → Kategorien“ oder die Standardkategorien des TPI Moritzburg per Befehl:
|
||||
```bash
|
||||
vendor/bin/contao-console wk-sync:categories:seed
|
||||
```
|
||||
@@ -50,13 +50,16 @@ vendor/bin/contao-console contao:migrate
|
||||
```
|
||||
Die 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.
|
||||
|
||||
3. **Kalender konfigurieren** – im Kalender „W&K-Sync aktivieren“ und einstellen:
|
||||
3. **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)
|
||||
- Benachrichtigungen: Standard sowie je Bedingung 1–12 (siehe unten); die Auswahl zeigt den Titel mit ID
|
||||
|
||||
`wk-sync:form:create --calendar=1` legt den Eintrag bei Bedarf mit an. Am Kalender selbst wird nichts konfiguriert.
|
||||
|
||||
4. **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.)
|
||||
@@ -65,15 +68,15 @@ vendor/bin/contao-console contao:migrate
|
||||
- Seite **Anfrage**: Formular des Formulargenerators mit „Daten in Tabelle speichern“ → `tl_wk_inquiry` (Feldnamen `gender`, `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.
|
||||
|
||||
5. **Benachrichtigungen** (Notification Center 2): Benachrichtigungen vom Typ **W&K-Anmeldung** anlegen und im Kalender zuordnen. 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-Namen `event_organizerCity` und `event_internalEventNumber` bleiben erhalten.
|
||||
5. **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-Namen `event_organizerCity` und `event_internalEventNumber` bleiben erhalten.
|
||||
|
||||
6. **Benutzergruppen**: Zugriff auf die Module „W&K-Sync“ (Import & Posteingang, Anmeldungen, Kontaktanfragen, Kategorien, Protokoll) freigeben. Anmeldungen werden ausschließlich dort bearbeitet, nicht am Event im Kalender.
|
||||
6. **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-Sync → Import & Posteingang → 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).
|
||||
**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:
|
||||
|
||||
@@ -94,7 +97,7 @@ Regeln beim Import:
|
||||
| `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-Sync → Protokoll); die Datei liegt unter `var/wk-sync/imports/`.
|
||||
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:
|
||||
|
||||
@@ -119,7 +122,7 @@ Zusätzlich prüft das Bundle vor dem Anzeigen und noch einmal beim Absenden: ve
|
||||
|
||||
## Benachrichtigungs-Bedingungen
|
||||
|
||||
Vorrang: Benachrichtigung an der Veranstaltung → erste erfüllte Bedingung des Kalenders → Standard-Benachrichtigung des Kalenders.
|
||||
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 |
|
||||
|---|---|
|
||||
@@ -139,9 +142,9 @@ Die Bestätigungsseite wird mit `?booking=<Token>` aufgerufen. Formulare des For
|
||||
|
||||
## Posteingang und Export
|
||||
|
||||
**W&K-Sync → Import & Posteingang → 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-Sync → Anmeldungen bzw. W&K-Sync → 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.
|
||||
**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 „Exporte für W&K“ zum erneuten Download.
|
||||
**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.
|
||||
|
||||
## Eigene Templates
|
||||
|
||||
|
||||
@@ -5,23 +5,34 @@ declare(strict_types=1);
|
||||
use Contao\ArrayUtil;
|
||||
use Mummert\ContaoWkSyncBundle\Backend\WkSyncModule;
|
||||
|
||||
// Backend-Bereich „W&K-Sync“ direkt nach „Inhalte“
|
||||
// Backend-Bereich „W&K-Tools“ direkt nach „Inhalte“
|
||||
ArrayUtil::arrayInsert($GLOBALS['BE_MOD'], 1, [
|
||||
'wk_sync' => [
|
||||
'wk_sync_tools' => [
|
||||
'wk_tools' => [
|
||||
'wk_import' => [
|
||||
'callback' => WkSyncModule::class,
|
||||
'stylesheet' => 'bundles/contaowksync/wk-sync-backend.css',
|
||||
],
|
||||
'wk_sync_bookings' => [
|
||||
'wk_inbox' => [
|
||||
'callback' => WkSyncModule::class,
|
||||
'stylesheet' => 'bundles/contaowksync/wk-sync-backend.css',
|
||||
],
|
||||
'wk_bookings' => [
|
||||
'tables' => ['tl_wk_booking'],
|
||||
],
|
||||
'wk_sync_categories' => [
|
||||
'tables' => ['tl_wk_category'],
|
||||
],
|
||||
'wk_sync_inquiries' => [
|
||||
'wk_inquiries' => [
|
||||
'tables' => ['tl_wk_inquiry'],
|
||||
],
|
||||
'wk_sync_log' => [
|
||||
'wk_exports' => [
|
||||
'callback' => WkSyncModule::class,
|
||||
'stylesheet' => 'bundles/contaowksync/wk-sync-backend.css',
|
||||
],
|
||||
'wk_categories' => [
|
||||
'tables' => ['tl_wk_category'],
|
||||
],
|
||||
'wk_config' => [
|
||||
'tables' => ['tl_wk_config'],
|
||||
],
|
||||
'wk_log' => [
|
||||
'tables' => ['tl_wk_sync_log'],
|
||||
],
|
||||
],
|
||||
|
||||
@@ -1,149 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Contao\CoreBundle\DataContainer\PaletteManipulator;
|
||||
use Mummert\ContaoWkSyncBundle\Booking\NotificationRouter;
|
||||
|
||||
$dca = &$GLOBALS['TL_DCA']['tl_calendar'];
|
||||
|
||||
$dca['palettes']['__selector__'][] = 'wkEnable';
|
||||
|
||||
$notificationFields = ['wkNotificationDefault'];
|
||||
|
||||
foreach (NotificationRouter::CONDITIONS as $condition) {
|
||||
$notificationFields[] = 'wkNotificationExplanation'.$condition;
|
||||
$notificationFields[] = 'wkNotification'.$condition;
|
||||
}
|
||||
|
||||
$dca['subpalettes']['wkEnable'] = implode(',', [
|
||||
'wkBookingForm', 'wkBookingPage', 'wkConfirmationPage', 'wkInquiryPage',
|
||||
'wkDeadlineDays', 'wkDeadlineDisplayDays', 'wkOwnVenues',
|
||||
'wkAuthor', 'wkInstructorGroup', 'wkSpeakerGroup',
|
||||
'wkNewsletterChannels', 'wkNewsletterPage', 'wkNewsletterText',
|
||||
...$notificationFields,
|
||||
]);
|
||||
|
||||
PaletteManipulator::create()
|
||||
->addLegend('wk_legend', 'title_legend', PaletteManipulator::POSITION_AFTER)
|
||||
->addField('wkEnable', 'wk_legend', PaletteManipulator::POSITION_APPEND)
|
||||
->applyToPalette('default', 'tl_calendar')
|
||||
;
|
||||
|
||||
$fields = [
|
||||
'wkEnable' => [
|
||||
'filter' => true,
|
||||
'inputType' => 'checkbox',
|
||||
'eval' => ['submitOnChange' => true, 'tl_class' => 'w50 m12'],
|
||||
'sql' => ['type' => 'boolean', 'default' => false],
|
||||
],
|
||||
'wkBookingForm' => [
|
||||
'inputType' => 'select',
|
||||
'foreignKey' => 'tl_form.title',
|
||||
'eval' => ['includeBlankOption' => true, 'chosen' => true, 'tl_class' => 'w50 clr'],
|
||||
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
|
||||
'relation' => ['type' => 'hasOne', 'load' => 'lazy'],
|
||||
],
|
||||
'wkBookingPage' => [
|
||||
'inputType' => 'pageTree',
|
||||
'foreignKey' => 'tl_page.title',
|
||||
'eval' => ['fieldType' => 'radio', 'tl_class' => 'clr'],
|
||||
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
|
||||
'relation' => ['type' => 'hasOne', 'load' => 'lazy'],
|
||||
],
|
||||
'wkConfirmationPage' => [
|
||||
'inputType' => 'pageTree',
|
||||
'foreignKey' => 'tl_page.title',
|
||||
'eval' => ['fieldType' => 'radio', 'tl_class' => 'clr'],
|
||||
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
|
||||
'relation' => ['type' => 'hasOne', 'load' => 'lazy'],
|
||||
],
|
||||
'wkInquiryPage' => [
|
||||
'inputType' => 'pageTree',
|
||||
'foreignKey' => 'tl_page.title',
|
||||
'eval' => ['fieldType' => 'radio', 'tl_class' => 'clr'],
|
||||
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
|
||||
'relation' => ['type' => 'hasOne', 'load' => 'lazy'],
|
||||
],
|
||||
'wkDeadlineDays' => [
|
||||
'default' => 1,
|
||||
'inputType' => 'text',
|
||||
'eval' => ['rgxp' => 'natural', 'maxlength' => 3, 'tl_class' => 'w50 clr'],
|
||||
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 1],
|
||||
],
|
||||
'wkDeadlineDisplayDays' => [
|
||||
'default' => 31,
|
||||
'inputType' => 'text',
|
||||
'eval' => ['rgxp' => 'natural', 'maxlength' => 3, 'tl_class' => 'w50'],
|
||||
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 31],
|
||||
],
|
||||
'wkOwnVenues' => [
|
||||
'default' => 'TPI Moritzburg',
|
||||
'inputType' => 'textarea',
|
||||
'eval' => ['style' => 'height:60px', 'decodeEntities' => true, 'tl_class' => 'clr'],
|
||||
'sql' => ['type' => 'text', 'notnull' => false],
|
||||
],
|
||||
'wkAuthor' => [
|
||||
'inputType' => 'select',
|
||||
'foreignKey' => 'tl_user.name',
|
||||
'eval' => ['includeBlankOption' => true, 'chosen' => true, 'tl_class' => 'w50 clr'],
|
||||
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
|
||||
'relation' => ['type' => 'hasOne', 'load' => 'lazy'],
|
||||
],
|
||||
'wkInstructorGroup' => [
|
||||
'inputType' => 'select',
|
||||
'foreignKey' => 'tl_member_group.name',
|
||||
'eval' => ['includeBlankOption' => true, 'chosen' => true, 'tl_class' => 'w50 clr'],
|
||||
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
|
||||
'relation' => ['type' => 'hasOne', 'load' => 'lazy'],
|
||||
],
|
||||
'wkSpeakerGroup' => [
|
||||
'inputType' => 'select',
|
||||
'foreignKey' => 'tl_member_group.name',
|
||||
'eval' => ['includeBlankOption' => true, 'chosen' => true, 'tl_class' => 'w50'],
|
||||
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
|
||||
'relation' => ['type' => 'hasOne', 'load' => 'lazy'],
|
||||
],
|
||||
'wkNewsletterChannels' => [
|
||||
'inputType' => 'checkbox',
|
||||
'eval' => ['multiple' => true, 'tl_class' => 'clr'],
|
||||
'sql' => ['type' => 'blob', 'length' => 65535, 'notnull' => false],
|
||||
],
|
||||
'wkNewsletterPage' => [
|
||||
'inputType' => 'pageTree',
|
||||
'foreignKey' => 'tl_page.title',
|
||||
'eval' => ['fieldType' => 'radio', 'tl_class' => 'clr'],
|
||||
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
|
||||
'relation' => ['type' => 'hasOne', 'load' => 'lazy'],
|
||||
],
|
||||
'wkNewsletterText' => [
|
||||
'inputType' => 'textarea',
|
||||
'eval' => ['style' => 'height:120px', 'decodeEntities' => true, 'tl_class' => 'clr'],
|
||||
'sql' => ['type' => 'text', 'notnull' => false],
|
||||
],
|
||||
'wkNotificationDefault' => [
|
||||
'inputType' => 'select',
|
||||
'eval' => ['includeBlankOption' => true, 'chosen' => true, 'tl_class' => 'w50 clr'],
|
||||
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
|
||||
],
|
||||
];
|
||||
|
||||
foreach (NotificationRouter::CONDITIONS as $condition) {
|
||||
$fields['wkNotificationExplanation'.$condition] = [
|
||||
'inputType' => 'explanation',
|
||||
'eval' => [
|
||||
'class' => 'tl_info',
|
||||
'text' => &$GLOBALS['TL_LANG']['tl_calendar']['wkNotificationExplanation'.$condition],
|
||||
'tl_class' => 'long clr',
|
||||
],
|
||||
];
|
||||
|
||||
$fields['wkNotification'.$condition] = [
|
||||
'label' => &$GLOBALS['TL_LANG']['tl_calendar']['wkNotificationCondition'],
|
||||
'inputType' => 'select',
|
||||
'eval' => ['includeBlankOption' => true, 'chosen' => true, 'tl_class' => 'w50 clr'],
|
||||
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
|
||||
];
|
||||
}
|
||||
|
||||
$dca['fields'] = array_merge($dca['fields'], $fields);
|
||||
@@ -0,0 +1,183 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
use Contao\DataContainer;
|
||||
use Contao\DC_Table;
|
||||
use Mummert\ContaoWkSyncBundle\Booking\NotificationRouter;
|
||||
|
||||
$notificationFields = ['notificationDefault'];
|
||||
|
||||
foreach (NotificationRouter::CONDITIONS as $condition) {
|
||||
$notificationFields[] = 'notificationExplanation'.$condition;
|
||||
$notificationFields[] = 'notification'.$condition;
|
||||
}
|
||||
|
||||
$GLOBALS['TL_DCA']['tl_wk_config'] = [
|
||||
'config' => [
|
||||
'dataContainer' => DC_Table::class,
|
||||
'enableVersioning' => true,
|
||||
'markAsCopy' => 'title',
|
||||
'sql' => [
|
||||
'keys' => [
|
||||
'id' => 'primary',
|
||||
'calendar' => 'unique',
|
||||
],
|
||||
],
|
||||
],
|
||||
'list' => [
|
||||
'sorting' => [
|
||||
'mode' => DataContainer::MODE_SORTED,
|
||||
'fields' => ['title'],
|
||||
'flag' => DataContainer::SORT_INITIAL_LETTER_ASC,
|
||||
'panelLayout' => 'search,limit',
|
||||
],
|
||||
'label' => [
|
||||
'fields' => ['title', 'calendar', 'bookingForm'],
|
||||
'showColumns' => true,
|
||||
],
|
||||
'operations' => [
|
||||
'edit',
|
||||
'copy',
|
||||
'delete',
|
||||
'show',
|
||||
],
|
||||
],
|
||||
'palettes' => [
|
||||
'default' => '{title_legend},title,calendar;'
|
||||
.'{page_legend},bookingForm,bookingPage,confirmationPage,inquiryPage;'
|
||||
.'{booking_legend},deadlineDays,deadlineDisplayDays,ownVenues;'
|
||||
.'{import_legend},author,instructorGroup,speakerGroup;'
|
||||
.'{newsletter_legend:hide},newsletterChannels,newsletterPage,newsletterText;'
|
||||
.'{notification_legend},'.implode(',', $notificationFields),
|
||||
],
|
||||
'fields' => [
|
||||
'id' => [
|
||||
'sql' => ['type' => 'integer', 'unsigned' => true, 'autoincrement' => true],
|
||||
],
|
||||
'tstamp' => [
|
||||
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
|
||||
],
|
||||
'title' => [
|
||||
'search' => true,
|
||||
'inputType' => 'text',
|
||||
'eval' => ['mandatory' => true, 'basicEntities' => true, 'maxlength' => 255, 'tl_class' => 'w50'],
|
||||
'sql' => ['type' => 'string', 'length' => 255, 'default' => ''],
|
||||
],
|
||||
'calendar' => [
|
||||
'filter' => true,
|
||||
'inputType' => 'select',
|
||||
'foreignKey' => 'tl_calendar.title',
|
||||
'eval' => ['mandatory' => true, 'unique' => true, 'includeBlankOption' => true, 'chosen' => true, 'tl_class' => 'w50'],
|
||||
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
|
||||
'relation' => ['type' => 'hasOne', 'load' => 'lazy'],
|
||||
],
|
||||
'bookingForm' => [
|
||||
'inputType' => 'select',
|
||||
'foreignKey' => 'tl_form.title',
|
||||
'eval' => ['includeBlankOption' => true, 'chosen' => true, 'tl_class' => 'w50'],
|
||||
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
|
||||
'relation' => ['type' => 'hasOne', 'load' => 'lazy'],
|
||||
],
|
||||
'bookingPage' => [
|
||||
'inputType' => 'pageTree',
|
||||
'foreignKey' => 'tl_page.title',
|
||||
'eval' => ['fieldType' => 'radio', 'tl_class' => 'clr'],
|
||||
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
|
||||
'relation' => ['type' => 'hasOne', 'load' => 'lazy'],
|
||||
],
|
||||
'confirmationPage' => [
|
||||
'inputType' => 'pageTree',
|
||||
'foreignKey' => 'tl_page.title',
|
||||
'eval' => ['fieldType' => 'radio', 'tl_class' => 'clr'],
|
||||
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
|
||||
'relation' => ['type' => 'hasOne', 'load' => 'lazy'],
|
||||
],
|
||||
'inquiryPage' => [
|
||||
'inputType' => 'pageTree',
|
||||
'foreignKey' => 'tl_page.title',
|
||||
'eval' => ['fieldType' => 'radio', 'tl_class' => 'clr'],
|
||||
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
|
||||
'relation' => ['type' => 'hasOne', 'load' => 'lazy'],
|
||||
],
|
||||
'deadlineDays' => [
|
||||
'default' => 1,
|
||||
'inputType' => 'text',
|
||||
'eval' => ['rgxp' => 'natural', 'maxlength' => 3, 'tl_class' => 'w50'],
|
||||
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 1],
|
||||
],
|
||||
'deadlineDisplayDays' => [
|
||||
'default' => 31,
|
||||
'inputType' => 'text',
|
||||
'eval' => ['rgxp' => 'natural', 'maxlength' => 3, 'tl_class' => 'w50'],
|
||||
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 31],
|
||||
],
|
||||
'ownVenues' => [
|
||||
'default' => 'TPI Moritzburg',
|
||||
'inputType' => 'textarea',
|
||||
'eval' => ['style' => 'height:60px', 'decodeEntities' => true, 'tl_class' => 'clr'],
|
||||
'sql' => ['type' => 'text', 'notnull' => false],
|
||||
],
|
||||
'author' => [
|
||||
'inputType' => 'select',
|
||||
'foreignKey' => 'tl_user.name',
|
||||
'eval' => ['includeBlankOption' => true, 'chosen' => true, 'tl_class' => 'w50'],
|
||||
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
|
||||
'relation' => ['type' => 'hasOne', 'load' => 'lazy'],
|
||||
],
|
||||
'instructorGroup' => [
|
||||
'inputType' => 'select',
|
||||
'foreignKey' => 'tl_member_group.name',
|
||||
'eval' => ['includeBlankOption' => true, 'chosen' => true, 'tl_class' => 'w50 clr'],
|
||||
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
|
||||
'relation' => ['type' => 'hasOne', 'load' => 'lazy'],
|
||||
],
|
||||
'speakerGroup' => [
|
||||
'inputType' => 'select',
|
||||
'foreignKey' => 'tl_member_group.name',
|
||||
'eval' => ['includeBlankOption' => true, 'chosen' => true, 'tl_class' => 'w50'],
|
||||
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
|
||||
'relation' => ['type' => 'hasOne', 'load' => 'lazy'],
|
||||
],
|
||||
'newsletterChannels' => [
|
||||
'inputType' => 'checkbox',
|
||||
'eval' => ['multiple' => true, 'tl_class' => 'clr'],
|
||||
'sql' => ['type' => 'blob', 'length' => 65535, 'notnull' => false],
|
||||
],
|
||||
'newsletterPage' => [
|
||||
'inputType' => 'pageTree',
|
||||
'foreignKey' => 'tl_page.title',
|
||||
'eval' => ['fieldType' => 'radio', 'tl_class' => 'clr'],
|
||||
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
|
||||
'relation' => ['type' => 'hasOne', 'load' => 'lazy'],
|
||||
],
|
||||
'newsletterText' => [
|
||||
'inputType' => 'textarea',
|
||||
'eval' => ['style' => 'height:120px', 'decodeEntities' => true, 'tl_class' => 'clr'],
|
||||
'sql' => ['type' => 'text', 'notnull' => false],
|
||||
],
|
||||
'notificationDefault' => [
|
||||
'inputType' => 'select',
|
||||
'eval' => ['includeBlankOption' => true, 'chosen' => true, 'tl_class' => 'w50 clr'],
|
||||
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
foreach (NotificationRouter::CONDITIONS as $condition) {
|
||||
$GLOBALS['TL_DCA']['tl_wk_config']['fields']['notificationExplanation'.$condition] = [
|
||||
'inputType' => 'explanation',
|
||||
'eval' => [
|
||||
'class' => 'tl_info',
|
||||
'text' => &$GLOBALS['TL_LANG']['tl_wk_config']['notificationExplanation'.$condition],
|
||||
'tl_class' => 'long clr',
|
||||
],
|
||||
];
|
||||
|
||||
$GLOBALS['TL_DCA']['tl_wk_config']['fields']['notification'.$condition] = [
|
||||
'label' => &$GLOBALS['TL_LANG']['tl_wk_config']['notificationCondition'],
|
||||
'inputType' => 'select',
|
||||
'eval' => ['includeBlankOption' => true, 'chosen' => true, 'tl_class' => 'w50 clr'],
|
||||
'sql' => ['type' => 'integer', 'unsigned' => true, 'default' => 0],
|
||||
];
|
||||
}
|
||||
@@ -64,9 +64,10 @@ $lang['wk_sync']['import']['file_help'] = 'Die in W&K exportierte Seminarliste (
|
||||
$lang['wk_sync']['import']['hint'] = 'Wichtig: In W&K das größtmögliche Zeitintervall exportieren. Seminare, die nicht in der Datei stehen, werden als storniert markiert und ausgeblendet. Nach dem Hochladen erscheint zuerst eine Vorschau, erst nach Bestätigung wird etwas geändert.';
|
||||
$lang['wk_sync']['import']['upload_button'] = 'Datei hochladen und Vorschau anzeigen';
|
||||
$lang['wk_sync']['import']['recent'] = 'Letzte Importe';
|
||||
$lang['wk_sync']['import']['open_config'] = 'Einstellungen öffnen';
|
||||
$lang['wk_sync']['import']['none'] = 'Bisher wurde noch nichts importiert.';
|
||||
$lang['wk_sync']['import']['no_categories'] = 'Es sind noch keine W&K-Kategorien angelegt. Ohne Kategorien werden alle Seminare storniert. Bitte zuerst unter „W&K-Sync → Kategorien“ anlegen (oder „wk-sync:categories:seed“ ausführen).';
|
||||
$lang['wk_sync']['import']['no_calendar'] = 'In keinem Kalender ist der W&K-Sync aktiviert. Bitte im gewünschten Kalender „W&K-Sync aktivieren“ einschalten.';
|
||||
$lang['wk_sync']['import']['no_calendar'] = 'Es sind noch keine W&K-Einstellungen angelegt (Kalender, Formular, Seiten, Benachrichtigungen).';
|
||||
$lang['wk_sync']['import']['applied'] = 'Der Import wurde angewendet: %s neu, %s geändert, %s storniert, %s unverändert.';
|
||||
$lang['wk_sync']['import']['not_found'] = 'Der Importvorgang wurde nicht gefunden.';
|
||||
$lang['wk_sync']['import']['discarded'] = 'Die Vorschau wurde verworfen. Es wurde nichts geändert.';
|
||||
|
||||
@@ -2,13 +2,16 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
$GLOBALS['TL_LANG']['MOD']['wk_sync'] = 'W&K-Sync';
|
||||
$GLOBALS['TL_LANG']['MOD']['wk_sync_tools'] = ['Import & Posteingang', 'Seminare aus W&K importieren, Anmeldungen bearbeiten und für W&K exportieren'];
|
||||
$GLOBALS['TL_LANG']['MOD']['wk_sync_categories'] = ['Kategorien', 'W&K-Kategorien (Bereiche) und ihre Zuordnung pflegen'];
|
||||
$GLOBALS['TL_LANG']['MOD']['wk_sync_inquiries'] = ['Kontaktanfragen', 'Anfragen aus dem Anfrageformular'];
|
||||
$GLOBALS['TL_LANG']['MOD']['wk_sync_log'] = ['Protokoll', 'Protokoll der Importe und Exporte'];
|
||||
$GLOBALS['TL_LANG']['MOD']['wk_tools'] = 'W&K-Tools';
|
||||
$GLOBALS['TL_LANG']['MOD']['wk_import'] = ['Import', 'Seminare aus einer W&K-Datei importieren (mit Vorschau)'];
|
||||
$GLOBALS['TL_LANG']['MOD']['wk_inbox'] = ['Posteingang', 'Anmeldungen und Kontaktanfragen sichten, in Ordner verschieben und für W&K exportieren'];
|
||||
$GLOBALS['TL_LANG']['MOD']['wk_bookings'] = ['Anmeldungen', 'Anmeldungen zu Veranstaltungen ansehen und bearbeiten'];
|
||||
$GLOBALS['TL_LANG']['MOD']['wk_inquiries'] = ['Kontaktanfragen', 'Anfragen aus dem Anfrageformular'];
|
||||
$GLOBALS['TL_LANG']['MOD']['wk_exports'] = ['Exporte', 'Erzeugte Exportdateien für W&K herunterladen'];
|
||||
$GLOBALS['TL_LANG']['MOD']['wk_categories'] = ['Kategorien', 'W&K-Kategorien (Bereiche) und ihre Zuordnung pflegen'];
|
||||
$GLOBALS['TL_LANG']['MOD']['wk_config'] = ['Einstellungen', 'Kalender, Formular, Seiten, Anmeldeschluss und Benachrichtigungen'];
|
||||
$GLOBALS['TL_LANG']['MOD']['wk_log'] = ['Protokoll', 'Protokoll der Importe und Exporte'];
|
||||
|
||||
$GLOBALS['TL_LANG']['FMD']['wk_sync'] = 'W&K-Sync';
|
||||
$GLOBALS['TL_LANG']['FMD']['wk_sync'] = 'W&K-Tools';
|
||||
$GLOBALS['TL_LANG']['FMD']['wk_booking_form'] = ['W&K-Anmeldeformular', 'Anmeldeformular zur Veranstaltung aus der URL (Alias der Veranstaltung).'];
|
||||
$GLOBALS['TL_LANG']['FMD']['wk_booking_status'] = ['W&K-Anmeldestatus', 'Freie Plätze, Anmeldeschluss und Link zur Anmeldung für die Veranstaltung aus der URL.'];
|
||||
$GLOBALS['TL_LANG']['MOD']['wk_sync_bookings'] = ['Anmeldungen', 'Anmeldungen zu Veranstaltungen ansehen und bearbeiten'];
|
||||
@@ -1,37 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
$lang = &$GLOBALS['TL_LANG']['tl_calendar'];
|
||||
|
||||
$lang['wk_legend'] = 'W&K-Sync';
|
||||
|
||||
$lang['wkEnable'] = ['W&K-Sync aktivieren', 'Seminare aus W&K in diesen Kalender importieren und Online-Anmeldungen ermöglichen.'];
|
||||
$lang['wkBookingForm'] = ['Anmeldeformular', 'Formular aus dem Formulargenerator, das für Anmeldungen verwendet wird (Feldnamen wie in tl_wk_booking; anlegen mit „wk-sync:form:create“).'];
|
||||
$lang['wkBookingPage'] = ['Seite mit dem Anmeldeformular', 'Seite, auf der das Modul „W&K-Anmeldeformular“ liegt. Der Link „Jetzt anmelden“ führt dorthin.'];
|
||||
$lang['wkConfirmationPage'] = ['Bestätigungsseite', 'Seite nach erfolgreicher Anmeldung, z. B. „Anmeldung eingegangen“. Kann je Veranstaltung übersteuert werden.'];
|
||||
$lang['wkInquiryPage'] = ['Seite mit dem Anfrageformular', 'Seite mit dem Kontakt-/Anfrageformular; sie wird mit ?event=ID verlinkt.'];
|
||||
$lang['wkDeadlineDays'] = ['Anmeldeschluss (Tage vor Beginn)', 'Bis so viele Tage vor Beginn sind Anmeldungen technisch möglich. 1 = bis einen Tag vor Beginn.'];
|
||||
$lang['wkDeadlineDisplayDays'] = ['Angezeigter Anmeldeschluss (Tage vor Beginn)', 'Datum, das als „Anmeldung möglich bis“ angezeigt wird. 0 = wie der technische Anmeldeschluss.'];
|
||||
$lang['wkOwnVenues'] = ['Eigene Veranstaltungsorte', 'Eine Bezeichnung pro Zeile. Veranstaltungsorte, die so beginnen (z. B. „TPI Moritzburg (barrierefrei)“), gelten als „im eigenen Haus“ – relevant für die Felder Übernachtung und Verpflegung.'];
|
||||
$lang['wkAuthor'] = ['Autor importierter Veranstaltungen', 'Backend-Benutzer, der als Autor neuer Seminare eingetragen wird (leer = der importierende Benutzer).'];
|
||||
$lang['wkInstructorGroup'] = ['Mitgliedergruppe Kursleitung', 'Kursleitungen aus W&K werden als Mitglieder dieser Gruppe angelegt (leer = keine Mitglieder anlegen).'];
|
||||
$lang['wkSpeakerGroup'] = ['Mitgliedergruppe Referenten', 'Referenten aus W&K werden als Mitglieder dieser Gruppe angelegt (leer = keine Mitglieder anlegen).'];
|
||||
$lang['wkNewsletterChannels'] = ['Newsletter-Verteiler', 'Verteiler, die bei „Newsletter abonnieren“ mit Double-Opt-in abonniert werden.'];
|
||||
$lang['wkNewsletterPage'] = ['Seite zur Newsletter-Aktivierung', 'Seite mit dem Modul „Abonnieren“, die den Aktivierungslink (?token=) verarbeitet.'];
|
||||
$lang['wkNewsletterText'] = ['Text der Aktivierungsmail', 'Optional. Token: ##link##, ##channels##, ##domain##. Leer = Standardtext.'];
|
||||
$lang['wkNotificationDefault'] = ['Standard-Benachrichtigung', 'Wird verschickt, wenn keine der Bedingungen zutrifft und an der Veranstaltung nichts eingestellt ist.'];
|
||||
$lang['wkNotificationCondition'] = ['Benachrichtigung', 'Benachrichtigung vom Typ „W&K-Anmeldung“ für diese Bedingung.'];
|
||||
|
||||
$lang['wkNotificationExplanation1'] = '<strong>Bedingung 1: Online-Kurse</strong> – alle Kategorien, Veranstaltungsort „Online“.';
|
||||
$lang['wkNotificationExplanation2'] = '<strong>Bedingung 2: Tagesveranstaltung Schulfortbildung</strong> – Beginn = Ende, Kategorie-Art „Schule“, Nummer beginnt mit EXTP.';
|
||||
$lang['wkNotificationExplanation3'] = '<strong>Bedingung 3: Tagesveranstaltung Gemeinde / Gottesdienst mit Kindern / Tagungen</strong> – Beginn = Ende, Kategorie-Art „Gemeinde“, „Gottesdienst mit Kindern“ oder „Tagungen“.';
|
||||
$lang['wkNotificationExplanation4'] = '<strong>Bedingung 4: Tagesveranstaltung Elementarbereich</strong> – Beginn = Ende, Kategorie-Art „Elementarbereich“.';
|
||||
$lang['wkNotificationExplanation5'] = '<strong>Bedingung 5: Mehrtägige Schulfortbildung</strong> – Beginn ≠ Ende, Kategorie-Art „Schule“, Nummer beginnt mit EXTP.';
|
||||
$lang['wkNotificationExplanation6'] = '<strong>Bedingung 6: Mehrtägige Fortbildung Elementarbereich</strong> – Beginn ≠ Ende, Kategorie-Art „Elementarbereich“.';
|
||||
$lang['wkNotificationExplanation7'] = '<strong>Bedingung 7: Mehrtägige Veranstaltung Gemeinde / Gottesdienst mit Kindern / Tagungen</strong> – Beginn ≠ Ende.';
|
||||
$lang['wkNotificationExplanation8'] = '<strong>Bedingung 8: Tagesveranstaltung Evangelische Schulen</strong> – Beginn = Ende, Kategorie-Art „Evangelische Schulen“.';
|
||||
$lang['wkNotificationExplanation9'] = '<strong>Bedingung 9: Mehrtägige Veranstaltung Evangelische Schulen</strong> – Beginn ≠ Ende, Kategorie-Art „Evangelische Schulen“.';
|
||||
$lang['wkNotificationExplanation10'] = '<strong>Bedingung 10: Tagesveranstaltung Mentoring</strong> – Beginn = Ende, Kategorie-Art „Mentoring“.';
|
||||
$lang['wkNotificationExplanation11'] = '<strong>Bedingung 11: Mehrtägige Veranstaltung Mentoring</strong> – Beginn ≠ Ende, Kategorie-Art „Mentoring“.';
|
||||
$lang['wkNotificationExplanation12'] = '<strong>Bedingung 12: Mehrtägige Ausbildung</strong> – Beginn ≠ Ende, Kategorie-Art „Ausbildung“.';
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
$lang = &$GLOBALS['TL_LANG']['tl_wk_config'];
|
||||
|
||||
$lang['title_legend'] = 'Kalender';
|
||||
$lang['page_legend'] = 'Formular und Seiten';
|
||||
$lang['booking_legend'] = 'Anmeldung';
|
||||
$lang['import_legend'] = 'Import';
|
||||
$lang['newsletter_legend'] = 'Newsletter';
|
||||
$lang['notification_legend'] = 'Benachrichtigungen';
|
||||
|
||||
$lang['title'] = ['Bezeichnung', 'Interner Name dieser Einstellungen, z. B. „Programm“.'];
|
||||
$lang['calendar'] = ['Kalender', 'Kalender, in den die W&K-Seminare importiert werden und dessen Veranstaltungen online buchbar sind. Je Kalender ein Eintrag.'];
|
||||
$lang['bookingForm'] = ['Anmeldeformular', 'Formular aus dem Formulargenerator, das für Anmeldungen verwendet wird (Feldnamen wie in tl_wk_booking; anlegen mit „wk-sync:form:create“).'];
|
||||
$lang['bookingPage'] = ['Seite mit dem Anmeldeformular', 'Seite, auf der das Modul „W&K-Anmeldeformular“ liegt. Der Link „Jetzt anmelden“ führt dorthin.'];
|
||||
$lang['confirmationPage'] = ['Bestätigungsseite', 'Seite nach erfolgreicher Anmeldung, z. B. „Anmeldung eingegangen“. Kann je Veranstaltung übersteuert werden.'];
|
||||
$lang['inquiryPage'] = ['Seite mit dem Anfrageformular', 'Seite mit dem Kontakt-/Anfrageformular; sie wird mit ?event=ID verlinkt.'];
|
||||
$lang['deadlineDays'] = ['Anmeldeschluss (Tage vor Beginn)', 'Bis so viele Tage vor Beginn sind Anmeldungen technisch möglich. 1 = bis einen Tag vor Beginn.'];
|
||||
$lang['deadlineDisplayDays'] = ['Angezeigter Anmeldeschluss (Tage vor Beginn)', 'Datum, das als „Anmeldung möglich bis“ angezeigt wird. 0 = wie der technische Anmeldeschluss.'];
|
||||
$lang['ownVenues'] = ['Eigene Veranstaltungsorte', 'Eine Bezeichnung pro Zeile. Veranstaltungsorte, die so beginnen (z. B. „TPI Moritzburg (barrierefrei)“), gelten als „im eigenen Haus“ – relevant für die Felder Übernachtung und Verpflegung.'];
|
||||
$lang['author'] = ['Autor importierter Veranstaltungen', 'Backend-Benutzer, der als Autor neuer Seminare eingetragen wird (leer = der importierende Benutzer).'];
|
||||
$lang['instructorGroup'] = ['Mitgliedergruppe Kursleitung', 'Kursleitungen aus W&K werden als Mitglieder dieser Gruppe angelegt (leer = keine Mitglieder anlegen).'];
|
||||
$lang['speakerGroup'] = ['Mitgliedergruppe Referenten', 'Referenten aus W&K werden als Mitglieder dieser Gruppe angelegt (leer = keine Mitglieder anlegen).'];
|
||||
$lang['newsletterChannels'] = ['Newsletter-Verteiler', 'Verteiler, die bei „Newsletter abonnieren“ mit Double-Opt-in abonniert werden.'];
|
||||
$lang['newsletterPage'] = ['Seite zur Newsletter-Aktivierung', 'Seite mit dem Modul „Abonnieren“, die den Aktivierungslink (?token=) verarbeitet.'];
|
||||
$lang['newsletterText'] = ['Text der Aktivierungsmail', 'Optional. Token: ##link##, ##channels##, ##domain##. Leer = Standardtext.'];
|
||||
$lang['notificationDefault'] = ['Standard-Benachrichtigung', 'Wird verschickt, wenn keine der Bedingungen zutrifft und an der Veranstaltung nichts eingestellt ist. Nur Benachrichtigungen vom Typ „W&K-Anmeldung“.'];
|
||||
$lang['notificationCondition'] = ['Benachrichtigung für diese Bedingung', 'Leer = Bedingung wird übersprungen, die nächste zutreffende Bedingung zählt.'];
|
||||
|
||||
$lang['notificationExplanation1'] = '<strong>Bedingung 1: Online-Kurse</strong> – alle Kategorien, Veranstaltungsort „Online“.';
|
||||
$lang['notificationExplanation2'] = '<strong>Bedingung 2: Tagesveranstaltung Schulfortbildung</strong> – Beginn = Ende, Kategorie-Art „Schule“, Nummer beginnt mit EXTP.';
|
||||
$lang['notificationExplanation3'] = '<strong>Bedingung 3: Tagesveranstaltung Gemeinde / Gottesdienst mit Kindern / Tagungen</strong> – Beginn = Ende, Kategorie-Art „Gemeinde“, „Gottesdienst mit Kindern“ oder „Tagungen“.';
|
||||
$lang['notificationExplanation4'] = '<strong>Bedingung 4: Tagesveranstaltung Elementarbereich</strong> – Beginn = Ende, Kategorie-Art „Elementarbereich“.';
|
||||
$lang['notificationExplanation5'] = '<strong>Bedingung 5: Mehrtägige Schulfortbildung</strong> – Beginn ≠ Ende, Kategorie-Art „Schule“, Nummer beginnt mit EXTP.';
|
||||
$lang['notificationExplanation6'] = '<strong>Bedingung 6: Mehrtägige Fortbildung Elementarbereich</strong> – Beginn ≠ Ende, Kategorie-Art „Elementarbereich“.';
|
||||
$lang['notificationExplanation7'] = '<strong>Bedingung 7: Mehrtägige Veranstaltung Gemeinde / Gottesdienst mit Kindern / Tagungen</strong> – Beginn ≠ Ende.';
|
||||
$lang['notificationExplanation8'] = '<strong>Bedingung 8: Tagesveranstaltung Evangelische Schulen</strong> – Beginn = Ende, Kategorie-Art „Evangelische Schulen“.';
|
||||
$lang['notificationExplanation9'] = '<strong>Bedingung 9: Mehrtägige Veranstaltung Evangelische Schulen</strong> – Beginn ≠ Ende, Kategorie-Art „Evangelische Schulen“.';
|
||||
$lang['notificationExplanation10'] = '<strong>Bedingung 10: Tagesveranstaltung Mentoring</strong> – Beginn = Ende, Kategorie-Art „Mentoring“.';
|
||||
$lang['notificationExplanation11'] = '<strong>Bedingung 11: Mehrtägige Veranstaltung Mentoring</strong> – Beginn ≠ Ende, Kategorie-Art „Mentoring“.';
|
||||
$lang['notificationExplanation12'] = '<strong>Bedingung 12: Mehrtägige Ausbildung</strong> – Beginn ≠ Ende, Kategorie-Art „Ausbildung“.';
|
||||
|
||||
$lang['new'] = ['Neue Einstellungen', 'Einstellungen für einen Kalender anlegen'];
|
||||
$lang['edit'] = ['Einstellungen bearbeiten', 'Einstellungen ID %s bearbeiten'];
|
||||
$lang['copy'] = ['Einstellungen duplizieren', 'Einstellungen ID %s duplizieren'];
|
||||
$lang['delete'] = ['Einstellungen löschen', 'Einstellungen ID %s löschen'];
|
||||
$lang['show'] = ['Details', 'Details der Einstellungen ID %s anzeigen'];
|
||||
@@ -60,9 +60,10 @@ $lang['wk_sync']['import']['file_help'] = 'The seminar list exported from W&K (s
|
||||
$lang['wk_sync']['import']['hint'] = 'Important: export the largest possible time range in W&K. Seminars missing from the file will be marked as cancelled and hidden. A preview is shown first; nothing changes until you confirm.';
|
||||
$lang['wk_sync']['import']['upload_button'] = 'Upload file and show preview';
|
||||
$lang['wk_sync']['import']['recent'] = 'Recent imports';
|
||||
$lang['wk_sync']['import']['open_config'] = 'Open settings';
|
||||
$lang['wk_sync']['import']['none'] = 'Nothing has been imported yet.';
|
||||
$lang['wk_sync']['import']['no_categories'] = 'No W&K categories exist yet. Without categories all seminars would be cancelled. Please create them under "W&K sync → Categories" first (or run "wk-sync:categories:seed").';
|
||||
$lang['wk_sync']['import']['no_calendar'] = 'W&K sync is not enabled in any calendar. Please enable "W&K sync" in the calendar settings.';
|
||||
$lang['wk_sync']['import']['no_calendar'] = 'No W&K settings exist yet (calendar, form, pages, notifications).';
|
||||
$lang['wk_sync']['import']['applied'] = 'The import has been applied: %s new, %s changed, %s cancelled, %s unchanged.';
|
||||
$lang['wk_sync']['import']['not_found'] = 'The import was not found.';
|
||||
$lang['wk_sync']['import']['discarded'] = 'The preview has been discarded. Nothing was changed.';
|
||||
|
||||
@@ -2,13 +2,16 @@
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
$GLOBALS['TL_LANG']['MOD']['wk_sync'] = 'W&K sync';
|
||||
$GLOBALS['TL_LANG']['MOD']['wk_sync_tools'] = ['Import & inbox', 'Import seminars from W&K, process bookings and export them for W&K'];
|
||||
$GLOBALS['TL_LANG']['MOD']['wk_sync_categories'] = ['Categories', 'Manage W&K categories and their mapping'];
|
||||
$GLOBALS['TL_LANG']['MOD']['wk_sync_inquiries'] = ['Inquiries', 'Inquiries from the contact form'];
|
||||
$GLOBALS['TL_LANG']['MOD']['wk_sync_log'] = ['Log', 'Log of imports and exports'];
|
||||
$GLOBALS['TL_LANG']['MOD']['wk_tools'] = 'W&K tools';
|
||||
$GLOBALS['TL_LANG']['MOD']['wk_import'] = ['Import', 'Import seminars from a W&K file (with preview)'];
|
||||
$GLOBALS['TL_LANG']['MOD']['wk_inbox'] = ['Inbox', 'Review bookings and inquiries, move them between folders and export them for W&K'];
|
||||
$GLOBALS['TL_LANG']['MOD']['wk_bookings'] = ['Bookings', 'View and edit bookings'];
|
||||
$GLOBALS['TL_LANG']['MOD']['wk_inquiries'] = ['Inquiries', 'Inquiries from the contact form'];
|
||||
$GLOBALS['TL_LANG']['MOD']['wk_exports'] = ['Exports', 'Download the export files created for W&K'];
|
||||
$GLOBALS['TL_LANG']['MOD']['wk_categories'] = ['Categories', 'Manage W&K categories and their mapping'];
|
||||
$GLOBALS['TL_LANG']['MOD']['wk_config'] = ['Settings', 'Calendar, form, pages, deadline and notifications'];
|
||||
$GLOBALS['TL_LANG']['MOD']['wk_log'] = ['Log', 'Log of imports and exports'];
|
||||
|
||||
$GLOBALS['TL_LANG']['FMD']['wk_sync'] = 'W&K sync';
|
||||
$GLOBALS['TL_LANG']['FMD']['wk_sync'] = 'W&K tools';
|
||||
$GLOBALS['TL_LANG']['FMD']['wk_booking_form'] = ['W&K booking form', 'Booking form for the event given in the URL.'];
|
||||
$GLOBALS['TL_LANG']['FMD']['wk_booking_status'] = ['W&K booking status', 'Free places, deadline and booking link for the event given in the URL.'];
|
||||
$GLOBALS['TL_LANG']['MOD']['wk_sync_bookings'] = ['Bookings', 'View and edit bookings'];
|
||||
@@ -1,37 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
$lang = &$GLOBALS['TL_LANG']['tl_calendar'];
|
||||
|
||||
$lang['wk_legend'] = 'W&K-Sync';
|
||||
|
||||
$lang['wkEnable'] = ['W&K-Sync aktivieren', 'Seminare aus W&K in diesen Kalender importieren und Online-Anmeldungen ermöglichen.'];
|
||||
$lang['wkBookingForm'] = ['Anmeldeformular', 'Formular aus dem Formulargenerator, das für Anmeldungen verwendet wird (Feldnamen wie in tl_wk_booking; anlegen mit „wk-sync:form:create“).'];
|
||||
$lang['wkBookingPage'] = ['Seite mit dem Anmeldeformular', 'Seite, auf der das Modul „W&K-Anmeldeformular“ liegt. Der Link „Jetzt anmelden“ führt dorthin.'];
|
||||
$lang['wkConfirmationPage'] = ['Bestätigungsseite', 'Seite nach erfolgreicher Anmeldung, z. B. „Anmeldung eingegangen“. Kann je Veranstaltung übersteuert werden.'];
|
||||
$lang['wkInquiryPage'] = ['Seite mit dem Anfrageformular', 'Seite mit dem Kontakt-/Anfrageformular; sie wird mit ?event=ID verlinkt.'];
|
||||
$lang['wkDeadlineDays'] = ['Anmeldeschluss (Tage vor Beginn)', 'Bis so viele Tage vor Beginn sind Anmeldungen technisch möglich. 1 = bis einen Tag vor Beginn.'];
|
||||
$lang['wkDeadlineDisplayDays'] = ['Angezeigter Anmeldeschluss (Tage vor Beginn)', 'Datum, das als „Anmeldung möglich bis“ angezeigt wird. 0 = wie der technische Anmeldeschluss.'];
|
||||
$lang['wkOwnVenues'] = ['Eigene Veranstaltungsorte', 'Eine Bezeichnung pro Zeile. Veranstaltungsorte, die so beginnen (z. B. „TPI Moritzburg (barrierefrei)“), gelten als „im eigenen Haus“ – relevant für die Felder Übernachtung und Verpflegung.'];
|
||||
$lang['wkAuthor'] = ['Autor importierter Veranstaltungen', 'Backend-Benutzer, der als Autor neuer Seminare eingetragen wird (leer = der importierende Benutzer).'];
|
||||
$lang['wkInstructorGroup'] = ['Mitgliedergruppe Kursleitung', 'Kursleitungen aus W&K werden als Mitglieder dieser Gruppe angelegt (leer = keine Mitglieder anlegen).'];
|
||||
$lang['wkSpeakerGroup'] = ['Mitgliedergruppe Referenten', 'Referenten aus W&K werden als Mitglieder dieser Gruppe angelegt (leer = keine Mitglieder anlegen).'];
|
||||
$lang['wkNewsletterChannels'] = ['Newsletter-Verteiler', 'Verteiler, die bei „Newsletter abonnieren“ mit Double-Opt-in abonniert werden.'];
|
||||
$lang['wkNewsletterPage'] = ['Seite zur Newsletter-Aktivierung', 'Seite mit dem Modul „Abonnieren“, die den Aktivierungslink (?token=) verarbeitet.'];
|
||||
$lang['wkNewsletterText'] = ['Text der Aktivierungsmail', 'Optional. Token: ##link##, ##channels##, ##domain##. Leer = Standardtext.'];
|
||||
$lang['wkNotificationDefault'] = ['Standard-Benachrichtigung', 'Wird verschickt, wenn keine der Bedingungen zutrifft und an der Veranstaltung nichts eingestellt ist.'];
|
||||
$lang['wkNotificationCondition'] = ['Benachrichtigung', 'Benachrichtigung vom Typ „W&K-Anmeldung“ für diese Bedingung.'];
|
||||
|
||||
$lang['wkNotificationExplanation1'] = '<strong>Bedingung 1: Online-Kurse</strong> – alle Kategorien, Veranstaltungsort „Online“.';
|
||||
$lang['wkNotificationExplanation2'] = '<strong>Bedingung 2: Tagesveranstaltung Schulfortbildung</strong> – Beginn = Ende, Kategorie-Art „Schule“, Nummer beginnt mit EXTP.';
|
||||
$lang['wkNotificationExplanation3'] = '<strong>Bedingung 3: Tagesveranstaltung Gemeinde / Gottesdienst mit Kindern / Tagungen</strong> – Beginn = Ende, Kategorie-Art „Gemeinde“, „Gottesdienst mit Kindern“ oder „Tagungen“.';
|
||||
$lang['wkNotificationExplanation4'] = '<strong>Bedingung 4: Tagesveranstaltung Elementarbereich</strong> – Beginn = Ende, Kategorie-Art „Elementarbereich“.';
|
||||
$lang['wkNotificationExplanation5'] = '<strong>Bedingung 5: Mehrtägige Schulfortbildung</strong> – Beginn ≠ Ende, Kategorie-Art „Schule“, Nummer beginnt mit EXTP.';
|
||||
$lang['wkNotificationExplanation6'] = '<strong>Bedingung 6: Mehrtägige Fortbildung Elementarbereich</strong> – Beginn ≠ Ende, Kategorie-Art „Elementarbereich“.';
|
||||
$lang['wkNotificationExplanation7'] = '<strong>Bedingung 7: Mehrtägige Veranstaltung Gemeinde / Gottesdienst mit Kindern / Tagungen</strong> – Beginn ≠ Ende.';
|
||||
$lang['wkNotificationExplanation8'] = '<strong>Bedingung 8: Tagesveranstaltung Evangelische Schulen</strong> – Beginn = Ende, Kategorie-Art „Evangelische Schulen“.';
|
||||
$lang['wkNotificationExplanation9'] = '<strong>Bedingung 9: Mehrtägige Veranstaltung Evangelische Schulen</strong> – Beginn ≠ Ende, Kategorie-Art „Evangelische Schulen“.';
|
||||
$lang['wkNotificationExplanation10'] = '<strong>Bedingung 10: Tagesveranstaltung Mentoring</strong> – Beginn = Ende, Kategorie-Art „Mentoring“.';
|
||||
$lang['wkNotificationExplanation11'] = '<strong>Bedingung 11: Mehrtägige Veranstaltung Mentoring</strong> – Beginn ≠ Ende, Kategorie-Art „Mentoring“.';
|
||||
$lang['wkNotificationExplanation12'] = '<strong>Bedingung 12: Mehrtägige Ausbildung</strong> – Beginn ≠ Ende, Kategorie-Art „Ausbildung“.';
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
$lang = &$GLOBALS['TL_LANG']['tl_wk_config'];
|
||||
|
||||
$lang['title_legend'] = 'Kalender';
|
||||
$lang['page_legend'] = 'Formular und Seiten';
|
||||
$lang['booking_legend'] = 'Anmeldung';
|
||||
$lang['import_legend'] = 'Import';
|
||||
$lang['newsletter_legend'] = 'Newsletter';
|
||||
$lang['notification_legend'] = 'Benachrichtigungen';
|
||||
|
||||
$lang['title'] = ['Bezeichnung', 'Interner Name dieser Einstellungen, z. B. „Programm“.'];
|
||||
$lang['calendar'] = ['Kalender', 'Kalender, in den die W&K-Seminare importiert werden und dessen Veranstaltungen online buchbar sind. Je Kalender ein Eintrag.'];
|
||||
$lang['bookingForm'] = ['Anmeldeformular', 'Formular aus dem Formulargenerator, das für Anmeldungen verwendet wird (Feldnamen wie in tl_wk_booking; anlegen mit „wk-sync:form:create“).'];
|
||||
$lang['bookingPage'] = ['Seite mit dem Anmeldeformular', 'Seite, auf der das Modul „W&K-Anmeldeformular“ liegt. Der Link „Jetzt anmelden“ führt dorthin.'];
|
||||
$lang['confirmationPage'] = ['Bestätigungsseite', 'Seite nach erfolgreicher Anmeldung, z. B. „Anmeldung eingegangen“. Kann je Veranstaltung übersteuert werden.'];
|
||||
$lang['inquiryPage'] = ['Seite mit dem Anfrageformular', 'Seite mit dem Kontakt-/Anfrageformular; sie wird mit ?event=ID verlinkt.'];
|
||||
$lang['deadlineDays'] = ['Anmeldeschluss (Tage vor Beginn)', 'Bis so viele Tage vor Beginn sind Anmeldungen technisch möglich. 1 = bis einen Tag vor Beginn.'];
|
||||
$lang['deadlineDisplayDays'] = ['Angezeigter Anmeldeschluss (Tage vor Beginn)', 'Datum, das als „Anmeldung möglich bis“ angezeigt wird. 0 = wie der technische Anmeldeschluss.'];
|
||||
$lang['ownVenues'] = ['Eigene Veranstaltungsorte', 'Eine Bezeichnung pro Zeile. Veranstaltungsorte, die so beginnen (z. B. „TPI Moritzburg (barrierefrei)“), gelten als „im eigenen Haus“ – relevant für die Felder Übernachtung und Verpflegung.'];
|
||||
$lang['author'] = ['Autor importierter Veranstaltungen', 'Backend-Benutzer, der als Autor neuer Seminare eingetragen wird (leer = der importierende Benutzer).'];
|
||||
$lang['instructorGroup'] = ['Mitgliedergruppe Kursleitung', 'Kursleitungen aus W&K werden als Mitglieder dieser Gruppe angelegt (leer = keine Mitglieder anlegen).'];
|
||||
$lang['speakerGroup'] = ['Mitgliedergruppe Referenten', 'Referenten aus W&K werden als Mitglieder dieser Gruppe angelegt (leer = keine Mitglieder anlegen).'];
|
||||
$lang['newsletterChannels'] = ['Newsletter-Verteiler', 'Verteiler, die bei „Newsletter abonnieren“ mit Double-Opt-in abonniert werden.'];
|
||||
$lang['newsletterPage'] = ['Seite zur Newsletter-Aktivierung', 'Seite mit dem Modul „Abonnieren“, die den Aktivierungslink (?token=) verarbeitet.'];
|
||||
$lang['newsletterText'] = ['Text der Aktivierungsmail', 'Optional. Token: ##link##, ##channels##, ##domain##. Leer = Standardtext.'];
|
||||
$lang['notificationDefault'] = ['Standard-Benachrichtigung', 'Wird verschickt, wenn keine der Bedingungen zutrifft und an der Veranstaltung nichts eingestellt ist. Nur Benachrichtigungen vom Typ „W&K-Anmeldung“.'];
|
||||
$lang['notificationCondition'] = ['Benachrichtigung für diese Bedingung', 'Leer = Bedingung wird übersprungen, die nächste zutreffende Bedingung zählt.'];
|
||||
|
||||
$lang['notificationExplanation1'] = '<strong>Bedingung 1: Online-Kurse</strong> – alle Kategorien, Veranstaltungsort „Online“.';
|
||||
$lang['notificationExplanation2'] = '<strong>Bedingung 2: Tagesveranstaltung Schulfortbildung</strong> – Beginn = Ende, Kategorie-Art „Schule“, Nummer beginnt mit EXTP.';
|
||||
$lang['notificationExplanation3'] = '<strong>Bedingung 3: Tagesveranstaltung Gemeinde / Gottesdienst mit Kindern / Tagungen</strong> – Beginn = Ende, Kategorie-Art „Gemeinde“, „Gottesdienst mit Kindern“ oder „Tagungen“.';
|
||||
$lang['notificationExplanation4'] = '<strong>Bedingung 4: Tagesveranstaltung Elementarbereich</strong> – Beginn = Ende, Kategorie-Art „Elementarbereich“.';
|
||||
$lang['notificationExplanation5'] = '<strong>Bedingung 5: Mehrtägige Schulfortbildung</strong> – Beginn ≠ Ende, Kategorie-Art „Schule“, Nummer beginnt mit EXTP.';
|
||||
$lang['notificationExplanation6'] = '<strong>Bedingung 6: Mehrtägige Fortbildung Elementarbereich</strong> – Beginn ≠ Ende, Kategorie-Art „Elementarbereich“.';
|
||||
$lang['notificationExplanation7'] = '<strong>Bedingung 7: Mehrtägige Veranstaltung Gemeinde / Gottesdienst mit Kindern / Tagungen</strong> – Beginn ≠ Ende.';
|
||||
$lang['notificationExplanation8'] = '<strong>Bedingung 8: Tagesveranstaltung Evangelische Schulen</strong> – Beginn = Ende, Kategorie-Art „Evangelische Schulen“.';
|
||||
$lang['notificationExplanation9'] = '<strong>Bedingung 9: Mehrtägige Veranstaltung Evangelische Schulen</strong> – Beginn ≠ Ende, Kategorie-Art „Evangelische Schulen“.';
|
||||
$lang['notificationExplanation10'] = '<strong>Bedingung 10: Tagesveranstaltung Mentoring</strong> – Beginn = Ende, Kategorie-Art „Mentoring“.';
|
||||
$lang['notificationExplanation11'] = '<strong>Bedingung 11: Mehrtägige Veranstaltung Mentoring</strong> – Beginn ≠ Ende, Kategorie-Art „Mentoring“.';
|
||||
$lang['notificationExplanation12'] = '<strong>Bedingung 12: Mehrtägige Ausbildung</strong> – Beginn ≠ Ende, Kategorie-Art „Ausbildung“.';
|
||||
|
||||
$lang['new'] = ['Neue Einstellungen', 'Einstellungen für einen Kalender anlegen'];
|
||||
$lang['edit'] = ['Einstellungen bearbeiten', 'Einstellungen ID %s bearbeiten'];
|
||||
$lang['copy'] = ['Einstellungen duplizieren', 'Einstellungen ID %s duplizieren'];
|
||||
$lang['delete'] = ['Einstellungen löschen', 'Einstellungen ID %s löschen'];
|
||||
$lang['show'] = ['Details', 'Details der Einstellungen ID %s anzeigen'];
|
||||
@@ -1,7 +0,0 @@
|
||||
{% trans_default_domain 'contao_default' %}
|
||||
{{ messages|raw }}
|
||||
<nav class="wk-sync-nav">
|
||||
<a href="{{ urls.dashboard }}" class="tl_submit{{ current_key in ['', 'preview'] ? ' active' }}">{{ 'MSC.wk_sync.nav.import'|trans }}</a>
|
||||
<a href="{{ urls.inbox }}" class="tl_submit{{ current_key == 'inbox' ? ' active' }}">{{ 'MSC.wk_sync.nav.inbox'|trans }}{% if counts is defined and counts[''] is defined and counts[''] > 0 %} <span class="wk-sync-badge">{{ counts[''] }}</span>{% endif %}</a>
|
||||
<a href="{{ urls.exports }}" class="tl_submit{{ current_key == 'exports' ? ' active' }}">{{ 'MSC.wk_sync.nav.exports'|trans }}</a>
|
||||
</nav>
|
||||
@@ -1,6 +1,6 @@
|
||||
{% trans_default_domain 'contao_default' %}
|
||||
<div class="wk-sync">
|
||||
{{ include('@Contao/backend/wk_sync/_nav.html.twig') }}
|
||||
{{ messages|raw }}
|
||||
|
||||
<h2>{{ 'MSC.wk_sync.exports.headline'|trans }}</h2>
|
||||
<p class="tl_help">{{ 'MSC.wk_sync.exports.help'|trans }}</p>
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
{% trans_default_domain 'contao_default' %}
|
||||
<div class="wk-sync">
|
||||
{{ include('@Contao/backend/wk_sync/_nav.html.twig') }}
|
||||
{{ messages|raw }}
|
||||
|
||||
<h2>{{ 'MSC.wk_sync.import.headline'|trans }}</h2>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
{% endif %}
|
||||
|
||||
{% if calendars is empty %}
|
||||
<p class="tl_error">{{ 'MSC.wk_sync.import.no_calendar'|trans }}</p>
|
||||
<p class="tl_error">{{ 'MSC.wk_sync.import.no_calendar'|trans }} <a href="{{ path('contao_backend', {do: 'wk_config'}) }}">{{ 'MSC.wk_sync.import.open_config'|trans }}</a></p>
|
||||
{% else %}
|
||||
<form method="post" action="{{ urls.upload }}" enctype="multipart/form-data" class="tl_form wk-sync-upload">
|
||||
<input type="hidden" name="REQUEST_TOKEN" value="{{ request_token }}">
|
||||
@@ -19,7 +19,7 @@
|
||||
<label for="wk_calendar"><strong>{{ 'MSC.wk_sync.import.calendar'|trans }}</strong></label>
|
||||
<select name="calendar" id="wk_calendar" class="tl_select">
|
||||
{% for calendar in calendars %}
|
||||
<option value="{{ calendar.id }}">{{ calendar.title }}</option>
|
||||
<option value="{{ calendar.id }}">{{ calendar.configTitle }} → {{ calendar.title }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
</div>
|
||||
@@ -1,6 +1,6 @@
|
||||
{% trans_default_domain 'contao_default' %}
|
||||
<div class="wk-sync">
|
||||
{{ include('@Contao/backend/wk_sync/_nav.html.twig') }}
|
||||
{{ messages|raw }}
|
||||
|
||||
<h2>{{ 'MSC.wk_sync.inbox.headline'|trans }}</h2>
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{% trans_default_domain 'contao_default' %}
|
||||
<div class="wk-sync">
|
||||
{{ include('@Contao/backend/wk_sync/_nav.html.twig') }}
|
||||
{{ messages|raw }}
|
||||
|
||||
<h2>{{ 'MSC.wk_sync.preview.headline'|trans([log.filename, calendar.title]) }}</h2>
|
||||
|
||||
|
||||
@@ -44,7 +44,11 @@ use Twig\Environment;
|
||||
*/
|
||||
class WkSyncBackend
|
||||
{
|
||||
public const string MODULE = 'wk_sync_tools';
|
||||
public const string MODULE_IMPORT = 'wk_import';
|
||||
public const string MODULE_INBOX = 'wk_inbox';
|
||||
public const string MODULE_EXPORTS = 'wk_exports';
|
||||
public const string MODULE_BOOKINGS = 'wk_bookings';
|
||||
public const string MODULE_INQUIRIES = 'wk_inquiries';
|
||||
|
||||
private const int MAX_UPLOAD_BYTES = 20 * 1024 * 1024;
|
||||
|
||||
@@ -75,32 +79,42 @@ class WkSyncBackend
|
||||
}
|
||||
|
||||
$this->framework->initialize();
|
||||
$module = (string) $request->query->get('do', '');
|
||||
$key = (string) $request->query->get('key', '');
|
||||
|
||||
try {
|
||||
return match ($key) {
|
||||
'' => $this->dashboard($request),
|
||||
'upload' => $this->upload($request),
|
||||
'preview' => $this->preview($request),
|
||||
'apply' => $this->apply($request),
|
||||
'discard' => $this->discard($request),
|
||||
'inbox' => $this->inboxView($request),
|
||||
'move' => $this->move($request),
|
||||
'export' => $this->export($request),
|
||||
'exports' => $this->exports($request),
|
||||
'download' => $this->download($request),
|
||||
default => throw new PageNotFoundException('Unknown action "'.$key.'"'),
|
||||
return match ($module) {
|
||||
self::MODULE_IMPORT => match ($key) {
|
||||
'' => $this->importView($request),
|
||||
'upload' => $this->upload($request),
|
||||
'preview' => $this->preview($request),
|
||||
'apply' => $this->apply($request),
|
||||
'discard' => $this->discard($request),
|
||||
default => throw new PageNotFoundException('Unknown action "'.$key.'"'),
|
||||
},
|
||||
self::MODULE_INBOX => match ($key) {
|
||||
'' => $this->inboxView($request),
|
||||
'move' => $this->move($request),
|
||||
'export' => $this->export($request),
|
||||
default => throw new PageNotFoundException('Unknown action "'.$key.'"'),
|
||||
},
|
||||
self::MODULE_EXPORTS => match ($key) {
|
||||
'' => $this->exportsView($request),
|
||||
'download' => $this->download($request),
|
||||
default => throw new PageNotFoundException('Unknown action "'.$key.'"'),
|
||||
},
|
||||
default => throw new PageNotFoundException('Unknown module "'.$module.'"'),
|
||||
};
|
||||
} catch (ImportException $e) {
|
||||
$this->message()->addError($e->getMessage());
|
||||
|
||||
throw new RedirectResponseException($this->url([]));
|
||||
throw new RedirectResponseException($this->url('' !== $module ? $module : self::MODULE_IMPORT));
|
||||
}
|
||||
}
|
||||
|
||||
private function dashboard(Request $request): string
|
||||
private function importView(Request $request): string
|
||||
{
|
||||
return $this->render('dashboard', [
|
||||
return $this->render('import', [
|
||||
'calendars' => $this->calendars->findEnabled(),
|
||||
'imports' => array_map($this->decorateLog(...), $this->log->findLatest(SyncLog::TYPE_IMPORT, 10)),
|
||||
'counts' => $this->inbox->countByState(),
|
||||
@@ -133,7 +147,7 @@ class WkSyncBackend
|
||||
|
||||
$prepared = $this->importService->prepare($path, $filename, $calendarId, $this->userId());
|
||||
|
||||
throw new RedirectResponseException($this->url(['key' => 'preview', 'id' => $prepared['logId']]));
|
||||
throw new RedirectResponseException($this->url(self::MODULE_IMPORT, ['key' => 'preview', 'id' => $prepared['logId']]));
|
||||
}
|
||||
|
||||
private function preview(Request $request): string
|
||||
@@ -186,7 +200,7 @@ class WkSyncBackend
|
||||
|
||||
$this->message()->addConfirmation($this->trans('import.applied', [$result['created'], $result['updated'], $result['cancelled'], $result['unchanged']]));
|
||||
|
||||
throw new RedirectResponseException($this->url(['key' => 'preview', 'id' => $id]));
|
||||
throw new RedirectResponseException($this->url(self::MODULE_IMPORT, ['key' => 'preview', 'id' => $id]));
|
||||
}
|
||||
|
||||
private function discard(Request $request): string
|
||||
@@ -200,7 +214,7 @@ class WkSyncBackend
|
||||
$this->message()->addInfo($this->trans('import.discarded'));
|
||||
}
|
||||
|
||||
throw new RedirectResponseException($this->url([]));
|
||||
throw new RedirectResponseException($this->url(self::MODULE_IMPORT));
|
||||
}
|
||||
|
||||
private function inboxView(Request $request): string
|
||||
@@ -257,7 +271,7 @@ class WkSyncBackend
|
||||
|
||||
$this->message()->addConfirmation($this->trans('inbox.moved', [$moved, $this->trans('state.'.$target->translationKey())]));
|
||||
|
||||
throw new RedirectResponseException($this->url(['key' => 'inbox', 'list' => $list]));
|
||||
throw new RedirectResponseException($this->url(self::MODULE_INBOX, ['list' => $list]));
|
||||
}
|
||||
|
||||
private function export(Request $request): string
|
||||
@@ -269,15 +283,15 @@ class WkSyncBackend
|
||||
if (null === $result) {
|
||||
$this->message()->addInfo($this->trans('export.empty'));
|
||||
|
||||
throw new RedirectResponseException($this->url(['key' => 'inbox', 'list' => InboxState::DownloadList->value]));
|
||||
throw new RedirectResponseException($this->url(self::MODULE_INBOX, ['list' => InboxState::DownloadList->value]));
|
||||
}
|
||||
|
||||
$this->message()->addConfirmation($this->trans('export.done', [$result['bookings'], $result['inquiries']]));
|
||||
|
||||
throw new RedirectResponseException($this->url(['key' => 'exports', 'highlight' => $result['logId']]));
|
||||
throw new RedirectResponseException($this->url(self::MODULE_EXPORTS, ['highlight' => $result['logId']]));
|
||||
}
|
||||
|
||||
private function exports(Request $request): string
|
||||
private function exportsView(Request $request): string
|
||||
{
|
||||
return $this->render('exports', [
|
||||
'exports' => array_map($this->decorateLog(...), $this->log->findLatest(SyncLog::TYPE_EXPORT, 50)),
|
||||
@@ -400,8 +414,8 @@ class WkSyncBackend
|
||||
{
|
||||
$log['date'] = $this->formatDate((int) $log['tstamp'], 'datimFormat');
|
||||
$log['calendarTitle'] = $this->calendars->find((int) $log['calendar'])?->title ?? '';
|
||||
$log['preview_url'] = $this->url(['key' => 'preview', 'id' => $log['id']]);
|
||||
$log['download_url'] = $this->url(['key' => 'download', 'id' => $log['id']]);
|
||||
$log['preview_url'] = $this->url(self::MODULE_IMPORT, ['key' => 'preview', 'id' => $log['id']]);
|
||||
$log['download_url'] = $this->url(self::MODULE_EXPORTS, ['key' => 'download', 'id' => $log['id']]);
|
||||
$log['file_exists'] = $this->storage->exists((string) ($log['path'] ?? ''));
|
||||
|
||||
return $log;
|
||||
@@ -410,8 +424,8 @@ class WkSyncBackend
|
||||
private function editUrl(InboxItem $item, string $referer): string
|
||||
{
|
||||
$params = $item->isBooking()
|
||||
? ['do' => 'wk_sync_bookings', 'table' => 'tl_wk_booking', 'act' => 'edit', 'id' => $item->id]
|
||||
: ['do' => 'wk_sync_inquiries', 'table' => 'tl_wk_inquiry', 'act' => 'edit', 'id' => $item->id];
|
||||
? ['do' => self::MODULE_BOOKINGS, 'table' => 'tl_wk_booking', 'act' => 'edit', 'id' => $item->id]
|
||||
: ['do' => self::MODULE_INQUIRIES, 'table' => 'tl_wk_inquiry', 'act' => 'edit', 'id' => $item->id];
|
||||
|
||||
if ('' !== $referer) {
|
||||
$params['ref'] = $referer;
|
||||
@@ -432,29 +446,31 @@ class WkSyncBackend
|
||||
'messages' => $this->message()->generate(),
|
||||
'request_token' => $this->csrfTokenManager->getDefaultTokenValue(),
|
||||
'urls' => [
|
||||
'dashboard' => $this->url([]),
|
||||
'upload' => $this->url(['key' => 'upload']),
|
||||
'apply' => $this->url(['key' => 'apply']),
|
||||
'discard' => $this->url(['key' => 'discard']),
|
||||
'inbox' => $this->url(['key' => 'inbox']),
|
||||
'move' => $this->url(['key' => 'move']),
|
||||
'export' => $this->url(['key' => 'export']),
|
||||
'exports' => $this->url(['key' => 'exports']),
|
||||
'import' => $this->url(self::MODULE_IMPORT),
|
||||
'upload' => $this->url(self::MODULE_IMPORT, ['key' => 'upload']),
|
||||
'apply' => $this->url(self::MODULE_IMPORT, ['key' => 'apply']),
|
||||
'discard' => $this->url(self::MODULE_IMPORT, ['key' => 'discard']),
|
||||
'inbox' => $this->url(self::MODULE_INBOX),
|
||||
'move' => $this->url(self::MODULE_INBOX, ['key' => 'move']),
|
||||
'export' => $this->url(self::MODULE_INBOX, ['key' => 'export']),
|
||||
'exports' => $this->url(self::MODULE_EXPORTS),
|
||||
'bookings' => $this->url(self::MODULE_BOOKINGS),
|
||||
'inquiries' => $this->url(self::MODULE_INQUIRIES),
|
||||
],
|
||||
'inbox_urls' => array_combine(
|
||||
array_map(static fn (InboxState $s): string => $s->translationKey(), InboxState::cases()),
|
||||
array_map(fn (InboxState $s): string => $this->url(['key' => 'inbox', 'list' => $s->value]), InboxState::cases()),
|
||||
array_map(fn (InboxState $s): string => $this->url(self::MODULE_INBOX, ['list' => $s->value]), InboxState::cases()),
|
||||
),
|
||||
'current_key' => (string) $request?->query->get('key', ''),
|
||||
'current_module' => (string) $request?->query->get('do', ''),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $params
|
||||
*/
|
||||
private function url(array $params): string
|
||||
private function url(string $module, array $params = []): string
|
||||
{
|
||||
return $this->router->generate('contao_backend', ['do' => self::MODULE, ...$params]);
|
||||
return $this->router->generate('contao_backend', ['do' => $module, ...$params]);
|
||||
}
|
||||
|
||||
private function requirePost(Request $request): void
|
||||
|
||||
@@ -41,6 +41,12 @@ class NotificationCenterNotifier implements BookingNotifierInterface
|
||||
|
||||
public function availableNotifications(): array
|
||||
{
|
||||
return $this->notificationCenter->getNotificationsForNotificationType(BookingNotificationType::NAME);
|
||||
$options = [];
|
||||
|
||||
foreach ($this->notificationCenter->getNotificationsForNotificationType(BookingNotificationType::NAME) as $id => $title) {
|
||||
$options[(int) $id] = \sprintf('%s (ID %d)', $title, $id);
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,7 @@ class CreateBookingFormCommand extends Command
|
||||
{
|
||||
$this
|
||||
->addOption('title', null, InputOption::VALUE_REQUIRED, 'Titel des Formulars', 'W&K-Anmeldung')
|
||||
->addOption('calendar', null, InputOption::VALUE_REQUIRED, 'Formular diesem Kalender (ID) als Anmeldeformular zuweisen')
|
||||
->addOption('calendar', null, InputOption::VALUE_REQUIRED, 'Formular in den W&K-Einstellungen dieses Kalenders (ID) eintragen; die Einstellungen werden bei Bedarf angelegt')
|
||||
->addOption('privacy-url', null, InputOption::VALUE_REQUIRED, 'Link zur Datenschutzseite', '/datenschutz')
|
||||
->addOption('terms-url', null, InputOption::VALUE_REQUIRED, 'Link zu den AGB', '/agb')
|
||||
;
|
||||
@@ -69,15 +69,38 @@ class CreateBookingFormCommand extends Command
|
||||
$calendarId = (int) $input->getOption('calendar');
|
||||
|
||||
if ($calendarId > 0) {
|
||||
$this->connection->update('tl_calendar', ['wkBookingForm' => $formId, 'tstamp' => $now], ['id' => $calendarId]);
|
||||
$io->writeln(\sprintf('Kalender %d verwendet das Formular jetzt als Anmeldeformular.', $calendarId));
|
||||
$this->assignToConfig($calendarId, $formId, $now);
|
||||
$io->writeln(\sprintf('Die W&K-Einstellungen für Kalender %d verwenden das Formular jetzt als Anmeldeformular.', $calendarId));
|
||||
} else {
|
||||
$io->note('Das Formular jetzt im Kalender unter „W&K-Sync → Anmeldeformular“ auswählen.');
|
||||
$io->note('Das Formular jetzt unter „W&K-Tools → Einstellungen“ als Anmeldeformular auswählen.');
|
||||
}
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
|
||||
private function assignToConfig(int $calendarId, int $formId, int $now): void
|
||||
{
|
||||
$configId = $this->connection->fetchOne('SELECT id FROM tl_wk_config WHERE calendar = ?', [$calendarId]);
|
||||
|
||||
if (false !== $configId) {
|
||||
$this->connection->update('tl_wk_config', ['bookingForm' => $formId, 'tstamp' => $now], ['id' => (int) $configId]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$title = (string) $this->connection->fetchOne('SELECT title FROM tl_calendar WHERE id = ?', [$calendarId]);
|
||||
|
||||
$this->insert('tl_wk_config', [
|
||||
'tstamp' => $now,
|
||||
'title' => '' !== $title ? $title : 'Kalender '.$calendarId,
|
||||
'calendar' => $calendarId,
|
||||
'bookingForm' => $formId,
|
||||
'deadlineDays' => 1,
|
||||
'deadlineDisplayDays' => 31,
|
||||
'ownVenues' => 'TPI Moritzburg',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return list<array<string, mixed>>
|
||||
*/
|
||||
|
||||
@@ -10,7 +10,7 @@ use Doctrine\DBAL\Connection;
|
||||
/**
|
||||
* Newsletter-Verteiler (leer, wenn das Newsletter-Bundle fehlt).
|
||||
*/
|
||||
#[AsCallback(table: 'tl_calendar', target: 'fields.wkNewsletterChannels.options')]
|
||||
#[AsCallback(table: 'tl_wk_config', target: 'fields.newsletterChannels.options')]
|
||||
class NewsletterChannelOptionsListener
|
||||
{
|
||||
public function __construct(private readonly Connection $connection)
|
||||
|
||||
@@ -10,19 +10,19 @@ use Mummert\ContaoWkSyncBundle\Booking\BookingNotifierInterface;
|
||||
/**
|
||||
* Auswahl der Benachrichtigungen vom Typ „W&K-Anmeldung“ (leer ohne Notification Center).
|
||||
*/
|
||||
#[AsCallback(table: 'tl_calendar', target: 'fields.wkNotificationDefault.options')]
|
||||
#[AsCallback(table: 'tl_calendar', target: 'fields.wkNotification1.options')]
|
||||
#[AsCallback(table: 'tl_calendar', target: 'fields.wkNotification2.options')]
|
||||
#[AsCallback(table: 'tl_calendar', target: 'fields.wkNotification3.options')]
|
||||
#[AsCallback(table: 'tl_calendar', target: 'fields.wkNotification4.options')]
|
||||
#[AsCallback(table: 'tl_calendar', target: 'fields.wkNotification5.options')]
|
||||
#[AsCallback(table: 'tl_calendar', target: 'fields.wkNotification6.options')]
|
||||
#[AsCallback(table: 'tl_calendar', target: 'fields.wkNotification7.options')]
|
||||
#[AsCallback(table: 'tl_calendar', target: 'fields.wkNotification8.options')]
|
||||
#[AsCallback(table: 'tl_calendar', target: 'fields.wkNotification9.options')]
|
||||
#[AsCallback(table: 'tl_calendar', target: 'fields.wkNotification10.options')]
|
||||
#[AsCallback(table: 'tl_calendar', target: 'fields.wkNotification11.options')]
|
||||
#[AsCallback(table: 'tl_calendar', target: 'fields.wkNotification12.options')]
|
||||
#[AsCallback(table: 'tl_wk_config', target: 'fields.notificationDefault.options')]
|
||||
#[AsCallback(table: 'tl_wk_config', target: 'fields.notification1.options')]
|
||||
#[AsCallback(table: 'tl_wk_config', target: 'fields.notification2.options')]
|
||||
#[AsCallback(table: 'tl_wk_config', target: 'fields.notification3.options')]
|
||||
#[AsCallback(table: 'tl_wk_config', target: 'fields.notification4.options')]
|
||||
#[AsCallback(table: 'tl_wk_config', target: 'fields.notification5.options')]
|
||||
#[AsCallback(table: 'tl_wk_config', target: 'fields.notification6.options')]
|
||||
#[AsCallback(table: 'tl_wk_config', target: 'fields.notification7.options')]
|
||||
#[AsCallback(table: 'tl_wk_config', target: 'fields.notification8.options')]
|
||||
#[AsCallback(table: 'tl_wk_config', target: 'fields.notification9.options')]
|
||||
#[AsCallback(table: 'tl_wk_config', target: 'fields.notification10.options')]
|
||||
#[AsCallback(table: 'tl_wk_config', target: 'fields.notification11.options')]
|
||||
#[AsCallback(table: 'tl_wk_config', target: 'fields.notification12.options')]
|
||||
#[AsCallback(table: 'tl_calendar_events', target: 'fields.wkNotification.options')]
|
||||
class NotificationOptionsListener
|
||||
{
|
||||
|
||||
+26
-20
@@ -7,7 +7,9 @@ namespace Mummert\ContaoWkSyncBundle\Sync;
|
||||
use Contao\StringUtil;
|
||||
|
||||
/**
|
||||
* W&K-Einstellungen eines Kalenders (tl_calendar).
|
||||
* W&K-Einstellungen für einen Kalender (tl_wk_config, je Kalender ein Eintrag).
|
||||
*
|
||||
* `id` ist die ID des Kalenders (tl_calendar), `configId` die des Einstellungs-Datensatzes.
|
||||
*/
|
||||
final readonly class CalendarConfig
|
||||
{
|
||||
@@ -18,7 +20,9 @@ final readonly class CalendarConfig
|
||||
*/
|
||||
public function __construct(
|
||||
public int $id,
|
||||
public int $configId,
|
||||
public string $title,
|
||||
public string $configTitle,
|
||||
public int $jumpTo,
|
||||
public bool $enabled,
|
||||
public int $bookingForm,
|
||||
@@ -40,40 +44,42 @@ final readonly class CalendarConfig
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $row
|
||||
* @param array<string, mixed> $row Zeile aus tl_wk_config, optional mit calendarTitle und calendarJumpTo
|
||||
*/
|
||||
public static function fromRow(array $row): self
|
||||
{
|
||||
$venues = preg_split('/\r?\n/', (string) ($row['wkOwnVenues'] ?? '')) ?: [];
|
||||
$venues = preg_split('/\r?\n/', (string) ($row['ownVenues'] ?? '')) ?: [];
|
||||
$venues = array_values(array_filter(array_map(trim(...), $venues), static fn (string $v): bool => '' !== $v));
|
||||
|
||||
$conditions = [];
|
||||
|
||||
foreach ($row as $key => $value) {
|
||||
if (preg_match('/^wkNotification(\d+)$/', (string) $key, $m)) {
|
||||
if (preg_match('/^notification(\d+)$/', (string) $key, $m)) {
|
||||
$conditions[(int) $m[1]] = (int) $value;
|
||||
}
|
||||
}
|
||||
|
||||
return new self(
|
||||
(int) $row['id'],
|
||||
(int) ($row['calendar'] ?? 0),
|
||||
(int) ($row['id'] ?? 0),
|
||||
(string) ($row['calendarTitle'] ?? ''),
|
||||
(string) ($row['title'] ?? ''),
|
||||
(int) ($row['jumpTo'] ?? 0),
|
||||
(bool) ($row['wkEnable'] ?? false),
|
||||
(int) ($row['wkBookingForm'] ?? 0),
|
||||
(int) ($row['wkBookingPage'] ?? 0),
|
||||
(int) ($row['wkConfirmationPage'] ?? 0),
|
||||
(int) ($row['wkInquiryPage'] ?? 0),
|
||||
(int) ($row['wkDeadlineDays'] ?? 1),
|
||||
(int) ($row['wkDeadlineDisplayDays'] ?? 0),
|
||||
(int) ($row['calendarJumpTo'] ?? 0),
|
||||
(int) ($row['calendar'] ?? 0) > 0,
|
||||
(int) ($row['bookingForm'] ?? 0),
|
||||
(int) ($row['bookingPage'] ?? 0),
|
||||
(int) ($row['confirmationPage'] ?? 0),
|
||||
(int) ($row['inquiryPage'] ?? 0),
|
||||
(int) ($row['deadlineDays'] ?? 1),
|
||||
(int) ($row['deadlineDisplayDays'] ?? 0),
|
||||
$venues,
|
||||
(int) ($row['wkAuthor'] ?? 0),
|
||||
(int) ($row['wkInstructorGroup'] ?? 0),
|
||||
(int) ($row['wkSpeakerGroup'] ?? 0),
|
||||
array_map(intval(...), StringUtil::deserialize($row['wkNewsletterChannels'] ?? null, true)),
|
||||
(int) ($row['wkNewsletterPage'] ?? 0),
|
||||
(string) ($row['wkNewsletterText'] ?? ''),
|
||||
(int) ($row['wkNotificationDefault'] ?? 0),
|
||||
(int) ($row['author'] ?? 0),
|
||||
(int) ($row['instructorGroup'] ?? 0),
|
||||
(int) ($row['speakerGroup'] ?? 0),
|
||||
array_map(intval(...), StringUtil::deserialize($row['newsletterChannels'] ?? null, true)),
|
||||
(int) ($row['newsletterPage'] ?? 0),
|
||||
(string) ($row['newsletterText'] ?? ''),
|
||||
(int) ($row['notificationDefault'] ?? 0),
|
||||
$conditions,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,8 +6,13 @@ namespace Mummert\ContaoWkSyncBundle\Sync;
|
||||
|
||||
use Doctrine\DBAL\Connection;
|
||||
|
||||
/**
|
||||
* Einstellungen je Kalender (tl_wk_config).
|
||||
*/
|
||||
class CalendarConfigRepository
|
||||
{
|
||||
private const string SELECT = 'SELECT c.*, k.title AS calendarTitle, k.jumpTo AS calendarJumpTo FROM tl_wk_config c INNER JOIN tl_calendar k ON k.id = c.calendar';
|
||||
|
||||
/** @var array<int, CalendarConfig|null> */
|
||||
private array $cache = [];
|
||||
|
||||
@@ -15,14 +20,17 @@ class CalendarConfigRepository
|
||||
{
|
||||
}
|
||||
|
||||
public function find(int $id): CalendarConfig|null
|
||||
/**
|
||||
* Einstellungen zum Kalender mit dieser ID.
|
||||
*/
|
||||
public function find(int $calendarId): CalendarConfig|null
|
||||
{
|
||||
if (!\array_key_exists($id, $this->cache)) {
|
||||
$row = $this->connection->fetchAssociative('SELECT * FROM tl_calendar WHERE id = ?', [$id]);
|
||||
$this->cache[$id] = false === $row ? null : CalendarConfig::fromRow($row);
|
||||
if (!\array_key_exists($calendarId, $this->cache)) {
|
||||
$row = $this->connection->fetchAssociative(self::SELECT.' WHERE c.calendar = ?', [$calendarId]);
|
||||
$this->cache[$calendarId] = false === $row ? null : CalendarConfig::fromRow($row);
|
||||
}
|
||||
|
||||
return $this->cache[$id];
|
||||
return $this->cache[$calendarId];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -30,7 +38,7 @@ class CalendarConfigRepository
|
||||
*/
|
||||
public function findEnabled(): array
|
||||
{
|
||||
$rows = $this->connection->fetchAllAssociative('SELECT * FROM tl_calendar WHERE wkEnable = 1 ORDER BY title');
|
||||
$rows = $this->connection->fetchAllAssociative(self::SELECT.' ORDER BY c.title');
|
||||
|
||||
return array_map(CalendarConfig::fromRow(...), $rows);
|
||||
}
|
||||
@@ -51,7 +59,7 @@ class CalendarConfigRepository
|
||||
return [];
|
||||
}
|
||||
|
||||
$rows = $this->connection->fetchAllAssociative('SELECT * FROM tl_calendar WHERE wkEnable = 1 AND wkBookingForm = ?', [$formId]);
|
||||
$rows = $this->connection->fetchAllAssociative(self::SELECT.' WHERE c.bookingForm = ?', [$formId]);
|
||||
|
||||
return array_map(CalendarConfig::fromRow(...), $rows);
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ class BookingRulesTest extends TestCase
|
||||
{
|
||||
private function calendar(): CalendarConfig
|
||||
{
|
||||
return CalendarConfig::fromRow(['id' => 1, 'wkOwnVenues' => "TPI Moritzburg\nMoritzburg"]);
|
||||
return CalendarConfig::fromRow(['id' => 1, 'calendar' => 1, 'ownVenues' => "TPI Moritzburg\nMoritzburg"]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,10 +14,10 @@ class NotificationRouterTest extends TestCase
|
||||
{
|
||||
private function calendar(): CalendarConfig
|
||||
{
|
||||
$row = ['id' => 1, 'wkNotificationDefault' => 99];
|
||||
$row = ['id' => 1, 'calendar' => 1, 'notificationDefault' => 99];
|
||||
|
||||
foreach (NotificationRouter::CONDITIONS as $c) {
|
||||
$row['wkNotification'.$c] = 100 + $c;
|
||||
$row['notification'.$c] = 100 + $c;
|
||||
}
|
||||
|
||||
return CalendarConfig::fromRow($row);
|
||||
@@ -83,7 +83,7 @@ class NotificationRouterTest extends TestCase
|
||||
|
||||
public function testFallsThroughToNextConditionWhenNotificationMissing(): void
|
||||
{
|
||||
$calendar = CalendarConfig::fromRow(['id' => 1, 'wkNotification1' => 0, 'wkNotification4' => 104]);
|
||||
$calendar = CalendarConfig::fromRow(['id' => 1, 'calendar' => 1, 'notification1' => 0, 'notification4' => 104]);
|
||||
$result = (new NotificationRouter())->resolve($this->event(CategoryKind::Elementary, true, ['location' => 'Online']), $calendar);
|
||||
|
||||
self::assertSame([1, 4], $result['conditions']);
|
||||
|
||||
Reference in new issue
Block a user