hook_user is declared as follows:

function hook_user($op, &$edit, &$account, $category = NULL)

According to the documentation of hook_user, when $op is set to 'submit' and/or 'update' a user account is about to be modified. This implies that $account, the user object, can be changed within hook_user and these changes will be saved to the database (note that $account is passed as reference). However, this is not the case: Changes made to $account will not be saved to the database.

I have tried this with $op == 'submit', $op == 'update' and $op == 'insert'. In every case Drupal failed to save the changes made to $account (I attempted to change $account->roles).

This behaviour makes it impossible for modules to modify user information when a user is updated or created.

Files: 
CommentFileSizeAuthor
#12 user-hook_user_presave_doc-124689-11.patch750 bytescck
PASSED: [[SimpleTest]]: [MySQL] 39,919 pass(es).
[ View ]
#9 user-hook_user_presave_doc-124689-8.patch752 bytescck
PASSED: [[SimpleTest]]: [MySQL] 39,919 pass(es).
[ View ]

Comments

When you want your modifications to 'take' (be saved), you have to set the fields to NULL in $edit, as per the documentation. Have you tried doing that ?

For example, something like that :

$account->roles[] = 'contributer';
$edit->roles = NULL;

Version:5.1» 6.13

I had a lot of trouble getting this work. Instead, I used the method below.

In this example, I'm modifying a profile field called 'public'.

<?php
function module_user($op, &$edit, &$account)
{
        switch(
$op)
        {
            case
'submit':
               
$edit['profile_public'] = 0;
                break;
        }
    }
}
?>

Version:6.13» 6.x-dev
Component:user system» documentation

The documentation for hook_user could use a little clarification, but the code is behaving correctly.

Title:hook_user ignores changes to $accounthook_user documentation needs clarification on how to modify values

Changing title to reflect what needs to be clarified in the documentation

Issue tags:+Novice

Probably could be done by a novice doc contributor

sub

$edit and $account are passed to user_save() where $account is used to find the user and $edit has the user information that will be saved in the database. Use, for example, edit[email]="user@foo.com" to update the user's email address. $account->email="user@foo.com" will not be saved. Setting $edit[email] to NULL will clear its value. I tested the update operation in 6.19 and 6.28. Still the documentation can be a bit more clear. I cannot find core.php. If someone can tell me where it is, i can update it.

For the insert operation user_save uses a different path and it seems to be a bug based on the current documentation as both should work the same way. Since Drupal 7 does not use this, I don't know if it helps to fix it.

Title:hook_user documentation needs clarification on how to modify valueshook_user/hook_user_presave documentation needs clarification on how to modify values
Version:6.x-dev» 7.x-dev

Drupal 7 has hook_user_update and hook_user_insert; both of these run after the user object has been saved. Then there is hook_user_presave(), which appears to have the same documentation problem that is described here (no information saying "put the info on $edit not on $account).

Drupal 8 uses a user object and this problem is not present in the docs.

So let's fix the Drupal 7 hook docs first.

Assigned:Unassigned» cck
StatusFileSize
new752 bytes
PASSED: [[SimpleTest]]: [MySQL] 39,919 pass(es).
[ View ]

Update for Drupal 7.

Status:Active» Needs review

Status:Needs review» Needs work

Thanks! The wording looks good. There are a couple of trailing spaces in the patch though -- those need to be removed.

Status:Needs work» Needs review
StatusFileSize
new750 bytes
PASSED: [[SimpleTest]]: [MySQL] 39,919 pass(es).
[ View ]

Thanks for reviewing. They are removed.

Status:Needs review» Reviewed & tested by the community

Thanks! That looks right to me.

Status:Reviewed & tested by the community» Fixed

Committed to 7.x - thanks! http://drupalcode.org/project/drupal.git/commit/fb0ecf1

I think technically it would be correct to say "will not necessarily be saved in the database" rather than "will not be saved"... For example, on programmatic user saves (or anything that does not pass a complete $edit array in), there will be properties not in $edit and therefore setting a property on $account should still result in it being saved.

However, this is confusing enough as it is, so I figured it's not so bad to be decisive rather than accurate here :) It should always be safe to use $edit (which will always take precedence over $account) and thus that one is preferred.

Status:Fixed» Closed (fixed)
Issue tags:-Novice

Automatically closed -- issue fixed for 2 weeks with no activity.