Branch 'roundcubemail-plugins-kolab-3.0' - 13 commits - plugins/calendar plugins/kolab_addressbook plugins/libcalendaring plugins/libkolab plugins/tasklist
Aleksander Machniak
machniak at kolabsys.com
Fri Jun 21 11:02:27 CEST 2013
plugins/calendar/drivers/database/database_driver.php | 4 -
plugins/calendar/drivers/kolab/kolab_calendar.php | 60 ++++++++++++++---
plugins/calendar/drivers/kolab/kolab_driver.php | 35 ++++++---
plugins/calendar/lib/calendar_ical.php | 3
plugins/calendar/lib/calendar_recurrence.php | 31 +++++++-
plugins/kolab_addressbook/lib/rcube_kolab_contacts.php | 4 -
plugins/libcalendaring/libcalendaring.php | 14 ++-
plugins/libkolab/lib/kolab_format.php | 15 ++--
plugins/libkolab/lib/kolab_storage.php | 2
plugins/libkolab/lib/kolab_storage_cache.php | 1
plugins/libkolab/lib/kolab_storage_folder.php | 19 ++++-
plugins/tasklist/tasklist.js | 2
12 files changed, 142 insertions(+), 48 deletions(-)
New commits:
commit a1f14a3f8fde16f4bea094b309c3072eb4443f31
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Thu Feb 21 13:04:00 2013 +0100
Allow libcalendaring to work without output
diff --git a/plugins/libcalendaring/libcalendaring.php b/plugins/libcalendaring/libcalendaring.php
index 24f98cb..c78173b 100644
--- a/plugins/libcalendaring/libcalendaring.php
+++ b/plugins/libcalendaring/libcalendaring.php
@@ -84,14 +84,16 @@ class libcalendaring extends rcube_plugin
$this->add_texts('localization/', false);
// include client scripts and styles
- $this->include_script('libcalendaring.js');
- $this->rc->output->set_env('libcal_settings', $this->load_settings());
+ if ($this->rc->output) {
+ $this->include_script('libcalendaring.js');
+ $this->rc->output->set_env('libcal_settings', $this->load_settings());
- $this->include_stylesheet($this->local_skin_path() . '/libcal.css');
+ $this->include_stylesheet($this->local_skin_path() . '/libcal.css');
- // add hook to display alarms
- $this->add_hook('refresh', array($this, 'refresh'));
- $this->register_action('plugin.alarms', array($this, 'alarms_action'));
+ // add hook to display alarms
+ $this->add_hook('refresh', array($this, 'refresh'));
+ $this->register_action('plugin.alarms', array($this, 'alarms_action'));
+ }
}
commit c6eb05eaa7af29a0cec0141ab48716185874a189
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Thu Feb 21 11:18:59 2013 +0100
Make some metadata from the Kolab storage backend available to the library user
diff --git a/plugins/libkolab/lib/kolab_storage_cache.php b/plugins/libkolab/lib/kolab_storage_cache.php
index 6f6e16e..ef4dd22 100644
--- a/plugins/libkolab/lib/kolab_storage_cache.php
+++ b/plugins/libkolab/lib/kolab_storage_cache.php
@@ -591,6 +591,7 @@ class kolab_storage_cache
$object['_type'] = $sql_arr['type'];
$object['_msguid'] = $sql_arr['msguid'];
$object['_mailbox'] = $this->folder->name;
+ $object['_size'] = strlen($sql_arr['xml']);
$object['_formatobj'] = kolab_format::factory($sql_arr['type'], 3.0, $sql_arr['xml']);
return $object;
diff --git a/plugins/libkolab/lib/kolab_storage_folder.php b/plugins/libkolab/lib/kolab_storage_folder.php
index 23ea4e3..2811886 100644
--- a/plugins/libkolab/lib/kolab_storage_folder.php
+++ b/plugins/libkolab/lib/kolab_storage_folder.php
@@ -51,6 +51,7 @@ class kolab_storage_folder
private $type_annotation;
private $imap;
private $info;
+ private $idata;
private $owner;
private $resource_uri;
private $uid2msg = array();
@@ -99,6 +100,16 @@ class kolab_storage_folder
return $this->info;
}
+ /**
+ * Make IMAP folder data available for this folder
+ */
+ public function get_imap_data()
+ {
+ if (!isset($this->idata))
+ $this->idata = $this->imap->folder_data($this->name);
+
+ return $this->idata;
+ }
/**
* Returns IMAP metadata/annotations (GETMETADATA/GETANNOTATION)
commit d8511c0429db91d5a9ffb1ab3c7e9b1a3a509f95
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Wed Feb 20 21:03:44 2013 +0100
Use generic getter for current user's email; also works in framework without session and user database record
diff --git a/plugins/libkolab/lib/kolab_storage_folder.php b/plugins/libkolab/lib/kolab_storage_folder.php
index 27517cf..23ea4e3 100644
--- a/plugins/libkolab/lib/kolab_storage_folder.php
+++ b/plugins/libkolab/lib/kolab_storage_folder.php
@@ -776,9 +776,9 @@ class kolab_storage_folder
$part_id = 1;
$encoding = $binary ? 'binary' : 'base64';
- if ($ident = $rcmail->user->get_identity()) {
- $headers['From'] = $ident['email'];
- $headers['To'] = $ident['email'];
+ if ($user_email = $rcmail->get_user_email()) {
+ $headers['From'] = $user_email;
+ $headers['To'] = $user_email;
}
$headers['Date'] = date('r');
$headers['X-Kolab-Type'] = kolab_format::KTYPE_PREFIX . $type;
@@ -820,7 +820,7 @@ class kolab_storage_folder
false, // is_file
'8bit', // encoding
'attachment', // disposition
- RCUBE_CHARSET // charset
+ RCUBE_CHARSET // charset
);
$part_id++;
commit 3bd67d91fc2304a7b71028df26cecbc5b1e086cb
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Wed Feb 20 09:56:13 2013 +0100
Backport changes from dev/version_compare branch
diff --git a/plugins/libkolab/lib/kolab_format.php b/plugins/libkolab/lib/kolab_format.php
index c0fb986..ccc7e46 100644
--- a/plugins/libkolab/lib/kolab_format.php
+++ b/plugins/libkolab/lib/kolab_format.php
@@ -41,7 +41,7 @@ abstract class kolab_format
protected $xmldata;
protected $xmlobject;
protected $loaded = false;
- protected $version = 3.0;
+ protected $version = '3.0';
const KTYPE_PREFIX = 'application/x-vnd.kolab.';
const PRODUCT_ID = 'Roundcube-libkolab-0.9';
@@ -54,7 +54,7 @@ abstract class kolab_format
* @param string Cached xml data to initialize with
* @return object kolab_format
*/
- public static function factory($type, $version = 3.0, $xmldata = null)
+ public static function factory($type, $version = '3.0', $xmldata = null)
{
if (!isset(self::$timezone))
self::$timezone = new DateTimeZone('UTC');
@@ -79,7 +79,7 @@ abstract class kolab_format
*/
public static function supports($version)
{
- if ($version == 2.0)
+ if ($version == '2.0')
return class_exists('kolabobject');
// default is version 3
return class_exists('kolabformat');
@@ -299,7 +299,7 @@ abstract class kolab_format
{
if (class_exists('kolabobject')) {
$version = $v ?: $this->version;
- if ($version <= 2.0)
+ if ($version <= '2.0')
return kolabobject::KolabV2;
else
return kolabobject::KolabV3;
diff --git a/plugins/libkolab/lib/kolab_storage.php b/plugins/libkolab/lib/kolab_storage.php
index ebbadf2..a569af7 100644
--- a/plugins/libkolab/lib/kolab_storage.php
+++ b/plugins/libkolab/lib/kolab_storage.php
@@ -51,7 +51,7 @@ class kolab_storage
$rcmail = rcube::get_instance();
self::$config = $rcmail->config;
- self::$version = $rcmail->config->get('kolab_format_version', self::$version);
+ self::$version = strval($rcmail->config->get('kolab_format_version', self::$version));
self::$imap = $rcmail->get_storage();
self::$ready = class_exists('kolabformat') &&
(self::$imap->get_capability('METADATA') || self::$imap->get_capability('ANNOTATEMORE') || self::$imap->get_capability('ANNOTATEMORE2'));
commit 826118b4a6b7e0bd6f37369557d226845a7d1e27
Author: Aleksander Machniak <machniak at kolabsys.com>
Date: Wed Feb 20 09:36:04 2013 +0100
Fix importing photo and notes fields (Bug #1635). Values of these fields
were imported from vCard as one-element-arrays. Setting limit=1 on these
fields makes that the array is converted to string as needed.
diff --git a/plugins/kolab_addressbook/lib/rcube_kolab_contacts.php b/plugins/kolab_addressbook/lib/rcube_kolab_contacts.php
index b34cc6c..6e32bc7 100644
--- a/plugins/kolab_addressbook/lib/rcube_kolab_contacts.php
+++ b/plugins/kolab_addressbook/lib/rcube_kolab_contacts.php
@@ -65,8 +65,8 @@ class rcube_kolab_contacts extends rcube_addressbook
'label' => 'kolab_addressbook.pgppublickey'),
'pkcs7publickey' => array('type' => 'textarea', 'size' => 70, 'rows' => 10, 'limit' => 1,
'label' => 'kolab_addressbook.pkcs7publickey'),
- 'notes' => array(),
- 'photo' => array(),
+ 'notes' => array('limit' => 1),
+ 'photo' => array('limit' => 1),
// TODO: define more Kolab-specific fields such as: language, latitude, longitude, crypto settings
);
commit 0a3071bfcfc0a64e5c2ee66422e60f4c83ed2e85
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Wed Jan 23 11:36:55 2013 +0100
Add fallback for recurrence computation when the kolabcalendaring php module isn't available
diff --git a/plugins/calendar/drivers/kolab/kolab_calendar.php b/plugins/calendar/drivers/kolab/kolab_calendar.php
index f2c106e..45db638 100644
--- a/plugins/calendar/drivers/kolab/kolab_calendar.php
+++ b/plugins/calendar/drivers/kolab/kolab_calendar.php
@@ -414,7 +414,14 @@ class kolab_calendar
}
// use libkolab to compute recurring events
- $recurrence = new kolab_date_recurrence($object);
+ if (class_exists('kolabcalendaring')) {
+ $recurrence = new kolab_date_recurrence($object);
+ }
+ else {
+ // fallback to local recurrence implementation
+ require_once($this->cal->home . '/lib/calendar_recurrence.php');
+ $recurrence = new calendar_recurrence($this->cal, $event);
+ }
$i = 0;
$events = array();
diff --git a/plugins/calendar/lib/calendar_recurrence.php b/plugins/calendar/lib/calendar_recurrence.php
index 03831c1..bf534f5 100644
--- a/plugins/calendar/lib/calendar_recurrence.php
+++ b/plugins/calendar/lib/calendar_recurrence.php
@@ -41,6 +41,10 @@ class calendar_recurrence
*/
function __construct($cal, $event)
{
+ // use Horde classes to compute recurring instances
+ // TODO: replace with something that has less than 6'000 lines of code
+ require_once(__DIR__ . '/Horde_Date_Recurrence.php');
+
$this->cal = $cal;
$this->event = $event;
$this->next = new Horde_Date($event['start'], $cal->timezone->getName());
@@ -49,10 +53,6 @@ class calendar_recurrence
if (is_object($event['start']) && is_object($event['end']))
$this->duration = $event['start']->diff($event['end']);
- // use Horde classes to compute recurring instances
- // TODO: replace with something that has less than 6'000 lines of code
- require_once($this->cal->home . '/lib/Horde_Date_Recurrence.php');
-
$this->engine = new Horde_Date_Recurrence($event['start']);
$this->engine->fromRRule20(libcalendaring::to_rrule($event['recurrence']));
@@ -83,4 +83,27 @@ class calendar_recurrence
return $time;
}
+ /**
+ * Get the next recurring instance of this event
+ *
+ * @return mixed Array with event properties or False if recurrence ended
+ */
+ public function next_instance()
+ {
+ if ($next_start = $this->next_start()) {
+ $next_end = clone $next_start;
+ $next_end->add($this->duration);
+
+ $next = $this->event;
+ $next['recurrence_id'] = $next_start->format('Y-m-d');
+ $next['start'] = $next_start;
+ $next['end'] = $next_end;
+ unset($next['_formatobj']);
+
+ return $next;
+ }
+
+ return false;
+ }
+
}
commit e5ab237c3bfc4c44e0ebedd2ef7879b137ac7528
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Wed Jan 23 10:06:44 2013 +0100
Fix ical export with (invalid) timezone +00:00
diff --git a/plugins/calendar/lib/calendar_ical.php b/plugins/calendar/lib/calendar_ical.php
index f77224d..cec2040 100644
--- a/plugins/calendar/lib/calendar_ical.php
+++ b/plugins/calendar/lib/calendar_ical.php
@@ -449,7 +449,8 @@ class calendar_ical
else {
// <ATTR>;TZID=Europe/Zurich:20120706T210000
$tz = $dt->getTimezone();
- $tzid = $tz && $tz->getName() != 'UTC' ? ';TZID=' . $tz->getName() : '';
+ $tzname = $tz ? $tz->getName() : null;
+ $tzid = $tzname && $tzname != 'UTC' && $tzname != '+00:00' ? ';TZID=' . $tzname : '';
return $attr . $tzid . ':' . $dt->format('Ymd\THis' . ($tzid ? '' : '\Z'));
}
}
commit e886498390f7692aab882146f0691a7fab5876c2
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Sat Jan 19 17:36:32 2013 +0100
Fix javascript error that prevents delete dialog from being closed (#1551)
diff --git a/plugins/tasklist/tasklist.js b/plugins/tasklist/tasklist.js
index f897d0d..daf157e 100644
--- a/plugins/tasklist/tasklist.js
+++ b/plugins/tasklist/tasklist.js
@@ -1319,7 +1319,7 @@ function rcube_tasklist_ui(settings)
rcmail.http_post('task', { action:'delete', t:{ id:rec.id, list:rec.list }, mode:mode, filter:filtermask });
// move childs to parent/root
- if (mode != 1) {
+ if (mode != 1 && rec.children !== undefined) {
var parent_node = rec.parent_id ? $('li[rel="'+rec.parent_id+'"] > .childtasks', rcmail.gui_objects.resultlist) : null;
if (!parent_node || !parent_node.length)
parent_node = rcmail.gui_objects.resultlist;
commit cb0ceb0df20085fa1182013f21f6e677f767b006
Author: Aleksander Machniak <machniak at kolabsys.com>
Date: Thu Jan 17 15:16:10 2013 +0100
More typos fixed
diff --git a/plugins/calendar/drivers/kolab/kolab_driver.php b/plugins/calendar/drivers/kolab/kolab_driver.php
index 3e5d05f..2b3694a 100644
--- a/plugins/calendar/drivers/kolab/kolab_driver.php
+++ b/plugins/calendar/drivers/kolab/kolab_driver.php
@@ -150,7 +150,7 @@ class kolab_driver extends calendar_driver
$plugin = $this->rc->plugins->exec_hook('calendar_list_filter', array(
'list' => $this->calendars, 'calendars' => $calendars,
- 'writable' => $writable, 'active' => $active, 'personal' => $personal,
+ 'writeable' => $writeable, 'active' => $active, 'personal' => $personal,
));
if ($plugin['abort']) {
commit 01850fc9ac9921797946dbeebb0ee6a327e9c3e2
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Thu Jan 17 09:37:48 2013 +0100
Fix typo in calendar selection; fixes bug #140
diff --git a/plugins/calendar/drivers/kolab/kolab_driver.php b/plugins/calendar/drivers/kolab/kolab_driver.php
index 687e39d..3e5d05f 100644
--- a/plugins/calendar/drivers/kolab/kolab_driver.php
+++ b/plugins/calendar/drivers/kolab/kolab_driver.php
@@ -138,13 +138,13 @@ class kolab_driver extends calendar_driver
/**
* Get list of calendars according to specified filters
*
- * @param bool $writable Return only writeable calendars
+ * @param bool $writeable Return only writeable calendars
* @param bool $active Return only active calendars
* @param bool $personal Return only personal calendars
*
* @return array List of calendars
*/
- protected function filter_calendars($writable = false, $active = false, $personal = false)
+ protected function filter_calendars($writeable = false, $active = false, $personal = false)
{
$calendars = array();
commit 6fac09efe1b8dea8a6cf38af3f33adc6b921b2fa
Author: Aleksander Machniak <machniak at kolabsys.com>
Date: Wed Jan 16 10:06:59 2013 +0100
Add workaround for situation when kolabobject doesn't generate UID but kolabformat does
(it's the case for File objects unsupported by libkolab)
diff --git a/plugins/libkolab/lib/kolab_format.php b/plugins/libkolab/lib/kolab_format.php
index c3c1b12..c0fb986 100644
--- a/plugins/libkolab/lib/kolab_format.php
+++ b/plugins/libkolab/lib/kolab_format.php
@@ -265,7 +265,12 @@ abstract class kolab_format
{
// get generated UID
if (!$this->data['uid']) {
- $this->data['uid'] = $this->xmlobject ? $this->xmlobject->getSerializedUID() : kolabformat::getSerializedUID();
+ if ($this->xmlobject) {
+ $this->data['uid'] = $this->xmlobject->getSerializedUID();
+ }
+ if (empty($this->data['uid'])) {
+ $this->data['uid'] = kolabformat::getSerializedUID();
+ }
$this->obj->setUid($this->data['uid']);
}
}
commit 6fe22f10b68e5f7b8f3b1604a136b9f8338ad928
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Wed Jan 9 11:49:12 2013 +0100
Fix modification of recurring events (#1499)
diff --git a/plugins/calendar/drivers/database/database_driver.php b/plugins/calendar/drivers/database/database_driver.php
index d6a4483..5a518f7 100644
--- a/plugins/calendar/drivers/database/database_driver.php
+++ b/plugins/calendar/drivers/database/database_driver.php
@@ -363,11 +363,11 @@ class database_driver extends calendar_driver
// use start date from master but try to be smart on time or duration changes
$old_start_date = $old['start']->format('Y-m-d');
- $old_start_time = $old['start']->format('H:i');
+ $old_start_time = $old['allday'] ? '' : $old['start']->format('H:i');
$old_duration = $old['end']->format('U') - $old['start']->format('U');
$new_start_date = $event['start']->format('Y-m-d');
- $new_start_time = $event['start']->format('H:i');
+ $new_start_time = $event['allday'] ? '' : $event['start']->format('H:i');
$new_duration = $event['end']->format('U') - $event['start']->format('U');
$diff = $old_start_date != $new_start_date || $old_start_time != $new_start_time || $old_duration != $new_duration;
diff --git a/plugins/calendar/drivers/kolab/kolab_calendar.php b/plugins/calendar/drivers/kolab/kolab_calendar.php
index 5200cff..f2c106e 100644
--- a/plugins/calendar/drivers/kolab/kolab_calendar.php
+++ b/plugins/calendar/drivers/kolab/kolab_calendar.php
@@ -181,9 +181,7 @@ class kolab_calendar
$this->events[$master_id] = $this->_to_rcube_event($record);
if (($master = $this->events[$master_id]) && $master['recurrence']) {
- $limit = clone $master['start'];
- $limit->add(new DateInterval('P10Y'));
- $this->_get_recurring_events($record, $master['start'], $limit, $id);
+ $this->_get_recurring_events($record, $master['start'], null, $id);
}
}
@@ -386,8 +384,14 @@ class kolab_calendar
/**
* Create instances of a recurring event
+ *
+ * @param array Hash array with event properties
+ * @param object DateTime Start date of the recurrence window
+ * @param object DateTime End date of the recurrence window
+ * @param string ID of a specific recurring event instance
+ * @return array List of recurring event instances
*/
- public function _get_recurring_events($event, $start, $end, $event_id = null)
+ public function _get_recurring_events($event, $start, $end = null, $event_id = null)
{
$object = $event['_formatobj'];
if (!$object) {
@@ -397,6 +401,19 @@ class kolab_calendar
if (!is_object($object))
return array();
+ // determine a reasonable end date if none given
+ if (!$end) {
+ switch ($event['recurrence']['FREQ']) {
+ case 'YEARLY': $intvl = 'P100Y'; break;
+ case 'MONTHLY': $intvl = 'P20Y'; break;
+ default: $intvl = 'P10Y'; break;
+ }
+
+ $end = clone $event['start'];
+ $end->add(new DateInterval($intvl));
+ }
+
+ // use libkolab to compute recurring events
$recurrence = new kolab_date_recurrence($object);
$i = 0;
diff --git a/plugins/calendar/drivers/kolab/kolab_driver.php b/plugins/calendar/drivers/kolab/kolab_driver.php
index c701077..687e39d 100644
--- a/plugins/calendar/drivers/kolab/kolab_driver.php
+++ b/plugins/calendar/drivers/kolab/kolab_driver.php
@@ -429,9 +429,7 @@ class kolab_driver extends calendar_driver
// removing the first instance => just move to next occurence
if ($master['id'] == $event['id']) {
- $limit = clone $event['end'];
- $limit->add(new DateInterval('P370D'));
- $recurring = reset($storage->_get_recurring_events($event, $event['start'], $limit, $event['id'].'-1'));
+ $recurring = reset($storage->_get_recurring_events($event, $event['start'], null, $event['id'].'-1'));
$master['start'] = $recurring['start'];
$master['end'] = $recurring['end'];
if ($master['recurrence']['COUNT'])
@@ -588,9 +586,7 @@ class kolab_driver extends calendar_driver
case 'current':
// modifying the first instance => just move to next occurence
if ($master['id'] == $event['id']) {
- $limit = clone $old['end'];
- $limit->add(new DateInterval('P370D'));
- $recurring = reset($storage->_get_recurring_events($event, $event['start'], $limit, $event['id'].'-1'));
+ $recurring = reset($storage->_get_recurring_events($event, $event['start'], null, $event['id'].'-1'));
$master['start'] = $recurring['start'];
$master['end'] = $recurring['end'];
if ($master['recurrence']['COUNT'])
@@ -643,11 +639,11 @@ class kolab_driver extends calendar_driver
// use start date from master but try to be smart on time or duration changes
$old_start_date = $old['start']->format('Y-m-d');
- $old_start_time = $old['start']->format('H:i');
+ $old_start_time = $old['allday'] ? '' : $old['start']->format('H:i');
$old_duration = $old['end']->format('U') - $old['start']->format('U');
$new_start_date = $event['start']->format('Y-m-d');
- $new_start_time = $event['start']->format('H:i');
+ $new_start_time = $event['allday'] ? '' : $event['start']->format('H:i');
$new_duration = $event['end']->format('U') - $event['start']->format('U');
$diff = $old_start_date != $new_start_date || $old_start_time != $new_start_time || $old_duration != $new_duration;
commit 7daf2b001c15cac0d77089b2088a8e4cc46d5a24
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Wed Jan 9 11:12:19 2013 +0100
Fix recurring event handling when first instance is modified and excluded (#1505)
diff --git a/plugins/calendar/drivers/kolab/kolab_calendar.php b/plugins/calendar/drivers/kolab/kolab_calendar.php
index 0a3d273..5200cff 100644
--- a/plugins/calendar/drivers/kolab/kolab_calendar.php
+++ b/plugins/calendar/drivers/kolab/kolab_calendar.php
@@ -248,7 +248,21 @@ class kolab_calendar
// list events in requested time window
if ($event['start'] <= $end && $event['end'] >= $start) {
unset($event['_attendees']);
- $events[] = $event;
+ $add = true;
+
+ // skip the first instance of a recurring event if listed in exdate
+ if ($virtual && !empty($event['recurrence']['EXDATE'])) {
+ $event_date = $event['start']->format('Ymd');
+ foreach ($event['recurrence']['EXDATE'] as $exdate) {
+ if ($exdate->format('Ymd') == $event_date) {
+ $add = false;
+ break;
+ }
+ }
+ }
+
+ if ($add)
+ $events[] = $event;
}
// resolve recurring events
@@ -409,9 +423,9 @@ class kolab_calendar
else if ($next_event['start'] > $end) // stop loop if out of range
break;
- // avoid endless recursion loops
- if ($i > 1000)
- break;
+ // avoid endless recursion loops
+ if ($i > 1000)
+ break;
}
return $events;
@@ -458,6 +472,10 @@ class kolab_calendar
if (is_array($record['categories']))
$record['categories'] = $record['categories'][0];
+ // remove empty recurrence array
+ if (empty($record['recurrence']))
+ unset($record['recurrence']);
+
// remove internals
unset($record['_mailbox'], $record['_msguid'], $record['_formatobj'], $record['_attachments']);
diff --git a/plugins/calendar/drivers/kolab/kolab_driver.php b/plugins/calendar/drivers/kolab/kolab_driver.php
index fcf05aa..c701077 100644
--- a/plugins/calendar/drivers/kolab/kolab_driver.php
+++ b/plugins/calendar/drivers/kolab/kolab_driver.php
@@ -408,10 +408,10 @@ class kolab_driver extends calendar_driver
public function remove_event($event, $force = true)
{
$success = false;
- $_savemode = $event['_savemode'];
+ $savemode = $event['_savemode'];
if (($storage = $this->calendars[$event['calendar']]) && ($event = $storage->get_event($event['id']))) {
- $event['_savemode'] = $_savemode;
+ $event['_savemode'] = $savemode;
$savemode = 'all';
$master = $event;
@@ -426,7 +426,7 @@ class kolab_driver extends calendar_driver
switch ($savemode) {
case 'current':
$_SESSION['calendar_restore_event_data'] = $master;
-
+
// removing the first instance => just move to next occurence
if ($master['id'] == $event['id']) {
$limit = clone $event['end'];
@@ -586,13 +586,26 @@ class kolab_driver extends calendar_driver
break;
case 'current':
- // add exception to master event
- $master['recurrence']['EXDATE'][] = $old['start'];
+ // modifying the first instance => just move to next occurence
+ if ($master['id'] == $event['id']) {
+ $limit = clone $old['end'];
+ $limit->add(new DateInterval('P370D'));
+ $recurring = reset($storage->_get_recurring_events($event, $event['start'], $limit, $event['id'].'-1'));
+ $master['start'] = $recurring['start'];
+ $master['end'] = $recurring['end'];
+ if ($master['recurrence']['COUNT'])
+ $master['recurrence']['COUNT']--;
+ }
+ else { // add exception to master event
+ $master['recurrence']['EXDATE'][] = $old['start'];
+ }
+
$storage->update_event($master);
// insert new event for this occurence
$event += $old;
$event['recurrence'] = array();
+ unset($event['recurrence_id']);
$event['uid'] = $this->cal->generate_uid();
$success = $storage->insert_event($event);
break;
More information about the commits
mailing list