Jump to content

Recommended Posts

I have a very simple shopping cart class that is going to be used for my work's e-commerce site.  The class is as follows:
[code]
<?php

class ShoppingCart{
  private $Cart = array();

  public function addProduct($name, $price, $quantity){
      $this -> Cart[] = new Product($name, $price, $quantity);
  }

  public function clearCart(){
      $this -> Cart = array();
  }

  public function getTotal(){
      $total = 0;

      foreach($this -> Cart as $value){
        $total += $value -> getPrice();
      }

      return $total;
  }

  public function showCart(){
      echo "<table><tr><th>Name:</th><th>Quantity:</th><th>Total Price:</th></tr>\n";

      foreach($this -> Cart as $value){
        echo "<tr><td>{$value->getName()}</td><td>{$value->getQuan()}</td><td>\${$value->getPrice()}</td></tr>\n";
      }
      echo "</table>\n";
  }
}

?>
[/code]

I'd like to add an Amazon.com-esque ability to remove individual items from the cart.  I'm thinking that I can add a 'delete' button to each item in the showCart method, but that's where I'm encountering my problem.

From what I can see, Amazon handles removing items by having each 'delete' button (visible when you view your shopping cart) as a form submission button.  My only problem is with delete button handling upon submission.  Each button has a value of delete#, with # = i+1.  How would I get a hold of the right delete value on submission?
Link to comment
https://forums.phpfreaks.com/topic/31136-shoppingcart-removing-items/
Share on other sites

