Email registration is great module.
The only problem is that the auto created usernames mighr reveal the real email of a user.
For example someone with email JohnDoe@hotmail.com will be the user with the user name JohnDoe . If someone want to find and use -spam email addresses could guess that the user name of the user is the first part of the email address before the @ . Then it is easy to try different major mail services to identify the real email address. So the only think he has to do is to send mail to JohnDoe@gmail.com, JohnDoe@aol.com, JohnDoe@yahoo.com and finally JohnDoe@hotmail.com!!!!
I recomend another way to create the user name from email. My changes to email_registration.module follows .
function email_registration_user($op, &$edit, &$account, $category = NULL) {
switch ($op) {
case 'insert':
// Other modules may implement hook_email_registration_name($edit, $account)
// to generate a username (return a string to be used as the username, NULL
// to have email_registration generate it)
$names = module_invoke_all('email_registration_name', $edit, $account);
// Remove any empty entries
$names = array_filter($names);
if (empty($names)) {
// Default implementation of name generation
$namenew = preg_replace('/@.*$/', '', $edit['mail']);
//Create a new user name using the email address and a timestamp
+ $namenew = str_pad($namenew, 14, strval(time())); /// be sure that you have at least 10 characters for the new username
+ $left = left($namenew,5);
+ $right = right($namenew,5);
+ $namenew = $left.$right; //construct a user name using 5 characters from the begin and 5 characters from the end
// 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);
}
}
else {
// One would expect a single implementation of the hook, but if there
// are multiples out there use the last one
$namenew = array_pop($names);
}
// replace with generated username
db_query("UPDATE {users} SET name = '%s' WHERE uid = '%s'", $namenew, $account->uid);
$account->name = $namenew;
break;
}
return;
}
function right($value, $count){
return substr($value, ($count*-1));
}
function left($string, $count){
return substr($string, 0, $count);
}
I believe that this could help someone
Comments
Comment #1
robby.smith commentedGreat work! That is a good point about spammers being able to guess the email.
Could you please provide an email of what JohnDoe@hotmail.com will turn into with your above code?
Comment #2
aleada commentedThe code above will produce a user name JohnD64495 where the last 5 numbers will be a part of the registration form submition timestamp.
Because of the pad fill emails with less than 5 characters for example bob@hotmail.com will produce a user name bob6464495 for the same submition timestamp with the previous example. So you don't have problem either with small email prefixes.
Comment #3
robby.smith commentedThanks for the quick reply. I understand the resulting username now.
I was wondering if it would be possible to have the option to just generate a random string of numbers for the username (same as above without the first part coming from the email)? It would be great if this module offered more control over this.
examples:
1) generate username as uid
2) generate username as random string of numbers
3) generate username starting with number x (ie 000001) and increment by 1 for each new user
Many thanks!
Comment #4
aleada commentedYou can do whatever you want. The only you have to do is to fill the $namenew variable using your prefered value (timestamp,uid,sequence).
If you want to have a sequence for usernames create a table with one column containing numeric data , and in every registration perform a select / update on this table-field or insert with return value.
Comment #5
robby.smith commentedI see now where that is done in your code above. Thanks for the explanation!
Comment #6
R-Man commentedHi there. I'm quite a noob here.
How can i generate username as random string of numbers using the above code.
Thanx in advance..
Comment #7
aleada commentedHi R-Man,
No problem. The code you have to modify with your needs is the part of the code bellow.....
//Create a new user name using the email address and a timestamp
+ $namenew = str_pad($namenew, 14, strval(time())); /// be sure that you have at least 10 characters for the new username
+ $left = left($namenew,5);
+ $right = right($namenew,5);
+ $namenew = $left.$right; //construct a user name using 5 characters from the begin and 5 characters from the end
you can modify the $namenew with a timestamp etc.
Comment #8
R-Man commentedOk..now, i'm trying to get the username to be generate like "ID21ABC" , "ID22ABC", "ID23ABC" and so on.....
I've tried the code below but doen't work.
=============
// 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,'ID',-1,'ABC') FROM {users} WHERE name REGEXP '%s' ORDER BY CAST(SUBSTRING_INDEX(name,'ID',-1,'ABC') AS
UNSIGNED) DESC LIMIT 1";
$nameidx = db_result(db_query($sql, '^'. $namenew .'ID[0-9]+$ABC'));
$namenew .= 'ID'. ($nameidx + 1). 'ABC';
}
=============
Comment #9
aleada commentedWhat is the error????
Comment #10
gregglesI think this is a known issue and should just be marked as "by design."