alecpl
2010-12-06 0e11940a65777b8dd22d017da472c2dc373d650c
- Improve performance of folder rename and delete actions. Don't get list of all folders when we need only children of the specified folder.


3 files modified
111 ■■■■ changed files
CHANGELOG 1 ●●●● patch | view | raw | blame | history
program/include/rcube_imap.php 94 ●●●● patch | view | raw | blame | history
program/steps/settings/folders.inc 16 ●●●●● patch | view | raw | blame | history
CHANGELOG
@@ -15,6 +15,7 @@
- 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
- Fix plaintext versions of HTML messages don't contain placeholders for emotions (#1485206)
- Improve performance of folder rename and delete actions
RELEASE 0.5-BETA
----------------
program/include/rcube_imap.php
@@ -3018,7 +3018,7 @@
    /**
     * Get mailbox size (size of all messages in a mailbox)
     *
     * @param string $name Mailbox name
     * @param string $name Mailbox name
     * @return int Mailbox size in bytes, False on error
     */
    function get_mailbox_size($name)
@@ -3093,6 +3093,7 @@
     *
     * @param string $mbox_name Mailbox to rename
     * @param string $new_name  New mailbox name
     *
     * @return boolean True on success
     */
    function rename_mailbox($mbox_name, $new_name)
@@ -3102,92 +3103,87 @@
        // make absolute path
        $mailbox  = $this->mod_mailbox($mbox_name);
        $abs_name = $this->mod_mailbox($new_name);
        $delm     = $this->get_hierarchy_delimiter();
        // check if mailbox is subscribed
        $a_subscribed = $this->_list_mailboxes();
        $subscribed   = in_array($mailbox, $a_subscribed);
        // unsubscribe folder
        if ($subscribed)
            $this->conn->unsubscribe($mailbox);
        // get list of subscribed folders
        if ((strpos($mailbox, '%') === false) && (strpos($mailbox, '*') === false)) {
            $a_subscribed = $this->_list_mailboxes('', $mbox_name . $delm . '*');
            $subscribed   = $this->mailbox_exists($mbox_name, true);
        }
        else {
            $a_subscribed = $this->_list_mailboxes();
            $subscribed   = in_array($mailbox, $a_subscribed);
        }
        if (strlen($abs_name))
            $result = $this->conn->renameFolder($mailbox, $abs_name);
        if ($result) {
            $delm = $this->get_hierarchy_delimiter();
            // unsubscribe the old folder, subscribe the new one
            if ($subscribed) {
                $this->conn->unsubscribe($mailbox);
                $this->conn->subscribe($abs_name);
            }
            // check if mailbox children are subscribed
            foreach ($a_subscribed as $c_subscribed)
            foreach ($a_subscribed as $c_subscribed) {
                if (preg_match('/^'.preg_quote($mailbox.$delm, '/').'/', $c_subscribed)) {
                    $this->conn->unsubscribe($c_subscribed);
                    $this->conn->subscribe(preg_replace('/^'.preg_quote($mailbox, '/').'/',
                        $abs_name, $c_subscribed));
                }
            }
            // clear cache
            $this->clear_message_cache($mailbox.'.msg');
            $this->clear_cache('mailboxes');
        }
        // try to subscribe it
        if ($result && $subscribed)
            $this->conn->subscribe($abs_name);
        return $result;
    }
    /**
     * Remove mailboxes from server
     * Remove mailbox from server
     *
     * @param string|array $mbox_name Mailbox name(s) string/array
     * @param string $mbox_name Mailbox name
     *
     * @return boolean True on success
     */
    function delete_mailbox($mbox_name)
    {
        $deleted = false;
        $result  = false;
        $mailbox = $this->mod_mailbox($mbox_name);
        $delm    = $this->get_hierarchy_delimiter();
        if (is_array($mbox_name))
            $a_mboxes = $mbox_name;
        else if (is_string($mbox_name) && strlen($mbox_name))
            $a_mboxes = explode(',', $mbox_name);
        // get list of folders
        if ((strpos($mailbox, '%') === false) && (strpos($mailbox, '*') === false))
            $sub_mboxes = $this->list_unsubscribed('', $mailbox . $delm . '*');
        else
            $sub_mboxes = $this->list_unsubscribed();
        if (is_array($a_mboxes)) {
            $delimiter = $this->get_hierarchy_delimiter();
            foreach ($a_mboxes as $mbox_name) {
                $mailbox = $this->mod_mailbox($mbox_name);
                $sub_mboxes = $this->conn->listMailboxes('', $mbox_name . $delimiter . '*');
        // send delete command to server
        $result = $this->conn->deleteFolder($mailbox);
                // unsubscribe mailbox before deleting
                $this->conn->unsubscribe($mailbox);
        if ($result) {
            // unsubscribe mailbox
            $this->conn->unsubscribe($mailbox);
                // send delete command to server
                $result = $this->conn->deleteFolder($mailbox);
                if ($result) {
                    $deleted = true;
                    $this->clear_message_cache($mailbox.'.msg');
                }
                foreach ($sub_mboxes as $c_mbox) {
                    if ($c_mbox != 'INBOX') {
                        $this->conn->unsubscribe($c_mbox);
                        $result = $this->conn->deleteFolder($c_mbox);
                        if ($result) {
                            $deleted = true;
                            $this->clear_message_cache($c_mbox.'.msg');
                        }
            foreach ($sub_mboxes as $c_mbox) {
                if (preg_match('/^'.preg_quote($mailbox.$delm, '/').'/', $c_mbox)) {
                    $this->conn->unsubscribe($c_mbox);
                    if ($this->conn->deleteFolder($c_mbox)) {
                        $this->clear_message_cache($c_mbox.'.msg');
                    }
                }
            }
            // clear mailbox-related cache
            $this->clear_message_cache($mailbox.'.msg');
            $this->clear_cache('mailboxes');
        }
        // clear mailboxlist cache
        if ($deleted)
            $this->clear_cache('mailboxes');
        return $deleted;
        return $result;
    }
program/steps/settings/folders.inc
@@ -65,17 +65,21 @@
// delete an existing mailbox
else if ($RCMAIL->action == 'delete-folder')
{
    $a_mboxes  = $IMAP->list_unsubscribed();
    $delimiter = $IMAP->get_hierarchy_delimiter();
    $mbox_utf8 = get_input_value('_mbox', RCUBE_INPUT_POST, true);
    $mbox      = rcube_charset_convert($mbox_utf8, RCMAIL_CHARSET, 'UTF7-IMAP');
    // get folder's children or all folders if the name contains special characters
    $delimiter = $IMAP->get_hierarchy_delimiter();
    if ((strpos($mbox, '%') === false) && (strpos($mbox, '*') === false))
        $a_mboxes  = $IMAP->list_unsubscribed('', $mbox.$delimiter.'*');
    else
        $a_mboxes  = $IMAP->list_unsubscribed();
    if (strlen($mbox))
        $deleted = $IMAP->delete_mailbox(array($mbox));
        $deleted = $IMAP->delete_mailbox($mbox);
    if ($OUTPUT->ajax_call && $deleted) {
        // Remove folder rows
        // Remove folder and subfolders rows
        $OUTPUT->command('remove_folder_row', $mbox_utf8);
        foreach ($a_mboxes as $folder) {
            if (preg_match('/^'. preg_quote($mbox.$delimiter, '/') .'/', $folder)) {
@@ -121,7 +125,7 @@
                    . rcube_charset_convert($foldersplit[$level], 'UTF7-IMAP');
                $before = isset($folderlist[$x+1]) ? rcube_charset_convert($folderlist[$x+1], 'UTF7-IMAP') : false;
                $OUTPUT->command('replace_folder_row', rcube_charset_convert($oldfolder, 'UTF7-IMAP'),
                    rcube_charset_convert($folderlist[$x], 'UTF7-IMAP'), $display_rename, $before);
            }