--- email_registration.module 2010-10-28 10:23:47.000000000 -0400 +++ email_registrationNew.module 2010-10-28 10:19:48.000000000 -0400 @@ -22,18 +22,9 @@ function email_registration_user($op, &$ $names = array_filter($names); if (empty($names)) { - // Default implementation of name generation + // Default implementation of name generation - use name portion of email address $namenew = preg_replace('/@.*$/', '', $edit['mail']); - // Remove unwanted characters - $namenew = preg_replace('/[^a-zA-Z0-9.-]/', '', $namenew); - - // if username generated from email record already exists, append underscore and number eg:(chris_123) - if (db_result(db_query("SELECT count(*) FROM {users} WHERE uid <> %d AND LOWER(name) = LOWER('%s')", $account->uid, $namenew)) > 0) { - // find the next number available to append to the name - $sql = "SELECT SUBSTRING_INDEX(name,'_',-1) FROM {users} WHERE name REGEXP '%s' ORDER BY CAST(SUBSTRING_INDEX(name,'_',-1) AS UNSIGNED) DESC LIMIT 1"; - $nameidx = db_result(db_query($sql, '^'. $namenew .'_[0-9]+$')); - $namenew .= '_'. ($nameidx + 1); - } + $namenew = email_registration_unique_username($namenew, $account->uid); } else { // One would expect a single implementation of the hook, but if there @@ -59,6 +50,49 @@ function email_registration_user($op, &$ } /** + * Given a starting point for a Drupal username (e.g. the name portion of an email address) return + * a legal, unique Drupal username. + * + * @param $name + * A name from which to base the final user name. May contain illegal characters; these will be stripped. + * + * @param $uid + * (optional) Uid to ignore when searching for unique user (e.g. if we update the username after the + * {users} row is inserted) + * + * @return + * A unique user name based on $name. + * + */ +function email_registration_unique_username($name, $uid = 0) { + // Strip illegal characters + $name = preg_replace('/[^\x{80}-\x{F7} a-zA-Z0-9@_.\'-]/', '', $name); + + // Strip leading and trailing spaces + $name = preg_replace('/^ +/', '', $name); + $name = preg_replace('/ +$/', '', $name); + + // Convert any other series of spaces to a single underscore + $name = preg_replace('/ +/', '_', $name); + + // If there's nothing left use a default + $name = ('' === $name) ? t('user') : $name; + + // Truncate to reasonable size + $name = (drupal_strlen($name) > (USERNAME_MAX_LENGTH - 10)) ? drupal_substr($name, 0, USERNAME_MAX_LENGTH - 11) : $name; + + // Iterate until we find a unique name + $i = 0; + do { + $newname = empty($i) ? $name : $name . '_' . $i; + $found = db_result(db_query_range("SELECT uid from {users} WHERE uid <> %d AND name = '%s'", $uid, $newname, 0, 1)); + $i++; + } while ($found); + + return $newname; +} + +/** * Implementation of hook_form_alter(). * */