CS71 – Ass1 – Finance – Part 5 – View users details – buy stock – change 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.

As from the previous post, most of this page is in similar in nature it is just displaying data to the user that was built up from the classes files.

So to buy some stock, what this page will do is wait for the user to type in a stock symbol and then use the stock class to get the data back from that symbol and then have another input that will allow the user to buy some of that stock, also if the user clicks on the link it will display at the bottom of the page new items about the stock itself.

 
<?php
	require("functions_start.php");
 
	global $theStock;
 
	if (!isset($_SESSION["authenticated"]) || $_SESSION["authenticated"]== false)
	{
		header("Location: /index.php");
		exit;
	}
 
	// of course the product price may change from searching to buying, depending on the time period so need to pull back 
	// the new value, just incase.
	if (isset($_REQUEST["buyme"]))
	{
		$stockID = strtoupper($_REQUEST["STOCK"]);
		$stockAmount = $_REQUEST["AMOUNT"];
		$stockPurchased = $theStock->BuyStock($_SESSION["username"], $stockID, $stockAmount);
	}
 
	if (isset($_REQUEST["searchSymbol"]))
	{
		if (strlen($_REQUEST["searchSymbol"]) >=3)
			$result = $theStock->GetStocksFromYahoo(strtoupper($_REQUEST["searchSymbol"]));
	}
 
	HTMLHeader("Buy some stock, search and buy");
 
	if (isset ($stockPurchased)) {
		echo "<p class=\"details\">";
		if ($stockPurchased >0 )
			echo "Stock was purchased ($stockID amount of $StockAmount total price of $stockPurchased each price was ". number_format($stockPurchased / $stockAmount,2).")"; 
		else
			echo "Problem with purchasing the stock, please email the error above to the support team";
		echo "</p>";
	}
?>
<form action="<?php echo $_SERVER["PHP_SELF"]; ?>" method="post" onsubmit="return CheckBuy()"/>
<?php
if (isset($result)) { 
  if ($result > 0) {
	echo "<h2>{$_REQUEST["searchSymbol"]}</h2>";
    echo "The price of {$_REQUEST["searchSymbol"]} is $result, do you want to buy ?<br/>Please enter how many and tick the box.<br/>";
	echo "<input type=\"text\" name=\"AMOUNT\" id=\"AMOUNT\" onkeyup=\"javascript:CheckKey(this)\"/>";
	echo "<input type=\"hidden\" name=\"STOCK\" value=\"{$_REQUEST["searchSymbol"]}\"/>";
	echo "<input type=\"checkbox\" name=\"buyme\" id=\"BUYME\"/>";
	echo "<input type=\"submit\" value=\"Submit\"/>";
	echo "<p><b>Or search for another stock</b></p>";
 }
else
    echo "<h2>Not stock of that symbol - {$_REQUEST["searchSymbol"]}</h2>";
}
?>
<br/>
Search Symbol :<input type="text" name="searchSymbol" id="searchSymbol"/>
<input type="submit" value="Submit"/>
</form>
<h2>Your present cash flow is</h2>
<?php
	echo number_format($theUser->GetCash($_SESSION["username"]),2);
 
	HTMLFooter();
?>

To view the stock details of the user, I just display the stock that the user has from data once again from the stock class, which also includes the current price of the stock. There is a checkbox that will allow the user to sell some of there stock (if they have any!!) and once again use the stock class to sell the stock and update the tables in the database.

<?php
	require("functions_start.php");
 
	global $theStock;
 
	if (!isset($_SESSION["authenticated"]) || $_SESSION["authenticated"]== false)
	{
		header("Location: /index.php");
		exit;
	}
	foreach ($_REQUEST as $key => $value)
	{
		if (strpos($key, "remove_") === 0)
			$theStock->SellStock($_SESSION["username"], $value);
		if ($key=="stock")
			$getStock = $value;
	}
	HTMLHeader("The details of your account");
