Community Documentation

hook_user

5 core.php hook_user($op, &$edit, &$account, $category = NULL)
6 core.php hook_user($op, &$edit, &$account, $category = NULL)

Act on user account actions.

This hook allows modules to react when operations are performed on user accounts.

Parameters

$op: What kind of action is being performed. Possible values (in alphabetical order):

  • after_update: The user object has been updated and changed. Use this (probably along with 'insert') if you want to reuse some information from the user object.
  • categories: A set of user information categories is requested.
  • delete: The user account is being deleted. The module should remove its custom additions to the user object from the database.
  • form: The user account edit form is about to be displayed. The module should present the form elements it wishes to inject into the form.
  • insert: The user account is being added. The module should save its custom additions to the user object into the database and set the saved fields to NULL in $edit.
  • load: The user account is being loaded. The module may respond to this and insert additional information into the user object.
  • login: The user just logged in.
  • logout: The user just logged out.
  • register: The user account registration form is about to be displayed. The module should present the form elements it wishes to inject into the form.
  • submit: Modify the account before it gets saved.
  • update: The user account is being changed. The module should save its custom additions to the user object into the database and set the saved fields to NULL in $edit.
  • validate: The user account is about to be modified. The module should validate its custom additions to the user object, registering errors as necessary.
  • view: The user's account information is being displayed. The module should format its custom additions for display, and add them to the $account->content array.

$edit: The array of form values submitted by the user.

$account: The user object on which the operation is being performed.

$category: The active category of user information being edited.

Return value

This varies depending on the operation.

  • categories: An array of associative arrays representing the categories added by the implementing module. Each array can have the following keys:

    • name: The internal name of the category.
    • title: The human-readable, localized name of the category.
    • weight: An integer specifying the category's sort ordering.
    • access callback: Name of a menu access callback function to use when editing this category. Defaults to using user_edit_access() if not specified. See hook_menu() for more information on menu access callbacks.
    • access arguments: Arguments for the access callback function. Defaults to array(1) if not specified.
  • delete: None.
  • form, register: An array containing the form elements to add to the form.
  • insert: None.
  • load: None.
  • login: None.
  • logout: None.
  • submit: None.
  • update: None.
  • validate: None.
  • view: None.

Related topics

▾ 21 functions implement hook_user()

BLOCK_CACHE_PER_USER in modules/block/block.module
The block can change depending on the user viewing the page. This setting can be resource-consuming for sites with large number of users, and thus should only be used when BLOCK_CACHE_PER_ROLE is not sufficient.
block_user in modules/block/block.module
Implementation of hook_user().
blogapi_validate_user in modules/blogapi/blogapi.module
Ensure that the given user has permission to edit a blog.
blog_feed_user in modules/blog/blog.pages.inc
Menu callback; displays an RSS feed containing recent blog entries of a given user.
blog_page_user in modules/blog/blog.pages.inc
Menu callback; displays a Drupal page containing recent blog entries of a given user.
blog_user in modules/blog/blog.module
Implementation of hook_user().
comment_user in modules/comment/comment.module
Implementation of hook_user().
contact_mail_user in modules/contact/contact.pages.inc
contact_user in modules/contact/contact.module
Implementation of hook_user().
dblog_user in modules/dblog/dblog.module
Implementation of hook_user().
drupal_anonymous_user in includes/bootstrap.inc
Generates a default anonymous $user object.
locale_user in modules/locale/locale.module
Implementation of hook_user().
node_user in modules/node/node.module
Implementation of hook_user().
openid_user in modules/openid/openid.module
Implementation of hook_user().
poll_user in modules/poll/poll.module
Implementation of hook_user().
profile_user in modules/profile/profile.module
Implementation of hook_user().
statistics_user in modules/statistics/statistics.module
Implementation of hook_user().
system_user in modules/system/system.module
Implementation of hook_user().
trigger_user in modules/trigger/trigger.module
Implementation of hook_user().
user_admin_check_user in modules/user/user.admin.inc
user_user in modules/user/user.module
Implementation of hook_user().

File

developer/hooks/core.php, line 2389
These are the hooks that are invoked by the Drupal core.

Code

<?php
function hook_user($op, &$edit, &$account, $category = NULL) {
  if ($op == 'form' && $category == 'account') {
    $form['comment_settings'] = array(
      '#type' => 'fieldset', 
      '#title' => t('Comment settings'), 
      '#collapsible' => TRUE, 
      '#weight' => 4,
    );
    $form['comment_settings']['signature'] = array(
      '#type' => 'textarea', 
      '#title' => t('Signature'), 
      '#default_value' => $edit['signature'], 
      '#description' => t('Your signature will be publicly displayed at the end of your comments.'),
    );
    return $form;
  }
}
?>

Comments

The hook has been replaced from a set of hooks, in Drupal 7

Drupal 7 doesn't use anymore hook_user(), but it uses a set of new hooks; see Converting 6.x modules to 7.x for more details.

List of D7 user hooks

For the API documentation of all new user hooks in Drupal 7, see http://api.drupal.org/api/search/7/hook_user_.

port $op == 'form'

hook_user_* group is missing $op == 'form'.
To port it, I suppose one should use hook_form_alter() or hook_form_user_profile_form_alter()

Not for Users

hook_form_alter() or hook_form_user_profile_form_alter() seem to have no effect on user/%/edit - http://drupal.org/node/1063690

