4

I want to add some data to global variable $user when user login, so when does system generate $user, and which hook I should implement?

2

The way is to make use of hook_user_load

Act on user objects when loaded from the database.

Parameters

$users: An array of user objects, indexed by uid.

Also see UserController

Controller class for users.

This extends the DrupalDefaultEntityController class, adding required special handling for user objects.

  • 1
    hook_user_load() is not invoked for the global $user, as user_load() is not used for it. – kiamlaluno Dec 14 '12 at 7:43
  • @kiamlaluno the doc says Act on user objects when loaded from the database. – niksmac Dec 14 '12 at 9:15
  • 1
    That is true when user_load() is used to load the user object, but the global $user is not loaded with that function. When the user object is loaded using db_query(), or db_select(), hook_user_load() is not invoked. – kiamlaluno Dec 14 '12 at 9:31
7

Drupal initializes the global $user during bootstrap. Unfortunately, it doesn't invoke any hook, as modules are not yet loaded. (Loading the enabled modules is the last step of Drupal bootstrap.)

The following code is used in the Drupal session handler _drupal_session_read().

  // Handle the case of first time visitors and clients that don't store
  // cookies (eg. web crawlers).
  $insecure_session_name = substr(session_name(), 1);
  if (!isset($_COOKIE[session_name()]) && !isset($_COOKIE[$insecure_session_name])) {
    $user = drupal_anonymous_user();
    return '';
  }

  // Otherwise, if the session is still active, we have a record of the
  // client's session in the database. If it's HTTPS then we are either have
  // a HTTPS session or we are about to log in so we check the sessions table
  // for an anonymous session with the non-HTTPS-only cookie.
  if ($is_https) {
    $user = db_query("SELECT u.*, s.* FROM {users} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE s.ssid = :ssid", array(':ssid' => $sid))->fetchObject();
    if (!$user) {
      if (isset($_COOKIE[$insecure_session_name])) {
        $user = db_query("SELECT u.*, s.* FROM {users} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE s.sid = :sid AND s.uid = 0", array(
          ':sid' => $_COOKIE[$insecure_session_name],
        ))
        ->fetchObject();
      }
    }
  }
  else {
    $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();
  }

To extend the global $user, you can implement hook_boot(), which is invoked when Drupal is still bootstrapping, or hook_init(), which is not invoked for cached pages. hook_user_load() is invoked when user_load() is called, but user_load() is not used for the global $user.

As side note, the global $user is not a complete user object. It contains the data saved in the "users" table, and not (for example) the value of any field (fields implemented from the field API) associated to the user entity.
$user->data can be used to store extra data for the user object. Its content can be altered through hook_user_presave() in the same way done by overlay_user_presave().

function overlay_user_presave(&$edit, $account, $category) {
  if (isset($edit['overlay'])) {
    $edit['data']['overlay'] = $edit['overlay'];
  }
}
  • $user->data is a neat approach to store additional info, but hook_user_load can also be used to modify $user variable right ? – GoodSp33d Dec 14 '12 at 9:29
  • It can be used to alter $user, as long as it doesn't alter any property loaded from the {users} table: "Due to the static cache in user_load_multiple() you should not use this hook to modify the user properties returned by the {users} table itself since this may result in unreliable results when loading from cache." – kiamlaluno Dec 14 '12 at 9:36
  • By modify I meant adding additional info, sorry I wasnt clear before. Suppose I want to add nickname which is stored in another table I can still use hook_user_load() to add it right ? – GoodSp33d Dec 14 '12 at 9:50
  • Yes, you can. For $GLOBALS['user'], that value would not be loaded, except when the user logs in with the login form/lock. Once the session is active, that value will not be added to the user object. – kiamlaluno Dec 14 '12 at 10:03
1

If you want to add some data to $user just after login, you need to implement hook_user_login in your module as

function ModuleName_user_login(&$edit, $account) {
  //add your code here
}
  • 3
    Once users are logged in, they are kept logged in until the session is not expired; this means hook_user_login() is not invoked until the session doesn't expire. If a user visits a Drupal site every day, the session could not expire at all. – kiamlaluno Dec 14 '12 at 7:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.