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