/** * Use with caution! This bypasses authentication. * This functionality should not be exposed externally. * @method setLoggedInUser * @static * @param {Users_User|string} $user The user object or user id */ static function setLoggedInUser($user = null) { if (!$user) { return Users::logout(); } if (is_string($user)) { $user = Users_User::fetch($user); } if (isset($_SESSION['Users']['loggedInUser']['id'])) { if ($user->id == $_SESSION['Users']['loggedInUser']['id']) { // This user is already the logged-in user. return; } } if ($sessionId = Q_Session::id()) { // Change the session id to prevent session fixation attacks $sessionId = Q_Session::regenerateId(true); } // Store the new information in the session $snf = Q_Config::get('Q', 'session', 'nonceField', 'nonce'); $_SESSION['Users']['loggedInUser']['id'] = $user->id; Q_Session::setNonce(true); $user->sessionCount = isset($user->sessionCount) ? $user->sessionCount + 1 : 1; // Do we need to update it? if (Q_Config::get('Users', 'setLoggedInUser', 'updateSessionKey', true)) { /** * @event Users/setLoggedInUser/updateSessionKey {before} * @param {Users_User} user */ Q::event('Users/setLoggedInUser/updateSessionKey', compact('user'), 'before'); $user->sessionId = $sessionId; $user->save(); // update sessionId in user /** * @event Users/setLoggedInUser/updateSessionKey {after} * @param {Users_User} user */ Q::event('Users/setLoggedInUser/updateSessionKey', compact('user'), 'after'); } $votes = Users_Vote::select('*')->where(array('userId' => $user->id, 'forType' => 'Users/hinted'))->fetchDbRows(null, null, 'forId'); // Cache already shown hints in the session. // The consistency of this mechanism across sessions is not perfect, i.e. // the same hint may repeat in multiple concurrent sessions, but it's ok. $_SESSION['Users']['hinted'] = array_keys($votes); /** * @event Users/setLoggedInUser {after} * @param {Users_User} user */ Q::event('Users/setLoggedInUser', compact('user'), 'after'); self::$loggedOut = false; }