#!/usr/bin/perl -wT
use CGI qw(:standard);
use CGI::Carp qw(warningsToBrowser fatalsToBrowser);
use DBI;
use Email::Valid;
use strict;

print header;
print start_html("Order Results");

my $dbh = DBI->connect( "dbi:mysql:products", "webserver", "", { RaiseError => 1, AutoCommit => 1 }) or &dienice("Can't connect to database: $DBI::errstr");

# First change:
# Detect the cookie, and bounce if it isnt there.
my $cookie_id = &validate_cookie;

# put all the form data into a hash
my %FORM = ();
foreach my $i (param()) {
   $FORM{$i} = param($i);

# here we check to make sure they actually filled out all 
# the fields. if they didn't, generate an error.

my @required = ("name","ship_addr","ship_city","ship_state","ship_zip",
"phone", "email");
foreach my $i (@required) {
   if (!(param($i))) {
      &dienice("You must fill out the fields for your name,
e-mail address, phone number and shipping address."); 

unless (Email::Valid->address($FORM{email})) {
   &dienice("$FORM{email} doesn't seem to be a valid e-mail address.");

# Second Change:
# Pull items from the cart, rather than from the items db.
my $sth = $dbh->prepare("select * from shopcart, items where shopcart.cookie=? and items.stocknum=shopcart.item_number") or &dbdie;
$sth->execute($cookie_id) or &dbdie;

my $subtotal = 0;
my $items_ordered = "";
while (my $rec = $sth->fetchrow_hashref) {
   $subtotal = $subtotal + ($rec->{price} * $rec->{qty});
   $items_ordered .= qq($rec->{name} (#$rec->{stocknum}) - $rec->{price} ea., qty: $rec->{qty}\n);
# Detect for empty carts:
if ($subtotal == 0) {
   &dienice("You didn't order anything?!");

# add $3 for shipping
my $total = $subtotal + 3;
$subtotal = sprintf("%4.2f", $subtotal);
$total = sprintf("%4.2f", $total);

my $ordermsg = <<End1;
Order From: $FORM{name}
Shipping Address: $FORM{ship_addr}
City: $FORM{ship_city}
State: $FORM{ship_state}
ZIP: $FORM{ship_zip}
Country: $FORM{ship_country}
Phone: $FORM{phone}
Email: $FORM{email}

Payment Method: $FORM{paytype}
Items Ordered:

Subtotal: \$$subtotal
Shipping: \$3.00
Total: \$$total

Thank you for your order!

# Tell them how to send us payment...
if ($FORM{paytype} eq "check") {
   $ordermsg .= qq(Please send a check or money order for \$$total to: 
      Kite Store, 555 Anystreet, Somecity, TX 12345.\n);
} elsif ($FORM{paytype} eq "cc") {
   $ordermsg .=  qq(Please call us at (555) 555-5555 with your credit card 
      information, or fax your card number, billing address and expiration date 
      to our fax number at (555) 555-5555.\n);
} else {
   $ordermsg .= qq(Please <a href="http://www.paypal.com">click here</a> to 
      complete your payment on Paypal.\n);

my $from = "webmaster\@cgi101.com";

# send the order to the store
&sendmail($from, "nullbox\@cgi101.com", "Kite Store Order", $ordermsg);

# also send a copy of the order to the customer
&sendmail($from, $FORM{email}, "Kite Store Order", $ordermsg);
# finally print a thank-you page.
print <<EndHTML;
<h2>Thank You!</h2>
Here's what you ordered:<br>

# Final Change:
# Delete the cookie info from the database. This doesn't delete
# it from their browser, but since the cart depends on the cookie
# in the database, it's the same as emptying their cart.

$sth = $dbh->prepare("delete from cart_cookies where cookie_id=?") or &dbdie;
$sth->execute($cookie_id) or &dbdie;
$sth = $dbh->prepare("delete from shopcart where cookie=?") or &dbdie;
$sth->execute($cookie_id) or &dbdie;


sub dienice {
    my($msg) = @_;
    print "<h2>Error</h2>\n";
    print $msg;

sub sendmail {
    my($from, $to, $subject, $msg) = @_;
    $ENV{PATH} = "/usr/sbin";
    my $mailprog = "/usr/sbin/sendmail";
    open (MAIL, "|/usr/sbin/sendmail -t -oi") or 
        &dienice("Can't fork for sendmail: $!\n");
    print MAIL "To: $to\n";
    print MAIL "From: $from\n";
    print MAIL "Subject: $subject\n\n";
    print MAIL $msg;

sub validate_cookie {
    my $cookie_id = "";
    if (cookie('cart')) {
       $cookie_id = cookie('cart');
    } else {
       &dienice("You don't have a cart. (Perhaps your cart expired?)");
    my $sth = $dbh->prepare("select * from cart_cookies where cookie_id=?") or &dbdie;
    $sth->execute(cookie('cart')) or &dbdie;
    unless ($sth->fetchrow_hashref) {
       &dienice("You don't have a cart. (Perhaps your cart expired?)");
    return $cookie_id;

sub dbdie {
    my($package, $filename, $line) = caller;
    my($errmsg) = "Database error: $DBI::errstr<br>
                called from $package $filename line $line";