user_save

Definition

user_save($account, $edit = array(), $category = 'account')
modules/user/user.module, line 217

Description

Save changes to a user account or add a new user.

Parameters

$account The $user object for the user to modify or add. If $user->uid is omitted, a new user will be added.

$edit An array of fields and values to save. For example array('name' => 'My name'). Keys that do not belong to columns in the user-related tables are added to the a serialized array in the 'data' column and will be loaded in the $user->data array by user_load(). Setting a field to NULL deletes it from the 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.

Code

<?php
function user_save($account, $edit = array(), $category = 'account') {
  $table = drupal_get_schema('users');
  $user_fields = $table['fields'];

  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 (is_object($account) && $account->uid) {
    user_module_invoke('update', $edit, $account, $category);
    $data = unserialize(db_result(db_query('SELECT data FROM {users} WHERE uid = %d', $account->uid)));
    // Consider users edited by an administrator as logged in, if they haven't
    // already, so anonymous users can view the profile (if allowed).
    if (empty($edit['access']) && empty($account->access) && user_access('administer users')) {
      $edit['access'] = REQUEST_TIME;
    }
    foreach ($edit as $key => $value) {
      // Fields that don't pertain to the users or user_roles
      // automatically serialized into the users.data column.
      if ($key != 'roles' && empty($user_fields[$key])) {
        if ($value === NULL) {
          unset($data[$key]);
        }
        else {
          $data[$key] = $value;
        }
      }
    }

    $edit['data'] = $data;
    $edit['uid'] = $account->uid;
    // Save changes to the users table.
    $success = drupal_write_record('users', $edit, 'uid');
    if (!$success) {
      // The query failed - better to abort the save than risk further data loss.
      return FALSE;
    }

    // Reload user roles if provided.
    if (isset($edit['roles']) && is_array($edit['roles'])) {
      db_query('DELETE FROM {users_roles} WHERE uid = %d', $account->uid);

      foreach (array_keys($edit['roles']) as $rid) {
        if (!in_array($rid, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) {
          db_query('INSERT INTO {users_roles} (uid, rid) VALUES (%d, %d)', $account->uid, $rid);
        }
      }
    }

    // Delete a blocked user's sessions to kick them if they are online.
    if (isset($edit['status']) && $edit['status'] == 0) {
      drupal_session_destroy_uid($account->uid);
    }

    // If the password changed, delete all open sessions and recreate
    // the current one.
    if (!empty($edit['pass'])) {
      drupal_session_destroy_uid($account->uid);
      if ($account->uid == $GLOBALS['user']->uid) {
        drupal_session_regenerate();
      }
    }

    // Refresh user object.
    $user = user_load(array('uid' => $account->uid));

    // Send emails after we have the new user object.
    if (isset($edit['status']) && $edit['status'] != $account->status) {
      // The user's status is changing; conditionally send notification email.
      $op = $edit['status'] == 1 ? 'status_activated' : 'status_blocked';
      _user_mail_notify($op, $user);
    }

    user_module_invoke('after_update', $edit, $user, $category);
  }
  else {
    // Allow 'created' to be set by the caller.
    if (!isset($edit['created'])) {
      $edit['created'] = REQUEST_TIME;
    }
    // Consider users created by an administrator as already logged in, so
    // anonymous users can view the profile (if allowed).
    if (empty($edit['access']) && user_access('administer users')) {
      $edit['access'] = REQUEST_TIME;
    }

    $success = drupal_write_record('users', $edit);
    if (!$success) {
      // On a failed INSERT some other existing user's uid may be returned.
      // We must abort to avoid overwriting their account.
      return FALSE;
    }

    // Build the initial user object.
    $user = user_load(array('uid' => $edit['uid']));

    user_module_invoke('insert', $edit, $user, $category);

    // Note, we wait with saving the data column to prevent module-handled
    // fields from being saved there.
    $data = array();
    foreach ($edit as $key => $value) {
      if (($key != 'roles') && (empty($user_fields[$key])) && ($value !== NULL)) {
        $data[$key] = $value;
      }
    }
    if (!empty($data)) {
      $data_array = array('uid' => $user->uid, 'data' => $data);
      drupal_write_record('users', $data_array, 'uid');
    }

    // Save user roles (delete just to be safe).
    if (isset($edit['roles']) && is_array($edit['roles'])) {
      db_query('DELETE FROM {users_roles} WHERE uid = %d', $edit['uid']);
      foreach (array_keys($edit['roles']) as $rid) {
        if (!in_array($rid, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) {
          db_query('INSERT INTO {users_roles} (uid, rid) VALUES (%d, %d)', $edit['uid'], $rid);
        }
      }
    }

    // Build the finished user object.
    $user = user_load(array('uid' => $edit['uid']));
  }

  return $user;
}
?>
 
 

All source code and documentation on this site is released under the terms of the GNU General Public License, version 2 and later. Drupal is a registered trademark of Dries Buytaert.