From d9dc320a40ef21cfc0a1f03d453784949da65f52 Mon Sep 17 00:00:00 2001
From: Aleksander Machniak <alec@alec.pl>
Date: Fri, 08 Mar 2013 09:35:03 -0500
Subject: [PATCH] Support IMAP MOVE extension [RFC 6851]

---
 CHANGELOG                                    |    1 +
 program/lib/Roundcube/rcube_imap.php         |    3 ---
 program/lib/Roundcube/rcube_imap_generic.php |   47 +++++++++++++++++++++++++++++++++++++----------
 3 files changed, 38 insertions(+), 13 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 062313e..baca867 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,7 @@
 CHANGELOG Roundcube Webmail
 ===========================
 
+- Support IMAP MOVE extension [RFC 6851]
 - Fix javascript errors when working in a page opened with taget="_blank"
 - Mention SQLite database format change in UPGRADING file (#1488983)
 - Increase maxlength to 254 chars for email input fields in addressbook (#1488987)
diff --git a/program/lib/Roundcube/rcube_imap.php b/program/lib/Roundcube/rcube_imap.php
index 18c6b12..8d9c375 100644
--- a/program/lib/Roundcube/rcube_imap.php
+++ b/program/lib/Roundcube/rcube_imap.php
@@ -2333,10 +2333,7 @@
         // move messages
         $moved = $this->conn->move($uids, $from_mbox, $to_mbox);
 
-        // send expunge command in order to have the moved message
-        // really deleted from the source folder
         if ($moved) {
-            $this->expunge_message($uids, $from_mbox, false);
             $this->clear_messagecount($from_mbox);
             $this->clear_messagecount($to_mbox);
         }
diff --git a/program/lib/Roundcube/rcube_imap_generic.php b/program/lib/Roundcube/rcube_imap_generic.php
index b9a796c..8532cf8 100644
--- a/program/lib/Roundcube/rcube_imap_generic.php
+++ b/program/lib/Roundcube/rcube_imap_generic.php
@@ -1065,8 +1065,8 @@
     /**
      * Executes EXPUNGE command
      *
-     * @param string $mailbox  Mailbox name
-     * @param string $messages Message UIDs to expunge
+     * @param string       $mailbox  Mailbox name
+     * @param string|array $messages Message UIDs to expunge
      *
      * @return boolean True on success, False on error
      */
@@ -1084,10 +1084,13 @@
         // Clear internal status cache
         unset($this->data['STATUS:'.$mailbox]);
 
-        if ($messages)
-            $result = $this->execute('UID EXPUNGE', array($messages), self::COMMAND_NORESPONSE);
-        else
+        if (!empty($messages) && $messages != '*' && $this->hasCapability('UIDPLUS')) {
+            $messages = self::compressMessageSet($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 = null; // state has changed, need to reselect
@@ -1980,7 +1983,6 @@
 
     /**
      * Moves message(s) from one folder to another.
-     * Original message(s) will be marked as deleted.
      *
      * @param string|array  $messages  Message UID(s)
      * @param string        $from      Mailbox name
@@ -1999,14 +2001,39 @@
             return false;
         }
 
-        $r = $this->copy($messages, $from, $to);
+        // use MOVE command (RFC 6851)
+        if ($this->hasCapability('MOVE')) {
+            // Clear last COPYUID data
+            unset($this->data['COPYUID']);
 
-        if ($r) {
             // Clear internal status cache
+            unset($this->data['STATUS:'.$to]);
             unset($this->data['STATUS:'.$from]);
 
-            return $this->flag($from, $messages, 'DELETED');
+            $r = $this->execute('UID MOVE', array(
+                $this->compressMessageSet($messages), $this->escape($to)),
+                self::COMMAND_NORESPONSE);
         }
+        // use COPY + STORE +FLAGS.SILENT \Deleted + EXPUNGE
+        else {
+            $r = $this->copy($messages, $from, $to);
+
+            if ($r) {
+                // Clear internal status cache
+                unset($this->data['STATUS:'.$from]);
+
+                $r = $this->flag($from, $messages, 'DELETED');
+
+                if ($messages == '*') {
+                    // CLOSE+SELECT should be faster than EXPUNGE
+                    $this->close();
+                }
+                else {
+                    $this->expunge($from, $messages);
+                }
+            }
+        }
+
         return $r;
     }
 
@@ -3502,7 +3529,7 @@
             // 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($messages, ':') !== false) {

--
Gitblit v1.9.1