. 54
( 132 .)


If the user is interested, he or she will go to this page.

If the winner comes to claim.php, we first need to check that the claim code exists
in the database. The query in the following code grabs queries from the database to
see if the claim code exists; if it does, the query performs a join and returns the user
information associated with the claim code.

$user_id = 0;
$winner_email = NULL;
$weekdate = NULL;

$claim_code = (string)array_key_value($_REQUEST,™claim_code™,™™);

if (!empty($claim_code))
$query = “select u.user_id, u.email, w.weekdate from users u,
winners w
where w.claim_code = ˜$claim_code™ and w.user_id = u.user_id
$result = my_query($query);
list($user_id, $winner_email, $weekdate) =
Chapter 9: Survey 305


if ($user_id == 0)
// we couldn™t find a record corresponding to the claim_code
// submitted (if any). print out an error and exit.
$msg = <<<EOQ

I™m sorry, that doesn™t appear to be a valid claim code.
The URL may not have registered properly.
Make sure to copy the complete link into your browser and try again,
or forward your original prize notification to $admin_email.

print paragraph($msg);

Once it is established that a claim code is valid, we want to do a bit of double-
checking and make sure that the person who submitted this claim code knows the
email address to which the notification was sent. The application does this by dis-
playing a form asking the user to enter the correct email. That form is sent and
processed by the form page. When the form is submitted, the following code will

$user_email = (string)array_key_value($_POST,™user_email™,™™);

if (!empty($user_email))
// the user has submitted an email address to claim
// the prize.
if ($user_email != $winner_email)
// the email address submitted by the user doesn™t
// match the one stored for the winning entry.
// display an error message.
$notice = <<<EOQ

I™m sorry, that email address doesn™t match our records.
Please try again, or forward your original prize notification
to $admin_email.

306 Part III: Simple Applications

The comparison $user_email != $winner_email will work because the query
that ran at the top of the page retrieved the correct winner™s email, and we get
$user_email from the form submitted by the user. If that comparison fails, an error
message prints. If it does not fail, the following code updates the winners database,
recording the time the prize was claimed, and sends an email to the winner letting
him or her know that the claim was successful:

// everything matches. we can update the database
// to record a valid claim.
$claimquery = “update winners set claim_dt = now()
where user_id = $user_id
and claim_code = ˜$claim_code™
and weekdate = ˜$weekdate™
if (mysql_affected_rows() > 0)
// send a notification to the administrator that
// the prize has been claimed.
$confirm_url = regular_url(˜admin/winners.php™);
$msgtext = <<<EOQ

The prize for $weekdate has been claimed by $user_email.

Confirm the prize at


$subject = ˜Prize Claim™;
$result = mail($admin_email,$subject,$msgtext);

if ($result)
// we don™t need to re-display the form now.
// print out congratulations and bail.
$msg = <<<EOQ
Thanks! Your claim has been accepted.
Your prize should be on its way soon!
print paragraph($msg);
Chapter 9: Survey 307

$private_error = <<<EOQ
could not send claim notification:
user_error(˜Warning: Could not notify administrator
of your claim.™, E_USER_WARNING);
// just in case the database is broken or
// some other horror has occurred...
$msgtext = <<<EOQ
The prize for $weekdate has been claimed by $user_email, but the
update did not work.
$subject = ˜Prize Claim™;
$result = mail($admin_email,$subject,$msgtext);
if (!$result)
$private_error = <<<EOQ
could not send claim problem notification:
user_error(˜Warning: Could not notify administrator
of your claim.™, E_USER_WARNING);

// let the user know that something broke
// and re-display the form by continuing
// with the script.
$notice = <<<EOQ

Your claim is valid, but we were unable to record that fact.
Please try again later, or forward your initial prize notification
to $admin_email and let them know there was a problem.

308 Part III: Simple Applications


The final portion of this page simply prints the form in which the user will enter
his or her email. There™s really no need to show that here.

The survey application involves quite a bit of code, but it isn™t anything that you
shouldn™t be able to figure out with some close scrutiny of the files and the comments.
Take a look at the complex_results.php page and its includes (age_results.php,
state_results.php, and country_results.php) for a look at how MySQL aggregate
functions can come in handy.
This application contains much more complexity than the guestbook. In it is a
real database schema complete with related tables. In the course of the application
we need to make use of queries that contain MySQL functions. (See Appendix J for
more information on MySQL functions.)
Another notable item seen in this chapter is the function set we™ve created for
creating common HTML elements. Whether you want to make use of such functions
or not is up to you. You may prefer typing out individual form elements, tables, and
the like. But you will be seeing these functions used in the remainder of this book.
Part IV
Not So Simple Applications
Threaded Discussion
Content-Management System
Problem-Tracking System
Shopping Cart
XML Parsing
Project Management
Chapter 10

Threaded Discussion

— Adding to your Web site features that promote community

— Using an advanced technique to write functions

— Looking at other criteria to use when designing a database

— Setting up error-handling and debugging functions

IF a Web site or are looking to create one, it™s probably safe to
assume that you want people to return frequently to your pages. But as everyone in
the Web industry knows, loyalty is fleeting, and people are always looking for
something better, more engaging, or closer to their interests.
One way to keep the anonymous masses involved with your site is to offer your
visitors a way to contribute to its content. If someone has accessed your site, it™s
likely that he or she has an opinion on the topic you are presenting. And if our con-
clusions from 30-plus years of observation are correct, people love to share their
Using the threaded-discussion application in this chapter, you can create an area
on your Web site where your users can share their opinions and interact with you
and each other.
Once you have this piece of your site up and running, you are well on your way
to creating your own Web community. I make special mention of the word commu-
nity for two reasons.

— First, it is a huge buzzword within the industry. Everyone is looking to
create a sense of familiarity and inclusion that tempts users to return.
— Second ” and perhaps more importantly ” you, the Webmaster, should
know what you™re getting yourself into. From personal experience, we
can tell you that “community” can be a real pain in the butt. On the Web,
everyone is pretty much anonymous, and few consequences are associated
with antisocial behavior. Thus, in many discussion groups, opinionated
windbags have a way of ruining a promising discussion.

312 Part IV: Not So Simple Applications

Before too long, you will undoubtedly see things that are mean or dis-
tasteful, and you must be prepared to deal with it. We™re not trying to
scare you away from including a discussion list on your site. We™re just
letting you know that you need to put some effort into administering it.
Whether you monitor the list yourself or appoint someone to do it for
you, somebody will need to make sure your users behave if you want it
to be orderly and functional.

Determining the Scope and Goals
of the Application
The purpose of any discussion board is reasonably simple. Any visitor to the site
should be able to post a new topic to the board or reply to any of the existing top-
ics. Furthermore, the board must be flexible enough to deal with any number of


. 54
( 132 .)