AJAX Using PHP File in Wordpress Plugin - php

I am following a tutorial on W3Schools for AJAX PHP. https://www.w3schools.com/php/php_ajax_php.asp
Here is the twist: I am doing this in wordpress. The following is a method that DOES work, but it is less than ideal.
1) Create the following gethint.php in the root directory.
<?php
// Array with names
$a[] = "Anna";
$a[] = "Brittany";
...
$a[] = "Vicky";
// get the q parameter from URL
$q = $_REQUEST["q"];
$hint = "";
// lookup all hints from array if $q is different from ""
if ($q !== "") {
$q = strtolower($q);
$len=strlen($q);
foreach($a as $name) {
if (stristr($q, substr($name, 0, $len))) {
if ($hint === "") {
$hint = $name;
} else {
$hint .= ", $name";
}
}
}
}
// Output "no suggestion" if no hint was found or output correct values
echo $hint === "" ? "no suggestion" : $hint;
2) Using the CSS & Javascript toolbox plugin, add this code to the header:
<script>
function showHint(str) {
if (str.length == 0) {
document.getElementById("txtHint").innerHTML = "";
return;
} else {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("txtHint").innerHTML = this.responseText;
}
};
xmlhttp.open("GET", "/gethint.php?q=" + str, true);
xmlhttp.send();
}
}
</script>
3) Create a page with the following code (in plain text):
<p><b>Start typing a name in the input field below:</b></p>
<form>
First name: <input type="text" onkeyup="showHint(this.value)">
</form>
<p>Suggestions: <span id="txtHint"></span></p>
While this works, having to create a php file and adding to the root directory seems like bad practice. It would be better to have this php file stored in the plugins directory. However that causes this line of the header script to fail as 404:
xmlhttp.open("GET", "/gethint.php?q=" + str, true);
Simply changing the relative path won't work, because theoretically, different users can have their plugin folder in different locations.
I figure I should be using the wp_ajax_ and wp_ajax_nopriv_ hooks, but my attempts I have failed, so I am probably doing it wrong. Please help.

Doing ajax in WordPress should all be sent to /wp-admin/admin-ajax.php,
to do that, in your plugin's main file or the index.php file,
register your ajax action like this:
// let's do the ajax thing here
add_action( 'wp_ajax_theNameOfMyCustomAjax', 'theFunctionThatMyAjaxWillCall' );
function theFunctionThatMyAjaxWillCall() {
// include your ajax file here, in this case
// I assumed that we placed the gethint.php in
// /wp-content/plugins/yourpluginname/gethint.php
include( plugin_dir_path( __FILE__ ).'gethint.php' );
// don't forget to add "die;" every time you return a response to your ajax
//Example: echo $hint ?? "no suggestion"; die;
// or you can add the termination code right here
die; // this will prevent the ajax response to have 0 in the end.
}
Now, in your javascript, instead of calling the filename of your ajax file, you can now use the global ajaxurl javascript variable like this:
xmlhttp.open("GET", ajaxurl+"?action=theNameOfMyCustomAjax&q=" + str, true);

Related

Want to perform php using OnClick function without clearing the current web page

