sorry for being late, i though i would have had more time the other night, and i must admit that this was a little more involved than i thought it was going to be, but nevertheless...
im thinking the easiest way to add this feature to the script would be to edit the function that checks the database to match a username against what the user has submitted. we should be able to amend that so if the function fails to find a matching username in the database, it then checks to see if it can find a matching email address.
we will start with
database.php and the
confirmUserPass function. look for the following code in that function (should start around line 57):
- Code:
/* Verify that user is in database */
$q = "SELECT password FROM ".TBL_USERS." WHERE username = '$username'";
$result = mysql_query($q, $this->connection);
if(!$result || (mysql_numrows($result) < 1)){
return 1; //Indicates username failure
}
now as im sure you have guessed by now, this block of code verifies that user is in database by way of checking the users input against the usernames currently in the database. if the database is queried and mysql doesnt return any rows, the functions displays the familiar username error message. what we are looking to do is that if the query doesnt return any rows, run another query checking the users input against email addresses currently in the database. we can do this pretty simply by editing the code above to something more like this:
- Code:
/* Verify that user is in database */
$q = "SELECT password FROM ".TBL_USERS." WHERE username = '$username'";
$result = mysql_query($q, $this->connection);
if(!$result || (mysql_numrows($result) < 1)){
$q = "SELECT username, password FROM ".TBL_USERS." WHERE email = '$username'";
$result = mysql_query($q, $this->connection);
if(!$result || (mysql_numrows($result) < 1)){
return 1; //Indicates username failure
}
}
just as i said before, this new block of code looks for a username first and if that fails, then tries to look for an email address. now if both of these checks fail we will display that username error message. of course if either one of these queries returns a row, we will move on to the next step which is checking the password the user submitted against the one attached to our username or email address.
that brings us to our next step. still inside
database.php and the
confirmUserPass function look for this code (around line 73):
- Code:
/* Validate that password is correct */
if($password == $dbarray['password']){
return 0; //Success! Username and password confirmed
}
else{
return 2; //Indicates password failure
}
once again, im sure you figured out this block of code is in charge of validating that the password is correct. the only thing is that if we are logging on with an email address, we are going to need to pass the username that goes with that email on to
session.php so we need to make a small change here. since we still need to pass a value of 0 onto
session.php were gonna create a quick little array to hold both the value of 0 and the username in one place. go ahead and change the code above to:
- Code:
/* Validate that password is correct */
if($password == $dbarray['password']){
$return_array = array();
$return_array[0] = 0;
if(isset($dbarray['username'])){
// if were logging on with an email address we
// need to pass the username back to session.php
$return_array[1] = $dbarray['username'];
}
return $return_array; //Success! Username and password confirmed
}
else{
return 2; //Indicates password failure
}
this new code does pretty much exactly what the old code did except for one thing - if the password the user submitted matches the password in the database, we create an array called
$return_array whos first value is
0 which indicates the username and password were confirmed. we then check to see if
$dbarray['username'] (the username) exists, which it will if the user attempted to log on with an email address. if it does, we add a second value of
$dbarray['username'] (again, the username) to our
$return_array array (of course if the user logged on with their username
$dbarray['username'] would not exist and the code inside the conditional would not be executed). that should pretty much wrap it up for
database.php.
and so its on to
session.php to make a few final changes. inside of
session.php look for the function
login and the block of code (around line 128):
- Code:
/* Username error checking */
$field = "user"; //Use field name for username
if(!$subuser || strlen($subuser = trim($subuser)) == 0){
$form->setError($field, "* Username not entered");
}
else{
/* Check if username is not alphanumeric */
if(!eregi("^([0-9a-z])*$", $subuser)){
$form->setError($field, "* Username not alphanumeric");
}
}
once again, the comment tells you this block of code checks the username the user just submitted for errors. the only problem with this is that the second part of this check looks to make sure username is not alphanumeric. the problem? email addresses are not alphanumeric and entering one without altering the script with throw an error every time. you have two options here: you can either take the much harder, more programming correct route and edit the regular expression code to properly accept email addresses as well as usernames. or you can take the ridiculous easy route and just comment out those lines of code. since im lazy and running out of time im just gonna comment out the three lines that check this and move on. of course if you are interested in doing it the 'right way' i encourage you to do so.
- Code:
/* Username error checking */
$field = "user"; //Use field name for username
if(!$subuser || strlen($subuser = trim($subuser)) == 0){
$form->setError($field, "* Username not entered");
}
else{
/* Check if username is not alphanumeric */
# if(!eregi("^([0-9a-z])*$", $subuser)){
# $form->setError($field, "* Username not alphanumeric");
# }
}
ok so now that that is taken care of, theres one other thing we have to do. this script was never intended to use email addresses as a method for a log on so almost all the data that makes this script work correctly looks for the username. thats why we needed to pass the username back to
session.php just before. look for the following block of code in
session.php (around line 170)
- Code:
/* Username and password correct, register session variables */
$this->userinfo = $database->getUserInfo($subuser);
$this->username = $_SESSION['username'] = $this->userinfo['username'];
$this->userid = $_SESSION['userid'] = $this->generateRandID();
$this->userlevel = $this->userinfo['userlevel'];
the comment tells us that this block of code register session variables because the username and password are both correct. the only thing is that if the user logged on with their email address, this code will be incorrectly registering that email address as the username. we can fix this by changing the code above to:
- Code:
/* Username and password correct, register session variables */
if(isset($result[1])){
$this->userinfo = $database->getUserInfo($result[1]);
}
else{
$this->userinfo = $database->getUserInfo($subuser);
}
$this->username = $_SESSION['username'] = $this->userinfo['username'];
$this->userid = $_SESSION['userid'] = $this->generateRandID();
$this->userlevel = $this->userinfo['userlevel'];
one more time, this runs a check to see if
$result[1] (our username passed from
database.php in the
$return_array array) exists and if it does, we use that array value as the argument in
$database->getUserInfo. now that we have the correct value, that should pass it on to everything else that needs it and all should be good! like i said, im sure there are a bunch of different ways you could have accomplished this but this way is working for me. if you see something you arent sure about or you think something may work out better for you feel free to comment or ask questions or to just up and change whatever you want.
let me know what you think! let me know if it works for you!!