Source for file compose.php

Documentation is available at compose.php

  1. <?php
  2. /**
  3.  * compose.php
  4.  *
  5.  * This code sends a mail.
  6.  *
  7.  * There are 4 modes of operation:
  8.  *    - Start new mail
  9.  *    - Add an attachment
  10.  *    - Send mail
  11.  *    - Save As Draft
  12.  *
  13.  * @copyright &copy; 1999-2006 The SquirrelMail Project Team
  14.  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  15.  * @version $Id: compose.php,v 1.450 2006/09/29 09:02:22 stekkel Exp $
  16.  * @package squirrelmail
  17.  */
  18.  
  19. /**
  20.  * Include the SquirrelMail initialization file.
  21.  */
  22. require('../include/init.php');
  23.  
  24. /* SquirrelMail required files. */
  25. require_once(SM_PATH . 'functions/imap_general.php');
  26. require_once(SM_PATH . 'functions/imap_messages.php');
  27. require_once(SM_PATH . 'functions/date.php');
  28. require_once(SM_PATH . 'functions/mime.php');
  29. require_once(SM_PATH . 'class/deliver/Deliver.class.php');
  30. require_once(SM_PATH . 'functions/addressbook.php');
  31. require_once(SM_PATH . 'functions/forms.php');
  32. require_once(SM_PATH . 'functions/identity.php');
  33.  
  34. /* --------------------- Get globals ------------------------------------- */
  35.  
  36. /** SESSION VARS */
  37. sqgetGlobalVar('delimiter', $delimiter,     SQ_SESSION);
  38.  
  39. sqgetGlobalVar('composesession',    $composesession,    SQ_SESSION);
  40. sqgetGlobalVar('compose_messages',  $compose_messages,  SQ_SESSION);
  41. sqgetGlobalVar('delayed_errors',  $delayed_errors,  SQ_SESSION);
  42.  
  43. // Turn on delayed error handling in case we wind up redirecting below
  44. $oErrorHandler->setDelayedErrors(true);
  45.  
  46. /** SESSION/POST/GET VARS */
  47. sqgetGlobalVar('session',$session);
  48. sqgetGlobalVar('mailbox',$mailbox);
  49. if(!sqgetGlobalVar('identity',$identity)) {
  50.     $identity=0;
  51. }
  52. sqgetGlobalVar('send_to',$send_to);
  53. sqgetGlobalVar('send_to_cc',$send_to_cc);
  54. sqgetGlobalVar('send_to_bcc',$send_to_bcc);
  55. sqgetGlobalVar('subject',$subject);
  56. sqgetGlobalVar('body',$body);
  57. sqgetGlobalVar('mailprio',$mailprio);
  58. sqgetGlobalVar('request_mdn',$request_mdn);
  59. sqgetGlobalVar('request_dr',$request_dr);
  60. sqgetGlobalVar('html_addr_search',$html_addr_search);
  61. sqgetGlobalVar('mail_sent',$mail_sent);
  62. sqgetGlobalVar('passed_id',$passed_id);
  63. sqgetGlobalVar('passed_ent_id',$passed_ent_id);
  64. sqgetGlobalVar('send',$send);
  65.  
  66. sqgetGlobalVar('attach',$attach);
  67.  
  68. sqgetGlobalVar('draft',$draft);
  69. sqgetGlobalVar('draft_id',$draft_id);
  70. sqgetGlobalVar('ent_num',$ent_num);
  71. sqgetGlobalVar('saved_draft',$saved_draft);
  72. sqgetGlobalVar('delete_draft',$delete_draft);
  73. if ( sqgetGlobalVar('startMessage',$startMessage) ) {
  74.     $startMessage = (int)$startMessage;
  75. } else {
  76.     $startMessage = 1;
  77. }
  78.  
  79.  
  80. /** POST VARS */
  81. sqgetGlobalVar('sigappend',             $sigappend,                 SQ_POST);
  82. sqgetGlobalVar('from_htmladdr_search',  $from_htmladdr_search,      SQ_POST);
  83. sqgetGlobalVar('addr_search_done',      $html_addr_search_done,     SQ_POST);
  84. sqgetGlobalVar('addr_search_cancel',    $html_addr_search_cancel,   SQ_POST);
  85. sqgetGlobalVar('send_to_search',        $send_to_search,            SQ_POST);
  86. sqgetGlobalVar('do_delete',             $do_delete,                 SQ_POST);
  87. sqgetGlobalVar('delete',                $delete,                    SQ_POST);
  88. sqgetGlobalVar('restoremessages',       $restoremessages,           SQ_POST);
  89. if ( sqgetGlobalVar('return', $temp, SQ_POST) ) {
  90.     $html_addr_search_done = 'Use Addresses';
  91. }
  92.  
  93. /** GET VARS */
  94. sqgetGlobalVar('attachedmessages', $attachedmessages, SQ_GET);
  95. if ( sqgetGlobalVar('account', $temp,  SQ_GET) ) {
  96.     $iAccount = (int) $temp;
  97. } else {
  98.     $iAccount = 0;
  99. }
  100.  
  101.  
  102. /** get smaction */
  103. if ( !sqgetGlobalVar('smaction',$action) )
  104. {
  105.     if ( sqgetGlobalVar('smaction_reply',$tmp) )      $action = 'reply';
  106.     if ( sqgetGlobalVar('smaction_reply_all',$tmp) )  $action = 'reply_all';
  107.     if ( sqgetGlobalVar('smaction_forward',$tmp) )    $action = 'forward';
  108.     if ( sqgetGlobalVar('smaction_attache',$tmp) )    $action = 'forward_as_attachment';
  109.     if ( sqgetGlobalVar('smaction_draft',$tmp) )      $action = 'draft';
  110.     if ( sqgetGlobalVar('smaction_edit_new',$tmp) )   $action = 'edit_as_new';
  111. }
  112.  
  113. /* Location (For HTTP 1.1 Header("Location: ...") redirects) */
  114. $location = get_location();
  115. /* Identities (fetch only once) */
  116. $idents = get_identities();
  117.  
  118. /* --------------------- Specific Functions ------------------------------ */
  119.  
  120. function replyAllString($header) {
  121.     global $include_self_reply_all, $idents;
  122.     $excl_ar = array();
  123.     /**
  124.      * 1) Remove the addresses we'll be sending the message 'to'
  125.      */
  126.     if (isset($header->replyto)) {
  127.         $excl_ar = $header->getAddr_a('replyto');
  128.     }
  129.     /**
  130.      * 2) Remove our identities from the CC list (they still can be in the
  131.      * TO list) only if $include_self_reply_all is turned off
  132.      */
  133.     if (!$include_self_reply_all) {
  134.         foreach($idents as $id) {
  135.             $excl_ar[strtolower(trim($id['email_address']))] = '';
  136.         }
  137.     }
  138.  
  139.     /**
  140.      * 3) get the addresses.
  141.      */
  142.     $url_replytoall_ar = $header->getAddr_a(array('to','cc'), $excl_ar);
  143.  
  144.     /**
  145.      * 4) generate the string.
  146.      */
  147.     $url_replytoallcc = '';
  148.     foreach( $url_replytoall_ar as $email => $personal) {
  149.         if ($personal) {
  150.             // if personal name contains address separator then surround
  151.             // the personal name with double quotes.
  152.             if (strpos($personal,',') !== false) {
  153.                 $personal = '"'.$personal.'"';
  154.             }
  155.             $url_replytoallcc .= ", $personal <$email>";
  156.         } else {
  157.             $url_replytoallcc .= ', '. $email;
  158.         }
  159.     }
  160.     $url_replytoallcc = substr($url_replytoallcc,2);
  161.  
  162.     return $url_replytoallcc;
  163. }
  164.  
  165. /**
  166.  * creates top line in reply citations
  167.  *
  168.  * Line style depends on user preferences.
  169.  * $orig_date argument is available only from 1.4.3 and 1.5.1 version.
  170.  * @param object $orig_from From: header object.
  171.  * @param integer $orig_date email's timestamp
  172.  * @return string reply citation
  173.  */
  174. function getReplyCitation($orig_from, $orig_date) {
  175.     global $reply_citation_style, $reply_citation_start, $reply_citation_end;
  176.  
  177.     if (!is_object($orig_from)) {
  178.         $sOrig_from = '';
  179.     } else {
  180.         $sOrig_from = decodeHeader($orig_from->getAddress(false),false,false,true);
  181.     }
  182.  
  183.     /* First, return an empty string when no citation style selected. */
  184.     if (($reply_citation_style == '') || ($reply_citation_style == 'none')) {
  185.         return '';
  186.     }
  187.  
  188.     /* Make sure our final value isn't an empty string. */
  189.     if ($sOrig_from == '') {
  190.         return '';
  191.     }
  192.  
  193.     /* Otherwise, try to select the desired citation style. */
  194.     switch ($reply_citation_style) {
  195.     case 'author_said':
  196.         /**
  197.          * To translators: %s is for author's name
  198.          */
  199.         $full_reply_citation = sprintf(_("%s wrote:"),$sOrig_from);
  200.         break;
  201.     case 'quote_who':
  202.         $start = '<quote who="';
  203.         $end   = '">';
  204.         $full_reply_citation = $start . $sOrig_from . $end;
  205.         break;
  206.     case 'date_time_author':
  207.         /**
  208.          * To translators:
  209.          *  first %s is for date string, second %s is for author's name. Date uses
  210.          *  formating from "D, F j, Y g:i a" and "D, F j, Y H:i" translations.
  211.          * Example string:
  212.          *  "On Sat, December 24, 2004 23:59, Santa wrote:"
  213.          * If you have to put author's name in front of date string, check comments about
  214.          * argument swapping at http://www.php.net/sprintf
  215.          */
  216.         $full_reply_citation = sprintf(_("On %s, %s wrote:"), getLongDateString($orig_date), $sOrig_from);
  217.         break;
  218.     case 'user-defined':
  219.         $start = $reply_citation_start .
  220.             ($reply_citation_start == '' ? '' : ' ');
  221.         $end   = $reply_citation_end;
  222.         $full_reply_citation = $start . $sOrig_from . $end;
  223.         break;
  224.     default:
  225.         return '';
  226.     }
  227.  
  228.     /* Add line feed and return the citation string. */
  229.     return ($full_reply_citation . "\n");
  230. }
  231.  
  232. /**
  233.  * Creates header fields in forwarded email body
  234.  *
  235.  * $default_charset global must be set correctly before you call this function.
  236.  * @param object $orig_header 
  237.  * @return $string 
  238.  */
  239. function getforwardHeader($orig_header) {
  240.     global $editor_size, $default_charset;
  241.  
  242.     // using own strlen function in order to detect correct string length
  243.     $display = array( _("Subject") => sq_strlen(_("Subject"),$default_charset),
  244.             _("From")    => sq_strlen(_("From"),$default_charset),
  245.             _("Date")    => sq_strlen(_("Date"),$default_charset),
  246.             _("To")      => sq_strlen(_("To"),$default_charset),
  247.             _("Cc")      => sq_strlen(_("Cc"),$default_charset) );
  248.     $maxsize = max($display);
  249.     $indent = str_pad('',$maxsize+2);
  250.     foreach($display as $key => $val) {
  251.         $display[$key] = $key .': '. str_pad('', $maxsize - $val);
  252.     }
  253.     $from = decodeHeader($orig_header->getAddr_s('from',"\n$indent"),false,false,true);
  254.     $from = str_replace('&nbsp;',' ',$from);
  255.     $to = decodeHeader($orig_header->getAddr_s('to',"\n$indent"),false,false,true);
  256.     $to = str_replace('&nbsp;',' ',$to);
  257.     $subject = decodeHeader($orig_header->subject,false,false,true);
  258.     $subject = str_replace('&nbsp;',' ',$subject);
  259.  
  260.     // using own str_pad function in order to create correct string pad
  261.     $bodyTop =  sq_str_pad(' '._("Original Message").' ',$editor_size -2,'-',STR_PAD_BOTH,$default_charset) .
  262.         "\n". $display[_("Subject")] . $subject . "\n" .
  263.         $display[_("From")] . $from . "\n" .
  264.         $display[_("Date")] . getLongDateString( $orig_header->date ). "\n" .
  265.         $display[_("To")] . $to . "\n";
  266.     if ($orig_header->cc != array() && $orig_header->cc !='') {
  267.         $cc = decodeHeader($orig_header->getAddr_s('cc',"\n$indent"),false,false,true);
  268.         $cc = str_replace('&nbsp;',' ',$cc);
  269.         $bodyTop .= $display[_("Cc")] .$cc . "\n";
  270.     }
  271.     $bodyTop .= str_pad('', $editor_size -2 , '-') .
  272.         "\n\n";
  273.     return $bodyTop;
  274. }
  275. /* ----------------------------------------------------------------------- */
  276.  
  277. /*
  278.  * If the session is expired during a post this restores the compose session
  279.  * vars.
  280.  */
  281. if (sqsession_is_registered('session_expired_post')) {
  282.     sqgetGlobalVar('session_expired_post', $session_expired_post, SQ_SESSION);
  283.     /*
  284.      * extra check for username so we don't display previous post data from
  285.      * another user during this session.
  286.      */
  287.     if ($session_expired_post['username'] != $username) {
  288.         unset($session_expired_post);
  289.         sqsession_unregister('session_expired_post');
  290.         session_write_close();
  291.     } else {
  292.         // these are the vars that we can set from the expired composed session   
  293.                 $compo_var_list = array ( 'send_to', 'send_to_cc','body','startMessage',
  294.             'passed_body','use_signature','signature','attachments','subject','newmail',
  295.             'send_to_bcc', 'passed_id', 'mailbox', 'from_htmladdr_search', 'identity',
  296.             'draft_id', 'delete_draft', 'mailprio', 'edit_as_new', 'compose_messsages',
  297.             'composesession', 'request_mdn', 'request_dr');
  298.  
  299.         foreach ($compo_var_list as $var) {
  300.             if ( isset($session_expired_post[$var]) && !isset($$var) ) {
  301.                $$var = $session_expired_post[$var];
  302.             }
  303.         }
  304.  
  305.         $compose_messages = unserialize(urldecode($restoremessages));
  306.         sqsession_register($compose_messages,'compose_messages');
  307.         sqsession_register($composesession,'composesession');
  308.         if (isset($send)) {
  309.             unset($send);
  310.         }
  311.         $session_expired = true;
  312.     }
  313.     unset($session_expired_post);
  314.     sqsession_unregister('session_expired_post');
  315.     if (!isset($mailbox)) {
  316.         $mailbox = '';
  317.     }
  318.     if ($compose_new_win == '1') {
  319.         compose_Header($color, $mailbox);
  320.     } else {
  321.         $sHeaderJs = (isset($sHeaderJs)) ? $sHeaderJs : '';
  322.         if (strpos($action, 'reply') !== false && $reply_focus) {
  323.             $sBodyTagJs = 'onload="checkForm(\''.$replyfocus.'\');"';
  324.         } else {
  325.             $sBodyTagJs = 'onload="checkForm();"';
  326.         }
  327.         displayPageHeader($color, $mailbox,$sHeaderJs,$sBodyTagJs);
  328.     }
  329.     showInputForm($session, false);
  330.     exit();
  331. }
  332. if (!isset($composesession)) {
  333.     $composesession = 0;
  334.     sqsession_register(0,'composesession');
  335. }
  336.  
  337. if (!isset($session) || (isset($newmessage) && $newmessage)) {
  338.     sqsession_unregister('composesession');
  339.     $session = "$composesession" +1;
  340.     $composesession = $session;
  341.     sqsession_register($composesession,'composesession');
  342. }
  343. if (!isset($compose_messages)) {
  344.     $compose_messages = array();
  345. }
  346.  
  347. if (!isset($compose_messages[$session]) || ($compose_messages[$session] == NULL)) {
  348.     $composeMessage = new Message();
  349.     $rfc822_header = new Rfc822Header();
  350.     $composeMessage->rfc822_header = $rfc822_header;
  351.     $composeMessage->reply_rfc822_header = '';
  352.     $compose_messages[$session] = $composeMessage;
  353.  
  354.     sqsession_register($compose_messages,'compose_messages');
  355. } else {
  356.     $composeMessage=$compose_messages[$session];
  357. }
  358.  
  359. if (!isset($mailbox) || $mailbox == '' || ($mailbox == 'None')) {
  360.     $mailbox = 'INBOX';
  361. }
  362.  
  363. if ($draft) {
  364.     /*
  365.      * Set $default_charset to correspond with the user's selection
  366.      * of language interface.
  367.      */
  368.     set_my_charset();
  369.     $composeMessage=$compose_messages[$session];
  370.     if (! deliverMessage($composeMessage, true)) {
  371.         showInputForm($session);
  372.         exit();
  373.     } else {
  374.         unset($compose_messages[$session]);
  375.         $draft_message = _("Draft Email Saved");
  376.         /* If this is a resumed draft, then delete the original */
  377.         if(isset($delete_draft)) {
  378.             $imap_stream = sqimap_login($username, false, $imapServerAddress, $imapPort, false);
  379.             sqimap_mailbox_select($imap_stream, $draft_folder);
  380.             // force bypass_trash=true because message should be saved when deliverMessage() returns true.
  381.             // in current implementation of sqimap_msgs_list_flag() single message id can
  382.             // be submitted as string. docs state that it should be array.
  383.                         sqimap_msgs_list_delete($imap_stream, $draft_folder, $delete_draft, true);
  384.             if ($auto_expunge) {
  385.                 sqimap_mailbox_expunge($imap_stream, $draft_folder, true);
  386.             }
  387.             sqimap_logout($imap_stream);
  388.         }
  389.         
  390.         $oErrorHandler->saveDelayedErrors();
  391.         session_write_close();
  392.  
  393.         if ($compose_new_win == '1') {
  394.             if ( !isset($pageheader_sent) || !$pageheader_sent ) {
  395.                 Header("Location: $location/compose.php?saved_draft=yes&session=$composesession");
  396.             } else {
  397.                 echo '   <br><br><div style="text-align: center;"><a href="' . $location
  398.                     . '/compose.php?saved_sent=yes&amp;session=' . $composesession . '">'
  399.                     . _("Return") . '</a></div>';
  400.             }
  401.             exit();
  402.         } else {
  403.             if ( !isset($pageheader_sent) || !$pageheader_sent ) {
  404.                 Header("Location: $location/right_main.php?mailbox=" . urlencode($draft_folder) .
  405.                    "&startMessage=1&note=".urlencode($draft_message));
  406.             } else {
  407.                 echo '   <br><br><div style="text-align: center;"><a href="' . $location
  408.                     . '/right_main.php?mailbox=' . urlencode($draft_folder)
  409.                     . '&amp;startMessage=1&amp;note=' . urlencode($draft_message) .'">'
  410.                     . _("Return") . '</a></div>';
  411.             }
  412.             exit();
  413.         }
  414.     }
  415. }
  416.  
  417. if ($send) {
  418.     if (isset($_FILES['attachfile']) &&
  419.             $_FILES['attachfile']['tmp_name'] &&
  420.             $_FILES['attachfile']['tmp_name'] != 'none') {
  421.         $AttachFailure = saveAttachedFiles($session);
  422.     }
  423.     if (checkInput(false) && !isset($AttachFailure)) {
  424.         if ($mailbox == "All Folders") {
  425.             /* We entered compose via the search results page */
  426.             $mailbox = 'INBOX'; /* Send 'em to INBOX, that's safe enough */
  427.         }
  428.         $urlMailbox = urlencode (trim($mailbox));
  429.         if (! isset($passed_id)) {
  430.             $passed_id = 0;
  431.         }
  432.         /**
  433.          * Set $default_charset to correspond with the user's selection
  434.          * of language interface.
  435.          */
  436.         set_my_charset();
  437.         /**
  438.          * This is to change all newlines to \n
  439.          * We'll change them to \r\n later (in the sendMessage function)
  440.          */
  441.         $body = str_replace("\r\n", "\n", $body);
  442.         $body = str_replace("\r", "\n", $body);
  443.  
  444.         /**
  445.          * Rewrap $body so that no line is bigger than $editor_size
  446.          */
  447.         $body = explode("\n", $body);
  448.         $newBody = '';
  449.         foreach ($body as $line) {
  450.             if( $line <> '-- ' ) {
  451.                 $line = rtrim($line);
  452.             }
  453.             if (sq_strlen($line,$default_charset) <= $editor_size + 1) {
  454.                 $newBody .= $line . "\n";
  455.             } else {
  456.                 sqWordWrap($line, $editor_size,$default_charset);
  457.                 $newBody .= $line . "\n";
  458.  
  459.             }
  460.  
  461.         }
  462.         $body = $newBody;
  463.  
  464.         $composeMessage=$compose_messages[$session];
  465.  
  466.         $Result = deliverMessage($composeMessage);
  467.  
  468.         do_hook('compose_send_after', $Result, $composeMessage);
  469.         if (! $Result) {
  470.             showInputForm($session);
  471.             exit();
  472.         }
  473.         unset($compose_messages[$session]);
  474.  
  475.         /* if it is resumed draft, delete draft message */
  476.         if ( isset($delete_draft)) {
  477.             $imap_stream = sqimap_login($username, false, $imapServerAddress, $imapPort, false);
  478.             sqimap_mailbox_select($imap_stream, $draft_folder);
  479.             // bypass_trash=true because message should be saved when deliverMessage() returns true.
  480.             // in current implementation of sqimap_msgs_list_flag() single message id can
  481.             // be submitted as string. docs state that it should be array.
  482.                         sqimap_msgs_list_delete($imap_stream, $draft_folder, $delete_draft, true);
  483.             if ($auto_expunge) {
  484.                 sqimap_mailbox_expunge($imap_stream, $draft_folder, true);
  485.             }
  486.             sqimap_logout($imap_stream);
  487.         }
  488.         /*
  489.          * Store the error array in the session because they will be lost on a redirect
  490.          */
  491.         $oErrorHandler->saveDelayedErrors();
  492.         session_write_close();
  493.  
  494.         if ($compose_new_win == '1') {
  495.             if ( !isset($pageheader_sent) || !$pageheader_sent ) {
  496.                 Header("Location: $location/compose.php?mail_sent=yes");
  497.             } else {
  498.                 echo '   <br><br><div style="text-align: center;"><a href="' . $location
  499.                     . '/compose.php?mail_sent=yes">'
  500.                     . _("Return") . '</a></div>';
  501.             }
  502.             exit();
  503.         } else {
  504.             if ( !isset($pageheader_sent) || !$pageheader_sent ) {
  505.                 Header("Location: $location/right_main.php?mailbox=$urlMailbox".
  506.                     "&startMessage=$startMessage&mail_sent=yes");
  507.             } else {
  508.                 echo '   <br><br><div style="text-align: center;"><a href="' . $location
  509.                     . "/right_main.php?mailbox=$urlMailbox"
  510.                     . "&amp;startMessage=$startMessage&amp;mail_sent=yes\">"
  511.                     . _("Return") . '</a></div>';
  512.             }
  513.             exit();
  514.         }
  515.     } else {
  516.         if ($compose_new_win == '1') {
  517.             compose_Header($color, $mailbox);
  518.         }
  519.         else {
  520.             displayPageHeader($color, $mailbox);
  521.         }
  522.         if (isset($AttachFailure)) {
  523.             plain_error_message(_("Could not move/copy file. File not attached"),
  524.                     $color);
  525.         }
  526.         checkInput(true);
  527.         showInputForm($session);
  528.         /* sqimap_logout($imapConnection); */
  529.     }
  530. } elseif (isset($html_addr_search_done)) {
  531.     if ($compose_new_win == '1') {
  532.         compose_Header($color, $mailbox);
  533.     }
  534.     else {
  535.         displayPageHeader($color, $mailbox);
  536.     }
  537.  
  538.     if (isset($send_to_search) && is_array($send_to_search)) {
  539.         foreach ($send_to_search as $k => $v) {
  540.             if (substr($k, 0, 1) == 'T') {
  541.                 if ($send_to) {
  542.                     $send_to .= ', ';
  543.                 }
  544.                 $send_to .= $v;
  545.             }
  546.             elseif (substr($k, 0, 1) == 'C') {
  547.                 if ($send_to_cc) {
  548.                     $send_to_cc .= ', ';
  549.                 }
  550.                 $send_to_cc .= $v;
  551.             }
  552.             elseif (substr($k, 0, 1) == 'B') {
  553.                 if ($send_to_bcc) {
  554.                     $send_to_bcc .= ', ';
  555.                 }
  556.                 $send_to_bcc .= $v;
  557.             }
  558.         }
  559.     }
  560.     showInputForm($session);
  561. } elseif (isset($html_addr_search) && !isset($html_addr_search_cancel)) {
  562.     if (isset($_FILES['attachfile']) &&
  563.             $_FILES['attachfile']['tmp_name'] &&
  564.             $_FILES['attachfile']['tmp_name'] != 'none') {
  565.         if(saveAttachedFiles($session)) {
  566.             plain_error_message(_("Could not move/copy file. File not attached"));
  567.         }
  568.     }
  569.     /*
  570.      * I am using an include so as to elminiate an extra unnecessary
  571.      * click.  If you can think of a better way, please implement it.
  572.      */
  573.     include_once('./addrbook_search_html.php');
  574. } elseif (isset($attach)) {
  575.     if ($compose_new_win == '1') {
  576.         compose_Header($color, $mailbox);
  577.     } else {
  578.         displayPageHeader($color, $mailbox);
  579.     }
  580.     if (saveAttachedFiles($session)) {
  581.         plain_error_message(_("Could not move/copy file. File not attached"));
  582.     }
  583.     showInputForm($session);
  584. }
  585. elseif (isset($sigappend)) {
  586.     $signature = $idents[$identity]['signature'];
  587.  
  588.     $body .= "\n\n".($prefix_sig==true? "-- \n":'').$signature;
  589.     if ($compose_new_win == '1') {
  590.         compose_Header($color, $mailbox);
  591.     } else {
  592.         displayPageHeader($color, $mailbox);
  593.     }
  594.     showInputForm($session);
  595. } elseif (isset($do_delete)) {
  596.     if ($compose_new_win == '1') {
  597.         compose_Header($color, $mailbox);
  598.     } else {
  599.         displayPageHeader($color, $mailbox);
  600.     }
  601.  
  602.     if (isset($delete) && is_array($delete)) {
  603.         $composeMessage = $compose_messages[$session];
  604.         foreach($delete as $index) {
  605.             if (!empty($composeMessage->entities) && isset($composeMessage->entities[$index])) {
  606.                 $composeMessage->entities[$index]->purgeAttachments();
  607.                 unset ($composeMessage->entities[$index]);
  608.             }
  609.         }
  610.         $new_entities = array();
  611.         foreach ($composeMessage->entities as $entity) {
  612.             $new_entities[] = $entity;
  613.         }
  614.         $composeMessage->entities = $new_entities;
  615.         $compose_messages[$session] = $composeMessage;
  616.         sqsession_register($compose_messages, 'compose_messages');
  617.     }
  618.     showInputForm($session);
  619. } else {
  620.     /*
  621.      * This handles the default case as well as the error case
  622.      * (they had the same code) --> if (isset($smtpErrors))
  623.      */
  624.  
  625.     if ($compose_new_win == '1') {
  626.         compose_Header($color, $mailbox);
  627.     } else {
  628.         displayPageHeader($color, $mailbox);
  629.     }
  630.  
  631.     $newmail = true;
  632.  
  633.     if (!isset($passed_ent_id)) {
  634.         $passed_ent_id = '';
  635.     }
  636.     if (!isset($passed_id)) {
  637.         $passed_id = '';
  638.     }
  639.     if (!isset($mailbox)) {
  640.         $mailbox = '';
  641.     }
  642.     if (!isset($action)) {
  643.         $action = '';
  644.     }
  645.  
  646.     $values = newMail($mailbox,$passed_id,$passed_ent_id, $action, $session);
  647.  
  648.     /* in case the origin is not read_body.php */
  649.     if (isset($send_to)) {
  650.         $values['send_to'] = $send_to;
  651.     }
  652.     if (isset($send_to_cc)) {
  653.         $values['send_to_cc'] = $send_to_cc;
  654.     }
  655.     if (isset($send_to_bcc)) {
  656.         $values['send_to_bcc'] = $send_to_bcc;
  657.     }
  658.     if (isset($subject)) {
  659.         $values['subject'] = $subject;
  660.     }
  661.     showInputForm($session, $values);
  662. }
  663.  
  664. exit();
  665.  
  666. /**************** Only function definitions go below *************/
  667.  
  668. function getforwardSubject($subject)
  669. {
  670.     if ((substr(strtolower($subject), 0, 4) != 'fwd:') &&
  671.             (substr(strtolower($subject), 0, 5) != '[fwd:') &&
  672.             (substr(strtolower($subject), 0, 6) != '[ fwd:')) {
  673.         $subject = '[Fwd: ' . $subject . ']';
  674.     }
  675.     return $subject;
  676. }
  677.  
  678. /* This function is used when not sending or adding attachments */
  679. function newMail ($mailbox='', $passed_id='', $passed_ent_id='', $action='', $session='') {
  680.     global $editor_size, $default_use_priority, $body, $idents,
  681.         $use_signature, $data_dir, $username,
  682.         $key, $imapServerAddress, $imapPort, $compose_messages,
  683.         $composeMessage, $body_quote, $request_mdn, $request_dr,
  684.         $default_use_mdn, $mdn_user_support;
  685.     global $languages, $squirrelmail_language, $default_charset;
  686.  
  687.     /*
  688.      * Set $default_charset to correspond with the user's selection
  689.      * of language interface. $default_charset global is not correct,
  690.      * if message is composed in new window.
  691.      */
  692.     set_my_charset();
  693.  
  694.     $send_to = $send_to_cc = $send_to_bcc = $subject = $identity = '';
  695.     $mailprio = 3;
  696.  
  697.     if ($passed_id) {
  698.         $imapConnection = sqimap_login($username, false, $imapServerAddress,
  699.                 $imapPort, 0);
  700.  
  701.         sqimap_mailbox_select($imapConnection, $mailbox);
  702.         $message = sqimap_get_message($imapConnection, $passed_id, $mailbox);
  703.  
  704.         $body = '';
  705.         if ($passed_ent_id) {
  706.             /* redefine the messsage in case of message/rfc822 */
  707.             $message = $message->getEntity($passed_ent_id);
  708.             /* message is an entity which contains the envelope and type0=message
  709.              * and type1=rfc822. The actual entities are childs from
  710.              * $message->entities[0]. That's where the encoding and is located
  711.              */
  712.  
  713.             $entities = $message->entities[0]->findDisplayEntity
  714.                 (array(), $alt_order = array('text/plain'));
  715.             if (!count($entities)) {
  716.                 $entities = $message->entities[0]->findDisplayEntity
  717.                     (array(), $alt_order = array('text/plain','html/plain'));
  718.             }
  719.             $orig_header = $message->rfc822_header; /* here is the envelope located */
  720.             /* redefine the message for picking up the attachments */
  721.             $message = $message->entities[0];
  722.  
  723.         } else {
  724.             $entities = $message->findDisplayEntity (array(), $alt_order = array('text/plain'));
  725.             if (!count($entities)) {
  726.                 $entities = $message->findDisplayEntity (array(), $alt_order = array('text/plain','html/plain'));
  727.             }
  728.             $orig_header = $message->rfc822_header;
  729.         }
  730.  
  731.         $type0 = $message->type0;
  732.         $type1 = $message->type1;
  733.         foreach ($entities as $ent) {
  734.             $msg = $message->getEntity($ent);
  735.             $type0 = $msg->type0;
  736.             $type1 = $msg->type1;
  737.             $unencoded_bodypart = mime_fetch_body($imapConnection, $passed_id, $ent);
  738.             $body_part_entity = $message->getEntity($ent);
  739.             $bodypart = decodeBody($unencoded_bodypart, 
  740.                     $body_part_entity->header->encoding);
  741.             if ($type1 == 'html') {
  742.                 $bodypart = str_replace("\n", ' ', $bodypart);
  743.                 $bodypart = preg_replace(array('/<\/?p>/i','/<div><\/div>/i','/<br\s*(\/)*>/i','/<\/?div>/i'), "\n", $bodypart);
  744.                 $bodypart = str_replace(array('&nbsp;','&gt;','&lt;'),array(' ','>','<'),$bodypart);
  745.                 $bodypart = strip_tags($bodypart);
  746.             }
  747.             if (isset($languages[$squirrelmail_language]['XTRA_CODE']) &&
  748.                     function_exists($languages[$squirrelmail_language]['XTRA_CODE'] . '_decode')) {
  749.                 if (mb_detect_encoding($bodypart) != 'ASCII') {
  750.                     $bodypart = call_user_func($languages[$squirrelmail_language]['XTRA_CODE'] . '_decode', $bodypart);
  751.                 }
  752.             }
  753.  
  754.             // charset encoding in compose form stuff
  755.             if (isset($body_part_entity->header->parameters['charset'])) {
  756.                 $actual = $body_part_entity->header->parameters['charset'];
  757.             } else {
  758.                 $actual = 'us-ascii';
  759.             }
  760.  
  761.             if ( $actual && is_conversion_safe($actual) && $actual != $default_charset){
  762.                 $bodypart = charset_convert($actual,$bodypart,$default_charset,false);
  763.             }
  764.             // end of charset encoding in compose
  765.  
  766.             $body .= $bodypart;
  767.         }
  768.         if ($default_use_priority) {
  769.             $mailprio = substr($orig_header->priority,0,1);
  770.             if (!$mailprio) {
  771.                 $mailprio = 3;
  772.             }
  773.         } else {
  774.             $mailprio = '';
  775.         }
  776.  
  777.         $identity = '';
  778.         $from_o = $orig_header->from;
  779.         if (is_array($from_o)) {
  780.             if (isset($from_o[0])) {
  781.                 $from_o = $from_o[0];
  782.             }
  783.         }
  784.         if (is_object($from_o)) {
  785.             $orig_from = $from_o->getAddress();
  786.         } else {
  787.             $orig_from = '';
  788.         }
  789.  
  790.         $identities = array();
  791.         if (count($idents) > 1) {
  792.             foreach($idents as $nr=>$data) {
  793.                 $enc_from_name = '"'.$data['full_name'].'" <'. $data['email_address'].'>';
  794.                 if($enc_from_name == $orig_from) {
  795.                     $identity = $nr;
  796.                     break;
  797.                 }
  798.                 $identities[] = $enc_from_name;
  799.             }
  800.  
  801.             $identity_match = $orig_header->findAddress($identities);
  802.             if ($identity_match) {
  803.                 $identity = $identity_match;
  804.             }
  805.         }
  806.  
  807.         switch ($action) {
  808.             case ('draft'):
  809.                 $use_signature = FALSE;
  810.                 $composeMessage->rfc822_header = $orig_header;
  811.                 $send_to = decodeHeader($orig_header->getAddr_s('to'),false,false,true);
  812.                 $send_to_cc = decodeHeader($orig_header->getAddr_s('cc'),false,false,true);
  813.                 $send_to_bcc = decodeHeader($orig_header->getAddr_s('bcc'),false,false,true);
  814.                 $send_from = $orig_header->getAddr_s('from');
  815.                 $send_from_parts = new AddressStructure();
  816.                 $send_from_parts = $orig_header->parseAddress($send_from);
  817.                 $send_from_add = $send_from_parts->mailbox . '@' . $send_from_parts->host;
  818.                 $identities = get_identities();
  819.                 if (count($identities) > 0) {
  820.                     foreach($identities as $iddata) {
  821.                         if ($send_from_add == $iddata['email_address']) {
  822.                             $identity = $iddata['index'];
  823.                             break;
  824.                         }
  825.                     }
  826.                 }
  827.                 $subject = decodeHeader($orig_header->subject,false,false,true);
  828.                 
  829.                 // Remember the receipt settings
  830.                 $request_mdn = $mdn_user_support && !empty($orig_header->dnt) ? '1' : '0';
  831.                 $request_dr = $mdn_user_support && !empty($orig_header->drnt) ? '1' : '0';
  832.                 
  833.                 /* remember the references and in-reply-to headers in case of an reply */
  834.                 $composeMessage->rfc822_header->more_headers['References'] = $orig_header->references;
  835.                 $composeMessage->rfc822_header->more_headers['In-Reply-To'] = $orig_header->in_reply_to;
  836.                 // rewrap the body to clean up quotations and line lengths
  837.                 sqBodyWrap($body, $editor_size);
  838.                 $composeMessage = getAttachments($message, $composeMessage, $passed_id, $entities, $imapConnection);
  839.                 break;
  840.             case ('edit_as_new'):
  841.                 $send_to = decodeHeader($orig_header->getAddr_s('to'),false,false,true);
  842.                 $send_to_cc = decodeHeader($orig_header->getAddr_s('cc'),false,false,true);
  843.                 $send_to_bcc = decodeHeader($orig_header->getAddr_s('bcc'),false,false,true);
  844.                 $subject = decodeHeader($orig_header->subject,false,false,true);
  845.                 $mailprio = $orig_header->priority;
  846.                 $orig_from = '';
  847.                 $composeMessage = getAttachments($message, $composeMessage, $passed_id, $entities, $imapConnection);
  848.                 // rewrap the body to clean up quotations and line lengths
  849.                 sqBodyWrap($body, $editor_size);
  850.                 break;
  851.             case ('forward'):
  852.                 $send_to = '';
  853.                 $subject = getforwardSubject(decodeHeader($orig_header->subject,false,false,true));
  854.                 $body = getforwardHeader($orig_header) . $body;
  855.                 // the logic for calling sqUnWordWrap here would be to allow the browser to wrap the lines
  856.                 // forwarded message text should be as undisturbed as possible, so commenting out this call
  857.                 // sqUnWordWrap($body);
  858.                 $composeMessage = getAttachments($message, $composeMessage, $passed_id, $entities, $imapConnection);
  859.  
  860.                 //add a blank line after the forward headers
  861.                 $body = "\n" . $body;
  862.                 break;
  863.             case ('forward_as_attachment'):
  864.                 $subject = getforwardSubject(decodeHeader($orig_header->subject,false,false,true));
  865.                 $composeMessage = getMessage_RFC822_Attachment($message, $composeMessage, $passed_id, $passed_ent_id, $imapConnection);
  866.                 $body = '';
  867.                 break;
  868.             case ('reply_all'):
  869.                 if(isset($orig_header->mail_followup_to) && $orig_header->mail_followup_to) {
  870.                     $send_to = $orig_header->getAddr_s('mail_followup_to');
  871.                 } else {
  872.                     $send_to_cc = replyAllString($orig_header);
  873.                     $send_to_cc = decodeHeader($send_to_cc,false,false,true);
  874.                 }
  875.             case ('reply'):
  876.                 // skip this if send_to was already set right above here
  877.                 if(!$send_to) {
  878.                     $send_to = $orig_header->reply_to;
  879.                     if (is_array($send_to) && count($send_to)) {
  880.                         $send_to = $orig_header->getAddr_s('reply_to');
  881.                     } else if (is_object($send_to)) { /* unneccesarry, just for failsafe purpose */
  882.                         $send_to = $orig_header->getAddr_s('reply_to');
  883.                     } else {
  884.                         $send_to = $orig_header->getAddr_s('from');
  885.                     }
  886.                 }
  887.                 $send_to = decodeHeader($send_to,false,false,true);
  888.                 $subject = decodeHeader($orig_header->subject,false,false,true);
  889.                 $subject = str_replace('"', "'", $subject);
  890.                 $subject = trim($subject);
  891.                 if (substr(strtolower($subject), 0, 3) != 're:') {
  892.                     $subject = 'Re: ' . $subject;
  893.                 }
  894.                 /* this corrects some wrapping/quoting problems on replies */
  895.                 $rewrap_body = explode("\n", $body);
  896.                 $from =  (is_array($orig_header->from)) ? $orig_header->from[0] : $orig_header->from;
  897.                 $body = '';
  898.                 $strip_sigs = getPref($data_dir, $username, 'strip_sigs');
  899.                 foreach ($rewrap_body as $line) {
  900.                     if ($strip_sigs && substr($line,0,3) == '-- ') {
  901.                         break;
  902.                     }
  903.                     if (preg_match("/^(>+)/", $line, $matches)) {
  904.                         $gt = $matches[1];
  905.                         $body .= $body_quote . str_replace("\n", "\n$body_quote$gt ", rtrim($line)) ."\n";
  906.                     } else {
  907.                         $body .= $body_quote . (!empty($body_quote) ? ' ' : '') . str_replace("\n", "\n$body_quote" . (!empty($body_quote) ? ' ' : ''), rtrim($line)) . "\n";
  908.                     }
  909.                 }
  910.  
  911.                 //rewrap the body to clean up quotations and line lengths
  912.                 $body = sqBodyWrap ($body, $editor_size);
  913.  
  914.                 $body = getReplyCitation($from , $orig_header->date) . $body;
  915.                 $composeMessage->reply_rfc822_header = $orig_header;
  916.  
  917.                 break;
  918.             default:
  919.                 break;
  920.         }
  921.         $compose_messages[$session] = $composeMessage;
  922.         sqsession_register($compose_messages, 'compose_messages');
  923.         session_write_close();
  924.         sqimap_logout($imapConnection);
  925.     }
  926.     $ret = array( 'send_to' => $send_to,
  927.             'send_to_cc' => $send_to_cc,
  928.             'send_to_bcc' => $send_to_bcc,
  929.             'subject' => $subject,
  930.             'mailprio' => $mailprio,
  931.             'body' => $body,
  932.             'identity' => $identity );
  933.  
  934.     return ($ret);
  935. } /* function newMail() */
  936.  
  937. /**
  938.  * downloads attachments from original message, stores them in attachment directory and adds
  939.  * them to composed message.
  940.  * @param object $message 
  941.  * @param object $composeMessage 
  942.  * @param integer $passed_id 
  943.  * @param mixed $entities 
  944.  * @param mixed $imapConnection 
  945.  * @return object 
  946.  */
  947. function getAttachments($message, &$composeMessage, $passed_id, $entities, $imapConnection) {
  948.     global $attachment_dir, $username, $data_dir, $squirrelmail_language, $languages;
  949.     $hashed_attachment_dir = getHashedDir($username, $attachment_dir);
  950.     if (!count($message->entities) ||
  951.             ($message->type0 == 'message' && $message->type1 == 'rfc822')) {
  952.         if ( !in_array($message->entity_id, $entities) && $message->entity_id) {
  953.             switch ($message->type0) {
  954.                 case 'message':
  955.                     if ($message->type1 == 'rfc822') {
  956.                         $filename = $message->rfc822_header->subject;
  957.                         if ($filename == "") {
  958.                             $filename = "untitled-".$message->entity_id;
  959.                         }
  960.                         $filename .= '.msg';
  961.                     } else {
  962.                         $filename = $message->getFilename();
  963.                     }
  964.                     break;
  965.                 default:
  966.                     if (!$message->mime_header) { /* temporary hack */
  967.                         $message->mime_header = $message->header;
  968.                     }
  969.                     $filename = $message->getFilename();
  970.                     break;
  971.             }
  972.             $filename = str_replace('&#32;', ' ', decodeHeader($filename));
  973.             if (isset($languages[$squirrelmail_language]['XTRA_CODE']) &&
  974.                     function_exists($languages[$squirrelmail_language]['XTRA_CODE'] . '_encode')) {
  975.                 $filename =  call_user_func($languages[$squirrelmail_language]['XTRA_CODE'] . '_encode', $filename);
  976.             }
  977.             $localfilename = GenerateRandomString(32, '', 7);
  978.             $full_localfilename = "$hashed_attachment_dir/$localfilename";
  979.             while (file_exists($full_localfilename)) {
  980.                 $localfilename = GenerateRandomString(32, '', 7);
  981.                 $full_localfilename = "$hashed_attachment_dir/$localfilename";
  982.             }
  983.             $message->att_local_name = $full_localfilename;
  984.  
  985.             $composeMessage->initAttachment($message->type0.'/'.$message->type1,$filename,
  986.                     $full_localfilename);
  987.  
  988.             /* Write Attachment to file */
  989.             $fp = fopen ("$hashed_attachment_dir/$localfilename", 'wb');
  990.             mime_print_body_lines ($imapConnection, $passed_id, $message->entity_id, $message->header->encoding, $fp);
  991.             fclose ($fp);
  992.         }
  993.     } else {
  994.         for ($i=0, $entCount=count($message->entities); $i<$entCount;$i++) {
  995.             $composeMessage=getAttachments($message->entities[$i], $composeMessage, $passed_id, $entities, $imapConnection);
  996.         }
  997.     }
  998.     return $composeMessage;
  999. }
  1000.  
  1001. function getMessage_RFC822_Attachment($message, $composeMessage, $passed_id,
  1002.         $passed_ent_id='', $imapConnection) {
  1003.     global $attachment_dir, $username, $data_dir;
  1004.     $hashed_attachment_dir = getHashedDir($username, $attachment_dir);
  1005.     if (!$passed_ent_id) {
  1006.         $body_a = sqimap_run_command($imapConnection,
  1007.                 'FETCH '.$passed_id.' RFC822',
  1008.                 TRUE, $response, $readmessage,
  1009.                 TRUE);
  1010.     } else {
  1011.         $body_a = sqimap_run_command($imapConnection,
  1012.                 'FETCH '.$passed_id.' BODY['.$passed_ent_id.']',
  1013.                 TRUE, $response, $readmessage, TRUE);
  1014.         $message = $message->parent;
  1015.     }
  1016.     if ($response == 'OK') {
  1017.         $subject = encodeHeader($message->rfc822_header->subject);
  1018.         array_shift($body_a);
  1019.         array_pop($body_a);
  1020.         $body = implode('', $body_a) . "\r\n";
  1021.  
  1022.         $localfilename = GenerateRandomString(32, 'FILE', 7);
  1023.         $full_localfilename = "$hashed_attachment_dir/$localfilename";
  1024.  
  1025.         $fp = fopen($full_localfilename, 'w');
  1026.         fwrite ($fp, $body);
  1027.         fclose($fp);
  1028.         $composeMessage->initAttachment('message/rfc822',$subject.'.msg',
  1029.                 $full_localfilename);
  1030.     }
  1031.     return $composeMessage;
  1032. }
  1033.  
  1034. function showInputForm ($session, $values=false) {
  1035.     global $send_to, $send_to_cc, $body, $startMessage, $action,
  1036.         $color, $use_signature, $signature, $prefix_sig,
  1037.         $editor_size, $editor_height, $subject, $newmail,
  1038.         $use_javascript_addr_book, $send_to_bcc, $passed_id, $mailbox,
  1039.         $from_htmladdr_search, $location_of_buttons, $attachment_dir,
  1040.         $username, $data_dir, $identity, $idents, $delete_draft,
  1041.         $mailprio, $compose_new_win, $saved_draft, $mail_sent, $sig_first,
  1042.         $compose_messages, $composesession, $default_charset,
  1043.         $compose_onsubmit, $oTemplate, $oErrorHandler;
  1044.  
  1045.     if (checkForJavascript()) {
  1046.         $onfocus = ' onfocus="alreadyFocused=true;"';
  1047.         $onfocus_array = array('onfocus' => 'alreadyFocused=true;');
  1048.     }
  1049.     else {
  1050.         $onfocus = '';
  1051.         $onfocus_array = array();
  1052.     }
  1053.  
  1054.     $composeMessage = $compose_messages[$session];
  1055.     if ($values) {
  1056.         $send_to = $values['send_to'];
  1057.         $send_to_cc = $values['send_to_cc'];
  1058.         $send_to_bcc = $values['send_to_bcc'];
  1059.         $subject = $values['subject'];
  1060.         $mailprio = $values['mailprio'];
  1061.         $body = $values['body'];
  1062.         $identity = (int) $values['identity'];
  1063.     } else {
  1064.         $send_to = decodeHeader($send_to, true, false);
  1065.         $send_to_cc = decodeHeader($send_to_cc, true, false);
  1066.         $send_to_bcc = decodeHeader($send_to_bcc, true, false);
  1067.     }
  1068.  
  1069.     if ($use_javascript_addr_book) {
  1070.         echo "\n". '<script type="text/javascript">'."\n<!--\n" .
  1071.             'function open_abook() { ' . "\n" .
  1072.             '  var nwin = window.open("addrbook_popup.php","abookpopup",' .
  1073.             '"width=670,height=300,resizable=yes,scrollbars=yes");' . "\n" .
  1074.             '  if((!nwin.opener) && (document.windows != null))' . "\n" .
  1075.             '    nwin.opener = document.windows;' . "\n" .
  1076.             "}\n" .
  1077.             "// -->\n</script>\n\n";
  1078.     }
  1079.  
  1080.     echo "\n" . '<form name="compose" action="compose.php" method="post" ' .
  1081.         'enctype="multipart/form-data"';
  1082.  
  1083.     $compose_onsubmit = array();
  1084.     do_hook('compose_form');
  1085.  
  1086.     // Plugins that use compose_form hook can add an array entry
  1087.     // to the globally scoped $compose_onsubmit; we add them up
  1088.     // here and format the form tag's full onsubmit handler.
  1089.     // Each plugin should use "return false" if they need to
  1090.     // stop form submission but otherwise should NOT use "return
  1091.     // true" to give other plugins the chance to do what they need
  1092.     // to do; SquirrelMail itself will add the final "return true".
  1093.     // Onsubmit text is enclosed inside of double quotes, so plugins
  1094.     // need to quote accordingly.
  1095.     if (checkForJavascript()) {
  1096.         $onsubmit_text = ' onsubmit="';
  1097.         if (empty($compose_onsubmit))
  1098.             $compose_onsubmit = array();
  1099.         else if (!is_array($compose_onsubmit))
  1100.             $compose_onsubmit = array($compose_onsubmit);
  1101.  
  1102.         foreach ($compose_onsubmit as $text) {
  1103.             $text = trim($text);
  1104.             if (substr($text, -1) != ';' && substr($text, -1) != '}')
  1105.                 $text .= '; ';
  1106.             $onsubmit_text .= $text;
  1107.         }
  1108.  
  1109.         echo $onsubmit_text . ' return true;"';
  1110.     }
  1111.  
  1112.  
  1113.     echo ">\n";
  1114.  
  1115.     echo addHidden('startMessage', $startMessage);
  1116.  
  1117.     if ($action == 'draft') {
  1118.         echo addHidden('delete_draft', $passed_id);
  1119.     }
  1120.     if (isset($delete_draft)) {
  1121.         echo addHidden('delete_draft', $delete_draft);
  1122.     }
  1123.     if (isset($session)) {
  1124.         echo addHidden('session', $session);
  1125.     }
  1126.  
  1127.     if (isset($passed_id)) {
  1128.         echo addHidden('passed_id', $passed_id);
  1129.     }
  1130.  
  1131.     if ($saved_draft == 'yes') {
  1132.         $oTemplate->assign('note', _("Draft Saved"));
  1133.         $oTemplate->display('note.tpl');
  1134.     }
  1135.     if ($mail_sent == 'yes') {
  1136.         $oTemplate->assign('note', _("Your message has been sent."));
  1137.         $oTemplate->display('note.tpl');
  1138.     }
  1139.     if ($compose_new_win == '1') {
  1140.         $oTemplate->display('compose_newwin_close.tpl');
  1141.     }
  1142.     
  1143.     if ($location_of_buttons == 'top') {
  1144.         showComposeButtonRow();
  1145.     }
  1146.  
  1147.     $identities = array();
  1148.     if (count($idents) > 1) {
  1149.         reset($idents);
  1150.         foreach($idents as $id => $data) {
  1151.             $identities[$id] = $data['full_name'].' &lt;'.$data['email_address'].'&gt;';
  1152.         }
  1153.     }
  1154.     
  1155.     $oTemplate->assign('identities', $identities);
  1156.     $oTemplate->assign('identity_def', $identity);
  1157.     $oTemplate->assign('input_onfocus', 'onfocus="'.join(' ', $onfocus_array).'"');
  1158.     
  1159.     $oTemplate->assign('to', htmlspecialchars($send_to));
  1160.     $oTemplate->assign('cc', htmlspecialchars($send_to_cc));
  1161.     $oTemplate->assign('bcc', htmlspecialchars($send_to_bcc));
  1162.     $oTemplate->assign('subject', htmlspecialchars($subject));
  1163.         
  1164.     $oTemplate->display('compose_header.tpl');
  1165.  
  1166.     if ($location_of_buttons == 'between') {
  1167.         showComposeButtonRow();
  1168.     }
  1169.  
  1170.     $body_str = '';
  1171.     if ($use_signature == true && $newmail == true && !isset($from_htmladdr_search)) {
  1172.         $signature = $idents[$identity]['signature'];
  1173.  
  1174.         if ($sig_first == '1') {
  1175.             /*
  1176.              * FIXME: test is specific to ja_JP translation implementation.
  1177.              * This test might apply incorrect conversion to other translations, but
  1178.              * use of 7bit iso-2022-jp charset in other translations might have other
  1179.              * issues too.
  1180.              */
  1181.             if ($default_charset == 'iso-2022-jp') {
  1182.                 $body_str = "\n\n".($prefix_sig==true? "-- \n":'').mb_convert_encoding($signature, 'EUC-JP');
  1183.             } else {
  1184.                 $body_str = "\n\n".($prefix_sig==true? "-- \n":'').decodeHeader($signature,false,false);
  1185.             }
  1186.             $body_str .= "\n\n".htmlspecialchars(decodeHeader($body,false,false));
  1187.         } else {
  1188.             $body_str = "\n\n".htmlspecialchars(decodeHeader($body,false,false));
  1189.             // FIXME: test is specific to ja_JP translation implementation. See above comments.
  1190.             if ($default_charset == 'iso-2022-jp') {
  1191.                 $body_str .= "\n\n".($prefix_sig==true? "-- \n":'').mb_convert_encoding($signature, 'EUC-JP');
  1192.             } else {
  1193.                 $body_str .= "\n\n".($prefix_sig==true? "-- \n":'').decodeHeader($signature,false,false);
  1194.             }
  1195.         }
  1196.     } else {
  1197.         $body_str = htmlspecialchars(decodeHeader($body,false,false));
  1198.     }
  1199.  
  1200.     $oTemplate->assign('editor_width', (int)$editor_size);
  1201.     $oTemplate->assign('editor_height', (int)$editor_height);
  1202.     $oTemplate->assign('input_onfocus', 'onfocus="'.join(' ', $onfocus_array).'"');
  1203.     $oTemplate->assign('body', $body_str);
  1204.     $oTemplate->assign('show_bottom_send', $location_of_buttons!='bottom');
  1205.     
  1206.     $oTemplate->display ('compose_body.tpl');
  1207.     
  1208.     if ($location_of_buttons == 'bottom') {
  1209.         showComposeButtonRow();
  1210.     }
  1211.  
  1212.     /* This code is for attachments */
  1213.     if ((bool) ini_get('file_uploads')) {
  1214.  
  1215.         /* Calculate the max size for an uploaded file.
  1216.          * This is advisory for the user because we can't actually prevent
  1217.          * people to upload too large files. */
  1218.         $sizes = array();
  1219.         /* php.ini vars which influence the max for uploads */
  1220.         $configvars = array('post_max_size', 'memory_limit', 'upload_max_filesize');
  1221.         foreach($configvars as $var) {
  1222.             /* skip 0 or empty values, and -1 which means 'unlimited' */
  1223.             if( $size = getByteSize(ini_get($var)) ) {
  1224.                 if ( $size != '-1' ) {
  1225.                     $sizes[] = $size;
  1226.                 }
  1227.             }
  1228.         }
  1229.  
  1230.         $attach = array();
  1231.         if ($composeMessage->entities) {
  1232.             foreach ($composeMessage->entities as $key => $attachment) {
  1233.                 $attached_file = $attachment->att_local_name;
  1234.                 if ($attachment->att_local_name || $attachment->body_part) {
  1235.                     $attached_filename = decodeHeader($attachment->mime_header->getParameter('name'));
  1236.                     $type = $attachment->mime_header->type0.'/'.
  1237.                         $attachment->mime_header->type1;
  1238.     
  1239.                     $a = array();
  1240.                     $a['Key'] = $key;
  1241.                     $a['FileName'] = $attached_filename;
  1242.                     $a['ContentType'] = $type;
  1243.                     $a['Size'] = filesize($attached_file);
  1244.                     $attach[$key] = $a;
  1245.                 }
  1246.             }
  1247.         }
  1248.     
  1249.         $max = min($sizes);
  1250.         $oTemplate->assign('max_file_size', empty($max) ? -1 : $max);
  1251.         $oTemplate->assign('attachments', $attach);
  1252.         
  1253.         $oTemplate->display('compose_attachments.tpl');
  1254.     } // End of file_uploads if-block
  1255.     /* End of attachment code */
  1256.  
  1257.     echo addHidden('username', $username).
  1258.          addHidden('smaction', $action).
  1259.          addHidden('mailbox', $mailbox);
  1260.     /*
  1261.        store the complete ComposeMessages array in a hidden input value
  1262.        so we can restore them in case of a session timeout.
  1263.      */
  1264.     sqgetGlobalVar('QUERY_STRING', $queryString, SQ_SERVER);
  1265.     echo addHidden('restoremessages', serialize($compose_messages)).
  1266.         addHidden('composesession', $composesession).
  1267.         addHidden('querystring', $queryString).
  1268.         "</form>\n";
  1269.     if (!(bool) ini_get('file_uploads')) {
  1270.         /* File uploads are off, so we didn't show that part of the form.
  1271.            To avoid bogus bug reports, tell the user why. */
  1272.         echo '<p style="text-align:center">'
  1273.             . _("Because PHP file uploads are turned off, you can not attach files to this message. Please see your system administrator for details.")
  1274.             . "</p>\r\n";
  1275.     }
  1276.  
  1277.     do_hook('compose_bottom');
  1278.  
  1279.     if ($compose_new_win=='1') {
  1280.         $oTemplate->display('compose_newwin_close.tpl');
  1281.     }
  1282.     
  1283.     $oErrorHandler->setDelayedErrors(false);
  1284.     $oTemplate->display('footer.tpl');
  1285. }
  1286.  
  1287.  
  1288. function showComposeButtonRow() {
  1289.     global $use_javascript_addr_book, $save_as_draft,
  1290.         $default_use_priority, $mailprio, $default_use_mdn,
  1291.         $request_mdn, $request_dr,
  1292.         $data_dir, $username;
  1293.  
  1294.     global $oTemplate, $buffer_hook;
  1295.     
  1296.     if ($default_use_priority) {    
  1297.         $priorities = array('1'=>_("High"), '3'=>_("Normal"), '5'=>_("Low"));
  1298.         $priority = isset($mailprio) ? $mailprio : 3;
  1299.     } else {
  1300.         $priorities = array();
  1301.         $priority = NULL;
  1302.     }
  1303.     
  1304.     $mdn_user_support=getPref($data_dir, $username, 'mdn_user_support',$default_use_mdn);
  1305.  
  1306.     if ($use_javascript_addr_book) {
  1307.         $addr_book = "         <script type=\"text/javascript\"><!--\n document.write(\"".
  1308.             "            <input type=button value=\\\""._("Addresses").
  1309.             "\\\" onclick=\\\"javascript:open_abook();\\\" />\");".
  1310.             "            // --></script><noscript>\n".
  1311.             '            <input type="submit" name="html_addr_search" value="'.
  1312.             _("Addresses").'" />'.
  1313.             "         </noscript>\n";
  1314.     } else {
  1315.         $addr_book = '         <input type="submit" name="html_addr_search" value="'.
  1316.             _("Addresses").'" />' . "\n";
  1317.     }
  1318.  
  1319.     $oTemplate->assign('allow_priority', $default_use_priority==1);
  1320.     $oTemplate->assign('priority_list', $priorities);
  1321.     $oTemplate->assign('current_priority', $priority);
  1322.     
  1323.     $oTemplate->assign('notifications_enabled', $mdn_user_support==1);
  1324.     $oTemplate->assign('read_receipt', $request_mdn=='1');
  1325.     $oTemplate->assign('delivery_receipt', $request_dr=='1');
  1326.     
  1327.     $oTemplate->assign('drafts_enabled', $save_as_draft);
  1328.     $oTemplate->assign('address_book_button', $addr_book);
  1329.  
  1330.     $oTemplate->display('compose_buttons.tpl');
  1331. }
  1332.  
  1333. function checkInput ($show) {
  1334.     /*
  1335.      * I implemented the $show variable because the error messages
  1336.      * were getting sent before the page header.  So, I check once
  1337.      * using $show=false, and then when i'm ready to display the error
  1338.      * message, show=true
  1339.      */
  1340.     global $send_to, $send_to_bcc;
  1341.  
  1342.     if ($send_to == '' && $send_to_bcc == '') {
  1343.         if ($show) {
  1344.             plain_error_message(_("You have not filled in the \"To:\" field."));
  1345.         }
  1346.         return false;
  1347.     }
  1348.     return true;
  1349. } /* function checkInput() */
  1350.  
  1351.  
  1352. /* True if FAILURE */
  1353. function saveAttachedFiles($session) {
  1354.     global $_FILES, $attachment_dir, $username,
  1355.         $data_dir, $compose_messages;
  1356.  
  1357.     /* get out of here if no file was attached at all */
  1358.     if (! is_uploaded_file($_FILES['attachfile']['tmp_name']) ) {
  1359.         return true;
  1360.     }
  1361.  
  1362.     $hashed_attachment_dir = getHashedDir($username, $attachment_dir);
  1363.     $localfilename = GenerateRandomString(32, '', 7);
  1364.     $full_localfilename = "$hashed_attachment_dir/$localfilename";
  1365.     while (file_exists($full_localfilename)) {
  1366.         $localfilename = GenerateRandomString(32, '', 7);
  1367.         $full_localfilename = "$hashed_attachment_dir/$localfilename";
  1368.     }
  1369.  
  1370.     // m_u_f works better with restricted PHP installs (safe_mode, open_basedir),
  1371.     // if that doesn't work, try a simple rename.
  1372.     if (!@move_uploaded_file($_FILES['attachfile']['tmp_name'],$full_localfilename)) {
  1373.         if (!@rename($_FILES['attachfile']['tmp_name'], $full_localfilename)) {
  1374.             return true;
  1375.         }
  1376.     }
  1377.     $message = $compose_messages[$session];
  1378.     $type = strtolower($_FILES['attachfile']['type']);
  1379.     $name = $_FILES['attachfile']['name'];
  1380.     $message->initAttachment($type, $name, $full_localfilename);
  1381.     $compose_messages[$session] = $message;
  1382.     sqsession_register($compose_messages , 'compose_messages');
  1383. }
  1384.  
  1385. /* parse values like 8M and 2k into bytes */
  1386. function getByteSize($ini_size) {
  1387.  
  1388.     if(!$ini_size) {
  1389.         return FALSE;
  1390.     }
  1391.  
  1392.     $ini_size = trim($ini_size);
  1393.  
  1394.     // if there's some kind of letter at the end of the string we need to multiply.
  1395.     if(!is_numeric(substr($ini_size, -1))) {
  1396.  
  1397.         switch(strtoupper(substr($ini_size, -1))) {
  1398.             case 'G':
  1399.                 $bytesize = 1073741824;
  1400.                 break;
  1401.             case 'M':
  1402.                 $bytesize = 1048576;
  1403.                 break;
  1404.             case 'K':
  1405.                 $bytesize = 1024;
  1406.                 break;
  1407.         }
  1408.  
  1409.         return ($bytesize * (int)substr($ini_size, 0, -1));
  1410.     }
  1411.  
  1412.     return $ini_size;
  1413. }
  1414.  
  1415.  
  1416. /**
  1417.  * temporary function to make use of the deliver class.
  1418.  * In the future the responsible backend should be automaticly loaded
  1419.  * and conf.pl should show a list of available backends.
  1420.  * The message also should be constructed by the message class.
  1421.  */
  1422. function deliverMessage($composeMessage, $draft=false) {
  1423.     global $send_to, $send_to_cc, $send_to_bcc, $mailprio, $subject, $body,
  1424.         $username, $popuser, $usernamedata, $identity, $idents, $data_dir,
  1425.         $request_mdn, $request_dr, $default_charset, $color, $useSendmail,
  1426.         $domain, $action, $default_move_to_sent, $move_to_sent;
  1427.     global $imapServerAddress, $imapPort, $sent_folder, $key;
  1428.  
  1429.     $rfc822_header = $composeMessage->rfc822_header;
  1430.  
  1431.     $abook = addressbook_init(false, true);
  1432.     $rfc822_header->to = $rfc822_header->parseAddress($send_to,true, array(), '', $domain, array(&$abook,'lookup'));
  1433.     $rfc822_header->cc = $rfc822_header->parseAddress($send_to_cc,true,array(), '',$domain, array(&$abook,'lookup'));
  1434.     $rfc822_header->bcc = $rfc822_header->parseAddress($send_to_bcc,true, array(), '',$domain, array(&$abook,'lookup'));
  1435.     $rfc822_header->priority = $mailprio;
  1436.     $rfc822_header->subject = $subject;
  1437.  
  1438.     $special_encoding='';
  1439.     if (strtolower($default_charset) == 'iso-2022-jp') {
  1440.         if (mb_detect_encoding($body) == 'ASCII') {
  1441.             $special_encoding = '8bit';
  1442.         } else {
  1443.             $body = mb_convert_encoding($body, 'JIS');
  1444.             $special_encoding = '7bit';
  1445.         }
  1446.     }
  1447.     $composeMessage->setBody($body);
  1448.  
  1449.     if (ereg("^([^@%/]+)[@%/](.+)$", $username, $usernamedata)) {
  1450.         $popuser = $usernamedata[1];
  1451.         $domain  = $usernamedata[2];
  1452.         unset($usernamedata);
  1453.     } else {
  1454.         $popuser = $username;
  1455.     }
  1456.     $reply_to = '';
  1457.     $from_mail = $idents[$identity]['email_address'];
  1458.     $full_name = $idents[$identity]['full_name'];
  1459.     $reply_to  = $idents[$identity]['reply_to'];
  1460.     if (!$from_mail) {
  1461.         $from_mail = "$popuser@$domain";
  1462.     }
  1463.     $rfc822_header->from = $rfc822_header->parseAddress($from_mail,true);
  1464.     if ($full_name) {
  1465.         $from = $rfc822_header->from[0];
  1466.         if (!$from->host) $from->host = $domain;
  1467.         $full_name_encoded = encodeHeader($full_name);
  1468.         if ($full_name_encoded != $full_name) {
  1469.             $from_addr = $full_name_encoded .' <'.$from->mailbox.'@'.$from->host.'>';
  1470.         } else {
  1471.             $from_addr = '"'.$full_name .'" <'.$from->mailbox.'@'.$from->host.'>';
  1472.         }
  1473.         $rfc822_header->from = $rfc822_header->parseAddress($from_addr,true);
  1474.     }
  1475.     if ($reply_to) {
  1476.         $rfc822_header->reply_to = $rfc822_header->parseAddress($reply_to,true);
  1477.     }
  1478.     /* Receipt: On Read */
  1479.     if (isset($request_mdn) && $request_mdn) {
  1480.         $rfc822_header->dnt = $rfc822_header->parseAddress($from_mail,true);
  1481.     } elseif (isset($rfc822_header->dnt)) {
  1482.         unset($rfc822_header->dnt);
  1483.     }
  1484.     
  1485.     /* Receipt: On Delivery */
  1486.     if (isset($request_dr) && $request_dr) {
  1487.         $rfc822_header->more_headers['Return-Receipt-To'] = $from_mail;
  1488.     } elseif (isset($rfc822_header->more_headers['Return-Receipt-To'])) {
  1489.         unset($rfc822_header->more_headers['Return-Receipt-To']);
  1490.     }
  1491.  
  1492.     /* multipart messages */
  1493.     if (count($composeMessage->entities)) {
  1494.         $message_body = new Message();
  1495.         $message_body->body_part = $composeMessage->body_part;
  1496.         $composeMessage->body_part = '';
  1497.         $mime_header = new MessageHeader;
  1498.         $mime_header->type0 = 'text';
  1499.         $mime_header->type1 = 'plain';
  1500.         if ($special_encoding) {
  1501.             $mime_header->encoding = $special_encoding;
  1502.         } else {
  1503.             $mime_header->encoding = '8bit';
  1504.         }
  1505.         if ($default_charset) {
  1506.             $mime_header->parameters['charset'] = $default_charset;
  1507.         }
  1508.         $message_body->mime_header = $mime_header;
  1509.         array_unshift($composeMessage->entities, $message_body);
  1510.         $content_type = new ContentType('multipart/mixed');
  1511.     } else {
  1512.         $content_type = new ContentType('text/plain');
  1513.         if ($special_encoding) {
  1514.             $rfc822_header->encoding = $special_encoding;
  1515.         } else {
  1516.             $rfc822_header->encoding = '8bit';
  1517.         }
  1518.         if ($default_charset) {
  1519.             $content_type->properties['charset']=$default_charset;
  1520.         }
  1521.     }
  1522.  
  1523.     $rfc822_header->content_type = $content_type;
  1524.     $composeMessage->rfc822_header = $rfc822_header;
  1525.     
  1526.     /* Here you can modify the message structure just before we hand
  1527.        it over to deliver */
  1528.     $hookReturn = do_hook('compose_send', $composeMessage);
  1529.     /* Get any changes made by plugins to $composeMessage. */
  1530.     if ( is_object($hookReturn[1]) ) {
  1531.         $composeMessage = $hookReturn[1];
  1532.     }
  1533.  
  1534.     if (!$useSendmail && !$draft) {
  1535.         require_once(SM_PATH . 'class/deliver/Deliver_SMTP.class.php');
  1536.         $deliver = new Deliver_SMTP();
  1537.         global $smtpServerAddress, $smtpPort, $pop_before_smtp;
  1538.  
  1539.         $authPop = (isset($pop_before_smtp) && $pop_before_smtp) ? true : false;
  1540.         get_smtp_user($user, $pass);
  1541.         $stream = $deliver->initStream($composeMessage,$domain,0,
  1542.                 $smtpServerAddress, $smtpPort, $user, $pass, $authPop);
  1543.     } elseif (!$draft) {
  1544.         require_once(SM_PATH . 'class/deliver/Deliver_SendMail.class.php');
  1545.         global $sendmail_path, $sendmail_args;
  1546.         // Check for outdated configuration
  1547.         if (!isset($sendmail_args)) {
  1548.             if ($sendmail_path=='/var/qmail/bin/qmail-inject') {
  1549.                 $sendmail_args = '';
  1550.             } else {
  1551.                 $sendmail_args = '-i -t';
  1552.             }
  1553.         }
  1554.         $deliver = new Deliver_SendMail(array('sendmail_args'=>$sendmail_args));
  1555.         $stream = $deliver->initStream($composeMessage,$sendmail_path);
  1556.     } elseif ($draft) {
  1557.         global $draft_folder;
  1558.         require_once(SM_PATH . 'class/deliver/Deliver_IMAP.class.php');
  1559.         $imap_stream = sqimap_login($username, false, $imapServerAddress,
  1560.                 $imapPort, 0);
  1561.         if (sqimap_mailbox_exists ($imap_stream, $draft_folder)) {
  1562.             require_once(SM_PATH . 'class/deliver/Deliver_IMAP.class.php');
  1563.             $imap_deliver = new Deliver_IMAP();
  1564.             $length = $imap_deliver->mail($composeMessage);
  1565.             sqimap_append ($imap_stream, $draft_folder, $length);
  1566.             $imap_deliver->mail($composeMessage, $imap_stream);
  1567.             sqimap_append_done ($imap_stream, $draft_folder);
  1568.             sqimap_logout($imap_stream);
  1569.             unset ($imap_deliver);
  1570.             $composeMessage->purgeAttachments();
  1571.             return $length;
  1572.         } else {
  1573.             $msg  = '<br />'.sprintf(_("Error: Draft folder %s does not exist."), htmlspecialchars($draft_folder));
  1574.             plain_error_message($msg);
  1575.             return false;
  1576.         }
  1577.     }
  1578.     $success = false;
  1579.     if ($stream) {
  1580.         $length = $deliver->mail($composeMessage, $stream);
  1581.         $success = $deliver->finalizeStream($stream);
  1582.     }
  1583.     if (!$success) {
  1584.         // $deliver->dlv_server_msg is not always server's reply
  1585.         $msg  = $deliver->dlv_msg;
  1586.         if (!empty($deliver->dlv_server_msg)) {
  1587.             // add 'server replied' part only when it is not empty.
  1588.             // Delivery error can be generated by delivery class itself
  1589.             $msg.='<br />' .
  1590.                 _("Server replied:") . ' ' . $deliver->dlv_ret_nr . ' ' .
  1591.                 nl2br(htmlspecialchars($deliver->dlv_server_msg));
  1592.         }
  1593.         plain_error_message($msg);
  1594.     } else {
  1595.         unset ($deliver);
  1596.         $move_to_sent = getPref($data_dir,$username,'move_to_sent');
  1597.         $imap_stream = sqimap_login($username, false, $imapServerAddress, $imapPort, 0);
  1598.  
  1599.         /* Move to sent code */
  1600.         if (isset($default_move_to_sent) && ($default_move_to_sent != 0)) {
  1601.             $svr_allow_sent = true;
  1602.         } else {
  1603.             $svr_allow_sent = false;
  1604.         }
  1605.  
  1606.         if (isset($sent_folder) && (($sent_folder != '') || ($sent_folder != 'none'))
  1607.                 && sqimap_mailbox_exists( $imap_stream, $sent_folder)) {
  1608.             $fld_sent = true;
  1609.         } else {
  1610.             $fld_sent = false;
  1611.         }
  1612.  
  1613.         if ((isset($move_to_sent) && ($move_to_sent != 0)) || (!isset($move_to_sent))) {
  1614.             $lcl_allow_sent = true;
  1615.         } else {
  1616.             $lcl_allow_sent = false;
  1617.         }
  1618.  
  1619.         if (($fld_sent && $svr_allow_sent && !$lcl_allow_sent) || ($fld_sent && $lcl_allow_sent)) {
  1620.             global $passed_id, $mailbox, $action;
  1621.             if ($action == 'reply' || $action == 'reply_all') {
  1622.                 $save_reply_with_orig=getPref($data_dir,$username,'save_reply_with_orig');
  1623.                 if ($save_reply_with_orig) {
  1624.                     $sent_folder = $mailbox;
  1625.                 }
  1626.             }
  1627.             sqimap_append ($imap_stream, $sent_folder, $length);
  1628.             require_once(SM_PATH . 'class/deliver/Deliver_IMAP.class.php');
  1629.             $imap_deliver = new Deliver_IMAP();
  1630.             $imap_deliver->mail($composeMessage, $imap_stream);
  1631.             sqimap_append_done ($imap_stream, $sent_folder);
  1632.             unset ($imap_deliver);
  1633.         }
  1634.  
  1635.         global $passed_id, $mailbox, $action, $what, $iAccount,$startMessage;
  1636.  
  1637.         $composeMessage->purgeAttachments();
  1638.         if ($action == 'reply' || $action == 'reply_all') {
  1639.             require(SM_PATH . 'functions/mailbox_display.php');
  1640.             $aMailbox = sqm_api_mailbox_select($imap_stream, $iAccount, $mailbox,array('setindex' => $what, 'offset' => $startMessage),array());
  1641.             // check if we are allowed to set the \\Answered flag
  1642.             if (in_array('\\answered',$aMailbox['PERMANENTFLAGS'], true)) {
  1643.                 $aUpdatedMsgs = sqimap_toggle_flag($imap_stream, array($passed_id), '\\Answered', true, false);
  1644.                 if (isset($aUpdatedMsgs[$passed_id]['FLAGS'])) {
  1645.                     /**
  1646.                      * Only update the cached headers if the header is
  1647.                      * cached.
  1648.                      */
  1649.                     if (isset($aMailbox['MSG_HEADERS'][$passed_id])) {
  1650.                         $aMailbox['MSG_HEADERS'][$passed_id]['FLAGS'] = $aMsg['FLAGS'];
  1651.                     }
  1652.                 }
  1653.             }
  1654.             /**
  1655.              * Write mailbox with updated seen flag information back to cache.
  1656.              */
  1657.             $mailbox_cache[$iAccount.'_'.$aMailbox['NAME']] = $aMailbox;
  1658.             sqsession_register($mailbox_cache,'mailbox_cache');
  1659.         }
  1660.         sqimap_logout($imap_stream);
  1661.     }
  1662.     return $success;
  1663. }
  1664. ?>

Documentation generated on Sat, 07 Oct 2006 16:09:39 +0300 by phpDocumentor 1.3.0RC6