PHP-Finalizing Orders

PHP-Finalizing Orders

New Page 1

PHP-Finalizing Orders
When a user finishes adding items to his cart, he usually proceeds to a purchase. Finalizing an order requires several steps that include checking that sufficient inventory is available to complete the order, converting the shopping cart to an order, and deducting the wines sold from the inventory. These tasks require locking of the database and are examples of moderately complex query processing. The script order.3 shown in Example 12-1 performs these tasks.

The script works as follows:

It tests that the user is logged in and that the cart has contents. These tests should never fail, as the Make Purchase button is shown only when the user is viewing the cart, is logged in, and the cart has contents. If either test fails, an error message is registered, and the script redirects to the calling script.

The inventory, items, and orders tables are locked for writing, and the users and customer tables are locked for reading. The inventory, items, and orders tables are all updated in the purchasing process, and they must be locked because the inventory is first checked to ensure that sufficient quantities of wine are available and then later updated. Without locking, it is possible for another user to purchase the wine while this script is running, resulting in more wine being sold than is in stock. This is an example of the dirty read concurrency problem discussed in Chapter 6, and locking must be used to avoid the problem.

Each item in the cart is then processed, and the inventory is checked to ensure that enough wine is available. If no wine is available—the count( ) of the matching inventory rows is zero—an error message is registered. Similarly, if less wine is available than the user wants—the sum( ) of the on_hand quantity of the matching rows is less than the user’s cart qty—an error message is also registered. On error, the script also updates the user’s cart so that the quantity (qty) of wine in the user’s cart matches the quantity that is on_hand. In the case of an error, the script uses the function showWine( ) to show the user the details of the wine. This function opens its own connection to the DBMS so that the wine, wine_variety, winery, and grape_variety tables don’t need to be locked for reading in the order.

If the inventory checks succeed, the script proceeds to convert the user’s cart to be a customer’s order. This process is straightforward:

Determine the cust_id from the loginUsername session variable using the function getCustomerID( ).

Find the maximum order_id for this customer.

Update the orders and items rows by replacing the cust_id of -1 with the customer’s cust_id and the order_id with the next available order_id for this customer.

After the database has been updated, the cart is emptied using session_unregister( ) to remove the order_no session variable.

Having completed the order and checked the inventory, the script finishes the ordering process by reducing the inventory. This can never fail, since all required tables are locked, and you’ve checked that sufficient quantities are available. The process is similar to checking the cart: you iterate through each item and, for each one, you update the inventory. The inventories are processed from oldest to newest. Consider an example in which the user wants to purchase 24 bottles of a wine. There are two inventories of this wine: the first has 13 bottles and was added in May 2000; the second has 25 bottles and was added in September 2001. To satisfy the order, the oldest inventory of 13 bottles is emptied and deleted, and the second inventory is reduced by 11 bottles.

With the process complete, the tables are unlocked. If there are no errors, the script redirects to the shipping.1 script to confirm the order, and the cust_id and order_id are passed as GET method parameters. If there are errors, the user is returned to the cart view page.

Example 12-1. order.3 finalizes the user’s purchase
<?php
// This script finalizes a purchase
// It expects that a cart has contents and that the
// user is logged in

include ‘include.inc’;

set_error_handler(”errorHandler”);

// Re-establish the existing session
session_start( );

// Check if a cart exists – this should never fail
// unless the script is run directly
if (!session_is_registered(”order_no”))
{
session_register(”message”);
$message =
“There are no items in your shopping cart!”;

// Redirect the browser back to the calling page
header(”Location: $HTTP_REFERER”);
exit;
}

// Check if the user is logged in – this should
// never fail unless the script is run directly
if (!session_is_registered(”loginUsername”))
{
session_register(”message”);
$message =
“You must login to finalize your purchase.”;

// Redirect the browser back to the calling page
header(”Location: $HTTP_REFERER”);
exit;
}

// Open a connection to the DBMS
if (!($connection = @ mysql_pconnect($hostName,
$username,
$password)))
showerror( );

if (!mysql_select_db($databaseName, $connection))
showerror( );

// Several tables must be locked to finalize a purchase.
// We avoid locking four other tables by
// using another DBMS connection to produce the wine
// information
$query = “LOCK TABLES inventory WRITE,
orders WRITE,
items WRITE,
users READ,
customer READ”;

// LOCK the tables
if (!(@ mysql_query ($query, $connection)))
showerror( );

// Process each wine in the cart and find out if
// there is sufficient stock available in the inventory
$query = “SELECT * FROM items
WHERE cust_id = -1
AND order_id = $order_no”;

// Initialise an empty error message
$message = “”;

if (!($result = @ mysql_query ($query, $connection)))
showerror( );