?>
<h2>The stocks that the user has</h2>
<form action="<?php echo $_SERVER["PHP_SELF"];?>" method="post" onsubmit="return checkSell()">
<table>
<tr><td>Stock Name</td><td>Quantity</td><td>Price of Stock</td><td>Value</td><td>Sell</td></tr>
<?php
    $totalValue = 0;
	$usersStock = $theStock->ReturnAllStocks($_SESSION["username"]);
	foreach ($usersStock as $theStocks)
	{
		echo "<tr><td><a href=\"{$_SERVER["PHP_SELF"]}?stock={$theStocks[0]}\">{$theStocks[0]}</a></td><td>{$theStocks[1]}</td><td>{$theStocks[2]}</td><td>".
			number_format($theStocks[2] * $theStocks[1],2)."</td><td><input type=\"checkbox\" value=\"{$theStocks[0]}\" name=\"remove_{$theStocks[0]}\"/></td></tr>";
		$totalValue += $theStocks[2] * $theStocks[1];
	}
	echo "<tr><td colspan=\"2\"></td><td>Total value</td><td>".number_format($totalValue,2)."</td></tr>";
?>
</table>
<input id="center" type="submit" value="Submit"/>
</form>
<h2>Your present cash flow is</h2>
<?php
	echo number_format($theUser->GetCash($_SESSION["username"]),2);
	echo "<h2>Your cash + investments</h2>" . number_format($theUser->GetCash($_SESSION["username"]) + $totalValue,2);
 
	if (isset($getStock))
	{
		echo "<h2>$getStock more information</h2><table><tr><td>Date</td><td>Title/Link</td></tr>";
		$stockDetailsArray = $theStock->ArrayOfStockDetails($getStock);
		for ($i = 0; $i < sizeof($stockDetailsArray); $i++)
		{
			echo "<tr><td>{$stockDetailsArray[$i]["Date"]}</td><td><a href=\"{$stockDetailsArray[$i]["Link"]}\" target=\"_blank\">{$stockDetailsArray[$i]["Title"]}</a>";
		}
		echo "</table>";
	}
 
	HTMLFooter();
?>

The last part is the change of the password, which just will use the user class to update the users password to the requested input from the change password page.

<?php
	require("functions_start.php");
 
	if (isset($_REQUEST["password1"]) && isset($_REQUEST["password2"]))
	{
		if ($_REQUEST["password1"] == $_REQUEST["password2"])
			$error = $theUser->ChangePassword($_SESSION["username"], $_REQUEST["password1"]);
		else
			$notSamePassword = true;
	}
 
	if (!isset($_SESSION["authenticated"]))
	{
		header("Location: /index.php");
		exit;
	}
 
	HTMLHeader("Change password",true);
 
	if (isset($error))
	{
		if ($error)
			echo "<div>Password updated</div>";
		else 
			echo "<div id=\"error\">Cannot update the password, please contact the system admin</div>";
	}
	if (isset($notSamePassword))
		echo "<div>Passwords are not the same</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 CheckChangePasswords()">
Change your password <p>
New Password : <input type="password" name="password1" id="password1" value=""/></p>
Retype New Password : <input type="password" name="password2" id="password2" value=""/></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();
?>

The actual pages that are displayed to the user are all very basic as them selves, but the actual logic and formula are all within the classes that is the gold dust as such, since it is one point of checking and also one file to update if there is a update to the yahoo etc stocks details, because would have to update the different pages that display the stocks and that is not good for testing and also updating.

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.

CS71 – Ass1 – Finance – Part 2 – Classes

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.

Here is the classes part of the project, I have only done two, one for the users which allow for registration/forgotten password/login etc and another for the stock function like buying and selling stock.

To start with here is the users.php file, this file will allow the user to login and setup the SESSION information,

<?php
// could have setup the contrustor to have a session ID of the user.
// I went for this of passing in the users ID in the parameters, encase I wanted to pass in a different user within a admin screen!.
 
