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