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