195 CHAPTER 6 Creating a Shopping Cart Deleting Items The showcart() function contains a link to delete.php, in which you can remove an item from the shopping cart. By clicking the link, the item is removed from the orderitems table, and the total price in the orders table is updated. Create delete.php and begin adding the code: <?php require("config.php"); require("db.php"); require("functions.php"); $validid = pf_validate_number($_GET['id'], "redirect", $config_basedir . "showcart.php"); $itemsql = "SELECT * FROM orderitems WHERE id = " . $_GET['id'] . ";"; $itemres = mysql_query($itemsql); $numrows = mysql_num_rows($itemres); if($numrows == 0) { header("Location: " . $config_basedir . "showcart.php"); } $itemrow = mysql_fetch_assoc($itemres); In this code, the query pulls the item from the orderitems table, and the number of rows returned is checked. This check prevents someone modifying the URL and adding delete.php?id=73 if there is no item with an id of 73. If no rows are returned, a header redirect jumps to showcart.php. If a row is returned, the script continues: $itemrow = mysql_fetch_assoc($itemres); $prodsql = "SELECT price FROM products WHERE id = " . $itemrow['product_id'] . ";"; $prodres = mysql_query($prodsql); $prodrow = mysql_fetch_assoc($prodres); $sql = "DELETE FROM orderitems WHERE id = " . $_GET['id']; mysql_query($sql); In this block, the price of the product is selected first and then a separate query removes the item from orderitems. Update the orders table with the new total price: 196 Practical PHP and MySQL FIGURE 6-6 The shopping cart summary displays a current list of items and the ability to remove them. mysql_query($sql); $totalprice = $prodrow['price'] * $itemrow['quantity'] ; $updsql = "UPDATE orders SET total = total - " . $totalprice . " WHERE id = " . $_SESSION['SESS_ORDERNUM'] . ";"; mysql_query($updres); header("Location: " . $config_basedir . "/showcart.php"); ?> With the cart summary function and pages complete, your browser should show something similar to the page shown in Figure 6-6. CHECKING IT OUT After the user has finished adding items to his shopping cart, the checkout process can begin. This process involves two steps: ■ Prompt the user for a delivery address. If the user is already logged in, he should be asked if he wants to use the address he registered or use a differ- ent address. All addresses should be validated. ■ Prompt the user to choose a payment method, either PayPal or a check. 197 CHAPTER 6 Creating a Shopping Cart Create checkout-address.php and add the form: require("header.php"); echo "<h1>Add a delivery address</h1>"; if(isset($_GET['error']) == TRUE) { echo "<strong>Please fill in the missing information from the form</strong>"; } echo "<form action='" . $SCRIPT_NAME . "' method='POST'>"; if($_SESSION['SESS_LOGGEDIN']) { ?> <input type="radio" name="addselecBox" value="1" checked>Use the address from my account</input><br> <input type="radio" name="addselecBox" value="2">Use the address below:</input> <?php } ?> <table> <tr> <td>Forename</td> <td><input type="text" name="forenameBox"></td> </tr> <tr> <td>Surname</td> <td><input type="text" name="surnameBox"></td> </tr> <tr> <td>House Number, Street</td> <td><input type="text" name="add1Box"></td> </tr> <tr> <td>Town/City</td> <td><input type="text" name="add2Box"></td> </tr> <tr> <td>County</td> <td><input type="text" name="add3Box"></td> </tr> <tr> <td>Postcode</td> <td><input type="text" name="postcodeBox"></td> </tr> <tr> <td>Phone</td> <td><input type="text" name="phoneBox"></td> 198 Practical PHP and MySQL NOTE Remember that the status can be any of the following values: 0 The user is still shopping. 1 The user has completed the address entry. 2 The user has paid. 10 The administrator has confirmed the order. </tr> <tr> <td>Email</td> <td><input type="text" name="emailBox"></td> </tr> <tr> <td></td> <td><input type="submit" name="submit" value="Add Address (press only once)"></td> </tr> </table> </form> Before the form is displayed, an if checks if an error GET variable exists. If it does, an error message is displayed. The script then checks if the user is logged in, and if so, two radio buttons are added so that the user can choose between the address he registered and a different address. Move to the start of the file and add the following code: <?php session_start(); require("db.php"); $statussql = "SELECT status FROM orders WHERE id = " . $_SESSION['SESS_ORDERNUM']; $statusres = mysql_query($statussql); $statusrow = mysql_fetch_assoc($statusres); $status = $statusrow['status']; The first step is to determine the current status of the order. If the user has already been through the address stage of the checkout process, redirect the page to the payment screen. Obtain the status by searching for a record in the orders table that matches SESS_ORDERNUM. Then, set the $status variable to the correct status. If the status is set to 1, the user has already entered an address and the page redirects to the payment screen. If the status is 2 or higher, the order has been com- pleted. Redirect the page to the base URL of the site: 199 CHAPTER 6 Creating a Shopping Cart $status = $statusrow['status']; if($status == 1) { header(“Location: “ . $config_basedir . “checkout-pay.php”); } if($status >= 2) { header(“Location: “ . $config_basedir); } Begin processing the form: if($status >= 2) { header("Location: " . $config_basedir); } if($_POST[‘submit’]) { if($_SESSION[‘SESS_LOGGEDIN’]) { if($_POST[‘addselecBox’] == 2) { if(empty($_POST[‘forenameBox’]) || empty($_POST[‘surnameBox’]) || empty($_POST[‘add1Box’]) || empty($_POST[‘add2Box’]) || empty($_POST[‘add3Box’]) || empty($_POST[‘postcodeBox’]) || empty($_POST[‘phoneBox’]) || empty($_POST[‘emailBox’])) { header(“Location: “ . $basedir . “checkout- address.php?error=1”); exit; } The first nested if checks if the user is logged in. A check is then made to see if the user selected the second radio button ( Use the address below). If so, the form fields are checked to see if they are empty. If they are, the page is reloaded with the error GET variable so that the error message can be dis- played. If the form is not empty, add the address to the delivery_addresses table and update the orders table: exit; } $addsql = "INSERT INTO delivery_addresses(forename, surname, add1, add2, add3, postcode, phone, email) 200 Practical PHP and MySQL VALUES('" . strip_tags(addslashes( $_POST['forenameBox'])) . "', '" . strip_tags(addslashes( $_POST['surnameBox'])) . "', '" . strip_tags(addslashes( $_POST['add1Box'])) . "', '" . strip_tags(addslashes( $_POST['add2Box'])) . "', '" . strip_tags(addslashes( $_POST['add3Box'])) . "', '" . strip_tags(addslashes( $_POST['postcodeBox'])) . "', '" . strip_tags(addslashes( $_POST['phoneBox'])) . "', '" . strip_tags(addslashes( $_POST['emailBox'])) . "')"; mysql_query($addsql); $setaddsql = "UPDATE orders SET delivery_add_id = " . mysql_insert_id() . ", status = 1 WHERE id = " . $_SESSION['SESS_ORDERNUM']; mysql_query($setaddsql); header("Location: " . $config_basedir . "checkout-pay.php"); } The delivery_addresses table contains a list of addresses for unregistered users and registered users who select a different address. When the information is added to the table, the strip_tags() function removes any HTML tags that may have been added, and the addslashes() function escapes any quotes. Finally, the orders table is updated with the id of the record from delivery_addresses, and the status is changed to 1. When this is complete, the page redirects to checkout-pay.php. If the user is logged in but selects the address on file, the orders table is updated also: header("Location: " . $config_basedir . "checkout-pay.php"); } else { $custsql = "UPDATE orders SET delivery_add_id = 0, status = 1 WHERE id = " . $_SESSION['SESS_ORDERNUM']; mysql_query($custsql); 201 CHAPTER 6 Creating a Shopping Cart header("Location: " . $config_basedir . "checkout-pay.php"); } } If no user is logged in, the form is validated and the address is added to the database: header("Location: " . $config_basedir . "checkout-pay.php"); } } else { if(empty($_POST['forenameBox']) || empty($_POST['surnameBox']) || empty($_POST['add1Box']) || empty($_POST['add2Box']) || empty($_POST['add3Box']) || empty($_POST['postcodeBox']) || empty($_POST['phoneBox']) || empty($_POST['emailBox'])) { header("Location: " . "checkout-address.php?error=1"); exit; } $addsql = "INSERT INTO delivery_addresses(forename, surname, add1, add2, add3, postcode, phone, email) VALUES('" . $_POST['forenameBox'] . "', '" . $_POST['surnameBox'] . "', '" . $_POST['add1Box'] . "', '" . $_POST['add2Box'] . "', '" . $_POST['add3Box'] . "', '" . $_POST['postcodeBox'] . "', '" . $_POST['phoneBox'] . "', '" . $_POST['emailBox'] . "')"; mysql_query($addsql); $setaddsql = "UPDATE orders SET delivery_add_id = " . mysql_insert_id() . ", status = 1 WHERE session = '" . session_id() . "'"; mysql_query($setaddsql); header("Location: " . $config_basedir . "checkout-pay.php"); } } 202 Practical PHP and MySQL In this block of code, the address is added to the delivery_addresses table, and the orders table is updated with the delivery_addresses id and the status is set to 1. Begin the form block: header("Location: " . $config_basedir . "checkout-pay.php"); } } else { require("header.php"); echo "<h1>Add a delivery address</h1>"; Finally, add the code after the form: </table> </form> <?php } require("footer.php"); ?> With the address code complete, your browser should display a page similar to Figure 6-7—when a user is logged in. FIGURE 6-7 When the user is logged in, the radio buttons prompt users which address to use. 203 CHAPTER 6 Creating a Shopping Cart Paying The final part of the checkout process is to take payment. Dealing with payments on a Web site can take a variety of different routes: PayPal, NOCHEX, Worldpay, and more. This project offers two payment methods: PayPal and checks. These two meth- ods demonstrate how to deal with automatic (PayPal) and manual (check) purchases. Create a new file called checkout-pay.php and add the form: <h2>Select a payment method</h2> <form action='checkout-pay.php' method='POST'> <table cellspacing=10> <tr> <td><h3>PayPal</h3></td> <td> This site uses PayPal to accept Switch/Visa/Mastercard cards. No PayPal account is required - you simply fill in your credit card details and the correct payment will be taken from your account. </td> <td><input type="submit" name="paypalsubmit" value="Pay with PayPal"></td> </tr> <tr> <td><h3>Cheque</h3></td> <td> If you would like to pay by cheque, you can post the cheque for the final amount to the office. </td> <td><input type="submit" name="chequesubmit" value="Pay by cheque"></td> </tr> </table> </form> This simple form provides two Submit buttons only—one to pay by PayPal and the other to pay by check. Processing the form involves two main sections—one for PayPal and one for the check. At the top of the file, begin adding the code: <?php session_start(); require("db.php"); require("functions.php"); If the user clicks the PayPal button, process the order: require("functions.php"); 204 Practical PHP and MySQL if($_POST['paypalsubmit']) { $upsql = "UPDATE orders SET status = 2, payment _type = 1 WHERE id = " . $_SESSION['SESS_ORDERNUM']; $upres = mysql_query($upsql); $itemssql = "SELECT total FROM orders WHERE id = " . $_SESSION['SESS_ORDERNUM']; $itemsres = mysql_query($itemssql); $row = mysql_fetch_assoc($itemsres); The orders table is updated to reflect the completion of the order. The status field is changed to 2 and the payment_type field is set to 1 (PayPal). A query then gets the total price from the order so that the PayPal link can be constructed later. Reset the order session: $row = mysql_fetch_assoc($itemsres); if($_SESSION['SESS_LOGGEDIN']) { unset($_SESSION['SESS_ORDERNUM']); } else { session_register("SESS_CHANGEID"); $_SESSION['SESS_CHANGEID'] = 1; } If the user is logged in, the SESS_ORDERNUM session variable is removed with unset(). If not, a new session variable called SESS_CHANGEID is created. The next time header.php is loaded, the code at the top of header.php will regenerate the new session and id. Redirect to www.paypal.com with the payment details: $_SESSION['SESS_CHANGEID'] = 1; } header("Location: https://www.paypal.com/ cgi-bin/webscr?cmd=_xclick&business= you%40youraddress.com&item_name=" . urlencode($config_sitename) . "+Order&item_number=PROD" . $row['id'] ."&amount=" . urlencode(sprintf('%.2f', $row['total'])) . "&no_note=1¤cy_code=GBP&lc=GB& submit.x=41&submit.y=15"); } [...]... information on the front page 227 228 Practical PHP and MySQL Create a file called index .php and add the following code: < ?php require(“config .php ); require(“functions .php ); One of the planned features for index .php is to list a range of categories that users can click to see the items in that category To create this functionality, the categories are listed as a series of links, and each link is passed the... Shopping Cart < ?php } else { require("header .php" ); echo "Payment"; showcart(); ?> Select a payment method Finally, add the closing code: < ?php } require("footer .php" ); ?> Your brand-new, home-grown payment screen should now resemble Figure 6-8 FIGURE 6-8 The finished payment screen 207 208 Practical PHP and MySQL ADMINISTRATOR... purchased, payment method, and so on) Create a new file called adminorderdetails .php and add the following code: < ?php session_start(); require("config .php" ); require("functions .php" ); if(isset($_SESSION['SESS_ADMINLOGGEDIN']) == FALSE) { header("Location: " $basedir); } $validid = pf_validate_number($_GET['id'], "redirect", $config_basedir "adminorders .php" ); require("header .php" ); echo "Order Details";... href=’logout .php >Logout”; } else { echo “Login”; } ?> New Item < ?php require(“bar .php ); ?> This header file is virtually identical to the ones you created in previous projects Create footer .php, as shown in Example 7-3 EXAMPLE 7-3 The footer code for the site © < ?php echo “ 2 15 216 Practical PHP and MySQL This code should look familiar you to you; it simply displays details from the orders, orderitems, and delivery_addresses tables The completed page should look like the one shown in Figure 6-10 FIGURE 6-10 The order summary in the... deadline are displayed The user can register and log in to the site The user can view an item—complete with pictures and place a bid The users can add items—complete with pictures—to the site When an auction is complete, the owner of the item and the winning bidder receive email messages that include the details of the closing auction 219 220 Practical PHP and MySQL From the outset, an auction site seems... 223 224 Practical PHP and MySQL EXAMPLE 7-2 Continued < ?php echo $config_forumsname; ?> BidTastic Auctions Home < ?php if(isset($_SESSION[‘USERNAME’])... if($row['payment_type'] == 1) { 211 212 Practical PHP and MySQL echo "PayPal"; } else { echo "Cheque"; } echo ""; echo "Confirm Payment"; echo ""; } echo ""; } } require("footer .php" ); ?> If all went well, the completed orders summary should look similar to the page shown Figure 6-9 FIGURE 6-9 The outstanding orders page provides... value="Log in"> < ?php } require("footer .php" ); ?> Much of this code should look familiar to you When the admin has successfully logged in, the SESS_ADMINLOGGEDIN variable is created Logging Out the Administrator To log out the administrator, create a file called adminlogout .php and add the following code: < ?php session_start(); require("config .php" ); session_unregister("SESS_ADMINLOGGEDIN");... bid made for particular item), and the images table (to store images added to the items) Implementing the Database Fire up phpMyAdmin Create a new database called auction and add the following tables: The categories Table ■ id Make this a TINYINT (there will not be many categories) and turn on in the Extras column Make this field a primary key cat Make this a VARCHAR and set the size to 20 It is unlikely . the orderitems table, and the total price in the orders table is updated. Create delete .php and begin adding the code: < ?php require("config .php& quot;); require("db .php& quot;); require("functions .php& quot;); $validid. "checkout-pay .php& quot;); } } 202 Practical PHP and MySQL In this block of code, the address is added to the delivery_addresses table, and the orders table is updated with the delivery_addresses id and. code: < ?php session_start(); require("db .php& quot;); require("functions .php& quot;); If the user clicks the PayPal button, process the order: require("functions .php& quot;); 204 Practical PHP and MySQL if($_POST['paypalsubmit']) { $upsql