Selaa lähdekoodia

Rewrite of internal message caching
Added paginator support for asearch
Added next/prev links in read_body to walk through search results
Added individual sort settings / mailbox
Added what I forgot to mention

stekkel 21 vuotta sitten
vanhempi
commit
abf6bbc461

+ 16 - 16
functions/file_prefs.php

@@ -20,14 +20,14 @@ include_once(SM_PATH . 'functions/display_messages.php');
  */
 function cachePrefValues($data_dir, $username) {
     global $prefs_are_cached, $prefs_cache;
-       
+
     if ( isset($prefs_are_cached) && $prefs_are_cached) {
         return;
     }
-    
+
     sqsession_unregister('prefs_cache');
     sqsession_unregister('prefs_are_cached');
-    
+
     /* Calculate the filename for the user's preference file */
     $filename = getHashedFile($username, $data_dir, "$username.pref");
 
@@ -82,7 +82,7 @@ function cachePrefValues($data_dir, $username) {
     sqsession_register($prefs_cache, 'prefs_cache');
     sqsession_register($prefs_are_cached, 'prefs_are_cached');
 }
-   
+
 /**
  * Return the value for the preference given by $string.
  */
@@ -91,15 +91,15 @@ function getPref($data_dir, $username, $string, $default = '') {
 
     $result = do_hook_function('get_pref_override',array($username,$string));
     if (!$result) {
-	cachePrefValues($data_dir, $username);
-	if (isset($prefs_cache[$string])) {
-    	    $result = $prefs_cache[$string];
-	} else {
-	    $result = do_hook_function('get_pref', array($username,$string));
-	    if (!$result) {	    
-    		$result = $default;
-	    }
-	}
+        cachePrefValues($data_dir, $username);
+        if (isset($prefs_cache[$string])) {
+                $result = $prefs_cache[$string];
+        } else {
+            $result = do_hook_function('get_pref', array($username,$string));
+            if (!$result) {
+                $result = $default;
+            }
+        }
     }
     return ($result);
 }
@@ -109,7 +109,7 @@ function getPref($data_dir, $username, $string, $default = '') {
  */
 function savePrefValues($data_dir, $username) {
     global $prefs_cache;
-   
+
     $filename = getHashedFile($username, $data_dir, "$username.pref");
 
     /* Open the file for writing, or else display an error to the user. */
@@ -143,11 +143,11 @@ function removePref($data_dir, $username, $string) {
     global $prefs_cache;
 
     cachePrefValues($data_dir, $username);
- 
+
     if (isset($prefs_cache[$string])) {
         unset($prefs_cache[$string]);
     }
- 
+
     savePrefValues($data_dir, $username);
 }
 

+ 1 - 1
functions/forms.php

@@ -44,7 +44,7 @@ function addCheckBox($name, $checked = false, $value = null) {
  * Form radio box
  */
 function addRadioBox($name, $checked = false, $value = null) {
-    return addInputField('radio', $name, $value, 
+    return addInputField('radio', $name, $value,
         ($checked ? ' checked="checked"' : ''));
 }
 

+ 38 - 226
functions/imap_asearch.php

@@ -194,10 +194,10 @@ function s_debug_dump($var_name, $var_var)
 
 /** Encode a string to quoted or literal as defined in rfc 3501
  *
- * - § 4.3 String:
+ * -  4.3 String:
  *	A quoted string is a sequence of zero or more 7-bit characters,
  *	 excluding CR and LF, with double quote (<">) characters at each end.
- * - § 9. Formal Syntax:
+ * -  9. Formal Syntax:
  *	quoted-specials = DQUOTE / "\"
  * @param string $what string to encode
  * @param string $charset search charset used
@@ -207,7 +207,6 @@ function sqimap_asearch_encode_string($what, $charset)
 {
 	if (strtoupper($charset) == 'ISO-2022-JP')	// This should be now handled in imap_utf7_local?
 		$what = mb_convert_encoding($what, 'JIS', 'auto');
-//if (ereg("[\"\\\r\n\x80-\xff]", $what))
 	if (preg_match('/["\\\\\r\n\x80-\xff]/', $what))
 		return '{' . strlen($what) . "}\r\n" . $what;	// 4.3 literal form
 	return '"' . $what . '"';	// 4.3 quoted string form
@@ -293,7 +292,7 @@ function sqimap_asearch_build_criteria($opcode, $what, $charset)
 		case 'afield':	/* HEADER field-name: field-body */
 			preg_match('/^([^:]+):(.*)$/', $what, $what_parts);
 			if (count($what_parts) == 3)
-				$criteria = $opcode . ' ' . 
+				$criteria = $opcode . ' ' .
 					sqimap_asearch_encode_string($what_parts[1], $charset) . ' ' .
 					sqimap_asearch_encode_string($what_parts[2], $charset) . ' ';
 		break;
@@ -348,15 +347,15 @@ function sqimap_run_search($imapConnection, $search_string, $search_charset)
 		$search_charset = '';
 	/* 6.4.4 try OPTIONAL [CHARSET] specification first */
 	if ($search_charset != '')
-		$query = 'SEARCH CHARSET "' . strtoupper($search_charset) . '" ALL ' . $search_string;
+		$query = 'SEARCH CHARSET "' . strtoupper($search_charset) . '" ' . $search_string;
 	else
-		$query = 'SEARCH ALL ' . $search_string;
+		$query = 'SEARCH ' . $search_string;
 	s_debug_dump('C:', $query);
 	$readin = sqimap_run_command($imapConnection, $query, false, $response, $message, TRUE);
 
 	/* 6.4.4 try US-ASCII charset if we tried an OPTIONAL [CHARSET] and received a tagged NO response (SHOULD be [BADCHARSET]) */
 	if (($search_charset != '')  && (strtoupper($response) == 'NO')) {
-		$query = 'SEARCH CHARSET US-ASCII ALL ' . $search_string;
+		$query = 'SEARCH CHARSET US-ASCII ' . $search_string;
 		s_debug_dump('C:', $query);
 		$readin = sqimap_run_command($imapConnection, $query, false, $response, $message, TRUE);
 	}
@@ -364,15 +363,7 @@ function sqimap_run_search($imapConnection, $search_string, $search_charset)
 		sqimap_asearch_error_box($response, $query, $message);
 		return array();
 	}
-
-	// Keep going till we find the * SEARCH response
-	foreach ($readin as $readin_part) {
-		s_debug_dump('S:', $readin_part);
-		if (substr($readin_part, 0, 9) == '* SEARCH ') {
-			//EIMS returns multiple SEARCH responses, and this allowed according to Mark Crispin
-			$messagelist = sqimap_array_merge_unique($messagelist, preg_split("/ /", substr($readin_part, 9)));
-		}
-	}
+    $messagelist = parseUidList($readin,'SEARCH');
 
 	if (empty($messagelist))	//Empty search response, ie '* SEARCH'
 		return array();
@@ -383,168 +374,6 @@ function sqimap_run_search($imapConnection, $search_string, $search_charset)
 	return $id;
 }
 
-/**
- * Run the imap SORT command as defined in 
- * @link http://www.ietf.org/internet-drafts/draft-ietf-imapext-sort-13.txt
- * @param resource $imapConnection the current imap stream
- * @param string $search_string the full search expression as defined in rfc 3501
- * @param string $search_charset mandatory charset
- * @param string $sort_criteria the full sort criteria expression eg "SUBJECT REVERSE DATE"
- * @return array an IDs or UIDs array of matching messages or an empty array
- */
-function sqimap_run_sort($imapConnection, $search_string, $search_charset, $sort_criteria)
-{
-	if ($search_charset == '')
-		$search_charset = 'US-ASCII';
-	$query = 'SORT (' . $sort_criteria . ') "' . strtoupper($search_charset) . '" ALL ' . $search_string;
-	s_debug_dump('C:', $query);
-	$readin = sqimap_run_command($imapConnection, $query, false, $response, $message, TRUE);
-	s_debug_dump('S:', $response);
-
-	/* 6.4 try US-ASCII charset if we received a tagged NO response (SHOULD be [BADCHARSET]) */
-	if (($search_charset != 'US-ASCII')  && (strtoupper($response) == 'NO')) {
-		s_debug_dump('S:', $readin);
-		$query = 'SORT (' . $sort_criteria . ') US-ASCII ALL ' . $search_string;
-		s_debug_dump('C:', $query);
-		$readin = sqimap_run_command($imapConnection, $query, false, $response, $message, TRUE);
-		s_debug_dump('S:', $response);
-	}
-
-	if (strtoupper($response) != 'OK') {
-		s_debug_dump('S:', $readin);
-//	sqimap_asearch_error_box($response, $query, $message);
-//	return array();
-		return sqimap_run_search($imapConnection, $search_string, $search_charset);	// Fell back to standard search
-	}
-
-	/* Keep going till we find the * SORT response */
-	foreach ($readin as $readin_part) {
-		s_debug_dump('S:', $readin_part);
-		if (substr($readin_part, 0, 7) == '* SORT ') {
-			//SORT returns untagged responses
-			$messagelist = sqimap_array_merge_unique($messagelist, preg_split("/ /", substr($readin_part, 7)));
-		}
-	}
-
-	if (empty($messagelist))	//Empty search response, ie '* SORT'
-		return array();
-
-	$cnt = count($messagelist);
-	for ($q = 0; $q < $cnt; $q++)
-		$id[$q] = trim($messagelist[$q]);
-	return $id;
-}
-
-/**
- * Run the imap THREAD command as defined in 
- * @link http://www.ietf.org/internet-drafts/draft-ietf-imapext-sort-13.txt
- * @param resource $imapConnection the current imap stream
- * @param string $search_string the full search expression as defined in rfc 3501
- * @param string $search_charset mandatory charset
- * @param string $thread_algorithm the threading algorithm "ORDEREDSUBJECT" or "REFERENCES"
- * @return array an IDs or UIDs array of matching messages or an empty array
- * @global array thread_new will be used by thread view in mailbox_display
- * @global array server_sort_array will be used by thread view in mailbox_display
- */
-function sqimap_run_thread($imapConnection, $search_string, $search_charset, $thread_algorithm)
-{
-	global $thread_new, $server_sort_array;
-
-	if (sqsession_is_registered('thread_new'))
-		sqsession_unregister('thread_new');
-	if (sqsession_is_registered('server_sort_array'))
-		sqsession_unregister('server_sort_array');
-
-	$thread_new = array();
-	$thread_new[0] = "";
-
-	$server_sort_array = array();
-
-	if ($search_charset == '')
-		$search_charset = 'US-ASCII';
-	$query = 'THREAD ' . $thread_algorithm . ' "' . strtoupper($search_charset) . '" ALL ' . $search_string;
-	s_debug_dump('C:', $query);
-	$readin = sqimap_run_command($imapConnection, $query, false, $response, $message, TRUE);
-	s_debug_dump('S:', $response);
-
-	/* 6.4 try US-ASCII charset if we received a tagged NO response (SHOULD be [BADCHARSET]) */
-	if (($search_charset != 'US-ASCII')  && (strtoupper($response) == 'NO')) {
-		s_debug_dump('S:', $readin);
-		$query = 'THREAD ' . $thread_algorithm . ' US-ASCII ALL ' . $search_string;
-		s_debug_dump('C:', $query);
-		$readin = sqimap_run_command($imapConnection, $query, false, $response, $message, TRUE);
-		s_debug_dump('S:', $response);
-	}
-
-	if (strtoupper($response) != 'OK') {
-		s_debug_dump('S:', $readin);
-		if (empty($response)) {	//imap server closed connection. We can't go further.
-/* we should at this point:
-	- warn the user that the THREAD call has failed
-	- (offer him a way to) disconnect it permanently in the prefs
-	- perform the regular search instead or provide a way to do it in one click
-*/
-			global $sort, $mailbox, $php_self;
-			$message = _("The imap server failed to handle threading.");
-			$unthread = _("Click here to unset thread view for this mailbox and start again.");
-			if (preg_match('/^(.+)\?.+$/', $php_self, $regs))
-				$source_url = $regs[1];
-    	else
-				$source_url = $php_self;
-			$link = '<a href=' . $source_url . '?sort=' . $sort . '&start_messages=1&set_thread=0&mailbox=' . urlencode($mailbox) . '>' . $unthread . '</a>';
-			sqimap_asearch_error_box($response, $query, $message, $link);
-			return array();
-		}
-		return sqimap_run_search($imapConnection, $search_string, $search_charset);	// Fell back to standard search
-	}
-
-	/* Keep going till we find the * THREAD response */
-	foreach ($readin as $readin_part) {
-		s_debug_dump('S:', $readin_part);
-		if (substr($readin_part, 0, 9) == '* THREAD ') {
-			$thread_temp = preg_split("//", substr($readin_part, 9), -1, PREG_SPLIT_NO_EMPTY);
-			break;	// Should be the last anyway
-		}
-	}
-
-	if (empty($thread_temp))	//Empty search response, ie '* THREAD'
-		return array();
-
-	$char_count = count($thread_temp);
-	$counter = 0;
-	$k = 0;
-	for ($i=0;$i<$char_count;$i++) {
-        if ($thread_temp[$i] != ')' && $thread_temp[$i] != '(') {
-                $thread_new[$k] = $thread_new[$k] . $thread_temp[$i];
-        }
-        elseif ($thread_temp[$i] == '(') {
-                $thread_new[$k] .= $thread_temp[$i];
-                $counter++;
-        }
-        elseif ($thread_temp[$i] == ')') {
-                if ($counter > 1) {
-                        $thread_new[$k] .= $thread_temp[$i];
-                        $counter = $counter - 1;
-                }
-                else {
-                        $thread_new[$k] .= $thread_temp[$i];
-                        $k++;
-                        $thread_new[$k] = "";
-                        $counter = $counter - 1;
-                }
-        }
-	}
-	sqsession_register($thread_new, 'thread_new');
-	$thread_new = array_reverse($thread_new);
-	$thread_list = implode(" ", $thread_new);
-	$thread_list = str_replace("(", " ", $thread_list);
-	$thread_list = str_replace(")", " ", $thread_list);
-	$thread_list = preg_split("/\s/", $thread_list, -1, PREG_SPLIT_NO_EMPTY);
-	$server_sort_array = $thread_list;
-	sqsession_register($server_sort_array, 'server_sort_array');
-	return $thread_list;
-}
-
 /**
  * @global bool allow_charset_search user setting
  * @global array languages sm languages array
@@ -602,7 +431,7 @@ function sqimap_asearch_get_sub_mailboxes($cur_mailbox, &$mboxes_array)
 }
 
 /**
- * Performs the search, given all the criteria, merging results for every mailbox
+ * Create the search query strings for all given criteria and merge results for every mailbox
  * @param resource $imapConnection
  * @param array $mailbox_array (reference)
  * @param array $biop_array (reference)
@@ -612,27 +441,19 @@ function sqimap_asearch_get_sub_mailboxes($cur_mailbox, &$mboxes_array)
  * @param array $exclude_array (reference)
  * @param array $sub_array (reference)
  * @param array $mboxes_array selectable unformatted mailboxes names (reference)
- * @global bool allow_server_sort comes from config.php
- * @global integer sort sm internal sort order
- * @global bool allow_thread_sort comes from config.php
- * @global bool thread_sort_messages does it really need to global?
- * @global integer sort_by_ref thread by references
- * @global string data_dir
- * @global string username
  * @return array array(mailbox => array(UIDs))
  */
 function sqimap_asearch($imapConnection, &$mailbox_array, &$biop_array, &$unop_array, &$where_array, &$what_array, &$exclude_array, &$sub_array, &$mboxes_array)
 {
-	global $allow_server_sort, $sort, $allow_thread_sort, $thread_sort_messages, $sort_by_ref;
-	global $data_dir, $username;
 
 	$search_charset = sqimap_asearch_get_charset();
 	$mbox_msgs = array();
+    $mbox_search = array();
 	$search_string = '';
 	$cur_mailbox = $mailbox_array[0];
 	$cur_biop = '';	/* Start with ALL */
 	/* We loop one more time than the real array count, so the last search gets fired */
-	for ($cur_crit = 0; $cur_crit <= count($where_array); $cur_crit++) {
+	for ($cur_crit=0,$iCnt=count($where_array); $cur_crit <= $iCnt; ++$cur_crit) {
 		if (empty($exclude_array[$cur_crit])) {
 			$next_mailbox = $mailbox_array[$cur_crit];
 			if ($next_mailbox != $cur_mailbox) {
@@ -644,61 +465,52 @@ function sqimap_asearch($imapConnection, &$mailbox_array, &$biop_array, &$unop_a
 				else
 					$search_mboxes = array($cur_mailbox);
 				foreach ($search_mboxes as $cur_mailbox) {
-					s_debug_dump('C:SELECT:', $cur_mailbox);
-					sqimap_mailbox_select($imapConnection, $cur_mailbox);
-					$thread_sort_messages = $allow_thread_sort && getPref($data_dir, $username, 'thread_' . $cur_mailbox);
-					if ($thread_sort_messages) {
-						if ($sort_by_ref == 1)
-							$thread_algorithm = 'REFERENCES';
-						else
-							$thread_algorithm = 'ORDEREDSUBJECT';
-						$found_msgs = sqimap_run_thread($imapConnection, $search_string, $search_charset, $thread_algorithm);
-					}
-					else
-					if (($allow_server_sort) && ($sort < 6)) {
-						$sort_criteria = sqimap_asearch_get_sort_criteria($cur_mailbox, $sort);
-						$found_msgs = sqimap_run_sort($imapConnection, $search_string, $search_charset, $sort_criteria);
-					}
-					else
-						$found_msgs = sqimap_run_search($imapConnection, $search_string, $search_charset);
-					if (isset($mbox_msgs[$cur_mailbox])) {
-						if ($cur_biop == 'OR')	/* Merge with previous results */
-							$mbox_msgs[$cur_mailbox] = sqimap_array_merge_unique($mbox_msgs[$cur_mailbox], $found_msgs);
-						else	/* Intersect previous results */
-							$mbox_msgs[$cur_mailbox] = array_values(array_intersect($found_msgs, $mbox_msgs[$cur_mailbox]));
-					}
-					else /* No previous results */
-						$mbox_msgs[$cur_mailbox] = $found_msgs;
-					if (empty($mbox_msgs[$cur_mailbox]))	/* Can happen with intersect, and we need at the end a contiguous array */
-						unset($mbox_msgs[$cur_mailbox]);
-				}
-				$cur_mailbox = $next_mailbox;
+                    if (isset($mbox_search[$cur_mailbox])) {
+                        $mbox_search[$cur_mailbox]['search'] .= ' ' . $search_string;
+                    } else {
+                        $mbox_search[$cur_mailbox]['search'] = $search_string;
+                    }
+                    $mbox_search[$cur_mailbox]['charset'] = $search_charset;
+                }
+   				$cur_mailbox = $next_mailbox;
 				$search_string = '';
+
 			}
-			if (isset($where_array[$cur_crit])) {
+			if (isset($where_array[$cur_crit]) && empty($exclude_array[$cur_crit])) {
 				$criteria = sqimap_asearch_build_criteria($where_array[$cur_crit], $what_array[$cur_crit], $search_charset);
 				if (!empty($criteria)) {
+                    //$criteria = 'ALL '. $criteria;
 					$unop = $unop_array[$cur_crit];
-					if (!empty($unop))
+					if (!empty($unop)) {
 						$criteria = $unop . ' ' . $criteria;
+                    } else {
+                        $criteria = 'ALL ' . $criteria;
+                    }
 					/* We need to infix the next non-excluded criteria's biop if it's the same mailbox */
 					$next_biop = '';
 					for ($next_crit = $cur_crit+1; $next_crit <= count($where_array); $next_crit++) {
 						if (empty($exclude_array[$next_crit])) {
-							if (asearch_nz($mailbox_array[$next_crit]) == $cur_mailbox)
+							if (asearch_nz($mailbox_array[$next_crit]) == $cur_mailbox) {
 								$next_biop = asearch_nz($biop_array[$next_crit]);
-							break;
+                                if ($next_biop == 'OR' || $next_biop == 'ALL') {
+                                    $next_criterium =  sqimap_asearch_build_criteria($where_array[$next_crit], $what_array[$next_crit], $search_charset);
+                                    // unset something
+                                    $exclude_array[$next_crit] = true;
+                                    $criteria .= $next_biop . ' '. $next_criterium;
+                                }
+						    }
 						}
 					}
-					if ($next_biop == 'OR')
-						$criteria = $next_biop . ' ' . $criteria;
+					//if ($next_biop == 'OR')
+					//	$criteria = $next_biop . ' ' . $criteria;
 					$search_string .= $criteria;
-					$cur_biop = asearch_nz($biop_array[$cur_crit]);
+					//$cur_biop = asearch_nz($biop_array[$cur_crit]);
 				}
 			}
+
 		}
 	}
-	return $mbox_msgs;
+    return ($mbox_search);
 }
 
 ?>

+ 0 - 38
functions/imap_mailbox.php

@@ -247,44 +247,6 @@ function sqimap_mailbox_expunge ($imap_stream, $mailbox, $handle_errors = true,
     return $cnt;
 }
 
-
-/**
- * Expunge specified message
- *
- * We'll use this wrapper function to
- * remove the message with the matching UID .. the order
- * won't be changed - the array element for the message
- * will just be removed.
- */
-
-function sqimap_mailbox_expunge_dmn($imapConnection, &$aMailbox, $message_id) {
-    $cnt = 0;
-
-    if ($aMailbox['AUTO_EXPUNGE']) {
-         $cnt = sqimap_mailbox_expunge($imapConnection, $aMailbox['NAME'], true);
-    } else {
-         return $cnt;
-    }
-    $error = '';
-    $message_id = (int) $message_id; // we use strickt array_search
-    if (is_array($aMailbox['UIDSET'])) {
-        $key = array_search($message_id,$aMailbox['UIDSET'],true);
-        if ($key !== false && !is_null($key)) {
-            unset($aMailbox['UIDSET'][$key]);
-            $aMailbox['UIDSET'] = array_values($aMailbox['UIDSET']);
-            // adapt the exists count to avoid triggering of a new sort
-            $aMailbox['EXISTS'] -= 1;
-        } else {
-            $aMailbox['UIDSET'] = get_sorted_msgs_list($imapConnection,$aMailbox,$error);
-        }
-    } else {
-        $aMailbox['UIDSET'] = get_sorted_msgs_list($imapConnection,$aMailbox,$error);
-    }
-    sqsession_register($aMailbox,'aLastSelectedMailbox');
-    sqsession_register($aMailbox['UIDSET'],'server_sort_array'); //fix me, use aMailbox instead
-    return $cnt;
-}
-
 /**
  * Checks whether or not the specified mailbox exists
  */

+ 85 - 56
functions/imap_messages.php

@@ -36,6 +36,11 @@ function sqimap_messages_copy ($imap_stream, $start, $end, $mailbox) {
 function sqimap_msgs_list_copy ($imap_stream, $id, $mailbox) {
     $msgs_id = sqimap_message_list_squisher($id);
     $read = sqimap_run_command ($imap_stream, "COPY $msgs_id " . sqimap_encode_mailbox_name($mailbox), true, $response, $message, TRUE);
+    if ($response == 'OK') {
+        return true;
+    } else {
+        return false;
+    }
 }
 
 /**
@@ -47,8 +52,11 @@ function sqimap_msgs_list_copy ($imap_stream, $id, $mailbox) {
 */
 function sqimap_msgs_list_move ($imap_stream, $id, $mailbox) {
     $msgs_id = sqimap_message_list_squisher($id);
-    $read = sqimap_run_command ($imap_stream, "COPY $msgs_id " . sqimap_encode_mailbox_name($mailbox), true, $response, $message, TRUE);
-    $read = sqimap_run_command ($imap_stream, "STORE $msgs_id +FLAGS (\\Deleted)", true, $response,$message, TRUE);
+    if (sqimap_msgs_list_copy ($imap_stream, $id, $mailbox)) {
+        return sqimap_toggle_flag($imap_stream, $id, '\\Deleted', true, true);
+    } else {
+        return false;
+    }
 }
 
 
@@ -72,13 +80,19 @@ function sqimap_messages_delete ($imap_stream, $start, $end, $mailbox, $bypass_t
 }
 
 function sqimap_msgs_list_delete ($imap_stream, $mailbox, $id, $bypass_trash=false) {
+    // FIX ME, remove globals by introducing an associative array with properties
+    // as 4th argument as replacement for the bypass_trash var
     global $move_to_trash, $trash_folder;
-    $msgs_id = sqimap_message_list_squisher($id);
+    $bRes = true;
     if (($move_to_trash == true) && ($bypass_trash != true) &&
         (sqimap_mailbox_exists($imap_stream, $trash_folder) &&  ($mailbox != $trash_folder)) ) {
-        $read = sqimap_run_command ($imap_stream, "COPY $msgs_id " . sqimap_encode_mailbox_name($trash_folder), true, $response, $message, TRUE);
+        $bRes = sqimap_msgs_list_copy ($imap_stream, $id, $trash_folder);
+    }
+    if ($bRes) {
+        return sqimap_toggle_flag($imap_stream, $id, '\\Deleted', true, true);
+    } else {
+        return false;
     }
-    $read = sqimap_run_command ($imap_stream, "STORE $msgs_id +FLAGS (\\Deleted)", true, $response, $message, TRUE);
 }
 
 
@@ -92,7 +106,9 @@ function sqimap_messages_flag ($imap_stream, $start, $end, $flag, $handle_errors
 function sqimap_toggle_flag($imap_stream, $id, $flag, $set, $handle_errors) {
     $msgs_id = sqimap_message_list_squisher($id);
     $set_string = ($set ? '+' : '-');
-    $read = sqimap_run_command ($imap_stream, "STORE $msgs_id ".$set_string."FLAGS ($flag)", $handle_errors, $response, $message, TRUE);
+    $aResponse = sqimap_run_command_list($imap_stream, "STORE $msgs_id ".$set_string."FLAGS ($flag)", $handle_errors, $response, $message, TRUE);
+    // parse the fetch response
+    return parseFetch($aResponse);
 }
 
 /** @deprecated */
@@ -131,13 +147,13 @@ function sqimap_message_list_squisher($messages_array) {
 
 /**
 * Retrieves an array with a sorted uid list. Sorting is done on the imap server
-*
+* @link http://www.ietf.org/internet-drafts/draft-ietf-imapext-sort-13.txt
 * @param resource $imap_stream IMAP socket connection
 * @param string $sSortField Field to sort on
 * @param bool $reverse Reverse order search
 * @return array $id sorted uid list
 */
-function sqimap_get_sort_order ($imap_stream, $sSortField,$reverse) {
+function sqimap_get_sort_order ($imap_stream, $sSortField, $reverse, $search='ALL') {
     global  $default_charset,
             $sent_folder;
 
@@ -149,22 +165,33 @@ function sqimap_get_sort_order ($imap_stream, $sSortField,$reverse) {
         if ($reverse) {
             $sSortField = 'REVERSE '.$sSortField;
         }
-        $query = "SORT ($sSortField) ".strtoupper($default_charset).' ALL';
-        $sort_test = sqimap_run_command ($imap_stream, $query, true, $response, $message, TRUE);
-    }
-    if (isset($sort_test[0])) {
-        for ($i=0,$iCnt=count($sort_test);$i<$iCnt;++$i) {
-            if (preg_match("/^\* SORT (.+)$/", $sort_test[$i], $regs)) {
-                $id = preg_split("/ /", trim($regs[1]));
-            break;
-            }
+        $query = "SORT ($sSortField) ".strtoupper($default_charset)." $search";
+        // FIX ME sqimap_run_command should return the parsed data accessible by $aDATA['SORT']
+        $aData = sqimap_run_command ($imap_stream, $query, false, $response, $message, TRUE);
+        /* fallback to default charset */
+        if ($response == 'NO' && strpos($message,'[BADCHARSET]') !== false) {
+            $query = "SORT ($sSortField) US-ASCII $search";
+            $aData = sqimap_run_command ($imap_stream, $query, true, $response, $message, TRUE);
         }
     }
-    if (!preg_match("/OK/", $response)) {
-        return false;
+
+    if ($response == 'OK') {
+        return parseUidList($aData,'SORT');
     } else {
-        return $id;
+        return false;
+    }
+}
+
+function parseUidList($aData,$sCommand) {
+    $aUid = array();
+    if (isset($aData) && count($aData)) {
+        for ($i=0,$iCnt=count($aData);$i<$iCnt;++$i) {
+            if (preg_match("/^\* $sCommand (.+)$/", $aData[$i], $aMatch)) {
+                $aUid += preg_split("/ /", trim($aMatch[1]));
+            }
+        }
     }
+    return array_unique($aUid);
 }
 
 /**
@@ -175,12 +202,15 @@ function sqimap_get_sort_order ($imap_stream, $sSortField,$reverse) {
 * @param bool $reverse Reverse order search
 * @return array $aUid sorted uid list
 */
-function get_squirrel_sort ($imap_stream, $sSortField, $reverse = false) {
+function get_squirrel_sort ($imap_stream, $sSortField, $reverse = false, $aUid = NULL) {
+    if ($aUID === NULL) {
+
+    }
     if ($sSortField != 'RFC822.SIZE' && $sSortField != 'INTERNALDATE') {
-        $msgs = sqimap_get_small_header_list($imap_stream, false, '*',
+        $msgs = sqimap_get_small_header_list($imap_stream, $aUid,
                                       array($sSortField), array());
     } else {
-        $msgs = sqimap_get_small_header_list($imap_stream, false, '*',
+        $msgs = sqimap_get_small_header_list($imap_stream, $aUid,
                                       array(), array($sSortField));
     }
     $aUid = array();
@@ -213,7 +243,7 @@ function get_squirrel_sort ($imap_stream, $sSortField, $reverse = false) {
             $walk = true;
         }
         foreach ($msgs as $item) {
-            $aUid[$item['ID']] = $item[$sSortField];
+            $aUid[$item['UID']] = $item[$sSortField];
         }
         natcasesort($aUid);
         $aUid = array_keys($aUid);
@@ -239,7 +269,7 @@ function get_squirrel_sort ($imap_stream, $sSortField, $reverse = false) {
             $sSortField = 'SIZE';
         }
         foreach ($msgs as $item) {
-            $aUid[$item['ID']] = (isset($item[$sSortField])) ? $item[$sSortField] : 0;
+            $aUid[$item['UID']] = (isset($item[$sSortField])) ? $item[$sSortField] : 0;
         }
         if ($reverse) {
             arsort($aUid,SORT_NUMERIC);
@@ -380,26 +410,25 @@ function get_parent_level ($thread_new) {
 /**
 * Returns an array with each element as a string representing one
 * message-thread as returned by the IMAP server.
+* @link http://www.ietf.org/internet-drafts/draft-ietf-imapext-sort-13.txt
 */
-function get_thread_sort ($imap_stream) {
+function get_thread_sort ($imap_stream, $search='ALL') {
     global $thread_new, $sort_by_ref, $default_charset, $server_sort_array, $indent_array;
-    if (sqsession_is_registered('thread_new')) {
-        sqsession_unregister('thread_new');
-    }
-    if (sqsession_is_registered('indent_array')) {
-        sqsession_unregister('indent_array');
-    }
-    if (sqsession_is_registered('server_sort_array')) {
-        sqsession_unregister('server_sort_array');
-    }
+
     $thread_temp = array ();
     if ($sort_by_ref == 1) {
         $sort_type = 'REFERENCES';
     } else {
         $sort_type = 'ORDEREDSUBJECT';
     }
-    $query = "THREAD $sort_type ".strtoupper($default_charset)." ALL";
-    $thread_test = sqimap_run_command ($imap_stream, $query, true, $response, $message, TRUE);
+    $query = "THREAD $sort_type ".strtoupper($default_charset)." $search";
+
+    $thread_test = sqimap_run_command ($imap_stream, $query, false, $response, $message, TRUE);
+    /* fallback to default charset */
+    if ($response == 'NO' && strpos($message,'[BADCHARSET]') !== false) {
+        $query = "THREAD $sort_type US-ASCII $search";
+        $thread_test = sqimap_run_command ($imap_stream, $query, true, $response, $message, TRUE);
+    }
     if (isset($thread_test[0])) {
         for ($i=0,$iCnt=count($thread_test);$i<$iCnt;++$i) {
             if (preg_match("/^\* THREAD (.+)$/", $thread_test[$i], $regs)) {
@@ -452,7 +481,7 @@ function get_thread_sort ($imap_stream) {
             }
         }
     }
-    sqsession_register($thread_new, 'thread_new');
+
     $thread_new = array_reverse($thread_new);
     /* place the threads after each other in one string */
     $thread_list = implode(" ", $thread_new);
@@ -462,10 +491,7 @@ function get_thread_sort ($imap_stream) {
     $server_sort_array = $thread_list;
 
     $indent_array = get_parent_level ($thread_new);
-    sqsession_register($indent_array, 'indent_array');
-
-    sqsession_register($server_sort_array, 'server_sort_array');
-    return $thread_list;
+    return array($thread_list,$indent_array);
 }
 
 
@@ -532,17 +558,17 @@ function parseArray($read,&$i) {
     }
 }
 
-function sqimap_get_small_header_list ($imap_stream, $msg_list, $show_num=false,
+function sqimap_get_small_header_list ($imap_stream, $msg_list,
     $aHeaderFields = array('Date', 'To', 'Cc', 'From', 'Subject', 'X-Priority', 'Content-Type'),
     $aFetchItems = array('FLAGS', 'RFC822.SIZE', 'INTERNALDATE')) {
 
-    $messages = array();
+    $aMessageList = array();
     $read_list = array();
 
     $bUidFetch = ! in_array('UID', $aFetchItems, true);
 
     /* Get the small headers for each message in $msg_list */
-    if ($show_num != '999999' && $show_num != '*' ) {
+    if ($msg_list !== NULL) {//$show_num != -1 && $show_num != '*' ) {
         $msgs_str = sqimap_message_list_squisher($msg_list);
         /*
         * We need to return the data in the same order as the caller supplied
@@ -551,15 +577,14 @@ function sqimap_get_small_header_list ($imap_stream, $msg_list, $show_num=false,
         */
         if ($bUidFetch) {
             for ($i = 0; $i < sizeof($msg_list); $i++) {
-                $messages["$msg_list[$i]"] = array();
+                $aMessageList["$msg_list[$i]"] = array();
             }
         }
     } else {
         $msgs_str = '1:*';
+        $aId = array();
     }
 
-
-
     /*
      * Create the query
      */
@@ -574,11 +599,14 @@ function sqimap_get_small_header_list ($imap_stream, $msg_list, $show_num=false,
         $sFetchItems .= ' BODY.PEEK[HEADER.FIELDS ('.$sHeaderFields.')]';
     }
     $query .= trim($sFetchItems) . ')';
+    $aResponse = sqimap_run_command_list ($imap_stream, $query, true, $response, $message, $bUidFetch);
+    $aMessages = parseFetch($aResponse,$aMessageList);
+    array_reverse($aMessages);
+    return $aMessages;
+}
 
-    $read_list = sqimap_run_command_list ($imap_stream, $query, true, $response, $message, $bUidFetch);
-    $i = 0;
-
-    foreach ($read_list as $r) {
+function parseFetch($aResponse,$aMessageList = array()) {
+    foreach ($aResponse as $r) {
         $msg = array();
         // use unset because we do isset below
         $read = implode('',$r);
@@ -590,6 +618,7 @@ function sqimap_get_small_header_list ($imap_stream, $msg_list, $show_num=false,
         /* extract the message id */
         $i_space = strpos($read,' ',2);
         $id = substr($read,2,$i_space-2);
+        $msg['ID'] = $id;
         $fetch = substr($read,$i_space+1,5);
         if (!is_numeric($id) && $fetch !== 'FETCH') {
             $msg['ERROR'] = $read; // htmlspecialchars should be done just before display. this is backend code
@@ -711,15 +740,15 @@ function sqimap_get_small_header_list ($imap_stream, $msg_list, $show_num=false,
             }
         }
         $msgi ="$unique_id";
-        $msg['ID'] = $unique_id;
+        $msg['UID'] = $unique_id;
 
-        $messages[$msgi] = $msg;
+        $aMessageList[$msgi] = $msg;
         ++$msgi;
     }
-    array_reverse($messages);
-    return $messages;
+    return $aMessageList;
 }
 
+
 function sqimap_parse_envelope($read, &$i, &$msg) {
     $arg_no = 0;
     $arg_a = array();

Tiedoston diff-näkymää rajattu, sillä se on liian suuri
+ 639 - 282
functions/mailbox_display.php


+ 8 - 8
functions/rfc822address.php

@@ -29,15 +29,15 @@ if (!defined('SQM_ADDR_HOST'))     define('SQM_ADDR_HOST',     3);
  **/
 
 function parseRFC822Address($sAddress,$aProps) {
-    $aPropsDefault = array (
-                            'domain' => '',         //
-                            'limit'  => 0,          // limits returned addresses
-                            'abooklookup' => false); // callback function for addressbook lookup
-
-    $aProps = is_array($aProps) ? array_merge($aPropsDefault,$aProps) : $aPropsDefault;
+//    $aPropsDefault = array (
+//                            'domain' => '',         //
+//                            'limit'  => 0,          // limits returned addresses
+//                            'abooklookup' => false); // callback function for addressbook lookup
+//
+//    $aProps = is_array($aProps) ? array_merge($aPropsDefault,$aProps) : $aPropsDefault;
 
-    $cbLookup = $aProps['abooklookup'];
-    $sDomain  = $aProps['domain'];
+//    $cbLookup = $aProps['abooklookup'];
+//    $sDomain  = $aProps['domain'];
     $iLimit   = $aProps['limit'];
 
     $aTokens = _getAddressTokens($sAddress);

+ 6 - 8
include/load_prefs.php

@@ -73,8 +73,8 @@ if (isset($chosen_theme) && $found_theme && (file_exists($chosen_theme))) {
 }
 
 
-if (!defined('download_php')) { 
-    sqsession_register($theme_css, 'theme_css'); 
+if (!defined('download_php')) {
+    sqsession_register($theme_css, 'theme_css');
 }
 
 // user's icon theme, if using icons
@@ -91,11 +91,11 @@ $move_to_trash =
 $save_as_draft =
     getPref($data_dir, $username, 'save_as_draft', $default_save_as_draft);
 
-if ($default_unseen_type == '') { 
-    $default_unseen_type = 1; 
+if ($default_unseen_type == '') {
+    $default_unseen_type = 1;
 }
-if ($default_unseen_notify == '') { 
-    $default_unseen_notify = 2; 
+if ($default_unseen_notify == '') {
+    $default_unseen_notify = 2;
 }
 $unseen_type =
     getPref($data_dir, $username, 'unseen_type', $default_unseen_type);
@@ -174,8 +174,6 @@ $reply_focus = getPref($data_dir, $username, 'reply_focus', '');
 $left_refresh = getPref($data_dir, $username, 'left_refresh', SMPREF_NONE );
 $left_refresh = strtolower($left_refresh);
 
-$sort = getPref($data_dir, $username, 'sort', 6 );
-
 /** Load up the Signature file **/
 $signature_abs = $signature = getSig($data_dir, $username, 'g');
 

+ 19 - 7
src/download.php

@@ -14,7 +14,7 @@
  */
 
 /**
- * Path for SquirrelMail required files. 
+ * Path for SquirrelMail required files.
  * @ignore
  */
 define('SM_PATH','../');
@@ -31,23 +31,34 @@ header('Cache-Control: cache');
 sqgetGlobalVar('key',        $key,          SQ_COOKIE);
 sqgetGlobalVar('username',   $username,     SQ_SESSION);
 sqgetGlobalVar('onetimepad', $onetimepad,   SQ_SESSION);
+sqgetGlobalVar('mailbox_cache',$mailbox_cache,SQ_SESSION);
 sqgetGlobalVar('messages',   $messages,     SQ_SESSION);
 sqgetGlobalVar('mailbox',    $mailbox,      SQ_GET);
 sqgetGlobalVar('ent_id',     $ent_id,       SQ_GET);
 sqgetGlobalVar('absolute_dl',$absolute_dl,  SQ_GET);
 if ( sqgetGlobalVar('passed_id', $temp, SQ_GET) ) {
-  $passed_id = (int) $temp;
+    $passed_id = (int) $temp;
 }
 
 /* end globals */
 
 $imapConnection = sqimap_login($username, $key, $imapServerAddress, $imapPort, 0);
-$mbx_response =  sqimap_mailbox_select($imapConnection, $mailbox);
+$aMailbox = sqm_api_mailbox_select($imapConnection, $mailbox,array(),array());
 
-$message = &$messages[$mbx_response['UIDVALIDITY']]["$passed_id"];
-if (!is_object($message)) {
-    $message = sqimap_get_message($imapConnection,$passed_id, $mailbox);
+if (isset($aMailbox['MSG_HEADERS'][$passed_id]['MESSAGE_OBJECT']) &&
+    is_object($aMailbox['MSG_HEADERS'][$passed_id]['MESSAGE_OBJECT']) ) {
+    $message = $aMailbox['MSG_HEADERS'][$passed_id]['MESSAGE_OBJECT'];
+} else {
+   $message = sqimap_get_message($imapConnection, $passed_id, $mailbox);
+   $aMailbox['MSG_HEADERS'][$passed_id]['MESSAGE_OBJECT'] = $message;
 }
+
+//$mbx_response =  sqimap_mailbox_select($imapConnection, $mailbox);
+
+//$message = &$messages[$mbx_response['UIDVALIDITY']]["$passed_id"];
+//if (!is_object($message)) {
+//    $message = sqimap_get_message($imapConnection,$passed_id, $mailbox);
+//}
 $subject = $message->rfc822_header->subject;
 if ($ent_id) {
     $message = &$message->getEntity($ent_id);
@@ -138,5 +149,6 @@ if (isset($absolute_dl) && $absolute_dl) {
 /* be aware that any warning caused by download.php will corrupt the
  * attachment in case of ERROR reporting = E_ALL and the output is the screen */
 mime_print_body_lines ($imapConnection, $passed_id, $ent_id, $encoding);
-
+$mailbox_cache[$aMailbox['NAME']] = $aMailbox;
+sqsession_register($mailbox_cache,'mailbox_cache');
 ?>

+ 11 - 11
src/left_main.php

@@ -68,7 +68,7 @@ function formatMailboxName($imapConnection, $box_array) {
 
     /* Create the link for this folder. */
     if ($status !== false) {
-    $line .= '<a href="right_main.php?PG_SHOWALL=0&amp;sort=0&amp;startMessage=1&amp;mailbox='.
+    $line .= '<a href="right_main.php?PG_SHOWALL=0&amp;startMessage=1&amp;mailbox='.
                 $mailboxURL.'" TARGET="right" STYLE="text-decoration:none">';
     }
     if ($special_color) {
@@ -297,7 +297,7 @@ function is_parent_box($curbox_name, $parbox_name) {
 
 function ListBoxes ($boxes, $j=0 ) {
     global $data_dir, $username, $startmessage, $color, $unseen_notify, $unseen_type,
-           $move_to_trash, $trash_folder, $collapse_folders, $imapConnection, 
+           $move_to_trash, $trash_folder, $collapse_folders, $imapConnection,
            $use_icons, $icon_theme, $use_special_folder_color;
 
     if (!isset($boxes) || empty($boxes))
@@ -380,7 +380,7 @@ function ListBoxes ($boxes, $j=0 ) {
         if ($unseen > 0) {
             $pre .= '<b>';
         }
-        $pre .= "<a href=\"right_main.php?PG_SHOWALL=0&amp;sort=0;startMessage=1&amp;mailbox=$mailboxURL\" target=\"right\" style=\"text-decoration:none\">";
+        $pre .= "<a href=\"right_main.php?PG_SHOWALL=0&amp;startMessage=1&amp;mailbox=$mailboxURL\" target=\"right\" style=\"text-decoration:none\">";
         if ($unseen > 0) {
             $end .= '</b>';
         }
@@ -389,7 +389,7 @@ function ListBoxes ($boxes, $j=0 ) {
             if ($unseen > 0) {
                 $pre .= '<b>';
             }
-            $pre .= "<a href=\"right_main.php?PG_SHOWALL=0&amp;sort=0;startMessage=1&amp;mailbox=$mailboxURL\" target=\"right\" style=\"text-decoration:none\">";
+            $pre .= "<a href=\"right_main.php?PG_SHOWALL=0&amp;startMessage=1&amp;mailbox=$mailboxURL\" target=\"right\" style=\"text-decoration:none\">";
             if ($unseen > 0) {
                 $end .= '</b>';
             }
@@ -406,7 +406,7 @@ function ListBoxes ($boxes, $j=0 ) {
             if ($unseen > 0) {
                 $pre .= '<b>';
             }
-            $pre .= "<a href=\"right_main.php?PG_SHOWALL=0&amp;sort=0&amp;startMessage=1&amp;mailbox=$mailboxURL\" target=\"right\" style=\"text-decoration:none\">";
+            $pre .= "<a href=\"right_main.php?PG_SHOWALL=0&amp;startMessage=1&amp;mailbox=$mailboxURL\" target=\"right\" style=\"text-decoration:none\">";
             if ($unseen > 0) {
                 $end .= '</b>';
             }
@@ -428,7 +428,7 @@ function ListBoxes ($boxes, $j=0 ) {
 
     // let plugins fiddle with end of line
     $end .= concat_hook_function('left_main_after_each_folder',
-        array(isset($numMessages) ? $numMessages : '', 
+        array(isset($numMessages) ? $numMessages : '',
               $boxes->mailboxname_full, $imapConnection));
 
     $end .= '</nobr>';
@@ -519,7 +519,7 @@ function ListAdvancedBoxes ($boxes, $mbx, $j='ID.0000' ) {
         if (! isset($numMessages)) {
             $numMessages = $boxes->total;
         }
-        $pre = "<a class=\"mbx_link\" href=\"right_main.php?PG_SHOWALL=0&amp;sort=0&amp;startMessage=1&amp;mailbox=$mailboxURL\" target=\"right\">" . $pre;
+        $pre = "<a class=\"mbx_link\" href=\"right_main.php?PG_SHOWALL=0&amp;startMessage=1&amp;mailbox=$mailboxURL\" target=\"right\">" . $pre;
         $end .= '</a>';
         if ($numMessages > 0) {
             $urlMailbox = urlencode($mailbox);
@@ -529,7 +529,7 @@ function ListAdvancedBoxes ($boxes, $mbx, $j='ID.0000' ) {
         }
     } else {
         if (!$boxes->is_noselect) { /* \Noselect boxes can't be selected */
-            $pre = "<a class=\"mbx_link\" href=\"right_main.php?PG_SHOWALL=0&amp;sort=0&amp;startMessage=1&amp;mailbox=$mailboxURL\" target=\"right\">" . $pre;
+            $pre = "<a class=\"mbx_link\" href=\"right_main.php?PG_SHOWALL=0&amp;startMessage=1&amp;mailbox=$mailboxURL\" target=\"right\">" . $pre;
             $end .= '</a>';
         }
     }
@@ -537,7 +537,7 @@ function ListAdvancedBoxes ($boxes, $mbx, $j='ID.0000' ) {
     // let plugins fiddle with end of line
     global $imapConnection;
     $end .= concat_hook_function('left_main_after_each_folder',
-        array(isset($numMessages) ? $numMessages : '', 
+        array(isset($numMessages) ? $numMessages : '',
               $boxes->mailboxname_full, $imapConnection));
 
     if (!$boxes->is_root) {
@@ -934,7 +934,7 @@ if ($auto_create_special && !isset($auto_create_done)) {
                 sqimap_mailbox_create($imapConnection, $folder, '');
             } else {
                 //if (!sqimap_mailbox_is_subscribed($imapConnection, $folder)) {
-                // check for subscription is useless and expensive  just 
+                // check for subscription is useless and expensive  just
                 // surpress the NO response
                 sqimap_subscribe($imapConnection, $folder, false);
             }
@@ -1112,7 +1112,7 @@ for ($i = 0; $i < count($boxes); $i++) {
         echo '</small>';
         echo '</form>'."\n";
     } else {
-        //sqimap_get_status_mbx_tree($imap_stream,$boxes)    
+        //sqimap_get_status_mbx_tree($imap_stream,$boxes)
         ListBoxes($boxes);
     }
 } /* if ($oldway) else ... */

+ 132 - 1
src/move_messages.php

@@ -1,5 +1,5 @@
 <?php
-
+exit;
 /**
  * move_messages.php
  *
@@ -265,5 +265,136 @@ if ($exception) {
     header("Location: $location");
     exit;
 }
+
+function handleMessageListForm($imapConnection,&$aMailbox) {
+    /* incoming formdata */
+    sqgetGlobalVar('moveButton',      $moveButton,      SQ_POST);
+    sqgetGlobalVar('expungeButton',   $expungeButton,   SQ_POST);
+    sqgetGlobalVar('targetMailbox',   $targetMailbox,   SQ_POST);
+    sqgetGlobalVar('expungeButton',   $expungeButton,   SQ_POST);
+    sqgetGlobalVar('undeleteButton',  $undeleteButton,  SQ_POST);
+    sqgetGlobalVar('markRead',        $markRead,        SQ_POST);
+    sqgetGlobalVar('markUnread',      $markUnread,      SQ_POST);
+    sqgetGlobalVar('markFlagged',     $markFlagged,     SQ_POST);
+    sqgetGlobalVar('markUnflagged',   $markUnflagged,   SQ_POST);
+    sqgetGlobalVar('attache',         $attache,         SQ_POST);
+    sqgetGlobalVar('location',        $location,        SQ_POST);
+    sqgetGlobalVar('bypass_trash',    $bypass_trash,    SQ_POST);
+    sqgetGlobalVar('msg',             $msg,             SQ_POST);
+
+    $sError = '';
+    /* retrieve the check boxes */
+    $aUid = array();
+    if (isset($msg) && is_array($msg)) {
+        foreach( $msg as $key=>$iUid ) {
+            // using foreach removes the risk of infinite loops that was there //
+            $aUid[] = $iUid;
+        }
+    }
+    $num_ids = count($id);
+
+    if (count($num_ids) && !isset($expungeButton)) {
+        /* handle submit buttons */
+        $sButton = '';
+        $sButton = (isset($expungeButton)) ? 'expunge'      : $sButton;
+        $sButton = (isset($attache))       ? 'attache'      : $sButton;
+        $sButton = (isset($moveButton))    ? 'move'         : $sButton;
+        $sButton = (isset($copyButton))    ? 'copy'         : $sButton;
+        $sButton = (isset($markDelete))    ? 'setDeleted'   : $sButton;
+        $sButton = (isset($markUndelete))  ? 'unsetDeleted' : $sButton;
+        $sButton = (isset($markSeen))      ? 'setSeen'      : $sButton;
+        $sButton = (isset($markUnseen))    ? 'unsetSeen'    : $sButton;
+        $sButton = (isset($markFlagged))   ? 'setFlagged'   : $sButton;
+        $sButton = (isset($markUnflagged)) ? 'unsetFlagged' : $sButton;
+
+        $aUpdatedMsgs = false;
+        $bExpunge = false;
+        switch ($sButton) {
+          case 'setDeleted':
+            // What kind of hook is this, can it be removed?
+            if (!boolean_hook_function('move_messages_button_action', NULL, 1)) {
+                $aUpdatedMsgs = sqimap_msgs_list_delete($imapConnection, $mailbox, $aUid,$bypass_trash);
+                $bExpunge = true;
+            }
+            break;
+          case 'unsetDeleted':
+          case 'setSeen':
+          case 'unsetSeen':
+          case 'setFlagged':
+          case 'unsetFlagged':
+            // get flag
+            $sFlag = (substr($sButton,0,3) == 'set') ? '\\'.substr($sButton,3) : '\\'.substr($sButton,5);
+            $bSet  = (substr($sButton,0,3) == 'set') ? true : false;
+            $aUpdatedMsgs = sqimap_toggle_flag($imapConnection, $aUid, $sFlag, $bSet, true);
+            break;
+          case 'move':
+            $aUpdatedMsgs = sqimap_msgs_list_move($imapConnection,$aId,$targetMailbox);
+            $bExpunge = true;
+            break;
+          case 'attache':
+            $composesession = attachSelectedMessages($id, $imapConnection);
+            // dirty hack, add info to $aMailbox
+            $aMailbox['FORWARD_SESSION'] = $composesession;
+            break;
+        }
+
+        if ($aUpdatedMsgs) {
+            foreach ($aUpdatedMsgs as $iUid => $aMsg) {
+                if (isset($aMsg['FLAGS'])) {
+                    $aMailbox['MSG_HEADERS'][$iUid]['FLAGS'] = $aMsg['FLAGS'];
+                }
+            }
+            if ($bExpunge && $aMailbox['AUTO_EXPUNGE'] &&
+                $iExpungedMessages = sqimap_mailbox_expunge($imapConnection, $aMailbox['NAME'], true))
+                {
+                if (count($aUpdateMsgs != $iExpungedMessages)) {
+                    // there are more messages deleted permanently then we expected
+                    // invalidate the cache
+                    $aMailbox['UIDSET'] = false;
+                    $aMailbox['MSG_HEADERS'] = false;
+                } else {
+                    // remove expunged messages from cache
+                    $aUidSet = $aMailbox['UIDSET'];
+                    $aDeleted = array();
+                    foreach ($aUpdatedMsgs as $iUid => $aValue) {
+                        if (isset($aValue['FLAGS']['\\deleted']) && $aValue['FLAGS']['\\deleted']) {
+                            $aDeleted[] = $iUid;
+                        }
+                    }
+                    if (count($aDeleted)) {
+                        // create a UID => array index temp array
+                        $aUidSetDummy = array_flip($aUidSet);
+                        foreach ($aDeleted as $iUid) {
+                            unset($aUidSetDummy[$iUid]);
+                        }
+                        $aUidSet = array_keys($aUidSetDummy);
+                        $aMailbox['UIDSET'] = $aUidSet;
+                        // update EXISTS info
+                        $aMailbox['EXISTS'] -= $iExpungedMessages;
+                    }
+                }
+                // Change the startMessage number if the mailbox was changed
+                if (($aMailbox['PAGEOFFSET']+$iExpungedMessages-1) >= $aMailbox['EXISTS']) {
+                    $aMailbox['PAGEOFFSET'] = ($aMailbox['PAGEOFFSET'] > $aMailbox['LIMIT']) ?
+                        $aMailbox['PAGEOFFSET'] - $aMailbox['LIMIT'] : 1;
+                }
+            }
+        }
+    } else {
+        if (isset($expungeButton)) {
+            // on expunge we do not know which messages will be deleted
+            // so it's useless to try to sync the cache
+
+            // Close the mailbox so we do not need to parse the untagged expunge responses
+            sqimap_run_command($imapConnection,'CLOSE',false,$result,$message);
+            $aMbxResponse = sqimap_select($imapConnection,$aMailbox['NAME'];
+            // update the $aMailbox array
+            $aMailbox['EXISTS'] = $aMbxResponse['EXISTS'];
+            $aMailbox['UIDSET'] = false;
+        } else {
+            $sError = _("No messages were selected.");
+        }
+    }
+}
 ?>
 </BODY></HTML>

+ 90 - 109
src/read_body.php

@@ -38,10 +38,11 @@ require_once(SM_PATH . 'functions/mailbox_display.php');
  * @return the index of the next valid message from the array
  */
 function findNextMessage($uidset,$passed_id='backwards') {
+    if (!is_array($uidset)) {
+        return -1;
+    }
     if ($passed_id=='backwards' || !is_array($uidset)) { // check for backwards compattibilty gpg plugin
         $passed_id = $uidset;
-        sqgetGlobalVar('server_sort_array',$server_sort_array,SQ_SESSION);
-        $uidset = $server_sort_array;
     }
     $result = -1;
     $count = count($uidset) - 1;
@@ -66,9 +67,8 @@ function findNextMessage($uidset,$passed_id='backwards') {
  */
 
 function findPreviousMessage($uidset, $passed_id) {
-    if (!is_array($uidset)) { //obsolete check
-        sqgetGlobalVar('server_sort_array',$server_sort_array,SQ_SESSION);
-        $uidset = $server_sort_array;
+    if (!is_array($uidset)) {
+        return -1;
     }
     $result = -1;
     foreach($uidset as $key=>$value) {
@@ -298,16 +298,16 @@ function ClearAttachments() {
 
     $rem_attachments = array();
     if (isset($attachments)) {
-	foreach ($attachments as $info) {
-    	    if ($info['session'] == -1) {
-        	$attached_file = "$hashed_attachment_dir/$info[localfilename]";
-        	if (file_exists($attached_file)) {
-            	    unlink($attached_file);
-        	}
-    	    } else {
-        	$rem_attachments[] = $info;
-    	    }
-	}
+        foreach ($attachments as $info) {
+            if ($info['session'] == -1) {
+                $attached_file = "$hashed_attachment_dir/$info[localfilename]";
+                if (file_exists($attached_file)) {
+                        unlink($attached_file);
+                }
+            } else {
+                $rem_attachments[] = $info;
+            }
+        }
     }
     $attachments = $rem_attachments;
 }
@@ -456,7 +456,7 @@ function formatEnvheader($aMailbox, $passed_id, $passed_ent_id, $message,
  * @param object $message Current message object
  * @param object $mbx_response
  */
-function formatMenubar($aMailbox, $passed_id, $passed_ent_id, $message, $mbx_response, $nav_on_top = TRUE) {
+function formatMenubar($aMailbox, $passed_id, $passed_ent_id, $message, $removedVar, $nav_on_top = TRUE) {
     global $base_uri, $draft_folder, $where, $what, $color, $sort,
            $startMessage, $PHP_SELF, $save_as_draft,
            $enable_forward_as_attachment, $imapConnection, $lastTargetMailbox,
@@ -523,14 +523,21 @@ function formatMenubar($aMailbox, $passed_id, $passed_ent_id, $message, $mbx_res
         $nav_row .= $double_delimiter . '[<a href="'.$url.'">'._("View Message").'</a>]';
 
     // Prev/Next links for regular messages
-    } else if ( !(isset($where) && isset($what)) ) {
-        $prev = findPreviousMessage($aMailbox['UIDSET'], $passed_id);
-        $next = findNextMessage($aMailbox['UIDSET'],$passed_id);
+    } else if ( true ) { //!(isset($where) && isset($what)) ) {
+        /**
+         * Check if cache is still valid
+         */
+        if (!is_array($aMailbox['UIDSET'][$what])) {
+            fetchMessageHeaders($imapConnection, $aMailbox);
+        }
+        $prev = findPreviousMessage($aMailbox['UIDSET'][$what], $passed_id);
+        $next = findNextMessage($aMailbox['UIDSET'][$what],$passed_id);
 
         $prev_link = _("Previous");
         if ($prev >= 0) {
             $uri = $base_uri . 'src/read_body.php?passed_id='.$prev.
                    '&amp;mailbox='.$urlMailbox.'&amp;sort='.$sort.
+                   "&amp;where=$where&amp;what=$what" .
                    '&amp;startMessage='.$startMessage.'&amp;show_more=0';
             $prev_link = '<a href="'.$uri.'">'.$prev_link.'</a>';
         }
@@ -539,6 +546,7 @@ function formatMenubar($aMailbox, $passed_id, $passed_ent_id, $message, $mbx_res
         if ($next >= 0) {
             $uri = $base_uri . 'src/read_body.php?passed_id='.$next.
                    '&amp;mailbox='.$urlMailbox.'&amp;sort='.$sort.
+                   "&amp;where=$where&amp;what=$what" .
                    '&amp;startMessage='.$startMessage.'&amp;show_more=0';
             $next_link = '<a href="'.$uri.'">'.$next_link.'</a>';
         }
@@ -546,12 +554,13 @@ function formatMenubar($aMailbox, $passed_id, $passed_ent_id, $message, $mbx_res
         // Only bother with Delete & Prev and Delete & Next IF
         // top display is enabled.
         if ( $delete_prev_next_display == 1 &&
-               in_array('\\deleted', $mbx_response['PERMANENTFLAGS'],true) ) {
+               in_array('\\deleted', $aMailbox['PERMANENTFLAGS'],true) ) {
             $del_prev_link = _("Delete & Prev");
             if ($prev >= 0) {
                 $uri = $base_uri . 'src/read_body.php?passed_id='.$prev.
                        '&amp;mailbox='.$urlMailbox.'&amp;sort='.$sort.
                        '&amp;startMessage='.$startMessage.'&amp;show_more=0'.
+                       "&amp;where=$where&amp;what=$what" .
                        '&amp;delete_id='.$passed_id;
                 $del_prev_link = '<a href="'.$uri.'">'.$del_prev_link.'</a>';
             }
@@ -561,6 +570,7 @@ function formatMenubar($aMailbox, $passed_id, $passed_ent_id, $message, $mbx_res
                 $uri = $base_uri . 'src/read_body.php?passed_id='.$next.
                        '&amp;mailbox='.$urlMailbox.'&amp;sort='.$sort.
                        '&amp;startMessage='.$startMessage.'&amp;show_more=0'.
+                       "&amp;where=$where&amp;what=$what" .
                        '&amp;delete_id='.$passed_id;
                 $del_next_link = '<a href="'.$uri.'">'.$del_next_link.'</a>';
             }
@@ -572,13 +582,11 @@ function formatMenubar($aMailbox, $passed_id, $passed_ent_id, $message, $mbx_res
     }
 
     // Start with Search Results or Message List link.
-    if (isset($where) && isset($what)) {
-        $msgs_url .= 'search.php?where=' . urlencode($where) .
-                     '&amp;what=' . urlencode($what) . '&amp;mailbox=' . $urlMailbox;
+    $msgs_url .= "$where?where=read_body.php&amp;what=$what&amp;mailbox=" . $urlMailbox.
+                 "&amp;startMessage=$startMessage";
+    if ($where == 'search.php') {
         $msgs_str  = _("Search Results");
     } else {
-        $msgs_url .= 'right_main.php?sort=' . $sort . '&amp;startMessage=' .
-                     $startMessage . '&amp;mailbox=' . $urlMailbox;
         $msgs_str  = _("Message List");
     }
     $nav_row .= $double_delimiter .
@@ -632,26 +640,19 @@ function formatMenubar($aMailbox, $passed_id, $passed_ent_id, $message, $mbx_res
 
     $menu_row .= '</form>&nbsp;';
 
-    if ( in_array('\\deleted', $mbx_response['PERMANENTFLAGS'],true) ) {
-    // Form for deletion
-        $delete_url = $base_uri . 'src/delete_message.php?mailbox=' . $urlMailbox;
+    if ( in_array('\\deleted', $aMailbox['PERMANENTFLAGS'],true) ) {
+    // Form for deletion. Form is handled by the originating display in $where. This is right_main.php or search.php
+        $delete_url = $base_uri . "src/$where";
         $menu_row .= '<form action="'.$delete_url.'" method="post" style="display: inline">';
 
         if (!(isset($passed_ent_id) && $passed_ent_id)) {
-            $menu_row .= addHidden('message', $passed_id);
-
-            if ($where && $what) {
-            $menu_row .= addHidden('where', $where);
-            $menu_row .= addHidden('what',  $what);
-            } else {
-            $menu_row .= addHidden('sort',  $sort);
-            $menu_row .= addHidden('startMessage', $startMessage);
-            }
+            $menu_row .= addHidden('mailbox', $aMailbox['NAME']);
+            $menu_row .= addHidden('msg[0]', $passed_id);
             $menu_row .= getButton('SUBMIT', 'delete', _("Delete"));
             $menu_row .= '<input type="checkbox" name="bypass_trash">' . _("Bypass Trash");
+        } else {
+            $menu_row .= getButton('SUBMIT', 'delete', _("Delete"), '', FALSE) . "\n"; // delete button is disabled
         }
-        else
-        $menu_row .= getButton('SUBMIT', 'delete', _("Delete"), '', FALSE) . "\n"; // delete button is disabled
 
         $menu_row .= '</form>';
     }
@@ -659,25 +660,13 @@ function formatMenubar($aMailbox, $passed_id, $passed_ent_id, $message, $mbx_res
     // Add top move link
     $menu_row .= '</small></td><td align="right">';
     if ( !(isset($passed_ent_id) && $passed_ent_id) &&
-        in_array('\\deleted', $mbx_response['PERMANENTFLAGS'],true) ) {
-
-        $current_box = 'mailbox='.$mailbox.'&sort='.$sort.'&startMessage='.$startMessage;
-
-        // Set subsequent location based on whether or not there is a 'next' message.
-        if ( isset($next) && $next >= 0 ) {
-            $location = $base_uri . 'src/read_body.php?passed_id='.$next.'&';
-        } elseif (isset($prev) && $prev >= 0) {
-            $location = $base_uri . 'src/read_body.php?passed_id='.$prev.'&';
-        } else {
-            $location = $base_uri . 'src/right_main.php?';
-        }
+        in_array('\\deleted', $aMailbox['PERMANENTFLAGS'],true) ) {
 
-        $menu_row .= '<form action="'.$base_uri.'src/move_messages.php?'.$current_box.'" method="post" style="display: inline">'.
+        $menu_row .= '<form action="'.$base_uri.'src/'.$where.'?'.'" method="post" style="display: inline">'.
               '<small>'.
-	      addHidden('show_more', '0' ).
-	      addHidden('dmn', '1').
-	      addHidden('location', $location.$current_box).
-	      addHidden('msg[0]', $passed_id) . _("Move to:") .
+
+          addHidden('mailbox',$aMailbox['NAME']) .
+          addHidden('msg[0]', $passed_id) . _("Move to:") .
               '<select name="targetMailbox" style="padding: 0px; margin: 0px">';
 
         if (isset($lastTargetMailbox) && !empty($lastTargetMailbox)) {
@@ -753,19 +742,19 @@ sqgetGlobalVar('username',  $username,      SQ_SESSION);
 sqgetGlobalVar('onetimepad',$onetimepad,    SQ_SESSION);
 sqgetGlobalVar('delimiter', $delimiter,     SQ_SESSION);
 sqgetGlobalVar('base_uri',  $base_uri,      SQ_SESSION);
-
-sqgetGlobalVar('msgs',      $msgs,          SQ_SESSION);
-sqgetGlobalVar('msort',     $msort,         SQ_SESSION);
 sqgetGlobalVar('lastTargetMailbox', $lastTargetMailbox, SQ_SESSION);
-sqgetGlobalVar('server_sort_array', $server_sort_array, SQ_SESSION);
 if (!sqgetGlobalVar('messages', $messages, SQ_SESSION) ) {
     $messages = array();
 }
 
 /** GET VARS */
 sqgetGlobalVar('sendreceipt',   $sendreceipt,   SQ_GET);
-sqgetGlobalVar('where',         $where,         SQ_GET);
-sqgetGlobalVar('what',          $what,          SQ_GET);
+if (!sqgetGlobalVar('where',         $where,         SQ_GET) ) {
+    $where = 'right_main.php';
+}
+if (!sqgetGlobalVar('what',          $what,          SQ_GET) ){
+    $what = 0;
+}
 if ( sqgetGlobalVar('show_more', $temp,  SQ_GET) ) {
     $show_more = (int) $temp;
 }
@@ -791,39 +780,36 @@ if ( sqgetGlobalVar('sort', $temp) ) {
 }
 if ( sqgetGlobalVar('startMessage', $temp) ) {
     $startMessage = (int) $temp;
+} else {
+    $startMessage = 1;
 }
+/**
+ * Retrieve mailbox cache
+ */
+sqgetGlobalVar('mailbox_cache',$mailbox_cache,SQ_SESSION);
 
 /* end of get globals */
 global $sqimap_capabilities, $lastTargetMailbox;
 
 $imapConnection = sqimap_login($username, $key, $imapServerAddress, $imapPort, 0);
-$mbx_response   = sqimap_mailbox_select($imapConnection, $mailbox, false, false, true);
+$aMailbox = sqm_api_mailbox_select($imapConnection, $mailbox,array('setindex' => $what),array());
 
-global $allow_thread_sort, $auto_expunge;
-
-if ($allow_thread_sort && getPref($data_dir, $username, "thread_$mailbox",0)) {
-    $aMailbox['SORT_METHOD'] = 'THREAD';
-} else if ($allow_server_sort) {
-    $aMailbox['SORT_METHOD'] = 'SERVER';
-} else {
-    $aMailbox['SORT_METHOD'] = 'SQUIRREL';
+/**
+ * Update the seen state
+ * and ignore in_array('\\seen',$aMailbox['PERMANENTFLAGS'],true)
+ */
+if (isset($aMailbox['MSG_HEADERS'][$passed_id]['FLAGS'])) {
+    $aMailbox['MSG_HEADERS'][$passed_id]['FLAGS']['\\seen'] = true;
 }
-sqgetGlobalVar('aLastSelectedMailbox',$aMailbox,SQ_SESSION);
-$aMailbox['UIDSET'] = $server_sort_array;
-$aMailbox['SORT'] = $sort;
-$aMailbox['NAME'] = $mailbox;
-$aMailbox['EXISTS'] = $mbx_response['EXISTS'];
-$aMailbox['AUTO_EXPUNGE'] = $auto_expunge;
-$aMailbox['MSG_HEADERS'] = $msgs;
-
 
 /**
  * Process Delete from delete-move-next
  * but only if delete_id was set
  */
 if ( sqgetGlobalVar('delete_id', $delete_id, SQ_GET) ) {
-    sqimap_messages_delete($imapConnection, $delete_id, $delete_id, $mailbox);
-    sqimap_mailbox_expunge_dmn($imapConnection,$aMailbox,$delete_id);
+    handleMessageListForm($imapConnection,$aMailbox,$sButton='setDeleted', array($delete_id));
+//    sqimap_messages_delete($imapConnection, $delete_id, $delete_id, $mailbox);
+//    sqimap_mailbox_expunge_dmn($imapConnection,$aMailbox,$delete_id);
 }
 
 /**
@@ -831,33 +817,27 @@ if ( sqgetGlobalVar('delete_id', $delete_id, SQ_GET) ) {
  * including header and body
  */
 
-$uidvalidity = $mbx_response['UIDVALIDITY'];
-
-if (!isset($messages[$uidvalidity])) {
-   $messages[$uidvalidity] = array();
-}
-if (!isset($messages[$uidvalidity][$passed_id]) || $delete_id) {
-   $message = sqimap_get_message($imapConnection, $passed_id, $mailbox);
-   $FirstTimeSee = !$message->is_seen;
-   $message->is_seen = true;
-   $messages[$uidvalidity][$passed_id] = $message;
+if (isset($aMailbox['MSG_HEADERS'][$passed_id]['MESSAGE_OBJECT'])) {
+    $message = $aMailbox['MSG_HEADERS'][$passed_id]['MESSAGE_OBJECT'];
+    $FirstTimeSee = !$message->is_seen;
 } else {
-//   $message = sqimap_get_message($imapConnection, $passed_id, $mailbox);
-   $message = $messages[$uidvalidity][$passed_id];
-   $FirstTimeSee = !$message->is_seen;
+    $message = sqimap_get_message($imapConnection, $passed_id, $mailbox);
+    $FirstTimeSee = !$message->is_seen;
+    $message->is_seen = true;
+    $aMailbox['MSG_HEADERS'][$passed_id]['MESSAGE_OBJECT'] = $message;
 }
 
 if (isset($passed_ent_id) && $passed_ent_id) {
-   $message = $message->getEntity($passed_ent_id);
-   if ($message->type0 != 'message'  && $message->type1 != 'rfc822') {
-      $message = $message->parent;
-   }
-   $read = sqimap_run_command ($imapConnection, "FETCH $passed_id BODY[$passed_ent_id.HEADER]", true, $response, $msg, TRUE);
-   $rfc822_header = new Rfc822Header();
-   $rfc822_header->parseHeader($read);
-   $message->rfc822_header = $rfc822_header;
+    $message = $message->getEntity($passed_ent_id);
+    if ($message->type0 != 'message'  && $message->type1 != 'rfc822') {
+        $message = $message->parent;
+    }
+    $read = sqimap_run_command ($imapConnection, "FETCH $passed_id BODY[$passed_ent_id.HEADER]", true, $response, $msg, TRUE);
+    $rfc822_header = new Rfc822Header();
+    $rfc822_header->parseHeader($read);
+    $message->rfc822_header = $rfc822_header;
 } else {
-   $passed_ent_id = 0;
+    $passed_ent_id = 0;
 }
 $header = $message->header;
 
@@ -874,7 +854,7 @@ if (isset($sendreceipt)) {
          $final_recipient = trim(getPref($data_dir, $username, 'email_address' . $identity, '' ));
       if ($final_recipient == '' )
          $final_recipient = trim(getPref($data_dir, $username, 'email_address', '' ));
-      $supportMDN = ServerMDNSupport($mbx_response["PERMANENTFLAGS"]);
+      $supportMDN = ServerMDNSupport($aMailbox["PERMANENTFLAGS"]);
       if ( SendMDN( $mailbox, $passed_id, $final_recipient, $message, $imapConnection ) > 0 && $supportMDN ) {
          ToggleMDNflag( true, $imapConnection, $mailbox, $passed_id);
          $message->is_mdnsent = true;
@@ -887,7 +867,7 @@ if (isset($sendreceipt)) {
 /* End of block for handling incoming url vars */
 /***********************************************/
 
-$msgs[$passed_id]['FLAG_SEEN'] = true;
+
 
 $messagebody = '';
 do_hook('read_body_top');
@@ -905,7 +885,7 @@ for ($i = 0; $i < $cnt; $i++) {
 }
 
 displayPageHeader($color, $mailbox);
-formatMenuBar($aMailbox, $passed_id, $passed_ent_id, $message, $mbx_response);
+formatMenuBar($aMailbox, $passed_id, $passed_ent_id, $message,false);
 formatEnvheader($aMailbox, $passed_id, $passed_ent_id, $message, $color, $FirstTimeSee);
 echo '<table width="100%" cellpadding="0" cellspacing="0" align="center" border="0">';
 echo '  <tr><td>';
@@ -966,15 +946,16 @@ if (($attachment_common_show_images) &&
     }
 }
 
-formatMenuBar($aMailbox, $passed_id, $passed_ent_id, $message, $mbx_response, FALSE);
+formatMenuBar($aMailbox, $passed_id, $passed_ent_id, $message, false, FALSE);
 
 do_hook('read_body_bottom');
 do_hook('html_bottom');
 sqimap_logout($imapConnection);
 /* sessions are written at the end of the script. it's better to register
    them at the end so we avoid double session_register calls */
-sqsession_register($messages,'messages');
-
+/* add the mailbox to the cache */
+$mailbox_cache[$aMailbox['NAME']] = $aMailbox;
+sqsession_register($mailbox_cache,'mailbox_cache');
 ?>
 </body>
 </html>

+ 124 - 125
src/right_main.php

@@ -54,32 +54,28 @@ sqgetGlobalVar('base_uri',  $base_uri,      SQ_SESSION);
 
 sqgetGlobalVar('mailbox',   $mailbox);
 sqgetGlobalVar('lastTargetMailbox', $lastTargetMailbox, SQ_SESSION);
-sqgetGlobalVar('sort'             , $sort,              SQ_SESSION);
-sqgetGlobalVar('session',           $session,           SQ_GET);
+sqgetGlobalVar('targetMailbox', $lastTargetMailbox, SQ_POST);
 sqgetGlobalVar('note',              $note,              SQ_GET);
 sqgetGlobalVar('mail_sent',         $mail_sent,         SQ_GET);
 
+
 if ( sqgetGlobalVar('startMessage', $temp) ) {
-  $startMessage = (int) $temp;
-}
-if ( sqgetGlobalVar('PG_SHOWNUM', $temp) ) {
-  $PG_SHOWNUM = (int) $temp;
+    $startMessage = (int) $temp;
+} else {
+    $startMessage = 1;
 }
-if ( sqgetGlobalVar('PG_SHOWALL', $temp, SQ_GET) ) {
-  $PG_SHOWALL = (int) $temp;
+// sort => srt because of the changed behaviour which can break new behaviour
+if ( sqgetGlobalVar('srt', $temp, SQ_GET) ) {
+    $srt = (int) $temp;
 }
-if ( sqgetGlobalVar('newsort', $temp, SQ_GET) ) {
-  $newsort = (int) $temp;
+
+if ( sqgetGlobalVar('showall', $temp, SQ_GET) ) {
+    $showall = (int) $temp;
 }
+
 if ( sqgetGlobalVar('checkall', $temp, SQ_GET) ) {
   $checkall = (int) $temp;
 }
-if ( sqgetGlobalVar('set_thread', $temp, SQ_GET) ) {
-  $set_thread = (int) $temp;
-}
-if ( !sqgetGlobalVar('composenew', $composenew, SQ_GET) ) {
-    $composenew = false;
-}
 /* end of get globals */
 
 
@@ -87,133 +83,120 @@ if ( !sqgetGlobalVar('composenew', $composenew, SQ_GET) ) {
 
 $imapConnection = sqimap_login($username, $key, $imapServerAddress, $imapPort, 0);
 
-if (isset($PG_SHOWALL)) {
-    if ($PG_SHOWALL) {
-       $PG_SHOWNUM=999999;
-       $show_num=$PG_SHOWNUM;
-       sqsession_register($PG_SHOWNUM, 'PG_SHOWNUM');
-    }
-    else {
-       sqsession_unregister('PG_SHOWNUM');
-       unset($PG_SHOWNUM);
-    }
-}
-else if( isset( $PG_SHOWNUM ) ) {
-    $show_num = $PG_SHOWNUM;
-}
 $mailbox = (isset($mailbox) && $mailbox) ? $mailbox : 'INBOX';
+
 /* compensate for the UW vulnerability. */
 if ($imap_server_type == 'uw' && (strstr($mailbox, '../') ||
                                   substr($mailbox, 0, 1) == '/')) {
    $mailbox = 'INBOX';
 }
+/**
+ * Set the global settings for a mailbox and merge them with the usersettings
+ * for the mailbox. In the future we can add more mailbox specific preferences
+ * preferences.
+ */
 
-if (isset($newsort) ) {
-    if ( $newsort != $sort ) {
-        setPref($data_dir, $username, 'sort', $newsort);
-    }
-    $oldsort = $sort;
-    $sort = $newsort;
-    sqsession_register($sort, 'sort');
-}
 
+$aMailboxGlobalPref = array(
+                       MBX_PREF_SORT         => 0,
+                       MBX_PREF_LIMIT        => (int)  $show_num,
+                       MBX_PREF_AUTO_EXPUNGE => (bool) $auto_expunge,
+                       MBX_PREF_INTERNALDATE => (bool) getPref($data_dir, $username, 'internal_date_sort')
+                    // MBX_PREF_FUTURE       => (var)  $future
+                     );
+
+/* not sure if this hook should be capable to alter the global pref array */
 do_hook ('generic_header');
 
-$aMbxResponse = sqimap_mailbox_select($imapConnection, $mailbox);
-$aMbxResponse['SORT_ARRAY'] = false;
+$aMailboxPrefSer=getPref($data_dir, $username, "pref_$mailbox");
+if ($aMailboxPrefSer) {
+    $aMailboxPref = unserialize($aMailboxPrefSer);
+} else {
+    setUserPref($username,"pref_$mailbox",serialize($aMailboxGlobalPref));
+    $aMailboxPref = $aMailboxGlobalPref;
+}
+if (isset($srt)) {
+    $aMailboxPref[MBX_PREF_SORT] = (int) $srt;
+}
+
+
+/**
+ * until there is no per mailbox option screen to set prefs we override
+ * the mailboxprefs by the default ones
+ */
+$aMailboxPref[MBX_PREF_LIMIT] = (int)  $show_num;
+$aMailboxPref[MBX_PREF_AUTO_EXPUNGE] = (bool) $auto_expunge;
+$aMailboxPref[MBX_PREF_INTERNALDATE] = (bool) getPref($data_dir, $username, 'internal_date_sort');
 
-sqgetGlobalVar('aLastSelectedMailbox',$aLastSelectedMailbox,SQ_SESSION);
 
-// deal with imap servers that do not return the required UIDNEXT or
-// UIDVALIDITY response
-// from a SELECT call (since rfc 3501 it's required)
-if (!isset($aMbxResponse['UIDNEXT']) || !isset($aMbxResponse['UIDVALIDITY'])) {
-    $aStatus = sqimap_status_messages($imapConnection,$mailbox,
-                                      array('UIDNEXT','UIDVALIDITY'));
-    $aMbxResponse['UIDNEXT'] = $aStatus['UIDNEXT'];
-    $aMbxResponse['UIDVALIDTY'] = $aStatus['UIDVALIDITY'];
+/**
+ * system wide admin settings and incoming vars.
+ */
+$aConfig = array(
+                'allow_thread_sort' => $allow_thread_sort,
+                'allow_server_sort' => $allow_server_sort,
+                'user'              => $username,
+                // incoming vars
+                'offset' => $startMessage
+                );
+/**
+ * The showall functionality is for the moment added to the config array
+ * to avoid storage of the showall link in the mailbox pref. We could change
+ * this behaviour later and add it to $aMailboxPref instead
+ */
+if (isset($showall)) {
+   $aConfig['showall'] = $showall;
 }
 
-if ($aLastSelectedMailbox) {
-    // check if we deal with the same mailbox
-    if ($aLastSelectedMailbox['NAME'] == $mailbox) {
-       if ($aLastSelectedMailbox['EXISTS'] == $aMbxResponse['EXISTS'] &&
-           $aLastSelectedMailbox['UIDVALIDITY'] == $aMbxResponse['UIDVALIDITY'] &&
-           $aLastSelectedMailbox['UIDNEXT']  == $aMbxResponse['UIDNEXT']) {
-           sqgetGlobalVar('server_sort_array',$server_sort_array,SQ_SESSION);
-           if ($server_sort_array && is_array($server_sort_array)) {
-               $aMbxResponse['SORT_ARRAY'] = $server_sort_array;
-               // check if oldsort can be used in case we changed the sort order of the same column
-               if (isset($newsort) && $newsort) {
-                    if ((($newsort % 2) && ($newsort + 1 == $oldsort)) ||
-                        (!($newsort % 2) && ($newsort - 1 == $oldsort))) {
-                        $server_sort_array = array_reverse($server_sort_array);
-                    } else {
-                        $server_sort_array = false;
-                    }
-               }
-               $aMbxResponse['SORT_ARRAY'] = $server_sort_array;
-           }
-       }
-    }
+/**
+ * Retrieve the mailbox cache from the session.
+ */
+sqgetGlobalVar('mailbox_cache',$mailbox_cache,SQ_SESSION);
+
+
+$aMailbox = sqm_api_mailbox_select($imapConnection,$mailbox,$aConfig,$aMailboxPref);
+
+
+/*
+ * After initialisation of the mailbox array it's time to handle the FORM data
+ */
+$sError = handleMessageListForm($imapConnection,$aMailbox);
+if ($sError) {
+   $note = $sError;
 }
 
-$aLastSelectedMailbox['NAME'] = $mailbox;
-$aLastSelectedMailbox['EXISTS'] = $aMbxResponse['EXISTS'];
-$aLastSelectedMailbox['UIDVALIDITY'] = $aMbxResponse['UIDVALIDITY'];
-$aLastSelectedMailbox['UIDNEXT'] = $aMbxResponse['UIDNEXT'];
-$aLastSelectedMailbox['PERMANENTFLAGS'] = $aMbxResponse['PERMANENTFLAGS'];
-$aLastSelectedMailbox['OFFSET'] = (isset($startMessage) && $startMessage) ? $startMessage -1 : 0;
-$aLastSelectedMailbox['PAGEOFFSET'] = (isset($startMessage) && $startMessage) ? $startMessage : 1;
-$aLastSelectedMailbox['SORT'] = ($sort !== false) ? $sort : 0;
-$aLastSelectedMailbox['LIMIT'] = ($show_num != 999999) ? $show_num : $aMbxResponse['EXISTS'];
-
-$aLastSelectedMailbox['UIDSET'] = $aMbxResponse['SORT_ARRAY'];
-$aLastSelectedMailbox['SEEN'] = (isset($aMbxResponse['SEEN'])) ? $aMbxResponse['SEEN'] : $aMbxResponse['EXISTS'];
-$aLastSelectedMailbox['RECENT'] = (isset($aMbxResponse['RECENT'])) ? $aMbxResponse['RECENT'] : 0;
-$aLastSelectedMailbox['RIGHTS'] = $aMbxResponse['RIGHTS'];
-
-$aLastSelectedMailbox['AUTO_EXPUNGE'] = $auto_expunge;
-
-/* decide if we are thread sorting or not */
-$aLastSelectedMailbox['ALLOW_THREAD'] = $allow_thread_sort;
-if ($allow_thread_sort == TRUE) {
-    if (isset($set_thread)) {
-        $aLastSelectedMailbox['SORT_ARRAY'] = false;
-        if (sqsession_is_registered('indent_array')) {
-            sqsession_unregister('indent_array');
-        }
-        if (sqsession_is_registered('server_sort_array')) {
-            sqsession_unregister('server_sort_array');
-        }
-        if ($set_thread == 1) {
-            setPref($data_dir, $username, "thread_$mailbox", 1);
-            $thread_sort_messages = '1';
-        } else if ($set_thread == 2)  {
-            setPref($data_dir, $username, "thread_$mailbox", 0);
-            $thread_sort_messages = '0';
-        }
+/*
+ * If we try to forward messages as attachment we have to open a new window
+ * in case of compose in new window or redirect to compose.php
+ */
+if (isset($aMailbox['FORWARD_SESSION'])) {
+    if ($compose_new_win) {
+        // write the session in order to make sure that the compose window has
+        // access to the composemessages array which is stored in the session
+        session_write_close();
+        sqsession_is_active();
+        $comp_uri = SM_PATH . 'src/compose.php?mailbox='. urlencode($mailbox).
+                    '&session='.$aMailbox['FORWARD_SESSION'];
+        displayPageHeader($color, $mailbox, "comp_in_new('$comp_uri');", false);
     } else {
-        $thread_sort_messages = getPref($data_dir, $username, "thread_$mailbox");
+        // save mailboxstate
+        sqsession_register($aMailbox,'aLastSelectedMailbox');
+        session_write_close();
+        // we have to redirect to the compose page
+        global $PHP_SELF;
+        if (!strpos($PHP_SELF,'?')) {
+            $location = $PHP_SELF.'?mailbox=INBOX&amp;startMessage=1';
+        } else {
+            $location = $PHP_SELF;
+        }
+        $location = set_url_var($location, 'session',$aMailbox['FORWARD_SESSION'], false);
+        header("Location: $location");
+        exit;
     }
-} else {
-    $thread_sort_messages = 0;
-}
-if ($thread_sort_messages == 1) {
-    $aLastSelectedMailbox['SORT_METHOD'] = 'THREAD';
-} else if ($allow_server_sort) {
-    $aLastSelectedMailbox['SORT_METHOD'] = 'SERVER';
-} else {
-    $aLastSelectedMailbox['SORT_METHOD'] = 'SQUIRREL';
-}
-
-if ($composenew) {
-    $comp_uri = SM_PATH . 'src/compose.php?mailbox='. urlencode($mailbox).
-        "&session=$session";
-    displayPageHeader($color, $mailbox, "comp_in_new('$comp_uri');", false);
 } else {
     displayPageHeader($color, $mailbox);
 }
+
 do_hook('right_main_after_header');
 
 /* display a message to the user that their mail has been sent */
@@ -244,13 +227,29 @@ if ( sqgetGlobalVar('just_logged_in', $just_logged_in, SQ_SESSION) ) {
         }
     }
 }
-
-showMessagesForMailbox($imapConnection,$aLastSelectedMailbox);
+if ($aMailbox['EXISTS'] > 0) {
+    showMessagesForMailbox($imapConnection,$aMailbox);
+} else {
+    $string = '<b>' . _("THIS FOLDER IS EMPTY") . '</b>';
+    echo '    <table width="100%" cellpadding="1" cellspacing="0" align="center"'.' border="0" bgcolor="'.$color[9].'">';
+    echo '     <tr><td>';
+    echo '       <table width="100%" cellpadding="0" cellspacing="0" align="center" border="0" bgcolor="'.$color[4].'">';
+    echo '        <tr><td><br />';
+    echo '            <table cellpadding="1" cellspacing="5" align="center" border="0">';
+    echo '              <tr>' . html_tag( 'td', $string."\n", 'left')
+                        . '</tr>';
+    echo '            </table>';
+    echo '        <br /></td></tr>';
+    echo '       </table></td></tr>';
+    echo '    </table>';
+}
 
 do_hook('right_main_bottom');
 sqimap_logout ($imapConnection);
 echo '</body></html>';
 
-sqsession_register($aLastSelectedMailbox,'aLastSelectedMailbox');
+/* add the mailbox to the cache */
+$mailbox_cache[$aMailbox['NAME']] = $aMailbox;
+sqsession_register($mailbox_cache,'mailbox_cache');
 
 ?>

+ 273 - 204
src/search.php

@@ -349,8 +349,13 @@ function asearch_find_recent(&$recent_array, &$mailbox_array, &$biop_array, &$un
 function asearch_push_recent(&$mailbox_array, &$biop_array, &$unop_array, &$where_array, &$what_array, &$exclude_array, &$sub_array)
 {
     global $recent_prefkeys, $search_memory;
-
-    $criteria = array($mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array, $sub_array);
+    //global $what; // Hack to access issued search from read_body.php
+    $what = 1;
+    /**
+     * Update search history and store it in the session so we can retrieve the
+     * issued search when returning from an external page like read_body.php
+     */
+    $criteria[$what] = array($mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array, $sub_array);
     sqsession_register($criteria, ASEARCH_CRITERIA);
     if ($search_memory > 0) {
         $recent_array = asearch_read_recent();
@@ -391,25 +396,26 @@ function asearch_edit_recent($index)
 }
 
 /** Get last search criteria from session or prefs
+* FIX ME, try to avoid globals
 */
-function asearch_edit_last()
-{
+function asearch_edit_last($index) {
     if (sqGetGlobalVar(ASEARCH_CRITERIA, $criteria, SQ_SESSION)) {
         global $where_array, $mailbox_array, $what_array, $unop_array;
         global $biop_array, $exclude_array, $sub_array;
-        $mailbox_array = $criteria[0];
-        $biop_array = $criteria[1];
-        $unop_array = $criteria[2];
-        $where_array = $criteria[3];
-        $what_array = $criteria[4];
-        $exclude_array = $criteria[5];
-        $sub_array = $criteria[6];
-        sqsession_unregister(ASEARCH_CRITERIA);
-    }
-    else {
+        $mailbox_array = $criteria[$index][0];
+        $biop_array = $criteria[$index][1];
+        $unop_array = $criteria[$index][2];
+        $where_array = $criteria[$index][3];
+        $what_array = $criteria[$index][4];
+        $exclude_array = $criteria[$index][5];
+        $sub_array = $criteria[$index][6];
+        unset($criteria[$index]);
+        //sqsession_unregister(ASEARCH_CRITERIA);
+    } else {
         global $search_memory;
-        if ($search_memory > 0)
+        if ($search_memory > 0) {
             asearch_edit_recent(0);
+        }
     }
 }
 
@@ -685,10 +691,11 @@ function asearch_mailbox_exists($mailbox, &$boxes)
 */
 function asearch_get_form_mailbox($imapConnection, &$boxes, $mailbox, $row_num = 0)
 {
-    if (($mailbox != 'All Folders') && (!asearch_mailbox_exists($mailbox, $boxes)))
+    if (($mailbox != 'All Folders') && (!asearch_mailbox_exists($mailbox, $boxes))) {
         $missing = asearch_opt($mailbox, $mailbox, '[' . _("Missing") . '] ' . asearch_get_mailbox_display($mailbox));
-    else
+    } else {
         $missing = '';
+    }
     return '<select name="mailbox[' . $row_num . ']">'
         . $missing
         . asearch_opt('All Folders', $mailbox, '[' . asearch_get_mailbox_display('All Folders') . ']')
@@ -852,51 +859,38 @@ function asearch_print_form_basic($imapConnection, &$boxes, $mailbox_array, $bio
 
 /** Print the $msgs messages from $mailbox mailbox
 */
-function asearch_print_mailbox_msgs($imapConnection, $mbxresponse, $mailbox, $id, $cnt, $sort, $color, $where, $what)
-{
-    /* initialize */
-    $aMailbox['NAME'] = $mailbox;
-    $aMailbox['EXISTS'] = $cnt;
-    $aMailbox['SORT'] = $sort;
-    $aMailbox['UIDVALIDITY'] = $mbxresponse['UIDVALIDITY'];
-    $aMailbox['UIDNEXT'] = $mbxresponse['UIDNEXT'];
-    $aMailbox['PERMANENTFLAGS'] = $mbxresponse['PERMANENTFLAGS'];
-    $aMailbox['RIGHTS'] = $mbxresponse['RIGHTS'];
-    $aMailbox['NAME'] = $mailbox;
-    $aMailbox['UIDSET'] = $id;
-    $aMailbox['OFFSET'] = 0;
-    $aMailbox['PAGEOFFSET'] = 0;
-    $aMailbox['LIMIT'] = $cnt;
-    $aMailbox['SEARCH'] = array($where,$what);
-    $aMailbox['SORT_METHOD'] = 'SEARCH';
-
-    if ($cnt > 0) {
-        global $allow_server_sort, $allow_thread_sort, $thread_sort_messages, $auto_expunge;
-        $aMailbox['ALLOW_THREAD'] = $allow_thread_sort;
-        $aMailbox['AUTO_EXPUNGE'] = $auto_expunge;
-        $msgs = sqimap_get_small_header_list ($imapConnection, $id, count($id));
-        $thread_sort_messages = 0;
-        if ($allow_thread_sort) {
-            global $data_dir, $username;
-            $thread_sort_messages = getPref($data_dir, $username, 'thread_' . $mailbox);
-        }
 
-        $mailbox_display = asearch_get_mailbox_display($mailbox);
+function asearch_print_mailbox_msgs($imapConnection, &$aMailbox, $color)
+{
+    if (fetchMessageHeaders($imapConnection, $aMailbox)) {
+        /**
+         * A mailbox can contain different sets with uid's. Default, for normal
+         * message list view we use '0' as setindex and for search a different
+         * setindex.
+         */
+        $iSetIndx = $aMailbox['SETINDEX'];
+
+        $mailbox_display = asearch_get_mailbox_display($aMailbox['NAME']);
         $mailbox_title = '<b><big>' . _("Folder:") . ' '. $mailbox_display . '&nbsp;</big></b>';
-        $devel = check_sm_version(1, 5, 0);
-        if (!$devel) {
-            echo html_tag('div', $mailbox_title, 'center') . "\n";
-            $mailbox_title = get_selectall_link(1, $real_sort);
-        }
-        $msg_cnt_str = get_msgcnt_str(1, $cnt, $cnt);
+
+        /**
+         * UIDSET contains the array with uid's returned by a search
+         */
+        $cnt = count($aMailbox['UIDSET'][$iSetIndx]);
+
+        $iLimit = ($aMailbox['SHOWALL'][$iSetIndx]) ? $cnt : $aMailbox['LIMIT'];
+        $iEnd = ($aMailbox['PAGEOFFSET'] + ($iLimit - 1) < $aMailbox['EXISTS']) ?
+                $aMailbox['PAGEOFFSET'] + $iLimit - 1 : $cnt;
+
+        $paginator_str = get_paginator_str($aMailbox['NAME'], $aMailbox['PAGEOFFSET'],
+                                        $cnt, $aMailbox['LIMIT'], $aMailbox['SHOWALL'][$iSetIndx]);
+
+        $msg_cnt_str = get_msgcnt_str($aMailbox['PAGEOFFSET'], $iEnd,$cnt);
 
         echo '<table border="0" width="100%" cellpadding="0" cellspacing="0">';
 
         echo '<tr><td>';
-        //if ($devel)
-            mail_message_listing_beginning($imapConnection, $aMailbox, $msg_cnt_str, $mailbox_title);
-        //else
-            /// mail_message_listing_beginning($imapConnection, $aMailbox $msg_cnt_str, $mailbox_title);
+        mail_message_listing_beginning($imapConnection, $aMailbox, $msg_cnt_str, $mailbox_title . " $paginator_str");
         echo '</td></tr>';
 
         echo '<tr><td HEIGHT="5" BGCOLOR="'.$color[4].'"></td></tr>';
@@ -908,14 +902,7 @@ function asearch_print_mailbox_msgs($imapConnection, $mbxresponse, $mailbox, $id
         echo '       <table width="100%" cellpadding="1" cellspacing="0" align="center" border="0" bgcolor="'.$color[5].'">';
         echo '        <tr><td>';
         printHeader($aMailbox);
-        $aMailbox['NAME'] = $mailbox;
-        $aMailbox['MSG_HEADERS'] = $msgs;
-        $aMailbox['UIDSET'] = $id;
-        $aMailbox['OFFSET'] = 0;
-        $aMailbox['PAGEOFFSET'] = 0;
-        $aMailbox['LIMIT'] = $cnt;
-        $aMailbox['SEARCH'] = array($where,$what);
-        displayMessageArray($imapConnection, $aMailbox);//$cnt, 1, $id, $msgs, $mailbox, $sort, $cnt, $where, $what);
+        displayMessageArray($imapConnection, $aMailbox);
         echo '        </td></tr>';
         echo '       </table>';
         echo '     </td></tr>';
@@ -924,6 +911,8 @@ function asearch_print_mailbox_msgs($imapConnection, $mbxresponse, $mailbox, $id
         echo '</td></tr>';
 
         echo '</table>';
+    } else {
+        echo '<br />' . html_tag('div', asearch_get_error_display($color, _("No Messages Found")), 'center') . "\n";
     }
 }
 
@@ -953,6 +942,11 @@ if ( sqgetGlobalVar('checkall', $temp, SQ_GET) ) {
     $checkall = (int) $temp;
 }
 
+/**
+ * Retrieve the mailbox cache from the session.
+ */
+sqgetGlobalVar('mailbox_cache',$mailbox_cache,SQ_SESSION);
+
 
 $search_button_html = _("Search");
 $search_button_text = asearch_unhtmlentities($search_button_html);
@@ -981,18 +975,18 @@ $allow_advanced_search = asearch_nz($allow_advanced_search, 2);
 /**
 * Toggle advanced/basic search
 */
-if (sqgetGlobalVar('advanced', $search_advanced, SQ_GET))
+if (sqgetGlobalVar('advanced', $search_advanced, SQ_GET)) {
     setPref($data_dir, $username, 'search_advanced', $search_advanced & 1);
-
+}
 /** If 1, show advanced search interface
 * Default from allow_advanced_search pref
 * @global integer $search_advanced
 */
-if ($allow_advanced_search > 1)
+if ($allow_advanced_search > 1) {
     $search_advanced = getPref($data_dir, $username, 'search_advanced', 0);
-else
+} else {
     $search_advanced = $allow_advanced_search;
-
+}
 if ($search_advanced) {
 /** Set recent prefkeys according to $search_advanced
 * @global array $recent_prefkeys
@@ -1005,8 +999,7 @@ if ($search_advanced) {
     $saved_prefkeys = array('asearch_saved_where', 'asearch_saved_mailbox', 'asearch_saved_what', 'asearch_saved_unop', 'asearch_saved_biop', 'asearch_saved_exclude', 'asearch_saved_sub');
 
 /*$asearch_prefkeys = array('where', 'mailbox', 'what', 'biop', 'unop', 'exclude', 'sub');*/
-}
-else {
+} else {
     $recent_prefkeys = array('search_where', 'search_folder', 'search_what', 'search_unop');
     $saved_prefkeys = array('saved_where', 'saved_folder', 'saved_what', 'saved_unop');
 }
@@ -1028,19 +1021,38 @@ else {
 * - 'delete_saved'
 * @global string $submit
 */
-if (isset($_GET['submit']))
+if (isset($_GET['submit'])) {
     $submit = strip_tags($_GET['submit']);
-
+}
 /** Searched mailboxes
 * @global array $mailbox_array
 */
 if (isset($_GET['mailbox'])) {
     $mailbox_array = $_GET['mailbox'];
-    if (!is_array($mailbox_array))
+    $targetmailbox = $_GET['mailbox'];
+    if (!is_array($mailbox_array)) {
         $mailbox_array = array($mailbox_array);
-}
-else
+    }
+} else {
     $mailbox_array = array();
+}
+$aMailboxGlobalPref = array(
+                       MBX_PREF_SORT         => 0,
+                       MBX_PREF_LIMIT        => (int)  $show_num,
+                       MBX_PREF_AUTO_EXPUNGE => (bool) $auto_expunge,
+                       MBX_PREF_INTERNALDATE => (bool) getPref($data_dir, $username, 'internal_date_sort')
+                    // MBX_PREF_FUTURE       => (var)  $future
+                     );
+
+/**
+ * system wide admin settings and incoming vars.
+ */
+$aConfig = array(
+                'allow_thread_sort' => $allow_thread_sort,
+                'allow_server_sort' => $allow_server_sort,
+                'user'              => $username,
+                'max_cache_size'
+                );
 
 /** Binary operators
 * @global array $biop_array
@@ -1049,10 +1061,9 @@ if (isset($_GET['biop'])) {
     $biop_array = $_GET['biop'];
     if (!is_array($biop_array))
         $biop_array = array($biop_array);
-}
-else
+} else {
     $biop_array = array();
-
+}
 /** Unary operators
 * @global array $unop_array
 */
@@ -1060,79 +1071,99 @@ if (isset($_GET['unop'])) {
     $unop_array = $_GET['unop'];
     if (!is_array($unop_array))
         $unop_array = array($unop_array);
-}
-else
+} else {
     $unop_array = array();
-
+}
 /** Where to search
 * @global array $where_array
 */
 if (isset($_GET['where'])) {
     $where_array = $_GET['where'];
-    if (!is_array($where_array))
+    if (!is_array($where_array)) {
         $where_array = array($where_array);
-}
-else
+    }
+} else {
     $where_array = array();
-
+}
 /** What to search
 * @global array $what_array
 */
 if (isset($_GET['what'])) {
     $what_array = $_GET['what'];
-    if (!is_array($what_array))
+    if (!is_array($what_array)) {
         $what_array = array($what_array);
-}
-else
+    }
+} else {
     $what_array = array();
-
+}
 /** Whether to exclude this criteria from search
 * @global array $exclude_array
 */
-if (isset($_GET['exclude']))
+if (isset($_GET['exclude'])) {
     $exclude_array = $_GET['exclude'];
-else
+} else {
     $exclude_array = array();
-
+}
 /** Search within subfolders
 * @global array $sub_array
 */
-if (isset($_GET['sub']))
+if (isset($_GET['sub'])) {
     $sub_array = $_GET['sub'];
-else
+} else {
     $sub_array = array();
-
+}
 /** Row number used by recent and saved stuff
 */
-if (isset($_GET['rownum']))
+if (isset($_GET['rownum'])) {
     $submit_rownum = strip_tags($_GET['rownum']);
-
+}
 /** Change global sort
 */
-if (sqgetGlobalVar('newsort', $newsort, SQ_GET)) {
-    setPref($data_dir, $username, 'sort', $newsort);
-    $sort = $newsort;
-    sqsession_register($sort, 'sort');
-    asearch_edit_last();
+if (sqgetGlobalVar('srt', $temp, SQ_GET)) {
+    $srt = (int) $temp;
+    asearch_edit_last(1);
+    asearch_push_recent($mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array, $sub_array);
+}
+if (sqgetGlobalVar('startMessage', $temp, SQ_GET)) {
+    $startMessage = (int) $temp;
+    asearch_edit_last(1);
+    asearch_push_recent($mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array, $sub_array);
 }
 
-/** Toggle mailbox threading
-*/
-if (sqgetGlobalVar('set_thread', $set_thread, SQ_GET)) {
-    setPref($data_dir, $username, 'thread_' . $mailbox_array[0], $set_thread & 1);
-    asearch_edit_last();
+if ( sqgetGlobalVar('showall', $temp, SQ_GET) ) {
+    $showall = (int) $temp;
+    asearch_edit_last(1);
+    asearch_push_recent($mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array, $sub_array);
 }
+/**
+ * Incoming submit buttons from the message list with search results
+ */
+if (sqgetGlobalVar('moveButton',      $moveButton,      SQ_POST) ||
+    sqgetGlobalVar('expungeButton',   $expungeButton,   SQ_POST) ||
+    sqgetGlobalVar('delete',          $markDelete,      SQ_POST) ||
+    sqgetGlobalVar('undeleteButton',  $undeleteButton,  SQ_POST) ||
+    sqgetGlobalVar('markRead',        $markRead,        SQ_POST) ||
+    sqgetGlobalVar('markUnread',      $markUnread,      SQ_POST) ||
+    sqgetGlobalVar('markFlagged',     $markFlagged,     SQ_POST) ||
+    sqgetGlobalVar('markUnflagged',   $markUnflagged,   SQ_POST) ||
+    sqgetGlobalVar('attache',         $attache,         SQ_POST)) {
+    asearch_edit_last(1);
+    $submit = '';
+    asearch_push_recent($mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array, $sub_array);
+}
+
+
 
 /** Toggle show/hide saved searches
 */
-if (sqgetGlobalVar('search_show_saved', $search_show_saved, SQ_GET))
+if (sqgetGlobalVar('search_show_saved', $search_show_saved, SQ_GET)) {
     setPref($data_dir, $username, 'search_show_saved', $search_show_saved & 1);
-
+}
 /** Toggle show/hide recent searches
 */
-if (sqgetGlobalVar('search_show_recent', $search_show_recent, SQ_GET))
+if (sqgetGlobalVar('search_show_recent', $search_show_recent, SQ_GET)) {
     setPref($data_dir, $username, 'search_show_recent', $search_show_recent & 1);
-
+}
 // end of get globals
 
 /** If TRUE, do not show search interface
@@ -1145,72 +1176,82 @@ $search_silent = FALSE;
 if ((empty($submit)) && (!empty($where_array))) {
     /* This happens when the Enter key is used or called from outside */
     $submit = $search_button_text;
-    if (count($where_array) != count($unop_array))	/* Hack needed to handle coming back from read_body et als */
-        asearch_edit_last();
+    /* Hack needed to handle coming back from read_body et als */
+    if (count($where_array) != count($unop_array)) {
+        /**
+         * Hack to use already existen where and what vars.
+         * where now contains the initiator page of the messagelist
+         * and in this case 'search'. what contains an index to access
+         * the search history
+         */
+
+        sqgetGlobalVar('what',$what,SQ_GET);
+        asearch_edit_last($what);
+    }
 }
 
 if (!isset($submit)) {
     $submit = '';
-}
-else {
+} else {
     switch ($submit) {
-        case $search_button_text:
-            if (asearch_check_query($where_array, $what_array, $exclude_array) == '')
-                asearch_push_recent($mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array, $sub_array);
+      case $search_button_text:
+        if (asearch_check_query($where_array, $what_array, $exclude_array) == '') {
+            asearch_push_recent($mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array, $sub_array);
+        }
         break;
-        case 'Search_silent':
-            $search_silent = TRUE;
+      case 'Search_silent':
+        $search_silent = TRUE;
         /*nobreak;*/
-        case 'Search_no_update':
-            $submit = $search_button_text;
+      case 'Search_no_update':
+        $submit = $search_button_text;
         break;
-        case $del_excluded_button_text:
-            $delarray = array_keys($exclude_array);
-            while (!empty($delarray)) {
-                $delrow = array_pop($delarray);
-                array_splice($mailbox_array, $delrow, 1);
-                array_splice($biop_array, $delrow, 1);
-                array_splice($unop_array, $delrow, 1);
-                array_splice($where_array, $delrow, 1);
-                array_splice($what_array, $delrow, 1);
-/*			array_splice($exclude_array, $delrow, 1);*/	/* There is still some php magic that eludes me */
-                array_splice($sub_array, $delrow, 1);
-            }
-            $exclude_array = array();
+      case $del_excluded_button_text:
+        $delarray = array_keys($exclude_array);
+        while (!empty($delarray)) {
+            $delrow = array_pop($delarray);
+            array_splice($mailbox_array, $delrow, 1);
+            array_splice($biop_array, $delrow, 1);
+            array_splice($unop_array, $delrow, 1);
+            array_splice($where_array, $delrow, 1);
+            array_splice($what_array, $delrow, 1);
+            /* array_splice($exclude_array, $delrow, 1);*/	/* There is still some php magic that eludes me */
+            array_splice($sub_array, $delrow, 1);
+        }
+        $exclude_array = array();
         break;
-        case $del_all_button_text:
-            $mailbox_array = array();
-            $biop_array = array();
-            $unop_array = array();
-            $where_array = array();
-            $what_array = array();
-            $exclude_array = array();
-            $sub_array = array();
+      case $del_all_button_text:
+        $mailbox_array = array();
+        $biop_array = array();
+        $unop_array = array();
+        $where_array = array();
+        $what_array = array();
+        $exclude_array = array();
+        $sub_array = array();
         break;
-        case 'save_recent':
-            asearch_save_recent($submit_rownum);
+      case 'save_recent':
+        asearch_save_recent($submit_rownum);
         break;
-        case 'search_recent':
-            $submit = $search_button_text;
-            asearch_edit_recent($submit_rownum);
-            asearch_push_recent($mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array, $sub_array);
+      case 'search_recent':
+        $submit = $search_button_text;
+        asearch_edit_recent($submit_rownum);
+        asearch_push_recent($mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array, $sub_array);
         break;
-        case 'edit_recent':	/* no link to do this, yet */
-            asearch_edit_recent($submit_rownum);
+      case 'edit_recent':	/* no link to do this, yet */
+        asearch_edit_recent($submit_rownum);
         break;
-        case 'forget_recent':
-            asearch_forget_recent($submit_rownum);
+      case 'forget_recent':
+        asearch_forget_recent($submit_rownum);
         break;
-        case 'search_saved':
-            $submit = $search_button_text;
-            asearch_edit_saved($submit_rownum);
-            asearch_push_recent($mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array, $sub_array);
+      case 'search_saved':
+        $submit = $search_button_text;
+        asearch_edit_saved($submit_rownum);
+        asearch_push_recent($mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array, $sub_array);
         break;
-        case 'edit_saved':
-            asearch_edit_saved($submit_rownum);
+      case 'edit_saved':
+        asearch_edit_saved($submit_rownum);
         break;
-        case 'delete_saved':
-            asearch_delete_saved($submit_rownum);
+      case 'delete_saved':
+        asearch_delete_saved($submit_rownum);
         break;
     }
 }
@@ -1271,8 +1312,7 @@ if ($search_advanced) {
         'ALL' => _("And"),
         'OR' => _("Or")
     );
-}
-else {
+} else {
     //Texts in basic form only
     $imap_asearch_options = array(
         'BCC' => _("Bcc"),
@@ -1289,6 +1329,8 @@ uasort($imap_asearch_options, 'asearch_unhtml_strcoll');
 
 /* open IMAP connection */
 $imapConnection = sqimap_login($username, $key, $imapServerAddress, $imapPort, 0);
+
+
 /* get mailboxes once here */
 $boxes = sqimap_mailbox_list($imapConnection);
 /* ensure we have a valid default mailbox name */
@@ -1300,10 +1342,9 @@ if (isset($composenew) && $composenew) {
     $comp_uri = "../src/compose.php?mailbox=" . urlencode($mailbox)
         . "&amp;session=$composesession&amp;attachedmessages=true&amp";
     displayPageHeader($color, $mailbox, "comp_in_new('$comp_uri');", false);
-}
-else
+} else {
     displayPageHeader($color, $mailbox);
-
+}
 do_hook('search_before_form');
 
 if (!$search_silent) {
@@ -1328,10 +1369,11 @@ if (!$search_silent) {
         $mailbox_array[0] = $mailbox;
         $biop_array[0] = '';
         $unop_array[0] = '';
-        if ($mailbox == $sent_folder)
+        if ($mailbox == $sent_folder) {
             $where_array[0] = 'TO';
-        else
+        } else {
             $where_array[0] = 'FROM';
+        }
         $what_array[0] = '';
         $exclude_array[0] = '';
         $sub_array[0] = '';
@@ -1349,20 +1391,11 @@ if (!$search_silent) {
             $sub_array[] = asearch_nz($sub_array[$last_index]);
         }
         asearch_print_form($imapConnection, $boxes, $mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array, $sub_array);
-    }
-    else
+    } else {
         asearch_print_form_basic($imapConnection, $boxes, $mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array, $sub_array);
+    }
 }
 
-/*********************************************************************
-* Check to see if we can use cache or not. Currently the only time  *
-* when you will not use it is when a link on the left hand frame is *
-* used. Also check to make sure we actually have the array in the   *
-* registered session data.  :)                                      *
-*********************************************************************/
-if (!isset($use_mailbox_cache))
-    $use_mailbox_cache = 0;
-
 do_hook('search_after_form');
 
 if ($submit == $search_button_text) {
@@ -1374,38 +1407,74 @@ if ($submit == $search_button_text) {
     flush();
 
     $query_error = asearch_check_query($where_array, $what_array, $exclude_array);
-    if ($query_error != '')
+    if ($query_error != '') {
         echo '<br />' . html_tag('div', asearch_get_error_display($color, $query_error), 'center') . "\n";
-    else {
-        // Disable thread sort for now if there is more than one mailbox or at least one 'All Folders'
-        global $allow_thread_sort;
-        $old_allow_thread_sort = $allow_thread_sort;
-        $allow_thread_sort = ((count(array_unique($mailbox_array)) <= 1) && (!in_array('All Folders', $mailbox_array)));
-
+    } else {
         $mboxes_array = sqimap_asearch_get_selectable_unformatted_mailboxes($boxes);
-        $mboxes_msgs = sqimap_asearch($imapConnection, $mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array, $sub_array, $mboxes_array);
-        if (empty($mboxes_msgs))
-            echo '<br />' . html_tag('div', asearch_get_error_display($color, _("No Messages Found")), 'center') . "\n";
-        else {
-            foreach($mboxes_msgs as $mailbox => $msgs) {
-                echo '<br />';
-                $mbxresponse = sqimap_mailbox_select($imapConnection, $mailbox);
-                //$msgs = sqimap_get_small_header_list ($imapConnection, $msgs, count($msgs));
-/* For now just keep the first criteria to make the regular search happy if the user tries to come back to search */
-/*			$where = asearch_serialize($where_array);
-                $what = asearch_serialize($what_array);*/
-                $where = $where_array[0];
-                $what = $what_array[0];
-                asearch_print_mailbox_msgs($imapConnection, $mbxresponse, $mailbox, $msgs, count($msgs), $sort, $color, urlencode($where), urlencode($what));
+        /**
+         * Retrieve the search queries
+         */
+        $mboxes_mailbox = sqimap_asearch($imapConnection, $mailbox_array, $biop_array, $unop_array, $where_array, $what_array, $exclude_array, $sub_array, $mboxes_array);
+        foreach($mboxes_mailbox as $mbx => $search) {
+            $aMailboxPrefSer=getPref($data_dir, $username, "pref_$mbx");
+
+            if ($aMailboxPrefSer) {
+                $aMailboxPref = unserialize($aMailboxPrefSer);
+            } else {
+                setUserPref($username,"pref_$mbx",serialize($aMailboxGlobalPref));
+                $aMailboxPref = $aMailboxGlobalPref;
             }
-        }
+            if (isset($srt) && $targetmailbox == $mbx) {
+                $aMailboxPref[MBX_PREF_SORT] = (int) $srt;
+            }
+            if (isset($startMessage) && $targetmailbox == $mbx) {
+                $aConfig['offset'] = $startMessage;
+            } else if (isset($aConfig['offset'])) {
+                unset($aConfig['offset']);
+            }
+            if (isset($showall) && $targetmailbox == $mbx) {
+                $aConfig['showall'] = $showall;
+            } else if (isset($aConfig['showall'])) {
+                unset($aConfig['showall']);
+            }
+            /**
+             * Set the max cache size to the number of mailboxes to avoid cache cleanups
+             * when searching all mailboxes
+             */
+            $aConfig['max_cache_size'] = count($mboxes_mailbox) +1;
+
+            /**
+            * until there is no per mailbox option screen to set prefs we override
+            * the mailboxprefs by the default ones
+            */
+            $aMailboxPref[MBX_PREF_LIMIT] = (int)  $show_num;
+            $aMailboxPref[MBX_PREF_AUTO_EXPUNGE] = (bool) $auto_expunge;
+            $aMailboxPref[MBX_PREF_INTERNALDATE] = (bool) getPref($data_dir, $username, 'internal_date_sort');
+
+            echo '<br />';
+            $aConfig['search'] = $search['search'];
+            $aConfig['charset'] = $search['charset'];
+            $aConfig['setindex'] = 1; // $what $where = 'search'
+
+            $aMailbox = sqm_api_mailbox_select($imapConnection,$mbx,$aConfig,$aMailboxPref);
+            /**
+            * Handle form actions like flag / unflag, seen / unseen, delete
+            */
+            if (sqgetGlobalVar('mailbox',$postMailbox,SQ_POST)) {
+                if ($postMailbox === $mbx) {
+                    handleMessageListForm($imapConnection,$aMailbox);
+                }
+            }
+            asearch_print_mailbox_msgs($imapConnection, $aMailbox, $color);
+            /* add the mailbox to the cache */
+            $mailbox_cache[$aMailbox['NAME']] = $aMailbox;
 
-        $allow_thread_sort = $old_allow_thread_sort;	// Restore thread sort
+        }
     }
 }
 
 do_hook('search_bottom');
 sqimap_logout($imapConnection);
 echo '</body></html>';
-
+sqsession_register($mailbox_cache,'mailbox_cache');
 ?>

Kaikkia tiedostoja ei voida näyttää, sillä liian monta tiedostoa muuttui tässä diffissä