/** * Sort thread * * @param string $mailbox Mailbox name * @param array $thread_tree Unsorted thread tree (rcube_imap_generic::thread() result) * @param array $ids Message IDs if we know what we need (e.g. search result) * @return array Sorted roots IDs * @access private */ private function _sort_threads($mailbox, $thread_tree, $ids = NULL) { // THREAD=ORDEREDSUBJECT: sorting by sent date of root message // THREAD=REFERENCES: sorting by sent date of root message // 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((array) $thread_tree); } else { // ($sort_field == 'date' && $this->threading != 'REFS') // use SORT command if ($this->get_capability('SORT') && ($a_index = $this->conn->sort($mailbox, $this->sort_field, !empty($ids) ? $ids : ($this->skip_deleted ? 'UNDELETED' : ''))) !== false) { // 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 = $this->conn->fetchHeaderIndex($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); } return $this->_sort_thread_refs($thread_tree, $a_index); } }
/** * protected search method * * @param string $folder Folder name * @param string $criteria Search criteria * @param string $charset Charset * @param string $sort_field Sorting field * * @return rcube_result_index|rcube_result_thread Search results (UIDs) * @see rcube_imap::search() */ protected function search_index($folder, $criteria = 'ALL', $charset = NULL, $sort_field = NULL) { $orig_criteria = $criteria; if (!$this->check_connection()) { if ($this->threading) { return new rcube_result_thread(); } else { return new rcube_result_index(); } } if ($this->options['skip_deleted'] && !preg_match('/UNDELETED/', $criteria)) { $criteria = 'UNDELETED ' . $criteria; } // unset CHARSET if criteria string is ASCII, this way // SEARCH won't be re-sent after "unsupported charset" response if ($charset && $charset != 'US-ASCII' && is_ascii($criteria)) { $charset = 'US-ASCII'; } if ($this->threading) { $threads = $this->conn->thread($folder, $this->threading, $criteria, true, $charset); // Error, try with US-ASCII (RFC5256: SORT/THREAD must support US-ASCII and UTF-8, // but I've seen that Courier doesn't support UTF-8) if ($threads->is_error() && $charset && $charset != 'US-ASCII') { $threads = $this->conn->thread($folder, $this->threading, $this->convert_criteria($criteria, $charset), true, 'US-ASCII'); } return $threads; } if ($sort_field && $this->get_capability('SORT')) { $charset = $charset ? $charset : $this->default_charset; $messages = $this->conn->sort($folder, $sort_field, $criteria, true, $charset); // Error, try with US-ASCII (RFC5256: SORT/THREAD must support US-ASCII and UTF-8, // but I've seen Courier with disabled UTF-8 support) if ($messages->is_error() && $charset && $charset != 'US-ASCII') { $messages = $this->conn->sort($folder, $sort_field, $this->convert_criteria($criteria, $charset), true, 'US-ASCII'); } if (!$messages->is_error()) { $this->search_sorted = true; return $messages; } } $messages = $this->conn->search($folder, ($charset && $charset != 'US-ASCII' ? "CHARSET {$charset} " : '') . $criteria, true); // Error, try with US-ASCII (some servers may support only US-ASCII) if ($messages->is_error() && $charset && $charset != 'US-ASCII') { $messages = $this->conn->search($folder, $this->convert_criteria($criteria, $charset), true); } $this->search_sorted = false; return $messages; }
/** * Sort thread * * @param string $mailbox Mailbox name * @param array $thread_tree Unsorted thread tree (rcube_imap_generic::thread() result) * @param array $ids Message IDs if we know what we need (e.g. search result) * * @return array Sorted roots IDs */ function sort_threads($mailbox, $thread_tree, $ids = null) { // THREAD=ORDEREDSUBJECT: sorting by sent date of root message // THREAD=REFERENCES: sorting by sent date of root message // 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((array) $thread_tree); } else { if ($mcache = $this->get_mcache_engine()) { $a_index = $mcache->get_index($mailbox, $this->sort_field, 'ASC'); if (is_array($a_index)) { $a_index = array_keys($a_index); // now we must remove IDs that doesn't exist in $ids if (!empty($ids)) { $a_index = array_intersect($a_index, $ids); } } } else { if ($this->get_capability('SORT') && ($a_index = $this->conn->sort($mailbox, $this->sort_field, !empty($ids) ? $ids : ($this->skip_deleted ? 'UNDELETED' : ''))) !== false) { // do nothing } else { // fetch specified headers for all messages and sort them $a_index = $this->conn->fetchHeaderIndex($mailbox, !empty($ids) ? $ids : "1:*", $this->sort_field, $this->skip_deleted); // return unsorted tree if we've got no index data if (!empty($a_index)) { asort($a_index); // ASC $a_index = array_values($a_index); } } } if (empty($a_index)) { return array_keys((array) $thread_tree); } return $this->_sort_thread_refs($thread_tree, $a_index); } }