0

I'm debugging a query created by the Post widget of Elementor, it should exclude the post with id 12419. I see the

[post__not_in] => Array
                    (
                        [0] => 12419
                    )

inside the [query] part, but the post is returned by the query (as you can see below from the dump of the query object).

WP_Query Object
(
    [query] => Array
        (
            [posts_per_page] => 20
            [paged] => 1
            [post_status] => publish
            [post_type] => post
            [orderby] => post_date
            [order] => desc
            [ignore_sticky_posts] => 1
            [post__not_in] => Array
                (
                    [0] => 12419
                )
        )
    [query_vars] => Array
        (
            [posts_per_page] => 20
            [paged] => 1
            [post_status] => publish
            [post_type] => post
            [orderby] => post_date
            [order] => DESC
            [ignore_sticky_posts] => 1
            [cache_results] => 1
            [update_post_term_cache] => 1
            [lazy_load_term_meta] => 1
            [update_post_meta_cache] => 1
            [comments_per_page] => 50
        )
    [tax_query] => WP_Tax_Query Object
        (
            [relation] => AND
            [primary_table] => wp_posts
            [primary_id_column] => ID
        )
    [meta_query] => WP_Meta_Query Object
        (
        )
    [request] => SELECT SQL_CALC_FOUND_ROWS  wp_posts.ID FROM wp_posts  WHERE 1=1  AND wp_posts.post_type = 'post' AND ((wp_posts.post_status = 'publish'))  ORDER BY wp_posts.post_date DESC LIMIT 0, 20
    [posts] => Array
        (
            [0] => WP_Post Object
                (
                    [ID] => 12419
                    [post_author] => 7
                    [post_date] => 2021-07-30 14:04:14
                    [post_date_gmt] => 2021-07-30 12:04:14
                    [post_content] => [post_title] => Attacchi di Panico: Cosa Sono, Sintomi, Cause, Conseguenze e Cura
                    [post_status] => publish
                    [comment_status] => open
                    [ping_status] => closed
                    [post_name] => attacchi-di-panico
                    [post_modified] => 2021-07-30 14:04:20
                    [post_modified_gmt] => 2021-07-30 12:04:20
                    [guid] => https://www.psicocultura.it/?p=12419
                    [post_type] => post
                    [filter] => raw
                    [word_count] => 2601
                    [permalink] => https://www.psicocultura.it/attacchi-di-panico/
                )
            [1] => WP_Post Object
                (
                    /*...*/
                )
            
    [current_comment] => -1
    [found_posts] => 137
    [max_num_pages] => 7
    [is_home] => 1
    [query_vars_hash:WP_Query:private] => 4c5b129a335cdd7e2b67ea909788224a
    [query_vars_changed:WP_Query:private] => 1
    [compat_fields:WP_Query:private] => Array
        (
            [0] => query_vars_hash
            [1] => query_vars_changed
        )
    [compat_methods:WP_Query:private] => Array
        (
            [0] => init_query_flags
            [1] => parse_tax_query
        )
)

1 Answer 1

2

Those [query] and [query_vars], i.e. WP_Query::$query and WP_Query::$query_vars, are defined as: (see source on Trac)

class WP_Query {

  /**
   * Query vars set by the user
   *
   * @since 1.5.0
   * @var array
   */
  public $query;

  /**
   * Query vars, after parsing
   *
   * @since 1.5.0
   * @var array
   */
  public $query_vars = array();

So the [query] is an array of arguments that are passed to the WP_Query class (the $args array in the following example), whereas the [query_vars] is an array of arguments in the [query] array and the default arguments like the ones listed here and including custom arguments that were not originally set in the [query], but are later set using hooks such as pre_get_posts.

So for example, with this:

$args = array(
    'posts_per_page' => 20,
    'post__not_in'   => [ 12419 ],
    'custom_arg'     => true,
);

$query = new WP_Query( $args );
  • var_dump( $query->query ); would output only the items in the above array:

    array(3) {
      ["posts_per_page"]=>
      int(20)
      ["post__not_in"]=>
      array(1) {
        [0]=>
        int(12419)
      }
      ["custom_arg"]=>
      bool(true)
    }
    
  • var_dump( $query->query_vars ); would also output the same items, but with many other items (note the array(64) below) like error and m:

    array(64) {
      ["posts_per_page"]=>
      int(20)
      ["post__not_in"]=>
      array(1) {
        [0]=>
        int(12419)
      }
      ["custom_arg"]=>
      bool(true)
      ["error"]=>
      string(0) ""
      ["m"]=>
      string(0) ""
      ["p"]=>
      int(0)
      ...
    }
    

Now, if I used pre_get_posts to change the post__not_in argument and also to add another custom argument:

add_action( 'pre_get_posts', function ( $query ) {
    if ( $query->get( 'custom_arg' ) ) {
        $query->set( 'post__not_in', [] );

        $query->set( 'custom_arg2', 'foo bar baz' );
    }
} );
  • var_dump( $query->query ); would show no changes, but var_dump( $query->query_vars ); would now output:

    array(65) {
      ["posts_per_page"]=>
      int(20)
      ["post__not_in"]=>
      array(0) {
      }
      ["custom_arg"]=>
      bool(true)
      ["error"]=>
      string(0) ""
      ["m"]=>
      string(0) ""
      ["p"]=>
      int(0)
      ...
      ["custom_arg2"]=>
      string(11) "foo bar baz"
      ...
    }
    
  • And if I apply array_filter() on the query_vars array, i.e. var_dump( array_filter( $query->query_vars ) ), then the output would no longer contain the post__not_in:

    array(9) {
      ["posts_per_page"]=>
      int(20)
      ["custom_arg"]=>
      bool(true)
      ["custom_arg2"]=>
      string(11) "foo bar baz"
      ["cache_results"]=>
      bool(true)
      ["update_post_term_cache"]=>
      bool(true)
      ["lazy_load_term_meta"]=>
      bool(true)
      ["update_post_meta_cache"]=>
      bool(true)
      ["comments_per_page"]=>
      string(2) "50"
      ["order"]=>
      string(4) "DESC"
    }
    

So I don't know how did you debug the query in question, i.e. I don't know what code or plugin you used, but I presumed that the [query_vars] values were filtered (empty ones were removed) (by your debug code?) and secondly, the post__not_in argument is probably being filtered similar or the same way I did it above.

Therefore if you can, try suppressing filters by adding 'suppress_filters' => true to the query arguments, and see if the post__not_in array is now good or that the post 12419 is now being excluded from the results.

1
  • 1
    Thank you very much and congratulations, it is a really great answer
    – Revious
    Commented Aug 2, 2021 at 8:24

Your Answer

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

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