svncommit
2007-10-15 97a656643866f16289264954be961aa3f314ac20
commit | author | age
4e17e6 1 <?php
T 2
3 /*
4  +-----------------------------------------------------------------------+
5  | program/steps/mail/compose.inc                                        |
6  |                                                                       |
7  | This file is part of the RoundCube Webmail client                     |
5349b7 8  | Copyright (C) 2005-2007, RoundCube Dev. - Switzerland                 |
30233b 9  | Licensed under the GNU GPL                                            |
4e17e6 10  |                                                                       |
T 11  | PURPOSE:                                                              |
12  |   Compose a new mail message with all headers and attachments         |
13  |                                                                       |
14  +-----------------------------------------------------------------------+
15  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
16  +-----------------------------------------------------------------------+
17
18  $Id$
19
20 */
21
22 require_once('Mail/mimeDecode.php');
dd792e 23 require_once('lib/html2text.inc');
8d4bcd 24
T 25 // define constants for message compose mode
26 define('RCUBE_COMPOSE_REPLY', 0x0106);
27 define('RCUBE_COMPOSE_FORWARD', 0x0107);
28 define('RCUBE_COMPOSE_DRAFT', 0x0108);
29
4e17e6 30
a894ba 31 // remove an attachment
8d0758 32 if ($_action=='remove-attachment' && preg_match('/^rcmfile([0-9]+)$/', $_POST['_file'], $regs))
a894ba 33   {
aade7b 34   $id = $regs[1];
T 35   if (is_array($_SESSION['compose']['attachments'][$id]))
36     {
37     @unlink($_SESSION['compose']['attachments'][$id]['path']);
38     $_SESSION['compose']['attachments'][$id] = NULL;
f11541 39     $OUTPUT->command('remove_from_attachment_list', "rcmfile$id");
T 40     $OUTPUT->send();
aade7b 41     exit;
T 42     }
a894ba 43   }
aade7b 44
f0f98f 45
S 46 $MESSAGE_FORM = NULL;
8d4bcd 47 $MESSAGE = NULL;
f0f98f 48
86df15 49 // Nothing below is called during message composition, only at "new/forward/reply/draft" initialization or
T 50 // if a compose-ID is given (i.e. when the compose step is opened in a new window/tab).
51 // Since there are many ways to leave the compose page improperly, it seems necessary to clean-up an old
f0f98f 52 // compose when a "new/forward/reply/draft" is called - otherwise the old session attachments will appear
S 53
86df15 54 if (!is_array($_SESSION['compose']) || $_SESSION['compose']['id'] != get_input_value('_id', RCUBE_INPUT_GET))
T 55   {
56   rcmail_compose_cleanup();
57   $_SESSION['compose'] = array('id' => uniqid(rand()));
58   }
4e17e6 59
10a699 60 // add some labels to client
a0109c 61 rcube_add_label('nosubject', 'norecipientwarning', 'nosubjectwarning', 'nobodywarning', 'notsentwarning', 'savingmessage', 'sendingmessage', 'messagesaved', 'converting');
10a699 62
d656f1 63 // add config parameter to client script
f11541 64 $OUTPUT->set_env('draft_autosave', !empty($CONFIG['drafts_mbox']) ? $CONFIG['draft_autosave'] : 0);
d656f1 65
10a699 66
8d4bcd 67 // get reference message and set compose mode
T 68 if ($msg_uid = get_input_value('_reply_uid', RCUBE_INPUT_GET))
69   $compose_mode = RCUBE_COMPOSE_REPLY;
70 else if ($msg_uid = get_input_value('_forward_uid', RCUBE_INPUT_GET))
71   $compose_mode = RCUBE_COMPOSE_FORWARD;
72 else if ($msg_uid = get_input_value('_draft_uid', RCUBE_INPUT_GET))
73   $compose_mode = RCUBE_COMPOSE_DRAFT;
74
75
76 if (!empty($msg_uid))
4e17e6 77   {
T 78   // similar as in program/steps/mail/show.inc
8d4bcd 79   $MESSAGE = array('UID' => $msg_uid);
T 80   $MESSAGE['headers'] = &$IMAP->get_headers($msg_uid);
81   $MESSAGE['structure'] = &$IMAP->get_structure($msg_uid);  
4e17e6 82   $MESSAGE['subject'] = $IMAP->decode_header($MESSAGE['headers']->subject);
8d4bcd 83   $MESSAGE['parts'] = $IMAP->get_mime_numbers($MESSAGE['structure']);
03ac21 84   
8d4bcd 85   if ($compose_mode == RCUBE_COMPOSE_REPLY)
4e17e6 86     {
8d4bcd 87     $_SESSION['compose']['reply_uid'] = $msg_uid;
T 88     $_SESSION['compose']['reply_msgid'] = $MESSAGE['headers']->messageID;
89     $_SESSION['compose']['references']  = $MESSAGE['headers']->reference;
90     $_SESSION['compose']['references'] .= !empty($MESSAGE['headers']->reference) ? ' ' : '';
91     $_SESSION['compose']['references'] .= $MESSAGE['headers']->messageID;
583f1c 92
8d4bcd 93     if (!empty($_GET['_all']))
T 94       $MESSAGE['reply_all'] = 1;
4e17e6 95     }
8d4bcd 96   else if ($compose_mode == RCUBE_COMPOSE_FORWARD)
4e17e6 97     {
8d4bcd 98     $_SESSION['compose']['forward_uid'] = $msg_uid;
4e17e6 99     }
8d4bcd 100   else if ($compose_mode == RCUBE_COMPOSE_DRAFT)
1966c5 101     {
8d4bcd 102     $_SESSION['compose']['draft_uid'] = $msg_uid;
1966c5 103     }
S 104
4e17e6 105   }
T 106
107 /****** compose mode functions ********/
108
109
110 function rcmail_compose_headers($attrib)
111   {
8d4bcd 112   global $IMAP, $MESSAGE, $DB, $compose_mode;
583f1c 113   static $sa_recipients = array();
4e17e6 114
T 115   list($form_start, $form_end) = get_form_tags($attrib);
116   
117   $out = '';
118   $part = strtolower($attrib['part']);
119   
120   switch ($part)
121     {
122     case 'from':
1cded8 123       return rcmail_compose_header_from($attrib);
4e17e6 124
T 125     case 'to':
126       $fname = '_to';
127       $header = 'to';
f11541 128       
T 129       // we have a set of recipients stored is session
130       if (($mailto_id = get_input_value('_mailto', RCUBE_INPUT_GET)) && $_SESSION['mailto'][$mailto_id])
131         $fvalue = $_SESSION['mailto'][$mailto_id];
597170 132       else if (!empty($_GET['_to']))
8d4bcd 133         $fvalue = get_input_value('_to', RCUBE_INPUT_GET);
4e17e6 134         
T 135     case 'cc':
136       if (!$fname)
137         {
138         $fname = '_cc';
583f1c 139         $header = 'cc';
4e17e6 140         }
T 141     case 'bcc':
142       if (!$fname)
462799 143         {
4e17e6 144         $fname = '_bcc';
462799 145         $header = 'bcc';
S 146         }
4e17e6 147         
bd4209 148       $allow_attrib = array('id', 'class', 'style', 'cols', 'rows', 'tabindex');
4e17e6 149       $field_type = 'textarea';            
T 150       break;
151
152     case 'replyto':
153     case 'reply-to':
154       $fname = '_replyto';
317219 155       $allow_attrib = array('id', 'class', 'style', 'size', 'tabindex');
4e17e6 156       $field_type = 'textfield';
T 157       break;
158     
159     }
1966c5 160  
597170 161   if ($fname && !empty($_POST[$fname]))
01c86f 162     $fvalue = get_input_value($fname, RCUBE_INPUT_POST, TRUE);
8d4bcd 163
T 164   else if ($header && $compose_mode == RCUBE_COMPOSE_REPLY)
4e17e6 165     {
T 166     // get recipent address(es) out of the message headers
8d4bcd 167     if ($header=='to' && !empty($MESSAGE['headers']->replyto))
03ac21 168       $fvalue = $MESSAGE['headers']->replyto;
58e360 169
8d4bcd 170     else if ($header=='to' && !empty($MESSAGE['headers']->from))
03ac21 171       $fvalue = $MESSAGE['headers']->from;
58e360 172
583f1c 173     // add recipent of original message if reply to all
8d4bcd 174     else if ($header=='cc' && !empty($MESSAGE['reply_all']))
583f1c 175       {
03ac21 176       if ($v = $MESSAGE['headers']->to)
8d4bcd 177         $fvalue .= $v;
583f1c 178
03ac21 179       if ($v = $MESSAGE['headers']->cc)
8d4bcd 180         $fvalue .= (!empty($fvalue) ? ', ' : '') . $v;
583f1c 181       }
T 182
4e17e6 183     // split recipients and put them back together in a unique way
583f1c 184     if (!empty($fvalue))
T 185       {
186       $to_addresses = $IMAP->decode_address_list($fvalue);
187       $fvalue = '';
188       foreach ($to_addresses as $addr_part)
189         {
3cf664 190         if (!empty($addr_part['mailto']) && !in_array($addr_part['mailto'], $sa_recipients) && (!$MESSAGE['FROM'] || !in_array($addr_part['mailto'], $MESSAGE['FROM'])))
583f1c 191           {
T 192           $fvalue .= (strlen($fvalue) ? ', ':'').$addr_part['string'];
193           $sa_recipients[] = $addr_part['mailto'];
194           }
195         }
196       }
4e17e6 197     }
8d4bcd 198   else if ($header && $compose_mode == RCUBE_COMPOSE_DRAFT)
1966c5 199     {
S 200     // get drafted headers
8d4bcd 201     if ($header=='to' && !empty($MESSAGE['headers']->to))
T 202       $fvalue = $IMAP->decode_header($MESSAGE['headers']->to);
1966c5 203
8d4bcd 204     if ($header=='cc' && !empty($MESSAGE['headers']->cc))
T 205       $fvalue = $IMAP->decode_header($MESSAGE['headers']->cc);
1966c5 206
8d4bcd 207     if ($header=='bcc' && !empty($MESSAGE['headers']->bcc))
T 208       $fvalue = $IMAP->decode_header($MESSAGE['headers']->bcc);
1966c5 209     }
583f1c 210
4e17e6 211         
T 212   if ($fname && $field_type)
213     {
214     // pass the following attributes to the form class
215     $field_attrib = array('name' => $fname);
216     foreach ($attrib as $attr => $value)
217       if (in_array($attr, $allow_attrib))
218         $field_attrib[$attr] = $value;
219
220     // create teaxtarea object
221     $input = new $field_type($field_attrib);
222     $out = $input->show($fvalue);    
223     }
224   
225   if ($form_start)
226     $out = $form_start.$out;
1966c5 227
4e17e6 228   return $out;  
T 229   }
230
231
1cded8 232
T 233 function rcmail_compose_header_from($attrib)
4e17e6 234   {
f11541 235   global $IMAP, $MESSAGE, $DB, $OUTPUT, $compose_mode;
1cded8 236     
T 237   // pass the following attributes to the form class
238   $field_attrib = array('name' => '_from');
239   foreach ($attrib as $attr => $value)
240     if (in_array($attr, array('id', 'class', 'style', 'size', 'tabindex')))
241       $field_attrib[$attr] = $value;
4e17e6 242
1cded8 243   // extract all recipients of the reply-message
T 244   $a_recipients = array();
8d4bcd 245   if ($compose_mode == RCUBE_COMPOSE_REPLY && is_object($MESSAGE['headers']))
1cded8 246     {
8d4bcd 247     $MESSAGE['FROM'] = array();
58e360 248
03ac21 249     $a_to = $IMAP->decode_address_list($MESSAGE['headers']->to);
1cded8 250     foreach ($a_to as $addr)
T 251       {
252       if (!empty($addr['mailto']))
253         $a_recipients[] = $addr['mailto'];
254       }
4e17e6 255
8d4bcd 256     if (!empty($MESSAGE['headers']->cc))
1cded8 257       {
8d4bcd 258       $a_cc = $IMAP->decode_address_list($MESSAGE['headers']->cc);
1cded8 259       foreach ($a_cc as $addr)
T 260         {
261         if (!empty($addr['mailto']))
262           $a_recipients[] = $addr['mailto'];
263         }
264       }
265     }
4e17e6 266
1cded8 267   // get this user's identities
a0109c 268   $sql_result = $DB->query("SELECT identity_id, name, email, signature, html_signature
1cded8 269                             FROM   ".get_table_name('identities')."
T 270                             WHERE user_id=?
271                             AND    del<>1
272                             ORDER BY ".$DB->quoteIdentifier('standard')." DESC, name ASC",
273                            $_SESSION['user_id']);
a0109c 274
1cded8 275   if ($DB->num_rows($sql_result))
T 276     {
277     $from_id = 0;
278     $a_signatures = array();
a0109c 279
f11541 280     $field_attrib['onchange'] = JS_OBJECT_NAME.".change_identity(this)";
1cded8 281     $select_from = new select($field_attrib);
a0109c 282
1cded8 283     while ($sql_arr = $DB->fetch_assoc($sql_result))
T 284       {
a0109c 285       $identity_id = $sql_arr['identity_id'];
S 286       $select_from->add(format_email_recipient($sql_arr['email'], $sql_arr['name']), $identity_id);
4e17e6 287
1cded8 288       // add signature to array
T 289       if (!empty($sql_arr['signature']))
a0109c 290         {
S 291         $a_signatures[$identity_id]['text'] = $sql_arr['signature'];
292         $a_signatures[$identity_id]['is_html'] = ($sql_arr['html_signature'] == 1) ? true : false;
dd792e 293         if ($a_signatures[$identity_id]['is_html'])
S 294           {
295             $h2t = new html2text($a_signatures[$identity_id]['text'], false, false);
296             $plainTextPart = $h2t->get_text();
297             $a_signatures[$identity_id]['plain_text'] = trim($plainTextPart);
298           }
a0109c 299         }
S 300
1cded8 301       // set identity if it's one of the reply-message recipients
T 302       if (in_array($sql_arr['email'], $a_recipients))
303         $from_id = $sql_arr['identity_id'];
a0109c 304
8d4bcd 305       if ($compose_mode == RCUBE_COMPOSE_REPLY && is_array($MESSAGE['FROM']))
T 306         $MESSAGE['FROM'][] = $sql_arr['email'];
1966c5 307
8d4bcd 308       if ($compose_mode == RCUBE_COMPOSE_DRAFT && strstr($MESSAGE['headers']->from, $sql_arr['email']))
1966c5 309         $from_id = $sql_arr['identity_id'];
1cded8 310       }
4e17e6 311
1cded8 312     // overwrite identity selection with post parameter
T 313     if (isset($_POST['_from']))
8d4bcd 314       $from_id = get_input_value('_from', RCUBE_INPUT_POST);
4e17e6 315
1cded8 316     $out = $select_from->show($from_id);
4e17e6 317
1cded8 318     // add signatures to client
f11541 319     $OUTPUT->set_env('signatures', $a_signatures);
1cded8 320     }
T 321   else
322     {
323     $input_from = new textfield($field_attrib);
324     $out = $input_from->show($_POST['_from']);
325     }
1966c5 326   
1cded8 327   if ($form_start)
T 328     $out = $form_start.$out;
4e17e6 329
1cded8 330   return $out;
4e17e6 331   }
T 332
1cded8 333   
4e17e6 334
T 335 function rcmail_compose_body($attrib)
336   {
f11541 337   global $CONFIG, $OUTPUT, $MESSAGE, $compose_mode;
4e17e6 338   
T 339   list($form_start, $form_end) = get_form_tags($attrib);
340   unset($attrib['form']);
dd53e2 341   
T 342   if (empty($attrib['id']))
343     $attrib['id'] = 'rcmComposeMessage';
a0109c 344
4e17e6 345   $attrib['name'] = '_message';
a0109c 346
S 347   if ($CONFIG['htmleditor'])
348     $isHtml = true;
349   else
350     $isHtml = false;
4e17e6 351
T 352   $body = '';
a0109c 353
4e17e6 354   // use posted message body
597170 355   if (!empty($_POST['_message']))
a0109c 356     {
ea7c46 357     $body = get_input_value('_message', RCUBE_INPUT_POST, TRUE);
a0109c 358     }
4e17e6 359   // compose reply-body
8d4bcd 360   else if ($compose_mode == RCUBE_COMPOSE_REPLY)
4e17e6 361     {
a0109c 362     $hasHtml = rcmail_has_html_part($MESSAGE['parts']); 
S 363     if ($hasHtml && $CONFIG['htmleditor'])
364       {
365       $body = rcmail_first_html_part($MESSAGE);
366       $isHtml = true;
367       }
368     else
369       {
370       $body = rcmail_first_text_part($MESSAGE);
371       $isHtml = false;
372       }
3cf664 373
T 374     $body = rcmail_create_reply_body($body, $isHtml);
4e17e6 375     }
T 376   // forward message body inline
8d4bcd 377   else if ($compose_mode == RCUBE_COMPOSE_FORWARD)
4e17e6 378     {
a0109c 379     $hasHtml = rcmail_has_html_part($MESSAGE['parts']);
S 380     if ($hasHtml && $CONFIG['htmleditor'])
381       {
382       $body = rcmail_first_html_part($MESSAGE);
383       $isHtml = true;
384       }
385     else
386       {
387       $body = rcmail_first_text_part($MESSAGE);
388       $isHtml = false;
389       }
5cc4b1 390
T 391     $body = rcmail_create_forward_body($body, $isHtml);
4e17e6 392     }
8d4bcd 393   else if ($compose_mode == RCUBE_COMPOSE_DRAFT)
1966c5 394     {
a0109c 395     $hasHtml = rcmail_has_html_part($MESSAGE['parts']);
S 396     if ($hasHtml && $CONFIG['htmleditor'])
397       {
398       $body = rcmail_first_html_part($MESSAGE);
399       $isHtml = true;
400       }
401     else
402       {
403       $body = rcmail_first_text_part($MESSAGE);
404       $isHtml = false;
405       }
3cf664 406
T 407     $body = rcmail_create_draft_body($body, $isHtml);
1966c5 408     }
a0109c 409
S 410   $OUTPUT->include_script('tiny_mce/tiny_mce.js');
411   $OUTPUT->include_script("editor.js");
380aed 412   $OUTPUT->add_script('rcmail_editor_init("$__skin_path");');
a0109c 413
4e17e6 414   $out = $form_start ? "$form_start\n" : '';
1966c5 415
03ac21 416   $saveid = new hiddenfield(array('name' => '_draft_saveid', 'value' => $compose_mode==RCUBE_COMPOSE_DRAFT ? str_replace(array('<','>'), "", $MESSAGE['headers']->messageID) : ''));
f0f98f 417   $out .= $saveid->show();
1966c5 418
S 419   $drafttoggle = new hiddenfield(array('name' => '_draft', 'value' => 'yes'));
420   $out .= $drafttoggle->show();
421
a0109c 422   $msgtype = new hiddenfield(array('name' => '_is_html', 'value' => ($isHtml?"1":"0")));
S 423   $out .= $msgtype->show();
424
425   // If desired, set this text area to be editable by TinyMCE
426   if ($isHtml)
427     $attrib['mce_editable'] = "true";
428   $textarea = new textarea($attrib);
4e17e6 429   $out .= $textarea->show($body);
T 430   $out .= $form_end ? "\n$form_end" : '';
a0109c 431
dd53e2 432   // include GoogieSpell
a0109c 433   if (!empty($CONFIG['enable_spellcheck']) && !$isHtml)
ed5d29 434     {
996066 435     $lang_set = '';
T 436     if (!empty($CONFIG['spellcheck_languages']) && is_array($CONFIG['spellcheck_languages']))
437       $lang_set = "googie.setLanguages(".array2js($CONFIG['spellcheck_languages']).");\n";
438     
ed5d29 439     $OUTPUT->include_script('googiespell.js');
2bca6e 440     $OUTPUT->add_script(sprintf(
T 441       "var googie = new GoogieSpell('\$__skin_path/images/googiespell/','%s&_action=spell&lang=');\n".
442       "googie.lang_chck_spell = \"%s\";\n".
443       "googie.lang_rsm_edt = \"%s\";\n".
444       "googie.lang_close = \"%s\";\n".
445       "googie.lang_revert = \"%s\";\n".
446       "googie.lang_no_error_found = \"%s\";\n%s".
447       "googie.setCurrentLanguage('%s');\n".
448       "googie.decorateTextarea('%s');\n".
449       "%s.set_env('spellcheck', googie);",
450       $GLOBALS['COMM_PATH'],
451       JQ(Q(rcube_label('checkspelling'))),
452       JQ(Q(rcube_label('resumeediting'))),
453       JQ(Q(rcube_label('close'))),
454       JQ(Q(rcube_label('revertto'))),
455       JQ(Q(rcube_label('nospellerrors'))),
456       $lang_set,
457       substr($_SESSION['user_lang'], 0, 2),
458       $attrib['id'],
f11541 459       JS_OBJECT_NAME), 'foot');
ed5d29 460
T 461     rcube_add_label('checking');
462     }
f0f98f 463  
41fa0b 464   $out .= "\n".'<iframe name="savetarget" src="program/blank.gif" style="width:0;height:0;visibility:hidden;"></iframe>';
T 465
4e17e6 466   return $out;
T 467   }
468
469
a0109c 470 function rcmail_create_reply_body($body, $bodyIsHtml)
4e17e6 471   {
8d4bcd 472   global $IMAP, $MESSAGE;
4e17e6 473
a0109c 474   if (! $bodyIsHtml)
S 475   {
476     // soft-wrap message first
477     $body = wordwrap($body, 75);
4e17e6 478   
a0109c 479     // split body into single lines
S 480     $a_lines = preg_split('/\r?\n/', $body);
4e17e6 481   
a0109c 482     // add > to each line
S 483     for($n=0; $n<sizeof($a_lines); $n++)
484       {
485       if (strpos($a_lines[$n], '>')===0)
486         $a_lines[$n] = '>'.$a_lines[$n];
487       else
488         $a_lines[$n] = '> '.$a_lines[$n];
489       }
4e17e6 490  
a0109c 491     $body = join("\n", $a_lines);
4e17e6 492
a0109c 493     // add title line
S 494     $prefix = sprintf("\n\n\nOn %s, %s wrote:\n",
495              $MESSAGE['headers']->date,
496              $IMAP->decode_header($MESSAGE['headers']->from));
1cded8 497
a0109c 498     // try to remove the signature
S 499     if ($sp = strrstr($body, '-- '))
500       {
501       if ($body{$sp+3}==' ' || $body{$sp+3}=="\n" || $body{$sp+3}=="\r")
502         $body = substr($body, 0, $sp-1);
503       }
504     $suffix = '';
505   }
506   else
507   {
508      $prefix = sprintf("<br><br>On %s, %s wrote:<br><blockquote type=\"cite\" " .
509                        "style=\"padding-left: 5px; border-left: #1010ff 2px solid; " .
510                        "margin-left: 5px; width: 100%%\">",
511                        $MESSAGE['headers']->date,
512                        $IMAP->decode_header($MESSAGE['headers']->from));
4e17e6 513
a0109c 514      $suffix = "</blockquote>";
S 515   }
516
517   return $prefix.$body.$suffix;
4e17e6 518   }
T 519
520
a0109c 521 function rcmail_create_forward_body($body, $bodyIsHtml)
4e17e6 522   {
8d4bcd 523   global $IMAP, $MESSAGE;
4e17e6 524
a0109c 525   if (! $bodyIsHtml)
S 526   {
527     // soft-wrap message first
528     $body = wordwrap($body, 80);
4e17e6 529   
a0109c 530     $prefix = sprintf("\n\n\n-------- Original Message --------\nSubject: %s\nDate: %s\nFrom: %s\nTo: %s\n\n",
S 531                      $MESSAGE['subject'],
532                      $MESSAGE['headers']->date,
533                      $IMAP->decode_header($MESSAGE['headers']->from),
534                      $IMAP->decode_header($MESSAGE['headers']->to));
535   }
536   else
537   {
538       $prefix = sprintf(
539         "<br><br>-------- Original Message --------" .
540         "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tbody>" .
541         "<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">Subject: </th><td>%s</td></tr>" .
542         "<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">Date: </th><td>%s</td></tr>" .
543         "<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">From: </th><td>%s</td></tr>" .
544         "<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">To: </th><td>%s</td></tr>" .
545         "</tbody></table><br>",
2bca6e 546                      Q($MESSAGE['subject']),
T 547                      Q($MESSAGE['headers']->date),
548                      Q($IMAP->decode_header($MESSAGE['headers']->from)),
549                      Q($IMAP->decode_header($MESSAGE['headers']->to)));
a0109c 550   }
S 551
597170 552   // add attachments
5cc4b1 553   if (!isset($_SESSION['compose']['forward_attachments']) && is_array($MESSAGE['parts']))
8d4bcd 554     rcmail_write_compose_attachments($MESSAGE);
5cc4b1 555     
4e17e6 556   return $prefix.$body;
T 557   }
558
8d4bcd 559
a0109c 560 function rcmail_create_draft_body($body, $bodyIsHtml)
1966c5 561   {
8d4bcd 562   global $IMAP, $MESSAGE;
1966c5 563     
S 564   // add attachments
8d4bcd 565   if (!isset($_SESSION['compose']['forward_attachments']) &&
T 566       is_array($MESSAGE['parts']) && sizeof($MESSAGE['parts'])>1)
567     rcmail_write_compose_attachments($MESSAGE);
1966c5 568
S 569   return $body;
8d4bcd 570   }
T 571   
572   
573 function rcmail_write_compose_attachments(&$message)
574   {
70d4b9 575   global $IMAP, $CONFIG;
T 576
577   $temp_dir = unslashify($CONFIG['temp_dir']);
8d4bcd 578
T 579   if (!is_array($_SESSION['compose']['attachments']))
580     $_SESSION['compose']['attachments'] = array();
581   
582   foreach ($message['parts'] as $pid => $part)
583     {
584     if ($part->ctype_primary != 'message' && $part->ctype_primary != 'text' &&
585         ($part->disposition=='attachment' || $part->disposition=='inline' || $part->headers['content-id'] ||
5cc4b1 586          (empty($part->disposition) && $part->filename)))
8d4bcd 587       {
T 588       $tmp_path = tempnam($temp_dir, 'rcmAttmnt');
589       if ($fp = fopen($tmp_path, 'w'))
590         {
591         fwrite($fp, $IMAP->get_message_part($message['UID'], $pid, $part->encoding));
592         fclose($fp);
593         
594         $_SESSION['compose']['attachments'][] = array(
595           'mimetype' => $part->ctype_primary . '/' . $part->ctype_secondary,
5cc4b1 596           'name' => $part->filename,
8d4bcd 597           'path' => $tmp_path
T 598           );
599         }
600       }
601     }
602     
603   $_SESSION['compose']['forward_attachments'] = TRUE;
1966c5 604   }
4e17e6 605
T 606
607 function rcmail_compose_subject($attrib)
608   {
8d4bcd 609   global $CONFIG, $MESSAGE, $compose_mode;
4e17e6 610   
T 611   list($form_start, $form_end) = get_form_tags($attrib);
612   unset($attrib['form']);
613   
614   $attrib['name'] = '_subject';
615   $textfield = new textfield($attrib);
616
617   $subject = '';
618
619   // use subject from post
597170 620   if (isset($_POST['_subject']))
01c86f 621     $subject = get_input_value('_subject', RCUBE_INPUT_POST, TRUE);
4e17e6 622     
T 623   // create a reply-subject
8d4bcd 624   else if ($compose_mode == RCUBE_COMPOSE_REPLY)
520c36 625     {
8d4bcd 626     if (eregi('^re:', $MESSAGE['subject']))
T 627       $subject = $MESSAGE['subject'];
520c36 628     else
8d4bcd 629       $subject = 'Re: '.$MESSAGE['subject'];
520c36 630     }
4e17e6 631
T 632   // create a forward-subject
8d4bcd 633   else if ($compose_mode == RCUBE_COMPOSE_FORWARD)
09941e 634     {
8d4bcd 635     if (eregi('^fwd:', $MESSAGE['subject']))
T 636       $subject = $MESSAGE['subject'];
09941e 637     else
8d4bcd 638       $subject = 'Fwd: '.$MESSAGE['subject'];
09941e 639     }
4e17e6 640
1966c5 641   // creeate a draft-subject
8d4bcd 642   else if ($compose_mode == RCUBE_COMPOSE_DRAFT)
T 643     $subject = $MESSAGE['subject'];
4e17e6 644   
T 645   $out = $form_start ? "$form_start\n" : '';
646   $out .= $textfield->show($subject);
647   $out .= $form_end ? "\n$form_end" : '';
648          
649   return $out;
650   }
651
652
653 function rcmail_compose_attachment_list($attrib)
654   {
f11541 655   global $OUTPUT, $CONFIG;
4e17e6 656   
T 657   // add ID if not given
658   if (!$attrib['id'])
659     $attrib['id'] = 'rcmAttachmentList';
660   
661   // allow the following attributes to be added to the <ul> tag
662   $attrib_str = create_attrib_string($attrib, array('id', 'class', 'style'));
663  
664   $out = '<ul'. $attrib_str . ">\n";
665   
666   if (is_array($_SESSION['compose']['attachments']))
667     {
a894ba 668     if ($attrib['deleteicon'])
aade7b 669       $button = sprintf('<img src="%s%s" alt="%s" border="0" style="padding-right:2px;vertical-align:middle" />',
508442 670                         $CONFIG['skin_path'],
T 671                         $attrib['deleteicon'],
672                         rcube_label('delete'));
a894ba 673     else
S 674       $button = rcube_label('delete');
675
aade7b 676     foreach ($_SESSION['compose']['attachments'] as $id => $a_prop)
T 677       $out .= sprintf('<li id="rcmfile%d"><a href="#delete" onclick="return %s.command(\'remove-attachment\',\'rcmfile%d\', this)" title="%s">%s</a>%s</li>',
678                       $id,
f11541 679                       JS_OBJECT_NAME,
aade7b 680                       $id,
2bca6e 681                       Q(rcube_label('delete')),
aade7b 682                       $button,
2bca6e 683                       Q($a_prop['name']));
4e17e6 684     }
T 685
f11541 686   $OUTPUT->add_gui_object('attachmentlist', $attrib['id']);
4e17e6 687     
T 688   $out .= '</ul>';
689   return $out;
690   }
691
692
693
694 function rcmail_compose_attachment_form($attrib)
695   {
f11541 696   global $OUTPUT, $SESS_HIDDEN_FIELD;
4e17e6 697
T 698   // add ID if not given
699   if (!$attrib['id'])
700     $attrib['id'] = 'rcmUploadbox';
701   
702   // allow the following attributes to be added to the <div> tag
703   $attrib_str = create_attrib_string($attrib, array('id', 'class', 'style'));
704   $input_field = rcmail_compose_attachment_field(array());
705   $label_send = rcube_label('upload');
706   $label_close = rcube_label('close');
f11541 707   $js_instance = JS_OBJECT_NAME;
4e17e6 708   
T 709   $out = <<<EOF
710 <div$attrib_str>
711 <form action="./" method="post" enctype="multipart/form-data">
712 $SESS_HIDDEN_FIELD
713 $input_field<br />
714 <input type="button" value="$label_close" class="button" onclick="document.getElementById('$attrib[id]').style.visibility='hidden'" />
f11541 715 <input type="button" value="$label_send" class="button" onclick="$js_instance.command('send-attachment', this.form)" />
4e17e6 716 </form>
T 717 </div>
718 EOF;
719
720   
f11541 721   $OUTPUT->add_gui_object('uploadbox', $attrib['id']);
4e17e6 722   return $out;
T 723   }
724
725
726 function rcmail_compose_attachment_field($attrib)
727   {
728   // allow the following attributes to be added to the <input> tag
729   $attrib_str = create_attrib_string($attrib, array('id', 'class', 'style', 'size'));
730  
731   $out = '<input type="file" name="_attachments[]"'. $attrib_str . " />";
732   return $out;
733   }
734
66e2bf 735
4e17e6 736 function rcmail_priority_selector($attrib)
T 737   {
738   list($form_start, $form_end) = get_form_tags($attrib);
739   unset($attrib['form']);
740   
741   $attrib['name'] = '_priority';
742   $selector = new select($attrib);
743
744   $selector->add(array(rcube_label('lowest'),
745                        rcube_label('low'),
746                        rcube_label('normal'),
747                        rcube_label('high'),
748                        rcube_label('highest')),
7902df 749                  array(5, 4, 0, 2, 1));
4e17e6 750                  
e17702 751   $sel = isset($_POST['_priority']) ? $_POST['_priority'] : 0;
4e17e6 752
T 753   $out = $form_start ? "$form_start\n" : '';
754   $out .= $selector->show($sel);
755   $out .= $form_end ? "\n$form_end" : '';
756          
757   return $out;
758   }
759
760
620439 761 function rcmail_receipt_checkbox($attrib)
T 762   {
763   list($form_start, $form_end) = get_form_tags($attrib);
764   unset($attrib['form']);
66e2bf 765   
T 766   if (!isset($attrib['id']))
767     $attrib['id'] = 'receipt';  
620439 768
T 769   $attrib['name'] = '_receipt';
66e2bf 770   $attrib['value'] = '1';
T 771   $checkbox = new checkbox($attrib);
620439 772
T 773   $out = $form_start ? "$form_start\n" : '';
774   $out .= $checkbox->show(0);
775   $out .= $form_end ? "\n$form_end" : '';
776
777   return $out;
778   }
779
780
a0109c 781 function rcmail_editor_selector($attrib)
S 782 {
783   global $CONFIG, $MESSAGE, $compose_mode;
784
785   $choices = array(
6b1fc0 786     'html'  => 'htmltoggle',
S 787     'plain' => 'plaintoggle'
a0109c 788   );
S 789
790   // determine whether HTML or plain text should be checked 
791   if ($CONFIG['htmleditor'])
792     $useHtml = true;
793   else
794     $useHtml = false;
795
796   if ($compose_mode == RCUBE_COMPOSE_REPLY ||
797       $compose_mode == RCUBE_COMPOSE_FORWARD ||
798       $compose_mode == RCUBE_COMPOSE_DRAFT)
799     {
800     $hasHtml = rcmail_has_html_part($MESSAGE['parts']);
801     $useHtml = ($hasHtml && $CONFIG['htmleditor']);
802     }
803
804   $selector = '';
6b1fc0 805   
S 806   $attrib['name'] = '_editorSelect';
b500b4 807   $attrib['onchange'] = 'return rcmail_toggle_editor(this)';
a0109c 808   foreach ($choices as $value => $text)
S 809     {
810     $checked = '';
6b1fc0 811     if ((($value == 'html') && $useHtml) ||
S 812         (($value != 'html') && !$useHtml))
813       $attrib['checked'] = 'true';
814     else
815       unset($attrib['checked']);
a0109c 816
6b1fc0 817     $attrib['id'] = '_' . $value;
S 818     $rb = new radiobutton($attrib);
f11541 819     $selector .= sprintf("%s<label for=\"%s\">%s</label>",
6b1fc0 820                          $rb->show($value),
S 821                          $attrib['id'],
822                          rcube_label($text));
a0109c 823     }
S 824
825   return $selector;
826 }
827
828
4e17e6 829 function get_form_tags($attrib)
T 830   {
f11541 831   global $CONFIG, $OUTPUT, $MESSAGE_FORM, $SESS_HIDDEN_FIELD;  
4e17e6 832
T 833   $form_start = '';
834   if (!strlen($MESSAGE_FORM))
835     {
836     $hiddenfields = new hiddenfield(array('name' => '_task', 'value' => $GLOBALS['_task']));
837     $hiddenfields->add(array('name' => '_action', 'value' => 'send'));
1966c5 838
597170 839     $form_start = empty($attrib['form']) ? '<form name="form" action="./" method="post">' : '';
4e17e6 840     $form_start .= "\n$SESS_HIDDEN_FIELD\n";
T 841     $form_start .= $hiddenfields->show();
842     }
843     
844   $form_end = (strlen($MESSAGE_FORM) && !strlen($attrib['form'])) ? '</form>' : '';
597170 845   $form_name = !empty($attrib['form']) ? $attrib['form'] : 'form';
4e17e6 846   
T 847   if (!strlen($MESSAGE_FORM))
f11541 848     $OUTPUT->add_gui_object('messageform', $form_name);
4e17e6 849   
T 850   $MESSAGE_FORM = $form_name;
851
852   return array($form_start, $form_end);  
853   }
854
855
f11541 856 // register UI objects
T 857 $OUTPUT->add_handlers(array(
858   'composeheaders' => 'rcmail_compose_headers',
859   'composesubject' => 'rcmail_compose_subject',
860   'composebody' => 'rcmail_compose_body',
861   'composeattachmentlist' => 'rcmail_compose_attachment_list',
862   'composeattachmentform' => 'rcmail_compose_attachment_form',
863   'composeattachment' => 'rcmail_compose_attachment_field',
864   'priorityselector' => 'rcmail_priority_selector',
865   'editorselector' => 'rcmail_editor_selector',
866   'receiptcheckbox' => 'rcmail_receipt_checkbox',
867 ));
fd8c50 868
T 869
4e17e6 870 /****** get contacts for this user and add them to client scripts ********/
T 871
f11541 872 require_once('include/rcube_contacts.inc');
T 873
874 $CONTACTS = new rcube_contacts($DB, $_SESSION['user_id']);
875 $CONTACTS->set_pagesize(1000);
4e17e6 876                                    
f11541 877 if ($result = $CONTACTS->list_records())
4e17e6 878   {        
T 879   $a_contacts = array();
f11541 880   while ($sql_arr = $result->iterate())
4e17e6 881     if ($sql_arr['email'])
2bca6e 882       $a_contacts[] = format_email_recipient($sql_arr['email'], JQ($sql_arr['name']));
4e17e6 883   
f11541 884   $OUTPUT->set_env('contacts', $a_contacts);
4e17e6 885   }
T 886
887
888 parse_template('compose');
1966c5 889 ?>