Branch 'dev/new-foldernav' - 2 commits - plugins/calendar plugins/libkolab plugins/tasklist
Thomas Brüderli
bruederli at kolabsys.com
Fri May 23 09:00:53 CEST 2014
plugins/calendar/drivers/kolab/kolab_calendar.php | 3
plugins/calendar/drivers/kolab/kolab_driver.php | 2
plugins/calendar/drivers/kolab/kolab_user_calendar.php | 3
plugins/libkolab/config.inc.php.dist | 4
plugins/libkolab/lib/kolab_storage.php | 112 +++++++++++++--
plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php | 6
plugins/tasklist/tasklist.js | 2
7 files changed, 120 insertions(+), 12 deletions(-)
New commits:
commit d9247aa5e55259c20dc474bd8ab157d3b6bf2724
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Fri May 23 09:00:46 2014 +0200
Add config option to exclude certain namespaces from grouware folder listing
diff --git a/plugins/calendar/drivers/kolab/kolab_driver.php b/plugins/calendar/drivers/kolab/kolab_driver.php
index a95e1c2..4df2d85 100644
--- a/plugins/calendar/drivers/kolab/kolab_driver.php
+++ b/plugins/calendar/drivers/kolab/kolab_driver.php
@@ -79,7 +79,7 @@ class kolab_driver extends calendar_driver
return $this->calendars;
// get all folders that have "event" type, sorted by namespace/name
- $folders = kolab_storage::sort_folders(kolab_storage::get_folders('event') + kolab_storage::get_user_folders(true));
+ $folders = kolab_storage::sort_folders(kolab_storage::get_folders('event') + kolab_storage::get_user_folders('event', true));
$this->calendars = array();
foreach ($folders as $folder) {
diff --git a/plugins/libkolab/config.inc.php.dist b/plugins/libkolab/config.inc.php.dist
index 3a3c287..fd8ac84 100644
--- a/plugins/libkolab/config.inc.php.dist
+++ b/plugins/libkolab/config.inc.php.dist
@@ -16,6 +16,10 @@ $rcmail_config['kolab_freebusy_server'] = 'https://<some-host>/<freebusy-path>';
// folders in calendar view or available addressbooks
$rcmail_config['kolab_use_subscriptions'] = false;
+// List any of 'personal','shared','other' namespaces to be excluded from groupware folder listing
+// example: array('other');
+$rcmail_config['kolab_skip_namespace'] = null;
+
// Enables the use of displayname folder annotations as introduced in KEP:?
// for displaying resource folder names (experimental!)
$rcmail_config['kolab_custom_display_names'] = false;
diff --git a/plugins/libkolab/lib/kolab_storage.php b/plugins/libkolab/lib/kolab_storage.php
index 4266fb5..1fd3d58 100644
--- a/plugins/libkolab/lib/kolab_storage.php
+++ b/plugins/libkolab/lib/kolab_storage.php
@@ -40,7 +40,9 @@ class kolab_storage
public static $encode_ids = false;
private static $ready = false;
+ private static $with_tempsubs = true;
private static $subscriptions;
+ private static $typedata = array();
private static $states;
private static $config;
private static $imap;
@@ -313,7 +315,7 @@ class kolab_storage
}
}
- return '/';
+ return '';
}
@@ -748,11 +750,12 @@ class kolab_storage
if ($subscribed) {
$folders = self::$imap->list_folders_subscribed($root, $mbox);
// add temporarily subscribed folders
- if (is_array($_SESSION['kolab_subscribed_folders']))
+ if (self::$with_tempsubs && is_array($_SESSION['kolab_subscribed_folders'])) {
$folders = array_unique(array_merge($folders, $_SESSION['kolab_subscribed_folders']));
+ }
}
else {
- $folders = self::$imap->list_folders($root, $mbox);
+ $folders = self::_imap_list_folders($root, $mbox);
}
return $folders;
@@ -784,11 +787,11 @@ class kolab_storage
$folders = self::$imap->list_folders_subscribed($root, $mbox);
// add temporarily subscribed folders
- if (is_array($_SESSION['kolab_subscribed_folders']))
+ if (self::$with_tempsubs && is_array($_SESSION['kolab_subscribed_folders']))
$folders = array_unique(array_merge($folders, $_SESSION['kolab_subscribed_folders']));
}
else {
- $folders = self::$imap->list_folders($root, $mbox);
+ $folders = self::_imap_list_folders($root, $mbox);
}
// In case of an error, return empty list (?)
@@ -798,6 +801,11 @@ class kolab_storage
// Filter folders list
foreach ($folders as $idx => $folder) {
+ // lookup folder type
+ if (!array_key_exists($folder, $folderdata)) {
+ $folderdata[$folder] = self::folder_type($folder);
+ }
+
$type = $folderdata[$folder];
if ($filter == 'mail' && empty($type)) {
@@ -811,6 +819,38 @@ class kolab_storage
return $folders;
}
+ /**
+ * Wrapper for rcube_imap::list_folders() with optional post-filtering
+ */
+ protected static function _imap_list_folders($root, $mbox)
+ {
+ $postfilter = null;
+
+ // compose a post-filter expression for the excluded namespaces
+ if ($root . $mbox == '*' && ($skip_ns = self::$config->get('kolab_skip_namespace'))) {
+ $excludes = array();
+ foreach ((array)$skip_ns as $ns) {
+ if ($ns_root = self::namespace_root($ns)) {
+ $excludes[] = $ns_root;
+ }
+ }
+
+ if (count($excludes)) {
+ $postfilter = '!^(' . join(')|(', array_map('preg_quote', $excludes)) . ')!';
+ }
+ }
+
+ // use normal LIST command to return all folders, it's fast enough
+ $folders = self::$imap->list_folders($root, $mbox, null, null, !empty($postfilter));
+
+ if (!empty($postfilter)) {
+ $folders = array_filter($folders, function($folder) use ($postfilter) { return !preg_match($postfilter, $folder); });
+ $folders = self::$imap->sort_folder_list($folders);
+ }
+
+ return $folders;
+ }
+
/**
* Search for shared or otherwise not listed groupware folders the user has access
@@ -959,13 +999,54 @@ class kolab_storage
return false;
}
- $folderdata = self::$imap->get_metadata($prefix, array(self::CTYPE_KEY, self::CTYPE_KEY_PRIVATE));
+ // return cached result
+ if (is_array(self::$typedata[$prefix])) {
+ return self::$typedata[$prefix];
+ }
+
+ $type_keys = array(self::CTYPE_KEY, self::CTYPE_KEY_PRIVATE);
+
+ // fetch metadata from *some* folders only
+ if (($prefix == '*' || $prefix == '') && ($skip_ns = self::$config->get('kolab_skip_namespace'))) {
+ $delimiter = self::$imap->get_hierarchy_delimiter();
+ $folderdata = $blacklist = array();
+ foreach ((array)$skip_ns as $ns) {
+ if ($ns_root = rtrim(self::namespace_root($ns), $delimiter)) {
+ $blacklist[] = $ns_root;
+ }
+ }
+ foreach (array('personal','other','shared') as $ns) {
+ if (!in_array($ns, (array)$skip_ns)) {
+ $ns_root = rtrim(self::namespace_root($ns), $delimiter);
+
+ // list top-level folders and their childs one by one
+ // GETMETADATA "%" doesn't list shared or other namespace folders but "*" would
+ if ($ns_root == '') {
+ foreach ((array)self::$imap->get_metadata('%', $type_keys) as $folder => $metadata) {
+ if (!in_array($folder, $blacklist)) {
+ $folderdata[$folder] = $metadata;
+ $folderdata += self::$imap->get_metadata($folder.$delimiter.'*', $type_keys);
+ }
+ }
+ }
+ else {
+ $folderdata += self::$imap->get_metadata($ns_root.$delimiter.'*', $type_keys);
+ }
+ }
+ }
+ }
+ else {
+ $folderdata = self::$imap->get_metadata($prefix, $type_keys);
+ }
if (!is_array($folderdata)) {
return false;
}
- return array_map(array('kolab_storage', 'folder_select_metadata'), $folderdata);
+ // keep list in memory
+ self::$typedata[$prefix] = array_map(array('kolab_storage', 'folder_select_metadata'), $folderdata);
+
+ return self::$typedata[$prefix];
}
@@ -996,6 +1077,11 @@ class kolab_storage
{
self::setup();
+ // return in-memory cached result
+ if (is_array(self::$typedata['*']) && array_key_exists($folder, self::$typedata['*'])) {
+ return self::$typedata['*'][$folder];
+ }
+
$metadata = self::$imap->get_metadata($folder, array(self::CTYPE_KEY, self::CTYPE_KEY_PRIVATE));
if (!is_array($metadata)) {
@@ -1045,7 +1131,9 @@ class kolab_storage
{
if (self::$subscriptions === null) {
self::setup();
+ self::$with_tempsubs = false;
self::$subscriptions = self::$imap->list_folders_subscribed();
+ self::$with_tempsubs = true;
}
return in_array($folder, self::$subscriptions) ||
@@ -1177,7 +1265,9 @@ class kolab_storage
else {
self::setup();
if (self::$subscriptions === null) {
+ self::$with_tempsubs = false;
self::$subscriptions = self::$imap->list_folders_subscribed();
+ self::$with_tempsubs = true;
}
self::$states = self::$subscriptions;
$folders = implode(self::$states, '**');
@@ -1372,8 +1462,9 @@ class kolab_storage
if (!empty($user[$user_attrib])) {
list($mbox) = explode('@', $user[$user_attrib]);
+ $delimiter = self::$imap->get_hierarchy_delimiter();
$other_ns = self::namespace_root('other');
- $folders = self::list_folders($other_ns . $mbox, '*', $type, $subscribed, $folderdata);
+ $folders = self::list_folders($other_ns . $mbox . $delimiter, '*', $type, $subscribed, $folderdata);
}
return $folders;
@@ -1383,11 +1474,12 @@ class kolab_storage
/**
* Get a list of (virtual) top-level folders from the other users namespace
*
+ * @param string Data type to list folders for (contact,event,task,journal,file,note,mail,configuration)
* @param boolean Enable to return subscribed folders only (null to use configured subscription mode)
*
* @return array List of kolab_storage_folder_user objects
*/
- public static function get_user_folders($subscribed)
+ public static function get_user_folders($type, $subscribed)
{
$folders = $folderdata = array();
@@ -1396,7 +1488,7 @@ class kolab_storage
$other_ns = rtrim(self::namespace_root('other'), $delimiter);
$path_len = count(explode($delimiter, $other_ns));
- foreach ((array)self::list_folders($other_ns, '*', '', $subscribed) as $foldername) {
+ foreach ((array)self::list_folders($other_ns, '*', $type, $subscribed) as $foldername) {
if ($foldername == 'INBOX') // skip INBOX which is added by default
continue;
commit 95491f0886228da853fd48257e1dfabc400bbea1
Author: Thomas Bruederli <bruederli at kolabsys.com>
Date: Thu May 22 19:00:49 2014 +0200
Don't write session data when fetching events/tasks
diff --git a/plugins/calendar/drivers/kolab/kolab_calendar.php b/plugins/calendar/drivers/kolab/kolab_calendar.php
index 3e5d28a..79df28a 100644
--- a/plugins/calendar/drivers/kolab/kolab_calendar.php
+++ b/plugins/calendar/drivers/kolab/kolab_calendar.php
@@ -302,6 +302,9 @@ class kolab_calendar extends kolab_storage_folder_api
}
}
+ // avoid session race conditions that will loose temporary subscriptions
+ $this->cal->rc->session->nowrite();
+
return $events;
}
diff --git a/plugins/calendar/drivers/kolab/kolab_user_calendar.php b/plugins/calendar/drivers/kolab/kolab_user_calendar.php
index 1ab8679..dc9bcf7 100644
--- a/plugins/calendar/drivers/kolab/kolab_user_calendar.php
+++ b/plugins/calendar/drivers/kolab/kolab_user_calendar.php
@@ -222,6 +222,9 @@ class kolab_user_calendar extends kolab_calendar
}
}
+ // avoid session race conditions that will loose temporary subscriptions
+ $this->cal->rc->session->nowrite();
+
return $events;
}
diff --git a/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php b/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php
index 50fa371..90c3048 100644
--- a/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php
+++ b/plugins/tasklist/drivers/kolab/tasklist_kolab_driver.php
@@ -481,6 +481,9 @@ class tasklist_kolab_driver extends tasklist_driver
}
}
+ // avoid session race conditions that will loose temporary subscriptions
+ $this->plugin->rc->session->nowrite();
+
return $counts;
}
@@ -537,6 +540,9 @@ class tasklist_kolab_driver extends tasklist_driver
}
}
+ // avoid session race conditions that will loose temporary subscriptions
+ $this->plugin->rc->session->nowrite();
+
return $results;
}
diff --git a/plugins/tasklist/tasklist.js b/plugins/tasklist/tasklist.js
index 75ba386..76d50d5 100644
--- a/plugins/tasklist/tasklist.js
+++ b/plugins/tasklist/tasklist.js
@@ -164,7 +164,7 @@ function rcube_tasklist_ui(settings)
var prop = { id:p.id, active:list.active?1:0 };
if (list.subscribed) prop.permanent = 1;
rcmail.http_post('tasklist', { action:'subscribe', l:prop });
- setTimeout(function(){ list_tasks(); }, 500);
+ list_tasks();
}
});
More information about the commits
mailing list