function registermodule_form_user_profile_form_alter($form, &$form_state){
global $user;
if(in_array("foo_role", $user->roles)){
unset($form['field_non_foo']);
unset($form_state['field']['field_non_foo']);
}
return $form;
}

has no impact on the edit form. no one has pointed out a problem with the function, please comment.

cache clear helps :-)

cache clear helps
:-)

hook_login gets easily disabled

If at least one module redirect Drupal while $op == "login" in hook_user(), then the other implementation of the hook will never be called.

For instance, if you use drupal_goto(), than no other hook_user will be called.

Cheers

Asiby

drupal_goto() calls exit()

Any use of drupal_goto() in a hook implementation will prevent later implementations of the same hook being called, because the final line of drupal_goto() is exit() ...

&$account

foo_user($op, &$edit, &$account, $category = NULL) {}

make sure you are using the "&" for &$account otherwise anything you change in $account will not be loaded with the user object.

How can I save the old session_id when use login?

Then people login,the session_id changes by function " session_regenerate_id();"
I want to save both the session_id before and after changes,can I achieve this by hook_use $op == 'login'?
And how?

The real problems is I want get the user's source Url which is related to the session Id of people first enter the websit and usually anonymous user,but we only need to store the user login.

To save new information for

To save new information for the user in the user table's "data" field, upon insert, you need to:

switch ($op) {
  case 'insert': {
     $account->field_whatever = your_value;
     $edit['field_whatever'] = NULL;
...

This is documented above, but not completely explicitly. The $edit['field_whatever'] will cause field_whatever to be picked out of the $account object, serialized and stored in the user table.

Hope this helps the next person poking around in this area.

I did the opposite, to make

I did the opposite, to make it work:

switch ($op) {
  case 'insert': {
     $account->field_whatever = NULL;
     $edit['field_whatever'] = your_value;
...

NULL in the $account field_whatever property, and the value in the $edit array. Am I wrong? Because I understood the concept the other way, when I read the docs and your comment.

UPDATE: Better than that, I only had to set the value in the $edit array:

switch ($op) {
  case 'insert': {
     $edit['field_whatever'] = your_value;
...

switch ($op) {  case

switch ($op) {
  case 'insert': {
     $edit['field_whatever'] = your_value;

yes, it works! thank you~

The "NULL" advice is wrong in 6.19 (at least)

As stated above correctly, for insert, the value in $account is ignored and the value in $edit is written to {users}, unless the value is NULL (in which case it is not included). See user.module / user_save():

<?php
   
// Build and save the serialized data field now.
   
$data = array();
    foreach (
$array as $key => $value) {
      if ((
substr($key, 0, 4) !== 'auth') && ($key != 'roles') && (!in_array($key, $user_fields)) && ($value !== NULL)) {
       
$data[$key] = $value;
      }
    }
   
db_query("UPDATE {users} SET data = '%s' WHERE uid = %d", serialize($data), $user->uid);
?>

does not work for user profile module

For 'insert' and 'update', changing either $account or $edit in any way described here only affects what is serialized into the user table's data field, not the user profile module's profile_values table.

This means that trying to alter the user this way will break any views or anything else you're doing that might involve profile_load_profile(), which utilizes the profile_values table.

So basically altering the user (at least as 'update') completely breaks the connection between the user edit form and what's actually going on in the profile_values table, because the profile_values table does not get updated along with the users table data cell.

@DanChadwick thanks

@DanChadwick thanks

unsetting validation errors

is it possible to unset validation errors in hook_user 'validate' since there is no $form_state? If a custom user form field is filled out a certain way I want to allow a required field to be empty. I can see the error set in my validation function doing print_r(form_get_errors());
Array ( [mymod_maybe_required] => This field is usually required, but not always field is required.) If I reset the error with form_set_error('mymod_maybe_required','',TRUE);
then print_r(form_get_errors()); shows an empty array, but the error message still displays
Thank You

I think I found the solution

I think I found the solution here should anyone else have the need
https://drupal.org/node/563938

register op

you can't return a FAPI array like $form['account']['my_field'] because rather than being appended to $form['account'], it will replace $form['account'];

you need to return $form['my_field'] which will then, possibly annoyingly, result in a fieldset being placed around the account fields.

hook_form_alter is also an option here.

When using this function with

When using this function with the 'view' $op parameter, what needs to be added to $account->content should be in a format similar to that used by Form API, like this:

<?php
$account
->content['my_user_info_section'] = array(
 
// This outer user_profile_category item defines a "section" for your content
  // to appear in.
 
'#type' => 'user_profile_category',
 
'#title' => t('Title of my section'),
 
'#weight' => 10,
 
'child_element' => array(
   
// For child elements, use the user_profile_item type.
   
'#type' => 'user_profile_item',
   
// Finally, you can add whatever mark-up you need in this element's #value.
   
'#value' => '<p>' .
     
t('This user has a UID of @uid.', array('@uid' => $account->uid)) .
     
'</p>',
    ),
  ),
);
?>

set role and user.data when op='insert'

I am new to Drupal. So please correct me if I am wrong.

Roles can be set at this stage by
$edit['roles'][rid]=something;
It seems that it is the key:rid that counts.
see also: http://drupal.org/node/137989

If you use profile to create extra fields, you would like to save it to db table profile_values via your own code. Otherwise, those values will be saved to user.data instead. If you browse the user info, everything seems to be OK until you write code to retrieve profile value from the database.

Login or register to post comments