MDL-46099 session: fix use of references for session globals

This reverses the references used for global $USER and $SESSION,
the reason is that PHP does not allow references to references.
$USER is a reference to $GLOBALS['USER'] which means we cannot
put any references to it. Solution is to store the current user and session
objects in $GLOBALS['USER'] and $GLOBALS['SESSIOn'] are reference
them in $_SESSION.

This patch makes the session code behave the same way in CLI,
phpunit and normal web requests - this allows use to finally
unit test most aspects of the session code in Moodle.
This commit is contained in:
Petr Skoda
2014-07-01 08:38:00 +12:00
parent 7a4832ecb9
commit 2e00d01db4
13 changed files with 431 additions and 92 deletions
+24 -8
View File
@@ -37,7 +37,10 @@ function sesskey() {
// note: do not use $USER because it may not be initialised yet
if (empty($_SESSION['USER']->sesskey)) {
if (!isset($_SESSION['USER'])) {
$_SESSION['USER'] = new stdClass;
// This should never happen,
// do not mess with session and globals here,
// let any checks fail instead!
return false;
}
$_SESSION['USER']->sesskey = random_string(10);
}
@@ -151,16 +154,28 @@ function get_moodle_cookie() {
* Sets up current user and course environment (lang, etc.) in cron.
* Do not use outside of cron script!
*
* @param stdClass $user full user object, null means default cron user (admin)
* @param $course full course record, null means $SITE
* @param stdClass $user full user object, null means default cron user (admin),
* value 'reset' means reset internal static caches.
* @param stdClass $course full course record, null means $SITE
* @return void
*/
function cron_setup_user($user = NULL, $course = NULL) {
global $CFG, $SITE, $PAGE;
if (!CLI_SCRIPT) {
throw new coding_exception('Function cron_setup_user() cannot be used in normal requests!');
}
static $cronuser = NULL;
static $cronsession = NULL;
if ($user === 'reset') {
$cronuser = null;
$cronsession = null;
\core\session\manager::init_empty_session();
return;
}
if (empty($cronuser)) {
/// ignore admins timezone, language and locale - use site default instead!
$cronuser = get_admin();
@@ -173,15 +188,16 @@ function cron_setup_user($user = NULL, $course = NULL) {
}
if (!$user) {
// cached default cron user (==modified admin for now)
// Cached default cron user (==modified admin for now).
\core\session\manager::init_empty_session();
\core\session\manager::set_user($cronuser);
$_SESSION['SESSION'] = $cronsession;
$GLOBALS['SESSION'] = $cronsession;
} else {
// emulate real user session - needed for caps in cron
if ($_SESSION['USER']->id != $user->id) {
// Emulate real user session - needed for caps in cron.
if ($GLOBALS['USER']->id != $user->id) {
\core\session\manager::init_empty_session();
\core\session\manager::set_user($user);
$_SESSION['SESSION'] = new stdClass();
}
}