alecpl
2010-12-03 e232acbfde30e27101f84da7f0a617f8a8522512
- Improve performance of moving or copying of all messages in a folder (use CLOSE intead of EXPUNGE)
- Code cleanup + added more phpdoc comments


3 files modified
239 ■■■■■ changed files
CHANGELOG 2 ●●●●● patch | view | raw | blame | history
program/include/rcube_imap.php 13 ●●●●● patch | view | raw | blame | history
program/include/rcube_imap_generic.php 224 ●●●●● patch | view | raw | blame | history
CHANGELOG
@@ -12,6 +12,8 @@
- Fix invalid Request when creating a folder (#1487443)
- Add folder size and quota indicator in folder manager (#1485780)
- Add possibility to move a subfolder into root folder (#1486791)
- Fix copying all messages in a folder copies only messages from current page
- Improve performance of moving or copying of all messages in a folder
RELEASE 0.5-BETA
----------------
program/include/rcube_imap.php
@@ -185,7 +185,7 @@
     */
    function close()
    {
        $this->conn->close();
        $this->conn->closeConnection();
        $this->write_cache();
    }
@@ -198,7 +198,7 @@
     */
    function reconnect()
    {
        $this->close();
        $this->closeConnection();
        $this->connect($this->host, $this->user, $this->pass, $this->port, $this->ssl);
        // issue SELECT command to restore connection status
@@ -617,7 +617,7 @@
        }
        // RECENT count is fetched a bit different
        else if ($mode == 'RECENT') {
            $count = $this->conn->checkForRecent($mailbox);
            $count = $this->conn->countRecent($mailbox);
        }
        // use SEARCH for message counting
        else if ($this->skip_deleted) {
@@ -2582,6 +2582,7 @@
        // send expunge command in order to have the moved message
        // really deleted from the source mailbox
$aa = rcube_timer();
        if ($moved) {
            $this->_expunge($from_mbox, false, $uids);
            $this->_clear_messagecount($from_mbox);
@@ -2591,7 +2592,7 @@
        else if ($config->get('delete_always', false) && $tbox == $config->get('trash_mbox')) {
            $moved = $this->delete_message($uids, $fbox);
        }
rcube_print_time($aa);
        if ($moved) {
            // unset threads internal cache
            unset($this->icache['threads']);
@@ -2774,6 +2775,10 @@
        else
            $a_uids = NULL;
        // CLOSE(+SELECT) should be faster than EXPUNGE
        if (empty($a_uids) || $a_uids == '1:*')
            $result = $this->conn->close();
        else
        $result = $this->conn->expunge($mailbox, $a_uids);
        if ($result && $clear_cache) {
program/include/rcube_imap_generic.php
@@ -683,7 +683,7 @@
                $error = sprintf("Empty startup greeting (%s:%d)", $host, $this->prefs['port']);
            $this->setError(self::ERROR_BAD, $error);
            $this->close();
            $this->closeConnection();
            return false;
        }
@@ -700,13 +700,13 @@
                   $res = $this->execute('STARTTLS');
                if ($res[0] != self::ERROR_OK) {
                    $this->close();
                    $this->closeConnection();
                    return false;
                }
                if (!stream_socket_enable_crypto($this->fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
                    $this->setError(self::ERROR_BAD, "Unable to negotiate TLS");
                    $this->close();
                    $this->closeConnection();
                    return false;
                }
@@ -738,7 +738,7 @@
            // Prevent from sending credentials in plain text when connection is not secure
            if ($auth_method == 'LOGIN' && $this->getCapability('LOGINDISABLED')) {
                $this->setError(self::ERROR_BAD, "Login disabled by IMAP server");
                $this->close();
                $this->closeConnection();
                return false;
            }
            // replace AUTH with CRAM-MD5 for backward compat.
@@ -778,8 +778,7 @@
            return true;
        }
        // Close connection
        $this->close();
        $this->closeConnection();
        return false;
    }
@@ -789,7 +788,7 @@
        return ($this->fp && $this->logged) ? true : false;
    }
    function close()
    function closeConnection()
    {
        if ($this->putLine($this->nextTag() . ' LOGOUT')) {
            $this->readReply();
@@ -799,6 +798,14 @@
        $this->fp = false;
    }
    /**
     * Executes SELECT command (if mailbox is already not in selected state)
     *
     * @param string $mailbox Mailbox name
     *
     * @return boolean True on success, false on error
     * @access public
     */
    function select($mailbox)
    {
        if (!strlen($mailbox)) {
@@ -842,7 +849,7 @@
    }
    /**
     * Executes STATUS comand
     * Executes STATUS command
     *
     * @param string $mailbox Mailbox name
     * @param array  $items   Additional requested item names. By default
@@ -887,21 +894,133 @@
        return false;
    }
    function checkForRecent($mailbox)
    /**
     * Executes EXPUNGE command
     *
     * @param string $mailbox  Mailbox name
     * @param string $messages Message UIDs to expunge
     *
     * @return boolean True on success, False on error
     * @access public
     */
    function expunge($mailbox, $messages=NULL)
    {
        if (!strlen($mailbox)) {
            $mailbox = 'INBOX';
        if (!$this->select($mailbox)) {
            return false;
        }
        $this->select($mailbox);
        // Clear internal status cache
        unset($this->data['STATUS:'.$mailbox]);
        if ($this->selected == $mailbox) {
            return $this->data['RECENT'];
        if ($messages)
            $result = $this->execute('UID EXPUNGE', array($messages), self::COMMAND_NORESPONSE);
        else
            $result = $this->execute('EXPUNGE', null, self::COMMAND_NORESPONSE);
        if ($result == self::ERROR_OK) {
            $this->selected = ''; // state has changed, need to reselect
            return true;
        }
        return false;
    }
    /**
     * Executes CLOSE command
     *
     * @return boolean True on success, False on error
     * @access public
     * @since 0.5
     */
    function close()
    {
        $result = $this->execute('CLOSE', NULL, self::COMMAND_NORESPONSE);
        if ($result == self::ERROR_OK) {
            $this->selected = '';
            return true;
        }
        return false;
    }
    /**
     * Executes SUBSCRIBE command
     *
     * @param string $mailbox Mailbox name
     *
     * @return boolean True on success, False on error
     * @access public
     */
    function subscribe($mailbox)
    {
        $result = $this->execute('SUBSCRIBE', array($this->escape($mailbox)),
            self::COMMAND_NORESPONSE);
        return ($result == self::ERROR_OK);
    }
    /**
     * Executes UNSUBSCRIBE command
     *
     * @param string $mailbox Mailbox name
     *
     * @return boolean True on success, False on error
     * @access public
     */
    function unsubscribe($mailbox)
    {
        $result = $this->execute('UNSUBSCRIBE', array($this->escape($mailbox)),
            self::COMMAND_NORESPONSE);
        return ($result == self::ERROR_OK);
    }
    /**
     * Executes DELETE command
     *
     * @param string $mailbox Mailbox name
     *
     * @return boolean True on success, False on error
     * @access public
     */
    function deleteFolder($mailbox)
    {
        $result = $this->execute('DELETE', array($this->escape($mailbox)),
            self::COMMAND_NORESPONSE);
        return ($result == self::ERROR_OK);
    }
    /**
     * Removes all messages in a folder
     *
     * @param string $mailbox Mailbox name
     *
     * @return boolean True on success, False on error
     * @access public
     */
    function clearFolder($mailbox)
    {
        $num_in_trash = $this->countMessages($mailbox);
        if ($num_in_trash > 0) {
            $this->delete($mailbox, '1:*');
        }
        $res = $this->close();
//        $res = $this->expunge($mailbox);
        return $res;
    }
    /**
     * Returns count of all messages in a folder
     *
     * @param string $mailbox Mailbox name
     *
     * @return int Number of messages, False on error
     * @access public
     */
    function countMessages($mailbox, $refresh = false)
    {
        if ($refresh) {
@@ -922,6 +1041,29 @@
        $counts = $this->status($mailbox);
        if (is_array($counts)) {
            return (int) $counts['MESSAGES'];
        }
        return false;
    }
    /**
     * Returns count of messages with \Recent flag in a folder
     *
     * @param string $mailbox Mailbox name
     *
     * @return int Number of messages, False on error
     * @access public
     */
    function countRecent($mailbox)
    {
        if (!strlen($mailbox)) {
            $mailbox = 'INBOX';
        }
        $this->select($mailbox);
        if ($this->selected == $mailbox) {
            return $this->data['RECENT'];
        }
        return false;
@@ -1565,27 +1707,6 @@
        return $result;
    }
    function expunge($mailbox, $messages=NULL)
    {
        if (!$this->select($mailbox)) {
            return false;
        }
        // Clear internal status cache
        unset($this->data['STATUS:'.$mailbox]);
        if ($messages)
            $result = $this->execute('UID EXPUNGE', array($messages), self::COMMAND_NORESPONSE);
        else
            $result = $this->execute('EXPUNGE', null, self::COMMAND_NORESPONSE);
        if ($result == self::ERROR_OK) {
            $this->selected = ''; // state has changed, need to reselect
            return true;
        }
        return false;
    }
    function modFlag($mailbox, $messages, $flag, $mod)
    {
@@ -2148,39 +2269,6 @@
    function renameFolder($from, $to)
    {
        $result = $this->execute('RENAME', array($this->escape($from), $this->escape($to)),
            self::COMMAND_NORESPONSE);
        return ($result == self::ERROR_OK);
    }
    function deleteFolder($mailbox)
    {
        $result = $this->execute('DELETE', array($this->escape($mailbox)),
            self::COMMAND_NORESPONSE);
        return ($result == self::ERROR_OK);
    }
    function clearFolder($mailbox)
    {
        $num_in_trash = $this->countMessages($mailbox);
        if ($num_in_trash > 0) {
            $this->delete($mailbox, '1:*');
        }
        return ($this->expunge($mailbox) >= 0);
    }
    function subscribe($mailbox)
    {
        $result = $this->execute('SUBSCRIBE', array($this->escape($mailbox)),
            self::COMMAND_NORESPONSE);
        return ($result == self::ERROR_OK);
    }
    function unsubscribe($mailbox)
    {
        $result = $this->execute('UNSUBSCRIBE', array($this->escape($mailbox)),
            self::COMMAND_NORESPONSE);
        return ($result == self::ERROR_OK);