findAddress() can return FALSE as well as zero
[squirrelmail.git] / src / compose.php
index ae6a4900744ab27be516dc8420bc107545142e99..b3511fc6784e7e78050a970ef13a34386a311188 100644 (file)
@@ -10,7 +10,7 @@
  *    - Send mail
  *    - Save As Draft
  *
- * @copyright 1999-2010 The SquirrelMail Project Team
+ * @copyright 1999-2012 The SquirrelMail Project Team
  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  * @version $Id$
  * @package squirrelmail
@@ -776,7 +776,7 @@ function newMail ($mailbox='', $passed_id='', $passed_ent_id='', $action='', $se
         $key, $imapServerAddress, $imapPort, 
         $composeMessage, $body_quote, $request_mdn, $request_dr,
         $mdn_user_support, $languages, $squirrelmail_language,
-        $default_charset;
+        $default_charset, $do_not_reply_to_self;
 
     /*
      * Set $default_charset to correspond with the user's selection
@@ -893,7 +893,7 @@ function newMail ($mailbox='', $passed_id='', $passed_ent_id='', $action='', $se
             }
 
             $identity_match = $orig_header->findAddress($identities);
-            if ($identity_match) {
+            if ($identity_match !== FALSE) {
                 $identity = $identity_match;
             }
         }
@@ -980,6 +980,78 @@ function newMail ($mailbox='', $passed_id='', $passed_ent_id='', $action='', $se
                 }
                 $send_to = decodeHeader($send_to,false,false,true);
                 $send_to = str_replace('""', '"', $send_to);
+
+
+                // If user doesn't want replies to her own messages
+                // going back to herself (instead send again to the
+                // original recipient of the message being replied to),
+                // then iterate through identities, checking if the TO
+                // field is one of them (if the reply is to ourselves)
+                //
+                // Note we don't bother if the original message doesn't
+                // have anything in the TO field itself (because that's
+                // what we use if we change the recipient to be that of
+                // the previous message)
+                //
+                if ($do_not_reply_to_self && !empty($orig_header->to)) {
+
+                    $orig_to = '';
+
+                    foreach($idents as $id) {
+
+                        if (!empty($id['email_address'])
+                         && strpos($send_to, $id['email_address']) !== FALSE) {
+
+                            // if this is a reply-all, the original recipient
+                            // is already in the CC field, so we can just blank
+                            // the recipient (TO field) (as long as the CC field
+                            // isn't empty that is) and we're done
+                            //
+                            if ($action == 'reply_all') {
+                                if (!empty($send_to_cc)) $send_to = '';
+                                break;
+                            }
+
+                            $orig_to = $orig_header->to;
+                            if (is_array($orig_to) && count($orig_to)) {
+                                $orig_to = $orig_header->getAddr_s('to', ',', FALSE, TRUE);
+                            } else if (is_object($orig_to)) { /* unneccesarry, just for failsafe purpose */
+                                $orig_to = $orig_header->getAddr_s('to', ',', FALSE, TRUE);
+                            } else {
+                                $orig_to = '';
+                            }
+                            $orig_to = decodeHeader($orig_to,false,false,true);
+                            $orig_to = str_replace('""', '"', $orig_to);
+
+                            break;
+                        }
+                    }
+
+                    // if the reply was addressed back to ourselves,
+                    // we will send it to the TO of the previous message,
+                    // first making sure that that address wasn't also
+                    // one of our identities
+                    //
+                    if (!empty($orig_to)) {
+
+                        foreach($idents as $id) {
+                            if (!empty($id['email_address'])
+                             && strpos($orig_to, $id['email_address']) !== FALSE) {
+                                $orig_to = '';
+                                break;
+                            }
+                        }
+
+                        // if $orig_to still not empty, we can use it
+                        //
+                        if (!empty($orig_to)) {
+                            $send_to = $orig_to;
+                        }
+                    }
+
+                }
+
+
                 $subject = decodeHeader($orig_header->subject,false,false,true);
                 $subject = str_replace('"', "'", $subject);
                 $subject = trim($subject);
