diff --git a/lib/adminlib.php b/lib/adminlib.php index 0c7b15667da..4b909cf7d67 100644 --- a/lib/adminlib.php +++ b/lib/adminlib.php @@ -7968,9 +7968,7 @@ function admin_externalpage_setup($section, $extrabutton = '', array $extraurlpa * @return object admin_root object */ function admin_get_root($reload=false, $requirefulltree=true) { - global $CFG, $DB, $OUTPUT; - - static $ADMIN = NULL; + global $CFG, $DB, $OUTPUT, $ADMIN; if (is_null($ADMIN)) { // create the admin tree! diff --git a/lib/classes/session/manager.php b/lib/classes/session/manager.php index f617cc2217c..6568e4b9b22 100644 --- a/lib/classes/session/manager.php +++ b/lib/classes/session/manager.php @@ -712,6 +712,7 @@ class manager { * @param \stdClass $user record */ public static function set_user(\stdClass $user) { + global $ADMIN; $GLOBALS['USER'] = $user; unset($GLOBALS['USER']->description); // Conserve memory. unset($GLOBALS['USER']->password); // Improve security. @@ -723,6 +724,9 @@ class manager { // Relink session with global $USER just in case it got unlinked somehow. $_SESSION['USER'] =& $GLOBALS['USER']; + // Nullify the $ADMIN tree global. If we're changing users, then this is now stale and must be generated again if needed. + $ADMIN = null; + // Init session key. sesskey(); } diff --git a/lib/tests/admintree_test.php b/lib/tests/admintree_test.php index 1dae629c0dd..a4a51f298b4 100644 --- a/lib/tests/admintree_test.php +++ b/lib/tests/admintree_test.php @@ -414,4 +414,28 @@ class core_admintree_testcase extends advanced_testcase { $this->assertEquals('These entries are invalid: nonvalid site name', $adminsetting->write_setting('nonvalid site name')); $this->assertEquals('Empty lines are not valid', $adminsetting->write_setting("localhost\n")); } + + /** + * Verifies the $ADMIN global (adminroot cache) is properly reset when changing users, which might occur naturally during cron. + */ + public function test_adminroot_cache_reset() { + $this->resetAfterTest(); + global $DB; + // Current user is a manager at site context, which won't have access to the 'debugging' section of the admin tree. + $manageruser = $this->getDataGenerator()->create_user(); + $context = context_system::instance(); + $managerrole = $DB->get_record('role', array('shortname' => 'manager')); + role_assign($managerrole->id, $manageruser->id, $context->id); + $this->setUser($manageruser); + $adminroot = admin_get_root(); + $section = $adminroot->locate('debugging'); + $this->assertEmpty($section); + + // Now, change the user to an admin user and confirm we get a new copy of the admin tree when next we ask for it. + $adminuser = get_admin(); + $this->setUser($adminuser); + $adminroot = admin_get_root(); + $section = $adminroot->locate('debugging'); + $this->assertInstanceOf('\admin_settingpage', $section); + } }