Skip to content

Commit

Permalink
MDL-48002 inbound: Remove quoted text from forum emails
Browse files Browse the repository at this point in the history
  • Loading branch information
ankitagarwal committed May 4, 2015
1 parent 24a2bab commit aef3c18
Show file tree
Hide file tree
Showing 3 changed files with 169 additions and 9 deletions.
94 changes: 94 additions & 0 deletions lib/classes/message/inbound/handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -237,4 +237,98 @@ public function get_success_message(\stdClass $messagedata, $handlerresult) {
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;
}
}
82 changes: 74 additions & 8 deletions mod/forum/classes/message/inbound/reply_handler.php
Original file line number Diff line number Diff line change
Expand Up @@ -162,13 +162,9 @@ public function process_message(\stdClass $record, \stdClass $messagedata) {
$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;
Expand Down Expand Up @@ -288,7 +284,6 @@ protected function process_attachment($acceptedtypes, \context_user $context, $i
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.
Expand All @@ -309,4 +304,75 @@ public function get_success_message(\stdClass $messagedata, $handlerresult) {
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;
}
}
2 changes: 1 addition & 1 deletion mod/forum/lang/en/forum.php
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@
$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';
Expand Down

0 comments on commit aef3c18

Please sign in to comment.