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