Merge branch 'MDL-53102-messageid' of https://github.com/brendanheywood/moodle

This commit is contained in:
David Monllao 2016-03-14 14:17:41 +08:00
commit c854ce6eb7
4 changed files with 95 additions and 10 deletions

View File

@ -5460,6 +5460,37 @@ function email_should_be_diverted($email) {
return true;
}
/**
* Generate a unique email Message-ID using the moodle domain and install path
*
* @param string $localpart An optional unique message id prefix.
* @return string The formatted ID ready for appending to the email headers.
*/
function generate_email_messageid($localpart = null) {
global $CFG;
$urlinfo = parse_url($CFG->wwwroot);
$base = '@' . $urlinfo['host'];
// If multiple moodles are on the same domain we want to tell them
// apart so we add the install path to the local part. This means
// that the id local part should never contain a / character so
// we can correctly parse the id to reassemble the wwwroot.
if (isset($urlinfo['path'])) {
$base = $urlinfo['path'] . $base;
}
if (empty($localpart)) {
$localpart = uniqid('', true);
}
// Because we may have an option /installpath suffix to the local part
// of the id we need to escape any / chars which are in the $localpart.
$localpart = str_replace('/', '%2F', $localpart);
return '<' . $localpart . $base . '>';
}
/**
* Send an email to a specified user
*
@ -5682,6 +5713,11 @@ function email_to_user($user, $from, $subject, $messagetext, $messagehtml = '',
$mail->FromName = $renderer->render_from_template('core/email_fromname', $context);
$messagetext = $renderer->render_from_template('core/email_text', $context);
// Autogenerate a MessageID if it's missing.
if (empty($mail->MessageID)) {
$mail->MessageID = generate_email_messageid();
}
if ($messagehtml && !empty($user->mailformat) && $user->mailformat == 1) {
// Don't ever send HTML to users who don't want it.
$mail->isHTML(true);

View File

@ -2644,7 +2644,50 @@ class core_moodlelib_testcase extends advanced_testcase {
$this->assertEventContextNotUsed($event);
}
/**
* A data provider for testing email messageid
*/
public function generate_email_messageid_provider() {
return array(
'nopath' => array(
'wwwroot' => 'http://www.example.com',
'ids' => array(
'a-custom-id' => '<a-custom-id@www.example.com>',
'an-id-with-/-a-slash' => '<an-id-with-%2F-a-slash@www.example.com>',
),
),
'path' => array(
'wwwroot' => 'http://www.example.com/path/subdir',
'ids' => array(
'a-custom-id' => '<a-custom-id/path/subdir@www.example.com>',
'an-id-with-/-a-slash' => '<an-id-with-%2F-a-slash/path/subdir@www.example.com>',
),
),
);
}
/**
* Test email message id generation
*
* @dataProvider generate_email_messageid_provider
*
* @param string $wwwroot The wwwroot
* @param array $msgids An array of msgid local parts and the final result
*/
public function test_generate_email_messageid($wwwroot, $msgids) {
global $CFG;
$this->resetAfterTest();
$CFG->wwwroot = $wwwroot;
foreach ($msgids as $local => $final) {
$this->assertEquals($final, generate_email_messageid($local));
}
}
/**
* A data provider for testing email diversion
*/
public function diverted_emails_provider() {
return array(
'nodiverts' => array(
@ -2697,7 +2740,14 @@ class core_moodlelib_testcase extends advanced_testcase {
}
/**
* Test email diversion
*
* @dataProvider diverted_emails_provider
*
* @param string $divertallemailsto An optional email address
* @param string $divertallemailsexcept An optional exclusion list
* @param array $addresses An array of test addresses
* @param boolean $expected Expected result
*/
public function test_email_should_be_diverted($divertallemailsto, $divertallemailsexcept, $addresses, $expected) {
global $CFG;

View File

@ -410,11 +410,10 @@ WHERE
*
* @param int $postid The ID of the forum post we are notifying the user about
* @param int $usertoid The ID of the user being notified
* @param string $hostname The server's hostname
* @return string A unique message-id
*/
function forum_get_email_message_id($postid, $usertoid, $hostname) {
return '<'.hash('sha256',$postid.'to'.$usertoid).'@'.$hostname.'>';
function forum_get_email_message_id($postid, $usertoid) {
return generate_email_messageid(hash('sha256', $postid . 'to' . $usertoid));
}
/**
@ -596,9 +595,6 @@ function forum_cron() {
if ($users && $posts) {
$urlinfo = parse_url($CFG->wwwroot);
$hostname = $urlinfo['host'];
foreach ($users as $userto) {
// Terminate if processing of any account takes longer than 2 minutes.
core_php_time_limit::raise(120);
@ -751,9 +747,9 @@ function forum_cron() {
$userfrom->customheaders = array (
// Headers to make emails easier to track.
'List-Id: "' . $cleanforumname . '" <moodleforum' . $forum->id . '@' . $hostname.'>',
'List-Id: "' . $cleanforumname . '" ' . generate_email_messageid('moodleforum' . $forum->id),
'List-Help: ' . $CFG->wwwroot . '/mod/forum/view.php?f=' . $forum->id,
'Message-ID: ' . forum_get_email_message_id($post->id, $userto->id, $hostname),
'Message-ID: ' . forum_get_email_message_id($post->id, $userto->id),
'X-Course-Id: ' . $course->id,
'X-Course-Name: ' . format_string($course->fullname, true),
@ -810,11 +806,11 @@ function forum_cron() {
$a->courseshortname = $data->get_coursename();
$postsubject = html_to_text(get_string('postmailsubject', 'forum', $a), 0);
$rootid = forum_get_email_message_id($discussion->firstpost, $userto->id, $hostname);
$rootid = forum_get_email_message_id($discussion->firstpost, $userto->id);
if ($post->parent) {
// This post is a reply, so add reply header (RFC 2822).
$parentid = forum_get_email_message_id($post->parent, $userto->id, $hostname);
$parentid = forum_get_email_message_id($post->parent, $userto->id);
$userfrom->customheaders[] = "In-Reply-To: $parentid";
// If the post is deeply nested we also reference the parent message id and

View File

@ -1,6 +1,9 @@
This files describes API changes in /mod/forum/*,
information provided here is intended especially for developers.
=== 3.1 ===
* The inteface to forum_get_email_message_id() has changed and no longer needs the $host argument.
=== 3.0 ===
* External function get_forums_by_courses now returns and additional field "cancreatediscussions" that indicates if the user
can create discussions in the forum.