How can I access this variable in Google Maps API? - javascript

I have a google maps web application for a game where the user will click a google map marker, make a selection in the window that pops up and click submit. It uses AJAX to update the database with information selected by the user. The database is pre-populated with names of the markers and GPS coordinates, which are loaded. The markers are also placed accordingly upon load via XML.
I'm having trouble updating one row in my DB called quest with the user selected information when it's submitted. Currently, a user can select a marker and submit a quest, but it won't update the DB at all. I'm unsure on the correct WHERE statement to use. Here's my current SQL statement, I'm attempting to update a row called quest.
mysqli_query($con, "UPDATE markers SET quest= '$questName' WHERE markerName = '$markerName'");
This is what happens when the submit button is pressed.
if (document.getElementById("questType").value ==
"quest1") { //if quest1 is selected upon submission
alert("quest1");
var markerName;
var questName = "Quest 1";
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "ajax.php?questName=" + questName + "&markerName=" + markerName, true);
xmlhttp.send(); //Sending the request to the server
ajax.php
<?php
include("connect.php");
require("call2.php");
$markerName = mysqli_real_escape_string($con, $_GET['markerName']);
$questName = mysqli_real_escape_string($con, $_GET['questName']);
$stmt = $con->prepare("UPDATE markers SET quest = $questName WHERE markerName = $markerName");
$stmt->bind_param($questName, $markerName);
$stmt->execute();
$stmt->close();
?>
Here is my relevant call file as well.
$dom = new DOMDocument("1.0");
$node = $dom->createElement("markers");
$parnode = $dom->appendChild($node);
include('connect.php');
$query = "SELECT * FROM markers WHERE 1"; // Select all the rows in the markers table
$result = mysqli_query($con, $query);
if (!$result) {
die('Invalid query: ' . mysqli_error($con));
}
// Iterate through the rows, adding XML nodes for each
while ($row = mysqli_fetch_assoc($result)) {
global $dom, $node, $parnode;
$node = $dom->createElement("marker");
$newnode = $parnode->appendChild($node);
$newnode->setAttribute("markerName",
$row['markerName']);
$newnode->setAttribute("quest", $row['quest']);
$newnode->setAttribute("lat", $row['lat']);
$newnode->setAttribute("longg", $row['longg']);
}
header("Content-type: text/xml");
echo $dom->saveXML();
Sorry if this is a lot, I think the problem is i'm not assigning a value to markerName. I don't get any errors, however when I hover over the ajaxphp in the network tab on chrome it looks like it's getting the questName but markerName remains undefined.
Here's where it's loading things in:
downloadUrl("call2.php", function(data) {
var xml = data.responseXML;
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var name = markers[i].getAttribute("markerName"); //<------ here's where it's getting markerName
// var address = markers[i].getAttribute("address");
var type = markers[i].getAttribute("type");
var point = new google.maps.LatLng(
parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("longg")));
var icon = customLabel[type] || {};
var marker = new google.maps.Marker({
map: map,
position: point,
icon: icon.icon,
shadow: icon.shadow
});
bindInfoWindow(marker, map, infoWindow, html);
}
});
I think I need to figure out a way to access name, but I'm unsure how to when it's local to the function which downloads the XML file.
connect.php
<?php
$con = mysqli_connect("localhost", "root", "", "pokestop-map");
?>

