user_save

Versions
mediamosa-21
user_save($account, $edit = array(), $category = 'account')

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

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'). 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, if you are modifying an existing user account.

$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.

▾ 11 functions call user_save()

devel_create_users in sites/all/modules/devel/devel_generate.inc
Generate some random users.
install_configure_form_submit in includes/install.core.inc
Form API submit for the site configuration form.
openid_authentication in modules/openid/openid.module
Authenticate a user or attempt registration.
system_admin_compact_page in modules/system/system.module
Menu callback; Sets whether the admin menu is in compact mode or not.
user_cancel_confirm_form_submit in modules/user/user.pages.inc
Submit handler for the account cancellation confirm form.
user_external_login_register in modules/user/user.module
Helper function for authentication modules. Either logs in or registers the current user, based on username. Either way, the global $user object is populated and login tasks are performed.
user_multiple_role_edit in modules/user/user.module
Callback function for admin mass adding/deleting a user role.
user_profile_form_submit in modules/user/user.pages.inc
Submit function for the user account and profile editing form.
user_register_submit in modules/user/user.module
Submit handler for the user registration form.
user_user_operations_block in modules/user/user.module
Callback function for admin mass blocking users.
user_user_operations_unblock in modules/user/user.module
Callback function for admin mass unblocking users.

Code

modules/user/user.module, line 343

<?php
function user_save($account, $edit = array(), $category = 'account') {
  $transaction = db_transaction();
  try {
    $table = drupal_get_schema('users');

    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']);
    }

    // Presave field allowing changing of $edit.
    $edit = (object) $edit;
    field_attach_presave('user', $edit);
    $edit = (array) $edit;

    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)) {
      $data = unserialize($account->data);
      foreach ($data as $key => $value) {
        $edit['data'][$key] = $value;
      }
    }
    user_module_invoke('presave', $edit, $account, $category);

    if (is_object($account) && !$account->is_new) {
      // 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;
      }

      // Process picture uploads.
      if (!empty($edit['picture']->fid)) {
        $picture = $edit['picture'];
        // If the picture is a temporary file move it to its final location and
        // make it permanent.
        if (($picture->status & FILE_STATUS_PERMANENT) == 0) {
          $info = image_get_info($picture->uri);
          $picture_directory =  variable_get('file_default_scheme', 'public') . '://' . 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 . '.' . $info['extension']);

          if ($picture = file_move($picture, $destination, FILE_EXISTS_REPLACE)) {
            $picture->status |= FILE_STATUS_PERMANENT;
            $edit['picture'] = file_save($picture);
          }
        }
      }
      $edit['picture'] = empty($edit['picture']->fid) ? 0 : $edit['picture']->fid;

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

      // If the picture changed or was unset, remove the old one. This step needs
      // to occur after updating the {users} record so that user_file_references()
      // doesn't report it in use and block the deletion.
      if (!empty($account->picture->fid) && ($edit['picture'] != $account->picture->fid)) {
        file_delete($account->picture);
      }

      // Reload user roles if provided.
      if (isset($edit['roles']) && is_array($edit['roles'])) {
        db_delete('users_roles')
          ->condition('uid', $account->uid)
          ->execute();

        $query = db_insert('users_roles')->fields(array('uid', 'rid'));
        foreach (array_keys($edit['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 (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();
        }
      }

      // Save Field data.
      $entity = (object) $edit;
      field_attach_update('user', $entity);

      // Refresh user object.
      $user = user_load($account->uid, TRUE);

      // 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('update', $edit, $user, $category);
      entity_invoke('update', 'user', $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($edit['uid'])) {
        $edit['uid'] = db_next_id(db_query('SELECT MAX(uid) FROM {users}')->fetchField());
      }
      // 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;
      }

      $edit['mail'] = trim($edit['mail']);
      $success = drupal_write_record('users', $edit);
      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;
      }

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

      $entity = (object) $edit;
      field_attach_insert('user', $entity);

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

      // Save user roles.
      if (isset($edit['roles']) && is_array($edit['roles'])) {
        $query = db_insert('users_roles')->fields(array('uid', 'rid'));
        foreach (array_keys($edit['roles']) as $rid) {
          if (!in_array($rid, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) {
            $query->values(array(
              'uid' => $edit['uid'],
              'rid' => $rid,
            ));
          }
        }
        $query->execute();
      }

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

    return $user;
  }
  catch (Exception $e) {
    $transaction->rollback('user', $e->getMessage(), array(), WATCHDOG_ERROR);
  }
}
?>