* CalDAV/Calendar: fix for first recurence being an exception cause it to be deleted by mac calendar

due to wrong start of series not taking execption into account
also fix missing timezone in EXDATE did not match recurrence
This commit is contained in:
Ralf Becker 2020-01-10 11:13:18 +01:00
parent 6113706921
commit 0f64b4c740
2 changed files with 16 additions and 7 deletions

View File

@ -688,7 +688,9 @@ class calendar_groupdav extends Api\CalDAV\Handler
if (isset($expand['start'])) $expand['start'] = $this->vCalendar->_parseDateTime($expand['start']);
if (isset($expand['end'])) $expand['end'] = $this->vCalendar->_parseDateTime($expand['end']);
}
$events =& self::get_series($event['uid'], $this->bo, $expand, $user);
// pass in original event as master, as it has correct start-date even if first recurrence is an exception
$events =& self::get_series($event['uid'], $this->bo, $expand, $user, $event);
// as alarm is now only on next recurrence, set alarm from original event on master
if ($event['alarm']) $events[0]['alarm'] = $event['alarm'];
}
@ -708,9 +710,10 @@ class calendar_groupdav extends Api\CalDAV\Handler
* @param calendar_bo $bo =null calendar_bo object to reuse for search call
* @param boolean|array $expand =false true or array with values for 'start', 'end' to expand recurrences
* @param int $user =null account_id of calendar to display, to remove master, if current user does not participate in
* @param array $master =null use provided event as master to fix wrong start-date if first recurrence is an exception
* @return array
*/
private static function &get_series($uid,calendar_bo $bo=null, $expand=false, $user=null)
private static function &get_series($uid,calendar_bo $bo=null, $expand=false, $user=null, $master=null)
{
if (is_null($bo)) $bo = new calendar_bopdate();
@ -729,13 +732,12 @@ class calendar_groupdav extends Api\CalDAV\Handler
}
// find master, which is not always first event, eg. when first event is an exception
$master = null;
$exceptions = array();
foreach($events as $k => &$recurrence)
{
if ($recurrence['recur_type'])
{
$master = $recurrence;
if (!isset($master)) $master = $recurrence;
$exceptions =& $master['recur_exception'];
unset($events[$k]);
break;

View File

@ -672,9 +672,10 @@ class calendar_ical extends calendar_boupdate
{
foreach ($event['recur_exception'] as $key => $timestamp)
{
// current Horde_Icalendar 2.1.4 exports EXDATE always in UTC, so we should not set a timezone here
// current Horde_Icalendar 2.1.4 exports EXDATE always postfixed with a Z :(
// so if we set a timezone here, we have to remove the Z, see the hack at the end of this method
// Apple calendar on OS X 10.11.4 uses a timezone, so does Horde eg. for Recurrence-ID
$event['recur_exception'][$key] = self::getDateTime($timestamp,$tzid);//,$parameters['EXDATE']);
$event['recur_exception'][$key] = self::getDateTime($timestamp, $tzid, $parameters['EXDATE']);
}
}
else
@ -1073,7 +1074,13 @@ class calendar_ical extends calendar_boupdate
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__ .
"()\n".array2string($retval)."\n",3,$this->logfile);
}
return $retval;
// hack to fix iCalendar exporting EXDATE always postfixed with a Z
// EXDATE can have multiple values and therefore be folded into multiple lines
return preg_replace_callback("/\nEXDATE;TZID=[^:]+:[0-9TZ \n,]+/", function($matches)
{
return preg_replace('/([0-9 ])Z/', '$1', $matches[0]);
}, $retval);
}
/**