CS71 – Ass1 – Finance – Part 4 – Login Register Forgotten password

I am doing the Harvards building dynamic websites called CS-75 (also could be called E-75), because someone told me about it and I just thought might as well, it is all learning 🙂 even if allot of it you may already know.

Since most of the work is done in the class files, from the previous post then we just use the classes to only have basic php pages for the user. So the login page is just, which also has a check for if the user is already logged in and goto the viewdetails page, or if the user requests to logout then logout the user, the main page is just logging the user in.

<?php
	require("functions_start.php");
 
	if (isset($_REQUEST["username"]) && isset($_REQUEST["password"]))
	{
		$error = $theUser->LoginCheck($_REQUEST["username"], $_REQUEST["password"]);
	}
 
	if (isset($_REQUEST["logout"]))
		$theUser->Logout();
 
	if (isset($_SESSION["authenticated"]) && $_SESSION["authenticated"]== true)
	{
		header("Location: /viewdetails.php");
		exit;
	}
 
	HTMLHeader("Login to the stocks!",false);
 
	if (isset($error))
	{
		if ($error==false)
			echo "<div>Not able to login, please try again</div>";
	}
	if (isset($_REQUEST["logout"])) 
		echo "Thanks for using the site, you are logged out!";
?>
<!-- taken from http://www.html.it/articoli/nifty/index.html-->
<div id="login">
<b class="rtop">
  <b class="r1"></b> <b class="r2"></b> <b class="r3"></b> <b class="r4"></b>
</b>
<form method="post" action="<?php echo $_SERVER["PHP_SELF"]; ?>" onsubmit="">
Login
<p>
Username : <input type="text" name="username" id="username" value="<?php echo $_REQUEST["username"]; ?>"/>
</p>
<p>
Password : <input type="password" name="password" id="password"/>
</p>
<p>
<input type="submit"/>
</p>
<p id="right">
<a href="register.php">Register</a> here.
</p>
</form>
<b class="rbottom">
  <b class="r4"></b> <b class="r3"></b> <b class="r2"></b> <b class="r1"></b>
</b>
</div>
<?php
	HTMLFooter();
?>

Here is the register page, where I send the request to the users class and utilize the return value to display either a message of check your emails (or in this case it will be a link on the top of the page) or display a error to the user depending on what could happen, e.g. not a valid valid/password(if the user turned off javascript checking) and also if there is already that email address present, the next check checks for the valid ID value that is sent to the user to validate there email.

<?php
	require("functions_start.php");
 
	if (isset($_REQUEST["username"]) && isset($_REQUEST["password"]))
	{
		$error = $theUser->RegisterUser($_REQUEST["username"], $_REQUEST["password"]);
		if ($error == -2)
			$notValidPassword = true;
		else if ($error == -1)
			$notValidEmail = true;
		else if ($error == 0)
			$emailAddressAlreadyPresent = true;
		else if ($error == 1)
			$checkEmails = true;
	}
 
	if (isset($_REQUEST["validid"]) && isset($_REQUEST["uid"]))
	{
		$error = $theUser->CheckUserGUID($_REQUEST["uid"], $_REQUEST["validid"]);
		if ($error == false)
			$userInvalid = true;
		else if ($error == true)
		{			
			$theUser->LoginCheck($_REQUEST["uid"],"",true);
			header("Location: /viewdetails.php");
			exit;
		}
	}
 
	if (isset($_SESSION["authenticated"]) && $_SESSION["authenticated"]== true)
	{
		header("Location: /viewdetails.php");
		exit;
	}
 
	HTMLHeader("Register",false);
 
	if (isset($error))
	{
		if (isset($checkEmails))
			echo "<div>Please check your emails to validate your email address</div>";
		else if (isset($notValidPassword))
			echo "<div id=\"error\">Not a valid password!, please enter one that is 6 characters and has at least 1 aphla/numeric</div>";
		else if (isset($emailAddressAlreadyPresent))
			echo "<div id=\"error\">Please use the forgotten password recovery,  already email address registered</div>";
		else if (isset($notValidEmail))
			echo "<div id=\"error\">Not a valid email address</div>";
		else if (isset($userInvalid))
			echo "<div id=\"error\">Does not validate correctly, please contact the system admin</div>";
	}
