From 0e11940a65777b8dd22d017da472c2dc373d650c Mon Sep 17 00:00:00 2001 From: alecpl Date: Mon, 6 Dec 2010 14:06:44 +0000 Subject: - Improve performance of folder rename and delete actions. Don't get list of all folders when we need only children of the specified folder. --- CHANGELOG | 1 + program/include/rcube_imap.php | 92 ++++++++++++++++++-------------------- program/steps/settings/folders.inc | 16 ++++--- 3 files changed, 55 insertions(+), 54 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 312c4a29d..8d51add5d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -15,6 +15,7 @@ CHANGELOG Roundcube Webmail - 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 ---------------- diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php index 8cb866a2e..7db5e5468 100644 --- a/program/include/rcube_imap.php +++ b/program/include/rcube_imap.php @@ -3018,7 +3018,7 @@ class rcube_imap /** * 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 @@ class rcube_imap * * @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 @@ class rcube_imap // 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 $mbox_name Mailbox name * - * @param string|array $mbox_name Mailbox name(s) string/array * @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 mailboxlist cache - if ($deleted) + // clear mailbox-related cache + $this->clear_message_cache($mailbox.'.msg'); $this->clear_cache('mailboxes'); + } - return $deleted; + return $result; } diff --git a/program/steps/settings/folders.inc b/program/steps/settings/folders.inc index b90487a07..1ceca7416 100644 --- a/program/steps/settings/folders.inc +++ b/program/steps/settings/folders.inc @@ -65,17 +65,21 @@ else if ($RCMAIL->action == 'unsubscribe') // 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 @@ else if ($RCMAIL->action == 'rename-folder') . 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); } -- cgit v1.2.3