Index
    Preface
      What This Book Is About
      What You Need to Know
      How This Book Is Organized
      How to Use This Book
      Conventions Used in This Book
      Using Code Examples
      How to Contact Us
      Web Site and Code Examples
      Acknowledgments
      Chapter 1.  Database Applications and the Web
      Section 1.1.  The Web
      Section 1.2.  Three-Tier Architectures
      Chapter 2.  The PHP Scripting Language
      Section 2.1.  Introducing PHP
      Section 2.2.  Conditions and Branches
      Section 2.3.  Loops
      Section 2.4.  Functions
      Section 2.5.  Working with Types
      Section 2.6.  User-Defined Functions
      Section 2.7.  A Working Example
      Chapter 3.  Arrays, Strings, and Advanced Data Manipulation in PHP
      Section 3.1.  Arrays
      Section 3.2.  Strings
      Section 3.3.  Regular Expressions
      Section 3.4.  Dates and Times
      Section 3.5.  Integers and Floats
      Chapter 4.  Introduction to Object-Oriented Programming with PHP 5
      Section 4.1.  Classes and Objects
      Section 4.2.  Inheritance
      Section 4.3.  Throwing and Catching Exceptions
      Chapter 5.  SQL and MySQL
      Section 5.1.  Database Basics
      Section 5.2.  MySQL Command Interpreter
      Section 5.3.  Managing Databases and Tables
      Section 5.4.  Inserting, Updating, and Deleting Data
      Section 5.5.  Querying with SQL SELECT
      Section 5.6.  Join Queries
      Section 5.7.  Case Study: Adding a New Wine
      Chapter 6.  Querying Web Databases
      Section 6.1.  Querying a MySQL Database Using PHP
      Section 6.2.  Processing User Input
      Section 6.3.  MySQL Function Reference
      Chapter 7.  PEAR
      Section 7.1.  Overview
      Section 7.2.  Core Components
      Section 7.3.  Packages
      Chapter 8.  Writing to Web Databases
      Section 8.1.  Database Inserts, Updates, and Deletes
      Section 8.2.  Issues in Writing Data to Databases
      Chapter 9.  Validation with PHP and JavaScript
      Section 9.1.  Validation and Error Reporting Principles
      Section 9.2.  Server-Side Validation with PHP
      Section 9.3.  JavaScript and Client-Side Validation
      Chapter 10.  Sessions
      Section 10.1.  Introducing Session Management
      Section 10.2.  PHP Session Management
      Section 10.3.  Case Study: Using Sessions in Validation
      Section 10.4.  When to Use Sessions
      Section 10.5.  PHP Session API and Configuration
      Chapter 11.  Authentication and Security
      Section 11.1.  HTTP Authentication
      Section 11.2.  HTTP Authentication with PHP
      Section 11.3.  Form-Based Authentication
      Section 11.4.  Protecting Data on the Web
      Chapter 12.  Errors, Debugging, and Deployment
      Section 12.1.  Errors
      Section 12.2.  Common Programming Errors
      Section 12.3.  Custom Error Handlers
      Chapter 13.  Reporting
      Section 13.1.  Creating a Report
      Section 13.2.  Producing PDF
      Section 13.3.  PDF-PHP Reference
      Chapter 14.  Advanced Features of Object-Oriented Programming in PHP 5
      Section 14.1.  Working with Class Hierarchies
      Section 14.2.  Class Type Hints
      Section 14.3.  Abstract Classes and Interfaces
      Section 14.4.  Freight Calculator Example
      Chapter 15.  Advanced SQL
      Section 15.1.  Exploring with SHOW
      Section 15.2.  Advanced Querying
      Section 15.3.  Manipulating Data and Databases
      Section 15.4.  Functions
      Section 15.5.  Automating Querying
      Section 15.6.  Table Types
      Section 15.7.  Backup and Recovery
      Section 15.8.  Managing Users and Privileges
      Section 15.9.  Tuning MySQL
      Chapter 16.  Hugh and Dave's Online Wines:A Case Study
      Section 16.1.  Functional and System Requirements
      Section 16.2.  Application Overview
      Section 16.3.  Common Components
      Chapter 17.  Managing Customers
      Section 17.1.  Code Overview
      Section 17.2.  Customer Validation
      Section 17.3.  The Customer Form
      Chapter 18.  The Shopping Cart
      Section 18.1.  Code Overview
      Section 18.2.  The Winestore Home Page
      Section 18.3.  The Shopping Cart Implementation
      Chapter 19.  Ordering and Shipping at the Online Winestore
      Section 19.1.  Code Overview
      Section 19.2.  Credit Card and Shipping Instructions
      Section 19.3.  Finalizing Orders
      Section 19.4.  HTML and Email Receipts
      Chapter 20.  Searching and Authentication in the Online Winestore
      Section 20.1.  Code Overview
      Section 20.2.  Searching and Browsing
      Section 20.3.  Authentication
      Appendix A.  Linux Installation Guide
      Section A.1.  Finding Out What's Installed
      Section A.2.  Installation Overview
      Section A.3.  Installing MySQL
      Section A.4.  Installing Apache
      Section A.5.  Installing PHP
      Section A.6.  What's Needed for This Book
      Appendix B.  Microsoft Windows Installation Guide
      Section B.1.  Installation Overview
      Section B.2.  Installing with EasyPHP
      Section B.3.  What's Needed for This Book
      Appendix C.  Mac OS X Installation Guide
      Section C.1.  Getting Started
      Section C.2.  Installing MySQL
      Section C.3.  Setting Up Apache and PHP
      Section C.4.  What's Needed for This Book
      Appendix D.  Web Protocols
      Section D.1.  Network Basics
      Section D.2.  Hypertext Transfer Protocol
      Appendix E.  Modeling and Designing Relational Databases
      Section E.1.  The Relational Model
      Section E.2.  Entity-Relationship Modeling
      Appendix F.  Managing Sessions in theDatabase Tier
      Section F.1.  Using a Database to Keep State
      Section F.2.  PHP Session Management
      Section F.3.  MySQL Session Store
      Appendix G.  Resources
      Section G.1.  Client Tier Resources
      Section G.2.  Middle-Tier Resources
      Section G.3.  Database Tier Resources
      Section G.4.  Security and Cryptography Resources
      Appendix H.  The Improved MySQL Library
      Section H.1.  New Features
      Section H.2.  Getting Started
      Section H.3.  Using the New Features
    Colophon
    Copyright



 

