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