MDL-64148 core: Make email greetings consistent
Some email body strings use first names as greetings, some use full names, and some do not. Using the first name for greeting makes it consistent and a bit more "personal".
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
issueNumber: MDL-64148
|
||||
notes:
|
||||
core:
|
||||
- message: >-
|
||||
Add \core_user::get_name_placeholders() to return an array of user name fields.
|
||||
type: improved
|
||||
@@ -29,7 +29,7 @@ Feature: A course welcome message will be sent to the user when they are enrolle
|
||||
Then I should see "Send course welcome message"
|
||||
And the field "Send course welcome message" matches value "From the course contact"
|
||||
And I should see "Custom welcome message"
|
||||
And the field "Custom welcome message" matches value "Dear {$a->fullname}, you have successfully been enrolled to course {$a->coursename}"
|
||||
And the field "Custom welcome message" matches value "Hi {$a->firstname}, you have successfully been enrolled to course {$a->coursename}"
|
||||
And I should see "Accepted formats: Plain text or Moodle-auto format. HTML tags and multi-lang tags are also accepted, as well as the following placeholders:"
|
||||
And I set the field "Send course welcome message" to "No"
|
||||
And I should not see "Custom welcome message"
|
||||
@@ -87,14 +87,14 @@ Feature: A course welcome message will be sent to the user when they are enrolle
|
||||
And I open the notification popover
|
||||
And I should see "Welcome to Course 1"
|
||||
And I click on "View full notification" "link" in the ".popover-region-notifications" "css_element"
|
||||
And I should see "Dear First User, you have successfully been enrolled to course Course 1"
|
||||
And I should see "Hi First, you have successfully been enrolled to course Course 1"
|
||||
# Login as second user and check the notification.
|
||||
And I am on the "C1" "course" page logged in as user2
|
||||
And I should see "1" in the "#nav-notification-popover-container [data-region='count-container']" "css_element"
|
||||
And I open the notification popover
|
||||
And I should see "Welcome to Course 2"
|
||||
And I click on "View full notification" "link" in the ".popover-region-notifications" "css_element"
|
||||
And I should see "Dear Second User, you have successfully been enrolled to course Course 2"
|
||||
And I should see "Hi Second, you have successfully been enrolled to course Course 2"
|
||||
|
||||
@javascript
|
||||
Scenario: Students should receive a welcome message if the setting is enabled - Custom message
|
||||
|
||||
@@ -843,7 +843,7 @@ class lib_test extends \advanced_testcase {
|
||||
get_string(
|
||||
'customwelcomemessageplaceholder',
|
||||
'core_enrol',
|
||||
['fullname' => fullname($student), 'coursename' => $course->fullname],
|
||||
['firstname' => $student->firstname, 'coursename' => $course->fullname],
|
||||
),
|
||||
$message->fullmessage,
|
||||
);
|
||||
|
||||
@@ -34,7 +34,7 @@ Feature: A course welcome message will be sent to the user when they auto-enrol
|
||||
Then I should see "Send course welcome message"
|
||||
And the field "Send course welcome message" matches value "From the course contact"
|
||||
And I should see "Custom welcome message"
|
||||
And the field "Custom welcome message" matches value "Dear {$a->fullname}, you have successfully been enrolled to course {$a->coursename}"
|
||||
And the field "Custom welcome message" matches value "Hi {$a->firstname}, you have successfully been enrolled to course {$a->coursename}"
|
||||
And I should see "Accepted formats: Plain text or Moodle-auto format. HTML tags and multi-lang tags are also accepted, as well as the following placeholders:"
|
||||
And I set the field "Send course welcome message" to "No"
|
||||
And I should not see "Custom welcome message"
|
||||
@@ -73,7 +73,7 @@ Feature: A course welcome message will be sent to the user when they auto-enrol
|
||||
And I open the notification popover
|
||||
And I should see "Welcome to Course 1"
|
||||
And I click on "View full notification" "link" in the ".popover-region-notifications" "css_element"
|
||||
And I should see "Dear First User, you have successfully been enrolled to course Course 1"
|
||||
And I should see "Hi First, you have successfully been enrolled to course Course 1"
|
||||
# Login as second user and check the notification.
|
||||
And I log in as "user2"
|
||||
And I am on "Course 2" course homepage
|
||||
@@ -82,7 +82,7 @@ Feature: A course welcome message will be sent to the user when they auto-enrol
|
||||
And I open the notification popover
|
||||
And I should see "Welcome to Course 2"
|
||||
And I click on "View full notification" "link" in the ".popover-region-notifications" "css_element"
|
||||
And I should see "Dear Second User, you have successfully been enrolled to course Course 2"
|
||||
And I should see "Hi Second, you have successfully been enrolled to course Course 2"
|
||||
|
||||
@javascript
|
||||
Scenario: Students should receive a welcome message if the setting is enabled - Custom message
|
||||
|
||||
@@ -1827,4 +1827,45 @@ class enrollib_test extends advanced_testcase {
|
||||
$modifiedinstance = $manualplugin->update_enrol_plugin_data($course->id, $enrolmentdata, $instance);
|
||||
$this->assertEquals($expectedinstance, $modifiedinstance);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test case for checking the email greetings in various user notification emails.
|
||||
*
|
||||
* @covers \enrol_plugin::send_course_welcome_message_to_user
|
||||
*/
|
||||
public function test_email_greetings(): void {
|
||||
global $DB;
|
||||
$this->resetAfterTest();
|
||||
|
||||
// Create course.
|
||||
$course = $this->getDataGenerator()->create_course([
|
||||
'fullname' => 'Course 1',
|
||||
'shortname' => 'C1',
|
||||
]);
|
||||
// Create user.
|
||||
$student = $this->getDataGenerator()->create_user();
|
||||
// Get manual plugin.
|
||||
$manualplugin = enrol_get_plugin('manual');
|
||||
$maninstance = $DB->get_record(
|
||||
'enrol',
|
||||
['courseid' => $course->id, 'enrol' => 'manual'],
|
||||
'*',
|
||||
MUST_EXIST,
|
||||
);
|
||||
|
||||
$messagesink = $this->redirectMessages();
|
||||
$manualplugin->send_course_welcome_message_to_user(
|
||||
instance: $maninstance,
|
||||
userid: $student->id,
|
||||
sendoption: ENROL_SEND_EMAIL_FROM_NOREPLY,
|
||||
message: '',
|
||||
);
|
||||
$messages = $messagesink->get_messages_by_component_and_type(
|
||||
'moodle',
|
||||
'enrolcoursewelcomemessage',
|
||||
);
|
||||
$this->assertNotEmpty($messages);
|
||||
$message = reset($messages);
|
||||
$this->assertStringContainsString('Hi ' . $student->firstname, quoted_printable_decode($message->fullmessage));
|
||||
}
|
||||
}
|
||||
|
||||
+3
-1
@@ -815,7 +815,9 @@ $string['locationsettings'] = 'Location settings';
|
||||
$string['locked'] = 'Locked';
|
||||
$string['lockoutduration'] = 'Account lockout duration';
|
||||
$string['lockoutduration_desc'] = 'Locked out account is automatically unlocked after this duration.';
|
||||
$string['lockoutemailbody'] = 'Your account with username {$a->username} on server \'{$a->sitename}\'
|
||||
$string['lockoutemailbody'] = 'Hi {$a->firstname},
|
||||
|
||||
Your account with username {$a->username} on server \'{$a->sitename}\'
|
||||
was locked out after multiple invalid login attempts.
|
||||
|
||||
To unlock the account immediately go to the following address
|
||||
|
||||
+1
-1
@@ -77,7 +77,7 @@ $string['emailchangecancel'] = 'Cancel email change';
|
||||
$string['emailchangepending'] = 'Change pending. Open the link sent to you at {$a->preference_newemail}.';
|
||||
$string['emailnowexists'] = 'The email address you tried to assign to your profile has been assigned to someone else since your original request. Your request for change of email address is hereby cancelled, but you may try again with a different address.';
|
||||
$string['emailupdate'] = 'Email address update';
|
||||
$string['emailupdatemessage'] = 'Dear {$a->fullname},
|
||||
$string['emailupdatemessage'] = 'Hi {$a->firstname},
|
||||
|
||||
You have requested a change of your email address for your account on {$a->site}. To confirm this change, please go to the following web address:
|
||||
|
||||
|
||||
+1
-1
@@ -45,7 +45,7 @@ $string['customwelcomemessage_help'] = 'Accepted formats: Plain text or Moodle-a
|
||||
<li>User last name {$a->lastname}</li>
|
||||
<li>User course role {$a->courserole}</li>
|
||||
</ul>';
|
||||
$string['customwelcomemessageplaceholder'] = 'Dear {$a->fullname}, you have successfully been enrolled to course {$a->coursename}';
|
||||
$string['customwelcomemessageplaceholder'] = 'Hi {$a->firstname}, you have successfully been enrolled to course {$a->coursename}';
|
||||
$string['defaultenrol'] = 'Add instance to new courses';
|
||||
$string['defaultenrol_desc'] = 'It is possible to add this plugin to all new courses by default.';
|
||||
$string['deleteinstanceconfirm'] = 'You are about to delete the enrolment method "{$a->name}". All {$a->users} users currently enrolled using this method will be unenrolled and any course-related data such as users\' grades, group membership or forum subscriptions will be deleted.
|
||||
|
||||
+3
-3
@@ -643,7 +643,7 @@ $string['emailalreadysent'] = 'A password reset email has already been sent. Ple
|
||||
$string['emailactive'] = 'Email activated';
|
||||
$string['emailagain'] = 'Email (again)';
|
||||
$string['emailconfirm'] = 'Confirm your account';
|
||||
$string['emailconfirmation'] = 'Hi,
|
||||
$string['emailconfirmation'] = 'Hi {$a->firstname},
|
||||
|
||||
A new account has been requested at \'{$a->sitename}\'
|
||||
using your email address.
|
||||
@@ -2501,8 +2501,6 @@ $string['coursesearch_help'] = 'You can search for multiple words at once and ca
|
||||
// Deprecated since Moodle 4.5.
|
||||
$string['commentscount'] = 'Comments ({$a})';
|
||||
$string['datechanged'] = 'Date changed';
|
||||
$string['registrationcontactno'] = 'No, I do not want to be contacted by other people';
|
||||
$string['registrationcontactyes'] = 'Yes, provide a form for other Moodlers to contact me';
|
||||
$string['newpasswordtext'] = 'Hi {$a->firstname},
|
||||
|
||||
Your account password at \'{$a->sitename}\' has been reset
|
||||
@@ -2522,3 +2520,5 @@ line at the top of your web browser window.
|
||||
|
||||
Cheers from the \'{$a->sitename}\' administrator,
|
||||
{$a->signoff}';
|
||||
$string['registrationcontactno'] = 'No, I do not want to be contacted by other people';
|
||||
$string['registrationcontactyes'] = 'Yes, provide a form for other Moodlers to contact me';
|
||||
|
||||
@@ -1589,4 +1589,20 @@ class core_user {
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an array of name placeholders for a given user.
|
||||
*
|
||||
* @param stdClass $user The user object containing name fields.
|
||||
* @return array An associative array of name placeholders.
|
||||
*/
|
||||
public static function get_name_placeholders(stdClass $user): array {
|
||||
$namefields = [
|
||||
'fullname' => fullname($user),
|
||||
'alternativefullname' => fullname($user, true),
|
||||
];
|
||||
foreach (fields::get_name_fields() as $namefield) {
|
||||
$namefields[$namefield] = $user->{$namefield};
|
||||
}
|
||||
return $namefields;
|
||||
}
|
||||
}
|
||||
|
||||
+5
-1
@@ -3670,7 +3670,11 @@ abstract class enrol_plugin {
|
||||
'course' => $instance->courseid,
|
||||
],
|
||||
))->out();
|
||||
$a->fullname = fullname($user);
|
||||
|
||||
$placeholders = \core_user::get_name_placeholders($user);
|
||||
foreach ($placeholders as $field => $value) {
|
||||
$a->{$field} = $value;
|
||||
}
|
||||
|
||||
if ($message && trim($message) !== '') {
|
||||
$placeholders = [
|
||||
|
||||
+17
-5
@@ -6039,7 +6039,10 @@ function setnew_password_and_mail($user, $fasthash = false) {
|
||||
update_internal_user_password($user, $newpassword, $fasthash);
|
||||
|
||||
$a = new stdClass();
|
||||
$a->firstname = fullname($user, true);
|
||||
$placeholders = \core_user::get_name_placeholders($user);
|
||||
foreach ($placeholders as $field => $value) {
|
||||
$a->{$field} = $value;
|
||||
}
|
||||
$a->sitename = format_string($site->fullname);
|
||||
$a->username = $user->username;
|
||||
$a->newpassword = $newpassword;
|
||||
@@ -6071,6 +6074,11 @@ function send_confirmation_email($user, $confirmationurl = null) {
|
||||
$data = new stdClass();
|
||||
$data->sitename = format_string($site->fullname);
|
||||
$data->admin = generate_email_signoff();
|
||||
// Add user name fields to $data based on $user.
|
||||
$placeholders = \core_user::get_name_placeholders($user);
|
||||
foreach ($placeholders as $field => $value) {
|
||||
$data->{$field} = $value;
|
||||
}
|
||||
|
||||
$subject = get_string('emailconfirmationsubject', '', format_string($site->fullname));
|
||||
|
||||
@@ -6116,8 +6124,10 @@ function send_password_change_confirmation_email($user, $resetrecord) {
|
||||
$pwresetmins = isset($CFG->pwresettime) ? floor($CFG->pwresettime / MINSECS) : 30;
|
||||
|
||||
$data = new stdClass();
|
||||
$data->firstname = $user->firstname;
|
||||
$data->lastname = $user->lastname;
|
||||
$placeholders = \core_user::get_name_placeholders($user);
|
||||
foreach ($placeholders as $field => $value) {
|
||||
$data->{$field} = $value;
|
||||
}
|
||||
$data->username = $user->username;
|
||||
$data->sitename = format_string($site->fullname);
|
||||
$data->link = $CFG->wwwroot .'/login/forgot_password.php?token='. $resetrecord->token;
|
||||
@@ -6143,8 +6153,10 @@ function send_password_change_info($user) {
|
||||
$supportuser = core_user::get_support_user();
|
||||
|
||||
$data = new stdClass();
|
||||
$data->firstname = $user->firstname;
|
||||
$data->lastname = $user->lastname;
|
||||
$placeholders = \core_user::get_name_placeholders($user);
|
||||
foreach ($placeholders as $field => $value) {
|
||||
$data->{$field} = $value;
|
||||
}
|
||||
$data->username = $user->username;
|
||||
$data->sitename = format_string($site->fullname);
|
||||
$data->admin = generate_email_signoff();
|
||||
|
||||
@@ -549,4 +549,22 @@ class authlib_test extends \advanced_testcase {
|
||||
$this->assertEquals(count($plugins), 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test case for checking the email greetings in account lockout notification emails.
|
||||
*
|
||||
* @covers ::login_lock_account()
|
||||
*/
|
||||
public function test_email_greetings(): void {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
|
||||
$sink = $this->redirectEmails(); // Make sure we are redirecting emails.
|
||||
login_lock_account($user);
|
||||
$result = $sink->get_messages();
|
||||
$sink->close();
|
||||
// Test greetings.
|
||||
$this->assertStringContainsString('Hi ' . $user->firstname, quoted_printable_decode($result[0]->body));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5593,4 +5593,45 @@ EOT;
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test case for checking the email greetings in various user notification emails.
|
||||
*
|
||||
* @dataProvider email_greetings_provider
|
||||
* @param string $funcname The name of the function to call for sending the email.
|
||||
* @param mixed $extra Any extra parameter required by the function.
|
||||
* @covers ::send_password_change_info()
|
||||
* @covers ::send_confirmation_email()
|
||||
* @covers ::setnew_password_and_mail()
|
||||
* @covers ::send_password_change_confirmation_email()
|
||||
*/
|
||||
public function test_email_greetings($funcname, $extra): void {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
|
||||
$sink = $this->redirectEmails(); // Make sure we are redirecting emails.
|
||||
$funcname($user, $extra);
|
||||
$result = $sink->get_messages();
|
||||
$sink->close();
|
||||
// Test greetings.
|
||||
$this->assertStringContainsString('Hi ' . $user->firstname, quoted_printable_decode($result[0]->body));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test_email_greetings tests.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function email_greetings_provider(): array {
|
||||
$extrasendpasswordchangeconfirmationemail = new \stdClass();
|
||||
$extrasendpasswordchangeconfirmationemail->token = '123';
|
||||
|
||||
return [
|
||||
['send_password_change_info', null],
|
||||
['send_confirmation_email', null],
|
||||
['setnew_password_and_mail', false],
|
||||
['send_password_change_confirmation_email', $extrasendpasswordchangeconfirmationemail],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
+6
-1
@@ -263,7 +263,12 @@ if ($userform->is_cancelled()) {
|
||||
$a = new stdClass();
|
||||
$a->url = $CFG->wwwroot . '/user/emailupdate.php?key=' . $emailchangedkey . '&id=' . $user->id;
|
||||
$a->site = format_string($SITE->fullname, true, array('context' => context_course::instance(SITEID)));
|
||||
$a->fullname = fullname($tempuser, true);
|
||||
|
||||
$placeholders = \core_user::get_name_placeholders($user);
|
||||
foreach ($placeholders as $field => $value) {
|
||||
$a->{$field} = $value;
|
||||
}
|
||||
|
||||
$a->supportemail = $OUTPUT->supportemail();
|
||||
|
||||
$emailupdatemessage = get_string('emailupdatemessage', 'auth', $a);
|
||||
|
||||
@@ -1048,4 +1048,39 @@ class userlib_test extends \advanced_testcase {
|
||||
$this->assertCount(1, $result['groups']);
|
||||
$this->assertEquals($group2->id, $result['groups'][0]['id']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that the get_name_placeholders function correctly generates
|
||||
* an array of name placeholders for a given user object.
|
||||
*
|
||||
* @covers ::get_name_placeholders()
|
||||
*/
|
||||
public function test_get_name_placeholders(): void {
|
||||
$this->resetAfterTest();
|
||||
|
||||
// Set format for fullname and alternativefullname.
|
||||
set_config('fullnamedisplay', 'firstname, lastname');
|
||||
set_config('alternativefullnameformat', 'firstnamephonetic lastnamephonetic');
|
||||
|
||||
// Create the target user.
|
||||
$user = $this->getDataGenerator()->create_user([
|
||||
'firstname' => 'FN',
|
||||
'lastname' => 'LN',
|
||||
'firstnamephonetic' => 'FNP',
|
||||
'lastnamephonetic' => 'LNP',
|
||||
'middlename' => 'MN',
|
||||
'alternatename' => 'AN',
|
||||
]);
|
||||
|
||||
// Add user name fields to $a as an object based on $user.
|
||||
$a = new \stdClass();
|
||||
$placeholders = \core_user::get_name_placeholders($user);
|
||||
foreach ($placeholders as $field => $value) {
|
||||
$a->{$field} = $value;
|
||||
}
|
||||
$this->assertEquals("Hello $a->firstname", "Hello FN");
|
||||
$this->assertEquals("Bonjour $a->fullname", "Bonjour FN, LN");
|
||||
$this->assertEquals("Privyet $a->alternativefullname", "Privyet FNP LNP");
|
||||
$this->assertEquals("Hola $a->alternatename '$a->middlename' $a->lastname", "Hola AN 'MN' LN");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user