+ CalDAV workflows for Kronolith ++ Create/Update
(davPutContents)- rpc determines this is a dav request - delegates to RPC dav backend - Feeds into Sabre\Dav\Server - SabreDAV stores the event to its calendar backend - horde/dav Calendar backend internally finds out the caldav name of the calendar is served by kronolith - Kronolith_Application::davPutObject is called. - Resolve external calendar name to kronolith-internal calendar name - Perform some access checks - Parse icalendar data string into a Horde_Icalendar object - Setup the Horde_Icalendar_Handler_Dav with the calendar backend and the icalendar Kronolith_Icalendar_Dav (inherits Kronolith_Icalendar_Base) - Get all components of the calendar - ignore everything which is not a VEVENT - try to load an existing kronolith event - check if existing event last modified is newer / abort - keep a list of exception events from the VEVENT for later - Create a list of organizer and attendee(s) who signal by attribute that it's not the server's job to send them itip mails - Create the new kronolith_Event base event object from the icalendar vevent - Delete all kronolith_events which are exceptions on the base event from the backend run the post-save actions for the base event - check for missing mapping between external and internal event id, add if missing - handle decision-making on itip: Is the change relevant for itip (prevent spam). Who should get an itip? which type of itip to send out? back in the main process - create an kronolith_event for each previously listed vevent exceptions and save it ++ TODOs/Refactoring TODO: Factor out the iTip handling into a separate service which just takes previous and current event and possibly some intent control TODO: Make this flow unit testable (How?) TODO: Make the iTip flow reusable for web UI and inter-app API cases.