From f0485adef1cd9b0d65bcbdd25bc546a2dff4095b Mon Sep 17 00:00:00 2001
From: alecpl <alec@alec.pl>
Date: Wed, 28 Apr 2010 08:24:48 -0400
Subject: [PATCH] - Fix folder subscription checking (#1486684) - Fix INBOX appears (sometimes) twice in mailbox list (#1486672)

---
 CHANGELOG                              |    2 
 program/include/rcube_imap.php         |   23 ++++---
 program/include/rcmail.php             |    2 
 program/include/rcube_imap_generic.php |  103 ++++++++-------------------------
 4 files changed, 43 insertions(+), 87 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index b1b053b..a8bb672 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,8 @@
 CHANGELOG RoundCube Webmail
 ===========================
 
+- Fix folder subscription checking (#1486684)
+- Fix INBOX appears (sometimes) twice in mailbox list (#1486672)
 - Fix listing of attachments of some types e.g. "x-epoc/x-sisx-app" (#1486653)
 - Fix DB Schema checking when some db_table_* options are not set (#1486654)
 
diff --git a/program/include/rcmail.php b/program/include/rcmail.php
index 1934535..e657abe 100644
--- a/program/include/rcmail.php
+++ b/program/include/rcmail.php
@@ -640,7 +640,7 @@
       else {
         raise_error(array(
           'code' => 600, 'type' => 'php',
-	  'file' => __FILE__, 'line' => __LINE__,
+	      'file' => __FILE__, 'line' => __LINE__,
           'message' => "Failed to create a user record. Maybe aborted by a plugin?"
           ), true, false);
       }
diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php
index 7a1ce47..f5b1728 100644
--- a/program/include/rcube_imap.php
+++ b/program/include/rcube_imap.php
@@ -2482,10 +2482,10 @@
         $a_out = array();
         $a_mboxes = $this->_list_mailboxes($root, $filter);
 
-        foreach ($a_mboxes as $mbox_row) {
-            $name = $this->mod_mailbox($mbox_row, 'out');
-            if (strlen($name))
+        foreach ($a_mboxes as $idx => $mbox_row) {
+            if ($name = $this->mod_mailbox($mbox_row, 'out'))
                 $a_out[] = $name;
+            unset($a_mboxes[$idx]);
         }
 
         // INBOX should always be available
@@ -2554,10 +2554,15 @@
         $a_mboxes = $this->conn->listMailboxes($this->mod_mailbox($root), '*');
 
         // modify names with root dir
-        foreach ($a_mboxes as $mbox_name) {
+        foreach ($a_mboxes as $idx => $mbox_name) {
             if ($name = $this->mod_mailbox($mbox_name, 'out'))
                 $a_folders[] = $name;
+            unset($a_mboxes[$idx]);
         }
+
+        // INBOX should always be available
+        if (!in_array('INBOX', $a_folders))
+            array_unshift($a_folders, 'INBOX');
 
         // filter folders and sort them
         $a_folders = $this->_sort_mailbox_list($a_folders);
@@ -2708,7 +2713,7 @@
             foreach ($a_mboxes as $mbox_name) {
                 $mailbox = $this->mod_mailbox($mbox_name);
                 $sub_mboxes = $this->conn->listMailboxes($this->mod_mailbox(''),
-	            $mbox_name . $this->delimiter . '*');
+	                $mbox_name . $this->delimiter . '*');
 
                 // unsubscribe mailbox before deleting
                 $this->conn->unsubscribe($mailbox);
@@ -2770,13 +2775,13 @@
                 return true;
 
             if ($subscription) {
-                if ($a_folders = $this->conn->listSubscribed($this->mod_mailbox(''), $mbox_name))
-                    return true;
+                $a_folders = $this->conn->listSubscribed($this->mod_mailbox(''), $mbox_name);
             }
             else {
                 $a_folders = $this->conn->listMailboxes($this->mod_mailbox(''), $mbox_name);
-	
-	        if (is_array($a_folders) && in_array($this->mod_mailbox($mbox_name), $a_folders))
+	        }
+	        
+            if (is_array($a_folders) && in_array($this->mod_mailbox($mbox_name), $a_folders)) {
                 return true;
             }
         }
diff --git a/program/include/rcube_imap_generic.php b/program/include/rcube_imap_generic.php
index 383211a..659a613 100644
--- a/program/include/rcube_imap_generic.php
+++ b/program/include/rcube_imap_generic.php
@@ -1612,6 +1612,16 @@
 
     function listMailboxes($ref, $mailbox)
     {
+        return $this->_listMailboxes($ref, $mailbox, false);
+    }
+
+    function listSubscribed($ref, $mailbox)
+    {
+        return $this->_listMailboxes($ref, $mailbox, true);
+    }
+
+    private function _listMailboxes($ref, $mailbox, $subscribed=false)
+    {
 		if (empty($mailbox)) {
 	        $mailbox = '*';
 	    }
@@ -1620,105 +1630,44 @@
 	        $ref = $this->rootdir;
 	    }
     
+        if ($subscribed) {
+            $key     = 'lsb';
+            $command = 'LSUB';
+        }
+        else {
+            $key     = 'lmb';
+            $command = 'LIST';
+        }
+
     	// send command
-	    if (!$this->putLine("lmb LIST \"". $this->escape($ref) ."\" \"". $this->escape($mailbox) ."\"")) {
+	    if (!$this->putLine($key." ".$command." \"". $this->escape($ref) ."\" \"". $this->escape($mailbox) ."\"")) {
+		    $this->error = "Couldn't send $command command";
 	        return false;
 	    }
     
-	    $i = 0;
 	    // get folder list
 	    do {
 		    $line = $this->readLine(500);
 		    $line = $this->multLine($line, true);
+		    $a    = explode(' ', $line);
 
-		    $a = explode(' ', $line);
-		    if (($line[0] == '*') && ($a[1] == 'LIST')) {
+		    if (($line[0] == '*') && ($a[1] == $command)) {
 			    $line = rtrim($line);
         		// split one line
 			    $a = rcube_explode_quoted_string(' ', $line);
         		// last string is folder name
-			    $folders[$i] = preg_replace(array('/^"/', '/"$/'), '', $this->unEscape($a[count($a)-1]));
+			    $folders[] = preg_replace(array('/^"/', '/"$/'), '', $this->unEscape($a[count($a)-1]));
 		        // second from last is delimiter
         		$delim = trim($a[count($a)-2], '"');
-        		// is it a container?
-        		$i++;
 		    }
-	    } while (!$this->startsWith($line, 'lmb', true));
+	    } while (!$this->startsWith($line, $key, true));
 
 	    if (is_array($folders)) {
-    	    if (!empty($ref)) {
-            	// if rootdir was specified, make sure it's the first element
-        	    // some IMAP servers (i.e. Courier) won't return it
-            	if ($ref[strlen($ref)-1]==$delim)
-	    	        $ref = substr($ref, 0, strlen($ref)-1);
-    	    	if ($folders[0]!=$ref)
-		            array_unshift($folders, $ref);
-    	    }
     	    return $folders;
 	    } else if ($this->parseResult($line) == 0) {
-		    return array('INBOX');
+            return array();
         }
 
-	    $this->error = $line;
-    	return false;
-    }
-
-    function listSubscribed($ref, $mailbox)
-    {
-	    if (empty($mailbox)) {
-		    $mailbox = '*';
-	    }
-	    if (empty($ref) && $this->rootdir) {
-		    $ref = $this->rootdir;
-	    }
-
-	    $folders = array();
-
-    	// send command
-	    if (!$this->putLine('lsb LSUB "'. $this->escape($ref) . '" "' . $this->escape($mailbox).'"')) {
-		    $this->error = "Couldn't send LSUB command";
-		    return false;
-	    }
-	
-    	$i = 0;
-	
-	    // get folder list
-	    do {
-		    $line = $this->readLine(500);
-    		$line = $this->multLine($line, true);
-	    	$a    = explode(' ', $line);
-        
-		    if (($line[0] == '*') && ($a[1] == 'LSUB' || $a[1] == 'LIST')) {
-			    $line = rtrim($line);
-            
-        		// split one line
-			    $a = rcube_explode_quoted_string(' ', $line);
-        		// last string is folder name
-    			$folder = preg_replace(array('/^"/', '/"$/'), '', $this->UnEscape($a[count($a)-1]));
-	    		// @TODO: do we need this check???
-		    	if (!in_array($folder, $folders)) {
-			        $folders[$i] = $folder;
-        		}
-        		// second from last is delimiter
-        		$delim = trim($a[count($a)-2], '"');
-        		// is it a container?
-        		$i++;
-		    }
-	    } while (!$this->startsWith($line, 'lsb', true));
-
-	    if (is_array($folders)) {
-    	    if (!empty($ref)) {
-            	// if rootdir was specified, make sure it's the first element
-        	    // some IMAP servers (i.e. Courier) won't return it
-            	if ($ref[strlen($ref)-1]==$delim) {
-            	    $ref = substr($ref, 0, strlen($ref)-1);
-            	}
-            	if ($folders[0]!=$ref) {
-            	    array_unshift($folders, $ref);
-        	    }
-    	    }
-    	    return $folders;
-	    }
 	    $this->error = $line;
     	return false;
     }

--
Gitblit v1.9.1