The winestore application was developed to meet the requirements outlined in the previous section. It is a complete PHP and MySQL web database application, and uses PEAR ITX templates and PEAR DB to abstract HTML presentation and the database layer. It was developed on a Linux platform using the MySQL 4.1 DBMS and PHP 4.3, but works in the Microsoft Windows and Mac OS X environments.
It has been tested with PHP 5.0.0 beta (b2). At the time of writing, PEAR DB does not work with PHP5 and MySQL 4.1. This will likely be fixed when PHP5 is released, and we'll provide updated code on our book's web site http://www.webdatabasebook.com.
The winestore has many components of a typical web database application, including:
Maintainable web pages generated with templates, and populated with data from a database.
User-driven querying and browsing, in which the user provides the parameters that limit the searching or browsing of the database. This includes one-component querying.
Data entry and validation.
User tracking with session management techniques.
User authentication and management.
SQL querying that requires table locking.
Receipt pages that avoid the reload problem.
Robust error handling with a custom error module.
Email- and browser-based receipts.
The application has five separate modules that we discuss in the next four chapters:
Becoming a member and amending membership details. The scripts that implement this functionality are in Chapter 17.
Adding wines to a shopping cart, deleting items from the cart, adjusting quantities, and emptying the cart. The shopping cart is discussed in Chapter 18.
Processing the cart so that it becomes an order, validating a credit card, confirming shipping details by email, and confirming shipping details with an HTML receipt. These scripts are the subject of Chapter 19.
Searching and browsing the wines using user-supplied parameters. Outlined in Chapter 20.
Logging in, logging out, and changing passwords. Also discussed in Chapter 20.
The application also has a set of common components, including PEAR ITX template extensions, authentication functions, a custom error handler, validation functions, and general purpose functions and constants. With the exception of the authentication functions, these common components are discussed later in this chapter. The general-purpose authentication functions are discussed in Chapter 20.
Figure 16-1 and Figure 16-2 show the scripts developed for the winestore application and how they interact. Scripts are shown as boxes. Solid boxes indicate scripts that generate HTML, while dashed boxes don't produce output but instead redirect to other scripts. Lines with arrows show how the scripts call each other, and dashed lines indicate the path is followed when validation fails or an error occurs. The three key user interface scripts, index.php, customer/details.php, and cart/showcart.php, are shown in both figures.
The main or home page of the online winestore is shown in Figure 16-1 and Figure 16-2 and is labeled index.php . This page allows the user to add bottles and cases of the three selected "hot new wines" to his shopping cart and to access the other parts of the application. The shopping cart functionality is shown by the double-ended arrow to the add-to-cart script labeled cart/addtocart.php . The cart/addtocart.php script is shown as a dashed rectangle in Figure 16-1, indicating that it's a one-component query module that has no output and instead redirects to the calling page.
The home page also allows the user to view his shopping cart by clicking on the cart icon at the top of the page or the View Cart button at the bottom of the page. View-the-cart functionality is provided by the cart/showcart.php script introduced later in this section. Three other actions are also possible from the home page:
Searching the wines using the script search/sea rchform.php
Becoming a member or changing customer details using the customer/details.php script
Logging in or logging out using the scripts auth/login.php and auth/logout.php, respectively
Figure 16-1 and Figure 16-2 show the cart, customer, authentication, password change, searching, ordering, and shipping scripts. In detail, the features are:
This is provided by the customer/details.php , customer/validate.php , and customer/receipt.php scripts that implement the become-a-member and change details features. The scripts show how to build a real-world data entry, validation, and receipt module using the techniques we discuss in Chapter 6 through Chapter 9.
The script customer/details.php presents an empty customer form to new customers. The form allows entry of all customer details, including an email address that is used as the login name of the user and a password for future visits to the site. The customer/validate.php script validates customer data and, on success, writes to the database and redirects to the customer receipt script customer/receipt.php.
On validation failure, customer/validate.php redirects to customer/details.php, where the validation errors are reported as batch errors that are interleaved with the form widgets.
For customers who are amending their details, the password and email input widgets are omitted from the customer form.
This is provided by the auth/password.php and auth/changepassword.php scripts. The scripts show how to build part of a real-world authentication module using the techniques discussed in Chapter 10 and Chapter 11, in conjunction with the basic techniques of Chapter 6 through Chapter 9.
Logged in users can change their passwords by clicking on the Change Password button at the bottom of the Change Details page which then calls the auth/password.php script.
To change their password, users are required to enter their current password to reduce the risk of an unauthorized change, and then to enter the new password twice to minimize the chance of a typing error. The password change is validated by the authorization script auth/changepassword.php. A receipt is shown for a successful change by redirecting the user to the customer details page customer/details.php, which then displays a confirmation message; we chose not to add a receipt page to this module because it's unnecessary when there's no information that the user needs to record.
An unsuccessful password change attempt redirects the user to auth/password.php where error messages are displayed.
The remaining three authorization scripts auth/login.php, auth/logincheck.php, and auth/logout.php are shown in Figure 16-2. These scripts continue our real-world examples of building an authentication module.
The auth/login.php script produces a form for the user to enter their email address and password. The auth/logincheck.php script validates the email address and password, and checks if a matching user is a member. If so, the script logs the user into the application and redirects the user to the index.php main page script, where their login status is displayed at the top of the page. If the login process fails, they're returned to auth/login.php and errors are displayed.
The script auth/logout.php logs the user out of the application and redirects her to the main page index.php; the logout script doesn't produce output. Figure 16-2 also shows the three scripts from Figure 16-1 that interact with the login and logout process.
The shopping cart scripts cart/showcart.php , cart/updatecart.php , and cart/emptycart.php are shown in Figure 16-1. These scripts show you how to build a scalable database-based shopping cart using the techniques described in Chapter 5 and Chapter 8, along with the sessions techniques in Chapter 10 and the basic web database querying techniques of Chapter 6.
The script cart/showcart.php shows the user the contents of his shopping cart. If the cart contains items, the quantities are presented in a form environment that allows the user to change them. The view cart script cart/showcart.php also allows the user to return to the home page, search, log in, and log out.
To update changes in quantities, the cart/updatecart.php script is requested by clicking the Update Quantities button; this script redirects to cart/showcart.php, and either shows the user the correctly updated quantities or reports an error describing why the update failed.
The user can also empty his cart completely by clicking on a button that requests the cart/emptycart.php script.
The ordering and shipping processes are implemented in the scripts order/order-step1.php , order/order-step2.php, order/order-step3.php, order/order-step4.php , order/order-step5.php, and order/receipt.php . These scripts show all aspects of data entry, querying, writing to databases using locks, validation, and receipts, and they make use of most of the techniques discussed in Chapter 5 through Chapter 10.
Users who are logged in place orders by clicking on the Make Purchase button in the view cart screen. When the button is clicked, the script order/order-step1.php is requested and a form is presented that requires the user to enter their credit card number and expiration date, as well as any optional delivery instructions. The application supports the fictional SurchargeCard credit card, which is validated according to the Luhn algorithm discussed in Chapter 9.
When the user submits the credit card form, the script order/order-step2.php is requested to perform validation. If the card validates, then the script redirects to order/order-step3.php otherwise the script returns to order/order-step1.php and shows error messages.
The complex database processing used to finalize an order is performed by order/order-step3.php. If the ordering process fails, the script redirects to order-step1.php, where errors are reported. If the ordering process succeeds, it redirects to order/order-step4.php. This script sends the user an email receipt of his order and redirects to order/receipt.php which shows the user the same receipt as an HTML page. From order/receipt.php, the user can return to the home page.
Searching and browsing is implemented in the scripts search/searchform.php and search/search.php . These scripts show an advanced example of embedding links in an HTML document and creating drop-down lists using the techniques from Chapter 6. They also show how to add validation and sessions to a querying module with the techniques of Chapter 9 and Chapter 10.
The search/searchform.php script shows a form that allows the user to enter wine search criteria. The users can choose to browse a specific wine type (such as red or white) and a specific region (such as Margaret River). They can also choose to browse all wine types or all regions. When the user submits the form, the script search/search.php is requested. The search criteria are saved using sessions for when the user revisits the page.
The search/search.php script shows the wines that match the search criteria in pages of 12 wines each, and the user can traverse the pages using previous and next links, or click on a page number link to jump to a specific page. Bottles or cases of wine can be added to the shopping cart by clicking on a link that requests and passes parameters to the cart/addtocart.php script.
As on the other main pages, the user can also click on buttons to view his cart, login or logout, return to the home page, or start a new search with different criteria.
The winestore application can be used at this book's web site or on your local server, if you have followed the instructions to install the examples in Appendix A to Appendix C. The source code can also be viewed at the book's web site and (if the installation instructions have been followed) can be edited and viewed in the directory /usr/local/apache2/htdocs/wda2-winestore/ on your local Unix server, in C:\Program Files\EasyPHP1-7\www\wda2-winestore under Microsoft Windows, or in /Library/WebServer/Documents/wda2-winestore on Mac OS X. A summary of the winestore scripts, and functions is shown in Table 16-1.
Script |
Function |
---|---|
index.php |
Main page and hot new wines panel |
templates/index.tpl |
Main page template |
VERSION |
Application version information for developers |
license.txt |
Application licensing information |
includes/authenticate.inc |
Authentication functions |
auth/login.php |
User login form |
auth/logincheck.php |
User login authentication |
auth/logout.php |
User logout |
auth/password.php |
User password change form |
auth/changepassword.php |
Password change validation and update |
cart/addtocart.php |
Add an item to the shopping cart |
cart/empty.php |
Empty the shopping cart |
cart/showcart.php |
Show the user the cart contents |
templates/showcart.tpl |
Cart template |
cart/updatecart.php |
Update cart quantities |
customer/details.php |
Enter or amend user details |
customer/validate.php |
Validate and update amended user details |
customer/receipt.php |
User update receipt |
templates/custreceipt.tpl |
User update receipt template |
order/order-step1.php |
Collect credit card details and delivery instructions |
order/order-step2.php |
Validate credit card details |
order/order-step3.php |
Finalize order |
order/order-step4.php |
Send email receipt |
order/receipt.php |
Show HTML order receipt |
search/searchform.php |
Collect search criteria |
search/search.php |
Browse wines |
templates/search.tpl |
Browse wines template |
includes/customHandler.inc |
Custom error handler |
templates/winestore.tpl |
Skeleton template for all winestore pages |
templates/details.tpl |
Template for most winestore form pages |
includes/validate.inc |
Validation functions |
includes/winestore.inc |
General-purpose functions and define( ) statements |
includes/db.inc |
DBMS credentials |