From 765fdeb5b5269f7647972046bac3d0054a6b7946 Mon Sep 17 00:00:00 2001
From: alecpl <alec@alec.pl>
Date: Mon, 03 Oct 2011 09:13:44 -0400
Subject: [PATCH] - Improved performance of draft saving by usage of APPENDUID response if available (skipped SEARCH call)

---
 program/include/rcube_imap.php         |    2 +-
 program/steps/mail/sendmail.inc        |   12 ++++++++----
 program/include/rcube_imap_generic.php |   39 +++++++++++++++++++++++++++++++++++++--
 3 files changed, 46 insertions(+), 7 deletions(-)

diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php
index f37cfda..5eee8d6 100644
--- a/program/include/rcube_imap.php
+++ b/program/include/rcube_imap.php
@@ -2531,7 +2531,7 @@
      * @param string  $headers Headers string if $message contains only the body
      * @param boolean $is_file True if $message is a filename
      *
-     * @return boolean True on success, False on error
+     * @return int|bool Appended message UID or True on success, False on error
      */
     function save_message($mailbox, &$message, $headers='', $is_file=false)
     {
diff --git a/program/include/rcube_imap_generic.php b/program/include/rcube_imap_generic.php
index 8b99da4..a25413c 100644
--- a/program/include/rcube_imap_generic.php
+++ b/program/include/rcube_imap_generic.php
@@ -310,6 +310,10 @@
                 }
                 else {
                     $this->resultcode = null;
+                    // parse response for [APPENDUID 1204196876 3456]
+                    if (preg_match("/^\[APPENDUID [0-9]+ ([0-9,:*]+)\]/i", $str, $m)) {
+                        $this->data['APPENDUID'] = $m[1];
+                    }
                 }
                 $this->result = $str;
 
@@ -2498,8 +2502,18 @@
         return ($result == self::ERROR_OK);
     }
 
+    /**
+     * Handler for IMAP APPEND command
+     *
+     * @param string $mailbox Mailbox name
+     * @param string $message Message content
+     *
+     * @return string|bool On success APPENDUID response (if available) or True, False on failure
+     */
     function append($mailbox, &$message)
     {
+        unset($this->data['APPENDUID']);
+
         if (!$mailbox) {
             return false;
         }
@@ -2538,7 +2552,12 @@
             // Clear internal status cache
             unset($this->data['STATUS:'.$mailbox]);
 
-            return ($this->parseResult($line, 'APPEND: ') == self::ERROR_OK);
+            if ($this->parseResult($line, 'APPEND: ') != self::ERROR_OK)
+                return false;
+            else if (!empty($this->data['APPENDUID']))
+                return $this->data['APPENDUID'];
+            else
+                return true;
         }
         else {
             $this->setError(self::ERROR_COMMAND, "Unable to send command: $request");
@@ -2547,8 +2566,19 @@
         return false;
     }
 
+    /**
+     * Handler for IMAP APPEND command.
+     *
+     * @param string $mailbox Mailbox name
+     * @param string $path    Path to the file with message body
+     * @param string $headers Message headers
+     *
+     * @return string|bool On success APPENDUID response (if available) or True, False on failure
+     */
     function appendFromFile($mailbox, $path, $headers=null)
     {
+        unset($this->data['APPENDUID']);
+
         if (!$mailbox) {
             return false;
         }
@@ -2615,7 +2645,12 @@
             // Clear internal status cache
             unset($this->data['STATUS:'.$mailbox]);
 
-            return ($this->parseResult($line, 'APPEND: ') == self::ERROR_OK);
+            if ($this->parseResult($line, 'APPEND: ') != self::ERROR_OK)
+                return false;
+            else if (!empty($this->data['APPENDUID']))
+                return $this->data['APPENDUID'];
+            else
+                return true;
         }
         else {
             $this->setError(self::ERROR_COMMAND, "Unable to send command: $request");
diff --git a/program/steps/mail/sendmail.inc b/program/steps/mail/sendmail.inc
index 9ea53ab..deddb45 100644
--- a/program/steps/mail/sendmail.inc
+++ b/program/steps/mail/sendmail.inc
@@ -624,7 +624,7 @@
   // save message sent time
   if (!empty($CONFIG['sendmail_delay']))
     $RCMAIL->user->save_prefs(array('last_message_time' => time()));
-  
+
   // set replied/forwarded flag
   if ($_SESSION['compose']['reply_uid'])
     $IMAP->set_flag($_SESSION['compose']['reply_uid'], 'ANSWERED', $_SESSION['compose']['mailbox']);
@@ -700,6 +700,7 @@
 
   if ($olddraftmessageid) {
     // delete previous saved draft
+    // @TODO: use message UID (remember to check UIDVALIDITY) to skip this SEARCH
     $a_deleteid = $IMAP->search_once($CONFIG['drafts_mbox'],
         'HEADER Message-ID '.$olddraftmessageid, true);
 
@@ -723,9 +724,12 @@
 if ($savedraft) {
   $msgid = strtr($message_id, array('>' => '', '<' => ''));
 
-  // remember new draft-uid
-  $draftuids = $IMAP->search_once($CONFIG['drafts_mbox'], 'HEADER Message-ID '.$msgid, true);
-  $_SESSION['compose']['param']['draft_uid'] = $draftuids[0];
+  // remember new draft-uid ($saved could be an UID or TRUE here)
+  if (is_bool($saved)) {
+    $draftuids = $IMAP->search_once($CONFIG['drafts_mbox'], 'HEADER Message-ID '.$msgid, true);
+    $saved     = $draftuids[0];
+  }
+  $_SESSION['compose']['param']['draft_uid'] = $saved;
 
   // display success
   $OUTPUT->show_message('messagesaved', 'confirmation');

--
Gitblit v1.9.1