diff --git a/lib/datalib.php b/lib/datalib.php index 4e47268c417..454bc7ec7b8 100644 --- a/lib/datalib.php +++ b/lib/datalib.php @@ -55,14 +55,17 @@ function get_admin() { global $CFG, $DB; static $mainadmin = null; + static $prevadmins = null; - if (isset($mainadmin)) { + if (empty($CFG->siteadmins)) { // Should not happen on an ordinary site. + return false; + } + + if (isset($mainadmin) and $prevadmins === $CFG->siteadmins) { return clone($mainadmin); } - if (empty($CFG->siteadmins)) { // Should not happen on an ordinary site - return false; - } + $mainadmin = null; foreach (explode(',', $CFG->siteadmins) as $id) { if ($user = $DB->get_record('user', array('id'=>$id, 'deleted'=>0))) { @@ -72,6 +75,7 @@ function get_admin() { } if ($mainadmin) { + $prevadmins = $CFG->siteadmins; return clone($mainadmin); } else { // this should not happen @@ -95,7 +99,19 @@ function get_admins() { FROM {user} u WHERE u.deleted = 0 AND u.id IN ($CFG->siteadmins)"; - return $DB->get_records_sql($sql); + // We want the same order as in $CFG->siteadmins. + $records = $DB->get_records_sql($sql); + $admins = array(); + foreach (explode(',', $CFG->siteadmins) as $id) { + $id = (int)$id; + if (!isset($records[$id])) { + // User does not exist, this should not happen. + continue; + } + $admins[$records[$id]->id] = $records[$id]; + } + + return $admins; } /** diff --git a/lib/tests/datalib_test.php b/lib/tests/datalib_test.php index 2d88ea9d32a..e758c74f857 100644 --- a/lib/tests/datalib_test.php +++ b/lib/tests/datalib_test.php @@ -87,4 +87,69 @@ class datalib_testcase extends advanced_testcase { $this->assertEquals(array('usersortexact1' => 'search', 'usersortexact2' => 'search', 'usersortexact3' => 'search', 'usersortexact4' => 'search', 'usersortexact5' => 'search'), $params); } + + public function test_get_admin() { + global $CFG, $DB; + + $this->resetAfterTest(); + + $this->assertSame('2', $CFG->siteadmins); // Admin always has id 2 in new installs. + $defaultadmin = get_admin(); + $this->assertEquals($defaultadmin->id, 2); + + unset_config('siteadmins'); + $this->assertFalse(get_admin()); + + set_config('siteadmins', -1); + $this->assertFalse(get_admin()); + + $user1 = $this->getDataGenerator()->create_user(); + $user2 = $this->getDataGenerator()->create_user(); + + set_config('siteadmins', $user1->id.','.$user2->id); + $admin = get_admin(); + $this->assertEquals($user1->id, $admin->id); + + set_config('siteadmins', '-1,'.$user2->id.','.$user1->id); + $admin = get_admin(); + $this->assertEquals($user2->id, $admin->id); + + $odlread = $DB->perf_get_reads(); + get_admin(); // No DB queries on repeated call expected. + get_admin(); + get_admin(); + $this->assertEquals($odlread, $DB->perf_get_reads()); + } + + public function test_get_admins() { + global $CFG, $DB; + + $this->resetAfterTest(); + + $this->assertSame('2', $CFG->siteadmins); // Admin always has id 2 in new installs. + + $user1 = $this->getDataGenerator()->create_user(); + $user2 = $this->getDataGenerator()->create_user(); + $user3 = $this->getDataGenerator()->create_user(); + $user4 = $this->getDataGenerator()->create_user(); + + $admins = get_admins(); + $this->assertEquals(1, count($admins)); + $admin = reset($admins); + $this->assertTrue(isset($admins[$admin->id])); + $this->assertEquals(2, $admin->id); + + unset_config('siteadmins'); + $this->assertSame(array(), get_admins()); + + set_config('siteadmins', -1); + $this->assertSame(array(), get_admins()); + + set_config('siteadmins', '-1,'.$user2->id.','.$user1->id.','.$user3->id); + $this->assertEquals(array($user2->id=>$user2, $user1->id=>$user1, $user3->id=>$user3), get_admins()); + + $odlread = $DB->perf_get_reads(); + get_admins(); // This should make just one query. + $this->assertEquals($odlread+1, $DB->perf_get_reads()); + } }