diff --git includes/session.inc includes/session.inc index 44c53c8..4983df8 100644 --- includes/session.inc +++ includes/session.inc @@ -102,9 +102,6 @@ function _drupal_session_read($sid) { // We found the client's session record and they are an authenticated user. if ($user && $user->uid > 0) { - // This is done to unserialize the data member of $user. - $user = drupal_unpack($user); - // Add roles element to $user. $user->roles = array(); $user->roles[DRUPAL_AUTHENTICATED_RID] = 'authenticated user'; diff --git modules/comment/comment.module modules/comment/comment.module index b58352e..80fa511 100644 --- modules/comment/comment.module +++ modules/comment/comment.module @@ -1499,13 +1499,12 @@ class CommentController extends DrupalDefaultEntityController { $this->query->addField('n', 'type', 'node_type'); $this->query->innerJoin('users', 'u', 'base.uid = u.uid'); $this->query->addField('u', 'name', 'registered_name'); - $this->query->fields('u', array('uid', 'signature', 'picture', 'data')); + $this->query->fields('u', array('uid', 'signature', 'picture')); } protected function attachLoad(&$comments) { // Setup standard comment properties. foreach ($comments as $key => $comment) { - $comment = drupal_unpack($comment); $comment->name = $comment->uid ? $comment->registered_name : $comment->name; $comment->new = node_mark($comment->nid, $comment->changed); $comment->node_type = 'comment_node_' . $comment->node_type; diff --git modules/comment/comment.pages.inc modules/comment/comment.pages.inc index f85c5ae..2a7070f 100644 --- modules/comment/comment.pages.inc +++ modules/comment/comment.pages.inc @@ -48,7 +48,7 @@ function comment_reply($node, $pid = NULL) { // $pid indicates that this is a reply to a comment. if ($pid) { // Load the comment whose cid = $pid - $comment = db_query('SELECT c.*, u.uid, u.name AS registered_name, u.signature, u.picture, u.data FROM {comment} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.cid = :cid AND c.status = :status', array( + $comment = db_query('SELECT c.*, u.uid, u.name AS registered_name, u.signature, u.picture FROM {comment} c INNER JOIN {users} u ON c.uid = u.uid WHERE c.cid = :cid AND c.status = :status', array( ':cid' => $pid, ':status' => COMMENT_PUBLISHED, ))->fetchObject(); @@ -61,7 +61,6 @@ function comment_reply($node, $pid = NULL) { drupal_goto("node/$node->nid"); } // Display the parent comment - $comment = drupal_unpack($comment); $comment->node_type = 'comment_node_' . $node->type; field_attach_load('comment', array($comment->cid => $comment)); $comment->name = $comment->uid ? $comment->registered_name : $comment->name; diff --git modules/user/user.install modules/user/user.install index 4bd65e9..b7f20d4 100644 --- modules/user/user.install +++ modules/user/user.install @@ -193,13 +193,6 @@ function user_schema() { 'default' => '', 'description' => 'Email address used for initial account creation.', ), - 'data' => array( - 'type' => 'text', - 'not null' => FALSE, - 'size' => 'big', - 'serialize' => TRUE, - 'description' => 'A serialized array of name value pairs that are related to the user. Any form values posted during user edit are stored and are loaded into the $user object during user_load(). Use of this field is discouraged and it will likely disappear in a future version of Drupal.', - ), ), 'indexes' => array( 'access' => array('access'), @@ -212,6 +205,39 @@ function user_schema() { 'primary key' => array('uid'), ); + $schema['users_data'] = array( + 'description' => 'Stores named variable/value pairs per user. Any form values posted during user edit are stored and loaded into the $user object during user_load(). All variables are loaded and cached in memory when a user is loaded, so developers should be careful about what is stored here.', + 'fields' => array( + 'uid' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + 'description' => 'Primary Key: {users}.uid for user.', + ), + 'name' => array( + 'description' => 'The name of the variable.', + 'type' => 'varchar', + 'length' => 128, + 'not null' => TRUE, + 'default' => '', + ), + 'value' => array( + 'description' => 'The serialized value of the variable.', + 'type' => 'text', + 'not null' => TRUE, + 'size' => 'big', + ), + ), + 'primary key' => array('uid', 'name'), + 'indexes' => array( + 'name' => array('name'), + ), + 'foreign keys' => array( + 'uid' => array('users' => 'uid'), + ), + ); + $schema['users_roles'] = array( 'description' => 'Maps users to roles.', 'fields' => array( @@ -297,7 +323,6 @@ function user_update_7000(&$sandbox) { * * These fields were previously used to store per-user comment settings. */ - function user_update_7001() { db_drop_field('users', 'threshold'); db_drop_field('users', 'mode'); @@ -478,6 +503,69 @@ function user_update_7004(&$sandbox) { } /** + * Move {users}.data into an own {users_data} table. + */ +function user_update_7005() { + $ret = array(); + // Create new {users_data} table. + db_create_table($ret, 'users_data', array( + 'description' => 'Stores named variable/value pairs per user. All variables are loaded and cached in memory when a user is loaded, so developers should not be careless about what is stored here.', + 'fields' => array( + 'uid' => array( + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + 'description' => 'Primary Key: {users}.uid for user.', + ), + 'name' => array( + 'description' => 'The name of the variable.', + 'type' => 'varchar', + 'length' => 128, + 'not null' => TRUE, + 'default' => '', + ), + 'value' => array( + 'description' => 'The value of the variable.', + 'type' => 'text', + 'not null' => TRUE, + 'size' => 'big', + ), + ), + 'primary key' => array('uid', 'name'), + 'indexes' => array( + 'name' => array('name'), + ), + 'foreign keys' => array( + 'uid' => array('users' => 'uid'), + ), + )); + + // Migrate existing data. + $result = db_query("SELECT uid, data FROM {users}")->fetchAllAssoc('uid'); + $query = db_insert('users_data')->fields(array('uid', 'name', 'value')); + foreach ($result as $uid => $user) { + if (empty($user->data)) { + continue; + } + $result[$uid]->data = unserialize($result[$uid]->data); + if (is_array($result[$uid]->data)) { + foreach ($result[$uid]->data as $name => $value) { + $query->values(array( + 'uid' => $uid, + 'name' => $name, + 'value' => serialize($value), + )); + } + } + } + $query->execute(); + + // Delete {users}.data. + db_drop_field($ret, 'users', 'data'); +} + +/** * @} End of "defgroup user-updates-6.x-to-7.x" * The next series of updates should start at 8000. */ diff --git modules/user/user.module modules/user/user.module index 1b8db22..dff4801 100644 --- modules/user/user.module +++ modules/user/user.module @@ -196,7 +196,6 @@ class UserController extends DrupalDefaultEntityController { $picture_fids = array(); foreach ($queried_users as $key => $record) { $picture_fids[] = $record->picture; - $queried_users[$key] = drupal_unpack($record); $queried_users[$key]->roles = array(); if ($record->uid) { $queried_users[$record->uid]->roles[DRUPAL_AUTHENTICATED_RID] = 'authenticated user'; @@ -206,6 +205,12 @@ class UserController extends DrupalDefaultEntityController { } } + // Attach user variables. + $data = db_query("SELECT uid, name, value FROM {users_data} WHERE uid IN (:uids)", array(':uids' => array_keys($queried_users))); + foreach ($data as $record) { + $queried_users[$record->uid]->{$record->name} = unserialize($record->value); + } + // Add any additional roles from the database. $result = db_query('SELECT r.rid, r.name, ur.uid FROM {role} r INNER JOIN {users_roles} ur ON ur.rid = r.rid WHERE ur.uid IN (:uids)', array(':uids' => array_keys($queried_users))); foreach ($result as $record) { @@ -293,9 +298,9 @@ function user_load_by_name($name) { * @param $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 + * tables may be added to the users_data table * 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 + * Setting a field to NULL deletes it from the users_data table, if you are * modifying an existing user account. * @param $category * (optional) The category for storing profile information in. @@ -340,7 +345,6 @@ function user_save($account, $edit = array(), $category = 'account') { user_module_invoke('presave', $edit, $account, $category); if (is_object($account) && !$account->is_new) { - $data = unserialize(db_query('SELECT data FROM {users} WHERE uid = :uid', array(':uid' => $account->uid))->fetchField()); // 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')) { @@ -352,10 +356,13 @@ function user_save($account, $edit = array(), $category = 'account') { // column. if (!in_array($key, array('roles', 'is_new')) && empty($user_fields[$key]) && empty($field_form[$key])) { if ($value === NULL) { - unset($data[$key]); + db_query("DELETE FROM {users_data} WHERE uid = :uid AND name = :name", array(':uid' => $account->uid, ':name' => $key)); } else { - $data[$key] = $value; + db_merge('users_data') + ->key(array('uid' => $account->uid, 'name' => $key)) + ->fields(array('value' => serialize($value))) + ->execute(); } } } @@ -381,7 +388,6 @@ function user_save($account, $edit = array(), $category = 'account') { } $edit['picture'] = empty($edit['picture']->fid) ? 0 : $edit['picture']->fid; - $edit['data'] = $data; // Do not allow 'uid' to be changed. $edit['uid'] = $account->uid; // Save changes to the user table. @@ -476,19 +482,17 @@ function user_save($account, $edit = array(), $category = 'account') { // Note, we wait with saving the data column to prevent module-handled // fields from being saved there. - $data = array(); foreach ($edit as $key => $value) { // Form fields that don't pertain to the users, user_roles, or // Field API are automatically serialized into the user.data // column. if ((!in_array($key, array('roles', 'is_new'))) && (empty($user_fields[$key]) && empty($field_form[$key])) && ($value !== NULL)) { - $data[$key] = $value; + db_merge('users_data') + ->key(array('uid' => $user->uid, 'name' => $key)) + ->fields(array('value' => serialize($value))) + ->execute(); } } - 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'])) { @@ -2978,13 +2982,12 @@ function user_node_load($nodes, $types) { } // Fetch name, picture, and data for these users. - $user_fields = db_query("SELECT uid, name, picture, data FROM {users} WHERE uid IN (:uids)", array(':uids' => $uids))->fetchAllAssoc('uid'); + $user_fields = db_query("SELECT uid, name, picture FROM {users} WHERE uid IN (:uids)", array(':uids' => $uids))->fetchAllAssoc('uid'); // Add these values back into the node objects. foreach ($uids as $nid => $uid) { $nodes[$nid]->name = $user_fields[$uid]->name; $nodes[$nid]->picture = $user_fields[$uid]->picture; - $nodes[$nid]->data = $user_fields[$uid]->data; } }