17.3 The Customer Form

The script customer/details.php is shown in Example 17-2. If the user is logged in and validation has not previously failed, the customer data is retrieved from the customer table and used to populate the form widgets. If the user isn't logged in, and validation has not previously failed, a blank form is shown to collect new member details. If data has failed validation, the form is repopulated and the error messages are displayed. Error messages and previously entered form values are stored by the customer/validate.php script in the session array variables $_SESSION["custFormVars"] and $_SESSION["custErrors"] respectively.

The customer form and its widgets are displayed using our winestoreFormTemplate class that's derived from the PEAR ITX template class. It's discussed in detail in Chapter 16.

Example 17-2. The customer form script customer/details.php
<?php

require_once "DB.php";

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

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

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



set_error_handler("customHandler");



// Show meaningful instructions for UPDATE or INSERT

if (isset($_SESSION["loginUsername"]))

   $instructions = "Please amend your details below as required.";

else

   $instructions = "Please fill in the details below to join.";



// Takes <form> heading, instructions, action, formVars name, 

// and formErrors name as parameters

$template = new winestoreFormTemplate("Customer Details",

                $instructions, S_VALIDATE, "custFormVars", "custErrors");



session_start( );



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

if (DB::isError($connection))

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



// Is the user logged in and are there no errors from previous

// validation?  If so, look up the customer for editing

if (isset($_SESSION["loginUsername"]) &&

    !isset($_SESSION["custErrors"]))

{

   // Check the user is properly logged in

   sessionAuthenticate(S_MAIN);



   $query = "SELECT title_id, surname, firstname, initial, address,

                    city, state, zipcode, country_id, phone,

                    birth_date

             FROM users, customer

             WHERE users.cust_id = customer.cust_id

             AND user_name = '{$_SESSION["loginUsername"]}'";



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

   if (DB::isError($result))

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

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



   // Reset $_SESSION["custFormVars"], since we're loading

   // from the customer table

   $_SESSION["custFormVars"] = array( );



   // Load all the <form> widgets with customer data

   foreach($row as $variable => $value)

      $_SESSION["custFormVars"]["{$variable}"] = $value;

}



// Load the titles from the title table

$titleResult = $connection->query("SELECT * FROM titles");

if (DB::isError($titleResult))

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



// Load the countries from the country table

$countryResult = $connection->query("SELECT * FROM countries");

if (DB::isError($countryResult))

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



// Create widgets for each of the customer fields

$template->selectWidget("title_id", "Title:",

                        "title", $titleResult);

$template->mandatoryWidget("firstname", "First name:", 50);

$template->mandatoryWidget("surname", "Surname:", 50);

$template->optionalWidget("initial", "Middle initial:", 1);

$template->mandatoryWidget("address", "Address:", 50);

$template->mandatoryWidget("city", "City:", 50);

$template->optionalWidget("state", "State:", 20);

$template->mandatoryWidget("zipcode", "Zip code:", 10);

$template->selectWidget("country_id", "Country:",

                        "country", $countryResult);

$template->optionalWidget("phone", "Telephone:", 15);

$template->mandatoryWidget("birth_date", 

                           "Date of Birth (dd/mm/yyyy):", 10);



// Only show the username/email and password widgets to new users

if (!isset($_SESSION["loginUsername"]))

{

   $template->mandatoryWidget("loginUsername", "Email/username:", 50);

   $template->passwordWidget("loginPassword", "Password:", 15);

}



// Add buttons and messages, and show the page

$template->showWinestore(NO_CART, B_ALL & ~B_EMPTY_CART & ~B_UPDATE_CART &

                ~B_PURCHASE & ~B_DETAILS & ~B_LOGINLOGOUT)



?>

17.3.1 The Customer Receipt Page

Example 17-3 shows the customer receipt script, customer/receipt.php, that is called after a database write to insert or update a customer. The script is a receipt page that can be bookmarked and the script only reads details from the database. Reloading of the page therefore has no undesirable side effects.

Example 17-3. The customer/receipt.php customer receipt page
<?php

// This script shows the user a receipt for their customer

// UPDATE or INSERT. It carries out no database writes and

// can be bookmarked.

// The user must be logged in to view it.



require_once "DB.php";

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

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

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



set_error_handler("customHandler");



// Show the user a customer INSERT or UPDATE receipt

function show_HTML_receipt($cust_id, $connection, &$template)

{

  // Retrieve the customer details

  $query = "SELECT * FROM customer WHERE cust_id = {$cust_id}";

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

  if (DB::isError($result))

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

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



  // Is there an optional phone field? If so, add it to the output

  if (!empty($row["phone"]))

  {

     $template->setCurrentBlock("phone");

     $template->setVariable("PHONE", $row["phone"]);

     $template->parseCurrentBlock("address");

  }



  // Now, add all the mandatory fields to the output

  $template->setCurrentBlock( );

  $template->setVariable("EMAIL", $_SESSION["loginUsername"]);

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

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

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

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

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

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

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

  $template->setVariable("DOB", $row["birth_date"]);

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

                         $connection));

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

                         $connection));

}



// -----



session_start( );



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

if (DB::isError($connection))

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



// Check the user is properly logged in

sessionAuthenticate(S_MAIN);



// Find out the cust_id of the user

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



// Start a new page

$template = new winestoreTemplate(T_CUSTRECEIPT);



// Show the customer confirmation

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



// Add buttons and messages, and show the page

$template->showWinestore(NO_CART, B_HOME);

?>

Customers can view their receipts only when logged in. The cust_id of the customer is again retrieved using the function getCust_id( ) that's discussed in Chapter 16.

The receipt script populates the templates/custreceipt.tpl template shown in Example 17-4. The receipt page uses the winestoreTemplate class that's discussed in Chapter 16 to provide the HTML framework for displaying the page and to show messages to the user. The templates/custreceipt.tpl template is therefore only part of the body of the page.

Example 17-4. The templates/custreceipt.tpl customer receipt template
h1>Account details for <font color="red">{EMAIL}</font></h1>



<p><i>Please record your password somewhere safe for future use.</i>



<p>Your shipping and billing details are as follows:

<br><b>{CUSTTITLE}&nbsp;{FIRSTNAME}&nbsp;{INITIAL}&nbsp;{SURNAME}

<br>{ADDRESS}

<br>{CITY} {STATE} {ZIPCODE}

<br>{COUNTRY}</b>

<br>

<!-- BEGIN phone -->

<br><b>Telephone: {PHONE}

<!-- END phone -->

<br><b>Date of Birth: {DOB}</b>

<br>

<br>