From 2dd7ee346fdc014b536de8cbbfe7630bac73a43b Mon Sep 17 00:00:00 2001
From: alecpl <alec@alec.pl>
Date: Wed, 10 Jun 2009 08:07:55 -0400
Subject: [PATCH] - Fixed many 'skip_deleted' issues (#1485634) - Fixed messages list sorting on servers without SORT capability - some preformance improvements

---
 CHANGELOG                      |    2 
 program/include/rcube_imap.php |  181 ++++++++++++----------
 program/steps/mail/show.inc    |   28 +-
 program/lib/imap.inc           |  260 +++++++++++---------------------
 4 files changed, 202 insertions(+), 269 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 204c97d..32d65bb 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,8 @@
 CHANGELOG RoundCube Webmail
 ===========================
 
+- Fixed many 'skip_deleted' issues (#1485634)
+- Fixed messages list sorting on servers without SORT capability
 - Colorized signatures in plain text messages
 - Reviewed/fixed skip_deleted/read_when_deleted/flag_for_deletion options handling in UI
 - Fix displaying of big maximum upload filesize (#1485889)
diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php
index 5130cd2..76aa853 100644
--- a/program/include/rcube_imap.php
+++ b/program/include/rcube_imap.php
@@ -506,14 +506,8 @@
 
       // get message count using SEARCH
       // not very performant but more precise (using UNDELETED)
-      $count = 0;
       $index = $this->_search_index($mailbox, $search_str);
-      if (is_array($index))
-        {
-        $str = implode(",", $index);
-        if (!empty($str))
-          $count = count($index);
-        }
+      $count = is_array($index) ? count($index) : 0;
       }
     else
       {
@@ -570,24 +564,16 @@
 
     $this->_set_sort_order($sort_field, $sort_order);
 
-    $max = $this->_messagecount($mailbox);
-    $start_msg = ($this->list_page-1) * $this->page_size;
-
-    list($begin, $end) = $this->_get_message_range($max, $page);
-
-    // mailbox is empty
-    if ($begin >= $end)
-      return array();
-      
-    $headers_sorted = FALSE;
+    $page = $page ? $page : $this->list_page;
     $cache_key = $mailbox.'.msg';
     $cache_status = $this->check_cache_status($mailbox, $cache_key);
 
     // cache is OK, we can get all messages from local cache
     if ($cache_status>0)
       {
+      $start_msg = ($page-1) * $this->page_size;
       $a_msg_headers = $this->get_message_cache($cache_key, $start_msg, $start_msg+$this->page_size, $this->sort_field, $this->sort_order);
-      $headers_sorted = TRUE;
+      return array_values($a_msg_headers);
       }
     // cache is dirty, sync it
     else if ($this->caching_enabled && $cache_status==-1 && !$recursive)
@@ -595,49 +581,54 @@
       $this->sync_header_index($mailbox);
       return $this->_list_headers($mailbox, $page, $this->sort_field, $this->sort_order, TRUE);
       }
+
+    // retrieve headers from IMAP
+    $a_msg_headers = array();
+
+    if ($this->get_capability('sort') && ($msg_index = iil_C_Sort($this->conn, $mailbox, $this->sort_field, $this->skip_deleted ? 'UNDELETED' : '')))
+      {
+      list($begin, $end) = $this->_get_message_range(count($msg_index), $page);
+      $max = max($msg_index);
+      $msg_index = array_slice($msg_index, $begin, $end-$begin);
+
+      // fetch reqested headers from server
+      $this->_fetch_headers($mailbox, join(',', $msg_index), $a_msg_headers, $cache_key);
+      }
     else
       {
-      // retrieve headers from IMAP
-      if ($this->get_capability('sort') && ($msg_index = iil_C_Sort($this->conn, $mailbox, $this->sort_field, $this->skip_deleted ? 'UNDELETED' : '')))
-        {
-        $mymsgidx = array_slice ($msg_index, $begin, $end-$begin);
-        $msgs = join(",", $mymsgidx);
-        }
-      else
-        {
-        $msgs = sprintf("%d:%d", $begin+1, $end);
-        $msg_index = range($begin, $end);
-        }
+      $a_index = iil_C_FetchHeaderIndex($this->conn, $mailbox, "1:*", $this->sort_field, $this->skip_deleted);
+    
+      if (empty($a_index))
+        return array();
 
+      asort($a_index); // ASC
+      $msg_index = array_keys($a_index);
+      $max = max($msg_index);
+      list($begin, $end) = $this->_get_message_range(count($msg_index), $page);
+      $msg_index = array_slice($msg_index, $begin, $end-$begin);
 
-      // fetch reuested headers from server
-      $a_msg_headers = array();
-      $deleted_count = $this->_fetch_headers($mailbox, $msgs, $a_msg_headers, $cache_key);
-
-      // delete cached messages with a higher index than $max+1
-      // Changed $max to $max+1 to fix this bug : #1484295
-      $this->clear_message_cache($cache_key, $max + 1);
-
-      // kick child process to sync cache
-      // ...
+      // fetch reqested headers from server
+      $this->_fetch_headers($mailbox, join(",", $msg_index), $a_msg_headers, $cache_key);
       }
+
+    // delete cached messages with a higher index than $max+1
+    // Changed $max to $max+1 to fix this bug : #1484295
+    $this->clear_message_cache($cache_key, $max + 1);
+
+    // kick child process to sync cache
+    // ...
 
     // return empty array if no messages found
-    if (!is_array($a_msg_headers) || empty($a_msg_headers)) {
+    if (!is_array($a_msg_headers) || empty($a_msg_headers))
       return array();
-    }
+    
+    // use this class for message sorting
+    $sorter = new rcube_header_sorter();
+    $sorter->set_sequence_numbers($msg_index);
+    $sorter->sort_headers($a_msg_headers);
 
-    // if not already sorted
-    if (!$headers_sorted)
-      {
-      // use this class for message sorting
-      $sorter = new rcube_header_sorter();
-      $sorter->set_sequence_numbers($msg_index);
-      $sorter->sort_headers($a_msg_headers);
-
-      if ($this->sort_order == 'DESC')
-        $a_msg_headers = array_reverse($a_msg_headers);
-      }
+    if ($this->sort_order == 'DESC')
+      $a_msg_headers = array_reverse($a_msg_headers);	    
 
     return array_values($a_msg_headers);
     }
@@ -661,7 +652,8 @@
 
     $msgs = $this->search_set;
     $a_msg_headers = array();
-    $start_msg = ($this->list_page-1) * $this->page_size;
+    $page = $page ? $page : $this->list_page;
+    $start_msg = ($page-1) * $this->page_size;
 
     $this->_set_sort_order($sort_field, $sort_order);
 
@@ -741,7 +733,7 @@
    */
   function _get_message_range($max, $page)
     {
-    $start_msg = ($this->list_page-1) * $this->page_size;
+    $start_msg = ($page-1) * $this->page_size;
     
     if ($page=='all')
       {
@@ -766,7 +758,6 @@
     return array($begin, $end);
     }
     
-    
 
   /**
    * Fetches message headers
@@ -776,7 +767,7 @@
    * @param  string  Message index to fetch
    * @param  array   Reference to message headers array
    * @param  array   Array with cache index
-   * @return int     Number of deleted messages
+   * @return int     Messages count
    * @access private
    */
   function _fetch_headers($mailbox, $msgs, &$a_msg_headers, $cache_key)
@@ -784,24 +775,23 @@
     // cache is incomplete
     $cache_index = $this->get_message_cache_index($cache_key);
     
-    // fetch reuested headers from server
+    // fetch reqested headers from server
     $a_header_index = iil_C_FetchHeaders($this->conn, $mailbox, $msgs, false, $this->fetch_add_headers);
-    $deleted_count = 0;
     
     if (!empty($a_header_index))
       {
       foreach ($a_header_index as $i => $headers)
-        {
+        { 
+/*
         if ($headers->deleted && $this->skip_deleted)
           {
           // delete from cache
           if ($cache_index[$headers->id] && $cache_index[$headers->id] == $headers->uid)
             $this->remove_message_cache($cache_key, $headers->uid);
 
-          $deleted_count++;
           continue;
           }
-
+*/
         // add message to cache
         if ($this->caching_enabled && $cache_index[$headers->id] != $headers->uid)
           $this->add_message_cache($cache_key, $headers->id, $headers);
@@ -810,7 +800,7 @@
         }
       }
         
-    return $deleted_count;
+    return count($a_msg_headers);
     }
     
   
@@ -846,7 +836,7 @@
         }
       else
         {
-        $a_index = iil_C_FetchHeaderIndex($this->conn, $mailbox, join(',', $this->search_set), $this->sort_field, false);
+        $a_index = iil_C_FetchHeaderIndex($this->conn, $mailbox, join(',', $this->search_set), $this->sort_field, $this->skip_deleted);
 
         if ($this->sort_order=="ASC")
           asort($a_index);
@@ -874,7 +864,7 @@
 
     // fetch complete message index
     $msg_count = $this->_messagecount($mailbox);
-    if ($this->get_capability('sort') && ($a_index = iil_C_Sort($this->conn, $mailbox, $this->sort_field, '')))
+    if ($this->get_capability('sort') && ($a_index = iil_C_Sort($this->conn, $mailbox, $this->sort_field, $this->skip_deleted ? 'UNDELETED' : '')))
       {
       if ($this->sort_order == 'DESC')
         $a_index = array_reverse($a_index);
@@ -883,7 +873,7 @@
       }
     else
       {
-      $a_index = iil_C_FetchHeaderIndex($this->conn, $mailbox, "1:$msg_count", $this->sort_field);
+      $a_index = iil_C_FetchHeaderIndex($this->conn, $mailbox, "1:$msg_count", $this->sort_field, $this->skip_deleted);
 
       if ($this->sort_order=="ASC")
         asort($a_index);
@@ -904,10 +894,12 @@
     {
     $cache_key = $mailbox.'.msg';
     $cache_index = $this->get_message_cache_index($cache_key);
-    $msg_count = $this->_messagecount($mailbox);
 
     // fetch complete message index
-    $a_message_index = iil_C_FetchHeaderIndex($this->conn, $mailbox, "1:$msg_count", 'UID');
+    $a_message_index = iil_C_FetchHeaderIndex($this->conn, $mailbox, "1:*", 'UID', $this->skip_deleted);
+    
+    if ($a_message_index === false)
+      return false;
         
     foreach ($a_message_index as $id => $uid)
       {
@@ -931,12 +923,16 @@
         unset($cache_index[$id]);
         }
         
-
-      // fetch complete headers and add to cache
-      $headers = iil_C_FetchHeader($this->conn, $mailbox, $id, false, $this->fetch_add_headers);
-      $this->add_message_cache($cache_key, $headers->id, $headers);
+	$toupdate[] = $id;
       }
 
+    // fetch complete headers and add to cache
+    if (!empty($toupdate)) {
+      if ($headers = iil_C_FetchHeader($this->conn, $mailbox, join(',', $toupdate), false, $this->fetch_add_headers))
+        foreach ($headers as $header)
+          $this->add_message_cache($cache_key, $header->id, $header);
+      }
+    
     // those ids that are still in cache_index have been deleted      
     if (!empty($cache_index))
       {
@@ -1006,6 +1002,8 @@
    */
   function _search_index($mailbox, $criteria='ALL', $charset=NULL, $sort_field=NULL)
     {
+    $orig_criteria = $criteria;
+
     if ($this->skip_deleted && !preg_match('/UNDELETED/', $criteria))
       $criteria = 'UNDELETED '.$criteria;
 
@@ -1024,6 +1022,11 @@
         if (empty($val))
           unset($a_messages[$i]);
       }
+    
+    // update messagecount cache ?
+//    $a_mailbox_cache = get_cache('messagecount');
+//    $a_mailbox_cache[$mailbox][$criteria] = sizeof($a_messages);
+//    $this->update_cache('messagecount', $a_mailbox_cache);
         
     return $a_messages;
     }
@@ -2219,7 +2222,7 @@
    * @return int -3 = off, -2 = incomplete, -1 = dirty
    */
   function check_cache_status($mailbox, $cache_key)
-    {
+  {
     if (!$this->caching_enabled)
       return -3;
 
@@ -2229,25 +2232,37 @@
 
     // console("Cache check: $msg_count !== ".count($cache_index));
 
-    if ($cache_count==$msg_count)
-      {
-      // get highest index
-      $header = iil_C_FetchHeader($this->conn, $mailbox, "$msg_count", false, $this->fetch_add_headers);
-      $cache_uid = array_pop($cache_index);
-      
-      // uids of highest message matches -> cache seems OK
-      if ($cache_uid == $header->uid)
-        return 1;
+    if ($cache_count==$msg_count) {
+      if ($this->skip_deleted) {
+	$h_index = iil_C_FetchHeaderIndex($this->conn, $mailbox, "1:*", 'UID', $this->skip_deleted);
 
+	if (sizeof($h_index) == $cache_count) {
+	  $cache_index = array_flip($cache_index);
+	  foreach ($h_index as $idx => $uid)
+            unset($cache_index[$uid]);
+
+	  if (empty($cache_index))
+	    return 1;
+	}
+	return -2;
+      } else {
+        // get highest index
+        $header = iil_C_FetchHeader($this->conn, $mailbox, "$msg_count");
+        $cache_uid = array_pop($cache_index);
+      
+        // uids of highest message matches -> cache seems OK
+        if ($cache_uid == $header->uid)
+          return 1;
+      }
       // cache is dirty
       return -1;
-      }
+    }
     // if cache count differs less than 10% report as dirty
     else if (abs($msg_count - $cache_count) < $msg_count/10)
       return -1;
     else
       return -2;
-    }
+  }
 
   /**
    * @access private
diff --git a/program/lib/imap.inc b/program/lib/imap.inc
index 64f0325..adc61af 100644
--- a/program/lib/imap.inc
+++ b/program/lib/imap.inc
@@ -84,6 +84,7 @@
 		- handling connection startup response
 		- added UID EXPUNGE support
 		- fixed problem with double quotes and spaces in folder names in LIST and LSUB 
+		- rewritten iil_C_FetchHeaderIndex()
 
 ********************************************************/
 
@@ -935,28 +936,18 @@
 	return $out;
 }
 
-function iil_C_FetchHeaderIndex(&$conn, $mailbox, $message_set, $index_field,
-    $normalize=true) {
-	global $IMAP_USE_INTERNAL_DATE;
-	
-	$c=0;
-	$result=array();
-	$fp = $conn->fp;
-		
-	if (empty($index_field)) {
-	    $index_field = 'DATE';
-	}
-	$index_field = strtoupper($index_field);
-	
+function iil_C_FetchHeaderIndex(&$conn, $mailbox, $message_set, $index_field='', $skip_deleted=true) {
+
 	list($from_idx, $to_idx) = explode(':', $message_set);
-	if (empty($message_set) || (isset($to_idx)
-    	    && (int)$from_idx > (int)$to_idx)) {
+	if (empty($message_set) ||
+		(isset($to_idx) && $to_idx != '*' && (int)$from_idx > (int)$to_idx)) {
 		return false;
 	}
+
+	$index_field = empty($index_field) ? 'DATE' : strtoupper($index_field);
 	
-	//$fields_a['DATE'] = ($IMAP_USE_INTERNAL_DATE?6:1);
 	$fields_a['DATE']         = 1;
-	$fields_a['INTERNALDATE'] = 6;
+	$fields_a['INTERNALDATE'] = 4;
 	$fields_a['FROM']         = 1;
 	$fields_a['REPLY-TO']     = 1;
 	$fields_a['SENDER']       = 1;
@@ -965,178 +956,107 @@
 	$fields_a['UID']          = 2;
 	$fields_a['SIZE']         = 2;
 	$fields_a['SEEN']         = 3;
-	$fields_a['RECENT']       = 4;
-	$fields_a['DELETED']      = 5;
-	
-	$mode=$fields_a[$index_field];
-	if (!($mode > 0)) {
-	    return false;
+	$fields_a['RECENT']       = 3;
+	$fields_a['DELETED']      = 3;
+
+	if (!($mode = $fields_a[$index_field])) {
+		return false;
 	}
-    
+
 	/*  Do "SELECT" command */
 	if (!iil_C_Select($conn, $mailbox)) {
-	    return false;
+		return false;
 	}
-    
-	/* FETCH date,from,subject headers */
-	if ($mode == 1) {
-		$key     = 'fhi' . ($c++);
-		$request = $key . " FETCH $message_set (BODY.PEEK[HEADER.FIELDS ($index_field)])";
-		if (!iil_PutLine($fp, $request)) {
-		    return false;
-    		}
-		do {
-			
-			$line=chop(iil_ReadLine($fp, 200));
-			$a=explode(' ', $line);
-			if (($line[0] == '*') && ($a[2] == 'FETCH')
-            		    && ($line[strlen($line)-1] != ')')) {
-				$id=$a[1];
+	
+	// build FETCH command string
+	$key     = 'fhi0';
+	$deleted = $skip_deleted ? ' FLAGS' : '';
 
-				$str=$line=chop(iil_ReadLine($fp, 300));
+	if ($mode == 1)
+		$request = " FETCH $message_set (BODY.PEEK[HEADER.FIELDS ($index_field)]$deleted)";
+	else if ($mode == 2) {
+		if ($index_field == 'SIZE')
+			$request = " FETCH $message_set (RFC822.SIZE$deleted)";
+		else
+			$request = " FETCH $message_set ($index_field$deleted)";
+	} else if ($mode == 3)
+		$request = " FETCH $message_set (FLAGS)";
+	else // 4
+		$request = " FETCH $message_set (INTERNALDATE$deleted)";
 
-				while ($line[0] != ')') {					//caution, this line works only in this particular case
-					$line=chop(iil_ReadLine($fp, 300));
-					if ($line[0] != ')') {
-						if (ord($line[0]) <= 32) {			//continuation from previous header line
-							$str.= ' ' . trim($line);
-						}
-						if ((ord($line[0]) > 32) || (strlen($line[0]) == 0)) {
-							list($field, $string) = iil_SplitHeaderLine($str);
-							if (strcasecmp($field, 'date') == 0) {
-								$result[$id] = iil_StrToTime($string);
-							} else {
-								$result[$id] = str_replace('"', '', $string);
-								if ($normalize) {
-								    $result[$id] = strtoupper($result[$id]);
-                            					}
-							}
-							$str=$line;
-						}
-					}
-				}
-			}
-			/*
-			$end_pos = strlen($line)-1;
-			if (($line[0]=="*") && ($a[2]=="FETCH") && ($line[$end_pos]=="}")) {
-				$id = $a[1];
-				$pos = strrpos($line, "{")+1;
-				$bytes = (int)substr($line, $pos, $end_pos-$pos);
-				$received = 0;
-				do {
-					$line      = iil_ReadLine($fp, 0);
-					$received += strlen($line);
-					$line      = chop($line);
+	$request = $key . $request;
+
+	if (!iil_PutLine($conn->fp, $request))
+		return false;
+
+	$result = array();
+
+	do {
+		$line = chop(iil_ReadLine($conn->fp, 200));
+		$line = iil_MultLine($conn->fp, $line);
+
+		if (preg_match('/^\* ([0-9]+) FETCH/', $line, $m)) {
+
+            		$id = $m[1];
+			$flags = NULL;
 					
-					if ($received>$bytes) {
-                    				break;
-					} else if (!$line) {
-                    				continue;
+			if ($skip_deleted && preg_match('/FLAGS \(([^)]+)\)/', $line, $matches)) {
+				$flags = explode(' ', strtoupper($matches[1]));
+				if (in_array('\\DELETED', $flags)) {
+					$deleted[$id] = $id;
+					continue;
+				}
+			}
+
+			if ($mode == 1) {
+				if (preg_match('/BODY\[HEADER\.FIELDS \((DATE|FROM|REPLY-TO|SENDER|TO|SUBJECT)\)\] (.*)/', $line, $matches)) {
+					$value = preg_replace(array('/^"*[a-z]+:/i', '/\s+$/sm'), array('', ''), $matches[2]);
+					$value = trim($value);
+					if ($index_field == 'DATE') {
+						$result[$id] = iil_StrToTime($value);
+					} else {
+						$result[$id] = $value;
 					}
-
-					list($field, $string) = explode(': ', $line);
-					
-					if (strcasecmp($field, 'date') == 0) {
-						$result[$id] = iil_StrToTime($string);
-					} else if ($index_field != 'DATE') {
-						$result[$id]=strtoupper(str_replace('"', '', $string));
-                			}
-				} while ($line[0] != ')');
-			} else {
-				//one line response, not expected so ignore				
-			}
-			*/
-		} while (!iil_StartsWith($line, $key, true));
-
-	}else if ($mode == 6) {
-
-		$key     = 'fhi' . ($c++);
-		$request = $key . " FETCH $message_set (INTERNALDATE)";
-		if (!iil_PutLine($fp, $request)) {
-		    return false;
-    		}
-		do {
-			$line=chop(iil_ReadLine($fp, 200));
-			if ($line[0] == '*') {
-				/*
-				 * original:
-				 * "* 10 FETCH (INTERNALDATE "31-Jul-2002 09:18:02 -0500")"
-				 */
-				$paren_pos = strpos($line, '(');
-				$foo       = substr($line, 0, $paren_pos);
-				$a         = explode(' ', $foo);
-				$id        = $a[1];
-				
-				$open_pos  = strpos($line, '"') + 1;
-				$close_pos = strrpos($line, '"');
-				if ($open_pos && $close_pos) {
-					$len         = $close_pos - $open_pos;
-					$time_str    = substr($line, $open_pos, $len);
-					$result[$id] = strtotime($time_str);
-				}
-			} else {
-				$a = explode(' ', $line);
-			}
-		} while (!iil_StartsWith($a[0], $key, true));
-	} else {
-		if ($mode >= 3) {
-		    $field_name = 'FLAGS';
-		} else if ($index_field == 'SIZE') {
-		    $field_name = 'RFC822.SIZE';
-		} else {
-		    $field_name = $index_field;
-    		}
-        
-		/* 			FETCH uid, size, flags		*/
-		$key     = 'fhi' .($c++);
-		$request = $key . " FETCH $message_set ($field_name)";
-
-		if (!iil_PutLine($fp, $request)) {
-		    return false;
-    		}
-		do {
-			$line=chop(iil_ReadLine($fp, 200));
-			$a = explode(' ', $line);
-			if (($line[0] == '*') && ($a[2] == 'FETCH')) {
-				$line = str_replace('(', '', $line);
-				$line = str_replace(')', '', $line);
-				$a    = explode(' ', $line);
-				
-				$id = $a[1];
-
-				if (isset($result[$id])) {
-				    continue; //if we already got the data, skip forward
-				}
-            			if ($a[3]!=$field_name) {
-                			continue;  //make sure it's returning what we requested
-				}
-                
-				/*  Caution, bad assumptions, next several lines */
-				if ($mode == 2) {
-				    $result[$id] = $a[4];
 				} else {
-					$haystack    = strtoupper($line);
-					$result[$id] = (strpos($haystack, $index_field) > 0 ? "F" : "N");
+					$result[$id] = '';
+				}
+			} else if ($mode == 2) {
+				if (preg_match('/\((UID|RFC822\.SIZE) ([0-9]+)/', $line, $matches)) {
+					$result[$id] = trim($matches[2]);
+				} else {
+					$result[$id] = 0;
+				}
+			} else if ($mode == 3) {
+				if (!$flags && preg_match('/FLAGS \(([^)]+)\)/', $line, $matches)) {
+					$flags = explode(' ', $matches[1]);
+				}
+				$result[$id] = in_array('\\'.$index_field, $flags) ? 1 : 0;
+			} else if ($mode == 4) {
+				if (preg_match('/INTERNALDATE "([^"]+)"/', $line, $matches)) {
+					$result[$id] = strtotime($matches[1]);
+				} else {
+					$result[$id] = 0;
 				}
 			}
-		} while (!iil_StartsWith($line, $key, true));
-	}
+		}
+	} while (!iil_StartsWith($line, $key, true));
 
+/*
 	//check number of elements...
-	list($start_mid, $end_mid) = explode(':', $message_set);
-	if (is_numeric($start_mid) && is_numeric($end_mid)) {
+	if (is_numeric($from_idx) && is_numeric($to_idx)) {
 		//count how many we should have
-		$should_have = $end_mid - $start_mid +1;
+		$should_have = $to_idx - $from_idx + 1;
 		
 		//if we have less, try and fill in the "gaps"
 		if (count($result) < $should_have) {
-			for ($i=$start_mid; $i<=$end_mid; $i++) {
+			for ($i=$from_idx; $i<=$to_idx; $i++) {
 				if (!isset($result[$i])) {
 			    		$result[$i] = '';
             			}
         		}
 		}
 	}
+*/
 	return $result;	
 }
 
@@ -1520,18 +1440,14 @@
 	$result = array();
 	$fp     = $conn->fp;
 	
-	list($from_idx, $to_idx) = explode(':', $message_set);
-	if (empty($message_set) || (isset($to_idx)
-		&& (int)$from_idx > (int)$to_idx)) {
-		return false;
-	}
-		
 	/*  Do "SELECT" command */
 	if (!iil_C_Select($conn, $mailbox)) {
 		$conn->error = "Couldn't select $mailbox";
 		return false;
 	}
 
+	$message_set = iil_CompressMessageSet($message_set);
+
 	if ($add)
 		$add = ' '.strtoupper(trim($add));
 
diff --git a/program/steps/mail/show.inc b/program/steps/mail/show.inc
index 9beb425..6ab5ba8 100644
--- a/program/steps/mail/show.inc
+++ b/program/steps/mail/show.inc
@@ -98,20 +98,8 @@
     {
     $next = $prev = $first = $last = -1;
 
-    if ((!($_SESSION['sort_col'] == 'date' && $_SESSION['sort_order'] == 'DESC') &&
-      $IMAP->get_capability('sort')) || !empty($_REQUEST['_search']))
-      {
-      // Only if we use custom sorting
-      $a_msg_index = $IMAP->message_index(NULL, $_SESSION['sort_col'], $_SESSION['sort_order']);
-
-      $MESSAGE->index = array_search($IMAP->get_id($MESSAGE->uid), $a_msg_index);
-
-      $prev = isset($a_msg_index[$MESSAGE->index-1]) ? $IMAP->get_uid($a_msg_index[$MESSAGE->index-1]) : -1 ;
-      $first = count($a_msg_index)>0 ? $IMAP->get_uid($a_msg_index[0]) : -1;
-      $next = isset($a_msg_index[$MESSAGE->index+1]) ? $IMAP->get_uid($a_msg_index[$MESSAGE->index+1]) : -1 ;
-      $last = count($a_msg_index)>0 ? $IMAP->get_uid($a_msg_index[count($a_msg_index)-1]) : -1;
-      }
-    else
+    if ($_SESSION['sort_col'] == 'date' && $_SESSION['sort_order'] != 'DESC'
+	&& empty($_REQUEST['_search']) && !$IMAP->skip_deleted)
       {
       // this assumes that we are sorted by date_DESC
       $cnt = $IMAP->messagecount();
@@ -123,6 +111,18 @@
       $next = $IMAP->get_uid($seq - 1);
       $last = $IMAP->get_uid(1);
       }
+    else 
+      {
+      // Only if we use custom sorting
+      $a_msg_index = $IMAP->message_index(NULL, $_SESSION['sort_col'], $_SESSION['sort_order']);
+
+      $MESSAGE->index = array_search($IMAP->get_id($MESSAGE->uid), $a_msg_index);
+
+      $prev = isset($a_msg_index[$MESSAGE->index-1]) ? $IMAP->get_uid($a_msg_index[$MESSAGE->index-1]) : -1 ;
+      $first = count($a_msg_index)>0 ? $IMAP->get_uid($a_msg_index[0]) : -1;
+      $next = isset($a_msg_index[$MESSAGE->index+1]) ? $IMAP->get_uid($a_msg_index[$MESSAGE->index+1]) : -1 ;
+      $last = count($a_msg_index)>0 ? $IMAP->get_uid($a_msg_index[count($a_msg_index)-1]) : -1;
+      }
 
     if ($prev > 0)
       $OUTPUT->set_env('prev_uid', $prev);

--
Gitblit v1.9.1