class User {
	// LoginCheck will check against the database the users creditials, please note that the string is send in clear text over the port/IP address from the php server to mysql database.
	public	function LoginCheck($varuser, $varpassword, $checkPassword = false)
	{
		global $db;
		if ($checkPassword == false)
			$sqlquery = sprintf("select uid from users where username = '%s' and pass =  AES_ENCRYPT('%s', '%s%s') and guid = 0", $varuser, $varuser, $varuser, $varpassword);
		else 
			$sqlquery = sprintf("select uid from users where username = '%s' and guid = 0", $varuser);
		$result = $db->query($sqlquery);
		if ($db->rowsNumber($result) === 1)
		{
			$output = $db->arrayResults($result);
			$_SESSION["authenticated"] = true;
			$_SESSION["username"] = $output["uid"];
			$db->freeResult($result);
			return true;
		}
		return false;
	}

here is the registration method, that will return values that are useful for the error reporting part of the web site

	// RegisterUser 
	// paramters : $varuser = email address
	//						$varpassword = password
	// return values
	// 					-2 : check password
	// 					-1 : not a valid email address
	// 					0 : already registered
	// 					1 : email check
	public	function RegisterUser($varuser, $varpassword)
	{
		global $db;
 
		if (!$this->CheckPassword($varpassword))
			return -2;
		// first lets check for a valid email address
		preg_match("/(\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,6})/", $varuser, $matches);
		if (isset($matches[0]))
		{
			// valid email address
			$sqlquery = sprintf("select uid from users where username = '%s'", $varuser);
			$result = $db->query($sqlquery);
			if ($db->rowsNumber($result) ===1)
			{
				$output  = $db->arrayResults($result);
				$db->freeResult($result);
				if ($output["uid"] > 0) return 0;
			}
			// so there is no user with that email address,
			// if there is not a trigger on the database
//			$sqlquery = sprintf("insert into users (username, pass) values ('%s',AES_ENCRYPT('%s','%s%s'))", $varuser, $varuser, $varuser, $varpassword);
			$sqlquery = sprintf("insert into users (username, pass,guid) values ('%s',AES_ENCRYPT('%s','%s%s'), uuid())", $varuser, $varuser, $varuser, $varpassword);
			$db->query($sqlquery);
			$sqlquery = sprintf("select guid from users where username = '%s'", $varuser);
			$result = $db->query($sqlquery);
			if ($db->rowsNumber($result) ===1)
			{
				$output = $db->arrayResults($result); 
				$guid = $output["guid"];
				$db->freeResult($result);
				// email the client a 
				$subject = 'Registration required for stocks program';
				$message = 'Please click on the link to register with the site';
				$message .= "<a href=\"http://{$_SERVER["SERVER_NAME"]}{$_SERVER["PHP_SELF"]}?uid=$varuser&validid=$guid\">http://{$_SERVER["SERVER_NAME"]}{$_SERVER["PHP_SELF"]}?uid=$varuser&validid=$guid</a>";
				$headers = 'From: noresponse@codingfriends.com' . "\r\n" . 'X-Mailer: PHP/' . phpversion();
 
				//mail($varuser, "Register with the stocks site", $message, $headers);
				// debugging, just output the message
				echo $message;
				return 1;
			}
		}
		else
			return -1;
	}

encase the user has javascript turned off and the javascript is not checking to make sure that the user is passing in a password that is at least 6 characters long and also has 1+ numeric/aplha characters.

	// checks password to be a minimum of 6 letters and also contains at least 
	// 1+ aplha/numeric
	private function CheckPassword($varpassword)
	{
		$varpassword = trim($varpassword);
		if (strlen($varpassword) >=6)
		{
			// if not all aplha or digit characters then return true else false
			if (!ctype_alpha($varpassword))
				if (!ctype_digit($varpassword))
					return true;
			return false;
		}	
		else
			return false;	
	}

Here the user will be emailed, if you uncomment the code, a link that will allow to change the password

