T1841: Support non-all-day exceptions to all-day events and vice-versa

This commit is contained in:
Aleksander Machniak 2016-12-30 05:33:02 -05:00
parent 1ae83ad853
commit c4f4f52aa0
6 changed files with 24 additions and 17 deletions

View file

@ -391,7 +391,7 @@ class database_driver extends calendar_driver
if ($event['id'] == $master['id']) {
$event += $old;
$event['recurrence_id'] = $master['id'];
$event['_instance'] = libcalendaring::recurrence_instance_identifier($old);
$event['_instance'] = libcalendaring::recurrence_instance_identifier($old, $master['allday']);
$event['isexception'] = 1;
$event_id = $this->_insert_event($event);
return $event_id;

View file

@ -207,7 +207,7 @@ class kolab_calendar extends kolab_storage_folder_api
if ($master) {
// check for match in top-level exceptions (aka loose single occurrences)
if ($master['_formatobj'] && ($instance = $master['_formatobj']->get_instance($instance_id))) {
$this->events[$id] = $this->_to_driver_event($instance);
$this->events[$id] = $this->_to_driver_event($instance, false, true, $master);
}
// check for match on the first instance already
else if ($master['_instance'] && $master['_instance'] == $instance_id) {
@ -354,7 +354,7 @@ class kolab_calendar extends kolab_storage_folder_api
// add top-level exceptions (aka loose single occurrences)
else if (is_array($record['exceptions'])) {
foreach ($record['exceptions'] as $ex) {
$component = $this->_to_driver_event($ex, false, false);
$component = $this->_to_driver_event($ex, false, false, $record);
if ($component['start'] <= $end && $component['end'] >= $start) {
$events[] = $component;
}
@ -629,9 +629,9 @@ class kolab_calendar extends kolab_storage_folder_api
if (is_array($event['recurrence']['EXCEPTIONS'])) {
foreach ($event['recurrence']['EXCEPTIONS'] as $exception) {
if (!$exception['_instance'])
$exception['_instance'] = libcalendaring::recurrence_instance_identifier($exception);
$exception['_instance'] = libcalendaring::recurrence_instance_identifier($exception, $event['allday']);
$rec_event = $this->_to_driver_event($exception, false, false);
$rec_event = $this->_to_driver_event($exception, false, false, $event);
$rec_event['id'] = $event['uid'] . '-' . $exception['_instance'];
$rec_event['isexception'] = 1;
@ -692,7 +692,7 @@ class kolab_calendar extends kolab_storage_folder_api
// add to output if in range
if (($event_start <= $end && $event_end >= $start) || ($event_id && $rec_id == $event_id)) {
$rec_event = $this->_to_driver_event($next_event, false, false);
$rec_event = $this->_to_driver_event($next_event, false, false, $event);
$rec_event['_instance'] = $instance_id;
$rec_event['_count'] = $i + 1;
@ -724,7 +724,7 @@ class kolab_calendar extends kolab_storage_folder_api
/**
* Convert from Kolab_Format to internal representation
*/
private function _to_driver_event($record, $noinst = false, $links = true)
private function _to_driver_event($record, $noinst = false, $links = true, $master_event = null)
{
$record['calendar'] = $this->id;
@ -738,7 +738,7 @@ class kolab_calendar extends kolab_storage_folder_api
}
// add instance identifier to first occurrence (master event)
$recurrence_id_format = libcalendaring::recurrence_id_format($record);
$recurrence_id_format = libcalendaring::recurrence_id_format($master_event ? $master_event : $record);
if (!$noinst && $record['recurrence'] && !$record['recurrence_id'] && !$record['_instance']) {
$record['_instance'] = $record['start']->format($recurrence_id_format);
}

View file

@ -1361,7 +1361,7 @@ class kolab_driver extends calendar_driver
}
if (!$event['_instance'] && is_a($event['recurrence_date'], 'DateTime')) {
$event['_instance'] = libcalendaring::recurrence_instance_identifier($event);
$event['_instance'] = libcalendaring::recurrence_instance_identifier($event, $master['allday']);
}
if (!is_array($master['exceptions']) && is_array($master['recurrence']['EXCEPTIONS'])) {

View file

@ -75,7 +75,7 @@ class calendar_recurrence extends libcalendaring_recurrence
}
$next['recurrence_date'] = clone $next_start;
$next['_instance'] = libcalendaring::recurrence_instance_identifier($next);
$next['_instance'] = libcalendaring::recurrence_instance_identifier($next, $this->event['allday']);
unset($next['_formatobj']);

View file

@ -1492,18 +1492,23 @@ class libcalendaring extends rcube_plugin
* Return the identifer for the given instance of a recurring event
*
* @param array Hash array with event properties
* @param bool All-day flag from the main event
*
* @return mixed Format string or null if identifier cannot be generated
*/
public static function recurrence_instance_identifier($event)
public static function recurrence_instance_identifier($event, $allday = null)
{
$instance_date = $event['recurrence_date'] ?: $event['start'];
if ($instance_date && is_a($instance_date, 'DateTime')) {
$recurrence_id_format = $event['allday'] ? 'Ymd' : 'Ymd\THis';
return $instance_date->format($recurrence_id_format);
}
// According to RFC5545 (3.8.4.4) RECURRENCE-ID format should
// be date/date-time depending on the main event type, not the exception
if ($allday === null) {
$allday = $event['allday'];
}
return null;
return $instance_date->format($allday ? 'Ymd' : 'Ymd\THis');
}
}

View file

@ -291,7 +291,9 @@ class kolab_format_event extends kolab_format_xcal
}
// preserve this property for date serialization
$exception['allday'] = $master['allday'];
if (!isset($exception['allday'])) {
$exception['allday'] = $master['allday'];
}
return $exception;
}
@ -304,7 +306,7 @@ class kolab_format_event extends kolab_format_xcal
// Note: If an exception has no attendees it means there's "no attendees
// for this occurrence", not "attendees are the same as in the event" (#5300)
$forbidden = array('exceptions', 'attendees');
$forbidden = array('exceptions', 'attendees', 'allday');
$is_recurring = !empty($master['recurrence']);
foreach ($master as $prop => $value) {