First of all, I think in some cases your Database Connection Credentials could be leaked if your Database is down and somebody is requesting ajax.php. If you want to use code in an production environment you should never leak errors to the client. Also I'm not sure if you're trying to add the Params to your Query through PHP's ability to evaluate variables in Strings, if so that is very unsecure and I would recommend you to read about Prepared Statements. Also I would recommend you to use PDO's (http://php.net/manual/de/book.pdo.php) instead of MySQLi but that's just a sidenote. I think the Problem here is that you don't bind your value to the Query. It's a long time ago that i've used MySQLi but I think you could do something like:
$stmt = $mysqli->prepare("UPDATE markers SET quest = ? WHERE markerName = ?");
$stmt->bind_param($questName, $markerName);
$stmt->execute();
$stmt->close();
Edit:
I would recommend you to look at ORM libraries which allow you to Map the Rows in a table to an object in PHP. There are a few of them out there like Doctrine or Idiorm. Working with Objects is much cleaner. But anyway I also wrote a little bit code which may help you, but I have to say its not tested.
DB.php (Holds an PDO in Singleton Pattern which will be used to communicate with the Database):
require_once('Config.php');
class DB {
private static $_instance = null;
private $_pdo;
private function __construct() {
try {
$this->_pdo = new PDO('mysql:host=' . Config::getDbHost() . ';dbname=' . Config::getDbName(), Config::getDbUser(), Config::getDbPass());
} catch(PDOException $e) {
die($e->getMessage());
}
}
public static function getInstance() {
if(!isset(self::$_instance)) {
self::$_instance = new DB();
}
return self::$_instance;
}
/**
* #return PDO
*/
public function getPdo()
{
return $this->_pdo;
}
}
Config.php (Holds the settings needed to connect to the Database, you can extend the Class and parse some kind of configuration file to fill the values if you want):
class Config
{
private static $_dbHost;
private static $_dbName;
private static $_dbUser;
private static $_dbPass;
/**
* #return mixed
*/
public static function getDbHost()
{
return self::$_dbHost;
}
/**
* #return mixed
*/
public static function getDbName()
{
return self::$_dbName;
}
/**
* #return mixed
*/
public static function getDbUser()
{
return self::$_dbUser;
}
/**
* #return mixed
*/
public static function getDbPass()
{
return self::$_dbPass;
}
}
With these classes you should be able to do the following:
<?php
require_once('DB.php');
$pdo = DB::getInstance()->getPdo();
$stmt = $pdo->prepare('UPDATE markers SET quest = :questName WHERE markerName = :markerName');
$stmt->bindValue('questName', $_GET['questName']);
$stmt->bindValue('markerName', $_GET['markerName']);
$stmt->execute();
As I said this is not tested, but it should work. Maybe you have to fix includes and Parameter Binding...

Related

Upgrading my PHP chat system? (Making it only update new messages?)

JS:
"use strict";
$(document).ready(function () {
var chatInterval = 250; //refresh interval in ms
var $userName = $("#userName");
var $chatOutput = $("#chatOutput");
var $chatInput = $("#chatInput");
var $chatSend = $("#chatSend");
function sendMessage() {
var userNameString = $userName.val();
var chatInputString = $chatInput.val();
$.get("./write.php", {
username: userNameString,
text: chatInputString
});
$userName.val("");
retrieveMessages();
}
function retrieveMessages() {
$.get("./read.php", function (data) {
$chatOutput.html(data); //Paste content into chat output
});
}
$chatSend.click(function () {
sendMessage();
});
setInterval(function () {
retrieveMessages();
}, chatInterval);
});
Write.php:
<?php
require("connect.php");
//connect to db
$db = new mysqli($db_host,$db_user, $db_password, $db_name);
if ($db->connect_errno) {
//if the connection to the db failed
echo "Failed to connect to MySQL: (" . $db->connect_errno . ") " . $db->connect_error;
}
//get userinput from url
$username=substr($_GET["username"], 0, 32);
$text=substr($_GET["text"], 0, 128);
//escaping is extremely important to avoid injections!
$nameEscaped = htmlentities(mysqli_real_escape_string($db,$username)); //escape username and limit it to 32 chars
$textEscaped = htmlentities(mysqli_real_escape_string($db, $text)); //escape text and limit it to 128 chars
//create query
$query="INSERT INTO chat (username, text) VALUES ('$nameEscaped', '$textEscaped')";
//execute query
if ($db->real_query($query)) {
//If the query was successful
echo "Wrote message to db";
}else{
//If the query was NOT successful
echo "An error occured";
echo $db->errno;
}
$db->close();
?>
Read.php
<?php
require("connect.php");
//connect to db
$db = new mysqli($db_host,$db_user, $db_password, $db_name);
if ($db->connect_errno) {
//if the connection to the db failed
echo "Failed to connect to MySQL: (" . $db->connect_errno . ") " . $db->connect_error;
}
$query="SELECT * FROM chat ORDER BY id ASC";
//execute query
if ($db->real_query($query)) {
//If the query was successful
$res = $db->use_result();
while ($row = $res->fetch_assoc()) {
$username=$row["username"];
$text=$row["text"];
$time=date('G:i', strtotime($row["time"])); //outputs date as # #Hour#:#Minute#
echo "<p>$time | $username: $text</p>\n";
}
}else{
//If the query was NOT successful
echo "An error occured";
echo $db->errno;
}
$db->close();
?>
Basically everything works perfectly, except I want to allow people to copy and paste, but what the script is doing at the moment is updating every message at the chatinterval which is 250MS.
How can I make it so I can highlight a message and copy it?
So my question is, can I do this:
Can I make it only update the new messages that appear every 250-500MS instead of updating every last bit of HTML as that is a waste of resources (Especially if there was a lot of messages)
I hope you can help!
p.s. I don't want to use web sockets
To make it update just starting from the last message, get the ID of the last message, and then in your next $.get include the id of that message and get only messages that came after that.
And then use .append() in your javascript so you're not overwriting the whole thing.
It looks like you're already using jQuery. You can create a PHP script that only queries the database for entries newer than the newest one displayed, then use $.append to append the message to the <div> (or whatever other element) that holds it.
Also, as the commenter pointed out, you're still probably susceptible to SQL injection. Considering using PDO with prepared SQL statements.

"CLI has stopped working" when trying to select all from an Oracle Database using JQuery?

I am attempting to use JavaScript and Jquery to search a database. I have set up a generic query.php file so that I can pass in the database and query and have it return an array. For some reason, when I try to select all using the *, my PHP server crashes with:
I am using the built in server with PHP 7.0.2. I am attempting to retrieve information from a Oracle database.
Here is the post statement:
$.post(DB1.filename,
{sid: DB1.sid,
username: DB1.username,
password: DB1.password,
host: DB1.host,
port: DB1.port,
sql: query},
function(res){
if(res == -1){
res = errorCode(DATABASE_CONNECTION_ERROR);
} else {
var a = parseObject(res);
var t = parseTable(a);
elements[TABLE].element.innerHTML = t;
}
log(FILE_NAME, "RETRIEVED query ");
}
);
Here is the query.php:
<?php
/* This script will connect to a database and search the given SQL string.
If the connection cannot be established, it will return -1. Otherwise, it will return a JSON array.
*/
//Parameters
$sql = $_POST["sql"];
//Database Information
$user = $_POST["username"];
$pass = $_POST["password"];
$host = $_POST["host"];
$port = $_POST["port"];
$sid = $_POST["sid"];
$connection = "(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = " . $host .")(PORT = " . $port . ")) (CONNECT_DATA = (SID = " . $sid . ")))";
//Establish connection
$conn = oci_connect($user, $pass, $connection);
//Check connection
if(!$conn){
echo -1;
} else {
//Query for the given SQL statement
$stRows = oci_parse($conn, $sql);
oci_execute($stRows);
oci_fetch_all($stRows, $res); //This is where the everything actually crashes
echo json_encode($res);
//Close the connection
oci_close($conn);
}
?>
So if I set the query as:
query = "select TABLE_NAME from ALL_TABLES";
everything works just fine. A table with a single column will be printed to the screen.
However, if I run:
query = "select * from ALL_TABLES";
I get the error above.
This happens regardless of which table I am attempting to connect to. My credentials are correct and I have tried different credentials as well. Any ideas why this is happening?
--UPDATE--
I tried hard coding the column names. I can select up to 8 columns before it crashes.There are 152 rows.
I circumvented the error by swapping the oci_fetch_all for oci_fetch_array as follows:
<?php
...
} else {
//Query for the given SQL statement
$stRows = oci_parse($conn, $sql);
oci_execute($stRows);
$res = array();
while($row = oci_fetch_array($stRows, OCI_NUM)){
$res[] = $row;
}
echo json_encode($res);
//Close the connection
oci_close($conn);
}
?>
This meant drastic changes to the function used to decode the JSON object array, but it does work. I will not mark this answer as correct though because I would very much like to know why my original code wasn't working...