	public function ForgottenUser($varuser)
	{
		global $db;
 
		$sqlquery = sprintf("update users set guid = uuid() where username = '%s'", $varuser);
		$result = $db->query($sqlquery);
		if ($db->rowsAffected() === 1)
		{
			$db->freeResult($result);
			$sqlquery = sprintf("select guid from users where username = '%s'", $varuser);
			$result = $db->query($sqlquery);
			$output = $db->arrayResults($result);
			$db->freeResult($result);
 
			$subject = 'Forgotten password';
			$message = 'Please click on the link to get back your password with the site';
			$message .= "<a href=\"http://{$_SERVER["SERVER_NAME"]}{$_SERVER["PHP_SELF"]}?uid=$varuser&validid={$output["guid"]}\">http://{$_SERVER["SERVER_NAME"]}{$_SERVER["PHP_SELF"]}?uid=$varuser&validid={$output["guid"]}</a>";
			$headers = 'From: noresponse@codingfriends.com' . "\r\n" . 'X-Mailer: PHP/' . phpversion();
 
			//mail($varuser, "Register with the stocks site", $message, $headers);
			// debugging, just output the message
			echo $message;
			return true;
		}
		$db->freeResult($result);
		return false;
	}

here this is checking to make sure that the value that was passed to the user to either registrar/forgotten password that is it the same as what is in the database and thus change that value to 0 to denote that the user is valid.

	public function CheckUserGUID($varuser, $guid)
	{
		global $db;
 
		$retValue = false;
		$sqlquery = sprintf("select guid from users where username = '%s'", $varuser);
		$result = $db->query($sqlquery);
		if ($db->rowsNumber($result) === 1)
		{
			$output = $db->arrayResults($result);
			if ($guid == $output["guid"])
				$retValue = true;
			$sqlquery = sprintf("update users set guid = 0 where username = '%s'", $varuser);
			$db->query($sqlquery);
		}
		$db->freeResult($result);
		return $retValue;
	}

If the user wants to update there password, here we alter the database values to for there password and using the AES_ENCRYPT function within MySQL to encrypted the password.

	public function ChangePassword($varuserID, $varpassword)
	{
		global $db;
 
		if (!$this->CheckPassword($varpassword))
			return false;
 
		$sqlquery = sprintf("select username from users where uid = %s", $varuserID);
		$result = $db->query($sqlquery);
		if ($db->rowsNumber($result) === 1)
		{
			$output = $db->arrayResults($result);
			$varuser = $output["username"];
			$db->freeResult($result);
 
			$sqlquery = sprintf("update users set pass = AES_ENCRYPT('%s', '%s%s') where username = '%s' and guid = 0", $varuser, $varuser, $varpassword, $varuser);
			$result = $db->query($sqlquery);
			return true;
			// if the password is the same, then the line is not updated and thus may come across as a weird message.
//			if ($db->rowsAffected() ===1)
//				return true;
		}
		$db->freeResult($result);
		return false;
	}

this is the method that will return the value of the users cash that they have left

	public function GetCash($varuser)
	{
		global $db;
		$returnValue = 0;
		$sqlquery = sprintf("select cash from users where uid = %d", $varuser);
		$result = $db->query($sqlquery);
		if ($db->rowsNumber($result) ===1)
		{
			$results = $db->arrayResults($result);
			$returnValue = $results["cash"];
		}
		$db->freeResult($result);
		return $returnValue;
	}

last but not the least, here is destroying the session data, so that the user is logout.

	// logout the user!
	public 	function Logout()
	{
		session_destroy();
	}
};
?>

The next class is the stock details, I called it getstocks.php, to start with I am getting the stock details from the yahoo site, with using the fopen of the yahoo.

