Php add to shopping cart problem - php

Im trying to create a php function that adds an item to a shopping cart. what i want it to do is check the array to see if the item is already in there, if it is increase the quantity, if not create the item in the cart.
What it is doing instead is it adding an item, it'll work the first time (if the items already there it'l just increase the quantity) but if you add another item it keeps on creating new instances of that item in the shopping cart
e.g
item 1 - quantity 4
item 2 - quantity 1
item 2 - quantity 1
item 2 - quantity 1... and so on...
below is the code i have so far?
function add_item ($id, $qty)
{
$count=$this->countItems;
echo "uytfdgghjkl;kj<br>";
$added = false;
if($count>0)
{
$i=0;
while($added == false)
{
echo "fghjkl<br>";
$tid = $this->items[$i]->getId();
echo "new ID: ".$tid."<br>";
echo "old ID: ".$id."<br>";
echo $i;
if($tid == $id)
{
$amount = $this->items[$i]->getQty();
$this->items[$i]->setQty($amount+1);
$added = true;
//$i++;
//break;
}
if($added == true)
{
break;
}
else //if($added == false)
{
$this->items[$this->countItems] = new OrderItem($id, $qty);
//$this->total = $total+ ($qty *$price);
$this->countItems++;
$added = true;
//break;
}
//else break;
$i++;
}
}
else
{
$this->items[$this->countItems] = new OrderItem($id, $qty);
//$this->total = $total+ ($qty *$price);
$this->countItems++;
}
}

The problem is that you aren't searching the whole array first to see if the item is present in it. The code below should work, but I may have made a typo or something else so make sure you double check it.
function add_item ($id, $qty)
{
$count=$this->countItems;
echo "uytfdgghjkl;kj<br>";
$added = false;
if($count>0)
{
for($i=0; $i < $count; $i++)
{
echo "fghjkl<br>";
$tid = $this->items[$i]->getId();
echo "new ID: ".$tid."<br>";
echo "old ID: ".$id."<br>";
echo $i;
if($tid == $id)
{
$amount = $this->items[$i]->getQty();
$this->items[$i]->setQty($amount+1);
$added = true;
break;
}
}
}
if(!$added)
{
$this->items[$this->countItems] = new OrderItem($id, $qty);
//$this->total = $total+ ($qty *$price);
$this->countItems++;
}
}
An even better option would be to use a dictionary
ie.
$arr = array();
$arr['item_id'] = new OrderItem(...);
Then you can check if the item is in the array using:
if(isset($arr[$id])){
...
}

The logic is flawed. The code will increment the item's quantity only if it happens to be the first item in the cart. Otherwise, it will add the item. Evidenced here:
if($added == true) // if this cart item's quantity was incremented
{
break;
}
else // add item
{
$this->items[$this->countItems] = new OrderItem($id, $qty);
// etc...
}
Instead, you should remove the new OrderItem($id, $qty) from the loop and check the value of $added after looping through all the cart items. For this to work, you need to loop via for (instead of a while) using $count.

class Products extends CI_Controller{
function __construct(){
parent::__construct();
// Load cart library
$this->load->library('cart');
// Load product model
$this->load->model('product');
}
function index(){
$data = array();
// Fetch products from the database
$data['products'] = $this->product->getRows();
// Load the product list view
$this->load->view('products/index', $data);
}
function addToCart($proID){
// Fetch specific product by ID
$product = $this->product->getRows($proID);
// Add product to the cart
$data = array(
'id' => $product['id'],
'qty' => 1,
'price' => $product['price'],
'name' => $product['name'],
'image' => $product['image']
);
$this->cart->insert($data);
// Redirect to the cart page
redirect('cart/');
}
}

Related

How to update quantity if same item chosen?