Multiple AJAX functions on one functions page

I'd like to find a way of having a single page in the root of each of my web sections to hold all of the databae queries I'm calling.
I'm using a little script .....
<script type="text/javascript">
$(function() {
var availableTags = <?php include('fn-search-em.php'); ?>;
$("#quick-add").autocomplete({
source: availableTags,
autoFocus:true
});
});
</script>
.... to do SQL searches that appear as the user is typing. Similar to this ....
$sql = "SELECT * FROM stock_c_colours WHERE current_c_status = 'current' AND deleted = 'no'";
$result = mysqli_query($conn, $sql);
$results_list = array();
while($row = mysqli_fetch_array($result))
{
$colour_id = $row['id'];
$range_name = $row['range_name'];
$range_colour = $row['colour'];
$colour_code = $row['code'];
$p1 = $row['piece_size_1'];
$p2 = $row['piece_size_2'];
if($p1 > 1){
$p_mark = 'x';
}
else {
$p_mark = '';
}
$results_list[] = $range_name.' ('.$range_colour.' '.$colour_code.' '.$p1.$p_mark.$p2.') ID:'.$colour_id;
}
echo json_encode($results_list);
Echos a list in the form of a JSON array back to the text box and voila, a list. However, the site I'm working on at the moment has about 20 search boxes for various reasons scattered around (user request), does this mean I have to have 20 separate php function pages, each with their own query on, or can a single page be used?
I suspect the java needs modifying a little to call a specific function on a page of multiple queries, but I'm not good with Java, so some help would be greatly appreciated.
I did initially try adding ?action= to the end of the PHP address in the Java script, hoping a GET on the other end would be able to separate the PHP end into sections, but had no luck.
You need to change <?php include('fn-search-em.php'); ?>; to <?php $action = 'mode1'; include('fn-search-em.php'); ?>;.
Then in your fn-search-em.php file, use the $action variable to determine what kind of MySQL query you make.
For example:
if ($action == 'mode1')
$sql = "SELECT * FROM stock_c_colours WHERE current_c_status = 'current' AND deleted = 'no'";
else
$sql = "SELECT * FROM stock_c_colours WHERE current_c_status = 'mode1' AND deleted = 'no'";
You can do this with by creating a php file with a switch statement to control what code is executed during your Ajax call:
JS:
$.ajax({url: 'ajax.php', method: 'POST', async:true, data: 'ari=1&'+formData,complete: function(xhr){ var availableTags = JSON.parse(xhr.responseText);}});
PHP:
<?php
switch($_REQUEST['ari']){
case 1:
$sql = "SELECT * FROM stock_c_colours WHERE current_c_status = 'current' AND deleted = 'no'";
$result = mysqli_query($conn, $sql);
$results_list = array();
while($row = mysqli_fetch_array($result)){
$colour_id = $row['id'];
$range_name = $row['range_name'];
$range_colour = $row['colour'];
$colour_code = $row['code'];
$p1 = $row['piece_size_1'];
$p2 = $row['piece_size_2'];
if($p1 > 1){$p_mark = 'x';}
else { $p_mark = ''; }
$results_list[] = $range_name.' ('.$range_colour.' '.$colour_code.' '.$p1.$p_mark.$p2.') ID:'.$colour_id;
}
echo json_encode($results_list);
break;
case 2:
// another SQL Query can go here and will only get run if ARI == 2
break;
}
?>
This allows you to keep multiple AJAX handlers in the same file, you just need to pass the index for the desired handler when you make calls to the PHP file or nothing will happen.