<?php
	class StocksDetails {
 
		public function GetStocksFromYahoo($varsearch)
		{
			$returnvalue = 0;
			$handle = fopen("http://download.finance.yahoo.com/d/quotes.csv?s=$varsearch&f=sl1d1t1c1ohgv&e=.csv", "r");
			while ($row = fgetcsv($handle))
			{
				if ($row[0] == $varsearch)
					$returnvalue = $row[1];
			}
			fclose($handle);
			return $returnvalue;
		}

This method will build up a array of the users stock details and also the present value of the stock symbol.

		// display all of the users stock details, 
		public function ReturnAllStocks($varusernameID)
		{
			global $db;
 
			$sqlquery = sprintf("select symbol, quantity from stocks where uid = '%s'", $varusernameID);
			$result = $db->query($sqlquery);
			$insI = 0;
			while ($row = $db->arrayResults($result))
			{
				$returnArr[$insI++] = array($row["symbol"], $row["quantity"],$this->GetStocksFromYahoo($row["symbol"]));
			}
			$db->freeResult($result);
			return $returnArr;
		}

This method will sell the stock that the user has, to start with need to update the users cash flow for the sale of the stock, and then delete the actual stock from stocks table in the database that is linked to the user.

		public function SellStock($varusernameID, $stockID)
		{
			global $db;
 
			$db->startTransaction();
			try {
//	need to pull back users stock quantity and then delete it from the list and update the cash within the users table.
				$sqlquery = sprintf("update users,stocks set users.cash = users.cash + (%f * stocks.quantity) where users.uid = stocks.uid and users.uid = %d and stocks.symbol = \"%s\"",$this->GetStocksFromYahoo($stockID), $varusernameID, $stockID);
				$result = $db->query($sqlquery);
				if ($db->rowsAffected() == 1)
				{
					$sqlquery = sprintf("delete from stocks where uid = %d and symbol = \"%s\"", $varusernameID, $stockID);
					$result2 = $db->query($sqlquery);
					if ($db->rowsAffected() != 1)
						throw new Exception("Error updating the stock details");
				}
				else
					throw new Exception("Error updating users cash");
 
				$db->commitTransaction();
			} catch (Exception $e)
			{
				echo "Possible error : {$e->getMessage()}";
				$db->rollbackTransaction();
			}
		}

this method is the opposite of the above, where we are buying stock, we have to check the users balance/cash to make sure that they are able to, and then go though the process of updating the users table and the stocks, I am using the START TRANSACTION from within MySQL database InnoDB so that if any of process errors I can rollback the updates to the database tables.

		// buy the stock into the users 
		public function BuyStock($varusernameID, $stockID, $stockQuantity)
		{
			global $db;
 
			$valueOfStock = $this->GetStocksFromYahoo($stockID) * $stockQuantity;
			if ($valueOfStock > 0)
			{
				try {
					$db->startTransaction();
					// update the users cash, whilst making sure that there is enought !!.
					$sqlquery = sprintf("update users set cash = cash - (%f) where uid = %d and cash > %f", $valueOfStock, $varusernameID, $valueOfStock);
					$db->query($sqlquery);
					// if there was enought money, place the update into the stocks table now!.
					if ($db->rowsAffected() ==1)
					{
						// now update the stock database table, could have used on duplicate key here.. 
						$sqlquery = sprintf("update stocks set quantity = quantity + %d where uid = %d and symbol = '%s'",$stockQuantity, $varusernameID, $stockID);
						$db->query($sqlquery);
						// there was no stock of that type already, then just insert
						if ($db->rowsAffected() == 0)
						{
							$sqlquery = sprintf("insert into stocks values (%d,\"%s\", %d)", $varusernameID, $stockID, $stockQuantity);
							$db->query($sqlquery);
						}
					}
					else 
						throw new Exception("Not enought money!");
					$db->commitTransaction();
				} catch (Exception $e)
				{
					echo "Possible error : {$e->getMessage()}";
					$db->rollbackTransaction();
					return 0;
				}
			}
			else
			{
				echo "Possible error : Getting values from Yahoo stock";
				return 0;
			}
			return $valueOfStock;
		}

Here, I am getting the news from of the symbol stock from the yahoo rss links.

		public function ArrayOfStockDetails($stockID)
		{
			$xmlDoc =  simplexml_load_file("http://finance.yahoo.com/rss/headline?s=$stockID");
			$xpath = $xmlDoc->xpath("//channel/item");
			$insI = 0;
			foreach ($xpath as $key)
			{
				$arrayRet[$insI++] = array("Date" => (string)$key->pubDate,
															  "Link" => (string)$key->link,
															"Title" =>  (string)$key->title);
			}
			return $arrayRet;
		}
	};
