query duplicated and change data - php

I am creating a coupon system for an online store using PHP (PDO queries), Mysql. Well, the system on a single page shows the coupons (table) and also creates them (form). In my BD there are 2 tables that play here in the implementation of the coupon system. (1.Table Coupons - is new) and (2.Table products - already existing before). then the products table has a last field called id_coupon and when I create a coupon I select a product from those that already exist in the store and in the products table I insert the id_coupon of the coupon in the id_coupon field of the products table located as the last column of the table and so the corresponding coupon and product correspond, likewise only if they correspond the table shows it, the problem lies in the fact that it inserts the coupon and links it perfectly in the products table (only the 1st time).
Problem: it only works in the creation of the first coupon, all linked (coupon-product with id_coupon in the 2 tables, everything is perfect), but! The second coupon created is the error (sometimes it creates 2 coupons) and other times, more than anything, it changes the id_coupon of the first coupon for the second coupon that creates a product that does not correspond and changes the corresponding id_coupon of the coupon that it was created for the previous product.
It sounds a bit confusing but that is my problem and it seems very strange to me, please I hope your collaboration and I will share the code with you (it is NOT laravel or codeigniter or object-oriented prog)
TABLE_COUPONS
TABLE_PRODUCTS
The correct solution for prevent change data to destinated product when insert a new second cupon and in this way prevent replazing first cupon id_coupon code for first product
<?php require_once('header.php'); ?>
<?php
$statement = $pdo->prepare("SELECT * FROM tbl_settings");
$statement->execute();
$result = $statement->fetchAll(PDO::FETCH_ASSOC);
foreach ($result as $row){
$row['ValorDolarUS'];
}
?>
<?php
if(isset($_POST['form1'])) {
$valid = 1;
if(empty($_POST['coupon_name'])) {
$valid = 0;
$error_message .= 'Coupon Name can not be empty<br>';
}
if(empty($_POST['coupon_start_date'])) {
$valid = 0;
$error_message .= 'Coupon Start Date can not be empty<br>';
}
if(empty($_POST['coupon_expire_date'])) {
$valid = 0;
$error_message .= 'Coupon Expire Date can not be empty<br>';
}
if(empty($_POST['coupon_code'])) {
$valid = 0;
$error_message .= 'Coupon Code can not be empty<br>';
}
if(empty($_POST['coupon_type'])) {
$valid = 0;
$error_message .= 'Coupon Type can not be empty<br>';
}
if(empty($_POST['coupon_discount'])) {
$valid = 0;
$error_message .= 'Coupon Discount can not be empty<br>';
}
if($valid == 1) {
$statement = $pdo->prepare("SELECT * FROM tbl_settings");
$statement->execute();
$result = $statement->fetchAll(PDO::FETCH_ASSOC);
foreach ($result as $row){
$row['ValorDolarUS'];
}
$ValorDolarUS = $row['ValorDolarUS'];
$CurrentPriceConvertToDolar = ($_POST['coupon_discount'] / $ValorDolarUS);
$statement = $pdo->prepare("INSERT INTO tbl_coupons(
coupon_name,
coupon_start_date,
coupon_expire_date,
coupon_code,
coupon_type,
coupon_discount,
ValorDolarUS
) VALUES (?,?,?,?,?,?,?)");
$statement->execute(array(
$_POST['coupon_name'],
$_POST['coupon_start_date'],
$_POST['coupon_expire_date'],
$_POST['coupon_code'],
$_POST['coupon_type'],
$CurrentPriceConvertToDolar,
$ValorDolarUS
));
$statement = $pdo->prepare("SELECT * FROM tbl_coupons");
$statement->execute();
$result = $statement->fetchAll(PDO::FETCH_ASSOC);
foreach($result as $row) {
$selected_product_id_coupon = $row['id_coupon'];
}
$statement = $pdo->prepare("SELECT * FROM tbl_product");
$statement->execute();
$result = $statement->fetchAll(PDO::FETCH_ASSOC);
foreach($result as $row) {
$selected_product_id = $row['p_id'];
}
$statement = $pdo->prepare("UPDATE tbl_product SET id_coupon=? WHERE p_id=?");
$statement->execute(array($selected_product_id_coupon,$selected_product_id));
$success_message = 'Coupon is created successfully and its aplied for selected product.';
$reloadpage = $_SERVER['PHP_SELF']."#CouponsForm";
header("Location:$reloadpage");
exit();
}
}
?>

Related

How to connect to tables and display their content? (MySQL and PHP)