// Get the next wine in the cart
for ($winesInCart = 0;
$winesInCart < mysql_num_rows($result);
$winesInCart++)
{
$cartRow[$winesInCart] = @ mysql_fetch_array($result);

// Is there enough of this wine on hand?
$query = “SELECT COUNT(on_hand), SUM(on_hand)
FROM inventory
WHERE wine_id = ” .
$cartRow[$winesInCart]["wine_id"];

if (!($stockResult = @ mysql_query ($query,
$connection)))
showerror( );

$on_hand = @ mysql_fetch_array($stockResult);

if ($on_hand["COUNT(on_hand)"] == 0)
$available = 0;
else
$available = $on_hand["SUM(on_hand)"];

// Is there more wine in the cart than is for sale?
if ($cartRow[$winesInCart]["qty"] > $available)
{
if (!session_is_registered(”message”))
session_register(”message”);

if ($available == 0)
$message .= “Sorry! We just sold out of ” .
showWine($cartRow[$winesInCart]["wine_id"],
NULL) .
“\n<br>”;
else
$message .= “Sorry! We only have ” .
$on_hand["SUM(on_hand)"] .
” bottles left of ” .
showWine($cartRow[$winesInCart]["wine_id"],
NULL) .
“\n<br>”;

// Update the user’s quantity to match the
// available amount
$query = “UPDATE items
SET qty = ” . $available .
” WHERE cust_id = -1
AND order_id = $order_no
AND item_id = ” .
$cartRow[$winesInCart]["item_id"];

if (!(@ mysql_query ($query, $connection)))
showerror( );
}
} // for $winesInCart < mysql_num_rows($result);

// We have now checked if there is enough wine
// available.
// If there is, we can proceed with the order.
// If not, we send the user back to the amended
// cart to think about purchasing the lesser
// amount.

if (empty($message))
{
// Everything is ok – let’s proceed then!
// First of all, find out the user’s cust_id and
// the next available order_id for this customer.
$custID = getCustomerID($loginUsername, NULL);

$query = “SELECT max(order_id)
FROM orders
WHERE cust_id = $custID”;

if (($result = @ mysql_query ($query, $connection)))
$row = mysql_fetch_array($result);
else
showerror( );

$newOrder_no = $row["max(order_id)"] + 1;

// Now, change the cust_id and order_id of their cart!
$query = “UPDATE orders
SET cust_id = $custID , ” .
“order_id = ” . $newOrder_no .
” WHERE order_id = $order_no”;

if (!(@ mysql_query ($query, $connection)))
showerror( );

$query = “UPDATE items
SET cust_id = $custID , ” .
“order_id = ” . $newOrder_no .
” WHERE order_id = $order_no”;

if (!(@ mysql_query ($query, $connection)))
showerror( );

// Officially empty the cart
session_unregister(”order_no”);

// Now we have to do the inventory.
// We do this one cart item at a time.
// For all items, we know that there *is*
// sufficient inventory, since we’ve checked earlier
foreach($cartRow as $currentRow)
{
// Find the inventories for this wine, oldest first
$query = “SELECT inventory_id, on_hand
FROM inventory
WHERE wine_id = ” .
$currentRow["wine_id"] .
” ORDER BY date_added”;

if (!($result = @ mysql_query ($query,
$connection)))
showerror( );

// While there are still bottles to be deducted
while($currentRow["qty"] > 0)
{
// Get the next-oldest inventory
$row = @ mysql_fetch_array($result);

// Is there more wine in this inventory than
// the user wants?
if ($row["on_hand"] > $currentRow["qty"])
{
// Reduce the inventory by the amount the
// user ordered
$query = “UPDATE inventory
SET on_hand = on_hand – ” .
$currentRow["qty"] .
” WHERE wine_id = ” .
$currentRow["wine_id"] .
” AND inventory_id = ” .
$row["inventory_id"];

// The user doesn’t need any more of this
// wine
$currentRow["qty"] = 0;
}
else
{
// Remove the inventory – we sold the
// remainder to this user
$query = “DELETE FROM inventory
WHERE wine_id = ” .
$currentRow["wine_id"] .
” AND inventory_id = ” .
$row["inventory_id"];

// This inventory reduces the customer’s
// required amount by at least 1, but
// we need to process more inventory
$currentRow["qty"] -= $row["on_hand"];
}

// UPDATE or DELETE the inventory
if (!(@ mysql_query ($query, $connection)))
showerror( );
}
}
}
else
$message .= “\n<br>The quantities in your cart ” .
“have been updated\n.”;

// Last, UNLOCK the tables
$query = “UNLOCK TABLES”;
if (!(@ mysql_query ($query, $connection)))
showerror( );

// Redirect to the email confirmation page if
// everything is ok
// (supply the custID and orderID to the script)
// otherwise go back to the cart page and show a message
if (empty($message))
{
header(”Location: example.shipping.1.php?” .
“custID=$custID&orderID=$newOrder_no”);
exit;
}
else
header(”Location: example.cart.2.php”);
?>

More PHP Tutorial

Watch the video related to Php Scripts

Help answer the question about Php Scripts

