#!/usr/bin/perl -wT use CGI qw(:standard); use CGI::Carp qw(warningsToBrowser fatalsToBrowser); use DBI; use strict; # if the pressed the "Check Out" button, redirect to the checkout # script instead if (param('cartact') eq "Check Out") { print redirect("http://www.cgi101.com/book/ch17/order.cgi"); exit; } print header; print start_html("Update Cart"); my $dbh = DBI->connect( "dbi:mysql:products", "webserver", "", { RaiseError => 1, AutoCommit => 1 }) or &dienice("Can't connect to database: $DBI::errstr"); # Put the cookie-detection stuff in a separate subroutine. # Since the validate_cookie routine must query the db, # be sure to open the database connection BEFORE this. my $cookie_id = &validate_cookie; # prepare three statement handles - one to select data from the cart, # a second to update a record in the cart with quantity changes, # and a third to delete a record from the cart (if qty==0). my $sth = $dbh->prepare("select * from shopcart where cookie=? and item_number=?") or &dbdie; my $sth2 = $dbh->prepare("update shopcart set qty=? where cookie=? and item_number=?") or &dbdie; my $sth3 = $dbh->prepare("delete from shopcart where cookie=? and item_number=?") or &dbdie; foreach my $p (param()) { # first, be sure it's a NUMBER. if not, skip it. if ($p =~ /^item_.*/ and param($p) =~ /\D/) { print "error, `",param($p),"' isn't a number.<br>\n"; next; } my $item = $p; $item =~ s/item_//; $sth->execute($cookie_id, $item) or &dbdie; if ($sth->fetchrow_hashref) { if (param($p) > 0) { $sth2->execute(param($p), $cookie_id, $item) or &dbdie; } else { $sth3->execute($cookie_id, $item) or &dbdie; } } } # Display the shopping cart &display_shopcart($cookie_id); print end_html; sub dienice { my($msg) = @_; print header; print start_html("Error"); print "<h2>Error</h2>\n"; print $msg; exit; } sub display_shopcart { my($cookie_id) = @_; 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; print qq( <center> <h3>Your Shopping Cart</h3> <form action="edcart.cgi" method="POST"> <table border=0 width=70%> <tr> <th bgcolor="#cccccc">Item Number</th> <th bgcolor="#cccccc">Name</th> <th bgcolor="#cccccc">Price</th> <th bgcolor="#cccccc">Qty.</th> </tr> ); while (my $rec = $sth->fetchrow_hashref) { $subtotal = $subtotal + ($rec->{price} * $rec->{qty}); print qq( <tr> <td align="CENTER">$rec->{item_number}</td> <td align="CENTER">$rec->{name}</td> <td align="CENTER">\$$rec->{price}</td> <td align="CENTER"><input type="text" name="item_$rec->{item_number}" size=3 value="$rec->{qty}"></td> </tr> ); } $subtotal = sprintf("%4.2f", $subtotal); print qq( <tr> <td></td> <td></td> <td><b>Subtotal:</b> \$$subtotal</td> <td></td> </tr> </table> <input name="cartact" type="submit" value="Update Qty"> <input name="cartact" type="submit" value="Check Out"> </form> </center> ); } sub validate_cookie { # Look for cookies. If they have a valid cookie, return it; if not, # print an error message and abort. 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"; &dienice($errmsg); }