Example #1
0
 /**
  * Protected method for getting number of messages
  *
  * @param string  $folder    Folder name
  * @param string  $mode      Mode for count [ALL|THREADS|UNSEEN|RECENT|EXISTS]
  * @param boolean $force     Force reading from server and update cache
  * @param boolean $status    Enables storing folder status info (max UID/count),
  *                           required for folder_status()
  * @param boolean $no_search Ignore current search result
  *
  * @return int Number of messages
  * @see rcube_imap::count()
  */
 protected function countmessages($folder, $mode = 'ALL', $force = false, $status = true, $no_search = false)
 {
     $mode = strtoupper($mode);
     // Count search set, assume search set is always up-to-date (don't check $force flag)
     // @TODO: this could be handled in more reliable way, e.g. a separate method
     //        maybe in rcube_imap_search
     if (!$no_search && $this->search_string && $folder == $this->folder) {
         if ($mode == 'ALL') {
             return $this->search_set->count_messages();
         } else {
             if ($mode == 'THREADS') {
                 return $this->search_set->count();
             }
         }
     }
     // EXISTS is a special alias for ALL, it allows to get the number
     // of all messages in a folder also when search is active and with
     // any skip_deleted setting
     $a_folder_cache = $this->get_cache('messagecount');
     // return cached value
     if (!$force && is_array($a_folder_cache[$folder]) && isset($a_folder_cache[$folder][$mode])) {
         return $a_folder_cache[$folder][$mode];
     }
     if (!is_array($a_folder_cache[$folder])) {
         $a_folder_cache[$folder] = array();
     }
     if ($mode == 'THREADS') {
         $res = $this->threads($folder);
         $count = $res->count();
         if ($status) {
             $msg_count = $res->count_messages();
             $this->set_folder_stats($folder, 'cnt', $msg_count);
             $this->set_folder_stats($folder, 'maxuid', $msg_count ? $this->id2uid($msg_count, $folder) : 0);
         }
     } else {
         if (!$this->check_connection()) {
             return 0;
         } else {
             if ($mode == 'RECENT') {
                 $count = $this->conn->countRecent($folder);
             } else {
                 if ($mode != 'EXISTS' && !empty($this->options['skip_deleted'])) {
                     $search_str = "ALL UNDELETED";
                     $keys = array('COUNT');
                     if ($mode == 'UNSEEN') {
                         $search_str .= " UNSEEN";
                     } else {
                         if ($this->messages_caching) {
                             $keys[] = 'ALL';
                         }
                         if ($status) {
                             $keys[] = 'MAX';
                         }
                     }
                     // @TODO: if $mode == 'ALL' we could try to use cache index here
                     // get message count using (E)SEARCH
                     // not very performant but more precise (using UNDELETED)
                     $index = $this->conn->search($folder, $search_str, true, $keys);
                     $count = $index->count();
                     if ($mode == 'ALL') {
                         // Cache index data, will be used in index_direct()
                         $this->icache['undeleted_idx'] = $index;
                         if ($status) {
                             $this->set_folder_stats($folder, 'cnt', $count);
                             $this->set_folder_stats($folder, 'maxuid', $index->max());
                         }
                     }
                 } else {
                     if ($mode == 'UNSEEN') {
                         $count = $this->conn->countUnseen($folder);
                     } else {
                         $count = $this->conn->countMessages($folder);
                         if ($status && $mode == 'ALL') {
                             $this->set_folder_stats($folder, 'cnt', $count);
                             $this->set_folder_stats($folder, 'maxuid', $count ? $this->id2uid($count, $folder) : 0);
                         }
                     }
                 }
             }
         }
     }
     $a_folder_cache[$folder][$mode] = (int) $count;
     // write back to cache
     $this->update_cache('messagecount', $a_folder_cache);
     return (int) $count;
 }
