views:

33

answers:

2

I have a module called "packages". I want to store information on what package the user is using upon log in. I.e. Where, using which hook, or at what point, can I run this code:

$user[packages] = packages_get_user_packages($user->uid);
+1  A: 

Edit

kiamlaluno's solution is far better, and you should use that, not what follows.


Rather than storing it when they log in, you should store it in the $user object as soon as you know what packages belong to the user. This will stay with the user, so you only have to do it once instead of every time they log in:

global $user;
user_save($user, array('packages' => packages_get_user_packages($user->uid));

Then, forever after, you merely have to call $user->packages to get the information.

If you really can only save the information when they log in, you can do it in hook_boot(), which runs on every page:

function packages_boot() {
  global $user;

  if ($user->uid > 0) { // If user isn't anonymous
    // Ensure required modules have been loaded since
    // it's not a guarantee when hook_boot gets invoked
    drupal_load('module', 'user');
    drupal_load('module', 'package');

    // $user object isn't fully loaded yet, so we need to load a copy
    $account = user_load(array('uid' => $user->uid));

    if (!isset($account->packages)) {
      $user->packages = packages_get_user_packages($user->uid);
      user_save($account, array('packages' => $user->packages);
    }
  }
}

Using hook_boot() should really be used as a last resort: there's a lot of stuff still not loaded when hook_boot() is invoked, and your module might not have what it needs.

Note that $user is an object, not an array: $user['packages'] will not work.

Mark Trapp
`hook_init()` is not invoked for cached pages.
kiamlaluno
You're right: changed it to `hook_boot()`.
Mark Trapp
If the information is not stored/used anywhere else, storage in $user is ok. But you have to known it will ends in the data column of the user table, making the information not efficiently queryable. Also if the information is complex or derivated from relations between existing object, simple storage in the $user is probably not a good option. And finally, the documentation for the data column in user_schema clearly states that "Use of this field is discouraged and it will likely disappear in a future version of Drupal".
mongolito404
+4  A: 

I would implement hook_user(), which is invoked when the user logs in, logs out, when the user account is loaded, or saved.

function packages_user($op, &$edit, &$account, $category = NULL) {
  if ($op == 'load') {
    // It could also be "$op == 'login'".
    // The difference is that if it's "$op == 'load'", the operation is invoked
    // also when user_load() is called by a third-party module.
    $account->packages = packages_get_user_packages($user->uid);
  }
  elseif ($op == 'save') {
    // Save the data in a database table, if necessary.
  }
}
kiamlaluno
+1, This is a much better solution.
Mark Trapp

related questions