summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--program/include/rcube_imap.inc45
-rw-r--r--program/lib/imap.inc35
-rw-r--r--program/steps/mail/show.inc26
3 files changed, 82 insertions, 24 deletions
diff --git a/program/include/rcube_imap.inc b/program/include/rcube_imap.inc
index f515b446d..c818fa010 100644
--- a/program/include/rcube_imap.inc
+++ b/program/include/rcube_imap.inc
@@ -503,7 +503,7 @@ class rcube_imap
$begin = 0;
$end = $max;
}
- else if ($this->sort_order=='DESC')
+ else if (!$this->get_capability('sort') && $this->sort_order=='DESC')
{
$begin = $max - $this->page_size - $start_msg;
$end = $max - $start_msg;
@@ -581,8 +581,13 @@ class rcube_imap
// if not already sorted
- if (!$headers_sorted)
- $a_msg_headers = iil_SortHeaders($a_msg_headers, $this->sort_field, $this->sort_order);
+// if (!$headers_sorted)
+// $a_msg_headers = iil_SortHeaders($a_msg_headers, $this->sort_field, $this->sort_order);
+
+
+ if (!$headers_sorted && $this->sort_order == 'DESC')
+ $a_msg_headers = array_reverse($a_msg_headers);
+
return array_values($a_msg_headers);
}
@@ -728,8 +733,7 @@ class rcube_imap
return $deleted_count;
}
-
-
+
// return sorted array of message UIDs
function message_index($mbox='', $sort_field=NULL, $sort_order=NULL)
{
@@ -759,17 +763,13 @@ class rcube_imap
// 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, '', TRUE)))
{
- $a_uids = iil_C_FetchUIDs($this->conn, $mailbox);
-
if ($this->sort_order == 'DESC')
$a_index = array_reverse($a_index);
- $i = 0;
- $this->cache[$key] = array();
- foreach ($a_index as $index => $value)
- $this->cache[$key][$i++] = $a_uids[$value];
+ $this->cache[$key] = $a_index;
+
}
else
{
@@ -1479,14 +1479,14 @@ class rcube_imap
$header = iil_C_FetchHeader($this->conn, $mailbox, "$msg_count");
$cache_uid = array_pop($cache_index);
- // uids of highes message matches -> cache seems OK
+ // 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 that 10% report as dirty
+ // if cache count differs less than 10% report as dirty
else if (abs($msg_count - $cache_count) < $msg_count/10)
return -1;
else
@@ -1835,6 +1835,15 @@ class rcube_imap
return array_merge($a_defaults, $a_out);
}
+ function get_id($uid)
+ {
+ return $this->_uid2id($uid);
+ }
+
+ function get_uid($id)
+ {
+ return $this->_id2uid($id);
+ }
function _uid2id($uid, $mbox=NULL)
{
@@ -1847,6 +1856,14 @@ class rcube_imap
return $this->uid_id_map[$mbox][$uid];
}
+ function _id2uid($id, $mbox=NULL)
+ {
+ if (!$mbox)
+ $mbox = $this->mailbox;
+
+ return iil_C_ID2UID($this->conn, $mbox, $id);
+ }
+
// parse string or array of server capabilities and put them in internal array
function _parse_capability($caps)
diff --git a/program/lib/imap.inc b/program/lib/imap.inc
index 97286c4ff..6067d81b8 100644
--- a/program/lib/imap.inc
+++ b/program/lib/imap.inc
@@ -41,6 +41,8 @@
- Avoid stripslahes in iil_Connect()
- Added patch to iil_SortHeaders() by Richard Green
- Removed <br> from error messages (better for logging)
+ - Added patch to iil_C_Sort() enabling UID SORT commands
+ - Added function iil_C_ID2UID()
- Removed some debuggers (echo ...)
********************************************************/
@@ -627,7 +629,7 @@ function iil_StrToTime($str){
return $time2;
}
-function iil_C_Sort(&$conn, $mailbox, $field, $add=''){
+function iil_C_Sort(&$conn, $mailbox, $field, $add='', $is_uid=FALSE, $encoding='US-ASCII'){
/* Do "SELECT" command */
if (!iil_C_Select($conn, $mailbox)) return false;
@@ -635,10 +637,16 @@ function iil_C_Sort(&$conn, $mailbox, $field, $add=''){
if ($field=='INTERNALDATE') $field='ARRIVAL';
$fields = array('ARRIVAL'=>1,'CC'=>1,'DATE'=>1,'FROM'=>1,'SIZE'=>1,'SUBJECT'=>1,'TO'=>1);
- if (!$fields[$field]) return false;
+ if (!$fields[$field])
+ return false;
+
+ $is_uid = $is_uid ? 'UID ' : '';
+ if (!empty($add))
+ $add = " $add";
+
$fp = $conn->fp;
- $command = 's SORT ('.$field.') US-ASCII ALL '."$add\r\n";
+ $command = 's '. $is_uid .'SORT ('.$field.') '.$encoding.' ALL'."$add\r\n";
$line = $data = '';
if (!fputs($fp, $command)) return false;
@@ -656,7 +664,7 @@ function iil_C_Sort(&$conn, $mailbox, $field, $add=''){
return $out;
}
-function iil_C_FetchHeaderIndex(&$conn, $mailbox, $message_set, $index_field,$normalize=true){
+function iil_C_FetchHeaderIndex(&$conn, $mailbox, $message_set, $index_field, $normalize=true){
global $IMAP_USE_INTERNAL_DATE;
$c=0;
@@ -1570,6 +1578,25 @@ function iil_C_UID2ID(&$conn, $folder, $uid){
return false;
}
+function iil_C_ID2UID(&$conn, $folder, $id){
+ $fp = $conn->fp;
+ $result=-1;
+ if ($id > 0) {
+ if (iil_C_Select($conn, $folder)){
+ $key = "FUID";
+ if (fputs($fp, "$key FETCH $id (UID)\r\n")){
+ do{
+ $line=chop(iil_ReadLine($fp, 1024));
+ if (eregi("^\* $id FETCH \(UID (.*)\)", $line, $r)){
+ $result = $r[1];
+ }
+ } while (!preg_match("/^$key/", $line));
+ }
+ }
+ }
+ return $result;
+}
+
function iil_C_Search(&$conn, $folder, $criteria){
$fp = $conn->fp;
if (iil_C_Select($conn, $folder)){
diff --git a/program/steps/mail/show.inc b/program/steps/mail/show.inc
index 49b83772b..27fc44b3f 100644
--- a/program/steps/mail/show.inc
+++ b/program/steps/mail/show.inc
@@ -64,14 +64,28 @@ if ($_GET['_uid'])
$javascript = sprintf("%s.set_env('uid', '%s');\n", $JS_OBJECT_NAME, $_GET['_uid']);
$javascript .= sprintf("%s.set_env('safemode', '%b');", $JS_OBJECT_NAME, $_GET['_safe']);
+ $next = $prev = -1;
// get previous and next message UID
- $a_msg_index = $IMAP->message_index(NULL, $_SESSION['sort_col'], $_SESSION['sort_order']);
- $MESSAGE['index'] = array_search((string)$_GET['_uid'], $a_msg_index, TRUE);
+ if (!($_SESSION['sort_col'] == 'date' && $_SESSION['sort_order'] == 'DESC') &&
+ $IMAP->get_capability('sort')) {
+ // Only if we use custom sorting
+ $a_msg_index = $IMAP->message_index(NULL, $_SESSION['sort_col'], $_SESSION['sort_order']);
+
+ $MESSAGE['index'] = array_search((string)$_GET['_uid'], $a_msg_index, TRUE);
+ $prev = isset($a_msg_index[$MESSAGE['index']-1]) ? $a_msg_index[$MESSAGE['index']-1] : -1 ;
+ $next = isset($a_msg_index[$MESSAGE['index']+1]) ? $a_msg_index[$MESSAGE['index']+1] : -1 ;
+ } else {
+ // this assumes that we are sorted by date_DESC
+ $seq = $IMAP->get_id($_GET['_uid']);
+ $prev = $IMAP->get_uid($seq + 1);
+ $next = $IMAP->get_uid($seq - 1);
+ $MESSAGE['index'] = $IMAP->messagecount() - $seq;
+ }
- if (isset($a_msg_index[$MESSAGE['index']-1]))
- $javascript .= sprintf("\n%s.set_env('prev_uid', '%s');", $JS_OBJECT_NAME, $a_msg_index[$MESSAGE['index']-1]);
- if (isset($a_msg_index[$MESSAGE['index']+1]))
- $javascript .= sprintf("\n%s.set_env('next_uid', '%s');", $JS_OBJECT_NAME, $a_msg_index[$MESSAGE['index']+1]);
+ if ($prev > 0)
+ $javascript .= sprintf("\n%s.set_env('prev_uid', '%s');", $JS_OBJECT_NAME, $prev);
+ if ($next > 0)
+ $javascript .= sprintf("\n%s.set_env('next_uid', '%s');", $JS_OBJECT_NAME, $next);
$OUTPUT->add_script($javascript);
}