Previous Section  < Day Day Up >  Next Section

19.4 HTML and Email Receipts

After an order has been processed, the winestore application confirms the shipping of the wines through both an email and an HTML receipt. The order/order-step4.php script sends the user an email. In turn, the order/order-step4.php script redirects to the order/receipt.php script which produces the HTML receipt.

The HTML receipt can be visited again at a later time by bookmarking the URL. As it carries out no database updates, it doesn't suffer from the reload problem described in Chapter 6. The receipt functionality is separated into two scripts so that returning to the HTML receipt doesn't cause an additional email receipt to be sent to the customer.

19.4.1 Email Receipt

Example 19-4 shows the order/order-step4.php script that sends an email receipt to the user. The function send_confirmation_email( ) creates the email body, destination address, subject, and additional headers of an email message, and then sends that email message. To do so, it uses the template that's shown in Example 19-5 and stored in the file templates/email.tpl.

Example 19-4. The order/order-step4.php script sends an order confirmation as an email
<?php

// This script sends the user a confirmation email for their order

// and then redirects to an HTML receipt version



// By default, this script uses PEAR's Mail package.

// To use PHP's internal mail( ) function instead, change "true" to "false"

// in the following line

define("USE_PEAR", true);



require_once "DB.php";

require_once "HTML/Template/ITX.php";

require_once "../includes/winestore.inc";

require_once "../includes/authenticate.inc";



// Use the PEAR Mail package if USE_PEAR is defined

if (USE_PEAR == true)

  require_once "Mail.php";



set_error_handler("customHandler");



// Send the user an email that summarises their purchase

function send_confirmation_email($custID, $orderID, $connection)

