PHP Classes
PHP Classes
elePHPant
Icontem

Creating an AJAX based PHP Shopping Cart Part 2: Removing Items and Checkout - Shopping Cart package blog

Recommend this page to a friend!
  All package blogs All package blogs   Shopping Cart Shopping Cart   Blog Shopping Cart package blog   RSS 1.0 feed RSS 2.0 feed   Blog Creating an AJAX base...  
  Post a comment Post a comment   See comments See comments (7)   Trackbacks (0)  

Author:

Updated on: 2015-09-21

Posted on:

Package: Shopping Cart

The first part of this tutorial article covered the importance of shopping carts in sites that sell products and how to make a simple shopping cart that can add products from a database via an AJAX based Web interface.

Read this part of the article to learn how to perform other important operations like removing products or empty the shopping cart and how to proceed to the checkout.




Contents

Introduction

Removing Cart Entries

The Javascript Code

The AJAX Part

The Cart Class

Checkout

Send the Order for Payment

Conclusion


Introduction

In the first part of this tutorial we talked about the importance of shopping carts and how to make a simple one.

It was demonstrated how to create a list of products from the database and add the products that the user picks to the cart session variables.

This part of the article shows how to remove a product from the cart, how to empty the cart, and after that it shows how to proceed to a simple checkout process.

Removing Cart Entries

In the previous article it was demonstrated how to show cart entries. We have created a script named show-cart.php. Let us add two elements to that script, one to remove one element, and a link to empty the cart.

<?php
  session_start();
  require_once( "config.php" );
  require_once( "cart.php" );
?>
<html xmlns = "http://www.w3.org/1999/xhtml">
  <head>
    <title>Example of AJAX Cart</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="description" content="" />
    <meta name="keywords" content="" />
    <script type="text/javascript" src= "https://code.jquery.com/jquery-1.11.3.min.js" ></script>
    <script type="text/javascript" src="main.js"></script>
  </head>
  <body leftmargin="0" marginwidth="0" topmargin="0" marginheight="0">
    <h1>Show cart</h1>
    <?php
      $cart = new cart();
      $products = $cart->getCart();
    ?>
    <table cellpadding="5" cellspacing="0" border="0">
      <tr>
        <td align="left" width="200"><b>Product</b></td>
        <td align="left" width="200"><b>Count</b></td>
        <td align="left" width="200" colspan="2"><b>Total</b></td>
      </tr>
      <?php
        foreach($products as $product){
      ?>
        <tr>
          <td align="left"><?php print HtmlSpecialChars( $product->product ); ?></td>
          <td align="left"><?php print $product->count; ?></td>
          <td align="left">$<?php print $product->total; ?></td>
          <td align="center"><span style="cursor:pointer;" class="removeFromCart" data-id="<?php print $product->id; ?>">remove one element</span></td>
        </tr>
      <?php 
        }
      ?>
    </table>
    <br /><a href="index.php" title="go back to products">Go back to products</a>     <a href="javascript:void(0);" class="emptyCart" title="empty cart">Empty cart</a>
  </body>
</html>

Show cart screenshot part 2

Maybe you did not notice the difference, but it was added the colspan attribute with value 2 in the TD tag which holds "Total" keyword. That is because it is necessary to split that column to add a span tag as a link.

In the foreach loop you may notice an additional TD tag with a span tag with the value "remove one element" where there is an attribute "data-id" with the product ID. That will be needed that later by the JavaScript code.

Another addition to the file is the "Empty cart" link in the end of the file. That will call a JavaScript function to empty the cart.

The Javascript Code

Now let us explore the JavaScript code for doing all the job on thr browser side. If you remember correctly, we have created "main.js", before closing the "$(document).ready()" function add this code:
  $( "span.removeFromCart" ).on( "click" , function() {
    var id = $(this).attr( "data-id" );
    $.ajax({
      type: "GET",
      url: "ajax.php?id=" + id + "&action=remove"
    })
    .done(function()
    {
      alert("Product have been removed.");
      location.reload();
    });
  });
  $( "a.emptyCart" ).on( "click" , function() {
    $.ajax({
      type: "GET",
      url: "ajax.php?action=empty"
    })
    .done(function()
    {
      alert("Cart been emptied.");
      location.reload();
    });
  });

In this file we have set now three different event handlers: add to cart, remove from cart and empty cart. These are used in the two front end files explained before. Note that we are attaching the two new event handlers after the document is fully loaded also. This is important for the code to work correctly.

In show-cart.php script we are removing product items, so we added the span elements with the class "removeFromCart" to an onclick handler which will trigger the call to a function that will send the AJAX request with the product ID and the action set to remove.

When the request is completed it shows an alert telling the user the action that was processed and then the page is reloaded so the users see the new status of the cart.

There is another event handler attached to the link empty cart. It will trigger the AJAX request sending just one parameter, which is the action empty the cart. When the request is processed it wil also show an alert message and the page reloaded as well.

