diff --git a/includes/bootstrap.inc b/includes/bootstrap.inc index b2f4a27..10c9798 100644 --- a/includes/bootstrap.inc +++ b/includes/bootstrap.inc @@ -658,7 +658,8 @@ function variable_del($name) { * a redirected form submission which was completed). */ function page_get_cache() { - global $user, $base_root; + $user = drupal_current_user(); + global $base_root; $cache = NULL; @@ -903,7 +904,8 @@ function request_uri() { * @see watchdog_severity_levels() */ function watchdog($type, $message, $variables = array(), $severity = WATCHDOG_NOTICE, $link = NULL) { - global $user, $base_root; + global $base_root; + $user = drupal_current_user(); static $in_error_state = FALSE; @@ -1137,8 +1139,8 @@ function _drupal_bootstrap($phase) { case DRUPAL_BOOTSTRAP_SESSION: require_once DRUPAL_ROOT . '/' . variable_get('session_inc', 'includes/session.inc'); - session_set_save_handler('_sess_open', '_sess_close', '_sess_read', '_sess_write', '_sess_destroy_sid', '_sess_gc'); - session_start(); + drupal_session(); + drupal_init_user(); break; case DRUPAL_BOOTSTRAP_VARIABLES: diff --git a/includes/cache.inc b/includes/cache.inc index a7ad162..62c8d1f 100644 --- a/includes/cache.inc +++ b/includes/cache.inc @@ -15,7 +15,7 @@ * @return The cache or FALSE on failure. */ function cache_get($cid, $table = 'cache') { - global $user; + $user = drupal_current_user(); // Garbage collection necessary when enforcing a minimum cache lifetime $cache_flush = variable_get('cache_flush', 0); @@ -145,7 +145,7 @@ function cache_set($cid, $data, $table = 'cache', $expire = CACHE_PERMANENT, $he * match. If '*' is given as $cid, the table $table will be emptied. */ function cache_clear_all($cid = NULL, $table = NULL, $wildcard = FALSE) { - global $user; + $user = drupal_current_user(); if (!isset($cid) && !isset($table)) { // Clear the block cache first, so stale data will diff --git a/includes/common.inc b/includes/common.inc index 76eac62..bd0a94f 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -340,7 +340,7 @@ function drupal_goto($path = '', $query = NULL, $fragment = NULL, $http_response // Even though session_write_close() is registered as a shutdown function, we // need all session data written to the database before redirecting. - session_write_close(); + Session::get()->__destruct(); header('Location: ' . $url, TRUE, $http_response_code); @@ -1362,7 +1362,7 @@ function format_interval($timestamp, $granularity = 2, $langcode = NULL) { function format_date($timestamp, $type = 'medium', $format = '', $timezone = NULL, $langcode = NULL) { static $timezones = array(); if (!isset($timezone)) { - global $user; + $user = drupal_current_user(); if (variable_get('configurable_timezones', 1) && $user->uid && $user->timezone) { $timezone = $user->timezone; } @@ -2707,7 +2707,7 @@ function drupal_get_token($value = '') { * is true, the return value will always be true for anonymous users. */ function drupal_valid_token($token, $value = '', $skip_anonymous = FALSE) { - global $user; + $user = drupal_current_user(); return (($skip_anonymous && $user->uid == 0) || ($token == md5(session_id() . $value . variable_get('drupal_private_key', '')))); } @@ -2790,7 +2790,8 @@ function _drupal_bootstrap_full() { * @see drupal_page_header */ function page_set_cache() { - global $user, $base_root; + global $base_root; + $user = drupal_current_user(); if (!$user->uid && ($_SERVER['REQUEST_METHOD'] == 'GET' || $_SERVER['REQUEST_METHOD'] == 'HEAD') && count(drupal_get_messages(NULL, FALSE)) == 0) { // This will fail in some cases, see page_get_cache() for the explanation. diff --git a/includes/file.inc b/includes/file.inc index 4327e0b..cccdf11 100644 --- a/includes/file.inc +++ b/includes/file.inc @@ -800,7 +800,7 @@ function file_space_used($uid = NULL, $status = FILE_STATUS_PERMANENT) { * error. */ function file_save_upload($source, $validators = array(), $destination = FALSE, $replace = FILE_EXISTS_RENAME) { - global $user; + $user = drupal_current_user(); static $upload_cache; // Return cached objects without processing since the file will have @@ -974,7 +974,7 @@ function file_validate_name_length($file) { * @see hook_file_validate() */ function file_validate_extensions($file, $extensions) { - global $user; + $user = drupal_current_user(); $errors = array(); @@ -1005,7 +1005,7 @@ function file_validate_extensions($file, $extensions) { * @see hook_file_validate() */ function file_validate_size($file, $file_limit = 0, $user_limit = 0) { - global $user; + $user = drupal_current_user(); $errors = array(); @@ -1124,7 +1124,7 @@ function file_validate_image_resolution(&$file, $maximum_dimensions = 0, $minimu * @see file_unmanaged_save_data() */ function file_save_data($data, $destination = NULL, $replace = FILE_EXISTS_RENAME) { - global $user; + $user = drupal_current_user(); if ($filepath = file_unmanaged_save_data($data, $destination, $replace)) { // Create a file object. diff --git a/includes/form.inc b/includes/form.inc index e182622..4b7e23a 100644 --- a/includes/form.inc +++ b/includes/form.inc @@ -221,7 +221,7 @@ function drupal_rebuild_form($form_id, &$form_state, $args, $form_build_id = NUL function form_get_cache($form_build_id, &$form_state) { if ($cached = cache_get('form_' . $form_build_id, 'cache_form')) { $form = $cached->data; - global $user; + $user = drupal_current_user(); if ((isset($form['#cache_token']) && drupal_valid_token($form['#cache_token'])) || (!isset($form['#cache_token']) && !$user->uid)) { if ($cached = cache_get('storage_' . $form_build_id, 'cache_form')) { $form_state['storage'] = $cached->data; @@ -237,7 +237,7 @@ function form_get_cache($form_build_id, &$form_state) { function form_set_cache($form_build_id, $form, $form_state) { // 6 hours cache life time for forms should be plenty. $expire = 21600; - global $user; + $user = drupal_current_user(); if ($user->uid) { $form['#cache_token'] = drupal_get_token(); } @@ -462,7 +462,7 @@ function drupal_process_form($form_id, &$form, &$form_state) { * in here so that hook_form_alter() calls can use it, as well. */ function drupal_prepare_form($form_id, &$form, &$form_state) { - global $user; + $user = drupal_current_user(); $form['#type'] = 'form'; $form['#programmed'] = isset($form['#post']); diff --git a/includes/language.inc b/includes/language.inc index 866947e..6894882 100644 --- a/includes/language.inc +++ b/includes/language.inc @@ -10,7 +10,7 @@ * Choose a language for the page, based on language negotiation settings. */ function language_initialize() { - global $user; + $user = drupal_current_user(); // Configured presentation language mode. $mode = variable_get('language_negotiation', LANGUAGE_NEGOTIATION_NONE); diff --git a/includes/locale.inc b/includes/locale.inc index 3e87754..436e462 100644 --- a/includes/locale.inc +++ b/includes/locale.inc @@ -1751,7 +1751,7 @@ function _locale_export_get_strings($language = NULL, $group = 'default') { * are provided for PO and POT files. */ function _locale_export_po_generate($language = NULL, $strings = array(), $header = NULL) { - global $user; + $user = drupal_current_user(); if (!isset($header)) { if (isset($language)) { diff --git a/includes/session.inc b/includes/session.inc index c911398..96eaf56 100644 --- a/includes/session.inc +++ b/includes/session.inc @@ -5,171 +5,410 @@ * @file * User session handling functions. * - * The user-level session storage handlers: - * - _sess_open() - * - _sess_close() - * - _sess_read() - * - _sess_write() - * - _sess_destroy_sid() - * - _sess_gc() - * are assigned by session_set_save_handler() in bootstrap.inc and are called - * automatically by PHP. These functions should not be called directly. Session - * data should instead be accessed via the $_SESSION superglobal. */ /** - * Session handler assigned by session_set_save_handler(). + * Helper function that retrieves the current Session object. * - * This function is used to handle any initialization, such as file paths or - * database connections, that is needed before accessing session data. Drupal - * does not need to initialize anything in this function. + * Pretty superfluous for now, but will be a helpful part of an abstraction + * layer later... * - * This function should not be called directly. - * - * @return - * This function will always return TRUE. + * @return Session */ -function _sess_open() { - return TRUE; +function drupal_session() { + return Session::get(); +} + +function drupal_current_user() { + return Session::get()->user; } /** - * Session handler assigned by session_set_save_handler(). - * - * This function is used to close the current session. Because Drupal stores - * session data in the database immediately on write, this function does - * not need to do anything. - * - * This function should not be called directly. - * - * @return - * This function will always return TRUE. + * Here temporarily to prevent breakage while keeping other functions clean. + * REMOVE BEFORE COMMITTING! */ -function _sess_close() { - return TRUE; +function drupal_init_user() { + global $user; + $user = Session::get()->user; } /** - * Session handler assigned by session_set_save_handler(). - * - * This function will be called by PHP to retrieve the current user's - * session data, which is stored in the database. It also loads the - * current user's appropriate roles into the user object. - * - * This function should not be called directly. Session data should - * instead be accessed via the $_SESSION superglobal. + * Singleton class that provides session handling and validation. * - * @param $key - * Session ID. - * @return - * Either an array of the session data, or an empty string, if no data - * was found or the user is anonymous. */ -function _sess_read($key) { - global $user; +final class Session { + private static $_instance; + /** + * Boolean governing whether or not session writing will be allowed at session + * termination. + * + * Primarily useful for potentially dangerous manipulations of the current + * user object. Replaces drupal_save_session(). + * + * Defaults to TRUE (i.e., session writing will be permitted). + * + * @var bool + */ + public $allowWrite = TRUE; + + // Protect the original uid discovered in Session::read() from external writes + // so we can be sure it is still the proper one later. + private $_uid; + + /** + * The currently logged in user. + * + * The currently logged in user, previously the $user = drupal_current_user(), is now attached + * directly to the global session object. + * + * @var stdClass + */ + public $user; - // Write and Close handlers are called after destructing objects - // since PHP 5.0.5. - // Thus destructors can use sessions but session handler can't use objects. - // So we are moving session closure before destructing objects. - register_shutdown_function('session_write_close'); - - // Handle the case of first time visitors and clients that don't store - // cookies (eg. web crawlers). - if (!isset($_COOKIE[session_name()])) { - $user = drupal_anonymous_user(); - return ''; + private $_initSid; + private $_sessionStarted = FALSE; + private $_sessionDestroyed = FALSE; + private $_sessionClosed = FALSE; + + /** + * The user-level session storage handlers: + * - Session::open() + * - Session::close() + * - Session::read() + * - Session::write() + * - Session::destroy() + * - Session::() + * are assigned by session_set_save_handler() in bootstrap.inc and are called + * automatically by PHP. These functions should not be called directly. Session + * data should instead be accessed via the $_SESSION superglobal. + * + * @return unknown_type + */ + private function __construct() { + session_set_save_handler( + array(&$this, "open"), + array(&$this, "close"), + array(&$this, "read"), + array(&$this, "write"), + array(&$this, "destroy"), + array(&$this, "gc") + ); + session_start(); + $this->_sessionStarted = TRUE; } - // Otherwise, if the session is still active, we have a record of the - // client's session in the database. - $user = db_query("SELECT u.*, s.* FROM {users} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE s.sid = :sid", array(':sid' => $key))->fetchObject(); + /** + * Retrieve the object instance containing all the current session data. + * + * First called from bootstrap.inc during DRUPAL_BOOTSTRAP_SESSION. + * + * @return Session + */ + public static function get() { + if (empty(self::$_instance)) { + self::$_instance = new Session(); + } + return self::$_instance; + } - // We found the client's session record and they are an authenticated user. - if ($user && $user->uid > 0) { - // This is done to unserialize the data member of $user. - $user = drupal_unpack($user); + /** + * Finalize the login process. Must be called when logging in a user. + * + * The method checks the account object that is to replace the current user, + * records a watchdog message about the new session, saves the login + * timestamp, calls hook_user op 'login' and generates a new session. + * + * @param $account + * The new user object intended to replace the currently logged in user. + * @param $edit + * This array is passed to hook_user op login. + * @return + * Returns the new current user object. + */ + public function userLogin($account, &$edit) { + // Set the provided account as the new current user. + $this->user = $account; + // Set the protected uid record to the new authorized uid. + $this->_uid = $this->user->uid; - // Add roles element to $user. - $user->roles = array(); - $user->roles[DRUPAL_AUTHENTICATED_RID] = 'authenticated user'; - $user->roles += db_query("SELECT r.rid, r.name FROM {role} r INNER JOIN {users_roles} ur ON ur.rid = r.rid WHERE ur.uid = :uid", array(':uid' => $user->uid))->fetchAllKeyed(0, 1); + watchdog('user', 'Session opened for %name.', array('%name' => $this->user->name)); + // Update the user table timestamp noting user has logged in. + // This is also used to invalidate one-time login links. + $this->user->login = REQUEST_TIME; + db_update('users') + ->fields(array( + 'login' => $this->user->login + )) + ->condition('uid', $this->user->uid) + ->execute(); + user_module_invoke('login', $edit, $this->user); + $this->regenerate(); + return $this->user; } - // We didn't find the client's record (session has expired), or they - // are an anonymous user. - else { - $session = isset($user->session) ? $user->session : ''; - $user = drupal_anonymous_user($session); + + public function userLogout() { + watchdog('user', 'Session closed for %name.', array('%name' => $this->user->name)); + // Destroy the current user's session. + session_destroy(); + $this->regenerate(); + module_invoke_all('user_logout', NULL, $this->user); + // Load the anonymous user into the current user. + $this->user = drupal_anonymous_user(); + $this->_uid = 0; } - return $user->session; -} + public function uidDestroySession($uid) { + db_delete('sessions') + ->condition('uid', $uid) + ->execute(); + if ($uid == $this->_uid) { + $this->regenerate(); + } + } -/** - * Session handler assigned by session_set_save_handler(). - * - * This function will be called by PHP to store the current user's - * session, which Drupal saves to the database. - * - * This function should not be called directly. Session data should - * instead be accessed via the $_SESSION superglobal. - * - * @param $key - * Session ID. - * @param $value - * Serialized array of the session data. - * @return - * This function will always return TRUE. - */ -function _sess_write($key, $value) { - global $user; + public function sessionClose() { + $this->__destruct(); + } + + /** + * Provide information about the current state of the Session singleton. + * + * @param $which + * @return mixed + */ + public function sessionState($which = '') { + switch ($which) { + case 'write': + return $this->allowWrite; + case 'started': + return $this->_sessionStarted; + case 'destroyed': + return $this->_sessionDestroyed; + default: + return array ( + 'write' => $this->allowWrite, + 'started' => $this->_sessionStarted, + 'destroyed' => $this->_sessionDestroyed, + ); + } + } + + public function regenerate() { + session_regenerate_id(); + db_update('sessions') + ->fields(array( + 'sid' => session_id() + )) + ->condition('sid', $this->_initSid) + ->execute(); + // $this->user->sid = session_id(); + return TRUE; + } - // If saving of session data is disabled or if the client doesn't have a session, - // and one isn't being created ($value), do nothing. This keeps crawlers out of - // the session table. This reduces memory and server load, and gives more useful - // statistics. We can't eliminate anonymous session table rows without breaking - // the "Who's Online" block. - if (!drupal_save_session() || ($user->uid == 0 && empty($_COOKIE[session_name()]) && empty($value))) { + /** + * 'Open' session handler assigned by session_set_save_handler(). + * + * This method is used to handle any initialization, such as file paths or + * database connections, that is needed before accessing session data. Drupal + * does not need to initialize anything in this function. + * + * @return + * This method will always return TRUE. + */ + private function open() { return TRUE; } - db_merge('sessions') - ->key(array('sid' => $key)) - ->fields(array( - 'uid' => $user->uid, - 'cache' => isset($user->cache) ? $user->cache : 0, - 'hostname' => ip_address(), - 'session' => $value, - 'timestamp' => REQUEST_TIME, - )) - ->execute(); + /** + * 'Close' session handler assigned by session_set_save_handler(). + * + * This method is used to close the current session. Because Drupal stores + * session data in the database immediately on write, this function does + * not need to do anything. + * + * + * @return + * This method will always return TRUE. + */ + public function close() { + return TRUE; + } - // Last access time is updated no more frequently than once every 180 seconds. - // This reduces contention in the users table. - if ($user->uid && REQUEST_TIME - $user->access > variable_get('session_write_interval', 180)) { - db_update('users') + /** + * 'Read' session handler assigned by session_set_save_handler(). + * + * This method will be called internally by PHP to retrieve the current user's + * session data, which is stored in the database. It also loads the + * current user's appropriate roles into the user object. + * + * @param string $key + * Session ID; exactly the same string value as what session_id() returns. + * @return mixed + * If no session data was found or if the user is anonymous, an empty string + * is returned. Otherwise, a special serialized string is returned that the + * PHP engine interprets into our $_SESSION array. The form of the string is + * governed by the session.serialize_handler variable in php.ini. + * + */ + private function read($sid) { + // Initialize $this->_initSid to the incoming session_id request. + $this->_initSid = $sid; + // Handle clients who present no cookies. These could be first-time visitors, + // regular visitors whose session data has just been purged (e.g., by + // logging out), or clients that don't store cookies (e.g., web crawlers). + if (!isset($_COOKIE[session_name()])) { + $this->user = drupal_anonymous_user(); + return ''; + } + + // Otherwise, if the session is still active, we have a record of the + // client's session in the database. + $this->user = db_query("SELECT u.*, s.* FROM {users} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE s.sid = :sid", array(':sid' => $sid))->fetchObject(); + + // We found the client's session record and they are an authenticated user. + if ($this->user && $this->user->uid > 0) { + // This is done to unserialize the data member of $user. + $this->user = drupal_unpack($this->user); + + // Add roles element to $this->user. + $this->user->roles = array(); + $this->user->roles[DRUPAL_AUTHENTICATED_RID] = 'authenticated user'; + $this->user->roles += db_query("SELECT r.rid, r.name FROM {role} r INNER JOIN {users_roles} ur ON ur.rid = r.rid WHERE ur.uid = :uid", array(':uid' => $this->user->uid))->fetchAllKeyed(0, 1); + } + // We didn't find the client's record (session has expired), or they + // are an anonymous user. + else { + $session = isset($this->user->session) ? $this->user->session : ''; + $this->user = drupal_anonymous_user($session); + } + + // Store the current user's uid in a protected property for verification + // against later. + $this->_uid = $this->user->uid; + + return $this->user->session; + } + + /** + * 'Write' session handler assigned by session_set_save_handler(). + * + * This method will be called by PHP to store the current user's + * session, which Drupal saves to the database. + * + * @param $sid + * Session ID. + * @param $value + * Serialized array of the session data. + * @return + * This function will always return TRUE. + */ + private function write($sid, $value) { + // Ensure we are safe to proceed with writing session data. + if (!$this->writeCheck($value)) { + return FALSE; + } + + db_merge('sessions') + ->key(array('sid' => $sid)) ->fields(array( - 'access' => REQUEST_TIME + 'uid' => $this->user->uid, + 'cache' => isset($this->user->cache) ? $this->user->cache : 0, + 'hostname' => ip_address(), + 'session' => $value, + 'timestamp' => REQUEST_TIME, )) - ->condition('uid', $user->uid) ->execute(); + + // Last access time is updated no more frequently than once every 180 seconds. + // This reduces contention in the users table. + if ($this->user->uid && REQUEST_TIME - $this->user->access > variable_get('session_write_interval', 180)) { + db_update('users') + ->fields(array( + 'access' => REQUEST_TIME + )) + ->condition('uid', $this->user->uid) + ->execute(); + } + + return TRUE; } - return TRUE; -} + /** + * Perform validation and security checks to ensure it is safe and appropriate + * to write data to the session table. + * + * First, if there is a mismatch between the user uid that was originally + * loaded into session data and Session::user->uid, then something has gone + * wrong, so we bail out without updating session data. + * + * Then, if saving of session data is disabled or if the client doesn't have a + * session, and one isn't being created ($value), do nothing. This keeps + * crawlers out of the session table, which reduces memory and server load, + * and results in more useful statistics. We can't eliminate anonymous session + * table rows without breaking the "Who's Online" block. + * + * @param $value + * Serialized array containing session data. + * @return bool + * Returns a boolean indicating whether the session write should continue. + */ + private function writeCheck($value) { + if (!$this->allowWrite || + $this->_uid != $this->user->uid || + ($this->_uid == 0 && empty($_COOKIE[session_name()]) && empty($value))) { + return FALSE; + } + return TRUE; + } -/** - * Called when an anonymous user becomes authenticated or vice-versa. - */ -function drupal_session_regenerate() { - $old_session_id = session_id(); - session_regenerate_id(); - db_update('sessions') - ->fields(array( - 'sid' => session_id() - )) - ->condition('sid', $old_session_id) - ->execute(); + /** + * 'Destroy' session handler assigned by session_set_save_handler(). + * + * Cleanup a specific session. + * + * @param string $sid + * Session ID. + */ + private function destroy($sid) { + db_delete('sessions') + ->condition('sid', $sid) + ->execute(); + $this->_sessionDestroyed = TRUE; + } + + /** + * Session handler assigned by session_set_save_handler(). + * + * Cleanup stalled sessions. + * + * @param int $lifetime + * The value of session.gc_maxlifetime, passed by PHP. + * Sessions not updated for more than $lifetime seconds will be removed. + */ + private function gc($lifetime) { + // Be sure to adjust 'php_value session.gc_maxlifetime' to a large enough + // value. For example, if you want user sessions to stay in your database + // for three weeks before deleting them, you need to set gc_maxlifetime + // to '1814400'. At that value, only after a user doesn't log in after + // three weeks (1814400 seconds) will his/her session be removed. + db_delete('sessions') + ->condition('timestamp', REQUEST_TIME - $lifetime, '<') + ->execute(); + return TRUE; + } + + /** + * Destructor magic method, called internally during PHP's shutdown sequence. + * + * By calling session_write_close() here, we are able to circumvent PHP's + * native shutdown ordering, which destructs objects before calling session + * Write and Close handlers. + * + * @return void + */ + public function __destruct() { + session_write_close(); + } } /** @@ -197,20 +436,6 @@ function drupal_session_count($timestamp = 0, $anonymous = TRUE) { } /** - * Session handler assigned by session_set_save_handler(). - * - * Cleanup a specific session. - * - * @param string $sid - * Session ID. - */ -function _sess_destroy_sid($sid) { - db_delete('sessions') - ->condition('sid', $sid) - ->execute(); -} - -/** * End a specific user's session(s). * * @param string $uid @@ -221,46 +446,3 @@ function drupal_session_destroy_uid($uid) { ->condition('uid', $uid) ->execute(); } - -/** - * Session handler assigned by session_set_save_handler(). - * - * Cleanup stalled sessions. - * - * @param int $lifetime - * The value of session.gc_maxlifetime, passed by PHP. - * Sessions not updated for more than $lifetime seconds will be removed. - */ -function _sess_gc($lifetime) { - // Be sure to adjust 'php_value session.gc_maxlifetime' to a large enough - // value. For example, if you want user sessions to stay in your database - // for three weeks before deleting them, you need to set gc_maxlifetime - // to '1814400'. At that value, only after a user doesn't log in after - // three weeks (1814400 seconds) will his/her session be removed. - db_delete('sessions') - ->condition('timestamp', REQUEST_TIME - $lifetime, '<') - ->execute(); - return TRUE; -} - -/** - * Determine whether to save session data of the current request. - * - * This function allows the caller to temporarily disable writing of - * session data, should the request end while performing potentially - * dangerous operations, such as manipulating the global $user object. - * See http://drupal.org/node/218104 for usage. - * - * @param $status - * Disables writing of session data when FALSE, (re-)enables - * writing when TRUE. - * @return - * FALSE if writing session data has been disabled. Otherwise, TRUE. - */ -function drupal_save_session($status = NULL) { - static $save_session = TRUE; - if (isset($status)) { - $save_session = $status; - } - return $save_session; -} diff --git a/includes/theme.inc b/includes/theme.inc index 00b8b50..c0a87d3 100644 --- a/includes/theme.inc +++ b/includes/theme.inc @@ -1484,7 +1484,7 @@ function theme_box($title, $content, $region = 'main') { * A string containing the marker. */ function theme_mark($type = MARK_NEW) { - global $user; + $user = drupal_current_user(); if ($user->uid) { if ($type == MARK_NEW) { return ' ' . t('new') . ''; @@ -1763,7 +1763,7 @@ function _theme_table_cell($cell, $header = FALSE) { * theme functions). */ function template_preprocess(&$variables, $hook) { - global $user; + $user = drupal_current_user(); static $count = array(); // Track run count for each hook to provide zebra striping. diff --git a/install.php b/install.php index 9b91d56..2e9daa4 100644 --- a/install.php +++ b/install.php @@ -1147,7 +1147,7 @@ function install_configure_form_validate($form, &$form_state) { * Form API submit for the site configuration form. */ function install_configure_form_submit($form, &$form_state) { - global $user; + $user = drupal_current_user(); variable_set('site_name', $form_state['values']['site_name']); variable_set('site_mail', $form_state['values']['site_mail']); diff --git a/modules/block/block.module b/modules/block/block.module index 641f1cd..176f371 100644 --- a/modules/block/block.module +++ b/modules/block/block.module @@ -409,7 +409,8 @@ function block_list($region) { * Load blocks information from the database. */ function _block_load_blocks() { - global $user, $theme_key; + global $theme_key; + $user = drupal_current_user(); $blocks = array(); $rids = array_keys($user->roles); diff --git a/modules/blog/blog.module b/modules/blog/blog.module index 50a01b4..3abf10d 100644 --- a/modules/blog/blog.module +++ b/modules/blog/blog.module @@ -170,7 +170,7 @@ function _blog_post_exists($account) { * Displays the most recent 10 blog titles. */ function blog_block($op = 'list', $delta = '') { - global $user; + $user = drupal_current_user(); if ($op == 'list') { $block['recent']['info'] = t('Recent blog posts'); return $block; diff --git a/modules/blog/blog.pages.inc b/modules/blog/blog.pages.inc index d44bbf5..d491978 100644 --- a/modules/blog/blog.pages.inc +++ b/modules/blog/blog.pages.inc @@ -10,7 +10,7 @@ * Menu callback; displays a Drupal page containing recent blog entries of a given user. */ function blog_page_user($account) { - global $user; + $user = drupal_current_user(); drupal_set_title($title = t("@name's blog", array('@name' => $account->name)), PASS_THROUGH); @@ -53,7 +53,7 @@ function blog_page_user($account) { * Menu callback; displays a Drupal page containing recent blog entries of all users. */ function blog_page_last() { - global $user; + $user = drupal_current_user(); $output = ''; $items = array(); diff --git a/modules/blogapi/blogapi.module b/modules/blogapi/blogapi.module index db7f01d..0494553 100644 --- a/modules/blogapi/blogapi.module +++ b/modules/blogapi/blogapi.module @@ -683,7 +683,7 @@ function blogapi_error($message) { * Ensure that the given user has permission to edit a blog. */ function blogapi_validate_user($username, $password) { - global $user; + $user = drupal_current_user(); $user = user_authenticate(array('name' => $username, 'pass' => $password)); diff --git a/modules/comment/comment.module b/modules/comment/comment.module index 7394eaa..419e952 100644 --- a/modules/comment/comment.module +++ b/modules/comment/comment.module @@ -683,7 +683,7 @@ function comment_user_delete(&$edit, &$user, $category = NULL) { * TRUE if the current user has acces to the comment, FALSE otherwise. */ function comment_access($op, $comment) { - global $user; + $user = drupal_current_user(); if ($op == 'edit') { return ($user->uid && $user->uid == $comment->uid && comment_num_replies($comment->cid) == 0) || user_access('administer comments'); @@ -711,7 +711,7 @@ function comment_node_url() { * is not saved, FALSE is returned. */ function comment_save($edit) { - global $user; + $user = drupal_current_user(); if (user_access('post comments') && (user_access('administer comments') || node_comment_mode($edit['nid']) == COMMENT_NODE_READ_WRITE)) { if (!form_get_errors()) { $edit += array( @@ -852,7 +852,7 @@ function comment_save($edit) { * An associative array containing the links. */ function comment_links($comment, $return = 1) { - global $user; + $user = drupal_current_user(); $links = array(); // If viewing just this comment, link back to the node. @@ -969,7 +969,7 @@ function comment_links($comment, $return = 1) { * to consider the trailing "/" so we use a substring only. */ function comment_render($node, $cid = 0) { - global $user; + $user = drupal_current_user(); $output = ''; if (user_access('access comments')) { @@ -1169,7 +1169,7 @@ function comment_num_replies($pid) { * @return The result or FALSE on error. */ function comment_num_new($nid, $timestamp = 0) { - global $user; + $user = drupal_current_user(); if ($user->uid) { // Retrieve the timestamp at which the current user last viewed this node. @@ -1200,7 +1200,7 @@ function comment_num_new($nid, $timestamp = 0) { * The original $edit. */ function comment_validate($edit) { - global $user; + $user = drupal_current_user(); // Invoke other validation handlers. comment_invoke_comment($edit, 'validate'); @@ -1263,7 +1263,7 @@ function comment_validate($edit) { * @see comment_form_submit() */ function comment_form(&$form_state, $edit, $title = NULL) { - global $user; + $user = drupal_current_user(); $op = isset($_POST['op']) ? $_POST['op'] : ''; $node = node_load($edit['nid']); @@ -1516,7 +1516,7 @@ function comment_form_box($edit, $title = NULL) { * @ingroup forms */ function comment_form_add_preview($form, &$form_state) { - global $user; + $user = drupal_current_user(); $edit = $form_state['values']; drupal_set_title(t('Preview comment'), PASS_THROUGH); $output = ''; @@ -1588,7 +1588,7 @@ function comment_form_add_preview($form, &$form_state) { * Validate comment form submissions. */ function comment_form_validate($form, &$form_state) { - global $user; + $user = drupal_current_user(); if ($user->uid === 0) { foreach (array('name', 'homepage', 'mail') as $field) { // Set cookie for 365 days. @@ -1791,7 +1791,7 @@ function theme_comment_thread_expanded($comment, $node) { * @ingroup themeable */ function theme_comment_post_forbidden($node) { - global $user; + $user = drupal_current_user(); static $authenticated_post_comments; if (!$user->uid) { diff --git a/modules/comment/comment.pages.inc b/modules/comment/comment.pages.inc index cc29135..ff30b4c 100644 --- a/modules/comment/comment.pages.inc +++ b/modules/comment/comment.pages.inc @@ -14,7 +14,7 @@ * @ingroup forms */ function comment_edit($cid) { - global $user; + $user = drupal_current_user(); $comment = db_query('SELECT c.*, u.uid, u.name AS registered_name, u.data FROM {comments} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.cid = :cid', array(':cid'=>$cid) )->fetchObject(); $comment = drupal_unpack($comment); $comment->name = $comment->uid ? $comment->registered_name : $comment->name; diff --git a/modules/contact/contact.module b/modules/contact/contact.module index 9eee755..348d333 100644 --- a/modules/contact/contact.module +++ b/modules/contact/contact.module @@ -115,7 +115,7 @@ function contact_menu() { * Determine if a user can access to the contact tab. */ function _contact_user_tab_access($account) { - global $user; + $user = drupal_current_user(); if (!isset($account->contact)) { $account->contact = FALSE; } diff --git a/modules/contact/contact.pages.inc b/modules/contact/contact.pages.inc index 041c051..cf843ec 100644 --- a/modules/contact/contact.pages.inc +++ b/modules/contact/contact.pages.inc @@ -11,7 +11,7 @@ * Site-wide contact page. */ function contact_site_page() { - global $user; + $user = drupal_current_user(); if (!flood_is_allowed('contact', variable_get('contact_hourly_threshold', 3)) && !user_access('administer site-wide contact form')) { $output = t("You cannot send more than %number messages per hour. Please try again later.", array('%number' => variable_get('contact_hourly_threshold', 3))); @@ -24,7 +24,7 @@ function contact_site_page() { } function contact_mail_page() { - global $user; + $user = drupal_current_user(); $form = $categories = array(); @@ -155,7 +155,7 @@ function contact_mail_page_submit($form, &$form_state) { * Personal contact page. */ function contact_user_page($account) { - global $user; + $user = drupal_current_user(); if (!valid_email_address($user->mail)) { $output = t('You need to provide a valid e-mail address to contact other users. Please update your user information and try again.', array('@url' => url("user/$user->uid/edit", array('query' => 'destination=' . drupal_get_destination())))); @@ -172,7 +172,7 @@ function contact_user_page($account) { } function contact_mail_user(&$form_state, $recipient) { - global $user; + $user = drupal_current_user(); $form['#token'] = $user->name . $user->mail; $form['recipient'] = array('#type' => 'value', '#value' => $recipient); $form['from'] = array('#type' => 'item', @@ -206,7 +206,7 @@ function contact_mail_user(&$form_state, $recipient) { * Process the personal contact page form submission. */ function contact_mail_user_submit($form, &$form_state) { - global $user, $language; + $user = drupal_current_user(), $language; $account = $form_state['values']['recipient']; diff --git a/modules/filter/filter.module b/modules/filter/filter.module index f77f539..46bbde1 100644 --- a/modules/filter/filter.module +++ b/modules/filter/filter.module @@ -286,7 +286,7 @@ function filter_filter_tips($delta, $format, $long = FALSE) { * Retrieve a list of input formats. */ function filter_formats($index = NULL) { - global $user; + $user = drupal_current_user(); static $formats; // Administrators can always use all input formats. diff --git a/modules/forum/forum.module b/modules/forum/forum.module index 8473ddd..f3764ed 100644 --- a/modules/forum/forum.module +++ b/modules/forum/forum.module @@ -615,7 +615,7 @@ function _forum_topics_unread($term, $uid) { } function forum_get_topics($tid, $sortby, $forum_per_page) { - global $user, $forum_topic_list_header; + $user = drupal_current_user(), $forum_topic_list_header; $forum_topic_list_header = array( NULL, @@ -675,7 +675,7 @@ function forum_get_topics($tid, $sortby, $forum_per_page) { * Finds the first unread node for a given forum. */ function _forum_new($tid) { - global $user; + $user = drupal_current_user(); $sql = "SELECT n.nid FROM {node} n LEFT JOIN {history} h ON n.nid = h.nid AND h.uid = %d INNER JOIN {term_node} r ON n.nid = r.nid AND r.tid = %d WHERE n.status = 1 AND h.nid IS NULL AND n.created > %d ORDER BY created"; $sql = db_rewrite_sql($sql); @@ -698,7 +698,7 @@ function _forum_new($tid) { * @see forums.tpl.php */ function template_preprocess_forums(&$variables) { - global $user; + $user = drupal_current_user(); $vid = variable_get('forum_nav_vocabulary', ''); $vocabulary = taxonomy_vocabulary_load($vid); @@ -801,7 +801,7 @@ function template_preprocess_forums(&$variables) { * @see theme_forum_list() */ function template_preprocess_forum_list(&$variables) { - global $user; + $user = drupal_current_user(); $row = 0; // Sanitize each forum so that the template can safely print the data. foreach ($variables['forums'] as $id => $forum) { @@ -977,7 +977,7 @@ function template_preprocess_forum_submitted(&$variables) { } function _forum_user_last_visit($nid) { - global $user; + $user = drupal_current_user(); static $history = array(); if (empty($history)) { diff --git a/modules/node/node.module b/modules/node/node.module index bf528cd..cdaa84a 100644 --- a/modules/node/node.module +++ b/modules/node/node.module @@ -187,7 +187,7 @@ function theme_node_list($items, $title = NULL) { * Update the 'last viewed' timestamp of the specified node for current user. */ function node_tag_new($nid) { - global $user; + $user = drupal_current_user(); if ($user->uid) { if (node_last_viewed($nid)) { @@ -204,7 +204,7 @@ function node_tag_new($nid) { * specified node. */ function node_last_viewed($nid) { - global $user; + $user = drupal_current_user(); static $history; if (!isset($history[$nid])) { @@ -225,7 +225,7 @@ function node_last_viewed($nid) { * One of the MARK constants. */ function node_mark($nid, $timestamp) { - global $user; + $user = drupal_current_user(); static $cache; if (!$user->uid) { @@ -861,7 +861,7 @@ function node_validate($node, $form = array()) { * Prepare node for save and allow modules to make changes. */ function node_submit($node) { - global $user; + $user = drupal_current_user(); // Convert the node to an object, if necessary. $node = (object)$node; @@ -905,7 +905,7 @@ function node_submit($node) { function node_save(&$node) { // Let modules modify the node before it is saved to the database. node_invoke_nodeapi($node, 'presave'); - global $user; + $user = drupal_current_user(); $node->is_new = FALSE; @@ -2087,7 +2087,7 @@ function node_search_validate($form, &$form_state) { * TRUE if the operation may be performed. */ function node_access($op, $node, $account = NULL) { - global $user; + $user = drupal_current_user(); if (!$node) { return FALSE; diff --git a/modules/node/node.pages.inc b/modules/node/node.pages.inc index fd326ff..120311a 100644 --- a/modules/node/node.pages.inc +++ b/modules/node/node.pages.inc @@ -50,7 +50,7 @@ function theme_node_add_list($content) { * Present a node submission form or a set of links to such forms. */ function node_add($type) { - global $user; + $user = drupal_current_user(); $types = node_get_types(); $type = isset($type) ? str_replace('-', '_', $type) : NULL; @@ -78,7 +78,7 @@ function node_object_prepare(&$node) { foreach (array('status', 'promote', 'sticky') as $key) { $node->$key = in_array($key, $node_options); } - global $user; + $user = drupal_current_user(); $node->uid = $user->uid; $node->created = REQUEST_TIME; } @@ -96,7 +96,7 @@ function node_object_prepare(&$node) { * Generate the node add/edit form array. */ function node_form(&$form_state, $node) { - global $user; + $user = drupal_current_user(); if (isset($form_state['node'])) { $node = $form_state['node'] + (array)$node; @@ -428,7 +428,7 @@ function theme_node_preview($node) { } function node_form_submit($form, &$form_state) { - global $user; + $user = drupal_current_user(); $node = node_form_submit_build_node($form, $form_state); $insert = empty($node->nid); diff --git a/modules/php/php.module b/modules/php/php.module index cf7dea4..fdafad0 100644 --- a/modules/php/php.module +++ b/modules/php/php.module @@ -50,7 +50,7 @@ print t(\'Welcome visitor! Thank you for visiting.\'); ') . ''; $output .= '
To display the name of a registered user, use this instead:
-global $user; +$user = drupal_current_user(); if ($user->uid) { print t(\'Welcome @name! Thank you for visiting.\', array(\'@name\' => $user->name)); } diff --git a/modules/poll/poll.module b/modules/poll/poll.module index f1b7254..be6f446 100644 --- a/modules/poll/poll.module +++ b/modules/poll/poll.module @@ -195,7 +195,7 @@ function poll_node_info() { * Implementation of hook_form(). */ function poll_form(&$node, $form_state) { - global $user; + $user = drupal_current_user(); $admin = user_access('administer nodes') || user_access('edit any poll content') || (user_access('edit own poll content') && $user->uid == $node->uid); @@ -452,7 +452,7 @@ function poll_validate($node) { * Implementation of hook_load(). */ function poll_load($node) { - global $user; + $user = drupal_current_user(); $poll = db_fetch_object(db_query("SELECT runtime, active FROM {poll} WHERE nid = %d", $node->nid)); @@ -544,7 +544,7 @@ function poll_delete($node) { * rendering of the poll. */ function poll_view($node, $teaser = FALSE, $page = FALSE, $block = FALSE) { - global $user; + $user = drupal_current_user(); $output = ''; // Special display for side-block @@ -646,7 +646,7 @@ function poll_vote($form, &$form_state) { $node = $form['#node']; $choice = $form_state['values']['choice']; - global $user; + $user = drupal_current_user(); if ($user->uid) { db_query('INSERT INTO {poll_votes} (nid, chid, uid) VALUES (%d, %d, %d)', $node->nid, $choice, $user->uid); } @@ -820,7 +820,7 @@ function poll_cancel_form(&$form_state, $nid) { */ function poll_cancel($form, &$form_state) { $node = node_load($form['#nid']); - global $user; + $user = drupal_current_user(); if ($user->uid) { db_query('DELETE FROM {poll_votes} WHERE nid = %d and uid = %d', $node->nid, $user->uid); diff --git a/modules/simpletest/drupal_web_test_case.php b/modules/simpletest/drupal_web_test_case.php index a81a2d7..d2d7f21 100644 --- a/modules/simpletest/drupal_web_test_case.php +++ b/modules/simpletest/drupal_web_test_case.php @@ -388,7 +388,7 @@ class DrupalWebTestCase { $defaults['date'] = format_date($defaults['created'], 'custom', 'Y-m-d H:i:s O'); } if (empty($settings['uid'])) { - global $user; + $user = drupal_current_user(); $defaults['uid'] = $user->uid; } $node = ($settings + $defaults); diff --git a/modules/simpletest/tests/file.test b/modules/simpletest/tests/file.test index 5da57ee..34a3a1a 100644 --- a/modules/simpletest/tests/file.test +++ b/modules/simpletest/tests/file.test @@ -263,9 +263,9 @@ class FileValidatorTest extends DrupalWebTestCase { * Test file_validate_size(). */ function testFileValidateSize() { - global $user; + $user = drupal_current_user(); $original_user = $user; - drupal_save_session(FALSE); + drupal_session()->allowWrite = FALSE; // Run these test as uid = 1. $user = user_load(array('uid' => 1)); @@ -291,7 +291,7 @@ class FileValidatorTest extends DrupalWebTestCase { $this->assertEqual(count($errors), 2, t('Errors for both the file and their limit.'), 'File'); $user = $original_user; - drupal_save_session(TRUE); + drupal_session()->allowWrite = TRUE; } } diff --git a/modules/simpletest/tests/session.test b/modules/simpletest/tests/session.test index 5e25339..da720aa 100644 --- a/modules/simpletest/tests/session.test +++ b/modules/simpletest/tests/session.test @@ -29,11 +29,9 @@ class SessionTestCase extends DrupalWebTestCase { * Tests for drupal_save_session(). */ function testSessionSaveSession() { - $this->assertTrue(drupal_save_session(), t('drupal_save_session() correctly returns TRUE when initially called with no arguments.'), t('Session')); - $this->assertFalse(drupal_save_session(FALSE), t('drupal_save_session() correctly returns FALSE when called with FALSE.'), t('Session')); - $this->assertFalse(drupal_save_session(), t('drupal_save_session() correctly returns FALSE when saving has been disabled.'), t('Session')); - $this->assertTrue(drupal_save_session(TRUE), t('drupal_save_session() correctly returns TRUE when called with TRUE.'), t('Session')); - $this->assertTrue(drupal_save_session(), t('drupal_save_session() correctly returns TRUE when saving has been enabled.'), t('Session')); + $this->assertTrue(drupal_session()->allowWrite, t('drupal_session()->allowWrite correctly initializes to TRUE.'), t('Session')); + $this->assertFalse(drupal_session()->allowWrite = FALSE, t('drupal_session()->allowWrite allows itself to be set to FALSE, disabling session writing.'), t('Session')); + $this->assertTrue(drupal_session()->allowWrite = TRUE, t('drupal_session()->allowWrite correctly allows itself to be reset to TRUE, re-enabling session writing.'), t('Session')); } /** diff --git a/modules/simpletest/tests/session_test.module b/modules/simpletest/tests/session_test.module index b183ec3..1d9b3e3 100644 --- a/modules/simpletest/tests/session_test.module +++ b/modules/simpletest/tests/session_test.module @@ -54,7 +54,7 @@ function _session_test_set($value) { * anyway. */ function _session_test_no_set($value) { - drupal_save_session(FALSE); + drupal_session()->allowWrite = FALSE; _session_test_set($value); return t('session saving was disabled, and then %val was set', array('%val' => $value)); } diff --git a/modules/statistics/statistics.module b/modules/statistics/statistics.module index 2bafc54..b2c6abb 100644 --- a/modules/statistics/statistics.module +++ b/modules/statistics/statistics.module @@ -43,7 +43,7 @@ function statistics_help($path, $arg) { * This is where statistics are gathered on page accesses. */ function statistics_exit() { - global $user; + $user = drupal_current_user(); drupal_bootstrap(DRUPAL_BOOTSTRAP_PATH); diff --git a/modules/system/system.module b/modules/system/system.module index a85e3fa..d552580 100644 --- a/modules/system/system.module +++ b/modules/system/system.module @@ -815,7 +815,7 @@ function system_user_login(&$edit, &$user, $category = NULL) { * Add the time zone field to the user edit and register forms. */ function system_user_timezone(&$edit, &$form) { - global $user; + $user = drupal_current_user(); $form['timezone'] = array( '#type' => 'fieldset', '#title' => t('Locale settings'), @@ -1437,7 +1437,7 @@ function confirm_form($form, $question, $path, $description = NULL, $yes = NULL, * Determine if a user is in compact mode. */ function system_admin_compact_mode() { - global $user; + $user = drupal_current_user(); return (isset($user->admin_compact_mode)) ? $user->admin_compact_mode : variable_get('admin_compact_mode', FALSE); } @@ -1448,7 +1448,7 @@ function system_admin_compact_mode() { * Valid values are 'on' and 'off'. */ function system_admin_compact_page($mode = 'off') { - global $user; + $user = drupal_current_user(); user_save($user, array('admin_compact_mode' => ($mode == 'on'))); drupal_goto(drupal_get_destination()); } @@ -1931,7 +1931,7 @@ function system_send_email_action_submit($form, $form_state) { * Implementation of a configurable Drupal action. Sends an email. */ function system_send_email_action($object, $context) { - global $user; + $user = drupal_current_user(); switch ($context['hook']) { case 'nodeapi': @@ -2054,7 +2054,7 @@ function system_message_action_submit($form, $form_state) { * A configurable Drupal action. Sends a message to the current user's screen. */ function system_message_action(&$object, $context = array()) { - global $user; + $user = drupal_current_user(); $variables = array( '%site_name' => variable_get('site_name', 'Drupal'), '%username' => $user->name ? $user->name : variable_get('anonymous', t('Anonymous')), diff --git a/modules/trigger/trigger.test b/modules/trigger/trigger.test index 566d252..67caacc 100644 --- a/modules/trigger/trigger.test +++ b/modules/trigger/trigger.test @@ -24,7 +24,7 @@ class TriggerContentTestCase extends DrupalWebTestCase { * Various tests, all in one function to assure they happen in the right order. */ function testActionsContent() { - global $user; + $user = drupal_current_user(); $content_actions = array('node_publish_action', 'node_unpublish_action', 'node_make_sticky_action', 'node_make_unsticky_action', 'node_promote_action', 'node_unpromote_action'); foreach ($content_actions as $action) { diff --git a/modules/upload/upload.module b/modules/upload/upload.module index 8f223ad..00161e6 100644 --- a/modules/upload/upload.module +++ b/modules/upload/upload.module @@ -172,7 +172,7 @@ function upload_file_download($filepath) { * A node object to associate with uploaded files. */ function upload_node_form_submit(&$form, &$form_state) { - global $user; + $user = drupal_current_user(); $limits = _upload_file_limits($user); $validators = array( @@ -485,7 +485,7 @@ function upload_save(&$node) { } function _upload_form($node) { - global $user; + $user = drupal_current_user(); $form = array( '#theme' => 'upload_form_new', diff --git a/modules/user/user.module b/modules/user/user.module index 6e8b83a..8d08e2a 100644 --- a/modules/user/user.module +++ b/modules/user/user.module @@ -126,9 +126,7 @@ function user_external_login($account, $edit = array()) { } // Valid login. - global $user; - $user = $account; - user_authenticate_finalize($state['values']); + drupal_session()->userLogin($account, $state['values']); return TRUE; } @@ -281,8 +279,7 @@ function user_save($account, $edit = array(), $category = 'account') { // If the password changed, delete all open sessions and recreate // the current one. if (!empty($edit['pass'])) { - drupal_session_destroy_uid($account->uid); - drupal_session_regenerate(); + drupal_session()->uidDestroySession($account->uid); } // Refresh user object. @@ -522,7 +519,7 @@ function user_role_permissions($roles = array(), $reset = FALSE) { * can perform all actions. */ function user_access($string, $account = NULL, $reset = FALSE) { - global $user; + $user = drupal_current_user(); static $perm = array(); if ($reset) { @@ -736,7 +733,7 @@ function user_login_block() { * Implementation of hook_block(). */ function user_block($op = 'list', $delta = '', $edit = array()) { - global $user; + $user = drupal_current_user(); if ($op == 'list') { $blocks['login']['info'] = t('User login'); @@ -1229,7 +1226,7 @@ function user_set_authmaps($account, $authmaps) { * @ingroup forms */ function user_login(&$form_state) { - global $user; + $user = drupal_current_user(); // If we are already logged on, go to the user page instead. if ($user->uid) { @@ -1291,7 +1288,7 @@ function user_login_name_validate($form, &$form_state) { /** * A validate handler on the login form. Check supplied username/password - * against local users table. If successful, sets the global $user object. + * against local users table. If successful, sets the $user = drupal_current_user() object. */ function user_login_authenticate_validate($form, &$form_state) { user_authenticate($form_state['values']); @@ -1302,7 +1299,7 @@ function user_login_authenticate_validate($form, &$form_state) { * error if user has not been authenticated yet. */ function user_login_final_validate($form, &$form_state) { - global $user; + $user = drupal_current_user(); if (!$user->uid) { form_set_error('name', t('Sorry, unrecognized username or password. Have you forgotten your password?', array('@password' => url('user/password')))); watchdog('user', 'Login attempt failed for %user.', array('%user' => $form_state['values']['name'])); @@ -1320,8 +1317,6 @@ function user_login_final_validate($form, &$form_state) { * A $user object, if successful. */ function user_authenticate($form_values = array()) { - global $user; - $password = trim($form_values['pass']); // Name and pass keys are required. if (!empty($form_values['name']) && !empty($password)) { @@ -1337,42 +1332,20 @@ function user_authenticate($form_values = array()) { } } $account = user_load(array('uid' => $account->uid, 'status' => 1)); - $user = $account; - user_authenticate_finalize($form_values); - return $user; + return drupal_session()->userLogin($account, $form_values); } } } } /** - * Finalize the login process. Must be called when logging in a user. - * - * The function records a watchdog message about the new session, saves the - * login timestamp, calls hook_user op 'login' and generates a new session. - * - * $param $edit - * This array is passed to hook_user op login. - */ -function user_authenticate_finalize(&$edit) { - global $user; - watchdog('user', 'Session opened for %name.', array('%name' => $user->name)); - // Update the user table timestamp noting user has logged in. - // This is also used to invalidate one-time login links. - $user->login = REQUEST_TIME; - db_query("UPDATE {users} SET login = %d WHERE uid = %d", $user->login, $user->uid); - user_module_invoke('login', $edit, $user); - drupal_session_regenerate(); -} - -/** * Submit handler for the login form. Redirects the user to a page. * * The user is redirected to the My Account page. Setting the destination in * the query string (as done by the user login block) overrides the redirect. */ function user_login_submit($form, &$form_state) { - global $user; + $user = drupal_current_user(); if ($user->uid) { $form_state['redirect'] = 'user/' . $user->uid; return; @@ -1381,15 +1354,13 @@ function user_login_submit($form, &$form_state) { /** * Helper function for authentication modules. Either login in or registers - * the current user, based on username. Either way, the global $user object is + * the current user, based on username. Either way, the $user = drupal_current_user() object is * populated based on $name. */ function user_external_login_register($name, $module) { - global $user; - $existing_user = user_load(array('name' => $name)); if (isset($existing_user->uid)) { - $user = $existing_user; + drupal_session()->user = $existing_user; } else { // Register this new user. @@ -1407,8 +1378,8 @@ function user_external_login_register($name, $module) { return; } user_set_authmaps($account, array("authname_$module" => $name)); - $user = $account; - watchdog('user', 'New external user: %name using module %module.', array('%name' => $name, '%module' => $module), WATCHDOG_NOTICE, l(t('edit'), 'user/' . $user->uid . '/edit')); + drupal_session()->user = $account; + watchdog('user', 'New external user: %name using module %module.', array('%name' => $name, '%module' => $module), WATCHDOG_NOTICE, l(t('edit'), 'user/' . drupal_current_user()->uid . '/edit')); } } @@ -1870,7 +1841,7 @@ function user_multiple_delete_confirm_submit($form, &$form_state) { * Implementation of hook_help(). */ function user_help($path, $arg) { - global $user; + $user = drupal_current_user(); switch ($path) { case 'admin/help#user': @@ -2144,7 +2115,7 @@ function _user_mail_notify($op, $account, $language = NULL) { */ function _user_password_dynamic_validation() { static $complete = FALSE; - global $user; + $user = drupal_current_user(); // Only need to do once per page. if (!$complete) { drupal_add_js(drupal_get_path('module', 'user') . '/user.js'); @@ -2224,7 +2195,7 @@ function user_block_user_action(&$object, $context = array()) { $uid = $context['uid']; } else { - global $user; + $user = drupal_current_user(); $uid = $user->uid; } db_query("UPDATE {users} SET status = 0 WHERE uid = %d", $uid); @@ -2345,7 +2316,7 @@ function user_register_submit($form, &$form_state) { * @see user_register_submit() */ function user_register() { - global $user; + $user = drupal_current_user(); $admin = user_access('administer users'); diff --git a/modules/user/user.pages.inc b/modules/user/user.pages.inc index ada98b6..11af31f 100644 --- a/modules/user/user.pages.inc +++ b/modules/user/user.pages.inc @@ -74,10 +74,10 @@ function user_pass_submit($form, &$form_state) { * Menu callback; process one time login link and redirects to the user page on success. */ function user_pass_reset(&$form_state, $uid, $timestamp, $hashed_pass, $action = NULL) { - global $user; + $user = drupal_current_user(); // Check if the user is already logged in. The back button is often the culprit here. - if ($user->uid) { + if (drupal_current_user()->uid) { drupal_set_message(t('You have already used this one-time login link. It is not necessary to use this link to login anymore. You are already logged in.')); drupal_goto(); } @@ -96,11 +96,10 @@ function user_pass_reset(&$form_state, $uid, $timestamp, $hashed_pass, $action = // First stage is a confirmation form, then login if ($action == 'login') { watchdog('user', 'User %name used one-time login link at time %timestamp.', array('%name' => $account->name, '%timestamp' => $timestamp)); - // Set the new user. - $user = $account; - // user_authenticate_finalize() also updates the login timestamp of the - // user, which invalidates further use of the one-time login link. - user_authenticate_finalize($form_state['values']); + // Session singleton takes care of updating relevant timestamp and + // session data, and registers the provided account as the new user. + // One one-time login link will also be invalidated. + drupal_session()->userLogin($account, $form_state['values']); drupal_set_message(t('You have just used your one-time login link. It is no longer necessary to use this link to login. Please change your password.')); drupal_goto('user/' . $user->uid . '/edit'); } @@ -129,17 +128,7 @@ function user_pass_reset(&$form_state, $uid, $timestamp, $hashed_pass, $action = * Menu callback; logs the current user out, and redirects to the home page. */ function user_logout() { - global $user; - - watchdog('user', 'Session closed for %name.', array('%name' => $user->name)); - - // Destroy the current session: - session_destroy(); - module_invoke_all('user_logout', NULL, $user); - - // Load the anonymous user - $user = drupal_anonymous_user(); - + drupal_session()->userLogout(); drupal_goto(); } @@ -354,7 +343,7 @@ function user_edit_submit($form, &$form_state) { * users. */ function user_page() { - global $user; + $user = drupal_current_user(); if ($user->uid) { menu_set_active_item('user/' . $user->uid); return menu_execute_active_handler();