From 0af82c8a59855d3010d935f3251a810d2a8cbe60 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Mon, 14 May 2012 19:25:09 +0200 Subject: Fix listing folders on Courier IMAP (#1488466) --- program/include/rcube_imap.php | 108 +++++++++++++++++++++++++++-------------- 1 file changed, 71 insertions(+), 37 deletions(-) (limited to 'program') diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php index 4cccd859a..20428ccc6 100644 --- a/program/include/rcube_imap.php +++ b/program/include/rcube_imap.php @@ -2524,11 +2524,30 @@ class rcube_imap extends rcube_storage // Server supports LIST-EXTENDED, we can use selection options // #1486225: Some dovecot versions returns wrong result using LIST-EXTENDED - if (!$config->get('imap_force_lsub') && $this->get_capability('LIST-EXTENDED')) { + $list_extended = !$config->get('imap_force_lsub') && $this->get_capability('LIST-EXTENDED'); + if ($list_extended) { // This will also set folder options, LSUB doesn't do that $a_folders = $this->conn->listMailboxes($root, $name, NULL, array('SUBSCRIBED')); + } + else { + // retrieve list of folders from IMAP server using LSUB + $a_folders = $this->conn->listSubscribed($root, $name); + } + + if (!is_array($a_folders)) { + return array(); + } + + // #1486796: some server configurations doesn't + // return folders in all namespaces, we'll try to detect that situation + // and ask for these namespaces separately + // @TODO: make this optional + if ($root == '' && $name == '*') { + $this->list_folders_update($a_folders, ($list_extended ? 'ext-' : '') . 'subscribed'); + } + if ($list_extended) { // unsubscribe non-existent folders, remove from the list // we can do this only when LIST response is available if (is_array($a_folders) && $name == '*' && !empty($this->conn->data['LIST'])) { @@ -2542,10 +2561,7 @@ class rcube_imap extends rcube_storage } } } - // retrieve list of folders from IMAP server using LSUB else { - $a_folders = $this->conn->listSubscribed($root, $name); - // unsubscribe non-existent folders, remove them from the list, // we can do this only when LIST response is available if (is_array($a_folders) && $name == '*' && !empty($this->conn->data['LIST'])) { @@ -2563,10 +2579,6 @@ class rcube_imap extends rcube_storage } } - if (!is_array($a_folders) || !sizeof($a_folders)) { - $a_folders = array(); - } - return $a_folders; } @@ -2664,47 +2676,69 @@ class rcube_imap extends rcube_storage // #1486796: some server configurations doesn't // return folders in all namespaces, we'll try to detect that situation // and ask for these namespaces separately + // @TODO: make this optional if ($root == '' && $name == '*') { - $delim = $this->get_hierarchy_delimiter(); - $namespace = $this->get_namespace(); - $search = array(); - - // build list of namespace prefixes - foreach ((array)$namespace as $ns) { - if (is_array($ns)) { - foreach ($ns as $ns_data) { - if (strlen($ns_data[0])) { - $search[] = $ns_data[0]; - } + $this->list_folders_update($result); + } + + return $result; + } + + + /** + * Fix folders list by adding folders from other namespaces. + * Needed on some servers eg. Courier IMAP + * + * @param array $result Reference to folders list + * @param string $type Listing type (ext-subscribed, subscribed or all) + */ + private function list_folders_update(&$result, $type = null) + { + $delim = $this->get_hierarchy_delimiter(); + $namespace = $this->get_namespace(); + $search = array(); + + // build list of namespace prefixes + foreach ((array)$namespace as $ns) { + if (is_array($ns)) { + foreach ($ns as $ns_data) { + if (strlen($ns_data[0])) { + $search[] = $ns_data[0]; } } } + } - if (!empty($search)) { - // go through all folders detecting namespace usage - foreach ($result as $folder) { - foreach ($search as $idx => $prefix) { - if (strpos($folder, $prefix) === 0) { - unset($search[$idx]); - } - } - if (empty($search)) { - break; + if (!empty($search)) { + // go through all folders detecting namespace usage + foreach ($result as $folder) { + foreach ($search as $idx => $prefix) { + if (strpos($folder, $prefix) === 0) { + unset($search[$idx]); } } + if (empty($search)) { + break; + } + } - // get folders in hidden namespaces and add to the result - foreach ($search as $prefix) { - $list = $this->conn->listMailboxes($prefix, $name); + // get folders in hidden namespaces and add to the result + foreach ($search as $prefix) { + if ($type == 'ext-subscribed') { + $list = $this->conn->listMailboxes('', $prefix . '*', null, array('SUBSCRIBED')); + } + else if ($type == 'subscribed') { + $list = $this->conn->listSubscribed('', $prefix . '*'); + } + else { + $list = $this->conn->listMailboxes('', $prefix . '*'); + } - if (!empty($list)) { - $result = array_merge($result, $list); - } + if (!empty($list)) { + $result = array_merge($result, $list); } } } - - return $result; } -- cgit v1.2.3 From 3c5489ba7547c88ba0f82b6ea0574d1a7185f416 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak Date: Mon, 21 May 2012 09:25:51 +0200 Subject: Add option imap_force_ns to make buggy servers support optional --- config/main.inc.php.dist | 4 ++++ plugins/subscriptions_option/package.xml | 4 ++-- plugins/subscriptions_option/subscriptions_option.php | 7 ++----- program/include/rcube_imap.php | 14 ++++---------- 4 files changed, 12 insertions(+), 17 deletions(-) (limited to 'program') diff --git a/config/main.inc.php.dist b/config/main.inc.php.dist index f5f42d7fb..e0fa933bf 100644 --- a/config/main.inc.php.dist +++ b/config/main.inc.php.dist @@ -106,6 +106,10 @@ $rcmail_config['imap_force_caps'] = false; // Enable this option to force LSUB command usage instead. $rcmail_config['imap_force_lsub'] = false; +// Some server configurations (e.g. Courier) doesn't list folders in all namespaces +// Enable this option to force listing of folders in all namespaces +$rcmail_config['imap_force_ns'] = false; + // IMAP connection timeout, in seconds. Default: 0 (no limit) $rcmail_config['imap_timeout'] = 0; diff --git a/plugins/subscriptions_option/package.xml b/plugins/subscriptions_option/package.xml index 1ecabf711..79d44f8c2 100644 --- a/plugins/subscriptions_option/package.xml +++ b/plugins/subscriptions_option/package.xml @@ -23,9 +23,9 @@ ziba@umich.edu yes - 2012-03-05 + 2012-05-21 - 1.2 + 1.3 1.1 diff --git a/plugins/subscriptions_option/subscriptions_option.php b/plugins/subscriptions_option/subscriptions_option.php index 28f826263..8b27afbdc 100644 --- a/plugins/subscriptions_option/subscriptions_option.php +++ b/plugins/subscriptions_option/subscriptions_option.php @@ -74,12 +74,9 @@ class subscriptions_option extends rcube_plugin function mailboxes_list($args) { - $rcmail = rcmail::get_instance(); + $rcmail = rcmail::get_instance(); if (!$rcmail->config->get('use_subscriptions', true)) { - $storage = $rcmail->get_storage(); - if ($storage->check_connection()) { - $args['folders'] = $storage->conn->listMailboxes($args['root'], $args['name']); - } + $args['folders'] = $rcmail->get_storage()->list_folders_direct(); } return $args; } diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php index 20428ccc6..f401f3707 100644 --- a/program/include/rcube_imap.php +++ b/program/include/rcube_imap.php @@ -2539,11 +2539,8 @@ class rcube_imap extends rcube_storage return array(); } - // #1486796: some server configurations doesn't - // return folders in all namespaces, we'll try to detect that situation - // and ask for these namespaces separately - // @TODO: make this optional - if ($root == '' && $name == '*') { + // #1486796: some server configurations doesn't return folders in all namespaces + if ($root == '' && $name == '*' && $config->get('imap_force_ns')) { $this->list_folders_update($a_folders, ($list_extended ? 'ext-' : '') . 'subscribed'); } @@ -2673,11 +2670,8 @@ class rcube_imap extends rcube_storage return array(); } - // #1486796: some server configurations doesn't - // return folders in all namespaces, we'll try to detect that situation - // and ask for these namespaces separately - // @TODO: make this optional - if ($root == '' && $name == '*') { + // #1486796: some server configurations doesn't return folders in all namespaces + if ($root == '' && $name == '*' && $config->get('imap_force_ns')) { $this->list_folders_update($result); } -- cgit v1.2.3