The AJAX Part

In the JavaScript file we send three types of AJAX requests from three event handlers. If you remember from the previous article we have written a switch statement but with only one case. Now we need to add two new cases.

    case "remove":
      $cart->removeFromCart();
      break;

    case "empty":
      $cart->emptyCart();
      break;

It is not necessary to explain this code. It is just two cases, one for remove a product and the other to empty the cart. They call our class to do the job.

The Cart Class

Finally we need to add our new methods to the cart class. Before the end of the class add this code:

  public function removeFromCart() {
    $id = intval( $_GET["id"] );
    if($id > 0) {
      if($_SESSION[ 'cart' ] != "") {
        $cart = json_decode( $_SESSION['cart'], true);
        for($i=0; $i<count($cart); $i++){
          if($cart[$i][ "product" ] == $id){
            $cart[$i][ "count" ] = $cart[$i]["count"]-1;
            if($cart[$i][ "count" ] < 1){
              unset($cart[$i]);
            }
            break;
          }
        }
        $cart = array_values($cart);
        $_SESSION['cart'] = json_encode($cart);
      }
    }
  }
  
  public function emptyCart() {
    $_SESSION['cart'] = "";
  }
 

If you remember correctly in "ajax.php" we used "removeFromCart" method for the "remove" action. As the methods before in the previous article, we use this method to manipulate cart data.

In this method we search for a product by its ID. If the product is found, we decrement the count field by one. If the count of a product drops to zero, we do not need it any more in our cart, so we just delete it. The array_values() function is used to rearrange the cart array after deleting an element from the cart.

The last action we used in AJAX handling script is "empty" where we call "emptyCart" method. This method it is very simple, we just empty the cart in the session by emptying its Array.

Checkout

Checkout page is very similar to the show-cart page, the only difference is it has a checkout button and a total for all products. It also does not has remove item or empty. It is a page where you make a final check and send the customer to payment page.

Before we start with checkout.php file, we need to add a link to it in show-cart.php. Just add the code below after the empty cart link.

     <a href="checkout.php" title="Checkout">Checkout</a>

The reason why we have a checkout page is to have a record of all the transactions we do in the site. When you send the customer to the payment page you do not have his information anymore, so we need to keep the data in our database. We will keep his contact information and what he bought on our site, so we can deliver it later to him.

Let us add two new tables to the database which will hold this information:

