2

I'm running in to a bit of a problem.

I have a function called get_press(), it retrieves newest press items. It is inside of a plugin:

class EWPress {
    function __construct()
    {
        load_plugin_textdomain( 'ew', flase, dirname( plugin_basename( __FILE__ ) ) . '/lang' );

        add_action( 'wp_enqueue_scripts', array( &$this, 'register_plugin_scripts' ) );

        // Add JS var ajaxurl to global namespace
        add_action( 'wp_head', array( &$this, 'add_ajax_library' ) );

        add_action( 'wp_ajax_get_press', array( &$this, 'get_press' ) );
        add_action( 'wp_ajax_nopriv_get_press', array( &$this, 'get_press' ) );

    }

    public function get_press()
    {
        $args = array(
            'status' => 'publish',
            'post_type' => 'press',
            'orderby' => 'meta_value',
            'meta_key' => 'press_date',
            'order' => 'DESC',
            'posts_per_page' => 2
        );

        $query = new WP_Query($args);
            return($query->posts);
            //echo json_encode($query->posts);
            //die();
    }
}

If I call this function directly in a template file via: echo EWPress::get_press() the output is completely fine:

Array
(
    [0] => WP_Post Object
        (
            [ID] => 229
            [post_author] => 1
            [post_date] => 2013-01-18 00:29:58
            [post_date_gmt] => 2013-01-18 00:29:58
            [post_content] => 
            [post_title] => Rundown
            [post_excerpt] => 
            [post_status] => publish
            [comment_status] => closed
            [ping_status] => closed
            [post_password] => 
            [post_name] => rundown
            [to_ping] => 
            [pinged] => 
            [post_modified] => 2013-01-18 00:29:58
            [post_modified_gmt] => 2013-01-18 00:29:58
            [post_content_filtered] => 
            [post_parent] => 0
            [guid] => http://site.com/?post_type=press&p=229
            [menu_order] => 0
            [post_type] => press
            [post_mime_type] => 
            [comment_count] => 0
            [filter] => raw
        )

    [1] => WP_Post Object
        (
            [ID] => 231
            [post_author] => 1
            [post_date] => 2013-01-18 00:44:35
            [post_date_gmt] => 2013-01-18 00:44:35
            [post_content] => 
            [post_title] => Clean Plates
            [post_excerpt] => 
            [post_status] => publish
            [comment_status] => closed
            [ping_status] => closed
            [post_password] => 
            [post_name] => clean-plates
            [to_ping] => 
            [pinged] => 
            [post_modified] => 2013-01-18 00:44:35
            [post_modified_gmt] => 2013-01-18 00:44:35
            [post_content_filtered] => 
            [post_parent] => 0
            [guid] => http://site.com/?post_type=press&p=231
            [menu_order] => 0
            [post_type] => press
            [post_mime_type] => 
            [comment_count] => 0
            [filter] => raw
        )

)

In order to make an AJAX request, I:

  • comment out the echo EWPress::get_press() on the template level
  • comment out the return $query->posts in the get_press() function
  • un-comment the echo json_encode($query->posts)
  • un-comment the die();

However, when I make the AJAX request to the SAME function the returned data is different (namely it is ignoring order = 'ASC' or 'DESC).

AJAX Function:

(function($) {
    $(document).ready(function(){
        $.ajax({
            url: ajaxurl,
            type: 'POST',
            dataType: 'json',
            data: {action: 'get_press'},
            complete: function(xhr, textStatus) {
                //
            },
            success: function(data, textStatus, xhr) {
                console.log(data);
            },
            error: function(xhr, textStatus, errorThrown) {
            //called when there is an error
            }
        });
    });
})(jQuery);

The console.log:

[Object, Object]
0: Object
    ID: 234
    comment_count: "0"
    comment_status: "closed"
    filter: "raw"
    guid: "http://site.com/?post_type=press&p=234"
    menu_order: 0
    ping_status: "closed"
    pinged: ""
    post_author: "1"
    post_content: ""
    post_content_filtered: ""
    post_date: "2013-01-18 02:33:41"
    post_date_gmt: "2013-01-18 02:33:41"
    post_excerpt: ""
    post_mime_type: ""
    post_modified: "2013-01-18 02:33:41"
    post_modified_gmt: "2013-01-18 02:33:41"
    post_name: "eater"
    post_parent: 0
    post_password: ""
    post_status: "publish"
    post_title: "Eater"
    post_type: "press"
    to_ping: ""
    __proto__: Object
1: Object
    ID: 231
    comment_count: "0"
    comment_status: "closed"
    filter: "raw"
    guid: "http://site.com/?post_type=press&p=231"
    menu_order: 0
    ping_status: "closed"
    pinged: ""
    post_author: "1"
    post_content: ""
    post_content_filtered: ""
    post_date: "2013-01-18 00:44:35"
    post_date_gmt: "2013-01-18 00:44:35"
    post_excerpt: ""
    post_mime_type: ""
    post_modified: "2013-01-18 00:44:35"
    post_modified_gmt: "2013-01-18 00:44:35"
    post_name: "clean-plates"
    post_parent: 0
    post_password: ""
    post_status: "publish"
    post_title: "Clean Plates"
    post_type: "press"
    to_ping: ""
    __proto__: Object
length: 2
__proto__: Array[0]

Does anyone know why this would be happening?

2
  • Where is the function that handles that AJAX action? It should be hooked to wp_ajax_*. You didn't post that.
    – s_ha_dum
    Jan 18, 2013 at 4:02
  • That doesn't really affect the overall problem, but I added it for completeness. I also completely re-edited the question.
    – tr3online
    Jan 18, 2013 at 21:22

4 Answers 4

3

I believe Milo is right, it's probably a filter affecting this. Ajax requests look like admin requests (that is, is_admin() returns true), so it's possible that something is checking if is_admin() and adding the filter in those cases.

You can set 'suppress_filters' => true in your args array and it will probably work. Note that doing so can prevent a query from being cached, or prevent plugins from doing what they need to with a query. It's possible that this may not affect you, but still something to keep in mind.

1

pre_get_posts actions can also affect query params. You can try adding remove_all_actions('pre_get_posts'); to your ajax handler before WP_Query. If this helps, check actions with

global $wp_filter
print_r($wp_filter['pre_get_posts']);

to see what can break WP_Query behavior. In my case it was Simple Custom Post Order which affected WP_Query in ajax mode.

0

For some odd reason WP_Query is the culprit behind this issue.

When doing an AJAX request to a function that returns a WP_Query object, the $query->posts object completely ignores any of the arguments supplied in $args.

A simple work around was to use get_posts instead with the same $args as with the WP_Query

One unfortunate drawback of this method is the loss of nice features of a WP_query object, such as $query->max_num_pages.

2
  • 2
    get_posts just creates a WP_Query instance, your issue is likely elsewhere, possibly a filter, which are suppressed by default when get_posts is used.
    – Milo
    Jan 18, 2013 at 23:10
  • Any idea which filters? I'd love to look in to this. It is quite odd that it would work fine on a non-AJAX request but switch with an AJAX request. I don't know what filters would kick in in that situation unless wp_ajax_action triggers something I'm unaware of.
    – tr3online
    Jan 30, 2013 at 4:55
-2
'suppress_filters' => true

This work for me!

1
  • 4
    And why does it work?
    – kaiser
    Oct 8, 2014 at 16:06

Your Answer

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

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