From e2ccf2849320926cb97ee3eceff32fde575aa34e Mon Sep 17 00:00:00 2001 From: pdontthink Date: Wed, 19 Dec 2007 08:24:36 +0000 Subject: [PATCH] Refactor how IMAP messages are "sent" git-svn-id: https://svn.code.sf.net/p/squirrelmail/code/trunk/squirrelmail@12831 7612ce4b-ef26-0410-bec9-ea0150e637f0 --- ChangeLog | 1 + class/deliver/Deliver.class.php | 63 ++++++++++++++++++++++++++-- class/deliver/Deliver_IMAP.class.php | 52 +++++++++++++++++++++++ src/compose.php | 10 +---- 4 files changed, 114 insertions(+), 12 deletions(-) diff --git a/ChangeLog b/ChangeLog index 73543831..47d27180 100644 --- 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) diff --git a/class/deliver/Deliver.class.php b/class/deliver/Deliver.class.php index 45ed6ab8..59312ebf 100644 --- a/class/deliver/Deliver.class.php +++ b/class/deliver/Deliver.class.php @@ -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 * diff --git a/class/deliver/Deliver_IMAP.class.php b/class/deliver/Deliver_IMAP.class.php index 855cd29d..fa7255fc 100644 --- a/class/deliver/Deliver_IMAP.class.php +++ b/class/deliver/Deliver_IMAP.class.php @@ -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 */ } diff --git a/src/compose.php b/src/compose.php index 619fc708..ab83c8c0 100644 --- a/src/compose.php +++ b/src/compose.php @@ -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); } -- 2.25.1