CREATE TABLE IF NOT EXISTS `order` (
  `id` int(9) NOT NULL,
  `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `email` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `total` float NOT NULL DEFAULT '0'
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
ALTER TABLE `order` ADD PRIMARY KEY (`id`);
ALTER TABLE `order` MODIFY `id` int(9) NOT NULL AUTO_INCREMENT;

And:

CREATE TABLE IF NOT EXISTS `order_items` (
  `id` int(9) NOT NULL,
  `order_id` int(9) NOT NULL,
  `product_id` int(9) NOT NULL,
  `nitem` int(9) NOT NULL,
  `total` float NOT NULL DEFAULT '0'
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
ALTER TABLE `order_items` ADD PRIMARY KEY (`id`);
ALTER TABLE `order_items` MODIFY `id` int(9) NOT NULL AUTO_INCREMENT;

The first table "order" will hold general information about every order. It will have customer name, email and total cost. The second table "order_items" will contain the detailed data about which items did this person buy.

It is important to note that we need the ID of the product, the ID of our order, number of items of that order and the total price. The price can not be taken from product table as prices change from time to time, so we need the exact price in that moment when the customer bought the product.

After creating the database tables, let us create "checkout.php" script:

<?php
  session_start();
  require_once("config.php");
  require_once("cart.php");
?>
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Example of AJAX Cart</title>
    <meta http-equiv = "Content-Type" content = "text/html; charset=utf-8" />
    <meta name="description" content="" />
    <meta name="keywords" content="" />
    <script type="text/javascript" src = "https://code.jquery.com/jquery-1.11.3.min.js" ></script>
    <script type="text/javascript" src="main.js"></script>
  </head>
  <body leftmargin="0" marginwidth="0" topmargin="0" marginheight="0">
    <h1>Show cart</h1>
    <?php
      $cart = new cart();
      $products = $cart->getCart();
    ?>
    <table cellpadding="5" cellspacing="0" border="0">
      <tr>
        <td align="left" width="200"><b>Product</b></td>
        <td align="left" width="200"><b>Count</b></td>
        <td align="left" width="200"><b>Total</b></td>
      </tr>
      <?php
        foreach($products as $product){
      ?>
        <tr>
          <td align="left"><?php print HtmlSpecialChars( $product->product ); ?></td>
          <td align="left"><?php print $product->count; ?></td>
          <td align="left">$<?php print $product->total; ?></td>
        </tr>
      <?php 
        }
      ?>
    </table>
 <h2>Insert your contact and submit to confirm your order</h2>
 <form action="/confirm.php" method="post">
  <table cellpadding="5" cellspacing="0" border="0">
   <tr>
    <td align="left" valign="top">Your name</td>
    <td align="left" valign="top"><input type="text" name="uname" /></td>
    <td align="left" valign="top">Email</td>
    <td align="left" valign="top"><input type="text" name="email" /></td>
    <td align="left" valign="top"><input type="submit" value="Send order" /></td>
   </tr>
  </table>
 </form>
  </body>
</html>

This script is very straightforward, basically the same as show-cart.php in structure. It was just removed the elements to remove products and empty cart links. And added a form so customers can add their name and email for contact and a button to send their order.

Send the Order for Payment

Finally we have arrived to the order insertion. We have customers contact information, we have the products he wants to buy and he clicked send order.

We will now insert a new row in order table then we will create a bunch of new rows for order_items table also. After that we just redirect the customer to payment page. Create a new file named "order.php" and add this code in it:

 <?php
  session_start();
  require_once( "config.php" );
  require_once( "cart.php" );
  $cart = new cart();
  $cart->sendOrder();
  $cart->emptyCart();
  $cart->redirect();
 ?>

OK, so "sendOrder" method will save the transaction in the database, "emptyCart" will empty our cart so we do not get duplicates in the future if the customer bookmarks this link or clicks on back button on the browsers toolbar. Also some external payment system will get the customer back to the cart page, so we need to empty the cart.

Finally redirect is a method to redirect the user to a payment page.

Now let us add the two new methods in our class:

public function redirect(){
 // here goes redirect code
}

public function sendOrder(){
 $arr = array();
 $name = strip_tags($_POST['uname']);
 $email = strip_tags($_POST['email']);
 $total = 0;

 $cart = $this->getCart();

 for($i=0; $i<count($cart); $i++){
  $total += $cart[$i]->total;
 }

 $dbConnection = $this->dbConnection;
 $dbConnection->query( "SET NAMES 'UTF8'" ); 

 $statement = $dbConnection->prepare( "insert into order( name, email, total) value(?, ?, ?)" );
 $statement->bind_param( 'ssd', $name, $email, $total);
 $statement->execute();
 $newid = $statement->insert_id;
 $statement->close();

 for($i=0; $i<count($cart); $i++){
  $statement = $dbConnection->prepare( "insert into order_items( order_id, product_id, nitem, total) value(" . $newid . ", ?, ?, ?)" );
  $statement->bind_param( 'iid', $cart[$i]->id, $cart[$i]->count, $cart[$i]->total);
  $statement->execute();
  $statement->close();
 }
}

You will notice that the method redirect is empty. That is why you need to add the code here that will communicate with your payment server API. Different servers have different API's, so I am leaving this to you to write according to the payment system you want to use.

The second method is sendOrder. It is very simple. We first collect the customer data to send with  the POST method, then with the getCart method we retrieve all data from the cart. We should not pass these data values via HTML, so nobody with malicious intentions can easily manipulate the information.

We loop through cart array and get the grand total price of all products. Then we insert a new row in orders table. We get back the ID of that row, so we can use it in our order_items table, which we will fill with a loop of the cart items.

Conclusion

In this article you learned how to build a simple shopping cart with a simple class, so you can sell products on your site without installing a full-blown e-commerce package.

The class package is available right here for you to download. You can enhance it in many ways to make the class even better to address your needs like adding support for VAT and specify price currency.

If you liked this article or you have questions or suggestions, just post comment here.  If you have great suggestions to improve the package I may implement your ideas in the class in the future. Just let me know.




You need to be a registered user or login to post a comment

1,422,865 PHP developers registered to the PHP Classes site.
Be One of Us!

Login Immediately with your account on:

FacebookGmail
HotmailStackOverflow
GitHubYahoo


Comments:

4. How to alert if product is already in the cart. - SHAMSUDIN SULAIMAN (2016-11-17 19:17)
Add alert if product is already in the cart.... - 0 replies
Read the whole comment and replies

3. Bad Practices - Sean M (2015-10-09 13:42)
This tutorial teaches a number of poor practices... - 0 replies
Read the whole comment and replies

2. Page reload - Kristof Dekany (2015-09-22 10:27)
you shouldn't reload the page after each request... - 2 replies
Read the whole comment and replies

1. What if a product is deleted - Joseph McMurry (2015-09-21 16:08)
If a product is deleted from the database, an issue may occur.... - 1 reply
Read the whole comment and replies




  Post a comment Post a comment   See comments See comments (7)   Trackbacks (0)  
  All package blogs All package blogs   Shopping Cart Shopping Cart   Blog Shopping Cart package blog   RSS 1.0 feed RSS 2.0 feed   Blog Creating an AJAX base...