| | |
| | | | program/steps/mail/compose.inc | |
| | | | | |
| | | | This file is part of the Roundcube Webmail client | |
| | | | Copyright (C) 2005-2009, The Roundcube Dev Team | |
| | | | Copyright (C) 2005-2011, The Roundcube Dev Team | |
| | | | Licensed under the GNU GPL | |
| | | | | |
| | | | PURPOSE: | |
| | |
| | | $MESSAGE = NULL; |
| | | |
| | | $COMPOSE_ID = get_input_value('_id', RCUBE_INPUT_GET); |
| | | $_SESSION['compose'] = $_SESSION['compose_data'][$COMPOSE_ID]; |
| | | $_SESSION['compose'] = $_SESSION['compose_data_'.$COMPOSE_ID]; |
| | | |
| | | // give replicated session storage some time to synchronize |
| | | $retries = 0; |
| | | while ($COMPOSE_ID && !is_array($_SESSION['compose']) && $RCMAIL->db->is_replicated() && $retries++ < 5) { |
| | | usleep(500000); |
| | | $RCMAIL->session->reload(); |
| | | $_SESSION['compose'] = $_SESSION['compose_data_'.$COMPOSE_ID]; |
| | | } |
| | | |
| | | // Nothing below is called during message composition, only at "new/forward/reply/draft" initialization or |
| | | // if a compose-ID is given (i.e. when the compose step is opened in a new window/tab). |
| | |
| | | if ($COMPOSE_ID) |
| | | raise_error(array('code' => 500, 'type' => 'php', |
| | | 'file' => __FILE__, 'line' => __LINE__, |
| | | 'message' => "Invalid session"), true, true); |
| | | 'message' => "Invalid compose ID"), true, true); |
| | | |
| | | $_SESSION['compose'] = array( |
| | | 'id' => uniqid(mt_rand()), |
| | | 'param' => request2param(RCUBE_INPUT_GET), |
| | | 'mailbox' => $IMAP->get_mailbox_name(), |
| | | ); |
| | | |
| | | |
| | | // process values like "mailto:foo@bar.com?subject=new+message&cc=another" |
| | | if ($_SESSION['compose']['param']['to']) { |
| | | // #1486037: remove "mailto:" prefix |
| | |
| | | $_SESSION['compose']['param'][$f] = $val; |
| | | } |
| | | } |
| | | |
| | | |
| | | // select folder where to save the sent message |
| | | $_SESSION['compose']['param']['sent_mbox'] = $RCMAIL->config->get('sent_mbox'); |
| | | |
| | | |
| | | // pipe compose parameters thru plugins |
| | | $plugin = $RCMAIL->plugins->exec_hook('message_compose', $_SESSION['compose']); |
| | | $_SESSION['compose']['param'] = array_merge($_SESSION['compose']['param'], $plugin['param']); |
| | |
| | | 'path' => $attach, |
| | | ); |
| | | } |
| | | |
| | | |
| | | // save attachment if valid |
| | | if (($attachment['data'] && $attachment['name']) || ($attachment['path'] && file_exists($attachment['path']))) { |
| | | $attachment = rcmail::get_instance()->plugins->exec_hook('attachment_save', $attachment); |
| | | } |
| | | |
| | | |
| | | if ($attachment['status'] && !$attachment['abort']) { |
| | | unset($attachment['data'], $attachment['status'], $attachment['abort']); |
| | | $_SESSION['compose']['attachments'][$attachment['id']] = $attachment; |
| | |
| | | } |
| | | // set current mailbox in client environment |
| | | $OUTPUT->set_env('mailbox', $IMAP->get_mailbox_name()); |
| | | $OUTPUT->set_env('sig_above', $CONFIG['sig_above']); |
| | | $OUTPUT->set_env('top_posting', $CONFIG['top_posting']); |
| | | $OUTPUT->set_env('sig_above', $RCMAIL->config->get('sig_above', false)); |
| | | $OUTPUT->set_env('top_posting', $RCMAIL->config->get('top_posting', false)); |
| | | $OUTPUT->set_env('recipients_separator', trim($RCMAIL->config->get('recipients_separator', ','))); |
| | | |
| | | // get reference message and set compose mode |
| | | if ($msg_uid = $_SESSION['compose']['param']['draft_uid']) { |
| | |
| | | // re-set 'prefer_html' to have possibility to use html part for compose |
| | | $CONFIG['prefer_html'] = $CONFIG['prefer_html'] || $CONFIG['htmleditor'] || $compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT; |
| | | $MESSAGE = new rcube_message($msg_uid); |
| | | |
| | | |
| | | // make sure message is marked as read |
| | | if ($MESSAGE && $MESSAGE->headers && !$MESSAGE->headers->seen) |
| | | if ($MESSAGE && $MESSAGE->headers && empty($MESSAGE->headers->flags['SEEN'])) |
| | | $IMAP->set_flag($msg_uid, 'SEEN'); |
| | | |
| | | if (!empty($MESSAGE->headers->charset)) |
| | | $IMAP->set_charset($MESSAGE->headers->charset); |
| | | |
| | | |
| | | if ($compose_mode == RCUBE_COMPOSE_REPLY) |
| | | { |
| | | $_SESSION['compose']['reply_uid'] = $msg_uid; |
| | |
| | | $MESSAGE->compose['from'] = $_SESSION['compose']['param']['from']; |
| | | } |
| | | else if (count($MESSAGE->identities)) { |
| | | // extract all recipients of the reply-message |
| | | $a_recipients = array(); |
| | | $a_names = array(); |
| | | |
| | | // extract all recipients of the reply-message |
| | | if (is_object($MESSAGE->headers) && in_array($compose_mode, array(RCUBE_COMPOSE_REPLY, RCUBE_COMPOSE_FORWARD))) |
| | | { |
| | | $a_to = $IMAP->decode_address_list($MESSAGE->headers->to); |
| | | foreach ($a_to as $addr) { |
| | | if (!empty($addr['mailto'])) |
| | | if (!empty($addr['mailto'])) { |
| | | $a_recipients[] = strtolower($addr['mailto']); |
| | | $a_names[] = $addr['name']; |
| | | } |
| | | } |
| | | |
| | | if (!empty($MESSAGE->headers->cc)) { |
| | | $a_cc = $IMAP->decode_address_list($MESSAGE->headers->cc); |
| | | foreach ($a_cc as $addr) { |
| | | if (!empty($addr['mailto'])) |
| | | if (!empty($addr['mailto'])) { |
| | | $a_recipients[] = strtolower($addr['mailto']); |
| | | $a_names[] = $addr['name']; |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | break; |
| | | } |
| | | // use replied message recipients |
| | | else if (in_array($ident['email_ascii'], $a_recipients)) { |
| | | $from_idx = $idx; |
| | | else if (($found = array_search($ident['email_ascii'], $a_recipients)) !== false) { |
| | | // match identity name, prefer default identity |
| | | if ($from_idx === null || ($a_names[$found] && $ident['name'] && $a_names[$found] == $ident['name'])) { |
| | | $from_idx = $idx; |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | // Set other headers |
| | | $a_recipients = array(); |
| | | $parts = array('to', 'cc', 'bcc', 'replyto', 'followupto'); |
| | | $separator = trim($RCMAIL->config->get('recipients_separator', ',')) . ' '; |
| | | |
| | | foreach ($parts as $header) { |
| | | $fvalue = ''; |
| | |
| | | $mailfollowup = $MESSAGE->headers->others['mail-followup-to']; |
| | | $mailreplyto = $MESSAGE->headers->others['mail-reply-to']; |
| | | |
| | | // Reply to mailing list... |
| | | if ($MESSAGE->reply_all == 'list' && $mailfollowup) |
| | | $fvalue = $mailfollowup; |
| | | else if ($MESSAGE->reply_all == 'list' |
| | | && preg_match('/<mailto:([^>]+)>/i', $MESSAGE->headers->others['list-post'], $m)) |
| | | $fvalue = $m[1]; |
| | | // Reply to... |
| | | else if ($MESSAGE->reply_all && $mailfollowup) |
| | | $fvalue = $mailfollowup; |
| | | else if ($mailreplyto) |
| | |
| | | $fvalue = $MESSAGE->headers->replyto; |
| | | else if (!empty($MESSAGE->headers->from)) |
| | | $fvalue = $MESSAGE->headers->from; |
| | | |
| | | // Reply to message sent by yourself (#1487074) |
| | | if (!empty($ident) && $fvalue == $ident['ident']) { |
| | | $fvalue = $MESSAGE->headers->to; |
| | | } |
| | | } |
| | | // add recipient of original message if reply to all |
| | | else if ($header == 'cc' && !empty($MESSAGE->reply_all) && $MESSAGE->reply_all != 'list') { |
| | | if ($v = $MESSAGE->headers->to) |
| | | $fvalue .= $v; |
| | | if ($v = $MESSAGE->headers->cc) |
| | | $fvalue .= (!empty($fvalue) ? ', ' : '') . $v; |
| | | $fvalue .= (!empty($fvalue) ? $separator : '') . $v; |
| | | } |
| | | } |
| | | else if (in_array($compose_mode, array(RCUBE_COMPOSE_DRAFT, RCUBE_COMPOSE_EDIT))) { |
| | |
| | | } |
| | | } |
| | | |
| | | $fvalue = implode(', ', $fvalue); |
| | | $fvalue = implode($separator, $fvalue); |
| | | } |
| | | |
| | | $MESSAGE->compose[$header] = $fvalue; |
| | |
| | | |
| | | // include GoogieSpell |
| | | if (!empty($CONFIG['enable_spellcheck'])) { |
| | | |
| | | $engine = $RCMAIL->config->get('spellcheck_engine','googie'); |
| | | $engine = $RCMAIL->config->get('spellcheck_engine','googie'); |
| | | $dictionary = (bool) $RCMAIL->config->get('spellcheck_dictionary'); |
| | | $spellcheck_langs = (array) $RCMAIL->config->get('spellcheck_languages', |
| | | array('da'=>'Dansk', 'de'=>'Deutsch', 'en' => 'English', 'es'=>'Español', |
| | | 'fr'=>'Français', 'it'=>'Italiano', 'nl'=>'Nederlands', 'pl'=>'Polski', |
| | |
| | | foreach ($spellcheck_langs as $key => $name) { |
| | | $editor_lang_set[] = ($key == $lang ? '+' : '') . JQ($name).'='.JQ($key); |
| | | } |
| | | |
| | | |
| | | $OUTPUT->include_script('googiespell.js'); |
| | | $OUTPUT->add_script(sprintf( |
| | | "var googie = new GoogieSpell('\$__skin_path/images/googiespell/','?_task=utils&_action=spell&lang=');\n". |
| | | "var googie = new GoogieSpell('\$__skin_path/images/googiespell/','?_task=utils&_action=spell&lang=', %s);\n". |
| | | "googie.lang_chck_spell = \"%s\";\n". |
| | | "googie.lang_rsm_edt = \"%s\";\n". |
| | | "googie.lang_close = \"%s\";\n". |
| | | "googie.lang_revert = \"%s\";\n". |
| | | "googie.lang_no_error_found = \"%s\";\n". |
| | | "googie.lang_learn_word = \"%s\";\n". |
| | | "googie.setLanguages(%s);\n". |
| | | "googie.setCurrentLanguage('%s');\n". |
| | | "googie.setSpellContainer('spellcheck-control');\n". |
| | | "googie.decorateTextarea('%s');\n". |
| | | "%s.set_env('spellcheck', googie);", |
| | | !empty($dictionary) ? 'true' : 'false', |
| | | JQ(Q(rcube_label('checkspelling'))), |
| | | JQ(Q(rcube_label('resumeediting'))), |
| | | JQ(Q(rcube_label('close'))), |
| | | JQ(Q(rcube_label('revertto'))), |
| | | JQ(Q(rcube_label('nospellerrors'))), |
| | | JQ(Q(rcube_label('addtodict'))), |
| | | json_serialize($spellcheck_langs), |
| | | $lang, |
| | | $attrib['id'], |
| | |
| | | |
| | | function rcmail_create_forward_body($body, $bodyIsHtml) |
| | | { |
| | | global $IMAP, $MESSAGE, $OUTPUT; |
| | | global $RCMAIL, $MESSAGE; |
| | | |
| | | // add attachments |
| | | if (!isset($_SESSION['compose']['forward_attachments']) && is_array($MESSAGE->mime_parts)) |
| | | $cid_map = rcmail_write_compose_attachments($MESSAGE, $bodyIsHtml); |
| | | |
| | | $date = format_date($MESSAGE->headers->date, $RCMAIL->config->get('date_long')); |
| | | $charset = $RCMAIL->output->get_charset(); |
| | | |
| | | if (!$bodyIsHtml) |
| | | { |
| | | $prefix = "\n\n\n-------- Original Message --------\n"; |
| | | $prefix .= 'Subject: ' . $MESSAGE->subject . "\n"; |
| | | $prefix .= 'Date: ' . $MESSAGE->headers->date . "\n"; |
| | | $prefix .= 'From: ' . $MESSAGE->get_header('from') . "\n"; |
| | | $prefix .= 'To: ' . $MESSAGE->get_header('to') . "\n"; |
| | | $prefix = "\n\n\n-------- " . rcube_label('originalmessage') . " --------\n"; |
| | | $prefix .= rcube_label('subject') . ': ' . $MESSAGE->subject . "\n"; |
| | | $prefix .= rcube_label('date') . ': ' . $date . "\n"; |
| | | $prefix .= rcube_label('from') . ': ' . $MESSAGE->get_header('from') . "\n"; |
| | | $prefix .= rcube_label('to') . ': ' . $MESSAGE->get_header('to') . "\n"; |
| | | |
| | | if ($MESSAGE->headers->cc) |
| | | $prefix .= 'Cc: ' . $MESSAGE->get_header('cc') . "\n"; |
| | | $prefix .= rcube_label('cc') . ': ' . $MESSAGE->get_header('cc') . "\n"; |
| | | if ($MESSAGE->headers->replyto && $MESSAGE->headers->replyto != $MESSAGE->headers->from) |
| | | $prefix .= 'Reply-To: ' . $MESSAGE->get_header('replyto') . "\n"; |
| | | $prefix .= rcube_label('replyto') . ': ' . $MESSAGE->get_header('replyto') . "\n"; |
| | | |
| | | $prefix .= "\n"; |
| | | } |
| | |
| | | $body = rcmail_wash_html($body, array('safe' => $MESSAGE->is_safe), $cid_map); |
| | | |
| | | $prefix = sprintf( |
| | | "<br /><p>-------- Original Message --------</p>" . |
| | | "<br /><p>-------- " . rcube_label('originalmessage') . " --------</p>" . |
| | | "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tbody>" . |
| | | "<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">Subject: </th><td>%s</td></tr>" . |
| | | "<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">Date: </th><td>%s</td></tr>" . |
| | | "<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">From: </th><td>%s</td></tr>" . |
| | | "<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">To: </th><td>%s</td></tr>", |
| | | Q($MESSAGE->subject), |
| | | Q($MESSAGE->headers->date), |
| | | htmlspecialchars(Q($MESSAGE->get_header('from'), 'replace'), ENT_COMPAT, $OUTPUT->get_charset()), |
| | | htmlspecialchars(Q($MESSAGE->get_header('to'), 'replace'), ENT_COMPAT, $OUTPUT->get_charset())); |
| | | "<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">%s: </th><td>%s</td></tr>" . |
| | | "<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">%s: </th><td>%s</td></tr>" . |
| | | "<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">%s: </th><td>%s</td></tr>" . |
| | | "<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">%s: </th><td>%s</td></tr>", |
| | | rcube_label('subject'), Q($MESSAGE->subject), |
| | | rcube_label('date'), Q($date), |
| | | rcube_label('from'), htmlspecialchars(Q($MESSAGE->get_header('from'), 'replace'), ENT_COMPAT, $charset), |
| | | rcube_label('to'), htmlspecialchars(Q($MESSAGE->get_header('to'), 'replace'), ENT_COMPAT, $charset)); |
| | | |
| | | if ($MESSAGE->headers->cc) |
| | | $prefix .= sprintf("<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">Cc: </th><td>%s</td></tr>", |
| | | htmlspecialchars(Q($MESSAGE->get_header('cc'), 'replace'), ENT_COMPAT, $OUTPUT->get_charset())); |
| | | $prefix .= sprintf("<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">%s: </th><td>%s</td></tr>", |
| | | rcube_label('cc'), |
| | | htmlspecialchars(Q($MESSAGE->get_header('cc'), 'replace'), ENT_COMPAT, $charset)); |
| | | |
| | | if ($MESSAGE->headers->replyto && $MESSAGE->headers->replyto != $MESSAGE->headers->from) |
| | | $prefix .= sprintf("<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">Reply-To: </th><td>%s</td></tr>", |
| | | htmlspecialchars(Q($MESSAGE->get_header('replyto'), 'replace'), ENT_COMPAT, $OUTPUT->get_charset())); |
| | | $prefix .= sprintf("<tr><th align=\"right\" nowrap=\"nowrap\" valign=\"baseline\">%s: </th><td>%s</td></tr>", |
| | | rcube_label('replyto'), |
| | | htmlspecialchars(Q($MESSAGE->get_header('replyto'), 'replace'), ENT_COMPAT, $charset)); |
| | | |
| | | $prefix .= "</tbody></table><br>"; |
| | | } |
| | |
| | | $attrib['name'] = '_store_target'; |
| | | $select = rcmail_mailbox_select(array_merge($attrib, array( |
| | | 'noselection' => '- '.rcube_label('dontsave').' -', |
| | | 'folder_filter' => 'mail' |
| | | 'folder_filter' => 'mail', |
| | | 'folder_rights' => 'w', |
| | | ))); |
| | | return $select->show($_SESSION['compose']['param']['sent_mbox'], $attrib); |
| | | } |