2 commits - plugins/calendar plugins/libcalendaring
Thomas Brüderli
bruederli at kolabsys.com
Fri Feb 27 18:14:01 CET 2015
plugins/calendar/calendar.php | 13 +
plugins/calendar/drivers/kolab/kolab_calendar.php | 79 +++++++----
plugins/calendar/drivers/kolab/kolab_driver.php | 147 +++++++++-------------
plugins/libcalendaring/libcalendaring.php | 17 ++
4 files changed, 141 insertions(+), 115 deletions(-)
New commits:
commit 16ad0e6215a0b6d72d254fc0680e0a7a777e7745
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Fri Feb 27 18:13:57 2015 +0100
Update parstat recursively on all recurrence exceptions
diff --git a/plugins/libcalendaring/libcalendaring.php b/plugins/libcalendaring/libcalendaring.php
index f215ce6..94ff7f2 100644
--- a/plugins/libcalendaring/libcalendaring.php
+++ b/plugins/libcalendaring/libcalendaring.php
@@ -401,17 +401,28 @@ class libcalendaring extends rcube_plugin
* @param string The PARTSTAT value to set
* @return mixed Email address of the updated attendee or False if none matching found
*/
- public function set_partstat(&$event, $status)
+ public function set_partstat(&$event, $status, $recursive = true)
{
+ $success = false;
$emails = $this->get_user_emails();
foreach ((array)$event['attendees'] as $i => $attendee) {
if ($attendee['email'] && in_array(strtolower($attendee['email']), $emails)) {
$event['attendees'][$i]['status'] = strtoupper($status);
- return $attendee['email'];
+ $success = $attendee['email'];
}
}
- return false;
+ // apply partstat update to each existing exception
+ if ($event['recurrence'] && is_array($event['recurrence']['EXCEPTIONS'])) {
+ foreach ($event['recurrence']['EXCEPTIONS'] as $i => $exception) {
+ $this->set_partstat($event['recurrence']['EXCEPTIONS'][$i], $status, false);
+ }
+
+ // set link to top-level exceptions
+ $event['exceptions'] = &$event['recurrence']['EXCEPTIONS'];
+ }
+
+ return $success;
}
commit 94260b2aebe81645761260f4f5d221bff0e96cf0
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Fri Feb 27 17:52:17 2015 +0100
Refactor identification of recurring event instances (#4722):
- All instances of a recurring series have -YmdTHis appended to their ID
- In 'all' savemode, the master event identified by UID is loaded and updated
- kolab_driver::update_event() returns the UID of the master event in 'all' mode.
This is then used to send iTip messages for the entire series
diff --git a/plugins/calendar/calendar.php b/plugins/calendar/calendar.php
index 5d32188..6cf29db 100644
--- a/plugins/calendar/calendar.php
+++ b/plugins/calendar/calendar.php
@@ -1175,9 +1175,13 @@ class calendar extends rcube_plugin
$event['attendees'] = $master['attendees']; // this tricks us into the next if clause
}
+ // delete old reference if saved as new
+ if ($event['_savemode'] == 'future' || $event['_savemode'] == 'new') {
+ $old = null;
+ }
+
$event['id'] = $success;
$event['_savemode'] = 'all';
- $old = null;
}
// send out notifications
@@ -1566,6 +1570,9 @@ class calendar extends rcube_plugin
$filename = asciiwords(html_entity_decode($filename)); // to 7bit ascii
if (!empty($event_id)) {
if ($event = $this->driver->get_event(array('calendar' => $calid, 'id' => $event_id))) {
+ if ($event['recurrence_id']) {
+ $event = $this->driver->get_event(array('calendar' => $calid, 'id' => $event['recurrence_id']));
+ }
$events = array($event);
$filename = asciiwords($event['title']);
if (empty($filename))
@@ -2276,9 +2283,9 @@ class calendar extends rcube_plugin
public static function event_diff($a, $b)
{
$diff = array();
- $ignore = array('changed' => 1, 'attachments' => 1, '_notify' => 1, '_owner' => 1, '_savemode' => 1);
+ $ignore = array('changed' => 1, 'attachments' => 1);
foreach (array_unique(array_merge(array_keys($a), array_keys($b))) as $key) {
- if (!$ignore[$key] && $a[$key] != $b[$key])
+ if (!$ignore[$key] && $key[0] != '_' && $a[$key] != $b[$key])
$diff[] = $key;
}
diff --git a/plugins/calendar/drivers/kolab/kolab_calendar.php b/plugins/calendar/drivers/kolab/kolab_calendar.php
index 79450af..10c256a 100644
--- a/plugins/calendar/drivers/kolab/kolab_calendar.php
+++ b/plugins/calendar/drivers/kolab/kolab_calendar.php
@@ -187,7 +187,7 @@ class kolab_calendar extends kolab_storage_folder_api
{
// directly access storage object
if (!$this->events[$id] && ($record = $this->storage->get_object($id)))
- $this->events[$id] = $this->_to_rcube_event($record);
+ $this->events[$id] = $this->_to_driver_event($record, true);
// event not found, maybe a recurring instance is requested
if (!$this->events[$id]) {
@@ -195,17 +195,16 @@ class kolab_calendar extends kolab_storage_folder_api
$instance_id = substr($id, strlen($master_id) + 1);
if ($master_id != $id && ($record = $this->storage->get_object($master_id))) {
- $master = $this->events[$master_id] = $this->_to_rcube_event($record);
+ $master = $this->_to_driver_event($record);
}
// check for match on the first instance already
if ($master['_instance'] && $master['_instance'] == $instance_id) {
- $this->events[$id] = $this->events[$master_id];
+ $this->events[$id] = $master;
}
// check for match in top-level exceptions (aka loose single occurrences)
else if ($master && $master['_formatobj'] && ($instance = $master['_formatobj']->get_instance($instance_id))) {
- $instance = $this->_to_rcube_event($instance);
- $this->events[$instance['id']] = $instance;
+ $this->events[$id] = $this->_to_driver_event($instance);
}
else if ($master && is_array($master['recurrence'])) {
$this->get_recurring_events($record, $master['start'], null, $id);
@@ -294,12 +293,13 @@ class kolab_calendar extends kolab_storage_folder_api
$events = array();
foreach ($this->storage->select($query) as $record) {
- $event = $this->_to_rcube_event($record);
- $this->events[$event['id']] = $event;
+ $event = $this->_to_driver_event($record, !$virtual);
// remember seen categories
- if ($event['categories'])
- $this->categories[$event['categories']]++;
+ if ($event['categories']) {
+ $cat = is_array($event['categories']) ? $event['categories'][0] : $event['categories'];
+ $this->categories[$cat]++;
+ }
// list events in requested time window
if ($event['start'] <= $end && $event['end'] >= $start) {
@@ -321,11 +321,11 @@ class kolab_calendar extends kolab_storage_folder_api
// find and merge exception for the first instance
if ($virtual && !empty($event['recurrence']) && is_array($event['recurrence']['EXCEPTIONS'])) {
- $event_date = $event['start']->format('Ymd');
foreach ($event['recurrence']['EXCEPTIONS'] as $exception) {
- $exdate = $exception['recurrence_date'] ? $exception['recurrence_date']->format('Ymd') : substr($exception['_instance'], 0, 8);
- if ($exdate == $event_date) {
- $event['_instance'] = $exception['_instance'];
+ if ($event['_instance'] == $exception['_instance']) {
+ // clone date objects from main event before adjusting them with exception data
+ if (is_object($event['start'])) $event['start'] = clone $record['start'];
+ if (is_object($event['end'])) $event['end'] = clone $record['end'];
kolab_driver::merge_exception_data($event, $exception);
}
}
@@ -342,7 +342,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_rcube_event($ex);
+ $component = $this->_to_driver_event($ex);
if ($component['start'] <= $end && $component['end'] >= $start) {
$events[] = $component;
}
@@ -445,7 +445,7 @@ class kolab_calendar extends kolab_storage_folder_api
unset($event['links']);
//generate new event from RC input
- $object = $this->_from_rcube_event($event);
+ $object = $this->_from_driver_event($event);
$saved = $this->storage->save($object, 'event');
if (!$saved) {
@@ -460,8 +460,7 @@ class kolab_calendar extends kolab_storage_folder_api
// save links in configuration.relation object
$this->save_links($event['uid'], $links);
- $event['id'] = $event['uid'];
- $this->events = array($event['uid'] => $this->_to_rcube_event($object));
+ $this->events = array($event['uid'] => $this->_to_driver_event($object, true));
}
return $saved;
@@ -485,7 +484,7 @@ class kolab_calendar extends kolab_storage_folder_api
$links = $event['links'];
unset($event['links']);
- $object = $this->_from_rcube_event($event, $old);
+ $object = $this->_from_driver_event($event, $old);
$saved = $this->storage->save($object, 'event', $old['uid']);
if (!$saved) {
@@ -500,7 +499,7 @@ class kolab_calendar extends kolab_storage_folder_api
$this->save_links($event['uid'], $links);
$updated = true;
- $this->events = array($event['id'] => $this->_to_rcube_event($object));
+ $this->events = array($event['uid'] => $this->_to_driver_event($object, true));
// refresh local cache with recurring instances
if ($exception_id) {
@@ -626,7 +625,7 @@ class kolab_calendar extends kolab_storage_folder_api
else if (!$exception['_instance'] && is_a($exception['start'], 'DateTime'))
$exception['_instance'] = $exception['start']->format($recurrence_id_format);
- $rec_event = $this->_to_rcube_event($exception);
+ $rec_event = $this->_to_driver_event($exception);
$rec_event['id'] = $event['uid'] . '-' . $exception['_instance'];
$rec_event['isexception'] = 1;
@@ -675,7 +674,7 @@ class kolab_calendar extends kolab_storage_folder_api
// add to output if in range
$rec_id = $event['uid'] . '-' . $instance_id;
if (($next_event['start'] <= $end && $next_event['end'] >= $start) || ($event_id && $rec_id == $event_id)) {
- $rec_event = $this->_to_rcube_event($next_event);
+ $rec_event = $this->_to_driver_event($next_event);
$rec_event['_instance'] = $instance_id;
$rec_event['_count'] = $i + 1;
@@ -707,7 +706,7 @@ class kolab_calendar extends kolab_storage_folder_api
/**
* Convert from Kolab_Format to internal representation
*/
- private function _to_rcube_event($record)
+ private function _to_driver_event($record, $noinst = false)
{
$record['calendar'] = $this->id;
$record['links'] = $this->get_links($record['uid']);
@@ -717,17 +716,31 @@ class kolab_calendar extends kolab_storage_folder_api
$record = kolab_driver::add_partstat_class($record, array('NEEDS-ACTION','DECLINED'), $this->get_owner());
}
- return kolab_driver::to_rcube_event($record);
+ // add instance identifier to first occurrence (master event)
+ $recurrence_id_format = $record['allday'] ? 'Ymd' : 'Ymd\THis';
+ if (!$noinst && $record['recurrence'] && !$record['recurrence_id'] && !$record['_instance']) {
+ $record['_instance'] = $record['start']->format($recurrence_id_format);
+ }
+ else if (is_a($record['recurrence_date'], 'DateTime')) {
+ $record['_instance'] = $record['recurrence_date']->format($recurrence_id_format);
+ }
+
+ // clean up exception data
+ if ($record['recurrence'] && is_array($record['recurrence']['EXCEPTIONS'])) {
+ array_walk($record['recurrence']['EXCEPTIONS'], function(&$exception) {
+ unset($exception['_mailbox'], $exception['_msguid'], $exception['_formatobj'], $exception['_attachments']);
+ });
+ }
+
+ return $record;
}
/**
* Convert the given event record into a data structure that can be passed to Kolab_Storage backend for saving
- * (opposite of self::_to_rcube_event())
+ * (opposite of self::_to_driver_event())
*/
- private function _from_rcube_event($event, $old = array())
+ private function _from_driver_event($event, $old = array())
{
- $event = kolab_driver::from_rcube_event($event, $old);
-
// set current user as ORGANIZER
$identity = $this->cal->rc->user->list_emails(true);
if (empty($event['attendees']) && $identity['email'])
@@ -750,8 +763,18 @@ class kolab_calendar extends kolab_storage_folder_api
$event['comment'] = $old['comment'];
}
+ // clean up exception data
+ if (is_array($event['exceptions'])) {
+ array_walk($event['exceptions'], function(&$exception) {
+ unset($exception['_mailbox'], $exception['_msguid'], $exception['_formatobj'], $exception['_attachments'],
+ $event['attachments'], $event['deleted_attachments'], $event['recurrence_id']);
+ });
+ }
+
+
// remove some internal properties which should not be saved
- unset($event['_savemode'], $event['_fromcalendar'], $event['_identity'], $event['_folder_id'], $event['className']);
+ unset($event['_savemode'], $event['_fromcalendar'], $event['_identity'], $event['_folder_id'],
+ $event['recurrence_id'], $event['attachments'], $event['deleted_attachments'], $event['className']);
// copy meta data (starting with _) from old object
foreach ((array)$old as $key => $val) {
diff --git a/plugins/calendar/drivers/kolab/kolab_driver.php b/plugins/calendar/drivers/kolab/kolab_driver.php
index cfdcb4c..1bd8caf 100644
--- a/plugins/calendar/drivers/kolab/kolab_driver.php
+++ b/plugins/calendar/drivers/kolab/kolab_driver.php
@@ -549,9 +549,7 @@ class kolab_driver extends calendar_driver
if ($cal) {
if ($storage = $this->get_calendar($cal)) {
$result = $storage->get_event($id);
- if (is_array($result))
- self::clean_rcube_event_out($result);
- return $result;
+ return self::to_rcube_event($result);
}
// get event from the address books birthday calendar
else if ($cal == self::BIRTHDAY_CALENDAR_ID) {
@@ -562,8 +560,7 @@ class kolab_driver extends calendar_driver
else {
foreach ($this->filter_calendars($writeable, $active, $personal) as $calendar) {
if ($result = $calendar->get_event($id)) {
- self::clean_rcube_event_out($result);
- return $result;
+ return self::to_rcube_event($result);
}
}
}
@@ -581,10 +578,12 @@ class kolab_driver extends calendar_driver
if (!$this->validate($event))
return false;
+ $event = self::from_rcube_event($event);
+
$cid = $event['calendar'] ? $event['calendar'] : reset(array_keys($this->calendars));
if ($storage = $this->get_calendar($cid)) {
// if this is a recurrence instance, append as exception to an already existing object for this UID
- if (!empty($event['recurrence_date']) && ($master = $this->get_event($event['uid']))) {
+ if (!empty($event['recurrence_date']) && ($master = $storage->get_event($event['uid']))) {
self::add_exception($master, $event);
$success = $storage->update_event($master);
}
@@ -611,7 +610,10 @@ class kolab_driver extends calendar_driver
*/
public function edit_event($event)
{
- return $this->update_event($event);
+ if (!($storage = $this->get_calendar($event['calendar'])))
+ return false;
+
+ return $this->update_event(self::from_rcube_event($event, $storage->get_event($event['id'])));
}
/**
@@ -630,12 +632,16 @@ class kolab_driver extends calendar_driver
if ($storage = $this->get_calendar($event['calendar'])) {
$update_event = $storage->get_event($event['recurrence_id']);
$update_event['_savemode'] = $event['_savemode'];
+ $update_event['id'] = $update_event['uid'];
unset($update_event['recurrence_id']);
self::merge_attendee_data($update_event, $attendees);
}
}
if (($ret = $this->update_attendees($update_event, $attendees)) && $this->rc->config->get('kolab_invitation_calendars')) {
+ // replace with master event (for iTip reply)
+ $event = self::to_rcube_event($update_event);
+
// re-assign to the according (virtual) calendar
if (strtoupper($status) == 'DECLINED')
$event['calendar'] = self::INVITATIONS_CALENDAR_DECLINED;
@@ -668,7 +674,7 @@ class kolab_driver extends calendar_driver
$saved = false;
foreach ($master['recurrence']['EXCEPTIONS'] as $i => $exception) {
// merge the new event properties onto future exceptions
- if ($exception['_instance'] >= $event['_instance']) {
+ if ($exception['_instance'] >= strval($event['_instance'])) {
self::merge_attendee_data($master['recurrence']['EXCEPTIONS'][$i], $attendees);
}
// update a specific instance
@@ -741,7 +747,7 @@ class kolab_driver extends calendar_driver
{
$success = false;
$savemode = $event['_savemode'];
- $decline = $event['decline'];
+ $decline = $event['_decline'];
if (($storage = $this->get_calendar($event['calendar'])) && ($event = $storage->get_event($event['id']))) {
$event['_savemode'] = $savemode;
@@ -752,7 +758,7 @@ class kolab_driver extends calendar_driver
// read master if deleting a recurring event
if ($event['recurrence'] || $event['recurrence_id'] || $event['isexception']) {
- $master = $event['recurrence_id'] || $event['isexception'] ? $storage->get_event($event['uid']) : $event;
+ $master = $storage->get_event($event['uid']);
$savemode = $event['_savemode'] ?: ($event['_instance'] || $event['isexception'] ? 'current' : 'all');
// force 'current' mode for single occurrences stored as exception
@@ -768,7 +774,6 @@ class kolab_driver extends calendar_driver
// set event date back to the actual occurrence
if ($exception['recurrence_date'])
$event['start'] = $exception['recurrence_date'];
- break;
}
}
@@ -782,7 +787,8 @@ class kolab_driver extends calendar_driver
$_SESSION['calendar_restore_event_data'] = $master;
// removing the first instance => just move to next occurence
- if ($master['id'] == $event['id'] && $master['recurrence']) {
+ $recurrence_id_format = $master['allday'] ? 'Ymd' : 'Ymd\THis';
+ if ($master['recurrence'] && $event['_instance'] == $master['start']->format($recurrence_id_format)) {
$recurring = reset($storage->get_recurring_events($event, $event['start'], null, $event['id'].'-1'));
// no future instances found: delete the master event (bug #1677)
@@ -840,7 +846,7 @@ class kolab_driver extends calendar_driver
default: // 'all' is default
// removing the master event with loose exceptions (not recurring though)
- if (!empty($event['recurrence_date']) && !empty($master['exceptions'])) {
+ if (!empty($event['recurrence_date']) && empty($master['recurrence']) && !empty($master['exceptions'])) {
// make the first exception the new master
$newmaster = array_shift($master['exceptions']);
$newmaster['exceptions'] = $master['exceptions'];
@@ -906,9 +912,12 @@ class kolab_driver extends calendar_driver
if (!($fromcalendar = $this->get_calendar($event['_fromcalendar'])))
return false;
+ $old = $fromcalendar->get_event($event['id']);
+
if ($event['_savemode'] != 'new') {
- if (!$fromcalendar->storage->move($event['id'], $storage->storage))
+ if (!$fromcalendar->storage->move($old['uid'], $storage->storage)) {
return false;
+ }
$fromcalendar = $storage;
}
@@ -919,7 +928,7 @@ class kolab_driver extends calendar_driver
$success = false;
$savemode = 'all';
$attachments = array();
- $old = $master = $fromcalendar->get_event($event['id']);
+ $old = $master = $storage->get_event($event['id']);
if (!$old || !$old['start']) {
rcube::raise_error(array(
@@ -930,45 +939,14 @@ class kolab_driver extends calendar_driver
return false;
}
- // delete existing attachment(s)
- if (!empty($event['deleted_attachments'])) {
- foreach ($event['deleted_attachments'] as $attachment) {
- if (!empty($old['attachments'])) {
- foreach ($old['attachments'] as $idx => $att) {
- if ($att['id'] == $attachment) {
- $old['attachments'][$idx]['_deleted'] = true;
- }
- }
- }
- }
- unset($event['deleted_attachments']);
- }
-
- // handle attachments to add
- if (!empty($event['attachments'])) {
- foreach ($event['attachments'] as $attachment) {
- // skip entries without content (could be existing ones)
- if (!$attachment['data'] && !$attachment['path'])
- continue;
-
- $attachments[] = array(
- 'name' => $attachment['name'],
- 'mimetype' => $attachment['mimetype'],
- 'content' => $attachment['data'],
- 'path' => $attachment['path'],
- );
- }
- }
-
- $event['attachments'] = array_merge((array)$old['attachments'], $attachments);
-
// modify a recurring event, check submitted savemode to do the right things
if ($old['recurrence'] || $old['recurrence_id'] || $old['isexception']) {
- $master = $old['recurrence_id'] || $old['isexception'] ? $fromcalendar->get_event($old['uid']) : $old;
+ $master = $storage->get_event($old['uid']);
$savemode = $event['_savemode'] ?: ($old['recurrence_id'] || $old['isexception'] ? 'current' : 'all');
// this-and-future on the first instance equals to 'all'
- if (!$old['recurrence_id'] && $savemode == 'future')
+ $recurrence_id_format = $master['allday'] ? 'Ymd' : 'Ymd\THis';
+ if ($savemode == 'future' && $master['start'] && $old['_instance'] == $master['start']->format($recurrence_id_format))
$savemode = 'all';
// force 'current' mode for single occurrences stored as exception
else if (!$old['recurrence'] && !$old['recurrence_id'] && $old['isexception'])
@@ -1021,7 +999,7 @@ class kolab_driver extends calendar_driver
// remove recurrence exceptions on re-scheduling
if ($reschedule) {
- unset($event['recurrence']['EXCEPTIONS'], $master['recurrence']['EXDATE']);
+ unset($event['recurrence']['EXCEPTIONS'], $event['exceptions'], $master['recurrence']['EXDATE']);
}
else if (is_array($event['recurrence']['EXCEPTIONS'])) {
// only keep relevant exceptions
@@ -1033,6 +1011,8 @@ class kolab_driver extends calendar_driver
return $exdate > $event['start'];
});
}
+ // set link to top-level exceptions
+ $event['exceptions'] = &$event['recurrence']['EXCEPTIONS'];
}
// compute remaining occurrences
@@ -1060,6 +1040,8 @@ class kolab_driver extends calendar_driver
$master['recurrence']['EXCEPTIONS'] = array_filter($master['recurrence']['EXCEPTIONS'], function($exception) use ($event) {
return $exception['start'] < $event['start'];
});
+ // set link to top-level exceptions
+ $master['exceptions'] = &$master['recurrence']['EXCEPTIONS'];
}
if (is_array($master['recurrence']['EXDATE'])) {
$master['recurrence']['EXDATE'] = array_filter($master['recurrence']['EXDATE'], function($exdate) use ($event) {
@@ -1102,7 +1084,7 @@ class kolab_driver extends calendar_driver
$add_exception = true;
// adjust matching RDATE entry if dates changed
- if ($savemode == 'current' && $master['recurrence']['RDATE'] && ($old_date = $old['start']->format('Ymd')) != $event['start']->format('Ymd')) {
+ if (is_array($master['recurrence']['RDATE']) && ($old_date = $old['start']->format('Ymd')) != $event['start']->format('Ymd')) {
foreach ($master['recurrence']['RDATE'] as $j => $rdate) {
if ($rdate->format('Ymd') == $old_date) {
$master['recurrence']['RDATE'][$j] = $event['start'];
@@ -1122,7 +1104,7 @@ class kolab_driver extends calendar_driver
break;
default: // 'all' is default
- $event['id'] = $master['id'];
+ $event['id'] = $master['uid'];
$event['uid'] = $master['uid'];
// use start date from master but try to be smart on time or duration changes
@@ -1152,7 +1134,7 @@ class kolab_driver extends calendar_driver
}
}
// dates did not change, use the ones from master
- else if ($event['start'] == $old['start'] && $event['end'] == $old['end']) {
+ else if ($new_start_date . $new_start_time == $old_start_date . $old_start_time) {
$event['start'] = $master['start'];
$event['end'] = $master['end'];
}
@@ -1198,12 +1180,15 @@ class kolab_driver extends calendar_driver
}
}
}
+
+ // set link to top-level exceptions
+ $event['exceptions'] = &$event['recurrence']['EXCEPTIONS'];
}
// unset _dateonly flags in (cached) date objects
unset($event['start']->_dateonly, $event['end']->_dateonly);
- $success = $storage->update_event($event);
+ $success = $storage->update_event($event) ? $event['id'] : false; // return master UID
break;
}
@@ -1500,7 +1485,7 @@ class kolab_driver extends calendar_driver
$this->rc->user->save_prefs(array('calendar_categories' => $old_categories));
}
- array_walk($events, 'kolab_driver::clean_rcube_event_out');
+ array_walk($events, 'kolab_driver::to_rcube_event');
return $events;
}
@@ -1663,8 +1648,8 @@ class kolab_driver extends calendar_driver
$event = $storage->get_event($event['id']);
- if ($event && !empty($event['attachments'])) {
- foreach ($event['attachments'] as $att) {
+ if ($event && !empty($event['_attachments'])) {
+ foreach ($event['_attachments'] as $att) {
if ($att['id'] == $id) {
return $att;
}
@@ -1878,12 +1863,22 @@ class kolab_driver extends calendar_driver
/**
- * Convert from Kolab_Format to internal representation
+ * Convert from driver format to external caledar app data
*/
- public static function to_rcube_event($record)
+ public static function to_rcube_event(&$record)
{
+ if (!is_array($record))
+ return $record;
+
$record['id'] = $record['uid'];
+ if ($record['_instance']) {
+ $record['id'] .= '-' . $record['_instance'];
+
+ if (!$record['recurrence_id'] && !empty($record['recurrence']))
+ $record['recurrence_id'] = $record['uid'];
+ }
+
// all-day events go from 12:00 - 13:00
if (is_a($record['start'], 'DateTime') && $record['end'] <= $record['start'] && $record['allday']) {
$record['end'] = clone $record['start'];
@@ -1932,17 +1927,6 @@ class kolab_driver extends calendar_driver
if (empty($record['recurrence']))
unset($record['recurrence']);
- // add instance identifier to first occurrence (master event)
- // do not add 'recurrence_date' though in order to keep the master even being exported as such
- $recurrence_id_format = $record['allday'] ? 'Ymd' : 'Ymd\THis';
- if ($record['recurrence'] && !$record['recurrence_id'] && !$record['_instance']) {
- $record['_instance'] = $record['start']->format($recurrence_id_format);
- }
- else if (is_a($record['recurrence_date'], 'DateTime')) {
- $record['_instance'] = $record['recurrence_date']->format($recurrence_id_format);
- $record['id'] = $record['uid'] . '-' . $record['_instance'];
- }
-
// clean up exception data
if (is_array($record['recurrence']['EXCEPTIONS'])) {
array_walk($record['recurrence']['EXCEPTIONS'], function(&$exception) {
@@ -1950,16 +1934,10 @@ class kolab_driver extends calendar_driver
});
}
- return $record;
- }
-
- /**
- * Remove some internal properties before sending to event out to the calendar app
- */
- public static function clean_rcube_event_out(&$record)
- {
unset($record['_mailbox'], $record['_msguid'], $record['_type'], $record['_size'],
$record['_formatobj'], $record['_attachments'], $record['exceptions'], $record['x-custom']);
+
+ return $record;
}
/**
@@ -1968,7 +1946,7 @@ class kolab_driver extends calendar_driver
public static function from_rcube_event($event, $old = array())
{
// in kolab_storage attachments are indexed by content-id
- if (is_array($event['attachments'])) {
+ if (is_array($event['attachments']) || !empty($event['deleted_attachments'])) {
$event['_attachments'] = array();
foreach ($event['attachments'] as $attachment) {
@@ -1985,7 +1963,7 @@ class kolab_driver extends calendar_driver
}
// flagged for deletion => set to false
- if ($attachment['_deleted']) {
+ if ($attachment['_deleted'] || in_array($attachment['id'], (array)$event['deleted_attachments'])) {
$event['_attachments'][$key] = false;
}
// replace existing entry
@@ -1998,7 +1976,14 @@ class kolab_driver extends calendar_driver
}
}
- unset($event['attachments']);
+ $event['_attachments'] = array_merge((array)$old['_attachments'], $event['_attachments']);
+
+ // attachments flagged for deletion => set to false
+ foreach ($event['_attachments'] as $key => $attachment) {
+ if ($attachment['_deleted'] || in_array($attachment['id'], (array)$event['deleted_attachments'])) {
+ $event['_attachments'][$key] = false;
+ }
+ }
}
return $event;
More information about the commits
mailing list