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