The problem I’m finding is that I can only get one to work at a time.
Whichever function is added first in the functions.php, that one works
– the other one gets a 403 error for admin-ajax.php.
Yes, because both your PHP functions (or AJAX callbacks) there are hooked to the same AJAX action, which is load_posts_by_ajax
:
// #1 AJAX action = load_posts_by_ajax
add_action('wp_ajax_load_posts_by_ajax', 'load_smart_maps_by_ajax_callback');
add_action('wp_ajax_nopriv_load_posts_by_ajax', 'load_smart_maps_by_ajax_callback');
// #2 AJAX action = load_posts_by_ajax
add_action('wp_ajax_load_posts_by_ajax', 'load_strats_by_ajax_callback');
add_action('wp_ajax_nopriv_load_posts_by_ajax', 'load_strats_by_ajax_callback');
And check_ajax_referer()
by default exits the page with a 403
(“forbidden”) status, when for example the nonce is not specified or has already expired:
// #1 $_REQUEST['security2'] will be checked for the load_smartmaps_posts nonce action.
check_ajax_referer('load_smartmaps_posts', 'security2');
// #2 $_REQUEST['security'] will be checked for the load_strats_posts nonce action.
check_ajax_referer('load_strats_posts', 'security');
You can send both nonces (although nobody would do that), or you can use the same nonce and same $_REQUEST
key (e.g. security
), but you’d still get an unexpected results/response.
So if you want a “single function”, you can use a secondary “action”:
-
PHP part in
functions.php
:// #1 Load More Smart Maps // No add_action( 'wp_ajax_...' ) calls here. function load_smart_maps_by_ajax_callback() { // No need to call check_ajax_referer() ...your code here... } // #2 Load More Strategic Events // No add_action( 'wp_ajax_...' ) calls here. function load_strats_by_ajax_callback() { // No need to call check_ajax_referer() ...your code here... } add_action( 'wp_ajax_load_posts_by_ajax', 'load_posts_by_ajax' ); add_action( 'wp_ajax_nopriv_load_posts_by_ajax', 'load_posts_by_ajax' ); function load_posts_by_ajax() { check_ajax_referer( 'load_posts_by_ajax', 'security' ); switch ( filter_input( INPUT_POST, 'action2' ) ) { case 'load_smartmaps_posts': load_smart_maps_by_ajax_callback(); break; case 'load_strats_posts': load_strats_by_ajax_callback(); break; } wp_die(); }
-
JS part — the
data
object:// #1 On click of `.loadmore.smarties` var data = { 'action': 'load_posts_by_ajax', 'action2': 'load_smartmaps_posts', 'security': '<?php echo wp_create_nonce( "load_posts_by_ajax" ); ?>', // same nonce ...other properties... }; // #2 On click of `.loadmore.strats` var data = { 'action': 'load_posts_by_ajax', 'action2': 'load_strats_posts', 'security': '<?php echo wp_create_nonce( "load_posts_by_ajax" ); ?>', // same nonce ...other properties... };
But why not hook the callbacks to their own specific AJAX action:
// #1 AJAX action = load_smart_maps_posts_by_ajax
add_action('wp_ajax_load_smart_maps_posts_by_ajax', 'load_smart_maps_by_ajax_callback');
add_action('wp_ajax_nopriv_load_smart_maps_posts_by_ajax', 'load_smart_maps_by_ajax_callback');
// #2 AJAX action = load_strats_posts_by_ajax
add_action('wp_ajax_load_strats_posts_by_ajax', 'load_strats_by_ajax_callback');
add_action('wp_ajax_nopriv_load_strats_posts_by_ajax', 'load_strats_by_ajax_callback');