Right now for my plugin, I am using in_admin() to determine if the user is in the frontend of the site or in the admin area. However, the problem occurs when plugins use admin-ajax.php to process ajax requests.

I need a way to register hooks and plugins only when processing admin-ajax.php file or in the frontend of the site. What is the best way to go about doing that?

up vote 57 down vote accepted

Check the constant DOING_AJAX. Its definition is the first working code in wp-admin/admin-ajax.php. Some very weird plugins, like Jetpack, are defining that constant in unexpected places, so you might include a check for is_admin() as well.

Example:

if ( is_admin() && defined( 'DOING_AJAX' ) && DOING_AJAX )
{
    // do something
}

I have asked for a simpler way to check this a long time ago, and this was finally implemented in 4.7.0.

So for WP 4.7 and higher you can use:

if ( wp_doing_ajax() )
{
    // do something
}
  • 4
    if ( defined( 'DOING_AJAX' ) ) is enough by itself. The constant is only set in admin-ajax.php so you don't need to check for a value. – John Reid Nov 26 '14 at 13:55
  • 5
    @JohnReid It is a global constant, anyone can set it to any value, including FALSE. – fuxia Nov 26 '14 at 16:36
  • Good point. There's nowhere in the WP core that sets this value but I suppose that it doesn't mean that some rogue plugin might not set it to false instead. A +1 for you, sir! – John Reid Dec 1 '14 at 10:32
  • 1
    It is the codex way, but in practice I saw people setting that flag in their theme, so this solution is good if you want to know if you should behave like it is ajax, but might not be best if you actually need to know if it is ajax request. – Mark Kaplun Mar 11 '16 at 9:05

Good news, the function is there now.

File: /wp-includes/load.php
1037: /**
1038:  * Determines whether the current request is a WordPress Ajax request.
1039:  *
1040:  * @since 4.7.0
1041:  *
1042:  * @return bool True if it's a WordPress Ajax request, false otherwise.
1043:  */
1044: function wp_doing_ajax() {
1045:   /**
1046:    * Filters whether the current request is a WordPress Ajax request.
1047:    *
1048:    * @since 4.7.0
1049:    *
1050:    * @param bool $wp_doing_ajax Whether the current request is a WordPress Ajax request.
1051:    */
1052:   return apply_filters( 'wp_doing_ajax', defined( 'DOING_AJAX' ) && DOING_AJAX );
1053: }

Just to recap, the admin-ajax.php defines something like this.

File: /wp-admin/admin-ajax.php
11: /**
12:  * Executing Ajax process.
13:  *
14:  * @since 2.1.0
15:  */
16: define( 'DOING_AJAX', true );
17: if ( ! defined( 'WP_ADMIN' ) ) {
18:     define( 'WP_ADMIN', true );
19: }
  • Thanks for the update! I missed that one in the 4.7 release notes. – Tom Auger Feb 1 '17 at 2:11
  • Hey @TomAuger, cool. This function is a Michael Jordan of ajax. Thanks 23 – prosti Feb 1 '17 at 14:42

Fuxias solution returns false also for ajax request made from the admin panel. But these requests should return true, because the data you are requesting is provided for an admin view. To solve this issue you can use the following function:

function saveIsAdmin() {
    //Ajax request are always identified as administrative interface page
    //so let's check if we are calling the data for the frontend or backend
    if (wp_doing_ajax()) {
        $adminUrl = get_admin_url();
        //If the referer is an admin url we are requesting the data for the backend
        return (substr($_SERVER['HTTP_REFERER'], 0, strlen($adminUrl)) === $adminUrl);
    }

    //No ajax request just use the normal function
    return is_admin();
}

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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