Beispiel #1
0
 /**
  * protected method for listing a set of message headers (search results)
  *
  * @param   string   $folder   Folder name
  * @param   int      $page     Current page to list
  * @param   int      $slice    Number of slice items to extract from result array
  *
  * @return  array    Indexed array with message header objects
  */
 protected function list_search_messages($folder, $page, $slice = 0)
 {
     if (!strlen($folder) || empty($this->search_set) || $this->search_set->is_empty()) {
         return array();
     }
     // use saved messages from searching
     if ($this->threading) {
         return $this->list_search_thread_messages($folder, $page, $slice);
     }
     // search set is threaded, we need a new one
     if ($this->search_threads) {
         $this->search('', $this->search_string, $this->search_charset, $this->sort_field);
     }
     $index = clone $this->search_set;
     $from = ($page - 1) * $this->page_size;
     $to = $from + $this->page_size;
     // return empty array if no messages found
     if ($index->is_empty()) {
         return array();
     }
     // quickest method (default sorting)
     if (!$this->search_sort_field && !$this->sort_field) {
         $got_index = true;
     } else {
         if ($this->search_sorted) {
             // SORT searching result
             $got_index = true;
             // reset search set if sorting field has been changed
             if ($this->sort_field && $this->search_sort_field != $this->sort_field) {
                 $this->search('', $this->search_string, $this->search_charset, $this->sort_field);
                 $index = clone $this->search_set;
                 // return empty array if no messages found
                 if ($index->is_empty()) {
                     return array();
                 }
             }
         }
     }
     if ($got_index) {
         if ($this->sort_order != $index->get_parameters('ORDER')) {
             $index->revert();
         }
         // get messages uids for one page
         $index->slice($from, $to - $from);
         if ($slice) {
             $index->slice(-$slice, $slice);
         }
         // fetch headers
         $a_index = $index->get();
         $a_msg_headers = $this->fetch_headers($folder, $a_index);
         return array_values($a_msg_headers);
     }
     // SEARCH result, need sorting
     $cnt = $index->count();
     // 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
         $index = clone $this->index('', $this->sort_field, $this->sort_order);
         // get messages uids for one page...
         $index->slice($from, min($cnt - $from, $this->page_size));
         if ($slice) {
             $index->slice(-$slice, $slice);
         }
         // ...and fetch headers
         $a_index = $index->get();
         $a_msg_headers = $this->fetch_headers($folder, $a_index);
         return array_values($a_msg_headers);
     } else {
         // for small result set we can fetch all messages headers
         $a_index = $index->get();
         $a_msg_headers = $this->fetch_headers($folder, $a_index, false);
         // return empty array if no messages found
         if (!is_array($a_msg_headers) || empty($a_msg_headers)) {
             return array();
         }
         if (!$this->check_connection()) {
             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
         $slice_length = min($this->page_size, $cnt - ($to > $cnt ? $from : $to));
         $a_msg_headers = array_slice(array_values($a_msg_headers), $from, $slice_length);
         if ($slice) {
             $a_msg_headers = array_slice($a_msg_headers, -$slice, $slice);
         }
         return $a_msg_headers;
     }
 }
