How to prevent user from bypassing the quantity using the add button - php

In my button the user can add more quantity from his order.
What I want is to prevent the user from adding more than the quantity left.
The button goes into the cart table. What I want is to connect the product_qty to the cart so that the user cannot abuse the add button.
E.G. Item A ( 5 stocks left ) , User inputs 4 , but the user can abuse it using the button going from 4 to 8.
my product table consists of
productid,
categoryid,
product_name,
product_price,
product_qty,
supplierid,
my cart table consists of
cartid,
userid,
productid,
qty,
This is my php file
<?php
include('session.php');
if(isset($_POST['add'])){
$id=$_POST['id'];
$query=mysqli_query($conn,"select * from cart where productid='$id'");
$row=mysqli_fetch_array($query);
$newqty=$row['qty']+1;
mysqli_query($conn,"update cart set qty='$newqty' where productid='$id'");
}
?>

You have to first check whether addition of the product exceeds the total stock or not, and then perform the UPDATE operation accordingly.
<?php
include('session.php');
if(isset($_POST['add'])){
$id=$_POST['id'];
$query=mysqli_query($conn,"SELECT * FROM product NATURAL JOIN cart where productid = '$id' AND userid = YOUR_USER_ID");
if(mysqli_num_rows($query)){
$row=mysqli_fetch_array($query);
if(($row['qty'] + 1) <= $row['product_qty']){
$newqty = $row['qty'] + 1;
mysqli_query($conn,"update cart set qty='$newqty' where productid='$id'");
// your code
}
}
}
?>
Sidenotes:
It is not a good idea to call SQL query/submit form for every addition of product. Let user decide the total quantity of the product user wants and then send the accumulated value to database. Use JavaScript for this.
Learn about prepared statement because right now your queries are susceptible to SQL injection attack. Also see how you can prevent SQL injection in PHP.

Related

Checking if user owns item before using

I have a simple market and user customisation system, when a user equips an item it goes to (URL)/render.php?id=item ID , in the render.php file it has simple code found below. How would I make the file check if the user actually owns the item before equiping it? (at the moment it doesn't and you can wear stuff you don't own by abusing that)
<? include "../../header.php";
$id = $_GET['id'];
$item = $handler->query("SELECT * FROM items WHERE id=" . $_GET['id']);
$gI = $item->fetch(PDO::FETCH_OBJ);
$handler->query("UPDATE `users` SET `$gI->type`='$gI->wearable' WHERE `id`='$myu->id'");
?>
<head><meta http-equiv="refresh" content="1; url=/Customize/"></head>
You can make a table for users_items and use the table to save the users items when a user obtains an item. You would insert a row in this table that links the user to the item, i.e: id, user_id, item_id, then instead of directly selecting from the items table, you select from users_items and JOIN from the items table the details of the item.
SELECT items.type,
items.wearable
FROM users_items
LEFT JOIN items ON items.id = users_items.item_id
WHERE users_items.item_id = ?
Then use prepared queries on ?, instead of string concatenation to prevent SQL injection

Why my PHP mysql code accepting customer orders with zero products in the cart?

