Case Study: Shopping Cart

Case Study Shopping Cart

Many businesses' Web sites contain shopping-cart applications, which allow customers to buy items conveniently on the Web. The sites record what the consumer wants to purchase and provide an easy, intuitive way to shop online. They do so by using an electronic shopping cart, just as people would use physical shopping carts in retail stores. As users add items to their shopping carts, the sites update the carts' contents. When users "check out," they pay for the items in their shopping carts. To see a real-world electronic shopping cart, we suggest going to the online bookstore Amazon.com (www.amazon.com).

The shopping cart implemented in this section (Figs. 19.2119.24) allows users to purchase books from a fictitious bookstore that sells four books (see Fig. 19.23). This example uses four scripts, two server-side files and cookies.

Figure 19.21. Program that outputs a login page.

(This item is displayed on pages 954 - 959 in the print version)

1 // Fig. 19.21: login.cpp 2 // Program to output an XHTML form, verify the 3 // username and password entered, and add members. 4 #include 5 using std::cerr; 6 using std::cin; 7 using std::cout; 8 using std::ios; 9 10 #include 11 using std::fstream; 12 13 #include 14 using std::string; 15 16 #include 17 using std::getenv; 18 using std::atoi; 19 using std::exit; 20 21 void header(); 22 void writeCookie(); 23 24 int main() 25 { 26 char query[ 1024 ] = ""; 27 string dataString = ""; 28 29 // strings to store username and password 30 string userName = ""; 31 string passWord = ""; 32 33 int contentLength = 0; 34 bool newMember = false; 35 36 // data was posted 37 if ( getenv( "CONTENT_LENGTH" ) ) 38 { 39 // retrieve query string 40 contentLength = atoi( getenv( "CONTENT_LENGTH" ) ); 41 cin.read( query, contentLength ); 42 dataString = query; 43 44 // find username location 45 int userLocation = dataString.find( "user=" ) + 5; 46 int endUser = dataString.find( "&" ); 47 48 // find password location 49 int passwordLocation = dataString.find( "password=" ) + 9; 50 int endPassword = dataString.find( "&new" ); 51 52 if ( endPassword > 0 ) // new membership requested 53 { 54 newMember = true; 55 passWord = dataString.substr( 56 passwordLocation, endPassword - passwordLocation ); 57 } // end if 58 else // existing member 59 passWord = dataString.substr( passwordLocation ); 60 61 userName = dataString.substr( 62 userLocation, endUser - userLocation ); 63 } // end if 64 65 // no data was retrieved 66 if ( dataString == "" ) 67 { 68 header(); 69 cout << "

Please login.

"; 70 71 // output login form 72 cout << "" 73 << "

User Name: " 74 << "Password: " 75 << " New? 76 << " value = "1"/>

" 77 << ""; 78 } // end if 79 else // process entered data 80 { 81 string fileUsername = ""; 82 string filePassword = ""; 83 bool userFound = false; 84 85 // open user data file for reading and writing 86 fstream userData( "userdata.txt", ios::in | ios::out); 87 88 if ( !userData ) // could not open file 89 { 90 cerr << "Could not open database."; 91 exit( 1 ); 92 } // end if 93 94 // add new member 95 if ( newMember ) 96 { 97 // read username and password from file 98 while ( !userFound && userData >> fileUsername >> filePassword ) 99 { 100 if ( userName == fileUsername ) // name is already taken 101 userFound = true; 102 } // end while 103 104 if ( userFound ) // user name is taken 105 { 106 header(); 107 cout << "

This name has already been taken.

" 108 << "<a href="">Try Again</a>"; 109 } // end if 110 else // process data 111 { 112 writeCookie(); // write cookie 113 header(); 114 115 // write user data to file 116 userData.clear(); // clear eof, allow write at end of file 117 userData << " " << userName << " " << passWord; 118 119 cout << "

Your information has been processed." 120 << "<a href="">Start Shopping</a>

"; 121 } // end else 122 } // end if 123 else // search for password if entered 124 { 125 bool authenticated = false; 126 127 // read in user data 128 while ( !userFound && userData >> fileUsername >> filePassword ) 129 { 130 // username was found 131 if ( userName == fileUsername ) 132 { 133 userFound = true; 134 135 // determine whether password is correct 136 // and assign bool result to authenticated 137 authenticated = ( passWord == filePassword ); 138 } // end if 139 } // end while 140 141 // user is authenticated 142 if ( authenticated ) 143 { 144 writeCookie(); 145 header(); 146 147 cout << "

