Fix broken file downloads
[squirrelmail.git] / src / compose.php
CommitLineData
59177427 1<?php
35586184 2/**
3 * compose.php
4 *
35586184 5 * This code sends a mail.
6 *
7 * There are 4 modes of operation:
8 * - Start new mail
9 * - Add an attachment
10 * - Send mail
11 * - Save As Draft
12 *
4b5049de 13 * @copyright &copy; 1999-2007 The SquirrelMail Project Team
4b4abf93 14 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
30967a1e 15 * @version $Id$
8f6f9ba5 16 * @package squirrelmail
35586184 17 */
f7fb20fe 18
ebd2391c 19/** This is the compose page */
20define('PAGE_NAME', 'compose');
21
30967a1e 22/**
202bcbcc 23 * Include the SquirrelMail initialization file.
30967a1e 24 */
202bcbcc 25require('../include/init.php');
86725763 26
c90271cb 27/* If email_address not set and admin wants us to ask user for it,
28 * redirect to options page. */
29if ( $ask_user_info && getPref($data_dir, $username,'email_address') == "" ) {
30 header("Location: " . get_location() . "/options.php?optpage=personal");
31 exit;
32}
33
86725763 34/* SquirrelMail required files. */
202bcbcc 35require_once(SM_PATH . 'functions/imap_general.php');
36require_once(SM_PATH . 'functions/imap_messages.php');
86725763 37require_once(SM_PATH . 'functions/date.php');
38require_once(SM_PATH . 'functions/mime.php');
628bce99 39require_once(SM_PATH . 'functions/compose.php');
86725763 40require_once(SM_PATH . 'class/deliver/Deliver.class.php');
24192f77 41require_once(SM_PATH . 'functions/addressbook.php');
df96b37a 42require_once(SM_PATH . 'functions/forms.php');
a2b193bc 43require_once(SM_PATH . 'functions/identity.php');
91f2085b 44
0b97a708 45/* --------------------- Get globals ------------------------------------- */
0b97a708 46
953fa718 47/** SESSION VARS */
953fa718 48sqgetGlobalVar('delimiter', $delimiter, SQ_SESSION);
49
f8eb968d 50sqgetGlobalVar('delayed_errors', $delayed_errors, SQ_SESSION);
953fa718 51sqgetGlobalVar('composesession', $composesession, SQ_SESSION);
52sqgetGlobalVar('compose_messages', $compose_messages, SQ_SESSION);
f8eb968d 53
54// compose_messages only useful in SESSION when a forward-as-attachment
55// has been preconstructed for us and passed in via that mechanism; once
56// we have it, we can clear it from the SESSION
57sqsession_unregister('compose_messages');
762853f4 58
59// Turn on delayed error handling in case we wind up redirecting below
60$oErrorHandler->setDelayedErrors(true);
953fa718 61
62/** SESSION/POST/GET VARS */
567dc524 63sqgetGlobalVar('send', $send, SQ_POST);
64// Send can only be achieved by setting $_POST var. If Send = true then
65// retrieve other form fields from $_POST
66if (isset($send) && $send) {
67 $SQ_GLOBAL = SQ_POST;
68} else {
69 $SQ_GLOBAL = SQ_FORM;
70}
71sqgetGlobalVar('session',$session, $SQ_GLOBAL);
72sqgetGlobalVar('mailbox',$mailbox, $SQ_GLOBAL);
73if(!sqgetGlobalVar('identity',$identity, $SQ_GLOBAL)) {
1e2a6ff6 74 $identity=0;
75}
567dc524 76sqgetGlobalVar('send_to',$send_to, $SQ_GLOBAL);
77sqgetGlobalVar('send_to_cc',$send_to_cc, $SQ_GLOBAL);
78sqgetGlobalVar('send_to_bcc',$send_to_bcc, $SQ_GLOBAL);
79sqgetGlobalVar('subject',$subject, $SQ_GLOBAL);
80sqgetGlobalVar('body',$body, $SQ_GLOBAL);
81sqgetGlobalVar('mailprio',$mailprio, $SQ_GLOBAL);
82sqgetGlobalVar('request_mdn',$request_mdn, $SQ_GLOBAL);
83sqgetGlobalVar('request_dr',$request_dr, $SQ_GLOBAL);
84sqgetGlobalVar('html_addr_search',$html_addr_search, $SQ_GLOBAL);
85sqgetGlobalVar('mail_sent',$mail_sent, $SQ_GLOBAL);
86sqgetGlobalVar('passed_id',$passed_id, $SQ_GLOBAL);
87sqgetGlobalVar('passed_ent_id',$passed_ent_id, $SQ_GLOBAL);
12a0ed01 88
567dc524 89sqgetGlobalVar('attach',$attach, SQ_POST);
90sqgetGlobalVar('draft',$draft, SQ_POST);
91sqgetGlobalVar('draft_id',$draft_id, $SQ_GLOBAL);
92sqgetGlobalVar('ent_num',$ent_num, $SQ_GLOBAL);
93sqgetGlobalVar('saved_draft',$saved_draft, SQ_FORM);
7e2ff844 94
95if ( sqgetGlobalVar('delete_draft',$delete_draft) ) {
96 $delete_draft = (int)$delete_draft;
97}
98
a6d3eff6 99if ( sqgetGlobalVar('startMessage',$startMessage) ) {
100 $startMessage = (int)$startMessage;
101} else {
102 $startMessage = 1;
103}
953fa718 104
8780308f 105
953fa718 106/** POST VARS */
167c6996 107sqgetGlobalVar('sigappend', $sigappend, SQ_POST);
108sqgetGlobalVar('from_htmladdr_search', $from_htmladdr_search, SQ_POST);
109sqgetGlobalVar('addr_search_done', $html_addr_search_done, SQ_POST);
110sqgetGlobalVar('addr_search_cancel', $html_addr_search_cancel, SQ_POST);
111sqgetGlobalVar('send_to_search', $send_to_search, SQ_POST);
112sqgetGlobalVar('do_delete', $do_delete, SQ_POST);
113sqgetGlobalVar('delete', $delete, SQ_POST);
f8eb968d 114sqgetGlobalVar('attachments', $attachments, SQ_POST);
953fa718 115if ( sqgetGlobalVar('return', $temp, SQ_POST) ) {
73ad81bf 116 $html_addr_search_done = 'Use Addresses';
953fa718 117}
118
119/** GET VARS */
8780308f 120if ( sqgetGlobalVar('account', $temp, SQ_GET) ) {
121 $iAccount = (int) $temp;
122} else {
123 $iAccount = 0;
124}
125
0b97a708 126
98a9cc03 127/** get smaction */
128if ( !sqgetGlobalVar('smaction',$action) )
129{
73ad81bf 130 if ( sqgetGlobalVar('smaction_reply',$tmp) ) $action = 'reply';
131 if ( sqgetGlobalVar('smaction_reply_all',$tmp) ) $action = 'reply_all';
132 if ( sqgetGlobalVar('smaction_forward',$tmp) ) $action = 'forward';
133 if ( sqgetGlobalVar('smaction_attache',$tmp) ) $action = 'forward_as_attachment';
134 if ( sqgetGlobalVar('smaction_draft',$tmp) ) $action = 'draft';
135 if ( sqgetGlobalVar('smaction_edit_new',$tmp) ) $action = 'edit_as_new';
98a9cc03 136}
137
7e2ff844 138/**
139 * Here we decode the data passed in from mailto.php.
140 */
141if ( sqgetGlobalVar('mailtodata', $mailtodata, SQ_GET) ) {
142 $trtable = array('to' => 'send_to',
143 'cc' => 'send_to_cc',
144 'bcc' => 'send_to_bcc',
145 'body' => 'body',
146 'subject' => 'subject');
147 $mtdata = unserialize($mailtodata);
1638beb6 148
7e2ff844 149 foreach ($trtable as $f => $t) {
150 if ( !empty($mtdata[$f]) ) {
151 $$t = $mtdata[$f];
152 }
153 }
154 unset($mailtodata,$mtdata, $trtable);
155}
156
39cf816f 157/* Location (For HTTP 1.1 header("Location: ...") redirects) */
3461167c 158$location = get_location();
1e2a6ff6 159/* Identities (fetch only once) */
160$idents = get_identities();
3461167c 161
09044055 162/* --------------------- Specific Functions ------------------------------ */
0b97a708 163
41b94d65 164function replyAllString($header) {
73ad81bf 165 global $include_self_reply_all, $idents;
166 $excl_ar = array();
167 /**
168 * 1) Remove the addresses we'll be sending the message 'to'
169 */
af084f6e 170 if (isset($header->reply_to)) {
171 $excl_ar = $header->getAddr_a('reply_to');
73ad81bf 172 }
173 /**
174 * 2) Remove our identities from the CC list (they still can be in the
175 * TO list) only if $include_self_reply_all is turned off
176 */
177 if (!$include_self_reply_all) {
178 foreach($idents as $id) {
179 $excl_ar[strtolower(trim($id['email_address']))] = '';
180 }
181 }
182
183 /**
184 * 3) get the addresses.
185 */
186 $url_replytoall_ar = $header->getAddr_a(array('to','cc'), $excl_ar);
187
188 /**
189 * 4) generate the string.
190 */
191 $url_replytoallcc = '';
192 foreach( $url_replytoall_ar as $email => $personal) {
193 if ($personal) {
194 // if personal name contains address separator then surround
195 // the personal name with double quotes.
196 if (strpos($personal,',') !== false) {
197 $personal = '"'.$personal.'"';
198 }
199 $url_replytoallcc .= ", $personal <$email>";
200 } else {
201 $url_replytoallcc .= ', '. $email;
1e2a6ff6 202 }
73ad81bf 203 }
204 $url_replytoallcc = substr($url_replytoallcc,2);
205
206 return $url_replytoallcc;
09044055 207}
208
50706f77 209/**
210 * creates top line in reply citations
211 *
212 * Line style depends on user preferences.
213 * $orig_date argument is available only from 1.4.3 and 1.5.1 version.
214 * @param object $orig_from From: header object.
215 * @param integer $orig_date email's timestamp
216 * @return string reply citation
217 */
b0323712 218function getReplyCitation($orig_from, $orig_date) {
12a0ed01 219 global $reply_citation_style, $reply_citation_start, $reply_citation_end;
50706f77 220
05f7db7a 221 if (!is_object($orig_from)) {
d1205176 222 $sOrig_from = '';
05f7db7a 223 } else {
d1205176 224 $sOrig_from = decodeHeader($orig_from->getAddress(false),false,false,true);
05f7db7a 225 }
91c27aee 226
12a0ed01 227 /* First, return an empty string when no citation style selected. */
228 if (($reply_citation_style == '') || ($reply_citation_style == 'none')) {
229 return '';
230 }
231
232 /* Make sure our final value isn't an empty string. */
d1205176 233 if ($sOrig_from == '') {
12a0ed01 234 return '';
235 }
236
237 /* Otherwise, try to select the desired citation style. */
238 switch ($reply_citation_style) {
50706f77 239 case 'author_said':
b986936a 240 // i18n: %s is for author's name
d1205176 241 $full_reply_citation = sprintf(_("%s wrote:"),$sOrig_from);
50706f77 242 break;
243 case 'quote_who':
a42c236f 244 $start = '<quote who="';
50706f77 245 $end = '">';
d1205176 246 $full_reply_citation = $start . $sOrig_from . $end;
50706f77 247 break;
248 case 'date_time_author':
b986936a 249 // i18n:
250 // The first %s is for date string, the second %s is for author's name.
251 // The date uses formating from "D, F j, Y g:i a" and "D, F j, Y H:i"
252 // translations.
253 // Example string:
254 // "On Sat, December 24, 2004 23:59, Santa wrote:"
255 // If you have to put author's name in front of date string, check comments about
256 // argument swapping at http://php.net/sprintf
d1205176 257 $full_reply_citation = sprintf(_("On %s, %s wrote:"), getLongDateString($orig_date), $sOrig_from);
50706f77 258 break;
259 case 'user-defined':
260 $start = $reply_citation_start .
261 ($reply_citation_start == '' ? '' : ' ');
262 $end = $reply_citation_end;
d1205176 263 $full_reply_citation = $start . $sOrig_from . $end;
50706f77 264 break;
265 default:
266 return '';
267 }
268
269 /* Add line feed and return the citation string. */
270 return ($full_reply_citation . "\n");
12a0ed01 271}
272
50706f77 273/**
274 * Creates header fields in forwarded email body
275 *
91c27aee 276 * $default_charset global must be set correctly before you call this function.
50706f77 277 * @param object $orig_header
91c27aee 278 * @return $string
50706f77 279 */
41b94d65 280function getforwardHeader($orig_header) {
50706f77 281 global $editor_size, $default_charset;
282
283 // using own strlen function in order to detect correct string length
284 $display = array( _("Subject") => sq_strlen(_("Subject"),$default_charset),
285 _("From") => sq_strlen(_("From"),$default_charset),
286 _("Date") => sq_strlen(_("Date"),$default_charset),
287 _("To") => sq_strlen(_("To"),$default_charset),
288 _("Cc") => sq_strlen(_("Cc"),$default_charset) );
73ad81bf 289 $maxsize = max($display);
290 $indent = str_pad('',$maxsize+2);
291 foreach($display as $key => $val) {
292 $display[$key] = $key .': '. str_pad('', $maxsize - $val);
293 }
294 $from = decodeHeader($orig_header->getAddr_s('from',"\n$indent"),false,false,true);
295 $from = str_replace('&nbsp;',' ',$from);
296 $to = decodeHeader($orig_header->getAddr_s('to',"\n$indent"),false,false,true);
297 $to = str_replace('&nbsp;',' ',$to);
298 $subject = decodeHeader($orig_header->subject,false,false,true);
299 $subject = str_replace('&nbsp;',' ',$subject);
50706f77 300
301 // using own str_pad function in order to create correct string pad
302 $bodyTop = sq_str_pad(' '._("Original Message").' ',$editor_size -2,'-',STR_PAD_BOTH,$default_charset) .
73ad81bf 303 "\n". $display[_("Subject")] . $subject . "\n" .
304 $display[_("From")] . $from . "\n" .
3aaa3214 305 $display[_("Date")] . getLongDateString( $orig_header->date, $orig_header->date_unparsed ). "\n" .
73ad81bf 306 $display[_("To")] . $to . "\n";
307 if ($orig_header->cc != array() && $orig_header->cc !='') {
308 $cc = decodeHeader($orig_header->getAddr_s('cc',"\n$indent"),false,false,true);
309 $cc = str_replace('&nbsp;',' ',$cc);
310 $bodyTop .= $display[_("Cc")] .$cc . "\n";
311 }
312 $bodyTop .= str_pad('', $editor_size -2 , '-') .
313 "\n\n";
314 return $bodyTop;
41b94d65 315}
09044055 316/* ----------------------------------------------------------------------- */
317
44560457 318/*
1c044820 319 * If the session is expired during a post this restores the compose session
44560457 320 * vars.
321 */
f8eb968d 322$session_expired = false;
5da08ef7 323if (sqsession_is_registered('session_expired_post')) {
953fa718 324 sqgetGlobalVar('session_expired_post', $session_expired_post, SQ_SESSION);
1c044820 325 /*
40934000 326 * extra check for username so we don't display previous post data from
327 * another user during this session.
328 */
c7ebdfcf 329 if (!empty($session_expired_post['username'])
330 && $session_expired_post['username'] == $username) {
1638beb6 331 // these are the vars that we can set from the expired composed session
f8eb968d 332 $compo_var_list = array ('send_to', 'send_to_cc', 'body',
333 'startMessage', 'passed_body', 'use_signature', 'signature',
334 'subject', 'newmail', 'send_to_bcc', 'passed_id', 'mailbox',
335 'from_htmladdr_search', 'identity', 'draft_id', 'delete_draft',
336 'mailprio', 'edit_as_new', 'attachments', 'composesession',
337 'request_mdn', 'request_dr');
c6f28eb1 338
339 foreach ($compo_var_list as $var) {
340 if ( isset($session_expired_post[$var]) && !isset($$var) ) {
774d79cc 341 $$var = $session_expired_post[$var];
61e96f7e 342 }
40934000 343 }
c6f28eb1 344
f8eb968d 345 if (!empty($attachments))
177cb345 346 $attachments = unserialize(urldecode($attachments));
f8eb968d 347
0ec1a14b 348 sqsession_register($composesession,'composesession');
f8eb968d 349
40934000 350 if (isset($send)) {
351 unset($send);
352 }
353 $session_expired = true;
354 }
5da08ef7 355 unset($session_expired_post);
0b97a708 356 sqsession_unregister('session_expired_post');
5da08ef7 357 session_write_close();
40934000 358 if (!isset($mailbox)) {
359 $mailbox = '';
360 }
361 if ($compose_new_win == '1') {
362 compose_Header($color, $mailbox);
363 } else {
91c27aee 364 $sHeaderJs = (isset($sHeaderJs)) ? $sHeaderJs : '';
365 if (strpos($action, 'reply') !== false && $reply_focus) {
366 $sBodyTagJs = 'onload="checkForm(\''.$replyfocus.'\');"';
367 } else {
368 $sBodyTagJs = 'onload="checkForm();"';
369 }
370 displayPageHeader($color, $mailbox,$sHeaderJs,$sBodyTagJs);
40934000 371 }
372 showInputForm($session, false);
373 exit();
44560457 374}
f8eb968d 375
da95c4b6 376if (!isset($composesession)) {
377 $composesession = 0;
a43e4b90 378 sqsession_register(0,'composesession');
7e2ff844 379} else {
380 $composesession = (int)$composesession;
da95c4b6 381}
382
d7f8e6e6 383if (!isset($session) || (isset($newmessage) && $newmessage)) {
0b97a708 384 sqsession_unregister('composesession');
1c044820 385 $session = "$composesession" +1;
91f2085b 386 $composesession = $session;
a43e4b90 387 sqsession_register($composesession,'composesession');
1c044820 388}
b4e7df34 389if (!empty($compose_messages[$session])) {
390 $composeMessage = $compose_messages[$session];
391} else {
73ad81bf 392 $composeMessage = new Message();
393 $rfc822_header = new Rfc822Header();
394 $composeMessage->rfc822_header = $rfc822_header;
395 $composeMessage->reply_rfc822_header = '';
a43e4b90 396}
a43e4b90 397
f8eb968d 398// re-add attachments that were already in this message
399// FIXME: note that technically this is very bad form -
400// should never directly manipulate an object like this
401if (!empty($attachments)) {
177cb345 402 $attachments = unserialize(urldecode($attachments));
f8eb968d 403 if (!empty($attachments) && is_array($attachments))
404 $composeMessage->entities = $attachments;
405}
406
876fdb60 407if (empty($mailbox)) {
00793a25 408 $mailbox = 'INBOX';
409}
410
4dfb9db7 411if ($draft) {
412 /*
413 * Set $default_charset to correspond with the user's selection
414 * of language interface.
415 */
416 set_my_charset();
b7ff469f 417 if (! deliverMessage($composeMessage, true)) {
da95c4b6 418 showInputForm($session);
00793a25 419 exit();
734f4ee6 420 } else {
00793a25 421 $draft_message = _("Draft Email Saved");
422 /* If this is a resumed draft, then delete the original */
423 if(isset($delete_draft)) {
906f7e9f 424 $imap_stream = sqimap_login($username, false, $imapServerAddress, $imapPort, false);
b034bca2 425 sqimap_mailbox_select($imap_stream, $draft_folder);
426 // force bypass_trash=true because message should be saved when deliverMessage() returns true.
91c27aee 427 // in current implementation of sqimap_msgs_list_flag() single message id can
b034bca2 428 // be submitted as string. docs state that it should be array.
429 sqimap_msgs_list_delete($imap_stream, $draft_folder, $delete_draft, true);
430 if ($auto_expunge) {
431 sqimap_mailbox_expunge($imap_stream, $draft_folder, true);
9c3e6cd4 432 }
b034bca2 433 sqimap_logout($imap_stream);
434 }
1638beb6 435
762853f4 436 $oErrorHandler->saveDelayedErrors();
c077ffeb 437 session_write_close();
762853f4 438
b034bca2 439 if ($compose_new_win == '1') {
09047d19 440 if ( !isset($pageheader_sent) || !$pageheader_sent ) {
39cf816f 441 header("Location: $location/compose.php?saved_draft=yes&session=$composesession");
09047d19 442 } else {
c8dc86c9 443//FIXME: DON'T ECHO HTML FROM CORE!
f265009a 444 echo ' <br><br><div style="text-align: center;"><a href="' . $location
09047d19 445 . '/compose.php?saved_sent=yes&amp;session=' . $composesession . '">'
f265009a 446 . _("Return") . '</a></div>';
a6d3eff6 447 }
b034bca2 448 exit();
449 } else {
09047d19 450 if ( !isset($pageheader_sent) || !$pageheader_sent ) {
39cf816f 451 header("Location: $location/right_main.php?mailbox=" . urlencode($draft_folder) .
b034bca2 452 "&startMessage=1&note=".urlencode($draft_message));
09047d19 453 } else {
c8dc86c9 454//FIXME: DON'T ECHO HTML FROM CORE!
f265009a 455 echo ' <br><br><div style="text-align: center;"><a href="' . $location
09047d19 456 . '/right_main.php?mailbox=' . urlencode($draft_folder)
457 . '&amp;startMessage=1&amp;note=' . urlencode($draft_message) .'">'
f265009a 458 . _("Return") . '</a></div>';
a6d3eff6 459 }
b034bca2 460 exit();
00793a25 461 }
462 }
463}
464
4dfb9db7 465if ($send) {
0b97a708 466 if (isset($_FILES['attachfile']) &&
73ad81bf 467 $_FILES['attachfile']['tmp_name'] &&
468 $_FILES['attachfile']['tmp_name'] != 'none') {
da95c4b6 469 $AttachFailure = saveAttachedFiles($session);
00793a25 470 }
471 if (checkInput(false) && !isset($AttachFailure)) {
73ad81bf 472 if ($mailbox == "All Folders") {
473 /* We entered compose via the search results page */
a42c236f 474 $mailbox = 'INBOX'; /* Send 'em to INBOX, that's safe enough */
73ad81bf 475 }
9a19cc66 476 $urlMailbox = urlencode($mailbox);
3f6b1b6f 477 if (! isset($passed_id)) {
478 $passed_id = 0;
00793a25 479 }
d4c5c50c 480 /**
00793a25 481 * Set $default_charset to correspond with the user's selection
7058a2a9 482 * of language interface.
00793a25 483 */
484 set_my_charset();
d4c5c50c 485 /**
00793a25 486 * This is to change all newlines to \n
7058a2a9 487 * We'll change them to \r\n later (in the sendMessage function)
00793a25 488 */
489 $body = str_replace("\r\n", "\n", $body);
490 $body = str_replace("\r", "\n", $body);
491
d4c5c50c 492 /**
18c9998a 493 * Rewrap $body so that no line is bigger than $editor_size
00793a25 494 */
18c9998a 495 $body = explode("\n", $body);
496 $newBody = '';
497 foreach ($body as $line) {
498 if( $line <> '-- ' ) {
73ad81bf 499 $line = rtrim($line);
18c9998a 500 }
774d79cc 501 if (sq_strlen($line, $default_charset) <= $editor_size + 1) {
18c9998a 502 $newBody .= $line . "\n";
503 } else {
774d79cc 504 sqWordWrap($line, $editor_size, $default_charset);
18c9998a 505 $newBody .= $line . "\n";
506
507 }
508
509 }
510 $body = $newBody;
1c044820 511
a91189d6 512 $Result = deliverMessage($composeMessage);
81de00c0 513
64793f9a 514 if ($Result)
515 $mail_sent = 'yes';
516 else
517 $mail_sent = 'no';
518
1638beb6 519 // NOTE: this hook changed in 1.5.2 from sending $Result and
6e515418 520 // $composeMessage as args #2 and #3 to being in an array
521 // under arg #2
802e7490 522 $temp = array(&$Result, &$composeMessage, &$mail_sent);
523 do_hook('compose_send_after', $temp);
00793a25 524 if (! $Result) {
da95c4b6 525 showInputForm($session);
00793a25 526 exit();
527 }
5c4ff7bf 528
b034bca2 529 /* if it is resumed draft, delete draft message */
00793a25 530 if ( isset($delete_draft)) {
906f7e9f 531 $imap_stream = sqimap_login($username, false, $imapServerAddress, $imapPort, false);
b034bca2 532 sqimap_mailbox_select($imap_stream, $draft_folder);
533 // bypass_trash=true because message should be saved when deliverMessage() returns true.
91c27aee 534 // in current implementation of sqimap_msgs_list_flag() single message id can
b034bca2 535 // be submitted as string. docs state that it should be array.
536 sqimap_msgs_list_delete($imap_stream, $draft_folder, $delete_draft, true);
537 if ($auto_expunge) {
538 sqimap_mailbox_expunge($imap_stream, $draft_folder, true);
539 }
540 sqimap_logout($imap_stream);
00793a25 541 }
81de00c0 542 /*
543 * Store the error array in the session because they will be lost on a redirect
544 */
762853f4 545 $oErrorHandler->saveDelayedErrors();
c077ffeb 546 session_write_close();
762853f4 547
9c3e6cd4 548 if ($compose_new_win == '1') {
09047d19 549 if ( !isset($pageheader_sent) || !$pageheader_sent ) {
39cf816f 550 header("Location: $location/compose.php?mail_sent=$mail_sent");
09047d19 551 } else {
c8dc86c9 552//FIXME: DON'T ECHO HTML FROM CORE!
f265009a 553 echo ' <br><br><div style="text-align: center;"><a href="' . $location
64793f9a 554 . '/compose.php?mail_sent=$mail_sent">'
f265009a 555 . _("Return") . '</a></div>';
09047d19 556 }
557 exit();
558 } else {
559 if ( !isset($pageheader_sent) || !$pageheader_sent ) {
39cf816f 560 header("Location: $location/right_main.php?mailbox=$urlMailbox".
64793f9a 561 "&startMessage=$startMessage&mail_sent=$mail_sent");
09047d19 562 } else {
c8dc86c9 563//FIXME: DON'T ECHO HTML FROM CORE!
f265009a 564 echo ' <br><br><div style="text-align: center;"><a href="' . $location
09047d19 565 . "/right_main.php?mailbox=$urlMailbox"
64793f9a 566 . "&amp;startMessage=$startMessage&amp;mail_sent=$mail_sent\">"
f265009a 567 . _("Return") . '</a></div>';
09047d19 568 }
569 exit();
9c3e6cd4 570 }
734f4ee6 571 } else {
9c3e6cd4 572 if ($compose_new_win == '1') {
573 compose_Header($color, $mailbox);
574 }
575 else {
576 displayPageHeader($color, $mailbox);
577 }
00793a25 578 if (isset($AttachFailure)) {
73ad81bf 579 plain_error_message(_("Could not move/copy file. File not attached"),
580 $color);
00793a25 581 }
00793a25 582 checkInput(true);
da95c4b6 583 showInputForm($session);
00793a25 584 /* sqimap_logout($imapConnection); */
585 }
e02775fe 586} elseif (isset($html_addr_search_done)) {
73ad81bf 587 if ($compose_new_win == '1') {
588 compose_Header($color, $mailbox);
589 }
590 else {
591 displayPageHeader($color, $mailbox);
592 }
00793a25 593
594 if (isset($send_to_search) && is_array($send_to_search)) {
595 foreach ($send_to_search as $k => $v) {
596 if (substr($k, 0, 1) == 'T') {
597 if ($send_to) {
598 $send_to .= ', ';
599 }
600 $send_to .= $v;
601 }
602 elseif (substr($k, 0, 1) == 'C') {
603 if ($send_to_cc) {
604 $send_to_cc .= ', ';
605 }
606 $send_to_cc .= $v;
607 }
608 elseif (substr($k, 0, 1) == 'B') {
609 if ($send_to_bcc) {
610 $send_to_bcc .= ', ';
611 }
612 $send_to_bcc .= $v;
613 }
614 }
615 }
da95c4b6 616 showInputForm($session);
167c6996 617} elseif (isset($html_addr_search) && !isset($html_addr_search_cancel)) {
0b97a708 618 if (isset($_FILES['attachfile']) &&
73ad81bf 619 $_FILES['attachfile']['tmp_name'] &&
620 $_FILES['attachfile']['tmp_name'] != 'none') {
0b97a708 621 if(saveAttachedFiles($session)) {
cb34dbd0 622 plain_error_message(_("Could not move/copy file. File not attached"));
00793a25 623 }
624 }
625 /*
626 * I am using an include so as to elminiate an extra unnecessary
627 * click. If you can think of a better way, please implement it.
628 */
629 include_once('./addrbook_search_html.php');
e02775fe 630} elseif (isset($attach)) {
73ad81bf 631 if ($compose_new_win == '1') {
632 compose_Header($color, $mailbox);
633 } else {
634 displayPageHeader($color, $mailbox);
635 }
5a3e52f3 636 if (saveAttachedFiles($session)) {
cb34dbd0 637 plain_error_message(_("Could not move/copy file. File not attached"));
5a3e52f3 638 }
da95c4b6 639 showInputForm($session);
01265fba 640}
641elseif (isset($sigappend)) {
1e2a6ff6 642 $signature = $idents[$identity]['signature'];
643
01265fba 644 $body .= "\n\n".($prefix_sig==true? "-- \n":'').$signature;
645 if ($compose_new_win == '1') {
73ad81bf 646 compose_Header($color, $mailbox);
01265fba 647 } else {
648 displayPageHeader($color, $mailbox);
649 }
da95c4b6 650 showInputForm($session);
e02775fe 651} elseif (isset($do_delete)) {
73ad81bf 652 if ($compose_new_win == '1') {
653 compose_Header($color, $mailbox);
654 } else {
655 displayPageHeader($color, $mailbox);
656 }
00793a25 657
00793a25 658 if (isset($delete) && is_array($delete)) {
659 foreach($delete as $index) {
a58b05b4 660 if (!empty($composeMessage->entities) && isset($composeMessage->entities[$index])) {
c077ffeb 661 $composeMessage->entities[$index]->purgeAttachments();
16449d84 662 // 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
663 //$composeMessage->entities[$index] = NULL;
a58b05b4 664 unset ($composeMessage->entities[$index]);
665 }
a91189d6 666 }
667 $new_entities = array();
668 foreach ($composeMessage->entities as $entity) {
669 $new_entities[] = $entity;
00793a25 670 }
a91189d6 671 $composeMessage->entities = $new_entities;
00793a25 672 }
da95c4b6 673 showInputForm($session);
734f4ee6 674} else {
00793a25 675 /*
676 * This handles the default case as well as the error case
1c044820 677 * (they had the same code) --> if (isset($smtpErrors))
00793a25 678 */
44560457 679
680 if ($compose_new_win == '1') {
73ad81bf 681 compose_Header($color, $mailbox);
44560457 682 } else {
73ad81bf 683 displayPageHeader($color, $mailbox);
44560457 684 }
00793a25 685
686 $newmail = true;
687
a61878d0 688 if (!isset($passed_ent_id)) {
689 $passed_ent_id = '';
690 }
691 if (!isset($passed_id)) {
1c044820 692 $passed_id = '';
a61878d0 693 }
694 if (!isset($mailbox)) {
695 $mailbox = '';
1c044820 696 }
a61878d0 697 if (!isset($action)) {
698 $action = '';
699 }
1c044820 700
44560457 701 $values = newMail($mailbox,$passed_id,$passed_ent_id, $action, $session);
b9928adc 702
703 /* in case the origin is not read_body.php */
704 if (isset($send_to)) {
73ad81bf 705 $values['send_to'] = $send_to;
b9928adc 706 }
707 if (isset($send_to_cc)) {
73ad81bf 708 $values['send_to_cc'] = $send_to_cc;
b9928adc 709 }
710 if (isset($send_to_bcc)) {
73ad81bf 711 $values['send_to_bcc'] = $send_to_bcc;
b9928adc 712 }
2a2f2185 713 if (isset($subject)) {
73ad81bf 714 $values['subject'] = $subject;
2a2f2185 715 }
41b94d65 716 showInputForm($session, $values);
00793a25 717}
718
719exit();
720
00793a25 721/**************** Only function definitions go below *************/
722
92c6f757 723function getforwardSubject($subject)
724{
725 if ((substr(strtolower($subject), 0, 4) != 'fwd:') &&
73ad81bf 726 (substr(strtolower($subject), 0, 5) != '[fwd:') &&
727 (substr(strtolower($subject), 0, 6) != '[ fwd:')) {
92c6f757 728 $subject = '[Fwd: ' . $subject . ']';
729 }
730 return $subject;
731}
00793a25 732
48985d59 733/* This function is used when not sending or adding attachments */
44560457 734function newMail ($mailbox='', $passed_id='', $passed_ent_id='', $action='', $session='') {
1e2a6ff6 735 global $editor_size, $default_use_priority, $body, $idents,
ce68b76b 736 $use_signature, $data_dir, $username,
b4e7df34 737 $key, $imapServerAddress, $imapPort,
74f66d27 738 $composeMessage, $body_quote, $request_mdn, $request_dr,
856e58ef 739 $mdn_user_support, $languages, $squirrelmail_language,
740 $default_charset;
e7f1a81d 741
d4f20027 742 /*
743 * Set $default_charset to correspond with the user's selection
744 * of language interface. $default_charset global is not correct,
745 * if message is composed in new window.
746 */
747 set_my_charset();
748
91f2085b 749 $send_to = $send_to_cc = $send_to_bcc = $subject = $identity = '';
bdb92db3 750 $mailprio = 3;
44560457 751
41b94d65 752 if ($passed_id) {
906f7e9f 753 $imapConnection = sqimap_login($username, false, $imapServerAddress,
73ad81bf 754 $imapPort, 0);
a61878d0 755
48985d59 756 sqimap_mailbox_select($imapConnection, $mailbox);
41b94d65 757 $message = sqimap_get_message($imapConnection, $passed_id, $mailbox);
1c044820 758
a61878d0 759 $body = '';
760 if ($passed_ent_id) {
761 /* redefine the messsage in case of message/rfc822 */
762 $message = $message->getEntity($passed_ent_id);
763 /* message is an entity which contains the envelope and type0=message
73ad81bf 764 * and type1=rfc822. The actual entities are childs from
765 * $message->entities[0]. That's where the encoding and is located
766 */
a61878d0 767
768 $entities = $message->entities[0]->findDisplayEntity
73ad81bf 769 (array(), $alt_order = array('text/plain'));
a61878d0 770 if (!count($entities)) {
771 $entities = $message->entities[0]->findDisplayEntity
9c462f8b 772 (array(), $alt_order = array('text/plain','text/html'));
a61878d0 773 }
774 $orig_header = $message->rfc822_header; /* here is the envelope located */
775 /* redefine the message for picking up the attachments */
776 $message = $message->entities[0];
777
778 } else {
779 $entities = $message->findDisplayEntity (array(), $alt_order = array('text/plain'));
780 if (!count($entities)) {
9c462f8b 781 $entities = $message->findDisplayEntity (array(), $alt_order = array('text/plain','text/html'));
a61878d0 782 }
783 $orig_header = $message->rfc822_header;
784 }
1c044820 785
a61878d0 786 $type0 = $message->type0;
787 $type1 = $message->type1;
41b94d65 788 foreach ($entities as $ent) {
b455e47b 789 $msg = $message->getEntity($ent);
790 $type0 = $msg->type0;
791 $type1 = $msg->type1;
a61878d0 792 $unencoded_bodypart = mime_fetch_body($imapConnection, $passed_id, $ent);
793 $body_part_entity = $message->getEntity($ent);
1638beb6 794 $bodypart = decodeBody($unencoded_bodypart,
73ad81bf 795 $body_part_entity->header->encoding);
a61878d0 796 if ($type1 == 'html') {
5b755d9f 797 $bodypart = str_replace("\n", ' ', $bodypart);
bb977394 798 $bodypart = preg_replace(array('/<\/?p>/i','/<div><\/div>/i','/<br\s*(\/)*>/i','/<\/?div>/i'), "\n", $bodypart);
5b755d9f 799 $bodypart = str_replace(array('&nbsp;','&gt;','&lt;'),array(' ','>','<'),$bodypart);
a61878d0 800 $bodypart = strip_tags($bodypart);
801 }
e842b215 802 if (isset($languages[$squirrelmail_language]['XTRA_CODE']) &&
73ad81bf 803 function_exists($languages[$squirrelmail_language]['XTRA_CODE'] . '_decode')) {
e842b215 804 if (mb_detect_encoding($bodypart) != 'ASCII') {
f4bb5d22 805 $bodypart = call_user_func($languages[$squirrelmail_language]['XTRA_CODE'] . '_decode', $bodypart);
e842b215 806 }
807 }
eceefdfe 808
bfa54da7 809 // charset encoding in compose form stuff
73ad81bf 810 if (isset($body_part_entity->header->parameters['charset'])) {
811 $actual = $body_part_entity->header->parameters['charset'];
812 } else {
813 $actual = 'us-ascii';
814 }
beca818e 815
73ad81bf 816 if ( $actual && is_conversion_safe($actual) && $actual != $default_charset){
817 $bodypart = charset_convert($actual,$bodypart,$default_charset,false);
818 }
bfa54da7 819 // end of charset encoding in compose
eceefdfe 820
a61878d0 821 $body .= $bodypart;
822 }
823 if ($default_use_priority) {
824 $mailprio = substr($orig_header->priority,0,1);
825 if (!$mailprio) {
826 $mailprio = 3;
827 }
828 } else {
829 $mailprio = '';
830 }
bdb92db3 831
a45887d7 832 $from_o = $orig_header->from;
fe868193 833 if (is_array($from_o)) {
834 if (isset($from_o[0])) {
835 $from_o = $from_o[0];
836 }
837 }
bdb92db3 838 if (is_object($from_o)) {
839 $orig_from = $from_o->getAddress();
840 } else {
841 $orig_from = '';
a61878d0 842 }
1e2a6ff6 843
a91189d6 844 $identities = array();
1e2a6ff6 845 if (count($idents) > 1) {
846 foreach($idents as $nr=>$data) {
847 $enc_from_name = '"'.$data['full_name'].'" <'. $data['email_address'].'>';
8d2d85f5 848 if(strtolower($enc_from_name) == strtolower($orig_from)) {
1e2a6ff6 849 $identity = $nr;
bc07287b 850 // don't stop! need to build $identities array for idents match below
851 //break;
a61878d0 852 }
a91189d6 853 $identities[] = $enc_from_name;
854 }
1e2a6ff6 855
a91189d6 856 $identity_match = $orig_header->findAddress($identities);
857 if ($identity_match) {
858 $identity = $identity_match;
a61878d0 859 }
bdb92db3 860 }
a61878d0 861
862 switch ($action) {
73ad81bf 863 case ('draft'):
864 $use_signature = FALSE;
865 $composeMessage->rfc822_header = $orig_header;
866 $send_to = decodeHeader($orig_header->getAddr_s('to'),false,false,true);
867 $send_to_cc = decodeHeader($orig_header->getAddr_s('cc'),false,false,true);
868 $send_to_bcc = decodeHeader($orig_header->getAddr_s('bcc'),false,false,true);
869 $send_from = $orig_header->getAddr_s('from');
870 $send_from_parts = new AddressStructure();
871 $send_from_parts = $orig_header->parseAddress($send_from);
872 $send_from_add = $send_from_parts->mailbox . '@' . $send_from_parts->host;
40e07136 873 $identity = find_identity(array($send_from_add));
73ad81bf 874 $subject = decodeHeader($orig_header->subject,false,false,true);
1638beb6 875
762853f4 876 // Remember the receipt settings
877 $request_mdn = $mdn_user_support && !empty($orig_header->dnt) ? '1' : '0';
878 $request_dr = $mdn_user_support && !empty($orig_header->drnt) ? '1' : '0';
1638beb6 879
73ad81bf 880 /* remember the references and in-reply-to headers in case of an reply */
657fe1bd 881//FIXME: it would be better to fiddle with headers inside of the message object or possibly when delivering the message to its destination (drafts folder?); is this possible?
73ad81bf 882 $composeMessage->rfc822_header->more_headers['References'] = $orig_header->references;
883 $composeMessage->rfc822_header->more_headers['In-Reply-To'] = $orig_header->in_reply_to;
884 // rewrap the body to clean up quotations and line lengths
885 sqBodyWrap($body, $editor_size);
886 $composeMessage = getAttachments($message, $composeMessage, $passed_id, $entities, $imapConnection);
887 break;
888 case ('edit_as_new'):
889 $send_to = decodeHeader($orig_header->getAddr_s('to'),false,false,true);
890 $send_to_cc = decodeHeader($orig_header->getAddr_s('cc'),false,false,true);
891 $send_to_bcc = decodeHeader($orig_header->getAddr_s('bcc'),false,false,true);
892 $subject = decodeHeader($orig_header->subject,false,false,true);
893 $mailprio = $orig_header->priority;
894 $orig_from = '';
895 $composeMessage = getAttachments($message, $composeMessage, $passed_id, $entities, $imapConnection);
896 // rewrap the body to clean up quotations and line lengths
897 sqBodyWrap($body, $editor_size);
898 break;
899 case ('forward'):
900 $send_to = '';
901 $subject = getforwardSubject(decodeHeader($orig_header->subject,false,false,true));
902 $body = getforwardHeader($orig_header) . $body;
903 // the logic for calling sqUnWordWrap here would be to allow the browser to wrap the lines
904 // forwarded message text should be as undisturbed as possible, so commenting out this call
905 // sqUnWordWrap($body);
906 $composeMessage = getAttachments($message, $composeMessage, $passed_id, $entities, $imapConnection);
91c27aee 907
73ad81bf 908 //add a blank line after the forward headers
909 $body = "\n" . $body;
910 break;
911 case ('forward_as_attachment'):
912 $subject = getforwardSubject(decodeHeader($orig_header->subject,false,false,true));
913 $composeMessage = getMessage_RFC822_Attachment($message, $composeMessage, $passed_id, $passed_ent_id, $imapConnection);
914 $body = '';
915 break;
916 case ('reply_all'):
917 if(isset($orig_header->mail_followup_to) && $orig_header->mail_followup_to) {
918 $send_to = $orig_header->getAddr_s('mail_followup_to');
b268e66b 919 } else {
73ad81bf 920 $send_to_cc = replyAllString($orig_header);
921 $send_to_cc = decodeHeader($send_to_cc,false,false,true);
b268e66b 922 }
73ad81bf 923 case ('reply'):
924 // skip this if send_to was already set right above here
925 if(!$send_to) {
926 $send_to = $orig_header->reply_to;
927 if (is_array($send_to) && count($send_to)) {
928 $send_to = $orig_header->getAddr_s('reply_to');
929 } else if (is_object($send_to)) { /* unneccesarry, just for failsafe purpose */
930 $send_to = $orig_header->getAddr_s('reply_to');
931 } else {
932 $send_to = $orig_header->getAddr_s('from');
933 }
dd4a44cd 934 }
73ad81bf 935 $send_to = decodeHeader($send_to,false,false,true);
936 $subject = decodeHeader($orig_header->subject,false,false,true);
937 $subject = str_replace('"', "'", $subject);
938 $subject = trim($subject);
939 if (substr(strtolower($subject), 0, 3) != 're:') {
940 $subject = 'Re: ' . $subject;
941 }
942 /* this corrects some wrapping/quoting problems on replies */
943 $rewrap_body = explode("\n", $body);
3aaa3214 944 $from = (is_array($orig_header->from) && !empty($orig_header->from)) ? $orig_header->from[0] : $orig_header->from;
73ad81bf 945 $body = '';
946 $strip_sigs = getPref($data_dir, $username, 'strip_sigs');
947 foreach ($rewrap_body as $line) {
948 if ($strip_sigs && substr($line,0,3) == '-- ') {
949 break;
950 }
951 if (preg_match("/^(>+)/", $line, $matches)) {
952 $gt = $matches[1];
953 $body .= $body_quote . str_replace("\n", "\n$body_quote$gt ", rtrim($line)) ."\n";
954 } else {
955 $body .= $body_quote . (!empty($body_quote) ? ' ' : '') . str_replace("\n", "\n$body_quote" . (!empty($body_quote) ? ' ' : ''), rtrim($line)) . "\n";
956 }
a61878d0 957 }
c9d61baf 958
73ad81bf 959 //rewrap the body to clean up quotations and line lengths
960 $body = sqBodyWrap ($body, $editor_size);
c9d61baf 961
73ad81bf 962 $body = getReplyCitation($from , $orig_header->date) . $body;
963 $composeMessage->reply_rfc822_header = $orig_header;
12a0ed01 964
73ad81bf 965 break;
966 default:
967 break;
41b94d65 968 }
b4e7df34 969//FIXME: we used to register $compose_messages in the session here, but not any more - so do we still need the session_write_close() and sqimap_logout() here? We probably need the IMAP logout, but what about the session closure?
5da08ef7 970 session_write_close();
a61878d0 971 sqimap_logout($imapConnection);
41b94d65 972 }
a61878d0 973 $ret = array( 'send_to' => $send_to,
73ad81bf 974 'send_to_cc' => $send_to_cc,
975 'send_to_bcc' => $send_to_bcc,
976 'subject' => $subject,
977 'mailprio' => $mailprio,
978 'body' => $body,
979 'identity' => $identity );
a61878d0 980
41b94d65 981 return ($ret);
48985d59 982} /* function newMail() */
983
50706f77 984/**
985 * downloads attachments from original message, stores them in attachment directory and adds
986 * them to composed message.
987 * @param object $message
988 * @param object $composeMessage
989 * @param integer $passed_id
990 * @param mixed $entities
991 * @param mixed $imapConnection
91c27aee 992 * @return object
50706f77 993 */
a43e4b90 994function getAttachments($message, &$composeMessage, $passed_id, $entities, $imapConnection) {
1f270d3c 995 global $squirrelmail_language, $languages, $username, $attachment_dir;
628bce99 996
1c044820 997 if (!count($message->entities) ||
73ad81bf 998 ($message->type0 == 'message' && $message->type1 == 'rfc822')) {
41b94d65 999 if ( !in_array($message->entity_id, $entities) && $message->entity_id) {
73ad81bf 1000 switch ($message->type0) {
1001 case 'message':
1002 if ($message->type1 == 'rfc822') {
1003 $filename = $message->rfc822_header->subject;
1004 if ($filename == "") {
1005 $filename = "untitled-".$message->entity_id;
1006 }
6f71f6e6 1007 $filename .= '.eml';
73ad81bf 1008 } else {
1009 $filename = $message->getFilename();
181538ac 1010 }
73ad81bf 1011 break;
1012 default:
1013 if (!$message->mime_header) { /* temporary hack */
1014 $message->mime_header = $message->header;
1015 }
1016 $filename = $message->getFilename();
1017 break;
1018 }
1019 $filename = str_replace('&#32;', ' ', decodeHeader($filename));
1020 if (isset($languages[$squirrelmail_language]['XTRA_CODE']) &&
1021 function_exists($languages[$squirrelmail_language]['XTRA_CODE'] . '_encode')) {
f4bb5d22 1022 $filename = call_user_func($languages[$squirrelmail_language]['XTRA_CODE'] . '_encode', $filename);
73ad81bf 1023 }
1f270d3c 1024
1025 $hashed_attachment_dir = getHashedDir($username, $attachment_dir);
628bce99 1026 $localfilename = sq_get_attach_tempfile();
1027 $message->att_local_name = $localfilename;
73ad81bf 1028
1029 $composeMessage->initAttachment($message->type0.'/'.$message->type1,$filename,
628bce99 1030 $localfilename);
73ad81bf 1031
1032 /* Write Attachment to file */
1f270d3c 1033 $fp = fopen ($hashed_attachment_dir . '/' . $localfilename, 'wb');
91c27aee 1034 mime_print_body_lines ($imapConnection, $passed_id, $message->entity_id, $message->header->encoding, $fp);
73ad81bf 1035 fclose ($fp);
48985d59 1036 }
734f4ee6 1037 } else {
a43e4b90 1038 for ($i=0, $entCount=count($message->entities); $i<$entCount;$i++) {
1039 $composeMessage=getAttachments($message->entities[$i], $composeMessage, $passed_id, $entities, $imapConnection);
48985d59 1040 }
1041 }
a43e4b90 1042 return $composeMessage;
48985d59 1043}
1044
1c044820 1045function getMessage_RFC822_Attachment($message, $composeMessage, $passed_id,
73ad81bf 1046 $passed_ent_id='', $imapConnection) {
756406df 1047 if (!$passed_ent_id) {
1c044820 1048 $body_a = sqimap_run_command($imapConnection,
73ad81bf 1049 'FETCH '.$passed_id.' RFC822',
1050 TRUE, $response, $readmessage,
1051 TRUE);
756406df 1052 } else {
1c044820 1053 $body_a = sqimap_run_command($imapConnection,
73ad81bf 1054 'FETCH '.$passed_id.' BODY['.$passed_ent_id.']',
1055 TRUE, $response, $readmessage, TRUE);
a61878d0 1056 $message = $message->parent;
756406df 1057 }
d0519c03 1058 if ($response == 'OK') {
a61878d0 1059 $subject = encodeHeader($message->rfc822_header->subject);
1060 array_shift($body_a);
1c044820 1061 array_pop($body_a);
a61878d0 1062 $body = implode('', $body_a) . "\r\n";
1c044820 1063
1f270d3c 1064 global $username, $attachment_dir;
1065 $hashed_attachment_dir = getHashedDir($username, $attachment_dir);
628bce99 1066 $localfilename = sq_get_attach_tempfile();
1f270d3c 1067 $fp = fopen($hashed_attachment_dir . '/' . $localfilename, 'wb');
a61878d0 1068 fwrite ($fp, $body);
1069 fclose($fp);
6f71f6e6 1070 $composeMessage->initAttachment('message/rfc822',$subject.'.eml',
628bce99 1071 $localfilename);
a43e4b90 1072 }
1073 return $composeMessage;
a6ec592e 1074}
1075
41b94d65 1076function showInputForm ($session, $values=false) {
856e58ef 1077 global $send_to, $send_to_cc, $send_to_bcc,
f8eb968d 1078 $body, $startMessage, $action, $attachments,
b2b614bb 1079 $use_signature, $signature, $prefix_sig, $session_expired,
8d8da447 1080 $editor_size, $editor_height, $subject, $newmail,
856e58ef 1081 $use_javascript_addr_book, $passed_id, $mailbox,
73ad81bf 1082 $from_htmladdr_search, $location_of_buttons, $attachment_dir,
ce68b76b 1083 $username, $data_dir, $identity, $idents, $delete_draft,
1084 $mailprio, $compose_new_win, $saved_draft, $mail_sent, $sig_first,
b4e7df34 1085 $composeMessage, $composesession, $default_charset,
762853f4 1086 $compose_onsubmit, $oTemplate, $oErrorHandler;
a43e4b90 1087
87745b9c 1088 if (checkForJavascript()) {
1089 $onfocus = ' onfocus="alreadyFocused=true;"';
1090 $onfocus_array = array('onfocus' => 'alreadyFocused=true;');
1091 }
1092 else {
1093 $onfocus = '';
1094 $onfocus_array = array();
1095 }
1096
41b94d65 1097 if ($values) {
73ad81bf 1098 $send_to = $values['send_to'];
1099 $send_to_cc = $values['send_to_cc'];
1100 $send_to_bcc = $values['send_to_bcc'];
1101 $subject = $values['subject'];
1102 $mailprio = $values['mailprio'];
1103 $body = $values['body'];
1104 $identity = (int) $values['identity'];
676bb189 1105 } else {
73ad81bf 1106 $send_to = decodeHeader($send_to, true, false);
1107 $send_to_cc = decodeHeader($send_to_cc, true, false);
1108 $send_to_bcc = decodeHeader($send_to_bcc, true, false);
41b94d65 1109 }
1c044820 1110
48985d59 1111 if ($use_javascript_addr_book) {
c8dc86c9 1112//FIXME: NO HTML IN CORE!
2c92ea9d 1113 echo "\n". '<script type="text/javascript">'."\n<!--\n" .
73ad81bf 1114 'function open_abook() { ' . "\n" .
1115 ' var nwin = window.open("addrbook_popup.php","abookpopup",' .
1116 '"width=670,height=300,resizable=yes,scrollbars=yes");' . "\n" .
1117 ' if((!nwin.opener) && (document.windows != null))' . "\n" .
1118 ' nwin.opener = document.windows;' . "\n" .
1119 "}\n" .
1120 "// -->\n</script>\n\n";
48985d59 1121 }
1122
c8dc86c9 1123//FIXME: NO HTML IN CORE!
4a1788b3 1124 echo "\n" . '<form name="compose" action="compose.php" method="post" ' .
73ad81bf 1125 'enctype="multipart/form-data"';
a34b07a5 1126
1127 $compose_onsubmit = array();
6e515418 1128 global $null;
1129 do_hook('compose_form', $null);
1c044820 1130
a34b07a5 1131 // Plugins that use compose_form hook can add an array entry
1132 // to the globally scoped $compose_onsubmit; we add them up
5c4ff7bf 1133 // here and format the form tag's full onsubmit handler.
1134 // Each plugin should use "return false" if they need to
a34b07a5 1135 // stop form submission but otherwise should NOT use "return
1136 // true" to give other plugins the chance to do what they need
1137 // to do; SquirrelMail itself will add the final "return true".
1138 // Onsubmit text is enclosed inside of double quotes, so plugins
1139 // need to quote accordingly.
1140 if (checkForJavascript()) {
1141 $onsubmit_text = ' onsubmit="';
5c4ff7bf 1142 if (empty($compose_onsubmit))
a34b07a5 1143 $compose_onsubmit = array();
5c4ff7bf 1144 else if (!is_array($compose_onsubmit))
a34b07a5 1145 $compose_onsubmit = array($compose_onsubmit);
1146
1147 foreach ($compose_onsubmit as $text) {
1148 $text = trim($text);
5c4ff7bf 1149 if (substr($text, -1) != ';' && substr($text, -1) != '}')
a34b07a5 1150 $text .= '; ';
1151 $onsubmit_text .= $text;
1152 }
1153
c8dc86c9 1154//FIXME: DON'T ECHO HTML FROM CORE!
a34b07a5 1155 echo $onsubmit_text . ' return true;"';
1156 }
5c4ff7bf 1157
a34b07a5 1158
c8dc86c9 1159//FIXME: NO HTML IN CORE!
48985d59 1160 echo ">\n";
1161
c8dc86c9 1162//FIXME: DON'T ECHO HTML FROM CORE!
df96b37a 1163 echo addHidden('startMessage', $startMessage);
4a1788b3 1164
41b94d65 1165 if ($action == 'draft') {
c8dc86c9 1166//FIXME: DON'T ECHO HTML FROM CORE!
df96b37a 1167 echo addHidden('delete_draft', $passed_id);
48985d59 1168 }
1169 if (isset($delete_draft)) {
c8dc86c9 1170//FIXME: DON'T ECHO HTML FROM CORE!
df96b37a 1171 echo addHidden('delete_draft', $delete_draft);
48985d59 1172 }
da95c4b6 1173 if (isset($session)) {
c8dc86c9 1174//FIXME: DON'T ECHO HTML FROM CORE!
df96b37a 1175 echo addHidden('session', $session);
da95c4b6 1176 }
1c044820 1177
08bad2b1 1178 if (isset($passed_id)) {
c8dc86c9 1179//FIXME: DON'T ECHO HTML FROM CORE!
df96b37a 1180 echo addHidden('passed_id', $passed_id);
08bad2b1 1181 }
44560457 1182
9c3e6cd4 1183 if ($saved_draft == 'yes') {
774d79cc 1184 $oTemplate->assign('note', _("Your draft has been saved."));
762853f4 1185 $oTemplate->display('note.tpl');
9c3e6cd4 1186 }
1187 if ($mail_sent == 'yes') {
774d79cc 1188 $oTemplate->assign('note', _("Your mail has been sent."));
762853f4 1189 $oTemplate->display('note.tpl');
9c3e6cd4 1190 }
9c3e6cd4 1191 if ($compose_new_win == '1') {
762853f4 1192 $oTemplate->display('compose_newwin_close.tpl');
9c3e6cd4 1193 }
1638beb6 1194
78a35fcd 1195 if ($location_of_buttons == 'top') {
c8dc86c9 1196//FIXME: DON'T ECHO HTML FROM CORE!
78a35fcd 1197 showComposeButtonRow();
1198 }
48985d59 1199
762853f4 1200 $identities = array();
1e2a6ff6 1201 if (count($idents) > 1) {
762853f4 1202 reset($idents);
73ad81bf 1203 foreach($idents as $id => $data) {
762853f4 1204 $identities[$id] = $data['full_name'].' &lt;'.$data['email_address'].'&gt;';
73ad81bf 1205 }
762853f4 1206 }
1638beb6 1207
762853f4 1208 $oTemplate->assign('identities', $identities);
1209 $oTemplate->assign('identity_def', $identity);
1210 $oTemplate->assign('input_onfocus', 'onfocus="'.join(' ', $onfocus_array).'"');
1638beb6 1211
762853f4 1212 $oTemplate->assign('to', htmlspecialchars($send_to));
1213 $oTemplate->assign('cc', htmlspecialchars($send_to_cc));
1214 $oTemplate->assign('bcc', htmlspecialchars($send_to_bcc));
1215 $oTemplate->assign('subject', htmlspecialchars($subject));
1638beb6 1216
762853f4 1217 $oTemplate->display('compose_header.tpl');
48985d59 1218
78a35fcd 1219 if ($location_of_buttons == 'between') {
c8dc86c9 1220//FIXME: DON'T ECHO HTML FROM CORE!
78a35fcd 1221 showComposeButtonRow();
1222 }
4dfb9db7 1223
762853f4 1224 $body_str = '';
48985d59 1225 if ($use_signature == true && $newmail == true && !isset($from_htmladdr_search)) {
1e2a6ff6 1226 $signature = $idents[$identity]['signature'];
d3c13a51 1227
3b17e952 1228 if ($sig_first == '1') {
50706f77 1229 /*
1230 * FIXME: test is specific to ja_JP translation implementation.
1231 * This test might apply incorrect conversion to other translations, but
91c27aee 1232 * use of 7bit iso-2022-jp charset in other translations might have other
50706f77 1233 * issues too.
1234 */
ab4700c3 1235 if ($default_charset == 'iso-2022-jp') {
762853f4 1236 $body_str = "\n\n".($prefix_sig==true? "-- \n":'').mb_convert_encoding($signature, 'EUC-JP');
83be314a 1237 } else {
762853f4 1238 $body_str = "\n\n".($prefix_sig==true? "-- \n":'').decodeHeader($signature,false,false);
83be314a 1239 }
762853f4 1240 $body_str .= "\n\n".htmlspecialchars(decodeHeader($body,false,false));
1241 } else {
1242 $body_str = "\n\n".htmlspecialchars(decodeHeader($body,false,false));
50706f77 1243 // FIXME: test is specific to ja_JP translation implementation. See above comments.
ab4700c3 1244 if ($default_charset == 'iso-2022-jp') {
762853f4 1245 $body_str .= "\n\n".($prefix_sig==true? "-- \n":'').mb_convert_encoding($signature, 'EUC-JP');
1246 } else {
1247 $body_str .= "\n\n".($prefix_sig==true? "-- \n":'').decodeHeader($signature,false,false);
73ad81bf 1248 }
3b17e952 1249 }
73ad81bf 1250 } else {
762853f4 1251 $body_str = htmlspecialchars(decodeHeader($body,false,false));
48985d59 1252 }
12a0ed01 1253
762853f4 1254 $oTemplate->assign('editor_width', (int)$editor_size);
1255 $oTemplate->assign('editor_height', (int)$editor_height);
1256 $oTemplate->assign('input_onfocus', 'onfocus="'.join(' ', $onfocus_array).'"');
1257 $oTemplate->assign('body', $body_str);
1258 $oTemplate->assign('show_bottom_send', $location_of_buttons!='bottom');
1638beb6 1259
762853f4 1260 $oTemplate->display ('compose_body.tpl');
1638beb6 1261
48985d59 1262 if ($location_of_buttons == 'bottom') {
c8dc86c9 1263//FIXME: DON'T ECHO HTML FROM CORE!
48985d59 1264 showComposeButtonRow();
48985d59 1265 }
46bb8da8 1266
f8eb968d 1267 // composeMessage can be empty when coming from a restored session
1268 if (is_object($composeMessage) && $composeMessage->entities)
1269 $attach_array = $composeMessage->entities;
1270 if ($session_expired && !empty($attachments) && is_array($attachments))
1271 $attach_array = $attachments;
1272
48985d59 1273 /* This code is for attachments */
73ad81bf 1274 if ((bool) ini_get('file_uploads')) {
1275
1276 /* Calculate the max size for an uploaded file.
1277 * This is advisory for the user because we can't actually prevent
1278 * people to upload too large files. */
1279 $sizes = array();
1280 /* php.ini vars which influence the max for uploads */
1281 $configvars = array('post_max_size', 'memory_limit', 'upload_max_filesize');
1282 foreach($configvars as $var) {
4f21ba00 1283 /* skip 0 or empty values, and -1 which means 'unlimited' */
73ad81bf 1284 if( $size = getByteSize(ini_get($var)) ) {
4f21ba00 1285 if ( $size != '-1' ) {
1286 $sizes[] = $size;
1287 }
73ad81bf 1288 }
0a2c3218 1289 }
0a2c3218 1290
762853f4 1291 $attach = array();
1f270d3c 1292 global $username, $attachment_dir;
1293 $hashed_attachment_dir = getHashedDir($username, $attachment_dir);
f8eb968d 1294 if (!empty($attach_array)) {
1295 foreach ($attach_array as $key => $attachment) {
73ad81bf 1296 $attached_file = $attachment->att_local_name;
1297 if ($attachment->att_local_name || $attachment->body_part) {
1298 $attached_filename = decodeHeader($attachment->mime_header->getParameter('name'));
1299 $type = $attachment->mime_header->type0.'/'.
a91189d6 1300 $attachment->mime_header->type1;
1638beb6 1301
762853f4 1302 $a = array();
1303 $a['Key'] = $key;
1304 $a['FileName'] = $attached_filename;
1305 $a['ContentType'] = $type;
1f270d3c 1306 $a['Size'] = filesize($hashed_attachment_dir . '/' . $attached_file);
762853f4 1307 $attach[$key] = $a;
73ad81bf 1308 }
1309 }
4dfb9db7 1310 }
1638beb6 1311
762853f4 1312 $max = min($sizes);
1313 $oTemplate->assign('max_file_size', empty($max) ? -1 : $max);
1314 $oTemplate->assign('attachments', $attach);
1638beb6 1315
762853f4 1316 $oTemplate->display('compose_attachments.tpl');
73ad81bf 1317 } // End of file_uploads if-block
41b94d65 1318 /* End of attachment code */
762853f4 1319
60445d64 1320//FIXME: no direct echoing to browser, no HTML output in core!
762853f4 1321 echo addHidden('username', $username).
1322 addHidden('smaction', $action).
1323 addHidden('mailbox', $mailbox);
953fa718 1324 sqgetGlobalVar('QUERY_STRING', $queryString, SQ_SERVER);
60445d64 1325//FIXME: no direct echoing to browser, no HTML output in core!
f8eb968d 1326 echo addHidden('composesession', $composesession).
73ad81bf 1327 addHidden('querystring', $queryString).
f8eb968d 1328 (!empty($attach_array) ?
1329 addHidden('attachments', urlencode(serialize($attach_array))) : '').
73ad81bf 1330 "</form>\n";
a64f47e7 1331 if (!(bool) ini_get('file_uploads')) {
73ad81bf 1332 /* File uploads are off, so we didn't show that part of the form.
1333 To avoid bogus bug reports, tell the user why. */
60445d64 1334//FIXME: no direct echoing to browser, no HTML output in core!
50706f77 1335 echo '<p style="text-align:center">'
1336 . _("Because PHP file uploads are turned off, you can not attach files to this message. Please see your system administrator for details.")
1337 . "</p>\r\n";
a64f47e7 1338 }
1339
762853f4 1340 if ($compose_new_win=='1') {
1341 $oTemplate->display('compose_newwin_close.tpl');
1342 }
1638beb6 1343
d22879f7 1344 do_hook('compose_bottom', $null);
1345
762853f4 1346 $oErrorHandler->setDelayedErrors(false);
5c4ff7bf 1347 $oTemplate->display('footer.tpl');
48985d59 1348}
1349
1350
70c4fd84 1351function showComposeButtonRow() {
78a35fcd 1352 global $use_javascript_addr_book, $save_as_draft,
73ad81bf 1353 $default_use_priority, $mailprio, $default_use_mdn,
1354 $request_mdn, $request_dr,
1355 $data_dir, $username;
70c4fd84 1356
762853f4 1357 global $oTemplate, $buffer_hook;
1638beb6 1358
1359 if ($default_use_priority) {
762853f4 1360 $priorities = array('1'=>_("High"), '3'=>_("Normal"), '5'=>_("Low"));
1361 $priority = isset($mailprio) ? $mailprio : 3;
1362 } else {
1363 $priorities = array();
1364 $priority = NULL;
ae25968c 1365 }
1638beb6 1366
ae25968c 1367 $mdn_user_support=getPref($data_dir, $username, 'mdn_user_support',$default_use_mdn);
48985d59 1368
c40a269e 1369 if ($use_javascript_addr_book && checkForJavascript()) {
1370 $addr_book = addButton(_("Addresses"), null, array('onclick' => 'javascript:open_abook();'));
734f4ee6 1371 } else {
c40a269e 1372 $addr_book = addSubmit(_("Addresses"), 'html_addr_search');
78a35fcd 1373 }
48985d59 1374
762853f4 1375 $oTemplate->assign('allow_priority', $default_use_priority==1);
1376 $oTemplate->assign('priority_list', $priorities);
1377 $oTemplate->assign('current_priority', $priority);
1638beb6 1378
762853f4 1379 $oTemplate->assign('notifications_enabled', $mdn_user_support==1);
1380 $oTemplate->assign('read_receipt', $request_mdn=='1');
1381 $oTemplate->assign('delivery_receipt', $request_dr=='1');
1638beb6 1382
762853f4 1383 $oTemplate->assign('drafts_enabled', $save_as_draft);
1384 $oTemplate->assign('address_book_button', $addr_book);
441f2d33 1385
762853f4 1386 $oTemplate->display('compose_buttons.tpl');
78a35fcd 1387}
b278172f 1388
70c4fd84 1389function checkInput ($show) {
78a35fcd 1390 /*
1391 * I implemented the $show variable because the error messages
1392 * were getting sent before the page header. So, I check once
1393 * using $show=false, and then when i'm ready to display the error
1394 * message, show=true
1395 */
1356041d 1396 global $send_to, $send_to_cc, $send_to_bcc;
78a35fcd 1397
1356041d 1398 $send_to = trim($send_to);
1399 $send_to_cc = trim($send_to_cc);
1400 $send_to_bcc = trim($send_to_bcc);
1401 if (empty($send_to) && empty($send_to_cc) && empty($send_to_bcc)) {
78a35fcd 1402 if ($show) {
cb34dbd0 1403 plain_error_message(_("You have not filled in the \"To:\" field."));
78a35fcd 1404 }
1405 return false;
1406 }
1407 return true;
1408} /* function checkInput() */
df15de21 1409
3806fa52 1410
00793a25 1411/* True if FAILURE */
da95c4b6 1412function saveAttachedFiles($session) {
b4e7df34 1413 global $composeMessage, $username, $attachment_dir;
bfa54da7 1414
45cdd1b5 1415 /* get out of here if no file was attached at all */
1416 if (! is_uploaded_file($_FILES['attachfile']['tmp_name']) ) {
1417 return true;
1418 }
1419
1f270d3c 1420 $hashed_attachment_dir = getHashedDir($username, $attachment_dir);
628bce99 1421 $localfilename = sq_get_attach_tempfile();
1f270d3c 1422 $fullpath = $hashed_attachment_dir . '/' . $localfilename;
4c9d2242 1423
a42c236f 1424 // m_u_f works better with restricted PHP installs (safe_mode, open_basedir),
1425 // if that doesn't work, try a simple rename.
8442ecb9 1426 if (!sq_call_function_suppress_errors('move_uploaded_file', array($_FILES['attachfile']['tmp_name'], $fullpath))) {
1427 if (!sq_call_function_suppress_errors('rename', array($_FILES['attachfile']['tmp_name'], $fullpath))) {
73ad81bf 1428 return true;
1429 }
a61878d0 1430 }
0b97a708 1431 $type = strtolower($_FILES['attachfile']['type']);
1432 $name = $_FILES['attachfile']['name'];
b4e7df34 1433 $composeMessage->initAttachment($type, $name, $localfilename);
4c9d2242 1434}
1435
0a2c3218 1436/* parse values like 8M and 2k into bytes */
1437function getByteSize($ini_size) {
1438
4d30dc83 1439 if(!$ini_size) {
1440 return FALSE;
1441 }
da95c4b6 1442
0a2c3218 1443 $ini_size = trim($ini_size);
1444
5b9716de 1445 // if there's some kind of letter at the end of the string we need to multiply.
1446 if(!is_numeric(substr($ini_size, -1))) {
1447
1448 switch(strtoupper(substr($ini_size, -1))) {
1449 case 'G':
73ad81bf 1450 $bytesize = 1073741824;
1451 break;
5b9716de 1452 case 'M':
73ad81bf 1453 $bytesize = 1048576;
1454 break;
5b9716de 1455 case 'K':
73ad81bf 1456 $bytesize = 1024;
1457 break;
5b9716de 1458 }
1459
4d30dc83 1460 return ($bytesize * (int)substr($ini_size, 0, -1));
0a2c3218 1461 }
1c044820 1462
4d30dc83 1463 return $ini_size;
0a2c3218 1464}
a43e4b90 1465
4c9d2242 1466
50706f77 1467/**
1468 * temporary function to make use of the deliver class.
a42c236f 1469 * In the future the responsible backend should be automaticly loaded
50706f77 1470 * and conf.pl should show a list of available backends.
1471 * The message also should be constructed by the message class.
b67d61ee 1472 *
10adeb76 1473 * @param object $composeMessage The message being sent. Please note
1474 * that it is passed by reference and
1475 * will be returned modified, with additional
1476 * headers, such as Message-ID, Date, In-Reply-To,
1477 * References, and so forth.
1478 *
b67d61ee 1479 * @return boolean FALSE if delivery failed, or some non-FALSE value
1480 * upon success.
1481 *
73ad81bf 1482 */
10adeb76 1483function deliverMessage(&$composeMessage, $draft=false) {
a43e4b90 1484 global $send_to, $send_to_cc, $send_to_bcc, $mailprio, $subject, $body,
10adeb76 1485 $username, $identity, $idents, $data_dir,
856e58ef 1486 $request_mdn, $request_dr, $default_charset, $useSendmail,
1487 $domain, $action, $default_move_to_sent, $move_to_sent,
1488 $imapServerAddress, $imapPort, $sent_folder, $key;
a43e4b90 1489
1490 $rfc822_header = $composeMessage->rfc822_header;
24192f77 1491
1492 $abook = addressbook_init(false, true);
310dfeb6 1493 $rfc822_header->to = $rfc822_header->parseAddress($send_to,true, array(), '', $domain, array(&$abook,'lookup'));
1494 $rfc822_header->cc = $rfc822_header->parseAddress($send_to_cc,true,array(), '',$domain, array(&$abook,'lookup'));
1495 $rfc822_header->bcc = $rfc822_header->parseAddress($send_to_bcc,true, array(), '',$domain, array(&$abook,'lookup'));
a43e4b90 1496 $rfc822_header->priority = $mailprio;
1497 $rfc822_header->subject = $subject;
310dfeb6 1498
a43e4b90 1499 $special_encoding='';
1500 if (strtolower($default_charset) == 'iso-2022-jp') {
1501 if (mb_detect_encoding($body) == 'ASCII') {
a91189d6 1502 $special_encoding = '8bit';
a43e4b90 1503 } else {
1504 $body = mb_convert_encoding($body, 'JIS');
1505 $special_encoding = '7bit';
1506 }
1507 }
1508 $composeMessage->setBody($body);
1509
a43e4b90 1510 $reply_to = '';
1e2a6ff6 1511 $reply_to = $idents[$identity]['reply_to'];
40e07136 1512
1513 $from_addr = build_from_header($identity);
1514 $rfc822_header->from = $rfc822_header->parseAddress($from_addr,true);
a43e4b90 1515 if ($reply_to) {
73ad81bf 1516 $rfc822_header->reply_to = $rfc822_header->parseAddress($reply_to,true);
a43e4b90 1517 }
1518 /* Receipt: On Read */
1519 if (isset($request_mdn) && $request_mdn) {
40e07136 1520 $rfc822_header->dnt = $rfc822_header->parseAddress($from_addr,true);
762853f4 1521 } elseif (isset($rfc822_header->dnt)) {
1522 unset($rfc822_header->dnt);
a43e4b90 1523 }
1638beb6 1524
a43e4b90 1525 /* Receipt: On Delivery */
657fe1bd 1526 if (!empty($request_dr)) {
1527//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?
cc51047f 1528 $rfc822_header->more_headers['Return-Receipt-To'] = $from_addr;
762853f4 1529 } elseif (isset($rfc822_header->more_headers['Return-Receipt-To'])) {
1530 unset($rfc822_header->more_headers['Return-Receipt-To']);
a43e4b90 1531 }
762853f4 1532
a43e4b90 1533 /* multipart messages */
1534 if (count($composeMessage->entities)) {
1535 $message_body = new Message();
a91189d6 1536 $message_body->body_part = $composeMessage->body_part;
1537 $composeMessage->body_part = '';
1538 $mime_header = new MessageHeader;
1539 $mime_header->type0 = 'text';
1540 $mime_header->type1 = 'plain';
1541 if ($special_encoding) {
1542 $mime_header->encoding = $special_encoding;
1c044820 1543 } else {
12a0ed01 1544 $mime_header->encoding = '8bit';
a91189d6 1545 }
1546 if ($default_charset) {
1547 $mime_header->parameters['charset'] = $default_charset;
1548 }
1c044820 1549 $message_body->mime_header = $mime_header;
a43e4b90 1550 array_unshift($composeMessage->entities, $message_body);
a91189d6 1551 $content_type = new ContentType('multipart/mixed');
a43e4b90 1552 } else {
1e2026df 1553 $content_type = new ContentType('text/plain');
1554 if ($special_encoding) {
1555 $rfc822_header->encoding = $special_encoding;
1c044820 1556 } else {
1e2026df 1557 $rfc822_header->encoding = '8bit';
1c044820 1558 }
426e0b72 1559 if ($default_charset) {
1560 $content_type->properties['charset']=$default_charset;
73ad81bf 1561 }
181538ac 1562 }
1c044820 1563
a43e4b90 1564 $rfc822_header->content_type = $content_type;
1565 $composeMessage->rfc822_header = $rfc822_header;
0fdb0aa1 1566 if ($action == 'reply' || $action == 'reply_all') {
1567 global $passed_id, $passed_ent_id;
1568 $reply_id = $passed_id;
1569 $reply_ent_id = $passed_ent_id;
1570 } else {
1571 $reply_id = '';
1572 $reply_ent_id = '';
1573 }
1638beb6 1574
1c044820 1575 /* Here you can modify the message structure just before we hand
6e515418 1576 it over to deliver; plugin authors note that $composeMessage
1577 is sent and modified by reference since 1.5.2 */
1578 do_hook('compose_send', $composeMessage);
a43e4b90 1579
b48d3c53 1580 if (!$useSendmail && !$draft) {
a91189d6 1581 require_once(SM_PATH . 'class/deliver/Deliver_SMTP.class.php');
1582 $deliver = new Deliver_SMTP();
783e926e 1583 global $smtpServerAddress, $smtpPort, $pop_before_smtp, $pop_before_smtp_host;
a91189d6 1584
a91189d6 1585 $authPop = (isset($pop_before_smtp) && $pop_before_smtp) ? true : false;
783e926e 1586 if (empty($pop_before_smtp_host)) $pop_before_smtp_host = $smtpServerAddress;
9bd3b1e6 1587 get_smtp_user($user, $pass);
a91189d6 1588 $stream = $deliver->initStream($composeMessage,$domain,0,
783e926e 1589 $smtpServerAddress, $smtpPort, $user, $pass, $authPop, $pop_before_smtp_host);
b48d3c53 1590 } elseif (!$draft) {
73ad81bf 1591 require_once(SM_PATH . 'class/deliver/Deliver_SendMail.class.php');
fd7ab795 1592 global $sendmail_path, $sendmail_args;
f3dc9c62 1593 // Check for outdated configuration
1594 if (!isset($sendmail_args)) {
1595 if ($sendmail_path=='/var/qmail/bin/qmail-inject') {
1596 $sendmail_args = '';
1597 } else {
1598 $sendmail_args = '-i -t';
1599 }
1600 }
fd7ab795 1601 $deliver = new Deliver_SendMail(array('sendmail_args'=>$sendmail_args));
73ad81bf 1602 $stream = $deliver->initStream($composeMessage,$sendmail_path);
b48d3c53 1603 } elseif ($draft) {
73ad81bf 1604 global $draft_folder;
906f7e9f 1605 $imap_stream = sqimap_login($username, false, $imapServerAddress,
73ad81bf 1606 $imapPort, 0);
1607 if (sqimap_mailbox_exists ($imap_stream, $draft_folder)) {
1608 require_once(SM_PATH . 'class/deliver/Deliver_IMAP.class.php');
1609 $imap_deliver = new Deliver_IMAP();
a90d951c 1610 $success = $imap_deliver->mail($composeMessage, $imap_stream, $reply_id, $reply_ent_id, $imap_stream, $draft_folder);
73ad81bf 1611 sqimap_logout($imap_stream);
1612 unset ($imap_deliver);
c077ffeb 1613 $composeMessage->purgeAttachments();
b67d61ee 1614 return $success;
4dfb9db7 1615 } else {
fd7ab795 1616 $msg = '<br />'.sprintf(_("Error: Draft folder %s does not exist."), htmlspecialchars($draft_folder));
cb34dbd0 1617 plain_error_message($msg);
73ad81bf 1618 return false;
a91189d6 1619 }
a43e4b90 1620 }
0c59bbe1 1621 $success = false;
a43e4b90 1622 if ($stream) {
10adeb76 1623 $deliver->mail($composeMessage, $stream, $reply_id, $reply_ent_id);
0c59bbe1 1624 $success = $deliver->finalizeStream($stream);
a43e4b90 1625 }
0c59bbe1 1626 if (!$success) {
fd7ab795 1627 // $deliver->dlv_server_msg is not always server's reply
6c3d00b5 1628 $msg = _("Message not sent.") . "<br />\n" .
1629 $deliver->dlv_msg;
a15f9d93 1630 if (!empty($deliver->dlv_server_msg)) {
1631 // add 'server replied' part only when it is not empty.
1632 // Delivery error can be generated by delivery class itself
1633 $msg.='<br />' .
1634 _("Server replied:") . ' ' . $deliver->dlv_ret_nr . ' ' .
1635 nl2br(htmlspecialchars($deliver->dlv_server_msg));
1636 }
cb34dbd0 1637 plain_error_message($msg);
a43e4b90 1638 } else {
1639 unset ($deliver);
906f7e9f 1640 $imap_stream = sqimap_login($username, false, $imapServerAddress, $imapPort, 0);
e4a1f097 1641
8780308f 1642
414303b8 1643 // mark as replied or forwarded if applicable
1644 //
1645 global $what, $iAccount, $startMessage, $passed_id, $mailbox;
8780308f 1646
bc29bf70 1647 if ($action=='reply' || $action=='reply_all' || $action=='forward' || $action=='forward_as_attachment') {
202bcbcc 1648 require(SM_PATH . 'functions/mailbox_display.php');
8780308f 1649 $aMailbox = sqm_api_mailbox_select($imap_stream, $iAccount, $mailbox,array('setindex' => $what, 'offset' => $startMessage),array());
bc29bf70 1650 switch($action) {
1651 case 'reply':
1652 case 'reply_all':
1653 // check if we are allowed to set the \\Answered flag
1654 if (in_array('\\answered',$aMailbox['PERMANENTFLAGS'], true)) {
1655 $aUpdatedMsgs = sqimap_toggle_flag($imap_stream, array($passed_id), '\\Answered', true, false);
1656 if (isset($aUpdatedMsgs[$passed_id]['FLAGS'])) {
1657 /**
1658 * Only update the cached headers if the header is
1659 * cached.
1660 */
1661 if (isset($aMailbox['MSG_HEADERS'][$passed_id])) {
1662 $aMailbox['MSG_HEADERS'][$passed_id]['FLAGS'] = $aMsg['FLAGS'];
1663 }
1664 }
1665 }
1666 break;
1667 case 'forward':
1668 case 'forward_as_attachment':
1669 // check if we are allowed to set the $Forwarded flag (RFC 4550 paragraph 2.8)
1638beb6 1670 if (in_array('$forwarded',$aMailbox['PERMANENTFLAGS'], true) ||
bc29bf70 1671 in_array('\\*',$aMailbox['PERMANENTFLAGS'])) {
1672
1673 $aUpdatedMsgs = sqimap_toggle_flag($imap_stream, array($passed_id), '$Forwarded', true, false);
1674 if (isset($aUpdatedMsgs[$passed_id]['FLAGS'])) {
1675 if (isset($aMailbox['MSG_HEADERS'][$passed_id])) {
1676 $aMailbox['MSG_HEADERS'][$passed_id]['FLAGS'] = $aMsg['FLAGS'];
1677 }
bda07b93 1678 }
8780308f 1679 }
bc29bf70 1680 break;
8780308f 1681 }
bc29bf70 1682
4d1cb59a 1683 /**
1684 * Write mailbox with updated seen flag information back to cache.
1685 */
bc29bf70 1686 if(isset($aUpdatedMsgs[$passed_id])) {
1687 $mailbox_cache[$iAccount.'_'.$aMailbox['NAME']] = $aMailbox;
1688 sqsession_register($mailbox_cache,'mailbox_cache');
1689 }
1690
a91189d6 1691 }
414303b8 1692
1693
1694 // move to sent folder
1695 //
1696 $move_to_sent = getPref($data_dir,$username,'move_to_sent');
1697 if (isset($default_move_to_sent) && ($default_move_to_sent != 0)) {
1698 $svr_allow_sent = true;
1699 } else {
1700 $svr_allow_sent = false;
1701 }
1702
1703 if (isset($sent_folder) && (($sent_folder != '') || ($sent_folder != 'none'))
1704 && sqimap_mailbox_exists( $imap_stream, $sent_folder)) {
1705 $fld_sent = true;
1706 } else {
1707 $fld_sent = false;
1708 }
1709
1710 if ((isset($move_to_sent) && ($move_to_sent != 0)) || (!isset($move_to_sent))) {
1711 $lcl_allow_sent = true;
1712 } else {
1713 $lcl_allow_sent = false;
1714 }
1715
1716 if (($fld_sent && $svr_allow_sent && !$lcl_allow_sent) || ($fld_sent && $lcl_allow_sent)) {
1717 if ($action == 'reply' || $action == 'reply_all') {
1718 $save_reply_with_orig=getPref($data_dir,$username,'save_reply_with_orig');
1719 if ($save_reply_with_orig) {
1720 $sent_folder = $mailbox;
1721 }
1722 }
414303b8 1723 require_once(SM_PATH . 'class/deliver/Deliver_IMAP.class.php');
1724 $imap_deliver = new Deliver_IMAP();
33f0da43 1725 $imap_deliver->mail($composeMessage, $imap_stream, $reply_id, $reply_ent_id, $imap_stream, $sent_folder);
414303b8 1726 unset ($imap_deliver);
1727 }
1728
1729
1730 // final cleanup
1731 //
1732 $composeMessage->purgeAttachments();
1733 sqimap_logout($imap_stream);
1734
a43e4b90 1735 }
0c59bbe1 1736 return $success;
a43e4b90 1737}