I have developed an online shopping website with PHP and mysql. When a customer placing an order, at first I am checking if there is any product in his cart. If there's no product, he cannot place order and show him a message that his cart is empty and redirect him to the home page.
But today someone somehow managed to place an order without a single product in his cart. How this can be possible? Is this possible that code may sometimes fail to execute accurately? If not, how come it happened in my case?
I am posting lines of my code I have used in saving a customer order.
<?php
session_start();
include "connection.php";
if (isset($_POST['submit'])){
$cutomer_id=$_SESSION['customer_id'];
$customer_address=$_POST['delivery_address'];
$customer_name=$_POST['customer_name'];
$session_id= session_id();
//IF CART EMPTY THEN REJECT ORDER
$strSql= "select * from cart where session_id='" .$session_id."'";
$result= mysqli_query ($con,$strSql);
//if nothing found in cart then opt out
$count_prods = mysqli_num_rows($result);
if($count_prods==0){
echo "Your cart is empty";
exit;
}
//UPDATE THE DELIVERY ADDRESS OF THE CUSTOMER
$update_address="UPDATE user_info SET address1='$customer_address', first_name='$customer_name' WHERE user_id='$cutomer_id'";
$success= mysqli_query($con,$update_address);
//making order number
$strsql2="SELECT NEXTval('order_number_producer') as order_number";
$result2=mysqli_query($con,$strsql2);
$got_it=mysqli_fetch_assoc($result2);
$order_number=$got_it['order_number'];
//first insert into new orders
date_default_timezone_set("Asia/Delhi");
$orderTime=date("d-m-Y h:i:s A");
$strsql3="INSERT INTO new_order (order_number, customer_id, order_status,delivery_date, delivery_time,order_time) VALUES ('$order_number','$cutomer_id','processing','$delivery_date','$delivery_time','$orderTime')";
$successfull= mysqli_query($con,$strsql3);
//Now insert order details into order_details table
$strSql= "select * from cart where session_id='" .$session_id."'";
$result= mysqli_query($con,$strSql);
while ($rows= mysqli_fetch_assoc($result)){
$p_id =$rows['p_id'];
$qty = $rows['qty'];
$price = $rows['price'];
$strsqlOrderDetails="INSERT INTO order_details(order_number, product_id, qty, price) VALUES ('$order_number','$p_id','$qty','$price')";
$done= mysqli_query($con,$strsqlOrderDetails);
}
//New order created, ordered products inserted...NOW CLEAR THE CART OF CUSTOMER
$clearcart=$strSql= "delete from cart where session_id='" .$session_id."'";
$cleared= mysqli_query($con,$clearcart);
echo "Order submitted. Your order number is # $order_number";
}
?>
Sounds like it could be the infamous button double click problem. Looks like the order went through on the first click and the cart was emptied as a result.
Then with the second click (in the double click) the order was not found?
Perhaps try to simulate this behaviour by double clicking on the button and if this is the culprit, add some javascript to prevent the double click of the button.

Checking for record in MySQL and create if not exist

When I click a buy now button I'm checking to see if the record (product id) exists in my mysql database table and if they don't create another one and if they do, just update the existing one.
It creates the first record fine and it even updates when I click it again without making another record, but when I click another product it creates another record and it never updates the following records.
In other words it just updates the first product id and it creates new records for the rest.
here is an image of my table
function add_to_cart(){
global $connection;
$ip = getIp();
if(isset($_GET['add'])) {
$product_id = $_GET['id'];
$product_price = get_item_price($product_id);
$query = "SELECT * FROM cart WHERE ip_address = '{$ip}' ";
$check_query = query($query);
confirm($check_query);
$row = fetch_array($check_query);
$db_product_id = $row['product_id'];
if(mysqli_num_rows($check_query) === 0 || $product_id != $db_product_id) {
$query = "INSERT INTO cart(product_id,ip_address,quantity,price_sum) VALUES('{$product_id}', '{$ip}' ,1, '{$product_price}')";
$send_query_cart = query($query);
confirm($send_query_cart);
redirect("index.php");
} else {
$query = "UPDATE cart SET quantity = quantity + 1, price_sum = price_sum + '{$product_price}' WHERE product_id = '{$product_id}' ";
$update_records = query($query);
confirm($update_records);
redirect("index.php");
}
}
}
Probably the best solution is to create a UNIQUE constraint on (I am assuming) product_id and ip_address.
ALTER TABLE `cart` ADD UNIQUE `unique_index`(`ip_address`, `product_id`);
Then, I would not store the price of items in the cart at all. The price of an item can be looked up in your items table. When an order is completed you can save the price of the individual item since it could change, but while it's in the cart you want the most recent price.
Once you have done that, your query can be simplified to
$query = "INSERT INTO cart(product_id,ip_address,quantity)
VALUES ('{$product_id}', '{$ip}', 1)
ON DUPLICATE KEY UPDATE
quantity = quantity+1";
and you don't even have to check it - the query will handle the update or insert automatically.
Also, I wouldn't rely on ip_address to identify users - if someone is shopping on their phone while riding in a car, it could easily change. Two people on the same router can appear to have the same ip address to your website. I would save something in the session or in a secure cookie and use that to identify them.
To get the totals, you would do something like:
$totals = "SELECT cart.product_id, cart.quantity * products.price as product_price_total
FROM cart
LEFT JOIN products USING(products.id = cart.product_id)
WHERE ip_address = '{$ip}'";