Thank you for returning, " << userName << "!

" 148 << "<a href="">Start Shopping</a>"; 149 } // end if 150 else // user not authenticated 151 { 152 header(); 153 154 if ( userFound ) // password is incorrect 155 cout << "

You have entered an incorrect password. " 156 << "Please try again.

" 157 << "<a href="">Back to login</a>"; 158 else // user is not registered 159 cout << "

You are not a registered user.

" 160 << "<a href="">Register</a>"; 161 } // end else 162 } // end else 163 } // end else 164 165 cout << " "; 166 return 0; 167 } // end main 168 169 // function to output header 170 void header() 171 { 172 cout << "Content-Type: text/html "; // output header 173 174 // output XML declaration and DOCTYPE 175 cout << "" 176 << " 177 << ""http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">"; 178 179 // output html element and some of its contents 180 cout << "" 181 << "Login Page; 182 } // end function header 183 184 // function to write cookie data 185 void writeCookie() 186 { 187 string expires = "Friday, 14-MAY-10 16:00:00 GMT"; 188 cout << "Set-Cookie: CART=; expires=" << expires << "; path= "; 189 } // end function writeCookie

Figure 19.21 shows the first of these scriptsthe login page. This script is the most complex of all the scripts in this section. The first if condition (line 37) determines whether data was posted to the program. The second if condition (line 66) determines whether dataString remains empty (i.e., there was no submitted data to decode or the decoding did not complete successfully). The first time we run this program, the first condition fails and the second condition succeeds, so lines 7277 output an XHTML form to the user, as shown in the first screen capture of Fig. 19.21. When the user fills out the form and clicks the login button, login.cgi is requested againthe request contains posted data this time, so the condition in line 37 evaluates to true and the condition in line 66 evaluates to false.



If the user submitted data, program control continues into the else block that begins in line 79, where the script processes the data. Line 86 opens userdata.txtthe file that contains all usernames and passwords for existing members. If the user checked the New checkbox on the Web page to create a new membership, the condition in line 95 evaluates to TRue, and the script attempts to record the user's information in the userdata.txt file on the server. Lines 98102 read through this file, comparing each username with the name entered. If the username already appears in the file, the loop in lines 98102 terminates before reaching the end of the file, and lines 107108 output an appropriate message to the user, and a hyperlink back to the form is provided. If the username entered does not already exist in userdata.txt, line 117 adds the new user information to the file in the format

 Bernard
 blue

 

Each username and password is separated by a newline character. Lines 119120 provide a hyperlink to the script of Fig. 19.22, which allows users to purchase items.

Figure 19.22. CGI script that allows users to buy a book.

(This item is displayed on pages 961 - 963 in the print version)

" 83 << "<a href="">Check Out</a>" 84 << ""; 85 return 0; 86 } // end main 87 88 // function to output header information 89 void header() 90 { 91 cout << "Content-Type: text/html "; // output header 92 93 // output XML declaration and DOCTYPE 94 cout << "" 95 << " 96 << ""http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">"; 97 98 // output html element and some of its contents 99 cout << "" 100 << "Shop Page"; 101 } // end function header

 1 // Fig. 19.22: shop.cpp
 2 // Program to display available books.
 3 #include 
 4 using std::cerr;
 5 using std::cout;
 6 using std::ios;
 7
 8 #include 
 9 using std::ifstream;