how to test PHP scripts ?
Hi,
Can anyone please tell me how to test any PHP scripts ?
And I would really appreciate if you gave me any good PHP tutorial links.
Thanks,
Sarah
Thank you so much all :)

About Author

PHP Tutorial

18 Responses to “PHP-Finalizing Orders”

  1. monkeymanbob says:

    Nice work, you did pretty good.

  2. champ0y says:

    You’re really good man. You’ve got excellent talent.

  3. superchode20164 says:

    amazing! Willy teach me how to paint like you!

  4. relientkfan153 says:

    The "something" can be accessed very easily with PHP. If you have a web page address that looks like this:

    index.php? month=september&name=smith&age=24

    Then you can access those values in PHP like this:

    <?php
    echo $_GET('month');
    echo $_GET('name');
    echo $_GET('age');
    ?>

    This will print septembersmith24.

    As for accessing a text file, that's easy too:

    <?php
    $text = file_get_contents( 'textfile.txt' );
    echo $text;
    ?>

    This will read the entire contents of the file textfile.txt into the variable $text, and then print it out for you.

    You can also access many databases with PHP, I highly recommend you use MySQL. It's a bit too complicated to describe here, though. There are some good references made to good books by folks above. The "Teach Yourself" series is great.

  5. Atticus says:

    You can use a menu maker if you're not sure how to code something on your own. There are a gazillion of them out there and many are even free. Pick one that suits you…

    http://www.google.com/search?source=ig&hl=en&rlz=&q=web+menu+maker&btnG=Google+Search

  6. Faithless863 says:

    hm i couldn’t tell the difference between photograph and painting comparing the final resault.

    This is sick

  7. Ars Magicana Arcanum says:

    Windows XP PRO has functionality for running a web server built in

    IIS is an option, however, under a "Default" installation of XP Pro, it might not be installed

    Control panel – > add / remove programs -> Add Remove Windows COmponents – Check "Internet Information Services"

    You could also look @ apache as has been mentioned, however, IIS is PART of windows.

  8. virgocrabtiger373 says:

    http://www.phpfreaks.com/tutorial_cat/8/Basics-&-Beginner-Tutorials.php

  9. ampersand1 says:

    http://www.phpfreaks.com

    If you are ready invest: Get Larry Ullman: 'PHP …" Nice book

  10. Mike says:

    Hi,

    Best Site to Learn PHP http://www.w3schools.com/php/default.asp

    I know this Answer Will solve your problem. Do one thing visit http://www.zakhas.com/Forum be a member first and Download 1800 Industry standard PHP Projects and source codes. Directly without any interrupting. Follow below link for direct access to the download link.http://www.zakhas.com/Forum/ViewThread.asp?Thread=161&Forum=26
    Definitly it will solve your problem. Download it BE Quick.

    Or you can try this sites below

    http://www.planetsourcecodes.com

    or

    http://www.scriptswave.com/free/scripts/php_scripts/9.html

    If you find this answer is best then you can choose it as best answer.

  11. Forbidia says:

    Brilliant Willy, Just Brilliant =D

  12. Sameer A says:

    http://www.elite.ro/free-hosting-php/
    http://www.awardspace.com/
    http://www.free-phphosts.com/
    http://www.freehostia.com/free_hosting.html

    Really what you need to run php is some one who also offers a sql database these do but I dont get the website builder thing?
    if your messing around with php why would you need a WYSIWYG builder?

  13. avb17018411 says:

    woww that’s really relax and beatiful soung .good picture of jhony depp !

  14. lidiabarbarita says:

    Very nice!!

  15. Simplicated says:

    If you have sensitive files that should be accessible only by scripts, put them somewhere on the server other than the web root. Your scripts will still be able to access them, but nobody can pull them off the web.

    /
    – /htdocs
    – — /www.site.com
    – /securedocs

  16. warah110 says:

    Perfect.

  17. TheTroubadourMusic says:

    :O

    :O

    :O

    how is this not a real photo?

  18. Jeremy H says:

    I don't think there is such a thing as a PHP emulator, and I don't know why you'd need one. It's likely that you either didn't install PHP and apache correctly or you aren't using it right.

    Use XAMPP to install PHP and apache. It will also include MySQL and phpMyAdmin (which you will need sooner or later) and some other good stuff too. It's much easier than trying to configure PHP and apache by hand. Best of all, it's all configured to run together immediately. XAMPP and all of its components are free and open source.
    http://www.apachefriends.org/en/xampp.html

    Once you've got a web server, you need to turn it on (that's not automatic.) There's a nice control panel that makes this easy with XAMPP. PHP files will only work if they're in a specific subdirectory (usually htdocs in the apache directory structure) Also, you can't just load a PHP file into the browser the same way you do an HTML file. Instead, you need to point the browser to
    http://localhost/yourFileName.php

    PHP is called by the server, so if you use a mechanism (like the file:// directive) that bypasses the server, your PHP programs won't run.

Leave a Reply