8

Had a situation today where I was using admin-ajax.php from a front end script. As I understand it this the wp way to make ajax calls (registering my function with the wp_ajax_nopriv_myfunction hook)

Seems to me that since admin-ajax.php is on the admin side is_admin() returns true whereas my script calls it from the front end side.

This causes an issue with a plugin I use that does things differently on front and admin side of things.

So I was wondering if I was doing something wrong

is there a way to use ajax in front end the wp way and have is_admin() to return false ?

hope I could make myself understand

1
  • Right. You can use function wp_doing_ajax() which check it is doing AJAX request or not. Commented Mar 5, 2019 at 17:36

5 Answers 5

6

WordPress sets is_admin() to true for all ajax requests (front-end or admin-side). (See codex).

WordPress doesn't allow overriding core AJAX functionality (and it's generally best practice to avoid it). However, if your AJAX request can be triggered from both the front-end and the admin area, including a flag like "is_admin" with your data can help the receiving code understand the request's origin. Unfortunately, without more details about the specific issues this is causing with your plugin, suggesting a suitable workaround is difficult.

1
  • In my case it's someone else's AJAX request. My plugin was not initializing properly when a 3rd party plugin was using admin-ajax.php on the front end, because I had separate initialization for 'admin' and front end. I hope this was just an optimization (can't remember), and a quick fix will be to check DOING_AJAX and if set initialize both. (Can't help thinking that AJAX via WordPress's built-in mechanism will be as slow as it was 11 years ago.)
    – Jake
    Commented Dec 21, 2023 at 0:37
5

is_admin() always returns true for every AJAX call. If you want to validate AJAX calls from frontend only, this may be a work-around:

if (!isset($GLOBALS['current_screen']) && !is_customize_preview()) {
    // AJAX calls from frontend, excludes customize preview screen.
}
2
  • 1
    wow - I've spent 2 days going round in circles because of this! Probably longer ;-/
    – v3nt
    Commented Jun 16, 2020 at 16:50
  • this worked for me, thanks! Commented Oct 15, 2020 at 16:28
0

I know this is old, but in case it helps anybody else that stumbles across this...

what I usually do is set some kind of flag in my frontend forms to denote that the incoming request is ajax.

<input type="hidden" id="my_ajax_flag" name="my_ajax_flag" value="false" />

Initially this is set to "false", which i then toggle to "true" while beginning to process the ajax.

$('#my_ajax_flag').val('true'); // example using jQuery

then in the admin side of my code, i check for that parameter and then either include my ajax hooks or perform my regular non-ajax admin stuff. So for example:

if ( isset( $_REQUEST['my_ajax_flag'] ) && $_REQUEST['my_ajax_flag'] == 'true' ) {
    add_action('wp_ajax_my_ajax_function', 'my_ajax_function');     
    add_action('wp_ajax_no_priv_my_ajax_function', 'my_ajax_function');
} else {
    // regular non-ajax stuff
}

depending on what you need to do, there are multiple variations of this idea, but it allows you to keep your regular admin code from interfering or firing while performing ajax requests.

another recommendation that can be handy is setting the WordPress "noheader" attribute in your forms.

<input type="hidden" name="noheader" value="true" />

when doing backend processing that ultimately results in a redirect (recommended for avoiding the dreaded double form submission), in rare fringe cases where you need to access wp hooks that would normally occur after "headers already sent".

3
  • 3
    Not needed: Just check defined( 'DOING_AJAX' ) && DOING_AJAX.
    – fuxia
    Commented Mar 24, 2013 at 22:19
  • Or if your code extends WooCommerce use their function is_ajax(). Yes it just checks the conditional @toscho mentioned, but a smidge shorter. Commented Oct 17, 2016 at 9:00
  • Depending on a 3rd party method that could change at any time for the sake of saving a few bytes of code is just bad practice. Don't be lazy and do this. If anything, build this method into your own base framework if you insist on saving a few bytes. Commented Oct 1, 2017 at 18:59
0

I wanted to enable/disable logging on the front end and admin using a dashboard menu button. I simply added a class to my menu button and then queried admin page status with jQuery

https://codex.wordpress.org/Class_Reference/WP_Admin_Bar/add_menu

Add a menu item with the admin status as a class

$wp_admin_bar -> add_menu(
  array(
        'title'     => '<span class="ab-icon"></span><span class="ab-label">' . __( 'Console Logging' , 'console-logging' ) . '</span>',
        'id'        => 'your-custom-id',
        'parent'    => false,
        'href'      => '',
        'meta'      => array('class' => 'is-admin-'.is_admin())//GET ACTUAL ADMIN OR NOT in php before page load
));

Get the menu item using jQuery in javascript and use it:

 //'is-admin-1' when is_admin() is true
 //'is-admin-0' when is_admin() is false

var is_admin = $('#wp-admin-bar-your-custom-id').hasClass('is-admin-1');

if(is_admin){
    //You are actually on an admin page
}else{
    //You are on a front end page
}
0

@fuxia's comment is the best if you want to test and specifically include ajax calls:

if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) :

and @wpclevel's answer is best if you want to test to specifically exclude any admin/dashboard screens:

if ( ! isset( $GLOBALS['current_screen'] ) && ! is_customize_preview() ) :

There is a lot of overlapping use cases where either one would work, but sometimes you will need one or the other of these solutions.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.