10
11 #include 
12 using std::string;
13
14 #include 
15 using std::exit;
16
17 void header();
18
19 int main()
20 {
21 // variables to store product information
22 char book[ 50 ] = "";
23 char year[ 50 ] = "";
24 char isbn[ 50 ] = "";
25 char price[ 50 ] = "";
26 
27 string bookString = "";
28 string yearString = "";
29 string isbnString = "";
30 string priceString = "";
31 
32 ifstream userData( "catalog.txt", ios::in ); // open file for input
33 
34 // file could not be opened
35 if ( !userData )
36 {
37 cerr << "Could not open database.";
38 exit( 1 );
39 } // end if
40 
41 header(); // output header
42 
43 // output available books 
44 cout << "
Books available for sale

"
45  << ""; 
46 
47 // file is open
48 while ( userData )
49 {
50 // retrieve data from file
51 userData.getline( book, 50 );
52 bookString = book;
53 
54 userData.getline( year, 50 );
55 yearString = year;
56 
57 userData.getline( isbn, 50 );
58 isbnString = isbn;
59 
60 userData.getline( price, 50 );
61 priceString = price;
62 
63 cout << "";
66 
67 // file is still open after reads
68 if ( userData )
69 {
70 // output form with buy button 
71 cout << "
"; 
77 } // end if
78 
79 cout << "
";
80 } // end while
81 
82 cout << "
" << bookString << " " << yearString 64 << " " << isbnString << " " << priceString 65 << "

72 << "action="/cgi-bin/viewcart.cgi">" 73 << "" 74 << " 75 << isbnString << ""/>" << " 76 << "value="Add to Cart"/>

The last possible scenario for this script is for returning users (lines 123162). This portion of the program executes when the user enters a name and password but does not select the New checkbox (i.e., the else of line 123 is evaluated). In this case, we assume that the user already has a username and password in userdata.txt. Lines 128139 read through userdata.txt in an attempt to locate the username entered. If the username is found (line 131), we determine whether the password entered matches the password stored in the file (line 137). If so, bool variable authenticated is set to true. Otherwise, authenticated remains false. If the user has been authenticated (line 142), line 144 calls function writeCookie to initialize a cookie named CART (line 188), which is used by other scripts to store data indicating which books the user has added to the shopping cart. Note that this cookie replaces any existing cookie of the same name, causing data from prior sessions to be deleted. After creating the cookie, the script outputs a message welcoming the user back to the Web site and providing a link to shop.cgi, where the user can purchase books (lines 147148).

If the user was not authenticated, the program determines why (lines 154160). If the user was found but not authenticated, a message is output indicating that the password is invalid (line 155157). A hyperlink is provided to the login page (<a href="/cgi-bin/login.cgi">), where the user can attempt to login again. If neither the username nor the password was found, an unregistered user has attempted to login. Lines 159160 output a message indicating that the user does not have the proper authorization to access the page and providing a link that allows the user to attempt another login.</a>

<a href="/cgi-bin/login.cgi">Figure 19.22 uses the values in catalog.txt (Fig. 19.25) to output in an XHTML table the items that the user can purchase (lines 4582). The last column for each row includes a button for adding the item to the shopping cart. Lines 6365 output the different values for each book, and lines 7176 output a form containing the submit button for adding each book to the shopping cart. Hidden form fields are specified for each book and its associated information. Note that the resulting XHTML document sent to the client contains several forms, one for each book. However, the user can submit only one form at a time. The name-value pairs of the hidden fields within the submitted form are posted to the viewcart.cgi script.</a>


<a href="/cgi-bin/login.cgi">[Page 963]</a>

<a href="/cgi-bin/login.cgi">When a user purchases a book, the viewcart.cgi script is requested, and the ISBN for the book to be purchased is sent to the script via a hidden form field. Figure 19.23 begins by reading the value of the cookie stored on the user's system (line 35). Any existing cookie data is stored in string cookieString (line 36). The entered ISBN number from the form of Fig. 19.22 is stored in string isbnEntered (line 52). The script then determines whether the cart already contains data (line 61). If not, the cookieString is given the value of the entered ISBN number (line 62). If the cookie already contains data, the entered ISBN is appended to the existing cookie data (line 64). The new book is stored in the CART cookie in lines 6768. Line 84 outputs the cart's contents in a table by calling function displayShoppingCart.</a>

<a href="/cgi-bin/login.cgi">Figure 19.23. CGI script that allows users to view their carts' contents.</a>

<a href="/cgi-bin/login.cgi">(This item is displayed on pages 964 - 967 in the print version) </a>

 1 // Fig. 19.23: viewcart.cpp
 2 // Program to view books in the shopping cart.
 3 #include 
 4 using std::cerr;
 5 using std::cin;
 6 using std::cout;
 7 using std::ios;
 8
 9 #include 
10 using std::ifstream;
11
12 #include 
13 using std::string;
14
15 #include 
16 using std::getenv;
17 using std::atoi;
18 using std::exit;
19
20 void displayShoppingCart( const string & );
21
22 int main()
23 {
24 char query[ 1024 ] = ""; // variable to store query string
25 string cartData; // variable to hold contents of cart
26 
27 string dataString = "";
28 string cookieString = "";
29 string isbnEntered = "";
30 int contentLength = 0;
31 
32 // retrieve cookie data 
33 if ( getenv( "HTTP_COOKIE" ) ) 
34 { 
35  cartData = getenv( "HTTP_COOKIE" );
36  cookieString = cartData; 
37 } // end if 
38 
39 // data was entered
40 if ( getenv( "CONTENT_LENGTH" ) )
41 {
42 contentLength = atoi( getenv( "CONTENT_LENGTH" ) );
43 cin.read( query, contentLength );
44 dataString = query;
45 
46 // find location of isbn value
47 int addLocation = dataString.find( "add=" ) + 4;
48 int endAdd = dataString.find( "&isbn" );
49 int isbnLocation = dataString.find( "isbn=" ) + 5;
50 
51 // retrieve isbn number to add to cart
52 isbnEntered = dataString.substr( isbnLocation );
53 
54 // write cookie
55 string expires = "Friday, 14-MAY-10 16:00:00 GMT";
56 int cartLocation = cookieString.find( "CART=" ) + 5;
57 
58 if ( cartLocation > 4 ) // cookie exists 
59  cookieString = cookieString.substr( cartLocation );
60 
61 if ( cookieString == "" ) // no cookie data exists
62 cookieString = isbnEntered;
63 else // cookie data exists
64 cookieString += "," + isbnEntered;
65 
66 // set cookie 
67 cout << "Set-Cookie: CART=" << cookieString << "; expires="
68  << expires << "; path=
"; 
69 } // end if
70 
71 cout << "Content-Type: text/html

"; // output HTTP header
72 
73 // output XML declaration and DOCTYPE
74 cout << ""
75 << "
76 << ""http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">";
77 
78 // output html element and some of its contents
79 cout << ""
80 << "Shopping Cart"
81 << "

Here is your current order:

"; 82 83 if ( cookieString != "" ) // cookie data exists 84 displayShoppingCart( cookieString ); 85 else 86 cout << "The shopping cart is empty."; 87 88 // output links back to book list and to check out 89 cout << "

"; 90 cout << "<a href="">Back to book list</a> "; 91 cout << "<a href="">Check Out</a>"; 92 cout << " "; 93 return 0; 94 } // end main 95 96 // function to display items in shopping cart 97 void displayShoppingCart( const string &cookieRef ) 98 { 99 char book[ 50 ] = ""; 100 char year[ 50 ] = ""; 101 char isbn[ 50 ] = ""; 102 char price[ 50 ] = ""; 103 104 string bookString = ""; 105 string yearString = ""; 106 string isbnString = ""; 107 string priceString = ""; 108 109 ifstream userData( "catalog.txt", ios::in ); // open file for input 110 111 if ( !userData ) // file could not be opened 112 { 113 cerr << "Could not open database."; 114 exit( 1 ); 115 } // end if 116 117 cout << ""; 118 cout << "" 119 << ""; 120 121 // file is open 122 while ( !userData.eof() ) 123 { 124 // retrieve book information 125 userData.getline( book, 50 ); 126 bookString = book; 127 128 // retrieve year information 129 userData.getline( year, 50 ); 130 yearString = year; 131 132 // retrieve isbn number 133 userData.getline( isbn, 50 ); 134 isbnString = isbn; 135 136 // retrieve price 137 userData.getline( price, 50 ); 138 priceString = price; 139 140 int match = cookieRef.find( isbnString, 0 ); 141 int count = 0; 142 143 // match has been made 144 while ( match >= 0 && isbnString != "" ) 145 { 146 count++; 147 match = cookieRef.find( isbnString, match + 13 ); 148 } // end while 149 150 // output table row with book information 151 if ( count != 0 ) 152 cout << ""; 155 } // end while 156 157 cout << "
Title Copyright ISBN Price Count
" << bookString << " " << yearString 153 << " " << isbnString << " " << priceString 154 << " " << count << "
"; // end table 158 } // end function displayShoppingCart <a href="/cgi-bin/login.cgi"></a> <a href="/cgi-bin/login.cgi"> </a>

<a href="/cgi-bin/login.cgi">Function displayShoppingCart displays the items in the shopping cart in a table. Line 109 opens the server-side file catalog.txt. If the file opens successfully, lines 122155 get each book's information (including its title, copyright, ISBN and price) from the file. Lines 125138 store these pieces of data in string objects. Lines 140148 count how many times the current ISBN appears in the cookie (i.e., in the shopping cart). If the current book appears in the user's cart, lines 151154 display a table row containing the book's title, copyright, ISBN and price, as well as the number of copies of the book the user has chosen to purchase.</a>


<a href="/cgi-bin/login.cgi">[Page 967]</a>

<a href="/cgi-bin/login.cgi">Figure 19.24 is the page that is displayed when the user chooses to check out (i.e., purchase the books in the shopping cart). This script outputs a message to the user and calls writeCookie (line 13), which effectively erases the current information in the shopping cart.</a>

<a href="/cgi-bin/login.cgi">Figure 19.24. Check out program.</a>

<a href="/cgi-bin/login.cgi">(This item is displayed on pages 967 - 968 in the print version) </a>

 1 // Fig. 19.24: checkout.cpp
 2 // Program to log out of the system.
 3 #include 
 4 using std::cout;
 5
 6 #include 
 7 using std::string;
 8
 9 void writeCookie();
10
11 int main()
12 {
13 writeCookie(); // write the cookie
14 cout << "Content-Type: text/html

"; // output header
15
16 // output XML declaration and DOCTYPE
17 cout << ""
18 << "
19 << ""http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">";
20
21 // output html element and its contents
22 cout << ""
23 << "Checked Out

" 24 << "

You have checked out " 25 << "You will be billed accordingly To login again, " 26 << "<a href="">click here</a>" 27 << "

"; 28 return 0; 29 } // end main 30 31 // function to write cookie 32 void writeCookie() 33 { 34 // string containing expiration date 35 string expires = "Friday, 14-MAY-10 16:00:00 GMT"; 36 37 // set cookie 38 cout << "Set-Cookie: CART=; expires=" << expires << "; path= "; 39 } // end writeCookie

<a href="/cgi-bin/login.cgi"></a>

<a href="/cgi-bin/login.cgi">Figure 19.25 shows the contents of the catalog.txt file. This file must reside in the same directory as the CGI scripts for this shopping-cart application to work correctly.</a>


<a href="/cgi-bin/login.cgi">[Page 968]</a>

<a href="/cgi-bin/login.cgi">Figure 19.25. Contents of catalog.txt.</a>

<a href="/cgi-bin/login.cgi">
 Visual Basic .NET How to Program
 2002
 0-13-029363-6
 $50.00
 C# How to Program
 2002
 0-13-062221-4
 $49.95
 C How to Program 4e
 2004
 0-13-142644-3
 $88.00
 Java How to Program 6e
 2005
 0-13-148398-6
 $88.00
</a>
 

<a href="/cgi-bin/login.cgi"> </a>

<a href="/cgi-bin/login.cgi">[Page 969]</a>

<a href="/cgi-bin/login.cgi">19 17 Wrap Up</a>

Introduction to Computers, the Internet and World Wide Web

Introduction to C++ Programming

Introduction to Classes and Objects

Control Statements: Part 1

Control Statements: Part 2

Functions and an Introduction to Recursion

Arrays and Vectors

Pointers and Pointer-Based Strings

Classes: A Deeper Look, Part 1

Classes: A Deeper Look, Part 2

Operator Overloading; String and Array Objects

Object-Oriented Programming: Inheritance

Object-Oriented Programming: Polymorphism

Templates

Stream Input/Output

Exception Handling

File Processing

Class string and String Stream Processing

Web Programming

Searching and Sorting

Data Structures

Bits, Characters, C-Strings and structs

Standard Template Library (STL)

Other Topics

Appendix A. Operator Precedence and Associativity Chart

Appendix B. ASCII Character Set

Appendix C. Fundamental Types

Appendix D. Number Systems

Appendix E. C Legacy Code Topics

Appendix F. Preprocessor

Appendix G. ATM Case Study Code

Appendix H. UML 2: Additional Diagram Types

Appendix I. C++ Internet and Web Resources

Appendix J. Introduction to XHTML

Appendix K. XHTML Special Characters

Appendix L. Using the Visual Studio .NET Debugger

Appendix M. Using the GNU C++ Debugger

Bibliography



C++ How to Program
C++ How to Program (5th Edition)
ISBN: 0131857576
EAN: 2147483647
Year: 2004
Pages: 627

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net