adding message copy buttons.
[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;
298 $deliver = new Deliver_SendMail();
299 $stream = $deliver->initStream($composeMessage,$sendmail_path);
300 } else {
301 require_once(SM_PATH . 'class/deliver/Deliver_SMTP.class.php');
302 $deliver = new Deliver_SMTP();
303 global $smtpServerAddress, $smtpPort, $pop_before_smtp;
304 $authPop = (isset($pop_before_smtp) && $pop_before_smtp) ? true : false;
305 get_smtp_user($user, $pass);
306 $stream = $deliver->initStream($composeMessage,$domain,0,
307 $smtpServerAddress, $smtpPort, $user, $pass, $authPop);
308 }
309 $success = false;
310 if ($stream) {
311 $length = $deliver->mail($composeMessage, $stream);
312 $success = $deliver->finalizeStream($stream);
313 }
314 if (!$success) {
315 $msg = $deliver->dlv_msg;
316 if (! empty($deliver->dlv_server_msg)) {
317 $msg.= '<br />' .
318 _("Server replied:") . ' ' . $deliver->dlv_ret_nr . ' ' .
319 nl2br(htmlspecialchars($deliver->dlv_server_msg));
320 }
321 plain_error_message($msg, $color);
322 } else {
323 unset ($deliver);
324 if (sqimap_mailbox_exists ($imapConnection, $sent_folder)) {
325 $sid = sqimap_append ($imapConnection, $sent_folder, $length);
326 require_once(SM_PATH . 'class/deliver/Deliver_IMAP.class.php');
327 $imap_deliver = new Deliver_IMAP();
328 $imap_deliver->mail($composeMessage, $imapConnection);
329 sqimap_append_done ($imapConnection, $sent_folder);
330 unset ($imap_deliver);
331 }
332 }
333 return $success;
334 }
335
336 function ToggleMDNflag ($set ,$imapConnection, $mailbox, $passed_id) {
337 $sg = $set?'+':'-';
338 $cmd = 'STORE ' . $passed_id . ' ' . $sg . 'FLAGS ($MDNSent)';
339 $read = sqimap_run_command ($imapConnection, $cmd, true, $response,
340 $readmessage, TRUE);
341 }
342
343 function formatRecipientString($recipients, $item ) {
344 global $show_more_cc, $show_more, $show_more_bcc,
345 $PHP_SELF;
346
347 $string = '';
348 if ((is_array($recipients)) && (isset($recipients[0]))) {
349 $show = false;
350
351 if ($item == 'to') {
352 if ($show_more) {
353 $show = true;
354 $url = set_url_var($PHP_SELF, 'show_more',0);
355 } else {
356 $url = set_url_var($PHP_SELF, 'show_more',1);
357 }
358 } else if ($item == 'cc') {
359 if ($show_more_cc) {
360 $show = true;
361 $url = set_url_var($PHP_SELF, 'show_more_cc',0);
362 } else {
363 $url = set_url_var($PHP_SELF, 'show_more_cc',1);
364 }
365 } else if ($item == 'bcc') {
366 if ($show_more_bcc) {
367 $show = true;
368 $url = set_url_var($PHP_SELF, 'show_more_bcc',0);
369 } else {
370 $url = set_url_var($PHP_SELF, 'show_more_bcc',1);
371 }
372 }
373
374 $cnt = count($recipients);
375 foreach($recipients as $r) {
376 $add = decodeHeader($r->getAddress(true));
377 if ($string) {
378 $string .= '<br />' . $add;
379 } else {
380 $string = $add;
381 if ($cnt > 1) {
382 $string .= '&nbsp;(<a href="'.$url;
383 if ($show) {
384 $string .= '">'._("less").'</a>)';
385 } else {
386 $string .= '">'._("more").'</a>)';
387 break;
388 }
389 }
390 }
391 }
392 }
393 return $string;
394 }
395
396 function formatEnvheader($aMailbox, $passed_id, $passed_ent_id, $message,
397 $color, $FirstTimeSee) {
398 global $default_use_mdn, $default_use_priority,
399 $show_xmailer_default, $mdn_user_support, $PHP_SELF, $javascript_on,
400 $squirrelmail_language;
401
402 $mailbox = $aMailbox['NAME'];
403
404 $header = $message->rfc822_header;
405 $env = array();
406 $env[_("Subject")] = str_replace("&nbsp;"," ",decodeHeader($header->subject));
407
408 $from_name = $header->getAddr_s('from');
409 if (!$from_name)
410 $from_name = $header->getAddr_s('sender');
411 if (!$from_name)
412 $env[_("From")] = _("Unknown sender");
413 else
414 $env[_("From")] = decodeHeader($from_name);
415 $env[_("Date")] = getLongDateString($header->date);
416 $env[_("To")] = formatRecipientString($header->to, "to");
417 $env[_("Cc")] = formatRecipientString($header->cc, "cc");
418 $env[_("Bcc")] = formatRecipientString($header->bcc, "bcc");
419 if ($default_use_priority) {
420 $env[_("Priority")] = htmlspecialchars(getPriorityStr($header->priority));
421 }
422 if ($show_xmailer_default) {
423 $env[_("Mailer")] = decodeHeader($header->xmailer);
424 }
425 if ($default_use_mdn) {
426 if ($mdn_user_support) {
427 if ($header->dnt) {
428 if ($message->is_mdnsent) {
429 $env[_("Read receipt")] = _("sent");
430 } else {
431 $env[_("Read receipt")] = _("requested");
432 if (!(handleAsSent($mailbox) ||
433 $message->is_deleted ||
434 $passed_ent_id)) {
435 $mdn_url = $PHP_SELF . '&sendreceipt=1';
436 if ($FirstTimeSee && $javascript_on) {
437 $script = '<script type="text/javascript">' . "\n";
438 $script .= '<!--'. "\n";
439 $script .= 'if(window.confirm("' .
440 _("The message sender has requested a response to indicate that you have read this message. Would you like to send a receipt?") .
441 '")) { '."\n" .
442 ' sendMDN()'.
443 '}' . "\n";
444 $script .= '// -->'. "\n";
445 $script .= '</script>'. "\n";
446 echo $script;
447 }
448 $env[_("Read receipt")] .= '&nbsp;<a href="' . $mdn_url . '">[' .
449 _("Send read receipt now") . ']</a>';
450 }
451 }
452 }
453 }
454 }
455
456 $s = '<table width="100%" cellpadding="0" cellspacing="2" border="0"';
457 $s .= ' align="center" bgcolor="'.$color[0].'">';
458 foreach ($env as $key => $val) {
459 if ($val) {
460 $s .= '<tr>';
461 $s .= html_tag('td', '<b>' . $key . ':&nbsp;&nbsp;</b>', 'right', '', 'valign="top" width="20%"') . "\n";
462 $s .= html_tag('td', $val, 'left', '', 'valign="top" width="80%"') . "\n";
463 $s .= '</tr>';
464 }
465 }
466 echo '<table bgcolor="'.$color[9].'" width="100%" cellpadding="1"'.
467 ' cellspacing="0" border="0" align="center">'."\n";
468 echo '<tr><td height="5" colspan="2" bgcolor="'.
469 $color[4].'"></td></tr><tr><td align="center">'."\n";
470 echo $s;
471 do_hook('read_body_header');
472 formatToolbar($mailbox, $passed_id, $passed_ent_id, $message, $color);
473 echo '</table>';
474 echo '</td></tr><tr><td height="5" colspan="2" bgcolor="'.$color[4].'"></td></tr>'."\n";
475 echo '</table>';
476 }
477
478 /**
479 * Format message toolbar
480 *
481 * @param string $mailbox Name of current mailbox
482 * @param int $passed_id UID of current message
483 * @param int $passed_ent_id Id of entity within message
484 * @param object $message Current message object
485 * @param object $mbx_response
486 */
487 function formatMenubar($aMailbox, $passed_id, $passed_ent_id, $message, $removedVar, $nav_on_top = TRUE) {
488 global $base_uri, $draft_folder, $where, $what, $color, $sort,
489 $startMessage, $PHP_SELF, $save_as_draft,
490 $enable_forward_as_attachment, $imapConnection, $lastTargetMailbox,
491 $username, $delete_prev_next_display, $show_copy_buttons,
492 $compose_new_win, $javascript_on, $compose_width, $compose_height;
493
494 //FIXME cleanup argument list, use $aMailbox where possible
495 $mailbox = $aMailbox['NAME'];
496
497 $topbar_delimiter = '&nbsp;|&nbsp;';
498 $double_delimiter = '&nbsp;&nbsp;&nbsp;&nbsp;';
499 $urlMailbox = urlencode($mailbox);
500
501 $msgs_url = $base_uri . 'src/';
502
503 // BEGIN NAV ROW - PREV/NEXT, DEL PREV/NEXT, LINKS TO INDEX, etc.
504 $nav_row = '<tr><td align="left" colspan="2" style="border: 1px solid '.$color[9].';"><small>';
505
506 // Create Prev & Next links
507 // Handle nested entities first (i.e. Mime Attach parts)
508 if (isset($passed_ent_id) && $passed_ent_id) {
509 // code for navigating through attached message/rfc822 messages
510 $url = set_url_var($PHP_SELF, 'passed_ent_id',0);
511 $entities = array();
512 $entity_count = array();
513 $c = 0;
514
515 foreach($message->parent->entities as $ent) {
516 if ($ent->type0 == 'message' && $ent->type1 == 'rfc822') {
517 $c++;
518 $entity_count[$c] = $ent->entity_id;
519 $entities[$ent->entity_id] = $c;
520 }
521 }
522
523 $prev_link = _("Previous");
524 if(isset($entities[$passed_ent_id]) && $entities[$passed_ent_id] > 1) {
525 $prev_ent_id = $entity_count[$entities[$passed_ent_id] - 1];
526 $prev_link = '<a href="'
527 . set_url_var($PHP_SELF, 'passed_ent_id', $prev_ent_id)
528 . '">' . $prev_link . '</a>';
529 }
530
531 $next_link = _("Next");
532 if(isset($entities[$passed_ent_id]) && $entities[$passed_ent_id] < $c) {
533 $next_ent_id = $entity_count[$entities[$passed_ent_id] + 1];
534 $next_link = '<a href="'
535 . set_url_var($PHP_SELF, 'passed_ent_id', $next_ent_id)
536 . '">' . $next_link . '</a>';
537 }
538
539 $par_ent_id = $message->parent->entity_id;
540 $up_link = '';
541 if ($par_ent_id) {
542 $par_ent_id = substr($par_ent_id,0,-2);
543 if ( $par_ent_id != 0 ) {
544 $up_link = $topbar_delimiter;
545 $url = set_url_var($PHP_SELF, 'passed_ent_id',$par_ent_id);
546 $up_link .= '<a href="'.$url.'">'._("Up").'</a>';
547 }
548 }
549
550 $nav_row .= $prev_link . $up_link . $topbar_delimiter . $next_link;
551 $nav_row .= $double_delimiter . '[<a href="'.$url.'">'._("View Message").'</a>]';
552
553 // Prev/Next links for regular messages
554 } else if ( true ) { //!(isset($where) && isset($what)) ) {
555 $prev = findPreviousMessage($aMailbox['UIDSET'][$what], $passed_id);
556 $next = findNextMessage($aMailbox['UIDSET'][$what],$passed_id);
557
558 $prev_link = _("Previous");
559 if ($prev >= 0) {
560 $uri = $base_uri . 'src/read_body.php?passed_id='.$prev.
561 '&amp;mailbox='.$urlMailbox.'&amp;sort='.$sort.
562 "&amp;where=$where&amp;what=$what" .
563 '&amp;startMessage='.$startMessage.'&amp;show_more=0';
564 $prev_link = '<a href="'.$uri.'">'.$prev_link.'</a>';
565 }
566
567 $next_link = _("Next");
568 if ($next >= 0) {
569 $uri = $base_uri . 'src/read_body.php?passed_id='.$next.
570 '&amp;mailbox='.$urlMailbox.'&amp;sort='.$sort.
571 "&amp;where=$where&amp;what=$what" .
572 '&amp;startMessage='.$startMessage.'&amp;show_more=0';
573 $next_link = '<a href="'.$uri.'">'.$next_link.'</a>';
574 }
575
576 // Only bother with Delete & Prev and Delete & Next IF
577 // top display is enabled.
578 if ( $delete_prev_next_display == 1 &&
579 in_array('\\deleted', $aMailbox['PERMANENTFLAGS'],true) ) {
580 $del_prev_link = _("Delete &amp; Prev");
581 if ($prev >= 0) {
582 $uri = $base_uri . 'src/read_body.php?passed_id='.$prev.
583 '&amp;mailbox='.$urlMailbox.'&amp;sort='.$sort.
584 '&amp;startMessage='.$startMessage.'&amp;show_more=0'.
585 "&amp;where=$where&amp;what=$what" .
586 '&amp;delete_id='.$passed_id;
587 $del_prev_link = '<a href="'.$uri.'">'.$del_prev_link.'</a>';
588 }
589
590 $del_next_link = _("Delete &amp; Next");
591 if ($next >= 0) {
592 $uri = $base_uri . 'src/read_body.php?passed_id='.$next.
593 '&amp;mailbox='.$urlMailbox.'&amp;sort='.$sort.
594 '&amp;startMessage='.$startMessage.'&amp;show_more=0'.
595 "&amp;where=$where&amp;what=$what" .
596 '&amp;delete_id='.$passed_id;
597 $del_next_link = '<a href="'.$uri.'">'.$del_next_link.'</a>';
598 }
599 }
600
601 $nav_row .= '['.$prev_link.$topbar_delimiter.$next_link.']';
602 if ( isset($del_prev_link) && isset($del_next_link) )
603 $nav_row .= $double_delimiter.'['.$del_prev_link.$topbar_delimiter.$del_next_link.']';
604 }
605
606 // Start with Search Results or Message List link.
607 $msgs_url .= "$where?where=read_body.php&amp;what=$what&amp;mailbox=" . $urlMailbox.
608 "&amp;startMessage=$startMessage";
609 if ($where == 'search.php') {
610 $msgs_str = _("Search Results");
611 } else {
612 $msgs_str = _("Message List");
613 }
614 $nav_row .= $double_delimiter .
615 '[<a href="' . $msgs_url . '">' . $msgs_str . '</a>]';
616
617 $nav_row .= '</small></td></tr>';
618
619
620 // BEGIN MENU ROW - DELETE/REPLY/FORWARD/MOVE/etc.
621 $menu_row = '<tr bgcolor="'.$color[0].'"><td><small>';
622 $comp_uri = $base_uri.'src/compose.php' .
623 '?passed_id=' . $passed_id .
624 '&amp;mailbox=' . $urlMailbox .
625 '&amp;startMessage=' . $startMessage .
626 (isset($passed_ent_id) ? '&amp;passed_ent_id='.$passed_ent_id : '');
627
628 // Start form for reply/reply all/forward..
629 $target = '';
630 $on_click='';
631 $method='method="post" ';
632 $onsubmit='';
633 if ($compose_new_win == '1') {
634 if (!preg_match("/^[0-9]{3,4}$/", $compose_width)) {
635 $compose_width = '640';
636 }
637 if (!preg_match("/^[0-9]{3,4}$/", $compose_height)) {
638 $compose_height = '550';
639 }
640 if ( $javascript_on ) {
641 $on_click=' onclick="comp_in_new_form(\''.$comp_uri.'\', this, this.form,'. $compose_width .',' . $compose_height .')"';
642 $comp_uri = 'javascript:void(0)';
643 $method='method="get" ';
644 $onsubmit = 'onsubmit="return false" ';
645 } else {
646 $target = 'target="_blank"';
647 }
648 }
649
650 $menu_row .= "\n".'<form name="composeForm" action="'.$comp_uri.'" '
651 . $method.$target.$onsubmit.' style="display: inline">'."\n";
652
653 // If Draft folder - create Resume link
654 if (($mailbox == $draft_folder) && ($save_as_draft)) {
655 $new_button = 'smaction_draft';
656 $comp_alt_string = _("Resume Draft");
657 } else if (handleAsSent($mailbox)) {
658 // If in Sent folder, edit as new
659 $new_button = 'smaction_edit_new';
660 $comp_alt_string = _("Edit Message as New");
661 }
662 // Show Alt URI for Draft/Sent
663 if (isset($comp_alt_string))
664 $menu_row .= getButton('submit', $new_button, $comp_alt_string, $on_click) . "\n";
665
666 $menu_row .= getButton('submit', 'smaction_reply', _("Reply"), $on_click) . "\n";
667 $menu_row .= getButton('submit', 'smaction_reply_all', _("Reply All"), $on_click) ."\n";
668 $menu_row .= getButton('submit', 'smaction_forward', _("Forward"), $on_click);
669 if ($enable_forward_as_attachment)
670 $menu_row .= '<input type="checkbox" name="smaction_attache" />' . _("As Attachment") .'&nbsp;&nbsp;'."\n";
671
672 $menu_row .= '</form>&nbsp;';
673
674 if ( in_array('\\deleted', $aMailbox['PERMANENTFLAGS'],true) ) {
675 // Form for deletion. Form is handled by the originating display in $where. This is right_main.php or search.php
676 $delete_url = $base_uri . "src/$where";
677 $menu_row .= '<form name="deleteMessageForm" action="'.$delete_url.'" method="post" style="display: inline">';
678
679 if (!(isset($passed_ent_id) && $passed_ent_id)) {
680 $menu_row .= addHidden('mailbox', $aMailbox['NAME']);
681 $menu_row .= addHidden('msg[0]', $passed_id);
682 $menu_row .= addHidden('startMessage', $startMessage);
683 $menu_row .= getButton('submit', 'delete', _("Delete"));
684 $menu_row .= '<input type="checkbox" name="bypass_trash" />' . _("Bypass Trash");
685 } else {
686 $menu_row .= getButton('submit', 'delete', _("Delete"), '', FALSE) . "\n"; // delete button is disabled
687 }
688
689 $menu_row .= '</form>';
690 }
691
692 // Add top move link
693 $menu_row .= '</small></td><td align="right">';
694 if ( !(isset($passed_ent_id) && $passed_ent_id) &&
695 in_array('\\deleted', $aMailbox['PERMANENTFLAGS'],true) ) {
696
697 $menu_row .= '<form name="moveMessageForm" action="'.$base_uri.'src/'.$where.'?'.'" method="post" style="display: inline">'.
698 '<small>'.
699
700 addHidden('mailbox',$aMailbox['NAME']) .
701 addHidden('msg[0]', $passed_id) . _("Move to:") .
702 '<select name="targetMailbox" style="padding: 0px; margin: 0px">';
703
704 if (isset($lastTargetMailbox) && !empty($lastTargetMailbox)) {
705 $menu_row .= sqimap_mailbox_option_list($imapConnection, array(strtolower($lastTargetMailbox)));
706 } else {
707 $menu_row .= sqimap_mailbox_option_list($imapConnection);
708 }
709 $menu_row .= '</select> ';
710
711 $menu_row .= getButton('submit', 'moveButton',_("Move")) . "\n";
712
713 // Add msg copy button
714 if ($show_copy_buttons) {
715 $menu_row .= getButton('submit', 'copyButton', _("Copy"));
716 }
717
718 $menu_row .= '</form>';
719 }
720 $menu_row .= '</td></tr>';
721
722 // echo rows, with hooks
723 $ret = do_hook_function('read_body_menu_top', array($nav_row, $menu_row));
724 if (is_array($ret)) {
725 if (isset($ret[0]) && !empty($ret[0])) {
726 $nav_row = $ret[0];
727 }
728 if (isset($ret[1]) && !empty($ret[1])) {
729 $menu_row = $ret[1];
730 }
731 }
732 echo '<table width="100%" cellpadding="3" cellspacing="0" align="center" border="0">';
733 echo $nav_on_top ? $nav_row . $menu_row : $menu_row . $nav_row;
734 echo '</table>'."\n";
735 do_hook('read_body_menu_bottom');
736 }
737
738 function formatToolbar($mailbox, $passed_id, $passed_ent_id, $message, $color) {
739 global $base_uri, $where, $what, $download_and_unsafe_link;
740
741 $urlMailbox = urlencode($mailbox);
742 $urlPassed_id = urlencode($passed_id);
743 $urlPassed_ent_id = urlencode($passed_ent_id);
744
745 $query_string = 'mailbox=' . $urlMailbox . '&amp;passed_id=' . $urlPassed_id . '&amp;passed_ent_id=' . $urlPassed_ent_id;
746
747 if (!empty($where)) {
748 $query_string .= '&amp;where=' . urlencode($where);
749 }
750
751 if (!empty($what)) {
752 $query_string .= '&amp;what=' . urlencode($what);
753 }
754
755 $url = $base_uri.'src/view_header.php?'.$query_string;
756
757 $s = "<tr>\n" .
758 html_tag( 'td', '', 'right', '', 'valign="middle" width="20%"' ) . '<b>' . _("Options") . ":&nbsp;&nbsp;</b></td>\n" .
759 html_tag( 'td', '', 'left', '', 'valign="middle" width="80%"' ) . '<small>' .
760 '<a href="'.$url.'">'._("View Full Header").'</a>';
761
762 /* Output the printer friendly link if we are in subtle mode. */
763 $s .= '&nbsp;|&nbsp;' .
764 printer_friendly_link($mailbox, $passed_id, $passed_ent_id);
765 echo $s;
766 echo view_as_html_link($mailbox, $passed_id, $passed_ent_id, $message);
767
768 /* Output the download and/or unsafe images link/-s, if any. */
769 if ($download_and_unsafe_link) {
770 echo $download_and_unsafe_link;
771 }
772
773 do_hook("read_body_header_right");
774 $s = "</small></td>\n" .
775 "</tr>\n";
776 echo $s;
777
778 }
779
780 /**
781 * Creates button
782 *
783 * @deprecated see form functions available in 1.5.1 and 1.4.3.
784 * @param string $type
785 * @param string $name
786 * @param string $value
787 * @param string $js
788 * @param bool $enabled
789 */
790 function getButton($type, $name, $value, $js = '', $enabled = TRUE) {
791 $disabled = ( $enabled ? '' : 'disabled ' );
792 $js = ( $js ? $js.' ' : '' );
793 return '<input '.$disabled.$js.
794 'type="'.$type.
795 '" name="'.$name.
796 '" value="'.$value .
797 '" style="padding: 0px; margin: 0px" />';
798 }
799
800
801 /***************************/
802 /* Main of read_body.php */
803 /***************************/
804
805 /* get the globals we may need */
806
807 sqgetGlobalVar('key', $key, SQ_COOKIE);
808 sqgetGlobalVar('username', $username, SQ_SESSION);
809 sqgetGlobalVar('onetimepad',$onetimepad, SQ_SESSION);
810 sqgetGlobalVar('delimiter', $delimiter, SQ_SESSION);
811 sqgetGlobalVar('base_uri', $base_uri, SQ_SESSION);
812 sqgetGlobalVar('lastTargetMailbox', $lastTargetMailbox, SQ_SESSION);
813 if (!sqgetGlobalVar('messages', $messages, SQ_SESSION) ) {
814 $messages = array();
815 }
816 sqgetGlobalVar('delayed_errors', $delayed_errors, SQ_SESSION);
817 if (is_array($delayed_errors)) {
818 $oErrorHandler->AssignDelayedErrors($delayed_errors);
819 sqsession_unregister("delayed_errors");
820 }
821 /** GET VARS */
822 sqgetGlobalVar('sendreceipt', $sendreceipt, SQ_GET);
823 if (!sqgetGlobalVar('where', $where, SQ_GET) ) {
824 $where = 'right_main.php';
825 }
826 /*
827 * Used as entry key to the list of uid's cached in the mailbox cache
828 * we use the cached uid's to get the next and prev message.
829 */
830 if (!sqgetGlobalVar('what', $what, SQ_GET) ){
831 $what = 0;
832 }
833 if ( sqgetGlobalVar('show_more', $temp, SQ_GET) ) {
834 $show_more = (int) $temp;
835 }
836 if ( sqgetGlobalVar('show_more_cc', $temp, SQ_GET) ) {
837 $show_more_cc = (int) $temp;
838 }
839 if ( sqgetGlobalVar('show_more_bcc', $temp, SQ_GET) ) {
840 $show_more_bcc = (int) $temp;
841 }
842 if ( sqgetGlobalVar('view_hdr', $temp, SQ_GET) ) {
843 $view_hdr = (int) $temp;
844 }
845
846 if ( sqgetGlobalVar('account', $temp, SQ_GET) ) {
847 $iAccount = (int) $temp;
848 } else {
849 $iAccount = 0;
850 }
851
852 /** GET/POST VARS */
853 sqgetGlobalVar('passed_ent_id', $passed_ent_id);
854 sqgetGlobalVar('mailbox', $mailbox);
855
856 if ( sqgetGlobalVar('passed_id', $temp) ) {
857 $passed_id = (int) $temp;
858 }
859 if ( sqgetGlobalVar('sort', $temp) ) {
860 $sort = (int) $temp;
861 }
862 if ( sqgetGlobalVar('startMessage', $temp) ) {
863 $startMessage = (int) $temp;
864 } else {
865 $startMessage = 1;
866 }
867 if(sqgetGlobalVar('show_html_default', $temp)) {
868 $show_html_default = (int) $temp;
869 }
870
871 if(sqgetGlobalVar('view_unsafe_images', $temp)) {
872 $view_unsafe_images = (int) $temp;
873 if($view_unsafe_images == 1) {
874 $show_html_default = 1;
875 }
876 } else {
877 $view_unsafe_images = 0;
878 }
879 /**
880 * Retrieve mailbox cache
881 */
882 sqgetGlobalVar('mailbox_cache',$mailbox_cache,SQ_SESSION);
883
884 /* end of get globals */
885 global $sqimap_capabilities, $lastTargetMailbox;
886
887 $imapConnection = sqimap_login($username, $key, $imapServerAddress, $imapPort, 0);
888 $aMailbox = sqm_api_mailbox_select($imapConnection, $iAccount, $mailbox,array('setindex' => $what, 'offset' => $startMessage),array());
889
890
891 /**
892 Start code to set the columns to fetch in case of hitting the next/prev link
893 The reason for this is the fact that the cache can be invalidated which means that the headers
894 to fetch aren't there anymore. Before they got calculated when the messagelist was shown.
895
896 Todo, better central handling of setting the mailbox options so we do not need to do the stuff below
897 */
898
899 /**
900 * Replace From => To in case it concerns a draft or sent folder
901 */
902 $aColumns = array();
903 if (($mailbox == $sent_folder || $mailbox == $draft_folder) &&
904 !in_array(SQM_COL_TO,$index_order)) {
905 $aNewOrder = array(); // nice var name ;)
906 foreach($index_order as $iCol) {
907 if ($iCol == SQM_COL_FROM) {
908 $iCol = SQM_COL_TO;
909 }
910 $aColumns[$iCol] = array();
911 }
912 } else {
913 foreach ($index_order as $iCol) {
914 $aColumns[$iCol] = array();
915 }
916 }
917
918 $aProps = array(
919 'columns' => $aColumns, // columns bound settings
920 'config' => array(
921 'highlight_list' => $message_highlight_list, // row highlighting rules
922 'trash_folder' => $trash_folder,
923 'sent_folder' => $sent_folder,
924 'draft_folder' => $draft_folder));
925
926 calcFetchColumns($aMailbox,$aProps);
927
928 /**
929 End code to set the columns to fetch in case of hitting the next/prev link
930 */
931
932
933
934 /**
935 * Check if cache is still valid, $what contains the key
936 * which gives us acces to the array with uid's. At this moment
937 * 0 is used for a normal message list and search uses 1 as key. This can be
938 * changed / extended in the future.
939 * If on a select of a mailbox we detect that the cache should be invalidated due to
940 * the delete of messages or due to new messages we empty the list with uid's and
941 * that's what we detect below.
942 */
943 if (!is_array($aMailbox['UIDSET'][$what])) {
944 fetchMessageHeaders($imapConnection, $aMailbox);
945 }
946
947 $iSetIndex = $aMailbox['SETINDEX'];
948 $aMailbox['CURRENT_MSG'][$iSetIndex] = $passed_id;
949
950 /**
951 * Update the seen state
952 * and ignore in_array('\\seen',$aMailbox['PERMANENTFLAGS'],true)
953 */
954 if (isset($aMailbox['MSG_HEADERS'][$passed_id]['FLAGS'])) {
955 $aMailbox['MSG_HEADERS'][$passed_id]['FLAGS']['\\seen'] = true;
956 }
957
958 /**
959 * Process Delete from delete-move-next
960 * but only if delete_id was set
961 */
962 if ( sqgetGlobalVar('delete_id', $delete_id, SQ_GET) ) {
963 handleMessageListForm($imapConnection,$aMailbox,$sButton='setDeleted', array($delete_id));
964 }
965
966 /**
967 * $message contains all information about the message
968 * including header and body
969 */
970
971 if (isset($aMailbox['MSG_HEADERS'][$passed_id]['MESSAGE_OBJECT'])) {
972 $message = $aMailbox['MSG_HEADERS'][$passed_id]['MESSAGE_OBJECT'];
973 $FirstTimeSee = !$message->is_seen;
974 } else {
975 $message = sqimap_get_message($imapConnection, $passed_id, $mailbox);
976 $FirstTimeSee = !$message->is_seen;
977 $message->is_seen = true;
978 $aMailbox['MSG_HEADERS'][$passed_id]['MESSAGE_OBJECT'] = $message;
979 }
980 if (isset($passed_ent_id) && $passed_ent_id) {
981 $message = $message->getEntity($passed_ent_id);
982 if ($message->type0 != 'message' && $message->type1 != 'rfc822') {
983 $message = $message->parent;
984 }
985 $read = sqimap_run_command ($imapConnection, "FETCH $passed_id BODY[$passed_ent_id.HEADER]", true, $response, $msg, TRUE);
986 $rfc822_header = new Rfc822Header();
987 $rfc822_header->parseHeader($read);
988 $message->rfc822_header = $rfc822_header;
989 } else if ($message->type0 == 'message' && $message->type1 == 'rfc822' && isset($message->entities[0])) {
990 $read = sqimap_run_command ($imapConnection, "FETCH $passed_id BODY[1.HEADER]", true, $response, $msg, TRUE);
991 $rfc822_header = new Rfc822Header();
992 $rfc822_header->parseHeader($read);
993 $message->rfc822_header = $rfc822_header;
994 } else {
995 $passed_ent_id = 0;
996 }
997 $header = $message->header;
998
999
1000 /****************************************/
1001 /* Block for handling incoming url vars */
1002 /****************************************/
1003
1004 if (isset($sendreceipt)) {
1005 if ( !$message->is_mdnsent ) {
1006 $final_recipient = '';
1007 if ((isset($identity)) && ($identity != 0)) //Main identity
1008 $final_recipient = trim(getPref($data_dir, $username, 'email_address' . $identity, '' ));
1009 if ($final_recipient == '' )
1010 $final_recipient = trim(getPref($data_dir, $username, 'email_address', '' ));
1011 $supportMDN = ServerMDNSupport($aMailbox["PERMANENTFLAGS"]);
1012 if ( SendMDN( $mailbox, $passed_id, $final_recipient, $message, $imapConnection ) > 0 && $supportMDN ) {
1013 ToggleMDNflag( true, $imapConnection, $mailbox, $passed_id);
1014 $message->is_mdnsent = true;
1015 $aMailbox['MSG_HEADERS'][$passed_id]['MESSAGE_OBJECT'] = $message;
1016 }
1017 }
1018 }
1019 /***********************************************/
1020 /* End of block for handling incoming url vars */
1021 /***********************************************/
1022
1023 $messagebody = '';
1024 do_hook('read_body_top');
1025 if ($show_html_default == 1) {
1026 $ent_ar = $message->findDisplayEntity(array());
1027 } else {
1028 $ent_ar = $message->findDisplayEntity(array(), array('text/plain'));
1029 }
1030 $cnt = count($ent_ar);
1031 for ($i = 0; $i < $cnt; $i++) {
1032 $messagebody .= formatBody($imapConnection, $message, $color, $wrap_at, $ent_ar[$i], $passed_id, $mailbox);
1033 if ($i != $cnt-1) {
1034 $messagebody .= '<hr style="height: 1px;" />';
1035 }
1036 }
1037
1038 /**
1039 * Write mailbox with updated seen flag information back to cache.
1040 */
1041 $mailbox_cache[$iAccount.'_'.$aMailbox['NAME']] = $aMailbox;
1042 sqsession_register($mailbox_cache,'mailbox_cache');
1043 $_SESSION['mailbox_cache'] = $mailbox_cache;
1044 $oTemplate->display('footer.tpl');
1045
1046 displayPageHeader($color, $mailbox,'','');
1047 formatMenuBar($aMailbox, $passed_id, $passed_ent_id, $message,false);
1048 formatEnvheader($aMailbox, $passed_id, $passed_ent_id, $message, $color, $FirstTimeSee);
1049 echo '<table width="100%" cellpadding="0" cellspacing="0" align="center" border="0">';
1050 echo ' <tr><td>';
1051 echo ' <table width="100%" cellpadding="1" cellspacing="0" align="center" border="0" bgcolor="'.$color[9].'">';
1052 echo ' <tr><td>';
1053 echo ' <table width="100%" cellpadding="3" cellspacing="0" align="center" border="0">';
1054 echo ' <tr bgcolor="'.$color[4].'"><td>';
1055 // echo ' <table cellpadding="1" cellspacing="5" align="left" border="0">';
1056 echo html_tag( 'table' ,'' , 'left', '', 'width="100%" cellpadding="1" cellspacing="5" border="0"' );
1057 echo ' <tr>' . html_tag( 'td', '<br />'. $messagebody."\n", 'left')
1058 . '</tr>';
1059 echo ' </table>';
1060 echo ' </td></tr>';
1061 echo ' </table></td></tr>';
1062 echo ' </table>';
1063 echo ' </td></tr>';
1064
1065 echo '<tr><td height="5" colspan="2" bgcolor="'.
1066 $color[4].'"></td></tr>'."\n";
1067
1068 $attachmentsdisplay = formatAttachments($message,$ent_ar,$mailbox, $passed_id);
1069 if ($attachmentsdisplay) {
1070 echo ' </table>';
1071 echo ' <table width="100%" cellpadding="1" cellspacing="0" align="center"'.' border="0" bgcolor="'.$color[9].'">';
1072 echo ' <tr><td>';
1073 echo ' <table width="100%" cellpadding="0" cellspacing="0" align="center" border="0" bgcolor="'.$color[4].'">';
1074 echo ' <tr>' . html_tag( 'td', '', 'left', $color[9] );
1075 echo ' <b>' . _("Attachments") . ':</b>';
1076 echo ' </td></tr>';
1077 echo ' <tr><td>';
1078 echo ' <table width="100%" cellpadding="2" cellspacing="2" align="center"'.' border="0" bgcolor="'.$color[0].'"><tr><td>';
1079 echo $attachmentsdisplay;
1080 echo ' </td></tr></table>';
1081 echo ' </td></tr></table>';
1082 echo ' </td></tr>';
1083 echo '<tr><td height="5" colspan="2" bgcolor="'.
1084 $color[4].'"></td></tr>';
1085 }
1086 echo '</table>';
1087
1088 /* show attached images inline -- if pref'fed so */
1089 if (($attachment_common_show_images) &&
1090 is_array($attachment_common_show_images_list)) {
1091 foreach ($attachment_common_show_images_list as $img) {
1092 $imgurl = SM_PATH . 'src/download.php' .
1093 '?' .
1094 'passed_id=' . urlencode($img['passed_id']) .
1095 '&amp;mailbox=' . urlencode($mailbox) .
1096 '&amp;ent_id=' . urlencode($img['ent_id']) .
1097 '&amp;absolute_dl=true';
1098
1099 echo html_tag( 'table', "\n" .
1100 html_tag( 'tr', "\n" .
1101 html_tag( 'td', '<img src="' . $imgurl . '" />' ."\n", 'left'
1102 )
1103 ) ,
1104 'center', '', 'cellspacing="0" border="0" cellpadding="2"');
1105 }
1106 }
1107
1108 formatMenuBar($aMailbox, $passed_id, $passed_ent_id, $message, false, FALSE);
1109
1110 do_hook('read_body_bottom');
1111 sqimap_logout($imapConnection);
1112
1113 ?>