Uniquely identifying Leaflet Markers

I've done some research on this topic before, but I have yet to find an answer to my particular question. I am currently working with Leaflet.js. Each marker has popup text that is pulled from a MySQL database. However, some of this data does not display in the popup and is only associated with the marker.
What I would like to do is whenever a particular marker is clicked, data that is associated with it is echoed in a location other than in the popup (ie. in a DIV).
Is there a way to uniquely identify a marker so that you can pull data that is associated with it and echo it elsewhere?
Edit:
Here's some code to make things a bit clearer:
Here is some of my JS:
var json_data = <?php echo json_encode($data); ?>;
for (var i = 0; i < json_data.length; i++) {
L.marker([json_data[i].latitude, json_data[i].longitude])
.bindPopup(json_data[i].firstName + ' ' + json_data[i].lastName + '<br>' + '<strong>Date:</strong>' + ' ' + json_data[i].dateOccurred)
.addTo(map);
}
And here is my PHP:
$query = "SELECT * FROM incident, victim WHERE incident.incidentID = victim.incidentID";
//converting the data from mySQL to PHP
$data = array(); //setting up an emtpy PHP array for the data to go into
if($result = mysqli_query($db,$query)) {
while ($row = mysqli_fetch_assoc($result))
{
$data[] = $row;
}
}
?>
Basically I pull the data via PHP and then encode it into JSON.
Also, thank you for your help, guys!! :)
You can try adding a custom attribute to the marker and then get that attribute in the onClick event:
//Handle marker click
var onMarkerClick = function(e){
alert("You clicked on marker with customId: " +this.options.myCustomId);
}
//Create marker with custom attribute
var marker = L.marker([36.83711,-2.464459], {myCustomId: "abc123"});
marker.on('click', onMarkerClick);
Example on JSFiddle

