For my bookshop, I started to built a cashdesk script. This is a very simple form, with an ajax dynamic search. This is a script for a local PC, so the script will not be publish on the web.
When I scan the EAN code, I've my form fill with title, author, editor and price. The book is ready to add in the basket.
Now I'm trying to introduce Json in this script : but I don't understand how to get the values of the mysql query in the script, and put them in the correct fields of my cashdesk form.
I've tested the Mysql query and the Json.
The query
<?php
header('Content-Type: text/html; charset=ISO-8859-1');
include('connexion.php');
$connect_db = connect();
$i = 0;
$tmp = array();
$fetch = mysql_query("SELECT jos_vm_product.product_id,product_name,product_author,product_editor,jos_vm_product_price.product_price FROM jos_vm_product INNER JOIN jos_vm_product_price ON (jos_vm_product.product_id = jos_vm_product_price.product_id) WHERE product_EAN = '$_POST[EAN]'");
while ($row = mysql_fetch_array($fetch, MYSQL_ASSOC)) {
$tmp[$i] = $row;
}
echo json_encode($tmp);
close();
?>
A json exemple :
[{"product_id":"7097","product_name":"Paix pour tous - Livre audio","product_author":"Wayne W. Dyer","product_editor":"Ada","product_price":"20.28"}]
The ajax script
var xhr = null;
function getXhr()
{
if(window.XMLHttpRequest) xhr = new XMLHttpRequest();
else if(window.ActiveXObject)
{
try
{
xhr = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e)
{
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
}
else
{
alert("Not Working");
xhr = false;
}
}
function ajaxEAN()
{
getXhr();
xhr.onreadystatechange = function()
{
if(xhr.readyState == 4 && xhr.status == 200)
{
var data = '{"product_id": "product_id", "product_name":"product_name", "product_author":"product_author", "product_editor":"product_editor", "product_price":"product_price"}';
oData = JSON.parse( data);
for( var i in oData){
document.getElementById( i).value = oData[i];
}
}
}
xhr.open("POST",'ajaxrecupaddr.php',true);
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
EAN = document.getElementById("EAN").value;
xhr.send("EAN="+EAN);
}
Thanks for any help !
As far as understand, you simply can't take a JSON from response. If so, than you simply should do:
xhr.onreadystatechange = function()
{
if(xhr.readyState == 4 && xhr.status == 200) {
oData = JSON.parse(xhr.responseText);
for(var i = 0; i < oData.length; i++) {
for( var key in oData[i]){
document.getElementById(key).value = oData[i][key];
}
}
}
There, xhr.responseText will return a string with JSON received from server.
Also, few notes:
Instead of
header('Content-Type: text/html; charset=ISO-8859-1');
you should better use:
header('Content-Type: application/json;');
Also, in line below you are opened to SQL Injections:
$fetch = mysql_query("SELECT jos_vm_product.product_id,product_name,product_author,product_editor,jos_vm_product_price.product_price FROM jos_vm_product INNER JOIN jos_vm_product_price ON (jos_vm_product.product_id = jos_vm_product_price.product_id) WHERE product_EAN = '$_POST[EAN]'");
instead of simply doing WHERE product_EAN = '$_POST[EAN]' you should do, at least, WHERE product_EAN = '".mysql_real_esape_string($_POST["EAN"]) . "':
$fetch = mysql_query("SELECT jos_vm_product.product_id,product_name,product_author,product_editor,jos_vm_product_price.product_price FROM jos_vm_product INNER JOIN jos_vm_product_price ON (jos_vm_product.product_id = jos_vm_product_price.product_id) WHERE product_EAN = '".mysql_real_esape_string($_POST["EAN"]) . "'");
See more about mysql_real_escape_string. It will correctly escape all potentially dangerous symbols and will save you from errors when you have ' symbol in EAN. Also, read warning shown on a page linked above. You should better change your database extension as MySQL extension is deprecated.
Related
I am having some issues with PHP, sqlite3 and HTML.
What I want is a modal in HTML, that gets its content (header, body, footer) from a sqlite3 database. To access the database I use PHP. The user can then edit the content in the modal and the updated text gets send to the database.
Now this works for plain text (e.g. 'Hello world'). But it fails as soon as I include special characters (e.g. < > &). There is no error message on the console, so I don't really know what to fix. I tried SQLite3::escapeString but that did not change anything.
As a potential improvement I would also be ok with saving the complete html body into the sqlite3 database, instead of only the innerHTML, then I could do some nicer layouts.
I attach some code that I hope adds clarity below. For simplicity I do not include the header and footer part as it is the same as the body part.
This is the HTML code for the modal:
<!-- Body content -->
<div class="modal-body">
<input id="editBtn" type="button" , class="editBtn", value="edit" onclick="editFunction();" />
<p id="modal-body-id"></p>
</div>
This is the javascript that edits the content
function editFunction() {
var editables_body = document.querySelectorAll('#modal-body-id');
if (!editables_body[0].isContentEditable) {
editables_body[0].contentEditable = 'true';
} else {
// Disable Editing
editables_body[0].contentEditable = 'false';
// Save the data to database
for (var i = 0; i < editables_body.length; i++) {
// console.log(editables_body[0].innerHTML)
sendData(modal_id)
}
}
Javascript to send the data to the database
function sendData(id){
var body = document.getElementById("modal-body-id").innerHTML;
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("POST", "send2db.php");
xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlhttp.send("id="+id+"&header="+header+"&body="+body+"&footer="+footer);
}
Javascript to read the data from the database
function get_body(id) {
var body = document.getElementById("modal-body-id");
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("POST", "get_from_db.php");
xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlhttp.send("id="+id+"&type=body");
xmlhttp.onreadystatechange = function() {
if (this.readyState === 4 && this.status === 200) {
// body.innerHTML = this.responseText;
body.innerHTML = xmlhttp.responseText;
} else {
body.innerHTML = "Loading...";
};
}
}
And finally the php scripts to send and read the database
send2db.php
<?php
// Database name
$database_name = "description.db";
// Database Connection
$db = new SQLite3($database_name);
// Get information
$id = $_POST['id'];
$header = SQLite3::escapeString($_POST["header"]);
$body = SQLite3::escapeString($_POST["body"]);
$footer = SQLite3::escapeString($_POST["footer"]);
// Create Table of file descriptions into Database if not exists
$db->exec("CREATE TABLE IF NOT EXISTS file_desc(id TEXT, header TEXT, body TEXT, footer TEXT)");
$res = $db->query("SELECT * FROM file_desc WHERE id = '$id' ");
$row = $res->fetchArray();
$db->exec("CREATE UNIQUE INDEX IF NOT EXISTS unique_id ON file_desc (id)");
$db->exec("REPLACE INTO file_desc (id, header, body, footer) VALUES('$id', '$header', '$body', '$footer') ");
// $db->exec("REPLACE INTO file_desc (id, '$type') VALUES('$id', '$body') ");
?>
get_from_db.php
<?php
// Database name
$database_name = "description.db";
// Database Connection
$db = new SQLite3($database_name);
// Create empty database if none exists
$db->exec("CREATE TABLE IF NOT EXISTS file_desc(id TEXT, header TEXT, body TEXT, footer TEXT)");
// Get information
$id = $_POST['id'];
// Get information
$type = $_POST['type'];
$res = $db->query("SELECT * FROM file_desc WHERE id = '$id' ");
while ($row = $res->fetchArray()) {
echo "{$row[$type]} \n";
}
// $row = $res->fetchArray();
// return "{$row['body']}";
?>
Thank you very much for your help!
I was able to solve the problem.
I encode the data package to be send using encodeURIComponent.
I attach the same functions I mentioned above in their new working version.
It is a lengthy answer but I hope someone with a similar problem finds it helpful.
javascript to edit content of the modal:
// Edit content of modal
function editFunction() {
// Get editables
var editables_body = document.querySelectorAll('#modal-body-id');
// Edit body
if (!editables_body[0].isContentEditable) {
editables_body[0].contentEditable = 'true';
} else {
// Disable Editing
editables_body[0].contentEditable = 'false';
sendData(modal_id);
}
};
The javascript to send to the database. This contains the new function to encode the data:
function sendData(id){
//Body
var body = document.getElementById("modal-body-id"); // Get the body
body.innerHTML = htmlEncode(body.innerHTML); // Encode HTML characters
body = encodeURIComponent(String(body.outerHTML)); //Encode for sending to database
// Open a new request
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("POST", "send2db.php");
xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
// Send the request to the php script that handles the database
xmlhttp.send("id="+id+"&body="+body);
};
javascript to read from the database. This contains the new function to decode the data.
function get_body(id) {
var body = document.getElementById("modal-body-id");
var bodyDiv = body.parentNode;
var xmlhttp = new XMLHttpRequest();
var response;
xmlhttp.open("POST", "get_from_db.php");
xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlhttp.send("id="+id+"&type=body");
// Create an empty paragraph element
// without an ID, any attributes, or any content
var newBody = document.createElement("p");
// Request from database
xmlhttp.onreadystatechange = function() {
if (this.readyState === 4 && this.status === 200) {
response = htmlDecode(decodeURIComponent(xmlhttp.response));
// Fill the new body with the response from the database
newBody.innerHTML = response.innerText;
newBody.id = 'modal-body-id';
// Replace body with new body from the database
bodyDiv.replaceChild(newBody,body)
};
}
}
The php scripts to send and read from the data base:
<?php
// Database name
$database_name = "description.db";
// Database Connection
$db = new SQLite3($database_name);
// Get information
$id = $_POST['id'];
$header = ($_POST["header"]);
$body = ($_POST['body']);
$footer = ($_POST["footer"]);
// Create Table of file descriptions into Database if not exists
$db->exec("CREATE TABLE IF NOT EXISTS file_desc(id TEXT, header BLOB, body BLOB, footer BLOB)");
// Send to database
$db->exec("CREATE UNIQUE INDEX IF NOT EXISTS unique_id ON file_desc (id)");
$db->exec("REPLACE INTO file_desc (id, header, body, footer) VALUES('$id', '$header', '$body', '$footer') ");
?>
<?php
// Database name
$database_name = "description.db";
// Database Connection
$db = new SQLite3($database_name);
// Create empty database if none exists
$db->exec("CREATE TABLE IF NOT EXISTS file_desc(id TEXT, header TEXT, body TEXT, footer TEXT)");
// Get information
$id = $_POST['id'];
// Get information
$type = $_POST['type'];
// Request from database
$res = $db->query("SELECT * FROM file_desc WHERE id = '$id' ");
// Read from database
while ($row = $res->fetchArray()) {
// echo "{$row[$type]} \n";
echo $row[$type];
}
?>
And finally the two new functions that help en/decoding the content so it can be send to the database and read from the database:
function htmlDecode(input){
var e = document.createElement('p');
e.innerHTML = input;
return e
}
function htmlEncode(input){
var e = input.replace(/</g,"<").replace(/>/g,">");
return e
}
I am currently building an "admin" section where the information shown on the main site can be added to, updated and deleted using this one page.
All of my scripts function as intended, information is added to the database, rows are updated and deleted with no errors in 99.9% of cases.
The database is set up with 3 columns TITLE, DESCRIPTION and Image and when updating any of the rows I use the value in TITLE as my reference for WHERE statements.
However, any title containing an '&' symbol are downloaded fine and insert into my HTML as intended, however when being sent to my update script they are sent as &. This then doesn't register correctly with the update script and then it fails to update. I know '&' is converted to '&' when escaped but cannot understand why there is a second 'amp;' being sent?
Can anyone shed some light on this / point me to appropriate documentation to solve this issue?
Javscript Function(dbtable and titler are variables that decide the table to insert into )
function updating(indexno) {
var current = document.getElementById('title'+indexno).innerHTML;
var newtitle = document.getElementById('titlelink'+indexno).value;
var newdesc = document.getElementById('desclink'+indexno).value;
var newimage = document.getElementById('imagelink'+indexno).value;
if(newtitle == ""){
newtitle = document.getElementById('title'+indexno).innerHTML;
};
if(newdesc == ""){
newdesc = document.getElementById('description'+indexno).innerHTML;
};
if(newimage == ""){
newimage = document.getElementById('image'+indexno).innerHTML;
}
var request = "updatingdb.php?newtitle="+escape(newtitle)+"&newdesc="+escape(newdesc)+"&newimage="+escape(newimage)+"¤ttitle="+escape(current)+"&thetable="+escape(dbtable);
var xhr = new XMLHttpRequest();
xhr.open("GET", request);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
console.log(xhr.responseText);
}
};
xhr.send(null);
thetester(dbtable,titler);
}
PHP Script
$thetable = htmlentities($_GET['thetable']);
$currenttitle = htmlentities($_GET['currenttitle']);
$newtitle = htmlentities($_GET['newtitle']);
$newdesc = htmlentities($_GET['newdesc']);
$newimage = htmlentities($_GET['newimage']);
$db = mysqli_connect($servername, $user, $password);
if (!$db)
{
echo"NO CONNECTION AVAILABLE";
exit();
}
mysqli_select_db ($db, "testing");
$query ="UPDATE `$thetable` SET `TITLE`= '$newtitle', `DESCRIPTION` ='$newdesc', `IMAGE` = '$newimage' WHERE `TITLE` = '$currenttitle'";
echo$query;
$results = mysqli_query($db, $query);
if(!$results)
{
echo"not working";
exit();
}
echo"updated";
This happens because you use htmlentities(), which will just see the & character and therefore makes an entity out of it. You could either remove htmlentities from the desired input field or do something like this:
$value = str_replace('&', '&', htmlentities($value));
or (better imo)
$value = htmlentities(html_entity_decode($value));
I am trying to pass data back to the server and then use the reply to update the browser page.
My code for a SELECT input is as follows;
<select id ="MatchCaptain" name="MatchCaptain" onchange="findTeleNo(this.value)"
<?php
$MC = $_SESSION["MatchCapt"];
player_load($MC);
?>
>
</select>
The script code is as follows;
<script>
function findTeleNo(that){
alert("I am an alert box!" + that);
var xhttp;
if (window.XMLHttpRequest) {
// code for modern browsers
xhttp = new XMLHttpRequest();
} else {
// code for old IE browsers
xhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("TeleNo").value = this.responseText;
}
}
};
xhttp.open("GET", "findTeleNo.php?q=" + that, true);
xhttp.send();
</script>
The purpose of the script is to take the value selected in the dropdown (variable "that") and submit it to the php file as variable q.
And the PHP file is as follows;
<?php
$MatchCaptain = $_REQUEST["q"];
$teleNo = "";
$db_handle = mysqli_connect(DB_SERVER, DB_USER, DB_PASS );
$database = "matchmanagementDB";
$db_found = mysqli_select_db($db_handle, $database);
if ($db_found) {
$SQL = "SELECT * FROM `playerstb` ORDER BY `Surname` ASC, `FirstName` ASC";
$result = mysqli_query($db_handle, $SQL);
$ufullName = split_name($MatchCaptain);
while ( $db_field = mysqli_fetch_assoc($result) ) {
$uName = $db_field['FirstName'];
$uName = trim($uName);
$Surname = $db_field['Surname'];
$Surname = trim($Surname);
$fullName = $uName." ".$Surname;
if ($fullName == $ufullName )
{
$teleNo = $db_field['TeleNo'];
break;
}
}
}
echo $teleNo;
function split_name($name) {
$name = trim($name);
$last_name = (strpos($name, ' ') === false) ? '' : preg_replace('#.*\s([\w-]*)$#', '$1', $name);
$first_name = trim( preg_replace('#'.$last_name.'#', '', $name ) );
$ufullName = $first_name." ".$last_name;
return $ufullName;
}
?>
The php file requests the q variable from the url and makes it $MatchCaptain.
This will be a name like Joe Bloggs. The next piece of code connects to a MySQL table to extract players first names surnames and telephone numbers. The first names and surnames are concatenated to form the fullname which is compared with the $MatchCaptainWhen a match is made the variable $teleNo is set to the Telephone Number of that player. The echo statement rerurns the value to the script.
The field id I am trying to update is;
<p><b>Telephone Number: </b> <span id="TeleNo"> <?php echo $_SESSION["TeleNo"]; ?></span></p>
The alert in the script function findTeleNo shows me that I have entered the function but nothing happens after that.
Any help as to how I get this working would be grateful.
I have changed my script to
<script>
function findTeleNo(that){
var xhttp;
if (window.XMLHttpRequest) {
// code for modern browsers
xhttp = new XMLHttpRequest();
} else {
// code for old IE browsers
xhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xhttp.open("GET", "findTeleNo.php?q=" + encodeURIComponent(that), true);
xhttp.send();
xhttp.onreadystatechange = function() {
if (xhttp.readyState === 4) {
if (xhttp.status === 200) {
// OK
alert('response:'+xhttp.responseText);
document.getElementById("TeleNo").innerHTML = this.responseText;
// here you can use the result (cli.responseText)
} else {
// not OK
alert('failure!');
}
}
};
};
</script>
The response shown by alert('response:'+xhttp.responseText); is correct and the line of code
document.getElementById("TeleNo").innerHTML = this.responseText;
does print the response to the web page.
Page1 has an input form. I validate the input field with a JavaScript:
<input type="text" name="frmBrand" size="50" onkeyup="BrandCheck();" maxlength="100" id="frmBrand" />
<span id="frmBrand_Status">Enter existing or new brand</span>
In the JavaScript I then call a PHP script:
function BrandCheck()
{
var jsBrandName = document.forms["AddPolish"]["frmBrand"].value;
if (jsBrandName !==null || jsBrandName !== "")
{
document.getElementById("frmBrand_Status").textContent = jsBrandName
// alert(jsBrandName);
var xmlhttp = new XMLHttpRequest();
var url = "CheckBrand.php";
var vars = "jsBrandName="+jsBrandName;
xmlhttp.open("POST",url,true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.onreadystatechange = function()
{
if(xmlhttp.readyState == 4 && xmlhttp.status == 200)
{
var return_data = xmlhttp.responseText;
document.getElementById("frmBrand_Status").innerHTML = return_data;
}
}
xmlhttp.send(vars);
document.getElementById("frmBrand_Status").innerHTML = "processing.....";
}
}
So far so good. I do get results from the CheckBrand.php because it changes the frmBrand_Status. But I can't get any database results from the PHP page.
<?php
if(mysqli_connect_errno()) { //if connection database fails
echo("Connection not established ");
}
//by now we have connection to the database
else
{
if(isset($_POST['jsBrandName']))
{ //if we get the name succesfully
$jsBrandName = $_POST['jsBrandName'];
$dbBrandName = mysql_real_escape_string($jsBrandName);
if (!empty($dbBrandName))
{
$dbBrandName = $dbBrandName . "%";
$sqlQuery = "SELECT `BrandName` FROM `Brand` WHERE `BrandName` like '$dbBrandName' ORDER BY `BrandName`";
$result = mysqli_query($con, $sqlQuery);
$NumRows = mysqli_num_rows($result);
// $BrandName_result = mysql_fetch_row($BrandName_query);
echo "Result " . $dbBrandName . " ----- ". $jsBrandName . "Number rows " .$NumRows. " BrandName = " .$result. " SQL " .$sqlQuery;
if( $BrandName_result = mysql_fetch_row($BrandName_query))
{
While ($BrandName_result = mysql_fetch_row($BrandName_query))
{
echo "Brand = " .$BrandName_result[0];
}
}
}
else
{
echo "dbBrandName = empty" . $dbBrandName;
}
}
}
?>
When doing this, the html page shows the constant change of the normal variables. For example when the input field holds "Clu" I get the following output the span ID frmBrand_Status:
Result Clu% ----- CluNumber rows BrandName = SQL SELECT `BrandName` FROM `Brand` WHERE `BrandName` like 'Clu%' ORDER BY `BrandName`
Which looks good as the brandname gets the % appended, but the Number of rows is not shown (empty field?), the SQL Query is shown and looks good, but I don't get any results.
And the if( $BrandName_result = mysql_fetch_row($BrandName_query)) section will not be reached, so there definitely is something going wrong in calling the query.
When I run that same query through PHPMyAdmin, i do get the result I expect, which is 1 row with a brandname.
I'm using firebug to try and troubleshoot the SQL Query, but I can't find where I can check this and I probably can't since PHP is serverside. correct? But how should I then trouble shoot this?
Found what was wrong.
The $con string I was using to open the database was no longer available. On other pages in the site, the $con is available, I load the database using an include script on my index page. But it seems that the variable gets lost when it is called through the XMLHttpRequest(). Which is logical now I think of it, since this can also be a call to a remote server. So my CheckBrand.php page was just missing the $con var to connect to the database.
I have this javascript file that is calling a php file to return a JSON string. Chrome dev tools is throwing the error at line 10 in the javascript code. I know the error relates to a missing bracket but for the life of my and 3 other people who have looked at it the syntax is correct.
var request = new XMLHttpRequest();
var listings = [];
var json;
var url = "getListing.php";
request.open("GET", url, true);
request.send();
request.onreadystatechange = function(e)
{
if(request.readyState == 4){
json = JSON.parse(request.responseText);
for(var x = 0; x < json.length; x++){
var list = new listingInfo();
list.category = json[x].category;
list.date = json[x].dateListed;
list.description = json[x].description;
list.id = json[x].listingID;
list.title = json[x].title;
list.userID = json[x].userID;
listings.push(list);
}
}
console.log(listings);
}
here is the php file
<?php
session_start();
$con = mysql_connect("localhost", "listAdmin", "hermes");
if(!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("GregsList", $con)
or die("Unable to select database:" . mysql_error());
$result = mysql_query("SELECT * FROM Listings WHERE userID = '$_SESSION[userID]' ORDER BY dateListed DESC");
#converts to json
$rows = array();
while($r = mysql_fetch_assoc($result))
{
$rows[] = $r;
}
#If you want to see if correct json is printing use ---> print json_encode($rows);
return json_encode($rows);
?>
request.readyState == 4 is not enough you should add request.status== 200
In your php script replace return json_encode($rows); with print json_encode($rows);