From 521bea4bd8f2e462df3cf79fa5f2230a00e1115c Mon Sep 17 00:00:00 2001 From: prashant <prashant@jois.ca> Date: Tue, 23 Jun 2015 18:09:14 -0400 Subject: [PATCH] Merge branch 'master' of https://github.com/roundcube/roundcubemail --- program/lib/Roundcube/rcube_smtp.php | 12 CHANGELOG | 4 Dockerfile | 4 plugins/filesystem_attachments/filesystem_attachments.php | 6 program/steps/mail/compose.inc | 349 ++++++++++++++++++++------------------ skins/larry/settings.css | 1 program/lib/Roundcube/rcube_message.php | 65 ++++--- tests/Framework/Html2text.php | 30 +++ composer.json-dist | 12 - plugins/redundant_attachments/redundant_attachments.php | 2 program/lib/Roundcube/rcube_html2text.php | 9 11 files changed, 275 insertions(+), 219 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index d0aee48..c838f49 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -16,6 +16,10 @@ - Fix bug where some messages in multi-folder search couldn't be opened (#1490426) - Fix unintentional messages list page change on page switch in compose addressbook (#1490427) - Fix race-condition in saving user preferences and loading plugin config (#1490431) +- Fix so plain text signature field uses monospace font (#1490435) +- Fix so links with href == content aren't added to links list on html to text conversion (#1490434) +- Fix handling of non-break spaces in html to text conversion (#1490436) +- Fix self-reply detection issues (#1490439) RELEASE 1.1.2 ------------- diff --git a/Dockerfile b/Dockerfile index ffade7e..450c278 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,10 +6,10 @@ RUN apt-get -qq update RUN apt-get install -qq apache2-mpm-event -RUN sed -e 's|/var/www|&/public_html|' -e 's/\(Log \+\)[^ ]\+/\1"|/bin/cat"/' -i /etc/apache2/sites-available/000-default.conf +RUN sed -e 's|/var/www/html|/var/www/public_html|' -e 's/\(Log \+\)[^ ]\+/\1"|/bin/cat"/' -i /etc/apache2/sites-available/000-default.conf RUN a2ensite 000-default -RUN sed -e 's|/var/www|&/public_html|' -e 's/\(Log \+\)[^ ]\+/\1"|/bin/cat"/' -i /etc/apache2/sites-available/default-ssl.conf +RUN sed -e 's|/var/www/html|/var/www/public_html|' -e 's/\(Log \+\)[^ ]\+/\1"|/bin/cat"/' -i /etc/apache2/sites-available/default-ssl.conf RUN sed -e '/SSLCertificateKeyFile/s|ssl-cert-snakeoil.key|ssl-cert.key|' -e '/SSLCertificateFile/s|ssl-cert-snakeoil.pem|ssl-cert.pem|' -i /etc/apache2/sites-available/default-ssl.conf RUN ln -snf ssl-cert-snakeoil.pem /etc/ssl/certs/ssl-cert.pem RUN ln -snf ssl-cert-snakeoil.key /etc/ssl/private/ssl-cert.key diff --git a/composer.json-dist b/composer.json-dist index e9aa03e..521f6ba 100644 --- a/composer.json-dist +++ b/composer.json-dist @@ -14,18 +14,6 @@ { "type": "vcs", "url": "https://git.kolab.org/diffusion/PNL/php-net_ldap.git" - }, - { - "type": "package", - "package": { - "name": "Net_SMTP", - "version": "dev-master", - "source": { - "url": "https://github.com/pear/Net_SMTP", - "type": "git", - "reference": "master" - } - } } ], "require": { diff --git a/plugins/filesystem_attachments/filesystem_attachments.php b/plugins/filesystem_attachments/filesystem_attachments.php index 50bd624..164efa6 100644 --- a/plugins/filesystem_attachments/filesystem_attachments.php +++ b/plugins/filesystem_attachments/filesystem_attachments.php @@ -50,7 +50,7 @@ { $args['status'] = false; $group = $args['group']; - $rcmail = rcmail::get_instance(); + $rcmail = rcube::get_instance(); // use common temp dir for file uploads $temp_dir = $rcmail->config->get('temp_dir'); @@ -78,7 +78,7 @@ $args['status'] = false; if (!$args['path']) { - $rcmail = rcmail::get_instance(); + $rcmail = rcube::get_instance(); $temp_dir = $rcmail->config->get('temp_dir'); $tmp_path = tempnam($temp_dir, 'rcmAttmnt'); @@ -160,7 +160,7 @@ function file_id() { - $userid = rcmail::get_instance()->user->ID; + $userid = rcube::get_instance()->user->ID; list($usec, $sec) = explode(' ', microtime()); $id = preg_replace('/[^0-9]/', '', $userid . $sec . $usec); diff --git a/plugins/redundant_attachments/redundant_attachments.php b/plugins/redundant_attachments/redundant_attachments.php index 24af7d9..17427f0 100644 --- a/plugins/redundant_attachments/redundant_attachments.php +++ b/plugins/redundant_attachments/redundant_attachments.php @@ -63,7 +63,7 @@ return; } - $rcmail = rcmail::get_instance(); + $rcmail = rcube::get_instance(); // load configuration $this->load_config(); diff --git a/program/lib/Roundcube/rcube_html2text.php b/program/lib/Roundcube/rcube_html2text.php index 15dc2b5..a2f6288 100644 --- a/program/lib/Roundcube/rcube_html2text.php +++ b/program/lib/Roundcube/rcube_html2text.php @@ -216,7 +216,7 @@ * @see $ent_search */ protected $ent_replace = array( - ' ', // Non-breaking space + "\xC2\xA0", // Non-breaking space '"', // Double quotes "'", // Single quotes '>', @@ -509,7 +509,7 @@ * @param string $link URL of the link * @param string $display Part of the text to associate number with */ - protected function _build_link_list( $link, $display ) + protected function _build_link_list($link, $display) { if (!$this->_do_links || empty($link)) { return $display; @@ -520,6 +520,11 @@ return $display; } + // skip links with href == content (#1490434) + if ($link === $display) { + return $display; + } + if (preg_match('!^([a-z][a-z0-9.+-]+:)!i', $link)) { $url = $link; } diff --git a/program/lib/Roundcube/rcube_message.php b/program/lib/Roundcube/rcube_message.php index cb958eb..d022185 100644 --- a/program/lib/Roundcube/rcube_message.php +++ b/program/lib/Roundcube/rcube_message.php @@ -322,11 +322,12 @@ * Determine if the message contains a HTML part. This must to be * a real part not an attachment (or its part) * - * @param bool $enriched Enables checking for text/enriched parts too + * @param bool $enriched Enables checking for text/enriched parts too + * @param rcube_message_part &$part Reference to the part if found * * @return bool True if a HTML is available, False if not */ - function has_html_part($enriched = false) + public function has_html_part($enriched = false, &$part = null) { // check all message parts foreach ($this->mime_parts as $part) { @@ -360,6 +361,8 @@ } } + $part = null; + return false; } @@ -367,9 +370,11 @@ * Determine if the message contains a text/plain part. This must to be * a real part not an attachment (or its part) * + * @param rcube_message_part &$part Reference to the part if found + * * @return bool True if a plain text part is available, False if not */ - function has_text_part() + public function has_text_part(&$part = null) { // check all message parts foreach ($this->mime_parts as $part) { @@ -399,52 +404,58 @@ } } + $part = null; + return false; } /** * Return the first HTML part of this message * + * @param rcube_message_part &$part Reference to the part if found + * @param bool $enriched Enables checking for text/enriched parts too + * * @return string HTML message part content */ - function first_html_part() + public function first_html_part(&$part = null, $enriched = false) { - // check all message parts - foreach ($this->mime_parts as $pid => $part) { - if ($part->mimetype == 'text/html') { - return $this->get_part_body($pid, true); + if ($this->has_html_part($enriched, $part)) { + $body = $this->get_part_body($part->mime_id, true); + + if ($part->mimetype == 'text/enriched') { + $body = rcube_enriched::to_html($body); } + + return $body; } } /** - * Return the first text part of this message + * Return the first text part of this message. + * If there's no text/plain part but $strict=true and text/html part + * exists, it will be returned in text/plain format. * - * @param rcube_message_part $part Reference to the part if found + * @param rcube_message_part &$part Reference to the part if found + * @param bool $strict Check only text/plain parts + * * @return string Plain text message/part content */ - function first_text_part(&$part=null) + public function first_text_part(&$part = null, $strict = false) { // no message structure, return complete body - if (empty($this->parts)) + if (empty($this->parts)) { return $this->body; - - // check all message parts - foreach ($this->mime_parts as $mime_id => $part) { - if ($part->mimetype == 'text/plain') { - return $this->get_part_body($mime_id, true); - } - else if ($part->mimetype == 'text/html') { - $out = $this->get_part_body($mime_id, true); - - // create instance of html2text class - $txt = new rcube_html2text($out); - return $txt->get_text(); - } } - $part = null; - return null; + if ($this->has_text_part($part)) { + return $this->get_part_body($part->mime_id, true); + } + + if (!$strict && ($body = $this->first_html_part($part, true))) { + // create instance of html2text class + $h2t = new rcube_html2text($body); + return $h2t->get_text(); + } } /** diff --git a/program/lib/Roundcube/rcube_smtp.php b/program/lib/Roundcube/rcube_smtp.php index a2d130e..bb1d2c8 100644 --- a/program/lib/Roundcube/rcube_smtp.php +++ b/program/lib/Roundcube/rcube_smtp.php @@ -208,11 +208,6 @@ else if (is_string($headers)) { $text_headers = $headers; } - else { - $this->reset(); - $this->response[] = "Invalid message headers"; - return false; - } // exit if no from address is given if (!isset($from)) { @@ -275,8 +270,11 @@ if (is_resource($body)) { // file handle - $data = $body; - $text_headers = preg_replace('/[\r\n]+$/', '', $text_headers); + $data = $body; + + if ($text_headers) { + $text_headers = preg_replace('/[\r\n]+$/', '', $text_headers); + } } else { // Concatenate headers and body so it can be passed by reference to SMTP_CONN->data diff --git a/program/steps/mail/compose.inc b/program/steps/mail/compose.inc index dcfc613..9bb8713 100644 --- a/program/steps/mail/compose.inc +++ b/program/steps/mail/compose.inc @@ -273,144 +273,9 @@ else if (count($MESSAGE->identities)) { $ident = rcmail_identity_select($MESSAGE, $MESSAGE->identities, $compose_mode); - $MESSAGE->compose['from_email'] = $ident['email']; - $MESSAGE->compose['from'] = $ident['identity_id']; + $MESSAGE->compose['from'] = $ident['identity_id']; + $MESSAGE->compose['ident'] = $ident; } - -// Set other headers -$a_recipients = array(); -$parts = array('to', 'cc', 'bcc', 'replyto', 'followupto'); -$separator = trim($RCMAIL->config->get('recipients_separator', ',')) . ' '; -$from_email = @mb_strtolower($MESSAGE->compose['from_email']); - -foreach ($parts as $header) { - $fvalue = ''; - $decode_header = true; - $charset = $MESSAGE->headers->charset; - - // we have a set of recipients stored is session - if ($header == 'to' && ($mailto_id = $COMPOSE['param']['mailto']) - && $_SESSION['mailto'][$mailto_id] - ) { - $fvalue = urldecode($_SESSION['mailto'][$mailto_id]); - $decode_header = false; - $charset = $RCMAIL->output->charset; - - // make session to not grow up too much - unset($_SESSION['mailto'][$mailto_id]); - $COMPOSE['param']['to'] = $fvalue; - } - else if (!empty($_POST['_'.$header])) { - $fvalue = rcube_utils::get_input_value('_'.$header, rcube_utils::INPUT_POST, TRUE); - $charset = $RCMAIL->output->charset; - } - else if (!empty($COMPOSE['param'][$header])) { - $fvalue = $COMPOSE['param'][$header]; - $charset = $RCMAIL->output->charset; - } - else if ($compose_mode == RCUBE_COMPOSE_REPLY) { - // get recipent address(es) out of the message headers - if ($header == 'to') { - $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 = $mailreplyto; - else if (!empty($MESSAGE->headers->replyto)) { - $fvalue = $MESSAGE->headers->replyto; - $replyto = true; - } - else if (!empty($MESSAGE->headers->from)) - $fvalue = $MESSAGE->headers->from; - - // Reply to message sent by yourself (#1487074, #1489230) - // Reply-To address need to be unset (#1490233) - if (!empty($ident) && empty($replyto) - && in_array($ident['ident'], array($fvalue, $MESSAGE->headers->from)) - ) { - $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) ? $separator : '') . $v; - // Use Sender header (#1489011) - if (($v = $MESSAGE->headers->get('Sender', false)) && strpos($v, '-bounces@') === false) - $fvalue .= (!empty($fvalue) ? $separator : '') . $v; - - // When To: and Reply-To: are the same we add From: address to the list (#1489037) - if ($v = $MESSAGE->headers->from) { - $from = rcube_mime::decode_address_list($v, null, false, $charset, true); - $to = rcube_mime::decode_address_list($MESSAGE->headers->to, null, false, $charset, true); - $replyto = rcube_mime::decode_address_list($MESSAGE->headers->replyto, null, false, $charset, true); - - if (count($replyto) && !count(array_diff($to, $replyto)) && count(array_diff($from, $to))) { - $fvalue .= (!empty($fvalue) ? $separator : '') . $v; - } - } - } - } - else if (in_array($compose_mode, array(RCUBE_COMPOSE_DRAFT, RCUBE_COMPOSE_EDIT))) { - // get drafted headers - if ($header=='to' && !empty($MESSAGE->headers->to)) - $fvalue = $MESSAGE->get_header('to', true); - else if ($header=='cc' && !empty($MESSAGE->headers->cc)) - $fvalue = $MESSAGE->get_header('cc', true); - else if ($header=='bcc' && !empty($MESSAGE->headers->bcc)) - $fvalue = $MESSAGE->get_header('bcc', true); - else if ($header=='replyto' && !empty($MESSAGE->headers->others['mail-reply-to'])) - $fvalue = $MESSAGE->get_header('mail-reply-to'); - else if ($header=='replyto' && !empty($MESSAGE->headers->replyto)) - $fvalue = $MESSAGE->get_header('reply-to'); - else if ($header=='followupto' && !empty($MESSAGE->headers->others['mail-followup-to'])) - $fvalue = $MESSAGE->get_header('mail-followup-to'); - } - - // split recipients and put them back together in a unique way - if (!empty($fvalue) && in_array($header, array('to', 'cc', 'bcc'))) { - $to_addresses = rcube_mime::decode_address_list($fvalue, null, $decode_header, $charset); - $fvalue = array(); - - foreach ($to_addresses as $addr_part) { - if (empty($addr_part['mailto'])) { - continue; - } - - // According to RFC5321 local part of email address is case-sensitive - // however, here it is better to compare addresses in case-insensitive manner - $mailto = format_email(rcube_utils::idn_to_utf8($addr_part['mailto'])); - $mailto_lc = mb_strtolower($addr_part['mailto']); - - if (($header == 'to' || $compose_mode != RCUBE_COMPOSE_REPLY || $mailto_lc != $from_email) - && !in_array($mailto_lc, $a_recipients) - ) { - if ($addr_part['name'] && $mailto != $addr_part['name']) { - $mailto = format_email_recipient($mailto, $addr_part['name']); - } - - $fvalue[] = $mailto; - $a_recipients[] = $mailto_lc; - } - } - - $fvalue = implode($separator, $fvalue); - } - - $MESSAGE->compose[$header] = $fvalue; -} -unset($a_recipients); // process $MESSAGE body/attachments, set $MESSAGE_BODY/$HTML_MODE vars and some session data $MESSAGE_BODY = rcmail_prepare_message_body(); @@ -584,7 +449,7 @@ // create teaxtarea object $input = new $field_type($field_attrib); - $out = $input->show($MESSAGE->compose[$param]); + $out = $input->show(rcmail_compose_header_value($param)); } if ($form_start) { @@ -600,7 +465,7 @@ function rcmail_compose_header_from($attrib) { - global $MESSAGE, $OUTPUT, $RCMAIL, $COMPOSE, $compose_mode; + global $MESSAGE, $OUTPUT, $RCMAIL, $COMPOSE; // pass the following attributes to the form class $field_attrib = array('name' => '_from'); @@ -615,7 +480,7 @@ $identities = array(); $top_posting = intval($RCMAIL->config->get('reply_mode')) > 0 && !$RCMAIL->config->get('sig_below') - && ($compose_mode == RCUBE_COMPOSE_REPLY || $compose_mode == RCUBE_COMPOSE_FORWARD); + && ($COMPOSE['mode'] == RCUBE_COMPOSE_REPLY || $COMPOSE['mode'] == RCUBE_COMPOSE_FORWARD); $separator = $top_posting ? '---' : '-- '; $field_attrib['onchange'] = rcmail_output::JS_OBJECT_NAME.".change_identity(this)"; @@ -673,17 +538,171 @@ return $out; } +function rcmail_compose_header_value($header) +{ + global $COMPOSE, $MESSAGE; + + $RCMAIL = rcube::get_instance(); + $fvalue = ''; + $decode_header = true; + $charset = $MESSAGE->headers->charset; + $separator = trim($RCMAIL->config->get('recipients_separator', ',')) . ' '; + + // we have a set of recipients stored is session + if ($header == 'to' && ($mailto_id = $COMPOSE['param']['mailto']) + && $_SESSION['mailto'][$mailto_id] + ) { + $fvalue = urldecode($_SESSION['mailto'][$mailto_id]); + $decode_header = false; + $charset = $RCMAIL->output->charset; + + // make session to not grow up too much + unset($_SESSION['mailto'][$mailto_id]); + $COMPOSE['param']['to'] = $fvalue; + } + else if (!empty($_POST['_' . $header])) { + $fvalue = rcube_utils::get_input_value('_' . $header, rcube_utils::INPUT_POST, true); + $charset = $RCMAIL->output->charset; + } + else if (!empty($COMPOSE['param'][$header])) { + $fvalue = $COMPOSE['param'][$header]; + $charset = $RCMAIL->output->charset; + } + else if ($COMPOSE['mode'] == RCUBE_COMPOSE_REPLY) { + // get recipent address(es) out of the message headers + if ($header == 'to') { + $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 = $mailreplyto; + } + else if (!empty($MESSAGE->headers->replyto)) { + $fvalue = $MESSAGE->headers->replyto; + $replyto = true; + } + else if (!empty($MESSAGE->headers->from)) { + $fvalue = $MESSAGE->headers->from; + } + + // Reply to message sent by yourself (#1487074, #1489230, #1490439) + // Reply-To address need to be unset (#1490233) + if (!empty($MESSAGE->compose['ident']) && empty($replyto)) { + foreach (array($fvalue, $MESSAGE->headers->from) as $sender) { + $senders = rcube_mime::decode_address_list($sender, null, false, $charset, true); + + if (in_array($MESSAGE->compose['ident']['email_ascii'], $senders)) { + $fvalue = $MESSAGE->headers->to; + break; + } + } + } + } + // 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) ? $separator : '') . $v; + } + // Use Sender header (#1489011) + if (($v = $MESSAGE->headers->get('Sender', false)) && strpos($v, '-bounces@') === false) { + $fvalue .= (!empty($fvalue) ? $separator : '') . $v; + } + + // When To: and Reply-To: are the same we add From: address to the list (#1489037) + if ($v = $MESSAGE->headers->from) { + $from = rcube_mime::decode_address_list($v, null, false, $charset, true); + $to = rcube_mime::decode_address_list($MESSAGE->headers->to, null, false, $charset, true); + $replyto = rcube_mime::decode_address_list($MESSAGE->headers->replyto, null, false, $charset, true); + + if (count($replyto) && !count(array_diff($to, $replyto)) && count(array_diff($from, $to))) { + $fvalue .= (!empty($fvalue) ? $separator : '') . $v; + } + } + } + } + else if (in_array($COMPOSE['mode'], array(RCUBE_COMPOSE_DRAFT, RCUBE_COMPOSE_EDIT))) { + // get drafted headers + if ($header == 'to' && !empty($MESSAGE->headers->to)) { + $fvalue = $MESSAGE->get_header('to', true); + } + else if ($header == 'cc' && !empty($MESSAGE->headers->cc)) { + $fvalue = $MESSAGE->get_header('cc', true); + } + else if ($header == 'bcc' && !empty($MESSAGE->headers->bcc)) { + $fvalue = $MESSAGE->get_header('bcc', true); + } + else if ($header == 'replyto' && !empty($MESSAGE->headers->others['mail-reply-to'])) { + $fvalue = $MESSAGE->get_header('mail-reply-to'); + } + else if ($header == 'replyto' && !empty($MESSAGE->headers->replyto)) { + $fvalue = $MESSAGE->get_header('reply-to'); + } + else if ($header == 'followupto' && !empty($MESSAGE->headers->others['mail-followup-to'])) { + $fvalue = $MESSAGE->get_header('mail-followup-to'); + } + } + + // split recipients and put them back together in a unique way + if (!empty($fvalue) && in_array($header, array('to', 'cc', 'bcc'))) { + $from_email = @mb_strtolower($MESSAGE->compose['ident']['email']); + $to_addresses = rcube_mime::decode_address_list($fvalue, null, $decode_header, $charset); + $fvalue = array(); + + foreach ($to_addresses as $addr_part) { + if (empty($addr_part['mailto'])) { + continue; + } + + // According to RFC5321 local part of email address is case-sensitive + // however, here it is better to compare addresses in case-insensitive manner + $mailto = format_email(rcube_utils::idn_to_utf8($addr_part['mailto'])); + $mailto_lc = mb_strtolower($addr_part['mailto']); + + if (($header == 'to' || $COMPOSE['mode'] != RCUBE_COMPOSE_REPLY || $mailto_lc != $from_email) + && !in_array($mailto_lc, (array) $MESSAGE->recipients) + ) { + if ($addr_part['name'] && $mailto != $addr_part['name']) { + $mailto = format_email_recipient($mailto, $addr_part['name']); + } + + $fvalue[] = $mailto; + $MESSAGE->recipients[] = $mailto_lc; + } + } + + $fvalue = implode($separator, $fvalue); + } + + return $fvalue; +} function rcmail_compose_editor_mode() { - global $RCMAIL, $compose_mode; + global $RCMAIL; static $useHtml; if ($useHtml !== null) { return $useHtml; } - $html_editor = intval($RCMAIL->config->get('htmleditor')); + $html_editor = intval($RCMAIL->config->get('htmleditor')); + $compose_mode = $COMPOSE['mode']; if (isset($_POST['_is_html'])) { $useHtml = !empty($_POST['_is_html']); @@ -713,7 +732,7 @@ function rcmail_prepare_message_body() { - global $RCMAIL, $MESSAGE, $COMPOSE, $compose_mode, $HTML_MODE; + global $RCMAIL, $MESSAGE, $COMPOSE, $HTML_MODE; // use posted message body if (!empty($_POST['_message'])) { @@ -725,20 +744,20 @@ $isHtml = (bool) $COMPOSE['param']['html']; } // forward as attachment - else if ($compose_mode == RCUBE_COMPOSE_FORWARD && $COMPOSE['as_attachment']) { + else if ($COMPOSE['mode'] == RCUBE_COMPOSE_FORWARD && $COMPOSE['as_attachment']) { $isHtml = rcmail_compose_editor_mode(); $body = ''; rcmail_write_forward_attachments(); } // reply/edit/draft/forward - else if ($compose_mode && ($compose_mode != RCUBE_COMPOSE_REPLY || intval($RCMAIL->config->get('reply_mode')) != -1)) { + else if ($COMPOSE['mode'] && ($COMPOSE['mode'] != RCUBE_COMPOSE_REPLY || intval($RCMAIL->config->get('reply_mode')) != -1)) { $isHtml = rcmail_compose_editor_mode(); $messages = array(); if (!empty($MESSAGE->parts)) { // collect IDs of message/rfc822 parts - if ($compose_mode == RCUBE_COMPOSE_EDIT || $compose_mode == RCUBE_COMPOSE_DRAFT) { + if ($COMPOSE['mode'] == RCUBE_COMPOSE_EDIT || $COMPOSE['mode'] == RCUBE_COMPOSE_DRAFT) { foreach ($MESSAGE->attachments as $part) { if ($part->mimetype == 'message/rfc822') { $messages[] = $part->mime_id; @@ -769,13 +788,13 @@ } // compose reply-body - if ($compose_mode == RCUBE_COMPOSE_REPLY) + if ($COMPOSE['mode'] == RCUBE_COMPOSE_REPLY) $body = rcmail_create_reply_body($body, $isHtml); // forward message body inline - else if ($compose_mode == RCUBE_COMPOSE_FORWARD) + else if ($COMPOSE['mode'] == RCUBE_COMPOSE_FORWARD) $body = rcmail_create_forward_body($body, $isHtml); // load draft message body - else if ($compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT) + else if ($COMPOSE['mode'] == RCUBE_COMPOSE_DRAFT || $COMPOSE['mode'] == RCUBE_COMPOSE_EDIT) $body = rcmail_create_draft_body($body, $isHtml); } else { // new message @@ -783,7 +802,7 @@ } $plugin = $RCMAIL->plugins->exec_hook('message_compose_body', - array('body' => $body, 'html' => $isHtml, 'mode' => $compose_mode)); + array('body' => $body, 'html' => $isHtml, 'mode' => $COMPOSE['mode'])); $body = $plugin['body']; unset($plugin); @@ -806,7 +825,7 @@ function rcmail_compose_part_body($part, $isHtml = false) { - global $RCMAIL, $MESSAGE, $LINE_LENGTH, $compose_mode; + global $RCMAIL, $MESSAGE, $LINE_LENGTH; // Check if we have enough memory to handle the message in it // #1487424: we need up to 10x more memory than the body @@ -830,7 +849,7 @@ } else { // try to remove the signature - if ($compose_mode != RCUBE_COMPOSE_DRAFT && $compose_mode != RCUBE_COMPOSE_EDIT) { + if ($COMPOSE['mode'] != RCUBE_COMPOSE_DRAFT && $COMPOSE['mode'] != RCUBE_COMPOSE_EDIT) { if ($RCMAIL->config->get('strip_existing_sig', true)) { $body = rcmail_remove_signature($body); } @@ -849,7 +868,7 @@ 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; + $len = $COMPOSE['mode'] == RCUBE_COMPOSE_REPLY ? $LINE_LENGTH-2 : $LINE_LENGTH; $txt = new rcube_html2text($body, false, true, $len); $body = $txt->get_text(); } @@ -859,7 +878,7 @@ } // try to remove the signature - if ($compose_mode != RCUBE_COMPOSE_DRAFT && $compose_mode != RCUBE_COMPOSE_EDIT) { + if ($COMPOSE['mode'] != RCUBE_COMPOSE_DRAFT && $COMPOSE['mode'] != RCUBE_COMPOSE_EDIT) { if ($RCMAIL->config->get('strip_existing_sig', true)) { $body = rcmail_remove_signature($body); } @@ -1158,7 +1177,7 @@ function rcmail_write_compose_attachments(&$message, $bodyIsHtml) { - global $RCMAIL, $COMPOSE, $compose_mode; + global $RCMAIL, $COMPOSE; $loaded_attachments = array(); foreach ((array)$COMPOSE['attachments'] as $attachment) { @@ -1176,12 +1195,12 @@ } // skip message attachments in reply mode - if ($part->ctype_primary == 'message' && $compose_mode == RCUBE_COMPOSE_REPLY) { + if ($part->ctype_primary == 'message' && $COMPOSE['mode'] == RCUBE_COMPOSE_REPLY) { continue; } // skip inline images when forwarding in text mode - if ($part->content_id && $part->disposition == 'inline' && !$bodyIsHtml && $compose_mode == RCUBE_COMPOSE_FORWARD) { + if ($part->content_id && $part->disposition == 'inline' && !$bodyIsHtml && $COMPOSE['mode'] == RCUBE_COMPOSE_FORWARD) { continue; } @@ -1191,12 +1210,12 @@ // skipped e.g. images used in HTML body or other attachments. So, // better to skip .eml attachments but not their content (included files). if ($part->mimetype == 'message/rfc822') { - if ($compose_mode == RCUBE_COMPOSE_FORWARD) { + if ($COMPOSE['mode'] == RCUBE_COMPOSE_FORWARD) { continue; } $messages[] = $part->mime_id; } - else if ($compose_mode != RCUBE_COMPOSE_FORWARD) { + else if ($COMPOSE['mode'] != RCUBE_COMPOSE_FORWARD) { // skip attachments included in message/rfc822 attachment (#1486487) foreach ($messages as $mimeid) { if (strpos($part->mime_id, $mimeid . '.') === 0) { @@ -1461,7 +1480,7 @@ function rcmail_compose_subject($attrib) { - global $MESSAGE, $COMPOSE, $compose_mode; + global $MESSAGE, $COMPOSE; list($form_start, $form_end) = get_form_tags($attrib); unset($attrib['form']); @@ -1480,7 +1499,7 @@ $subject = $COMPOSE['param']['subject']; } // create a reply-subject - else if ($compose_mode == RCUBE_COMPOSE_REPLY) { + else if ($COMPOSE['mode'] == RCUBE_COMPOSE_REPLY) { if (preg_match('/^re:/i', $MESSAGE->subject)) $subject = $MESSAGE->subject; else @@ -1490,14 +1509,14 @@ $subject = preg_replace('/\s*\([wW]as:[^\)]+\)\s*$/', '', $subject); } // create a forward-subject - else if ($compose_mode == RCUBE_COMPOSE_FORWARD) { + else if ($COMPOSE['mode'] == RCUBE_COMPOSE_FORWARD) { if (preg_match('/^fwd:/i', $MESSAGE->subject)) $subject = $MESSAGE->subject; else $subject = 'Fwd: '.$MESSAGE->subject; } // creeate a draft-subject - else if ($compose_mode == RCUBE_COMPOSE_DRAFT || $compose_mode == RCUBE_COMPOSE_EDIT) { + else if ($COMPOSE['mode'] == RCUBE_COMPOSE_DRAFT || $COMPOSE['mode'] == RCUBE_COMPOSE_EDIT) { $subject = $MESSAGE->subject; } @@ -1667,7 +1686,7 @@ function rcmail_mdn_checkbox($attrib) { - global $RCMAIL, $MESSAGE, $compose_mode; + global $RCMAIL, $MESSAGE; list($form_start, $form_end) = get_form_tags($attrib); unset($attrib['form']); @@ -1682,7 +1701,7 @@ if (isset($_POST['_mdn'])) $mdn_default = $_POST['_mdn']; - else if (in_array($compose_mode, array(RCUBE_COMPOSE_DRAFT, RCUBE_COMPOSE_EDIT))) + else 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'); diff --git a/skins/larry/settings.css b/skins/larry/settings.css index 83446f1..b02c6d5 100644 --- a/skins/larry/settings.css +++ b/skins/larry/settings.css @@ -334,6 +334,7 @@ #rcmfd_signature { width: 99%; min-width: 390px; + font-family: monospace; } #rcmfd_signature_toolbar1 td, diff --git a/tests/Framework/Html2text.php b/tests/Framework/Html2text.php index dee7670..be14882 100644 --- a/tests/Framework/Html2text.php +++ b/tests/Framework/Html2text.php @@ -51,6 +51,11 @@ 'in' => 'test<br> test', 'out' => "test\ntest", ), + 8 => array( + 'title' => ' handling test', + 'in' => '<div>eye: test<br /> tes: test</div>', + 'out' => "eye: test\ntes: test", + ), ); } @@ -113,4 +118,29 @@ $this->assertContains('QUOTED TEXT INNER 1 INNER 2 NO END', $res, 'No quoating on invalid html'); } + + function test_links() + { + $html = '<a href="http://test.com">content</a>'; + $expected = 'content [1] + +Links: +------ +[1] http://test.com +'; + + $ht = new rcube_html2text($html, false, true); + $res = $ht->get_text(); + + $this->assertSame($expected, $res, 'Links list'); + + // href == content (#1490434) + $html = '<a href="http://test.com">http://test.com</a>'; + $expected = 'http://test.com'; + + $ht = new rcube_html2text($html, false, true); + $res = $ht->get_text(); + + $this->assertSame($expected, $res, 'Skip link with href == content'); + } } -- Gitblit v1.9.1