I'm running PHP site with a user database and a shared calendar (events) moderated database.
I want to publish these events in iCal/CalDAV so that members can:
- Get all calendar events, in sync, with authentication (private URL...)
- Join an event
- (But not create or modify an event)
The app shall leverage the site existing user & calendar database.
I've looked at the CalDav implementations in PHP & Python, they all seem too complicate for this simple usage:
- sabre/dav has experimental shared calendar support, and leveraging the existing user database seems tricky.
- DAViCal seems to have its own user database, complex ACL schemes, etc.
- Etc.
How to do that?
- Use an CalDAV/iCal library that is adapted? Any idea of a library that would do the job?
- Write my own CalDAV/iCal server, with the risk of poor client support.
EDIT: Useful links to use sabre/dav with an existing website database:
EDIT: Improvements:
Although it works as expected, sabre/DAV is way too slow in creating a server-side event with invites for ~100 local people ("principals"). And it generates 99x useless copies of the event for each invitee. It took like 8 seconds to process the invites (30+ seconds with xdebug profiling on and it crashed it!).
Regarding using a shared calendar, there's only two possibilities in the standard: either give the invitee read-write acces, so he can join the event (but also change/delete it!) or give him read-only access... but he can't join it. So I've played with
Sabre\CalDAV\Backend\PDO::updateCalendarObject()
to restrict event edits to the participantPARTSTAT
.
But whatever the solution, there's an issue with conflicts:
When a participant A modifies a calendar entry saying it participates (
PARTSTAT ACCEPTED
), Sabre/DAV processes this information by updating all calendar objects, in all user calendars. When doing so, SabreDAV increments the SYNC token of all these calendars.Therefore, when a participant B tries to join an event, but has not synchronized the information that participant A joined the event in the meantime, there's a conflict and participant B join information is LOST.
Conflict solution:
RFC 6638 defines a way to avoid such conflicts by using a
schedule-tag
. This is only in Sabre/DAV roadmap for v3.3. I've developed experimental support for sabre/dav here but still, all Android clients I've tested don't support this RFC, only iOS does! Anyway, even withschedule-tag
, if the organizer changes the event data or when using shared calendars, some participant join information will be lost.So I've made my own sabre/dav implementation to mostly never loose participant join information (except when the event is reschedule): sabre/dav partstat-only-calendar. Basically, it works by into account the conflicting EVENT sent by the user and records only the participant PARSTAT info in the server event, instead of normally pushing a PreconditionFailed exception. I still need to publish an exemple of server run script that leverage all the functionalities.