{"id":1147,"date":"2010-08-11T16:21:02","date_gmt":"2010-08-11T15:21:02","guid":{"rendered":"http:\/\/www.codingfriends.com\/?p=1147"},"modified":"2010-08-11T16:21:02","modified_gmt":"2010-08-11T15:21:02","slug":"cs71-ass1-finance-part-2-classes","status":"publish","type":"post","link":"https:\/\/www.codingfriends.com\/index.php\/2010\/08\/11\/cs71-ass1-finance-part-2-classes\/","title":{"rendered":"CS71 &#8211; Ass1 &#8211; Finance &#8211; Part 2 &#8211; Classes"},"content":{"rendered":"<p><span id=\"zipfile\"><a href=\"http:\/\/www.codingfriends.com\/wp-content\/uploads\/2010\/08\/cs75-ass1.zip\"><\/a><\/span>I am doing the <a href=\"http:\/\/www.harvard.edu\/\">Harvards<\/a> building dynamic websites called <a href=\"http:\/\/www.cs75.net\/\">CS-75<\/a> (also could be called E-75), because someone told me about it and I just thought might as well, it is all learning \ud83d\ude42 even if allot of it you may already know.<\/p>\n<p>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.<\/p>\n<p>To start with here is the users.php file, this file will allow the user to login and setup the SESSION information, <\/p>\n<pre lang=\"php\">\r\n<?php\r\n\/\/ could have setup the contrustor to have a session ID of the user.\r\n\/\/ 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!.\r\n\r\nclass User {\r\n\t\/\/ 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.\r\n\tpublic\tfunction LoginCheck($varuser, $varpassword, $checkPassword = false)\r\n\t{\r\n\t\tglobal $db;\r\n\t\tif ($checkPassword == false)\r\n\t\t\t$sqlquery = sprintf(\"select uid from users where username = '%s' and pass =  AES_ENCRYPT('%s', '%s%s') and guid = 0\", $varuser, $varuser, $varuser, $varpassword);\r\n\t\telse \r\n\t\t\t$sqlquery = sprintf(\"select uid from users where username = '%s' and guid = 0\", $varuser);\r\n\t\t$result = $db->query($sqlquery);\r\n\t\tif ($db->rowsNumber($result) === 1)\r\n\t\t{\r\n\t\t\t$output = $db->arrayResults($result);\r\n\t\t\t$_SESSION[\"authenticated\"] = true;\r\n\t\t\t$_SESSION[\"username\"] = $output[\"uid\"];\r\n\t\t\t$db->freeResult($result);\r\n\t\t\treturn true;\r\n\t\t}\r\n\t\treturn false;\r\n\t}\r\n\t\r\n<\/pre>\n<p>here is the registration method, that will return values that are useful for the error reporting part of the web site<\/p>\n<pre lang=\"php\">\r\n\t\/\/ RegisterUser \r\n\t\/\/ paramters : $varuser = email address\r\n\t\/\/\t\t\t\t\t\t$varpassword = password\r\n\t\/\/ return values\r\n\t\/\/ \t\t\t\t\t-2 : check password\r\n\t\/\/ \t\t\t\t\t-1 : not a valid email address\r\n\t\/\/ \t\t\t\t\t0 : already registered\r\n\t\/\/ \t\t\t\t\t1 : email check\r\n\tpublic\tfunction RegisterUser($varuser, $varpassword)\r\n\t{\r\n\t\tglobal $db;\r\n\t\t\r\n\t\tif (!$this->CheckPassword($varpassword))\r\n\t\t\treturn -2;\r\n\t\t\/\/ first lets check for a valid email address\r\n\t\tpreg_match(\"\/(\\w+@[a-zA-Z_]+?\\.[a-zA-Z]{2,6})\/\", $varuser, $matches);\r\n\t\tif (isset($matches[0]))\r\n\t\t{\r\n\t\t\t\/\/ valid email address\r\n\t\t\t$sqlquery = sprintf(\"select uid from users where username = '%s'\", $varuser);\r\n\t\t\t$result = $db->query($sqlquery);\r\n\t\t\tif ($db->rowsNumber($result) ===1)\r\n\t\t\t{\r\n\t\t\t\t$output  = $db->arrayResults($result);\r\n\t\t\t\t$db->freeResult($result);\r\n\t\t\t\tif ($output[\"uid\"] > 0) return 0;\r\n\t\t\t}\r\n\t\t\t\/\/ so there is no user with that email address,\r\n\t\t\t\/\/ if there is not a trigger on the database\r\n\/\/\t\t\t$sqlquery = sprintf(\"insert into users (username, pass) values ('%s',AES_ENCRYPT('%s','%s%s'))\", $varuser, $varuser, $varuser, $varpassword);\r\n\t\t\t$sqlquery = sprintf(\"insert into users (username, pass,guid) values ('%s',AES_ENCRYPT('%s','%s%s'), uuid())\", $varuser, $varuser, $varuser, $varpassword);\r\n\t\t\t$db->query($sqlquery);\r\n\t\t\t$sqlquery = sprintf(\"select guid from users where username = '%s'\", $varuser);\r\n\t\t\t$result = $db->query($sqlquery);\r\n\t\t\tif ($db->rowsNumber($result) ===1)\r\n\t\t\t{\r\n\t\t\t\t$output = $db->arrayResults($result); \r\n\t\t\t\t$guid = $output[\"guid\"];\r\n\t\t\t\t$db->freeResult($result);\r\n\t\t\t\t\/\/ email the client a \r\n\t\t\t\t$subject = 'Registration required for stocks program';\r\n\t\t\t\t$message = 'Please click on the link to register with the site';\r\n\t\t\t\t$message .= \"<a href=\\\"http:\/\/{$_SERVER[\"SERVER_NAME\"]}{$_SERVER[\"PHP_SELF\"]}?uid=$varuser&#038;validid=$guid\\\">http:\/\/{$_SERVER[\"SERVER_NAME\"]}{$_SERVER[\"PHP_SELF\"]}?uid=$varuser&validid=$guid<\/a>\";\r\n\t\t\t\t$headers = 'From: noresponse@codingfriends.com' . \"\\r\\n\" . 'X-Mailer: PHP\/' . phpversion();\r\n\r\n\t\t\t\t\/\/mail($varuser, \"Register with the stocks site\", $message, $headers);\r\n\t\t\t\t\/\/ debugging, just output the message\r\n\t\t\t\techo $message;\r\n\t\t\t\treturn 1;\r\n\t\t\t}\r\n\t\t}\r\n\t\telse\r\n\t\t\treturn -1;\r\n\t}\r\n<\/pre>\n<p>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.<\/p>\n<pre lang=\"php\">\r\n\t\/\/ checks password to be a minimum of 6 letters and also contains at least \r\n\t\/\/ 1+ aplha\/numeric\r\n\tprivate function CheckPassword($varpassword)\r\n\t{\r\n\t\t$varpassword = trim($varpassword);\r\n\t\tif (strlen($varpassword) >=6)\r\n\t\t{\r\n\t\t\t\/\/ if not all aplha or digit characters then return true else false\r\n\t\t\tif (!ctype_alpha($varpassword))\r\n\t\t\t\tif (!ctype_digit($varpassword))\r\n\t\t\t\t\treturn true;\r\n\t\t\treturn false;\r\n\t\t}\t\r\n\t\telse\r\n\t\t\treturn false;\t\r\n\t}\r\n<\/pre>\n<p>Here the user will be emailed, if you uncomment the code, a link that will allow to change the password<\/p>\n<pre lang=\"php\">\r\n\tpublic function ForgottenUser($varuser)\r\n\t{\r\n\t\tglobal $db;\r\n\t\t\r\n\t\t$sqlquery = sprintf(\"update users set guid = uuid() where username = '%s'\", $varuser);\r\n\t\t$result = $db->query($sqlquery);\r\n\t\tif ($db->rowsAffected() === 1)\r\n\t\t{\r\n\t\t\t$db->freeResult($result);\r\n\t\t\t$sqlquery = sprintf(\"select guid from users where username = '%s'\", $varuser);\r\n\t\t\t$result = $db->query($sqlquery);\r\n\t\t\t$output = $db->arrayResults($result);\r\n\t\t\t$db->freeResult($result);\r\n\t\t\t\r\n\t\t\t$subject = 'Forgotten password';\r\n\t\t\t$message = 'Please click on the link to get back your password with the site';\r\n\t\t\t$message .= \"<a href=\\\"http:\/\/{$_SERVER[\"SERVER_NAME\"]}{$_SERVER[\"PHP_SELF\"]}?uid=$varuser&#038;validid={$output[\"guid\"]}\\\">http:\/\/{$_SERVER[\"SERVER_NAME\"]}{$_SERVER[\"PHP_SELF\"]}?uid=$varuser&validid={$output[\"guid\"]}<\/a>\";\r\n\t\t\t$headers = 'From: noresponse@codingfriends.com' . \"\\r\\n\" . 'X-Mailer: PHP\/' . phpversion();\r\n\r\n\t\t\t\/\/mail($varuser, \"Register with the stocks site\", $message, $headers);\r\n\t\t\t\/\/ debugging, just output the message\r\n\t\t\techo $message;\r\n\t\t\treturn true;\r\n\t\t}\r\n\t\t$db->freeResult($result);\r\n\t\treturn false;\r\n\t}\r\n<\/pre>\n<p>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.<\/p>\n<pre lang=\"php\">\t\r\n\tpublic function CheckUserGUID($varuser, $guid)\r\n\t{\r\n\t\tglobal $db;\r\n\t\t\r\n\t\t$retValue = false;\r\n\t\t$sqlquery = sprintf(\"select guid from users where username = '%s'\", $varuser);\r\n\t\t$result = $db->query($sqlquery);\r\n\t\tif ($db->rowsNumber($result) === 1)\r\n\t\t{\r\n\t\t\t$output = $db->arrayResults($result);\r\n\t\t\tif ($guid == $output[\"guid\"])\r\n\t\t\t\t$retValue = true;\r\n\t\t\t$sqlquery = sprintf(\"update users set guid = 0 where username = '%s'\", $varuser);\r\n\t\t\t$db->query($sqlquery);\r\n\t\t}\r\n\t\t$db->freeResult($result);\r\n\t\treturn $retValue;\r\n\t}\r\n<\/pre>\n<p>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.<\/p>\n<pre lang=\"php\">\r\n\tpublic function ChangePassword($varuserID, $varpassword)\r\n\t{\r\n\t\tglobal $db;\r\n\t\t\r\n\t\tif (!$this->CheckPassword($varpassword))\r\n\t\t\treturn false;\r\n\r\n\t\t$sqlquery = sprintf(\"select username from users where uid = %s\", $varuserID);\r\n\t\t$result = $db->query($sqlquery);\r\n\t\tif ($db->rowsNumber($result) === 1)\r\n\t\t{\r\n\t\t\t$output = $db->arrayResults($result);\r\n\t\t\t$varuser = $output[\"username\"];\r\n\t\t\t$db->freeResult($result);\r\n\t\t\t\r\n\t\t\t$sqlquery = sprintf(\"update users set pass = AES_ENCRYPT('%s', '%s%s') where username = '%s' and guid = 0\", $varuser, $varuser, $varpassword, $varuser);\r\n\t\t\t$result = $db->query($sqlquery);\r\n\t\t\treturn true;\r\n\t\t\t\/\/ if the password is the same, then the line is not updated and thus may come across as a weird message.\r\n\/\/\t\t\tif ($db->rowsAffected() ===1)\r\n\/\/\t\t\t\treturn true;\r\n\t\t}\r\n\t\t$db->freeResult($result);\r\n\t\treturn false;\r\n\t}\r\n<\/pre>\n<p>this is the method that will return the value of the users cash that they have left<\/p>\n<pre lang=\"php\">\t\r\n\tpublic function GetCash($varuser)\r\n\t{\r\n\t\tglobal $db;\r\n\t\t$returnValue = 0;\r\n\t\t$sqlquery = sprintf(\"select cash from users where uid = %d\", $varuser);\r\n\t\t$result = $db->query($sqlquery);\r\n\t\tif ($db->rowsNumber($result) ===1)\r\n\t\t{\r\n\t\t\t$results = $db->arrayResults($result);\r\n\t\t\t$returnValue = $results[\"cash\"];\r\n\t\t}\r\n\t\t$db->freeResult($result);\r\n\t\treturn $returnValue;\r\n\t}\r\n<\/pre>\n<p>last but not the least, here is destroying the session data, so that the user is logout.<\/p>\n<pre lang=\"php\">\r\n\t\/\/ logout the user!\r\n\tpublic \tfunction Logout()\r\n\t{\r\n\t\tsession_destroy();\r\n\t}\r\n};\r\n?><\/pre>\n<p>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.<\/p>\n<pre lang=\"php\">\r\n<?php\r\n\tclass StocksDetails {\r\n\t\t\r\n\t\tpublic function GetStocksFromYahoo($varsearch)\r\n\t\t{\r\n\t\t\t$returnvalue = 0;\r\n\t\t\t$handle = fopen(\"http:\/\/download.finance.yahoo.com\/d\/quotes.csv?s=$varsearch&#038;f=sl1d1t1c1ohgv&#038;e=.csv\", \"r\");\r\n\t\t\twhile ($row = fgetcsv($handle))\r\n\t\t\t{\r\n\t\t\t\tif ($row[0] == $varsearch)\r\n\t\t\t\t\t$returnvalue = $row[1];\r\n\t\t\t}\r\n\t\t\tfclose($handle);\r\n\t\t\treturn $returnvalue;\r\n\t\t}\r\n<\/pre>\n<p>This method will build up a array of the users stock details and also the present value of the stock symbol.<\/p>\n<pre lang=\"php\">\r\n\t\t\/\/ display all of the users stock details, \r\n\t\tpublic function ReturnAllStocks($varusernameID)\r\n\t\t{\r\n\t\t\tglobal $db;\r\n\t\t\t\r\n\t\t\t$sqlquery = sprintf(\"select symbol, quantity from stocks where uid = '%s'\", $varusernameID);\r\n\t\t\t$result = $db->query($sqlquery);\r\n\t\t\t$insI = 0;\r\n\t\t\twhile ($row = $db->arrayResults($result))\r\n\t\t\t{\r\n\t\t\t\t$returnArr[$insI++] = array($row[\"symbol\"], $row[\"quantity\"],$this->GetStocksFromYahoo($row[\"symbol\"]));\r\n\t\t\t}\r\n\t\t\t$db->freeResult($result);\r\n\t\t\treturn $returnArr;\r\n\t\t}\r\n<\/pre>\n<p>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.<\/p>\n<pre lang=\"php\">\r\n\t\tpublic function SellStock($varusernameID, $stockID)\r\n\t\t{\r\n\t\t\tglobal $db;\r\n\t\t\t\r\n\t\t\t$db->startTransaction();\r\n\t\t\ttry {\r\n\/\/\tneed to pull back users stock quantity and then delete it from the list and update the cash within the users table.\r\n\t\t\t\t$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);\r\n\t\t\t\t$result = $db->query($sqlquery);\r\n\t\t\t\tif ($db->rowsAffected() == 1)\r\n\t\t\t\t{\r\n\t\t\t\t\t$sqlquery = sprintf(\"delete from stocks where uid = %d and symbol = \\\"%s\\\"\", $varusernameID, $stockID);\r\n\t\t\t\t\t$result2 = $db->query($sqlquery);\r\n\t\t\t\t\tif ($db->rowsAffected() != 1)\r\n\t\t\t\t\t\tthrow new Exception(\"Error updating the stock details\");\r\n\t\t\t\t}\r\n\t\t\t\telse\r\n\t\t\t\t\tthrow new Exception(\"Error updating users cash\");\r\n\t\t\t\t\t\r\n\t\t\t\t$db->commitTransaction();\r\n\t\t\t} catch (Exception $e)\r\n\t\t\t{\r\n\t\t\t\techo \"Possible error : {$e->getMessage()}\";\r\n\t\t\t\t$db->rollbackTransaction();\r\n\t\t\t}\r\n\t\t}\r\n<\/pre>\n<p>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. <\/p>\n<pre lang=\"php\">\r\n\t\t\/\/ buy the stock into the users \r\n\t\tpublic function BuyStock($varusernameID, $stockID, $stockQuantity)\r\n\t\t{\r\n\t\t\tglobal $db;\r\n\t\t\t\r\n\t\t\t$valueOfStock = $this->GetStocksFromYahoo($stockID) * $stockQuantity;\r\n\t\t\tif ($valueOfStock > 0)\r\n\t\t\t{\r\n\t\t\t\ttry {\r\n\t\t\t\t\t$db->startTransaction();\r\n\t\t\t\t\t\/\/ update the users cash, whilst making sure that there is enought !!.\r\n\t\t\t\t\t$sqlquery = sprintf(\"update users set cash = cash - (%f) where uid = %d and cash > %f\", $valueOfStock, $varusernameID, $valueOfStock);\r\n\t\t\t\t\t$db->query($sqlquery);\r\n\t\t\t\t\t\/\/ if there was enought money, place the update into the stocks table now!.\r\n\t\t\t\t\tif ($db->rowsAffected() ==1)\r\n\t\t\t\t\t{\r\n\t\t\t\t\t\t\/\/ now update the stock database table, could have used on duplicate key here.. \r\n\t\t\t\t\t\t$sqlquery = sprintf(\"update stocks set quantity = quantity + %d where uid = %d and symbol = '%s'\",$stockQuantity, $varusernameID, $stockID);\r\n\t\t\t\t\t\t$db->query($sqlquery);\r\n\t\t\t\t\t\t\/\/ there was no stock of that type already, then just insert\r\n\t\t\t\t\t\tif ($db->rowsAffected() == 0)\r\n\t\t\t\t\t\t{\r\n\t\t\t\t\t\t\t$sqlquery = sprintf(\"insert into stocks values (%d,\\\"%s\\\", %d)\", $varusernameID, $stockID, $stockQuantity);\r\n\t\t\t\t\t\t\t$db->query($sqlquery);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse \r\n\t\t\t\t\t\tthrow new Exception(\"Not enought money!\");\r\n\t\t\t\t\t$db->commitTransaction();\r\n\t\t\t\t} catch (Exception $e)\r\n\t\t\t\t{\r\n\t\t\t\t\techo \"Possible error : {$e->getMessage()}\";\r\n\t\t\t\t\t$db->rollbackTransaction();\r\n\t\t\t\t\treturn 0;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\telse\r\n\t\t\t{\r\n\t\t\t\techo \"Possible error : Getting values from Yahoo stock\";\r\n\t\t\t\treturn 0;\r\n\t\t\t}\r\n\t\t\treturn $valueOfStock;\r\n\t\t}\r\n<\/pre>\n<p>Here, I am getting the news from of the symbol stock from the yahoo rss links.<\/p>\n<pre lang=\"php\">\t\t\r\n\t\tpublic function ArrayOfStockDetails($stockID)\r\n\t\t{\r\n\t\t\t$xmlDoc =  simplexml_load_file(\"http:\/\/finance.yahoo.com\/rss\/headline?s=$stockID\");\r\n\t\t\t$xpath = $xmlDoc->xpath(\"\/\/channel\/item\");\r\n\t\t\t$insI = 0;\r\n\t\t\tforeach ($xpath as $key)\r\n\t\t\t{\r\n\t\t\t\t$arrayRet[$insI++] = array(\"Date\" => (string)$key->pubDate,\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  \"Link\" => (string)$key->link,\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"Title\" =>  (string)$key->title);\r\n\t\t\t}\r\n\t\t\treturn $arrayRet;\r\n\t\t}\r\n\t};\r\n?><\/pre>\n<p>Next going to do the basic php file to load up the class files and connect to the database, with also the javascript code.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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 \ud83d\ude42 even if allot of it you may already know. Here is the classes part of the project, I have only done two, &hellip; <a href=\"https:\/\/www.codingfriends.com\/index.php\/2010\/08\/11\/cs71-ass1-finance-part-2-classes\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">CS71 &#8211; Ass1 &#8211; Finance &#8211; Part 2 &#8211; Classes<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[17],"tags":[246,249,251],"class_list":["post-1147","post","type-post","status-publish","format-standard","hentry","category-php","tag-assignment-1","tag-cs75","tag-e75"],"_links":{"self":[{"href":"https:\/\/www.codingfriends.com\/index.php\/wp-json\/wp\/v2\/posts\/1147","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.codingfriends.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.codingfriends.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.codingfriends.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.codingfriends.com\/index.php\/wp-json\/wp\/v2\/comments?post=1147"}],"version-history":[{"count":1,"href":"https:\/\/www.codingfriends.com\/index.php\/wp-json\/wp\/v2\/posts\/1147\/revisions"}],"predecessor-version":[{"id":1148,"href":"https:\/\/www.codingfriends.com\/index.php\/wp-json\/wp\/v2\/posts\/1147\/revisions\/1148"}],"wp:attachment":[{"href":"https:\/\/www.codingfriends.com\/index.php\/wp-json\/wp\/v2\/media?parent=1147"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.codingfriends.com\/index.php\/wp-json\/wp\/v2\/categories?post=1147"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.codingfriends.com\/index.php\/wp-json\/wp\/v2\/tags?post=1147"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}