Beispiel #2
0
 /**
  * protected method for listing a set of message headers (search results)
  *
  * @param   string   $folder   Folder name
  * @param   int      $page     Current page to list
  * @param   int      $slice    Number of slice items to extract from result array
  *
  * @return array Indexed array with message header objects
  */
 protected function list_search_messages($folder, $page, $slice = 0)
 {
     if (!strlen($folder) || empty($this->search_set) || $this->search_set->is_empty()) {
         return array();
     }
     // gather messages from a multi-folder search
     if ($this->search_set->multi) {
         $page_size = $this->page_size;
         $sort_field = $this->sort_field;
         $search_set = $this->search_set;
         // prepare paging
         $cnt = $search_set->count();
         $from = ($page - 1) * $page_size;
         $to = $from + $page_size;
         $slice_length = min($page_size, $cnt - $from);
         // fetch resultset headers, sort and slice them
         if (!empty($sort_field) && $search_set->get_parameters('SORT') != $sort_field) {
             $this->sort_field = null;
             $this->page_size = 1000;
             // fetch up to 1000 matching messages per folder
             $this->threading = false;
             $a_msg_headers = array();
             foreach ($search_set->sets as $resultset) {
                 if (!$resultset->is_empty()) {
                     $this->search_set = $resultset;
                     $this->search_threads = $resultset instanceof rcube_result_thread;
                     $a_headers = $this->list_search_messages($resultset->get_parameters('MAILBOX'), 1);
                     $a_msg_headers = array_merge($a_msg_headers, $a_headers);
                     unset($a_headers);
                 }
             }
             // sort headers
             if (!empty($a_msg_headers)) {
                 $a_msg_headers = rcube_imap_generic::sortHeaders($a_msg_headers, $sort_field, $this->sort_order);
             }
             // store (sorted) message index
             $search_set->set_message_index($a_msg_headers, $sort_field, $this->sort_order);
             // only return the requested part of the set
             $a_msg_headers = array_slice(array_values($a_msg_headers), $from, $slice_length);
         } else {
             if ($this->sort_order != $search_set->get_parameters('ORDER')) {
                 $search_set->revert();
             }
             // slice resultset first...
             $fetch = array();
             foreach (array_slice($search_set->get(), $from, $slice_length) as $msg_id) {
                 list($uid, $folder) = explode('-', $msg_id, 2);
                 $fetch[$folder][] = $uid;
             }
             // ... and fetch the requested set of headers
             $a_msg_headers = array();
             foreach ($fetch as $folder => $a_index) {
                 $a_msg_headers = array_merge($a_msg_headers, array_values($this->fetch_headers($folder, $a_index)));
             }
         }
         if ($slice) {
             $a_msg_headers = array_slice($a_msg_headers, -$slice, $slice);
         }
         // restore members
         $this->sort_field = $sort_field;
         $this->page_size = $page_size;
         $this->search_set = $search_set;
         return $a_msg_headers;
     }
     // use saved messages from searching
     if ($this->threading) {
         return $this->list_search_thread_messages($folder, $page, $slice);
     }
     // search set is threaded, we need a new one
     if ($this->search_threads) {
         $this->search('', $this->search_string, $this->search_charset, $this->sort_field);
     }
     $index = clone $this->search_set;
     $from = ($page - 1) * $this->page_size;
     $to = $from + $this->page_size;
     // return empty array if no messages found
     if ($index->is_empty()) {
         return array();
     }
     // quickest method (default sorting)
     if (!$this->search_sort_field && !$this->sort_field) {
         $got_index = true;
     } else {
         if ($this->search_sorted) {
             // SORT searching result
             $got_index = true;
             // reset search set if sorting field has been changed
             if ($this->sort_field && $this->search_sort_field != $this->sort_field) {
                 $this->search('', $this->search_string, $this->search_charset, $this->sort_field);
                 $index = clone $this->search_set;
                 // return empty array if no messages found
                 if ($index->is_empty()) {
                     return array();
                 }
             }
         }
     }
     if ($got_index) {
         if ($this->sort_order != $index->get_parameters('ORDER')) {
             $index->revert();
         }
         // get messages uids for one page
         $index->slice($from, $to - $from);
         if ($slice) {
             $index->slice(-$slice, $slice);
         }
         // fetch headers
         $a_index = $index->get();
         $a_msg_headers = $this->fetch_headers($folder, $a_index);
         return array_values($a_msg_headers);
     }
     // SEARCH result, need sorting
     $cnt = $index->count();
     // 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
         $index = clone $this->index('', $this->sort_field, $this->sort_order);
         // get messages uids for one page...
         $index->slice($from, min($cnt - $from, $this->page_size));
         if ($slice) {
             $index->slice(-$slice, $slice);
         }
         // ...and fetch headers
         $a_index = $index->get();
         $a_msg_headers = $this->fetch_headers($folder, $a_index);
         return array_values($a_msg_headers);
     } else {
         // for small result set we can fetch all messages headers
         $a_index = $index->get();
         $a_msg_headers = $this->fetch_headers($folder, $a_index, false);
         // 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 = rcube_imap_generic::sortHeaders($a_msg_headers, $this->sort_field, $this->sort_order);
         // only return the requested part of the set
         $slice_length = min($this->page_size, $cnt - ($to > $cnt ? $from : $to));
         $a_msg_headers = array_slice(array_values($a_msg_headers), $from, $slice_length);
         if ($slice) {
             $a_msg_headers = array_slice($a_msg_headers, -$slice, $slice);
         }
         return $a_msg_headers;
     }
 }
Beispiel #3
0
 /**
  * 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
         $this->_fetch_headers($mailbox, join(',', $msgs), $a_msg_headers, NULL);
         // I didn't found in RFC that FETCH always returns messages sorted by index
         $sorter = new rcube_header_sorter();
         $sorter->set_sequence_numbers($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
         $this->_fetch_headers($mailbox, join(',', $msgs), $a_msg_headers, NULL);
         $sorter = new rcube_header_sorter();
         $sorter->set_sequence_numbers($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
             $this->_fetch_headers($mailbox, join(',', $msgs), $a_msg_headers, NULL);
             // 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_sequence_numbers($msgs);
             $sorter->sort_headers($a_msg_headers);
             return array_values($a_msg_headers);
         } else {
             // for small result set we can fetch all messages headers
             $this->_fetch_headers($mailbox, join(',', $msgs), $a_msg_headers, NULL);
             // 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;
         }
     }
 }