mirror of
https://github.com/moodle/moodle.git
synced 2025-04-13 04:22:07 +02:00
MDL-26171 user: implement method for retrieving fullname via SQL.
This commit is contained in:
parent
a747fd3055
commit
4098af1c52
@ -16,6 +16,8 @@
|
||||
|
||||
namespace core_user;
|
||||
|
||||
use core_text;
|
||||
|
||||
/**
|
||||
* Class for retrieving information about user fields that are needed for displaying user identity.
|
||||
*
|
||||
@ -571,6 +573,65 @@ class fields {
|
||||
'mappings' => $mappings];
|
||||
}
|
||||
|
||||
/**
|
||||
* Similar to {@see \moodle_database::sql_fullname} except it returns all user name fields as defined by site config, in a
|
||||
* single select statement suitable for inclusion in a query/filter for a users fullname, e.g.
|
||||
*
|
||||
* [$select, $params] = fields::get_sql_fullname('u');
|
||||
* $users = $DB->get_records_sql_menu("SELECT u.id, {$select} FROM {user} u", $params);
|
||||
*
|
||||
* @param string|null $tablealias User table alias, if set elsewhere in the query, null if not required
|
||||
* @param bool $override If true then the alternativefullnameformat format rather than fullnamedisplay format will be used
|
||||
* @return array SQL select snippet and parameters
|
||||
*/
|
||||
public static function get_sql_fullname(?string $tablealias = 'u', bool $override = false): array {
|
||||
global $DB;
|
||||
|
||||
$unique = self::$uniqueidentifier++;
|
||||
|
||||
$namefields = self::get_name_fields();
|
||||
|
||||
// Create a dummy user object containing all name fields.
|
||||
$dummyuser = (object) array_combine($namefields, $namefields);
|
||||
$dummyfullname = fullname($dummyuser, $override);
|
||||
|
||||
// Extract any name fields from the fullname format in the order that they appear.
|
||||
$matchednames = array_values(order_in_string($namefields, $dummyfullname));
|
||||
$namelookup = $namepattern = $elements = $params = [];
|
||||
|
||||
foreach ($namefields as $index => $namefield) {
|
||||
$namefieldwithalias = $tablealias ? "{$tablealias}.{$namefield}" : $namefield;
|
||||
|
||||
// Coalesce the name fields to ensure we don't return null.
|
||||
$emptyparam = "uf{$unique}ep_{$index}";
|
||||
$namelookup[$namefield] = "COALESCE({$namefieldwithalias}, :{$emptyparam})";
|
||||
$params[$emptyparam] = '';
|
||||
|
||||
$namepattern[] = '\b' . preg_quote($namefield) . '\b';
|
||||
}
|
||||
|
||||
// Grab any content between the name fields, inserting them after each name field.
|
||||
$chunks = preg_split('/(' . implode('|', $namepattern) . ')/', $dummyfullname);
|
||||
foreach ($chunks as $index => $chunk) {
|
||||
if ($index > 0) {
|
||||
$elements[] = $namelookup[$matchednames[$index - 1]];
|
||||
}
|
||||
|
||||
if (core_text::strlen($chunk) > 0) {
|
||||
// If content is just whitespace, add to elements directly (also Oracle doesn't support passing ' ' as param).
|
||||
if (preg_match('/^\s+$/', $chunk)) {
|
||||
$elements[] = "'$chunk'";
|
||||
} else {
|
||||
$elementparam = "uf{$unique}fp_{$index}";
|
||||
$elements[] = ":{$elementparam}";
|
||||
$params[$elementparam] = $chunk;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [$DB->sql_concat(...$elements), $params];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the display name of a given user field.
|
||||
*
|
||||
|
@ -960,6 +960,8 @@ class participants_search {
|
||||
$keywords = $keywordsfilter->get_filter_values();
|
||||
}
|
||||
|
||||
$canviewfullnames = has_capability('moodle/site:viewfullnames', $this->context);
|
||||
|
||||
foreach ($keywords as $index => $keyword) {
|
||||
$searchkey1 = 'search' . $index . '1';
|
||||
$searchkey2 = 'search' . $index . '2';
|
||||
@ -970,9 +972,11 @@ class participants_search {
|
||||
$searchkey7 = 'search' . $index . '7';
|
||||
|
||||
$conditions = [];
|
||||
|
||||
// Search by fullname.
|
||||
$fullname = $DB->sql_fullname('u.firstname', 'u.lastname');
|
||||
[$fullname, $fullnameparams] = fields::get_sql_fullname('u', $canviewfullnames);
|
||||
$conditions[] = $DB->sql_like($fullname, ':' . $searchkey1, false, false);
|
||||
$params = array_merge($params, $fullnameparams);
|
||||
|
||||
// Search by email.
|
||||
$email = $DB->sql_like('email', ':' . $searchkey2, false, false);
|
||||
|
@ -521,4 +521,77 @@ class fields_test extends \advanced_testcase {
|
||||
$selects = $fields->get_sql()->selects;
|
||||
$this->assertEquals(', id, city', $selects);
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for {@see test_get_sql_fullname}
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_sql_fullname_provider(): array {
|
||||
return [
|
||||
['firstname lastname', 'FN LN'],
|
||||
['lastname, firstname', 'LN, FN'],
|
||||
['alternatename \'middlename\' lastname!', 'AN \'MN\' LN!'],
|
||||
['[firstname lastname alternatename]', '[FN LN AN]'],
|
||||
['firstnamephonetic lastnamephonetic', 'FNP LNP'],
|
||||
['firstname alternatename lastname', 'FN AN LN'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test sql_fullname_display method with various fullname formats
|
||||
*
|
||||
* @param string $fullnamedisplay
|
||||
* @param string $expectedfullname
|
||||
*
|
||||
* @dataProvider get_sql_fullname_provider
|
||||
*/
|
||||
public function test_get_sql_fullname(string $fullnamedisplay, string $expectedfullname): void {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest();
|
||||
|
||||
set_config('fullnamedisplay', $fullnamedisplay);
|
||||
$user = $this->getDataGenerator()->create_user([
|
||||
'firstname' => 'FN',
|
||||
'lastname' => 'LN',
|
||||
'firstnamephonetic' => 'FNP',
|
||||
'lastnamephonetic' => 'LNP',
|
||||
'middlename' => 'MN',
|
||||
'alternatename' => 'AN',
|
||||
]);
|
||||
|
||||
[$sqlfullname, $params] = fields::get_sql_fullname('u');
|
||||
$fullname = $DB->get_field_sql("SELECT {$sqlfullname} FROM {user} u WHERE u.id = :id", $params + [
|
||||
'id' => $user->id,
|
||||
]);
|
||||
|
||||
$this->assertEquals($expectedfullname, $fullname);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test sql_fullname_display when one of the configured name fields is null
|
||||
*/
|
||||
public function test_get_sql_fullname_null_field(): void {
|
||||
global $DB;
|
||||
|
||||
$this->resetAfterTest();
|
||||
|
||||
set_config('fullnamedisplay', 'firstname lastname alternatename');
|
||||
$user = $this->getDataGenerator()->create_user([
|
||||
'firstname' => 'FN',
|
||||
'lastname' => 'LN',
|
||||
]);
|
||||
|
||||
// Set alternatename field to null, ensure we still get result in later assertion.
|
||||
$user->alternatename = null;
|
||||
user_update_user($user, false);
|
||||
|
||||
[$sqlfullname, $params] = fields::get_sql_fullname('u');
|
||||
$fullname = $DB->get_field_sql("SELECT {$sqlfullname} FROM {user} u WHERE u.id = :id", $params + [
|
||||
'id' => $user->id,
|
||||
]);
|
||||
|
||||
$this->assertEquals('FN LN ', $fullname);
|
||||
}
|
||||
}
|
||||
|
@ -1073,6 +1073,14 @@ class participants_search_test extends advanced_testcase {
|
||||
'tony.rogers',
|
||||
],
|
||||
],
|
||||
'ANY: Filter on fullname only' => (object) [
|
||||
'keywords' => ['Barbara Bennett'],
|
||||
'jointype' => filter::JOINTYPE_ANY,
|
||||
'count' => 1,
|
||||
'expectedusers' => [
|
||||
'barbara.bennett',
|
||||
],
|
||||
],
|
||||
'ANY: Filter on middlename only' => (object) [
|
||||
'keywords' => ['Jeff'],
|
||||
'jointype' => filter::JOINTYPE_ANY,
|
||||
|
@ -6,6 +6,7 @@ This files describes API changes for code that uses the user API.
|
||||
update failed all users in the operation would fail.
|
||||
* External function core_user_external::update_users() now returns an error code and message to why a user update
|
||||
action failed.
|
||||
* New method `core_user\fields::get_sql_fullname` for retrieving user fullname format in SQL statement
|
||||
|
||||
=== 3.11 ===
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user