summaryrefslogtreecommitdiff
path: root/plugins/libkolab
diff options
context:
space:
mode:
authorThomas Bruederli <bruederli@kolabsys.com>2015-02-12 09:08:22 (GMT)
committerThomas Bruederli <bruederli@kolabsys.com>2015-02-12 09:08:22 (GMT)
commitad55fc706d3f5813f6a0f4b0f93b8970046b4d6d (patch)
tree7e63054ab188d83c44f2c5b3e75a1c5f4df80933 /plugins/libkolab
parent49280a6f62f487b5099a8e7a21271de83f6772ca (diff)
downloadroundcubemail-plugins-kolab-ad55fc706d3f5813f6a0f4b0f93b8970046b4d6d.tar.gz
Fix handling of Recurrence-ID properties for recurrence exceptions to comply with RFC 5545 (#4385)
Diffstat (limited to 'plugins/libkolab')
-rw-r--r--plugins/libkolab/lib/kolab_format_event.php65
1 files changed, 47 insertions, 18 deletions
diff --git a/plugins/libkolab/lib/kolab_format_event.php b/plugins/libkolab/lib/kolab_format_event.php
index 8cad89a..03b5dde 100644
--- a/plugins/libkolab/lib/kolab_format_event.php
+++ b/plugins/libkolab/lib/kolab_format_event.php
@@ -94,13 +94,26 @@ class kolab_format_event extends kolab_format_xcal
$this->obj->setStatus($status);
// save recurrence exceptions
- if (is_array($object['recurrence']) && $object['recurrence']['EXCEPTIONS']) {
+ if (is_array($object['recurrence']) && is_array($object['recurrence']['EXCEPTIONS'])) {
+ $recurrence_id_format = $object['allday'] ? 'Ymd' : 'Ymd\THis';
$vexceptions = new vectorevent;
foreach((array)$object['recurrence']['EXCEPTIONS'] as $i => $exception) {
$exevent = new kolab_format_event;
$exevent->set(($compacted = $this->compact_exception($exception, $object))); // only save differing values
- $exevent->obj->setRecurrenceID(self::get_datetime($exception['start'], null, true), (bool)$exception['thisandfuture']);
+
+ // get value for recurrence-id
+ if (!empty($exception['recurrence_date']) && is_a($exception['recurrence_date'], 'DateTime')) {
+ $recurrence_id = $exception['recurrence_date'];
+ $compacted['_instance'] = $recurrence_id->format($recurrence_id_format);
+ }
+ else if (!empty($exception['_instance']) && strlen($exception['_instance']) > 4) {
+ $recurrence_id = rcube_utils::anytodatetime($exception['_instance'], $object['start']->getTimezone());
+ $compacted['recurrence_date'] = $recurrence_id;
+ }
+ $exevent->obj->setRecurrenceID(self::get_datetime($recurrence_id ?: $exception['start'], null, $object['allday']), (bool)$exception['thisandfuture']);
+
$vexceptions->push($exevent->obj);
+
// write cleaned-up exception data back to memory/cache
$object['recurrence']['EXCEPTIONS'][$i] = $this->expand_exception($compacted, $object);
}
@@ -172,15 +185,27 @@ class kolab_format_event extends kolab_format_xcal
// this is an exception object
if ($this->obj->recurrenceID()->isValid()) {
$object['thisandfuture'] = $this->obj->thisAndFuture();
+ $object['recurrence_date'] = self::php_datetime($this->obj->recurrenceID());
}
// read exception event objects
else if (($exceptions = $this->obj->exceptions()) && is_object($exceptions) && $exceptions->size()) {
$recurrence_exceptions = array();
+ $recurrence_id_format = $object['allday'] ? 'Ymd' : 'Ymd\THis';
for ($i=0; $i < $exceptions->size(); $i++) {
if (($exobj = $exceptions->get($i))) {
$exception = new kolab_format_event($exobj);
if ($exception->is_valid()) {
- $recurrence_exceptions[] = $this->expand_exception($exception->to_array(), $object);
+ $exdata = $exception->to_array();
+
+ // fix date-only recurrence ID saved by old versions
+ if ($exdata['recurrence_date'] && $exdata['recurrence_date']->_dateonly && !$object['allday']) {
+ $exdata['recurrence_date']->setTimezone($object['start']->getTimezone());
+ $exdata['recurrence_date']->setTime($object['start']->format('G'), intval($object['start']->format('i')), intval($object['start']->format('s')));
+ }
+
+ $recurrence_id = $exdata['recurrence_date'] ?: $exdata['start'];
+ $exdata['_instance'] = $recurrence_id->format($recurrence_id_format);
+ $recurrence_exceptions[] = $this->expand_exception($exdata, $object);
}
}
}
@@ -211,21 +236,21 @@ class kolab_format_event extends kolab_format_xcal
*/
private function compact_exception($exception, $master)
{
- $forbidden = array('recurrence','organizer','attendees','sequence');
+ $forbidden = array('recurrence','organizer','_attachments');
- foreach ($forbidden as $prop) {
- if (array_key_exists($prop, $exception)) {
- unset($exception[$prop]);
+ foreach ($forbidden as $prop) {
+ if (array_key_exists($prop, $exception)) {
+ unset($exception[$prop]);
+ }
}
- }
- foreach ($master as $prop => $value) {
- if (isset($exception[$prop]) && gettype($exception[$prop]) == gettype($value) && $exception[$prop] == $value) {
- unset($exception[$prop]);
+ foreach ($master as $prop => $value) {
+ if (isset($exception[$prop]) && gettype($exception[$prop]) == gettype($value) && $exception[$prop] == $value) {
+ unset($exception[$prop]);
+ }
}
- }
- return $exception;
+ return $exception;
}
/**
@@ -233,12 +258,16 @@ class kolab_format_event extends kolab_format_xcal
*/
private function expand_exception($exception, $master)
{
- foreach ($master as $prop => $value) {
- if (empty($exception[$prop]) && !empty($value))
- $exception[$prop] = $value;
- }
+ foreach ($master as $prop => $value) {
+ if (empty($exception[$prop]) && !empty($value)) {
+ $exception[$prop] = $value;
+ if ($prop == 'recurrence') {
+ unset($exception[$prop]['EXCEPTIONS']);
+ }
+ }
+ }
- return $exception;
+ return $exception;
}
}