show result from PDO query every 10 seconds

Not sure if this is possible but here goes, I have a basic PDO query that stores the results in a array.
<?php
// configuration
$dbtype = "";
$dbhost = "";
$dbname = "";
$dbuser = "";
$dbpass = "";
// database connection
$conn = new PDO("mysql:host=$dbhost;dbname=$dbname",$dbuser,$dbpass);
$title = 'PHP AJAX';
// query
$sql = "SELECT * FROM thankyou";
$q = $conn->prepare($sql);
$q->execute(array($title));
$q->setFetchMode(PDO::FETCH_BOTH);
// fetch
while($r = $q->fetch()){
echo"<br>";
print_r ($r);
}
?>
Now the bit I can't get my head around, I have also never used JavaScript. Can I rotate through the results to show one at a time for 5-10 seconds then show another? It can be random or in order, I'm not fussed. I found this, which works, but can't figure out how to get the array into it. I am aware one is client side and one is server side.
<script type="text/javascript">
var rotatingTextElement;
var rotatingText = new Array();
var ctr = 0;
function initRotateText() {
rotatingTextElement = document.getElementById("textToChange");
rotatingText[0] = rotatingTextElement.innerHTML; // store the content that's already on the page
rotatingText[1] = "need to write PDO array here";
setInterval(rotateText, 5000);
}
function rotateText() {
ctr++;
if(ctr >= rotatingText.length) {
ctr = 0;
}
rotatingTextElement.innerHTML = rotatingText[ctr];
}
window.onload = initRotateText;
</script>
and this is were the results are shown
<span id="textToChange">this is were the result is displayed</span>
If I need to do it a totally different way, it's not a problem if someone can point me in the correct direction.
If you're not so familiar with JavaScript, I also suggest using some JS library for the task. In fact, Prototype.js has a class exactly for this purpose: http://prototypejs.org/doc/latest/ajax/Ajax/PeriodicalUpdater/index.html
A working example: http://www.tutorialspoint.com/prototype/prototype_ajax_periodicalupdater.htm
i decided to use AJAX to call a seprate PHP page in the end and works fine this is the updated page.
<script type="text/javascript">
$(function() {
getStatus();
});
function getStatus() {
$('div#status').load('thankyou.php')//Thankyou being the page the query is on
setTimeout("getStatus()",5000);//refreshes every 5 seconds
}
</script>
The query itself is a standard PDO
$query = $db->query("SELECT * FROM `thankyou` ORDER BY RAND() LIMIT 1
Thanks for the pointers all.

Categories

Resources