From 8eefbb2158c43b51a8c33e6c480cbe61539b9535 Mon Sep 17 00:00:00 2001 From: Aleksander Machniak <alec@alec.pl> Date: Mon, 27 Aug 2012 04:16:04 -0400 Subject: [PATCH] Add option to enable HTML editor on forwarding (#1488517) --- program/steps/mail/compose.inc | 400 ++++++++++++++++++++++++++++++++++++++++---------------- 1 files changed, 283 insertions(+), 117 deletions(-) diff --git a/program/steps/mail/compose.inc b/program/steps/mail/compose.inc index 4d54db4..e57b44a 100644 --- a/program/steps/mail/compose.inc +++ b/program/steps/mail/compose.inc @@ -5,8 +5,11 @@ | program/steps/mail/compose.inc | | | | This file is part of the Roundcube Webmail client | - | Copyright (C) 2005-2011, The Roundcube Dev Team | - | Licensed under the GNU GPL | + | Copyright (C) 2005-2012, The Roundcube Dev Team | + | | + | Licensed under the GNU General Public License version 3 or | + | any later version with exceptions for skins & plugins. | + | See the README file for a full license statement. | | | | PURPOSE: | | Compose a new mail message with all headers and attachments | @@ -14,9 +17,6 @@ +-----------------------------------------------------------------------+ | Author: Thomas Bruederli <roundcube@gmail.com> | +-----------------------------------------------------------------------+ - - $Id$ - */ // define constants for message compose mode @@ -26,7 +26,6 @@ define('RCUBE_COMPOSE_EDIT', 0x0109); $MESSAGE_FORM = null; -$MESSAGE = null; $COMPOSE_ID = get_input_value('_id', RCUBE_INPUT_GET); $COMPOSE = null; @@ -56,7 +55,7 @@ $_SESSION['compose_data_'.$COMPOSE_ID] = array( 'id' => $COMPOSE_ID, 'param' => request2param(RCUBE_INPUT_GET), - 'mailbox' => $IMAP->get_mailbox_name(), + 'mailbox' => $RCMAIL->storage->get_folder(), ); $COMPOSE =& $_SESSION['compose_data_'.$COMPOSE_ID]; @@ -116,7 +115,11 @@ } // redirect to a unique URL with all parameters stored in session - $OUTPUT->redirect(array('_action' => 'compose', '_id' => $COMPOSE['id'])); + $OUTPUT->redirect(array( + '_action' => 'compose', + '_id' => $COMPOSE['id'], + '_search' => $_REQUEST['_search'], + )); } @@ -124,7 +127,7 @@ $OUTPUT->add_label('nosubject', 'nosenderwarning', 'norecipientwarning', 'nosubjectwarning', 'cancel', 'nobodywarning', 'notsentwarning', 'notuploadedwarning', 'savingmessage', 'sendingmessage', 'messagesaved', 'converting', 'editorwarning', 'searching', 'uploading', 'uploadingmany', - 'fileuploaderror'); + 'fileuploaderror', 'sendmessage'); $OUTPUT->set_env('compose_id', $COMPOSE['id']); @@ -134,14 +137,20 @@ $OUTPUT->set_env('draft_autosave', $CONFIG['draft_autosave']); } // set current mailbox in client environment -$OUTPUT->set_env('mailbox', $IMAP->get_mailbox_name()); +$OUTPUT->set_env('mailbox', $RCMAIL->storage->get_folder()); $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('top_posting', intval($RCMAIL->config->get('reply_mode')) > 0); $OUTPUT->set_env('recipients_separator', trim($RCMAIL->config->get('recipients_separator', ','))); + +// default font for HTML editor +$font = rcube_fontdefs($RCMAIL->config->get('default_font', 'Verdana')); +if ($font && !is_array($font)) { + $OUTPUT->set_env('default_font', $font); +} // get reference message and set compose mode if ($msg_uid = $COMPOSE['param']['draft_uid']) { - $RCMAIL->imap->set_mailbox($CONFIG['drafts_mbox']); + $RCMAIL->storage->set_folder($CONFIG['drafts_mbox']); $compose_mode = RCUBE_COMPOSE_DRAFT; } else if ($msg_uid = $COMPOSE['param']['reply_uid']) @@ -172,11 +181,11 @@ $MESSAGE = new rcube_message($msg_uid); // make sure message is marked as read - if ($MESSAGE && $MESSAGE->headers && empty($MESSAGE->headers->flags['SEEN'])) - $IMAP->set_flag($msg_uid, 'SEEN'); + if ($MESSAGE->headers && empty($MESSAGE->headers->flags['SEEN'])) + $RCMAIL->storage->set_flag($msg_uid, 'SEEN'); if (!empty($MESSAGE->headers->charset)) - $IMAP->set_charset($MESSAGE->headers->charset); + $RCMAIL->storage->set_charset($MESSAGE->headers->charset); if ($compose_mode == RCUBE_COMPOSE_REPLY) { @@ -232,15 +241,19 @@ $MESSAGE->forward_attachment = true; } } +else { + $MESSAGE = new stdClass(); +} $MESSAGE->compose = array(); // get user's identities -$MESSAGE->identities = $USER->list_identities(); +$MESSAGE->identities = $RCMAIL->user->list_identities(); if (count($MESSAGE->identities)) { foreach ($MESSAGE->identities as $idx => $ident) { - $email = mb_strtolower(rcube_idn_to_utf8($ident['email'])); + $ident['email'] = format_email($ident['email']); + $email = format_email(rcube_idn_to_utf8($ident['email'])); $MESSAGE->identities[$idx]['email_ascii'] = $ident['email']; $MESSAGE->identities[$idx]['ident'] = format_email_recipient($ident['email'], $ident['name']); @@ -262,19 +275,19 @@ // 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); + $a_to = rcube_mime::decode_address_list($MESSAGE->headers->to, null, true, $MESSAGE->headers->charset); foreach ($a_to as $addr) { if (!empty($addr['mailto'])) { - $a_recipients[] = strtolower($addr['mailto']); + $a_recipients[] = format_email($addr['mailto']); $a_names[] = $addr['name']; } } if (!empty($MESSAGE->headers->cc)) { - $a_cc = $IMAP->decode_address_list($MESSAGE->headers->cc); + $a_cc = rcube_mime::decode_address_list($MESSAGE->headers->cc, null, true, $MESSAGE->headers->charset); foreach ($a_cc as $addr) { if (!empty($addr['mailto'])) { - $a_recipients[] = strtolower($addr['mailto']); + $a_recipients[] = format_email($addr['mailto']); $a_names[] = $addr['name']; } } @@ -350,6 +363,10 @@ ) { $fvalue = urldecode($_SESSION['mailto'][$mailto_id]); $decode_header = false; + + // make session to not grow up too much + unset($_SESSION['mailto'][$mailto_id]); + $COMPOSE['param']['to'] = $fvalue; } else if (!empty($_POST['_'.$header])) { $fvalue = get_input_value('_'.$header, RCUBE_INPUT_POST, TRUE); @@ -410,14 +427,14 @@ // split recipients and put them back together in a unique way if (!empty($fvalue) && in_array($header, array('to', 'cc', 'bcc'))) { - $to_addresses = $IMAP->decode_address_list($fvalue, null, $decode_header); + $to_addresses = rcube_mime::decode_address_list($fvalue, null, $decode_header, $MESSAGE->headers->charset); $fvalue = array(); foreach ($to_addresses as $addr_part) { if (empty($addr_part['mailto'])) continue; - $mailto = mb_strtolower(rcube_idn_to_utf8($addr_part['mailto'])); + $mailto = format_email(rcube_idn_to_utf8($addr_part['mailto'])); if (!in_array($mailto, $a_recipients) && ($header == 'to' || empty($MESSAGE->compose['from_email']) || $mailto != $MESSAGE->compose['from_email']) @@ -513,7 +530,7 @@ function rcmail_compose_header_from($attrib) { - global $MESSAGE, $OUTPUT; + global $MESSAGE, $OUTPUT, $RCMAIL, $compose_mode; // pass the following attributes to the form class $field_attrib = array('name' => '_from'); @@ -524,6 +541,8 @@ if (count($MESSAGE->identities)) { $a_signatures = array(); + $separator = $RCMAIL->config->get('sig_above') + && ($compose_mode == RCUBE_COMPOSE_REPLY || $compose_mode == RCUBE_COMPOSE_FORWARD) ? '---' : '-- '; $field_attrib['onchange'] = JS_OBJECT_NAME.".change_identity(this)"; $select_from = new html_select($field_attrib); @@ -537,13 +556,27 @@ // add signature to array if (!empty($sql_arr['signature']) && empty($COMPOSE['param']['nosig'])) { - $a_signatures[$identity_id]['text'] = $sql_arr['signature']; - $a_signatures[$identity_id]['is_html'] = ($sql_arr['html_signature'] == 1) ? true : false; - if ($a_signatures[$identity_id]['is_html']) - { - $h2t = new html2text($a_signatures[$identity_id]['text'], false, false); - $a_signatures[$identity_id]['plain_text'] = trim($h2t->get_text()); + $text = $html = $sql_arr['signature']; + + if ($sql_arr['html_signature']) { + $h2t = new html2text($sql_arr['signature'], false, false); + $text = trim($h2t->get_text()); } + else { + $html = htmlentities($html, ENT_NOQUOTES, RCMAIL_CHARSET); + } + + if (!preg_match('/^--[ -]\r?\n/m', $text)) { + $text = $separator . "\n" . $text; + $html = $separator . "<br>" . $html; + } + + if (!$sql_arr['html_signature']) { + $html = "<pre>" . $html . "</pre>"; + } + + $a_signatures[$identity_id]['text'] = $text; + $a_signatures[$identity_id]['html'] = $html; } } @@ -574,12 +607,15 @@ $html_editor = intval($RCMAIL->config->get('htmleditor')); if ($compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT) { - $useHtml = $MESSAGE->has_html_part(); + $useHtml = $MESSAGE->has_html_part(false); } else if ($compose_mode == RCUBE_COMPOSE_REPLY) { - $useHtml = ($html_editor == 1 || ($html_editor == 2 && $MESSAGE->has_html_part())); + $useHtml = ($html_editor == 1 || ($html_editor >= 2 && $MESSAGE->has_html_part(false))); } - else { // RCUBE_COMPOSE_FORWARD or NEW + else if ($compose_mode == RCUBE_COMPOSE_FORWARD) { + $useHtml = ($html_editor == 1 || ($html_editor == 3 && $MESSAGE->has_html_part(false))); + } + else { $useHtml = ($html_editor == 1); } @@ -608,41 +644,23 @@ rcmail_write_forward_attachment($MESSAGE); } // reply/edit/draft/forward - else if ($compose_mode) { - $has_html_part = $MESSAGE->has_html_part(); + else if ($compose_mode && ($compose_mode != RCUBE_COMPOSE_REPLY || $RCMAIL->config->get('reply_mode') != -1)) { $isHtml = rcmail_compose_editor_mode(); - if ($isHtml) { - if ($has_html_part) { - $body = $MESSAGE->first_html_part(); - } - else { - $body = $MESSAGE->first_text_part(); - // try to remove the signature - if ($RCMAIL->config->get('strip_existing_sig', true)) - $body = rcmail_remove_signature($body); - // add HTML formatting - $body = rcmail_plain_body($body); - if ($body) - $body = '<pre>' . $body . '</pre>'; + if (!empty($MESSAGE->parts)) { + foreach ($MESSAGE->parts as $part) { + // skip no-content and attachment parts (#1488557) + if ($part->type != 'content' || !$part->size || $MESSAGE->is_attachment($part)) { + continue; + } + + if ($part_body = rcmail_compose_part_body($part, $isHtml)) { + $body .= ($body ? ($isHtml ? '<br/>' : "\n") : '') . $part_body; + } } } else { - if ($has_html_part) { - // use html part if it has been used for message (pre)viewing - // decrease line length for quoting - $len = $compose_mode == RCUBE_COMPOSE_REPLY ? $LINE_LENGTH-2 : $LINE_LENGTH; - $txt = new html2text($MESSAGE->first_html_part(), false, true, $len); - $body = $txt->get_text(); - } - else { - $body = $MESSAGE->first_text_part($part); - if ($body && $part && $part->ctype_secondary == 'plain' - && $part->ctype_parameters['format'] == 'flowed' - ) { - $body = rcube_message::unfold_flowed($body); - } - } + $body = rcmail_compose_part_body($MESSAGE, $isHtml); } // compose reply-body @@ -665,18 +683,82 @@ unset($plugin); // add blocked.gif attachment (#1486516) - if ($isHtml && preg_match('#<img src="\./program/blocked\.gif"#', $body)) { - if ($attachment = rcmail_save_image('program/blocked.gif', 'image/gif')) { + if ($isHtml && preg_match('#<img src="\./program/resources/blocked\.gif"#', $body)) { + if ($attachment = rcmail_save_image('program/resources/blocked.gif', 'image/gif')) { $COMPOSE['attachments'][$attachment['id']] = $attachment; - $body = preg_replace('#\./program/blocked\.gif#', - $RCMAIL->comm_path.'&_action=display-attachment&_file=rcmfile'.$attachment['id'].'&_id='.$COMPOSE['id'], - $body); + $url = sprintf('%s&_id=%s&_action=display-attachment&_file=rcmfile%s', + $RCMAIL->comm_path, $COMPOSE['id'], $attachment['id']); + $body = preg_replace('#\./program/resources/blocked\.gif#', $url, $body); } } $HTML_MODE = $isHtml; return $body; +} + +function rcmail_compose_part_body($part, $isHtml = false) +{ + global $RCMAIL, $MESSAGE, $compose_mode; + + // Check if we have enough memory to handle the message in it + // #1487424: we need up to 10x more memory than the body + if (!rcmail_mem_check($part->size * 10)) { + return ''; + } + + if (empty($part->ctype_parameters) || empty($part->ctype_parameters['charset'])) { + $part->ctype_parameters['charset'] = $MESSAGE->headers->charset; + } + + // fetch part if not available + if (!isset($part->body)) { + $part->body = $MESSAGE->get_part_content($part->mime_id); + } + + // message is cached but not exists (#1485443), or other error + if ($part->body === false) { + return ''; + } + + $body = $part->body; + + if ($isHtml) { + if ($part->ctype_secondary == 'html') { + } + else { + // try to remove the signature + if ($RCMAIL->config->get('strip_existing_sig', true)) { + $body = rcmail_remove_signature($body); + } + // add HTML formatting + $body = rcmail_plain_body($body); + if ($body) { + $body = '<pre>' . $body . '</pre>'; + } + } + } + else { + if ($part->ctype_secondary == 'html') { + // use html part if it has been used for message (pre)viewing + // decrease line length for quoting + $len = $compose_mode == RCUBE_COMPOSE_REPLY ? $LINE_LENGTH-2 : $LINE_LENGTH; + $txt = new html2text($body, false, true, $len); + $body = $txt->get_text(); + } + else { + if ($part->ctype_secondary == 'plain' && $part->ctype_parameters['format'] == 'flowed') { + $body = rcube_mime::unfold_flowed($body); + } + + // try to remove the signature + if ($RCMAIL->config->get('strip_existing_sig', true)) { + $body = rcmail_remove_signature($body); + } + } + } + + return $body; } function rcmail_compose_body($attrib) @@ -706,7 +788,9 @@ // If desired, set this textarea to be editable by TinyMCE if ($isHtml) { + $MESSAGE_BODY = htmlentities($MESSAGE_BODY, ENT_NOQUOTES, RCMAIL_CHARSET); $attrib['class'] = 'mce_editor'; + $attrib['is_escaped'] = true; $textarea = new html_textarea($attrib); $out .= $textarea->show($MESSAGE_BODY); } @@ -726,14 +810,14 @@ // include HTML editor rcube_html_editor(); - // include GoogieSpell + // Set language list if (!empty($CONFIG['enable_spellcheck'])) { $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', - 'pt'=>'Português', 'fi'=>'Suomi', 'sv'=>'Svenska')); + 'pt'=>'Português', 'ru'=>'Русский', 'fi'=>'Suomi', 'sv'=>'Svenska')); // googie works only with two-letter codes if ($engine == 'googie') { @@ -755,14 +839,18 @@ if (!$spellcheck_langs[$lang]) $lang = 'en'; + $OUTPUT->set_env('spell_langs', $spellcheck_langs); + $OUTPUT->set_env('spell_lang', $lang); + $editor_lang_set = array(); foreach ($spellcheck_langs as $key => $name) { $editor_lang_set[] = ($key == $lang ? '+' : '') . JQ($name).'='.JQ($key); } + // include GoogieSpell $OUTPUT->include_script('googiespell.js'); $OUTPUT->add_script(sprintf( - "var googie = new GoogieSpell('\$__skin_path/images/googiespell/','?_task=utils&_action=spell&lang=', %s);\n". + "var googie = new GoogieSpell('%s/images/googiespell/','%s&lang=', %s);\n". "googie.lang_chck_spell = \"%s\";\n". "googie.lang_rsm_edt = \"%s\";\n". "googie.lang_close = \"%s\";\n". @@ -771,9 +859,11 @@ "googie.lang_learn_word = \"%s\";\n". "googie.setLanguages(%s);\n". "googie.setCurrentLanguage('%s');\n". - "googie.setSpellContainer('spellcheck-control');\n". + "googie.setDecoration(false);\n". "googie.decorateTextarea('%s');\n". "%s.set_env('spellcheck', googie);", + $RCMAIL->output->get_skin_path(), + $RCMAIL->url(array('_task' => 'utils', '_action' => 'spell', '_remote' => 1)), !empty($dictionary) ? 'true' : 'false', JQ(Q(rcube_label('checkspelling'))), JQ(Q(rcube_label('resumeediting'))), @@ -790,7 +880,7 @@ $OUTPUT->set_env('spellcheck_langs', join(',', $editor_lang_set)); } - $out .= "\n".'<iframe name="savetarget" src="program/blank.gif" style="width:0;height:0;border:none;visibility:hidden;"></iframe>'; + $out .= "\n".'<iframe name="savetarget" src="program/resources/blank.gif" style="width:0;height:0;border:none;visibility:hidden;"></iframe>'; return $out; } @@ -801,7 +891,7 @@ global $RCMAIL, $MESSAGE, $LINE_LENGTH; // build reply prefix - $from = array_pop($RCMAIL->imap->decode_address_list($MESSAGE->get_header('from'), 1, false)); + $from = array_pop(rcube_mime::decode_address_list($MESSAGE->get_header('from'), 1, false, $MESSAGE->headers->charset)); $prefix = rcube_label(array( 'name' => 'mailreplyintro', 'vars' => array( @@ -813,18 +903,15 @@ if (!$bodyIsHtml) { $body = preg_replace('/\r?\n/', "\n", $body); - // try to remove the signature - if ($RCMAIL->config->get('strip_existing_sig', true)) - $body = rcmail_remove_signature($body); - // soft-wrap and quote message text $body = rcmail_wrap_and_quote(rtrim($body, "\n"), $LINE_LENGTH); $prefix .= "\n"; $suffix = ''; - if ($RCMAIL->config->get('top_posting')) + if (intval($RCMAIL->config->get('reply_mode')) > 0) { // top-posting $prefix = "\n\n\n" . $prefix; + } } else { // save inline images to files @@ -838,7 +925,7 @@ $prefix = '<p>' . Q($prefix) . "</p>\n"; $prefix .= '<blockquote>'; - if ($RCMAIL->config->get('top_posting')) { + if (intval($RCMAIL->config->get('reply_mode')) > 0) { // top-posting $prefix = '<br>' . $prefix; $suffix = '</blockquote>'; } @@ -893,18 +980,18 @@ "<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)); + rcube_label('from'), Q($MESSAGE->get_header('from'), 'replace'), + rcube_label('to'), Q($MESSAGE->get_header('to'), 'replace')); if ($MESSAGE->headers->cc) $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)); + Q($MESSAGE->get_header('cc'), 'replace')); if ($MESSAGE->headers->replyto && $MESSAGE->headers->replyto != $MESSAGE->headers->from) $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)); + Q($MESSAGE->get_header('replyto'), 'replace')); $prefix .= "</tbody></table><br>"; } @@ -940,7 +1027,8 @@ { global $RCMAIL; - $len = strlen($body); + $body = str_replace("\r\n", "\n", $body); + $len = strlen($body); $sig_max_lines = $RCMAIL->config->get('sig_max_lines', 15); while (($sp = strrpos($body, "-- \n", $sp ? -$len+$sp-1 : 0)) !== false) { @@ -983,7 +1071,8 @@ if (!$skip && ($attachment = rcmail_save_attachment($message, $pid))) { $COMPOSE['attachments'][$attachment['id']] = $attachment; if ($bodyIsHtml && ($part->content_id || $part->content_location)) { - $url = $RCMAIL->comm_path.'&_action=display-attachment&_file=rcmfile'.$attachment['id'].'&_id='.$COMPOSE['id']; + $url = sprintf('%s&_id=%s&_action=display-attachment&_file=rcmfile%s', + $RCMAIL->comm_path, $COMPOSE['id'], $attachment['id']); if ($part->content_id) $cid_map['cid:'.$part->content_id] = $url; else @@ -1008,7 +1097,8 @@ if (($part->content_id || $part->content_location) && $part->filename) { if ($attachment = rcmail_save_attachment($message, $pid)) { $COMPOSE['attachments'][$attachment['id']] = $attachment; - $url = $RCMAIL->comm_path.'&_action=display-attachment&_file=rcmfile'.$attachment['id'].'&_id='.$COMPOSE['id']; + $url = sprintf('%s&_id=%s&_action=display-attachment&_file=rcmfile%s', + $RCMAIL->comm_path, $COMPOSE['id'], $attachment['id']); if ($part->content_id) $cid_map['cid:'.$part->content_id] = $url; else @@ -1041,12 +1131,12 @@ $temp_dir = unslashify($RCMAIL->config->get('temp_dir')); $path = tempnam($temp_dir, 'rcmAttmnt'); if ($fp = fopen($path, 'w')) { - $RCMAIL->imap->get_raw_body($message->uid, $fp); + $RCMAIL->storage->get_raw_body($message->uid, $fp); fclose($fp); } else return false; } else { - $data = $RCMAIL->imap->get_raw_body($message->uid); + $data = $RCMAIL->storage->get_raw_body($message->uid); } $attachment = array( @@ -1095,10 +1185,22 @@ $data = $message->get_part_content($pid); } + $mimetype = $part->ctype_primary . '/' . $part->ctype_secondary; + $filename = $part->filename; + if (!strlen($filename)) { + if ($mimetype == 'text/html') { + $filename = rcube_label('htmlmessage'); + } + else { + $filename = 'Part_'.$pid; + } + $filename .= '.' . $part->ctype_secondary; + } + $attachment = array( 'group' => $COMPOSE['id'], - 'name' => $part->filename ? $part->filename : 'Part_'.$pid.'.'.$part->ctype_secondary, - 'mimetype' => $part->ctype_primary . '/' . $part->ctype_secondary, + 'name' => $filename, + 'mimetype' => $mimetype, 'content_id' => $part->content_id, 'data' => $data, 'path' => $path, @@ -1220,18 +1322,18 @@ else $button = Q(rcube_label('delete')); - foreach ($COMPOSE['attachments'] as $id => $a_prop) - { + foreach ($COMPOSE['attachments'] as $id => $a_prop) { if (empty($a_prop)) continue; - $out .= html::tag('li', array('id' => 'rcmfile'.$id), + $out .= html::tag('li', array('id' => 'rcmfile'.$id, 'class' => rcmail_filetype2classname($a_prop['mimetype'], $a_prop['name'])), html::a(array( 'href' => "#delete", 'title' => rcube_label('delete'), - 'onclick' => sprintf("return %s.command('remove-attachment','rcmfile%s', this)", JS_OBJECT_NAME, $id)), + 'onclick' => sprintf("return %s.command('remove-attachment','rcmfile%s', this)", JS_OBJECT_NAME, $id), + 'class' => 'delete'), $button) . Q($a_prop['name'])); - + $jslist['rcmfile'.$id] = array('name' => $a_prop['name'], 'complete' => true, 'mimetype' => $a_prop['mimetype']); } } @@ -1245,18 +1347,17 @@ $OUTPUT->set_env('attachments', $jslist); $OUTPUT->add_gui_object('attachmentlist', $attrib['id']); - + return html::tag('ul', $attrib, $out, html::$common_attrib); } function rcmail_compose_attachment_form($attrib) { - global $RCMAIL, $OUTPUT; + global $OUTPUT; - // add ID if not given - if (!$attrib['id']) - $attrib['id'] = 'rcmUploadbox'; + // set defaults + $attrib += array('id' => 'rcmUploadbox', 'buttons' => 'yes'); // Get filesize, enable upload progress bar $max_filesize = rcube_upload_init(); @@ -1264,17 +1365,17 @@ $button = new html_inputfield(array('type' => 'button')); $out = html::div($attrib, - $OUTPUT->form_tag(array('name' => 'uploadform', 'method' => 'post', 'enctype' => 'multipart/form-data'), + $OUTPUT->form_tag(array('id' => $attrib['id'].'Frm', 'name' => 'uploadform', 'method' => 'post', 'enctype' => 'multipart/form-data'), html::div(null, rcmail_compose_attachment_field(array('size' => $attrib['attachmentfieldsize']))) . html::div('hint', rcube_label(array('name' => 'maxuploadsize', 'vars' => array('size' => $max_filesize)))) . - html::div('buttons', + (get_boolean($attrib['buttons']) ? html::div('buttons', $button->show(rcube_label('close'), array('class' => 'button', 'onclick' => "$('#$attrib[id]').hide()")) . ' ' . $button->show(rcube_label('upload'), array('class' => 'button mainaction', 'onclick' => JS_OBJECT_NAME . ".command('send-attachment', this.form)")) - ) + ) : '') ) ); - $OUTPUT->add_gui_object('uploadbox', $attrib['id']); + $OUTPUT->add_gui_object('uploadform', $attrib['id'].'Frm'); return $out; } @@ -1293,7 +1394,7 @@ function rcmail_priority_selector($attrib) { global $MESSAGE; - + list($form_start, $form_end) = get_form_tags($attrib); unset($attrib['form']); @@ -1330,13 +1431,13 @@ unset($attrib['form']); if (!isset($attrib['id'])) - $attrib['id'] = 'receipt'; + $attrib['id'] = 'receipt'; $attrib['name'] = '_receipt'; $attrib['value'] = '1'; $checkbox = new html_checkbox($attrib); - if ($MESSAGE && in_array($compose_mode, array(RCUBE_COMPOSE_DRAFT, RCUBE_COMPOSE_EDIT))) + if (in_array($compose_mode, array(RCUBE_COMPOSE_DRAFT, RCUBE_COMPOSE_EDIT))) $mdn_default = (bool) $MESSAGE->headers->mdn_to; else $mdn_default = $RCMAIL->config->get('mdn_default'); @@ -1373,8 +1474,6 @@ function rcmail_editor_selector($attrib) { - global $CONFIG, $MESSAGE, $compose_mode; - // determine whether HTML or plain text should be checked $useHtml = rcmail_compose_editor_mode(); @@ -1419,18 +1518,18 @@ function rcmail_check_sent_folder($folder, $create=false) { - global $IMAP; + global $RCMAIL; - if ($IMAP->mailbox_exists($folder, true)) { + if ($RCMAIL->storage->folder_exists($folder, true)) { return true; } // folder may exist but isn't subscribed (#1485241) if ($create) { - if (!$IMAP->mailbox_exists($folder)) - return $IMAP->create_mailbox($folder, true); + if (!$RCMAIL->storage->folder_exists($folder)) + return $RCMAIL->storage->create_folder($folder, true); else - return $IMAP->subscribe($folder); + return $RCMAIL->storage->subscribe($folder); } return false; @@ -1447,6 +1546,7 @@ $hiddenfields = new html_hiddenfield(array('name' => '_task', 'value' => $RCMAIL->task)); $hiddenfields->add(array('name' => '_action', 'value' => 'send')); $hiddenfields->add(array('name' => '_id', 'value' => $COMPOSE['id'])); + $hiddenfields->add(array('name' => '_attachments')); $form_start = empty($attrib['form']) ? $RCMAIL->output->form_tag(array('name' => "form", 'method' => "post")) : ''; $form_start .= $hiddenfields->show(); @@ -1464,6 +1564,71 @@ } +function rcmail_addressbook_list($attrib = array()) +{ + global $RCMAIL, $OUTPUT; + + $attrib += array('id' => 'rcmdirectorylist'); + + $out = ''; + $line_templ = html::tag('li', array( + 'id' => 'rcmli%s', 'class' => '%s'), + html::a(array('href' => '#list', + 'rel' => '%s', + 'onclick' => "return ".JS_OBJECT_NAME.".command('list-adresses','%s',this)"), '%s')); + + foreach ($RCMAIL->get_address_sources() as $j => $source) { + $id = strval(strlen($source['id']) ? $source['id'] : $j); + $js_id = JQ($id); + + // set class name(s) + $class_name = 'addressbook'; + if ($source['class_name']) + $class_name .= ' ' . $source['class_name']; + + $out .= sprintf($line_templ, + html_identifier($id), + $class_name, + $source['id'], + $js_id, (!empty($source['name']) ? Q($source['name']) : Q($id))); + } + + $OUTPUT->add_gui_object('addressbookslist', $attrib['id']); + + return html::tag('ul', $attrib, $out, html::$common_attrib); +} + +// return the contacts list as HTML table +function rcmail_contacts_list($attrib = array()) +{ + global $OUTPUT; + + $attrib += array('id' => 'rcmAddressList'); + + // set client env + $OUTPUT->add_gui_object('contactslist', $attrib['id']); + $OUTPUT->set_env('pagecount', 0); + $OUTPUT->set_env('current_page', 0); + $OUTPUT->include_script('list.js'); + + return rcube_table_output($attrib, array(), array('name'), 'ID'); +} + + +/** + * Register a certain container as active area to drop files onto + */ +function compose_file_drop_area($attrib) +{ + global $OUTPUT; + + if ($attrib['id']) { + $OUTPUT->add_gui_object('filedrop', $attrib['id']); + $OUTPUT->set_env('filedrop', array('action' => 'upload', 'fieldname' => '_attachments')); + } +} + + // register UI objects $OUTPUT->add_handlers(array( 'composeheaders' => 'rcmail_compose_headers', @@ -1472,13 +1637,14 @@ 'composeattachmentlist' => 'rcmail_compose_attachment_list', 'composeattachmentform' => 'rcmail_compose_attachment_form', 'composeattachment' => 'rcmail_compose_attachment_field', + 'filedroparea' => 'compose_file_drop_area', 'priorityselector' => 'rcmail_priority_selector', 'editorselector' => 'rcmail_editor_selector', 'receiptcheckbox' => 'rcmail_receipt_checkbox', 'dsncheckbox' => 'rcmail_dsn_checkbox', 'storetarget' => 'rcmail_store_target_selection', + 'addressbooks' => 'rcmail_addressbook_list', + 'addresslist' => 'rcmail_contacts_list', )); $OUTPUT->send('compose'); - - -- Gitblit v1.9.1