mirror of
https://github.com/moodle/moodle.git
synced 2025-06-04 07:06:45 +02:00
Merge branch 'MDL-26171' of git://github.com/paulholden/moodle
This commit is contained in:
commit
c3a731d2d2
@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
namespace core_user;
|
namespace core_user;
|
||||||
|
|
||||||
|
use core_text;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class for retrieving information about user fields that are needed for displaying user identity.
|
* Class for retrieving information about user fields that are needed for displaying user identity.
|
||||||
*
|
*
|
||||||
@ -571,6 +573,65 @@ class fields {
|
|||||||
'mappings' => $mappings];
|
'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.
|
* Gets the display name of a given user field.
|
||||||
*
|
*
|
||||||
|
@ -960,6 +960,8 @@ class participants_search {
|
|||||||
$keywords = $keywordsfilter->get_filter_values();
|
$keywords = $keywordsfilter->get_filter_values();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$canviewfullnames = has_capability('moodle/site:viewfullnames', $this->context);
|
||||||
|
|
||||||
foreach ($keywords as $index => $keyword) {
|
foreach ($keywords as $index => $keyword) {
|
||||||
$searchkey1 = 'search' . $index . '1';
|
$searchkey1 = 'search' . $index . '1';
|
||||||
$searchkey2 = 'search' . $index . '2';
|
$searchkey2 = 'search' . $index . '2';
|
||||||
@ -970,9 +972,11 @@ class participants_search {
|
|||||||
$searchkey7 = 'search' . $index . '7';
|
$searchkey7 = 'search' . $index . '7';
|
||||||
|
|
||||||
$conditions = [];
|
$conditions = [];
|
||||||
|
|
||||||
// Search by fullname.
|
// 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);
|
$conditions[] = $DB->sql_like($fullname, ':' . $searchkey1, false, false);
|
||||||
|
$params = array_merge($params, $fullnameparams);
|
||||||
|
|
||||||
// Search by email.
|
// Search by email.
|
||||||
$email = $DB->sql_like('email', ':' . $searchkey2, false, false);
|
$email = $DB->sql_like('email', ':' . $searchkey2, false, false);
|
||||||
|
@ -521,4 +521,77 @@ class fields_test extends \advanced_testcase {
|
|||||||
$selects = $fields->get_sql()->selects;
|
$selects = $fields->get_sql()->selects;
|
||||||
$this->assertEquals(', id, city', $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',
|
'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) [
|
'ANY: Filter on middlename only' => (object) [
|
||||||
'keywords' => ['Jeff'],
|
'keywords' => ['Jeff'],
|
||||||
'jointype' => filter::JOINTYPE_ANY,
|
'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.
|
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
|
* External function core_user_external::update_users() now returns an error code and message to why a user update
|
||||||
action failed.
|
action failed.
|
||||||
|
* New method `core_user\fields::get_sql_fullname` for retrieving user fullname format in SQL statement
|
||||||
|
|
||||||
=== 3.11 ===
|
=== 3.11 ===
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user