lib/plugins
Aleksander Machniak
machniak at kolabsys.com
Thu Jan 2 15:51:00 CET 2014
lib/plugins/libkolab/SQL/mysql.initial.sql | 18 +-
lib/plugins/libkolab/SQL/mysql/2013110400.sql | 1
lib/plugins/libkolab/SQL/mysql/2013121100.sql | 13 +
lib/plugins/libkolab/lib/kolab_date_recurrence.php | 27 ++-
lib/plugins/libkolab/lib/kolab_format.php | 8
lib/plugins/libkolab/lib/kolab_format_event.php | 14 -
lib/plugins/libkolab/lib/kolab_storage.php | 151 ++++++++++++++---
lib/plugins/libkolab/lib/kolab_storage_cache.php | 43 +++-
lib/plugins/libkolab/lib/kolab_storage_cache_event.php | 2
lib/plugins/libkolab/lib/kolab_storage_folder.php | 3
10 files changed, 220 insertions(+), 60 deletions(-)
New commits:
commit 18672e97970855f36dd87efea9a46764731c53ec
Author: Aleksander Machniak <alec at alec.pl>
Date: Thu Jan 2 15:50:07 2014 +0100
Update libkolab plugin
diff --git a/lib/plugins/libkolab/SQL/mysql.initial.sql b/lib/plugins/libkolab/SQL/mysql.initial.sql
index 4f23a52..40b8631 100644
--- a/lib/plugins/libkolab/SQL/mysql.initial.sql
+++ b/lib/plugins/libkolab/SQL/mysql.initial.sql
@@ -30,7 +30,7 @@ CREATE TABLE `kolab_cache_contact` (
`created` DATETIME DEFAULT NULL,
`changed` DATETIME DEFAULT NULL,
`data` TEXT NOT NULL,
- `xml` TEXT NOT NULL,
+ `xml` LONGBLOB NOT NULL,
`tags` VARCHAR(255) NOT NULL,
`words` TEXT NOT NULL,
`type` VARCHAR(32) CHARACTER SET ascii NOT NULL,
@@ -49,7 +49,7 @@ CREATE TABLE `kolab_cache_event` (
`created` DATETIME DEFAULT NULL,
`changed` DATETIME DEFAULT NULL,
`data` TEXT NOT NULL,
- `xml` TEXT NOT NULL,
+ `xml` LONGBLOB NOT NULL,
`tags` VARCHAR(255) NOT NULL,
`words` TEXT NOT NULL,
`dtstart` DATETIME,
@@ -68,7 +68,7 @@ CREATE TABLE `kolab_cache_task` (
`created` DATETIME DEFAULT NULL,
`changed` DATETIME DEFAULT NULL,
`data` TEXT NOT NULL,
- `xml` TEXT NOT NULL,
+ `xml` LONGBLOB NOT NULL,
`tags` VARCHAR(255) NOT NULL,
`words` TEXT NOT NULL,
`dtstart` DATETIME,
@@ -87,7 +87,7 @@ CREATE TABLE `kolab_cache_journal` (
`created` DATETIME DEFAULT NULL,
`changed` DATETIME DEFAULT NULL,
`data` TEXT NOT NULL,
- `xml` TEXT NOT NULL,
+ `xml` LONGBLOB NOT NULL,
`tags` VARCHAR(255) NOT NULL,
`words` TEXT NOT NULL,
`dtstart` DATETIME,
@@ -106,7 +106,7 @@ CREATE TABLE `kolab_cache_note` (
`created` DATETIME DEFAULT NULL,
`changed` DATETIME DEFAULT NULL,
`data` TEXT NOT NULL,
- `xml` TEXT NOT NULL,
+ `xml` LONGBLOB NOT NULL,
`tags` VARCHAR(255) NOT NULL,
`words` TEXT NOT NULL,
CONSTRAINT `fk_kolab_cache_note_folder` FOREIGN KEY (`folder_id`)
@@ -123,7 +123,7 @@ CREATE TABLE `kolab_cache_file` (
`created` DATETIME DEFAULT NULL,
`changed` DATETIME DEFAULT NULL,
`data` TEXT NOT NULL,
- `xml` TEXT NOT NULL,
+ `xml` LONGBLOB NOT NULL,
`tags` VARCHAR(255) NOT NULL,
`words` TEXT NOT NULL,
`filename` varchar(255) DEFAULT NULL,
@@ -142,7 +142,7 @@ CREATE TABLE `kolab_cache_configuration` (
`created` DATETIME DEFAULT NULL,
`changed` DATETIME DEFAULT NULL,
`data` TEXT NOT NULL,
- `xml` TEXT NOT NULL,
+ `xml` LONGBLOB NOT NULL,
`tags` VARCHAR(255) NOT NULL,
`words` TEXT NOT NULL,
`type` VARCHAR(32) CHARACTER SET ascii NOT NULL,
@@ -161,7 +161,7 @@ CREATE TABLE `kolab_cache_freebusy` (
`created` DATETIME DEFAULT NULL,
`changed` DATETIME DEFAULT NULL,
`data` TEXT NOT NULL,
- `xml` TEXT NOT NULL,
+ `xml` LONGBLOB NOT NULL,
`tags` VARCHAR(255) NOT NULL,
`words` TEXT NOT NULL,
`dtstart` DATETIME,
@@ -172,4 +172,4 @@ CREATE TABLE `kolab_cache_freebusy` (
) /*!40000 ENGINE=INNODB */ /*!40101 CHARACTER SET utf8 COLLATE utf8_general_ci */;
-INSERT INTO `system` (`name`, `value`) VALUES ('libkolab-version', '2013100400');
+INSERT INTO `system` (`name`, `value`) VALUES ('libkolab-version', '2013121100');
diff --git a/lib/plugins/libkolab/SQL/mysql/2013110400.sql b/lib/plugins/libkolab/SQL/mysql/2013110400.sql
new file mode 100644
index 0000000..5b7a9ef
--- /dev/null
+++ b/lib/plugins/libkolab/SQL/mysql/2013110400.sql
@@ -0,0 +1 @@
+ALTER TABLE `kolab_cache_contact` CHANGE `xml` `xml` LONGTEXT NOT NULL;
diff --git a/lib/plugins/libkolab/SQL/mysql/2013121100.sql b/lib/plugins/libkolab/SQL/mysql/2013121100.sql
new file mode 100644
index 0000000..8cab5ef
--- /dev/null
+++ b/lib/plugins/libkolab/SQL/mysql/2013121100.sql
@@ -0,0 +1,13 @@
+-- well, these deletes are really optional
+-- we can clear all caches or only contacts/events/tasks
+-- the issue we're fixing here was about contacts (Bug #2662)
+DELETE FROM `kolab_folders` WHERE `type` IN ('contact', 'event', 'task');
+
+ALTER TABLE `kolab_cache_contact` CHANGE `xml` `xml` LONGBLOB NOT NULL;
+ALTER TABLE `kolab_cache_event` CHANGE `xml` `xml` LONGBLOB NOT NULL;
+ALTER TABLE `kolab_cache_task` CHANGE `xml` `xml` LONGBLOB NOT NULL;
+ALTER TABLE `kolab_cache_journal` CHANGE `xml` `xml` LONGBLOB NOT NULL;
+ALTER TABLE `kolab_cache_note` CHANGE `xml` `xml` LONGBLOB NOT NULL;
+ALTER TABLE `kolab_cache_file` CHANGE `xml` `xml` LONGBLOB NOT NULL;
+ALTER TABLE `kolab_cache_configuration` CHANGE `xml` `xml` LONGBLOB NOT NULL;
+ALTER TABLE `kolab_cache_freebusy` CHANGE `xml` `xml` LONGBLOB NOT NULL;
diff --git a/lib/plugins/libkolab/lib/kolab_date_recurrence.php b/lib/plugins/libkolab/lib/kolab_date_recurrence.php
index 3aaa399..85ffd91 100644
--- a/lib/plugins/libkolab/lib/kolab_date_recurrence.php
+++ b/lib/plugins/libkolab/lib/kolab_date_recurrence.php
@@ -101,16 +101,35 @@ class kolab_date_recurrence
/**
* Get the end date of the occurence of this recurrence cycle
*
- * @param string Date limit (where infinite recurrences should abort)
* @return mixed Timestamp with end date of the last event or False if recurrence exceeds limit
*/
- public function end($limit = 'now +1 year')
+ public function end()
{
- $limit_dt = new DateTime($limit);
- if ($this->engine && ($cend = $this->engine->getLastOccurrence()) && ($end_dt = kolab_format::php_datetime(new cDateTime($cend))) && $end_dt < $limit_dt) {
+ $event = $this->object->to_array();
+
+ // recurrence end date is given
+ if ($event['recurrence']['UNTIL'] instanceof DateTime) {
+ return $event['recurrence']['UNTIL']->format('U');
+ }
+
+ // let libkolab do the work
+ if ($this->engine && ($cend = $this->engine->getLastOccurrence()) && ($end_dt = kolab_format::php_datetime(new cDateTime($cend)))) {
return $end_dt->format('U');
}
+ // determine a reasonable end date if none given
+ if (!$event['recurrence']['COUNT']) {
+ switch ($event['recurrence']['FREQ']) {
+ case 'YEARLY': $intvl = 'P100Y'; break;
+ case 'MONTHLY': $intvl = 'P20Y'; break;
+ default: $intvl = 'P10Y'; break;
+ }
+
+ $end_dt = clone $event['start'];
+ $end_dt->add(new DateInterval($intvl));
+ return $end_dt->format('U');
+ }
+
return false;
}
}
diff --git a/lib/plugins/libkolab/lib/kolab_format.php b/lib/plugins/libkolab/lib/kolab_format.php
index 5bcc57a..679ae10 100644
--- a/lib/plugins/libkolab/lib/kolab_format.php
+++ b/lib/plugins/libkolab/lib/kolab_format.php
@@ -123,7 +123,7 @@ abstract class kolab_format
if (!$dateonly)
$result->setTime($datetime->format('G'), $datetime->format('i'), $datetime->format('s'));
- if ($tz && $tz->getName() == 'UTC')
+ if ($tz && in_array($tz->getName(), array('UTC', 'GMT', '+00:00', 'Z')))
$result->setUTC(true);
else if ($tz !== false)
$result->setTimezone($tz->getName());
@@ -401,13 +401,13 @@ abstract class kolab_format
// set some automatic values if missing
if (empty($object['created']) && method_exists($this->obj, 'setCreated')) {
$cdt = $this->obj->created();
- $object['created'] = $cdt && $cdt->isValid() ? self::php_datetime($cdt) : new DateTime('now', self::$timezone);
+ $object['created'] = $cdt && $cdt->isValid() ? self::php_datetime($cdt) : new DateTime('now', new DateTimeZone('UTC'));
if (!$cdt || !$cdt->isValid())
$this->obj->setCreated(self::get_datetime($object['created']));
}
- $object['changed'] = new DateTime('now', self::$timezone);
- $this->obj->setLastModified(self::get_datetime($object['changed'], new DateTimeZone('UTC')));
+ $object['changed'] = new DateTime('now', new DateTimeZone('UTC'));
+ $this->obj->setLastModified(self::get_datetime($object['changed']));
// Save custom properties of the given object
if (isset($object['x-custom'])) {
diff --git a/lib/plugins/libkolab/lib/kolab_format_event.php b/lib/plugins/libkolab/lib/kolab_format_event.php
index 9be9bdf..6a8c3ae 100644
--- a/lib/plugins/libkolab/lib/kolab_format_event.php
+++ b/lib/plugins/libkolab/lib/kolab_format_event.php
@@ -163,20 +163,22 @@ class kolab_format_event extends kolab_format_xcal
else if ($status == kolabformat::StatusCancelled)
$object['cancelled'] = true;
+ // this is an exception object
+ if ($this->obj->recurrenceID()->isValid()) {
+ $object['thisandfuture'] = $this->obj->thisAndFuture();
+ }
// read exception event objects
- if (($exceptions = $this->obj->exceptions()) && is_object($exceptions) && $exceptions->size()) {
+ else if (($exceptions = $this->obj->exceptions()) && is_object($exceptions) && $exceptions->size()) {
+ $recurrence_exceptions = array();
for ($i=0; $i < $exceptions->size(); $i++) {
if (($exobj = $exceptions->get($i))) {
$exception = new kolab_format_event($exobj);
if ($exception->is_valid()) {
- $object['recurrence']['EXCEPTIONS'][] = $this->expand_exception($exception->to_array(), $object);
+ $recurrence_exceptions[] = $this->expand_exception($exception->to_array(), $object);
}
}
}
- }
- // this is an exception object
- else if ($this->obj->recurrenceID()->isValid()) {
- $object['thisandfuture'] = $this->obj->thisAndFuture();
+ $object['recurrence']['EXCEPTIONS'] = $recurrence_exceptions;
}
return $this->data = $object;
diff --git a/lib/plugins/libkolab/lib/kolab_storage.php b/lib/plugins/libkolab/lib/kolab_storage.php
index 5f8b9c6..3d1dccb 100644
--- a/lib/plugins/libkolab/lib/kolab_storage.php
+++ b/lib/plugins/libkolab/lib/kolab_storage.php
@@ -433,13 +433,14 @@ class kolab_storage
// get username
$pos = strpos($folder, $delim);
if ($pos) {
- $prefix = '('.substr($folder, 0, $pos).') ';
+ $prefix = '('.substr($folder, 0, $pos).')';
$folder = substr($folder, $pos+1);
}
else {
- $prefix = '('.$folder.')';
+ $prefix = $folder;
$folder = '';
}
+
$found = true;
$folder_ns = 'other';
break;
@@ -467,7 +468,7 @@ class kolab_storage
$folder = str_replace(html::quote($delim), ' » ', $folder);
if ($prefix)
- $folder = html::quote($prefix) . ' ' . $folder;
+ $folder = html::quote($prefix) . ($folder !== '' ? ' ' . $folder : '');
if (!$folder_ns)
$folder_ns = 'personal';
@@ -492,7 +493,8 @@ class kolab_storage
}
/**
- * Helper method to generate a truncated folder name to display
+ * Helper method to generate a truncated folder name to display.
+ * Note: $origname is a string returned by self::object_name()
*/
public static function folder_displayname($origname, &$names)
{
@@ -504,10 +506,29 @@ class kolab_storage
$length = strlen($names[$i] . ' » ');
$prefix = substr($name, 0, $length);
$count = count(explode(' » ', $prefix));
- $name = str_repeat(' ', $count-1) . '» ' . substr($name, $length);
+ $diff = 1;
+
+ // check if prefix folder is in other users namespace
+ for ($n = count($names)-1; $n >= 0; $n--) {
+ if (strpos($prefix, '(' . $names[$n] . ') ') === 0) {
+ $diff = 0;
+ break;
+ }
+ }
+
+ $name = str_repeat(' ', $count - $diff) . '» ' . substr($name, $length);
+ break;
+ }
+ // other users namespace and parent folder exists
+ else if (strpos($name, '(' . $names[$i] . ') ') === 0) {
+ $length = strlen('(' . $names[$i] . ') ');
+ $prefix = substr($name, 0, $length);
+ $count = count(explode(' » ', $prefix));
+ $name = str_repeat(' ', $count) . '» ' . substr($name, $length);
break;
}
}
+
$names[] = $origname;
return $name;
@@ -525,8 +546,8 @@ class kolab_storage
*/
public static function folder_selector($type, $attrs, $current = '')
{
- // get all folders of specified type
- $folders = self::get_folders($type, false);
+ // get all folders of specified type (sorted)
+ $folders = self::get_folders($type, true);
$delim = self::$imap->get_hierarchy_delimiter();
$names = array();
@@ -540,13 +561,15 @@ class kolab_storage
// Filter folders list
foreach ($folders as $c_folder) {
$name = $c_folder->name;
+
// skip current folder and it's subfolders
if ($len && ($name == $current || strpos($name, $current.$delim) === 0)) {
continue;
}
// always show the parent of current folder
- if ($p_len && $name == $parent) { }
+ if ($p_len && $name == $parent) {
+ }
// skip folders where user have no rights to create subfolders
else if ($c_folder->get_owner() != $_SESSION['username']) {
$rights = $c_folder->get_myrights();
@@ -555,17 +578,14 @@ class kolab_storage
}
}
- $names[$name] = self::object_name($name);
- }
+ // Make sure parent folder is listed (might be skipped e.g. if it's namespace root)
+ if ($p_len && !isset($names[$parent]) && strpos($name, $parent.$delim) === 0) {
+ $names[$parent] = self::object_name($parent);
+ }
- // Make sure parent folder is listed (might be skipped e.g. if it's namespace root)
- if ($p_len && !isset($names[$parent])) {
- $names[$parent] = self::object_name($parent);
+ $names[$name] = self::object_name($name);
}
- // Sort folders list
- asort($names, SORT_LOCALE_STRING);
-
// Build SELECT field of parent folder
$attrs['is_escaped'] = true;
$select = new html_select($attrs);
@@ -643,7 +663,8 @@ class kolab_storage
unset($folderdata[$folder]);
}
}
- return array_keys($folderdata);
+
+ return self::$imap->sort_folder_list(array_keys($folderdata), true);
}
// Get folders list
@@ -683,26 +704,74 @@ class kolab_storage
*/
public static function sort_folders($folders)
{
- $pad = ' ';
+ $pad = ' ';
+ $out = array();
$nsnames = array('personal' => array(), 'shared' => array(), 'other' => array());
+
foreach ($folders as $folder) {
$folders[$folder->name] = $folder;
$ns = $folder->get_namespace();
$nsnames[$ns][$folder->name] = strtolower(html_entity_decode(self::object_name($folder->name, $ns), ENT_COMPAT, RCUBE_CHARSET)) . $pad; // decode »
}
- $names = array();
- foreach ($nsnames as $ns => $dummy) {
- asort($nsnames[$ns], SORT_LOCALE_STRING);
- $names += $nsnames[$ns];
+ // $folders is a result of get_folders() we can assume folders were already sorted
+ foreach (array_keys($nsnames) as $ns) {
+ // asort($nsnames[$ns], SORT_LOCALE_STRING);
+ foreach (array_keys($nsnames[$ns]) as $utf7name) {
+ $out[] = $folders[$utf7name];
+ }
}
- $out = array();
- foreach ($names as $utf7name => $name) {
- $out[] = $folders[$utf7name];
+ return $out;
+ }
+
+
+ /**
+ * Check the folder tree and add the missing parents as virtual folders
+ *
+ * @param array $folders Folders list
+ *
+ * @return array Folders list
+ */
+ public static function folder_hierarchy($folders)
+ {
+ $_folders = array();
+ $existing = array_map(function($folder){ return $folder->get_name(); }, $folders);
+ $delim = rcube::get_instance()->get_storage()->get_hierarchy_delimiter();
+
+ foreach ($folders as $idx => $folder) {
+ $path = explode($delim, $folder->name);
+ array_pop($path);
+
+ // skip top folders or ones with a custom displayname
+ if (count($path) <= 1 || kolab_storage::custom_displayname($folder->name)) {
+ }
+ else {
+ $parents = array();
+
+ while (count($path) > 1 && ($parent = join($delim, $path))) {
+ $name = kolab_storage::object_name($parent, $folder->get_namespace());
+ if (!in_array($name, $existing)) {
+ $parents[$parent] = new virtual_kolab_storage_folder($parent, $name, $folder->get_namespace());
+ $existing[] = $name;
+ }
+
+ array_pop($path);
+ }
+
+ if (!empty($parents)) {
+ $parents = array_reverse(array_values($parents));
+ foreach ($parents as $parent) {
+ $_folders[] = $parent;
+ }
+ }
+ }
+
+ $_folders[] = $folder;
+ unset($folders[$idx]);
}
- return $out;
+ return $_folders;
}
@@ -1047,3 +1116,33 @@ class kolab_storage
}
}
+
+/**
+ * Helper class that represents a virtual IMAP folder
+ * with a subset of the kolab_storage_folder API.
+ */
+class virtual_kolab_storage_folder
+{
+ public $id;
+ public $name;
+ public $namespace;
+ public $virtual = true;
+
+ public function __construct($realname, $name, $ns)
+ {
+ $this->id = kolab_storage::folder_id($realname);
+ $this->name = $name;
+ $this->namespace = $ns;
+ }
+
+ public function get_namespace()
+ {
+ return $this->namespace;
+ }
+
+ public function get_name()
+ {
+ // this is already kolab_storage::object_name() result
+ return $this->name;
+ }
+}
diff --git a/lib/plugins/libkolab/lib/kolab_storage_cache.php b/lib/plugins/libkolab/lib/kolab_storage_cache.php
index 732ce8f..db174e5 100644
--- a/lib/plugins/libkolab/lib/kolab_storage_cache.php
+++ b/lib/plugins/libkolab/lib/kolab_storage_cache.php
@@ -117,6 +117,15 @@ class kolab_storage_cache
}
/**
+ * Getter for the numeric ID used in cache tables
+ */
+ public function get_folder_id()
+ {
+ $this->_read_folder_data();
+ return $this->folder_id;
+ }
+
+ /**
* Synchronize local cache data with remote
*/
public function synchronize()
@@ -133,7 +142,6 @@ class kolab_storage_cache
// check cache status hash first ($this->metadata is set in _read_folder_data())
if ($this->metadata['ctag'] != $this->folder->get_ctag()) {
-
// lock synchronization for this folder or wait if locked
$this->_sync_lock();
@@ -144,7 +152,7 @@ class kolab_storage_cache
$this->imap->folder_sync($this->folder->name);
// compare IMAP index with object cache index
- $imap_index = $this->imap->index($this->folder->name);
+ $imap_index = $this->imap->index($this->folder->name, null, null, true, true);
$this->index = $imap_index->get();
// determine objects to fetch or to invalidate
@@ -342,7 +350,7 @@ class kolab_storage_cache
$this->db->query(
"UPDATE $this->cache_table SET folder_id=?, msguid=? ".
"WHERE folder_id=? AND msguid=?",
- $target->folder_id,
+ $target->cache->get_folder_id(),
$new_msguid,
$this->folder_id,
$msguid
@@ -365,7 +373,7 @@ class kolab_storage_cache
$this->_read_folder_data();
$result = $this->db->query(
- "DELETE FROM $this->cache_table WHERE folder_id=?".
+ "DELETE FROM $this->cache_table WHERE folder_id=?",
$this->folder_id
);
return $this->db->affected_rows($result);
@@ -660,7 +668,9 @@ class kolab_storage_cache
}
}
- $sql_data['data'] = serialize($data);
+ // use base64 encoding (Bug #1912, #2662)
+ $sql_data['data'] = base64_encode(serialize($data));
+
return $sql_data;
}
@@ -669,8 +679,23 @@ class kolab_storage_cache
*/
protected function _unserialize($sql_arr)
{
+ // check if data is a base64-encoded string, for backward compat.
+ if (strpos(substr($sql_arr['data'], 0, 64), ':') === false) {
+ $sql_arr['data'] = base64_decode($sql_arr['data']);
+ }
+
$object = unserialize($sql_arr['data']);
+ // de-serialization failed
+ if ($object === false) {
+ rcube::raise_error(array(
+ 'code' => 900, 'type' => 'php',
+ 'message' => "Malformed data for {$this->resource_uri}/{$sql_arr['msguid']} object."
+ ), true);
+
+ return null;
+ }
+
// decode binary properties
foreach ($this->binary_items as $key => $regexp) {
if (!empty($object[$key]) && preg_match($regexp, $sql_arr['xml'], $m)) {
@@ -679,10 +704,10 @@ class kolab_storage_cache
}
// add meta data
- $object['_type'] = $sql_arr['type'] ?: $this->folder->type;
- $object['_msguid'] = $sql_arr['msguid'];
- $object['_mailbox'] = $this->folder->name;
- $object['_size'] = strlen($sql_arr['xml']);
+ $object['_type'] = $sql_arr['type'] ?: $this->folder->type;
+ $object['_msguid'] = $sql_arr['msguid'];
+ $object['_mailbox'] = $this->folder->name;
+ $object['_size'] = strlen($sql_arr['xml']);
$object['_formatobj'] = kolab_format::factory($object['_type'], 3.0, $sql_arr['xml']);
return $object;
diff --git a/lib/plugins/libkolab/lib/kolab_storage_cache_event.php b/lib/plugins/libkolab/lib/kolab_storage_cache_event.php
index 69134e7..876c3b4 100644
--- a/lib/plugins/libkolab/lib/kolab_storage_cache_event.php
+++ b/lib/plugins/libkolab/lib/kolab_storage_cache_event.php
@@ -41,7 +41,7 @@ class kolab_storage_cache_event extends kolab_storage_cache
// extend date range for recurring events
if ($object['recurrence'] && $object['_formatobj']) {
$recurrence = new kolab_date_recurrence($object['_formatobj']);
- $sql_data['dtend'] = date('Y-m-d 23:59:59', $recurrence->end() ?: strtotime('now +1 year'));
+ $sql_data['dtend'] = date('Y-m-d 23:59:59', $recurrence->end() ?: strtotime('now +10 years'));
}
return $sql_data;
diff --git a/lib/plugins/libkolab/lib/kolab_storage_folder.php b/lib/plugins/libkolab/lib/kolab_storage_folder.php
index 80f13fc..12da5e9 100644
--- a/lib/plugins/libkolab/lib/kolab_storage_folder.php
+++ b/lib/plugins/libkolab/lib/kolab_storage_folder.php
@@ -280,7 +280,7 @@ class kolab_storage_folder
}
// generate a folder UID and set it to IMAP
- $uid = rtrim(chunk_split(md5($this->name . $this->get_owner()), 12, '-'), '-');
+ $uid = rtrim(chunk_split(md5($this->name . $this->get_owner() . uniqid('-', true)), 12, '-'), '-');
$this->set_uid($uid);
return $uid;
@@ -764,6 +764,7 @@ class kolab_storage_folder
// update cache with new UID
if ($result) {
$object['_msguid'] = $result;
+ $object['_mailbox'] = $this->name;
$this->cache->insert($result, $object);
// remove temp file
More information about the commits
mailing list