MDL-84960 core: Added initials to the user structures

This commit is contained in:
Daniel Ureña
2026-03-11 09:38:53 +01:00
parent 00beb65e6e
commit 752a75008a
21 changed files with 545 additions and 15 deletions
@@ -0,0 +1,30 @@
issueNumber: MDL-84960
notes:
core:
- message: >-
Several core web services now include a new initials field in user data
structures. This change is backward-compatible and only adds an optional
field; no existing fields or field semantics have been changed.
Client applications should ensure they can handle the additional initials
field in web service responses, but clients that ignore unknown fields can
continue working without changes. The affected web services are:
- core_enrol_get_enrolled_users
- core_enrol_get_enrolled_users_with_capability
- core_enrol_get_potential_users
- core_enrol_search_users
- core_user_get_users_by_field
- core_user_get_users
- core_user_get_course_user_profiles
- core_grades_get_enrolled_users_for_selector
- core_grades_get_gradable_users
- gradereport_grader_get_users_in_report
- core_message_get_contact_requests
- core_message_get_conversation_members
- core_message_message_search_users
- core_message_get_user_contacts
- core_message_get_member_info
- core_message_get_conversation_messages
- mod_assign_list_participants
- mod_assign_get_participant
- mod_forum_get_forum_discussions
type: improved
+44 -5
View File
@@ -103,6 +103,7 @@ class core_enrol_external extends external_api {
$groupid = 0;
$onlyactive = false;
$userfields = array();
$includeinitials = false;
$limitfrom = 0;
$limitnumber = 0;
foreach ($params['options'] as $option) {
@@ -115,8 +116,12 @@ class core_enrol_external extends external_api {
break;
case 'userfields':
$thefields = explode(',', $option['value']);
foreach ($thefields as $f) {
$userfields[] = clean_param($f, PARAM_ALPHANUMEXT);
foreach ($thefields as $field) {
$clean = clean_param($field, PARAM_ALPHANUMEXT);
if ($clean === '') {
continue;
}
$userfields[] = $clean;
}
break;
case 'limitfrom' :
@@ -163,6 +168,17 @@ class core_enrol_external extends external_api {
// To see the permissions of others role:review capability is required.
require_capability('moodle/role:review', $coursecontext);
// Decide when to include initials.
if (empty($userfields)) {
$includeinitials = true;
} else {
$key = array_search('initials', $userfields, true);
if ($key !== false) {
unset($userfields[$key]);
$includeinitials = true;
}
}
foreach ($coursecapability['capabilities'] as $capability) {
$courseusers['courseid'] = $courseid;
$courseusers['capability'] = $capability;
@@ -180,6 +196,9 @@ class core_enrol_external extends external_api {
$users = array();
foreach ($enrolledusers as $courseuser) {
if ($userdetails = user_get_user_details($courseuser, $course, $userfields)) {
if ($includeinitials) {
$userdetails['initials'] = core_user::get_initials($courseuser);
}
$users[] = $userdetails;
}
}
@@ -209,6 +228,7 @@ class core_enrol_external extends external_api {
'username' => new external_value(PARAM_RAW, 'Username', VALUE_OPTIONAL),
'firstname' => new external_value(PARAM_NOTAGS, 'The first name(s) of the user', VALUE_OPTIONAL),
'lastname' => new external_value(PARAM_NOTAGS, 'The family name of the user', VALUE_OPTIONAL),
'initials' => new external_value(PARAM_NOTAGS, 'The initials of the user', VALUE_OPTIONAL),
'fullname' => new external_value(PARAM_NOTAGS, 'The fullname of the user'),
'email' => new external_value(PARAM_TEXT, 'Email address', VALUE_OPTIONAL),
'address' => new external_value(PARAM_TEXT, 'Postal address', VALUE_OPTIONAL),
@@ -599,6 +619,7 @@ class core_enrol_external extends external_api {
}
$userdetails['customfields'] = array_values($userdetails['customfields']);
}
$userdetails['initials'] = core_user::get_initials($user);
$results[] = $userdetails;
}
}
@@ -699,6 +720,7 @@ class core_enrol_external extends external_api {
);
foreach ($users['users'] as $user) {
if ($userdetails = user_get_user_details($user, $course, $requiredfields)) {
$userdetails['initials'] = core_user::get_initials($user);
$results[] = $userdetails;
}
}
@@ -782,6 +804,7 @@ class core_enrol_external extends external_api {
$onlyactive = false;
$onlysuspended = false;
$userfields = [];
$includeinitials = false;
$limitfrom = 0;
$limitnumber = 0;
$sortby = 'us.id';
@@ -803,8 +826,12 @@ class core_enrol_external extends external_api {
break;
case 'userfields':
$thefields = explode(',', $option['value']);
foreach ($thefields as $f) {
$userfields[] = clean_param($f, PARAM_ALPHANUMEXT);
foreach ($thefields as $field) {
$clean = clean_param($field, PARAM_ALPHANUMEXT);
if ($clean === '') {
continue;
}
$userfields[] = $clean;
}
break;
case 'limitfrom' :
@@ -853,6 +880,16 @@ class core_enrol_external extends external_api {
}
course_require_view_participants($context);
// Decide when to include initials.
if (empty($userfields)) {
$includeinitials = true;
} else {
$key = array_search('initials', $userfields, true);
if ($key !== false) {
unset($userfields[$key]);
$includeinitials = true;
}
}
// to overwrite this parameter, you need role:review capability
if ($withcapability) {
@@ -912,7 +949,8 @@ class core_enrol_external extends external_api {
$userpicture = new user_picture($user);
$userpicture->size = 1;
$userdetails['profileimageurl'] = $userpicture->get_url($PAGE)->out(false);
}
}
$userdetails['initials'] = core_user::get_initials($user);
$users[] = $userdetails;
}
$enrolledusers->close();
@@ -933,6 +971,7 @@ class core_enrol_external extends external_api {
'username' => new external_value(PARAM_RAW, 'Username policy is defined in Moodle security config', VALUE_OPTIONAL),
'firstname' => new external_value(PARAM_NOTAGS, 'The first name(s) of the user', VALUE_OPTIONAL),
'lastname' => new external_value(PARAM_NOTAGS, 'The family name of the user', VALUE_OPTIONAL),
'initials' => new external_value(PARAM_NOTAGS, 'The initials of the user', VALUE_OPTIONAL),
'fullname' => new external_value(PARAM_NOTAGS, 'The fullname of the user'),
'email' => new external_value(PARAM_TEXT, 'An email address - allow email as root@localhost', VALUE_OPTIONAL),
'address' => new external_value(PARAM_TEXT, 'Postal address', VALUE_OPTIONAL),
+178 -2
View File
@@ -21,6 +21,7 @@ use core_enrol_external;
use core_external\external_api;
use enrol_user_enrolment_form;
use stdClass;
use core_user;
defined('MOODLE_INTERNAL') || die();
@@ -37,6 +38,7 @@ require_once($CFG->dirroot . '/enrol/externallib.php');
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since Moodle 2.4
*/
#[\PHPUnit\Framework\Attributes\CoversClass(core_enrol_external::class)]
final class externallib_test extends \core_external\tests\externallib_testcase {
/**
* dataProvider for test_get_enrolled_users_visibility().
@@ -301,7 +303,7 @@ final class externallib_test extends \core_external\tests\externallib_testcase {
$this->getDataGenerator()->create_group_member(array('groupid' => $group2->id, 'userid' => $userall->id));
$this->getDataGenerator()->create_group_member(array('groupid' => $group3->id, 'userid' => $userall->id));
// Create a role to add the allowedcaps. Users will have this role assigned.
// Create a role to add the allowed capabilities. Users will have this role assigned.
$roleid = $this->getDataGenerator()->create_role();
// Allow the specified capabilities.
if (!empty($settings['allowedcaps'])) {
@@ -451,6 +453,105 @@ final class externallib_test extends \core_external\tests\externallib_testcase {
core_enrol_external::get_enrolled_users($course->id, $options);
}
/**
* Verify get_enrolled_users() initials behaviour with and without userfields.
*/
public function test_get_enrolled_users_initials(): void {
$this->resetAfterTest();
// Create the course and the users.
$course = $this->getDataGenerator()->create_course();
$coursecontext = \context_course::instance($course->id);
$user0 = $this->getDataGenerator()->create_user(['username' => 'user0active']);
// Create a role to add the allowedcaps. Users will have this role assigned.
$roleid = $this->getDataGenerator()->create_role();
// Allow the specified capabilities.
assign_capability('moodle/course:enrolreview', CAP_ALLOW, $roleid, $coursecontext);
assign_capability('moodle/user:viewalldetails', CAP_ALLOW, $roleid, $coursecontext);
// Enrol the user in the course.
$this->getDataGenerator()->enrol_user($user0->id, $course->id, $roleid);
// Switch to the enrolled user so the external function has a valid course context.
$this->setUser($user0);
// Case 1: No userfields requested => initials must be returned.
$options = [
['name' => 'onlyactive', 'value' => true],
];
$activeusers = core_enrol_external::get_enrolled_users($course->id, $options);
// We need to execute the return values cleaning process to simulate the web service server.
$activeusers = external_api::clean_returnvalue(core_enrol_external::get_enrolled_users_returns(), $activeusers);
$this->assertCount(1, $activeusers);
$this->assertArrayHasKey('initials', $activeusers[0]);
// Case 2: userfields requested but "initials" not included => initials must NOT be returned.
$options = [
['name' => 'onlyactive', 'value' => true],
['name' => 'userfields', 'value' => 'id,username'],
];
$activeusers = core_enrol_external::get_enrolled_users($course->id, $options);
$activeusers = external_api::clean_returnvalue(core_enrol_external::get_enrolled_users_returns(), $activeusers);
$this->assertCount(1, $activeusers);
$this->assertArrayNotHasKey('initials', $activeusers[0]);
// Case 3: userfields requested including "initials" => initials must be returned.
$options = [
['name' => 'onlyactive', 'value' => true],
['name' => 'userfields', 'value' => 'id,username,initials'],
];
$activeusers = core_enrol_external::get_enrolled_users($course->id, $options);
$activeusers = external_api::clean_returnvalue(core_enrol_external::get_enrolled_users_returns(), $activeusers);
$this->assertCount(1, $activeusers);
$this->assertArrayHasKey('initials', $activeusers[0]);
}
/**
* Test initials behaviour using the default name fields (no userfields option).
*/
public function test_get_enrolled_users_initials_alternative_names(): void {
$this->resetAfterTest();
$this->setAdminUser();
$course = $this->getDataGenerator()->create_course();
$user1 = $this->getDataGenerator()->create_user([
'firstname' => 'John',
'lastname' => 'Smith',
'middlename' => 'William',
]);
$users[$user1->id] = $user1;
$user2 = $this->getDataGenerator()->create_user([
'firstname' => 'María',
'lastname' => 'García',
'firstnamephonetic' => 'Maria',
'lastnamephonetic' => 'Garcia',
]);
$users[$user2->id] = $user2;
$user3 = $this->getDataGenerator()->create_user([
'firstname' => 'Robert',
'lastname' => 'Johnson',
'alternatename' => 'Bob',
]);
$users[$user3->id] = $user3;
$this->getDataGenerator()->enrol_user($user1->id, $course->id);
$this->getDataGenerator()->enrol_user($user2->id, $course->id);
$this->getDataGenerator()->enrol_user($user3->id, $course->id);
$result = core_enrol_external::get_enrolled_users($course->id);
// We need to execute the return values cleaning process to simulate the web service server.
$result = external_api::clean_returnvalue(core_enrol_external::get_enrolled_users_returns(), $result);
// Default format (firstname lastname): initials must match core_user::get_initials().
foreach ($result as $user) {
$this->assertNotEmpty($user['initials']);
$expectedinitials = core_user::get_initials($users[$user['id']]);
$this->assertEquals($expectedinitials, $user['initials']);
}
}
/**
* Test get_users_courses
*/
@@ -1067,7 +1168,80 @@ final class externallib_test extends \core_external\tests\externallib_testcase {
$expecteduserlist = $result[0]['users'];
$expecteduser = reset($expecteduserlist);
$this->assertEquals(1, count($expecteduserlist));
// The returned user must contain a valid user structure.
$this->assertArrayHasKey('id', $expecteduser);
$this->assertEquals($data->student1->id, $expecteduser['id']);
// With userfields restricted to id, initials should not be present.
$this->assertArrayNotHasKey('initials', $expecteduser);
}
/**
* Test get_enrolled_users_with_capability initials behaviour with and without userfields.
*/
public function test_get_enrolled_users_with_capability_initials(): void {
$capability = 'moodle/course:viewparticipants';
$data = $this->get_enrolled_users_with_capability_setup($capability);
// Case 1: No userfields requested => initials must be returned.
$result = core_enrol_external::get_enrolled_users_with_capability(
[
'coursecapabilities' => [
'courseid' => $data->course->id,
'capabilities' => [
$capability,
],
],
],
[]
);
$result = external_api::clean_returnvalue(core_enrol_external::get_enrolled_users_with_capability_returns(), $result);
$expecteduserlist = $result[0]['users'];
$this->assertEquals(2, count($expecteduserlist));
foreach ($expecteduserlist as $user) {
$this->assertArrayHasKey('initials', $user);
}
// Case 2: userfields requested but "initials" not included => initials must NOT be returned.
$result = core_enrol_external::get_enrolled_users_with_capability(
[
'coursecapabilities' => [
'courseid' => $data->course->id,
'capabilities' => [
$capability,
],
],
],
[
['name' => 'userfields', 'value' => 'id,firstname'],
]
);
$result = external_api::clean_returnvalue(core_enrol_external::get_enrolled_users_with_capability_returns(), $result);
$expecteduserlist = $result[0]['users'];
$this->assertEquals(2, count($expecteduserlist));
foreach ($expecteduserlist as $user) {
$this->assertArrayNotHasKey('initials', $user);
}
// Case 3: userfields requested including "initials" => initials must be returned.
$result = core_enrol_external::get_enrolled_users_with_capability(
[
'coursecapabilities' => [
'courseid' => $data->course->id,
'capabilities' => [
$capability,
],
],
],
[
['name' => 'userfields', 'value' => 'id,firstname,initials'],
]
);
$result = external_api::clean_returnvalue(core_enrol_external::get_enrolled_users_with_capability_returns(), $result);
$expecteduserlist = $result[0]['users'];
$this->assertEquals(2, count($expecteduserlist));
foreach ($expecteduserlist as $user) {
$this->assertArrayHasKey('initials', $user);
}
}
/**
@@ -1404,6 +1578,7 @@ final class externallib_test extends \core_external\tests\externallib_testcase {
$this->assertEquals($user1->id, $result['id']);
$this->assertEquals($user1->email, $result['email']);
$this->assertEquals(fullname($user1), $result['fullname']);
$this->assertEquals(core_user::get_initials($user1), $result['initials']);
$this->setUser($user1);
@@ -1529,8 +1704,9 @@ final class externallib_test extends \core_external\tests\externallib_testcase {
// Check the fields are the expected ones.
$this->assertEquals(['id', 'fullname', 'customfields',
'profileimageurl', 'profileimageurlsmall', 'department'], array_keys($result1));
'profileimageurl', 'profileimageurlsmall', 'department', 'initials'], array_keys($result1));
$this->assertEquals('Eigh User', $result1['fullname']);
$this->assertEquals(core_user::get_initials($user1), $result1['initials']);
$this->assertEquals('Amphibians', $result1['department']);
// Check the custom fields ONLY include the user identity one.
@@ -16,6 +16,7 @@
namespace core_grades\external;
use core_user;
use core_user_external;
use core_external\external_api;
use core_external\external_function_parameters;
@@ -102,6 +103,7 @@ class get_enrolled_users_for_selector extends external_api {
$userforselector = new \stdClass();
$userforselector->id = $userdata->user->id;
$userforselector->fullname = fullname($userdata->user);
$userforselector->initials = core_user::get_initials($userdata->user);
foreach (\core_user\fields::get_name_fields() as $field) {
$userforselector->$field = $userdata->user->$field ?? null;
}
+2
View File
@@ -24,6 +24,7 @@ use core_external\external_single_structure;
use core_external\external_value;
use core_external\external_warnings;
use core_external\restricted_context_exception;
use core_user;
use core_user_external;
use invalid_parameter_exception;
use moodle_exception;
@@ -94,6 +95,7 @@ class get_gradable_users extends external_api {
$users = get_gradable_users($course->id, $params['groupid'], $onlyactive);
$users = array_map(function ($user) use ($PAGE) {
$user->fullname = fullname($user);
$user->initials = core_user::get_initials($user);
$userpicture = new user_picture($user);
$userpicture->size = 1;
$user->profileimageurlsmall = $userpicture->get_url($PAGE)->out(false);
@@ -17,6 +17,7 @@
namespace gradereport_grader\external;
use context_course;
use core_user;
use core_user_external;
use core_external\external_api;
use core_external\external_function_parameters;
@@ -95,6 +96,7 @@ class get_users_in_report extends external_api {
$userforselector = new \stdClass();
$userforselector->id = $user->id;
$userforselector->fullname = fullname($user);
$userforselector->initials = core_user::get_initials($user);
foreach (\core_user\fields::get_name_fields() as $field) {
$userforselector->$field = $user->$field ?? null;
}
@@ -0,0 +1,85 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Unit tests for the gradereport_grader\external\get_users_in_report.
*
* @package gradereport_grader
* @category external
* @copyright 2025 Daniel Ureña
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace gradereport_grader\external;
use gradereport_grader\external\get_users_in_report;
use core_external\external_api;
/**
* Unit tests for the gradereport_grader\external\get_users_in_report.
*
* @package gradereport_grader
* @category external
* @copyright 2025 Daniel Ureña
*/
#[\PHPUnit\Framework\Attributes\CoversClass(get_users_in_report::class)]
final class get_users_in_report_test extends \core_external\tests\externallib_testcase {
public function test_execute(): void {
$this->resetAfterTest();
$this->setAdminUser();
// Create course and users.
$course = $this->getDataGenerator()->create_course();
$user1 = $this->getDataGenerator()->create_user();
$user2 = $this->getDataGenerator()->create_user();
// Enrol users in course.
$this->getDataGenerator()->enrol_user($user1->id, $course->id);
$this->getDataGenerator()->enrol_user($user2->id, $course->id);
// Call the external function.
$result = get_users_in_report::execute($course->id);
$result = external_api::clean_returnvalue(get_users_in_report::execute_returns(), $result);
// Two enrolled users should be returned.
$this->assertCount(2, $result['users']);
$createdusers = [
$user1->id => $user1,
$user2->id => $user2,
];
// Assert required fields and that their values match the created users.
foreach ($result['users'] as $user) {
$this->assertArrayHasKey('id', $user);
$this->assertArrayHasKey('fullname', $user);
$this->assertArrayHasKey('initials', $user);
$this->assertArrayHasKey('profileimageurl', $user);
// It must be one of the enrolled users.
$this->assertArrayHasKey($user['id'], $createdusers);
$expecteduser = $createdusers[$user['id']];
$this->assertEquals(fullname($expecteduser), $user['fullname']);
$this->assertEquals(\core_user::get_initials($expecteduser), $user['initials']);
// Profile image should be a non-empty string.
$this->assertIsString($user['profileimageurl']);
$this->assertNotEmpty($user['profileimageurl']);
}
// Assert no warnings.
$this->assertEmpty($result['warnings']);
}
}
@@ -0,0 +1,102 @@
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
* Unit tests for the core_grades\external\get_enrolled_users_for_selector.
*
* @package core_grades
* @category external
* @copyright 2025 Daniel Ureña
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace core_grades\external;
use core_grades\external\get_enrolled_users_for_selector;
use core_external\external_api;
use core_user;
/**
* Unit tests for the core_grades\external\get_enrolled_users_for_selector.
*
* @package core_grades
* @category external
* @copyright 2025 Daniel Ureña
*/
#[\PHPUnit\Framework\Attributes\CoversClass(get_enrolled_users_for_selector::class)]
final class get_enrolled_users_for_selector_test extends \core_external\tests\externallib_testcase {
public function test_get_enrolled_users_for_selector(): void {
$this->resetAfterTest();
$this->setAdminUser();
// Create course and users.
$generator = $this->getDataGenerator();
$course = $generator->create_course();
// Create an activity to ensure grade items exist.
$assign = $generator->create_module('assign', ['course' => $course->id]);
$user1 = $generator->create_user([
'firstname' => 'Ana',
'lastname' => 'García',
]);
$user2 = $generator->create_user([
'firstname' => 'Luis',
'lastname' => 'Martínez',
]);
$createdusers = [
$user1->id => $user1,
$user2->id => $user2,
];
// Enrol users in course.
$generator->enrol_user($user1->id, $course->id);
$generator->enrol_user($user2->id, $course->id);
// Call the external function.
$result = get_enrolled_users_for_selector::execute($course->id, 0);
$result = external_api::clean_returnvalue(get_enrolled_users_for_selector::execute_returns(), $result);
// Assert users are returned.
$this->assertCount(2, $result['users']);
// Assert required fields and that their values match the created users.
foreach ($result['users'] as $user) {
$this->assertArrayHasKey('id', $user);
$this->assertArrayHasKey('fullname', $user);
$this->assertArrayHasKey('initials', $user);
$this->assertArrayHasKey('profileimageurl', $user);
$this->assertArrayHasKey('profileimageurlsmall', $user);
// It must be one of the enrolled users.
$this->assertArrayHasKey($user['id'], $createdusers);
$expecteduser = $createdusers[$user['id']];
$this->assertEquals(fullname($expecteduser), $user['fullname']);
$this->assertEquals(core_user::get_initials($expecteduser), $user['initials']);
$this->assertEquals($expecteduser->firstname, $user['firstname']);
$this->assertEquals($expecteduser->lastname, $user['lastname']);
// Profile images should be non-empty strings.
$this->assertIsString($user['profileimageurl']);
$this->assertNotEmpty($user['profileimageurl']);
$this->assertIsString($user['profileimageurlsmall']);
$this->assertNotEmpty($user['profileimageurlsmall']);
}
// Assert no warnings.
$this->assertEmpty($result['warnings']);
}
}
+13
View File
@@ -80,6 +80,7 @@ final class get_gradable_users_test extends \core_external\tests\externallib_tes
$mapped = array_map(function($user) {
return [
'fullname' => $user['fullname'],
'initials' => $user['initials'],
'firstname' => $user['firstname'],
'lastname' => $user['lastname'],
'profileimageurl' => $user['profileimageurl'],
@@ -104,30 +105,35 @@ final class get_gradable_users_test extends \core_external\tests\externallib_tes
'firstname' => 'Apple',
'lastname' => 'Apricot',
'fullname' => 'Apple Apricot',
'initials' => 'AA',
],
[
'profileimageurl' => 'https://www.example.com/moodle/theme/image.php/boost/core/1/u/f1',
'firstname' => 'Banana',
'lastname' => 'Blueberry',
'fullname' => 'Banana Blueberry',
'initials' => 'BB',
],
[
'profileimageurl' => 'https://www.example.com/moodle/theme/image.php/boost/core/1/u/f1',
'firstname' => 'Cherry',
'lastname' => 'Cranberry',
'fullname' => 'Cherry Cranberry',
'initials' => 'CC',
],
[
'profileimageurl' => 'https://www.example.com/moodle/theme/image.php/boost/core/1/u/f1',
'firstname' => 'Durian',
'lastname' => 'Dracontomelon',
'fullname' => 'Durian Dracontomelon',
'initials' => 'DD',
],
[
'profileimageurl' => 'https://www.example.com/moodle/theme/image.php/boost/core/1/u/f1',
'firstname' => 'Eggplant',
'lastname' => 'Ensete',
'fullname' => 'Eggplant Ensete',
'initials' => 'EE',
],
],
],
@@ -140,24 +146,28 @@ final class get_gradable_users_test extends \core_external\tests\externallib_tes
'firstname' => 'Apple',
'lastname' => 'Apricot',
'fullname' => 'Apple Apricot',
'initials' => 'AA',
],
[
'profileimageurl' => 'https://www.example.com/moodle/theme/image.php/boost/core/1/u/f1',
'firstname' => 'Banana',
'lastname' => 'Blueberry',
'fullname' => 'Banana Blueberry',
'initials' => 'BB',
],
[
'profileimageurl' => 'https://www.example.com/moodle/theme/image.php/boost/core/1/u/f1',
'firstname' => 'Cherry',
'lastname' => 'Cranberry',
'fullname' => 'Cherry Cranberry',
'initials' => 'CC',
],
[
'profileimageurl' => 'https://www.example.com/moodle/theme/image.php/boost/core/1/u/f1',
'firstname' => 'Durian',
'lastname' => 'Dracontomelon',
'fullname' => 'Durian Dracontomelon',
'initials' => 'DD',
],
],
],
@@ -170,18 +180,21 @@ final class get_gradable_users_test extends \core_external\tests\externallib_tes
'firstname' => 'Apple',
'lastname' => 'Apricot',
'fullname' => 'Apple Apricot',
'initials' => 'AA',
],
[
'profileimageurl' => 'https://www.example.com/moodle/theme/image.php/boost/core/1/u/f1',
'firstname' => 'Banana',
'lastname' => 'Blueberry',
'fullname' => 'Banana Blueberry',
'initials' => 'BB',
],
[
'profileimageurl' => 'https://www.example.com/moodle/theme/image.php/boost/core/1/u/f1',
'firstname' => 'Cherry',
'lastname' => 'Cranberry',
'fullname' => 'Cherry Cranberry',
'initials' => 'CC',
],
],
],
+1
View File
@@ -329,6 +329,7 @@ class api {
// Otherwise it means that the $USER was not allowed to search the returned user.
if (!empty($userdetails) and !empty($userdetails['fullname'])) {
// We know we've matched, but only save the record if it's within the offset area we need.
$user->initials = \core_user::get_initials($user);
if ($limitfrom == 0) {
// No offset specified, so just save.
$returnedusers[$id] = $user;
+2
View File
@@ -166,6 +166,7 @@ class helper {
$data->userid = $userfields->id;
$data->useridfrom = null;
$data->fullname = fullname($userfields);
$data->initials = \core_user::get_initials($userfields);
// Get the user picture data.
$userpicture = new \user_picture($userfields);
$userpicture->size = 1; // Size f1.
@@ -437,6 +438,7 @@ class helper {
$data = new stdClass();
$data->id = $member->id;
$data->fullname = fullname($member);
$data->initials = \core_user::get_initials($member);
// Create the URL for their profile.
$profileurl = new \moodle_url('/user/profile.php', ['id' => $member->id]);
+3
View File
@@ -997,6 +997,7 @@ class core_message_external extends external_api {
array(
'userid' => new external_value(PARAM_INT, 'The user\'s id'),
'fullname' => new external_value(PARAM_NOTAGS, 'The user\'s name'),
'initials' => new external_value(PARAM_NOTAGS, 'The initials of the user', VALUE_OPTIONAL),
'profileimageurl' => new external_value(PARAM_URL, 'User picture URL'),
'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL'),
'ismessaging' => new external_value(PARAM_BOOL, 'If we are messaging the user'),
@@ -1059,6 +1060,7 @@ class core_message_external extends external_api {
$result = [
'id' => new external_value(PARAM_INT, 'The user id'),
'fullname' => new external_value(PARAM_NOTAGS, 'The user\'s name'),
'initials' => new external_value(PARAM_NOTAGS, 'The initials of the user', VALUE_OPTIONAL),
'profileurl' => new external_value(PARAM_URL, 'The link to the user\'s profile page'),
'profileimageurl' => new external_value(PARAM_URL, 'User picture URL'),
'profileimageurlsmall' => new external_value(PARAM_URL, 'Small user picture URL'),
@@ -1256,6 +1258,7 @@ class core_message_external extends external_api {
$contact = new \stdClass();
$contact->userid = $message->userid;
$contact->fullname = $message->fullname;
$contact->initials = $message->initials;
$contact->profileimageurl = $message->profileimageurl;
$contact->profileimageurlsmall = $message->profileimageurlsmall;
$contact->messageid = $message->messageid;
+21
View File
@@ -19,6 +19,7 @@ namespace core_message;
use core_external\external_api;
use core_message\tests\helper as testhelper;
use core_message_external;
use core_user;
defined('MOODLE_INTERNAL') || die();
@@ -451,6 +452,7 @@ final class externallib_test extends \core_external\tests\externallib_testcase {
$this->assertEquals($user2->id, $request['id']);
$this->assertEquals(fullname($user2), $request['fullname']);
$this->assertEquals(core_user::get_initials($user2), $request['initials']);
$this->assertArrayHasKey('profileimageurl', $request);
$this->assertArrayHasKey('profileimageurlsmall', $request);
$this->assertArrayHasKey('isonline', $request);
@@ -2186,7 +2188,9 @@ final class externallib_test extends \core_external\tests\externallib_testcase {
// Check that we retrieved the correct contacts.
$this->assertCount(2, $contacts);
$this->assertEquals($users[2]->id, $contacts[0]['id']);
$this->assertEquals(core_user::get_initials($users[2]), $contacts[0]['initials']);
$this->assertEquals($users[3]->id, $contacts[1]['id']);
$this->assertEquals(core_user::get_initials($users[3]), $contacts[1]['initials']);
// Verify the correct conversations were returned for the contacts.
$this->assertCount(2, $contacts[0]['conversations']);
@@ -2204,9 +2208,13 @@ final class externallib_test extends \core_external\tests\externallib_testcase {
// In this case, as a student, that's the course contact for course2 and those noncontacts sharing a course with user1.
$this->assertCount(4, $noncontacts);
$this->assertEquals($users[1]->id, $noncontacts[0]['id']);
$this->assertEquals(core_user::get_initials($users[1]), $noncontacts[0]['initials']);
$this->assertEquals($users[6]->id, $noncontacts[1]['id']);
$this->assertEquals(core_user::get_initials($users[6]), $noncontacts[1]['initials']);
$this->assertEquals($users[7]->id, $noncontacts[2]['id']);
$this->assertEquals(core_user::get_initials($users[7]), $noncontacts[2]['initials']);
$this->assertEquals($users[9]->id, $noncontacts[3]['id']);
$this->assertEquals(core_user::get_initials($users[9]), $noncontacts[3]['initials']);
// Verify the correct conversations were returned for the non-contacts.
$this->assertCount(1, $noncontacts[1]['conversations']);
@@ -2483,6 +2491,7 @@ final class externallib_test extends \core_external\tests\externallib_testcase {
$this->assertEquals($user2->id, $message1['userid']);
$this->assertEquals(fullname($user2), $message1['fullname']);
$this->assertEquals(core_user::get_initials($user2), $message1['initials']);
$this->assertTrue($message1['ismessaging']);
$this->assertFalse($message1['sentfromcurrentuser']);
$this->assertEquals('Word.', $message1['lastmessage']);
@@ -2495,6 +2504,7 @@ final class externallib_test extends \core_external\tests\externallib_testcase {
$this->assertEquals($user2->id, $message2['userid']);
$this->assertEquals(fullname($user2), $message2['fullname']);
$this->assertEquals(core_user::get_initials($user2), $message2['initials']);
$this->assertTrue($message2['ismessaging']);
$this->assertTrue($message2['sentfromcurrentuser']);
$this->assertEquals('Yo!', $message2['lastmessage']);
@@ -2658,14 +2668,17 @@ final class externallib_test extends \core_external\tests\externallib_testcase {
$this->assertEquals($user2->id, $contact1['id']);
$this->assertEquals(fullname($user2), $contact1['fullname']);
$this->assertEquals(core_user::get_initials($user2), $contact1['initials']);
$this->assertTrue($contact1['iscontact']);
$this->assertEquals($user3->id, $contact2['id']);
$this->assertEquals(fullname($user3), $contact2['fullname']);
$this->assertEquals(core_user::get_initials($user3), $contact2['initials']);
$this->assertTrue($contact2['iscontact']);
$this->assertEquals($user4->id, $contact3['id']);
$this->assertEquals(fullname($user4), $contact3['fullname']);
$this->assertEquals(core_user::get_initials($user4), $contact3['initials']);
$this->assertTrue($contact3['iscontact']);
}
@@ -2842,6 +2855,11 @@ final class externallib_test extends \core_external\tests\externallib_testcase {
$this->assertContainsEquals(fullname($user2), $membersfullnames);
$this->assertContainsEquals(fullname($user3), $membersfullnames);
$membersinitials = [$members[0]['initials'], $members[1]['initials'], $members[2]['initials']];
$this->assertContainsEquals(core_user::get_initials($user1), $membersinitials);
$this->assertContainsEquals(core_user::get_initials($user2), $membersinitials);
$this->assertContainsEquals(core_user::get_initials($user3), $membersinitials);
// Confirm the messages data is correct.
$messages = $result['messages'];
$this->assertCount(4, $messages);
@@ -4521,6 +4539,7 @@ final class externallib_test extends \core_external\tests\externallib_testcase {
// Confirm the standard fields are OK.
$this->assertEquals($user1->id, $member1->id);
$this->assertEquals(fullname($user1), $member1->fullname);
$this->assertEquals(core_user::get_initials($user1), $member1->initials);
$this->assertEquals(true, $member1->isonline);
$this->assertEquals(true, $member1->showonlinestatus);
$this->assertEquals(false, $member1->iscontact);
@@ -4530,6 +4549,7 @@ final class externallib_test extends \core_external\tests\externallib_testcase {
$this->assertEquals($user2->id, $member2->id);
$this->assertEquals(fullname($user2), $member2->fullname);
$this->assertEquals(core_user::get_initials($user2), $member2->initials);
$this->assertEquals(false, $member2->isonline);
$this->assertEquals(true, $member2->showonlinestatus);
$this->assertEquals(true, $member2->iscontact);
@@ -4539,6 +4559,7 @@ final class externallib_test extends \core_external\tests\externallib_testcase {
$this->assertEquals($user3->id, $member3->id);
$this->assertEquals(fullname($user3), $member3->fullname);
$this->assertEquals(core_user::get_initials($user3), $member3->initials);
$this->assertEquals(false, $member3->isonline);
$this->assertEquals(true, $member3->showonlinestatus);
$this->assertEquals(false, $member3->iscontact);
+9 -2
View File
@@ -2729,8 +2729,14 @@ class mod_assign_external extends \mod_assign\external\external_api {
// Now we do the expensive lookup of user details because we completed the filtering.
if (!$assign->is_blind_marking() && !$params['onlyids']) {
$userdetails = user_get_user_details($record, $course, $userfields);
if ($userdetails === null) {
// If user details are not available (e.g. access prevented), fall back to minimal data.
$userdetails = ['id' => $record->id];
} else {
$userdetails['initials'] = core_user::get_initials($record);
}
} else {
$userdetails = array('id' => $record->id);
$userdetails = ['id' => $record->id];
}
$userdetails['fullname'] = $fullname;
$userdetails['submitted'] = $record->submitted;
@@ -2769,7 +2775,7 @@ class mod_assign_external extends \mod_assign\external\external_api {
$userdesc = core_user_external::user_description();
// List unneeded properties.
$unneededproperties = [
'auth', 'confirmed', 'lang', 'calendartype', 'theme', 'timezone', 'mailformat'
'auth', 'confirmed', 'lang', 'calendartype', 'theme', 'timezone', 'mailformat',
];
// Remove unneeded properties for consistency with the previous version.
foreach ($unneededproperties as $prop) {
@@ -2913,6 +2919,7 @@ class mod_assign_external extends \mod_assign\external\external_api {
// hasn't asked for user details to be embedded.
if (!$assign->is_blind_marking() && $embeduser) {
if ($userdetails = user_get_user_details($participant, $course)) {
$userdetails['initials'] = core_user::get_initials($participant);
$return['user'] = $userdetails;
}
}
@@ -57,6 +57,8 @@ class author {
private $alternatename;
/** @var string $imagealt Image alt */
private $imagealt;
/** @var string $initials Initials */
private $initials;
/**
* Constructor.
@@ -85,7 +87,8 @@ class author {
?string $firstnamephonetic = null,
?string $lastnamephonetic = null,
?string $alternatename = null,
?string $imagealt = null
?string $imagealt = null,
?string $initials = null
) {
$this->id = $id;
$this->pictureitemid = $pictureitemid;
@@ -99,6 +102,7 @@ class author {
$this->lastnamephonetic = $lastnamephonetic;
$this->alternatename = $alternatename;
$this->imagealt = $imagealt;
$this->initials = $initials;
}
/**
@@ -208,4 +212,13 @@ class author {
public function get_image_alt(): ?string {
return $this->imagealt;
}
/**
* Return the initials.
*
* @return string
*/
public function get_initials(): string {
return $this->initials ?? '';
}
}
@@ -91,6 +91,12 @@ class author extends exporter {
'default' => null,
'null' => NULL_ALLOWED
],
'initials' => [
'type' => PARAM_NOTAGS,
'optional' => true,
'default' => null,
'null' => NULL_ALLOWED,
],
'isdeleted' => [
'type' => PARAM_BOOL,
'optional' => true,
@@ -154,6 +160,7 @@ class author extends exporter {
return [
'id' => $author->get_id(),
'fullname' => get_string('deleteduser', 'mod_forum'),
'initials' => null,
'isdeleted' => true,
'groups' => [],
'urls' => [
@@ -184,6 +191,7 @@ class author extends exporter {
return [
'id' => $author->get_id(),
'fullname' => $author->get_full_name(),
'initials' => $author->get_initials(),
'isdeleted' => false,
'groups' => $groups,
'urls' => [
@@ -197,6 +205,7 @@ class author extends exporter {
return [
'id' => null,
'fullname' => get_string('forumauthorhidden', 'mod_forum'),
'initials' => null,
'isdeleted' => null,
'groups' => [],
'urls' => [
@@ -38,6 +38,7 @@ use context;
use cm_info;
use user_picture;
use moodle_url;
use core_user;
/**
* Entity factory to create the forum entities.
@@ -170,6 +171,7 @@ class entity {
* @return author_entity
*/
public function get_author_from_stdclass(stdClass $record): author_entity {
$initials = core_user::get_initials($record);
return new author_entity(
$record->id,
$record->picture,
@@ -182,7 +184,8 @@ class entity {
$record->firstnamephonetic,
$record->lastnamephonetic,
$record->alternatename,
$record->imagealt
$record->imagealt,
$initials,
);
}
+6
View File
@@ -506,18 +506,22 @@ class mod_forum_external extends external_api {
if (forum_is_author_hidden($discussionobject, $forumrecord)) {
$discussionobject->userid = null;
$discussionobject->userfullname = null;
$discussionobject->userinitials = null;
$discussionobject->userpictureurl = null;
$discussionobject->usermodified = null;
$discussionobject->usermodifiedfullname = null;
$discussionobject->usermodifiedinitials = null;
$discussionobject->usermodifiedpictureurl = null;
} else {
$discussionobject->userfullname = $firstpostauthor->get_full_name();
$discussionobject->userinitials = $firstpostauthor->get_initials();
$discussionobject->userpictureurl = $urlfactory->get_author_profile_image_url($firstpostauthor, null, 2)
->out(false);
$discussionobject->usermodifiedfullname = $latestpostauthor->get_full_name();
$discussionobject->usermodifiedinitials = $latestpostauthor->get_initials();
$discussionobject->usermodifiedpictureurl = $urlfactory->get_author_profile_image_url(
$latestpostauthor, null, 2)->out(false);
}
@@ -567,7 +571,9 @@ class mod_forum_external extends external_api {
'totalscore' => new external_value(PARAM_INT, 'The post message total score'),
'mailnow' => new external_value(PARAM_INT, 'Mail now?'),
'userfullname' => new external_value(PARAM_TEXT, 'Post author full name'),
'userinitials' => new external_value(PARAM_NOTAGS, 'Post author initials', VALUE_OPTIONAL),
'usermodifiedfullname' => new external_value(PARAM_TEXT, 'Post modifier full name'),
'usermodifiedinitials' => new external_value(PARAM_NOTAGS, 'Post modifier initials', VALUE_OPTIONAL),
'userpictureurl' => new external_value(PARAM_URL, 'Post author picture.'),
'usermodifiedpictureurl' => new external_value(PARAM_URL, 'Post modifier picture.'),
'numreplies' => new external_value(PARAM_INT, 'The number of replies in the discussion'),
+9 -4
View File
@@ -17,6 +17,7 @@
namespace mod_forum;
use core_external\external_api;
use core_user;
use mod_forum_external;
/**
@@ -355,6 +356,7 @@ final class externallib_test extends \core_external\tests\externallib_testcase {
$exporteduser2 = [
'id' => (int) $user2->id,
'fullname' => fullname($user2),
'initials' => \core_user::get_initials($user2),
'isdeleted' => false,
'groups' => [],
'urls' => [
@@ -362,13 +364,13 @@ final class externallib_test extends \core_external\tests\externallib_testcase {
'profileimage' => $urlfactory->get_author_profile_image_url($user2entity),
]
];
$user2->fullname = $exporteduser2['fullname'];
$user3 = self::getDataGenerator()->create_user(['fullname' => "Mr Pants 1"]);
$user3entity = $entityfactory->get_author_from_stdClass($user3);
$exporteduser3 = [
'id' => (int) $user3->id,
'fullname' => fullname($user3),
'initials' => \core_user::get_initials($user3),
'groups' => [],
'isdeleted' => false,
'urls' => [
@@ -376,7 +378,6 @@ final class externallib_test extends \core_external\tests\externallib_testcase {
'profileimage' => $urlfactory->get_author_profile_image_url($user3entity),
]
];
$user3->fullname = $exporteduser3['fullname'];
$forumgenerator = self::getDataGenerator()->get_plugin_generator('mod_forum');
// Set the first created user to the test user.
@@ -453,6 +454,7 @@ final class externallib_test extends \core_external\tests\externallib_testcase {
$exporteduser3 = [
'id' => (int) $user3->id,
'fullname' => get_string('deleteduser', 'mod_forum'),
'initials' => '',
'groups' => [],
'isdeleted' => true,
'urls' => [
@@ -978,7 +980,7 @@ final class externallib_test extends \core_external\tests\externallib_testcase {
'message' => $post1->message,
'messageformat' => (int) $post1->messageformat,
'messagetrust' => (int) $post1->messagetrust,
'attachment' => $post1->attachment,
'attachment' => !empty($post1->attachment) ? $post1->attachment : false,
'totalscore' => (int) $post1->totalscore,
'mailnow' => (int) $post1->mailnow,
'userfullname' => fullname($user1),
@@ -994,7 +996,6 @@ final class externallib_test extends \core_external\tests\externallib_testcase {
'starred' => false,
'canfavourite' => true
);
// Call the external function passing forum id.
$discussions = mod_forum_external::get_forum_discussions($forum1->id);
$discussions = external_api::clean_returnvalue(mod_forum_external::get_forum_discussions_returns(), $discussions);
@@ -1007,10 +1008,12 @@ final class externallib_test extends \core_external\tests\externallib_testcase {
$userpicture = new \user_picture($user1);
$userpicture->size = 2; // Size f2.
$expectedreturn['discussions'][0]['userpictureurl'] = $userpicture->get_url($PAGE)->out(false);
$expectedreturn['discussions'][0]['userinitials'] = core_user::get_initials($user1);
$userpicture = new \user_picture($user4);
$userpicture->size = 2; // Size f2.
$expectedreturn['discussions'][0]['usermodifiedpictureurl'] = $userpicture->get_url($PAGE)->out(false);
$expectedreturn['discussions'][0]['usermodifiedinitials'] = core_user::get_initials($user4);
$this->assertEquals($expectedreturn, $discussions);
@@ -2335,6 +2338,7 @@ final class externallib_test extends \core_external\tests\externallib_testcase {
$exporteduser1 = [
'id' => (int) $user1->id,
'fullname' => fullname($user1),
'initials' => \core_user::get_initials($user1),
'groups' => [],
'urls' => [
'profile' => $urlfactory->get_author_profile_url($user1entity, $course1->id)->out(false),
@@ -2348,6 +2352,7 @@ final class externallib_test extends \core_external\tests\externallib_testcase {
$exporteduser2 = [
'id' => (int) $user2->id,
'fullname' => fullname($user2),
'initials' => \core_user::get_initials($user2),
'groups' => [],
'urls' => [
'profile' => $urlfactory->get_author_profile_url($user2entity, $course1->id)->out(false),
+4
View File
@@ -786,6 +786,7 @@ class core_user_external extends \core_external\external_api {
// Return the user only if the searched field is returned.
// Otherwise it means that the $USER was not allowed to search the returned user.
if (!empty($userdetails) and !empty($userdetails[$field])) {
$userdetails['initials'] = core_user::get_initials($user);
$returnedusers[] = $userdetails;
}
}
@@ -948,6 +949,7 @@ class core_user_external extends \core_external\external_api {
// Otherwise it means that the $USER was not allowed to search the returned user.
if (!empty($userdetails)) {
$validuser = true;
$userdetails['initials'] = core_user::get_initials($user);
foreach ($params['criteria'] as $criteria) {
if (empty($userdetails[$criteria['key']])) {
@@ -1056,6 +1058,7 @@ class core_user_external extends \core_external\external_api {
$context = context_course::instance($courseids[$user->id], IGNORE_MISSING);
self::validate_context($context);
if ($userarray = user_get_user_details($user, $course)) {
$userarray['initials'] = core_user::get_initials($user);
$result[] = $userarray;
}
}
@@ -1117,6 +1120,7 @@ class core_user_external extends \core_external\external_api {
'firstname' => new external_value(core_user::get_property_type('firstname'), 'The first name(s) of the user', VALUE_OPTIONAL),
'lastname' => new external_value(core_user::get_property_type('lastname'), 'The family name of the user', VALUE_OPTIONAL),
'fullname' => new external_value(core_user::get_property_type('firstname'), 'The fullname of the user'),
'initials' => new external_value(PARAM_NOTAGS, 'The initials of the user', VALUE_OPTIONAL),
'email' => new external_value(core_user::get_property_type('email'), 'An email address - allow email as root@localhost', VALUE_OPTIONAL),
'address' => new external_value(core_user::get_property_type('address'), 'Postal address', VALUE_OPTIONAL),
'phone1' => new external_value(core_user::get_property_type('phone1'), 'Phone 1', VALUE_OPTIONAL),
+5
View File
@@ -29,6 +29,7 @@ namespace core_user;
use core_external\external_api;
use core_files_external;
use core_user_external;
use core_user;
defined('MOODLE_INTERNAL') || die();
@@ -120,6 +121,7 @@ final class externallib_test extends \core_external\tests\externallib_testcase {
}
$this->assertEquals($generateduser->firstname, $returneduser['firstname']);
$this->assertEquals($generateduser->lastname, $returneduser['lastname']);
$this->assertEquals(core_user::get_initials($generateduser), $returneduser['initials']);
if ($generateduser->email != $USER->email) { // Don't check the tmp modified $USER email.
$this->assertEquals($generateduser->email, $returneduser['email']);
}
@@ -277,6 +279,7 @@ final class externallib_test extends \core_external\tests\externallib_testcase {
}
$this->assertEquals($generateduser->firstname, $returneduser['firstname']);
$this->assertEquals($generateduser->lastname, $returneduser['lastname']);
$this->assertEquals(core_user::get_initials($generateduser), $returneduser['initials']);
if ($generateduser->email != $USER->email) { //don't check the tmp modified $USER email
$this->assertEquals($generateduser->email, $returneduser['email']);
}
@@ -436,6 +439,7 @@ final class externallib_test extends \core_external\tests\externallib_testcase {
// Check we retrieve the good total number of enrolled users + no error on capability.
$this->assertEquals(1, count($enrolledusers));
$this->assertEquals(core_user::get_initials($USER), $enrolledusers[0]['initials']);
}
public function test_get_user_course_profile_as_admin(): void {
@@ -466,6 +470,7 @@ final class externallib_test extends \core_external\tests\externallib_testcase {
$this->assertEquals($data->user1->idnumber, $enrolleduser['idnumber']);
$this->assertEquals($data->user1->firstname, $enrolleduser['firstname']);
$this->assertEquals($data->user1->lastname, $enrolleduser['lastname']);
$this->assertEquals(core_user::get_initials($data->user1), $enrolleduser['initials']);
$this->assertEquals($data->user1->email, $enrolleduser['email']);
$this->assertEquals($data->user1->address, $enrolleduser['address']);
$this->assertEquals($data->user1->phone1, $enrolleduser['phone1']);