Insert Value From One Table to Another on Update MySql, PHP

I was wondering if there was a way to take one value from a column in a Table and add it to a column in another table.
The Scenario: I have a table (Shopping_Cart). It stores all of my customers shopping cart items in the columns CustomerID, PID, Price, Status (Status can be "IN_CART" which means it was added and "OPEN" means that it has been paid for and ready to be processed and shipped). Then I have a table (Products). It stores product information in columns PID, Price,Weight`. When My customers place an item in the shopping cart I do not capture the price. Prices can change daily so if they add something today, when they come back tomorrow the price may increase or decrease in their shopping cart. When my customer checks out and payment is confirmed, I am trying to grab the Price in the (Products) table where Products.PID = Shopping_Cart.PID and then apply that price to the Shopping_Cart.Price to lock in that final price since the customer has paid for it. Any Ideas? I got it set up to change the items for that customers cart to "OPEN" but I am a little lost on getting my script to grab a value from one table and applying it to another table. Below is my PHP Script for changing the Lines from "IN_CART" to "OPEN".
if($The_Function=="CLOSE_LINES"){
$cart_close_session_id = $_GET['close_session_id'];
$response = array();
require_once __DIR__ . '/db_connect.php';
//connect to my db
$db = new DB_CONNECT();
$result = mysql_query("UPDATE shopping_cart SET Status = 'OPEN' WHERE SessionID LIKE '$cart_close_session_id' AND Status LIKE 'IN_CART'");
if ($result) {
$response["close_success"] = 1;
//GRAB PRICE FROM "PRODUCTS TABLE" AND UPDATE SHOPPING_CART
}else{
$response["close_success"] = 0;
}
echo json_encode($response);
}
Assuming that you have a *shopping_cart* table with a price and a product_id column, you can update it with the price of the products table, like this:
UPDATE shopping_cart SET price =
(SELECT price FROM products WHERE id = shopping_cart.product_id)
You can join against the products table and update the shopping_cart upon purchase as seen below:
UPDATE shopping_cart c
JOIN products p
ON p.pid = c.pid
SET c.price = p.price
WHERE c.customer_id = ?

Insert ID for 5 items or More

I continued from the previous topic - 1 id for more items - that I discuss.
In that last topic, I ask about the concept and now what I'm doing is continue to coding concept.
The code successfully save the data into database, but still when insert 5 item, it submit the data per item per ID. Example :
Item 1 - Computer (Purchase No 1)
Item 2 - Mouse (Purchase No 2)
That I wanted is :
Item 1 - Computer (Purchase No 1)
Item 2 - Mouse (Purchase No 1)
and here it's my code : I using purchase no with autoincrement.
Here it's my execute code :
<?php
$conn = oci_connect("system", "dev01");
$n = $_POST['jum'];
for ($i=1; $i<=$n; $i++)
{
$dept=$_POST['dept'];
$date_request=$_POST['date_request'];
$supplier=$_POST['supplier'];
$item=$_POST['item'.$i];
$qty=$_POST['qty'.$i];
$uprice=$_POST['uprice'.$i];
$total=$_POST['total'.$i];
$s = oci_parse($conn,
"insert into purchase_request(dept_id, supplier_id, date_request, item, qty, uprice, total_amount) values ('$dept', '$supplier', '$date_request', '$item'
, '$qty', '$uprice', '$total'
)");
$r = oci_execute($s);
oci_rollback($conn);
echo "Data was committed\n";
}
?>
Any suggestions ?
You should follow the suggestion you marked as accepted in your earlier post, but don't make purchase ID an autoincrement field. The whole point is that it doesn't auto-increment; it goes up when you specifically want it to (so that multiple items can have the same purchase_id). This does mean you'll need to explicitly assign it a value. The simplest way would be to query for the maximum purchase id that's currently in the purchases table, and for your query, add 1 to that.

Categories