i'm working on this site that allows to students to book seats for training sessions by selectiong theme on a drop down list and clincking on a button. i created a javascript(ajax) script that contains a function which calls a php script that reduces the number of seats on my database.
But unfortunately it's not working... i need your help guys :
here's my javascript :
<select name="Branche" name="clock" id="clock" onchange="count()"></select>
<a onclick="count()" class="button">
<span class="user">Réserver une place</span>
</a>
<script>
function count(){
var place = document.getElementByTagName(clock);
var option = place.options[place.selectedIndex].id;
alert(option);
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "count.php?place=" + place,true);
xmlhttp.send(null);
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var reponse = xmlhttp.responseText;
if(reponse == "yes") {
alert("Votre place a été réservé");
} else {
alert("Vous êtes arrivé trop tard !");
}
}
}
}
</script>
and here's my php script :
try {
$db = new PDO('mysql:host=localhost;dbname=projet','root','',array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
} catch(Exception $e){
echo $e->getMessage();
die();
}
$nom = $_GET['place'];
$sq="SELECT place FROM formation WHERE nom='$nom'";
$re = $db->query($sq);
$i = $re->fetch(PDO::FETCH_ASSOC);
if($i > 0){
$sqq="UPDATE formation SET place = place - 1 WHERE nom='$nom'";
$res = $db->query($sqq);
echo 'yes';
} else {
echo 'no';
}
The first errors are in this line:
var place=document.getElementTagName(clock);
You need to find the element by it's id, not its tag name. Also click is an non-existing variable; you should use "clock" with quotes:
var place=document.getElementById("clock");
That way place will be the select element. But then later you use this in building the URL parameter:
xmlhttp.open("GET","count.php?place="+place,true);
But place is not the selected value; it is the select element, so that will not work right. Instead you should send the value you have in the option variable:
xmlhttp.open("GET","count.php?place="+option,true);
This is assuming that the value of option is correct. Without seeing the HTML and your database table content, this is impossible to say at this moment.
The PHP script has an error here:
$i = $re->fetch(PDO::FETCH_ASSOC);
if($i>0){
You use $i as if it is the selected value, but that is not true. fetch() returns an array with values, in this case an array with one value. The comparison as you have it will always return true, even if the selected place value is 0.
Furthermore you should alter your PHP script so you do not concatenate values into an SQL string, as it makes you vulnerable to SQL injection. Instead use prepared statements.
Also, your PHP script is not working well when there is a lot of concurrency. Imagine that there is one seat left and two make the PHP call at the same time, then both will see there is one place left before the other one has decreased the count, and both will get a "yes".
Instead you should first perform the update and check for availability within the update statement. Then check if the statement updated a record. If not, then there were no places left. As an update statement locks the record during the update, only one process can do it at a time.
Suggested PHP code after database connection is established:
$stmt = $db->prepare("UPDATE formation
SET place = place - 1
WHERE nom = ?
AND place > 0");
$stmt->execute(array($_GET['place']));
echo $stmt->rowCount() ? 'yes' : 'no';
Related
I have about 60 landing pages that use different phone numbers on them. I am using a combination of WordPress and Advanced Custom Fields to place the phone numbers on their respective pages.
I am being asked to show a <div> based on the landing page URL that will not only show the phone number assigned to that page, but, keep showing the <div> (and phone number) regardless of what page the user navigates to on the website.
I have found little to no support on how to make the <div> remain visible throughout the entire session until the user closes the window.
I am thinking that this will somehow revolve around a cookie and Dynamic Number Insertion but I have no real progress to speak of. Should this be done using PHP or JS? Does a plugin exist that would allow for this on WordPress? I'm open to all suggestions.
Please try this code. Like #John C mentioned, WP Engine doesn't recommend Cookie nor PHP Session for the sake of performance and security. This is pure JavaScript code, and I think this will solve your problem.
Code in your Post/Page template file:
<div id="phone-number"></div>
<?php if( get_field('phone_number') ): ?>
<script type="text/javascript">
let phone_number = "<?php the_field('phone_number'); ?>";
</script>
<?php endif; ?>
Code in your theme JavaScript file:
<script type="text/javascript">
// in the case of the div data is persistent on the same site
// let storage = localStorage;
// in the case of the div data is persistent in the same tab, but not in new tab
let storage = sessionStorage;
let key = "phone_number"; // storage key
var global_phone_number = storage.getItem(key);
// check if storage data is set before
if (null === global_phone_number) {
// if not set the data on page into storage
global_phone_number = phone_number ? phone_number : '';
storage.setItem(key, global_phone_number);
}
document.getElementById('phone-number').innerHTML = global_phone_number;
</script>
You should use PHP and capture the session.
(untested code warning)
add_action('wp_footer', 'dynamic_phone_div');
function dynamic_phone_div() {
session_start;
if(isset($_SESSION['phone_div']) ? $phone_div = $_SESSION['phone_div'] :
$phone_div = '';
if($phone_div != '') {
echo '<div class="that_div_thing">';
echo $phone_div;
echo '</div>';
} else {
$_SESSION['phone_div'] = 123456789;
echo '<div class="that_div_thing">';
echo '123456789';
echo '</div>';
}
}
This is only raw logic. I am not sure where your div is (header/footer/page) - depending on where it is you should either use a hook (header/footer) or code it into a template (page/post).
The session will be destroyed after the user closes the tab/window.
I would probably do this with client side session storage. Providing all pages open in the same tab, the value will remain for the session, then be removed.
PHP code (in your functions.php file?) would be something like this:
function phone_script() {
$params = array(
'phone_number' => null, // Insert logic for current number. Can stay null if this is running on a non-landing page
'is_landing_page' => false // Change to true/false based on is current page a landing one or not
);
$params = json_encode( $params );
echo <<< EOT
<script>
let settings = $params;
document.addEventListener("DOMContentLoaded", function() {
if( settings.is_landing_page ) {
window.sessionStorage.setItem( 'phone-number', settings.phone_number );
} else {
settings.phone_number = window.sessionStorage.getItem( 'phone-number' );
}
if( settings.phone_number ) {
let div = document.createElement('div');
div.classList.add('phone-div');
// or add inline style
// div.style.cssText = 'position:fixed'; //etc
// Some logic here to actually add the number and any other content to the div
div.innerHTML = `The Phone number is: ${settings.phone_number}`;
document.body.appendChild(div);
}
});
</script>
EOT;
}
add_action( 'wp_footer', 'phone_script');
Note that the EOT; line MUST have no leading or trailing spaces.
The above is untested.
I have a PHP page, where it has 12 individual form with individual form ID, and individual checkbox, dropdown etc. Like this pic:
Now, forms have Update Zone, which basically fetches, Name, Enable check or not, Time, Dim and sends it to PHP file for processing.
Code for 3 Zones
So, each form has hard coded URL LoopInfo.php?id=1 where id changes from 1 to 12, so the LoopInfo.php knows which Zone's update button is clicked and grabs post variables from that paticular zone
PHP Processing and updating XML
$id = $_GET['id'];
// echo "ID - ".$id.'<br>';
if($id > 0 && $id < 13)
{
// ZName - 1-12
// Zmode - 1-12
// ZTime - 1-12
// ZDim - 1-12
$radio = $_POST['radio'];
if($radio == 1)
{
$radio = 0;
}
// echo "Radio - ".$radio.'<br>';
$zn = "zname".$id;
$znam = $_POST["$zn"];
// echo "Name - ".$znam.'<br>';
$et = "EnTim".$id;
$entim = $_POST["$et"];
// echo "Timer - ".$entim.'<br>';
$ot = "OnTim".$id;
$ontim = $_POST["$ot"];
// echo "On Time - ".$ontim.'<br>';
$oft = "OfTim".$id;
$oftim = $_POST["$oft"];
// echo "Off Time - ".$oftim.'<br>';
$ed = "EnDim".$id;
$endim = $_POST["$ed"];
// echo "Dim - ".$endim.'<br>';
$d = "Dim".$id;
$dim = $_POST["$d"];
// echo "Dim Per - ".$dim.'<br>';
$bin = $radio.$endim."00000".$entim;
// echo "Binary - ".$bin.'<br>';
$loopval = bindec($bin);
// echo "Loop Val - ".$loopval.'<br>';
// print_r($_POST);
// die;
$hunza=simplexml_load_file('LoopInfo.xml');
if($hunza)
{
$zmode='Z'.$id.'Mode';
$hunza->$zmode=$loopval;
if($znam == '')
{
}
else
{
$name='Zname'.$id;
$hunza->$name=$znam;
}
if($entim == 1)
{
$ontime='Z'.$id.'TimeOn';
$hunza->$ontime=$ontim;
$oftime='Z'.$id.'TimeOff';
$hunza->$oftime=$oftim;
}
if($endim == 1)
{
$dimval='Z'.$id.'Dim';
$hunza->$dimval=$dim;
}
$hunza->asXML('LoopInfo.xml');
// echo "<script>console.log('File Updated' );</script>";
header("Location: index.php");
}
else
{
echo "Error Loading File";
echo "<script>console.log('Error Load File' );</script>";
}
}
So basically, each one is a form, when pressed on Update zone, grabs all form data, gives it to LoopInfo.php and LoopInfo.php updates those values to XML in their corresponding tags.
Target: What I am trying to achieve is that, is there any way, where I can update zone without the page being reloaded i.e., using Ajax Javascript. So Javascript grabs all value on update from form, creates Ajax request and post to the same PHP file for processing. I tried Googling "Javascript Ajax Multiple Form send data in one PHP" with no results. Is it possible to get a generic function which when invokes get the form Id and get to know this is ID 1 and created URL LoopInfo.php?id=1 and sends all form data along with this URL request.
The issue is cause of event propagation. Check your event - is it cause of multiple times form is submitting.
To avoid this place event.stopImmediatePropagation();
1 - addlist.php
In this page, I've only a text input. I can scan a barcode, that gives me a text result in the input (ex: "banana").
2 - validaiton.php
This page connect my SQL DataBase and checks if value put in the textbox of my other page (addlist.php) is in my DB.
3 - addlist.php
If the value exists in DB, set a message and put the value in a list. If not, set an other message and do nothing.
/!\ For information: I've a barcode scanner, so I couldn't press a button or to display value in the list. So I chose to set a timer and every 800ms, it takes value and clears. With that, I can scan a value, display and clear it dynamically without touch my keyboard. /!\
addlist.php
<input type="text" id="IDAlim">
<div class="col-md-6">
<section>
<li id="demo"></li>
</section>
</div>
<script src="js\jquery.js"></script>
<script type="text/javascript">
var list = document.getElementById('demo');
$(document).ready(function()
{
putIn();
function putIn() {
var focused = $(':focus');
$("#IDAlim").focus();
focused.focus();
var IDAlim = document.getElementById('IDAlim').value;
var quantite = "1";
var entry = document.createElement('li');
if(IDAlim != "")
{
$.post('validation.php',{IDAlim: $('#IDAlim').val()}, function(data){
if(data.exists){
alert('Is in DB');
$("#demo").append('<li class="list-group-item">'+IDAlim+' '+quantite+'x'+'</li>');
}else{
alert('Re-Scan please');
}
}, 'JSON');
setTimeout(function(){ putIn() }, 800);
$("#IDAlim").val('');
}
else
{
entry.appendChild(document.createTextNode(IDAlim));
setTimeout(function(){ putIn() }, 800);
$("#IDAlim").val('');
}
}
})
</script>
validation.php
<?php
//set the headers to be a json string
header('content-type: text/json');
//no need to continue if there is no value in the POST IDAlim
if(!isset($_POST['IDAlim']))
echo json_encode(array('non' => 'POSTError'));
//Variable for db connection
$host="localhost";
$user="root";
$pass="";
$dbname="aliments";
try
{
$dbcon = new PDO("mysql:host={$host};dbname={$dbname}",$user,$pass, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
$query = $dbcon->prepare('SELECT nom FROM tblaliments WHERE nom = :nomAlim');
$query->bindParam(':nomAlim', $_POST['IDAlim']);
$query->execute();
//return the json object containing the result of if the IDAlim exists or not. The $.post in my jquery will access it.
echo json_encode(array('exists' => $query->rowCount()));
}
catch (Exception $e)
{
echo json_encode(array('non' => 'PDOError'));
}
?>
I would update my quantity when I scan a same value, in my case, I put pending "1" for "quantite" (=quantity in french) to show you an example.
That's my problem
What I would like to have
Thank you in advance to help me and sorry for my bad english (I speak french)
I want to get the refreshed option values from database only when i click on select box.
Suppose two waiter open the same order panel page at same time. Then table no:2 is shown as free in both of the panel.
Now a waiter booked table no:2. Then another waiter when clicked on the select box, he will not get the table no:2 in the options.
<select name="table_id" class="form-control tablename">
<option disabled="disabled">Select Table</option>
<?php $result = mysql_query("select * from rtable r
inner join table_status as ts
on ts.status_id=r.status_id
where ts.status!='Booked'
order by r.table_id desc")or die(mysql_error());
while ($row=mysql_fetch_array($result)){ ?>
<option value="<?php echo $row['table_id'];?>"><?php echo $row['table_name']; ?></option>
<?php } ?>
</select>
table_status
rtable
Create function in php to generate options ( sending html is not good practice but I am adjusting to this example). In this particular example i suggest to create functions.php file and there add printSelectOptions function declaration:
function printSelectOptions(){
$result = mysql_query("select * from rtable r
inner join table_status as ts
on ts.status_id=r.status_id
where ts.status!='Booked'
order by r.table_id desc")or die(mysql_error());
echo "<option disabled='disabled'>Select Table</option>";
while ($row=mysql_fetch_array($result)){
echo "<option value=".$row['table_id'].">".$row['table_name']."</option>";
}
}
Above function prints all html options for select.
Use it function in generating select ( remember that functions.php should be included in any file with usage of printSelectOptions ):
<?php
//db connection code
require_once("functions.php");//here we add our function to be available in this file
?>
<select name="table_id" class="form-control tablename">
<?php printSelectOptions() ?>
</select>
In frontend bind Your select ( javascript code ):
document.addEventListener("DOMContentLoaded", function(event) {
var select=document.querySelector("select"); //this is pure selector gets first select on page
//function sends ajax and refresh options of select
function refreshOptions(){
//send ajax request
select.innerHTML="<option>Loading..</option>"; //loading info
var xmlhttp=new XMLHttpRequest();
xmlhttp.open("GET", 'yourSecondPHPScript.php');//here example url where we get updated options
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
if(xmlhttp.status == 200){
select.innerHTML = xmlhttp.responseText;//set new options
}else{
console.log('Error: ' + xmlhttp.statusText )
select.innerHTML="<option>Connection problem</option>";
}
}
}
xmlhttp.send();
};
//bind our select
select.addEventListener("focus",function(){
refreshOptions();
});
});
Last create example yourSecondPHPScript.php and in it use function:
<?php
//db connection code
require_once("functions.php");//here we add our function to be available in this file
printSelectOptions();//outputs options
To be sure that users will not take the same table besides checking in focus check it again in some submit of order form. So if table was taken refresh select ( by ajax using refreshOptions() ) and show info that this table was taken.
Last thing is to secure it on server side, create some check function in php ( PHP CODE ):
function tableCanBeTaken($optionId){
//this code adds **and** to query with id to check but optionId should be validate before using in query
$result = mysql_query("select * from rtable r
inner join table_status as ts
on ts.status_id=r.status_id
where ts.status!='Booked'
and ts.table_id=$optionId ")or die(mysql_error());
return mysql_fetch_array($result); //if row exists - will be false if not exists row with table_id==$optionId and not booked
}
}
Then use it (PHP CODE ):
if (tableCanBeTaken($youOptionId)){
//here code for taking option
}else{
//here option is taken
}
Have the ajax call in the focus event of the select box.In the success of the call, append the data(available tables) to the select input.Until then, leave the select box options as 'Loading. Hope this helps!
#Maciej Sikora
problem is fixed. printSelectOptions() function can not be called from another file like yourSecondPHPScript.
And also needs to remove the back-slash from url.
xmlhttp.open("GET", 'yourSecondPHPScript.php');
i just paste the same code in yourSecondPHPScript.php like below
<?php
include("connect.php");
$result = mysql_query("select * from rtable r inner join table_status as ts on ts.status_id=r.status_id where ts.status!='Booked' order by r.table_id desc")or die(mysql_error());
echo "<option disabled='disabled'>Select Table</option>";
while ($row=mysql_fetch_array($result))
{
echo "<option value=".$row['table_id'].">".$row['table_name']."</option>";
}
?>
if($rx==$_SESSION['randomx'] and $ry==$_SESSION['randomy']){
echo "Cestitam, zadeli ste pravilno celico! rabili ste samo:".$_SESSION['poskus'];
}
else{
$razdalija=sqrt(($rx-$_SESSION['randomx'])*($rx-$_SESSION['randomx'])+($ry-$_SESSION['randomy'])*($ry-$_SESSION['randomy']));
echo $_SESSION["poskus"].". Zgresili ste za: ".round($razdalija);
$_SESSION["poskus"]++;
}
Both echos return a sentense how can i differenciete those two sentences?
In the ajax function i want to compare which one came back so i can set the background color.
I would return json instead and use the key to differentiate between the possible outputs.
For example:
$arr = array();
if ($rx==$_SESSION['randomx'] and $ry==$_SESSION['randomy']) {
$arr['good'] = "Cestitam, zadeli ste pravilno celico! rabili ste samo:".$_SESSION['poskus'];
} else {
$razdalija=sqrt(($rx-$_SESSION['randomx'])*($rx-$_SESSION['randomx'])+($ry-$_SESSION['randomy'])*($ry-$_SESSION['randomy']));
$arr['bad'] = $_SESSION["poskus"].". Zgresili ste za: ".round($razdalija);
$_SESSION["poskus"]++;
}
echo json_encode($arr);
Now you can check in javascript which one is set and do what you want to do.
You could also return an additional value that determines the status and a text value for the text, plenty of possibilities. The key is sending back structured data instead of just a text string.