From a128fafbe8ba5657f0c2cbc6dd2caeba79d4ad4c Mon Sep 17 00:00:00 2001
From: alecpl <alec@alec.pl>
Date: Tue, 03 Jan 2012 04:57:14 -0500
Subject: [PATCH] - Backport r5689 from trunk

---
 program/include/rcube_imap.php |   88 +++++++++++++++++++++++++++++++++++++++----
 1 files changed, 79 insertions(+), 9 deletions(-)

diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php
index 8c1fab8..514d11b 100644
--- a/program/include/rcube_imap.php
+++ b/program/include/rcube_imap.php
@@ -1373,6 +1373,11 @@
         $this->_messagecount($mailbox, 'ALL', true);
 
         $result = 0;
+
+        if (empty($old)) {
+            return $result;
+        }
+
         $new = $this->get_folder_stats($mailbox);
 
         // got new messages
@@ -1631,6 +1636,7 @@
      * @param  string  $sort_field Header field to sort by
      * @return array   search results as list of message IDs
      * @access public
+     * @todo: Search criteria should be provided in non-IMAP format, eg. array
      */
     function search($mailbox='', $str=NULL, $charset=NULL, $sort_field=NULL)
     {
@@ -1716,7 +1722,7 @@
             // Error, try with US-ASCII (some servers may support only US-ASCII)
             if ($a_messages === false && $charset && $charset != 'US-ASCII')
                 $a_messages = $this->conn->search($mailbox,
-                    'CHARSET US-ASCII ' . $this->convert_criteria($criteria, $charset));
+                    $this->convert_criteria($criteria, $charset));
 
             // I didn't found that SEARCH should return sorted IDs
             if (is_array($a_messages) && !$this->sort_field)
@@ -1770,9 +1776,9 @@
                 $string_offset = $m[1] + strlen($m[0]) + 4; // {}\r\n
                 $string = substr($str, $string_offset - 1, $m[0]);
                 $string = rcube_charset_convert($string, $charset, $dest_charset);
-                if (!$string)
+                if ($string === false)
                     continue;
-                $res .= sprintf("%s{%d}\r\n%s", substr($str, $last, $m[1] - $last - 1), strlen($string), $string);
+                $res .= substr($str, $last, $m[1] - $last - 1) . rcube_imap_generic::escape($string);
                 $last = $m[0] + $string_offset - 1;
             }
             if ($last < strlen($str))
@@ -2999,14 +3005,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
      */
@@ -3109,7 +3115,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)) {
@@ -3140,6 +3146,70 @@
         $this->update_cache($cache_key, $a_mboxes);
 
         return $a_mboxes;
+    }
+
+
+    /**
+     * 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 (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;
+                    }
+                }
+
+                // get folders in hidden namespaces and add to the result
+                foreach ($search as $prefix) {
+                    $list = $this->conn->listMailboxes($prefix, $name);
+
+                    if (!empty($list)) {
+                        $result = array_merge($result, $list);
+                    }
+                }
+            }
+        }
+
+        return $result;
     }
 
 
@@ -3415,8 +3485,8 @@
         foreach ($this->namespace as $type => $namespace) {
             if (is_array($namespace)) {
                 foreach ($namespace as $ns) {
-                    if (strlen($ns[0])) {
-                        if ((strlen($ns[0])>1 && $mailbox == substr($ns[0], 0, -1))
+                    if ($len = strlen($ns[0])) {
+                        if (($len > 1 && $mailbox == substr($ns[0], 0, -1))
                             || strpos($mailbox, $ns[0]) === 0
                         ) {
                             return $type;
@@ -4093,7 +4163,7 @@
         $input = preg_replace("/\?=\s+=\?/", '?==?', $input);
 
         // encoded-word regexp
-        $re = '/=\?([^?]+)\?([BbQq])\?([^?\n]*)\?=/';
+        $re = '/=\?([^?]+)\?([BbQq])\?([^\n]*?)\?=/';
 
         // Find all RFC2047's encoded words
         if (preg_match_all($re, $input, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {

--
Gitblit v1.9.1