Files
caldav-sync-bundle/README.md
T

4.4 KiB

CalDAV Sync Bundle (Contao 5.7)

Produktionsreifes 2-Way-CalDAV-Sync-Bundle fuer Contao 5.7 (PHP 8.4). Es synchronisiert Events zwischen tl_calendar_events und einem oder mehreren CalDAV-Kalendern.

Umfang (V1)

  • Kein RRULE/EXDATE/RECURRENCE-ID-Support
  • Kein Backend-Button, Sync nur ueber Command/Cron
  • Harte Loeschung auf beiden Seiten, wenn das Gegenstueck fehlt
  • Konfliktaufloesung pro Event ueber Last-Modified-Wins (mit Toleranz)
  • Contao-only-Felder werden nicht in den Sync-Hash aufgenommen

Voraussetzungen

  • PHP ^8.4
  • Contao ^5.7
  • symfony/http-client ^7.3
  • sabre/vobject ^4.5

Installation

1) Bundle als Composer-Abhaengigkeit einbinden

Bei lokalem Bundle-Checkout z. B. im Projekt-Composer:

{
  "repositories": [
    {
      "type": "path",
      "url": "bundles/caldav-sync-bundle",
      "options": { "symlink": true }
    }
  ],
  "require": {
    "mummert/caldav-sync-bundle": "*@dev"
  }
}

Dann installieren:

composer update mummert/caldav-sync-bundle
php vendor/bin/contao-console contao:migrate
php vendor/bin/contao-console cache:clear

Backend-Konfiguration (Kalender)

In System -> Kalender den gewuenschten Kalender oeffnen und unter CalDAV konfigurieren:

  • CalDAV Sync aktivieren
  • CalDAV URL
  • CalDAV Benutzername
  • CalDAV Passwort
  • CalDAV Autor (Pflichtfeld, wird fuer importierte Events gesetzt)
  • optional CalDAV Zeitzone (Fallback: UTC)
  • Remote-Kalender als Mehrfachauswahl (CheckboxWizard)

Hinweis zur Mehrfachauswahl:

  • Es koennen mehrere Remote-Kalender unter einer Verbindung ausgewaehlt werden.
  • Events aus abgewaehlten Remote-Kalendern werden beim naechsten Pull fuer den betroffenen Contao-Kalender entfernt.

Sync ausfuehren

php bin/console contao:caldav:sync --direction=both
php bin/console contao:caldav:sync --calendar=4 --direction=pull
php bin/console contao:caldav:sync --direction=push --dry-run

Optionen:

  • --calendar=ID: nur einen tl_calendar synchronisieren
  • --direction=pull|push|both: Richtung waehlen (Default both)
  • --dry-run: keine Schreiboperationen lokal/remote

Sync-Verhalten im Detail

Reihenfolge bei --direction=both

  1. Push (lokal -> remote)
  2. Pull (remote -> lokal)

Konfliktregel (Last-Modified-Wins)

  • Lokal wird ueber tl_calendar_events.tstamp bewertet.
  • Remote wird ueber LAST-MODIFIED bzw. DTSTAMP bewertet.
  • Es gilt eine Toleranz von 120 Sekunden.
  • Wenn Remote-Zeitstempel fehlen, wird konservativ lokal bevorzugt.

Loeschverhalten

  • Pull: lokale Gegenstuecke ohne Remote-Pendant werden geloescht.
  • Push: Remote-Events ohne lokales Pendant werden geloescht.
  • Zusaetzlich entfernt der Runner bei Pull importierte Events aus inzwischen abgewaehlten Remote-Kalendern.

Publikationsverhalten

  • Remote-importierte Events werden auf published = 1 gesetzt.

Feldmapping

Bidirektional (hash-relevant):

  • title
  • start/end
  • all-day (addTime)
  • description <-> teaser (Plaintext/HTML-Konvertierung)
  • location
  • url (optional)

Technische Sync-Felder in tl_calendar_events:

  • caldavCalendarHref
  • caldavUid
  • caldavHref
  • caldavEtag
  • caldavSyncHash
  • caldavLastSync
  • caldavOrigin
  • caldavSyncState

Alias-Verhalten:

  • Alias wird bei Remote-Neuanlage als YYYY-MM-DD_slug erzeugt.
  • Maximale Laenge: 40 Zeichen.
  • Kollisionen werden mit Suffix (_2, _3, ...) aufgeloest.

Wichtige Architekturpunkte

  • SyncRunner: Orchestrierung pro Kalender und Richtung
  • RemoteToLocalSynchronizer: Pull + lokale Upserts/Deletes
  • LocalToRemoteSynchronizer: Push + remote Upserts/Deletes
  • SyncFieldExtractor: Mapping, Datumslogik, Teaser-Konvertierung, Aliasbildung
  • RemoteCalendarReader / RemoteCalendarWriter: CalDAV Lesen/Schreiben
  • ContaoCalendarEventRepository: DB-Zugriff inkl. schema-toleranter Writes

Grenzen und Hinweise

  • V1 behandelt keine Serienereignisse.
  • Sync ist command-getrieben; ein Cronjob sollte das Command zyklisch starten.
  • CalDAV-Passwort wird als Klartext fuer Authentifizierung verwendet.

Troubleshooting

  • Keine Kalender in der Mehrfachauswahl:
    • URL, Benutzername, Passwort pruefen
    • Server muss CalDAV-Discovery/PROPFIND erlauben
  • Unerwartete Konflikte:
    • tstamp lokal und LAST-MODIFIED remote vergleichen
    • Zeitzonen-Setup im Kalender pruefen
  • Schreibfehler beim Push:
    • ETag-Precondition und Zugriffsrechte am CalDAV-Server pruefen