* - Send mail
* - Save As Draft
*
- * @copyright © 1999-2007 The SquirrelMail Project Team
+ * @copyright 1999-2010 The SquirrelMail Project Team
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
* @version $Id$
* @package squirrelmail
$oErrorHandler->setDelayedErrors(true);
/** SESSION/POST/GET VARS */
-sqgetGlobalVar('send', $send, SQ_POST);
+sqgetGlobalVar('send_button_count', $send_button_count, SQ_POST, 1, SQ_TYPE_INT);
+for ($i = 1; $i <= $send_button_count; $i++)
+ if (sqgetGlobalVar('send' . $i, $send, SQ_POST)) break;
// Send can only be achieved by setting $_POST var. If Send = true then
// retrieve other form fields from $_POST
if (isset($send) && $send) {
sqgetGlobalVar('request_dr',$request_dr, $SQ_GLOBAL);
sqgetGlobalVar('html_addr_search',$html_addr_search, $SQ_GLOBAL);
sqgetGlobalVar('mail_sent',$mail_sent, $SQ_GLOBAL);
-sqgetGlobalVar('passed_id',$passed_id, $SQ_GLOBAL);
+sqgetGlobalVar('passed_id',$passed_id, $SQ_GLOBAL, NULL, SQ_TYPE_BIGINT);
sqgetGlobalVar('passed_ent_id',$passed_ent_id, $SQ_GLOBAL);
+sqgetGlobalVar('fwduid',$fwduid, $SQ_GLOBAL, '');
sqgetGlobalVar('attach',$attach, SQ_POST);
sqgetGlobalVar('draft',$draft, SQ_POST);
if ( sqgetGlobalVar('smaction_edit_new',$tmp) ) $action = 'edit_as_new';
}
+sqgetGlobalVar('smtoken', $submitted_token, $SQ_GLOBAL, '');
+
/**
* Here we decode the data passed in from mailto.php.
*/
$url_replytoallcc = '';
foreach( $url_replytoall_ar as $email => $personal) {
if ($personal) {
- // if personal name contains address separator then surround
- // the personal name with double quotes.
- if (strpos($personal,',') !== false) {
- $personal = '"'.$personal.'"';
- }
- $url_replytoallcc .= ", $personal <$email>";
+ // always quote personal name (can't just quote it if
+ // it contains a comma separator, since it might still
+ // be encoded)
+ $url_replytoallcc .= ", \"$personal\" <$email>";
} else {
$url_replytoallcc .= ', '. $email;
}
/* Otherwise, try to select the desired citation style. */
switch ($reply_citation_style) {
case 'author_said':
- /**
- * To translators: %s is for author's name
- */
+ // i18n: %s is for author's name
$full_reply_citation = sprintf(_("%s wrote:"),$sOrig_from);
break;
case 'quote_who':
$full_reply_citation = $start . $sOrig_from . $end;
break;
case 'date_time_author':
- /**
- * To translators:
- * first %s is for date string, second %s is for author's name. Date uses
- * formating from "D, F j, Y g:i a" and "D, F j, Y H:i" translations.
- * Example string:
- * "On Sat, December 24, 2004 23:59, Santa wrote:"
- * If you have to put author's name in front of date string, check comments about
- * argument swapping at http://www.php.net/sprintf
- */
+ // i18n:
+ // The first %s is for date string, the second %s is for author's name.
+ // The date uses formating from "D, F j, Y g:i a" and "D, F j, Y H:i"
+ // translations.
+ // Example string:
+ // "On Sat, December 24, 2004 23:59, Santa wrote:"
+ // If you have to put author's name in front of date string, check comments about
+ // argument swapping at http://php.net/sprintf
$full_reply_citation = sprintf(_("On %s, %s wrote:"), getLongDateString($orig_date), $sOrig_from);
break;
case 'user-defined':
'subject', 'newmail', 'send_to_bcc', 'passed_id', 'mailbox',
'from_htmladdr_search', 'identity', 'draft_id', 'delete_draft',
'mailprio', 'edit_as_new', 'attachments', 'composesession',
- 'request_mdn', 'request_dr');
+ 'request_mdn', 'request_dr', 'fwduid');
foreach ($compo_var_list as $var) {
if ( isset($session_expired_post[$var]) && !isset($$var) ) {
} else {
$sHeaderJs = (isset($sHeaderJs)) ? $sHeaderJs : '';
if (strpos($action, 'reply') !== false && $reply_focus) {
- $sBodyTagJs = 'onload="checkForm(\''.$replyfocus.'\');"';
+ $sOnload = 'checkForm(\''.$replyfocus.'\');';
} else {
- $sBodyTagJs = 'onload="checkForm();"';
+ $sOnload = 'checkForm();';
}
- displayPageHeader($color, $mailbox,$sHeaderJs,$sBodyTagJs);
+ displayPageHeader($color, $mailbox,$sHeaderJs,$sOnload);
}
showInputForm($session, false);
exit();
}
if ($draft) {
+
+ // validate security token
+ //
+ sm_validate_security_token($submitted_token, 3600, TRUE);
+
/*
* Set $default_charset to correspond with the user's selection
* of language interface.
}
if ($send) {
+
+ // validate security token
+ //
+ sm_validate_security_token($submitted_token, 3600, TRUE);
+
if (isset($_FILES['attachfile']) &&
$_FILES['attachfile']['tmp_name'] &&
$_FILES['attachfile']['tmp_name'] != 'none') {
$AttachFailure = saveAttachedFiles($session);
}
+
if (checkInput(false) && !isset($AttachFailure)) {
if ($mailbox == "All Folders") {
/* We entered compose via the search results page */
/* sqimap_logout($imapConnection); */
}
} elseif (isset($html_addr_search_done)) {
+
+ // validate security token
+ //
+ sm_validate_security_token($submitted_token, 3600, TRUE);
+
if ($compose_new_win == '1') {
compose_Header($color, $mailbox);
}
*/
include_once('./addrbook_search_html.php');
} elseif (isset($attach)) {
+
+ // validate security token
+ //
+ sm_validate_security_token($submitted_token, 3600, TRUE);
+
if ($compose_new_win == '1') {
compose_Header($color, $mailbox);
} else {
showInputForm($session);
}
elseif (isset($sigappend)) {
+
+ // validate security token
+ //
+ sm_validate_security_token($submitted_token, 3600, TRUE);
+
$signature = $idents[$identity]['signature'];
$body .= "\n\n".($prefix_sig==true? "-- \n":'').$signature;
}
showInputForm($session);
} elseif (isset($do_delete)) {
+
+ // validate security token
+ //
+ sm_validate_security_token($submitted_token, 3600, TRUE);
+
if ($compose_new_win == '1') {
compose_Header($color, $mailbox);
} else {
foreach($delete as $index) {
if (!empty($composeMessage->entities) && isset($composeMessage->entities[$index])) {
$composeMessage->entities[$index]->purgeAttachments();
+ // FIXME: one person reported that unset() didn't do anything at all here, so this is a work-around... but it triggers PHP notices if the unset() doesn't work, which should be fixed... but bigger question is if unset() doesn't work here, what about everywhere else? Anyway, uncomment this if you think you need it
+ //$composeMessage->entities[$index] = NULL;
unset ($composeMessage->entities[$index]);
}
}
$values = newMail($mailbox,$passed_id,$passed_ent_id, $action, $session);
+ // forward as attachment - subject is in the message in session
+ //
+ if ($action == 'forward_as_attachment' && empty($values['subject']))
+ $subject = $composeMessage->rfc822_header->subject;
+
/* in case the origin is not read_body.php */
if (isset($send_to)) {
$values['send_to'] = $send_to;
$enc_from_name = '"'.$data['full_name'].'" <'. $data['email_address'].'>';
if(strtolower($enc_from_name) == strtolower($orig_from)) {
$identity = $nr;
- break;
+ // don't stop! need to build $identities array for idents match below
+ //break;
}
$identities[] = $enc_from_name;
}
case ('forward_as_attachment'):
$subject = getforwardSubject(decodeHeader($orig_header->subject,false,false,true));
$composeMessage = getMessage_RFC822_Attachment($message, $composeMessage, $passed_id, $passed_ent_id, $imapConnection);
+ $subject = decodeHeader($orig_header->subject,false,false,true);
+ $subject = str_replace('"', "'", $subject);
+ $subject = trim($subject);
+ if (substr(strtolower($subject), 0, 4) != 'fwd:') {
+ $subject = 'Fwd: ' . $subject;
+ }
$body = '';
break;
case ('reply_all'):
} else {
$send_to_cc = replyAllString($orig_header);
$send_to_cc = decodeHeader($send_to_cc,false,false,true);
+ $send_to_cc = str_replace('""', '"', $send_to_cc);
}
case ('reply'):
// skip this if send_to was already set right above here
if(!$send_to) {
$send_to = $orig_header->reply_to;
if (is_array($send_to) && count($send_to)) {
- $send_to = $orig_header->getAddr_s('reply_to');
+ $send_to = $orig_header->getAddr_s('reply_to', ',', FALSE, TRUE);
} else if (is_object($send_to)) { /* unneccesarry, just for failsafe purpose */
- $send_to = $orig_header->getAddr_s('reply_to');
+ $send_to = $orig_header->getAddr_s('reply_to', ',', FALSE, TRUE);
} else {
- $send_to = $orig_header->getAddr_s('from');
+ $send_to = $orig_header->getAddr_s('from', ',', FALSE, TRUE);
}
}
$send_to = decodeHeader($send_to,false,false,true);
+ $send_to = str_replace('""', '"', $send_to);
$subject = decodeHeader($orig_header->subject,false,false,true);
$subject = str_replace('"', "'", $subject);
$subject = trim($subject);
$body = '';
$strip_sigs = getPref($data_dir, $username, 'strip_sigs');
foreach ($rewrap_body as $line) {
- if ($strip_sigs && substr($line,0,3) == '-- ') {
+ if ($strip_sigs && rtrim($line, "\r\n") == '-- ') {
break;
}
if (preg_match("/^(>+)/", $line, $matches)) {
if ($filename == "") {
$filename = "untitled-".$message->entity_id;
}
- $filename .= '.msg';
+ $filename .= '.eml';
} else {
$filename = $message->getFilename();
}
$fp = fopen($hashed_attachment_dir . '/' . $localfilename, 'wb');
fwrite ($fp, $body);
fclose($fp);
- $composeMessage->initAttachment('message/rfc822',$subject.'.msg',
+ $composeMessage->initAttachment('message/rfc822',$subject.'.eml',
$localfilename);
}
return $composeMessage;
$body, $startMessage, $action, $attachments,
$use_signature, $signature, $prefix_sig, $session_expired,
$editor_size, $editor_height, $subject, $newmail,
- $use_javascript_addr_book, $passed_id, $mailbox,
+ $use_javascript_addr_book, $passed_id, $mailbox, $fwduid,
$from_htmladdr_search, $location_of_buttons, $attachment_dir,
$username, $data_dir, $identity, $idents, $delete_draft,
$mailprio, $compose_new_win, $saved_draft, $mail_sent, $sig_first,
// Onsubmit text is enclosed inside of double quotes, so plugins
// need to quote accordingly.
if (checkForJavascript()) {
- $onsubmit_text = ' onsubmit="';
if (empty($compose_onsubmit))
$compose_onsubmit = array();
else if (!is_array($compose_onsubmit))
$compose_onsubmit = array($compose_onsubmit);
+ $onsubmit_text = '';
foreach ($compose_onsubmit as $text) {
$text = trim($text);
- if (substr($text, -1) != ';' && substr($text, -1) != '}')
- $text .= '; ';
- $onsubmit_text .= $text;
+ if (!empty($text)) {
+ if (substr($text, -1) != ';' && substr($text, -1) != '}')
+ $text .= '; ';
+ $onsubmit_text .= $text;
+ }
}
+ if (!empty($onsubmit_text))
//FIXME: DON'T ECHO HTML FROM CORE!
- echo $onsubmit_text . ' return true;"';
+ echo ' onsubmit="' . $onsubmit_text . ' return true;"';
}
//FIXME: NO HTML IN CORE!
echo ">\n";
+//FIXME: DON'T ECHO HTML FROM CORE!
+ echo addHidden('smtoken', sm_generate_security_token());
+
//FIXME: DON'T ECHO HTML FROM CORE!
echo addHidden('startMessage', $startMessage);
echo addHidden('passed_id', $passed_id);
}
+ if (isset($fwduid)) {
+//FIXME: DON'T ECHO HTML FROM CORE!
+ echo addHidden('fwduid', $fwduid);
+ }
+
if ($saved_draft == 'yes') {
$oTemplate->assign('note', _("Your draft has been saved."));
$oTemplate->display('note.tpl');
$oTemplate->assign('bcc', htmlspecialchars($send_to_bcc));
$oTemplate->assign('subject', htmlspecialchars($subject));
+ // access keys...
+ //
+ global $accesskey_compose_to, $accesskey_compose_cc,
+ $accesskey_compose_identity, $accesskey_compose_bcc,
+ $accesskey_compose_subject;
+ $oTemplate->assign('accesskey_compose_identity', $accesskey_compose_identity);
+ $oTemplate->assign('accesskey_compose_to', $accesskey_compose_to);
+ $oTemplate->assign('accesskey_compose_cc', $accesskey_compose_cc);
+ $oTemplate->assign('accesskey_compose_bcc', $accesskey_compose_bcc);
+ $oTemplate->assign('accesskey_compose_subject', $accesskey_compose_subject);
+
$oTemplate->display('compose_header.tpl');
if ($location_of_buttons == 'between') {
$oTemplate->assign('body', $body_str);
$oTemplate->assign('show_bottom_send', $location_of_buttons!='bottom');
+ // access keys...
+ //
+ global $accesskey_compose_body, $accesskey_compose_send;
+ $oTemplate->assign('accesskey_compose_body', $accesskey_compose_body);
+ $oTemplate->assign('accesskey_compose_send', $accesskey_compose_send);
+
$oTemplate->display ('compose_body.tpl');
if ($location_of_buttons == 'bottom') {
$oTemplate->assign('max_file_size', empty($max) ? -1 : $max);
$oTemplate->assign('attachments', $attach);
+ // access keys...
+ //
+ global $accesskey_compose_attach_browse, $accesskey_compose_attach,
+ $accesskey_compose_delete_attach;
+ $oTemplate->assign('accesskey_compose_attach_browse', $accesskey_compose_attach_browse);
+ $oTemplate->assign('accesskey_compose_attach', $accesskey_compose_attach);
+ $oTemplate->assign('accesskey_compose_delete_attach', $accesskey_compose_delete_attach);
+
$oTemplate->display('compose_attachments.tpl');
} // End of file_uploads if-block
/* End of attachment code */
-//FIXME: no direct echoing to browser, no HTML output in core!
- echo addHidden('username', $username).
- addHidden('smaction', $action).
- addHidden('mailbox', $mailbox);
+ $oTemplate->assign('username', $username);
+ $oTemplate->assign('smaction', $action);
+ $oTemplate->assign('mailbox', $mailbox);
sqgetGlobalVar('QUERY_STRING', $queryString, SQ_SERVER);
-//FIXME: no direct echoing to browser, no HTML output in core!
- echo addHidden('composesession', $composesession).
- addHidden('querystring', $queryString).
- (!empty($attach_array) ?
- addHidden('attachments', urlencode(serialize($attach_array))) : '').
- "</form>\n";
+ $oTemplate->assign('querystring', $queryString);
+ $oTemplate->assign('composesession', $composesession);
+ $oTemplate->assign('send_button_count', unique_widget_name('send', TRUE));
+ if (!empty($attach_array))
+ $oTemplate->assign('attachments', urlencode(serialize($attach_array)));
+
+ $aUserNotices = array();
+
+ // File uploads are off, so we didn't show that part of the form.
+ // To avoid bogus bug reports, tell the user why.
if (!(bool) ini_get('file_uploads')) {
- /* File uploads are off, so we didn't show that part of the form.
- To avoid bogus bug reports, tell the user why. */
-//FIXME: no direct echoing to browser, no HTML output in core!
- echo '<p style="text-align:center">'
- . _("Because PHP file uploads are turned off, you can not attach files to this message. Please see your system administrator for details.")
- . "</p>\r\n";
+ $aUserNotices[] = _("Because PHP file uploads are turned off, you can not attach files to this message. Please see your system administrator for details.");
}
+ $oTemplate->assign('user_notices', $aUserNotices);
+
+ $oTemplate->display('compose_form_close.tpl');
+
if ($compose_new_win=='1') {
$oTemplate->display('compose_newwin_close.tpl');
}
- do_hook('compose_bottom', $null);
-
$oErrorHandler->setDelayedErrors(false);
$oTemplate->display('footer.tpl');
}
$mdn_user_support=getPref($data_dir, $username, 'mdn_user_support',$default_use_mdn);
+ $address_book_button_attribs = array();
+ global $accesskey_compose_addresses;
+ if ($accesskey_compose_addresses != 'NONE')
+ $address_book_button_attribs['accesskey'] = $accesskey_compose_addresses;
if ($use_javascript_addr_book && checkForJavascript()) {
- $addr_book = addButton(_("Addresses"), null, array('onclick' => 'javascript:open_abook();'));
+ $addr_book = addButton(_("Addresses"),
+ null,
+ array_merge($address_book_button_attribs, array('onclick' => 'javascript:open_abook();')));
} else {
- $addr_book = addSubmit(_("Addresses"), 'html_addr_search');
+ $addr_book = addSubmit(_("Addresses"), 'html_addr_search', $address_book_button_attribs);
}
$oTemplate->assign('allow_priority', $default_use_priority==1);
$oTemplate->assign('drafts_enabled', $save_as_draft);
$oTemplate->assign('address_book_button', $addr_book);
+ // access keys...
+ //
+ global $accesskey_compose_priority, $accesskey_compose_on_read,
+ $accesskey_compose_on_delivery, $accesskey_compose_signature,
+ $accesskey_compose_save_draft, $accesskey_compose_send;
+ $oTemplate->assign('accesskey_compose_priority', $accesskey_compose_priority);
+ $oTemplate->assign('accesskey_compose_on_read', $accesskey_compose_on_read);
+ $oTemplate->assign('accesskey_compose_on_delivery', $accesskey_compose_on_delivery);
+ $oTemplate->assign('accesskey_compose_signature', $accesskey_compose_signature);
+ $oTemplate->assign('accesskey_compose_save_draft', $accesskey_compose_save_draft);
+ $oTemplate->assign('accesskey_compose_send', $accesskey_compose_send);
+
$oTemplate->display('compose_buttons.tpl');
}
$composeMessage->initAttachment($type, $name, $localfilename);
}
-/* parse values like 8M and 2k into bytes */
+/**
+ * Parse strings such as "8M" and "2k" into their corresponding size in bytes
+ *
+ * NOTE: This function only recognizes the suffixes "K", "M" and "G"
+ * and will probably break very easily if the given size is in
+ * some completely different format.
+ *
+ * @param string $ini_size The input string to be converted
+ *
+ * @return mixed Boolean FALSE if something went wrong (the value passed in
+ * was empty?, the suffix was not recognized?), otherwise, the
+ * converted size in bytes (just the number (as an integer),
+ * no unit identifier included)
+ *
+ */
function getByteSize($ini_size) {
if(!$ini_size) {
case 'K':
$bytesize = 1024;
break;
+ default:
+ return FALSE;
}
return ($bytesize * (int)substr($ini_size, 0, -1));
* and conf.pl should show a list of available backends.
* The message also should be constructed by the message class.
*
+ * @param object $composeMessage The message being sent. Please note
+ * that it is passed by reference and
+ * will be returned modified, with additional
+ * headers, such as Message-ID, Date, In-Reply-To,
+ * References, and so forth.
+ *
* @return boolean FALSE if delivery failed, or some non-FALSE value
* upon success.
*
*/
-function deliverMessage($composeMessage, $draft=false) {
+function deliverMessage(&$composeMessage, $draft=false) {
global $send_to, $send_to_cc, $send_to_bcc, $mailprio, $subject, $body,
- $username, $identity, $idents, $data_dir, $message_id,
+ $username, $identity, $idents, $data_dir,
$request_mdn, $request_dr, $default_charset, $useSendmail,
$domain, $action, $default_move_to_sent, $move_to_sent,
$imapServerAddress, $imapPort, $sent_folder, $key;
/* Receipt: On Delivery */
if (!empty($request_dr)) {
//FIXME: it would be better to fiddle with headers inside of the message object or possibly when delivering the message to its destination; is this possible?
- $rfc822_header->more_headers['Return-Receipt-To'] = $from->mailbox.'@'.$from->domain;
+ $rfc822_header->more_headers['Return-Receipt-To'] = $from_addr;
} elseif (isset($rfc822_header->more_headers['Return-Receipt-To'])) {
unset($rfc822_header->more_headers['Return-Receipt-To']);
}
if (!$useSendmail && !$draft) {
require_once(SM_PATH . 'class/deliver/Deliver_SMTP.class.php');
$deliver = new Deliver_SMTP();
- global $smtpServerAddress, $smtpPort, $pop_before_smtp;
+ global $smtpServerAddress, $smtpPort, $pop_before_smtp, $pop_before_smtp_host;
$authPop = (isset($pop_before_smtp) && $pop_before_smtp) ? true : false;
+ if (empty($pop_before_smtp_host)) $pop_before_smtp_host = $smtpServerAddress;
get_smtp_user($user, $pass);
$stream = $deliver->initStream($composeMessage,$domain,0,
- $smtpServerAddress, $smtpPort, $user, $pass, $authPop);
+ $smtpServerAddress, $smtpPort, $user, $pass, $authPop, $pop_before_smtp_host);
} elseif (!$draft) {
require_once(SM_PATH . 'class/deliver/Deliver_SendMail.class.php');
global $sendmail_path, $sendmail_args;
if (sqimap_mailbox_exists ($imap_stream, $draft_folder)) {
require_once(SM_PATH . 'class/deliver/Deliver_IMAP.class.php');
$imap_deliver = new Deliver_IMAP();
- list($success, $ignore) = $imap_deliver->mail($composeMessage, $imap_stream, $reply_id, $reply_ent_id, $draft_folder);
+ $success = $imap_deliver->mail($composeMessage, $imap_stream, $reply_id, $reply_ent_id, $imap_stream, $draft_folder);
sqimap_logout($imap_stream);
unset ($imap_deliver);
$composeMessage->purgeAttachments();
}
$success = false;
if ($stream) {
- list($ignore, $message_id) = $deliver->mail($composeMessage, $stream, $reply_id, $reply_ent_id);
+ $deliver->mail($composeMessage, $stream, $reply_id, $reply_ent_id);
$success = $deliver->finalizeStream($stream);
}
if (!$success) {
// mark as replied or forwarded if applicable
//
- global $what, $iAccount, $startMessage, $passed_id, $mailbox;
+ global $what, $iAccount, $startMessage, $passed_id, $fwduid, $mailbox;
if ($action=='reply' || $action=='reply_all' || $action=='forward' || $action=='forward_as_attachment') {
require(SM_PATH . 'functions/mailbox_display.php');
if (in_array('$forwarded',$aMailbox['PERMANENTFLAGS'], true) ||
in_array('\\*',$aMailbox['PERMANENTFLAGS'])) {
- $aUpdatedMsgs = sqimap_toggle_flag($imap_stream, array($passed_id), '$Forwarded', true, false);
- if (isset($aUpdatedMsgs[$passed_id]['FLAGS'])) {
- if (isset($aMailbox['MSG_HEADERS'][$passed_id])) {
- $aMailbox['MSG_HEADERS'][$passed_id]['FLAGS'] = $aMsg['FLAGS'];
+ // when forwarding as an attachment from the message
+ // list, passed_id is not used, need to get UID(s)
+ // from the query string
+ //
+ if (empty($passed_id) && !empty($fwduid))
+ $ids = explode('_', $fwduid);
+ else
+ $ids = array($passed_id);
+
+ $aUpdatedMsgs = sqimap_toggle_flag($imap_stream, $ids, '$Forwarded', true, false);
+
+ foreach ($ids as $id) {
+ if (isset($aUpdatedMsgs[$id]['FLAGS'])) {
+ if (isset($aMailbox['MSG_HEADERS'][$id])) {
+ $aMailbox['MSG_HEADERS'][$id]['FLAGS'] = $aMsg['FLAGS'];
+ }
}
}
}
}
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, $sent_folder);
+ $imap_deliver->mail($composeMessage, $imap_stream, $reply_id, $reply_ent_id, $imap_stream, $sent_folder);
unset ($imap_deliver);
}