Example #2
0
 /**
  * Private method for listing message headers
  *
  * @param   string   $mailbox    Mailbox 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_headers
  */
 private function _list_headers($mailbox = '', $page = NULL, $sort_field = NULL, $sort_order = NULL, $recursive = false, $slice = 0)
 {
     if (!strlen($mailbox)) {
         return array();
     }
     // use saved message set
     if ($this->search_string && $mailbox == $this->mailbox) {
         return $this->_list_header_set($mailbox, $page, $sort_field, $sort_order, $slice);
     }
     if ($this->threading) {
         return $this->_list_thread_headers($mailbox, $page, $sort_field, $sort_order, $recursive, $slice);
     }
     $this->_set_sort_order($sort_field, $sort_order);
     $page = $page ? $page : $this->list_page;
     $cache_key = $mailbox . '.msg';
     if ($this->caching_enabled) {
         // cache is OK, we can get messages from local cache
         // (assume cache is in sync when in recursive mode)
         if ($recursive || $this->check_cache_status($mailbox, $cache_key) > 0) {
             $start_msg = ($page - 1) * $this->page_size;
             $a_msg_headers = $this->get_message_cache($cache_key, $start_msg, $start_msg + $this->page_size, $this->sort_field, $this->sort_order);
             $result = array_values($a_msg_headers);
             if ($slice) {
                 $result = array_slice($result, -$slice, $slice);
             }
             return $result;
         } else {
             if (!$recursive) {
                 $this->sync_header_index($mailbox);
                 return $this->_list_headers($mailbox, $page, $this->sort_field, $this->sort_order, true, $slice);
             }
         }
     }
     // retrieve headers from IMAP
     $a_msg_headers = array();
     // use message index sort as default sorting (for better performance)
     if (!$this->sort_field) {
         if ($this->skip_deleted) {
             // @TODO: this could be cached
             if ($msg_index = $this->_search_index($mailbox, 'ALL UNDELETED')) {
                 $max = max($msg_index);
                 list($begin, $end) = $this->_get_message_range(count($msg_index), $page);
                 $msg_index = array_slice($msg_index, $begin, $end - $begin);
             }
         } else {
             if ($max = $this->conn->countMessages($mailbox)) {
                 list($begin, $end) = $this->_get_message_range($max, $page);
                 $msg_index = range($begin + 1, $end);
             } else {
                 $msg_index = array();
             }
         }
         if ($slice && $msg_index) {
             $msg_index = array_slice($msg_index, $this->sort_order == 'DESC' ? 0 : -$slice, $slice);
         }
         // fetch reqested headers from server
         if ($msg_index) {
             $this->_fetch_headers($mailbox, join(",", $msg_index), $a_msg_headers, $cache_key);
         }
     } else {
         if ($this->get_capability('SORT') && ($msg_index = $this->conn->sort($mailbox, $this->sort_field, $this->skip_deleted ? 'UNDELETED' : '')) !== false) {
             if (!empty($msg_index)) {
                 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);
                 }
                 // fetch reqested headers from server
                 $this->_fetch_headers($mailbox, join(',', $msg_index), $a_msg_headers, $cache_key);
             }
         } else {
             if ($a_index = $this->conn->fetchHeaderIndex($mailbox, "1:*", $this->sort_field, $this->skip_deleted)) {
                 asort($a_index);
                 // ASC
                 $msg_index = array_keys($a_index);
                 $max = max($msg_index);
                 list($begin, $end) = $this->_get_message_range(count($msg_index), $page);
                 $msg_index = array_slice($msg_index, $begin, $end - $begin);
                 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);
             }
         }
     }
     // delete cached messages with a higher index than $max+1
     // Changed $max to $max+1 to fix this bug : #1484295
     $this->clear_message_cache($cache_key, $max + 1);
     // kick child process to sync cache
     // ...
     // return empty array if no messages found
     if (!is_array($a_msg_headers) || empty($a_msg_headers)) {
         return array();
     }
     // use this class for message sorting
     $sorter = new rcube_header_sorter();
     $sorter->set_sequence_numbers($msg_index);
     $sorter->sort_headers($a_msg_headers);
     if ($this->sort_order == 'DESC') {
         $a_msg_headers = array_reverse($a_msg_headers);
     }
     return array_values($a_msg_headers);
 }
 /**
  * protected method for getting nr of messages
  *
  * @param string  $folder  Folder name
  * @param string  $mode    Mode for count [ALL|THREADS|UNSEEN|RECENT]
  * @param boolean $force   Force reading from server and update cache
  * @param boolean $status  Enables storing folder status info (max UID/count),
  *                         required for folder_status()
  *
  * @return int Number of messages
  * @see rcube_imap::count()
  */
 protected function countmessages($folder, $mode = 'ALL', $force = false, $status = true)
 {
     $mode = strtoupper($mode);
     // count search set, assume search set is always up-to-date (don't check $force flag)
     if ($this->search_string && $folder == $this->folder && ($mode == 'ALL' || $mode == 'THREADS')) {
         if ($mode == 'ALL') {
             return $this->search_set->count_messages();
         } else {
             return $this->search_set->count();
         }
     }
     $a_folder_cache = $this->get_cache('messagecount');
     // return cached value
     if (!$force && is_array($a_folder_cache[$folder]) && isset($a_folder_cache[$folder][$mode])) {
         return $a_folder_cache[$folder][$mode];
     }
     if (!is_array($a_folder_cache[$folder])) {
         $a_folder_cache[$folder] = array();
     }
     if ($mode == 'THREADS') {
         $res = $this->fetch_threads($folder, $force);
         $count = $res->count();
         if ($status) {
             $msg_count = $res->count_messages();
             $this->set_folder_stats($folder, 'cnt', $msg_count);
             $this->set_folder_stats($folder, 'maxuid', $msg_count ? $this->id2uid($msg_count, $folder) : 0);
         }
     } else {
         if (!$this->check_connection()) {
             return 0;
         } else {
             if ($mode == 'RECENT') {
                 $count = $this->conn->countRecent($folder);
             } else {
                 if (!empty($this->options['skip_deleted'])) {
                     $search_str = "ALL UNDELETED";
                     $keys = array('COUNT');
                     if ($mode == 'UNSEEN') {
                         $search_str .= " UNSEEN";
                     } else {
                         if ($this->messages_caching) {
                             $keys[] = 'ALL';
                         }
                         if ($status) {
                             $keys[] = 'MAX';
                         }
                     }
                     // @TODO: if $force==false && $mode == 'ALL' we could try to use cache index here
                     // get message count using (E)SEARCH
                     // not very performant but more precise (using UNDELETED)
                     $index = $this->conn->search($folder, $search_str, true, $keys);
                     $count = $index->count();
                     if ($mode == 'ALL') {
                         // Cache index data, will be used in index_direct()
                         $this->icache['undeleted_idx'] = $index;
                         if ($status) {
                             $this->set_folder_stats($folder, 'cnt', $count);
                             $this->set_folder_stats($folder, 'maxuid', $index->max());
                         }
                     }
                 } else {
                     if ($mode == 'UNSEEN') {
                         $count = $this->conn->countUnseen($folder);
                     } else {
                         $count = $this->conn->countMessages($folder);
                         if ($status) {
                             $this->set_folder_stats($folder, 'cnt', $count);
                             $this->set_folder_stats($folder, 'maxuid', $count ? $this->id2uid($count, $folder) : 0);
                         }
                     }
                 }
             }
         }
     }
     $a_folder_cache[$folder][$mode] = (int) $count;
     // write back to cache
     $this->update_cache('messagecount', $a_folder_cache);
     return (int) $count;
 }
