summaryrefslogtreecommitdiff
path: root/plugins/libkolab
diff options
context:
space:
mode:
authorThomas Bruederli <bruederli@kolabsys.com>2015-02-26 10:25:29 (GMT)
committerThomas Bruederli <bruederli@kolabsys.com>2015-02-26 14:05:55 (GMT)
commit31ad93a62e93cf12fbe7dcc885e077026d7655f4 (patch)
treea74ae36896ed5d8d257197f1956a42f694a4d2fd /plugins/libkolab
parent1c590d3969f95eec73ea9c30207780e8f0b46a1c (diff)
downloadroundcubemail-plugins-kolab-31ad93a62e93cf12fbe7dcc885e077026d7655f4.tar.gz
Provide access to exception instances outside of a recurring event context (#4722)
Diffstat (limited to 'plugins/libkolab')
-rw-r--r--plugins/libkolab/lib/kolab_format_event.php69
-rw-r--r--plugins/libkolab/lib/kolab_format_xcal.php8
-rw-r--r--plugins/libkolab/lib/kolab_storage_cache_event.php18
3 files changed, 83 insertions, 12 deletions
diff --git a/plugins/libkolab/lib/kolab_format_event.php b/plugins/libkolab/lib/kolab_format_event.php
index 91efb26..3207927 100644
--- a/plugins/libkolab/lib/kolab_format_event.php
+++ b/plugins/libkolab/lib/kolab_format_event.php
@@ -96,11 +96,15 @@ class kolab_format_event extends kolab_format_xcal
$status = $this->status_map[$object['status']];
$this->obj->setStatus($status);
- // save recurrence exceptions
- if (is_array($object['recurrence']) && is_array($object['recurrence']['EXCEPTIONS'])) {
+ // save (recurrence) exceptions
+ if (is_array($object['recurrence']) && is_array($object['recurrence']['EXCEPTIONS']) && !isset($object['exceptions'])) {
+ $object['exceptions'] = $object['recurrence']['EXCEPTIONS'];
+ }
+
+ if (is_array($object['exceptions'])) {
$recurrence_id_format = $object['allday'] ? 'Ymd' : 'Ymd\THis';
$vexceptions = new vectorevent;
- foreach((array)$object['recurrence']['EXCEPTIONS'] as $i => $exception) {
+ foreach ($object['exceptions'] as $i => $exception) {
$exevent = new kolab_format_event;
$exevent->set(($compacted = $this->compact_exception($exception, $object))); // only save differing values
@@ -118,11 +122,17 @@ class kolab_format_event extends kolab_format_xcal
$vexceptions->push($exevent->obj);
// write cleaned-up exception data back to memory/cache
- $object['recurrence']['EXCEPTIONS'][$i] = $this->expand_exception($exevent->data, $object);
+ $object['exceptions'][$i] = $this->expand_exception($exevent->data, $object);
}
$this->obj->setExceptions($vexceptions);
+
+ // link with recurrence.EXCEPTIONS for compatibility
+ if (is_array($object['recurrence'])) {
+ $object['recurrence']['EXCEPTIONS'] = &$object['exceptions'];
+ }
}
- else if ($object['recurrence_date'] && $object['recurrence_date'] instanceof DateTime) {
+
+ if ($object['recurrence_date'] && $object['recurrence_date'] instanceof DateTime) {
$this->obj->setRecurrenceID(self::get_datetime($object['recurrence_date'], null, $object['allday']), (bool)$object['thisandfuture']);
}
@@ -194,7 +204,7 @@ class kolab_format_event extends kolab_format_xcal
$object['recurrence_date'] = self::php_datetime($this->obj->recurrenceID());
}
// read exception event objects
- else if (($exceptions = $this->obj->exceptions()) && is_object($exceptions) && $exceptions->size()) {
+ 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++) {
@@ -215,13 +225,54 @@ class kolab_format_event extends kolab_format_xcal
}
}
}
- $object['recurrence']['EXCEPTIONS'] = $recurrence_exceptions;
+ $object['exceptions'] = $recurrence_exceptions;
+
+ // also link with recurrence.EXCEPTIONS for compatibility
+ if (is_array($object['recurrence'])) {
+ $object['recurrence']['EXCEPTIONS'] = &$object['exceptions'];
+ }
}
return $this->data = $object;
}
/**
+ * Getter for a single instance from a recurrence series or stored subcomponents
+ *
+ * @param mixed The recurrence-id of the requested instance, either as string or a DateTime object
+ * @return array Event data as hash array or null if not found
+ */
+ public function get_instance($recurrence_id)
+ {
+ $result = null;
+ $object = $this->to_array();
+
+ $recurrence_id_format = $object['allday'] ? 'Ymd' : 'Ymd\THis';
+ $instance_id = $recurrence_id instanceof DateTime ? $recurrence_id->format($recurrence_id_format) : strval($recurrence_id);
+
+ if ($object['recurrence_date'] instanceof DateTime) {
+ if ($object['recurrence_date']->format($recurrence_id_format) == $instance_id) {
+ $result = $object;
+ }
+ }
+
+ if (!$result && is_array($object['exceptions'])) {
+ foreach ($object['exceptions'] as $exception) {
+ if ($exception['_instance'] == $instance_id) {
+ $result = $exception;
+ $result['isexception'] = 1;
+ break;
+ }
+ }
+ }
+
+ // TODO: compute instances from recurrence rule and return the matching instance
+ // clone from plugins/calendar/drivers/kolab/kolab_calendar::get_recurring_events()
+
+ return $result;
+ }
+
+ /**
* Callback for kolab_storage_cache to get object specific tags to cache
*
* @return array List of tags to save in cache
@@ -262,8 +313,10 @@ class kolab_format_event extends kolab_format_xcal
*/
private function expand_exception($exception, $master)
{
+ $is_recurring = !empty($master['recurrence']);
+
foreach ($master as $prop => $value) {
- if (empty($exception[$prop]) && !empty($value)) {
+ if (empty($exception[$prop]) && !empty($value) && ($is_recurring || in_array($prop, array('uid','organizer','_attachments')))) {
$exception[$prop] = $value;
if ($prop == 'recurrence') {
unset($exception[$prop]['EXCEPTIONS']);
diff --git a/plugins/libkolab/lib/kolab_format_xcal.php b/plugins/libkolab/lib/kolab_format_xcal.php
index 3a9ad1f..605d557 100644
--- a/plugins/libkolab/lib/kolab_format_xcal.php
+++ b/plugins/libkolab/lib/kolab_format_xcal.php
@@ -597,8 +597,8 @@ abstract class kolab_format_xcal extends kolab_format
$words = rcube_utils::normalize_string($data, true);
// collect words from recurrence exceptions
- if (is_array($object['recurrence']) && $object['recurrence']['EXCEPTIONS']) {
- foreach((array)$object['recurrence']['EXCEPTIONS'] as $exception) {
+ if (is_array($object['exceptions'])) {
+ foreach ($object['exceptions'] as $exception) {
$words = array_merge($words, $this->get_words($exception));
}
}
@@ -629,8 +629,8 @@ abstract class kolab_format_xcal extends kolab_format
}
// collect tags from recurrence exceptions
- if (is_array($object['recurrence']) && $object['recurrence']['EXCEPTIONS']) {
- foreach((array)$object['recurrence']['EXCEPTIONS'] as $exception) {
+ if (is_array($object['exceptions'])) {
+ foreach ($object['exceptions'] as $exception) {
$tags = array_merge($tags, $this->get_tags($exception));
}
}
diff --git a/plugins/libkolab/lib/kolab_storage_cache_event.php b/plugins/libkolab/lib/kolab_storage_cache_event.php
index 5fc44cd..e25bd89 100644
--- a/plugins/libkolab/lib/kolab_storage_cache_event.php
+++ b/plugins/libkolab/lib/kolab_storage_cache_event.php
@@ -44,6 +44,24 @@ class kolab_storage_cache_event extends kolab_storage_cache
$sql_data['dtend'] = $dtend->format(self::DB_DATE_FORMAT);
}
+ // extend start/end dates to spawn all exceptions
+ if (is_array($object['exceptions'])) {
+ foreach ($object['exceptions'] as $exception) {
+ if (is_a($exception['start'], 'DateTime')) {
+ $exstart = $exception['start']->format(self::DB_DATE_FORMAT);
+ if ($exstart < $sql_data['dtstart']) {
+ $sql_data['dtstart'] = $exstart;
+ }
+ }
+ if (is_a($exception['end'], 'DateTime')) {
+ $exend = $exception['end']->format(self::DB_DATE_FORMAT);
+ if ($exend > $sql_data['dtend']) {
+ $sql_data['dtend'] = $exend;
+ }
+ }
+ }
+ }
+
return $sql_data;
}
} \ No newline at end of file