From 89dcf540719af6fc7161c45d5bc11e171afa3697 Mon Sep 17 00:00:00 2001
From: alecpl <alec@alec.pl>
Date: Tue, 15 Nov 2011 03:23:24 -0500
Subject: [PATCH] - Fix listing of folders in hidden namespaces (#1486796)

---
 CHANGELOG                      |    1 
 program/include/rcube_imap.php |   70 +++++++++++++++++++++++++++++++++-
 2 files changed, 68 insertions(+), 3 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 4641795..ee8cb50 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,7 @@
 CHANGELOG Roundcube Webmail
 ===========================
 
+- Fix listing of folders in hidden namespaces (#1486796)
 - Don't consider \Noselect flag when building folders tree (#1488004)
 - Fix sorting autocomplete results (#1488084)
 - Add option to set session name (#1486433)
diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php
index 6f2e3d8..4fe39e1 100644
--- a/program/include/rcube_imap.php
+++ b/program/include/rcube_imap.php
@@ -3004,14 +3004,14 @@
 
 
     /**
-     * Private method for mailbox listing
+     * Private method for mailbox listing (LSUB)
      *
      * @param   string  $root   Optional root folder
      * @param   string  $name   Optional name pattern
      * @param   mixed   $filter Optional filter
      * @param   string  $rights Optional ACL requirements
      *
-     * @return  array   List of mailboxes/folders
+     * @return  array   List of subscribed folders
      * @see     rcube_imap::list_mailboxes()
      * @access  private
      */
@@ -3114,7 +3114,7 @@
         }
         else {
             // retrieve list of folders from IMAP server
-            $a_mboxes = $this->conn->listMailboxes($root, $name);
+            $a_mboxes = $this->_list_unsubscribed($root, $name);
         }
 
         if (!is_array($a_mboxes)) {
@@ -3149,6 +3149,70 @@
 
 
     /**
+     * Private method for mailbox listing (LIST)
+     *
+     * @param   string  $root   Optional root folder
+     * @param   string  $name   Optional name pattern
+     *
+     * @return  array   List of folders
+     * @see     rcube_imap::list_unsubscribed()
+     */
+    private function _list_unsubscribed($root='', $name='*')
+    {
+        $result = $this->conn->listMailboxes($root, $name);
+
+        if (!is_array($result)) {
+            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
+        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 ($len = strlen($ns_data[0])) {
+                            $search = array('len' => $len, 'prefix' => $ns_data[0]);
+                        }
+                    }
+                }
+            }
+
+            if (!empty($search)) {
+                // go through all folders detecting namespace usage
+                foreach ($list as $folder) {
+                    foreach ($search as $idx => $s) {
+                        if ($s['prefix'] == substr($folder, 0, $s['len'])) {
+                            unset($search[$idx]);
+                        }
+                    }
+                    if (empty($search)) {
+                        break;
+                    }
+                }
+
+                // get folders in hidden namespaces and add to the result
+                foreach ($search as $s) {
+                    $list = $this->conn->listMailboxes($s['prefix'], $name);
+
+                    if (!empty($list)) {
+                        $result = array_merge($result, $list);
+                    }
+                }
+            }
+        }
+
+        return $result;
+    }
+
+
+    /**
      * Filter the given list of folders according to access rights
      */
     private function filter_rights($a_folders, $rights)

--
Gitblit v1.9.1