I am making an e-commerce web app and I am trying to write code to handle if the user clicks the add to basket button on an item that is already in the basket but it doesn't seem to work correctly. If the button is clicked for a second time then the first item quantity is overridden by the second
if ($action === 'add_product') {
$id = isset($_REQUEST['id']) ? (int) $_REQUEST['id'] : null;
$price = isset($_REQUEST['price']) ? (float) $_REQUEST['price'] : null;
$quantity = isset($_REQUEST['quantity']) ? (int) $_REQUEST['quantity'] : null;
$name = isset($_REQUEST['name']) ? trim($_REQUEST['name']) : null;
if ($id && $price && $quantity) {
$_SESSION['cart'][$id] = [
'id' => $id,
'price' => $price,
'quantity' => $quantity,
'name' => $name
];
} // if the action is increment, increse the quantity of the item.
} elseif ($action === 'increment' and array_key_exists('id', $_SESSION['cart'][$_REQUEST['id']])) {
$_SESSION['cart'][$_REQUEST['id']]['quantity'] += 1;
//if the action is decrement, decrease the quantity of item by 1
} elseif(array_key_exists('id',$_SESSION['cart'][$_REQUEST['id']))//here is where it is supposed to handle adding the same item twice {
$_SESSION['cart'][$_REQUEST['id']]['quantity'] += 1;
} elseif ($action === 'decrement' and array_key_exists('id', $_SESSION['cart'][$_REQUEST['id']])) {
$_SESSION['cart'][$_REQUEST['id']]['quantity'] -= 1;
if ($_SESSION['cart'][$_REQUEST['id']]['quantity'] <= 0) {
unset($_SESSION['cart'][$_REQUEST['id']]);
}
} elseif ($action === 'remove' and array_key_exists('id', $_SESSION['cart'][$_REQUEST['id']])) {
unset($_SESSION['cart'][$_REQUEST['id']]);
}
I have commented where it is supposed to be adding to the quantity, but it does not add to the quantity and update it simply overrides the old quality and I don't know why. I have also tried if(in_array($id,$_SESSION['cart'][$_REQUEST['id'])) but that also did not work. I don't quite understand why it won't be working so any help is greatly appreciated.
Related
I have a multidimensional array. The parent array includes items that each item inside is an array with its properties.
insertProduct.php checks everytime I add a new product to the array if the product already exists. If it doesn't it pushes it to the array, if it already exists it finds it and adds +1 to its quantity.
I am trying to create a functionality where pressing a button "Undo" removes the latest addition whether it was a whole product (which means its QTY would be 1 so it removes it altoghether) or if the latest addition was just a QTY increase (from 1 to 2) then remove 1 from the QTY.
However my issue is when I add a product that already exists but is not in the last spot of the array, the QTY does increase as it should be but then the UNDO does not do -1 to this item's QTY.
I don't know if it's alright to post a video but here's the pattern of the problem in a short gif
insertProduct.php
if (isset($_SESSION['myArray'])) {
$inserted_products = $_SESSION['myArray'];
$position = array_search($inserted_product_ean, array_column($inserted_products,0));
//check if new product already exists
if ($position !== false) {
$inserted_products[$position][2] = $inserted_products[$position][2] + 1;
$latest_product = $inserted_products[$position];
$_SESSION['latestProduct'] = $latest_product;
$_SESSION['myArray'] = $inserted_products;
} else {
array_push($inserted_products, $product); //$product is an array of info about the item inserted
$latest_product = $product;
$_SESSION['latestProduct'] = $latest_product;
$_SESSION['myArray'] = $inserted_products;
}
} else {
$latest_product = $product;
$_SESSION['latestProduct'] = $latest_product;
array_push($inserted_products, $product);
$_SESSION['myArray'] = $inserted_products;
}
deleteLastEntry.php
<?php
if (isset($_SESSION['myArray'])) {
$inserted_products = $_SESSION['myArray'];
$inserted_products_length = count($inserted_products);
if ($inserted_products_length > 0){
$latest_product = $_SESSION['latestProduct'];
$qty = $latest_product[2];
if ($qty !== false && $qty > 1) {
$qty = $qty - 1;
$latest_product[2] = $qty;
array_pop($inserted_products);
array_push($inserted_products, $latest_product);
$_SESSION['myArray'] = $inserted_products;
}else{
array_pop($inserted_products);
$_SESSION['myArray'] = $inserted_products;
}
}else{
echo '<div class="error-msg">No products to remove</div>';
}
}
?>
I'm working on a php shopping cart and I'm trying to have the cart update the quantity of the item, rather than creating new entries for the same item. However when entering a product that is already in the cart, my foreach statement only checks it against the first array value and then creates a new entry for that product.
Can someone please help me work through this and figure out why it's not checking against the whole array list?
Here's my update method:
function CheckForExistingEntry($id, $setOf, $quantity) {
// if the product ID and the SET OF is equal in multiple products, update the quanity instead of making new records
foreach ($_SESSION['shopping_cart'] as $key => $product) {
if ($id == $product['product_id'] && $setOf == $product['setOf']) {
// Update Cart Value
$_SESSION['shopping_cart'][$key]['quantity'] += $quantity;
$_SESSION['shopping_cart'][$key]['price'] *= $_SESSION['shopping_cart'][$key]['quantity'];
break;
} else {
// Add New Cart Value
AddToCart($id, $setOf, $quantity);
break;
}
}
}
You have a break; in both if and else, which means that it will always break after the first iteration.
Let's remove the else-block, since we just want to continue to the next item if it wasn't found.
Try this: (I've commented the changes):
// Define a variable that holds the state.
$updated = false;
foreach ($_SESSION['shopping_cart'] as $key => $product) {
if ($id == $product['product_id'] && $setOf == $product['setOf']) {
// Update Cart Value
$_SESSION['shopping_cart'][$key]['quantity'] += $quantity;
$_SESSION['shopping_cart'][$key]['price'] *= $_SESSION['shopping_cart'][$key]['quantity'];
// Set updated as true and break the loop
$updated = true;
break;
}
}
if (!$updated) {
// We didn't update any items, add a new item instead
AddToCart($id, $setOf, $quantity);
}
I want to avoid modifing every data from a SalesOrder when the status equals "Cancelled", I get it to work with the part that involves SalesOrder info data, but I can`t get it to work with product part... any ideas?
$pedido = SalesOrder_Record_Model::getInstanceById($entityId);
$vtEntityDelta = new VTEntityDelta ();
$anterior = $vtEntityDelta->getOldValue($entity->getModuleName(), $entityId, "sostatus");
$actual = $pedido->get("sostatus");
$VTIGER_BULK_SAVE_MODE = true;
if($anterior == "Approved" || $anterior == "Cancelled" || (($actual == "Approved" || $actual == "Cancelled") && (!$vtEntityDelta->hasChanged($entity->getModuleName(), $entityId, 'sostatus')))){
foreach ($pedido->getModule()->getFields() as $field)
if($vtEntityDelta->hasChanged($entity->getModuleName(), $entityId, $field->getName()))
$pedido->set($field->getName(), $vtEntityDelta->getOldValue($entity->getModuleName(), $entityId, $field->getName()));
$pedido->set("mode","edit");
$pedido->save();
}
That works for info data as I was saying, some has any idea about this??
Thanks!
I am interested in implementing an "order again" function for OpenCart, with a button located in the order history list under account/order. This button would take all this particular order's products (and its associated options) and add them all back to the cart.
The following code I have allows me to loop through my product as well as its respective product options depending on the order ID.
$products = $this->model_account_order->getOrderProducts(
$this->request->get['order_id']
);
foreach ($products as $product) {
$options = $this->model_account_order->getOrderOptions(
$this->request->get['order_id'],
$product['order_product_id']
);
foreach ($product['option'] as $option) {
// Implement custom logic
}
}
I have no issues at the moment to get the products that I have already ordered. What I do not understand what to do and need help on is - how do I use this [if this is the way to add items to cart] to add the items back to the cart?
By knowing the product ID and quantities (and options if any) you can just call:
$this->cart->add($product_id, $quantity, $options); // use array() instead of $options if there are none
for each product respectively. $options is an array, to see what structure it has to have look into the AJAX request when adding a product with options to the cart (I think it's single array with product_option_id as key and option_value as value).
Try this
$this->cart->add($product_id, $quantity, $options);
This is actually already implemented on the customer side of the cart. Here's the code contained in the /catalog/controller/account/order.php that does exactly what you want (1.5.5.1 in this particular case)
if (isset($this->request->get['order_id'])) {
$order_info = $this->model_account_order->getOrder($this->request->get['order_id']);
if ($order_info) {
$order_products = $this->model_account_order->getOrderProducts($this->request->get['order_id']);
foreach ($order_products as $order_product) {
$option_data = array();
$order_options = $this->model_account_order->getOrderOptions($this->request->get['order_id'], $order_product['order_product_id']);
foreach ($order_options as $order_option) {
if ($order_option['type'] == 'select' || $order_option['type'] == 'radio') {
$option_data[$order_option['product_option_id']] = $order_option['product_option_value_id'];
} elseif ($order_option['type'] == 'checkbox') {
$option_data[$order_option['product_option_id']][] = $order_option['product_option_value_id'];
} elseif ($order_option['type'] == 'text' || $order_option['type'] == 'textarea' || $order_option['type'] == 'date' || $order_option['type'] == 'datetime' || $order_option['type'] == 'time') {
$option_data[$order_option['product_option_id']] = $order_option['value'];
} elseif ($order_option['type'] == 'file') {
$option_data[$order_option['product_option_id']] = $this->encryption->encrypt($order_option['value']);
}
}
$this->session->data['success'] = sprintf($this->language->get('text_success'), $this->request->get['order_id']);
$this->cart->add($order_product['product_id'], $order_product['quantity'], $option_data);
}
$this->redirect($this->url->link('checkout/cart'));
}
}
Upon investigation and posting on the OpenCart website, it turns out reorder is already a functionality in OpenCart, but we never enabled it [or someone disabled it months ago]. We had to renable it by adding a button and attributed the reorder link under /catalog/controller/account/order.php.
We also added some custom logic in our:
if ($order_option['type'] == 'select' || $order_option['type'] == 'radio') {
$option_data[$order_option['product_option_id']] = $order_option['product_option_value_id'];
} elseif ($order_option['type'] == 'checkbox') {
$option_data[$order_option['product_option_id']][] = $order_option['product_option_value_id'];
} elseif ($order_option['type'] == 'text' || $order_option['type'] == 'textarea' || $order_option['type'] == 'date' || $order_option['type'] == 'datetime' || $order_option['type'] == 'time') {
$option_data[$order_option['product_option_id']] = $order_option['value'];
} elseif ($order_option['type'] == 'file') {
$option_data[$order_option['product_option_id']] = $this->encryption->encrypt($order_option['value']);
}
Since we have a custom option type called checkbox+quantity. For the future users, please make sure to add your custom option type logic to this logical statement.
Thanks Jay for pointing this out as well.
I know that my question could be very similar to anothers in Stackoverflow. I have found some similar questions but actually I couldn't get the right solution for my problem;
I am writing shopping cart using Sessions and ajax-json.
My products
structure is a bit complicated. It has name, size, type, colour and a
specific price for each type and size. The main point is that I can't
increment the item quantity if the name, size, type, color and price are
the same, if I'm adding the same product. Here is my code. I think I
am writing right, but I can't understand what is the problem.
Actually it increments the item quantity, but just one time, and when
I am checking the array, it's item quantity has not been incremented.
$data = json_decode($_POST['jsonData'], true);
$pr_type = $data['pr_type'];
$pr_size = $data['pr_size'];
$pr_link = $data['pr_link'];
$pr_color = $data['pr_color'];
$pr_price = $data['pr_price'];
$products_s = $this->getSession()->get('prof_cart');
$product = array();
if (empty($products_s)) {
$products_s = array();
} else {
$products_s = $products_s;
}
$products = Model::factory('Client_Product')->getProductById($pr_link);
$type = Model::factory("Client_Product")->getProductTypeByLink($pr_type);
$size = Model::factory("Client_Product")->getProductSizeById($pr_size);
if ($pr_type != 'undefined') {
$product['type'] = $type[0]['title'];
} else {
$product['type'] = "";
}
$isCreate = true;
foreach ($products_s as $id) {
if ($id['price'] == $pr_price &&
$id['title'] == $products[0]['title'] &&
$id['size'] == $size[0]['size'] &&
$id['type'] == $type[0]['title']) {
$id['quant']++;
$isCreate = false;
}
}
if ($isCreate) {
$product['quant'] = 1;
$product['size'] = $size[0]['size'];
$product['title'] = $products[0]['title'];
$product['price'] = $pr_price;
$product['color'] = $pr_color;
array_push($products_s, $product);
}
$sum = 0;
foreach ($products_s as $id) {
$sum += $id['price'] * $id['quant'];
}
//echo $sum;
echo "<pre>";
var_dump($products_s);
echo "</pre>";
$this->getSession()->set('prof_cart', $products_s);
$this->getSession()->set('prof_sum', $sum);
You need to increase quantity in your main product array like below.
foreach ($products_s as $key => $id) {
if ($id['price'] == $pr_price &&
$id['title'] == $products[0]['title'] &&
$id['size'] == $size[0]['size'] &&
$id['type'] == $type[0]['title']) {
$products_s[$key]['quant']++;
$isCreate = false;
}
}
try this :
foreach ($products_s as $id) {
if ($id['price'] == $pr_price &&
$id['title'] == $products[0]['title'] &&
$id['size'] == $size[0]['size'] &&
$id['type'] == $type[0]['title']) {
$id['quant'] = $id['quant']++;
$isCreate = false;
}
}