Search code examples
wordpresswordpress-rest-api

Why does my WP_Query not find one result?


I have a plugin I wrote which works perfectly for all functions except one. The one which doesn't quite work is when I am performing a WP_Query within a REST API function which looks like this:

  $args = array(
    'post_type' => 'download',
    'post_status' => 'publish',
    'posts_per_page' => 100,
    'paged' => $request['id']
  );

  $posts = new WP_Query( $args );

It correctly returns every single post_type of type download except one which never get's included in the results. If I use get_post( 1256 ) then I get the following:

{
    "ID": 1256,
    "post_author": "1",
    "post_date": "2021-06-17 09:57:06",
    "post_date_gmt": "2021-06-17 08:57:06",
    "post_content": "An example: hello world",
    "post_title": "My Ticket",
    "post_excerpt": "",
    "post_status": "publish",
    "comment_status": "closed",
    "ping_status": "closed",
    "post_password": "",
    "post_name": "my-ticket",
    "to_ping": "",
    "pinged": "",
    "post_modified": "2021-06-17 10:28:08",
    "post_modified_gmt": "2021-06-17 09:28:08",
    "post_content_filtered": "",
    "post_parent": 0,
    "guid": "https://www.example.com/my-ticket",
    "menu_order": 0,
    "post_type": "download",
    "post_mime_type": "",
    "comment_count": "0",
    "filter": "raw"
}

This looks like my query is correct and this post should be returned, i.e. it's the correct download post_type and it is post_status of publish.

I can't see why else my query wouldn't work. What have I missed or is there some other filter that would be stopping it being returned?


Solution

  • As you have mentioned in the comment.

    You were correct. AND wp_posts.ID NOT IN (1256) is in the SQL. How can I query my data correctly? I can't turn off the plugins, I just want to control my own data.

    As I don't have the plugin code, I would try to explain how you can bypass the exclusion of the post id.

    Lets suppose this is the code that is excluding the post.

    add_action('pre_get_posts','alter_query');
    
    function alter_query($query) {
        $query-> set('post__not_in' ,array(33));
    }
    

    There can be other actions as well which would be triggering this exclusion.

    If you are getting you code using the following function.

    function get_data() {
        $args = array(
            'post_type' => 'page',
            'post_status' => 'publish',
            'posts_per_page' => 100,
        );
    
        $posts = new WP_Query( $args );
    
        return $posts;
    }
    
    var_dump(get_data());
    

    then you can get rid of the exclusion like this.

    function get_data() {
        // Remove the removal action
        remove_action( 'pre_get_posts', 'alter_query' );
        $args = array(
            'post_type' => 'page',
            'post_status' => 'publish',
            'posts_per_page' => 100,
        );
    
        $posts = new WP_Query( $args );
    
        // Add the removal action back.
        add_action( 'pre_get_posts', 'alter_query' );
    
        return $posts;
    }
    
    

    This way your aren't acutally changing any code of your plugin, you are just switching it off when you want to run your code.

    This is just an example you would want to change it according to your own situation.

    Finding action code which is causing issue.

    1. Install Query Monitor plugin and activate it.

    2. Run your query on a particular page and visit the page with admin logged in. You will see query monitors tab on admin bar. enter image description here

    3. Click on it to open and select Hooks and Actions. enter image description here

    4. Make a search (ctrl + f) for "pre_get_posts" in the hooks column. This on the condition that pre_get_posts is only used to alter the query. enter image description here

    5. Once you find the instance of you can check the name of the function. In this case : alter_query() and the location wp-content/themes/storefront/functions.php:113

    Once you have the function name you remove and add the action as shown above. remove_action( 'pre_get_posts', 'alter_query' );