| 5 user.module | user_save($account, $array = array(), $category = 'account') |
| 6 user.module | user_save($account, |
| 7 user.module | user_save($account, $edit = array(), $category = 'account') |
Save changes to a user account or add a new user.
@todo D8: Drop $edit and fix user_save() to be consistent with others.
Parameters
$account: (optional) The user object to modify or add. If you want to modify an existing user account, you will need to ensure that (a) $account is an object, and (b) you have set $account->uid to the numeric user ID of the user account you wish to modify. If you want to create a new user account, you can set $account->is_new to TRUE or omit the $account->uid field.
$edit: An array of fields and values to save. For example array('name' => 'My name'). Key / value pairs added to the $edit['data'] will be serialized and saved in the {users.data} column.
$category: (optional) The category for storing profile information in.
Return value
A fully-loaded $user object upon successful save or FALSE if the save failed.
22 calls to user_save()
File
- modules/
user/ user.module, line 420 - Enables the user registration and login system.
Code
function user_save($account, $edit = array(), $category = 'account') {
$transaction = db_transaction();
try {
if (!empty($edit['pass'])) {
// Allow alternate password hashing schemes.
require_once DRUPAL_ROOT . '/' . variable_get('password_inc', 'includes/password.inc');
$edit['pass'] = user_hash_password(trim($edit['pass']));
// Abort if the hashing failed and returned FALSE.
if (!$edit['pass']) {
return FALSE;
}
}
else {
// Avoid overwriting an existing password with a blank password.
unset($edit['pass']);
}
if (isset($edit['mail'])) {
$edit['mail'] = trim($edit['mail']);
}
// Load the stored entity, if any.
if (!empty($account->uid) && !isset($account->original)) {
$account->original = entity_load_unchanged('user', $account->uid);
}
if (empty($account)) {
$account = new stdClass();
}
if (!isset($account->is_new)) {
$account->is_new = empty($account->uid);
}
// Prepopulate $edit['data'] with the current value of $account->data.
// Modules can add to or remove from this array in hook_user_presave().
if (!empty($account->data)) {
$edit['data'] = !empty($edit['data']) ? array_merge($account->data, $edit['data']) : $account->data;
}
// Invoke hook_user_presave() for all modules.
user_module_invoke('presave', $edit, $account, $category);
// Invoke presave operations of Field Attach API and Entity API. Those APIs
// require a fully-fledged and updated entity object. Therefore, we need to
// copy any new property values of $edit into it.
foreach ($edit as $key => $value) {
$account->$key = $value;
}
field_attach_presave('user', $account);
module_invoke_all('entity_presave', $account, 'user');
if (is_object($account) && !$account->is_new) {
// Process picture uploads.
if (!empty($account->picture->fid) && (!isset($account->original->picture->fid) || $account->picture->fid != $account->original->picture->fid)) {
$picture = $account->picture;
// If the picture is a temporary file move it to its final location and
// make it permanent.
if (!$picture->status) {
$info = image_get_info($picture->uri);
$picture_directory = file_default_scheme() . '://' . variable_get('user_picture_path', 'pictures');
// Prepare the pictures directory.
file_prepare_directory($picture_directory, FILE_CREATE_DIRECTORY);
$destination = file_stream_wrapper_uri_normalize($picture_directory . '/picture-' . $account->uid . '-' . REQUEST_TIME . '.' . $info['extension']);
// Move the temporary file into the final location.
if ($picture = file_move($picture, $destination, FILE_EXISTS_RENAME)) {
$picture->status = FILE_STATUS_PERMANENT;
$account->picture = file_save($picture);
file_usage_add($picture, 'user', 'user', $account->uid);
}
}
// Delete the previous picture if it was deleted or replaced.
if (!empty($account->original->picture->fid)) {
file_usage_delete($account->original->picture, 'user', 'user', $account->uid);
file_delete($account->original->picture);
}
}
elseif (isset($edit['picture_delete']) && $edit['picture_delete']) {
file_usage_delete($account->original->picture, 'user', 'user', $account->uid);
file_delete($account->original->picture);
}
$account->picture = empty($account->picture->fid) ? 0 : $account->picture->fid;
// Do not allow 'uid' to be changed.
$account->uid = $account->original->uid;
// Save changes to the user table.
$success = drupal_write_record('users', $account, 'uid');
if ($success === FALSE) {
// The query failed - better to abort the save than risk further
// data loss.
return FALSE;
}
// Reload user roles if provided.
if ($account->roles != $account->original->roles) {
db_delete('users_roles')
->condition('uid', $account->uid)
->execute();
$query = db_insert('users_roles')->fields(array('uid', 'rid'));
foreach (array_keys($account->roles) as $rid) {
if (!in_array($rid, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) {
$query->values(array(
'uid' => $account->uid,
'rid' => $rid,
));
}
}
$query->execute();
}
// Delete a blocked user's sessions to kick them if they are online.
if ($account->original->status != $account->status && $account->status == 0) {
drupal_session_destroy_uid($account->uid);
}
// If the password changed, delete all open sessions and recreate
// the current one.
if ($account->pass != $account->original->pass) {
drupal_session_destroy_uid($account->uid);
if ($account->uid == $GLOBALS['user']->uid) {
drupal_session_regenerate();
}
}
// Save Field data.
field_attach_update('user', $account);
// Send emails after we have the new user object.
if ($account->status != $account->original->status) {
// The user's status is changing; conditionally send notification email.
$op = $account->status == 1 ? 'status_activated' : 'status_blocked';
_user_mail_notify($op, $account);
}
// Update $edit with any interim changes to $account.
foreach ($account as $key => $value) {
if (!property_exists($account->original, $key) || $value !== $account->original->$key) {
$edit[$key] = $value;
}
}
user_module_invoke('update', $edit, $account, $category);
module_invoke_all('entity_update', $account, 'user');
}
else {
// Allow 'uid' to be set by the caller. There is no danger of writing an
// existing user as drupal_write_record will do an INSERT.
if (empty($account->uid)) {
$account->uid = db_next_id(db_query('SELECT MAX(uid) FROM {users}')->fetchField());
}
// Allow 'created' to be set by the caller.
if (!isset($account->created)) {
$account->created = REQUEST_TIME;
}
$success = drupal_write_record('users', $account);
if ($success === FALSE) {
// On a failed INSERT some other existing user's uid may be returned.
// We must abort to avoid overwriting their account.
return FALSE;
}
// Make sure $account is properly initialized.
$account->roles[DRUPAL_AUTHENTICATED_RID] = 'authenticated user';
field_attach_insert('user', $account);
$edit = (array) $account;
user_module_invoke('insert', $edit, $account, $category);
module_invoke_all('entity_insert', $account, 'user');
// Save user roles.
if (count($account->roles) > 1) {
$query = db_insert('users_roles')->fields(array('uid', 'rid'));
foreach (array_keys($account->roles) as $rid) {
if (!in_array($rid, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) {
$query->values(array(
'uid' => $account->uid,
'rid' => $rid,
));
}
}
$query->execute();
}
}
// Clear internal properties.
unset($account->is_new);
unset($account->original);
// Clear the static loading cache.
entity_get_controller('user')->resetCache(array($account->uid));
return $account;
}
catch (Exception $e) {
$transaction->rollback();
watchdog_exception('user', $e);
throw $e;
}
}
Login or register to post comments
Comments
Saving fields in user account
To save fields data in user account we can act this way:
$account = user_load($uid); // Loading account$edit = array(
'field_some_custom_field' => array(
'und' => array(
0 => array(
'value' => $new_value,
),
),
),
);
user_save($account, $edit);
Big typo
Depends on Field type.
Some types want other than standard "value" key name:
Link - "url"
Email - "email"
Getting newly saved user id
I was looking and looking to find out how to add a new user to an organic group via a custom form.
Here is what I found out.
$new_user = array(
'name' => $form_state['values']['name'],
'pass' => user_password(),
'mail' => $form_state['values']['mail'],
'init' => $form_state['values']['mail'],
'field_first_name' => array(LANGUAGE_NONE => array(array('value' => $form_state['values']['field_first_name']))),
'field_last_name' => array(LANGUAGE_NONE => array(array('value' => $form_state['values']['field_last_name']))),
'field_phone_number' => array(LANGUAGE_NONE => array(array('value' => $form_state['values']['field_phone_number']))),
'status' => 1,
'access' => REQUEST_TIME,
'roles' => $roles,
);
// $account returns user object
$account = user_save(null, $new_user);
// $group is organic group node I want to add the brand new user to
$group = og_get_group('node', $node->nid);
// This adds user to the group
og_group($group->gid, array('entity' => $account));
Hope this helps some folks along with adding a new user to a group!
Saving a new profile picture
Worth noting:
Even though the user object that is returned from
user_load()(and by this function) stores an integer value in$user->picture(being the file'sfid), that is not the correct data type to use if you wish to update the profile picture using this function. If you try to do so, somehow this function silently fails, and none of your other attempted edits will be saved either (still not sure why there isn't instead an error somewhere).The correct way to update the profile picture is to pass its associated file object in the
$editarray, not its integerfid.user_save cannot be used to edit the anonymous user
The anonymous user in Drupal has a uid=0.
When execution reaches this line:
if (!empty($account->uid) && !isset($account->original)) {The call to empty returns true because of the zero value, and user_save decides it is a new user. This will fail because the new user has a duplicate username.
So if you need to edit all users (I am setting a default value for a custom field), you need to strip uid=0 from the list and deal with it as a special case.
User data going away
User data is going away in Drupal 8 and user data is difficult to list. Move your data into fields. You can then list users that have your data and you can list their values.
Each extra field will slow down your database a little bit. If you have several related items, you might want to group them the way the address field module groups address fields in one row.
User save trips up some other modules
When you save a user, other modules have their user hooks called to modify the user. If you get weird results, such as missing fields, it can be another module responding to a hook and changing stuff.
Your save might be followed by another module changing the same field. Another module might respond as if you are editing the user in the admin page. A good test is to visit the user in the admin edit page, note all the values, run your save, then visit the user in the admin edit page and look for unexpected changes.