Source for file read_body.php

Documentation is available at 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 1999-2020 The SquirrelMail Project Team
  10.  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  11.  * @version $Id: read_body.php 14845 2020-01-07 08:09:34Z pdontthink $
  12.  * @package squirrelmail
  13.  */
  14.  
  15. /** This is the read_body page */
  16. define('PAGE_NAME''read_body');
  17.  
  18. /**
  19.  * Include the SquirrelMail initialization file.
  20.  */
  21. require('../include/init.php');
  22.  
  23. /* SquirrelMail required files. */
  24. require_once(SM_PATH 'functions/imap.php');
  25. require_once(SM_PATH 'functions/imap_asearch.php')// => move to mailbox_display
  26. require_once(SM_PATH 'functions/mime.php');
  27. require_once(SM_PATH 'functions/date.php');
  28. require_once(SM_PATH 'functions/url_parser.php');
  29. require_once(SM_PATH 'functions/identity.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. require_once(SM_PATH 'functions/compose.php');
  34.  
  35. /**
  36.  * Given an IMAP message id number, this will look it up in the cached
  37.  * and sorted msgs array and return the index of the next message
  38.  *
  39.  * @param int $passed_id The current message UID
  40.  * @return the index of the next valid message from the array
  41.  */
  42. function findNextMessage($uidset,$passed_id='backwards'{
  43.     if (!is_array($uidset)) {
  44.         return -1;
  45.     }
  46.     if ($passed_id=='backwards' || !is_array($uidset)) // check for backwards compattibilty gpg plugin
  47.         $passed_id $uidset;
  48.     }
  49.     $result sqm_array_get_value_by_offset($uidset,$passed_id,1);
  50.     if ($result === false{
  51.         return -1;
  52.     else {
  53.         return $result;
  54.     }
  55. }
  56.  
  57. /**
  58.  * Given an IMAP message id number, this will look it up in the cached
  59.  * and sorted msgs array and return the index of the previous message
  60.  *
  61.  * @param int $passed_id The current message UID
  62.  * @return the index of the next valid message from the array
  63.  */
  64.  
  65. function findPreviousMessage($uidset$passed_id{
  66.     if (!is_array($uidset)) {
  67.         return -1;
  68.     }
  69.     $result sqm_array_get_value_by_offset($uidset,$passed_id,-1);
  70.     if ($result === false{
  71.         return -1;
  72.     else {
  73.         return $result;
  74.     }
  75. }
  76.  
  77. function html_toggle_href ($mailbox$passed_id$passed_ent_id$message{
  78.     global $base_uri$show_html_default;
  79.  
  80.     $has_html false;
  81.     if ($message->header->type0 == 'message' && $message->header->type1 == 'rfc822'{
  82.         $type0 $message->rfc822_header->content_type->type0;
  83.         $type1 $message->rfc822_header->content_type->type1;
  84.     else {
  85.         $type0 $message->header->type0;
  86.         $type1 $message->header->type1;
  87.     }
  88.     if($type0 == 'multipart' &&
  89.        ($type1 == 'alternative' || $type1 == 'mixed' || $type1 == 'related' || $type1=='signed')) {
  90.         if ($message->findDisplayEntity(array()array('text/html')true)) {
  91.             $has_html true;
  92.         }
  93.     }
  94.     /*
  95.      * Normal single part message so check its type.
  96.      */
  97.     else {
  98.         if($type0 == 'text' && $type1 == 'html'{
  99.             $has_html true;
  100.         }
  101.     }
  102.     if($has_html == true{
  103.         $vars array('passed_ent_id''show_more''show_more_cc''override_type0''override_type1''startMessage','where''what');
  104.  
  105.         $new_link $base_uri 'src/read_body.php?passed_id=' urlencode($passed_id.
  106.                     '&amp;passed_ent_id=' urlencode($passed_ent_id.
  107.                     '&amp;mailbox=' urlencode($mailbox);
  108.         foreach($vars as $var{
  109.             if(sqgetGlobalVar($var$temp)) {
  110.                 $new_link .= '&amp;' $var '=' urlencode($temp);
  111.             }
  112.         }
  113.  
  114.         if($show_html_default == 1{
  115.             $new_link .= '&amp;show_html_default=0';
  116.         else {
  117.             $new_link .= '&amp;show_html_default=1';
  118.         }
  119.         return $new_link;
  120.     }
  121.     return '';
  122. }
  123.  
  124. function ServerMDNSupport($aFlags{
  125.     /* escaping $ doesn't work -> \x36 */
  126.     return in_array('$mdnsent',$aFlags,true||
  127.              in_array('\\*',$aFlags,true) ) ;
  128. }
  129.  
  130. function SendMDN $mailbox$passed_id$message$imapConnection{
  131.     global $squirrelmail_language$default_charset$default_move_to_sent,
  132.            $languages$useSendmail$domain$sent_folder$username,
  133.            $data_dir;
  134.  
  135.     sqgetGlobalVar('SERVER_NAME'$SERVER_NAMESQ_SERVER);
  136.  
  137.     $header $message->rfc822_header;
  138.  
  139.     $rfc822_header new Rfc822Header();
  140.     $content_type  new ContentType('multipart/report');
  141.     $content_type->properties['report-type']='disposition-notification';
  142.  
  143.     set_my_charset();
  144.     if ($default_charset{
  145.         $content_type->properties['charset']=$default_charset;
  146.     }
  147.     $rfc822_header->content_type $content_type;
  148.     $rfc822_header->to[$header->dnt;
  149.     $rfc822_header->subject _("Read:"' ' decodeHeader($header->subject,true,false);
  150.  
  151.     $idents get_identities();
  152.     $needles array();
  153.     if ($header->to{
  154.         foreach ($header->to as $message_to{
  155.              $needles[$message_to->mailbox.'@'.$message_to->host;
  156.         }
  157.     }
  158.     $identity find_identity($needles);
  159.     $from_addr build_from_header($identity);
  160.     $reply_to = isset($idents[$identity]['reply_to']$idents[$identity]['reply_to''';
  161.     // FIXME: this must actually be the envelope address of the orginal message,
  162.     // but do we have that information? For now the first identity is our best guess.
  163.     $final_recipient $idents[0]['email_address'];
  164.  
  165.     $rfc822_header->from $rfc822_header->parseAddress($from_addr,true);
  166.     if ($reply_to{
  167.        $rfc822_header->reply_to $rfc822_header->parseAddress($reply_to,true);
  168.     }
  169.  
  170.     // part 1 (RFC2298)
  171.     $senton getLongDateString$header->date$header->date_unparsed );
  172.     $to_array $header->to;
  173.     $to '';
  174.     foreach ($to_array as $line{
  175.         $to .= ' '.$line->getAddress();
  176.     }
  177.     $now getLongDateStringtime() );
  178.     set_my_charset();
  179.     $body _("Your message""\r\n\r\n" .
  180.             "\t" _("To"': ' decodeHeader($to,false,false"\r\n" .
  181.             "\t" _("Subject"': ' decodeHeader($header->subject,false,false"\r\n" .
  182.             "\t" _("Sent"': ' $senton "\r\n" .
  183.             "\r\n" .
  184.             sprintf_("Was displayed on %s")$now );
  185.  
  186.     $special_encoding '';
  187.     if (isset($languages[$squirrelmail_language]['XTRA_CODE']&&
  188.         function_exists($languages[$squirrelmail_language]['XTRA_CODE''_encode')) {
  189.         $body call_user_func($languages[$squirrelmail_language]['XTRA_CODE''_encode'$body);
  190.         if (strtolower($default_charset== 'iso-2022-jp'{
  191.             if (mb_detect_encoding($body== 'ASCII'{
  192.                 $special_encoding '8bit';
  193.             else {
  194.                 $body mb_convert_encoding($body'JIS');
  195.                 $special_encoding '7bit';
  196.             }
  197.         }
  198.     elseif (sq_is8bit($body)) {
  199.         $special_encoding '8bit';
  200.     }
  201.     $part1 new Message();
  202.     $part1->setBody($body);
  203.     $mime_header new MessageHeader;
  204.     $mime_header->type0 'text';
  205.     $mime_header->type1 'plain';
  206.     if ($special_encoding{
  207.         $mime_header->encoding $special_encoding;
  208.     else {
  209.         $mime_header->encoding '7bit';
  210.     }
  211.     if ($default_charset{
  212.         $mime_header->parameters['charset'$default_charset;
  213.     }
  214.     $part1->mime_header $mime_header;
  215.  
  216.     // part2  (RFC2298)
  217.     $original_recipient  $to;
  218.     $original_message_id $header->message_id;
  219.  
  220.     $report "Reporting-UA : $SERVER_NAME ; SquirrelMail (version SM_VERSION ") \r\n";
  221.     if ($original_recipient != ''{
  222.         $report .= "Original-Recipient : $original_recipient\r\n";
  223.     }
  224.     $report .= "Final-Recipient: rfc822; $final_recipient\r\n.
  225.               "Original-Message-ID : $original_message_id\r\n.
  226.               "Disposition: manual-action/MDN-sent-manually; displayed\r\n";
  227.  
  228.     $part2 new Message();
  229.     $part2->setBody($report);
  230.     $mime_header new MessageHeader;
  231.     $mime_header->type0 'message';
  232.     $mime_header->type1 'disposition-notification';
  233.     $mime_header->encoding '7bit';
  234.     $part2->mime_header $mime_header;
  235.  
  236.     $composeMessage new Message();
  237.     $composeMessage->rfc822_header $rfc822_header;
  238.     $composeMessage->addEntity($part1);
  239.     $composeMessage->addEntity($part2);
  240.  
  241.  
  242.     if ($useSendmail{
  243.         require_once(SM_PATH 'class/deliver/Deliver_SendMail.class.php');
  244.         global $sendmail_path$sendmail_args;
  245.         // Check for outdated configuration
  246.         if (!isset($sendmail_args)) {
  247.             if ($sendmail_path=='/var/qmail/bin/qmail-inject'{
  248.                 $sendmail_args '';
  249.             else {
  250.                 $sendmail_args '-i -t';
  251.             }
  252.         }
  253.         $deliver new Deliver_SendMail(array('sendmail_args'=>$sendmail_args));
  254.         $stream $deliver->initStream($composeMessage,$sendmail_path);
  255.     else {
  256.         require_once(SM_PATH 'class/deliver/Deliver_SMTP.class.php');
  257.         $deliver new Deliver_SMTP();
  258.         $authPop (isset($pop_before_smtp&& $pop_before_smtptrue false;
  259.         if (empty($pop_before_smtp_host)) $pop_before_smtp_host $smtpServerAddress;
  260.         get_smtp_user($user$pass);
  261.         $stream $deliver->initStream($composeMessage,$domain,0,
  262.                                        $smtpServerAddress$smtpPort$user$pass$authPop$pop_before_smtp_host);
  263.     }
  264.     $success false;
  265.     if ($stream{
  266.         $deliver->mail($composeMessage$stream);
  267.         $success $deliver->finalizeStream($stream);
  268.     }
  269.     if (!$success{
  270.         $msg _("Message not sent.""\n" .
  271.             $deliver->dlv_msg;
  272.         if (empty($deliver->dlv_server_msg)) {
  273.             $msg.= "\n" .
  274.                 _("Server replied:"' ' $deliver->dlv_ret_nr ' ' .
  275.                 nl2br(sm_encode_html_special_chars($deliver->dlv_server_msg));
  276.         }
  277.         plain_error_message($msg);
  278.     else {
  279.         unset ($deliver);
  280.  
  281.         // move to sent folder
  282.         //
  283.         $move_to_sent getPref($data_dir,$username,'move_to_sent');
  284.         if (isset($default_move_to_sent&& ($default_move_to_sent != 0)) {
  285.             $svr_allow_sent true;
  286.         else {
  287.             $svr_allow_sent false;
  288.         }
  289.  
  290.         if (isset($sent_folder&& (($sent_folder != ''|| ($sent_folder != 'none'))
  291.                 && sqimap_mailbox_exists$imapConnection$sent_folder)) {
  292.             $fld_sent true;
  293.         else {
  294.             $fld_sent false;
  295.         }
  296.  
  297.         if ((isset($move_to_sent&& ($move_to_sent != 0)) || (!isset($move_to_sent))) {
  298.             $lcl_allow_sent true;
  299.         else {
  300.             $lcl_allow_sent false;
  301.         }
  302.  
  303.         if (($fld_sent && $svr_allow_sent && !$lcl_allow_sent|| ($fld_sent && $lcl_allow_sent)) {
  304.             $save_reply_with_orig=getPref($data_dir,$username,'save_reply_with_orig');
  305.             if ($save_reply_with_orig{
  306.                 $sent_folder $mailbox;
  307.             }
  308.             require_once(SM_PATH 'class/deliver/Deliver_IMAP.class.php');
  309.             $imap_deliver new Deliver_IMAP();
  310.             $imap_deliver->mail($composeMessage$imapConnection00$imapConnection$sent_folder);
  311.             unset ($imap_deliver);
  312.         }
  313.     }
  314.     return $success;
  315. }
  316.  
  317. function ToggleMDNflag ($set ,$imapConnection$mailbox$passed_id{
  318.     $sg   =  $set?'+':'-';
  319.     $cmd  'STORE ' $passed_id ' ' $sg 'FLAGS ($MDNSent)';
  320.     $read sqimap_run_command ($imapConnection$cmdtrue$response,
  321.                                 $readmessageTRUE);
  322. }
  323.  
  324. function formatRecipientString($recipients$item {
  325.     global $show_more$show_more_cc$show_more_bcc,
  326.            $PHP_SELF$oTemplate;
  327.  
  328.     $string '';
  329.     if ((is_array($recipients)) && (isset($recipients[0]))) {
  330.         $show false;
  331.  
  332.         if ($item == 'to'{
  333.             if ($show_more{
  334.                 $show true;
  335.                 $url set_url_var($PHP_SELF'show_more',0);
  336.             else {
  337.                 $url set_url_var($PHP_SELF'show_more',1);
  338.             }
  339.         else if ($item == 'cc'{
  340.             if ($show_more_cc{
  341.                 $show true;
  342.                 $url set_url_var($PHP_SELF'show_more_cc',0);
  343.             else {
  344.                 $url set_url_var($PHP_SELF'show_more_cc',1);
  345.             }
  346.         else if ($item == 'bcc'{
  347.             if ($show_more_bcc{
  348.                 $show true;
  349.                 $url set_url_var($PHP_SELF'show_more_bcc',0);
  350.             else {
  351.                 $url set_url_var($PHP_SELF'show_more_bcc',1);
  352.             }
  353.         }
  354.  
  355.         $a array();
  356.         foreach ($recipients as $r{
  357.             $a[array(
  358.                             // note: decodeHeader is htmlsafe by default
  359.                             'Name'  => decodeHeader($r->getAddress(false)),
  360.                             'Email' => sm_encode_html_special_chars($r->getEmail()),
  361.                             'Full'  => decodeHeader($r->getAddress(true))
  362.                         );
  363.         }
  364.  
  365.         $oTemplate->assign('which_field'$item);
  366.         $oTemplate->assign('recipients'$a);
  367.         $oTemplate->assign('more_less_toggle_href'$url);
  368.         $oTemplate->assign('show_more'$show);
  369.  
  370.         $string $oTemplate->fetch('read_recipient_list.tpl');
  371.     }
  372.     return $string;
  373. }
  374.  
  375. function formatEnvheader($aMailbox$passed_id$passed_ent_id$message,
  376.                          $color$FirstTimeSee{
  377.            $show_xmailer_default$mdn_user_support$PHP_SELF,
  378.            $squirrelmail_language$oTemplate;
  379.  
  380.     $mailbox $aMailbox['NAME'];
  381.  
  382.     $header $message->rfc822_header;
  383.     $env array();
  384.     $env[_("Subject")str_replace("&nbsp;"," ",decodeHeader($header->subject));
  385.  
  386.     $from_name $header->getAddr_s('from');
  387.     if (!$from_name)
  388.         $from_name $header->getAddr_s('sender');
  389.     if (!$from_name)
  390.         $env[_("From")_("Unknown sender");
  391.     else
  392.         $env[_("From")decodeHeader($from_name);
  393.     $env[_("Date")getLongDateString($header->date$header->date_unparsed);
  394.     $env[_("To")formatRecipientString($header->to"to");
  395.     $env[_("Cc")formatRecipientString($header->cc"cc");
  396.     $env[_("Bcc")formatRecipientString($header->bcc"bcc");
  397.     if ($default_use_priority{
  398.         $oTemplate->assign('message_priority'$header->priority);
  399.         $env[_("Priority")$oTemplate->fetch('read_message_priority.tpl');
  400.     }
  401.     if ($show_xmailer_default{
  402.         $oTemplate->assign('xmailer'decodeHeader($header->xmailer));
  403.         $env[_("Mailer")$oTemplate->fetch('read_xmailer.tpl');
  404.     }
  405.  
  406.     // this is used for both mdn and also general use for plugins, etc
  407.     $oTemplate->assign('first_time_reading'$FirstTimeSee);
  408.  
  409.     if ($default_use_mdn{
  410.         if ($mdn_user_support{
  411.             if ($header->dnt{
  412.                 $mdn_url $PHP_SELF;
  413.                 $mdn_url set_url_var($mdn_url'mailbox'urlencode($mailbox));
  414.                 $mdn_url set_url_var($mdn_url'passed_id'$passed_id);
  415.                 $mdn_url set_url_var($mdn_url'passed_ent_id'$passed_ent_id);
  416.                 $mdn_url set_url_var($mdn_url'sendreceipt'1);
  417.  
  418.                 $oTemplate->assign('read_receipt_sent'$message->is_mdnsent);
  419.                 $oTemplate->assign('send_receipt_href'$mdn_url);
  420.  
  421.                 $env[_("Read Receipt")$oTemplate->fetch('read_handle_receipt.tpl');
  422.             }
  423.         }
  424.     }
  425.  
  426.     $statuses array();
  427.     if (isset($aMailbox['MSG_HEADERS'][$passed_id]['FLAGS'])) {
  428.         if (isset($aMailbox['MSG_HEADERS'][$passed_id]['FLAGS']['\\deleted']&&
  429.                   $aMailbox['MSG_HEADERS'][$passed_id]['FLAGS']['\\deleted'=== true{
  430.             $statuses[_("deleted");
  431.         }
  432.         if (isset($aMailbox['MSG_HEADERS'][$passed_id]['FLAGS']['\\answered']&&
  433.                   $aMailbox['MSG_HEADERS'][$passed_id]['FLAGS']['\\answered'=== true{
  434.             $statuses[_("answered");
  435.         }
  436.         if (isset($aMailbox['MSG_HEADERS'][$passed_id]['FLAGS']['\\draft']&&
  437.                   $aMailbox['MSG_HEADERS'][$passed_id]['FLAGS']['\\draft'=== true{
  438.             $statuses[_("draft");
  439.         }
  440.         if (isset($aMailbox['MSG_HEADERS'][$passed_id]['FLAGS']['\\flagged']&&
  441.                   $aMailbox['MSG_HEADERS'][$passed_id]['FLAGS']['\\flagged'=== true{
  442.             $statuses[_("flagged");
  443.         }
  444.         if count($statuses) ) {
  445.             $env[_("Status")implode(', '$statuses);
  446.         }
  447.     }
  448.  
  449.     $env[_("Options")formatToolbar($mailbox$passed_id$passed_ent_id$message$color);
  450.  
  451.  
  452.     $oTemplate->assign('headers_to_display'$env);
  453.  
  454.     $oTemplate->display('read_headers.tpl');
  455. }
  456.  
  457. /**
  458.  * Format message toolbar
  459.  *
  460.  * @param array   $aMailbox      Current mailbox information array
  461.  * @param int     $passed_id     UID of current message
  462.  * @param int     $passed_ent_id Id of entity within message
  463.  * @param object  $message       Current message object
  464.  * @param void    $removedVar    This parameter is no longer used, but remains
  465.  *                                so as not to break this function's prototype
  466.  *                                (OPTIONAL)
  467.  * @param boolean $nav_on_top    When TRUE, the menubar is being constructed
  468.  *                                for use at the top of the page, otherwise it
  469.  *                                will be used for page bottom (OPTIONAL;
  470.  *                                default = TRUE)
  471.  */
  472. function formatMenubar($aMailbox$passed_id$passed_ent_id$message,
  473.                        $removedVar=FALSE$nav_on_top=TRUE{
  474.  
  475.     global $base_uri$draft_folder$where$what$sort,
  476.            $startMessage$PHP_SELF$save_as_draft,
  477.            $enable_forward_as_attachment$imapConnection$lastTargetMailbox,
  478.            $delete_prev_next_display$show_copy_buttons,
  479.            $compose_new_win$compose_width$compose_height,
  480.            $oTemplate;
  481.  
  482.     //FIXME cleanup argument list, use $aMailbox where possible
  483.     $mailbox $aMailbox['NAME'];
  484.  
  485.     $urlMailbox urlencode($mailbox);
  486.  
  487.     // Create Prev & Next links
  488.     // Handle nested entities first (i.e. Mime Attach parts)
  489.     $prev_href $next_href $up_href $del_href $del_prev_href $del_next_href '';
  490.     $msg_list_href $search_href $view_msg_href '';
  491.     if (isset($passed_ent_id&& $passed_ent_id{
  492.         // code for navigating through attached message/rfc822 messages
  493.         $url set_url_var($PHP_SELF'passed_ent_id',0);
  494.         $entities     array();
  495.         $entity_count array();
  496.         $c 0;
  497.  
  498.         foreach($message->parent->entities as $ent{
  499.             if ($ent->type0 == 'message' && $ent->type1 == 'rfc822'{
  500.  
  501.                 $c++;
  502.                 $entity_count[$c$ent->entity_id;
  503.                 $entities[$ent->entity_id$c;
  504.             }
  505.         }
  506.  
  507.         if(isset($entities[$passed_ent_id]&& $entities[$passed_ent_id1{
  508.             $prev_ent_id $entity_count[$entities[$passed_ent_id1];
  509.             $prev_href set_url_var($PHP_SELF'passed_ent_id'$prev_ent_id);
  510.         }
  511.  
  512.         if(isset($entities[$passed_ent_id]&& $entities[$passed_ent_id$c{
  513.             $next_ent_id $entity_count[$entities[$passed_ent_id1];
  514.             $next_href set_url_var($PHP_SELF'passed_ent_id'$next_ent_id);
  515.         }
  516.  
  517.         $par_ent_id $message->parent->entity_id;
  518.         if ($par_ent_id{
  519.             $par_ent_id substr($par_ent_id,0,-2);
  520.             if $par_ent_id != {
  521.                 $up_href set_url_var($PHP_SELF'passed_ent_id',$par_ent_id);
  522.             }
  523.         }
  524.  
  525.         $view_msg_href $url;
  526.  
  527.     // Prev/Next links for regular messages
  528.     else if true //!(isset($where) && isset($what)) ) {
  529.         $prev findPreviousMessage($aMailbox['UIDSET'][$what]$passed_id);
  530.         $next findNextMessage($aMailbox['UIDSET'][$what],$passed_id);
  531.  
  532.         if ($prev >= 0{
  533.             $prev_href $base_uri 'src/read_body.php?passed_id='.$prev.
  534.                    '&amp;mailbox='.$urlMailbox.'&amp;sort='.$sort.
  535.                    "&amp;where=$where&amp;what=$what.
  536.                    '&amp;startMessage='.$startMessage.'&amp;show_more=0';
  537.         }
  538.  
  539.         if ($next >= 0{
  540.             $next_href $base_uri 'src/read_body.php?passed_id='.$next.
  541.                    '&amp;mailbox='.$urlMailbox.'&amp;sort='.$sort.
  542.                    "&amp;where=$where&amp;what=$what.
  543.                    '&amp;startMessage='.$startMessage.'&amp;show_more=0';
  544.         }
  545.  
  546.         // Only bother with Delete & Prev and Delete & Next IF
  547.         // top display is enabled.
  548.         if $delete_prev_next_display == &&
  549.                in_array('\\deleted'$aMailbox['PERMANENTFLAGS'],true) ) {
  550.             if ($prev >= 0{
  551.                 $del_prev_href $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.                        '&amp;smtoken='.sm_generate_security_token();
  557.             }
  558.  
  559.             if ($next >= 0{
  560.                 $del_next_href $base_uri 'src/read_body.php?passed_id='.$next.
  561.                        '&amp;mailbox='.$urlMailbox.'&amp;sort='.$sort.
  562.                        '&amp;startMessage='.$startMessage.'&amp;show_more=0'.
  563.                        "&amp;where=$where&amp;what=$what.
  564.                        '&amp;delete_id='.$passed_id .
  565.                        '&amp;smtoken='.sm_generate_security_token();
  566.             }
  567.         }
  568.     }
  569.  
  570.     $msg_list_href get_message_list_uri($aMailbox['NAME']$startMessage$what);
  571.     if ($where == 'search.php')
  572.         $search_href str_replace('read_body.php''search.php'$msg_list_href);
  573.     else
  574.         $search_href '';
  575.  
  576.     $comp_uri $base_uri.'src/compose.php' .
  577.                 '?passed_id=' $passed_id .
  578.                 '&amp;mailbox=' $urlMailbox .
  579.                 '&amp;startMessage=' $startMessage .
  580.                  (isset($passed_ent_id'&amp;passed_ent_id='.$passed_ent_id '');
  581.  
  582.     // Start form for reply/reply all/forward..
  583.     $target '';
  584.     $on_click='';
  585.     $method='post';
  586.     $onsubmit='';
  587.     if ($compose_new_win == '1'{
  588.         if (!preg_match("/^[0-9]{3,4}$/"$compose_width)) {
  589.             $compose_width '640';
  590.         }
  591.         if (!preg_match("/^[0-9]{3,4}$/"$compose_height)) {
  592.             $compose_height '550';
  593.         }
  594.         if checkForJavascript() ) {
  595.           $on_click='comp_in_new_form(\''.$comp_uri.'\', this, this.form,'$compose_width .',' $compose_height .')';
  596.           $comp_uri 'javascript:void(0)';
  597.           $method='get';
  598.           $onsubmit 'return false';
  599.         else {
  600.           $target '_blank';
  601.         }
  602.     }
  603.  
  604.     $oTemplate->assign('nav_on_top'$nav_on_top);
  605.  
  606.     $oTemplate->assign('prev_href'$prev_href);
  607.     $oTemplate->assign('up_href'$up_href);
  608.     $oTemplate->assign('next_href'$next_href);
  609.     $oTemplate->assign('del_prev_href'$del_prev_href);
  610.     $oTemplate->assign('del_next_href'$del_next_href);
  611.     $oTemplate->assign('view_msg_href'$view_msg_href);
  612.  
  613.     $oTemplate->assign('message_list_href'$msg_list_href);
  614.     $oTemplate->assign('search_href'$search_href);
  615.  
  616.     $oTemplate->assign('form_extra''');
  617.     $oTemplate->assign('form_method'$method);
  618.     $oTemplate->assign('form_target'$target);
  619.     $oTemplate->assign('form_onsubmit'$onsubmit);
  620.     $oTemplate->assign('compose_href'$comp_uri);
  621.     $oTemplate->assign('button_onclick'$on_click);
  622.     $oTemplate->assign('forward_as_attachment_enabled'$enable_forward_as_attachment==1);
  623.  
  624.     //FIXME: I am surprised these aren't already given to the template; probably needs to be given at a higher level, so I have NO IDEA if this is the right place to do this...  adding them so template can construct its own API calls... we can build those herein too if preferrable
  625.     $oTemplate->assign('mailbox'$aMailbox['NAME']);
  626.     $oTemplate->assign('passed_id'$passed_id);
  627.     $oTemplate->assign('what'$what);
  628.  
  629.     // If Draft folder - create Resume link
  630.     $resume_draft $edit_as_new false;
  631.     if (isDraftMailbox($mailbox&& ($save_as_draft)) {
  632.         $resume_draft true;
  633.     else if (handleAsSent($mailbox)) {
  634.         $edit_as_new true;
  635.     }
  636.     $oTemplate->assign('can_resume_draft'$resume_draft);
  637.     $oTemplate->assign('can_edit_as_new'$edit_as_new);
  638.  
  639.     $oTemplate->assign('mailboxes'sqimap_mailbox_option_array($imapConnection));
  640.     if (in_array('\\deleted'$aMailbox['PERMANENTFLAGS'],true)) {
  641.         $delete_url $base_uri "src/$where";
  642.         $oTemplate->assign('can_be_deleted'true);
  643.         $oTemplate->assign('move_delete_form_action'$base_uri.'src/'.$where);
  644.         $oTemplate->assign('delete_form_extra'addHidden('mailbox'$aMailbox['NAME'])."\n" .
  645.                                                 addHidden('msg[0]'$passed_id)."\n" .
  646.                                                 addHidden('startMessage'$startMessage)."\n" );
  647.         if (!(isset($passed_ent_id&& $passed_ent_id)) {
  648.             $oTemplate->assign('can_be_moved'true);
  649.             $oTemplate->assign('move_form_extra'addHidden('mailbox'$aMailbox['NAME'])."\n" .
  650.                                                   addHidden('msg[0]'$passed_id)."\n" );
  651.             $oTemplate->assign('last_move_target'isset($lastTargetMailbox&& !empty($lastTargetMailbox$lastTargetMailbox '');
  652.             $oTemplate->assign('can_be_copied'$show_copy_buttons==1);
  653.         else {
  654.             $oTemplate->assign('can_be_moved'false);
  655.             $oTemplate->assign('move_form_extra''');
  656.             $oTemplate->assign('last_move_target''');
  657.             $oTemplate->assign('can_be_copied'false);
  658.         }
  659.     else {
  660.         $oTemplate->assign('can_be_deleted'false);
  661.         $oTemplate->assign('move_delete_form_action''');
  662.         $oTemplate->assign('delete_form_extra''');
  663.         $oTemplate->assign('can_be_moved'false);
  664.         $oTemplate->assign('move_form_extra''');
  665.         $oTemplate->assign('last_move_target''');
  666.         $oTemplate->assign('can_be_copied'false);
  667.     }
  668.  
  669.     // access keys... only add to the top menubar, because adding
  670.     // them twice makes them less functional (press access key, *then*
  671.     // press <enter> to make it work)
  672.     //
  673.     if ($nav_on_top{
  674.         global $accesskey_read_msg_reply$accesskey_read_msg_reply_all,
  675.                $accesskey_read_msg_forward$accesskey_read_msg_as_attach,
  676.                $accesskey_read_msg_delete$accesskey_read_msg_bypass_trash,
  677.                $accesskey_read_msg_move$accesskey_read_msg_move_to,
  678.                $accesskey_read_msg_copy;
  679.     else {
  680.         $accesskey_read_msg_reply $accesskey_read_msg_reply_all =
  681.         $accesskey_read_msg_forward $accesskey_read_msg_as_attach =
  682.         $accesskey_read_msg_delete $accesskey_read_msg_bypass_trash =
  683.         $accesskey_read_msg_move $accesskey_read_msg_move_to =
  684.         $accesskey_read_msg_copy 'NONE';
  685.     }
  686.     $oTemplate->assign('accesskey_read_msg_reply'$accesskey_read_msg_reply);
  687.     $oTemplate->assign('accesskey_read_msg_reply_all'$accesskey_read_msg_reply_all);
  688.     $oTemplate->assign('accesskey_read_msg_forward'$accesskey_read_msg_forward);
  689.     $oTemplate->assign('accesskey_read_msg_as_attach'$accesskey_read_msg_as_attach);
  690.     $oTemplate->assign('accesskey_read_msg_delete'$accesskey_read_msg_delete);
  691.     $oTemplate->assign('accesskey_read_msg_bypass_trash'$accesskey_read_msg_bypass_trash);
  692.     $oTemplate->assign('accesskey_read_msg_move_to'$accesskey_read_msg_move_to);
  693.     $oTemplate->assign('accesskey_read_msg_move'$accesskey_read_msg_move);
  694.     $oTemplate->assign('accesskey_read_msg_copy'$accesskey_read_msg_copy);
  695.  
  696.     global $null;
  697.     do_hook('read_body_menu'$null);
  698.  
  699.     if ($nav_on_top{
  700.         $oTemplate->display('read_menubar_nav.tpl');
  701.         $oTemplate->display('read_menubar_buttons.tpl');
  702.     else {
  703.         $oTemplate->display('read_menubar_buttons.tpl');
  704.         $oTemplate->display('read_menubar_nav.tpl');
  705.     }
  706.  
  707. }
  708.  
  709. function formatToolbar($mailbox$passed_id$passed_ent_id$message$color{
  710.     global $base_uri$where$what$show_html_default,
  711.            $oTemplate$download_href$PHP_SELF,
  712.            $unsafe_image_toggle_href$unsafe_image_toggle_text;
  713.  
  714.     $urlMailbox urlencode($mailbox);
  715.     $urlPassed_id urlencode($passed_id);
  716.     $urlPassed_ent_id urlencode($passed_ent_id);
  717.  
  718.     $query_string 'mailbox=' $urlMailbox '&amp;passed_id=' $urlPassed_id '&amp;passed_ent_id=' $urlPassed_ent_id;
  719.     if (!empty($where)) {
  720.         $query_string .= '&amp;where=' urlencode($where);
  721.     }
  722.     if (!empty($what)) {
  723.         $query_string .= '&amp;what=' urlencode($what);
  724.     }
  725.     $url $base_uri.'src/view_header.php?'.$query_string;
  726.  
  727.     $links array();
  728.     $links[array (
  729.                         'URL'   => $url,
  730.                         'Text'  => _("View Full Header")
  731.                      );
  732.  
  733.     if checkForJavaScript() ) 
  734.         $links[array (
  735.                         'URL'   => 'javascript:printThis();',
  736.                         'Text'  => _("Print"),
  737.                      );
  738.     else {
  739.         $links[array (
  740.                         'URL'   => set_url_var($PHP_SELF'print''1'),
  741.                         'Text'  => _("Print"),
  742.                         'Target' => '_blank'
  743.                      );
  744.     }
  745.  
  746.     $links[array (
  747.                         'URL'   => $download_href,
  748.                         'Text'  => _("Download this as a file")
  749.                      );
  750.     $toggle html_toggle_href($mailbox$passed_id$passed_ent_id$message);
  751.     if (!empty($toggle)) {
  752.         $links[array (
  753.                             'URL'   => $toggle,
  754.                             'Text'  => $show_html_default==_("View as plain text"_("View as HTML")
  755.                          );
  756.     }
  757.     if (!empty($unsafe_image_toggle_href)) {
  758.         $links[array (
  759.                             'URL'   => $unsafe_image_toggle_href,
  760.                             'Text'  => $unsafe_image_toggle_text
  761.                          );
  762.     }
  763.  
  764.     do_hook('read_body_header_right'$links);
  765.  
  766.     $oTemplate->assign('links'$links);
  767.  
  768.     return $oTemplate->fetch('read_toolbar.tpl');
  769. }
  770.  
  771. /***************************/
  772. /*   Main of read_body.php */
  773. /***************************/
  774.  
  775. /* get the globals we may need */
  776.  
  777. sqgetGlobalVar('delimiter'$delimiter,     SQ_SESSION);
  778. sqgetGlobalVar('lastTargetMailbox'$lastTargetMailboxSQ_SESSION);
  779. if (!sqgetGlobalVar('messages'$messagesSQ_SESSION) ) {
  780.     $messages array();
  781. }
  782. sqgetGlobalVar('delayed_errors',  $delayed_errors,  SQ_SESSION);
  783. if (is_array($delayed_errors)) {
  784.     $oErrorHandler->AssignDelayedErrors($delayed_errors);
  785.     sqsession_unregister("delayed_errors");
  786. }
  787. /** GET VARS */
  788. sqgetGlobalVar('sendreceipt',   $sendreceipt,   SQ_GET);
  789. if (!sqgetGlobalVar('where',         $where,         SQ_GET) ) {
  790.     $where 'right_main.php';
  791. }
  792. /*
  793.  * Used as entry key to the list of uid's cached in the mailbox cache
  794.  * we use the cached uid's to get the next and prev  message.
  795.  */
  796. if (!sqgetGlobalVar('what',          $what,          SQ_GET) ){
  797.     $what 0;
  798. }
  799. if sqgetGlobalVar('show_more'$temp,  SQ_GET) ) {
  800.     $show_more = (int) $temp;
  801. }
  802. if sqgetGlobalVar('show_more_cc'$temp,  SQ_GET) ) {
  803.     $show_more_cc = (int) $temp;
  804. }
  805. if sqgetGlobalVar('show_more_bcc'$temp,  SQ_GET) ) {
  806.     $show_more_bcc = (int) $temp;
  807. }
  808. if sqgetGlobalVar('view_hdr'$temp,  SQ_GET) ) {
  809.     $view_hdr = (int) $temp;
  810. }
  811.  
  812. if sqgetGlobalVar('account'$temp,  SQ_GET) ) {
  813.     $iAccount = (int) $temp;
  814. else {
  815.     $iAccount 0;
  816. }
  817.  
  818. /** GET/POST VARS */
  819. sqgetGlobalVar('passed_id',     $passed_idSQ_INORDERNULLSQ_TYPE_BIGINT);
  820. sqgetGlobalVar('passed_ent_id'$passed_ent_id);
  821. sqgetGlobalVar('mailbox',       $mailbox);
  822.  
  823. if sqgetGlobalVar('sort'$temp) ) {
  824.     $sort = (int) $temp;
  825. }
  826. if sqgetGlobalVar('startMessage'$temp) ) {
  827.     $startMessage = (int) $temp;
  828. else {
  829.     $startMessage 1;
  830. }
  831. if(sqgetGlobalVar('show_html_default'$temp)) {
  832.     $show_html_default = (int) $temp;
  833. }
  834.  
  835. if(sqgetGlobalVar('view_unsafe_images'$temp)) {
  836.     $view_unsafe_images = (int) $temp;
  837.     if($view_unsafe_images == 1{
  838.         $show_html_default 1;
  839.     }
  840. else {
  841.     $view_unsafe_images 0;
  842. }
  843.  
  844. /**
  845.  * Retrieve mailbox cache
  846.  */
  847. sqgetGlobalVar('mailbox_cache',$mailbox_cache,SQ_SESSION);
  848.  
  849. /* end of get globals */
  850.  
  851. $imapConnection sqimap_login($usernamefalse$imapServerAddress$imapPort0);
  852. $aMailbox sqm_api_mailbox_select($imapConnection$iAccount$mailbox,array('setindex' => $what'offset' => $startMessage),array());
  853.  
  854.  
  855. /**
  856.  Start code to set the columns to fetch in case of hitting the next/prev link
  857.  The reason for this is the fact that the cache can be invalidated which means that the headers
  858.  to fetch aren't there anymore. Before they got calculated when the messagelist was shown.
  859.  
  860.  Todo, better central handling of setting the mailbox options so we do not need to do the stuff below
  861. */
  862.  
  863. /**
  864.  * Replace From => To  in case it concerns a draft or sent folder
  865.  */
  866. $aColumns array();
  867. if (($mailbox == $sent_folder || $mailbox == $draft_folder&&
  868.     !in_array(SQM_COL_TO,$index_order)) {
  869.     $aNewOrder array()// nice var name ;)
  870.     foreach($index_order as $iCol{
  871.         if ($iCol == SQM_COL_FROM{
  872.             $iCol SQM_COL_TO;
  873.         }
  874.         $aColumns[$iColarray();
  875.    }
  876. else {
  877.    foreach ($index_order as $iCol{
  878.        $aColumns[$iColarray();
  879.    }
  880. }
  881.  
  882. $aProps array(
  883.     'columns' => $aColumns// columns bound settings
  884.     'config'  => array(
  885.                         'highlight_list'        => $message_highlight_list// row highlighting rules
  886.                         'trash_folder'          => $trash_folder,
  887.                         'sent_folder'           => $sent_folder,
  888.                         'draft_folder'          => $draft_folder));
  889.  
  890. calcFetchColumns($aMailbox,$aProps);
  891.  
  892. /**
  893.  End code to set the columns to fetch in case of hitting the next/prev link
  894. */
  895.  
  896.  
  897.  
  898. /**
  899.  * Check if cache is still valid, $what contains the key
  900.  * which gives us acces to the array with uid's. At this moment
  901.  * 0 is used for a normal message list and search uses 1 as key. This can be
  902.  * changed / extended in the future.
  903.  * If on a select of a mailbox we detect that the cache should be invalidated due to
  904.  * the delete of messages or due to new messages we empty the list with uid's and
  905.  * that's what we detect below.
  906.  */
  907. if (!is_array($aMailbox['UIDSET'][$what])) {
  908.     fetchMessageHeaders($imapConnection$aMailbox);
  909. }
  910.  
  911. $iSetIndex $aMailbox['SETINDEX'];
  912. $aMailbox['CURRENT_MSG'][$iSetIndex$passed_id;
  913.  
  914. /**
  915.  * Update the seen state
  916.  * and ignore in_array('\\seen',$aMailbox['PERMANENTFLAGS'],true)
  917.  */
  918. if (isset($aMailbox['MSG_HEADERS'][$passed_id]['FLAGS'])) {
  919.     $aMailbox['MSG_HEADERS'][$passed_id]['FLAGS']['\\seen'true;
  920. }
  921.  
  922. /**
  923.  * Process Delete from delete-move-next
  924.  * but only if delete_id was set
  925.  */
  926. if sqgetGlobalVar('delete_id'$delete_idSQ_GET) ) {
  927.     handleMessageListForm($imapConnection,$aMailbox,$sButton='setDeleted'array($delete_id));
  928. }
  929.  
  930. /**
  931.  * $message contains all information about the message
  932.  * including header and body
  933.  */
  934.  
  935. if (isset($aMailbox['MSG_HEADERS'][$passed_id]['MESSAGE_OBJECT'])) {
  936.     $message $aMailbox['MSG_HEADERS'][$passed_id]['MESSAGE_OBJECT'];
  937.     $FirstTimeSee !$message->is_seen;
  938. else {
  939.     $message sqimap_get_message($imapConnection$passed_id$mailbox);
  940.     $FirstTimeSee !$message->is_seen;
  941. }
  942.  
  943. /**
  944.  * update message seen status and put in cache
  945.  */
  946. $message->is_seen true;
  947. $aMailbox['MSG_HEADERS'][$passed_id]['MESSAGE_OBJECT'$message;
  948.  
  949. if (isset($passed_ent_id&& $passed_ent_id{
  950.     $message $message->getEntity($passed_ent_id);
  951.     if ($message->type0 != 'message'  && $message->type1 != 'rfc822'{
  952.         $message $message->parent;
  953.     }
  954.     $read sqimap_run_command ($imapConnection"FETCH $passed_id BODY[$passed_ent_id.HEADER]"true$response$msgTRUE);
  955.     $rfc822_header new Rfc822Header();
  956.     $rfc822_header->parseHeader($read);
  957.     $message->rfc822_header $rfc822_header;
  958. else if ($message->type0 == 'message'  && $message->type1 == 'rfc822' && isset($message->entities[0])) {
  959.     $read sqimap_run_command ($imapConnection"FETCH $passed_id BODY[1.HEADER]"true$response$msgTRUE);
  960.     $rfc822_header new Rfc822Header();
  961.     $rfc822_header->parseHeader($read);
  962.     $message->rfc822_header $rfc822_header;
  963. else {
  964.     $passed_ent_id 0;
  965. }
  966. $header $message->header;
  967.  
  968. // gmail does not mark messages as read when retrieving the message body
  969. // even though RFC 3501, section 6.4.5 (FETCH Command) says:
  970. // "The \Seen flag is implicitly set; if this causes the flags to change,
  971. // they SHOULD be included as part of the FETCH responses."
  972. //
  973. if ($imap_server_type == 'gmail'{
  974.     sqimap_toggle_flag($imapConnection$passed_id'\\Seen'truetrue);
  975. }
  976.  
  977. /****************************************/
  978. /* Block for handling incoming url vars */
  979. /****************************************/
  980.  
  981. if (isset($sendreceipt)) {
  982.    if !$message->is_mdnsent {
  983.       $supportMDN ServerMDNSupport($aMailbox["PERMANENTFLAGS"]);
  984.       if SendMDN$mailbox$passed_id$message$imapConnection && $supportMDN {
  985.          ToggleMDNflagtrue$imapConnection$mailbox$passed_id);
  986.          $message->is_mdnsent true;
  987.          $aMailbox['MSG_HEADERS'][$passed_id]['MESSAGE_OBJECT'$message;
  988.       }
  989.    }
  990. }
  991. /***********************************************/
  992. /* End of block for handling incoming url vars */
  993. /***********************************************/
  994.  
  995. $oTemplate->assign('aAttribs'array('class' => 'entity_sep'));
  996. $hr $oTemplate->fetch('horizontal_rule.tpl');
  997. $messagebody '';
  998. do_hook('read_body_top'$null);
  999. if ($show_html_default == 1{
  1000.     $ent_ar $message->findDisplayEntity(array());
  1001. else {
  1002.     $ent_ar $message->findDisplayEntity(array()array('text/plain'));
  1003. }
  1004. $cnt count($ent_ar);
  1005. for ($i 0$i $cnt$i++{
  1006.    $messagebody .= formatBody($imapConnection$message$color$wrap_at$ent_ar[$i]$passed_id$mailbox);
  1007.    if ($i != $cnt-1{
  1008.        $messagebody .= $hr;
  1009.    }
  1010. }
  1011.  
  1012. /**
  1013.  * Write mailbox with updated seen flag information back to cache.
  1014.  */
  1015. $mailbox_cache[$iAccount.'_'.$aMailbox['NAME']] $aMailbox;
  1016. sqsession_register($mailbox_cache,'mailbox_cache');
  1017. $_SESSION['mailbox_cache'$mailbox_cache;
  1018.  
  1019. // message list URI is used in page header when on read_body
  1020. $oTemplate->assign('message_list_href'get_message_list_uri($aMailbox['NAME']$startMessage$what));
  1021.  
  1022. displayPageHeader($color$mailbox,'','');
  1023.  
  1024. /* this is the non-javascript version of printer friendly */
  1025. if sqgetGlobalVar('print'$printSQ_GET) ) {
  1026.     $oTemplate->display('read_message_print.tpl');
  1027. else {
  1028.     formatMenubar($aMailbox$passed_id$passed_ent_id$message,false);
  1029. }
  1030. formatEnvheader($aMailbox$passed_id$passed_ent_id$message$color$FirstTimeSee);
  1031.  
  1032. $oTemplate->assign('message_body'$messagebody);
  1033. $oTemplate->display('read_message_body.tpl');
  1034.  
  1035. formatAttachments($message,$ent_ar,$mailbox$passed_id);
  1036.  
  1037. /* show attached images inline -- if pref'fed so */
  1038. if ($attachment_common_show_images && is_array($attachment_common_show_images_list)) {
  1039.     $images array();
  1040.     foreach ($attachment_common_show_images_list as $img{
  1041.         $imgurl SM_PATH 'src/download.php' .
  1042.                 '?' .
  1043.                 'passed_id='     urlencode($img['passed_id'].
  1044.                 '&amp;mailbox='       urlencode($mailbox.
  1045.                 '&amp;ent_id=' urlencode($img['ent_id'].
  1046.                 '&amp;absolute_dl=true';
  1047.         $a array();
  1048.         $a['Name'$img['name'];
  1049.         $a['DisplayURL'$imgurl;
  1050.         $a['DownloadURL'$img['download_href'];
  1051.         $images[$a;
  1052.     }
  1053.  
  1054.     $oTemplate->assign('images'$images);
  1055.     $oTemplate->display('read_display_images_inline.tpl');
  1056. }
  1057.  
  1058. formatMenubar($aMailbox$passed_id$passed_ent_id$messagefalseFALSE);
  1059.  
  1060. do_hook('read_body_bottom'$null);
  1061. sqimap_logout($imapConnection);
  1062. $oTemplate->display('footer.tpl');

Documentation generated on Mon, 13 Jan 2020 04:23:25 +0100 by phpDocumentor 1.4.3