mirror of
https://github.com/moodle/moodle.git
synced 2025-01-18 22:08:20 +01:00
MDL-61028 core_user: Function to search visible users
Implements core_user::search function which can search through the names (and, if allowed, other identity fields) of all users visible to the current logged-in user, within a course context or globally.
This commit is contained in:
parent
a97c937033
commit
71d985ab7d
@ -172,6 +172,235 @@ class core_user {
|
||||
return $DB->get_record('user', array('username' => $username, 'mnethostid' => $mnethostid), $fields, $strictness);
|
||||
}
|
||||
|
||||
/**
|
||||
* Searches for users by name, possibly within a specified context, with current user's access.
|
||||
*
|
||||
* Deciding which users to search is complicated because it relies on user permissions;
|
||||
* ideally, we shouldn't show names if you aren't allowed to see their profile. The permissions
|
||||
* for seeing profile are really complicated.
|
||||
*
|
||||
* Even if search is restricted to a course, it's possible that other people might have
|
||||
* been able to contribute within the course (e.g. they were enrolled before and not now;
|
||||
* or people with system-level roles) so if the user has permission we do want to include
|
||||
* everyone. However, if there are multiple results then we prioritise the ones who are
|
||||
* enrolled in the course.
|
||||
*
|
||||
* If you have moodle/user:viewdetails at system level, you can search everyone.
|
||||
* Otherwise we check which courses you *do* have that permission and search everyone who is
|
||||
* enrolled on those courses.
|
||||
*
|
||||
* Normally you can only search the user's name. If you have the moodle/site:viewuseridentity
|
||||
* capability then we also let you search the fields which are listed as identity fields in
|
||||
* the 'showuseridentity' config option. For example, this might include the user's ID number
|
||||
* or email.
|
||||
*
|
||||
* The $max parameter controls the maximum number of users returned. If users are restricted
|
||||
* from view for some reason, multiple runs of the main query might be made; the $querylimit
|
||||
* parameter allows this to be restricted. Both parameters can be zero to remove limits.
|
||||
*
|
||||
* The returned user objects include id, username, all fields required for user pictures, and
|
||||
* user identity fields.
|
||||
*
|
||||
* @param string $query Search query text
|
||||
* @param \context_course|null $coursecontext Course context or null if system-wide
|
||||
* @param int $max Max number of users to return, default 30 (zero = no limit)
|
||||
* @param int $querylimit Max number of database queries, default 5 (zero = no limit)
|
||||
* @return array Array of user objects with limited fields
|
||||
*/
|
||||
public static function search($query, \context_course $coursecontext = null,
|
||||
$max = 30, $querylimit = 5) {
|
||||
global $CFG, $DB;
|
||||
require_once($CFG->dirroot . '/user/lib.php');
|
||||
|
||||
// Allow limits to be turned off.
|
||||
if (!$max) {
|
||||
$max = PHP_INT_MAX;
|
||||
}
|
||||
if (!$querylimit) {
|
||||
$querylimit = PHP_INT_MAX;
|
||||
}
|
||||
|
||||
// Check permission to view profiles at each context.
|
||||
$systemcontext = \context_system::instance();
|
||||
$viewsystem = has_capability('moodle/user:viewdetails', $systemcontext);
|
||||
if ($viewsystem) {
|
||||
$userquery = 'SELECT id FROM {user}';
|
||||
$userparams = [];
|
||||
}
|
||||
if (!$viewsystem) {
|
||||
list($userquery, $userparams) = self::get_enrolled_sql_on_courses_with_capability(
|
||||
'moodle/user:viewdetails');
|
||||
if (!$userquery) {
|
||||
// No permissions anywhere, return nothing.
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
// Start building the WHERE clause based on name.
|
||||
list ($where, $whereparams) = users_search_sql($query, 'u', false);
|
||||
|
||||
// We allow users to search with extra identity fields (as well as name) but only if they
|
||||
// have the permission to display those identity fields.
|
||||
$extrasql = '';
|
||||
$extraparams = [];
|
||||
|
||||
if (empty($CFG->showuseridentity)) {
|
||||
// Explode gives wrong result with empty string.
|
||||
$extra = [];
|
||||
} else {
|
||||
$extra = explode(',', $CFG->showuseridentity);
|
||||
}
|
||||
|
||||
// We need the username just to skip guests.
|
||||
$extrafieldlist = $extra;
|
||||
if (!in_array('username', $extra)) {
|
||||
$extrafieldlist[] = 'username';
|
||||
}
|
||||
// The deleted flag will always be false because users_search_sql excludes deleted users,
|
||||
// but it must be present or it causes PHP warnings in some functions below.
|
||||
if (!in_array('deleted', $extra)) {
|
||||
$extrafieldlist[] = 'deleted';
|
||||
}
|
||||
$extrafields = \user_picture::fields('u',
|
||||
array_merge(get_all_user_name_fields(), $extrafieldlist));
|
||||
|
||||
$index = 1;
|
||||
foreach ($extra as $fieldname) {
|
||||
if ($extrasql) {
|
||||
$extrasql .= ' OR ';
|
||||
}
|
||||
$extrasql .= $DB->sql_like('u.' . $fieldname, ':extra' . $index, false);
|
||||
$extraparams['extra' . $index] = $query . '%';
|
||||
$index++;
|
||||
}
|
||||
|
||||
$identitysystem = has_capability('moodle/site:viewuseridentity', $systemcontext);
|
||||
$usingshowidentity = false;
|
||||
if ($identitysystem) {
|
||||
// They have permission everywhere so just add the extra query to the normal query.
|
||||
$where .= ' OR ' . $extrasql;
|
||||
$whereparams = array_merge($whereparams, $extraparams);
|
||||
} else {
|
||||
// Get all courses where user can view full user identity.
|
||||
list($sql, $params) = self::get_enrolled_sql_on_courses_with_capability(
|
||||
'moodle/site:viewuseridentity');
|
||||
if ($sql) {
|
||||
// Join that with the user query to get an extra field indicating if we can.
|
||||
$userquery = "
|
||||
SELECT innerusers.id, COUNT(identityusers.id) AS showidentity
|
||||
FROM ($userquery) innerusers
|
||||
LEFT JOIN ($sql) identityusers ON identityusers.id = innerusers.id
|
||||
GROUP BY innerusers.id";
|
||||
$userparams = array_merge($userparams, $params);
|
||||
$usingshowidentity = true;
|
||||
|
||||
// Query on the extra fields only in those places.
|
||||
$where .= ' OR (users.showidentity > 0 AND (' . $extrasql . '))';
|
||||
$whereparams = array_merge($whereparams, $extraparams);
|
||||
}
|
||||
}
|
||||
|
||||
// Default order is just name order. But if searching within a course then we show users
|
||||
// within the course first.
|
||||
list ($order, $orderparams) = users_order_by_sql('u', $query, $systemcontext);
|
||||
if ($coursecontext) {
|
||||
list ($sql, $params) = get_enrolled_sql($coursecontext);
|
||||
$mainfield = 'innerusers2.id';
|
||||
if ($usingshowidentity) {
|
||||
$mainfield .= ', innerusers2.showidentity';
|
||||
}
|
||||
$userquery = "
|
||||
SELECT $mainfield, COUNT(courseusers.id) AS incourse
|
||||
FROM ($userquery) innerusers2
|
||||
LEFT JOIN ($sql) courseusers ON courseusers.id = innerusers2.id
|
||||
GROUP BY $mainfield";
|
||||
$userparams = array_merge($userparams, $params);
|
||||
|
||||
$order = 'incourse DESC, ' . $order;
|
||||
}
|
||||
|
||||
// Get result (first 30 rows only) from database. Take a couple spare in case we have to
|
||||
// drop some.
|
||||
$result = [];
|
||||
$got = 0;
|
||||
$pos = 0;
|
||||
$readcount = $max + 2;
|
||||
for ($i = 0; $i < $querylimit; $i++) {
|
||||
$rawresult = $DB->get_records_sql("
|
||||
SELECT users.*, $extrafields
|
||||
FROM ($userquery) users
|
||||
JOIN {user} u ON u.id = users.id
|
||||
WHERE $where
|
||||
ORDER BY $order", array_merge($userparams, $whereparams, $orderparams),
|
||||
$pos, $readcount);
|
||||
foreach ($rawresult as $user) {
|
||||
// Skip guest.
|
||||
if ($user->username === 'guest') {
|
||||
continue;
|
||||
}
|
||||
// Check user can really view profile (there are per-user cases where this could
|
||||
// be different for some reason, this is the same check used by the profile view pages
|
||||
// to double-check that it is OK).
|
||||
if (!user_can_view_profile($user)) {
|
||||
continue;
|
||||
}
|
||||
$result[] = $user;
|
||||
$got++;
|
||||
if ($got >= $max) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($got >= $max) {
|
||||
// All necessary results obtained.
|
||||
break;
|
||||
}
|
||||
if (count($rawresult) < $readcount) {
|
||||
// No more results from database.
|
||||
break;
|
||||
}
|
||||
$pos += $readcount;
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an SQL query that lists all enrolled user ids on any course where the current
|
||||
* user has the specified capability. Helper function used for searching users.
|
||||
*
|
||||
* @param string $capability Required capability
|
||||
* @return array Array containing SQL and params, or two nulls if there are no courses
|
||||
*/
|
||||
protected static function get_enrolled_sql_on_courses_with_capability($capability) {
|
||||
// Get all courses where user have the capability.
|
||||
$courses = get_user_capability_course($capability, null, true,
|
||||
'ctxid, ctxpath, ctxdepth, ctxlevel, ctxinstance');
|
||||
if (!$courses) {
|
||||
return [null, null];
|
||||
}
|
||||
|
||||
// Loop around all courses getting the SQL for enrolled users. Note: This query could
|
||||
// probably be more efficient (without the union) if get_enrolled_sql had a way to
|
||||
// pass an array of courseids, but it doesn't.
|
||||
$unionsql = '';
|
||||
$unionparams = [];
|
||||
foreach ($courses as $course) {
|
||||
// Get SQL to list user ids enrolled in this course.
|
||||
\context_helper::preload_from_record($course);
|
||||
list ($sql, $params) = get_enrolled_sql(\context_course::instance($course->id));
|
||||
|
||||
// Combine to a big union query.
|
||||
if ($unionsql) {
|
||||
$unionsql .= ' UNION ';
|
||||
}
|
||||
$unionsql .= $sql;
|
||||
$unionparams = array_merge($unionparams, $params);
|
||||
}
|
||||
|
||||
return [$unionsql, $unionparams];
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function to return dummy noreply user record.
|
||||
*
|
||||
|
@ -117,6 +117,304 @@ class core_user_testcase extends advanced_testcase {
|
||||
$this->assertFalse(core_user::get_user_by_username('janedoe'));
|
||||
}
|
||||
|
||||
public function test_search() {
|
||||
global $DB;
|
||||
|
||||
self::init_search_tests();
|
||||
|
||||
// Set up three courses for test.
|
||||
$generator = $this->getDataGenerator();
|
||||
$course1 = $generator->create_course();
|
||||
$course2 = $generator->create_course();
|
||||
$course3 = $generator->create_course();
|
||||
|
||||
// Manager user in system level.
|
||||
$manager = $generator->create_user(['firstname' => 'Manager', 'lastname' => 'Person',
|
||||
'email' => 'x@x.x']);
|
||||
$systemcontext = \context_system::instance();
|
||||
$generator->role_assign($DB->get_field('role', 'id', ['shortname' => 'manager']),
|
||||
$manager->id, $systemcontext->id);
|
||||
|
||||
// Teachers in one and two courses.
|
||||
$teacher1 = $generator->create_user(['firstname' => 'Alberto', 'lastname' => 'Unwin',
|
||||
'email' => 'a.unwin@x.x']);
|
||||
$generator->enrol_user($teacher1->id, $course1->id, 'teacher');
|
||||
$teacher2and3 = $generator->create_user(['firstname' => 'Alexandra', 'lastname' => 'Penguin',
|
||||
'email' => 'sillypenguin@x.x']);
|
||||
$generator->enrol_user($teacher2and3->id, $course2->id, 'teacher');
|
||||
$generator->enrol_user($teacher2and3->id, $course3->id, 'teacher');
|
||||
|
||||
// Students in each course and some on multiple courses.
|
||||
$student1 = $generator->create_user(['firstname' => 'Amanda', 'lastname' => 'Hodder',
|
||||
'email' => 'hodder_a@x.x']);
|
||||
$generator->enrol_user($student1->id, $course1->id, 'student');
|
||||
$student2 = $generator->create_user(['firstname' => 'Audrey', 'lastname' => 'Methuen',
|
||||
'email' => 'audrey@x.x']);
|
||||
$generator->enrol_user($student2->id, $course2->id, 'student');
|
||||
$student3 = $generator->create_user(['firstname' => 'Austin', 'lastname' => 'Bloomsbury',
|
||||
'email' => 'a.bloomsbury@x.x']);
|
||||
$generator->enrol_user($student3->id, $course3->id, 'student');
|
||||
$student1and2 = $generator->create_user(['firstname' => 'Augustus', 'lastname' => 'Random',
|
||||
'email' => 'random@x.x']);
|
||||
$generator->enrol_user($student1and2->id, $course1->id, 'student');
|
||||
$generator->enrol_user($student1and2->id, $course2->id, 'student');
|
||||
$studentall = $generator->create_user(['firstname' => 'Amelia', 'lastname' => 'House',
|
||||
'email' => 'house@x.x']);
|
||||
$generator->enrol_user($studentall->id, $course1->id, 'student');
|
||||
$generator->enrol_user($studentall->id, $course2->id, 'student');
|
||||
$generator->enrol_user($studentall->id, $course3->id, 'student');
|
||||
|
||||
// Special mixed user (name does not begin with A) is a teacher in one course and student
|
||||
// in another.
|
||||
$mixed = $generator->create_user(['firstname' => 'Xavier', 'lastname' => 'Harper',
|
||||
'email' => 'xh1248@x.x']);
|
||||
$generator->enrol_user($mixed->id, $course1->id, 'student');
|
||||
$generator->enrol_user($mixed->id, $course3->id, 'teacher');
|
||||
|
||||
// As admin user, try searching for somebody at system level by first name, checking the
|
||||
// results.
|
||||
$this->setAdminUser();
|
||||
$result = core_user::search('Amelia');
|
||||
$this->assertCount(1, $result);
|
||||
|
||||
// Check some basic fields, and test other fields are present.
|
||||
$this->assertEquals($studentall->id, $result[0]->id);
|
||||
$this->assertEquals('Amelia', $result[0]->firstname);
|
||||
$this->assertEquals('House', $result[0]->lastname);
|
||||
$this->assertEquals('house@x.x', $result[0]->email);
|
||||
$this->assertEquals(0, $result[0]->deleted);
|
||||
$this->assertObjectHasAttribute('firstnamephonetic', $result[0]);
|
||||
$this->assertObjectHasAttribute('lastnamephonetic', $result[0]);
|
||||
$this->assertObjectHasAttribute('middlename', $result[0]);
|
||||
$this->assertObjectHasAttribute('alternatename', $result[0]);
|
||||
$this->assertObjectHasAttribute('imagealt', $result[0]);
|
||||
$this->assertObjectHasAttribute('username', $result[0]);
|
||||
|
||||
// Now search by lastname, both names, and partials, case-insensitive.
|
||||
$this->assertEquals($result, core_user::search('House'));
|
||||
$this->assertEquals($result, core_user::search('Amelia house'));
|
||||
$this->assertEquals($result, core_user::search('amelI'));
|
||||
$this->assertEquals($result, core_user::search('hoUs'));
|
||||
$this->assertEquals($result, core_user::search('Amelia H'));
|
||||
|
||||
// Admin user can also search by email (full or partial).
|
||||
$this->assertEquals($result, core_user::search('house@x.x'));
|
||||
$this->assertEquals($result, core_user::search('hOuse@'));
|
||||
|
||||
// What if we just search for A? (They all begin with A except the manager.)
|
||||
$result = core_user::search('a');
|
||||
$this->assertCount(7, $result);
|
||||
|
||||
// Au gets us Audrey, Austin, and Augustus - in alphabetical order by surname.
|
||||
$result = core_user::search('au');
|
||||
$this->assertCount(3, $result);
|
||||
$this->assertEquals('Austin', $result[0]->firstname);
|
||||
$this->assertEquals('Audrey', $result[1]->firstname);
|
||||
$this->assertEquals('Augustus', $result[2]->firstname);
|
||||
|
||||
// But if we search within course 2 we'll get Audrey and Augustus first.
|
||||
$course2context = \context_course::instance($course2->id);
|
||||
$result = core_user::search('au', $course2context);
|
||||
$this->assertCount(3, $result);
|
||||
$this->assertEquals('Audrey', $result[0]->firstname);
|
||||
$this->assertEquals('Augustus', $result[1]->firstname);
|
||||
$this->assertEquals('Austin', $result[2]->firstname);
|
||||
|
||||
// Try doing a few searches as manager - we should get the same results and can still
|
||||
// search by email too.
|
||||
$this->setUser($manager);
|
||||
$result = core_user::search('a');
|
||||
$this->assertCount(7, $result);
|
||||
$result = core_user::search('au', $course2context);
|
||||
$this->assertCount(3, $result);
|
||||
$result = core_user::search('house@x.x');
|
||||
$this->assertCount(1, $result);
|
||||
|
||||
// Teacher 1. No site-level permission so can't see users outside the enrolled course.
|
||||
$this->setUser($teacher1);
|
||||
$result = core_user::search('au');
|
||||
$this->assertCount(1, $result);
|
||||
$this->assertEquals('Augustus', $result[0]->firstname);
|
||||
|
||||
// Can still search by email for that user.
|
||||
$result = core_user::search('random@x.x');
|
||||
$this->assertCount(1, $result);
|
||||
|
||||
// Search everyone - teacher can only see four users (including themself).
|
||||
$result = core_user::search('a');
|
||||
$this->assertCount(4, $result);
|
||||
|
||||
// Search within course 2 - you get the same four users (which doesn't include
|
||||
// everyone on that course) but the two on course 2 should be first.
|
||||
$result = core_user::search('a', $course2context);
|
||||
$this->assertCount(4, $result);
|
||||
$this->assertEquals('Amelia', $result[0]->firstname);
|
||||
$this->assertEquals('Augustus', $result[1]->firstname);
|
||||
|
||||
// Other teacher.
|
||||
$this->setUser($teacher2and3);
|
||||
$result = core_user::search('au');
|
||||
$this->assertCount(3, $result);
|
||||
|
||||
$result = core_user::search('a');
|
||||
$this->assertCount(5, $result);
|
||||
|
||||
// Student can only see users on course 3.
|
||||
$this->setUser($student3);
|
||||
$result = core_user::search('a');
|
||||
$this->assertCount(3, $result);
|
||||
|
||||
$result = core_user::search('au');
|
||||
$this->assertCount(1, $result);
|
||||
$this->assertEquals('Austin', $result[0]->firstname);
|
||||
|
||||
// Student cannot search by email.
|
||||
$result = core_user::search('a.bloomsbury@x.x');
|
||||
$this->assertCount(0, $result);
|
||||
|
||||
// Student on all courses can see all the A users.
|
||||
$this->setUser($studentall);
|
||||
$result = core_user::search('a');
|
||||
$this->assertCount(7, $result);
|
||||
|
||||
// Mixed user can see users on courses 1 and 3.
|
||||
$this->setUser($mixed);
|
||||
$result = core_user::search('a');
|
||||
$this->assertCount(6, $result);
|
||||
|
||||
// Mixed user can search by email for students on course 3 but not on course 1.
|
||||
$result = core_user::search('hodder_a@x.x');
|
||||
$this->assertCount(0, $result);
|
||||
$result = core_user::search('house@x.x');
|
||||
$this->assertCount(1, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the search() function with limits on the number to return.
|
||||
*/
|
||||
public function test_search_with_count() {
|
||||
self::init_search_tests();
|
||||
$generator = $this->getDataGenerator();
|
||||
$course = $generator->create_course();
|
||||
|
||||
// Check default limit (30).
|
||||
for ($i = 0; $i < 31; $i++) {
|
||||
$student = $generator->create_user(['firstname' => 'Guy', 'lastname' => 'Xxx' . $i,
|
||||
'email' => 'xxx@x.x']);
|
||||
$generator->enrol_user($student->id, $course->id, 'student');
|
||||
}
|
||||
$this->setAdminUser();
|
||||
$result = core_user::search('Guy');
|
||||
$this->assertCount(30, $result);
|
||||
|
||||
// Check a small limit.
|
||||
$result = core_user::search('Guy', null, 10);
|
||||
$this->assertCount(10, $result);
|
||||
|
||||
// Check no limit.
|
||||
$result = core_user::search('Guy', null, 0);
|
||||
$this->assertCount(31, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* When course is in separate groups mode and user is a student, they can't see people who
|
||||
* are not in the same group. This is checked by the user profile permission thing and not
|
||||
* currently by the original query.
|
||||
*/
|
||||
public function test_search_group_permissions() {
|
||||
global $DB;
|
||||
|
||||
self::init_search_tests();
|
||||
|
||||
// Create one user to do the searching.
|
||||
$generator = $this->getDataGenerator();
|
||||
$course = $generator->create_course(['groupmode' => SEPARATEGROUPS]);
|
||||
$searcher = $generator->create_user(['firstname' => 'Searchy', 'lastname' => 'Sam',
|
||||
'email' => 'xxx@x.x']);
|
||||
$generator->enrol_user($searcher->id, $course->id, 'student');
|
||||
$group = $generator->create_group(['courseid' => $course->id]);
|
||||
groups_add_member($group, $searcher);
|
||||
|
||||
// Create a large number of people so that we have to make multiple database reads.
|
||||
$targets = [];
|
||||
for ($i = 0; $i < 50; $i++) {
|
||||
$student = $generator->create_user(['firstname' => 'Guy', 'lastname' => 'Xxx' . $i,
|
||||
'email' => 'xxx@x.x']);
|
||||
$generator->enrol_user($student->id, $course->id, 'student');
|
||||
$targets[] = $student;
|
||||
}
|
||||
|
||||
// The first and last people are in the same group.
|
||||
groups_add_member($group, $targets[0]);
|
||||
groups_add_member($group, $targets[49]);
|
||||
|
||||
// As searcher, we only find the 2 in the same group.
|
||||
$this->setUser($searcher);
|
||||
$result = core_user::search('Guy');
|
||||
$this->assertCount(2, $result);
|
||||
|
||||
// If we change the course to visible groups though, we get the max number.
|
||||
$DB->set_field('course', 'groupmode', VISIBLEGROUPS, ['id' => $course->id]);
|
||||
$result = core_user::search('Guy');
|
||||
$this->assertCount(30, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* When course is in separate groups mode and user is a student, they can't see people who
|
||||
* are not in the same group. This is checked by the user profile permission thing and not
|
||||
* currently by the original query.
|
||||
*/
|
||||
public function test_search_deleted_users() {
|
||||
self::init_search_tests();
|
||||
|
||||
// Create one user to do the searching.
|
||||
$generator = $this->getDataGenerator();
|
||||
$course = $generator->create_course();
|
||||
$searcher = $generator->create_user(['firstname' => 'Searchy', 'lastname' => 'Sam',
|
||||
'email' => 'xxx@x.x']);
|
||||
$generator->enrol_user($searcher->id, $course->id, 'student');
|
||||
|
||||
// Create another two users to search for.
|
||||
$student1 = $generator->create_user(['firstname' => 'Amelia', 'lastname' => 'Aardvark']);
|
||||
$student2 = $generator->create_user(['firstname' => 'Amelia', 'lastname' => 'Beetle']);
|
||||
$generator->enrol_user($student1->id, $course->id, 'student');
|
||||
$generator->enrol_user($student2->id, $course->id, 'student');
|
||||
|
||||
// As searcher, we find both users.
|
||||
$this->setUser($searcher);
|
||||
$result = core_user::search('Amelia');
|
||||
$this->assertCount(2, $result);
|
||||
|
||||
// What if one is deleted?
|
||||
delete_user($student1);
|
||||
$result = core_user::search('Amelia');
|
||||
$this->assertCount(1, $result);
|
||||
$this->assertEquals('Beetle', $result[0]->lastname);
|
||||
|
||||
// Delete the other, for good measure.
|
||||
delete_user($student2);
|
||||
$result = core_user::search('Amelia');
|
||||
$this->assertCount(0, $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Carries out standard setup for the search test functions.
|
||||
*/
|
||||
protected static function init_search_tests() {
|
||||
global $DB;
|
||||
|
||||
// For all existing users, set their name and email to something stupid so we don't
|
||||
// accidentally find one, confusing the test counts.
|
||||
$DB->set_field('user', 'firstname', 'Zaphod');
|
||||
$DB->set_field('user', 'lastname', 'Beeblebrox');
|
||||
$DB->set_field('user', 'email', 'zaphod@beeblebrox.example.org');
|
||||
|
||||
// This is the default value, but let's set it just to be certain in case it changes later.
|
||||
// It affects what fields admin (and other users with the viewuseridentity permission) can
|
||||
// search in addition to the name.
|
||||
set_config('showuseridentity', 'email');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test require_active_user
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user