When trying to get data within an instance of a plugin, all of the PHP methods defined in our plugin class file can "see" the data that was just set for a certain property.
However, when we create a PHP method that responds to an AJAX post request from the JavaScript file in our plugin, all of a sudden that property is just empty as if it's never been set.
Accessing it from any other method works fine, so it leads me to believe that the AJAX-callable method is seeing a different context of $this which hasn't had the property set yet.
Is this likely the case? Or is something else afoot?
Edited for clarity:
The data in question is set at run-time via a parameter in the shortcode that kickstarts the main functionality. So it doesn't exist until the shortcode is executed which got me wondering if the way AJAX calls the method exists in a different context than the plugin object created by WordPress on page load.
Edited to add code snippets (just the relevant stuff, these are NOT complete):
// From WP template file:
// This is well-formed and on the other end the plugin can print_r() the
// unserialized $args just fine
<?php echo do_shortcode('[cptgm ' . serialize($args) . ']'); ?>
// From plugin class file:
private query_args;
public function get_query_args() {
if (!empty($this->query_args)) {
return $this->query_args;
}
return false;
}
public function set_query_args($newArgs) {
if (empty($newArgs)) {
return false;
}
$this->query_args = $newArgs;
}
public function render_map_shortcode($atts = [], $content = null, $shortcode_tag = '') {
// We know from doing a print_r() of $this->get_query_args immediately after
// this line that the property is set and can be accessed
$this->set_query_args(unserialize($atts[0]));
$this->render_map();
}
// This is the method called via AJAX and is the only time in the plugin
// that we seem to have an issue. When called via AJAX, we can't print_r()
// here, but the return value is an empty array ONLY when we replace a hard-coded
// $args with $this->get_query_args(), which works everywhere else
public function get_data_from_custom_fields() {
$return_data = [];
$args = $this->get_query_args();
// If we hard-code the $args, the WP_Query works fine and echos JSON
// as a response to the JS file just fine. Only when we try and use
// $this->get_query_args(); does the plugin end up echoing back $return_data
// as an empty array (the way it was initialized above)
// This is what led us to believe that, in the AJAX context,
// $this->get_query_args(); didn't seem to be supplying the $args we knew where
// there when the same getter was called from other methods
$wp_query = new WP_Query($args);
// ... echo/return results from $wp_query as JSON to the calling JS file
}
// From the plugin's JS file:
function cptgmRenderMap() {
console.log('[CPTGM] Rendering map...');
cptgmData = {
'action': 'get_data_from_custom_fields'
}
$.post(ajax_object.ajax_url, cptgmData, function(response) {
var parsedResponse = JSON.parse(response);
// Setup map markers, etc. EXCEPT that the return JSON is now empty
// ...
}
}
$args
, passed via a serialized parameter in the shortcode and set as$this->query_args
, so the JS can use AJAX and request its own data from our PHP that matches the set, but it sees$this->query_args
as empty even though all other non-AJAX methods can see it.$this->query_args
using the attributes passed via the shortcode params. All the methods in the class can see those query args, too. But not if the data is requested via the method exposed as an AJAX action to the plugin's JS file. I thought perhaps there was a race condition, but before the JS is even enqueued in WP (though it had earlier been registered), the object sets the property immediately upon the shortcode callback running. THEN thewp_enqueue_script
is called among other things.My_Example_Plugin::Ajax_method()
and so it exists in a different context from when the shortcode instantiates the plugin.wp_localize_script()
does is output a script tag into the HTML that sets some JavaScript variables.