[quote author=utexas_pjm link=topic=119145.msg487819#msg487819 date=1166489503]
Use the index of the item in your internal array, $cart.  The code would looks something like this:

[code]
<?PHP
...
deleteItem($index){
  unset($this->Cart[$index]);
}
...
?>
[/code]
[/quote]

True, but that's not what I was really asking. ;)

Say my showCart method is modified as follows:
[code]
<?php

public function showCart(){
  echo "<table><tr><th>Name:</th><th>Quantity:</th><th>Total Price:</th></tr>\n";

  foreach($this -> Cart as $key => $value){
      echo "<tr><td><input type='submit' name='submit{$key}' value='Delete' /></td><td>{$value->getName()}</td><td>{$value->getQuan()}</td><td>\${$value->getPrice()}</td></tr>\n";
  }
  echo "</table>\n";
}

?>
[/code]

And the script that displays the cart is something like:
[code]
<?php

include('../php_config/config.php');

session_start();
ob_start();

//do session validation/verification here, and retrieve $myCart

if(isset($_POST['submit'])){ // <-- trouble area
  //remove item
}

//show the form regardless

?>

<form name="cart" action="<?php echo $_SERVER['PHP_SELF'] ?>" method="POST">
<?php
$myCart -> showCart();
?>
</form>
[/code]

How can I get a hold of submit{$key}, which comes from the showCart method, in order to check if it's set or not?  Since my cart has no size limit, it would be inefficient to loop through the entire cart, wouldn't it?  Or is that really the only way I can get a hold of the right item to delete?
I'll admit that I didn't read the full thread, but why don't you simply use checkboxes?

If you insist on using a button for each item, then why not simply use an array?

<input type='submit' name='submit[$key]' value='Delete' />

[code]<?php
if(isset($_POST['submit'])){
foreach($_POST['submit'] as $index=>$value){
if(!empty($value)){
unset($this->Cart[$index]);
}
}
}
?>[/code]

I would use some top limit for the cart size, be it very high. Like 250 or something. Anything 'unlimited' is a possible one way ticket to disaster.
Hmm...I might use the checkbox method so one doesn't have to delete each item at a time if they have multiple items they want to remove.  Actually, that would probably be easier, as I can just use the cart's key values as the checkbox values, and unset those items that way.
I've almost got it working.  I decided to use the checkbox method -- unfortunately, it doesn't always remove what I want, often just leaving the item(s) I've checked in the shopping cart.  I'm not getting any errors, though, unless I click on the 'Remove Checked Items' submit button when there's nothing in the cart at all, so I think I'm on the right track (and that's an easy error to remedy, regardless).  I think my problem is stemming from it being a sticky form.  I can usually remove something from the cart when I first go to my viewcart.php script, but all subsequent attempts fail.  Any ideas?  I'll post my code below.

My modified ShoppingCart class:
[code]
<?php

class ShoppingCart{
   private $Cart = array();

   public function addProduct($name, $price, $quantity){
      $this -> Cart[] = new Product($name, $price, $quantity);
   }

   public function removeProduct($key){
      unset($this -> Cart[$key]);
   }

   public function clearCart(){
      $this -> Cart = array();
   }

   public function getTotal(){
      $total = 0;

      foreach($this -> Cart as $value){
         $total += $value -> getPrice();
      }

      return $total;
   }

   public function showCart(){
      echo "<table><tr><th>Name:</th><th>Quantity:</th><th>Total Price:</th></tr>\n";

      foreach($this -> Cart as $value){
         echo "<tr><td><input type='checkbox' name='tmpCart[]' />{$value->getName()}</td><td>{$value->getQuan()}</td><td>\${$value->getPrice()}</td></tr>\n";
      }
      echo "</table>\n";
   }
}

?>
[/code]

My viewcart.php file:
[code]
<?php

include('../php_config/config.php');

session_start();
ob_start();

if(!isset($_SESSION['ip'])){
   $ip = $_SERVER['REMOTE_ADDR'];
   $myCart = new ShoppingCart();
}

else{
   if($_SERVER['REMOTE_ADDR'] != unserialize(urldecode($_SESSION['ip']))){
      $ip = $_SERVER['REMOTE_ADDR'];
      $myCart = new ShoppingCart();
   }

   else{
      $ip = unserialize(urldecode($_SESSION['ip']));
      $myCart = unserialize(urldecode($_SESSION['myCart']));
   }
}

if(isset($_POST['submit'])){
   foreach($_POST['tmpCart'] as $key => $value){
      if(!empty($value)){
         $myCart -> removeProduct($key);
      }
   }
}

if(isset($_POST['clear'])){
   $myCart -> clearCart();
}

include('../templates/header.inc');

echo "<form name='shoppingcart' action='{$_SERVER['PHP_SELF']}' method='POST'><br />\n";
$myCart -> showCart();
echo "<input type='submit' name='submit' value='Remove Checked Items' />\n<input type='submit' name='clear' value='Remove All Items' />\n</form><br />\n";

include('../templates/footer.inc');

ob_end_flush();

$_SESSION['ip'] = urlencode(serialize($ip));
$_SESSION['myCart'] = urlencode(serialize($myCart));

?>
[/code]

EDIT: After some more testing, I think my problem is actually caused by my tmpCart array not staying matched up with myCart's internal array when individual items are deleted, but I'm not sure how to fix it.
Your code is not making any sense to me. It's obfuscated.  :P

Anyway, you should be using an associative array, because the items in tmpCart will be reindexed unless you check all items (empty indices aren't kept).

[code]<input type='checkbox' name='tmpCart[$itemId]' />[/code]

In this, right now, $key is just the numeric index of items checked:

[code]<?php
if(isset($_POST['submit'])){
  foreach($_POST['tmpCart'] as $key => $value){
      if(!empty($value)){
        $myCart -> removeProduct($key);
      }
  }
}
?>[/code]

Dump $_POST and you'll see what I mean, if not already.
Thanks for your help, it appears to be working correctly now.

I know my code is a bit...jumbled, at least with the showCart method.  I broke the form up unto two pieces (the form tags in viewcart.php, the inputs in the class) because I wasn't sure if the form would use the right action if I put all of the form's code in the showCart method.  In other words, I thought that the <?php echo $_SERVER['PHP_SELF'] ?> bit would refer to the shopping cart class file, rather than the viewcart file.

If you have any suggestions on how to clean up that bit of code (or anything else that's messy), I'd love to hear it.

And yeah, this thread should probably be moved over to the general PHP Help area.
This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.