diff options
-rw-r--r-- | program/include/rcube_imap.php | 88 | ||||
-rw-r--r-- | program/lib/imap.inc | 121 |
2 files changed, 102 insertions, 107 deletions
diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php index 332d53029..57a66751c 100644 --- a/program/include/rcube_imap.php +++ b/program/include/rcube_imap.php @@ -682,17 +682,19 @@ class rcube_imap $this->_fetch_headers($mailbox, join(",", $msg_index), $a_msg_headers, $cache_key); } // use SORT command - else if ($this->get_capability('sort') && ($msg_index = iil_C_Sort($this->conn, $mailbox, $this->sort_field, $this->skip_deleted ? 'UNDELETED' : ''))) + else if ($this->get_capability('sort')) { - list($begin, $end) = $this->_get_message_range(count($msg_index), $page); - $max = max($msg_index); - $msg_index = array_slice($msg_index, $begin, $end-$begin); + if ($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); - if ($slice) - $msg_index = array_slice($msg_index, ($this->sort_order == 'DESC' ? 0 : -$slice), $slice); + if ($slice) + $msg_index = array_slice($msg_index, ($this->sort_order == 'DESC' ? 0 : -$slice), $slice); - // fetch reqested headers from server - $this->_fetch_headers($mailbox, join(',', $msg_index), $a_msg_headers, $cache_key); + // fetch reqested headers from server + $this->_fetch_headers($mailbox, join(',', $msg_index), $a_msg_headers, $cache_key); + } } // fetch specified header for all messages and sort else if ($a_index = iil_C_FetchHeaderIndex($this->conn, $mailbox, "1:*", $this->sort_field, $this->skip_deleted)) @@ -773,7 +775,7 @@ class rcube_imap // get all threads list ($thread_tree, $msg_depth, $has_children) = iil_C_Thread($this->conn, $mailbox, $this->threading, $this->skip_deleted ? 'UNDELETED' : ''); - + // add to internal (fast) cache $this->icache['threads'] = array(); $this->icache['threads']['tree'] = $thread_tree; @@ -1082,25 +1084,25 @@ class rcube_imap // fetch reqested headers from server $a_header_index = iil_C_FetchHeaders($this->conn, $mailbox, $msgs, false, false, $this->fetch_add_headers); - if (!empty($a_header_index)) - { - // cache is incomplete - $cache_index = $this->get_message_cache_index($cache_key); - - foreach ($a_header_index as $i => $headers) { - if ($this->caching_enabled && $cache_index[$headers->id] != $headers->uid) { - // prevent index duplicates - if ($cache_index[$headers->id]) { - $this->remove_message_cache($cache_key, $headers->id, true); - unset($cache_index[$headers->id]); + if (empty($a_header_index)) + return 0; + + // cache is incomplete + $cache_index = $this->get_message_cache_index($cache_key); + + foreach ($a_header_index as $i => $headers) { + if ($this->caching_enabled && $cache_index[$headers->id] != $headers->uid) { + // prevent index duplicates + if ($cache_index[$headers->id]) { + $this->remove_message_cache($cache_key, $headers->id, true); + unset($cache_index[$headers->id]); } - // add message to cache - $this->add_message_cache($cache_key, $headers->id, $headers, NULL, - !in_array($headers->uid, $cache_index)); + // add message to cache + $this->add_message_cache($cache_key, $headers->id, $headers, NULL, + !in_array($headers->uid, $cache_index)); } - $a_msg_headers[$headers->uid] = $headers; - } + $a_msg_headers[$headers->uid] = $headers; } return count($a_msg_headers); @@ -1223,17 +1225,16 @@ class rcube_imap $this->cache[$key] = $a_index; } // fetch complete message index - else if ($this->get_capability('sort') && ($a_index = iil_C_Sort($this->conn, $mailbox, $this->sort_field, $this->skip_deleted ? 'UNDELETED' : ''))) + else if ($this->get_capability('sort')) { - if ($this->sort_order == 'DESC') - $a_index = array_reverse($a_index); - - $this->cache[$key] = $a_index; + if ($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); + + $this->cache[$key] = $a_index; + } } - else - { - $a_index = iil_C_FetchHeaderIndex($this->conn, $mailbox, "1:*", $this->sort_field, $this->skip_deleted); - + else if ($a_index = iil_C_FetchHeaderIndex($this->conn, $mailbox, "1:*", $this->sort_field, $this->skip_deleted)) { if ($this->sort_order=="ASC") asort($a_index); else if ($this->sort_order=="DESC") @@ -1461,6 +1462,9 @@ class rcube_imap else if ($sort_field && $this->get_capability('sort')) { $charset = $charset ? $charset : $this->default_charset; $a_messages = iil_C_Sort($this->conn, $mailbox, $sort_field, $criteria, FALSE, $charset); + + if (!$a_messages) + return array(); } else { if ($orig_criteria == 'ALL') { @@ -1469,7 +1473,10 @@ class rcube_imap } else { $a_messages = iil_C_Search($this->conn, $mailbox, ($charset ? "CHARSET $charset " : '') . $criteria); - + + if (!$a_messages) + return array(); + // I didn't found that SEARCH always returns sorted IDs if (!$this->sort_field) sort($a_messages); @@ -1500,7 +1507,7 @@ class rcube_imap // THREAD=REFS: sorting by the most recent date in each thread // default sorting if (!$this->sort_field || ($this->sort_field == 'date' && $this->threading == 'REFS')) { - return array_keys($thread_tree); + return array_keys((array)$thread_tree); } // here we'll implement REFS sorting, for performance reason else { // ($sort_field == 'date' && $this->threading != 'REFS') @@ -1508,11 +1515,20 @@ class rcube_imap if ($this->get_capability('sort')) { $a_index = iil_C_Sort($this->conn, $mailbox, $this->sort_field, !empty($ids) ? $ids : ($this->skip_deleted ? 'UNDELETED' : '')); + + // return unsorted tree if we've got no index data + if (!$a_index) + return array_keys((array)$thread_tree); } else { // fetch specified headers for all messages and sort them $a_index = iil_C_FetchHeaderIndex($this->conn, $mailbox, !empty($ids) ? $ids : "1:*", $this->sort_field, $this->skip_deleted); + + // return unsorted tree if we've got no index data + if (!$a_index) + return array_keys((array)$thread_tree); + asort($a_index); // ASC $a_index = array_values($a_index); } diff --git a/program/lib/imap.inc b/program/lib/imap.inc index 42677164f..48363bec9 100644 --- a/program/lib/imap.inc +++ b/program/lib/imap.inc @@ -741,32 +741,6 @@ function iil_ExplodeQuotedString($delimiter, $string) { return $result; } -function iil_CheckForRecent($host, $user, $password, $mailbox) { - if (empty($mailbox)) { - $mailbox = 'INBOX'; - } - - $conn = iil_Connect($host, $user, $password, 'plain'); - $fp = $conn->fp; - if ($fp) { - iil_PutLine($fp, "a002 EXAMINE \"".iil_Escape($mailbox)."\""); - do { - $line=chop(iil_ReadLine($fp, 300)); - $a=explode(' ', $line); - if (($a[0] == '*') && (strcasecmp($a[2], 'RECENT') == 0)) { - $result = (int) $a[1]; - } - } while (!iil_StartsWith($a[0], 'a002', true)); - - iil_PutLine($fp, "a003 LOGOUT"); - fclose($fp); - } else { - $result = -2; - } - - return $result; -} - function iil_C_Select(&$conn, $mailbox) { if (empty($mailbox)) { @@ -1619,61 +1593,66 @@ function iil_ParseThread($str, $begin, $end, $root, $parent, $depth, &$depthmap, function iil_C_Thread(&$conn, $folder, $algorithm='REFERENCES', $criteria='', $encoding='US-ASCII') { - if (iil_C_Select($conn, $folder)) { - - $encoding = $encoding ? trim($encoding) : 'US-ASCII'; - $algorithm = $algorithm ? trim($algorithm) : 'REFERENCES'; - $criteria = $criteria ? 'ALL '.trim($criteria) : 'ALL'; - - iil_PutLineC($conn->fp, "thrd1 THREAD $algorithm $encoding $criteria"); - do { - $line = trim(iil_ReadLine($conn->fp, 10000)); - if (preg_match('/^\* THREAD/', $line)) { - $str = trim(substr($line, 8)); - $depthmap = array(); - $haschildren = array(); - $tree = iil_ParseThread($str, 0, strlen($str), null, null, 0, $depthmap, $haschildren); - } - } while (!iil_StartsWith($line, 'thrd1', true)); + if (!iil_C_Select($conn, $folder)) { + $conn->error = "Couldn't select $folder"; + return false; + } - $result_code = iil_ParseResult($line); - if ($result_code == 0) { - return array($tree, $depthmap, $haschildren); + $encoding = $encoding ? trim($encoding) : 'US-ASCII'; + $algorithm = $algorithm ? trim($algorithm) : 'REFERENCES'; + $criteria = $criteria ? 'ALL '.trim($criteria) : 'ALL'; + + if (!iil_PutLineC($conn->fp, "thrd1 THREAD $algorithm $encoding $criteria")) { + return false; + } + do { + $line = trim(iil_ReadLine($conn->fp, 10000)); + if (preg_match('/^\* THREAD/', $line)) { + $str = trim(substr($line, 8)); + $depthmap = array(); + $haschildren = array(); + $tree = iil_ParseThread($str, 0, strlen($str), null, null, 0, $depthmap, $haschildren); } - $conn->error = 'iil_C_Thread: ' . $line . "\n"; - return false; + } while (!iil_StartsWith($line, 'thrd1', true)); + + $result_code = iil_ParseResult($line); + if ($result_code == 0) { + return array($tree, $depthmap, $haschildren); } - $conn->error = "iil_C_Thread: Couldn't select \"$folder\"\n"; - return false; + + $conn->error = 'iil_C_Thread: ' . $line . "\n"; + return false; } function iil_C_Search(&$conn, $folder, $criteria) { - if (iil_C_Select($conn, $folder)) { - $data = ''; - - $query = 'srch1 SEARCH ' . chop($criteria); - if (!iil_PutLineC($conn->fp, $query)) { - return false; - } - do { - $line = trim(iil_ReadLine($conn->fp)); - if (iil_StartsWith($line, '* SEARCH')) { - $data .= substr($line, 8); - } else if (preg_match('/^[0-9 ]+$/', $line)) { - $data .= $line; - } - } while (!iil_StartsWith($line, 'srch1', true)); + if (!iil_C_Select($conn, $folder)) { + $conn->error = "Couldn't select $folder"; + return false; + } + + $data = ''; + $query = 'srch1 SEARCH ' . chop($criteria); - $result_code = iil_ParseResult($line); - if ($result_code == 0) { - return preg_split('/\s+/', $data, -1, PREG_SPLIT_NO_EMPTY); + if (!iil_PutLineC($conn->fp, $query)) { + return false; + } + do { + $line = trim(iil_ReadLine($conn->fp)); + if (iil_StartsWith($line, '* SEARCH')) { + $data .= substr($line, 8); + } else if (preg_match('/^[0-9 ]+$/', $line)) { + $data .= $line; } - $conn->error = 'iil_C_Search: ' . $line . "\n"; - return false; + } while (!iil_StartsWith($line, 'srch1', true)); + + $result_code = iil_ParseResult($line); + if ($result_code == 0) { + return preg_split('/\s+/', $data, -1, PREG_SPLIT_NO_EMPTY); } - $conn->error = "iil_C_Search: Couldn't select \"$folder\"\n"; - return false; + + $conn->error = 'iil_C_Search: ' . $line . "\n"; + return false; } function iil_C_Move(&$conn, $messages, $from, $to) { |