PHP - Issue with removing or modifying specific item in multidimensional array - php

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>';
}
}
?>

Related

Prevent duplicate items being added to cart in PHP

I'm using a session array to store products in a cart.
If the selected product is already in the cart, instead of the product being added again, I want to display a message informing the user that the product has already been added.
I've tried looping through the array to find the matching key. I've also tried the in_array($var1,$var2) function. With these, the status tells the user their product is already in the cart but adds the product anyway.
The last thing I tried was the array_search function to check if the key exists but the product is still getting added to the cart regardless.
if(isset($_GET['productID']) && $_GET['productID'] != "") {
$product = $_GET['productID'];
$product = (string)$product;
$result_product = GetSpecificProduct($product);
if(!empty($result_product)) {
$cart_array[$result_product['ProductID']] = array(
'ProductID'=>$result_product['ProductID'],
'ProductName'=>$result_product['ProductName'],
'Price'=>$result_product['Price'],
'Specifications'=>$result_product['Specifications'],
'CO'=>$result_product['CO'],
'CatID'=>$result_product['CatID'],
'Name'=>$result_product['Name'],
'Quantity'=>1
);
}
if(empty($_SESSION['tocoto_cart'])){
$_SESSION['tocoto_cart'] = $cart_array;
$status = $result_product['ProductName']." added to your cart.";
}else if(!empty($_SESSION['tocoto_cart'])) {
$key = array_search($result_product['ProductID'],$_SESSION['tocoto_cart']);
if($key !== false) {
$status = "Selected product is already in your cart.";
} else {
$status = $result_product['ProductName'] . " added to your cart.";
$_SESSION['tocoto_cart'] = array_merge($_SESSION['tocoto_cart'],$cart_array );
}
try to do something like this
$array = $_SESSION['tocoto_cart'];
$key = array_search($result_product['ProductID'], array_column($array, 'ProductID'));
if($key !== false) {
$status = "Selected product is already in your cart.";
} else {
$status = $result_product['ProductName'] . " added to your cart.";
$_SESSION['tocoto_cart'] = array_merge( $_SESSION['tocoto_cart'], $cart_array );
}
Bad approach to store cart items in session, because when server (or php-fpm/apache process) restarts, all carts will be cleared with the sessions.
Store cart items in DB, and to be sure that item is unique within the single cart use combined unique constraint on user_token, cart_id and item_id with ON DUPLICATE KEY UPDATE quantity = quantity + 1 SQL
If this is too complex for you, try to modify this piece of your code
$key = array_search($result_product['ProductID'],$_SESSION['tocoto_cart']);
if($key !== false) {
to
if (array_key_exists($result_product['ProductID'],$_SESSION['tocoto_cart'])) {
$_SESSION['tocoto_cart'][$result_product['ProductID']]['Quantity'] += 1;
}

Laravel Trying to Get property of non object (from eloquent model)

Already read some of questions about this problem on stackoverflow and none of that answers apply to me.
When I run:
$item_price = ItemPrice::where('item_name',$itemname)->first();
and then
$item_price->price
I get Trying to get property of non-object but when I run:
dd($item_price = ItemPrice::where('item_name',$itemname)->first());
It's returning object with attributes name, price etc. I don't really understand what is happening here.
Full code:
foreach ($inventorydecoded->assets as $asset) {
$i = 0;
$a = 0;
while ($a < 1) {
if ($inventorydecoded->descriptions[$i]->classid == $asset->classid) {
$a = 1;
$classid = $inventorydecoded->descriptions[$i]->classid;
$itemname = $inventorydecoded->descriptions[$i]->market_hash_name;
$tradable = $inventorydecoded->descriptions[$i]->tradable;
$name_color = $inventorydecoded->descriptions[$i]->name_color;
;
}
$i++;
} // end of while
if ($tradable === 1 && strpos_arr($itemname, $blacklist) == false ) {
$item_price = ItemPrice::whereItemName($itemname)->first();
// dd(ItemPrice::where('item_name',$itemname)->first());
$items[] = ['assetid' => $asset->assetid,'classid'=> $classid,'itemname'=>$itemname,'name_color'=>$name_color,'price'=> $item_price->price];
$serialized_inventory = serialize($items);
}
} // end of foreach
You're using this query in loop, so one of those is empty and returns null. So you need to do simple check:
if (is_null($item_price)) {
// There is no price for this item, do something.
}
Try this:
$item_price = ItemPrice::whereItemName($itemname)->first();

foreach only checks first value in array, then creates new value

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);
}

Undefined offset Error checking php

Im getting an undefined offset error. I know why i am getting the error and where it is. What i am trying to work out is how to implement the appropriate error checking to prevent this from happening. The method is currently being called via ajax and thus the error cause's issues with the return of any strings etc.
Following is the class's method being called, its variables are being set vie $_GET.
$id = $_GET['id'];
$product = $_GET['name'];
$price = $_GET['price'];
//check for existing product
for($i = 0; $i <= count($_SESSION['BASKET']); $i++) {
//if product exsits incrent by 1
if($_SESSION['BASKET'][$i]['id'] == $id){
$_SESSION['BASKET'][$i]['amount'] = $_SESSION['BASKET'][$i]['amount'] + 1;
break;
//if doesnt exsist creat product array
} else {
$item = array('id' => $id,'amount' => 1,'product' => $product,'price' => $price);
}
}
if(isset($item)){
//push product to session array
array_push($_SESSION['BASKET'], $item);
}
As you can see the method checks to see if the basket currently contains a product and updates by incrementing the quantity ('amount'). I have a constructer that creates the basket array in the class. The issue occurs when the $_SESSION['BASKET'] is called and is empty but still exists as in :
array (
)
this creates and undefined offset error when checking the id in the if statement as the array technically exists but the offset 0 does not. Any ideas how i can handle this?.
Code changes i a have made that cause the same error
if(isset($_SESSION['BASKET'][$i]) && $_SESSION['BASKET'][$i]['id'] == $id){
I have moved the logic outside the loop and added a bool variable, i can then query this to check if a item was found in the array. This allowed me to create another if statement to check if the sessions values were set rather than checking if the array was created.
$id = $_GET['id'];
$product = $_GET['name'];
$price = $_GET['price'];
$exsist = false;
//check for existing product
for($i = 0; $i <= count($_SESSION['BASKET']); $i++) {
if(isset($_SESSION['BASKET'][$i])){
//if product exsits incrent by 1
if(isset($_SESSION['BASKET'][$i]) && $_SESSION['BASKET'][$i]['id'] == $id){
$_SESSION['BASKET'][$i]['amount'] = $_SESSION['BASKET'][$i]['amount'] + 1;
$exsist = true;
break;
}
}
}
if($exsist != true){
$item = array('id' => $id,'amount' => 1,'product' => $product,'price' => $price);
array_push($_SESSION['BASKET'], $item);
}

problem with comparing two arrays

I'm trying to compare the content of 2 arrays, basically I'm using a shopping cart and I need to check the prices of submitted forms against a database, the problem is when I have one incorrect price in the shopping cart it gives me an error message but when I have 1 correct price and 1 incorrect it continues with the checkout, I don't know what I'm doing wrong any help would be appreciated.
foreach ($cart->get_contents() as $item)
{
$item_id = $item['id'];
$item_name = $item['name'];
$item_price = $item['price'];
$item_qty = $item['qty'];
$connection = mysql_connect($dbhost,$dbuser,$dbpass) or die("Error connecting to mysql");
mysql_select_db($dbname);
$query = "select * from products where product_name = '$item_name'";
$result = mysql_query($query);
if (!$result) {
echo mysql_error();
}
while ($row = mysql_fetch_assoc($result)) {
$sql_price[] = $row['product_price'];
$qty[] = $row['product_qty'];
$name = $row['product_name'];
}
foreach($sql_price as $price) {
$price = $price;
if ($price !== $item_price) {
$valid_prices = false;
}else{
$valid_prices = true;
}
}
}
if ($valid_prices !== true)
{
// KILL THE SCRIPT
die($jcart['text']['checkout_error']);
}
The problem is you marking the cart entry as valid if the last array element of $sql_price equals $item_price.
Rewrite the loop as:
$valid_prices = true;
foreach($sql_price as $price) {
$price = $price;
if ($price !== $item_price) {
$valid_prices = false;
}
}
To prevent extra iterating, add a break in the inner if to stop the loop after finding an invalid price.
Or even this:
$valid_prices = (array_search($price, $sql_price) !== false);
You can have MySQL do all your work for you, even:
$query = 'select 1 from products where product_name = "' . mysql_real_escape_string($item_name) . '" and product_price = ' . (int)$item_price;
$result = mysql_query($query);
if (!$result) {
echo mysql_error();
}
if (mysql_num_rows($result) > 0) {
$valid_prices = true;
echo 'price is good!';
} else {
$valid_prices = bad;
echo 'price is bad!';
}
You are setting $valid_prices to true or false on every loop iteration. So after the loop it only corresponds to the last item in the loop.
It might be better to set it to true outside (before) the loop, and then set it false when you find a bad case - that way it can't be set back to true. Alternatively you could just throw the error inside the loop as soon as you find the invalid price.
The main issue seems to be your inner foreach loop and the setting of valid_prices. Your loop continues through all prices so $valid_prices will depend on the last price only. You should break out of your loop as soon as you detect an invalid price.
A few other small things:
you don't seem to use the $qty or $name variables
$name does not use [] like $sql_price, $qty
You could use != not !==

Categories