Getting ready for 1.2.0 release.
[squirrelmail.git] / functions / imap_mailbox.php
index cac503365c1e18ddf1f7acc03a2f2349627b3345..a4936b67812c44ef33bc6f8d220ecf43a17b6298 100755 (executable)
@@ -3,7 +3,7 @@
 /**
  * imap_mailbox.php
  *
- * Copyright (c) 1999-2001 The SquirrelMail Development Team
+ * Copyright (c) 1999-2002 The SquirrelMail Project Team
  * Licensed under the GNU GPL. For full terms see the file COPYING.
  *
  * This impliments all functions that manipulate mailboxes
@@ -220,14 +220,59 @@ function sqimap_mailbox_parse ($line, $line_lsub)
     return $boxes;
 }
 
-/* Apparently you must call a user function with usort instead
- * of calling a built-in directly.  Stupid.
- * Patch from dave_michmerhuizen@yahoo.com
- * Allows case insensitivity when sorting folders
+/**
+ * Sorting function used to sort mailbox names.
+ *   + Original patch from dave_michmerhuizen@yahoo.com
+ *   + Allows case insensitivity when sorting folders
+ *   + Takes care of the delimiter being sorted to the end, causing
+ *     subfolders to be listed in below folders that are prefixed
+ *     with their parent folders name.
+ *        For example: INBOX.foo, INBOX.foobar, and INBOX.foo.bar
+ *        Without special sort function: foobar between foo and foo.bar
+ *        With special sort function: foobar AFTER foo and foo.bar :)
  */
-function user_strcasecmp($a, $b)
-{
-    return strcasecmp($a, $b);
+function user_strcasecmp($a, $b) {
+    global $delimiter;
+
+    /* Calculate the length of some strings. */
+    $a_length = strlen($a);
+    $b_length = strlen($b);
+    $min_length = min($a_length, $b_length);
+    $delimiter_length = strlen($delimiter);
+
+    /* Set the initial result value. */
+    $result = 0;
+
+    /* Check the strings... */
+    for ($c = 0; $c < $min_length; ++$c) {
+        $a_del = substr($a, $c, $delimiter_length);
+        $b_del = substr($b, $c, $delimiter_length);
+
+        if (($a_del == $delimiter) && ($b_del == $delimiter)) {
+            $result = 0;
+        } else if (($a_del == $delimiter) && ($b_del != $delimiter)) {
+            $result = 1;
+        } else if (($a_del != $delimiter) && ($b_del != $delimiter)) {
+            $result = -1;
+        } else {
+            $result = strcasecmp($a{$c}, $b{$c});
+        }
+
+        if ($result != 0) {
+            break;
+        }
+    }
+    
+    /* If one string is a prefix of the other... */
+    if ($result == 0) {
+        if ($a_length < $b_length) {
+            $result = -1;
+        } else if ($a_length > $b_length) {
+            $result = 1;
+        }
+    }
+
+    return ($result);
 }
 
 
@@ -235,8 +280,7 @@ function user_strcasecmp($a, $b)
  **  Returns sorted mailbox lists in several different ways.
  **  See comment on sqimap_mailbox_parse() for info about the returned array.
  ******************************************************************************/
-function sqimap_mailbox_list ($imap_stream)
-{
+function sqimap_mailbox_list ($imap_stream) {
     global $data_dir, $username, $list_special_folders_first;
     global $folder_prefix, $trash_folder, $sent_folder, $draft_folder;
     global $move_to_trash, $move_to_sent, $save_as_draft;
@@ -283,7 +327,6 @@ function sqimap_mailbox_list ($imap_stream)
     $sorted_lsub_ary = $new_ary;
     if (isset($sorted_lsub_ary)) {
         usort($sorted_lsub_ary, 'user_strcasecmp');
-        /*sort($sorted_lsub_ary); */
     }   
     
     /** LIST array **/
@@ -297,7 +340,8 @@ function sqimap_mailbox_list ($imap_stream)
         }
         
         fputs ($imap_stream, sqimap_session_id() . " LIST \"\" \"$mbx\"\r\n");
-        $read = sqimap_read_data ($imap_stream, sqimap_session_id(), true, $response, $message);
+        $read = sqimap_read_data ($imap_stream, sqimap_session_id(),
+                                  true, $response, $message);
         /* Another workaround for EIMS */
         if (isset($read[1]) && 
             ereg("^(\\* [A-Z]+.*)\\{[0-9]+\\}([ \n\r\t]*)$", 
@@ -449,7 +493,8 @@ function sqimap_mailbox_list_all ($imap_stream)
             $mailbox = find_mailbox_name($read_ary[$i]);
             $dm_count = countCharInString($mailbox, $delimiter);
             if (substr($mailbox, -1) == $delimiter) {
-                $dm_count--;  /* If name ends in delimiter - decrement count by one */
+                /* If name ends in delimiter - decrement count by one */
+                $dm_count--;  
             }
             
             /* Format folder name, but only if it's a INBOX.* or have */
@@ -476,12 +521,14 @@ function sqimap_mailbox_list_all ($imap_stream)
                 $mailbox = substr($mailbox, 0, strlen($mailbox) - 1);
             }
             $boxes[$g]["unformatted"] = $mailbox;
-            $boxes[$g]["unformatted-disp"] = ereg_replace('^' . $folder_prefix, '', $mailbox);
+            $boxes[$g]["unformatted-disp"] =
+                ereg_replace('^' . $folder_prefix, '', $mailbox);
             $boxes[$g]["id"] = $g;
             
             /** Now lets get the flags for this mailbox **/
-            fputs ($imap_stream, sqimap_session_id() . " LIST \"\" \"$mailbox\"\r\n"); 
-            $read_mlbx = sqimap_read_data ($imap_stream, sqimap_session_id(), true, $response, $message);
+            fputs ($imap_stream, sqimap_session_id() . " LIST \"\" \"$mailbox\"\r\n");
+            $read_mlbx = sqimap_read_data ($imap_stream, sqimap_session_id(),
+                                           true, $response, $message);
             
             /* Another workaround for EIMS */
             if (isset($read_mlbx[1]) &&