Source for file compose.php
Documentation is available at compose.php
* This code sends a mail.
* There are 4 modes of operation:
* @copyright © 1999-2006 The SquirrelMail Project Team
* @license http://opensource.org/licenses/gpl-license.php GNU Public License
* @version $Id: compose.php,v 1.450 2006/09/29 09:02:22 stekkel Exp $
* Include the SquirrelMail initialization file.
require
('../include/init.php');
/* SquirrelMail required files. */
require_once(SM_PATH .
'functions/imap_general.php');
require_once(SM_PATH .
'functions/imap_messages.php');
require_once(SM_PATH .
'functions/date.php');
require_once(SM_PATH .
'functions/mime.php');
require_once(SM_PATH .
'class/deliver/Deliver.class.php');
require_once(SM_PATH .
'functions/addressbook.php');
require_once(SM_PATH .
'functions/forms.php');
require_once(SM_PATH .
'functions/identity.php');
/* --------------------- Get globals ------------------------------------- */
// Turn on delayed error handling in case we wind up redirecting below
$oErrorHandler->setDelayedErrors(true);
/** SESSION/POST/GET VARS */
$startMessage = (int)
$startMessage;
$html_addr_search_done =
'Use Addresses';
if ( sqgetGlobalVar('smaction_reply_all',$tmp) ) $action =
'reply_all';
if ( sqgetGlobalVar('smaction_attache',$tmp) ) $action =
'forward_as_attachment';
if ( sqgetGlobalVar('smaction_edit_new',$tmp) ) $action =
'edit_as_new';
/* Location (For HTTP 1.1 Header("Location: ...") redirects) */
/* Identities (fetch only once) */
/* --------------------- Specific Functions ------------------------------ */
global $include_self_reply_all, $idents;
* 1) Remove the addresses we'll be sending the message 'to'
if (isset
($header->replyto)) {
$excl_ar =
$header->getAddr_a('replyto');
* 2) Remove our identities from the CC list (they still can be in the
* TO list) only if $include_self_reply_all is turned off
if (!$include_self_reply_all) {
foreach($idents as $id) {
$url_replytoall_ar =
$header->getAddr_a(array('to','cc'), $excl_ar);
* 4) generate the string.
foreach( $url_replytoall_ar as $email =>
$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>";
$url_replytoallcc .=
', '.
$email;
$url_replytoallcc =
substr($url_replytoallcc,2);
return $url_replytoallcc;
* creates top line in reply citations
* Line style depends on user preferences.
* $orig_date argument is available only from 1.4.3 and 1.5.1 version.
* @param object $orig_from From: header object.
* @param integer $orig_date email's timestamp
* @return string reply citation
global $reply_citation_style, $reply_citation_start, $reply_citation_end;
$sOrig_from =
decodeHeader($orig_from->getAddress(false),false,false,true);
/* First, return an empty string when no citation style selected. */
if (($reply_citation_style ==
'') ||
($reply_citation_style ==
'none')) {
/* Make sure our final value isn't an empty string. */
/* Otherwise, try to select the desired citation style. */
switch ($reply_citation_style) {
* To translators: %s is for author's name
$full_reply_citation =
sprintf(_("%s wrote:"),$sOrig_from);
$full_reply_citation =
$start .
$sOrig_from .
$end;
* 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.
* "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
$start =
$reply_citation_start .
($reply_citation_start ==
'' ?
'' :
' ');
$end =
$reply_citation_end;
$full_reply_citation =
$start .
$sOrig_from .
$end;
/* Add line feed and return the citation string. */
return ($full_reply_citation .
"\n");
* Creates header fields in forwarded email body
* $default_charset global must be set correctly before you call this function.
* @param object $orig_header
// using own strlen function in order to detect correct string length
$display =
array( _("Subject") =>
sq_strlen(_("Subject"),$default_charset),
$maxsize =
max($display);
foreach($display as $key =>
$val) {
$display[$key] =
$key .
': '.
str_pad('', $maxsize -
$val);
$from =
decodeHeader($orig_header->getAddr_s('from',"\n$indent"),false,false,true);
$to =
decodeHeader($orig_header->getAddr_s('to',"\n$indent"),false,false,true);
$subject =
decodeHeader($orig_header->subject,false,false,true);
// using own str_pad function in order to create correct string pad
$bodyTop =
sq_str_pad(' '.
_("Original Message").
' ',$editor_size -
2,'-',STR_PAD_BOTH,$default_charset) .
"\n".
$display[_("Subject")] .
$subject .
"\n" .
$display[_("From")] .
$from .
"\n" .
$display[_("To")] .
$to .
"\n";
if ($orig_header->cc !=
array() &&
$orig_header->cc !=
'') {
$cc =
decodeHeader($orig_header->getAddr_s('cc',"\n$indent"),false,false,true);
$bodyTop .=
$display[_("Cc")] .
$cc .
"\n";
$bodyTop .=
str_pad('', $editor_size -
2 , '-') .
/* ----------------------------------------------------------------------- */
* If the session is expired during a post this restores the compose session
* extra check for username so we don't display previous post data from
* another user during this session.
if ($session_expired_post['username'] !=
$username) {
unset
($session_expired_post);
// these are the vars that we can set from the expired composed session
$compo_var_list =
array ( 'send_to', 'send_to_cc','body','startMessage',
'passed_body','use_signature','signature','attachments','subject','newmail',
'send_to_bcc', 'passed_id', 'mailbox', 'from_htmladdr_search', 'identity',
'draft_id', 'delete_draft', 'mailprio', 'edit_as_new', 'compose_messsages',
'composesession', 'request_mdn', 'request_dr');
foreach ($compo_var_list as $var) {
if ( isset
($session_expired_post[$var]) &&
!isset
($
$var) ) {
$
$var =
$session_expired_post[$var];
unset
($session_expired_post);
if ($compose_new_win ==
'1') {
$sHeaderJs =
(isset
($sHeaderJs)) ?
$sHeaderJs :
'';
if (strpos($action, 'reply') !==
false &&
$reply_focus) {
$sBodyTagJs =
'onload="checkForm(\''.
$replyfocus.
'\');"';
$sBodyTagJs =
'onload="checkForm();"';
if (!isset
($composesession)) {
if (!isset
($session) ||
(isset
($newmessage) &&
$newmessage)) {
$session =
"$composesession" +
1;
$composesession =
$session;
if (!isset
($compose_messages)) {
$compose_messages =
array();
if (!isset
($compose_messages[$session]) ||
($compose_messages[$session] ==
NULL)) {
$composeMessage->rfc822_header =
$rfc822_header;
$composeMessage->reply_rfc822_header =
'';
$compose_messages[$session] =
$composeMessage;
$composeMessage=
$compose_messages[$session];
if (!isset
($mailbox) ||
$mailbox ==
'' ||
($mailbox ==
'None')) {
* Set $default_charset to correspond with the user's selection
$composeMessage=
$compose_messages[$session];
unset
($compose_messages[$session]);
$draft_message =
_("Draft Email Saved");
/* If this is a resumed draft, then delete the original */
if(isset
($delete_draft)) {
$imap_stream =
sqimap_login($username, false, $imapServerAddress, $imapPort, false);
// force bypass_trash=true because message should be saved when deliverMessage() returns true.
// in current implementation of sqimap_msgs_list_flag() single message id can
// be submitted as string. docs state that it should be array.
$oErrorHandler->saveDelayedErrors();
if ($compose_new_win ==
'1') {
if ( !isset
($pageheader_sent) ||
!$pageheader_sent ) {
Header("Location: $location/compose.php?saved_draft=yes&session=$composesession");
echo
' <br><br><div style="text-align: center;"><a href="' .
$location
.
'/compose.php?saved_sent=yes&session=' .
$composesession .
'">'
.
_("Return") .
'</a></div>';
if ( !isset
($pageheader_sent) ||
!$pageheader_sent ) {
Header("Location: $location/right_main.php?mailbox=" .
urlencode($draft_folder) .
"&startMessage=1¬e=".
urlencode($draft_message));
echo
' <br><br><div style="text-align: center;"><a href="' .
$location
.
'/right_main.php?mailbox=' .
urlencode($draft_folder)
.
'&startMessage=1&note=' .
urlencode($draft_message) .
'">'
.
_("Return") .
'</a></div>';
if (isset
($_FILES['attachfile']) &&
$_FILES['attachfile']['tmp_name'] &&
$_FILES['attachfile']['tmp_name'] !=
'none') {
if (checkInput(false) &&
!isset
($AttachFailure)) {
if ($mailbox ==
"All Folders") {
/* We entered compose via the search results page */
$mailbox =
'INBOX'; /* Send 'em to INBOX, that's safe enough */
if (! isset
($passed_id)) {
* Set $default_charset to correspond with the user's selection
* This is to change all newlines to \n
* We'll change them to \r\n later (in the sendMessage function)
* Rewrap $body so that no line is bigger than $editor_size
foreach ($body as $line) {
if (sq_strlen($line,$default_charset) <=
$editor_size +
1) {
$newBody .=
$line .
"\n";
$newBody .=
$line .
"\n";
$composeMessage=
$compose_messages[$session];
do_hook('compose_send_after', $Result, $composeMessage);
unset
($compose_messages[$session]);
/* if it is resumed draft, delete draft message */
if ( isset
($delete_draft)) {
$imap_stream =
sqimap_login($username, false, $imapServerAddress, $imapPort, false);
// bypass_trash=true because message should be saved when deliverMessage() returns true.
// in current implementation of sqimap_msgs_list_flag() single message id can
// be submitted as string. docs state that it should be array.
* Store the error array in the session because they will be lost on a redirect
$oErrorHandler->saveDelayedErrors();
if ($compose_new_win ==
'1') {
if ( !isset
($pageheader_sent) ||
!$pageheader_sent ) {
Header("Location: $location/compose.php?mail_sent=yes");
echo
' <br><br><div style="text-align: center;"><a href="' .
$location
.
'/compose.php?mail_sent=yes">'
.
_("Return") .
'</a></div>';
if ( !isset
($pageheader_sent) ||
!$pageheader_sent ) {
Header("Location: $location/right_main.php?mailbox=$urlMailbox".
"&startMessage=$startMessage&mail_sent=yes");
echo
' <br><br><div style="text-align: center;"><a href="' .
$location
.
"/right_main.php?mailbox=$urlMailbox"
.
"&startMessage=$startMessage&mail_sent=yes\">"
.
_("Return") .
'</a></div>';
if ($compose_new_win ==
'1') {
if (isset
($AttachFailure)) {
/* sqimap_logout($imapConnection); */
} elseif (isset
($html_addr_search_done)) {
if ($compose_new_win ==
'1') {
if (isset
($send_to_search) &&
is_array($send_to_search)) {
foreach ($send_to_search as $k =>
$v) {
if (substr($k, 0, 1) ==
'T') {
elseif (substr($k, 0, 1) ==
'C') {
elseif (substr($k, 0, 1) ==
'B') {
} elseif (isset
($html_addr_search) &&
!isset
($html_addr_search_cancel)) {
if (isset
($_FILES['attachfile']) &&
$_FILES['attachfile']['tmp_name'] &&
$_FILES['attachfile']['tmp_name'] !=
'none') {
* I am using an include so as to elminiate an extra unnecessary
* click. If you can think of a better way, please implement it.
include_once('./addrbook_search_html.php');
} elseif (isset
($attach)) {
if ($compose_new_win ==
'1') {
elseif (isset
($sigappend)) {
$signature =
$idents[$identity]['signature'];
$body .=
"\n\n".
($prefix_sig==
true?
"-- \n":
'').
$signature;
if ($compose_new_win ==
'1') {
} elseif (isset
($do_delete)) {
if ($compose_new_win ==
'1') {
if (isset
($delete) &&
is_array($delete)) {
$composeMessage =
$compose_messages[$session];
foreach($delete as $index) {
if (!empty($composeMessage->entities) && isset
($composeMessage->entities[$index])) {
$composeMessage->entities[$index]->purgeAttachments();
unset
($composeMessage->entities[$index]);
foreach ($composeMessage->entities as $entity) {
$new_entities[] =
$entity;
$composeMessage->entities =
$new_entities;
$compose_messages[$session] =
$composeMessage;
* This handles the default case as well as the error case
* (they had the same code) --> if (isset($smtpErrors))
if ($compose_new_win ==
'1') {
if (!isset
($passed_ent_id)) {
if (!isset
($passed_id)) {
$values =
newMail($mailbox,$passed_id,$passed_ent_id, $action, $session);
/* in case the origin is not read_body.php */
$values['send_to'] =
$send_to;
if (isset
($send_to_cc)) {
$values['send_to_cc'] =
$send_to_cc;
if (isset
($send_to_bcc)) {
$values['send_to_bcc'] =
$send_to_bcc;
$values['subject'] =
$subject;
/**************** Only function definitions go below *************/
$subject =
'[Fwd: ' .
$subject .
']';
/* This function is used when not sending or adding attachments */
function newMail ($mailbox=
'', $passed_id=
'', $passed_ent_id=
'', $action=
'', $session=
'') {
$composeMessage, $body_quote, $request_mdn, $request_dr,
* Set $default_charset to correspond with the user's selection
* of language interface. $default_charset global is not correct,
* if message is composed in new window.
$send_to =
$send_to_cc =
$send_to_bcc =
$subject =
$identity =
'';
$imapConnection =
sqimap_login($username, false, $imapServerAddress,
/* redefine the messsage in case of message/rfc822 */
$message =
$message->getEntity($passed_ent_id);
/* message is an entity which contains the envelope and type0=message
* and type1=rfc822. The actual entities are childs from
* $message->entities[0]. That's where the encoding and is located
$entities =
$message->entities[0]->findDisplayEntity
(array(), $alt_order =
array('text/plain'));
$entities =
$message->entities[0]->findDisplayEntity
(array(), $alt_order =
array('text/plain','html/plain'));
$orig_header =
$message->rfc822_header; /* here is the envelope located */
/* redefine the message for picking up the attachments */
$message =
$message->entities[0];
$entities =
$message->findDisplayEntity (array(), $alt_order =
array('text/plain'));
$entities =
$message->findDisplayEntity (array(), $alt_order =
array('text/plain','html/plain'));
$orig_header =
$message->rfc822_header;
$type0 =
$message->type0;
$type1 =
$message->type1;
foreach ($entities as $ent) {
$body_part_entity =
$message->getEntity($ent);
$body_part_entity->header->encoding);
$bodypart =
preg_replace(array('/<\/?p>/i','/<div><\/div>/i','/<br\s*(\/)*>/i','/<\/?div>/i'), "\n", $bodypart);
$bodypart =
str_replace(array(' ','>','<'),array(' ','>','<'),$bodypart);
if (isset
($languages[$squirrelmail_language]['XTRA_CODE']) &&
function_exists($languages[$squirrelmail_language]['XTRA_CODE'] .
'_decode')) {
if (mb_detect_encoding($bodypart) !=
'ASCII') {
$bodypart =
call_user_func($languages[$squirrelmail_language]['XTRA_CODE'] .
'_decode', $bodypart);
// charset encoding in compose form stuff
if (isset
($body_part_entity->header->parameters['charset'])) {
$actual =
$body_part_entity->header->parameters['charset'];
// end of charset encoding in compose
if ($default_use_priority) {
$mailprio =
substr($orig_header->priority,0,1);
$from_o =
$orig_header->from;
$orig_from =
$from_o->getAddress();
if (count($idents) >
1) {
foreach($idents as $nr=>
$data) {
$enc_from_name =
'"'.
$data['full_name'].
'" <'.
$data['email_address'].
'>';
if($enc_from_name ==
$orig_from) {
$identities[] =
$enc_from_name;
$identity_match =
$orig_header->findAddress($identities);
$identity =
$identity_match;
$composeMessage->rfc822_header =
$orig_header;
$send_to =
decodeHeader($orig_header->getAddr_s('to'),false,false,true);
$send_to_cc =
decodeHeader($orig_header->getAddr_s('cc'),false,false,true);
$send_to_bcc =
decodeHeader($orig_header->getAddr_s('bcc'),false,false,true);
$send_from =
$orig_header->getAddr_s('from');
$send_from_add =
$send_from_parts->mailbox .
'@' .
$send_from_parts->host;
if (count($identities) >
0) {
foreach($identities as $iddata) {
if ($send_from_add ==
$iddata['email_address']) {
$identity =
$iddata['index'];
$subject =
decodeHeader($orig_header->subject,false,false,true);
// Remember the receipt settings
$request_mdn =
$mdn_user_support &&
!empty($orig_header->dnt) ?
'1' :
'0';
$request_dr =
$mdn_user_support &&
!empty($orig_header->drnt) ?
'1' :
'0';
/* remember the references and in-reply-to headers in case of an reply */
$composeMessage->rfc822_header->more_headers['References'] =
$orig_header->references;
$composeMessage->rfc822_header->more_headers['In-Reply-To'] =
$orig_header->in_reply_to;
// rewrap the body to clean up quotations and line lengths
$composeMessage =
getAttachments($message, $composeMessage, $passed_id, $entities, $imapConnection);
$send_to =
decodeHeader($orig_header->getAddr_s('to'),false,false,true);
$send_to_cc =
decodeHeader($orig_header->getAddr_s('cc'),false,false,true);
$send_to_bcc =
decodeHeader($orig_header->getAddr_s('bcc'),false,false,true);
$subject =
decodeHeader($orig_header->subject,false,false,true);
$mailprio =
$orig_header->priority;
$composeMessage =
getAttachments($message, $composeMessage, $passed_id, $entities, $imapConnection);
// rewrap the body to clean up quotations and line lengths
// the logic for calling sqUnWordWrap here would be to allow the browser to wrap the lines
// forwarded message text should be as undisturbed as possible, so commenting out this call
$composeMessage =
getAttachments($message, $composeMessage, $passed_id, $entities, $imapConnection);
//add a blank line after the forward headers
case ('forward_as_attachment'):
if(isset
($orig_header->mail_followup_to) &&
$orig_header->mail_followup_to) {
$send_to =
$orig_header->getAddr_s('mail_followup_to');
// skip this if send_to was already set right above here
$send_to =
$orig_header->reply_to;
$send_to =
$orig_header->getAddr_s('reply_to');
} 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('from');
$subject =
decodeHeader($orig_header->subject,false,false,true);
$subject =
trim($subject);
$subject =
'Re: ' .
$subject;
/* this corrects some wrapping/quoting problems on replies */
$rewrap_body =
explode("\n", $body);
$from =
(is_array($orig_header->from)) ?
$orig_header->from[0] :
$orig_header->from;
$strip_sigs =
getPref($data_dir, $username, 'strip_sigs');
foreach ($rewrap_body as $line) {
if ($strip_sigs &&
substr($line,0,3) ==
'-- ') {
$body .=
$body_quote .
str_replace("\n", "\n$body_quote$gt ", rtrim($line)) .
"\n";
$body .=
$body_quote .
(!empty($body_quote) ?
' ' :
'') .
str_replace("\n", "\n$body_quote" .
(!empty($body_quote) ?
' ' :
''), rtrim($line)) .
"\n";
//rewrap the body to clean up quotations and line lengths
$composeMessage->reply_rfc822_header =
$orig_header;
$compose_messages[$session] =
$composeMessage;
$ret =
array( 'send_to' =>
$send_to,
'send_to_cc' =>
$send_to_cc,
'send_to_bcc' =>
$send_to_bcc,
'identity' =>
$identity );
} /* function newMail() */
* downloads attachments from original message, stores them in attachment directory and adds
* them to composed message.
* @param object $composeMessage
* @param integer $passed_id
* @param mixed $imapConnection
function getAttachments($message, &$composeMessage, $passed_id, $entities, $imapConnection) {
$hashed_attachment_dir =
getHashedDir($username, $attachment_dir);
if (!count($message->entities) ||
($message->type0 ==
'message' &&
$message->type1 ==
'rfc822')) {
if ( !in_array($message->entity_id, $entities) &&
$message->entity_id) {
switch ($message->type0) {
if ($message->type1 ==
'rfc822') {
$filename =
$message->rfc822_header->subject;
$filename =
"untitled-".
$message->entity_id;
$filename =
$message->getFilename();
if (!$message->mime_header) { /* temporary hack */
$message->mime_header =
$message->header;
$filename =
$message->getFilename();
if (isset
($languages[$squirrelmail_language]['XTRA_CODE']) &&
function_exists($languages[$squirrelmail_language]['XTRA_CODE'] .
'_encode')) {
$filename =
call_user_func($languages[$squirrelmail_language]['XTRA_CODE'] .
'_encode', $filename);
$full_localfilename =
"$hashed_attachment_dir/$localfilename";
$full_localfilename =
"$hashed_attachment_dir/$localfilename";
$message->att_local_name =
$full_localfilename;
$composeMessage->initAttachment($message->type0.
'/'.
$message->type1,$filename,
/* Write Attachment to file */
$fp =
fopen ("$hashed_attachment_dir/$localfilename", 'wb');
for ($i=
0, $entCount=
count($message->entities); $i<
$entCount;$i++
) {
$composeMessage=
getAttachments($message->entities[$i], $composeMessage, $passed_id, $entities, $imapConnection);
$passed_ent_id=
'', $imapConnection) {
$hashed_attachment_dir =
getHashedDir($username, $attachment_dir);
'FETCH '.
$passed_id.
' RFC822',
TRUE, $response, $readmessage,
'FETCH '.
$passed_id.
' BODY['.
$passed_ent_id.
']',
TRUE, $response, $readmessage, TRUE);
$message =
$message->parent;
$body =
implode('', $body_a) .
"\r\n";
$full_localfilename =
"$hashed_attachment_dir/$localfilename";
$fp =
fopen($full_localfilename, 'w');
$composeMessage->initAttachment('message/rfc822',$subject.
'.msg',
global $send_to, $send_to_cc, $body, $startMessage, $action,
$color, $use_signature, $signature, $prefix_sig,
$editor_size, $editor_height, $subject, $newmail,
$use_javascript_addr_book, $send_to_bcc, $passed_id, $mailbox,
$username, $data_dir, $identity, $idents, $delete_draft,
$mailprio, $compose_new_win, $saved_draft, $mail_sent, $sig_first,
$compose_onsubmit, $oTemplate, $oErrorHandler;
$onfocus =
' onfocus="alreadyFocused=true;"';
$onfocus_array =
array('onfocus' =>
'alreadyFocused=true;');
$onfocus_array =
array();
$composeMessage =
$compose_messages[$session];
$send_to =
$values['send_to'];
$send_to_cc =
$values['send_to_cc'];
$send_to_bcc =
$values['send_to_bcc'];
$subject =
$values['subject'];
$mailprio =
$values['mailprio'];
$identity = (int)
$values['identity'];
if ($use_javascript_addr_book) {
echo
"\n".
'<script type="text/javascript">'.
"\n<!--\n" .
'function open_abook() { ' .
"\n" .
' var nwin = window.open("addrbook_popup.php","abookpopup",' .
'"width=670,height=300,resizable=yes,scrollbars=yes");' .
"\n" .
' if((!nwin.opener) && (document.windows != null))' .
"\n" .
' nwin.opener = document.windows;' .
"\n" .
echo
"\n" .
'<form name="compose" action="compose.php" method="post" ' .
'enctype="multipart/form-data"';
$compose_onsubmit =
array();
// Plugins that use compose_form hook can add an array entry
// to the globally scoped $compose_onsubmit; we add them up
// here and format the form tag's full onsubmit handler.
// Each plugin should use "return false" if they need to
// stop form submission but otherwise should NOT use "return
// true" to give other plugins the chance to do what they need
// to do; SquirrelMail itself will add the final "return true".
// Onsubmit text is enclosed inside of double quotes, so plugins
// need to quote accordingly.
$onsubmit_text =
' onsubmit="';
if (empty($compose_onsubmit))
$compose_onsubmit =
array();
$compose_onsubmit =
array($compose_onsubmit);
foreach ($compose_onsubmit as $text) {
echo
$onsubmit_text .
' return true;"';
echo
addHidden('startMessage', $startMessage);
if ($action ==
'draft') {
if (isset
($delete_draft)) {
echo
addHidden('delete_draft', $delete_draft);
if ($saved_draft ==
'yes') {
$oTemplate->assign('note', _("Draft Saved"));
$oTemplate->display('note.tpl');
if ($mail_sent ==
'yes') {
$oTemplate->assign('note', _("Your message has been sent."));
$oTemplate->display('note.tpl');
if ($compose_new_win ==
'1') {
$oTemplate->display('compose_newwin_close.tpl');
if ($location_of_buttons ==
'top') {
if (count($idents) >
1) {
foreach($idents as $id =>
$data) {
$identities[$id] =
$data['full_name'].
' <'.
$data['email_address'].
'>';
$oTemplate->assign('identities', $identities);
$oTemplate->assign('identity_def', $identity);
$oTemplate->assign('input_onfocus', 'onfocus="'.
join(' ', $onfocus_array).
'"');
$oTemplate->display('compose_header.tpl');
if ($location_of_buttons ==
'between') {
if ($use_signature ==
true &&
$newmail ==
true &&
!isset
($from_htmladdr_search)) {
$signature =
$idents[$identity]['signature'];
* FIXME: test is specific to ja_JP translation implementation.
* This test might apply incorrect conversion to other translations, but
* use of 7bit iso-2022-jp charset in other translations might have other
if ($default_charset ==
'iso-2022-jp') {
$body_str =
"\n\n".
($prefix_sig==
true?
"-- \n":
'').
mb_convert_encoding($signature, 'EUC-JP');
$body_str =
"\n\n".
($prefix_sig==
true?
"-- \n":
'').
decodeHeader($signature,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');
$body_str .=
"\n\n".
($prefix_sig==
true?
"-- \n":
'').
decodeHeader($signature,false,false);
$oTemplate->assign('editor_width', (int)
$editor_size);
$oTemplate->assign('editor_height', (int)
$editor_height);
$oTemplate->assign('input_onfocus', 'onfocus="'.
join(' ', $onfocus_array).
'"');
$oTemplate->assign('body', $body_str);
$oTemplate->assign('show_bottom_send', $location_of_buttons!=
'bottom');
$oTemplate->display ('compose_body.tpl');
if ($location_of_buttons ==
'bottom') {
/* This code is for attachments */
if ((bool)
ini_get('file_uploads')) {
/* Calculate the max size for an uploaded file.
* This is advisory for the user because we can't actually prevent
* people to upload too large files. */
/* php.ini vars which influence the max for uploads */
$configvars =
array('post_max_size', 'memory_limit', 'upload_max_filesize');
foreach($configvars as $var) {
/* skip 0 or empty values, and -1 which means 'unlimited' */
if ($composeMessage->entities) {
foreach ($composeMessage->entities as $key =>
$attachment) {
$attached_file =
$attachment->att_local_name;
if ($attachment->att_local_name ||
$attachment->body_part) {
$attached_filename =
decodeHeader($attachment->mime_header->getParameter('name'));
$type =
$attachment->mime_header->type0.
'/'.
$attachment->mime_header->type1;
$a['FileName'] =
$attached_filename;
$a['ContentType'] =
$type;
$oTemplate->assign('max_file_size', empty($max) ? -
1 :
$max);
$oTemplate->assign('attachments', $attach);
$oTemplate->display('compose_attachments.tpl');
} // End of file_uploads if-block
/* End of attachment code */
store the complete ComposeMessages array in a hidden input value
so we can restore them in case of a session timeout.
addHidden('composesession', $composesession).
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. */
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.")
if ($compose_new_win==
'1') {
$oTemplate->display('compose_newwin_close.tpl');
$oErrorHandler->setDelayedErrors(false);
$oTemplate->display('footer.tpl');
global $use_javascript_addr_book, $save_as_draft,
$request_mdn, $request_dr,
global $oTemplate, $buffer_hook;
if ($default_use_priority) {
$priorities =
array('1'=>
_("High"), '3'=>
_("Normal"), '5'=>
_("Low"));
$priority = isset
($mailprio) ?
$mailprio :
3;
$mdn_user_support=
getPref($data_dir, $username, 'mdn_user_support',$default_use_mdn);
if ($use_javascript_addr_book) {
$addr_book =
" <script type=\"text/javascript\"><!--\n document.write(\"".
" <input type=button value=\\\"".
_("Addresses").
"\\\" onclick=\\\"javascript:open_abook();\\\" />\");".
" // --></script><noscript>\n".
' <input type="submit" name="html_addr_search" value="'.
$addr_book =
' <input type="submit" name="html_addr_search" value="'.
_("Addresses").
'" />' .
"\n";
$oTemplate->assign('allow_priority', $default_use_priority==
1);
$oTemplate->assign('priority_list', $priorities);
$oTemplate->assign('current_priority', $priority);
$oTemplate->assign('notifications_enabled', $mdn_user_support==
1);
$oTemplate->assign('read_receipt', $request_mdn==
'1');
$oTemplate->assign('delivery_receipt', $request_dr==
'1');
$oTemplate->assign('drafts_enabled', $save_as_draft);
$oTemplate->assign('address_book_button', $addr_book);
$oTemplate->display('compose_buttons.tpl');
* I implemented the $show variable because the error messages
* were getting sent before the page header. So, I check once
* using $show=false, and then when i'm ready to display the error
global $send_to, $send_to_bcc;
if ($send_to ==
'' &&
$send_to_bcc ==
'') {
} /* function checkInput() */
/* get out of here if no file was attached at all */
$hashed_attachment_dir =
getHashedDir($username, $attachment_dir);
$full_localfilename =
"$hashed_attachment_dir/$localfilename";
$full_localfilename =
"$hashed_attachment_dir/$localfilename";
// m_u_f works better with restricted PHP installs (safe_mode, open_basedir),
// if that doesn't work, try a simple rename.
if (!@rename($_FILES['attachfile']['tmp_name'], $full_localfilename)) {
$message =
$compose_messages[$session];
$type =
strtolower($_FILES['attachfile']['type']);
$name =
$_FILES['attachfile']['name'];
$message->initAttachment($type, $name, $full_localfilename);
$compose_messages[$session] =
$message;
/* parse values like 8M and 2k into bytes */
$ini_size =
trim($ini_size);
// if there's some kind of letter at the end of the string we need to multiply.
return ($bytesize * (int)
substr($ini_size, 0, -
1));
* temporary function to make use of the deliver class.
* In the future the responsible backend should be automaticly loaded
* and conf.pl should show a list of available backends.
* The message also should be constructed by the message class.
global $send_to, $send_to_cc, $send_to_bcc, $mailprio, $subject, $body,
$username, $popuser, $usernamedata, $identity, $idents, $data_dir,
$domain, $action, $default_move_to_sent, $move_to_sent;
$rfc822_header =
$composeMessage->rfc822_header;
$rfc822_header->to =
$rfc822_header->parseAddress($send_to,true, array(), '', $domain, array(&$abook,'lookup'));
$rfc822_header->cc =
$rfc822_header->parseAddress($send_to_cc,true,array(), '',$domain, array(&$abook,'lookup'));
$rfc822_header->bcc =
$rfc822_header->parseAddress($send_to_bcc,true, array(), '',$domain, array(&$abook,'lookup'));
$rfc822_header->priority =
$mailprio;
$rfc822_header->subject =
$subject;
if (strtolower($default_charset) ==
'iso-2022-jp') {
if (mb_detect_encoding($body) ==
'ASCII') {
$special_encoding =
'8bit';
$body =
mb_convert_encoding($body, 'JIS');
$special_encoding =
'7bit';
$composeMessage->setBody($body);
if (ereg("^([^@%/]+)[@%/](.+)$", $username, $usernamedata)) {
$popuser =
$usernamedata[1];
$domain =
$usernamedata[2];
$from_mail =
$idents[$identity]['email_address'];
$full_name =
$idents[$identity]['full_name'];
$reply_to =
$idents[$identity]['reply_to'];
$from_mail =
"$popuser@$domain";
$rfc822_header->from =
$rfc822_header->parseAddress($from_mail,true);
$from =
$rfc822_header->from[0];
if (!$from->host) $from->host =
$domain;
if ($full_name_encoded !=
$full_name) {
$from_addr =
$full_name_encoded .
' <'.
$from->mailbox.
'@'.
$from->host.
'>';
$from_addr =
'"'.
$full_name .
'" <'.
$from->mailbox.
'@'.
$from->host.
'>';
$rfc822_header->from =
$rfc822_header->parseAddress($from_addr,true);
$rfc822_header->reply_to =
$rfc822_header->parseAddress($reply_to,true);
if (isset
($request_mdn) &&
$request_mdn) {
$rfc822_header->dnt =
$rfc822_header->parseAddress($from_mail,true);
} elseif (isset
($rfc822_header->dnt)) {
unset
($rfc822_header->dnt);
/* Receipt: On Delivery */
if (isset
($request_dr) &&
$request_dr) {
$rfc822_header->more_headers['Return-Receipt-To'] =
$from_mail;
} elseif (isset
($rfc822_header->more_headers['Return-Receipt-To'])) {
unset
($rfc822_header->more_headers['Return-Receipt-To']);
if (count($composeMessage->entities)) {
$message_body->body_part =
$composeMessage->body_part;
$composeMessage->body_part =
'';
$mime_header->type0 =
'text';
$mime_header->type1 =
'plain';
$mime_header->encoding =
$special_encoding;
$mime_header->encoding =
'8bit';
$mime_header->parameters['charset'] =
$default_charset;
$message_body->mime_header =
$mime_header;
$rfc822_header->encoding =
$special_encoding;
$rfc822_header->encoding =
'8bit';
$content_type->properties['charset']=
$default_charset;
$rfc822_header->content_type =
$content_type;
$composeMessage->rfc822_header =
$rfc822_header;
/* Here you can modify the message structure just before we hand
$hookReturn =
do_hook('compose_send', $composeMessage);
/* Get any changes made by plugins to $composeMessage. */
$composeMessage =
$hookReturn[1];
if (!$useSendmail &&
!$draft) {
require_once(SM_PATH .
'class/deliver/Deliver_SMTP.class.php');
$authPop =
(isset
($pop_before_smtp) &&
$pop_before_smtp) ?
true :
false;
$stream =
$deliver->initStream($composeMessage,$domain,0,
$smtpServerAddress, $smtpPort, $user, $pass, $authPop);
require_once(SM_PATH .
'class/deliver/Deliver_SendMail.class.php');
// Check for outdated configuration
if (!isset
($sendmail_args)) {
if ($sendmail_path==
'/var/qmail/bin/qmail-inject') {
$sendmail_args =
'-i -t';
$stream =
$deliver->initStream($composeMessage,$sendmail_path);
require_once(SM_PATH .
'class/deliver/Deliver_IMAP.class.php');
$imap_stream =
sqimap_login($username, false, $imapServerAddress,
require_once(SM_PATH .
'class/deliver/Deliver_IMAP.class.php');
$length =
$imap_deliver->mail($composeMessage);
$imap_deliver->mail($composeMessage, $imap_stream);
$composeMessage->purgeAttachments();
$length =
$deliver->mail($composeMessage, $stream);
$success =
$deliver->finalizeStream($stream);
// $deliver->dlv_server_msg is not always server's reply
$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
_("Server replied:") .
' ' .
$deliver->dlv_ret_nr .
' ' .
$move_to_sent =
getPref($data_dir,$username,'move_to_sent');
$imap_stream =
sqimap_login($username, false, $imapServerAddress, $imapPort, 0);
if (isset
($default_move_to_sent) &&
($default_move_to_sent !=
0)) {
if (isset
($sent_folder) &&
(($sent_folder !=
'') ||
($sent_folder !=
'none'))
if ((isset
($move_to_sent) &&
($move_to_sent !=
0)) ||
(!isset
($move_to_sent))) {
if (($fld_sent &&
$svr_allow_sent &&
!$lcl_allow_sent) ||
($fld_sent &&
$lcl_allow_sent)) {
global $passed_id, $mailbox, $action;
if ($action ==
'reply' ||
$action ==
'reply_all') {
$save_reply_with_orig=
getPref($data_dir,$username,'save_reply_with_orig');
if ($save_reply_with_orig) {
require_once(SM_PATH .
'class/deliver/Deliver_IMAP.class.php');
$imap_deliver->mail($composeMessage, $imap_stream);
global $passed_id, $mailbox, $action, $what, $iAccount,$startMessage;
$composeMessage->purgeAttachments();
if ($action ==
'reply' ||
$action ==
'reply_all') {
require
(SM_PATH .
'functions/mailbox_display.php');
$aMailbox =
sqm_api_mailbox_select($imap_stream, $iAccount, $mailbox,array('setindex' =>
$what, 'offset' =>
$startMessage),array());
// check if we are allowed to set the \\Answered flag
if (in_array('\\answered',$aMailbox['PERMANENTFLAGS'], true)) {
$aUpdatedMsgs =
sqimap_toggle_flag($imap_stream, array($passed_id), '\\Answered', true, false);
if (isset
($aUpdatedMsgs[$passed_id]['FLAGS'])) {
* Only update the cached headers if the header is
if (isset
($aMailbox['MSG_HEADERS'][$passed_id])) {
$aMailbox['MSG_HEADERS'][$passed_id]['FLAGS'] =
$aMsg['FLAGS'];
* Write mailbox with updated seen flag information back to cache.
$mailbox_cache[$iAccount.
'_'.
$aMailbox['NAME']] =
$aMailbox;
Documentation generated on Sat, 07 Oct 2006 16:09:39 +0300 by phpDocumentor 1.3.0RC6