summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG1
-rw-r--r--program/include/rcube_message.php42
-rw-r--r--program/steps/mail/compose.inc116
3 files changed, 109 insertions, 50 deletions
diff --git a/CHANGELOG b/CHANGELOG
index dd7568cbc..2b52fe19f 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,7 @@
CHANGELOG Roundcube Webmail
===========================
+- Fix issue where some text from original message was missing on reply (#1488340)
- Fix parse errors in DDL files for MS SQL Server
- Make contacts list sorting configurable for the admin/user
- Revert SORT=DISPLAY support, removed by mistake (#1488327)
diff --git a/program/include/rcube_message.php b/program/include/rcube_message.php
index d0959efe0..ee1e92de1 100644
--- a/program/include/rcube_message.php
+++ b/program/include/rcube_message.php
@@ -188,15 +188,36 @@ class rcube_message
/**
* Determine if the message contains a HTML part
*
+ * @param bool $recursive Enables checking in all levels of the structure
+ *
* @return bool True if a HTML is available, False if not
*/
- function has_html_part()
+ function has_html_part($recursive = true)
{
// check all message parts
- foreach ($this->parts as $pid => $part) {
- $mimetype = strtolower($part->ctype_primary . '/' . $part->ctype_secondary);
- if ($mimetype == 'text/html')
+ foreach ($this->parts as $part) {
+ if ($part->mimetype == 'text/html') {
+ // Level check, we'll skip e.g. HTML attachments
+ if (!$recursive) {
+ $level = explode('.', $part->mime_id);
+
+ // Level too high
+ if (count($level) > 2) {
+ continue;
+ }
+
+ // HTML part can be on the lower level, if not...
+ if (count($level) > 1) {
+ // It can be an alternative or related message part
+ $parent = $this->mime_parts[0];
+ if ($parent->mimetype != 'multipart/alternative' && $parent->mimetype != 'multipart/related') {
+ continue;
+ }
+ }
+ }
+
return true;
+ }
}
return false;
@@ -211,10 +232,9 @@ class rcube_message
function first_html_part()
{
// check all message parts
- foreach ($this->mime_parts as $mime_id => $part) {
- $mimetype = strtolower($part->ctype_primary . '/' . $part->ctype_secondary);
- if ($mimetype == 'text/html') {
- return $this->get_part_content($mime_id);
+ foreach ($this->mime_parts as $pid => $part) {
+ if ($part->mimetype == 'text/html') {
+ return $this->get_part_content($pid);
}
}
}
@@ -234,12 +254,10 @@ class rcube_message
// check all message parts
foreach ($this->mime_parts as $mime_id => $part) {
- $mimetype = $part->ctype_primary . '/' . $part->ctype_secondary;
-
- if ($mimetype == 'text/plain') {
+ if ($part->mimetype == 'text/plain') {
return $this->get_part_content($mime_id);
}
- else if ($mimetype == 'text/html') {
+ else if ($part->mimetype == 'text/html') {
$out = $this->get_part_content($mime_id);
// remove special chars encoding
diff --git a/program/steps/mail/compose.inc b/program/steps/mail/compose.inc
index cbef36884..47342276e 100644
--- a/program/steps/mail/compose.inc
+++ b/program/steps/mail/compose.inc
@@ -587,10 +587,10 @@ function rcmail_compose_editor_mode()
$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
$useHtml = ($html_editor == 1);
@@ -622,40 +622,21 @@ function rcmail_prepare_message_body()
}
// reply/edit/draft/forward
else if ($compose_mode) {
- $has_html_part = $MESSAGE->has_html_part();
$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) {
+ if ($part->type != 'content' || !$part->size) {
+ 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_mime::unfold_flowed($body);
- }
- }
+ $body = rcmail_compose_part_body($MESSAGE, $isHtml);
}
// compose reply-body
@@ -692,6 +673,70 @@ function rcmail_prepare_message_body()
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)
{
global $RCMAIL, $CONFIG, $OUTPUT, $MESSAGE, $compose_mode, $LINE_LENGTH, $HTML_MODE, $MESSAGE_BODY;
@@ -828,10 +873,6 @@ function rcmail_create_reply_body($body, $bodyIsHtml)
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);
@@ -955,7 +996,8 @@ function rcmail_remove_signature($body)
{
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) {
@@ -1546,5 +1588,3 @@ $OUTPUT->add_handlers(array(
));
$OUTPUT->send('compose');
-
-