phpDocumentor updates
[squirrelmail.git] / functions / imap_mailbox.php
index 2d5fe2fb651a4abbe5b891097f6ba2ceeb56207f..128b27a1f2fa4c5d474a053e658f1af6e89c4e70 100755 (executable)
@@ -3,16 +3,18 @@
 /**
  * imap_mailbox.php
  *
- * Copyright (c) 1999-2005 The SquirrelMail Project Team
- * Licensed under the GNU GPL. For full terms see the file COPYING.
- *
- * This impliments all functions that manipulate mailboxes
+ * This implements all functions that manipulate mailboxes
  *
+ * @copyright © 1999-2005 The SquirrelMail Project Team
+ * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  * @version $Id$
  * @package squirrelmail
  * @subpackage imap
  */
 
+/** @ignore */
+if (! defined('SM_PATH')) define('SM_PATH','../');
+
 /** UTF7 support */
 require_once(SM_PATH . 'functions/imap_utf7_local.php');
 
@@ -27,9 +29,11 @@ global $boxesnew;
  * should be called is the sqimap_get_status_mbx_tree. In case of subscribe
  * / rename / delete / new we have to create methods for adding/changing the
  * mailbox in the mbx_tree without the need for a refresh.
+ *
+ * Some code fragments are present in 1.3.0 - 1.4.4.
  * @package squirrelmail
  * @subpackage imap