?>

Next going to do the basic php file to load up the class files and connect to the database, with also the javascript code.

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.

CS107 – Assignment 1 – Context Free Grammar – Random Sentence Generator

This is assignment 1 from a older CS107 course, because the latest course work is held on a UNIX server which in turn you need access to!!.. kinder does not help when you do not have access too!!.. Here is where I got the files from cs107 link, there is a zip file at the bottom of that page which has all of the assignments and handouts etc.

The basics of a context free grammar is (as taken from the PDF file attached which is the assignment 1 in more details), the tokens as such are the <..> parts of the block, so that you start at <start> and then you print out “The ” and then goto the <object> block to then print out a randomly picked object to then print out the <verb> if there is any blocks within the object/verb then do them before heading back to the last word on the <start> block which is “tonight”. That is it, it generates random text :).

The Poem grammar
{
<start>
	The <object> <verb> tonight. ;
}
 
{
<object>
	waves	;
	big yellow flowers ;
	slugs ;
}
 
{
<verb>
	sigh <adverb> ;
	portend like <object> ;
	die <adverb> ;
}
 
{
<adverb>
	warily ;
	grumpily ;
}

So the assignment is mainly to get used to compiling up programs within a Linux/Unix environment, I was using qt-creator IDE (which has placed some files within the zip file attached, but it does not effect the directory structure as such). To compile on Linux/Unix as long as there is a Makefile you can just

make

So, the assignment 1 base code reads in the textual files and all is required is to output the text within a random sentence and repeat 3 times, so the start of the code does the looping and calls the doRandomText function which requires as parameters the mapped (map) grammar and where to start ()

  for (int i =1;i <= 3; i++)
  {
      cout << "Version #" << i << endl << endl;
      doRandomText(grammar, "<start>");
      cout << endl << endl;
  }
  return 0;
}
 
// recursive loop in the text and produce randomly generated text
void doRandomText(map<string, Definition> theGrammar, string terminal)
{
    Definition def = theGrammar[terminal];
    assert(def.getNonterminal().size() !=0);
    Production prod = def.getRandomProduction();
    for (Production::iterator prodIter = prod.begin(); prodIter != prod.end(); prodIter++)
    {
        string theText = *prodIter;
        if (theText.at(0)=='<' && theText.at(theText.size()-1)== '>')
            doRandomText(theGrammar, theText);
        else
        {
            if (theText == "," || theText == ".")
                cout << theText;
            else
                cout << " " << theText;
        }
    }
}

The recursive function above basically tries to find the terminal within the grammar definitions and if there is not one, exit the code (assert), else print out the textual data whilst iterating over them, if there is any more terminals within the sentence then goto that terminal by calling this same function.

Here is the output of a run from the program.

./rsg assn-1-rsg-data/excuse.g 
The grammar file called "assn-1-rsg-data/excuse.g" contains 7 definitions.
Version #1
 
 I need an extension because my disk got erased, and I'm sure you've heard this before, but I had to make up a lot of documentation for the Navy in a big hurry, and I'm sure you've heard this before, but my printout was enshrowded in a mysterious fog for three days and then vanished, and I'm sure you've heard this before, but all my pencils broke, and just then I had 7 programs in like, a billion different langauges, and if you can believe it, I just didn't feel like working, and and then if I recall correctly I had to worry about the Winter Olympics, and and then if I recall correctly my disk got erased, and as if that wasn't enough I forgot how to write.
 
Version #2
 
 I need an extension because I got stuck in a blizzard at Tahoe, and then get this, my Mac was enshrowded in a mysterious fog for three days and then vanished.
 
Version #3
 
 I need an extension because I didn't know I was in this class, and then I just didn't feel like working, and I'm sure you've heard this before, but I thought I already graduated, and then, just when my mojo was getting back on its feet, the bookstore was out of erasers, and if you can believe it, I didn't know I was in this class, and and then if I recall correctly my dorm burned down.