Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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?

share|improve this question
    
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 '13 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 '13 at 21:22

2 Answers 2

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.

share|improve this answer
1  
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 '13 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 '13 at 4:55

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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