/** * Fetches messages headers (by UID) * * @param string $folder Folder name * @param array $msgs Message UIDs * @param bool $sort Enables result sorting by $msgs * @param bool $force Disables cache use * * @return array Messages headers indexed by UID */ function fetch_headers($folder, $msgs, $sort = true, $force = false) { if (empty($msgs)) { return array(); } if (!$force && ($mcache = $this->get_mcache_engine())) { $headers = $mcache->get_messages($folder, $msgs); } else { if (!$this->check_connection()) { return array(); } else { // fetch reqested headers from server $headers = $this->conn->fetchHeaders($folder, $msgs, true, false, $this->get_fetch_headers()); } } if (empty($headers)) { return array(); } foreach ($headers as $h) { $a_msg_headers[$h->uid] = $h; } if ($sort) { // use this class for message sorting $sorter = new rcube_header_sorter(); $sorter->set_index($msgs); $sorter->sort_headers($a_msg_headers); } return $a_msg_headers; }
/** * Private method for listing a set of message headers (search results) * * @param string $mailbox Mailbox/folder name * @param int $page Current page to list * @param string $sort_field Header field to sort by * @param string $sort_order Sort order [ASC|DESC] * @param int $slice Number of slice items to extract from result array * @return array Indexed array with message header objects * @access private * @see rcube_imap::list_header_set() */ private function _list_header_set($mailbox, $page = NULL, $sort_field = NULL, $sort_order = NULL, $slice = 0) { if (!strlen($mailbox) || empty($this->search_set)) { return array(); } // use saved messages from searching if ($this->threading) { return $this->_list_thread_header_set($mailbox, $page, $sort_field, $sort_order, $slice); } // search set is threaded, we need a new one if ($this->search_threads) { if (empty($this->search_set['tree'])) { return array(); } $this->search('', $this->search_string, $this->search_charset, $sort_field); } $msgs = $this->search_set; $a_msg_headers = array(); $page = $page ? $page : $this->list_page; $start_msg = ($page - 1) * $this->page_size; $this->_set_sort_order($sort_field, $sort_order); // quickest method (default sorting) if (!$this->search_sort_field && !$this->sort_field) { if ($sort_order == 'DESC') { $msgs = array_reverse($msgs); } // get messages uids for one page $msgs = array_slice(array_values($msgs), $start_msg, min(count($msgs) - $start_msg, $this->page_size)); if ($slice) { $msgs = array_slice($msgs, -$slice, $slice); } // fetch headers $a_msg_headers = $this->fetch_headers($mailbox, $msgs); // I didn't found in RFC that FETCH always returns messages sorted by index $sorter = new rcube_header_sorter(); $sorter->set_index($msgs); $sorter->sort_headers($a_msg_headers); return array_values($a_msg_headers); } // sorted messages, so we can first slice array and then fetch only wanted headers if ($this->search_sorted) { // SORT searching result // reset search set if sorting field has been changed if ($this->sort_field && $this->search_sort_field != $this->sort_field) { $msgs = $this->search('', $this->search_string, $this->search_charset, $this->sort_field); } // return empty array if no messages found if (empty($msgs)) { return array(); } if ($sort_order == 'DESC') { $msgs = array_reverse($msgs); } // get messages uids for one page $msgs = array_slice(array_values($msgs), $start_msg, min(count($msgs) - $start_msg, $this->page_size)); if ($slice) { $msgs = array_slice($msgs, -$slice, $slice); } // fetch headers $a_msg_headers = $this->fetch_headers($mailbox, $msgs); $sorter = new rcube_header_sorter(); $sorter->set_index($msgs); $sorter->sort_headers($a_msg_headers); return array_values($a_msg_headers); } else { // SEARCH result, need sorting $cnt = count($msgs); // 300: experimantal value for best result if ($cnt > 300 && $cnt > $this->page_size || !$this->sort_field) { // use memory less expensive (and quick) method for big result set $a_index = $this->message_index('', $this->sort_field, $this->sort_order); // get messages uids for one page... $msgs = array_slice($a_index, $start_msg, min($cnt - $start_msg, $this->page_size)); if ($slice) { $msgs = array_slice($msgs, -$slice, $slice); } // ...and fetch headers $a_msg_headers = $this->fetch_headers($mailbox, $msgs); // return empty array if no messages found if (!is_array($a_msg_headers) || empty($a_msg_headers)) { return array(); } $sorter = new rcube_header_sorter(); $sorter->set_index($msgs); $sorter->sort_headers($a_msg_headers); return array_values($a_msg_headers); } else { // for small result set we can fetch all messages headers $a_msg_headers = $this->fetch_headers($mailbox, $msgs); // return empty array if no messages found if (!is_array($a_msg_headers) || empty($a_msg_headers)) { return array(); } // if not already sorted $a_msg_headers = $this->conn->sortHeaders($a_msg_headers, $this->sort_field, $this->sort_order); // only return the requested part of the set $a_msg_headers = array_slice(array_values($a_msg_headers), $start_msg, min($cnt - $start_msg, $this->page_size)); if ($slice) { $a_msg_headers = array_slice($a_msg_headers, -$slice, $slice); } return $a_msg_headers; } } }