thomascube
2010-03-02 7c9d922b96f9a88b350d6e07f5bde84ccc40f9b0
New recent check based on UIDs

3 files modified
87 ■■■■■ changed files
program/include/rcube_imap.php 37 ●●●● patch | view | raw | blame | history
program/lib/imap.inc 15 ●●●● patch | view | raw | blame | history
program/steps/mail/check_recent.inc 35 ●●●●● patch | view | raw | blame | history
program/include/rcube_imap.php
@@ -495,6 +495,9 @@
    if (!$force && is_array($a_mailbox_cache[$mailbox]) && isset($a_mailbox_cache[$mailbox][$mode]))
      return $a_mailbox_cache[$mailbox][$mode];
    if (!is_array($a_mailbox_cache[$mailbox]))
      $a_mailbox_cache[$mailbox] = array();
    // RECENT count is fetched a bit different
    if ($mode == 'RECENT')
       $count = iil_C_CheckForRecent($this->conn, $mailbox);
@@ -513,17 +516,15 @@
      $index = $this->_search_index($mailbox, $search_str);
      $count = is_array($index) ? count($index) : 0;
      }
    else
      {
    else {
      if ($mode == 'UNSEEN')
        $count = iil_C_CountUnseen($this->conn, $mailbox);
      else
      else {
        $count = iil_C_CountMessages($this->conn, $mailbox);
        $_SESSION['maxuid'][$mailbox] = $count ? $this->_id2uid($count) : 0;
      }
    }
    if (!is_array($a_mailbox_cache[$mailbox]))
      $a_mailbox_cache[$mailbox] = array();
    $a_mailbox_cache[$mailbox][$mode] = (int)$count;
    // write back to cache
@@ -863,7 +864,31 @@
    return count($a_msg_headers);
    }
  /**
   * Fetches IDS of pseudo recent messages.
   *
   * We compare the maximum UID to determine the number of
   * new messages because the RECENT flag is not reliable.
   *
   * @param string  Mailbox/folder name
   * @return array  List of recent message UIDs
   */
  function recent_uids($mbox_name = null, $nofetch = false)
  {
    $mailbox = $mbox_name ? $this->mod_mailbox($mbox_name) : $this->mailbox;
    $old_maxuid = intval($_SESSION['maxuid'][$mailbox]);
    
    // refresh message count -> will update $_SESSION['maxuid'][$mailbox]
    $this->messagecount($mbox_name, 'ALL', true);
    if ($_SESSION['maxuid'][$mailbox] > $old_maxuid) {
      $maxuid = max(1, $old_maxuid+1);
      return array_values((array)iil_C_FetchHeaderIndex($this->conn, $mailbox, "$maxuid:*", 'UID', $this->skip_deleted, true));
    }
    return array();
  }
  
  /**
   * Return sorted array of message IDs (not UIDs)
program/lib/imap.inc
@@ -915,7 +915,7 @@
    return preg_split('/\s+/', $data, -1, PREG_SPLIT_NO_EMPTY);
}
function iil_C_FetchHeaderIndex(&$conn, $mailbox, $message_set, $index_field='', $skip_deleted=true) {
function iil_C_FetchHeaderIndex(&$conn, $mailbox, $message_set, $index_field='', $skip_deleted=true, $uidfetch=false) {
    list($from_idx, $to_idx) = explode(':', $message_set);
    if (empty($message_set) ||
@@ -949,21 +949,22 @@
    
    // build FETCH command string
    $key     = 'fhi0';
    $cmd     = $uidfetch ? 'UID FETCH' : 'FETCH';
    $deleted = $skip_deleted ? ' FLAGS' : '';
    if ($mode == 1 && $index_field == 'DATE')
        $request = " FETCH $message_set (INTERNALDATE BODY.PEEK[HEADER.FIELDS (DATE)]$deleted)";
        $request = " $cmd $message_set (INTERNALDATE BODY.PEEK[HEADER.FIELDS (DATE)]$deleted)";
    else if ($mode == 1)
        $request = " FETCH $message_set (BODY.PEEK[HEADER.FIELDS ($index_field)]$deleted)";
        $request = " $cmd $message_set (BODY.PEEK[HEADER.FIELDS ($index_field)]$deleted)";
    else if ($mode == 2) {
        if ($index_field == 'SIZE')
            $request = " FETCH $message_set (RFC822.SIZE$deleted)";
            $request = " $cmd $message_set (RFC822.SIZE$deleted)";
        else
            $request = " FETCH $message_set ($index_field$deleted)";
            $request = " $cmd $message_set ($index_field$deleted)";
    } else if ($mode == 3)
        $request = " FETCH $message_set (FLAGS)";
        $request = " $cmd $message_set (FLAGS)";
    else // 4
        $request = " FETCH $message_set (INTERNALDATE$deleted)";
        $request = " $cmd $message_set (INTERNALDATE$deleted)";
    $request = $key . $request;
program/steps/mail/check_recent.inc
@@ -5,7 +5,7 @@
 | program/steps/mail/check_recent.inc                                   |
 |                                                                       |
 | This file is part of the RoundCube Webmail client                     |
 | Copyright (C) 2005-2009, RoundCube Dev. - Switzerland                 |
 | Copyright (C) 2005-2010, RoundCube Dev. - Switzerland                 |
 | Licensed under the GNU GPL                                            |
 |                                                                       |
 | PURPOSE:                                                              |
@@ -20,29 +20,19 @@
*/
$a_mailboxes = $IMAP->list_mailboxes();
$check_all = (bool)$RCMAIL->config->get('check_all_folders');
// check if unread count of INBOX changed and refresh message list if so
if (!empty($_GET['_refresh'])) {
  $unread_count = $IMAP->messagecount('INBOX', 'UNSEEN', TRUE);
  if ($unread_count > $_SESSION['unseen_count']['INBOX']) {
    $OUTPUT->command('set_unread_count', 'INBOX', $unread_count, true);
    $OUTPUT->command('list_mailbox', 'INBOX', 1);  // let the client switch to INBOX and get the message list
    $OUTPUT->send();
  }
}
$check_all = !empty($_GET['_refresh']) || (bool)$RCMAIL->config->get('check_all_folders');
// check recent/unseen counts for all mailboxes
foreach ($a_mailboxes as $mbox_name) {
  if ($mbox_name == $IMAP->get_mailbox_name()) {
    if ($recent_count = $IMAP->messagecount(NULL, 'RECENT', TRUE)) {
    if ($recents = $IMAP->recent_uids($mbox_name)) {
      // refresh saved search set
      if (($search_request = get_input_value('_search', RCUBE_INPUT_GPC)) && isset($_SESSION['search'][$search_request])) {
        $_SESSION['search'][$search_request] = $IMAP->refresh_search();
        $all_count = $IMAP->messagecount();
      } else {
        $all_count = $IMAP->messagecount(NULL, 'ALL', TRUE);
      }
      // get overall message count; allow caching because rcube_imap::recent_uids() did a refresh
      $all_count = $IMAP->messagecount();
      
      $unread_count = $IMAP->messagecount(NULL, 'UNSEEN', TRUE);
      $_SESSION['unseen_count'][$mbox_name] = $unread_count;
@@ -53,30 +43,27 @@
      $OUTPUT->command('set_unread_count', $mbox_name, $unread_count, ($mbox_name == 'INBOX'));
      $OUTPUT->command('set_rowcount', rcmail_get_messagecount_text($all_count));
      if (rcmail::get_instance()->config->get('focus_on_new_message',true))
      if ($RCMAIL->config->get('focus_on_new_message',true))
        $OUTPUT->command('new_message_focus');
      if (!empty($_GET['_quota']))
        $OUTPUT->command('set_quota', rcmail_quota_content());
      // trigger plugin hook
      $RCMAIL->plugins->exec_hook('new_messages', array('mailbox' => $mbox_name, 'count' => $unread_count));
      $RCMAIL->plugins->exec_hook('new_messages', array('mailbox' => $mbox_name, 'count' => count($recents)));
      // "No-list" mode, don't get messages
      if (empty($_GET['_list']))
        continue;
      // use SEARCH/SORT to find recent messages
      $search_str = 'RECENT';
      $search_str = 'UID '.min($recents).':'.max($recents);
      if ($search_request)
        $search_str .= ' '.$IMAP->search_string;
      $result = $IMAP->search($mbox_name, $search_str, NULL, 'date');
      if ($result) {
        // get the headers
      if ($IMAP->search($mbox_name, $search_str, NULL, 'date')) {
        // get the headers and add them to the list
        $result_h = $IMAP->list_headers($mbox_name, 1, 'date', 'DESC');
        // add to the list
        rcmail_js_message_list($result_h, true, false);
      }
    }