@@ -1185,6 +1257,12 @@ function showInputForm ($session, $values=false) {
     // to do; SquirrelMail itself will add the final "return true".
     // Onsubmit text is enclosed inside of double quotes, so plugins
     // need to quote accordingly.
+    //
+    // Also, plugin authors should try to retain compatibility with
+    // the Compose Extras plugin by resetting its compose submit
+    // counter when preventing form submit.  Use this code: 
+    // if (your-code-here) { submit_count = 0; return false; }
+    //
     if (checkForJavascript()) {
         if (empty($compose_onsubmit))
             $compose_onsubmit = array();
@@ -1268,10 +1346,10 @@ function showInputForm ($session, $values=false) {
     $oTemplate->assign('identity_def', $identity);
     $oTemplate->assign('input_onfocus', 'onfocus="'.join(' ', $onfocus_array).'"');
 
-    $oTemplate->assign('to', htmlspecialchars($send_to));
-    $oTemplate->assign('cc', htmlspecialchars($send_to_cc));
-    $oTemplate->assign('bcc', htmlspecialchars($send_to_bcc));
-    $oTemplate->assign('subject', htmlspecialchars($subject));
+    $oTemplate->assign('to', sm_encode_html_special_chars($send_to));
+    $oTemplate->assign('cc', sm_encode_html_special_chars($send_to_cc));
+    $oTemplate->assign('bcc', sm_encode_html_special_chars($send_to_bcc));
+    $oTemplate->assign('subject', sm_encode_html_special_chars($subject));
 
     // access keys...
     //
@@ -1307,9 +1385,9 @@ function showInputForm ($session, $values=false) {
             } else {
                 $body_str = "\n\n".($prefix_sig==true? "-- \n":'').decodeHeader($signature,false,false);
             }
-            $body_str .= "\n\n".htmlspecialchars(decodeHeader($body,false,false));
+            $body_str .= "\n\n".sm_encode_html_special_chars(decodeHeader($body,false,false));
         } else {
-            $body_str = "\n\n".htmlspecialchars(decodeHeader($body,false,false));
+            $body_str = "\n\n".sm_encode_html_special_chars(decodeHeader($body,false,false));
             // FIXME: test is specific to ja_JP translation implementation. See above comments.
             if ($default_charset == 'iso-2022-jp') {
                 $body_str .= "\n\n".($prefix_sig==true? "-- \n":'').mb_convert_encoding($signature, 'EUC-JP');
@@ -1318,7 +1396,7 @@ function showInputForm ($session, $values=false) {
             }
         }
     } else {
-        $body_str = htmlspecialchars(decodeHeader($body,false,false));
+        $body_str = sm_encode_html_special_chars(decodeHeader($body,false,false));
     }
 
     $oTemplate->assign('editor_width', (int)$editor_size);
@@ -1627,6 +1705,8 @@ function deliverMessage(&$composeMessage, $draft=false) {
 
     $reply_to = '';
     $reply_to  = $idents[$identity]['reply_to'];
+    if ($reply_to && strpos($reply_to, '@') === FALSE)
+        $reply_to .= '@' . $domain;
     
     $from_addr = build_from_header($identity);
     $rfc822_header->from = $rfc822_header->parseAddress($from_addr,true);
@@ -1731,7 +1811,7 @@ function deliverMessage(&$composeMessage, $draft=false) {
             $composeMessage->purgeAttachments();
             return $success;
         } else {
-            $msg  = '<br />'.sprintf(_("Error: Draft folder %s does not exist."), htmlspecialchars($draft_folder));
+            $msg  = '<br />'.sprintf(_("Error: Draft folder %s does not exist."), sm_encode_html_special_chars($draft_folder));
             plain_error_message($msg);
             return false;
         }
@@ -1743,14 +1823,16 @@ function deliverMessage(&$composeMessage, $draft=false) {
     }
     if (!$success) {
         // $deliver->dlv_server_msg is not always server's reply
-        $msg = _("Message not sent.") . "<br />\n" .
-            $deliver->dlv_msg;
+        $msg = _("Message not sent.")
+             . "<br />\n"
+             . (isset($deliver->dlv_msg) ? $deliver->dlv_msg : '');
         if (!empty($deliver->dlv_server_msg)) {
             // add 'server replied' part only when it is not empty.
             // Delivery error can be generated by delivery class itself
-            $msg.='<br />' .
-                _("Server replied:") . ' ' . $deliver->dlv_ret_nr . ' ' .
-                nl2br(htmlspecialchars($deliver->dlv_server_msg));
+            $msg .= '<br />'
+                  . _("Server replied:") . ' '
+                  . (isset($deliver->dlv_ret_nr) ? $deliver->dlv_ret_nr . ' ' : '')
+                  . nl2br(sm_encode_html_special_chars($deliver->dlv_server_msg));
         }
         plain_error_message($msg);
     } else {