Index: drupal-6.x-dev/install.php =================================================================== RCS file: /cvs/drupal/drupal/install.php,v retrieving revision 1.85 diff -u -p -r1.85 install.php --- drupal-6.x-dev/install.php 31 Oct 2007 16:14:15 -0000 1.85 +++ drupal-6.x-dev/install.php 3 Nov 2007 04:18:17 -0000 @@ -887,7 +887,14 @@ function install_configure_form() { $form['admin_account']['account']['name'] = array('#type' => 'textfield', '#title' => st('Username'), '#maxlength' => USERNAME_MAX_LENGTH, - '#description' => st('Spaces are allowed; punctuation is not allowed except for periods, hyphens, and underscores.'), + '#description' => st('Lower case characters only. Only syntax with vaild e-mail local-part or complete e-mail address are allowed. See RFC 2822 for details.', array('@rfc' => 'http://tools.ietf.org/html/rfc2822')), + '#required' => TRUE, + '#weight' => -15, + ); + $form['admin_account']['account']['fullname'] = array('#type' => 'textfield', + '#title' => st('Full name'), + '#maxlength' => FULLNAME_MAX_LENGTH, + '#description' => st('Specify your first and last name.'), '#required' => TRUE, '#weight' => -10, ); @@ -961,6 +968,9 @@ function install_configure_form_validate if ($error = user_validate_name($form_state['values']['account']['name'])) { form_error($form['admin_account']['account']['name'], $error); } + if ($error = user_validate_fullname($form_state['values']['account']['fullname'])) { + form_error($form['admin_account']['account']['fullname'], $error); + } if ($error = user_validate_mail($form_state['values']['account']['mail'])) { form_error($form['admin_account']['account']['mail'], $error); } Index: drupal-6.x-dev/modules/comment/comment.module =================================================================== RCS file: /cvs/drupal/drupal/modules/comment/comment.module,v retrieving revision 1.597 diff -u -p -r1.597 comment.module --- drupal-6.x-dev/modules/comment/comment.module 31 Oct 2007 17:50:47 -0000 1.597 +++ drupal-6.x-dev/modules/comment/comment.module 3 Nov 2007 04:18:17 -0000 @@ -1132,7 +1132,7 @@ function comment_validate($edit) { $node = node_load($edit['nid']); if (variable_get('comment_anonymous_'. $node->type, COMMENT_ANONYMOUS_MAYNOT_CONTACT) > COMMENT_ANONYMOUS_MAYNOT_CONTACT) { if ($edit['name']) { - $taken = db_result(db_query("SELECT COUNT(uid) FROM {users} WHERE LOWER(name) = '%s'", $edit['name'])); + $taken = db_result(db_query("SELECT COUNT(uid) FROM {users} WHERE name = '%s'", strtolower($edit['name']))); if ($taken != 0) { form_set_error('name', t('The name you used belongs to a registered user.')); Index: drupal-6.x-dev/modules/system/system.install =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.install,v retrieving revision 1.167 diff -u -p -r1.167 system.install --- drupal-6.x-dev/modules/system/system.install 25 Oct 2007 20:41:16 -0000 1.167 +++ drupal-6.x-dev/modules/system/system.install 3 Nov 2007 04:18:19 -0000 @@ -251,7 +251,7 @@ function system_install() { // presumed to be a serialized array. Install will change uid 1 immediately // anyways. So we insert the superuser here, the uid is 2 here for now, but // very soon it will be changed to 1. - db_query("INSERT INTO {users} (name, mail, created, data) VALUES('%s', '%s', %d, '%s')", 'placeholder-for-uid-1', 'placeholder-for-uid-1', time(), serialize(array())); + db_query("INSERT INTO {users} (name, fullname, mail, created, data) VALUES('%s', '%s', '%s', %d, '%s')", 'placeholder-for-uid-1', 'placeholder-for-uid-1', 'placeholder-for-uid-1', time(), serialize(array())); // This sets the above two users to 1 -1 = 0 (anonymous) and // 2- 1 = 1 (superuser). We skip uid 2 but that's not a big problem. db_query('UPDATE {users} SET uid = uid - 1'); Index: drupal-6.x-dev/modules/user/user.install =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.install,v retrieving revision 1.2 diff -u -p -r1.2 user.install --- drupal-6.x-dev/modules/user/user.install 10 Oct 2007 11:39:35 -0000 1.2 +++ drupal-6.x-dev/modules/user/user.install 3 Nov 2007 04:18:19 -0000 @@ -142,6 +142,13 @@ function user_schema() { 'default' => '', 'description' => t('Unique user name.'), ), + 'fullname' => array( + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'default' => '', + 'description' => t('User full name.'), + ), 'pass' => array( 'type' => 'varchar', 'length' => 32, @@ -282,3 +289,18 @@ function user_schema() { return $schema; } +/** + * Add a fullname field to users table, folk from name, and convert all stored + * name to lower case. + * + * NOTE: We ONLY convert name to lower during update, but not handle the + * convert of invalid characters, or else user will not able to login + * again. + */ +function user_update_6000() { + $ret = array(); + db_add_field($ret, 'users', 'fullname', array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '', 'description' => t('User full name.'))); + $ret[] = update_sql('UPDATE {users} SET fullname = name'); + $ret[] = update_sql('UPDATE {users} SET name = LOWER(name)'); + return $ret; +} Index: drupal-6.x-dev/modules/user/user.module =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.module,v retrieving revision 1.857 diff -u -p -r1.857 user.module --- drupal-6.x-dev/modules/user/user.module 27 Oct 2007 14:01:12 -0000 1.857 +++ drupal-6.x-dev/modules/user/user.module 3 Nov 2007 04:18:19 -0000 @@ -7,6 +7,7 @@ */ define('USERNAME_MAX_LENGTH', 60); +define('FULLNAME_MAX_LENGTH', 255); define('EMAIL_MAX_LENGTH', 64); /** @@ -144,17 +145,23 @@ function user_load($array = array()) { } foreach ($array as $key => $value) { - if ($key == 'uid' || $key == 'status') { - $query[] = "$key = %d"; - $params[] = $value; - } - else if ($key == 'pass') { - $query[] = "pass = '%s'"; - $params[] = md5($value); - } - else { - $query[]= "LOWER($key) = LOWER('%s')"; - $params[] = $value; + switch ($key) { + case 'uid': + case 'status': + $query[] = "$key = %d"; + $params[] = $value; + break; + case 'pass': + $query[] = "pass = '%s'"; + $params[] = md5($value); + break; + case 'name': + $query[]= "$key = '%s'"; + $params[] = strtolower($value); + break; + default: + $query[]= "LOWER($key) = LOWER('%s')"; + $params[] = $value; } } $result = db_query('SELECT * FROM {users} u WHERE '. implode(' AND ', $query), $params); @@ -204,6 +211,10 @@ function user_save($account, $array = ar $query = ''; $data = unserialize(db_result(db_query('SELECT data FROM {users} WHERE uid = %d', $account->uid))); foreach ($array as $key => $value) { + // Always format username as lower case. + if ($key == 'name') { + $value = strtolower($value); + } if ($key == 'pass' && !empty($value)) { $query .= "$key = '%s', "; $v[] = md5($value); @@ -287,6 +298,11 @@ function user_save($account, $array = ar $values[] = $value; $s[] = "%d"; break; + case 'name': + $fields[] = $key; + $values[] = strtolower($value); + $s[] = "'%s'"; + break; default: if (substr($key, 0, 4) !== 'auth' && in_array($key, $user_fields)) { $fields[] = $key; @@ -345,27 +361,21 @@ function user_save($account, $array = ar * Verify the syntax of the given name. */ function user_validate_name($name) { + $user = '[a-zA-Z0-9_\-\.\+\^!#\$%&*+\/\=\?\`\|\{\}~\']+'; + $domain = '(?:(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.?)+'; if (!strlen($name)) return t('You must enter a username.'); - if (substr($name, 0, 1) == ' ') return t('The username cannot begin with a space.'); - if (substr($name, -1) == ' ') return t('The username cannot end with a space.'); - if (strpos($name, ' ') !== FALSE) return t('The username cannot contain multiple spaces in a row.'); - if (ereg("[^\x80-\xF7 [:alnum:]@_.-]", $name)) return t('The username contains an illegal character.'); - if (preg_match('/[\x{80}-\x{A0}'. // Non-printable ISO-8859-1 + NBSP - '\x{AD}'. // Soft-hyphen - '\x{2000}-\x{200F}'. // Various space characters - '\x{2028}-\x{202F}'. // Bidirectional text overrides - '\x{205F}-\x{206F}'. // Various text hinting characters - '\x{FEFF}'. // Byte order mark - '\x{FF01}-\x{FF60}'. // Full-width latin - '\x{FFF9}-\x{FFFD}'. // Replacement characters - '\x{0}]/u', // NULL byte - $name)) { - return t('The username contains an illegal character.'); - } - if (strpos($name, '@') !== FALSE && !eregi('@([0-9a-z](-?[0-9a-z])*.)+[a-z]{2}([zmuvtg]|fo|me)?$', $name)) return t('The username is not a valid authentication ID.'); + if (!preg_match("/^($user|$user@$domain)$/", $name)) return t('The username %name contains an illegal character.', array('%name' => $name)); if (strlen($name) > USERNAME_MAX_LENGTH) return t('The username %name is too long: it must be %max characters or less.', array('%name' => $name, '%max' => USERNAME_MAX_LENGTH)); } +/** + * Verify the syntax of the given full name. + */ +function user_validate_fullname($fullname) { + if (!strlen($fullname)) return t('You must enter a full name.'); + if (strlen($fullname) > FULLNAME_MAX_LENGTH) return t('The full name %fullname is too long: it must be %max characters or less.', array('%fullname' => $name, '%max' => FULLNAME_MAX_LENGTH)); +} + function user_validate_mail($mail) { if (!$mail) return t('You must enter an e-mail address.'); if (!valid_email_address($mail)) { @@ -471,7 +481,7 @@ function user_access($string, $account = * @return boolean TRUE for blocked users, FALSE for active */ function user_is_blocked($name) { - $deny = db_fetch_object(db_query("SELECT name FROM {users} WHERE status = 0 AND name = LOWER('%s')", $name)); + $deny = db_fetch_object(db_query("SELECT name FROM {users} WHERE status = 0 AND name = '%s'", $name)); return $deny; } @@ -528,13 +538,13 @@ function user_search($op = 'search', $ke $keys = preg_replace('!\*+!', '%', $keys); if (user_access('administer users')) { // Administrators can also search in the otherwise private email field. - $result = pager_query("SELECT name, uid, mail FROM {users} WHERE LOWER(name) LIKE LOWER('%%%s%%') OR LOWER(mail) LIKE LOWER('%%%s%%')", 15, 0, NULL, $keys, $keys); + $result = pager_query("SELECT name, uid, mail FROM {users} WHERE name LIKE '%%%s%%' OR mail LIKE '%%%s%%'", 15, 0, NULL, strtolower($keys), strtolower($keys)); while ($account = db_fetch_object($result)) { $find[] = array('title' => $account->name .' ('. $account->mail .')', 'link' => url('user/'. $account->uid, array('absolute' => TRUE))); } } else { - $result = pager_query("SELECT name, uid FROM {users} WHERE LOWER(name) LIKE LOWER('%%%s%%')", 15, 0, NULL, $keys); + $result = pager_query("SELECT name, uid FROM {users} WHERE name LIKE '%%%s%%'", 15, 0, NULL, strtolower($keys)); while ($account = db_fetch_object($result)) { $find[] = array('title' => $account->name, 'link' => url('user/'. $account->uid, array('absolute' => TRUE))); } @@ -688,7 +698,7 @@ function user_block($op = 'list', $delta case 1: if ($menu = menu_tree()) { - $block['subject'] = $user->uid ? check_plain($user->name) : t('Navigation'); + $block['subject'] = $user->uid ? check_plain($user->fullname) : t('Navigation'); $block['content'] = $menu; } return $block; @@ -1283,10 +1293,17 @@ function user_edit_form(&$form_state, $u '#title' => t('Username'), '#default_value' => $edit['name'], '#maxlength' => USERNAME_MAX_LENGTH, - '#description' => t('Your preferred username; punctuation is not allowed except for periods, hyphens, and underscores.'), + '#description' => t('Your preferred username. Lower case characters only. Only syntax with vaild e-mail local-part or complete e-mail address are allowed. See RFC 2822 for details.', array('@rfc' => 'http://tools.ietf.org/html/rfc2822')), '#required' => TRUE, ); } + $form['account']['fullname'] = array('#type' => 'textfield', + '#title' => t('Full name'), + '#default_value' => $edit['fullname'], + '#maxlength' => USERNAME_MAX_LENGTH, + '#description' => t('Specify your first and last name.'), + '#required' => TRUE, + ); $form['account']['mail'] = array('#type' => 'textfield', '#title' => t('E-mail address'), '#default_value' => $edit['mail'], @@ -1361,7 +1378,7 @@ function _user_edit_validate($uid, &$edi if ($error = user_validate_name($edit['name'])) { form_set_error('name', $error); } - else if (db_result(db_query("SELECT COUNT(*) FROM {users} WHERE uid != %d AND LOWER(name) = LOWER('%s')", $uid, $edit['name'])) > 0) { + else if (db_result(db_query("SELECT COUNT(*) FROM {users} WHERE uid != %d AND name = '%s'", $uid, strtolower($edit['name']))) > 0) { form_set_error('name', t('The name %name is already taken.', array('%name' => $edit['name']))); } else if (drupal_is_denied('user', $edit['name'])) { @@ -1369,11 +1386,16 @@ function _user_edit_validate($uid, &$edi } } + // Validate the full name: + if ($error = user_validate_fullname($edit['fullname'])) { + form_set_error('fullname', $error); + } + // Validate the e-mail address: if ($error = user_validate_mail($edit['mail'])) { form_set_error('mail', $error); } - else if (db_result(db_query("SELECT COUNT(*) FROM {users} WHERE uid != %d AND LOWER(mail) = LOWER('%s')", $uid, $edit['mail'])) > 0) { + else if (db_result(db_query("SELECT COUNT(*) FROM {users} WHERE uid != %d AND mail = '%s'", $uid, strtolower($edit['mail']))) > 0) { form_set_error('mail', t('The e-mail address %email is already registered. Have you forgotten your password?', array('%email' => $edit['mail'], '@password' => url('user/password')))); } else if (drupal_is_denied('mail', $edit['mail'])) { @@ -2196,7 +2218,7 @@ function user_register() { // Remove form_group around default fields if there are no other groups. if (!$extra) { - foreach (array('name', 'mail', 'pass', 'status', 'roles', 'notify') as $key) { + foreach (array('name', 'fullname', 'mail', 'pass', 'status', 'roles', 'notify') as $key) { if (isset($form['account'][$key])) { $form[$key] = $form['account'][$key]; } Index: drupal-6.x-dev/modules/user/user.pages.inc =================================================================== RCS file: /cvs/drupal/drupal/modules/user/user.pages.inc,v retrieving revision 1.3 diff -u -p -r1.3 user.pages.inc --- drupal-6.x-dev/modules/user/user.pages.inc 27 Oct 2007 14:01:12 -0000 1.3 +++ drupal-6.x-dev/modules/user/user.pages.inc 3 Nov 2007 04:18:20 -0000 @@ -12,7 +12,7 @@ function user_autocomplete($string = '') { $matches = array(); if ($string) { - $result = db_query_range("SELECT name FROM {users} WHERE LOWER(name) LIKE LOWER('%s%%')", $string, 0, 10); + $result = db_query_range("SELECT name FROM {users} WHERE name LIKE '%s%%'", strtolower($string), 0, 10); while ($user = db_fetch_object($result)) { $matches[$user->name] = check_plain($user->name); } @@ -150,7 +150,7 @@ function user_logout() { * Menu callback; Displays a user or user profile page. */ function user_view($account) { - drupal_set_title(check_plain($account->name)); + drupal_set_title(check_plain($account->fullname)); // Retrieve all profile fields and attach to $account->content. user_build_content($account); /** @@ -222,7 +222,7 @@ function template_preprocess_user_profil * @see user_edit_submit(). */ function user_edit($account, $category = 'account') { - drupal_set_title(check_plain($account->name)); + drupal_set_title(check_plain($account->fullname)); return drupal_get_form('user_profile_form', $account, $category); }