Web Database Applications With Php And Mysql (2nd Edition) [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Web Database Applications With Php And Mysql (2nd Edition) [Electronic resources] - نسخه متنی

David Lane, Hugh E. Williams

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید








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>


/ 176