I have two mysql tables (products and categories). I have some mock data in both tables. Now I need to somehow attach the categories to the products. For example - The product witht he ID 1 should return the following:
| product name | category |
| Monitor | Technology |
I know I have done this bevore, but today I simply can't seem to find the solution to this.
EDIT
This is waht I have so far. The connection works well and I can display the data in a Table.
<?php
// Include database connection
include("connection.php");
// Create variables for later use
$db = $conn;
$tableName = "Produkte";
$columns= ['id_product', 'name_product'];
// Create variable to use in index.php
$fetchData = fetch_data($db, $tableName, $columns);
// The function below feteches data from the tables specified and checks if the colums are emtpy by any chance.
function fetch_data($db, $tableName, $columns) {
// Check db connection
if (empty($db)) {
$message= "Database connection error";
}
// Check if the columns variable is empty and not an array by any chance
elseif (empty($columns) || !is_array($columns)) {
$message="Product Name must be defined in an indexed array";
}
// Check if table name is empty
elseif (empty($tableName)) {
$message= "Table Name is empty";
}
// Else proceed as usual.
else {
$columnName = implode(", ", $columns);
// The query needs to be repalced. Today my SQL stuff is leaving me a bit.
$query = "SELECT p.".$columnName." AS product, c.name_category FROM $tableName p JOIN Kategorie c ON c.id_";
$result = $db->query($query);
if ($result== true) {
if ($result->num_rows > 0) {
$row= mysqli_fetch_all($result, MYSQLI_ASSOC);
$message= $row;
}
else {
$message= "No Data Found";
}
}
// Throw error if error occures
else{
$message= mysqli_error($db);
}
}
return $message;
}
The table products has only 2 columns. An id column and a product_name column.
It's vary basic technics:
// create DBquery using JOIN statement
$query = "
SELECT
p.name AS product, c.name AS category
FROM products p
JOIN categories c ON c.id = p.category_id;";
// get DB data using PDO
$stmt = $pdo->prepare($query);
$stmt->execute();
// show table header
printf('| product name | category |' . PHP_EOL);
// loop for output result as table rows
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
printf('| %-12s | %10s |' . PHP_EOL, $row['product'], $row['category']);
}
Try online

Create a "Secret Santa" generator using MySQL and PHP