This is the js script at the bottom of my wp post.
<script type="text/javascript" src="jquery-1.10.2.min.js">
</script>
<script type="text/javascript">
var id = 'downloadid';
var data_from_ajax;
$.post('download.php', {id : id}) .done(function(data) {
data_from_ajax = data;
});
function hey() {
document.write(data_from_ajax);
}
</script>
Function hey was being called from a link OnClick function. When using this, the page would successfully perform the php code on download php (update a db then download a file) although it would clear the current page I was on. What I wanted to do was perform the php and keep the current page template. So next I tried using
document.getElementById("download").innerHTML = data_from_ajax;
instead of document.write. I made a div with the id download. Now when I click it, it simply won't perform the php. when I replace the data_from_ajax with a string, it gladly puts it in the div though.
Any help would be great.
EDIT:
my html is
download
<div id='download'>&nbsp</div>
http://jsfiddle.net/7smJE/
From PHP code which you've provided, I think you should replace document.write() in your code with $('#download').html(). This way you don't need to put the returned result in your download div anymore because when PHP page gets loaded it'll do this for you and you have to put your $.post in hey() function too because you need this to perform when your link gets clicked.
PHP:
<?php
$fileid = $id;
if (is_file('d84ue9d/' . $fileid . '.apk'))
{
$ip = $_SERVER['REMOTE_ADDR'];
$con=mysqli_connect("localhost","docvet95_check","%tothemax%","docvet95_downcheck");
$result = mysqli_query($con,"SELECT * FROM `download-check` where ip = '$ip'");
while ($row = mysqli_fetch_array($result))
{
$files = $row['files'];
$downloads = $row['downloads'];
}
if ($downloads > 4)
{
print "$('#download').html(unescape('%3C%73%63%72%69%70%74%20%74%79%70%65%3D%22%74%65%78%74%2F%6A%61%76%61%73%63%72%69%70%74%22%3E%0A%61%6C%65%72%74%28%27%59%6F%75%5C%27%76%65%20%64%6F%77%6E%6C%6F%61%64%65%64%20%66%69%76%65%20%6F%72%20%6D%6F%72%65%20%66%69%6C%65%73%2E%20%46%6F%72%20%72%69%67%68%74%20%6E%6F%77%2C%20%74%68%69%73%20%69%73%20%6F%6B%61%79%2E%20%49%6E%20%74%68%65%20%66%75%74%75%72%65%2C%20%79%6F%75%20%77%69%6C%6C%20%6E%65%65%64%20%74%6F%20%63%6F%6D%70%6C%65%74%65%20%61%20%73%75%72%76%65%79%20%69%6E%20%6F%72%64%65%72%20%74%6F%20%63%6F%6E%74%69%6E%75%65%20%64%6F%77%6E%6C%6F%61%64%69%6E%67%2E%20%54%68%61%6E%6B%20%79%6F%75%20%66%6F%72%20%75%73%69%6E%67%20%6F%75%72%20%77%65%62%73%69%74%65%27%29%3B%20%0A%77%69%6E%64%6F%77%2E%6F%70%65%6E%28%27%2F%61%70%6B%73%2F%64%38%34%75%65%39%64%2F". $fileid . "%2E%61%70%6B%27%2C%27%5F%73%65%6C%66%27%29%0A%3C%2F%73%63%72%69%70%74%3E'));";
}
else
{
$downloadq = $downloads + 1;
$there = $result->num_rows;
if ($there <1)
{
$addidnip = mysqli_query($con,"INSERT INTO `download-check` (ip, files, downloads) VALUES ('$ip', '$fileid', 1)");
}
else
{
$idtoarray = explode(",", $files);
if (!in_array($fileid, $idtoarray))
{
array_push($idtoarray, $fileid);
$newfile = implode(",", $idtoarray);
$adddw = mysqli_query($con,"UPDATE `download-check` SET downloads=$downloadq, files='$newfile' where ip = '$ip'");
}
}
print "<script type=\"text/javascript\">";
print "$('#download').html(unescape('%3C%73%63%72%69%70%74%20%74%79%70%65%3D%22%74%65%78%74%2F%6A%61%76%61%73%63%72%69%70%74%22%3E%0A%77%69%6E%64%6F%77%2E%6F%70%65%6E%28%27%64%38%34%75%65%39%64%2F". $fileid . "%2E%61%70%6B%27%2C%27%5F%73%65%6C%66%27%29%0A%3C%2F%73%63%72%69%70%74%3E'));";
print "</script>";
}
}
else
{ echo 'Whoops, looks like we couldn\'t find that file. You could try searching for it?'; }
?>
JavaScript:
var id = 'downloadid';
var data_from_ajax;
function hey() {
$.post('download.php', {id : id});
}
But I recommend you to return the exact data from your PHP without any extra tag and then use it this way:
var id = 'downloadid';
function hey() {
$.post('download.php', {id : id}).done(function(data) {
$("#download").html(unescape(data));
});
}
From what I can see without the fiddle:
The hey function is probably fired before the done function is ready. Why don't you call hey() from within done()?

Unable to extract post arguments after encodeURIComponent()

