35

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?

4 Answers 4

72

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
  • 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
    Commented Nov 26, 2014 at 13:55
  • 5
    @JohnReid It is a global constant, anyone can set it to any value, including FALSE.
    – fuxia
    Commented Nov 26, 2014 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
    Commented Dec 1, 2014 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. Commented Mar 11, 2016 at 9:05
6

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: }
2
  • Thanks for the update! I missed that one in the 4.7 release notes.
    – Tom Auger
    Commented Feb 1, 2017 at 2:11
  • Hey @TomAuger, cool. This function is a Michael Jordan of ajax. Thanks 23
    – prosti
    Commented Feb 1, 2017 at 14:42
1

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();
}
1

DOING_AJAX constant checks if you are in admin-ajax.php

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

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