billy_111 Posted May 23, 2010 Share Posted May 23, 2010 Hey, I am just finishing off my shopping cart however i have stumbled upon a problem. When i add to basket i execute the following method: public function AddToCart(){ !isset($_SESSION['ID']) ? $_SESSION['ID'] = array() : ''; !isset($_SESSION['theName']) ? $_SESSION['theName'] = array() : ''; !isset($_SESSION['quantity']) ? $_SESSION['quantity'] = array() : ''; !isset($_SESSION['price']) ? $_SESSION['price'] = array() : ''; !isset($_SESSION['image']) ? $_SESSION['image'] = array() : ''; array_push($_SESSION['ID'], $_POST['ID']); array_push($_SESSION['theName'], $_POST['theName']); array_push($_SESSION['quantity'], $_POST['quantity']); array_push($_SESSION['price'], $_POST['price']); array_push($_SESSION['image'], $_POST['image']); $loc = $_SERVER['HTTP_REFERER']; echo "<script>window.location.href='".$loc."'</script>"; } This creates the session as an array. Now lets say i click on the add to basket button twice for the same item. I don't want to have 2 instances of the same item which is what i have not, but i want to have the item name once and then 'x2' next to the quantity. So moving on on my items page i have hidden input values which populates the basket session, shown below: <input type="hidden" name="ID" value="<?php echo $row['theID']; ?>" /> <input type="hidden" name="theName" value="<?php echo $row['theName']; ?>" /> <input type="hidden" name="price" value="<?php echo $row['price']; ?>" /> <input type="hidden" name="image" value="<?php echo $row['image']; ?>" /> <input type="hidden" name="quantity" value="1" /> Now what i have managed to do is when my basket is empty and i add an item to the basket multiple times the basket works exactly how i want. However when i then add a different item to the basket more than once it adds a quantity to both items. This is because i need to target the specific item in the basket. if(isset($_POST['ID'])){ if(!empty($_SESSION['theName'])){ $i=0; foreach($_SESSION['theName'] as $name){ if($_POST['theName'] == $name){ $_SESSION['quantity'][$i] = $_SESSION['quantity'][$i] + 1; }else { $cart->AddToCart(); } } } } I tested this code and clicked add to cart multiple times on 2 different items. I get this: Dior - £69.99 x4 CK Top - £1.99 x1 CK Top - £1.99 x1 Now this item: Dior - £69.99 x4 was actually x3 but when i clicked on a different item more than once it updated both items quantities. So my question is, can i target a specific item in a session array and accomplish what i am trying to do? Just to be clear, i need to in essence update the quantity of the item within the session array. So for example if i add 3 items to my basket i will have 3 items in my array, would i be able to alter the second item in the array? Many thanks. Kind regards Billy Quote Link to comment https://forums.phpfreaks.com/topic/202645-php-shopping-cart-update-basket-item/ Share on other sites More sharing options...
billy_111 Posted May 23, 2010 Author Share Posted May 23, 2010 Any ideas anyone? I just want to be able to update a value in an existing array? Is this possible? Quote Link to comment https://forums.phpfreaks.com/topic/202645-php-shopping-cart-update-basket-item/#findComment-1062278 Share on other sites More sharing options...
ignace Posted May 23, 2010 Share Posted May 23, 2010 I see you are already using objects to handle it, however it's design is very inflexible (which is why you get these headaches). class Cart { private $items = array(); public function addItem(CartItem $item) { $object = $this->findItemByName($item->getName()); if (null === $object) { $this->items[] = $object; } } public function findItemByName($name) { foreach ($this->items as $item) { if (0 === strcasecmp($name, $item->getName())) { return $item; } } return NULL; } } class CartItem { private $id = 0; private $name = ''; private $quantity = 0; private $price = 0.0; private $image = ''; public function getName() { return $this->name; } public function addQuantity($quantity) { if (!ctype_digit($quantity)) { throw new Exception(''); } if (0 > (int) $quantity) { throw new Exception(''); } $this->quantity += (int) $quantity; return $this; } public function equals(CartItem $item) {} } $cart = Cart::fromArray($_SESSION['cart']); .. if (array_key_exists(array('id', 'name', 'quantity', 'price', 'image'), $_POST)) { $id = $_POST['id']; $name = $_POST['name']; .. $temp = new CartItem(); $temp->setId($id); $temp->setName($name); $temp->setQuantity($quantity); .. $item = $cart->findItemByName($temp->getName());//or $cart->findItemById($temp->getId()); if (NULL === $item) {//does not yet exists $cart->addItem($temp); } else { $item->addQuantity(1); } $_SESSION['cart'] = $cart->toArray();//store } Quote Link to comment https://forums.phpfreaks.com/topic/202645-php-shopping-cart-update-basket-item/#findComment-1062295 Share on other sites More sharing options...
billy_111 Posted May 23, 2010 Author Share Posted May 23, 2010 Hey, Thanks so much for your code ignace. I have just started to go OO so apologies for it not being strong Now the code you have suggested looks like a much better way however would this mean i have to change my whole class? Just to show you my full Cart class is shown below: <?php class Cart { public function sanitise($data) { // Escapes parameters before sending SQL query foreach($data as $key => $value){ $data[$key] = $this->mysqli->real_escape_string($value); } return $data; } public function __construct($host, $username, $password, $dbname) { $this->mysqli = new mysqli($host, $username, $password, $dbname); if ($this->mysqli->errno){ echo 'Unable to connect'.$this->mysqli->error; exit(); } } public function AddToCart(){ !isset($_SESSION['ID']) ? $_SESSION['ID'] = array() : ''; !isset($_SESSION['theName']) ? $_SESSION['theName'] = array() : ''; !isset($_SESSION['quantity']) ? $_SESSION['quantity'] = array() : ''; !isset($_SESSION['price']) ? $_SESSION['price'] = array() : ''; !isset($_SESSION['image']) ? $_SESSION['image'] = array() : ''; array_push($_SESSION['ID'], $_POST['ID']); array_push($_SESSION['theName'], $_POST['theName']); array_push($_SESSION['quantity'], $_POST['quantity']); array_push($_SESSION['price'], $_POST['price']); array_push($_SESSION['image'], $_POST['image']); $loc = $_SERVER['HTTP_REFERER']; echo "<script>window.location.href='".$loc."'</script>"; } public function getTotalPrice(){ $i = 0; $total = 0; if(isset($_SESSION['quantity'])){ foreach($_SESSION['price'] as $price){ while(!isset($_SESSION['price'][$i]) && !isset($_SESSION['quantity'][$i])){ $i++; } $total = $total + ($price * $_SESSION['quantity'][$i]); $i++; } } return $total; } public function getTotalItems(){ $total = 0; if(isset($_SESSION['quantity'])){ foreach($_SESSION['quantity'] as $quantity){ $total = $total + $quantity; } } return $total; } public function removeItem(){ $id = $_GET['ID']; unset($_SESSION['ID'][$id]); unset($_SESSION['theName'][$id]); unset($_SESSION['price'][$id]); unset($_SESSION['quantity'][$id]); } public function emptyCart(){ unset($_SESSION['ID']); unset($_SESSION['theName']); unset($_SESSION['price']); unset($_SESSION['quantity']); } public function addCustomerToSession(){ $_SESSION['billingFirstName'] = $_POST['billingFirstName']; $_SESSION['billingSurname'] = $_POST['billingSurname']; $_SESSION['billingAddress1'] = $_POST['billingAddress1']; $_SESSION['billingAddress1'] = $_POST['billingAddress1']; $_SESSION['billingAddress2'] = $_POST['billingAddress2']; $_SESSION['billingCity'] = $_POST['billingCity']; $_SESSION['billingPostcode'] = $_POST['billingPostcode']; } public function insertOrder($data, $sessionID){ $data = $this->sanitise($data); $i=0; session_start(); foreach($_SESSION['ID'] as $ID): $sql = 'INSERT INTO hussaini_orders (userID, itemID, quantity, fname, sname, address1, address2, city, postcode, date_added) VALUES ('.$sessionID.', '.$ID.', '.$_SESSION['quantity'][$i].', \''.$data['billingFirstName'].'\', \''.$data['billingSurname'].'\', \''.$data['billingAddress1'].'\', \''.$data['billingAddress2'].'\', \''.$data['billingCity'].'\', \''.$data['billingPostcode'].'\', now())'; $this->mysqli->query($sql) or die($this->mysqli->error); $i++; endforeach; } public function deductQuantitiesFromItems(){ $i=0; session_start(); foreach($_SESSION['ID'] as $ID): $sql = 'UPDATE hussaini_items SET stock = stock - '.$_SESSION['quantity'][$i].' WHERE ID = '.$ID; $result = $this->mysqli->query($sql) or die($this->mysqli->query($sql)); return $result; $i++; endforeach; } public function __destruct() { $this->mysqli->close(); } } Is there a quick fix for me to go with? On my add to cart item page i have this in my controller: <?php $view->pageTitle = 'Manstore | Items'; require_once('Models/Items.class.php'); require_once('Models/Cart.class.php'); $items = new Items('localhost', 'root', '', 'test'); $cart = new Cart('localhost', 'root', '', 'test'); session_start(); if(isset($_GET['ID'])){ $result = $items->selectItemsByID($_GET['ID']); } if(isset($_POST['ID'])){ if(!empty($_SESSION['theName'])){ $i=0; foreach($_SESSION['theName'] as $name){ if($_POST['theName'] == $name){ $_SESSION['quantity'][$i] = $_SESSION['quantity'][$i] + 1; }else { $cart->AddToCart(); } } } else { $cart->AddToCart(); } } require_once('Views/view-item.phtml'); I need to set this site live soon so i was hoping i could get away with a quick fix for now and implementing a better method like yours later this week.. What do you think? Again i appreciate your support. Kind regards Billy Quote Link to comment https://forums.phpfreaks.com/topic/202645-php-shopping-cart-update-basket-item/#findComment-1062301 Share on other sites More sharing options...
ignace Posted May 23, 2010 Share Posted May 23, 2010 Well your current design is really inflexible due to $_POST, $_SESSION and the database being tightly coupled to your class. For highest flexibility you'd best remove all these dependencies like shown in my example. I could easily modify my example to be used with a database instead of a $_SESSION. $cart = Cart::fromArray($db->execute("SELECT * FROM cart WHERE user_id = {$_SESSION['user_id']}")->fetchAll()); .. if (array_key_exists(array('id', 'name', 'quantity', 'price', 'image'), $_POST)) { $id = $_POST['id']; $name = $_POST['name']; .. $temp = new CartItem(); $temp->setId($id); $temp->setName($name); $temp->setQuantity($quantity); .. $item = $cart->findItemByName($temp->getName());//or $cart->findItemById($temp->getId()); if (NULL === $item) {//does not yet exists $cart->addItem($temp); } else { $item->addQuantity(1); } foreach ($cart->toArray() as $item) {//store $db->execute("INSERT INTO cart (id, name, quantity, price, image) VALUES ({$item['id']}, {$item['name']}, {$item['quantity']}, {$item['price']}, {$item['image']}) ON DUPLICATE KEY UPDATE quantity = quantity + 1"); } } See, how easily I modified my code to match the new setting. Quote Link to comment https://forums.phpfreaks.com/topic/202645-php-shopping-cart-update-basket-item/#findComment-1062305 Share on other sites More sharing options...
ignace Posted May 23, 2010 Share Posted May 23, 2010 I need to set this site live soon so i was hoping i could get away with a quick fix for now and implementing a better method like yours later this week.. This is the kind of thinking you need to get away from. Transforming your application from a badly-designed to a well-designed is not an easy task. Don't forget you are actually rewriting the application which means you put in twice the effort required then if you would have if you would have thought-out the application design. Well, look over my code. All you need is go over all stored items and check if it already exists if so then update otherwise create. I have just started to go OO so apologies for it not being strong If you are working against a deadline then I don't understand why you would start out with something you barely understand? Why didn't you stick to the things you understand? Quote Link to comment https://forums.phpfreaks.com/topic/202645-php-shopping-cart-update-basket-item/#findComment-1062307 Share on other sites More sharing options...
billy_111 Posted May 23, 2010 Author Share Posted May 23, 2010 Hey, Thanks for the advice, this is actually a learning curve for me and once the site is finished it is checked by another developer, who i could just ask but i want to learn myself as it's the best way. I appreciate your suggestions and will definitely try follow your code and try to understand how it works. Thanks again Quote Link to comment https://forums.phpfreaks.com/topic/202645-php-shopping-cart-update-basket-item/#findComment-1062312 Share on other sites More sharing options...
ignace Posted May 23, 2010 Share Posted May 23, 2010 once the site is finished it is checked by another developer, who i could just ask but i want to learn myself as it's the best way You are better off on these forums, nothing guarantee's that what he said is true or that he is the most knowledgeable on the subject. These forums on the other hand have a good deal of highly educated/experienced professionals recognizable by the tag below their name (Guru, Administrator, ..). Quote Link to comment https://forums.phpfreaks.com/topic/202645-php-shopping-cart-update-basket-item/#findComment-1062317 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.