From f7e7df62a28541b0d3bcecf77ffc2819e006924f Mon Sep 17 00:00:00 2001 From: Thomas Bruederli Date: Tue, 17 Feb 2015 15:49:14 +0100 Subject: [PATCH] Apply date offset from exceptions to recurring occurrences (#4386) --- .../calendar/drivers/kolab/kolab_calendar.php | 4 ++-- .../calendar/drivers/kolab/kolab_driver.php | 23 +++++++++++++++---- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/plugins/calendar/drivers/kolab/kolab_calendar.php b/plugins/calendar/drivers/kolab/kolab_calendar.php index 43165421..a392a9f8 100644 --- a/plugins/calendar/drivers/kolab/kolab_calendar.php +++ b/plugins/calendar/drivers/kolab/kolab_calendar.php @@ -297,7 +297,7 @@ class kolab_calendar extends kolab_storage_folder_api $exdate = $exception['recurrence_date'] ? $exception['recurrence_date']->format('Ymd') : substr($exception['_instance'], 0, 8); if ($exdate == $event_date) { $event['_instance'] = $exception['_instance']; - kolab_driver::merge_event_data($event, $exception); + kolab_driver::merge_exception_data($event, $exception); } } } @@ -641,7 +641,7 @@ class kolab_calendar extends kolab_storage_folder_api $rec_event['_instance'] = $instance_id; if ($overlay_data || $exdata[$datestr]) // copy data from exception - kolab_driver::merge_event_data($rec_event, $exdata[$datestr] ?: $overlay_data); + kolab_driver::merge_exception_data($rec_event, $exdata[$datestr] ?: $overlay_data); $rec_event['id'] = $rec_id; $rec_event['recurrence_id'] = $event['uid']; diff --git a/plugins/calendar/drivers/kolab/kolab_driver.php b/plugins/calendar/drivers/kolab/kolab_driver.php index 0a9790c9..ff02fbb4 100644 --- a/plugins/calendar/drivers/kolab/kolab_driver.php +++ b/plugins/calendar/drivers/kolab/kolab_driver.php @@ -928,6 +928,10 @@ class kolab_driver extends calendar_driver if ($old['recurrence'] || $old['recurrence_id']) { $master = $old['recurrence_id'] ? $fromcalendar->get_event($old['recurrence_id']) : $old; $savemode = $event['_savemode'] ?: ($old['recurrence_id'] ? 'current' : 'all'); + + // this-and-future on the first instance equals to 'all' + if (!$old['recurrence_id'] && $savemode == 'future') + $savemode = 'all'; } // check if update affects scheduling and update attendee status accordingly @@ -1135,7 +1139,7 @@ class kolab_driver extends calendar_driver // merge the new event properties onto future exceptions if ($savemode == 'future' && $exception['_instance'] >= $old['_instance']) { unset($event['thisandfuture']); - self::merge_event_data($master['recurrence']['EXCEPTIONS'][$i], $event); + self::merge_exception_data($master['recurrence']['EXCEPTIONS'][$i], $event); } } /* @@ -1171,19 +1175,28 @@ class kolab_driver extends calendar_driver * @param array The event object to be altered * @param array The overlay event object to be merged over $event */ - public static function merge_event_data(&$event, $overlay) + public static function merge_exception_data(&$event, $overlay) { static $forbidden = array('id','uid','recurrence','recurrence_date','thisandfuture','organizer','_attachments'); + // compute date offset from the exception + if ($overlay['start'] instanceof DateTime && $overlay['recurrence_date'] instanceof DateTime) { + $date_offset = $overlay['recurrence_date']->diff($overlay['start']); + } + foreach ($overlay as $prop => $value) { - // adjust time of the recurring event instance if ($prop == 'start' || $prop == 'end') { - if (is_object($event[$prop]) && is_a($event[$prop], 'DateTime')) { - $event[$prop]->setTime($value->format('G'), intval($value->format('i')), intval($value->format('s'))); + if (is_object($event[$prop]) && $event[$prop] instanceof DateTime) { // set date value if overlay is an exception of the current instance if (substr($overlay['_instance'], 0, 8) == substr($event['_instance'], 0, 8)) { $event[$prop]->setDate(intval($value->format('Y')), intval($value->format('n')), intval($value->format('j'))); } + // apply date offset + else if ($date_offset) { + $event[$prop]->add($date_offset); + } + // adjust time of the recurring event instance + $event[$prop]->setTime($value->format('G'), intval($value->format('i')), intval($value->format('s'))); } } else if ($prop == 'thisandfuture' && $overlay['_instance'] == $event['_instance']) {