Conditional check for front-end which includes ajax

I need a conditional which exits if the context is not a front-end view including AJAX requests. I have this at the moment:

if (is_admin() && !DOING_AJAX) 
    return;

The DOING_AJAX bit is required since is_admin() returns true for ajax requests. However I believe DOING_AJAX will be true for ALL ajax requests including those on the backend. Thus it doesn’t really add anything here.

Read More

How can I fork the two conditions? Can front-end/back-end ajax requests be distinguished?

thanks!

Clarification

Thanks for the insights but to clarify, in this instance, the hook itself is NOT an ajax action. It’s a filter hook into get_the_terms which needs to operate on any front-end request including any arbitrary theme or plugin ajax code. It also needs to bypass processing for the back-end hence the need for the forking condition. The problem is that ajax requests always return true for is_admin()

In case you are curious it’s a plugin which hides “secret” or “hidden” tags on the front-end, while still allowing their taxonomy pages to exist. The “hiding” needs to be bypassed on the backend for obvious reasons.

Thanks for the help. Sorry for the initial confusion!

Related posts

Leave a Reply

5 comments

  1. DOING_AJAX and WP_ADMIN (this constant is checked within is_admin() ) are defined in admin-ajax.php and set tro true. Both are not very helpfull in this situation.

    Add a parameter to your ajax request if the request come from the front-end:

    <?php
    
    function my_action_javascript() {
    
    ?>
    <script type="text/javascript" >
    jQuery(document).ready(function($) {
    
        var data = {
            action: 'my_action',
            frontend_request: true,
            whatever: 1234
        };
    
        // since 2.8 ajaxurl is always defined in the admin header and points to admin-ajax.php
        $.post(ajaxurl, data, function(response) {
            alert('Got this from the server: ' + response);
        });
    });
    </script>
    <?php
    }
    

    In your ajax callback you can now check if the parameter is present and set to true:

    $from_frontend = isset( $_REQUEST['frontend_request'] ) && ( TRUE === (bool) $_REQUEST['frontend_request'] );
    $doing_ajax = defined( 'DOING_AJAX' ) && TRUE === DOING_AJAX;
    $is_frontend_request = $frontend && $doing_ajax; 
    
    if( TRUE === $is_frontend_request ){
        // yes, this request came from the front-end
        echo 'On frontend';
    } else {
        // no, we are somewhere else
        echo 'Somewhere else';
    }
    
  2. Probably you are using AJAX hook

    add_action('wp_ajax_{your_hook}', 'your_function');
    

    in your_function you can add:

    function your_function() {
    
      define('FRONT_AJAX',true);
    
    }
    

    So you can add your needed check like this:

    if (is_admin() && defined('FRONT_AJAX')) 
    return;
    
  3. Simple use a separate actions for front-end and admin ajax requests.

    Regardless of whether the request is from the front-end or admin:

    • wp_ajax_{action} is triggered when the user is logged in
    • wp_ajax_nopriv_{action} is triggered when the user is not.

    So if you want to discern whether the request is from the front-end, or the admin – I recommend using different actions. This is similar to @Ralf912 approach – except rather than sending a separate variable just have different actions for front-end and admin-requests.

    You can also protect yourself from being ‘duped’ by using nonces (but if security is an issue – you should only be using wp_ajax_{action} when the request is from an admin screen).

  4. The idea shared by Stephen Harris is nice, but my idea is very simple.

    is_admin() returns always true whether it is from back or front ajax request.
    

    Just define two different names for the nonce field. (So, other than the developer, no one will know which name for which purpose.) Example:

    add_action('wp_ajax_{my_ajax_hook}', 'my_ajax_function');
    function my_ajax_function() {
    
        if( isset($_REQUEST['f_nonce']) ){
            $fromFront = true;
            $nonceField = 'f_nonce';
        }else{
            //by default from backend or you can alter;
            $fromFront = false;
            $nonceField = 'b_nonce';
        }
    
        if ( ! wp_verify_nonce( $_REQUEST[$nonceField], 'my-nonce-pass' ) ) {
            die( 'Security check' ); 
    
        } else {
            // Do stuff here according to the value of $fromFront;
    
        }
        exit();
    }
    

    * The nonce data should be with each ajax call to secure your script according to http://codex.wordpress.org/AJAX_in_Plugins .

  5. You, guys, are very close! But wp_ajax_** hooks fire later than we usually need that constant FRONT_AJAX.
    So, my solution works better as for my needs.

    in functions.php:

    add_action( 'init', 'ib_define_front_ajax', 1 );
    function ib_define_front_ajax(){
        if (isset($_REQUEST['FRONT_AJAX']) && $_REQUEST['FRONT_AJAX']=='true')
            define('FRONT_AJAX',true);
    }
    

    Then, when you need to exclude:

    if ( !is_admin() || defined('FRONT_AJAX'))
    

    Or to just check (as per gagn’s answer):

    if (is_admin() && defined('FRONT_AJAX')) 
    return;