diff --git a/lib/classes/message/inbound/handler.php b/lib/classes/message/inbound/handler.php index 3c8d7e8904c..fcf9c37ff79 100644 --- a/lib/classes/message/inbound/handler.php +++ b/lib/classes/message/inbound/handler.php @@ -237,4 +237,98 @@ abstract class handler { return false; } + /** + * Remove quoted message string from the text (NOT HTML) message. + * + * @param \stdClass $messagedata The Inbound Message record + * + * @return array message and message format to use. + */ + protected static function remove_quoted_text($messagedata) { + $linecount = self::get_linecount_to_remove($messagedata); + if (!empty($messagedata->plain)) { + $text = $messagedata->plain; + } else { + $text = html_to_text($messagedata->html); + } + $messageformat = FORMAT_PLAIN; + + $splitted = preg_split("/\n|\r/", $text); + if (empty($splitted)) { + return array($text, $messageformat); + } + + // Remove extra line. "Xyz wrote on...". + $count = 0; + $i = 0; + $flag = false; + foreach ($splitted as $i => $element) { + if (stripos($element, ">") === 0) { + // Quoted text found. + $flag = true; + // Remove 2 non empty line before this. + for ($j = $i - 1; ($j >= 0); $j--) { + $element = $splitted[$j]; + if (!empty($element)) { + unset($splitted[$j]); + $count++; + } + if ($count == $linecount) { + break; + } + } + break; + } + } + if ($flag) { + // Quoted text was found. + $k = $i - $linecount; // Where to start the chopping process. + + // Remove quoted text. + $splitted = array_slice($splitted, 0, $k); + + // Strip out empty lines towards the end, since a lot of clients add a huge chunk of empty lines. + $reverse = array_reverse($splitted); + foreach ($reverse as $i => $line) { + if (empty($line)) { + unset($reverse[$i]); + } else { + // Non empty line found. + break; + } + } + + $replaced = implode(PHP_EOL, array_reverse($reverse)); + $message = trim($replaced); + } else { + // No quoted text, fallback to original text. + if (!empty($messagedata->html)) { + $message = $messagedata->html; + $messageformat = FORMAT_HTML; + } else { + $message = $messagedata->plain; + } + } + return array($message, $messageformat); + } + + /** + * Try to guess how many lines to remove from the email to delete "xyz wrote on" text. Hard coded numbers for various email + * clients. + * Gmail uses two + * Evolution uses one + * Thunderbird uses one + * + * @param \stdClass $messagedata The Inbound Message record + * + * @return int number of lines to chop off before the start of quoted text. + */ + protected static function get_linecount_to_remove($messagedata) { + $linecount = 1; + if (!empty($messagedata->html) && stripos($messagedata->html, 'gmail_quote') !== false) { + // Gmail uses two lines. + $linecount = 2; + } + return $linecount; + } } diff --git a/mod/forum/classes/message/inbound/reply_handler.php b/mod/forum/classes/message/inbound/reply_handler.php index 1c094963799..7baab87c5f0 100644 --- a/mod/forum/classes/message/inbound/reply_handler.php +++ b/mod/forum/classes/message/inbound/reply_handler.php @@ -162,13 +162,9 @@ class reply_handler extends \core\message\inbound\handler { $addpost->parent = $post->id; $addpost->itemid = file_get_unused_draft_itemid(); - if (!empty($messagedata->html)) { - $addpost->message = $messagedata->html; - $addpost->messageformat = FORMAT_HTML; - } else { - $addpost->message = $messagedata->plain; - $addpost->messageformat = FORMAT_PLAIN; - } + list ($message, $format) = self::remove_quoted_text($messagedata); + $addpost->message = $message; + $addpost->messageformat = $format; // We don't trust text coming from e-mail. $addpost->messagetrust = false; @@ -288,7 +284,6 @@ class reply_handler extends \core\message\inbound\handler { return $fs->create_file_from_string($record, $attachment->content); } - /** * Return the content of any success notification to be sent. * Both an HTML and Plain Text variant must be provided. @@ -309,4 +304,75 @@ class reply_handler extends \core\message\inbound\handler { return $message; } + /** + * Remove quoted message string from the text message. + * + * @param string $text text message. + * @param int $linecount number of lines to remove before quoted text. + * @return mixed|string + */ + protected static function remove_quoted_text($text, $linecount = 1) { + $splitted = preg_split("/\n|\r/", $text); + if (empty($splitted)) { + return $text; + } + + // Remove extra line. "Xyz wrote on...". + $count = 0; + $i = 0; + foreach ($splitted as $i => $element) { + if (stripos($element, ">") === 0) { + // Remove 2 non empty line before this. + for ($j = $i - 1; ($j >= 0); $j--) { + $element = $splitted[$j]; + if (!empty($element)) { + unset($splitted[$j]); + $count++; + } + if ($count == $linecount) { + break; + } + } + break; + } + } + $k = $i - $linecount; // Where to start the chopping process. + + // Remove quoted text. + $splitted = array_slice($splitted, 0, $k); + + // Strip out empty lines towards the end, since a lot of clients add a huge chunk of empty lines. + $reverse = array_reverse($splitted); + foreach ($reverse as $i => $line) { + if (empty($line)) { + unset($reverse[$i]); + } else { + // Non empty line found. + break; + } + } + + $replaced = implode(PHP_EOL, array_reverse($reverse)); + return trim($replaced); + } + + /** + * Try to guess how many lines to remove from the email to delete "xyz wrote on" text. Hard coded numbers for various email + * clients. + * Gmail uses two + * Evolution uses one + * Thunderbird uses one + * + * @param \stdClass $messagedata The Inbound Message record + * + * @return int number of lines to chop off before the start of quoted text. + */ + protected static function get_linecount_to_remove($messagedata) { + $linecount = 1; + if (!empty($messagedata->html) && stripos($messagedata->html, 'gmail_quote') !== false) { + // Gmail uses two lines. + $linecount = 2; + } + return $linecount; + } } diff --git a/mod/forum/lang/en/forum.php b/mod/forum/lang/en/forum.php index 1c4e99a3706..dd596944731 100644 --- a/mod/forum/lang/en/forum.php +++ b/mod/forum/lang/en/forum.php @@ -417,7 +417,7 @@ $string['repliesmany'] = '{$a} replies so far'; $string['repliesone'] = '{$a} reply so far'; $string['reply'] = 'Reply'; $string['replyforum'] = 'Reply to forum'; -$string['replytopostbyemail'] = 'If you reply to this via email, don\'t include a quoted copy of this post. '; +$string['replytopostbyemail'] = 'You can reply to this via email.'; $string['replytouser'] = 'Use email address in reply'; $string['reply_handler'] = 'Reply to forum posts via email'; $string['reply_handler_name'] = 'Reply to forum posts';