I encoded a parameter string from the fields collected by a form using encodeURIComponent() and then sent it to the server using XMLHttpRequest.
In the server side PHP script I'm using extract(urldecode($_POST), EXTR_SKIP); to extract the parameters to variables.
Although the process was working fine before I added the encoding of the URI component, the variables are now not being extracted on the server. What am I doing wrong please?
This is the JavaScript which does the sending:
function postData(url, parameters, postprocess, displayURL, runOnError) {
// Check whether user action has already failed validation
if (typeof cancel !== 'undefined') {
// Deleting a variable only works if a global
delete cancel;
return false;
}
var
xmlHttp = AJAX(),
resp,
defcon,
json;
parameters = EncodeURIComponent(parameters);
if( url.charAt( 0 ) === '&' ) {
url = url.slice( 1 );
}
xmlHttp.onreadystatechange = function(){
if (xmlHttp.readyState == 4) {
resp = xmlHttp.responseText;
checkSessionTimeout(resp);
// REDIRECT TO POST-PROCESSORS
if (postprocess !== '') {
// Goto custom post processing function
eval(unescape(postprocess));
}
// Determine whether json response or not
else if ( resp.charAt( 0 ) == '{' ) {
// it's json so redirect to...
jsonGenericRespHandler(resp, displayURL);
} else {
// Use generic post process
/* The following is depreciated. We should
* be using jsonGenericRespHandler(resp).
*/
if (resp.toLowerCase().indexOf('error') > -1) defcon = 'error';
else if (resp.toLowerCase().indexOf('success') > -1) defcon = 'success';
else if (resp.toLowerCase().indexOf('warn') > -1) defcon = 'warn';
else defcon = 'info';
// Make sure we don't miss an important message.
if (defcon === 'warn' || defcon === 'error') {
alert(resp);
eval(runOnError);
} else {
// Redirect to dashboard
if (displayURL === '') {
ajaxLoader('main/home.php', 'contentMain');
} else if (displayURL !== 0) {
ajaxLoader(displayURL, 'contentMain');
}
showMessage(defcon, resp);
}
}
}
}
xmlHttp.open("POST", url, true);
xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlHttp.setRequestHeader("Content-length", parameters.length);
xmlHttp.setRequestHeader("Connection", "close");
xmlHttp.send(parameters);
}
I should probably mention that the reason I added encodeURIComponent() was because I noticed that if the visitor entered a legitimate ampersand in the form, it was being treated as an extra argument on the server.

Detecting Failure with Javascript error event listener versus PHP return 1 in responseText

