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'$tempSQ_POST) ) {
  90.     $html_addr_search_done 'Use Addresses';
  91. }
  92.  
  93. /** GET VARS */
  94. sqgetGlobalVar('attachedmessages'$attachedmessagesSQ_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 -'-'.
  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_postSQ_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($sessionfalse);
  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($composeMessagetrue)) {
  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($usernamefalse$imapServerAddress$imapPortfalse);
  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_drafttrue);
  384.             if ($auto_expunge{
  385.                 sqimap_mailbox_expunge($imap_stream$draft_foldertrue);
  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($usernamefalse$imapServerAddress$imapPortfalse);
  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_drafttrue);
  483.             if ($auto_expunge{
  484.                 sqimap_mailbox_expunge($imap_stream$draft_foldertrue);
  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($k01== 'T'{
  541.                 if ($send_to{
  542.                     $send_to .= ', ';
  543.                 }
  544.                 $send_to .= $v;
  545.             }
  546.             elseif (substr($k01== 'C'{
  547.                 if ($send_to_cc{
  548.                     $send_to_cc .= ', ';
  549.                 }
  550.                 $send_to_cc .= $v;
  551.             }
  552.             elseif (substr($k01== '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)04!= 'fwd:'&&
  671.             (substr(strtolower($subject)05!= '[fwd:'&&
  672.             (substr(strtolower($subject)06!= '[ 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($usernamefalse$imapServerAddress,
  699.                 $imapPort0);
  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($idents1{
  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($identities0{
  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)03!= '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$readmessageTRUE);
  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_totruefalse);
  1065.         $send_to_cc decodeHeader($send_to_cctruefalse);
  1066.         $send_to_bcc decodeHeader($send_to_bcctruefalse);
  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($idents1{
  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? -$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'$queryStringSQ_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_size0-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(falsetrue);
  1432.     $rfc822_header->to $rfc822_header->parseAddress($send_to,truearray()''$domainarray(&$abook,'lookup'));
  1433.     $rfc822_header->cc $rfc822_header->parseAddress($send_to_cc,true,array()'',$domainarray(&$abook,'lookup'));
  1434.     $rfc822_header->bcc $rfc822_header->parseAddress($send_to_bcc,truearray()'',$domainarray(&$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_smtptrue 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($usernamefalse$imapServerAddress,
  1560.                 $imapPort0);
  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($usernamefalse$imapServerAddress$imapPort0);
  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_streamarray($passed_id)'\\Answered'truefalse);
  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