- * @since 1.3.0
+ * @since 1.5.0
  */
 class mailboxes {
     var $mailboxname_full = '', $mailboxname_sub= '', $is_noselect = false, $is_noinferiors = false,
@@ -142,6 +146,8 @@ function find_mailbox_name($line) {
 
 /**
  * Detects if mailbox has noselect flag (can't store messages)
+ * In versions older than 1.4.5 function checks only LSUB responses
+ * and can produce pcre warnings.
  * @param string $lsub_line mailbox line from untagged LIST or LSUB response
  * @return bool whether this is a Noselect mailbox.
  * @since 1.3.2
@@ -424,16 +430,20 @@ function sqimap_unsubscribe ($imap_stream, $mailbox) {
 function sqimap_mailbox_delete ($imap_stream, $mailbox) {
     global $data_dir, $username;
     sqimap_unsubscribe ($imap_stream, $mailbox);
-    $read_ary = sqimap_run_command($imap_stream, 'DELETE ' .
-                                   sqimap_encode_mailbox_name($mailbox),
-                                   true, $response, $message);
-    if ($response !== 'OK') {
-        // subscribe again
-        sqimap_subscribe ($imap_stream, $mailbox);
-    } else {
-        do_hook_function('rename_or_delete_folder', $args = array($mailbox, 'delete', ''));
-        removePref($data_dir, $username, "thread_$mailbox");
-        removePref($data_dir, $username, "collapse_folder_$mailbox");
+
+    if (sqimap_mailbox_exists($imap_stream, $mailbox)) {
+
+        $read_ary = sqimap_run_command($imap_stream, 'DELETE ' .
+                                       sqimap_encode_mailbox_name($mailbox),
+                                       true, $response, $message);
+        if ($response !== 'OK') {
+            // subscribe again
+            sqimap_subscribe ($imap_stream, $mailbox);
+        } else {
+            do_hook_function('rename_or_delete_folder', $args = array($mailbox, 'delete', ''));
+            removePref($data_dir, $username, "thread_$mailbox");
+            removePref($data_dir, $username, "collapse_folder_$mailbox");
+        }
     }
 }
 
@@ -883,115 +893,117 @@ function sqimap_mailbox_list_all($imap_stream) {
 }
 
 /**
+ * Fills mailbox object
+ *
+ * Some code fragments are present in 1.3.0 - 1.4.4.
  * @param stream $imap_stream imap connection resource
  * @return object see mailboxes class.
- * @since 1.3.0
+ * @since 1.5.0
  */
 function sqimap_mailbox_tree($imap_stream) {
-    global $default_folder_prefix;
-    if (true) {
-        global $data_dir, $username, $list_special_folders_first,
-               $folder_prefix, $delimiter, $trash_folder, $move_to_trash,
-               $imap_server_type, $show_only_subscribed_folders;
+    global $default_folder_prefix, $data_dir, $username, $list_special_folders_first,
+        $folder_prefix, $delimiter, $trash_folder, $move_to_trash,
+        $imap_server_type, $show_only_subscribed_folders;
 
-        $noselect = false;
-        $noinferiors = false;
+    // TODO: implement mailbox tree caching. maybe store object in session?
 
-        require_once(SM_PATH . 'include/load_prefs.php');
+    $noselect = false;
+    $noinferiors = false;
 
-        if ($show_only_subscribed_folders) {
-            $lsub_cmd = 'LSUB';
-        } else {
-            $lsub_cmd = 'LIST';
-        }
+    require_once(SM_PATH . 'include/load_prefs.php');
 
-        /* LSUB array */
-        $lsub_ary = sqimap_run_command ($imap_stream, "$lsub_cmd \"$folder_prefix\" \"*\"",
-                                        true, $response, $message);
-        $lsub_ary = compact_mailboxes_response($lsub_ary);
+    if ($show_only_subscribed_folders) {
+        $lsub_cmd = 'LSUB';
+    } else {
+        $lsub_cmd = 'LIST';
+    }
 
-        /* Check to see if we have an INBOX */
-        $has_inbox = false;
-
-        for ($i = 0, $cnt = count($lsub_ary); $i < $cnt; $i++) {
-            if (preg_match("/^\*\s+$lsub_cmd.*\s\"?INBOX\"?[^(\/\.)].*$/i",$lsub_ary[$i])) {
-                $lsub_ary[$i] = strtoupper($lsub_ary[$i]);
-                // in case of an unsubscribed inbox an imap server can
-                // return the inbox in the lsub results with a \NoSelect
-                // flag.
-                if (!preg_match("/\*\s+$lsub_cmd\s+\(.*\\\\NoSelect.*\).*/i",$lsub_ary[$i])) {
-                    $has_inbox = true;
-                } else {
-                    // remove the result and request it again  with a list
-                    // response at a later stage.
-                    unset($lsub_ary[$i]);
-                    // re-index the array otherwise the addition of the LIST
-                    // response will fail in PHP 4.1.2 and probably other older versions
-                    $lsub_ary = array_values($lsub_ary);
-                }
-                break;
+    /* LSUB array */
+    $lsub_ary = sqimap_run_command ($imap_stream, "$lsub_cmd \"$folder_prefix\" \"*\"",
+                                    true, $response, $message);
+    $lsub_ary = compact_mailboxes_response($lsub_ary);
+
+    /* Check to see if we have an INBOX */
+    $has_inbox = false;
+
+    for ($i = 0, $cnt = count($lsub_ary); $i < $cnt; $i++) {
+        if (preg_match("/^\*\s+$lsub_cmd.*\s\"?INBOX\"?\s*$/i",$lsub_ary[$i])) {
+            $lsub_ary[$i] = strtoupper($lsub_ary[$i]);
+            // in case of an unsubscribed inbox an imap server can
+            // return the inbox in the lsub results with a \NoSelect
+            // flag.
+            if (!preg_match("/\*\s+$lsub_cmd\s+\(.*\\\\NoSelect.*\).*/i",$lsub_ary[$i])) {
+                $has_inbox = true;
+            } else {
+                // remove the result and request it again  with a list
+                // response at a later stage.
+                unset($lsub_ary[$i]);
+                // re-index the array otherwise the addition of the LIST
+                // response will fail in PHP 4.1.2 and probably other older versions
+                $lsub_ary = array_values($lsub_ary);
             }
+            break;
         }
+    }
 
-        if ($has_inbox == false) {
-            // do a list request for inbox because we should always show
-            // inbox even if the user isn't subscribed to it.
-            $inbox_ary = sqimap_run_command ($imap_stream, 'LIST "" "INBOX"',
-                                             true, $response, $message);
-            $inbox_ary = compact_mailboxes_response($inbox_ary);
-            if (count($inbox_ary)) {
-                $lsub_ary[] = $inbox_ary[0];
-            }
+    if ($has_inbox == false) {
+        // do a list request for inbox because we should always show
+        // inbox even if the user isn't subscribed to it.
+        $inbox_ary = sqimap_run_command ($imap_stream, 'LIST "" "INBOX"',
+                                         true, $response, $message);
+        $inbox_ary = compact_mailboxes_response($inbox_ary);
+        if (count($inbox_ary)) {
+            $lsub_ary[] = $inbox_ary[0];
         }
+    }
 
-        /*
-         * Section about removing the last element was removed
-         * We don't return "* OK" anymore from sqimap_read_data
-         */
+    /*
+     * Section about removing the last element was removed
+     * We don't return "* OK" anymore from sqimap_read_data
+     */
+
+    $sorted_lsub_ary = array();
+    $cnt = count($lsub_ary);
+    for ($i = 0; $i < $cnt; $i++) {
+        $mbx = find_mailbox_name($lsub_ary[$i]);
 
+        // only do the noselect test if !uw, is checked later. FIX ME see conf.pl setting
+        if ($imap_server_type != "uw") {
+            $noselect = check_is_noselect($lsub_ary[$i]);
+            $noinferiors = check_is_noinferiors($lsub_ary[$i]);
+        }
+        if (substr($mbx, -1) == $delimiter) {
+            $mbx = substr($mbx, 0, strlen($mbx) - 1);
+        }
+        $sorted_lsub_ary[] = array ('mbx' => $mbx, 'noselect' => $noselect, 'noinferiors' => $noinferiors);
+    }
+    // FIX ME this requires a config setting inside conf.pl instead of checking on server type
+    if ($imap_server_type == "uw") {
+        $aQuery = array();
+        $aTag = array();
+        // prepare an array with queries
+        foreach ($sorted_lsub_ary as $aMbx) {
+            $mbx = stripslashes($aMbx['mbx']);
+            sqimap_prepare_pipelined_query('LIST "" ' . sqimap_encode_mailbox_name($mbx), $tag, $aQuery, false);
+            $aTag[$tag] = $mbx;
+        }
         $sorted_lsub_ary = array();
-        $cnt = count($lsub_ary);
-        for ($i = 0; $i < $cnt; $i++) {
-            $mbx = find_mailbox_name($lsub_ary[$i]);
-
-            // only do the noselect test if !uw, is checked later. FIX ME see conf.pl setting
-            if ($imap_server_type != "uw") {
-                $noselect = check_is_noselect($lsub_ary[$i]);
-                $noinferiors = check_is_noinferiors($lsub_ary[$i]);
-            }
-            if (substr($mbx, -1) == $delimiter) {
-                $mbx = substr($mbx, 0, strlen($mbx) - 1);
+        // execute all the queries at once
+        $aResponse = sqimap_run_pipelined_command ($imap_stream, $aQuery, false, $aServerResponse, $aServerMessage);
+        foreach($aTag as $tag => $mbx) {
+            if ($aServerResponse[$tag] == 'OK') {
+                $sResponse = implode('', $aResponse[$tag]);
+                $noselect = check_is_noselect($sResponse);
+                $noinferiors = check_is_noinferiors($sResponse);
+                $sorted_lsub_ary[] = array ('mbx' => $mbx, 'noselect' => $noselect, 'noinferiors' => $noinferiors);
             }
-            $sorted_lsub_ary[] = array ('mbx' => $mbx, 'noselect' => $noselect, 'noinferiors' => $noinferiors);
         }
-        // FIX ME this requires a config setting inside conf.pl instead of checking on server type
-        if ($imap_server_type == "uw") {
-           $aQuery = array();
-           $aTag = array();
-           // prepare an array with queries
-           foreach ($sorted_lsub_ary as $aMbx) {
-               $mbx = stripslashes($aMbx['mbx']);
-               sqimap_prepare_pipelined_query('LIST "" ' . sqimap_encode_mailbox_name($mbx), $tag, $aQuery, false);
-               $aTag[$tag] = $mbx;
-           }
-           $sorted_lsub_ary = array();
-           // execute all the queries at once
-           $aResponse = sqimap_run_pipelined_command ($imap_stream, $aQuery, false, $aServerResponse, $aServerMessage);
-           foreach($aTag as $tag => $mbx) {
-               if ($aServerResponse[$tag] == 'OK') {
-                   $sResponse = implode('', $aResponse[$tag]);
-                   $noselect = check_is_noselect($sResponse);
-                   $noinferiors = check_is_noinferiors($sResponse);
-                   $sorted_lsub_ary[] = array ('mbx' => $mbx, 'noselect' => $noselect, 'noinferiors' => $noinferiors);
-               }
-           }
-           $cnt = count($sorted_lsub_ary);
-       }
-       $sorted_lsub_ary = array_values($sorted_lsub_ary);
-       usort($sorted_lsub_ary, 'mbxSort');
-       $boxestree = sqimap_fill_mailbox_tree($sorted_lsub_ary,false,$imap_stream);
-       return $boxestree;
+        $cnt = count($sorted_lsub_ary);
     }
+    $sorted_lsub_ary = array_values($sorted_lsub_ary);
+    usort($sorted_lsub_ary, 'mbxSort');
+    $boxestree = sqimap_fill_mailbox_tree($sorted_lsub_ary,false,$imap_stream);
+    return $boxestree;
 }
 
 /**
@@ -1006,11 +1018,14 @@ function mbxSort($a, $b) {
 }
 
 /**
+ * Fills mailbox object
+ *
+ * Some code fragments are present in 1.3.0 - 1.4.4.
  * @param array $mbx_ary
  * @param $mbxs
- * @param stream $imap_stream (since 1.5.0) imap connection resource
+ * @param stream $imap_stream imap connection resource
  * @return object see mailboxes class
- * @since 1.3.0
+ * @since 1.5.0
  */
 function sqimap_fill_mailbox_tree($mbx_ary, $mbxs=false,$imap_stream) {
     global $data_dir, $username, $list_special_folders_first,
@@ -1047,46 +1062,15 @@ function sqimap_fill_mailbox_tree($mbx_ary, $mbxs=false,$imap_stream) {
             $mailbox = $mbx_ary[$i]['mbx'];
 
             /*
-                sent subfolders messes up using existing code as subfolders
-                were marked, but the parents were ordered somewhere else in
-                the list, despite having "special folders at top" option set.
-                Need a better method than this.
-            */
-/*
-            if ($mailbox == 'INBOX') {
-                $mbx->is_special = true;
-            } elseif (stristr($trash_folder , $mailbox)) {
-                $mbx->is_special = true;
-            } elseif (stristr($sent_folder , $mailbox)) {
-                $mbx->is_special = true;
-            } elseif (stristr($draft_folder , $mailbox)) {
-                $mbx->is_special = true;
-            }
-
-            switch ($mailbox) {
-                case 'INBOX':
-                    $mbx->is_inbox = true;
-                    $mbx->is_special = true;
-                    $mbx_ary[$i]['noselect'] = false;
-                    break;
-                case $trash_folder:
-                    $mbx->is_trash = true;
-                    $mbx->is_special = true;
-                    break;
-                case $sent_folder:
-                    $mbx->is_sent = true;
-                    $mbx->is_special = true;
-                    break;
-                case $draft_folder:
-                    $mbx->is_draft = true;
-                    $mbx->is_special = true;
-                    break;
-            }
-*/
+             * Set the is_special flag if it concerned a special mailbox.
+             * Used for displaying the special folders on top in the mailbox
+             * tree displaying code.
+             */
             $mbx->is_special |= ($mbx->is_inbox = (strtoupper($mailbox) == 'INBOX'));
             $mbx->is_special |= ($mbx->is_trash = isTrashMailbox($mailbox));
             $mbx->is_special |= ($mbx->is_sent = isSentMailbox($mailbox));
             $mbx->is_special |= ($mbx->is_draft = isDraftMailbox($mailbox));
+
             if (!$mbx->is_special)
                 $mbx->is_special = boolean_hook_function('special_mailbox', $mailbox, 1);