Example #4
0
 /**
  * Private method for listing message headers
  *
  * @param   string   $mailbox    Mailbox 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
  * @see     rcube_imap::list_headers
  */
 private function _list_headers($mailbox = '', $page = NULL, $sort_field = NULL, $sort_order = NULL, $slice = 0)
 {
     if (!strlen($mailbox)) {
         return array();
     }
     // use saved message set
     if ($this->search_string && $mailbox == $this->mailbox) {
         return $this->_list_header_set($mailbox, $page, $sort_field, $sort_order, $slice);
     }
     if ($this->threading) {
         return $this->_list_thread_headers($mailbox, $page, $sort_field, $sort_order, $slice);
     }
     $this->_set_sort_order($sort_field, $sort_order);
     $page = $page ? $page : $this->list_page;
     // Use messages cache
     if ($mcache = $this->get_mcache_engine()) {
         $msg_index = $mcache->get_index($mailbox, $this->sort_field, $this->sort_order);
         if (empty($msg_index)) {
             return array();
         }
         $from = ($page - 1) * $this->page_size;
         $to = $from + $this->page_size;
         $msg_index = array_values($msg_index);
         // UIDs
         $is_uid = true;
         $sorted = true;
         if ($from || $to) {
             $msg_index = array_slice($msg_index, $from, $to - $from);
         }
         if ($slice) {
             $msg_index = array_slice($msg_index, -$slice, $slice);
         }
         $a_msg_headers = $mcache->get_messages($mailbox, $msg_index);
     } else {
         if (!$this->sort_field) {
             if ($this->skip_deleted) {
                 // @TODO: this could be cached
                 if ($msg_index = $this->_search_index($mailbox, 'ALL UNDELETED')) {
                     list($begin, $end) = $this->_get_message_range(count($msg_index), $page);
                     $msg_index = array_slice($msg_index, $begin, $end - $begin);
                 }
             } else {
                 if ($max = $this->conn->countMessages($mailbox)) {
                     list($begin, $end) = $this->_get_message_range($max, $page);
                     $msg_index = range($begin + 1, $end);
                 } else {
                     $msg_index = array();
                 }
             }
             if ($slice && $msg_index) {
                 $msg_index = array_slice($msg_index, $this->sort_order == 'DESC' ? 0 : -$slice, $slice);
             }
             // fetch reqested headers from server
             if ($msg_index) {
                 $a_msg_headers = $this->fetch_headers($mailbox, $msg_index);
             }
         } else {
             if ($this->get_capability('SORT') && ($msg_index = $this->conn->sort($mailbox, $this->sort_field, $this->skip_deleted ? 'UNDELETED' : '', true)) !== false) {
                 if (!empty($msg_index)) {
                     list($begin, $end) = $this->_get_message_range(count($msg_index), $page);
                     $msg_index = array_slice($msg_index, $begin, $end - $begin);
                     $is_uid = true;
                     if ($slice) {
                         $msg_index = array_slice($msg_index, $this->sort_order == 'DESC' ? 0 : -$slice, $slice);
                     }
                     // fetch reqested headers from server
                     $a_msg_headers = $this->fetch_headers($mailbox, $msg_index, true);
                 }
             } else {
                 if ($msg_index = $this->conn->fetchHeaderIndex($mailbox, "1:*", $this->sort_field, $this->skip_deleted)) {
                     asort($msg_index);
                     // ASC
                     $msg_index = array_keys($msg_index);
                     list($begin, $end) = $this->_get_message_range(count($msg_index), $page);
                     $msg_index = array_slice($msg_index, $begin, $end - $begin);
                     if ($slice) {
                         $msg_index = array_slice($msg_index, $this->sort_order == 'DESC' ? 0 : -$slice, $slice);
                     }
                     // fetch reqested headers from server
                     $a_msg_headers = $this->fetch_headers($mailbox, $msg_index);
                 }
             }
         }
     }
     // return empty array if no messages found
     if (!is_array($a_msg_headers) || empty($a_msg_headers)) {
         return array();
     }
     // use this class for message sorting
     $sorter = new rcube_header_sorter();
     $sorter->set_index($msg_index, $is_uid);
     $sorter->sort_headers($a_msg_headers);
     if ($this->sort_order == 'DESC' && !$sorted) {
         $a_msg_headers = array_reverse($a_msg_headers);
     }
     return array_values($a_msg_headers);
 }