How to update an item quantity if the product already exists in shopping cart?
Here's my add to cart function:
public function add() {
$product= $this->products_model->listProduct($this->input->post('id_product'));
$data = array(
'id' => $this->input->post('id_product'),
'qty' => $this->input->post('qty'),
'price' => $product->price,
'name' => $product->title );
$this->cart->insert($data);
redirect('product/'.$product->id.'/'.url_title($product->title, 'dash', TRUE));
}
With this function, if the product exists in the cart, let's say with quantity of 8, if i add the same product with quantity of 1 it'll be 1 and not 9.
Thanks in advance.
#AFRC
you can try
public function add() {
$flag = TRUE;
$dataTmp = $this->cart->contents();
foreach ($dataTmp as $item) {
if ($item['id'] == 'sku_123ABC') {
echo "Found Id so updatig quantity";
$qtyn = $item['qty'] + 1;
$this->update($item['rowid'], $qtyn);
$flag = FALSE;
break;
}
}
if ($flag) {
$data = array(
'id' => 'sku_123ABC',
'qty' => 1,
'price' => 39.95,
'name' => 'T-Shirt',
);
$this->cart->insert($data);
echo "Inserting as not found in the cart";
}
echo "Add1 called";
}
I don't see where $produto is defined, shouldn't it be, instead, $product->price and $product->title, respectively?
According to the docs :
Important: The first four array
indexes above (id, qty, price, and
name) are required. If you omit any of
them the data will not be saved to the
cart.
Be sure to check if they're acqually set (maybe look for spelling errors, like, I shoot in the dark, 'qtd' instead of 'qty', or something like that).
Moreover, if you want to UPDATE a product already present, you need to use $this->cart->update() instead of $this->cart->insert()
Just check with this if you have options
$rowid == md5($items['id'].implode('', $items['options']));
if not
$rowid == md5($items['id']);
use this code for add to cart
if (count($this->cart->contents())>0){
foreach ($this->cart->contents() as $item){
if ($item['id']==$product->id){
$data = array('rowid'=>$item['rowid'],'qty'=>++$item['qty']);
$this->cart->update($data);
}else{
$data = array('id'=>$product->id,'qty'=>1,'price'=>$product->price,'name'=>$product->id,'options'=>array('image'=>$product->thumb,'product_name'=>$product->title));
$this->cart->insert($data);
}
}
I used AFRC's answer to create the code below, it may be helpful. Thanks for your reply it really helped me! You can call the cart function below if there is an id present matching in your cart update will occur, otherwise insert will. It'll also display the cart view reguardless of insert, update, or just display. Please note i have a separate function get_specific_craft that is being used to get the slug items data (such as price and name).
public function cart($slug = "")
{
if($slug != "")
{
$craft = $this->crafts_model->get_specific_craft($slug);
$flag = TRUE;
foreach ($this->cart->contents() as $item)
{
if ($item['id'] == $slug)
{
$qtyn = $item['qty'] + 1;
$dat = array(
'rowid' => $item['rowid'],
'qty' => $qtyn
);
$this->cart->update($dat);
$flag = FALSE;
break;
}
}
if ($flag)
{
$crt = array(
'id' => $craft['id'],
'qty' => 1,
'price' => $craft['price'],
'name' => $craft['name']
//'options' => array('Size' => 'L', 'Color' => 'Red')
);
$this->cart->insert($crt);
}
}
$this->load->view('cart' , $this->data);
}
Related
I need to add items to my cart, so if I add one product of productid = 1, and then I add that same product of productid = 1, I need it to only increase the quantity of the item, and not add another session of that product.
I've tried the following:
foreach ($_SESSION['cart'] as $item) {
if ($item['product_id'] == $part_id) {
$quantity++;
}
}
But I need to know how to remove the previous added session for that product.
This is the code that I am using to add products to my cart currently, but the following just adds another product with the quantity 2, so I have:
// -- Cart -- //
Product : 1 Quantity : 1
Product : 1 Quantity : 2
// -- Cart -- //
Code:
foreach ($_SESSION['cart'] as $item) {
if ($item['product_id'] == $part_id) {
$quantity++;
}
}
$_SESSION['cart'][] = array(
'product_id' => $part_id,
'title' => $title,
'price' => $price,
'default_img' => $default_img,
'quantity' => $quantity);
EDIT: My initial question on how to unset the previous session, but if I add the same product another time, the quantity stays at 2, meaning it unsets the previous session with quantity = 3, and just increments the quantity +1 meaning the quantity remains at 2.
This worked for me :
$exists = false;
foreach ($_SESSION['cart'] as $key => $item) {
if ($item['product_id'] == $part_id) {
$exists = true;
}
}
if ($exists == true) {
$_SESSION["cart"][$key]['quantity']++;
}
else{
$_SESSION['cart'][] = array(
'product_id' => $part_id,
'title' => $title,
'price' => $price,
'default_img' => $default_img,
'quantity' => $quantity);
}
You are dealing with an associative array. You have the key to the object you want to remove. I would unset it right after adding the quantity. Now you can push your next object with the updated quantity.
foreach ($_SESSION['cart'] as $item) {
if ($item['product_id'] == $part_id) {
$quantity++;
$_SESSION['cart'][$part_id] == NULL //Add this
}
}
The assignment is to have a table display some products with an add to cart link which sends the user to another page which uses the information in the link to get the data to display the total of the purchase. The table is adding in new items that are clicked but not updating the actual quantity when an item is clicked more than once.
I have tried placing an echo in the check for the item already being in the cart and it does state the quantity of 1 before the quantity update and 2 after the update but for some reason this is not actually updating. The same goes for the price.
<?php
session_start();
if(empty($_SESSION['cart'])) {
$_SESSION['cart'] = array();
}
$cart = $_SESSION['cart'];
$id = $_GET['productid'];
$name = $_GET['productname'];
$price = $_GET['productprice'];
$qty = 1;
$alreadyHas = 0;
foreach($cart as $cartKey => $cartItem) {
if(!empty($cartItem['pid'])) {
if($cartItem['pid'] == $id) {
$cartItem['qty'] = $cartItem['qty'] + 1;
$cartItem['total'] = $cartItem['price'] * $cartItem['qty'];
$alreadyHas = 1;
}
}
}
if($alreadyHas == 0) {
$cartItem = array(
'pid' => $id,
'name' => $name,
'price' => $price,
'qty' => $qty,
'total' => $price
);
array_push($cart, $cartItem);
}
$_SESSION['cart'] = $cart;
?>
Your problem is in your foreach loop. You are updating $cartitem however because you are not passing it by reference in the loop the $cart variable itself is not being updated. Try changing the foreach loop to this (note the addition of & before `$cartItem):
foreach($cart as $cartKey => &$cartItem) {
Note that you could simplify your code with the use of array_search and array_column:
if (($k = array_search($id, array_column($cart, 'pid'))) !== false) {
$cart[$k]['qty'] = $cart[$k]['qty'] + 1;
$cart[$k]['total'] = $cart[$k]['price'] * $cart[$k]['qty'];
}
else {
$cartItem = array(
'pid' => $id,
'name' => $name,
'price' => $price,
'qty' => $qty,
'total' => $price
);
array_push($cart, $cartItem);
}
I have written code to add and update users and also I want to add and update categories they can work in. The added users will go in users table and the categories they can access goes in the category_permitted table. I have the following code for adding and updating tables:
if ($user_info) {
if ($act == "add") {
if ($user_info) {
$array = array(
'user_id' => $user_info,
'category_id' => $temp['cat_access']
);
$category_permitted->addCategoryAccess($array);
}
} else {
if ($user_info) {
$array = array(
'user_id' => $id,
'category_id' => $temp['cat_access']
);
$deleteold = $category_permitted->deleteCategoryAccess($id);
$category_permitted->addCategoryAccess($array);
}
}
}
This my function to add and update category access:
public function addCategoryAccess($data, $is_die = false){
return $this->insert($data, $is_die);
}
public function updateCategoryAccess($data, $id, $is_die = false){
$args = array(
'where' => array('user_id' => $id),
);
return $this->update($data, $args, $is_die);
}
And this is the data in database table .
My update function is updating all data of the column category_id with the number being added while updating category access for the user.
I want to leave 2 and 3 as it is and add another category id which is 1 but after running the update code it updates the data like this. Do I have to add another condition to WHERE CLAUSE to get the expected output?
To update only one row you need an unique identifier for that row.
If the column id is the primary key, you can use that column to update only the corresponding row.
$args = array(
'where' => array('id' => $category_permitted_id),
);
As an alternative, if you know which category is changing, and the relation (user_id,category_id) is unique, you can add the changing category to the where.
$args = array(
'where' => array(
'user_id' => $user_id,
'category_id' => $category_id
),
);
Please note that i don't know your Database abstraction layer and i'm implying that you can simply add another entry in the array to put conditions in 'AND', this could be wrong in your case.
Managing relationships this way takes a bit of effort, and in my opinion is not worth it.
If you are able to modify the application logic, i suggest you to switch to using only insert/delete, like so:
Add a permitted category: Just add it creating a new record with insert
Remove a permitted category: Remove it trough a delete function
Change a permitted category to another: Delete the one that is changing and add the new one
Doing this in my code worked for me. I called the function $deleteold = $category_permitted->deleteCategoryAccess($id); just before the for loop to avoid deleting the previous data being deleted in every iteration.
if ($user_info) {
$cat_access = (isset($_POST['cat_access']) && !empty($_POST['cat_access'])) ? ($_POST['cat_access']) : $_SESSION['cat_access'];
$value = array();
if (!empty( $cat_access ) && is_array( $cat_access ) ) {
foreach( $cat_access as $key => $item ) {
$value[] = filter_var( $item, FILTER_SANITIZE_NUMBER_INT );
}
}
$categoryData = $value;
$temp = array();
if ($categoryData) {
$count = count($categoryData);
if ($count > 0) {
$deleteold = $category_permitted->deleteCategoryAccess($id);
for($i=0; $i<$count; $i++){
$temp =array(
'cat_access' => $categoryData[$i]
);
if ($act == "add") {
if ($user_info) {
$array = array(
'user_id' => $user_info,
'category_id' => $temp['cat_access']
);
$category_permitted->addCategoryAccess($array);
}
} else {
if ($user_info) {
$array = array(
'user_id' => $id,
'category_id' => $temp['cat_access']
);
$category_permitted->addCategoryAccess($array);
}
}
}
}
}
}
how to update plan with vendor_plan_task_status_mapp table.
the model for plan update is
public function updatePlanData(){
$planId = $this->input->post('plan_id');
$data = array(
'plan_title' => $this->input->post('plan_title'),
'plan_price' => $this->input->post('plan_price'),
'plan_desc' => $this->input->post('plan_desc')
);
$this->db->where('plan_id', $planId);
$this->db->update('tbl_plan', $data);
$this->db->where('plan_id',$planId);
$this->db->delete('plan_task_mapping');
foreach ($this->input->post('task_id') as $key => $value)
{
$data2 = array(
'plan_id' => $planId,
'task_id' => $value
);
// echo "Index {$key}'s value is {$value}.";
$this->db->insert('plan_task_mapping', $data2);
}
//-------- HEAR I NEED A CODE TO UPDATE The V_T_S_M table-----------
}
after 1st table update i want to update the data in vendr_task_status_mapping table?????
IN THIS ANSWER YOU GET AN ERROR IF YOU CHANGE THE PLAN BUT USING THIS CODE YOU HAVE TO SIMPLY EDIT AND UPDATE IT ANGIN AND THIS MODEL IS CREATE A NEW ID FOR YOUR TASK AND INSERT IT AGAIN.
public function vendorUpdateModel($data)
{
$vendor_id = $this->input->post('vendor_id');
$data = array(
'category_id' => $this->input->post('category_id'),
'plan_id' => $this->input->post('plan_id'),
'city_id' => $this->input->post('city_id'),
'business_name' => $this->input->post('business_name'),
'owner_name' => $this->input->post('owner_name'),
'contact_no1' => $this->input->post('contact_no1'),
'contact_no2' => $this->input->post('contact_no2'),
'vendor_email' => $this->input->post('vendor_email'),
'subscription_date' => $this->input->post('subscription_date'),
'vendor_description' => $this->input->post('vendor_description'),
'vendor_address' => $this->input->post('vendor_address')
);
$this->db->where('vendor_id', $vendor_id);
$this->db->update('vendor',$data);
$this->db->where('vendor_id',$vendor_id);
$this->db->delete('vendor_task_status_mapping');
$this->db->select('task_mapp_id');
$this->db->where('plan_id',$this->input->post('plan_id'));
$query = $this->db->get('plan_task_mapping');
foreach($query->result() as $row)
{
$data2 = array(
'task_mapp_id' => $row->task_mapp_id,
'vendor_id' => $vendor_id,
'task_status' => '0'
);
$this->db->insert('vendor_task_status_mapping', $data2);
}
return;
}
If you added one field in plan_task_mapping table for add unique number then... As you mention your code:
$unique=array();
foreach ($this->input->post('task_id') as $key => $value)
{
$no=rand(0, 15);
$data2 = array(
'unique_no'=>$no,
'plan_id' => $planId,
'task_id' => $value
);
$unique[] = $no; //store no in array to use it.
// echo "Index {$key}'s value is {$value}.";
$this->db->insert('plan_task_mapping', $data2);
}
Before deleting plan_task_mapping table data. fetch that data.
function select()
{
$this->db->where('plan_id',$planId);
$Q = $this->db->get('plan_task_mapping');
if($Q->num_rows() > 0)
{
foreach ($Q->result_array() as $row)
{
$data[] = $row;
}
}
$Q->free_result();
return $data;
}
Then delete the data as you mention in you code:
$this->db->where('plan_id',$planId);
$this->db->delete('plan_task_mapping');
Then delete that old data from VTSM table:
$this->db->where('vendor_plan_task_mapping_id',$data[0]['id']); //this data[0]['id'] come form select(). change field name if required.
$this->db->delete('VTSM');
Here fetch that new inserted data by that unique no: //which we stored it in array.
foreach($unique as $u_no)
{
$this->db->where('unique_no',$u_no);
$Q = $this->db->get('plan_task_mapping');
if($Q->num_rows() > 0)
{
foreach ($Q->result_array() as $row1)
{
$plan[] = $row1;
}
}
$Q->free_result();
return $plan;
}
In above code we have fetched that new inserted data to get their id to insert status.
Now inserting status:
foreach($plan as $a)
{
$Sdata=array(
"plan_task_mapping_id"=>$a['id'], //this is new id change name if required
"status"="your new status");
$this->db->insert('VTSM',$Sdata);
}
Use $this->db->insert_batch(); instead of inserting in foreach loop.
Check at this link how to use it.
I've got the following code to remove 1 from the qty when a remove button is pressed and if the qty=1 the item will be removed from the array at the specific index.
for example if the first item in the array has an ID of '1B' and qty of '5' and name 'item1' second item in the array has the ID of '2B' and qty of '3' and name 'item2' and the remove button for this item is pressed, the qty will change to 2(as required) but the id will change to 1B and the name to 'item1'. The same thing happens if there are more than 2 products in the $_SESSION["Cart"] array.
I'm not sure where i'm going wrong, but this is my code:
code for $_SESSION["Cart"]
$_SESSION["Cart"] = array(
array(
'name' => "namehere",
'id' => "idHere",
'qty' => 1,
'price' => "pricehere"
)
//more arrays here
);
Code for Removing item
$prodID = $_GET["removeProd"];
foreach ($_SESSION["Cart"] as $cartItem) {
//only continue if qty is more than one
//remove item if 0 qty
if ($cartItem["id"] == $prodID) {
if ($cartItem["qty"] > 1) {
$qty = $cartItem["qty"] - 1; //decrease qty by one
$cart[] = array(
'name' => $cartItem["name"],
'id' => $cartItem["id"],
'qty' => $qty,
'price' => $cartItem["price"]
);
} //end if
} else {
$cart[] = array(
'name' => $cartItem["name"],
'id' => $cartItem["id"],
'qty' => $cartItem["qty"],
'price' => $cartItem["price"]
);
} //end else
$_SESSION["Cart"] = $cart;
} //end foreach
The problem is that you're assigning $_SESSION['Cart'] = $cart on each iteration, so it will only ever contain the last item in the $_SESSION['Cart'] array. If you move it below the end of the foreach your code should work.
You could simplify this a bit by passing $cartItem by reference. That way you only modify array elements which match $prodID:
foreach ($_SESSION['Cart'] as $key => &$cartItem) {
if ($cartItem['id'] == $prodID) {
if ($cartItem['qty'] > 1) {
$cartItem['qty'] -= 1;
} else {
unset($_SESSION['Cart'][$key]);
}
}
}
unset($cartItem); // break the binding
Your code has some algorhithmic/logic flaws. This code should do what you need it to do. Please try to find out what it actually does, and where are the flaws in your approach.
foreach ($_SESSION["Cart"] as $key=>$cartItem) {
//only continue if qty is more than one
//remove item if 0 qty
if ($cartItem["id"] == $prodID) {
if ($cartItem["qty"] > 1) {
$qty = $cartItem["qty"]--;// does the same thing as x = x - 1; //decrease qty by one
$cart[$key]['qty'] = $qty;
} //end if
else {
unset($cart[$key]);
}
break;// ends foreach loop ( assuming there can be only one item of the same type in the cart )
}
} //end foreach
$_SESSION["Cart"] = $cart;