I'm creating an application in PHP for Wordpress and at this point, I'm trying to fetch a value from a database through AJAX every 2 seconds, and I've created a new file with the function that should be fired.
<?php
global $wpdb;
function conta(){
global $wpdb, $table_name;
$count = $wpdb->get_var("SELECT contatore FROM $table_name WHERE email = '$mail'");
echo "$count";
}
conta()
?>
An this function is called here with an XMLHttpRequest Object every 2 seconds
setInterval(function () {
var url = <?php echo json_encode($con); ?>;
var valuereq = new XMLHttpRequest();
valuereq.open("GET", url, true);
valuereq.send();
valuereq.status;
valuereq.onreadystatechange = function () {
if (valuereq.readyState == 4 && valuereq.status == 200) {
var return_data = valuereq.responseText;
document.getElementById("conta").innerHTML = "Executed: " + return_data;
}
else document.getElementById("conta").innerHTML = "Error";
}
}, 2000);
The Http request is executed correctly, but I receive this error:
Fatal error: Uncaught Error: Call to a member function get_var() on null in
C:\xampp\apps\wordpress\htdocs\wp-content\plugins\bittrex-
trader\admin\partials\conta.php:7 Stack trace: #0
C:\xampp\apps\wordpress\htdocs\wp-content\plugins\bittrex-
trader\admin\partials\conta.php(11): conta() #1 {main} thrown in
C:\xampp\apps\wordpress\htdocs\wp-content\plugins\bittrex-
trader\admin\partials\conta.php on line 7
The program is not able to find the global variable $wpdb, even though is declared. This happens only with the AJAX request because if i include directly the file $wpdb is found and working.
Is there a reason?
Thank you in advance.
Your $mail variable is not set inside the conta() function, yet you perform a query with it.
Use this to load basic wordpress (only loads wordpress core) so you can use $wpbd:
<?php
// use this flag to load only wordpress core
define( 'SHORTINIT', true );
// find the wp-load.php file and require it
require( '/path/to/wp-load.php' );
// now you can use $wpdb
function conta($wpdb, $table_name, $mail)
{
$count = $wpdb->get_var("SELECT `contatore` FROM `".$table_name."` WHERE `email` = '".$mail."'");
echo "$count";
}
// call the function and pass the parameters
conta($wpdb, $table_name, $mail);
// close connection
$wpdb->close();
?>
More on the flag for worpdress core here.
Related
I am trying to search for all properties in a database that are in one suburb. I have read that it has something to do with the HTML code 204 but I still do not undertand what to do or what it really means. I have not done any JS or PHP in a while so this may be a really silly error but I cannot for the life of me figure it out. Please Help!
Here is my JS code:
function basicSearch(){
//Connect Script to the PHP
var urlLink = "basicSearch.php";
//Get search parameters:
var searchAreaBar = document.getElementById("searchAreaBar").value;
//define the parameters to send to php
var strParameters = "searchAreaBar="+searchAreaBar + "&sid=" + Math.random();
// define the options for the AJAX request
var objOptions = {
// use method post
method: "post",
// use strParameters as the parameters
parameters: strParameters,
// if successfil call fuction(objXHR)
onSuccess: function(objXHR) {
// if objXHR. responseText = yes
if(objXHR.responseText=='Yes'){
alert("Success!");
}
else{
alert("Error! No Properties Found!");
}
}
}
// define the AJAX request object
var objRequest = new Ajax.Request(urlLink,objOptions);
}
Here is my PHP code:
<?php
//Link the username and password:
$connect = mysqli_connect("localhost", "admin", "12345", "realestate") or die ('Connection to database failed: ' . mysql_error());
//Extract variables for request parameters:
extract($_REQUEST);
//Define the query:
$BasicSearch = "SELECT * FROM properties WHERE Suberb='$searchAreaBar'";
//Run the query:
$resDasicSearch = mysqli_query($BasicSearch) or die(mysql_error());
//SET intCount to number of rows in result:
$intCount = mysqli_num_rows($resDasicSearch);
//If intCount is greater than 0:
if($intCount > 0){
//Echo Yes:
echo "Yes";
}
else{
//Echo no:
echo "No";
}
?>
Thanks in advance.
The error was that the browser's compiler was "commenting out" all the php and adding empty HTML tags. It was then getting confused as there was an "empty" document.
This was because the website (including JS, PHP and HTML files) were being stored and run from a local directory. For example:
the URL read:
file:///C:/xampp/htdocs/"Project Name"/Index.html
the correct URL is:
localhost/"Project Name"
IF you are using XAMPP, the folder containing all your project files need to be placed in the htdocs folder in the xampp directory.
As you seem to be using an Ajax function that is not shown it is hard to determine the root cause of the problem because nothing above, as far as I can tell, would yield the error you allude to in the title of the posting - namely "XML Parsing Error: no root element found" - I wonder therefore if there should be a configuration option in Ajax.Request that needs to be set to deal with a basic string response?
That aside you might be able to make use of the following - perhaps even for diagnosis purposes.
<?php
/*
---------------
basicSearch.php
---------------
*/
$dbhost = 'localhost';
$dbuser = 'admin';
$dbpwd = '12345';
$dbname = 'realestate';
$db = new mysqli( $dbhost, $dbuser, $dbpwd, $dbname );
$sql='select * from `properties` where `suberb`=?';
$stmt=$db->prepare( $sql );
if( $stmt ){
$searcharea = $_POST['searchAreaBar'];
$stmt->bind_param( 's', $searcharea );
$stmt->execute();
$stmt->store_result();
$stmt->bind_result( $suberbs );
$stmt->fetch();
echo $stmt->num_rows()==0 ? "No" : "Yes";
}
$stmt->close();
$db->close();
?>
<script>
/* reuseable utility ajax function */
function ajax( method, url, params, callback, options ){
var xhr=new XMLHttpRequest();
xhr.onreadystatechange=function(){
if( xhr.readyState==4 && xhr.status==200 )callback.call( this, xhr.response, options, xhr.getAllResponseHeaders() );
};
var async=params.hasOwnProperty('async') ? params.async : true;
var query=[];
for( var n in params )query.push(n+'='+params[n]);
switch( method.toLowerCase() ){
case 'post': query=query.join('&'); break;
case 'get': url+='?'+query.join('&'); params=null; break;
}
xhr.open( method.toUpperCase(), url, async );
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.send( params );
}
/* function that does the search */
function function basicSearch(){
/* configure the parameters to be used in the ajax request */
var method='post';
var url='basicSearch.php';
var params={
searchAreaBar:document.getElementById('searchAreaBar').value,
sid:Math.random()
};
var callback=function(r,o,h){
alert( r ? 'Success' : 'Error! No Properties Found!' )
}
var options={};
/* call the ajax function */
ajax.call(this,method, url, params, callback, options);
}
</script>
Today I meet this error in Firefox's console, that is so simple, while all my API return JSON, one of my API return text/html and it causes Firefox show up that error!
I have changed my NodeJS Express code:
res.end('');
To
res.json({});
ANd it is okay now! Hope it can help someone!
I'm trying to add ajax autosave to my settings page in plugin and made this code:
<?php
function cfgeo_settings_javascript() { ?>
<script type="text/javascript" >
(function($){
$(document).ready(function(){
$("input[id^='cf_geo_'], select[id^='cf_geo_'], textarea[id^='cf_geo_']").on("change keyup", function(){
var This = $(this),
name = This.attr("name"),
value = This.val(),
data = {};
data['action'] = 'cfgeo_settings';
data[name] = value;
console.log(data);
console.log(ajaxurl);
$.post(ajaxurl, data).done(function(returns){
console.log(returns);
});
});
});
}(window.jQuery));
</script> <?php
}
add_action( 'admin_footer', 'cfgeo_settings_javascript');
function cfgeo_settings_callback() {
global $wpdb; // this is how you get access to the database
var_dump($_POST);
if (isset($_POST)) {
// Do the saving
$front_page_elements = array();
$updates=array();
foreach($_POST as $key=>$val){
if($key != 'cfgeo_settings')
update_option($key, esc_attr($val));
}
echo 'true';
}
else
echo 'false';
wp_die(); // this is required to terminate immediately and return a proper response
}
add_action( 'wp_ajax_cfgeo_settings', 'cfgeo_settings_callback');
?>
I find problem that everytime I want to send this simple ajax request I get 0 what is realy enoying.
Here is Console Log when I try to made some change in select option box:
Object {action: "cfgeo_settings", cf_geo_enable_ssl: "true"}
admin.php?page=cf-geoplugin-settings:1733 /wp-admin/admin-ajax.php
admin.php?page=cf-geoplugin-settings:1736 0
What's wrong in my ajax call or PHP script?
I need to mention that both codes are in the one PHP file.
You should have to follow guideline of WordPress ajax method by this admin ajax reference. Please follow this.
https://codex.wordpress.org/AJAX_in_Plugins
Here is a working example with notes included in the comments, there are a lot of don't does in your code and this example addresses those concerns in the code comments.
https://gist.github.com/topdown/23070e48bfed00640bd190edaf6662dc
I am getting a very generic error message from an Ajax calls xhr parameter
readyState 0
responseText ""
statusText "error"
The rest are all function() or function(e) or function(e,t)
I know the issue can't be a domain based error as I'm calling the same server and it's local
Here is the script:
$(function(){
$.ajaxSetup({
timeout: 100000 //Time in milliseconds
});
loadTest();
});
function loadTest(){
//var postValues=null;
$.post("pieTest.Json.php")
.done(function(data){
console.log("pi: "+data.pie+" Time: "+data.sequentialTime)
})
.fail(function(xhr,textStatus,errorThrown){
console.log(xhr);
})
}
here is the text from thte file that it's calling (called pieTest.Json.php:
<?php
require_once($_SERVER['DOCUMENT_ROOT'] . "/php/init.php");
$result = array();
set_time_limit ( 200 );
try {
$startT = time();
$result['pie'] = pie(100000);
$endT = time();
$result['sequentialTime']=$endT-$startT;
$result['seqStart']=$startT;
$result['endTime']=$endT;
}catch(DisplayableException $e){
$result['status'] = "fail";
$result['errorMessage'] = $e->getMessage();
}catch (exception $e){
$result['status'] = "fail";
$result['errorMessage'] =$e->getMessage();
inspect($e);
}
header('Content-Type: application/json');
echo json_encode($result);
function pie ($n)
{
if ($n==1)
return 4*1;
else
return ( 4*(pow(-1,$n+1)*(1/(2*$n-1))) + pie($n-1) );
}
I'm attempting to use the pie function to test sequential vs some parrallel styles in php. But when I ratchet up the parameter being passed into pie around 21999 I get that error. Before that I get a value for pi and a time of 0 (which seems low for the diff and is why I want to raise the speed so I can get the diff between a seq and parallel solution).
I have a folder watcher that i want to be called once a minute, but i cant get it working.
The folder watcher will return 1 or 0. If data == 1 then the page will be refreshed, if 0 wait a min and run again.
Can someone help me to find out whats wrong?
The script:
<script type="text/javascript">
function timedRefresh(timeoutPeriod) {
setTimeout(Update(),timeoutPeriod);
}
function Update() {
$.ajax({
url: "checkfolder.php",
type: "POST",
success: function (data) {
if(data == "1"){
//Page will be updated
}
else{
timedRefresh(60000);
}
}
});
}
</script>
Heres the checkfolder.php:
<?php
// Configuration ///////////////////////////////////////////////////////////////
$host ='xxxx';
$port = 21;
$user = 'xxxx';
$pass = 'xxxx';
$remote_dir = '../img/uploads/';
$cache_file = 'ftp_cache';
// Main Run Program ////////////////////////////////////////////////////////////
// Connect to FTP Host
$conn = ftp_connect($host, $port) or die("Could not connect to {$host}\n");
// Login
if(ftp_login($conn, $user, $pass)) {
// Retrieve File List
$files = ftp_nlist($conn, $remote_dir);
// Filter out . and .. listings
$ftpFiles = array();
foreach($files as $file)
{
$thisFile = basename($file);
if($thisFile != '.' && $thisFile != '..') {
$ftpFiles[] = $thisFile;
}
}
// Retrieve the current listing from the cache file
$currentFiles = array();
if(file_exists($cache_file))
{
// Read contents of file
$handle = fopen($cache_file, "r");
if($handle)
{
$contents = fread($handle, filesize($cache_file));
fclose($handle);
// Unserialize the contents
$currentFiles = unserialize($contents);
}
}
// Sort arrays before comparison
sort($currentFiles, SORT_STRING);
sort($ftpFiles, SORT_STRING);
// Perform an array diff to see if there are changes
$diff = array_diff($ftpFiles, $currentFiles);
if(count($diff) > 0)
{
echo "1";//New file/deleted file
}
else{
echo "0";//nothing new
}
// Write new file list out to cache
$handle = fopen($cache_file, "w");
fwrite($handle, serialize($ftpFiles));
fflush($handle);
fclose($handle);
}
else {
echo "Could not login to {$host}\n";
}
// Close Connection
ftp_close($conn);
?>
just change
setTimeout(Update(),timeoutPeriod);
to
setTimeout(Update,timeoutPeriod);
setTimeout takes the function reference as the first parameter while you were passing the function call. You dont need the setInterval here as on receiving '0' you are already calling the refresh function.
You need to pass function reference to setTimeout, also need to use setInterval() as you need to invoke it every minute
function timedRefresh(timeoutPeriod) {
setInterval(Update,timeoutPeriod);
}
All you need to do is to put your function inside $(document).ready() and change your time out structure:
<script>
$(document).ready(function(){
setTimeout(function(){
Update()
},timeoutPeriod);
});
</script>
Try this one
$(document).ready(function(){
setInterval(function(){
//code goes here that will be run every 5 seconds.
$.ajax({
type: "POST",
url: "php_file.php",
success: function(result) {
//alert(result);
}
});
}, 5000);
});
I have a script that requires quite a few seconds of processing, up to about minute. The script resizes an array of images, sharpens them and finally zips them up for the user to download.
Now I need some sort of progress messages.
I was thinking that with jQuery's .post() method the data from the callback function would progressively update, but that doesn't seem to work.
In my example I am just using a loop to simulate my script:
$(document).ready(function() {
$('a.loop').click(function() {
$.post('loop.php', {foo:"bar"},
function(data) {
$("div").html(data);
});
return false;
});
});
loop.php:
for ($i = 0; $i <= 100; $i++) {
echo $i . "<br />";
}
echo "done";
Update: Getting progress information is a lot easier since jQuery Ajax requests have a promise interface. Use this answer:
https://stackoverflow.com/a/32272660/18771
The original answer below is outdated (it is originally from 2010). It still works but is more complicated than it needs to be. I'll keep it in place for reference and and comparison.
You need some kind of progress info from the server. The ajax callbacks do no progressive work, they fire just once - after the request returned successfully.
So... in PHP you would need something like this:
/* progress.php */
$batch_done = some_way_to_find_out_that_number();
$batch_size = some_way_to_find_out_that_number_too();
header('Content-type: application/json');
// TODO: format number
echo '{"progress":'. ($batch_size==0 ? '0' : $batch_done*100.0/$batch_size).'}';
For this to work your image processing script must leave some evidence of its progress of course.
And in JavaScript something like this:
$(document).ready(function() {
$('a.loop').click(function() {
var queryData = {foo:"bar"};
// prepare a function that does cyclic progress checking
var progressCheck = function() {
$.getJSON(
"progress.php", queryData,
function(data) {
$("div.progress").css("width", data.progress+"%");
}
)
};
$.post(
'loop.php', queryData,
/* create the post request callback now */
function(intvalId){
return function(data) {
$("div").html(data);
clearInterval(intvalId);
}
}( setInterval(progressCheck, 1000) )
);
return false;
});
});
This part requires some explanation:
function(intvalId){
return function(data) {
$("div").html(data);
clearInterval(intvalId);
};
}( setInterval(progressCheck, 1000) )
function(intvalId) is an anonymous function that takes one argument - an interval ID. This ID is necessary to stop an interval that has been set up via setInterval(). Luckily, the call to setInterval() returns this very ID.
The anonymous outer function returns an inner function(data), this one will be the actual callback for $.post().
We call the outer function immediately, doing two things in the process: Triggering off the interval with setInterval() and passing in its return value (the ID) as an argument. This argument value will be available to the inner function at its call time (which may be some minutes in the future). The callback for post() now can actually stop the interval.
As an exercise for you ;)
Modify the ajax call such that it stops the interval on request error or timeout, too. Currently, if the callback is never run (and it runs on success only!), the interval will never stop.
Make sure the post() cannot be triggered twice inadvertently.
Thanks to Tomalak I finally put something together that works.
Since I am not actually writing my image files on the server when processing the batch I wrote a log file that I am consulting in the progress.php script.
I would like to know if this is the best way of doing this. I wanted to avoid writing to a file and tried with PHP's $_session but cannot seem to progressively read from it.
Is this possible with $_session?
HTML:
<a class="download" href="#">request download</a>
<p class="message"></p>
JS:
$('a.download').click(function() {
var queryData = {images : ["001.jpg", "002.jpg", "003.jpg"]};
var progressCheck = function() {
$.get("progress.php",
function(data) {
$("p.message").html(data);
}
);
};
$.post('proccess.php', queryData,
function(intvalId) {
return function(data) {
$("p.message").html(data);
clearInterval(intvalId);
}
} (setInterval(progressCheck, 1000))
);
return false;
});
process.php:
$arr = $_POST['images'];
$arr_cnt = count($arr);
$filename = "log.txt";
$i = 1;
foreach ($arr as $val) {
$content = "processing $val ($i/$arr_cnt)";
$handle = fopen($filename, 'w');
fwrite($handle, $content);
fclose($handle);
$i++;
sleep(3); // to mimic image processing
}
echo "<a href='#'>download zip</a>";
progress.php:
$filename = "log.txt";
$handle = fopen($filename, "r");
$contents = fread($handle, filesize($filename));
fclose($handle);
echo $contents;