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