I'm going to use the session['cart'] elsewehere on the site to show the items chosen by user..(e-commerce). So I wish to perform 'addition' on quantity data if item chosen is same.
<?php
session_start();
$return = $_POST;
//$return ='{"qty":"54","id":"8375","action":"test"}';
$return['json']= json_encode($return);
$data = json_decode($return['json'], true);
if(empty($_SESSION['cart'])){
$_SESSION['cart']=array();
}
array_push($_SESSION['cart'], array("quantity"=>$data['qty'],"id"=>$data['id']));
echo json_encode($_SESSION['cart']);
?>
DO I add 'quantity' here or in the place where display the session data like below?
foreach($_SESSION['cart'] as $k=>$v)
{
?>
<tr><th><?php echo $v['id'];?></th><th><?php echo $v['quantity'];?></th></tr>
<?php
}
?>
This is my a little cleaner implementation:
// create new cart if needed
if (empty($_SESSION['cart'])) {
$_SESSION['cart'] = array();
}
// check if item with id exists in cart
if (array_key_exists($data['id'], $_SESSION['cart']) {
// update quantity only
$_SESSION['cart'][$data['id']] = $data['qty']; // or you can increment it
} else {
// add item to cart with defined quantity
$_SESSION['cart'][$data['id']] = array(
'id' => $data['id'],
'quantity' => $data['qty'],
);
}
echo json_encode($_SESSION['cart']);

Auto increment a SESSION key ID

I'm having a problem in doing something.
I have this code snippet to add a product to cart:
$product_id = isset($_GET['product_id']) ? $_GET['product_id'] : "";
$product_name = isset($_GET['product_name']) ? $_GET['product_name'] : "";
$sql = "SELECT * FROM products WHERE product_id LIKE '{$product_id}' AND product_name LIKE '{$product_name}' LIMIT 1";
$stmt = $connection->prepare($sql);
$stmt->execute();
$num = $stmt->rowCount();
if($num == 1)
{
while ($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
extract($row);
if(!isset($_SESSION['cart']))
{
$product_id_session = 1;
}
else
{
$count = count($_SESSION['cart']);
$product_id_session = $count++;
}
$columns = array
(
'product_id_session' => $product_id_session,
'product_id' => $product_id,
'product_name' => $product_name,
'product_price' => $product_price
);
$_SESSION['cart'][$product_id_session] = $columns;
redirect_to('products.php?&message=added&product_name='. $_SESSION['cart'][$product_id_session]['product_name']);
}
}
As you can see, if the session cart is created, I assign the variable $product_id_session with the count of SESSION arrays plus one. Otherwise, the variable $product_id_session is set to 1. In the cart page I have a link to remove the selected product:
foreach($_SESSION['cart'] as $product)
{
echo "<button onClick=\"location.href='remove.php?product_id_session={$product['product_id_session']}'\">
Remove from cart
</button>";
}
Then, in the remove.php file I have this to process the data from Query String and remove the product from the cart:
$product_id_session = isset($_GET['product_id_session']) ? $_GET['product_id_session'] : "";
unset($_SESSION['cart'][$product_id_session]);
The problem I'm facing is: for example, I added two products in the cart. Then I removed the first product and added another product to the cart. The new product, instead of being added, just will replace the product that was previously added in the cart and the $product_id_session will be always the same value. What I'm doing wrong? How to specify an ID for the SESSION?
You can add new items to the cart just with:
$_SESSION['cart'][] = $columns;
Then it will be appended to end of the array.
And, after deleting item from the array, you can (but it is not necessary) re-index it by
$_SESSION['cart'] = array_values($_SESSION['cart']);
When printing out the cart, you just update the foreach loop to catch the key value into some variable, i.e. $index. The difference is in the $index=>$product part.
foreach($_SESSION['cart'] as $index=>$product)
{
echo "<button onClick=\"location.href='remove.php?product_id_session={$index}'\">
Remove from cart
</button>";
}
Remove.php remains basically the same, I just updated it for better readibility:
if (isset($_GET['product_id_session']) and $_GET['product_id_session']) {
$product_id_session = $_GET['product_id_session'];
unset($_SESSION['cart'][$product_id_session]);
}
Instead of trying to create an extra ID to manage your cart you should just rely on the unique product ID already stored in your database :
if($num == 1) {
$row = $stmt->fetch(PDO::FETCH_ASSOC); // no need for the loop as you only have 1 result
extract($row);
if(!isset($_SESSION['cart'])) {
$_SESSION['cart'] = array();
}
// keep track of the added product for the time being
if (!isset($_SESSION['cart'][$product_id])) {
$columns = array(
'product_id_session' => $product_id_session,
'product_id' => $product_id,
'product_name' => $product_name,
'product_price' => $product_price,
'amount' => 0, //just add last comma as good practise here
);
$_SESSION['cart'][$product_id] = $columns;
}
//raise the amount
$_SESSION['cart'][$product_id]['amount']++;
redirect_to('products.php?&message=added&product_name='. $_SESSION['cart'][$product_id_session]['product_name']);
}
And change the remove accordingly :
foreach($_SESSION['cart'] as $product) {
echo "<button onClick=\"location.href='remove.php?product_id={$product['product_id']}'\">Remove from cart</button>";
}
EDIT :
To keep an "unique" id you should not use count to calculate the ID
Just use an extra variable to keep track of last Id :
if(!isset($_SESSION['cart']))
{
$_SESSION['cart'] = array();
$_SERVER['cart_product_id'] = 1;
}
else
{
$_SERVER['cart_product_id']++;
$product_id_session = $_SERVER['cart_product_id'];
}

Add exactly 1 product to cart programmatically in Magento

Using Magento 1.8.1, on the checkout page, I'm trying to add a product to the cart in the code. Here is the code I'm using:
$totals = Mage::getSingleton('checkout/cart')->getQuote()->getTotals();
$subtotal = $totals["subtotal"]->getValue();
$free_samples_prod_id = 1285;
if ( $subtotal >= 50 ) {
$this->addProduct($free_samples_prod_id, 1);
}
else{
$cartHelper = Mage::helper('checkout/cart');
$items = $cartHelper->getCart()->getItems();
foreach ($items as $item) {
if ($item->getProduct()->getId() == $free_samples_prod_id) {
$itemId = $item->getItemId();
$cartHelper->getCart()->removeItem($itemId)->save();
break;
}
}
}
The code is in: app\code\core\Mage\Checkout\Model\Cart.php under public function init()
The product does get added sucessfully, however, everytime somebody visits their cart page, the quantity increases by one. How can I modify that code so the quantity is always 1?
Thank you
Axel makes a very good point, but to answer your immediate question, why not test for the product's presence before you add it
$cartHelper = Mage::helper('checkout/cart');
$items = $cartHelper->getCart()->getItems();
$subtotal = $totals["subtotal"]->getValue();
$free_samples_prod_id = 1285;
if ( $subtotal >= 50 ) {
$alreadyAdded = false;
foreach ($items as $item) {
if($item->getId() == $free_samples_prod_id) { $alreadyAdded = true; break; }
}
if(!$alreadyAdded) { $this->addProduct($free_samples_prod_id, 1); }
}

Adjust Array Value in Shopping Cart based on User login state

How would I adjust individual values within the $_SESSION array depending on whether the user is logged_in or not logged_in. So basically the array values equate to the individual item prices within the shopping cart and will be adjusted if the user logs in or logs out of the SESSION.
Here's my current code:
PHP
if(!empty($_SESSION)){
foreach($_SESSION['basket'] as $b){
if ($session->logged_in) { $b['itemprice'] = ""; }
$sub_total = $b['itemprice'] * $b['itemqty'];
$total = $total + $sub_total;
// display contents of shopping cart
}
}
elseif (empty($_SESSION)) { ?>
// display message informing the user that their cart is empty
MYSQL
$itemids = array();
foreach ($_SESSION['basket'] as $item) {
$itemids[] = "'" . $item['itemid'] . "'";
}
$itemids_str = implode(',', $itemids);
$query = mysql_query("SELECT product_id, price, price_100 FROM product WHERE product_id IN ($itemids_str)");
while ($result=mysql_fetch_array($query)) { }
The closest I've come to getting this to work is each product in the cart is given the same price which changes if the user logs in or out. However, I need each item to change to the new price specific to that items product ID.
Some of our members receive a discount on certain items, so once the user logs in from being a GUEST to the registered USER the price needs to be changed on page refresh.
An example being :
**Logged in == FALSE**
Item 1 Price: 100.00
Item 2 Price: 100.00
**User logs in (Logged in == TRUE)**
Item 1 Price: 85.00
Item 2 Price: 94.00
I hope I've been clear - any advice would be appreciated.
Thanks
OPTION A:
function updateCartPrices()
{
$itemids = array();
foreach ($_SESSION['basket'] as $item) {
$itemids[] = "'" . $item['itemid'] . "'";
}
$itemids_str = implode(',', $itemids);
$query = mysql_query("SELECT product_id, price, price_100 FROM product WHERE product_id IN ($itemids_str)");
while ($result=mysql_fetch_array($query)) {
foreach ($_SESSION['basket'] as $key => $item)
{
if($result['product_id'] == $item['itemid'])
{
$_SESSION['basket'][$key]['itemprice'] = ($_SESSION['logged_in']) ? $result['price'] : $result['price_100'];
}
}
}
}
if(!empty($_SESSION)){
updateCartPrices();
foreach($_SESSION['basket'] as $b){
$sub_total = $b['itemprice'] * $b['itemqty'];
$total = $total + $sub_total;
// display contents of shopping cart
}
}
elseif (empty($_SESSION)) { ?>
// display message informing the user that their cart is empty
OPTION B (performance better):
function getLoggedInPrices()
{
$itemids = array();
foreach ($_SESSION['basket'] as $item) {
$itemids[] = "'" . $item['itemid'] . "'";
}
$itemids_str = implode(',', $itemids);
$query = mysql_query("SELECT product_id, price, price_100 FROM product WHERE product_id IN ($itemids_str)");
$prices = array();
while ($result=mysql_fetch_array($query)) {
$prices[$result['product_id']] = $result['price'];
}
return $prices;
}
if(!empty($_SESSION)){
$loggedInPrices = getLoggedInPrices();
foreach($_SESSION['basket'] as $b){
if($_SESSION['logged_in'])
{
$b['itemprice'] = $loggedInPrices[$b['itemid']];
}
$sub_total = $b['itemprice'] * $b['itemqty'];
$total = $total + $sub_total;
// display contents of shopping cart
}
}
elseif (empty($_SESSION)) {

php shopping cart unable to stop adding same product to cart array

This is just a picture of the result I got. As you can see, item 4 can be added again and again. What I want in my shopping cart is that, for each color, item 4 can only be added once.
if( isset($_SESSION['cart']) ){
################## Do looping to check array cart if already has item with same id and color ##########################
$i = 0;
$j = 1; // set to index [1] //
$found = '';
foreach( $_SESSION['cart'] as $cart ){
######## Check if product chosen already exist in the cart #######
if( $cart[$i]['id'] == $new_product['id'] && $cart[$i]['color'] == $new_product['color'] ){
$found = true; // Found existing item in the array cart //
}
else{
$found = false;
$j++; // No item found in array cart, increase to index [2] //
}
####### If no same item is found in cart, add the new product to the cart array ###############
$i++; // Increase array index to check second array and so on //
}
if(!$found){ // No item found in array cart, add item into cart //
$_SESSION['cart'][$j]['id'] = $new_product['id'];
$_SESSION['cart'][$j]['product_name'] = $new_product['product_name'];
$_SESSION['cart'][$j]['discount'] = $new_product['discount'];
$_SESSION['cart'][$j]['qty'] = $new_product['qty'];
$_SESSION['cart'][$j]['color'] = $new_product['color'];
$_SESSION['cart'][$j]['shipping_fee'] = $new_product['shipping_fee'];
}
}
else{
$_SESSION['cart'][0]['id'] = $product['id'];
$_SESSION['cart'][0]['product_name'] = $product['product_name'];
$_SESSION['cart'][0]['discount'] = $product['discount'];
$_SESSION['cart'][0]['qty'] = $qty;
$_SESSION['cart'][0]['color'] = $color;
$_SESSION['cart'][0]['shipping_fee'] = $shipping_fee;
}
How could I have my codes changed?
try this ...
if($found){ // item found in array cart
$_SESSION['cart'][0]['id'] = $product['id'];
$_SESSION['cart'][0]['product_name'] = $product['product_name'];
$_SESSION['cart'][0]['discount'] = $product['discount'];
$_SESSION['cart'][0]['qty'] = $qty;
$_SESSION['cart'][0]['color'] = $color;
$_SESSION['cart'][0]['shipping_fee'] = $shipping_fee;
}
}
else{ // no item found
$_SESSION['cart'][$j]['id'] = $new_product['id'];
$_SESSION['cart'][$j]['product_name'] = $new_product['product_name'];
$_SESSION['cart'][$j]['discount'] = $new_product['discount'];
$_SESSION['cart'][$j]['qty'] = $new_product['qty'];
$_SESSION['cart'][$j]['color'] = $new_product['color'];
$_SESSION['cart'][$j]['shipping_fee'] = $new_product['shipping_fee'];
}

Categories