{

   $template = new HTML_Template_ITX(D_TEMPLATES);

   $template->loadTemplatefile(T_EMAIL, true, true);



   // Find customer information

   $query = "SELECT * FROM customer, users

            WHERE customer.cust_id = {$custID}

            AND users.cust_id = customer.cust_id";



   $result = $connection->query($query);

   if (DB::isError($result))

      trigger_error($result->getMessage( ), E_USER_ERROR);

   $row = $result->fetchRow(DB_FETCHMODE_ASSOC);



   // Start by setting up the "To:" email address

   $to = "{$row["firstname"]} {$row["surname"]} <{$row["user_name"]}>";



   // Now setup all the customer fields

   $template->setVariable("TITLE", showTitle($row["title_id"],

                          $connection));

   $template->setVariable("SURNAME", $row["surname"]);

   $template->setVariable("CUST_ID", $custID);

   $template->setVariable("ORDER_ID", $orderID);

   $template->setVariable("FIRSTNAME", $row["firstname"]);

   $template->setVariable("INITIAL", $row["initial"]);

   $template->setVariable("ADDRESS", $row["address"]);

   $template->setVariable("CITY", $row["city"]);

   $template->setVariable("STATE", $row["state"]);

   $template->setVariable("COUNTRY", showCountry($row["country_id"],

                          $connection));

   $template->setVariable("ZIPCODE", $row["zipcode"]);



   $orderTotalPrice = 0;



   // list the particulars of each item in the order

   $query = "SELECT  i.qty, w.wine_name, i.price,

                     w.wine_id, w.year, wi.winery_name

             FROM    items i, wine w, winery wi

             WHERE   i.cust_id = {$custID}

             AND     i.order_id = {$orderID}

             AND     i.wine_id = w.wine_id

             AND     w.winery_id = wi.winery_id

             ORDER BY item_id";



   $result = $connection->query($query);

   if (DB::isError($result))

      trigger_error($result->getMessage( ), E_USER_ERROR);



   // Add each item to the email

   while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))

   {

     // Work out the cost of this line item

     $itemsPrice = $row["qty"] * $row["price"];



     $orderTotalPrice += $itemsPrice;



     $wineDetail = showWine($row["wine_id"], $connection);



     $template->setCurrentBlock("row");

     $template->setVariable("QTY", str_pad($row["qty"],9));

     $template->setVariable("WINE",

                             str_pad(substr($wineDetail, 0, 53), 55));

     $template->setVariable("PRICE",

                            str_pad(sprintf("$%4.2f" ,

                            $row["price"]), 11));

     $template->setVariable("TOTAL",

                            str_pad(sprintf("$%4.2f", $itemsPrice), 12));

     $template->parseCurrentBlock("row");

   }



   $template->setCurrentBlock("items");

   $template->setVariable("ORDER_TOTAL",

                          sprintf("$%4.2f\n", $orderTotalPrice));

   $template->parseCurrentBlock("items");

   $template->setCurrentBlock( );

   $template->parseCurrentBlock( );



   $out = $template->get( );



   if (USE_PEAR == false)

   {

     // --------------------------------------------

     // The internal PHP mail( ) function is used only if USE_PEAR is false



     // Now, setup the "Subject:" line

     $subject = "Hugh and Dave's Online Wines: Order Confirmation";



     // And, last (before we build the email), set up some mail headers

     $headers  = "From: Hugh and Dave's Online Wines " .

                 "<help@webdatabasebook.com>\r\n";

     $headers .= "X-Sender: <help@webdatabasebook.com>\r\n";

     $headers .= "X-Mailer: PHP\r\n";

     $headers .= "Return-Path: <help@webdatabasebook.com>\r\n";



     // Send the email!

     mail($to, $subject, $out, $headers);

     // --------------------------------------------

   }

   else

   {

     // --------------------------------------------

     // Use the PEAR Mail package and SMTP since USE_PEAR is true



     // Now, setup the "Subject:" line

     $headers["Subject"] = 

       "Hugh and Dave's Online Wines: Order Confirmation";



     // And, last (before we build the email), set up some mail headers

     $headers["From"] = "Hugh and Dave's Online Wines " .

                        "<help@webdatabasebook.com>";

     $headers["X-Sender"] = "<help@webdatabasebook.com>";

     $headers["X-Mailer"] = "PHP";

     $headers["Return-Path"] = "<help@webdatabasebook.com>";



     $smtpMail =& Mail::factory("smtp");

     $smtpMail->send($to, $headers, $out);

     // --------------------------------------------

   }

}



// ----------



session_start( );



// Connect to a authenticated session

sessionAuthenticate(S_SHOWCART);



// Check the correct parameters have been passed

if (!isset($_GET["cust_id"]) || !isset($_GET["order_id"]))

{

   $_SESSION["message"] =

     "Incorrect parameters to order-step4.php";

   header("Location: " . S_SHOWCART);

   exit;

}



// Check this customer matches the $cust_id

$connection = DB::connect($dsn, true);



if (DB::isError($connection))

   trigger_error($connection->getMessage( ), E_USER_ERROR);



