MDL-77353 core_user: new functions
New functions:
* `core_user::get_profile_picture` for retrieving user picture.
* `core_user::get_profile_url` for retrieving profile url.
* `core_user::get_fullname` for retrieving user full name.
Note: the context is not used as this stage. It will be used by "User Disguises" plugin, which will be implemented later.
This commit is contained in:
@@ -1226,4 +1226,190 @@ class core_user {
|
||||
};
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return full name depending on context.
|
||||
* This function should be used for displaying purposes only as the details may not be the same as it is on database.
|
||||
*
|
||||
* @param stdClass $user the person to get details of.
|
||||
* @param context|null $context The context will be used to determine the visibility of the user's full name.
|
||||
* @param array $options can include: override - if true, will not use forced firstname/lastname settings
|
||||
* @return string Full name of the user
|
||||
*/
|
||||
public static function get_fullname(stdClass $user, context $context = null, array $options = []): string {
|
||||
global $CFG, $SESSION;
|
||||
|
||||
// Clone the user so that it does not mess up the original object.
|
||||
$user = clone($user);
|
||||
|
||||
// Override options.
|
||||
$override = $options["override"] ?? false;
|
||||
|
||||
if (!isset($user->firstname) && !isset($user->lastname)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Get all of the name fields.
|
||||
$allnames = \core_user\fields::get_name_fields();
|
||||
if ($CFG->debugdeveloper) {
|
||||
$missingfields = [];
|
||||
foreach ($allnames as $allname) {
|
||||
if (!property_exists($user, $allname)) {
|
||||
$missingfields[] = $allname;
|
||||
}
|
||||
}
|
||||
if (!empty($missingfields)) {
|
||||
debugging('The following name fields are missing from the user object: ' . implode(', ', $missingfields));
|
||||
}
|
||||
}
|
||||
|
||||
if (!$override) {
|
||||
if (!empty($CFG->forcefirstname)) {
|
||||
$user->firstname = $CFG->forcefirstname;
|
||||
}
|
||||
if (!empty($CFG->forcelastname)) {
|
||||
$user->lastname = $CFG->forcelastname;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($SESSION->fullnamedisplay)) {
|
||||
$CFG->fullnamedisplay = $SESSION->fullnamedisplay;
|
||||
}
|
||||
|
||||
$template = null;
|
||||
// If the fullnamedisplay setting is available, set the template to that.
|
||||
if (isset($CFG->fullnamedisplay)) {
|
||||
$template = $CFG->fullnamedisplay;
|
||||
}
|
||||
// If the template is empty, or set to language, return the language string.
|
||||
if ((empty($template) || $template == 'language') && !$override) {
|
||||
return get_string('fullnamedisplay', null, $user);
|
||||
}
|
||||
|
||||
// Check to see if we are displaying according to the alternative full name format.
|
||||
if ($override) {
|
||||
if (empty($CFG->alternativefullnameformat) || $CFG->alternativefullnameformat == 'language') {
|
||||
// Default to show just the user names according to the fullnamedisplay string.
|
||||
return get_string('fullnamedisplay', null, $user);
|
||||
} else {
|
||||
// If the override is true, then change the template to use the complete name.
|
||||
$template = $CFG->alternativefullnameformat;
|
||||
}
|
||||
}
|
||||
|
||||
$requirednames = array();
|
||||
// With each name, see if it is in the display name template, and add it to the required names array if it is.
|
||||
foreach ($allnames as $allname) {
|
||||
if (strpos($template, $allname) !== false) {
|
||||
$requirednames[] = $allname;
|
||||
}
|
||||
}
|
||||
|
||||
$displayname = $template;
|
||||
// Switch in the actual data into the template.
|
||||
foreach ($requirednames as $altname) {
|
||||
if (isset($user->$altname)) {
|
||||
// Using empty() on the below if statement causes breakages.
|
||||
if ((string)$user->$altname == '') {
|
||||
$displayname = str_replace($altname, 'EMPTY', $displayname);
|
||||
} else {
|
||||
$displayname = str_replace($altname, $user->$altname, $displayname);
|
||||
}
|
||||
} else {
|
||||
$displayname = str_replace($altname, 'EMPTY', $displayname);
|
||||
}
|
||||
}
|
||||
// Tidy up any misc. characters (Not perfect, but gets most characters).
|
||||
// Don't remove the "u" at the end of the first expression unless you want garbled characters when combining hiragana or
|
||||
// katakana and parenthesis.
|
||||
$patterns = array();
|
||||
// This regular expression replacement is to fix problems such as 'James () Kirk' Where 'Tiberius' (middlename) has not been
|
||||
// filled in by a user.
|
||||
// The special characters are Japanese brackets that are common enough to make allowances for them (not covered by :punct:).
|
||||
$patterns[] = '/[[:punct:]「」]*EMPTY[[:punct:]「」]*/u';
|
||||
// This regular expression is to remove any double spaces in the display name.
|
||||
$patterns[] = '/\s{2,}/u';
|
||||
foreach ($patterns as $pattern) {
|
||||
$displayname = preg_replace($pattern, ' ', $displayname);
|
||||
}
|
||||
|
||||
// Trimming $displayname will help the next check to ensure that we don't have a display name with spaces.
|
||||
$displayname = trim($displayname);
|
||||
if (empty($displayname)) {
|
||||
// Going with just the first name if no alternate fields are filled out. May be changed later depending on what
|
||||
// people in general feel is a good setting to fall back on.
|
||||
$displayname = $user->firstname;
|
||||
}
|
||||
return $displayname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return profile url depending on context.
|
||||
*
|
||||
* @param stdClass $user the person to get details of.
|
||||
* @param context|null $context The context will be used to determine the visibility of the user's profile url.
|
||||
* @return moodle_url Profile url of the user
|
||||
*/
|
||||
public static function get_profile_url(stdClass $user, context $context = null): moodle_url {
|
||||
if (empty($user->id)) {
|
||||
throw new coding_exception('User id is required when displaying profile url.');
|
||||
}
|
||||
|
||||
// Params to be passed to the user view page.
|
||||
$params = ['id' => $user->id];
|
||||
|
||||
// Get courseid if provided.
|
||||
if (isset($options['courseid'])) {
|
||||
$params['courseid'] = $options['courseid'];
|
||||
}
|
||||
|
||||
// Get courseid from context if provided.
|
||||
if ($context) {
|
||||
$coursecontext = $context->get_course_context(false);
|
||||
if ($coursecontext) {
|
||||
$params['courseid'] = $coursecontext->instanceid;
|
||||
}
|
||||
}
|
||||
|
||||
// If courseid is not set or is set to site id, then return profile page, otherwise return view page.
|
||||
if (!isset($params['courseid']) || $params['courseid'] == SITEID) {
|
||||
return new moodle_url('/user/profile.php', $params);
|
||||
} else {
|
||||
return new moodle_url('/user/view.php', $params);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return user picture depending on context.
|
||||
* This function should be used for displaying purposes only as the details may not be the same as it is on database.
|
||||
*
|
||||
* @param stdClass $user the person to get details of.
|
||||
* @param context|null $context The context will be used to determine the visibility of the user's picture.
|
||||
* @param array $options public properties of {@see user_picture} to be overridden
|
||||
* - courseid = $this->page->course->id (course id of user profile in link)
|
||||
* - size = 35 (size of image)
|
||||
* - link = true (make image clickable - the link leads to user profile)
|
||||
* - popup = false (open in popup)
|
||||
* - alttext = true (add image alt attribute)
|
||||
* - class = image class attribute (default 'userpicture')
|
||||
* - visibletoscreenreaders = true (whether to be visible to screen readers)
|
||||
* - includefullname = false (whether to include the user's full name together with the user picture)
|
||||
* - includetoken = false (whether to use a token for authentication. True for current user, int value for other user id)
|
||||
* @return user_picture User picture object
|
||||
*/
|
||||
public static function get_profile_picture(stdClass $user, context $context = null, array $options = []): user_picture {
|
||||
// Create a new user picture object.
|
||||
$userpicture = new user_picture($user);
|
||||
|
||||
// Override the user picture object with the options provided.
|
||||
foreach ($options as $key => $value) {
|
||||
if (property_exists($userpicture, $key)) {
|
||||
$userpicture->$key = $value;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the user picture.
|
||||
return $userpicture;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+6
-93
@@ -3595,103 +3595,16 @@ function ismoving($courseid) {
|
||||
* @return string
|
||||
*/
|
||||
function fullname($user, $override=false) {
|
||||
global $CFG, $SESSION;
|
||||
// Note: We do not intend to deprecate this function any time soon as it is too widely used at this time.
|
||||
// Uses of it should be updated to use the new API and pass updated arguments.
|
||||
|
||||
if (!isset($user->firstname) and !isset($user->lastname)) {
|
||||
// Return an empty string if there is no user.
|
||||
if (empty($user)) {
|
||||
return '';
|
||||
}
|
||||
|
||||
// Get all of the name fields.
|
||||
$allnames = \core_user\fields::get_name_fields();
|
||||
if ($CFG->debugdeveloper) {
|
||||
foreach ($allnames as $allname) {
|
||||
if (!property_exists($user, $allname)) {
|
||||
// If all the user name fields are not set in the user object, then notify the programmer that it needs to be fixed.
|
||||
debugging('You need to update your sql to include additional name fields in the user object.', DEBUG_DEVELOPER);
|
||||
// Message has been sent, no point in sending the message multiple times.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$override) {
|
||||
if (!empty($CFG->forcefirstname)) {
|
||||
$user->firstname = $CFG->forcefirstname;
|
||||
}
|
||||
if (!empty($CFG->forcelastname)) {
|
||||
$user->lastname = $CFG->forcelastname;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($SESSION->fullnamedisplay)) {
|
||||
$CFG->fullnamedisplay = $SESSION->fullnamedisplay;
|
||||
}
|
||||
|
||||
$template = null;
|
||||
// If the fullnamedisplay setting is available, set the template to that.
|
||||
if (isset($CFG->fullnamedisplay)) {
|
||||
$template = $CFG->fullnamedisplay;
|
||||
}
|
||||
// If the template is empty, or set to language, return the language string.
|
||||
if ((empty($template) || $template == 'language') && !$override) {
|
||||
return get_string('fullnamedisplay', null, $user);
|
||||
}
|
||||
|
||||
// Check to see if we are displaying according to the alternative full name format.
|
||||
if ($override) {
|
||||
if (empty($CFG->alternativefullnameformat) || $CFG->alternativefullnameformat == 'language') {
|
||||
// Default to show just the user names according to the fullnamedisplay string.
|
||||
return get_string('fullnamedisplay', null, $user);
|
||||
} else {
|
||||
// If the override is true, then change the template to use the complete name.
|
||||
$template = $CFG->alternativefullnameformat;
|
||||
}
|
||||
}
|
||||
|
||||
$requirednames = array();
|
||||
// With each name, see if it is in the display name template, and add it to the required names array if it is.
|
||||
foreach ($allnames as $allname) {
|
||||
if (strpos($template, $allname) !== false) {
|
||||
$requirednames[] = $allname;
|
||||
}
|
||||
}
|
||||
|
||||
$displayname = $template;
|
||||
// Switch in the actual data into the template.
|
||||
foreach ($requirednames as $altname) {
|
||||
if (isset($user->$altname)) {
|
||||
// Using empty() on the below if statement causes breakages.
|
||||
if ((string)$user->$altname == '') {
|
||||
$displayname = str_replace($altname, 'EMPTY', $displayname);
|
||||
} else {
|
||||
$displayname = str_replace($altname, $user->$altname, $displayname);
|
||||
}
|
||||
} else {
|
||||
$displayname = str_replace($altname, 'EMPTY', $displayname);
|
||||
}
|
||||
}
|
||||
// Tidy up any misc. characters (Not perfect, but gets most characters).
|
||||
// Don't remove the "u" at the end of the first expression unless you want garbled characters when combining hiragana or
|
||||
// katakana and parenthesis.
|
||||
$patterns = array();
|
||||
// This regular expression replacement is to fix problems such as 'James () Kirk' Where 'Tiberius' (middlename) has not been
|
||||
// filled in by a user.
|
||||
// The special characters are Japanese brackets that are common enough to make allowances for them (not covered by :punct:).
|
||||
$patterns[] = '/[[:punct:]「」]*EMPTY[[:punct:]「」]*/u';
|
||||
// This regular expression is to remove any double spaces in the display name.
|
||||
$patterns[] = '/\s{2,}/u';
|
||||
foreach ($patterns as $pattern) {
|
||||
$displayname = preg_replace($pattern, ' ', $displayname);
|
||||
}
|
||||
|
||||
// Trimming $displayname will help the next check to ensure that we don't have a display name with spaces.
|
||||
$displayname = trim($displayname);
|
||||
if (empty($displayname)) {
|
||||
// Going with just the first name if no alternate fields are filled out. May be changed later depending on what
|
||||
// people in general feel is a good setting to fall back on.
|
||||
$displayname = $user->firstname;
|
||||
}
|
||||
return $displayname;
|
||||
$options = ['override' => $override];
|
||||
return core_user::get_fullname($user, null, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -813,4 +813,95 @@ class user_test extends \advanced_testcase {
|
||||
$this->assertFalse(\core_user::awaiting_action($admin));
|
||||
$this->assertTrue(\core_user::awaiting_action($manager));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for function to get user details.
|
||||
*
|
||||
* @covers \core_user::get_fullname
|
||||
*/
|
||||
public function test_display_name() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$user = $this->getDataGenerator()->create_user(['firstname' => 'John', 'lastname' => 'Doe']);
|
||||
$context = \context_system::instance();
|
||||
|
||||
// Show real name as the force names config are not set.
|
||||
$this->assertEquals('John Doe', \core_user::get_fullname($user, $context));
|
||||
|
||||
// With override, still show real name.
|
||||
$options = ['override' => true];
|
||||
$this->assertEquals('John Doe', \core_user::get_fullname($user, $context, $options));
|
||||
|
||||
// Set the force names config.
|
||||
set_config('forcefirstname', 'Bruce');
|
||||
set_config('forcelastname', 'Simpson');
|
||||
|
||||
// Show forced names.
|
||||
$this->assertEquals('Bruce Simpson', \core_user::get_fullname($user, $context));
|
||||
|
||||
// With override, show real name.
|
||||
$options = ['override' => true];
|
||||
$this->assertEquals('John Doe', \core_user::get_fullname($user, $context, $options));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for function to get user details.
|
||||
*
|
||||
* @covers \core_user::get_profile_url
|
||||
*/
|
||||
public function test_display_profile_url() {
|
||||
$this->resetAfterTest();
|
||||
|
||||
$user = $this->getDataGenerator()->create_user(['firstname' => 'John', 'lastname' => 'Doe']);
|
||||
|
||||
// Display profile url at site context.
|
||||
$this->assertEquals("https://www.example.com/moodle/user/profile.php?id={$user->id}",
|
||||
\core_user::get_profile_url($user)->out());
|
||||
|
||||
// Display profile url at course context.
|
||||
$course = $this->getDataGenerator()->create_course();
|
||||
$coursecontext = \context_course::instance($course->id);
|
||||
$this->assertEquals("https://www.example.com/moodle/user/view.php?id={$user->id}&courseid={$course->id}",
|
||||
\core_user::get_profile_url($user, $coursecontext));
|
||||
|
||||
// Throw error if userid is invalid.
|
||||
unset($user->id);
|
||||
$this->expectException(\coding_exception::class);
|
||||
$this->expectExceptionMessage('User id is required when displaying profile url.');
|
||||
\core_user::get_profile_url($user, $coursecontext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for function to get user details.
|
||||
*
|
||||
* @covers \core_user::get_profile_picture
|
||||
*/
|
||||
public function test_display_profile_picture() {
|
||||
global $OUTPUT, $CFG;
|
||||
$this->resetAfterTest();
|
||||
|
||||
$user1 = $this->getDataGenerator()->create_user(['firstname' => 'John', 'lastname' => 'Doe']);
|
||||
$user2 = $this->getDataGenerator()->create_user(['picture' => 1]);
|
||||
|
||||
// Display profile picture.
|
||||
$context = \context_system::instance();
|
||||
// No image, show initials.
|
||||
$this->assertStringContainsString("<span class=\"userinitials size-35\">JD</span></a>",
|
||||
$OUTPUT->render(\core_user::get_profile_picture($user1, $context)));
|
||||
// With Image.
|
||||
$expectedimagesrc = $CFG->wwwroot . '/pluginfile.php/' . \context_user::instance($user2->id)->id .
|
||||
'/user/icon/boost/f2?rev=1';
|
||||
$this->assertStringContainsString($expectedimagesrc,
|
||||
$OUTPUT->render(\core_user::get_profile_picture($user2, $context)));
|
||||
|
||||
// Display profile picture with options.
|
||||
$options = ['size' => 50, 'includefullname' => true];
|
||||
$this->assertStringContainsString("<span class=\"userinitials size-50\">JD</span>John Doe</a>",
|
||||
$OUTPUT->render(\core_user::get_profile_picture($user1, $context, $options)));
|
||||
|
||||
// Display profile picture with options, no link.
|
||||
$options = ['link' => false];
|
||||
$this->assertEquals("<span class=\"userinitials size-35\">JD</span>",
|
||||
$OUTPUT->render(\core_user::get_profile_picture($user1, $context, $options)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,11 @@ This files describes API changes for code that uses the user API.
|
||||
|
||||
=== 4.3 ===
|
||||
|
||||
* Added new methods:
|
||||
- `core_user::get_profile_picture` for retrieving user picture.
|
||||
- `core_user::get_profile_url` for retrieving profile url.
|
||||
- `core_user::get_fullname` for retrieving user full name.
|
||||
|
||||
* The following previously deprecated methods have been removed and can no longer be used:
|
||||
- `profile_display_fields`
|
||||
- `profile_edit_category`
|
||||
|
||||
Reference in New Issue
Block a user