752 Chapter 31 Connecting to Web Services with XML and SOAP Product.php Class file Contains the PHP class that stores information on one particular book bookdisplayfunctions Functions Contains functions that help display a book and .php lists of books cachefunctions.php Functions Contains functions to carry out the caching required by Amazon cartfunctions.php Functions Contains shopping cart related functions categoryfunctions.php Functions Contains functions that help retrieve and display a category utilityfunctions.php Functions Contains a set of utility functions used through- out the application You will also need the nusoap.php file we mentioned previously, as it is required in these files. NuSOAP is in the chapter31 directory on the CD-ROM at the back of the book, but you might like to replace it with a newer version from http:// dietrich.ganx4.com/nusoap/index.php. We will begin by looking at the core application file index.php. Core Application The application file index.php is shown in Listing 31.3. Listing 31.3 index.php—The Core Application File <?php //we are only using one session variable 'cart' to store the cart contents session_start(); require_once('constants.php'); require_once('utilityfunctions.php'); require_once('bookdisplayfunctions.php'); require_once('cartfunctions.php'); require_once('categoryfunctions.php'); // These are the variables we are expecting from outside. // They will be validated and converted to globals $external = array('action', 'ASIN', 'mode', 'browseNode', 'page', 'search'); // the variables may come via Get or Post // convert all our expected external variables to short global names foreach ($external as $e) { Table 31.1 Continued Filename Type Description 37 525x ch31 1/24/03 3:35 PM Page 752 753 Solution Overview if(@$HTTP_POST_VARS[$e]) $$e = $HTTP_POST_VARS[$e]; else if(@$HTTP_GET_VARS[$e]) $$e = $HTTP_GET_VARS[$e]; else $$e = ''; $$e = trim($$e); } // default values for global variables if($mode=='') $mode = 'books'; // No other modes have been tested if($browseNode=='') $browseNode = 1000; //1000 is bestselling books if($page=='') $page = 1; // First Page - there are 10 items per page //validate/strip input if(!eregi('^[A-Z0-9]+$', $ASIN)) // ASINS must be alpha-numeric $ASIN =''; if(!eregi('^[a-z]+$', $mode)) // mode must be alphabetic $mode = 'books'; $page=intval($page); // pages and browseNodes must be integers $browseNode = intval($browseNode); // it may cause some confusion, but we are stripping characters out from // $search it seems only fair to modify it now so it will be displayed // in the heading $search = safeString($search); if(!isset($HTTP_SESSION_VARS['cart'])) { session_register('cart'); $HTTP_SESSION_VARS['cart'] = array(); } // tasks that need to be done before the top bar is shown if($action == 'addtocart') addToCart($HTTP_SESSION_VARS['cart'], $ASIN, $mode); if($action == 'deletefromcart') deleteFromCart($HTTP_SESSION_VARS['cart'], $ASIN) ; if($action == 'emptycart') $HTTP_SESSION_VARS['cart'] = array(); Listing 31.3 Continued 37 525x ch31 1/24/03 3:35 PM Page 753 754 Chapter 31 Connecting to Web Services with XML and SOAP // show top bar require_once ('topbar.php'); // main event loop. Reacts to user action on the calling page switch ($action) { case 'detail' : showCategories($mode); showDetail($ASIN, $mode); break; case 'addtocart' : case 'deletefromcart' : case 'emptycart' : case 'showcart' : echo '<hr /><h1>Your Shopping Cart</h1>'; showCart($HTTP_SESSION_VARS['cart'], $mode); break; case 'image' : showCategories($mode); echo '<h1>Large Product Image</h1>'; showImage($ASIN, $mode); break; case 'search' : showCategories($mode); echo "<h1>Search Results For '$search'</h1>"; showSearch($search, $page, $mode); break; case 'browsenode': default: showCategories($mode); $category = getCategoryName($browseNode); if(!$category||$category=='Best Selling Books') { echo '<h1>Current Best Sellers</h1>'; } else { echo "<h1>Current Best Sellers in $category</h1>"; } showBrowseNode($browseNode, $page, $mode) ; break; Listing 31.3 Continued 37 525x ch31 1/24/03 3:35 PM Page 754 755 Solution Overview } require ('bottom.php'); ? > Let’s work our way through this file.We begin by creating a session.We will store the customer’s shopping cart as a session variable as we have done before. We then include several files. Most of these are functions that we’ll discuss later, but we need to talk about the first included file now.This file, constants.php, defines some important constants that will be used throughout the application.The contents of con- stants.php can be found in Listing 31.4. Listing 31.4 constants.php—Declaring Key Global Constants <?php // this application can connect via XML/HTTP or SOAP // define one version of METHOD to choose. define('METHOD', 'SOAP'); //define('METHOD', 'XML/HTTP'); // make sure to create a cache directory an make it writable define('CACHE', 'cache'); // path to cached files define('ASSOCIATEID', 'webservices-20); //put your associate id here define('DEVTAG', 'XXXXXXXXXXXXXX'); // put your developer tag here //give an error if software is run with the dummy devtag if(DEVTAG=='XXXXXXXXXXXXXX') die ('You need to sign up for an Amazon.com developer tag at<a href = "http://associates.amazon.com/exec/panama/associates/join/ developer/kit.html">Amazon</a> when you install this software. You should probably sign up for an associate ID at the same time. Edit the file constants.php.'); ? > This application has been developed to use either XML over HTTP or SOAP.You can set which one it should use by changing the value of the METHOD constant. The CACHE constant holds the path to the cache for the data we download from Amazon. Change this to the path you would like used on your system. The ASSOCIATEID constant holds the value of your Associate ID. If you send this to Amazon with transactions, you get a commission. Change this to your own Associate ID. The DEVTAG constant holds the value of the developer token Amazon will give you when you sign up.You need to change this to your own developer tag, or the application will not work.You can sign up for a tag at http://associates.amazon.com/exec/panama/associates/join/developer/kit.html Listing 31.3 Continued 37 525x ch31 1/24/03 3:35 PM Page 755 756 Chapter 31 Connecting to Web Services with XML and SOAP Let’s look back at index.php. It contains some preliminaries, and then the main event loop.We begin by extracting any incoming variables that came via GET or POST.We then set up some default values for some standard global variables that determine what will be displayed later on, as follows: // default values for global variables if($mode=='') $mode = 'books'; // No other modes have been tested if($browseNode=='') $browseNode = 1000; //1000 is bestselling books if($page=='') $page = 1; // First Page - there are 10 items per page We set the mode variable to books. Amazon supports many other modes (types of prod- ucts), but for this application, we will only worry about books. It should not be too hard to modify the code in this chapter to deal with other categories.The first step in this expansion would be to reset $mode.You would need to check the Amazon documenta- tion to see what other attributes are returned for non-book products and remove book- specific language from the user interface. The browseNode variable is used to specify what category of books we would like displayed.This may be set if the user has clicked through one of the Selected Categories links. If it is not set—for example, when the user first enters the site—we will set it to 1000. Amazon’s browse nodes are simply integers that identify a category.The value 1000 represents the category Best Selling Books, which is what we display on the initial front page. The page variable is used to tell Amazon which subset of the results we would like displayed within a given category. Page 1 contains results 1–10, page 2 has results 11–20, and so on. Amazon sets the number of items on a page, and we do not have control over this.We could, of course, display two or more Amazon “pages” of data on one of our pages, but 10 is both a reasonable figure and the path of least resistance. Next, we tidy up any input data we have received, whether through the search box or via GET or POST parameters: //validate/strip input if(!eregi('^[A-Z0-9]+$', $ASIN)) // ASINS must be alpha-numeric $ASIN =''; if(!eregi('^[a-z]+$', $mode)) // mode must be alphabetic $mode = 'books'; $page=intval($page); // pages and browseNodes must be integers $browseNode = intval($browseNode); // it may cause some confusion, but we are stripping characters out // from $search // it seems only fair to modify it now so it will be displayed in the // heading $search = safeString($search) ; 37 525x ch31 1/24/03 3:35 PM Page 756 . // First Page - there are 10 items per page //validate/strip input if(!eregi('^[A-Z 0-9 ]+$', $ASIN)) // ASINS must be alpha-numeric $ASIN =''; if(!eregi('^[a-z]+$',. functions that help display a book and .php lists of books cachefunctions .php Functions Contains functions to carry out the caching required by Amazon cartfunctions .php Functions Contains shopping. functions categoryfunctions .php Functions Contains functions that help retrieve and display a category utilityfunctions .php Functions Contains a set of utility functions used through- out the application You