diff --git a/lib/kolab_sync_data_calendar.php b/lib/kolab_sync_data_calendar.php --- a/lib/kolab_sync_data_calendar.php +++ b/lib/kolab_sync_data_calendar.php @@ -803,21 +803,60 @@ throw new Syncroton_Exception_Status_MeetingResponse(Syncroton_Exception_Status_MeetingResponse::INVALID_REQUEST); } - if ($event['free_busy']) { - $old['free_busy'] = $event['free_busy']; + // A single recurring event occurrence + if (!empty($event['recurrence_date'])) { + $event['recurrence'] = []; + + if ($status) { + $this->update_attendee_status($event, $status); + $status = null; + } + + if (!isset($old['exceptions'])) { + if (isset($old['recurrence']['EXCEPTIONS'])) { + $old['exceptions'] = &$old['recurrence']['EXCEPTIONS']; + } + else { + $old['exceptions'] = []; + } + } + + $existing = false; + foreach ($old['exceptions'] as $i => $exception) { + if (libcalendaring::is_recurrence_exception($event, $exception)) { + $old['exceptions'][$i] = $event; + $existing = true; + } + } + + if (!$existing) { + $old['exceptions'][] = $event; + } + } + // A main event update + else if (isset($event['sequence']) && $event['sequence'] > $old['sequence']) { + // FIXME: Can we be smarter here? Should we update everything? What about e.g. new attendees? + // And do we need to check the sequence? + $props = ['start', 'end', 'title', 'description', 'location', 'free_busy']; + + foreach ($props as $prop) { + if (isset($event[$prop])) { + $old[$prop] = $event[$prop]; + } + } + + // Copy new custom properties + if (!empty($event['x-custom'])) { + foreach ($event['x-custom'] as $key => $val) { + $old['x-custom'][$key] = $val; + } + } } // Updating an existing event is most-likely a response // to an iTip request with bumped SEQUENCE $old['sequence'] += 1; - // Copy new custom properties - if (!empty($event['x-custom'])) { - foreach ($event['x-custom'] as $key => $val) { - $old['x-custom'][$key] = $val; - } - } - // Update the event return $this->save_event($old, $status); }