alecpl
2010-10-29 c309cd8928af861637996f5c5490a2db0dc626dc
- Improve performance of setting IMAP flags using .SILENT suffix


4 files modified
106 ■■■■ changed files
CHANGELOG 1 ●●●● patch | view | raw | blame | history
program/include/rcube_imap.php 30 ●●●●● patch | view | raw | blame | history
program/include/rcube_imap_generic.php 71 ●●●●● patch | view | raw | blame | history
program/steps/mail/mark.inc 4 ●●●● patch | view | raw | blame | history
CHANGELOG
@@ -56,6 +56,7 @@
- Add SORT=DISPLAY support (RFC 5957)
- Plugin API: add possibility to disable plugin in AJAX mode, 'noajax' property
- Plugin API: add possibility to disable plugin in framed mode, 'noframe' property
- Improve performance of setting IMAP flags using .SILENT suffix
RELEASE 0.4.2
-------------
program/include/rcube_imap.php
@@ -2353,7 +2353,7 @@
     * @param string  $flag       Flag to set: SEEN, UNDELETED, DELETED, RECENT, ANSWERED, DRAFT, MDNSENT
     * @param string  $mbox_name  Folder name
     * @param boolean $skip_cache True to skip message cache clean up
     * @return int    Number of flagged messages, -1 on failure
     * @return boolean  Operation status
     */
    function set_flag($uids, $flag, $mbox_name=NULL, $skip_cache=false)
    {
@@ -2367,7 +2367,7 @@
        else
            $result = $this->conn->flag($mailbox, $uids, $flag);
        if ($result >= 0) {
        if ($result) {
            // reload message headers if cached
            if ($this->caching_enabled && !$skip_cache) {
                $cache_key = $mailbox.'.msg';
@@ -2376,13 +2376,15 @@
                else
                    $this->remove_message_cache($cache_key, explode(',', $uids));
            }
            // update counters
            if ($flag=='SEEN')
                $this->_set_messagecount($mailbox, 'UNSEEN', $result*(-1));
            else if ($flag=='UNSEEN')
                $this->_set_messagecount($mailbox, 'UNSEEN', $result);
            else if ($flag=='DELETED')
                $this->_set_messagecount($mailbox, 'ALL', $result*(-1));
            // clear cached counters
            if ($flag == 'SEEN' || $flag == 'UNSEEN') {
                $this->_clear_messagecount($mailbox, 'SEEN');
                $this->_clear_messagecount($mailbox, 'UNSEEN');
            }
            else if ($flag == 'DELETED') {
                $this->_clear_messagecount($mailbox, 'DELETED');
            }
        }
        return $result;
@@ -4425,15 +4427,19 @@
     * Remove messagecount of a specific mailbox from cache
     * @access private
     */
    private function _clear_messagecount($mbox_name='')
    private function _clear_messagecount($mbox_name='', $mode=null)
    {
        $a_mailbox_cache = false;
        $mailbox = $mbox_name ? $mbox_name : $this->mailbox;
        $a_mailbox_cache = $this->get_cache('messagecount');
        if (is_array($a_mailbox_cache[$mailbox])) {
            unset($a_mailbox_cache[$mailbox]);
            if ($mode) {
                unset($a_mailbox_cache[$mailbox][$mode]);
            }
            else {
                unset($a_mailbox_cache[$mailbox]);
            }
            $this->update_cache('messagecount', $a_mailbox_cache);
        }
    }
program/include/rcube_imap_generic.php
@@ -1007,11 +1007,6 @@
            return false;
        }
        // RFC 5957: SORT=DISPLAY
        if (($field == 'FROM' || $field == 'TO') && $this->getCapability('SORT=DISPLAY')) {
            $field = 'DISPLAY' . $field;
        }
        // message IDs
        if (is_array($add))
            $add = $this->compressMessageSet(join(',', $add));
@@ -1155,29 +1150,32 @@
        return $result;
    }
    private function compressMessageSet($message_set, $force=false)
    private function compressMessageSet($messages, $force=false)
    {
        // given a comma delimited list of independent mid's,
        // compresses by grouping sequences together
        // if less than 255 bytes long, let's not bother
        if (!$force && strlen($message_set)<255) {
            return $message_set;
        }
        if (!is_array($message_set)) {
            // if less than 255 bytes long, let's not bother
            if (!$force && strlen($messages)<255) {
                return $messages;
            }
        // see if it's already been compressed
        if (strpos($message_set, ':') !== false) {
            return $message_set;
        }
            // see if it's already been compressed
            if (strpos($messages, ':') !== false) {
                return $messages;
            }
        // separate, then sort
        $ids = explode(',', $message_set);
        sort($ids);
            // separate, then sort
            $messages = explode(',', $messages);
        }
        sort($messages);
        $result = array();
        $start  = $prev = $ids[0];
        $start  = $prev = $messages[0];
        foreach ($ids as $id) {
        foreach ($messages as $id) {
            $incr = $id - $prev;
            if ($incr > 1) {            //found a gap
                if ($start == $prev) {
@@ -1191,7 +1189,7 @@
        }
        // handle the last sequence/id
        if ($start==$prev) {
        if ($start == $prev) {
            $result[] = $prev;
        } else {
            $result[] = $start.':'.$prev;
@@ -1587,35 +1585,19 @@
    function modFlag($mailbox, $messages, $flag, $mod)
    {
        if ($mod != '+' && $mod != '-') {
            return -1;
            $mod = '+';
        }
        $flag = $this->flags[strtoupper($flag)];
        if (!$this->select($mailbox)) {
            return -1;
            return false;
        }
        $c = 0;
        $key = $this->next_tag();
        $command = "$key UID STORE $messages {$mod}FLAGS ($flag)";
        if (!$this->putLine($command)) {
            $this->set_error(self::ERROR_COMMAND, "Unable to send command: $command");
            return -1;
        }
        $flag   = $this->flags[strtoupper($flag)];
        $result = $this->execute('UID STORE', array(
            $this->compressMessageSet($messages), $mod . 'FLAGS.SILENT', "($flag)"),
            self::COMMAND_NORESPONSE);
        do {
            $line = $this->readLine();
            if ($line[0] == '*') {
                $c++;
            }
        } while (!$this->startsWith($line, $key, true, true));
        if ($this->parseResult($line, 'STORE: ') == self::ERROR_OK) {
            return $c;
        }
        return -1;
        return ($result == self::ERROR_OK);
    }
    function flag($mailbox, $messages, $flag) {
@@ -1640,7 +1622,8 @@
            return -1;
        }
        $result = $this->execute('UID COPY', array($messages, $this->escape($to)),
        $result = $this->execute('UID COPY', array(
            $this->compressMessageSet($messages), $this->escape($to)),
            self::COMMAND_NORESPONSE);
        return $result;
program/steps/mail/mark.inc
@@ -43,7 +43,7 @@
  $marked = $IMAP->set_flag($uids, $flag);
  if ($marked == -1) {
  if (!$marked) {
    // send error message
    if ($_POST['_from'] != 'show')
      $OUTPUT->command('list_mailbox');
@@ -56,7 +56,7 @@
    $ruids = get_input_value('_ruid', RCUBE_INPUT_POST);
    $read = $IMAP->set_flag($ruids, 'SEEN');
    if ($read != -1 && !$CONFIG['skip_deleted'])
    if ($read && !$CONFIG['skip_deleted'])
      $OUTPUT->command('flag_deleted_as_read', $ruids);
  }