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 !==
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 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;
}
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;
}
}
So I have a query that I am returning all of the items into a mysql_fetch_array. Now, I know I could write another query and just select the items I need into a seperate query but, is there a way to just filter from the larger query what I want dependent on $_GET?
So, in english the user comes from a hyperlink that has ?id=1 and I peform a while that gets the all the values but, only display the $_GET['id'] items in a list
<?php //give ma all values but only echo out list of the $_GET['id'] in the url
while ($row = mysql_fetch_array($result) {
$id = $rowvideo["id"];
$title = $rowvideo["title"];
$length = $rowvideo["length"];
}
echo("<li><a href='#'>". $title." " .$length. "</a></li>");
?>
Hope this makes sense. Thank you all.
If you do not want a second query to get just what you need, a simple-if-statement in your loop should work:
<?php
$getId = isset($_GET['id']) ? $_GET['id'] : false;
//give ma all values but only echo out list of the $_GET['id'] in the url
while ($row = mysql_fetch_array($result)) {
$id = $row["id"];
$title = $row["title"];
$length = $row["length"];
if ($id == $getId) {
echo("<li><a href='#'>". $title." " .$length. "</a></li>");
}
}
?>
Note that I declared $getId outside of the loop to prevent having to use isset() during every iteration. If you don't verify if it's set and attempt to use it it will throw an undefined index warning - assuming you have error_reporting turned on (with that level enabled).
Alternatively, you could use PHP's array_filter() on the data after you've parsed it all:
$results = array();
while ($row = mysql_fetch_array($result)) $results[] = $row;
if (isset($_GET['id'])) {
$filtered = array_filter($results, function($element) use ($_GET['id']) { return ($element['id'] == $_GET['id']); });
$results = $filtered;
}
foreach ($results as $result) {
echo("<li><a href='#'>". $result['title']." " .$result['length']. "</a></li>");
}
My personal opinion would be to be more efficient and write the second query though, assuming of course you don't actually need all of the results when an id is specified. It would be as simple as:
if (isset($_GET['id']) && is_numeric($_GET['id'])) {
$query = 'SELECT id, title, length FROM table WHERE id=' . (int)$_GET['id'];
} else {
$query = 'SELECT id, title, length FROM table';
}
// your existing code as-is
A little more clarity here:
This will allow the filter by id in the url by specifying id=xxx, IF xxx is an integer that is positive. So id of 'bob' or -1 will not filter the results still giving all results
$filter=false;
if(isset($_GET['id']))
{
$filter_id=intval($_GET['id']);
if($id>0) $filter=true;
}
while($row = mysql_fetch_array($result))
{
if( (!$filter) || ( ($filter) && ($filter_id==$row['id']) ) )
{
$id = $row["id"];
$title = $row["title"];
$length = $row["length"];
// do other stuff here
}
}
I also changed $rowvideo to $row as this is the array you used to fetch the results.
<?php //give ma all values but only echo out list of the $_GET['id'] in the url
while ($row = mysql_fetch_array($result)) {
$id = $rowvideo["id"];
$title = $rowvideo["title"];
$length = $rowvideo["length"];
if ($id == $_GET['id']) { // or even ===
echo("<li><a href='#'>". $title." " .$length. "</a></li>");
}
}
?>
I've created some if / else statements to get name from url like http://website.com/page.php?name=Love It seems to look good and trows no errors, but for some reason I am not getting data from the database. Basically it gets 'name' from url and checks of it is one of allowed categories, if yes it selects article from database that has st_category = to what user selected.
But than again for some reason it doesn't work.
Here is a snippet of code that I think causes the problem.
<?php
$category = preg_replace('#[^a-z]#i', '', $_GET["name"]);
if ($category = "Love") {
$st_category = "Love";
}
else if ($category = "Work") {
$st_category = "Work";
}
else if ($category = "Money") {
$st_category = "Money";
}
else if ($category = "Kids") {
$st_category = "Kids";
}
else if ($category = "Health") {
$st_category = "Health";
}
else if ($category = "Friends") {
$st_category = "Friends";
}
else if ($category = "Education") {
$st_category = "Education";
}
else if ($category = "Other") {
$st_category = "Other";
}
else {
header("Location: http://www.inelmo.com/");
exit;
}
$sql = mysql_query("SELECT * FROM stories WHERE showing = 1 AND st_category = '$st_category' ORDER BY st_date DESC LIMIT 10") or die (mysql_error("There was an error in connection"));
//And another stuff here to display article
?>
= is not the same as ==. In your if statements you are doing assignments not comparison.
if ($category = "Love") should be changed to if ($category == "Love") (or to if ($category === "Love") and so on...
That could be tidied up to much less code, much more maintainable, using in_array().
$categories = array(
'Love',
'Work',
'Money',
'Kids',
'Health',
'Friends',
'Education',
'Other'
);
$category = preg_replace('#[^a-z]#i', '', $_GET["name"]);
if (!in_array($category, $categories)) {
header("Location: http://www.inelmo.com/");
exit;
}
$sql = mysql_query("SELECT * FROM stories WHERE showing = 1 AND st_category = '$category' ORDER BY st_date DESC LIMIT 10") or die (mysql_error("There was an error in connection"));
And this also fixes the problem that #matino rightly pointed out, which is that you were assigning and not comparing.
You have used a single "=" in every if.
The correct syntax is with "==" or "===", like:
<?php
$category = preg_replace('#[^a-z]#i', '', $_GET["name"]);
if ($category == "Love") {
$st_category = "Love";
}
else if ($category == "Work") {
$st_category = "Work";
}
...
?>
Please use double equal sign like
if($foo=="foo1")
In your if-statements you used the = while you had to used the == sign. With the = you assign a value to a variable on the left, like $sum = 1 + 2; you wanted is $sum==3.