added safety checks for outdated config.php and
[squirrelmail.git] / src / read_body.php
1 <?php
2
3 /**
4 * read_body.php
5 *
6 * This file is used for reading the msgs array and displaying
7 * the resulting emails in the right frame.
8 *
9 * @copyright &copy; 1999-2006 The SquirrelMail Project Team
10 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
11 * @version $Id$
12 * @package squirrelmail
13 */
14
15 /**
16 * Include the SquirrelMail initialization file.
17 */
18 require('../include/init.php');
19
20 /* SquirrelMail required files. */
21
22
23 require_once(SM_PATH . 'functions/imap.php');
24 require_once(SM_PATH . 'functions/imap_asearch.php'); // => move to mailbox_display
25 require_once(SM_PATH . 'functions/mime.php');
26 require_once(SM_PATH . 'functions/date.php');
27 require_once(SM_PATH . 'functions/url_parser.php');
28 require_once(SM_PATH . 'functions/identity.php');
29 require_once(SM_PATH . 'functions/arrays.php');
30 require_once(SM_PATH . 'functions/mailbox_display.php');
31 require_once(SM_PATH . 'functions/forms.php');
32 require_once(SM_PATH . 'functions/attachment_common.php');
33
34 /**
35 * Given an IMAP message id number, this will look it up in the cached
36 * and sorted msgs array and return the index of the next message
37 *
38 * @param int $passed_id The current message UID
39 * @return the index of the next valid message from the array
40 */
41 function findNextMessage($uidset,$passed_id='backwards') {
42 if (!is_array($uidset)) {
43 return -1;
44 }
45 if ($passed_id=='backwards' || !is_array($uidset)) { // check for backwards compattibilty gpg plugin
46 $passed_id = $uidset;
47 }
48 $result = sqm_array_get_value_by_offset($uidset,$passed_id,1);
49 if ($result === false) {
50 return -1;
51 } else {
52 return $result;
53 }
54 }
55
56 /**
57 * Given an IMAP message id number, this will look it up in the cached
58 * and sorted msgs array and return the index of the previous message
59 *
60 * @param int $passed_id The current message UID
61 * @return the index of the next valid message from the array
62 */
63
64 function findPreviousMessage($uidset, $passed_id) {
65 if (!is_array($uidset)) {
66 return -1;
67 }
68 $result = sqm_array_get_value_by_offset($uidset,$passed_id,-1);
69 if ($result === false) {
70 return -1;
71 } else {
72 return $result;
73 }
74 }
75
76 /**
77 * Displays a link to a page where the message is displayed more
78 * "printer friendly".
79 * @param string $mailbox Name of current mailbox
80 * @param int $passed_id
81 */
82 function printer_friendly_link($mailbox, $passed_id, $passed_ent_id) {
83 global $javascript_on, $show_html_default;
84
85 /* hackydiehack */
86 if( !sqgetGlobalVar('view_unsafe_images', $view_unsafe_images, SQ_GET) ) {
87 $view_unsafe_images = false;
88 } else {
89 $view_unsafe_images = true;
90 }
91 $params = '?passed_ent_id=' . urlencode($passed_ent_id) .
92 '&mailbox=' . urlencode($mailbox) .
93 '&passed_id=' . urlencode($passed_id) .
94 '&view_unsafe_images='. (bool) $view_unsafe_images .
95 '&show_html_default=' . $show_html_default;
96
97 $print_text = _("View Printable Version");
98
99 $result = '';
100 /* Output the link. */
101 if ($javascript_on) {
102 $result = '<script type="text/javascript">' . "\n" .
103 '<!--' . "\n" .
104 " function printFormat() {\n" .
105 ' window.open("../src/printer_friendly_main.php' .
106 $params . '","Print","width=800,height=600");' . "\n".
107 " }\n" .
108 "// -->\n" .
109 "</script>\n" .
110 "<a href=\"javascript:printFormat();\">$print_text</a>\n";
111 } else {
112 $result = '<a target="_blank" href="../src/printer_friendly_bottom.php' .
113 "$params\">$print_text</a>\n";
114 }
115 return $result;
116 }
117
118 function view_as_html_link($mailbox, $passed_id, $passed_ent_id, $message) {
119 global $base_uri, $show_html_default;
120
121 $has_html = false;
122 if ($message->header->type0 == 'message' && $message->header->type1 == 'rfc822') {
123 $type0 = $message->rfc822_header->content_type->type0;
124 $type1 = $message->rfc822_header->content_type->type1;
125 } else {
126 $type0 = $message->header->type0;
127 $type1 = $message->header->type1;
128 }
129 if($type0 == 'multipart' &&
130 ($type1 == 'alternative' || $type1 == 'mixed' || $type1 == 'related')) {
131 if ($message->findDisplayEntity(array(), array('text/html'), true)) {
132 $has_html = true;
133 }
134 }
135 /*
136 * Normal single part message so check its type.
137 */
138 else {
139 if($type0 == 'text' && $type1 == 'html') {
140 $has_html = true;
141 }
142 }
143 if($has_html == true) {
144 $vars = array('passed_ent_id', 'show_more', 'show_more_cc', 'override_type0', 'override_type1', 'startMessage','where', 'what');
145
146 $new_link = $base_uri . 'src/read_body.php?passed_id=' . urlencode($passed_id) .
147 '&amp;passed_ent_id=' . urlencode($passed_ent_id) .
148 '&amp;mailbox=' . urlencode($mailbox);
149 foreach($vars as $var) {
150 if(sqgetGlobalVar($var, $temp)) {
151 $new_link .= '&amp;' . $var . '=' . urlencode($temp);
152 }
153 }
154
155 if($show_html_default == 1) {
156 $new_link .= '&amp;show_html_default=0';
157 $link = _("View as plain text");
158 } else {
159 $new_link .= '&amp;show_html_default=1';
160 $link = _("View as HTML");
161 }
162 return '&nbsp;|&nbsp<a href="' . $new_link . '">' . $link . '</a>';
163 }
164 return '';
165 }
166
167 function ServerMDNSupport($aFlags) {
168 /* escaping $ doesn't work -> \x36 */
169 return ( in_array('$mdnsent',$aFlags,true) ||
170 in_array('\\*',$aFlags,true) ) ;
171 }
172
173 function SendMDN ( $mailbox, $passed_id, $sender, $message, $imapConnection) {
174 global $username, $attachment_dir, $popuser, $username, $color,
175 $version, $squirrelmail_language, $default_charset,
176 $languages, $useSendmail, $domain, $sent_folder;
177
178 sqgetGlobalVar('SERVER_NAME', $SERVER_NAME, SQ_SERVER);
179
180 $header = $message->rfc822_header;
181
182 $rfc822_header = new Rfc822Header();
183 $content_type = new ContentType('multipart/report');
184 $content_type->properties['report-type']='disposition-notification';
185
186 set_my_charset();
187 if ($default_charset) {
188 $content_type->properties['charset']=$default_charset;
189 }
190 $rfc822_header->content_type = $content_type;
191 $rfc822_header->to[] = $header->dnt;
192 $rfc822_header->subject = _("Read:") . ' ' . encodeHeader($header->subject);
193
194 // Patch #793504 Return Receipt Failing with <@> from Tim Craig (burny_md)
195 // This merely comes from compose.php and only happens when there is no
196 // email_addr specified in user's identity (which is the startup config)
197 if (ereg("^([^@%/]+)[@%/](.+)$", $username, $usernamedata)) {
198 $popuser = $usernamedata[1];
199 $domain = $usernamedata[2];
200 unset($usernamedata);
201 } else {
202 $popuser = $username;
203 }
204
205 $reply_to = '';
206 $ident = get_identities();
207 if(!isset($identity)) $identity = 0;
208 $full_name = $ident[$identity]['full_name'];
209 $from_mail = $ident[$identity]['email_address'];
210 $from_addr = '"'.$full_name.'" <'.$from_mail.'>';
211 $reply_to = $ident[$identity]['reply_to'];
212
213 if (!$from_mail) {
214 $from_mail = "$popuser@$domain";
215 $from_addr = $from_mail;
216 }
217 $rfc822_header->from = $rfc822_header->parseAddress($from_addr,true);
218 if ($reply_to) {
219 $rfc822_header->reply_to = $rfc822_header->parseAddress($reply_to,true);
220 }
221
222 // part 1 (RFC2298)
223 $senton = getLongDateString( $header->date );
224 $to_array = $header->to;
225 $to = '';
226 foreach ($to_array as $line) {
227 $to .= ' '.$line->getAddress();
228 }
229 $now = getLongDateString( time() );
230 set_my_charset();
231 $body = _("Your message") . "\r\n\r\n" .
232 "\t" . _("To") . ': ' . decodeHeader($to,false,false) . "\r\n" .
233 "\t" . _("Subject") . ': ' . decodeHeader($header->subject,false,false) . "\r\n" .
234 "\t" . _("Sent") . ': ' . $senton . "\r\n" .
235 "\r\n" .
236 sprintf( _("Was displayed on %s"), $now );
237
238 $special_encoding = '';
239 if (isset($languages[$squirrelmail_language]['XTRA_CODE']) &&
240 function_exists($languages[$squirrelmail_language]['XTRA_CODE'] . '_encode')) {
241 $body = call_user_func($languages[$squirrelmail_language]['XTRA_CODE'] . '_encode', $body);
242 if (strtolower($default_charset) == 'iso-2022-jp') {
243 if (mb_detect_encoding($body) == 'ASCII') {
244 $special_encoding = '8bit';
245 } else {
246 $body = mb_convert_encoding($body, 'JIS');
247 $special_encoding = '7bit';
248 }
249 }
250 } elseif (sq_is8bit($body)) {
251 $special_encoding = '8bit';
252 }
253 $part1 = new Message();
254 $part1->setBody($body);
255 $mime_header = new MessageHeader;
256 $mime_header->type0 = 'text';
257 $mime_header->type1 = 'plain';
258 if ($special_encoding) {
259 $mime_header->encoding = $special_encoding;
260 } else {
261 $mime_header->encoding = 'us-ascii';
262 }
263 if ($default_charset) {
264 $mime_header->parameters['charset'] = $default_charset;
265 }
266 $part1->mime_header = $mime_header;
267
268 // part2 (RFC2298)
269 $original_recipient = $to;
270 $original_message_id = $header->message_id;
271
272 $report = "Reporting-UA : $SERVER_NAME ; SquirrelMail (version $version) \r\n";
273 if ($original_recipient != '') {
274 $report .= "Original-Recipient : $original_recipient\r\n";
275 }
276 $final_recipient = $sender;
277 $report .= "Final-Recipient: rfc822; $final_recipient\r\n" .
278 "Original-Message-ID : $original_message_id\r\n" .
279 "Disposition: manual-action/MDN-sent-manually; displayed\r\n";
280
281 $part2 = new Message();
282 $part2->setBody($report);
283 $mime_header = new MessageHeader;
284 $mime_header->type0 = 'message';
285 $mime_header->type1 = 'disposition-notification';
286 $mime_header->encoding = 'us-ascii';
287 $part2->mime_header = $mime_header;
288
289 $composeMessage = new Message();
290 $composeMessage->rfc822_header = $rfc822_header;
291 $composeMessage->addEntity($part1);
292 $composeMessage->addEntity($part2);
293
294
295 if ($useSendmail) {
296 require_once(SM_PATH . 'class/deliver/Deliver_SendMail.class.php');
297 global $sendmail_path, $sendmail_args;
298 // Check for outdated configuration
299 if (!isset($sendmail_args)) {
300 if ($sendmail_path=='/var/qmail/bin/qmail-inject') {
301 $sendmail_args = '';
302 } else {
303 $sendmail_args = '-i -t';
304 }
305 }
306 $deliver = new Deliver_SendMail(array('sendmail_args'=>$sendmail_args));
307 $stream = $deliver->initStream($composeMessage,$sendmail_path);
308 } else {
309 require_once(SM_PATH . 'class/deliver/Deliver_SMTP.class.php');
310 $deliver = new Deliver_SMTP();
311 global $smtpServerAddress, $smtpPort, $pop_before_smtp;
312 $authPop = (isset($pop_before_smtp) && $pop_before_smtp) ? true : false;
313 get_smtp_user($user, $pass);
314 $stream = $deliver->initStream($composeMessage,$domain,0,
315 $smtpServerAddress, $smtpPort, $user, $pass, $authPop);
316 }
317 $success = false;
318 if ($stream) {
319 $length = $deliver->mail($composeMessage, $stream);
320 $success = $deliver->finalizeStream($stream);
321 }
322 if (!$success) {
323 $msg = $deliver->dlv_msg;
324 if (! empty($deliver->dlv_server_msg)) {
325 $msg.= '<br />' .
326 _("Server replied:") . ' ' . $deliver->dlv_ret_nr . ' ' .
327 nl2br(htmlspecialchars($deliver->dlv_server_msg));
328 }
329 plain_error_message($msg, $color);
330 } else {
331 unset ($deliver);
332 if (sqimap_mailbox_exists ($imapConnection, $sent_folder)) {
333 $sid = sqimap_append ($imapConnection, $sent_folder, $length);
334 require_once(SM_PATH . 'class/deliver/Deliver_IMAP.class.php');
335 $imap_deliver = new Deliver_IMAP();
336 $imap_deliver->mail($composeMessage, $imapConnection);
337 sqimap_append_done ($imapConnection, $sent_folder);
338 unset ($imap_deliver);
339 }
340 }
341 return $success;
342 }
343
344 function ToggleMDNflag ($set ,$imapConnection, $mailbox, $passed_id) {
345 $sg = $set?'+':'-';
346 $cmd = 'STORE ' . $passed_id . ' ' . $sg . 'FLAGS ($MDNSent)';
347 $read = sqimap_run_command ($imapConnection, $cmd, true, $response,
348 $readmessage, TRUE);
349 }
350
351 function formatRecipientString($recipients, $item ) {
352 global $show_more_cc, $show_more, $show_more_bcc,
353 $PHP_SELF;
354
355 $string = '';
356 if ((is_array($recipients)) && (isset($recipients[0]))) {
357 $show = false;
358
359 if ($item == 'to') {
360 if ($show_more) {
361 $show = true;
362 $url = set_url_var($PHP_SELF, 'show_more',0);
363 } else {
364 $url = set_url_var($PHP_SELF, 'show_more',1);
365 }
366 } else if ($item == 'cc') {
367 if ($show_more_cc) {
368 $show = true;
369 $url = set_url_var($PHP_SELF, 'show_more_cc',0);
370 } else {
371 $url = set_url_var($PHP_SELF, 'show_more_cc',1);
372 }
373 } else if ($item == 'bcc') {
374 if ($show_more_bcc) {
375 $show = true;
376 $url = set_url_var($PHP_SELF, 'show_more_bcc',0);
377 } else {
378 $url = set_url_var($PHP_SELF, 'show_more_bcc',1);
379 }
380 }
381
382 $cnt = count($recipients);
383 foreach($recipients as $r) {
384 $add = decodeHeader($r->getAddress(true));
385 if ($string) {
386 $string .= '<br />' . $add;
387 } else {
388 $string = $add;
389 if ($cnt > 1) {
390 $string .= '&nbsp;(<a href="'.$url;
391 if ($show) {
392 $string .= '">'._("less").'</a>)';
393 } else {
394 $string .= '">'._("more").'</a>)';
395 break;
396 }
397 }
398 }
399 }
400 }
401 return $string;
402 }
403
404 function formatEnvheader($aMailbox, $passed_id, $passed_ent_id, $message,
405 $color, $FirstTimeSee) {
406 global $default_use_mdn, $default_use_priority,
407 $show_xmailer_default, $mdn_user_support, $PHP_SELF, $javascript_on,
408 $squirrelmail_language;
409
410 $mailbox = $aMailbox['NAME'];
411
412 $header = $message->rfc822_header;
413 $env = array();
414 $env[_("Subject")] = str_replace("&nbsp;"," ",decodeHeader($header->subject));
415
416 $from_name = $header->getAddr_s('from');
417 if (!$from_name)
418 $from_name = $header->getAddr_s('sender');
419 if (!$from_name)
420 $env[_("From")] = _("Unknown sender");
421 else
422 $env[_("From")] = decodeHeader($from_name);
423 $env[_("Date")] = getLongDateString($header->date);
424 $env[_("To")] = formatRecipientString($header->to, "to");
425 $env[_("Cc")] = formatRecipientString($header->cc, "cc");
426 $env[_("Bcc")] = formatRecipientString($header->bcc, "bcc");
427 if ($default_use_priority) {
428 $env[_("Priority")] = htmlspecialchars(getPriorityStr($header->priority));
429 }
430 if ($show_xmailer_default) {
431 $env[_("Mailer")] = decodeHeader($header->xmailer);
432 }
433 if ($default_use_mdn) {
434 if ($mdn_user_support) {
435 if ($header->dnt) {
436 if ($message->is_mdnsent) {
437 $env[_("Read receipt")] = _("sent");
438 } else {
439 $env[_("Read receipt")] = _("requested");
440 if (!(handleAsSent($mailbox) ||
441 $message->is_deleted ||
442 $passed_ent_id)) {
443 $mdn_url = $PHP_SELF;
444 $mdn_url = set_url_var($PHP_SELF, 'mailbox', urlencode($mailbox));
445 $mdn_url = set_url_var($PHP_SELF, 'passed_id', $passed_id);
446 $mdn_url = set_url_var($PHP_SELF, 'passed_ent_id', $passed_ent_id);
447 $mdn_url = set_url_var($PHP_SELF, 'sendreceipt', 1);
448 if ($FirstTimeSee && $javascript_on) {
449 $script = '<script type="text/javascript">' . "\n";
450 $script .= '<!--'. "\n";
451 $script .= 'if(window.confirm("' .
452 _("The message sender has requested a response to indicate that you have read this message. Would you like to send a receipt?") .
453 '")) { '."\n" .
454 ' sendMDN()'.
455 '}' . "\n";
456 $script .= '// -->'. "\n";
457 $script .= '</script>'. "\n";
458 echo $script;
459 }
460 $env[_("Read receipt")] .= '&nbsp;<a href="' . $mdn_url . '">[' .
461 _("Send read receipt now") . ']</a>';
462 }
463 }
464 }
465 }
466 }
467
468 $s = '<table width="100%" cellpadding="0" cellspacing="2" border="0"';
469 $s .= ' align="center" bgcolor="'.$color[0].'">';
470 foreach ($env as $key => $val) {
471 if ($val) {
472 $s .= '<tr>';
473 $s .= html_tag('td', '<b>' . $key . ':&nbsp;&nbsp;</b>', 'right', '', 'valign="top" width="20%"') . "\n";
474 $s .= html_tag('td', $val, 'left', '', 'valign="top" width="80%"') . "\n";
475 $s .= '</tr>';
476 }
477 }
478 echo '<table bgcolor="'.$color[9].'" width="100%" cellpadding="1"'.
479 ' cellspacing="0" border="0" align="center">'."\n";
480 echo '<tr><td height="5" colspan="2" bgcolor="'.
481 $color[4].'"></td></tr><tr><td align="center">'."\n";
482 echo $s;
483 do_hook('read_body_header');
484 formatToolbar($mailbox, $passed_id, $passed_ent_id, $message, $color);
485 echo '</table>';
486 echo '</td></tr><tr><td height="5" colspan="2" bgcolor="'.$color[4].'"></td></tr>'."\n";
487 echo '</table>';
488 }
489
490 /**
491 * Format message toolbar
492 *
493 * @param string $mailbox Name of current mailbox
494 * @param int $passed_id UID of current message
495 * @param int $passed_ent_id Id of entity within message
496 * @param object $message Current message object
497 * @param object $mbx_response
498 */
499 function formatMenubar($aMailbox, $passed_id, $passed_ent_id, $message, $removedVar, $nav_on_top = TRUE) {
500 global $base_uri, $draft_folder, $where, $what, $color, $sort,
501 $startMessage, $PHP_SELF, $save_as_draft,
502 $enable_forward_as_attachment, $imapConnection, $lastTargetMailbox,
503 $username, $delete_prev_next_display, $show_copy_buttons,
504 $compose_new_win, $javascript_on, $compose_width, $compose_height;
505
506 //FIXME cleanup argument list, use $aMailbox where possible
507 $mailbox = $aMailbox['NAME'];
508
509 $topbar_delimiter = '&nbsp;|&nbsp;';
510 $double_delimiter = '&nbsp;&nbsp;&nbsp;&nbsp;';
511 $urlMailbox = urlencode($mailbox);
512
513 $msgs_url = $base_uri . 'src/';
514
515 // BEGIN NAV ROW - PREV/NEXT, DEL PREV/NEXT, LINKS TO INDEX, etc.
516 $nav_row = '<tr><td align="left" colspan="2" style="border: 1px solid '.$color[9].';"><small>';
517
518 // Create Prev & Next links
519 // Handle nested entities first (i.e. Mime Attach parts)
520 if (isset($passed_ent_id) && $passed_ent_id) {
521 // code for navigating through attached message/rfc822 messages
522 $url = set_url_var($PHP_SELF, 'passed_ent_id',0);
523 $entities = array();
524 $entity_count = array();
525 $c = 0;
526
527 foreach($message->parent->entities as $ent) {
528 if ($ent->type0 == 'message' && $ent->type1 == 'rfc822') {
529 $c++;
530 $entity_count[$c] = $ent->entity_id;
531 $entities[$ent->entity_id] = $c;
532 }
533 }
534
535 $prev_link = _("Previous");
536 if(isset($entities[$passed_ent_id]) && $entities[$passed_ent_id] > 1) {
537 $prev_ent_id = $entity_count[$entities[$passed_ent_id] - 1];
538 $prev_link = '<a href="'
539 . set_url_var($PHP_SELF, 'passed_ent_id', $prev_ent_id)
540 . '">' . $prev_link . '</a>';
541 }
542
543 $next_link = _("Next");
544 if(isset($entities[$passed_ent_id]) && $entities[$passed_ent_id] < $c) {
545 $next_ent_id = $entity_count[$entities[$passed_ent_id] + 1];
546 $next_link = '<a href="'
547 . set_url_var($PHP_SELF, 'passed_ent_id', $next_ent_id)
548 . '">' . $next_link . '</a>';
549 }
550
551 $par_ent_id = $message->parent->entity_id;
552 $up_link = '';
553 if ($par_ent_id) {
554 $par_ent_id = substr($par_ent_id,0,-2);
555 if ( $par_ent_id != 0 ) {
556 $up_link = $topbar_delimiter;
557 $url = set_url_var($PHP_SELF, 'passed_ent_id',$par_ent_id);
558 $up_link .= '<a href="'.$url.'">'._("Up").'</a>';
559 }
560 }
561
562 $nav_row .= $prev_link . $up_link . $topbar_delimiter . $next_link;
563 $nav_row .= $double_delimiter . '[<a href="'.$url.'">'._("View Message").'</a>]';
564
565 // Prev/Next links for regular messages
566 } else if ( true ) { //!(isset($where) && isset($what)) ) {
567 $prev = findPreviousMessage($aMailbox['UIDSET'][$what], $passed_id);
568 $next = findNextMessage($aMailbox['UIDSET'][$what],$passed_id);
569
570 $prev_link = _("Previous");
571 if ($prev >= 0) {
572 $uri = $base_uri . 'src/read_body.php?passed_id='.$prev.
573 '&amp;mailbox='.$urlMailbox.'&amp;sort='.$sort.
574 "&amp;where=$where&amp;what=$what" .
575 '&amp;startMessage='.$startMessage.'&amp;show_more=0';
576 $prev_link = '<a href="'.$uri.'">'.$prev_link.'</a>';
577 }
578
579 $next_link = _("Next");
580 if ($next >= 0) {
581 $uri = $base_uri . 'src/read_body.php?passed_id='.$next.
582 '&amp;mailbox='.$urlMailbox.'&amp;sort='.$sort.
583 "&amp;where=$where&amp;what=$what" .
584 '&amp;startMessage='.$startMessage.'&amp;show_more=0';
585 $next_link = '<a href="'.$uri.'">'.$next_link.'</a>';
586 }
587
588 // Only bother with Delete & Prev and Delete & Next IF
589 // top display is enabled.
590 if ( $delete_prev_next_display == 1 &&
591 in_array('\\deleted', $aMailbox['PERMANENTFLAGS'],true) ) {
592 $del_prev_link = _("Delete &amp; Prev");
593 if ($prev >= 0) {
594 $uri = $base_uri . 'src/read_body.php?passed_id='.$prev.
595 '&amp;mailbox='.$urlMailbox.'&amp;sort='.$sort.
596 '&amp;startMessage='.$startMessage.'&amp;show_more=0'.
597 "&amp;where=$where&amp;what=$what" .
598 '&amp;delete_id='.$passed_id;
599 $del_prev_link = '<a href="'.$uri.'">'.$del_prev_link.'</a>';
600 }
601
602 $del_next_link = _("Delete &amp; Next");
603 if ($next >= 0) {
604 $uri = $base_uri . 'src/read_body.php?passed_id='.$next.
605 '&amp;mailbox='.$urlMailbox.'&amp;sort='.$sort.
606 '&amp;startMessage='.$startMessage.'&amp;show_more=0'.
607 "&amp;where=$where&amp;what=$what" .
608 '&amp;delete_id='.$passed_id;
609 $del_next_link = '<a href="'.$uri.'">'.$del_next_link.'</a>';
610 }
611 }
612
613 $nav_row .= '['.$prev_link.$topbar_delimiter.$next_link.']';
614 if ( isset($del_prev_link) && isset($del_next_link) )
615 $nav_row .= $double_delimiter.'['.$del_prev_link.$topbar_delimiter.$del_next_link.']';
616 }
617
618 // Start with Search Results or Message List link.
619 $msgs_url .= "$where?where=read_body.php&amp;what=$what&amp;mailbox=" . $urlMailbox.
620 "&amp;startMessage=$startMessage";
621 if ($where == 'search.php') {
622 $msgs_str = _("Search Results");
623 } else {
624 $msgs_str = _("Message List");
625 }
626 $nav_row .= $double_delimiter .
627 '[<a href="' . $msgs_url . '">' . $msgs_str . '</a>]';
628
629 $nav_row .= '</small></td></tr>';
630
631
632 // BEGIN MENU ROW - DELETE/REPLY/FORWARD/MOVE/etc.
633 $menu_row = '<tr bgcolor="'.$color[0].'"><td><small>';
634 $comp_uri = $base_uri.'src/compose.php' .
635 '?passed_id=' . $passed_id .
636 '&amp;mailbox=' . $urlMailbox .
637 '&amp;startMessage=' . $startMessage .
638 (isset($passed_ent_id) ? '&amp;passed_ent_id='.$passed_ent_id : '');
639
640 // Start form for reply/reply all/forward..
641 $target = '';
642 $on_click='';
643 $method='method="post" ';
644 $onsubmit='';
645 if ($compose_new_win == '1') {
646 if (!preg_match("/^[0-9]{3,4}$/", $compose_width)) {
647 $compose_width = '640';
648 }
649 if (!preg_match("/^[0-9]{3,4}$/", $compose_height)) {
650 $compose_height = '550';
651 }
652 if ( $javascript_on ) {
653 $on_click=' onclick="comp_in_new_form(\''.$comp_uri.'\', this, this.form,'. $compose_width .',' . $compose_height .')"';
654 $comp_uri = 'javascript:void(0)';
655 $method='method="get" ';
656 $onsubmit = 'onsubmit="return false" ';
657 } else {
658 $target = 'target="_blank"';
659 }
660 }
661
662 $menu_row .= "\n".'<form name="composeForm" action="'.$comp_uri.'" '
663 . $method.$target.$onsubmit.' style="display: inline">'."\n";
664
665 // If Draft folder - create Resume link
666 if (($mailbox == $draft_folder) && ($save_as_draft)) {
667 $new_button = 'smaction_draft';
668 $comp_alt_string = _("Resume Draft");
669 } else if (handleAsSent($mailbox)) {
670 // If in Sent folder, edit as new
671 $new_button = 'smaction_edit_new';
672 $comp_alt_string = _("Edit Message as New");
673 }
674 // Show Alt URI for Draft/Sent
675 if (isset($comp_alt_string))
676 $menu_row .= getButton('submit', $new_button, $comp_alt_string, $on_click) . "\n";
677
678 $menu_row .= getButton('submit', 'smaction_reply', _("Reply"), $on_click) . "\n";
679 $menu_row .= getButton('submit', 'smaction_reply_all', _("Reply All"), $on_click) ."\n";
680 $menu_row .= getButton('submit', 'smaction_forward', _("Forward"), $on_click);
681 if ($enable_forward_as_attachment)
682 $menu_row .= '<input type="checkbox" name="smaction_attache" />' . _("As Attachment") .'&nbsp;&nbsp;'."\n";
683
684 $menu_row .= '</form>&nbsp;';
685
686 if ( in_array('\\deleted', $aMailbox['PERMANENTFLAGS'],true) ) {
687 // Form for deletion. Form is handled by the originating display in $where. This is right_main.php or search.php
688 $delete_url = $base_uri . "src/$where";
689 $menu_row .= '<form name="deleteMessageForm" action="'.$delete_url.'" method="post" style="display: inline">';
690
691 if (!(isset($passed_ent_id) && $passed_ent_id)) {
692 $menu_row .= addHidden('mailbox', $aMailbox['NAME']);
693 $menu_row .= addHidden('msg[0]', $passed_id);
694 $menu_row .= addHidden('startMessage', $startMessage);
695 $menu_row .= getButton('submit', 'delete', _("Delete"));
696 $menu_row .= '<input type="checkbox" name="bypass_trash" />' . _("Bypass Trash");
697 } else {
698 $menu_row .= getButton('submit', 'delete', _("Delete"), '', FALSE) . "\n"; // delete button is disabled
699 }
700
701 $menu_row .= '</form>';
702 }
703
704 // Add top move link
705 $menu_row .= '</small></td><td align="right">';
706 if ( !(isset($passed_ent_id) && $passed_ent_id) &&
707 in_array('\\deleted', $aMailbox['PERMANENTFLAGS'],true) ) {
708
709 $menu_row .= '<form name="moveMessageForm" action="'.$base_uri.'src/'.$where.'?'.'" method="post" style="display: inline">'.
710 '<small>'.
711
712 addHidden('mailbox',$aMailbox['NAME']) .
713 addHidden('msg[0]', $passed_id) . _("Move to:") .
714 '<select name="targetMailbox" style="padding: 0px; margin: 0px">';
715
716 if (isset($lastTargetMailbox) && !empty($lastTargetMailbox)) {
717 $menu_row .= sqimap_mailbox_option_list($imapConnection, array(strtolower($lastTargetMailbox)));
718 } else {
719 $menu_row .= sqimap_mailbox_option_list($imapConnection);
720 }
721 $menu_row .= '</select> ';
722
723 $menu_row .= getButton('submit', 'moveButton',_("Move")) . "\n";
724
725 // Add msg copy button
726 if ($show_copy_buttons) {
727 $menu_row .= getButton('submit', 'copyButton', _("Copy"));
728 }
729
730 $menu_row .= '</form>';
731 }
732 $menu_row .= '</td></tr>';
733
734 // echo rows, with hooks
735 $ret = do_hook_function('read_body_menu_top', array($nav_row, $menu_row));
736 if (is_array($ret)) {
737 if (isset($ret[0]) && !empty($ret[0])) {
738 $nav_row = $ret[0];
739 }
740 if (isset($ret[1]) && !empty($ret[1])) {
741 $menu_row = $ret[1];
742 }
743 }
744 echo '<table width="100%" cellpadding="3" cellspacing="0" align="center" border="0">';
745 echo $nav_on_top ? $nav_row . $menu_row : $menu_row . $nav_row;
746 echo '</table>'."\n";
747 do_hook('read_body_menu_bottom');
748 }
749
750 function formatToolbar($mailbox, $passed_id, $passed_ent_id, $message, $color) {
751 global $base_uri, $where, $what, $download_and_unsafe_link;
752
753 $urlMailbox = urlencode($mailbox);
754 $urlPassed_id = urlencode($passed_id);
755 $urlPassed_ent_id = urlencode($passed_ent_id);
756
757 $query_string = 'mailbox=' . $urlMailbox . '&amp;passed_id=' . $urlPassed_id . '&amp;passed_ent_id=' . $urlPassed_ent_id;
758
759 if (!empty($where)) {
760 $query_string .= '&amp;where=' . urlencode($where);
761 }
762
763 if (!empty($what)) {
764 $query_string .= '&amp;what=' . urlencode($what);
765 }
766
767 $url = $base_uri.'src/view_header.php?'.$query_string;
768
769 $s = "<tr>\n" .
770 html_tag( 'td', '', 'right', '', 'valign="middle" width="20%"' ) . '<b>' . _("Options") . ":&nbsp;&nbsp;</b></td>\n" .
771 html_tag( 'td', '', 'left', '', 'valign="middle" width="80%"' ) . '<small>' .
772 '<a href="'.$url.'">'._("View Full Header").'</a>';
773
774 /* Output the printer friendly link if we are in subtle mode. */
775 $s .= '&nbsp;|&nbsp;' .
776 printer_friendly_link($mailbox, $passed_id, $passed_ent_id);
777 echo $s;
778 echo view_as_html_link($mailbox, $passed_id, $passed_ent_id, $message);
779
780 /* Output the download and/or unsafe images link/-s, if any. */
781 if ($download_and_unsafe_link) {
782 echo $download_and_unsafe_link;
783 }
784
785 do_hook("read_body_header_right");
786 $s = "</small></td>\n" .
787 "</tr>\n";
788 echo $s;
789
790 }
791
792 /**
793 * Creates button
794 *
795 * @deprecated see form functions available in 1.5.1 and 1.4.3.
796 * @param string $type
797 * @param string $name
798 * @param string $value
799 * @param string $js
800 * @param bool $enabled
801 */
802 function getButton($type, $name, $value, $js = '', $enabled = TRUE) {
803 $disabled = ( $enabled ? '' : 'disabled ' );
804 $js = ( $js ? $js.' ' : '' );
805 return '<input '.$disabled.$js.
806 'type="'.$type.
807 '" name="'.$name.
808 '" value="'.$value .
809 '" style="padding: 0px; margin: 0px" />';
810 }
811
812
813 /***************************/
814 /* Main of read_body.php */
815 /***************************/
816
817 /* get the globals we may need */
818
819 sqgetGlobalVar('key', $key, SQ_COOKIE);
820 sqgetGlobalVar('username', $username, SQ_SESSION);
821 sqgetGlobalVar('onetimepad',$onetimepad, SQ_SESSION);
822 sqgetGlobalVar('delimiter', $delimiter, SQ_SESSION);
823 sqgetGlobalVar('base_uri', $base_uri, SQ_SESSION);
824 sqgetGlobalVar('lastTargetMailbox', $lastTargetMailbox, SQ_SESSION);
825 if (!sqgetGlobalVar('messages', $messages, SQ_SESSION) ) {
826 $messages = array();
827 }
828 sqgetGlobalVar('delayed_errors', $delayed_errors, SQ_SESSION);
829 if (is_array($delayed_errors)) {
830 $oErrorHandler->AssignDelayedErrors($delayed_errors);
831 sqsession_unregister("delayed_errors");
832 }
833 /** GET VARS */
834 sqgetGlobalVar('sendreceipt', $sendreceipt, SQ_GET);
835 if (!sqgetGlobalVar('where', $where, SQ_GET) ) {
836 $where = 'right_main.php';
837 }
838 /*
839 * Used as entry key to the list of uid's cached in the mailbox cache
840 * we use the cached uid's to get the next and prev message.
841 */
842 if (!sqgetGlobalVar('what', $what, SQ_GET) ){
843 $what = 0;
844 }
845 if ( sqgetGlobalVar('show_more', $temp, SQ_GET) ) {
846 $show_more = (int) $temp;
847 }
848 if ( sqgetGlobalVar('show_more_cc', $temp, SQ_GET) ) {
849 $show_more_cc = (int) $temp;
850 }
851 if ( sqgetGlobalVar('show_more_bcc', $temp, SQ_GET) ) {
852 $show_more_bcc = (int) $temp;
853 }
854 if ( sqgetGlobalVar('view_hdr', $temp, SQ_GET) ) {
855 $view_hdr = (int) $temp;
856 }
857
858 if ( sqgetGlobalVar('account', $temp, SQ_GET) ) {
859 $iAccount = (int) $temp;
860 } else {
861 $iAccount = 0;
862 }
863
864 /** GET/POST VARS */
865 sqgetGlobalVar('passed_ent_id', $passed_ent_id);
866 sqgetGlobalVar('mailbox', $mailbox);
867
868 if ( sqgetGlobalVar('passed_id', $temp) ) {
869 $passed_id = (int) $temp;
870 }
871 if ( sqgetGlobalVar('sort', $temp) ) {
872 $sort = (int) $temp;
873 }
874 if ( sqgetGlobalVar('startMessage', $temp) ) {
875 $startMessage = (int) $temp;
876 } else {
877 $startMessage = 1;
878 }
879 if(sqgetGlobalVar('show_html_default', $temp)) {
880 $show_html_default = (int) $temp;
881 }
882
883 if(sqgetGlobalVar('view_unsafe_images', $temp)) {
884 $view_unsafe_images = (int) $temp;
885 if($view_unsafe_images == 1) {
886 $show_html_default = 1;
887 }
888 } else {
889 $view_unsafe_images = 0;
890 }
891 /**
892 * Retrieve mailbox cache
893 */
894 sqgetGlobalVar('mailbox_cache',$mailbox_cache,SQ_SESSION);
895
896 /* end of get globals */
897 global $sqimap_capabilities, $lastTargetMailbox;
898
899 $imapConnection = sqimap_login($username, $key, $imapServerAddress, $imapPort, 0);
900 $aMailbox = sqm_api_mailbox_select($imapConnection, $iAccount, $mailbox,array('setindex' => $what, 'offset' => $startMessage),array());
901
902
903 /**
904 Start code to set the columns to fetch in case of hitting the next/prev link
905 The reason for this is the fact that the cache can be invalidated which means that the headers
906 to fetch aren't there anymore. Before they got calculated when the messagelist was shown.
907
908 Todo, better central handling of setting the mailbox options so we do not need to do the stuff below
909 */
910
911 /**
912 * Replace From => To in case it concerns a draft or sent folder
913 */
914 $aColumns = array();
915 if (($mailbox == $sent_folder || $mailbox == $draft_folder) &&
916 !in_array(SQM_COL_TO,$index_order)) {
917 $aNewOrder = array(); // nice var name ;)
918 foreach($index_order as $iCol) {
919 if ($iCol == SQM_COL_FROM) {
920 $iCol = SQM_COL_TO;
921 }
922 $aColumns[$iCol] = array();
923 }
924 } else {
925 foreach ($index_order as $iCol) {
926 $aColumns[$iCol] = array();
927 }
928 }
929
930 $aProps = array(
931 'columns' => $aColumns, // columns bound settings
932 'config' => array(
933 'highlight_list' => $message_highlight_list, // row highlighting rules
934 'trash_folder' => $trash_folder,
935 'sent_folder' => $sent_folder,
936 'draft_folder' => $draft_folder));
937
938 calcFetchColumns($aMailbox,$aProps);
939
940 /**
941 End code to set the columns to fetch in case of hitting the next/prev link
942 */
943
944
945
946 /**
947 * Check if cache is still valid, $what contains the key
948 * which gives us acces to the array with uid's. At this moment
949 * 0 is used for a normal message list and search uses 1 as key. This can be
950 * changed / extended in the future.
951 * If on a select of a mailbox we detect that the cache should be invalidated due to
952 * the delete of messages or due to new messages we empty the list with uid's and
953 * that's what we detect below.
954 */
955 if (!is_array($aMailbox['UIDSET'][$what])) {
956 fetchMessageHeaders($imapConnection, $aMailbox);
957 }
958
959 $iSetIndex = $aMailbox['SETINDEX'];
960 $aMailbox['CURRENT_MSG'][$iSetIndex] = $passed_id;
961
962 /**
963 * Update the seen state
964 * and ignore in_array('\\seen',$aMailbox['PERMANENTFLAGS'],true)
965 */
966 if (isset($aMailbox['MSG_HEADERS'][$passed_id]['FLAGS'])) {
967 $aMailbox['MSG_HEADERS'][$passed_id]['FLAGS']['\\seen'] = true;
968 }
969
970 /**
971 * Process Delete from delete-move-next
972 * but only if delete_id was set
973 */
974 if ( sqgetGlobalVar('delete_id', $delete_id, SQ_GET) ) {
975 handleMessageListForm($imapConnection,$aMailbox,$sButton='setDeleted', array($delete_id));
976 }
977
978 /**
979 * $message contains all information about the message
980 * including header and body
981 */
982
983 if (isset($aMailbox['MSG_HEADERS'][$passed_id]['MESSAGE_OBJECT'])) {
984 $message = $aMailbox['MSG_HEADERS'][$passed_id]['MESSAGE_OBJECT'];
985 $FirstTimeSee = !$message->is_seen;
986 } else {
987 $message = sqimap_get_message($imapConnection, $passed_id, $mailbox);
988 $FirstTimeSee = !$message->is_seen;
989 $message->is_seen = true;
990 $aMailbox['MSG_HEADERS'][$passed_id]['MESSAGE_OBJECT'] = $message;
991 }
992 if (isset($passed_ent_id) && $passed_ent_id) {
993 $message = $message->getEntity($passed_ent_id);
994 if ($message->type0 != 'message' && $message->type1 != 'rfc822') {
995 $message = $message->parent;
996 }
997 $read = sqimap_run_command ($imapConnection, "FETCH $passed_id BODY[$passed_ent_id.HEADER]", true, $response, $msg, TRUE);
998 $rfc822_header = new Rfc822Header();
999 $rfc822_header->parseHeader($read);
1000 $message->rfc822_header = $rfc822_header;
1001 } else if ($message->type0 == 'message' && $message->type1 == 'rfc822' && isset($message->entities[0])) {
1002 $read = sqimap_run_command ($imapConnection, "FETCH $passed_id BODY[1.HEADER]", true, $response, $msg, TRUE);
1003 $rfc822_header = new Rfc822Header();
1004 $rfc822_header->parseHeader($read);
1005 $message->rfc822_header = $rfc822_header;
1006 } else {
1007 $passed_ent_id = 0;
1008 }
1009 $header = $message->header;
1010
1011
1012 /****************************************/
1013 /* Block for handling incoming url vars */
1014 /****************************************/
1015
1016 if (isset($sendreceipt)) {
1017 if ( !$message->is_mdnsent ) {
1018 $final_recipient = '';
1019 if ((isset($identity)) && ($identity != 0)) //Main identity
1020 $final_recipient = trim(getPref($data_dir, $username, 'email_address' . $identity, '' ));
1021 if ($final_recipient == '' )
1022 $final_recipient = trim(getPref($data_dir, $username, 'email_address', '' ));
1023 $supportMDN = ServerMDNSupport($aMailbox["PERMANENTFLAGS"]);
1024 if ( SendMDN( $mailbox, $passed_id, $final_recipient, $message, $imapConnection ) > 0 && $supportMDN ) {
1025 ToggleMDNflag( true, $imapConnection, $mailbox, $passed_id);
1026 $message->is_mdnsent = true;
1027 $aMailbox['MSG_HEADERS'][$passed_id]['MESSAGE_OBJECT'] = $message;
1028 }
1029 }
1030 }
1031 /***********************************************/
1032 /* End of block for handling incoming url vars */
1033 /***********************************************/
1034
1035 $messagebody = '';
1036 do_hook('read_body_top');
1037 if ($show_html_default == 1) {
1038 $ent_ar = $message->findDisplayEntity(array());
1039 } else {
1040 $ent_ar = $message->findDisplayEntity(array(), array('text/plain'));
1041 }
1042 $cnt = count($ent_ar);
1043 for ($i = 0; $i < $cnt; $i++) {
1044 $messagebody .= formatBody($imapConnection, $message, $color, $wrap_at, $ent_ar[$i], $passed_id, $mailbox);
1045 if ($i != $cnt-1) {
1046 $messagebody .= '<hr style="height: 1px;" />';
1047 }
1048 }
1049
1050 /**
1051 * Write mailbox with updated seen flag information back to cache.
1052 */
1053 $mailbox_cache[$iAccount.'_'.$aMailbox['NAME']] = $aMailbox;
1054 sqsession_register($mailbox_cache,'mailbox_cache');
1055 $_SESSION['mailbox_cache'] = $mailbox_cache;
1056
1057 displayPageHeader($color, $mailbox,'','');
1058 formatMenuBar($aMailbox, $passed_id, $passed_ent_id, $message,false);
1059 formatEnvheader($aMailbox, $passed_id, $passed_ent_id, $message, $color, $FirstTimeSee);
1060 echo '<table width="100%" cellpadding="0" cellspacing="0" align="center" border="0">';
1061 echo ' <tr><td>';
1062 echo ' <table width="100%" cellpadding="1" cellspacing="0" align="center" border="0" bgcolor="'.$color[9].'">';
1063 echo ' <tr><td>';
1064 echo ' <table width="100%" cellpadding="3" cellspacing="0" align="center" border="0">';
1065 echo ' <tr bgcolor="'.$color[4].'"><td>';
1066 // echo ' <table cellpadding="1" cellspacing="5" align="left" border="0">';
1067 echo html_tag( 'table' ,'' , 'left', '', 'width="100%" cellpadding="1" cellspacing="5" border="0"' );
1068 echo ' <tr>' . html_tag( 'td', '<br />'. $messagebody."\n", 'left')
1069 . '</tr>';
1070 echo ' </table>';
1071 echo ' </td></tr>';
1072 echo ' </table></td></tr>';
1073 echo ' </table>';
1074 echo ' </td></tr>';
1075
1076 echo '<tr><td height="5" colspan="2" bgcolor="'.
1077 $color[4].'"></td></tr>'."\n";
1078
1079 $attachmentsdisplay = formatAttachments($message,$ent_ar,$mailbox, $passed_id);
1080 if ($attachmentsdisplay) {
1081 echo ' </table>';
1082 echo ' <table width="100%" cellpadding="1" cellspacing="0" align="center"'.' border="0" bgcolor="'.$color[9].'">';
1083 echo ' <tr><td>';
1084 echo ' <table width="100%" cellpadding="0" cellspacing="0" align="center" border="0" bgcolor="'.$color[4].'">';
1085 echo ' <tr>' . html_tag( 'td', '', 'left', $color[9] );
1086 echo ' <b>' . _("Attachments") . ':</b>';
1087 echo ' </td></tr>';
1088 echo ' <tr><td>';
1089 echo ' <table width="100%" cellpadding="2" cellspacing="2" align="center"'.' border="0" bgcolor="'.$color[0].'"><tr><td>';
1090 echo $attachmentsdisplay;
1091 echo ' </td></tr></table>';
1092 echo ' </td></tr></table>';
1093 echo ' </td></tr>';
1094 echo '<tr><td height="5" colspan="2" bgcolor="'.
1095 $color[4].'"></td></tr>';
1096 }
1097 echo '</table>';
1098
1099 /* show attached images inline -- if pref'fed so */
1100 if (($attachment_common_show_images) &&
1101 is_array($attachment_common_show_images_list)) {
1102 foreach ($attachment_common_show_images_list as $img) {
1103 $imgurl = SM_PATH . 'src/download.php' .
1104 '?' .
1105 'passed_id=' . urlencode($img['passed_id']) .
1106 '&amp;mailbox=' . urlencode($mailbox) .
1107 '&amp;ent_id=' . urlencode($img['ent_id']) .
1108 '&amp;absolute_dl=true';
1109
1110 echo html_tag( 'table', "\n" .
1111 html_tag( 'tr', "\n" .
1112 html_tag( 'td', '<img src="' . $imgurl . '" />' ."\n", 'left'
1113 )
1114 ) ,
1115 'center', '', 'cellspacing="0" border="0" cellpadding="2"');
1116 }
1117 }
1118
1119 formatMenuBar($aMailbox, $passed_id, $passed_ent_id, $message, false, FALSE);
1120
1121 do_hook('read_body_bottom');
1122 sqimap_logout($imapConnection);
1123 $oTemplate->display('footer.tpl');
1124 ?>