On the initial call the store-locator-plus.php MUP is called first an is loading with the initMySLP _jsonp call from the embed script.
the SLPlus::initialize_after_plugins_loaded() is being called.
DOING_AJAX is not set, so createobject_AJAX() is not called.
MySLP_REST_API->get_options() is called, which expects SLP->AJAX to be set, but it is not.
The front-end/locations.js is using jQuery.ajax() but it is calling a REST API url, not an AJAX listener endpoint… from the locations.js call…
Update the MySLP_REST_API->get_options() method to use SLP_Ajax::get_instance() to ensure that object is instantiated before use when not doing an AJAX call.
Use the main MySLP::getUserBlogId() to fetch blog IDs. Use SLP_Ajax::get_instance() versus the uninitialized slplus->AjaxHandler to get the SLP AJAX instance.
slplus->AJAX (slplus->AJAX_Handler) was not initialized because the call is a REST call not an AJAX call.
Location bulk actions allow for users to work on multiple locations at once. Export a list of locations, delete select locations from the location table, geocode locations ,and more.
2209.12
Export locations is our first attempt at making bulk actions work more like a single page application.
Instead of doing a form post and submitting the location list, then reading in some PHP-driven variables to set the JavaScript behavior — in 2209.12 the export process bypasses the form submit.
Bypass is handled by using a pub/sub module with a dynamic filter name “exportBulkAction”. This tells the main SLP JavaScript process to execute the callback stack instead of pushing a form submit. This allows the AJAX call to happen immediately without a full page re-render.
2208.15
The apply button processing is handled in the main plugin’s admin.js file.
It uses jQuery to process form variables and prepare the #locationForm to be submitted.
When submitted it sends the request back to WordPress for standard “full page load” processing.
The process starts with a standard form submit from the Bulk Actions “Apply” button.
WordPress sets up a JavaScript variable location_import that has info about the action “export”.
This triggers a jQuery(document).ready() call that fires another request via AJAX back to WordPress with some new parameters in place.
That AJAX call eventually sends back a CSV file that is stored in a DOM div that was prepared with the jQuery() document loader when the refreshed page (post original submit) was rendered.
The front end sends a request back to WordPress via AJAX to request a list of locations. Part of that request encodes all of the form field entries, including the category drop down selection, into a query-encoded (key/value pairs with an & delimiter) string that is send in the formData property to the backend.
The category ID is not being parsed and filtered properly.
Looking At The Data Request
Via browser developer tools and the network I/O inspector, XHR filter…
HTTP Method: POST URL: /wp-admin/admin-ajax.php Request Payload…
You can see the formdata property in the POST body along with the encoded form data including the cat=5 entry. This is where the requests tells the back end to limit results to those that have WordPress category ID #5 attached to the location.
Diving Into The Code
On the back end the AJAX is routed through the Store Locator Plus® base plugin via the standard WordPress hooks and filters. These are setup in the SLP_AJAX class via this add_ajax_hooks method:
Where the csl_ajax_search eventually finds its way to the find_locations method.
Debugging the find_locations method it looks like the formdata variable coming in via the superglobal $_REQUEST variable is not being set properly.
Digging Into The Malformed Variables
Looking at the call stack the form data is mishandled causing the & in the query string to be encoded as &, this causes wp_parse_args() to set the property name incorrect as you can see in the debugging screenshot below.
Turns out the wp_kses_post() is too aggressive with the data munging and converts & to & which then throws wp_parse_args() for a loop.
Instead we need to use esc_url_raw() to leave most URL entities intact.
Originally all of the SLP settings forms had to be submitted by clicking a save button. This runs a typical form post + full page render… old-school web 1.X style.
Along the way work was done to utilize JavaScript triggers and save data with an onBlur on settings form fields. The tech uses jQuery using an AJAX-type model to send a single form field to the WordPress AJAX processor to manage saving a single field without re-rendering the entire page or sending the entire form.
How It Is Triggered
SLP base plugin’s admin.js initializes and hooks a change_option JS function to any INPUT type field with a quick_save CSS class attached.
var qs_inputs = jQuery('.quick_save').find(':input');
qs_inputs.on('change', function (e) {
change_option(e.currentTarget);
});
qs_inputs.on('blur', function (e) {
var start_val = e.currentTarget.defaultValue;
if (e.currentTarget.value !== start_val) {
change_option(e.currentTarget);
}
});