diff --git a/core/includes/common.inc b/core/includes/common.inc diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index 8f79e65..bafe34f 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -1862,8 +1862,13 @@ function install_configure_form_submit($form, &$form_state) { // We precreated user 1 with placeholder values. Let's save the real values. $account = user_load(1); - $merge_data = array('init' => $form_state['values']['account']['mail'], 'roles' => !empty($account->roles) ? $account->roles : array(), 'status' => 1, 'timezone' => $form_state['values']['date_default_timezone']); - user_save($account, array_merge($form_state['values']['account'], $merge_data)); + $account->init = $account->mail = $form_state['values']['account']['mail']; + $account->roles = !empty($account->roles) ? $account->roles : array(); + $account->status = 1; + $account->timezone = $form_state['values']['date_default_timezone']; + $account->pass = $form_state['values']['account']['pass']; + $account->name = $form_state['values']['account']['name']; + $account->save(); // Load global $user and perform final login tasks. $user = user_load(1); user_login_finalize(); diff --git a/core/modules/block/block.module b/core/modules/block/block.module index 55b0b40..e827bc0 100644 --- a/core/modules/block/block.module +++ b/core/modules/block/block.module @@ -631,9 +631,9 @@ function block_form_user_profile_form_alter(&$form, &$form_state) { /** * Implements hook_user_presave(). */ -function block_user_presave(&$edit, $account) { - if (isset($edit['block'])) { - $edit['data']['block'] = $edit['block']; +function block_user_presave($edit) { + if (isset($edit->block)) { + $edit->data['block'] = $edit->block; } } diff --git a/core/modules/entity/entity.controller.inc b/core/modules/entity/entity.controller.inc diff --git a/core/modules/entity/entity.module b/core/modules/entity/entity.module diff --git a/core/modules/overlay/overlay.module b/core/modules/overlay/overlay.module index 5433d3e..293426d 100644 --- a/core/modules/overlay/overlay.module +++ b/core/modules/overlay/overlay.module @@ -102,9 +102,9 @@ function overlay_form_user_profile_form_alter(&$form, &$form_state) { /** * Implements hook_user_presave(). */ -function overlay_user_presave(&$edit, $account) { - if (isset($edit['overlay'])) { - $edit['data']['overlay'] = $edit['overlay']; +function overlay_user_presave($edit) { + if (isset($edit->overlay)) { + $edit->data['overlay'] = $edit->overlay; } } diff --git a/core/modules/simpletest/drupal_web_test_case.php b/core/modules/simpletest/drupal_web_test_case.php index 5c711fb..d23aaaf 100644 --- a/core/modules/simpletest/drupal_web_test_case.php +++ b/core/modules/simpletest/drupal_web_test_case.php @@ -1116,7 +1116,9 @@ class DrupalWebTestCase extends DrupalTestCase { $edit['pass'] = user_password(); $edit['status'] = 1; - $account = user_save(drupal_anonymous_user(), $edit); + $account = entity_create('user', $edit); + + $account->save(); $this->assertTrue(!empty($account->uid), t('User created with name %name and pass %pass', array('%name' => $edit['name'], '%pass' => $edit['pass'])), t('User login')); if (empty($account->uid)) { @@ -1220,7 +1222,7 @@ class DrupalWebTestCase extends DrupalTestCase { * * @see drupalCreateUser() */ - protected function drupalLogin(stdClass $user) { + protected function drupalLogin(User $user) { if ($this->loggedInUser) { $this->drupalLogout(); } diff --git a/core/modules/user/user.entity.inc b/core/modules/user/user.entity.inc index 5549c77..a970e4e 100644 --- a/core/modules/user/user.entity.inc +++ b/core/modules/user/user.entity.inc @@ -5,12 +5,131 @@ */ /** + * Defines the user entity class. + */ +class User extends Entity { + + /** + * The user ID. + * + * @var integer + */ + public $uid; + + /** + * The unique user name. + * + * @var string + */ + public $name = ''; + + /** + * The user's password (hashed). + * + * @var string + */ + public $pass; + + /** + * The user's email address. + * + * @var string + */ + public $mail = ''; + + /** + * The user's default theme. + * + * @var string + */ + public $theme; + + /** + * The user's signature. + * + * @var string + */ + public $signature; + + /** + * The user's signature format. + * + * @var string + */ + public $signature_format = NULL; + + /** + * The timestamp when the user was created. + * + * @var integer + */ + public $created = 0; + + /** + * The timestamp when the user last accessed the site. + * + * @var integer + */ + public $access = 0; + + /** + * The timestamp when the user lasted logged in. + * + * @var integer + */ + public $login = 0; + + /** + * Whether the user is active(1) or blocked(0). + * + * @var integer + */ + public $status = 0; + + /** + * The user's timezone. + * + * @var string + */ + public $timezone = NULL; + + /** + * The user's default language. + * + * @var string + */ + public $language = ''; + + /** + * The fid of the user's picture. + * + * @var integer + */ + public $picture = 0; + + /** + * The email address used for initial account creation. + * + * @var string + */ + public $init = ''; + + /** + * The user's roles. + * + * @var array + */ + public $roles = array(); + +} + +/** * Controller class for users. * * This extends the DrupalDefaultEntityController class, adding required * special handling for user objects. */ -class UserController extends DrupalDefaultEntityController { +class UserController extends EntityDatabaseStorageController { function attachLoad(&$queried_users, $revision_id = FALSE) { // Build an array of user picture IDs so that these can be fetched later. @@ -49,4 +168,139 @@ class UserController extends DrupalDefaultEntityController { // hook_user_load(). parent::attachLoad($queried_users, $revision_id); } + + function save(EntityInterface $entity) { + $entity->is_new = $entity->isNew(); + if (empty($entity->uid)) { + $entity->uid = db_next_id(db_query('SELECT MAX(uid) FROM {users}')->fetchField()); + } + parent::save($entity); + } + + function preSave(EntityInterface $entity) { + // Update the user password if it has changed. + if ($entity->is_new || $entity->pass != $entity->original->pass) { + // Allow alternate password hashing schemes. + require_once DRUPAL_ROOT . '/' . variable_get('password_inc', 'core/includes/password.inc'); + $entity->pass = user_hash_password(trim($entity->pass)); + // Abort if the hashing failed and returned FALSE. + if (!$entity->pass) { + return FALSE; + } + } + + if (!$entity->is_new) { + // Process picture uploads. + if (!empty($entity->picture->fid) && (!isset($entity->original->picture->fid) || $entity->picture->fid != $entity->original->picture->fid)) { + $picture = $entity->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($entity->original->picture->fid)) { + file_usage_delete($entity->original->picture, 'user', 'user', $account->uid); + file_delete($entity->original->picture); + } + } + $entity->picture = empty($entity->picture->fid) ? 0 : $entity->picture->fid; + + // Do not allow 'uid' to be changed. + $entity->uid = $entity->original->uid; + + // If the password changed, delete all open sessions and recreate + // the current one. + if ($entity->pass != $entity->original->pass) { + drupal_session_destroy_uid($entity->uid); + if ($entity->uid == $GLOBALS['user']->uid) { + drupal_session_regenerate(); + } + } + + // Reload user roles if provided. + if ($entity->roles != $entity->original->roles) { + db_delete('users_roles') + ->condition('uid', $entity->uid) + ->execute(); + + $query = db_insert('users_roles')->fields(array('uid', 'rid')); + foreach (array_keys($entity->roles) as $rid) { + if (!in_array($rid, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) { + $query->values(array( + 'uid' => $entity->uid, + 'rid' => $rid, + )); + } + } + $query->execute(); + } + + // Delete a blocked user's sessions to kick them if they are online. + if ($entity->original->status != $entity->status && $entity->status == 0) { + drupal_session_destroy_uid($entity->uid); + } + + // Send emails after we have the new user object. + if ($entity->status != $entity->original->status) { + // The user's status is changing; conditionally send notification email. + $op = $entity->status == 1 ? 'status_activated' : 'status_blocked'; + _user_mail_notify($op, $entity); + } + } + else { + // Allow 'created' to be set by the caller. + if (!isset($entity->created)) { + $entity->created = REQUEST_TIME; + } + + // Make sure $account is properly initialized. + $entity->roles[DRUPAL_AUTHENTICATED_RID] = 'authenticated user'; + + // Save user roles. + if (count($entity->roles) > 1) { + $query = db_insert('users_roles')->fields(array('uid', 'rid')); + foreach (array_keys($entity->roles) as $rid) { + if (!in_array($rid, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID))) { + $query->values(array( + 'uid' => $entity->uid, + 'rid' => $rid, + )); + } + } + $query->execute(); + } + } + + if (!empty($entity->picture_upload)) { + $entity->picture = $entity->picture_upload; + } + // Delete picture if requested, and if no replacement picture was given. + elseif (!empty($entity->picture_delete)) { + $entity->picture = NULL; + } + // Prepare user roles. + if (isset($entity->roles)) { + $entity->roles = array_filter($entity->roles); + } + + // Move account cancellation information into $user->data. + foreach (array('user_cancel_method', 'user_cancel_notify') as $key) { + if (isset($entity->{$key})) { + $entity->data[$key] = $entity->{$key}; + } + } + } } diff --git a/core/modules/user/user.module b/core/modules/user/user.module index 2dded35..9bba3a3 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -143,7 +143,7 @@ function user_theme() { * Implements hook_entity_info(). */ function user_entity_info() { - $return = array( + return array( 'user' => array( 'label' => t('User'), 'controller class' => 'UserController', @@ -151,6 +151,7 @@ function user_entity_info() { 'uri callback' => 'user_uri', 'label callback' => 'user_label', 'fieldable' => TRUE, + 'entity class' => 'User', 'entity keys' => array( 'id' => 'uid', ), @@ -171,7 +172,6 @@ function user_entity_info() { ), ), ); - return $return; } /** @@ -1181,30 +1181,6 @@ function user_account_form_validate($form, &$form_state) { } } -/** - * Implements hook_user_presave(). - */ -function user_user_presave(&$edit, $account) { - if (!empty($edit['picture_upload'])) { - $edit['picture'] = $edit['picture_upload']; - } - // Delete picture if requested, and if no replacement picture was given. - elseif (!empty($edit['picture_delete'])) { - $edit['picture'] = NULL; - } - // Prepare user roles. - if (isset($edit['roles'])) { - $edit['roles'] = array_filter($edit['roles']); - } - - // Move account cancellation information into $user->data. - foreach (array('user_cancel_method', 'user_cancel_notify') as $key) { - if (isset($edit[$key])) { - $edit['data'][$key] = $edit[$key]; - } - } -} - function user_login_block($form) { $form['#action'] = url($_GET['q'], array('query' => drupal_get_destination())); $form['#id'] = 'user-login-form';