Commit 60688d68 authored by Dries's avatar Dries

- Patch #181411 by Moshe: use schema API for saving and updating user records.

parent 029b6b91
......@@ -3273,12 +3273,24 @@ function drupal_write_record($table, &$object, $update = array()) {
if (empty($info['serialize'])) {
$values[] = $object->$field;
}
else {
elseif (!empty($object->$field)) {
$values[] = serialize($object->$field);
}
else {
$values[] = '';
}
}
}
if (empty($fields)) {
// No changes requested.
// If we began with an array, convert back so we don't surprise the caller.
if ($array) {
$object = (array)$object;
}
return;
}
// Build the SQL.
$query = '';
if (!count($update)) {
......
......@@ -293,7 +293,8 @@ function profile_field_form_validate($form, &$form_state) {
form_set_error('name', t('The specified form name contains one or more illegal characters. Spaces or any other special characters except dash (-) and underscore (_) are not allowed.'));
}
if (in_array($form_state['values']['name'], user_fields())) {
$users_table = drupal_get_schema('users');
if (!empty($users_table['fields'][$form_state['values']['name']])) {
form_set_error('name', t('The specified form name is reserved for use by Drupal.'));
}
// Validate the category:
......
......@@ -247,6 +247,7 @@ function user_schema() {
'type' => 'text',
'not null' => FALSE,
'size' => 'big',
'serialize' => TRUE,
'description' => t('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.'),
),
),
......
......@@ -197,9 +197,11 @@ function user_load($array = array()) {
* omitted, a new user will be added.
*
* @param $array
* (optional) An array of fields and values to save. For example,
* array('name' => 'My name'); Setting a field to NULL deletes it from
* the data column.
* 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.
*
* @param $category
* (optional) The category for storing profile information in.
......@@ -208,11 +210,19 @@ function user_load($array = array()) {
* A fully-loaded $user object upon successful save or FALSE if the save failed.
*/
function user_save($account, $array = array(), $category = 'account') {
// Dynamically compose a SQL query:
$user_fields = user_fields();
$table = drupal_get_schema('users');
$user_fields = $table['fields'];
if (!empty($array['pass'])) {
$array['pass'] = md5($array['pass']);
}
else {
// Avoid overwriting an existing password with a blank password.
unset($array['pass']);
}
if (is_object($account) && $account->uid) {
user_module_invoke('update', $array, $account, $category);
$query = '';
$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).
......@@ -220,31 +230,23 @@ function user_save($account, $array = array(), $category = 'account') {
$array['access'] = time();
}
foreach ($array as $key => $value) {
if ($key == 'pass' && !empty($value)) {
$query .= "$key = '%s', ";
$v[] = md5($value);
}
else if ((substr($key, 0, 4) !== 'auth') && ($key != 'pass')) {
if (in_array($key, $user_fields)) {
// Save standard fields.
$query .= "$key = '%s', ";
$v[] = $value;
// Fields that don't pertain to the users, users_roles, or
// authmap tables are automatically serialized into the
// users.data column. Authmap fields always begin with 'auth'.
if ($key != 'roles' && substr($key, 0, 4) !== 'auth' && empty($user_fields[$key])) {
if ($value === NULL) {
unset($data[$key]);
}
else if ($key != 'roles') {
// Roles is a special case: it used below.
if ($value === NULL) {
unset($data[$key]);
}
else {
$data[$key] = $value;
}
else {
$data[$key] = $value;
}
}
}
$query .= "data = '%s' ";
$v[] = serialize($data);
$success = db_query("UPDATE {users} SET $query WHERE uid = %d", array_merge($v, array($account->uid)));
$array['data'] = $data;
$array['uid'] = $account->uid;
// Save changes to the users table.
$success = drupal_write_record('users', $array, 'uid');
if (!$success) {
// The query failed - better to abort the save than risk further data loss.
return FALSE;
......@@ -296,33 +298,7 @@ function user_save($account, $array = array(), $category = 'account') {
$array['access'] = time();
}
// Note: we wait to save the data column to prevent module-handled
// fields from being saved there. We cannot invoke hook_user('insert') here
// because we don't have a fully initialized user object yet.
foreach ($array as $key => $value) {
switch ($key) {
case 'pass':
$fields[] = $key;
$values[] = md5($value);
$s[] = "'%s'";
break;
case 'mode': case 'sort': case 'timezone':
case 'threshold': case 'created': case 'access':
case 'login': case 'status':
$fields[] = $key;
$values[] = $value;
$s[] = "%d";
break;
default:
if (substr($key, 0, 4) !== 'auth' && in_array($key, $user_fields)) {
$fields[] = $key;
$values[] = $value;
$s[] = "'%s'";
}
break;
}
}
$success = db_query('INSERT INTO {users} ('. implode(', ', $fields) .') VALUES ('. implode(', ', $s) .')', $values);
$success = drupal_write_record('users', $array);
if (!$success) {
// On a failed INSERT some other existing user's uid may be returned.
// We must abort to avoid overwriting their account.
......@@ -330,19 +306,22 @@ function user_save($account, $array = array(), $category = 'account') {
}
// Build the initial user object.
$array['uid'] = db_last_insert_id('users', 'uid');
$user = user_load(array('uid' => $array['uid']));
user_module_invoke('insert', $array, $user, $category);
// Build and save the serialized data field now.
// Note, we wait with saving the data column to prevent module-handled
// fields from being saved there.
$data = array();
foreach ($array as $key => $value) {
if ((substr($key, 0, 4) !== 'auth') && ($key != 'roles') && (!in_array($key, $user_fields)) && ($value !== NULL)) {
if ((substr($key, 0, 4) !== 'auth') && ($key != 'roles') && (empty($user_fields[$key])) && ($value !== NULL)) {
$data[$key] = $value;
}
}
db_query("UPDATE {users} SET data = '%s' WHERE uid = %d", serialize($data), $user->uid);
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($array['roles']) && is_array($array['roles'])) {
......@@ -520,23 +499,6 @@ function user_is_blocked($name) {
return $deny;
}
function user_fields() {
static $fields;
if (!$fields) {
$result = db_query('SELECT * FROM {users} WHERE uid = 1');
if ($field = db_fetch_array($result)) {
$fields = array_keys($field);
}
else {
// Make sure we return the default fields at least.
$fields = array('uid', 'name', 'pass', 'mail', 'picture', 'mode', 'sort', 'threshold', 'theme', 'signature', 'created', 'access', 'login', 'status', 'timezone', 'language', 'init', 'data');
}
}
return $fields;
}
/**
* Implementation of hook_perm().
*/
......@@ -2280,7 +2242,7 @@ function user_register_submit($form, &$form_state) {
}
// The unset below is needed to prevent these form values from being saved as
// user data.
unset($form_state['values']['form_token'], $form_state['values']['submit'], $form_state['values']['op'], $form_state['values']['notify'], $form_state['values']['form_id'], $form_state['values']['affiliates'], $form_state['values']['destination']);
unset($form_state['values']['form_token'], $form_state['values']['submit'], $form_state['values']['op'], $form_state['values']['notify'], $form_state['values']['form_id'], $form_state['values']['affiliates'], $form_state['values']['destination'], $form_state['values']['form_build_id']);
$merge_data = array('pass' => $pass, 'init' => $mail, 'roles' => $roles);
if (!$admin) {
......
......@@ -270,7 +270,7 @@ function user_profile_form_validate($form, &$form_state) {
function user_profile_form_submit($form, &$form_state) {
$account = $form_state['values']['_account'];
$category = $form_state['values']['_category'];
unset($form_state['values']['_account'], $form_state['values']['op'], $form_state['values']['submit'], $form_state['values']['delete'], $form_state['values']['form_token'], $form_state['values']['form_id'], $form_state['values']['_category']);
unset($form_state['values']['_account'], $form_state['values']['op'], $form_state['values']['submit'], $form_state['values']['delete'], $form_state['values']['form_token'], $form_state['values']['form_id'], $form_state['values']['_category'], $form_state['values']['form_build_id']);
user_module_invoke('submit', $form_state['values'], $account, $category);
user_save($account, $form_state['values'], $category);
......@@ -336,7 +336,7 @@ function user_edit_validate($form, &$form_state) {
function user_edit_submit($form, &$form_state) {
$account = $form_state['values']['_account'];
$category = $form_state['values']['_category'];
unset($form_state['values']['_account'], $form_state['values']['op'], $form_state['values']['submit'], $form_state['values']['delete'], $form_state['values']['form_token'], $form_state['values']['form_id'], $form_state['values']['_category']);
unset($form_state['values']['_account'], $form_state['values']['op'], $form_state['values']['submit'], $form_state['values']['delete'], $form_state['values']['form_token'], $form_state['values']['form_id'], $form_state['values']['_category'], $form_state['values']['form_build_id']);
user_module_invoke('submit', $form_state['values'], $account, $category);
user_save($account, $form_state['values'], $category);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment