Refactor how IMAP messages are "sent"
authorpdontthink <pdontthink@7612ce4b-ef26-0410-bec9-ea0150e637f0>
Wed, 19 Dec 2007 08:24:36 +0000 (08:24 +0000)
committerpdontthink <pdontthink@7612ce4b-ef26-0410-bec9-ea0150e637f0>
Wed, 19 Dec 2007 08:24:36 +0000 (08:24 +0000)
git-svn-id: https://svn.code.sf.net/p/squirrelmail/code/trunk/squirrelmail@12831 7612ce4b-ef26-0410-bec9-ea0150e637f0

ChangeLog
class/deliver/Deliver.class.php
class/deliver/Deliver_IMAP.class.php
src/compose.php

index 73543831b949695186661d9f5d55b7fbf65c18ae..47d27180503445b3b07ef55c3478e9326d2b1cd2 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -238,6 +238,7 @@ Version 1.5.2 - SVN
     (#1829098).
   - Some IMAP servers send nil for an empty email body (See RFC2180,
     section 4.1.3 on empty strings).
+  - Fix for IMAP servers that were having problems saving sent messages
 
 
 Version 1.5.1 (branched on 2006-02-12)
index 45ed6ab8375faaa5033d7f57d713ed9e8f137991..59312ebf5802fd1e99ae9b3f34cda8095d8900fc 100644 (file)
@@ -33,6 +33,11 @@ class Deliver {
      *
      * @param Message  $message      Message object to send
      * @param resource $stream       Handle to the SMTP stream
+     *                               (when FALSE, nothing will be
+     *                               written to the stream; this can
+     *                               be used to determine the actual
+     *                               number of bytes that will be
+     *                               written to the stream)
      * @param string   $reply_id     Identifies message being replied to
      *                               (OPTIONAL; caller should ONLY specify
      *                               a value for this when the message
@@ -42,10 +47,17 @@ class Deliver {
      *                               message inside another (OPTIONAL; caller
      *                               should ONLY specify a value for this 
      *                               when the message being sent is a reply)
+     * @param mixed    $extra        Any implementation-specific variables
+     *                               can be passed in here and used in
+     *                               an overloaded version of this method
+     *                               if needed.
      *
-     * @return integer $raw_length
+     * @return integer $raw_length The number of bytes written (or that would 
+     *                             have been written) to the output stream
      */
-    function mail($message, $stream=false, $reply_id=0, $reply_ent_id=0) {
+    function mail($message, $stream=false, $reply_id=0, $reply_ent_id=0,
+                  $extra=NULL) {
+
         $rfc822_header = $message->rfc822_header;
         if (count($message->entities)) {
             $boundary = $this->mimeBoundary();
@@ -61,7 +73,8 @@ class Deliver {
         if ($reply_id) {
             global $imapConnection, $username, $imapServerAddress, 
                    $imapPort, $mailbox;
-            if (!$imapConnection)
+
+            if (!is_resource($imapConnection))
                 $imapConnection = sqimap_login($username, FALSE,
                                                $imapServerAddress, $imapPort, 0);
 
@@ -89,12 +102,44 @@ class Deliver {
                              ? $message->reply_rfc822_header : '');
         $header = $this->prepareRFC822_Header($rfc822_header, $reply_rfc822_header, $raw_length);
 
+        $this->send_mail($message, $header, $boundary, $stream, $raw_length, $extra);
+
+        return $raw_length;
+    }
+
+    /**
+     * function send_mail - send the message parts to the IMAP stream
+     *
+     * @param Message  $message      Message object to send
+     * @param string   $header       Headers ready to send
+     * @param string   $boundary     Message parts boundary
+     * @param resource $stream       Handle to the SMTP stream
+     *                               (when FALSE, nothing will be
+     *                               written to the stream; this can
+     *                               be used to determine the actual
+     *                               number of bytes that will be
+     *                               written to the stream)
+     * @param int     &$raw_length   The number of bytes written (or that
+     *                               would have been written) to the 
+     *                               output stream - NOTE that this is
+     *                               passed by reference
+     * @param mixed    $extra        Any implementation-specific variables
+     *                               can be passed in here and used in
+     *                               an overloaded version of this method
+     *                               if needed.
+     *
+     * @return void
+     *
+     */
+    function send_mail($message, $header, $boundary, $stream=false, 
+                       &$raw_length, $extra=NULL) {
+
+
         if ($stream) {
             $this->preWriteToStream($header);
             $this->writeToStream($stream, $header);
         }
         $this->writeBody($message, $stream, $raw_length, $boundary);
-        return $raw_length;
     }
 
     /**
@@ -105,6 +150,11 @@ class Deliver {
      *
      * @param Message   $message      Message object to transform
      * @param resource  $stream       SMTP output stream
+     *                                (when FALSE, nothing will be
+     *                                written to the stream; this can
+     *                                be used to determine the actual
+     *                                number of bytes that will be
+     *                                written to the stream)
      * @param integer  &$length_raw   raw length of the message (part)
      *                                as returned by mail fn
      * @param string    $boundary     custom boundary to call, usually for subparts
@@ -163,6 +213,11 @@ class Deliver {
      *
      * @param Message   $message      Message object to transform
      * @param resource  $stream       SMTP output stream
+     *                                (when FALSE, nothing will be
+     *                                written to the stream; this can
+     *                                be used to determine the actual
+     *                                number of bytes that will be
+     *                                written to the stream)
      * @param integer  &$length       length of the message part
      *                                as returned by mail fn
      *
index 855cd29df03f829a6781c73a55832a57f64e785b..fa7255fcbef39066cc3b7c2b99b5e0f057f75a13 100644 (file)
@@ -25,6 +25,58 @@ class Deliver_IMAP extends Deliver {
        return true;
     }
 
+    /**
+     * function send_mail - send the message parts to the IMAP stream
+     *
+     * Overridden from parent class so that we can insert some 
+     * IMAP APPEND commands before and after the message is 
+     * sent on the IMAP stream.
+     *
+     * @param Message  $message      Message object to send
+     * @param string   $header       Headers ready to send
+     * @param string   $boundary     Message parts boundary
+     * @param resource $stream       Handle to the SMTP stream
+     *                               (when FALSE, nothing will be
+     *                               written to the stream; this can
+     *                               be used to determine the actual
+     *                               number of bytes that will be
+     *                               written to the stream)
+     * @param int     &$raw_length   The number of bytes written (or that
+     *                               would have been written) to the 
+     *                               output stream - NOTE that this is
+     *                               passed by reference
+     * @param string   $folder       The IMAP folder to which the 
+     *                               message is being sent
+     *
+     * @return void
+     *
+     */
+    function send_mail($message, $header, $boundary, $stream=false, 
+                       &$raw_length, $folder) {
+
+        // write the body without providing a stream so we
+        // can calculate the final length - after this call,
+        // $final_length will be our correct final length value
+        //
+        $final_length = $raw_length;
+        $this->writeBody($message, 0, $final_length, $boundary);
+
+
+        // now if we have a real live stream, send the message
+        //
+        if ($stream) {
+            sqimap_append ($stream, $folder, $final_length);
+
+            $this->preWriteToStream($header);
+            $this->writeToStream($stream, $header);
+            $this->writeBody($message, $stream, $raw_length, $boundary);
+
+            sqimap_append_done ($stream, $folder);
+        }
+
+    }
+
+
     /* to do: finishing the imap-class so the initStream function can call the
        imap-class */
 }
index 619fc70869ccedfc37ccf9482f3402ec5ba6634c..ab83c8c019473ff29dde78092f27bb80da8fceb1 100644 (file)
@@ -1588,16 +1588,12 @@ function deliverMessage($composeMessage, $draft=false) {
         $stream = $deliver->initStream($composeMessage,$sendmail_path);
     } elseif ($draft) {
         global $draft_folder;
-        require_once(SM_PATH . 'class/deliver/Deliver_IMAP.class.php');
         $imap_stream = sqimap_login($username, false, $imapServerAddress,
                 $imapPort, 0);
         if (sqimap_mailbox_exists ($imap_stream, $draft_folder)) {
             require_once(SM_PATH . 'class/deliver/Deliver_IMAP.class.php');
             $imap_deliver = new Deliver_IMAP();
-            $length = $imap_deliver->mail($composeMessage, 0, $reply_id, $reply_ent_id);
-            sqimap_append ($imap_stream, $draft_folder, $length);
-            $imap_deliver->mail($composeMessage, $imap_stream, $reply_id, $reply_ent_id);
-            sqimap_append_done ($imap_stream, $draft_folder);
+            $imap_deliver->mail($composeMessage, $imap_stream, $reply_id, $reply_ent_id, $draft_folder);
             sqimap_logout($imap_stream);
             unset ($imap_deliver);
             $composeMessage->purgeAttachments();
@@ -1710,11 +1706,9 @@ function deliverMessage($composeMessage, $draft=false) {
                     $sent_folder = $mailbox;
                 }
             }
-            sqimap_append ($imap_stream, $sent_folder, $length);
             require_once(SM_PATH . 'class/deliver/Deliver_IMAP.class.php');
             $imap_deliver = new Deliver_IMAP();
-            $imap_deliver->mail($composeMessage, $imap_stream, $reply_id, $reply_ent_id);
-            sqimap_append_done ($imap_stream, $sent_folder);
+            $imap_deliver->mail($composeMessage, $imap_stream, $reply_id, $reply_ent_id, $sent_folder);
             unset ($imap_deliver);
         }