How does xhr.upload.addEventListener("error", failed, false) differ from me having $success = move_uploaded_file($tmp_name, $name); if $(success) { echo "0" } else { echo "1" }? Is this unnecessary redundancy?
function uploadPHP() {
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener("progress", updateProgress, false);
xhr.upload.addEventListener("load", complete, false);
xhr.upload.addEventListener("error", failed, false);
xhr.upload.addEventListener("abort", cancelled, false);
var foo = document.getElementById("uploadScreen");
var form = document.getElementById("uploadForm");
var percentComplete;
var index;
xhr.onreadystatechange = function () {
if (xhr.readyState == 1){
}
--
function cancelled() {
//cancel
}
}
localhost file_server # cat php/upload.php
<?php
//
//require_once('PhpConsole.php');
//PhpConsole::start();
$tmp_name = $_FILES['file1']['tmp_name'];
$path = "/trunk";
$name = $path . DIRECTORY_SEPARATOR . $_FILES['file1']['name'];
$success = move_uploaded_file($tmp_name, $name);
if ($success) {
echo "0";
} else {
echo "1";
}
?>
"error" occurs if your request doesn't get through, for example if it times out.
Say you need to validate some data. If it is invalid, the "error" event won't occur unless you throw an uncaught exception in your PHP. Instead, it will simply return some data that indicates the values were invalid, for example the string "0".
In your given example, it is entirely possible for the move_uploaded_file to fail, yet the error handler won't trigger because technically the request completed without untoward incident. The only indication you will have of the action you wanted to take having failed will be the "0" response.

How can I use a php file's output with Ajax?

I was following this tutorial.
I need to use a php file's ouput in my HTML file to dynamically load images into a gallery. I call
function setOutput()
{
if (httpObject.readyState == 4)
document.getElementById('main').src = httpObject.responseText;
alert("set output: " + httpObject.responseText);
}
from
function doWork()
{
httpObject = getHTTPObject();
if (httpObject != null) {
httpObject.open("GET", "gallery.php?no=0", true);
httpObject.send(null);
httpObject.onreadystatechange = setOutput;
}
}
However, the alert returns the php file, word for word. It's probably a really stupid error, but I can't seem to find it.
The php file:
<?php
if (isset($_GET['no'])) {
$no = $_GET['no'];
if ($no <= 10 && $no >1) {
$xml = simplexml_load_file('gallery.xml');
echo "images/" . $xml->image[$no]->src;
}
else die("Number isn't between 1 and 10");
}
else die("No number set.");
?>
If the alert is returning the contents of the PHP file instead of the results of executing it, then the server is not executing it.
Test by accessing the URI directly (instead of going via JavaScript).
You probably need to configure PHP support on the server.
Your Server doesn't serve/parse PHP files! You could test your JavaScript code by setting the content of gallery.php to the HTML code you want to receive.

[PHP / AJAX]: Change color of the message according to the entered text

In my website home page, I have a new user registration Form. It contains a field "User Name". When the user enters the user name and the focus is pointed to another field, an AJAX code is executed that checks whether any user with the entered username already exists or not.
The AJAX code that I am using is this:
function toggle_username(userid) {
if (window.XMLHttpRequest) {
http = new XMLHttpRequest();
} else if (window.ActiveXObject) {
http = new ActiveXObject("Microsoft.XMLHTTP");
}
handle = document.getElementById(userid);
var url = 'ajax.php?';
if(handle.value.length > 0) {
var fullurl = url + 'do=check_username_exists&username=' + encodeURIComponent(handle.value);
http.open("GET", fullurl, true);
http.send(null);
http.onreadystatechange = statechange_username;
}
else
{
document.getElementById('username_exists').innerHTML = '';
}
}
The file "AJAX.PHP" called by the above code, is like this:
<?php
mysql_connect ('localhost', 'MyServer', 'user1');
mysql_select_db('globaldb');
$do = $_GET['do'];
switch($do) {
case 'check_username_exists':
if(get_magic_quotes_gpc()) {
$username = $_GET['username'];
}else{
$username = addslashes($_GET['username']);
}
$count = mysql_num_rows(mysql_query("SELECT * FROM `student_login` WHERE `username`='".$username."'"));
header('Content-Type: text/xml');
header('Pragma: no-cache');
echo '<?xml version="1.0" encoding="UTF-8"?>';
echo '<result>';
if($count > 0) {
$_SESSION['UserExists'] = "true";
}else{
$_SESSION['UserExists'] = "false";
}
$_SESSION['UserExists'] = "false";
echo '</result>';
break;
default:
echo 'Error, invalid action';
break;
}
?>
In my registration form, just below the username input box, I want to define a section where in I can show the messages:
User with this name exists, or
Username is available.
In my home page, I am using following code:
<input name="username" type="text" id="username" onchange="toggle_username('username')" style="width:150px;" maxlength="40" size="22" >
<?PHP
if ($_SESSION['UserExists'] == "true")
{
echo "<div id='username_exists' style='font-size: 11px;font-weight: bold;color:red'>User with this name unavailable.</div>";
}
else
{
echo "<div id='username_exists' style='font-size: 11px;font-weight: bold;color:darkgreen'> User with this name is available </div>";
}
?>
The home page consists of the above code and the first code block (JavaScript) on top that I gave.
This code is not working. And I guess the reason is that I am have included the messages in the PHP block. Being server-side, it is not showing the messages.
Please let me know how to handle this issue. Whether to modify the JavaScript code that calls the AJAX or include something in the PHP.
Please also note that what actually I want is to show the messages in green or red color. If the user name is available, then green else in red color.
I'd do this using jQuery and have the PHP page return a code (0 for false, 1 for true) or similar. You can then use jQuery's addClass() method depending on the returned result, all in the javascript.
How about having ajax.php return a bit of pre-formatted HTML and using the statechange_username function, which you've set to process the response, to stick it in a placeholder div/span?
By the way, why are you setting a session variable?
I guess you are missing the statechange_username function, something like
function statechange_username()
{
if (http.readyState==4)
{
document.getElementById(\"username_eixsts\").innerHTML=http.responseText;
}
}

Categories