?>
<!-- taken from http://www.html.it/articoli/nifty/index.html-->
<div id="login">
<b class="rtop">
  <b class="r1"></b> <b class="r2"></b> <b class="r3"></b> <b class="r4"></b>
</b>
<form method="post" action="<?php echo $_SERVER["PHP_SELF"]; ?>" onsubmit="return CheckRegister()">
Register <p>
Username : <input type="text" name="username" id="username" value="<?php echo $_REQUEST["username"]; ?>"/>
(valid email address)</p>
<p>
Password : <input type="password" name="password" id="password"/>
(Has to be at least 6 characters and with 1 numeric and aplha character</p>
<p>
<input type="submit"/>
</p>
</form>
<b class="rbottom">
  <b class="r4"></b> <b class="r3"></b> <b class="r2"></b> <b class="r1"></b>
</b>
</div>
<?php
	HTMLFooter();
?>

Here is the last part, that will allow the user to enter there email to be able to get a link to enable them to change there password.

<?php
	require("functions_start.php");
 
	if (isset($_REQUEST["username"]) )
	{
		$error = $theUser->ForgottenUser($_REQUEST["username"]);
		if ($error)
			$checkEmails = true;
		else 
			$notValidEmail = true;
	}
 
	if (isset($_REQUEST["validid"]) && isset($_REQUEST["uid"]))
	{
		$error = $theUser->CheckUserGUID($_REQUEST["uid"], $_REQUEST["validid"]);
		if ($error == false)
			$userInvalid = true;
		else if ($error == true)
		{			
			$theUser->LoginCheck($_REQUEST["uid"],"",true);
			header("Location: /changepassword.php");
			exit;
		}
	}
 
	if (isset($_SESSION["authenticated"]) && $_SESSION["authenticated"]== true)
	{
		header("Location: /viewdetails.php");
		exit;
	}
 
	HTMLHeader("Forgotten password",false);
 
	if (isset($error))
	{
		if (isset($checkEmails))
			echo "<div>Please check your emails to validate your email address</div>";
		else if (isset($notValidEmail))
			echo "<div id=\"error\">Cannot find that email address</div>";
	}
?>
<!-- taken from http://www.html.it/articoli/nifty/index.html-->
<div id="login">
<b class="rtop">
  <b class="r1"></b> <b class="r2"></b> <b class="r3"></b> <b class="r4"></b>
</b>
<form method="post" action="<?php echo $_SERVER["PHP_SELF"]; ?>" onsubmit="return CheckRegister(true)">
Forgotten password, please enter your username <p>
Username : <input type="text" name="username" id="username" value="<?php echo $_REQUEST["username"]; ?>"/>
(valid email address)</p>
<input type="submit"/>
</p>
</form>
<b class="rbottom">
  <b class="r4"></b> <b class="r3"></b> <b class="r2"></b> <b class="r1"></b>
</b>
</div>
<?php
	HTMLFooter();
?>

As you can see the actual pages are really simple because most of the work is done in the class files

CS71 – Ass1 – Finance – Part 3 – javascript and common php page

I am doing the Harvards building dynamic websites called CS-75 (also could be called E-75), because someone told me about it and I just thought might as well, it is all learning 🙂 even if allot of it you may already know.

Before any of the actual pages start, they will all call this php file so that it will build up the classes and connect to the database, so to start with need to pull in there classes and also start the session. The two functions are the HTML header and footer parts of each page, so that do not have to alter every page to just add in another style as such, the last part is when we are creating the objects for the database/users/stocks.

<?php
	require("database.php");
	require("getstocks.php");
	require("user.php");
 
	session_start();
 
	function HTMLHeader($titleTag,$loggedIn = true)
	{
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
<html>
  <head>
    <title><?php echo $titleTag;?></title>
	<link href="style.css" rel="stylesheet" type="text/css"/>
	<script src="ass1.js" language="javascript"></script>
  </head>
 <body>
<div id="mainpage"> 
	<ul id="menuoptions">
	<?php if ($loggedIn) { ?>
	<li><a href="viewdetails.php">View your stock</a></li>
	<li><a href="buystock.php">Buy stock</a></li>
	<li><a href="index.php?logout=true">Logout</a></li>
	<li><a href="changepassword.php">Change password</a></li>
	<?php } else { ?>
	<li><a href="index.php">Login</a></li>
	<li><a href="register.php">Register</a></li>
	<li><a href="forgotten.php">Forgotten password</a></li>
	<?php } ?>
	</ul>
<div id ="container">
<?php
	}
 
	function HTMLFooter()
	{
?>
</div>
</div>
</body>
</html>
<?php
	}
 
	$db= new mysqlConnect("localhost", "username","password", "cs75_project1");
	$theStock = new StocksDetails();
	$theUser = new User();
?>

Because in the HTMLHeader function I am linking to the ass1.js file, which is the javascript code that will allow for a better user experience because we can do some input tests before sending to the server.

This is the function that checks the users input when they are trying to sell some of the stock that they have

function checkSell()
{
	var formElem = document.forms[0];
	var elemsEmpty =0;
	for (var i = 0; i < formElem.length; i++)
	{
		var elem = formElem[i];
		if (elem.type == "checkbox" && elem.checked)
			elemsEmpty++;
	}
	if (elemsEmpty ==0)
	{
		alert("Please select a item to sell");
		return false;
	}
	return true;
}

When the user is on the buying stock page, it would be good to make sure that the value is a integer value before the user actually sends the request to the server, it will also check to make sure that there is a symbol to search for, saves on just clicking on the submit without any data.

function CheckBuy()
{
	var symbol = document.getElementById("searchSymbol");
	var amount = document.getElementById("AMOUNT");
 
	if (symbol.value.length < 3 && amount == null)
	{
		alert("Please insert a search symbol");
		symbol.focus();
		return false;
	}
 
	if (amount != null && amount.length >0)
	{
		if (isNaN(amount) && amount.value > 0)
		{
			if (!document.getElementById("BUYME").checked)
			{
				alert("Please select the tick box next to the amount");
				return false;
			}	
		}
		else 
		{
			alert("Please enter a valid amount to buy");
			document.getElementById("AMOUNT").focus();
			return false;
		}
	}
	return true;
}

This function actually checks the users input on the amount of stock to buy and making sure that it is only numeric values.

// only allow integer values within the box
function CheckKey(boxToCheck)
{
	var boxValue="";
	for (i = 0; i < boxToCheck.value.length; i++)
	{
		if (!isNaN(boxToCheck.value[i]))
			boxValue += boxToCheck.value[i];
	}
	boxToCheck.value = boxValue;
}

This function, checks to make sure that the registration screen has a valid email address (does another check on the server if the user turns off javascript), and also checks the password for the correct format.

function CheckRegister(justUsername)
{
	var username = document.getElementById("username");
	var password = document.getElementById("password");
	if (username.value.match(/^([a-zA-Z0-9_.-])+@([a-zA-Z0-9_.-])+\.([a-zA-Z])+([a-zA-Z])+/)) {
		if (justUsername)
			return true;
		return CheckPassword(password);
    }else{   
		alert("Incorrect email format"); 
    }
	return false;
}

This the actual function that will check the password is in the correct format, e.g. 1+ numeric/alpha characters. and more than 6 in length.

function CheckPassword(password)
{
	if (password.value.length >=6) {
		var addLet = 0;
		for (var i =0; i < password.value.length; i++) {
			if (isNaN(password.value[i]))
				addLet++;
		}
		if (addLet == password.value.length)
		{
			alert("Please enter a password that contains at least 1 aplha/numeric character");
		} else
			return true;
	} else
		alert("Please enter a password that is at least 6 characters long");
	return false;
}

Here on the change password, I am making sure that the first password conforms to the above function check and also that the two passwords are the same in value.

function CheckChangePasswords()
{
	if (CheckPassword(document.getElementById("password1"))) 
	{
		if (document.getElementById("password1").value == document.getElementById("password2").value)
			return true;
		else
			alert("Passwords do not match");
	}
	return false;
}

Next is the actual php pages that the user will interact with.

CS75 – Ass1 – Finance

I am doing the Harvards building dynamic websites called CS-75 (also could be called E-75), because someone told me about it and I just thought might as well, it is all learning 🙂 even if allot of it you may already know.

I have done the previous project here Three aces, where it was to develop a menu system using simpleXML.

This project is to communicate with the Yahoo finance website, and bring back details of stock prices for different companies, and also to keep track of the users purchases and also allow them to sell the stock that they have purchased, I have attached the PDF of the assignment if you want more information about the assignment.

Since it is a bit bigger than the previous project I am going to split each part into a different post, so this one is going to be about the database setup. So to start with here is the details of the database tables, I have included the full source code and sql file to create the database within MySQL, here is what phpmyadmin export created, I did not include the trigger on the users table that was creating a UUID, because some versions of MySQL does not support that syntax

--
-- Table structure for table `stocks`
--
 
DROP TABLE IF EXISTS `stocks`;
CREATE TABLE IF NOT EXISTS `stocks` (
  `UID` INT(30) UNSIGNED NOT NULL DEFAULT '0' COMMENT 'Link to users table',
  `SYMBOL` VARCHAR(20) DEFAULT NULL,
  `Quantity` INT(20) DEFAULT NULL,
  KEY `UID` (`UID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
 
--
-- Dumping data for table `stocks`
--
 
-- --------------------------------------------------------
 
--
-- Table structure for table `users`
--
 
DROP TABLE IF EXISTS `users`;
CREATE TABLE IF NOT EXISTS `users` (
  `UID` INT(30) UNSIGNED NOT NULL AUTO_INCREMENT,
  `username` VARCHAR(255) NOT NULL,
  `pass` BLOB NOT NULL,
  `cash` DECIMAL(10,2) NOT NULL DEFAULT '10000.00' COMMENT 'the default value is the free gift',
  `GUID` CHAR(36) NOT NULL COMMENT 'Use this string to validate the user, if the value is 0, then validated',
  PRIMARY KEY (`UID`),
  UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=11 ;
 
--
-- Constraints for table `stocks`
--
ALTER TABLE `stocks`
  ADD CONSTRAINT `stocks_ibfk_1` FOREIGN KEY (`UID`) REFERENCES `users` (`UID`) ON DELETE CASCADE;

If you are running the latest version of MySQL then you can have the trigger on the database table :), and just need to take out the uncomment code within the users.php file!.

-- Triggers `users`
--
DROP TRIGGER IF EXISTS `users_insert`;
DELIMITER //
CREATE TRIGGER `users_insert` BEFORE INSERT ON `users`
 FOR EACH ROW BEGIN
SET NEW.guid = uuid();
END
//
DELIMITER ;

Here is my database.php file where I connect to the database and also perform some of the required actions, like queries etc and also since I am using the InnoDB MySQL engine, then I can use the START TRANSACTION which will allow the ROLLBACK function within mysql so that if any of the SQL between them do not work, then I can roll back to where I was before I started that transaction, or commit the sql to the database.

<?php
	class mysqlConnect
	{
		public function __construct($connectionHost, $connectionUser, $connectionPW, $connectionDB)
		{
			if (($this->theConnection = 
				mysql_connect($connectionHost, $connectionUser, $connectionPW)) === FALSE)
				die("Problems - connection to the database, please check");
			if (mysql_select_db($connectionDB, $this->theConnection) === FALSE)
				die("Problems - connected to database engine, but not the database");
		}
 
		public function __destruct()
		{
			if ($this->theConnection)
				mysql_close($this->theConnection);
		}
 
		public function query($stringQuery)
		{
			$q = mysql_real_escape_string($stringQuery);
			return mysql_query($stringQuery);
		}
 
		// if the database supports the result of returning the number of rows effected with the last call.
		public function rowsNumber($connection)
		{
			return mysql_num_rows($connection);
		}
 
		public function rowsAffected()
		{
			return mysql_affected_rows();
		}
 
		public function arrayResults($connection)
		{
			return mysql_fetch_assoc($connection);
		}
 
		public function freeResult($connection)
		{
			mysql_free_result($connection);
		}
 
		public function startTransaction()
		{
			$this->query("START TRANSACTION");
		}
 
		public function commitTransaction()
		{
			$this->query("COMMIT");
		}
 
		public function rollbackTransaction()
		{
			$this->query("ROLLBACK");
		}
 
		private $theConnection;
	};
?>

Shall does the classes next of the project and then the actual php files that do the user interaction.