Posting from dynamic form (Multiple rows) - php

I have a form that creates form rows (fields) dynamically (add-delete) up to seven. Each additional form row has an incrimental number appended to it (ie: name="product" next is name="product2".. "Product3" etc.). So I thought I would just use isset to see what is posted and only insert what is posted but my lack of skills has led to this not working. See my code below:
mysql_select_db("inventory", $con);
$sql="INSERT INTO shipped (id, type, client, product, color, quantity)
VALUES ('$_POST[productid]','$_POST[type]','$_POST[client]','$_POST[product]','$_POST[color]','$_POST[quantity]')";
if( isset($_POST['productid2']) ) {
"INSERT INTO shipped (id, type, client, product, color, quantity)
VALUES ('$_POST[productid2]','$_POST[type2]','$_POST[client2]','$_POST[product2]','$_POST[color2]','$_POST[quantity2]')";
}
I planned to just add "isset" for each product but as it turns out this will only insert one of the set of post values and not both. I am going to have up to product7 (so seven inserts at max). Any help?

You would use the array in input fields
<input type="text" name="productid[]" />
<input type="text" name="type[]" />
<input type="text" name="client[]" />
<input type="text" name="product[]" />
<input type="text" name="color[]" />
<input type="text" name="quantity[]" />
At server side:
foreach($_POST['product'] as $k => $v){
$sql="INSERT INTO shipped (id, type, client, product, color, quantity) VALUES
($_POST['productid'][$k],$_POST['type'][$k],$_POST[client][$k]','$v','$_POST[color][$k]','$_POST[quantity][$k]')";
}

Ok so I did like the other answer as it seemed much more elegant than the solution I ended up using - but the fact is the other answer just did not work. So my solution just ended up just checking if the next form set of form fields is set, and if it is it displays the proper inserts. See the first part here:
mysql_select_db("inventory", $con);
if( !isset($_POST['productid2']) ) {
$sql="INSERT INTO shipped (id, type, client, product, color, quantity)
VALUES ('$_POST[productid]','$_POST[type]','$_POST[client]','$_POST[product]','$_POST[color]','$_POST[quantity]')";
}
if( isset($_POST['productid2']) ) {
$sql="INSERT INTO shipped (id, type, client, product, color, quantity)
VALUES ('$_POST[productid]','$_POST[type]','$_POST[client]','$_POST[product]','$_POST[color]','$_POST[quantity]'),
('$_POST[productid2]','$_POST[type2]','$_POST[client2]','$_POST[product2]','$_POST[color2]','$_POST[quantity2]')";
}
if( isset($_POST['productid3']) ) {
$sql="INSERT INTO shipped (id, type, client, product, color, quantity)
VALUES ('$_POST[productid]','$_POST[type]','$_POST[client]','$_POST[product]','$_POST[color]','$_POST[quantity]'),
('$_POST[productid2]','$_POST[type2]','$_POST[client2]','$_POST[product2]','$_POST[color2]','$_POST[quantity2]'),
('$_POST[productid3]','$_POST[type3]','$_POST[client3]','$_POST[product3]','$_POST[color3]','$_POST[quantity3]')";
}
Like this another four times... adding the other values each time. This works for me because my form fields can only be added a max of seven times so it doesn't need to be infinite. So if you are only allowing a small amount of form fields to be added this will work well.

Related

Problem with query to update foreign key column

I am working on a cms for properties/ads in oop php for learning purposes. I have three tables that are connected with pivot table.
photos (id, name, extension),
property_photo (id, property_id, photo_id),
properties (id, title, description, main_photo_id)
I have a gallery of photos for every property and I am trying to be able to insert main photo (one of existing photos in gallery) for each property through foreign key (main_photo_id) and display that photo on a different page. I am having trouble writing function (query) in model. Any help is much appreciated. Here is some of my code:
AdModel:
public function MainPhotoInsert($id)
{
$this->db->query('INSERT INTO properties (main_photo_id) VALUES (:main_photo_id) SELECT id FROM PHOTOS WHERE id = :id LIMIT 1');
$this->db->bind(':id', $id);
$row = $this->db->single();
return $row;
}
AdsController:
public function galleryAction()
{
if (!isset($_GET['id'])) {
$photo_id = $_SESSION['photo_id'];
} else {
$photo_id = $_GET['id'];
}
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$_POST = filter_input_array(INPUT_POST, FILTER_SANITIZE_STRING);
if(isset($_POST['radio']))
{
$this->AdModel->MainPhotoInsert($photo_id);
redirect('ads/index');
}
}
$data = $this->AdModel->getPhotosForProperty($photo_id);
$data1 = $this->AdModel->MainPhotoData($photo_id);
$this->view->render('ads/gallery', $data, $data1);
}
gallery.php:
<form action="/ads/gallery?id=<?php echo $_GET['id']; ?>" method="POST">
<?php foreach ($data as $key => $value) : ?>
<img src="<?php echo '/public/photos/'.$value->name.'.'.$value->extension ?>" class="img-fluid img-thumbnail" width="250" height="250">
<input type="radio" name="radio" value="<?php echo $value->photo_id; ?>" >Make main
<br>
<?php endforeach; ?>
<br>
<br>
<button type="submit" name="submit" value="submit" class="btn btn-success form-control">Submit</button>
</form>
You shouldn't have a select clause in your insert statement (at least not for what you are trying to do). IF you only ever need to set it once then you need to tweak the query to include the other two values (title and description) or they will always be blank. It should end up looking something like this:
INSERT INTO properties (main_photo_id, title, description) VALUES (:main_photo_id, : title, : description)
More likely, you want an upsert (update if a relevant row already exists, insert if one doesn't). In MySQL the syntax is insert ... on duplicate key update. This means you are going to need a primary key on the properties table (it's unclear if you already have one). The syntax is pretty similar to the insert above but without knowing the exact structure of the table I can't give you the exact query.
Update:
The on duplicate key syntax would look something like this (it depends on how you have your primary key set up on the table, e.g. if main_photo_id is the primary key then this likely won't work):
INSERT INTO properties
(id, main_photo_id, title, description)
VALUES
(:id, :main_photo_id, : title, : description)
ON DUPLICATE KEY UPDATE
main_photo_id = :main_photo_id,
title = :title,
description = :description
Side note:
gallery.php is also going to produce a separate HTML form for each image with one radio button on the form which isn't really what you want. You should move the form to wrap around the entire foreach loop so that you have one form. Then you should put the image ID as the value for the radio button.

PDO multiple checkboxs inserting or delete

I need help to link between three tables by checkboxe:
features table ( id, title, sulg )
posts table (id, title, slug, added )
posts_features ( fea_id, post_id )
<input type="text" name="title" value="$post->title">
<input type="text" name="slug" value="$post->slug">
// importing all features
<input type="checkbox" name="featuresid[]" value="$features->id">
If checked ( insert ) if not exist.
foreach ($_POST['featuresid'] as $choice) {
$sql = $dbh->prepare("INSERT INTO posts_features (fea_id, post_id) VALUES ($choice, $id)");
$sql->execute();
}
and if un-checked ( delete ) from posts_features
$sql = $dbh->prepare("delete form posts_features where ........
Thanks in advance.
A checkbox doesn't $_POST if it's not checked, so you would not have a way to see (from the $_POST, anyway) which features where not checked.
There's several ways to do this, but without more information about your application, it's hard to make the "best" suggestion, but here's one method that will leverage $_POST:
Add an additional "hidden" input, with the corresponding $features->id, to set up the "existing" entries:
Note: I'm following your conventions in your code above to demonstrate this, even though they are clearly pseudo-code, and won't work properly.
<input type="checkbox" name="featuresid[]" value="$features->id">
<input type="hidden" name="existing[]" value="$features->id">
Then, you can leverage your loop like so:
foreach ($_POST['featuresid'] as $choice) {
$sql = $dbh->prepare("INSERT INTO posts_features (fea_id, post_id) VALUES ($choice, $id)");
$sql->execute();
}
// loop through ALL feature ids listed on the page
foreach( $_POST['existing'] AS $features_id ) {
// if the feature id wasn't in the checkboxes, then delete
if ( ! in_array( $features_id, $_POST['featuresid'] ) ) {
$sql = $dbh->prepare("DELETE FROM posts_features WHERE ........");
}
}
Un-checked checkboxes are not sent to PHP. So as you iterate through $_POST['featuresid'], you will only see the checkboxes that were checked. This means that to delete unchecked features really means to delete all features that are not in the checked group.
First, insert the selected features: important don't execute DB queries in a loop; they will really slow down your script. Instead, insert all records at once. You should also use parameterized queries; never insert user-supplied values directly into your DB queries!
After the insert, delete those features that were not selected:
DELETE FROM posts_features WHERE fea_id NOT IN (?, ?, ?, ?)
Each of the ? corresponds to a value in $_POST['featuresid']
An alternative, if you want PHP to receive an explicit selected/unselected value for each feature is to use Yes/No radio buttons or dropdown list for each feature in the HTML.

How do I use AES_Decrypt

I know this question has been asked a billion times as I've spent the last 2 weeks looking at all the previously asked questions and answers
but none of them actually have an understandable answer. So my question is this, I have a form that I'm passing the data input by users into a mysql
database and a portion of that data is encrypted with AES_Encrypt. When I check the database I can see the data has been encrypted so I'm good on the encryption part.
My issue lies in the decryption part. I've tried multiple variations from previous questions asked with no success, This is what I have so far,
//ENCRYPTING DATA
require 'path to key.php';
$sql = "INSERT INTO applications "(fname, lname, dob, ssn) VALUES ('$fname', '$lname', '$dob', AES_ENCRYPT('$ssn', '".$aeskey."')";
The code above works fine to encrypt the string.
This is where I'm confused, I'm wanting to select all the data associated with the ID for a record and decrypt the encrypted data for that record as well,
for example I have a search form that pulls up all the records in the database, you can then select to view a record and the results display in a form similar to the form used
to input the information.
So in my form to view records I have the following code.
//DECRYPT DATA
require 'path to key.php';
$conn = new mysqli($servername, $username, $password, $dbname);
$data = "SELECT * FROM $tbl_name where ID = $id";
$query = mysqli_query($conn, $data);
$data2 = mysqli_fetch_array($query);
<input type = "text" name="fname" value="<?php echo $data2['fname']?>"/>
<input type = "text" name="lname" value="<?php echo $data2['lname']?>"/>
<input type = "text" name="dob" value="<?php echo $data2['dob']?>"/>
<input type = "text" name="ssn" value="<?php echo $data2['ssn']?>"/><-----This will display the encrypted data in the encrypted form
So do I need to decrypt the encrypted data from the input box like
<input type = "text" name="ssn" value=<?php echo [AES_DECRYPT('ssn', '$aeskey')]?>"/> <---Doesn't work
or do I need to do something like this:
$sql SELECT * FROM $tbl_name (AES_DECRYPT('ssn', '$aeskey')) WHERE ID=$id;
Or am I totally wrong in how I think AES_DECRYPT should be used?
In the INSERT you use AES_ENCRYPT (of MySQL); then you have in your SELECT apply AES_DECRYPT; ejem:
SELECT fname, lname, dob, AES_DECRYPT(ssn, yourAESKey) as ssn
FROM applications [wHERE ... and other more that you require]
See that AES_DECRYPT have alias to return of result.
EDITED
Only change in $data the string with the SQL:
$data= "SELECT fname, lname, dob, AES_DECRYPT(ssn, yourAESKey) as ssn
FROM applications [WHERE ... and other more that you require]"
You line: <input type = "text" name="ssn" value="<?php echo $data2['ssn']?>"/><-----This will display the encrypted data in the encrypted form not change; unless instead of ssn (all in lowercase) in the alias you change some letter or all the letters to capital letters, you assign another alias name to the decrypted text; In order not to be ssn (in lower case).

Logic for inserting form with/without optional inputs into MySQL

Using: Brackets Html editor, MySQL Workbench
Simplified, I have a database with these tables
(main table) person
idperson PK NN UN AI
*fk_job NN UN (foreign key refering to idjob)
fn NN
ln NN
job
idjob PK NN UN AI
jobname NN
adress
idadress PK NN UN AI
*fk_person NN UN (foreign key refering to idperson)
adress NN
and this form. In the form it is required to fill on one adress, and optional to fill in a second one.
<?php
$con = new mysqli("localhost","user","password","database");
if ($con->
connect_error) {
die('Error : ('. $con->connect_errno .') '. $con->connect_error .'');
}
$job_sql = "SELECT idtype, typename FROM type;";
$job_data = $con->query($job_sql);
//insert if(isset()) here
$con->close();
?>
<form method="post">
<select name="typeSlc" required>
<option disabled selected>_</option>
<?php while($row = mysqli_fetch_array($job_data)) { ?>
<option value="<?php echo $row['jobid'];?>"><?php echo $row['jobname'];?></option>
<?php } ?>
</select>
<input name="fnTxt" required type="text">
<input name="lnTxt" required type="text">
<input name="adressTxt" required type="text">
<input name="cityTxt" required type="text">
<input name="opt_adressTxt" type="text">
<input name="opt_cityTxt" type="text">
<input name="submit" value="submit" type="submit">
</form
Issue:
I want to send a transaction with one batch of queries to the server when 'opt_adress' isset and another when it is not, namely:
if(isset($_POST['submit'])) {
if(isset($_POST['opt_adress'])) {
$sql = sprintf ("BEGIN;
INSERT INTO person (fk_job, fn, ln)
VALUES (%s, '%s', '%s');
SELECT LAST_INSERT_ID() INTO #id;
INSERT INTO adress (fk_person, adress)
VALUES (#id, '%s');
INSERT INTO adress (fk_person, adress, city)
VALUES (#id, '%s', '%s');
COMMIT;",
$con->real_escape_string($_POST['jobSlc']),
$con->real_escape_string($_POST['fnTxt']),
$con->real_escape_string($_POST['lnTxt']),
$con->real_escape_string($_POST['adressTxt']),
$con->real_escape_string($_POST['cityTxt']),
$con->real_escape_string($_POST['opt_adressTxt']),
$con->real_escape_string($_POST['opt_cityTxt']))
;
} else {
$sql = sprintf ("BEGIN;
INSERT INTO person (fk_job, fn, ln)
VALUES (%s, '%s', '%s');
INSERT INTO adress (fk_person, adress, city)
VALUES (LAST_INSERT_ID(), '%s', '%s');
COMMIT;",
$con->real_escape_string($_POST['jobSlc']),
$con->real_escape_string($_POST['fnTxt']),
$con->real_escape_string($_POST['lnTxt']),
$con->real_escape_string($_POST['adressTxt']),
$con->real_escape_string($_POST['cityTxt']))
;
}
$con->query($sql);
header("Location: samepage.php");
When I try to run the query it does not go through to the database (I am using MySQL Workbench). There are no error messages, yet the query is unsuccesful.
I want to insert batches if queries in a transaction if there are existing values in the optional inputs. Is this the correct string for that? Or is there a sleeker code I can use?
The form and database in this question is a simplified version on the one I use in reality.
Thanks in advance, -burrdie
You have to understand the difference between a query and a batch of queries.
Since you have to execute several separate queries, you have to make several separate query() calls as well.
So change your code like this
$con->query("BEGIN");
$con->query(sprintf ("INSERT INTO person (fk_job, fn, ln)...");
$con->query("SELECT LAST_INSERT_ID() INTO #id");
// ...so on
and you'll be set.
Besides, it will let you write sleeker code, as you will be able to add your condition in the middle of the execution, thus not duplicating the code.

How to insert 2 post (submitted) values that begins with specific names to same table row, and loop for more same results?

How to loop 2 values from a submitted form that begins with specific names, insert it in a mysql table row and loop for more?
I have a post form with many input select and textareas, in a part of that form there are 2 fields (link, description) then i have a button which generate an extra line with the same fields but adding the number 1 2 3 in the name. So here how it looks like when i click to generate the new line of that 2 fields:
<label for="stack_input"><input id="stack_input" name="extravalue" value="" type="text"></label>
<label for="flow_input"><input id="flow_input" name="secondextravalue" value="" type="text"></label>
<label for="stack_input"><input id="stack_input" name="extravalue1" value="" type="text"></label>
<label for="flow_input"><input id="flow_input" name="secondextravalue1" value="" type="text"></label>
<label for="stack_input"><input id="stack_input" name="extravalue2" value="" type="text"></label>
<label for="flow_input"><input id="flow_input" name="secondextravalue2" value="" type="text"></label>
Now i post the form together with the rest inputs and textareas of the form, but i want those each 2 extra fields at a time to be added to a new database row, as a pair to be added on same row each time. For now i can make a foreach but i can add only 1 of the 2 fields at a time to a new table row.
Here the code to make this happen for 1 field. I say to php to take all post data that begins with "extravalue" which is the first of the two (pair generated) input fields, and each time that find a post value begins with "extravalue" to be inserted in the table. Because each time i generate a new line of that two input fields have as base name "extravalue" and "secondextravalue" respectively and each time add the number 1 2 3 etc at the end of the name. Here the code:
foreach($_POST as $key => $value)
{
if (strpos($key, 'extravalue') === 0)
{
mysql_query("INSERT INTO tablename VALUES ('','','$value','','','')")or die("ADD Error: ".mysql_error());
}
}
Now i want to take each pair of the generated input fields and insert in the database in same row.
So i want to do the following:
For each,
"extravalue" "secondextravalue"
"extravalue1" "secondextravalue1"
"extravalue2" "secondextravalue2"
mysql_query("INSERT INTO tablename VALUES ('','','$value','$value2','','')")or die("ADD Error: ".mysql_error());
mysql_query("INSERT INTO tablename VALUES ('','','$value','$value2','','')")or die("ADD Error: ".mysql_error());
mysql_query("INSERT INTO tablename VALUES ('','','$value','$value2','','')")or die("ADD Error: ".mysql_error());
In short i want to say to php that every time you find values that begin with "extravalue" and "secondextravalue" to insert them in the same table row, and then to loop to continue searching for the next pair of that two values which begins with the same names.
Instead of doing it like this, create the fieldnames as an array: name="extravalue[]"
THat will give you all extra values in an array in your $_POST, allowing you to loop through them at ease, and insert them easily too. Add a counter ($i++;) to the loop, so you can also get the second extra value at ease.

Categories