Release: CalDAV sync bundle hardening and LMW sync
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
# CalDAV Sync Bundle (Contao 5.7)
|
||||
|
||||
Produktionsreifes Grundgeruest fuer einen 2-Way-CalDAV-Sync (V1) zwischen `tl_calendar_events` und einem CalDAV-Kalender.
|
||||
|
||||
## V1-Scope
|
||||
|
||||
- Kein RRULE/EXDATE/RECURRENCE-ID
|
||||
- Kein Backend-Button, nur Command
|
||||
- Harte Loeschung bei fehlendem Gegenstueck
|
||||
- Konfliktregel: remote gewinnt
|
||||
- Contao-only-Felder werden niemals remote geschrieben
|
||||
|
||||
## Verzeichnisstruktur
|
||||
|
||||
```text
|
||||
caldav-sync-bundle/
|
||||
composer.json
|
||||
config/
|
||||
services.yaml
|
||||
contao/
|
||||
dca/
|
||||
tl_calendar.php
|
||||
tl_calendar_events.php
|
||||
languages/
|
||||
de/
|
||||
tl_calendar.php
|
||||
tl_calendar_events.php
|
||||
src/
|
||||
CalDavSyncBundle.php
|
||||
Command/
|
||||
CalDavSyncCommand.php
|
||||
Config/
|
||||
CalendarSyncConfig.php
|
||||
Contao/Manager/
|
||||
Plugin.php
|
||||
DependencyInjection/
|
||||
CalDavSyncExtension.php
|
||||
Repository/
|
||||
ContaoCalendarRepository.php
|
||||
ContaoCalendarEventRepository.php
|
||||
Migration/
|
||||
Version20260327000000.php
|
||||
Service/
|
||||
CalendarConfigProvider.php
|
||||
CalDav/
|
||||
Transport/
|
||||
CalDavTransportInterface.php
|
||||
CalDavTransport.php
|
||||
TransportResponse.php
|
||||
Parser/
|
||||
CalDavXmlParser.php
|
||||
ICalendarParser.php
|
||||
ICalendarSerializer.php
|
||||
Remote/
|
||||
RemoteCalendarReader.php
|
||||
RemoteCalendarWriter.php
|
||||
Sync/
|
||||
RemoteEvent.php
|
||||
EventMatchResolver.php
|
||||
SyncFieldExtractor.php
|
||||
SyncHashGenerator.php
|
||||
SyncResult.php
|
||||
RemoteToLocalSynchronizer.php
|
||||
LocalToRemoteSynchronizer.php
|
||||
SyncRunner.php
|
||||
```
|
||||
|
||||
## Klassenuebersicht
|
||||
|
||||
- `CalendarConfigProvider`: Liefert pro `tl_calendar` die Sync-Konfiguration.
|
||||
- `ContaoCalendarRepository`: Zugriff auf Sync-faehige Kalender.
|
||||
- `ContaoCalendarEventRepository`: CRUD fuer `tl_calendar_events`.
|
||||
- `CalDavTransport`: HTTP/WebDAV via Symfony HttpClient (`PROPFIND`, `REPORT`, `GET`, `PUT`, `DELETE`).
|
||||
- `CalDavXmlParser`: Parsing von WebDAV-Multistatus XML.
|
||||
- `ICalendarParser`: VEVENT-Parsing via `sabre/vobject`.
|
||||
- `ICalendarSerializer`: VEVENT-Serialisierung via `sabre/vobject`.
|
||||
- `RemoteCalendarReader`: Liest Remote-Kalender.
|
||||
- `RemoteCalendarWriter`: Schreibt/loescht Remote-Events mit ETag-Unterstuetzung.
|
||||
- `EventMatchResolver`: Matching zuerst ueber `caldavHref`, dann `caldavUid`.
|
||||
- `SyncFieldExtractor`: Trennt bidirektionale Sync-Felder von lokalen Contao-only-Feldern.
|
||||
- `SyncHashGenerator`: SHA-256 ueber kanonische Sync-Felder.
|
||||
- `RemoteToLocalSynchronizer`: Pull inkl. Konfliktregel und Hard-Delete lokal.
|
||||
- `LocalToRemoteSynchronizer`: Push inkl. Konfliktregel und Hard-Delete remote.
|
||||
- `SyncRunner`: Orchestrierung je Kalender und Richtung.
|
||||
- `CalDavSyncCommand`: CLI-Einstiegspunkt.
|
||||
|
||||
## Mapping-Strategie
|
||||
|
||||
Bidirektionale Felder (sync-relevant):
|
||||
|
||||
- `title`
|
||||
- `start/end`
|
||||
- `all-day / with-time` (`addTime` Mapping)
|
||||
- `description` (`details`)
|
||||
- `location`
|
||||
- optional `url`
|
||||
|
||||
Contao-only-Felder sind explizit nicht Teil des Sync-Hashes und loesen damit keinen Push aus.
|
||||
|
||||
## Logging-Strategie
|
||||
|
||||
- `info`: erfolgreicher Abschluss pro Kalender inkl. Zaehler
|
||||
- `warning`: Konflikte (`remote wins`) mit Kontext (`calendarId`, `eventId`, `href`, `uid`)
|
||||
- Fehler laufen als Exceptions hoch und werden im Command als `FAILURE` signalisiert
|
||||
|
||||
## Command
|
||||
|
||||
```bash
|
||||
php bin/console contao:caldav:sync --direction=both
|
||||
php bin/console contao:caldav:sync --calendar=3 --direction=pull
|
||||
php bin/console contao:caldav:sync --direction=push --dry-run
|
||||
```
|
||||
|
||||
Optionen:
|
||||
|
||||
- `--calendar=ID`
|
||||
- `--direction=pull|push|both`
|
||||
- `--dry-run`
|
||||
Reference in New Issue
Block a user