$cust_id = pearclean($_GET, "cust_id", 5, $connection);

$order_id = pearclean($_GET, "order_id", 5, $connection);



$real_cust_id = getCust_id($_SESSION["loginUsername"]);



if ($cust_id != $real_cust_id)

   $_SESSION["message"] = "You can only view your own receipts!";

   header("Location: " . S_HOME);

   exit;

}



// Send the user a confirmation email

send_confirmation_email($cust_id, $order_id, $connection);



// Redirect to a receipt page (this can't be the receipt page,

// since the reload problem would cause extra emails).

header("Location: " . S_ORDERRECEIPT .

       "?cust_id={$cust_id}&order_id={$order_id}");

?>

Example 19-5. The template templates/email.tpl that's used to compose an email receipt
Dear {TITLE} {SURNAME},



Thank you for placing an order at Hugh and Dave's Online Wines. This email

is best viewed in a fixed-width font such as Courier.



Your fictional order (reference # {CUST_ID} - {ORDER_ID}) has been

dispatched. Please quote this number in any correspondence.



If it existed, the order would have been shipped to:

{TITLE} {FIRSTNAME} {INITIAL} {SURNAME}

{ADDRESS}

{CITY} {STATE}

{COUNTRY} {ZIPCODE}



We have billed your fictional SurchargeCard credit card.



Your fictional order contains:

<!-- BEGIN items -->

Quantity Wine                                             Unit Price Total

<!-- BEGIN row -->

{QTY}{WINE}{PRICE}{TOTAL}

<!-- END row -->

Total of this order: {ORDER_TOTAL}

<!-- END items -->



Thank you for shopping at Hugh and Dave's Online Wines!



Kind Regards,





Hugh and Dave, http://www.webdatabasebook.com/

The destination $to address is created using the firstname, surname, and user_name (which is the email address) attributes of the customer that are retrieved from the customer and users tables. For example, with a surname value of Smith, a firstname of Michael, and a user_name of mike@webdatabasebook.com, it has the following format:

Michael Smith <mike@webdatabasebook.com>

The additional email headers are static and always have the following format:

From: "Hugh and Dave's Online Wines" <help@webdatabasebook.com>

X-Sender: <help@webdatabasebook.com>

X-Mailer: PHP

Return-Path: <help@webdatabasebook.com>

The subject of the email is always:

Hugh and Dave's Online Wines: Order Confirmation

The body of the message is created by querying and retrieving the details of the customer, orders, and items tables and setting variables in the template. The following is an example of the body of a confirmation email:

Dear Dr Smith,

  

Thank you for placing an order at Hugh and Dave's Online Wines. This email

is best viewed in a fixed-width font such as Courier.

 

Your fictional order (reference # 651 - 12) has been

dispatched. Please quote this number in any correspondence.

 

If it existed, the order would be shipped to:

 

Dr Michael Smith

12 Hotham St.

Collingwood Victoria 3066

Australia

 

We have billed your fictional SurchargeCard credit card.



Your fictional order contains:



Quantity  Wine                           Unit Price  Total

12        1999 Smith's Chardonnay        $22.25      $267.00



Total: $267.00



Thank you for shopping at Hugh and Dave's Online Wines!



Kind Regards,





Hugh and Dave, http://www.webdatabasebook.com/

In our template examples so far, the HTML_Template_IT::show( ) method is used to output data to the browser. However, in this case, we don't want to output the data to the browser and so we use the HTML_Template_IT::get( ) method instead. This method returns the template as a string after all placeholder replacements have been made, and we assign the return value to the variable $out. The variable is used as a parameter to the mailing method. The HTML_Template_IT::get( ) method is described in Chapter 7.

The email itself is sent using the PEAR Mail package with the following fragment:

$smtpMail =& Mail::factory("smtp");

$smtpMail->send($to, $headers, $out);

The Mail class supports three different ways of sending email, and we use a Simple Mail Transfer Protocol (SMTP) server in this example to send the email. The class is discussed in the next section.

The body of the script also checks that the user is logged in, that the correct parameters of a cust_id and an order_id have been provided, and that the user viewing the receipt is the owner of the receipt. If any of the checks fail, the user is redirected so that an error message can be displayed.

19.4.1.1 The PEAR Mail package

The PEAR Mail package is used to send the order confirmation receipt by connecting to an SMTP server. PEAR Mail works well, but requires that you install the Mail package by following the package installation instructions in Chapter 7. If you don't want to use the PEAR Mail package, then change the define( ) at beginning of the file order/order-step4.php shown in Example 19-4 to:

define("USE_PEAR", false);

When PEAR Mail isn't used, the PHP library function mail( ) is used instead. Without additional configuration, mail( ) only works on Unix platforms.

After installation, using PEAR's Mail package requires only two simple steps: first, create an instance of a mailer backend; and, second, send the email. There are three choices of backends:


Simple Mail Transfer Protocol (SMTP) server

This is most generic approach, as it doesn't rely on having specific software installed on the web server, and is portable across all PHP platforms. The disadvantage is that it requires an SMTP server, and these sometimes require username and password credentials, or can be configured in a non-standard way.


The internal PHP mail( ) function

Without additional configuration, this only works on Unix platforms. Under Microsoft Windows, it needs to be configured to use an SMTP-based approach.


The Unix sendmail program

This only works on Unix platforms. (It also supports other mail sending programs that have a wrapper that makes them look like sendmail).

We create the backend in our code using:

$smtpMail =& Mail::factory("smtp");

However, the Mail::factory( ) method for the SMTP mailer also supports an optional second array parameter $params that can contain the following associative elements:


$params["host"]

The host name of the SMTP server. It's set to localhost by default.


$params["post"]

The port number of the SMTP server. Set to 25 by default.


$params["auth"]

Whether to use SMTP authentication. Set to false by default.


$params["username"]

The username to use for authentication. No default value.


$params["password"]

The password to use for authentication. No default value.

In general, the defaults work for most Unix installations. If you don't have a mailer installed on your server or you're using Microsoft Windows, then try setting $params["host"] to your ISP's mail server. For example, if you were a customer of bigpond.com, you would use:

$params["host"] = "mail.bigpond.com";

$smtpMail =& Mail::factory("smtp", $params);

If you want to use PHP's internal mail( ) function with PEAR Mail, then use:

$smtpMail =& Mail::factory("mail");

$smtpMail->send($to, $headers, $out);

It has no additional parameters.

If you want to use the Unix sendmail backend, then use:

$smtpMail =& Mail::factory("sendmail");

$smtpMail->send($to, $headers, $out);

The factory( ) method for the sendmail mailer also supports the optional second array parameter $params that can contain the following associative elements:


$params["sendmail_path"]

The path to the sendmail program. By default it's /usr/bin/sendmail.


$params["sendmail_args"]

Additional arguments to the sendmail program. There's none by default.

19.4.2 HTML Receipts

Example 19-6 shows the order/receipt.php script that confirms the shipping of an order using HTML. The script has an identical structure to order/order-step4.php and executes the same queries. The only difference is that the script outputs HTML rather than creating a template that's emailed to the customer. The template that's used with the script is shown in Example 19-7; as with other templates in the winestore, the winestoreTemplate class that's explained in Chapter 16 is used to display the page.

Example 19-6. The order/receipt.php script confirms an order as an HTML receipt
<?php

// This script shows the user an HTML receipt



require_once "DB.php";

require_once "../includes/template.inc";

require_once "../includes/winestore.inc";

require_once "../includes/authenticate.inc";



set_error_handler("customHandler");



function show_HTML_receipt($custID, $orderID, $connection)

{

   $template = new winestoreTemplate(T_ORDERRECEIPT);



   // Find customer information

   $query = "SELECT * FROM customer, users

             WHERE customer.cust_id = {$custID}

             AND users.cust_id = customer.cust_id";

   $result = $connection->query($query);

   if (DB::isError($result))

      trigger_error($result->getMessage( ), E_USER_ERROR);



   $row = $result->fetchRow(DB_FETCHMODE_ASSOC);



   // Now setup all the customer fields

   $template->setVariable("CUSTTITLE", showTitle($row["title_id"],

                          $connection));

   $template->setVariable("SURNAME", $row["surname"]);

   $template->setVariable("CUST_ID", $custID);

   $template->setVariable("ORDER_ID", $orderID);

   $template->setVariable("FIRSTNAME", $row["firstname"]);

   $template->setVariable("INITIAL", $row["initial"]);

   $template->setVariable("ADDRESS", $row["address"]);

   $template->setVariable("CITY", $row["city"]);

   $template->setVariable("STATE", $row["state"]);

   $template->setVariable("COUNTRY", showCountry($row["country_id"],

                          $connection));

   $template->setVariable("ZIPCODE", $row["zipcode"]);



   $orderTotalPrice = 0;



   // list the particulars of each item in the order

   $query = "SELECT  i.qty, w.wine_name, i.price,

                     w.wine_id, w.year, wi.winery_name

             FROM    items i, wine w, winery wi

             WHERE   i.cust_id = {$custID}

             AND     i.order_id = {$orderID}

             AND     i.wine_id = w.wine_id

             AND     w.winery_id = wi.winery_id

             ORDER BY item_id";



   $result = $connection->query($query);

   if (DB::isError($result))

      trigger_error($result->getMessage( ), E_USER_ERROR);



   // Add each item to the page

   while ($row = $result->fetchRow(DB_FETCHMODE_ASSOC))

   {

     // Work out the cost of this line item

     $itemsPrice = $row["qty"] * $row["price"];



     $orderTotalPrice += $itemsPrice;



     $wineDetail = showWine($row["wine_id"], $connection);



     $template->setCurrentBlock("row");

     $template->setVariable("QTY", $row["qty"]);

     $template->setVariable("WINE", $wineDetail);

     $template->setVariable("PRICE",

                            sprintf("$%4.2f" , $row["price"]), 11);

     $template->setVariable("TOTAL", sprintf("$%4.2f", $itemsPrice));

     $template->parseCurrentBlock("row");

   }



   $template->setCurrentBlock("items");

   $template->setVariable("ORDER_TOTAL",

                          sprintf("$%4.2f\n", $orderTotalPrice));

   $template->parseCurrentBlock("items");

   $template->setCurrentBlock( );



   $template->showWinestore(NO_CART, B_HOME);

}



// ----------



session_start( );



// Connect to a authenticated session

sessionAuthenticate(S_SHOWCART);



// Check the correct parameters have been passed

if (!isset($_GET["cust_id"]) || !isset($_GET["order_id"]))

{

   $_SESSION["message"] =

     "Incorrect parameters to order-step4.php";

   header("Location: " . S_SHOWCART);

   exit;

}



// Check this customer matches the $cust_id

$connection = DB::connect($dsn, true);



if (DB::isError($connection))

   trigger_error($connection->getMessage( ), E_USER_ERROR);



$cust_id = pearclean($_GET, "cust_id", 5, $connection);

$order_id = pearclean($_GET, "order_id", 5, $connection);



$real_cust_id = getCust_id($_SESSION["loginUsername"]);



if ($cust_id != $real_cust_id)

{

   $_SESSION["message"] = "You can only view your own receipts!";

   header("Location: " . S_HOME);

   exit;

}



// Show the confirmation HTML page

show_HTML_receipt($cust_id, $order_id, $connection);

?>

Example 19-7. The templates/orderreceipt.tpl order receipt template
<h1>Your order (reference # {CUST_ID} - {ORDER_ID}) has

been dispatched</h1>

Thank you {CUSTTITLE} {SURNAME},

your order has been completed and dispatched.

Your order reference number is {CUST_ID} - {ORDER_ID}.

Please quote this number in any correspondence.

<br>

<p>If it existed, the order would have been shipped to:

<br><b>

{CUSTTITLE} {FIRSTNAME} {INITIAL} {SURNAME}

<br>

{ADDRESS}

<br>{CITY} {STATE}

<br>{COUNTRY} {ZIPCODE}

</b>

<br>

<br>

<p>We have billed your fictional credit card.

<!-- BEGIN items -->

<table border=0 width=70% cellpadding=0 cellspacing=5>

<tr>

   <td><b>Quantity</b></td>

   <td><b>Wine</b></td>

   <td align="right"><b>Unit Price</b></td>

   <td align="right"><b>Total</b></td>

</tr>

<!-- BEGIN row -->

<tr>

   <td>{QTY}</td>

   <td>{WINE}</td>

   <td align="right">{PRICE}</td>

   <td align="right">{TOTAL}</td>

</tr>

<!-- END row -->

<tr></tr>

<tr>

   <td colspan=2 align="left"><i><b>Total of this order</b></td>

   <td></td>

   <td align="right"><b><i>{ORDER_TOTAL}</b></td>

</tr>

</table>

<!-- END items -->

<p><i>An email confirmation has been sent to you.

Thank you for shopping at Hugh and Dave's Online Wines.</i>

    Previous Section  < Day Day Up >  Next Section







    Copyright © 2010 | Domen maybe sale - bye this domen