I am trying to create a Secret Santa system using a PHP page and a MySQL database to store the details so if someone forgets their match they can re-request it.
Step 1: I created a random number generator based on the number of people in the list in the database.
Count Function:
$maxSQL = "SELECT COUNT(id) as total FROM secretsanta";
$maxRS = mysqli_query($conn, $maxSQL);
$maxQuery = mysqli_fetch_array($maxRS);
$maxpersons = $maxQuery['total'];
Then the Random Number Generator:
$assigned = rand(1,$maxpersons);
Step 2: Test if the random number matches the persons own id and regenerate a new number if true.
do {
$assigned = rand(1,$maxpersons);
} while ($assigned==$id);
Step 3: Write the paired id to the persons database record.
$assignSQL = "UPDATE secretsanta SET assigned = '".$assigned."' WHERE secretsanta.id = ".$id;
if (mysqli_query($conn, $assignSQL)) {
echo "Record updated successfully";
} else {
echo "Error updating record: " . mysqli_error($conn);
}
The Problem: Now I need to check that other people aren't assigned to that person or otherwise some could miss out and others would get more than others.
I tried to implement a function that contained a query to test each record to see if that number already existed and was hoping to add it as a condition to perhaps a while or do while statement?
if (!function_exists('checkRandom')){
function checkRandom($funcid){
$Check_SQL = "SELECT assigned FROM secretsanta ORDER BY id ASC";
$Check_RES = mysqli_query($conn, $Check_SQL);
if (Check_RES) {
while ($CheckArray = mysqli_fetch_array($Check_RES, MYSQLI_ASSOC)) {
$CheckAsgn = $CheckArray['assigned'];
if ($funcid==$CheckAsgn) {return true;}else{return false;}
}
}
}
}
Then implement it into the do while statement like this:
do {
$assigned = rand(1,$maxpersons);
} while ($assigned==$id||checkRandom($assigned));
No luck so far...HELP!.. please :)
P.S. I know there are websites that already do this, I just don't trust them to give out mine and family email address' if I can make my own private version myself.
Using your method, the first few assignments will be done with no problem, but imagine the last unassigned entry and how many times it will try a random number only to find the person with that id is already assigned..
I'm gonna give you another approach to your problem: for each user that you want to assign a santa to, make a new SELECT statement with a WHERE clause that lets you select only those users that are not assigned yet.
check out my code and see if that helps you. I just typed this and didnt test it so there could be some mistakes.
// load all unassigned users into an array
$unassignedUsers = [];
$query = "SELECT id, assigned FROM secretsanta WHERE assigned is NULL";
$res = mysqli_query($conn, $query);
while($row = mysqli_fetch_assoc($res){
$unassignedUsers[] = $row;
}
if(count($unassignedUsers) == 1){
echo 'There is only 1 unassigned user. Therefore he cannot be matched';
} else {
// for loop for each user in DB that is not assigned yet
//for ($i = 1;$i <= count($unassignedUsers); $i++){
$i = 0;
foreach($unassignedUsers as $user)
// if its the second-to-last iterations of the for-loop, check for legality of the last one
if(count($unassignedUsers) - $i == 1){
$lastUserID = $unassignedUsers[count($unassignedUsers)-1]['id'];
$query = "SELECT id FROM secretsanta WHERE assigned is NULL AND id = ".$lastUserID;
$res = mysqli_query($conn, $query);
$rowcount = mysqli_num_rows($res);
if ($rowcount){
// last user is still unassigned
$query = "UPDATE secretsanta SET assigned = '".$lastUserID."' WHERE id = ".$user['id'];
if(mysqli_query($conn, $query)){
echo "Record with id ".$user['id']." updated successfully";
} else {
echo "Error updating record: ".mysqli_error($conn);
}
}
} else {
// select all unassigned users
$unassignedIDs = [];
$query = "SELECT id FROM secretsanta WHERE assigned is NULL AND id <> ".$user['id'];
$res = mysqli_query($conn, $query);
while($row = mysqli_fetch_assoc($res){
$unassignedIDs[] = $row['id'];
}
// get a random id from $unassignedIDs
$randomIndex = rand(0, count($unassignedIDs)-1);
$randomID = $unassignedIDs[$randomIndex];
// assign $randomID to user
$query = "UPDATE secretsanta SET assigned = '".$randomID."' WHERE id = ".$user['id'];
if(mysqli_query($conn, $query)){
echo "Record with id ".$user['id']." updated successfully";
} else {
echo "Error updating record: ".mysqli_error($conn);
}
}
$i++;
}
}
last edit: refactored whole code so it is able to be run multiple times and only assigns new users who are not assigned yet.
Step 1 is dependent on have a contiguous set of ids for the people. Think what happens if '3' leaves the company and it hires 6 to replace them....1,2,4,5,6 ($maxpersons=5)
"Now I need to check" - no you are still trying to solve the problem by guessing then seeing if your guess worked. Use an algorithm which is always going to return a correct result. The method below requires the addition of a temporary field 'sequence' of type float.
mysqli_query($conn,"UPDATE secretsanta SET sequence=RAND()");
$first=false;
$prev=false;
$all=mysqli_query($conn, "SELECT * FROM secretsanta ORDER BY sequence, id");
while ($r=mysqli_fetch_assoc($all)) {
if (false===$first) {
$first=$r['id'];
} else {
save_pair($prev, $r['id']);
}
$prev=$r['id'];
}
save_pair($prev, $first);
(but with better error checking)

Get data from different table based on Id

I'm building a small e-commerce website and I want to display the reviews, and I want to create screen names for people (first letter of first name concatenated onto the last name), but I can't figure out how to get the information from my clients table. Let me show you the code I've done so far:
$invId = filter_input(INPUT_GET, 'invId', FILTER_SANITIZE_NUMBER_INT); // this is taken from a name value pair from the view
// Gets the raw data from the database
function getProRev($invId){
$db = acmeConnect();
$sql = "SELECT * FROM reviews WHERE invId = :invId ORDER BY reviewId DESC";
$stmt = $db->prepare($sql);
$stmt->bindValue(':invId', $invId, PDO::PARAM_STR);
$stmt->execute();
$tn = $stmt->fetchAll();
$stmt->closeCursor();
return $tn;
}
// Builds the simple review display
function buildReviewDisplay($reviews){
$rd = "<div id='reviewView'>";
foreach ($reviews as $review){
$rd .= "<h2>$review[clientId]</h2>";
$rd .= "<h3>$review[reviewDate]</h3>";
$rd .= "<p>$review[reviewText]</p>";
$rd .= "<hr>";
}
$rd .= "</div>";
return $rd;
}
As you can see, I'm displaying the clientId (a number) which is not what I want, and now this is where I'm stuck. I have the relationship between the two tables (clients and reviews) set up, but I can't figure out how to get the data. Here is the function I tried to write, but it didn't work:
// Trying to get the dang client info
function getUsername($clientId){
$db = acmeConnect();
$sql = "SELECT * FROM clients WHERE clientId = :clientId";
$stmt = $db->prepare($sql);
$stmt->bindValue(':clientId', $clientId, PDO::PARAM_STR);
$stmt->execute();
$cd = $stmt->fetchAll();
$stmt->closeCursor();
$fletter = substr($cd['clientFirstname'], 0, 1);
$scrnam = $fletter . $cd['clientLastname'];
return $scrnam;
}
And I understand that this didn't work because there was nothing passing the $clientId parameter to the function, but the is contained in the $tn[] array, so there has to be a way that I can take the $clientId from the $tn[] array and query the database for the first and last name, but I can't figure out how.
You can join the clients table to the reviews table in your first query.
SELECT * FROM reviews
LEFT JOIN clients ON reviews.clientId = clients.clientId
WHERE invId = :invId ORDER BY reviewId DESC
Then you'll have access to the client name columns without needing to execute an additional query for each review you display.
That way you can use your code from getUsername in buildReviewDisplay.
foreach ($reviews as $review) {
$fletter = substr($review['clientFirstname'], 0, 1);
$scrnam = $fletter . $review['clientLastname'];
$rd .= "<h2>$scrnam</h2>";
$rd .= "<h3>$review[reviewDate]</h3>";
$rd .= "<p>$review[reviewText]</p>";
$rd .= "<hr>";
}

PHP update via textboxes

Right now the update only works if all textboxes are filled out, so the user can't just update productName for example. There isn't an error, but if the other textboxes are left blank then the database is updated with blanks and 0's. I want this to update whatever textboxes receive input, be it one or all, and leave the rest of the info alone if nothing is entered.
If productName for that row is Samsung, description is 'A phone' wholesalePrice is 179.99 and I just update the productName textbox only I still want the description and wholesalePrice to stay the same. Right now if I just update the productName only then the wholesalePrice shows as 0.00 and the description is blank. I tried using OR statements rather than commas in the query and whatever textbox I entered info in returned a 0.
if(isset($_POST['id'])) {
try {
$query = "UPDATE products SET productName = :productName, description = :description, wholesalePrice = :wholesalePrice,
retailPrice = :retailPrice, category = :category, quantityOnHand = :quantityOnHand
WHERE productID = :productID";
$statement = $db->prepare($query);
$statement->bindValue(':productID', $_POST['id']);
$statement->bindValue(':productName', $productName);
$statement->bindValue(':description', $description);
$statement->bindValue(':wholesalePrice', $wholesalePrice);
$statement->bindValue(':retailPrice', $retailPrice);
$statement->bindValue(':category', $category);
$statement->bindValue(':quantityOnHand', $quantityOnHand);
$statement->execute();
$statement->closeCursor();
//reload page after data is entered into the table and display a message if successful for 3 seconds before redirect
$page = $_SERVER['PHP_SELF'];
header('Location: ' . $_SERVER["HTTP_REFERER"] );
exit;
You can use a helper array for your columns to bind values dynamically if each $_POST value is set. Then you can create the update query for only those values.
$fields = array('productName', 'description', 'wholesalePrice', 'retailPrice', 'category', 'quantityOnHand');
$values = array();
$binds = array();
foreach($fields as $key => $value) {
if (isset($_POST[$value])) {
$values[] = $value.' = :'.$value;
$binds[':'.$value] = $_POST[$value];
}
}
if (!empty($values)) {
$query = "UPDATE products SET ";
$query .= implode(', ', $values);
$query .= " WHERE productID = :productID";
$binds[':productID'] = $_POST['id'];
$statement = $db->prepare($query);
$statement->execute($binds);
$statement->closeCursor();
}
EDIT:
If you have the values stored in variables then you can use variable variables:
foreach($fields as $key => $value) {
if (isset($$value)) {
$values[] = $value.' = :'.$value;
$binds[':'.$value] = $$value;
}
}
You need to pass all existing values to form fields so existing data is passed to the sql update if nothing changes. On submit validate the data, then do the update.
<textarea name="description">'.$row['description'].'</textarea>
if(isset($_POST['id'])) {
$productname = $_POST['productname'];
$description = $_POST['description'];
// etc ....
try {
// sql
}catch{
// error
}
}

Checking For Values in string in table field

I have a table with blog posts, and i want to control display based on who's seen which article. I added a new table field in db 'post_seen' and want to append 'viewer_id' to the field (eg.: 'user5,user2,user8'). I want then be able to check if the user id is in the post seen field, to do some action.
The queries dont seem to be working So far I've done this
public function checkUnSeenPosts($myid){
//select all posts where user_id not found in post_seen column
$query = "SELECT * FROM mutamba_posts WHERE INSTR('post_seen',".$myid.") > 0";
$sql = $this->db->query($query);
if($sql->num_rows() > 0){
return true;
}else{
return false;
}
}
function markPostsAsSeen($user_id){
//select all posts where user_id not found in post_seen column
$query = "SELECT * FROM mutamba_posts WHERE INSTR('post_seen',".$user_id.")< 0";
$sql = $this->db->query($query);
if($sql->num_rows() > 0){
foreach ($sql->result() as $r){
$data = array('post_seen' => $r->post_seen.','.$user_id);
$this->db->update('mutamba_posts',$data);
}
}
}

Categories