MDL-84960 core: Added initials to the user structures
This commit is contained in:
@@ -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
|
||||
@@ -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),
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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']);
|
||||
}
|
||||
}
|
||||
@@ -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',
|
||||
],
|
||||
],
|
||||
],
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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]);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -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'),
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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']);
|
||||
|
||||
Reference in New Issue
Block a user