0

I am covering several options in a single file, and loading posts via AJAX so I put in data attributes query variables: cat, tag_id, author, year and monthnum.

Based on what is present or not (if you're on category page the cat query variable will be some number, but tag_id will be empty for instance). Now the query looks like this:

$cat = ( isset( $_GET['cat'] ) && '' !== $_GET['cat'] ) ? sanitize_text_field( wp_unslash( $_GET['cat'] ) ) : ''; // Input var okay.
$tag = ( isset( $_GET['tag'] ) && '' !== $_GET['tag'] ) ? sanitize_text_field( wp_unslash( $_GET['tag'] ) ) : ''; // Input var okay.
$year = ( isset( $_GET['year'] ) && '' !== $_GET['year'] ) ? sanitize_text_field( wp_unslash( $_GET['year'] ) ) : ''; // Input var okay.
$month = ( isset( $_GET['month'] ) && '' !== $_GET['month'] ) ? sanitize_text_field( wp_unslash( $_GET['month'] ) ) : ''; // Input var okay.
$author = ( isset( $_GET['author'] ) && '' !== $_GET['author'] ) ? sanitize_text_field( wp_unslash( $_GET['author'] ) ) : ''; // Input var okay.
$post__not_in = ( isset( $_GET['post__not_in'] ) && '' !== $_GET['post__not_in'] ) ? sanitize_text_field( wp_unslash( $_GET['post__not_in'] ) ) : ''; // Input var okay.

$the_query = new WP_Query(array(
    'cat'          => $cat,
    'tag_id'       => $tag,
    'author'       => $author,
    'date_query' => array(
        array(
            'year'  => $year,
            'month' => $month,
        ),
    ),
    'post_status'  => 'publish',
    'post__not_in' => json_decode( $post__not_in, true ),
));

post__not_in is there to make sure that when I set the home page as a blog page, that I get the correct posts loaded (I had some issues with paged variable and sticky posts, and this solved that issue).

Now what I haven't found is, will having empty query arguments make the query slower?

Should I base my query arguments based on what variable is empty? Is this better thing to do than to just put it all in one array? Something tells me that this is better because there are less query variables and therefore the query is more specific?

Also when loading posts using AJAX, should I add no_found_rows => 1, because I'm not using pagination? This should make my query even more faster from what I've read.

Any advice is welcome :)

1 Answer 1

1

I would not write it the same way, because the more cluttered a query gets, the more likely it is to return unexpected results.

Here's how I'd handle your code:

$args = array(); // All your WP_Query args go here.

// You don't need to pass 'post_status' => 'publish' because that's default

// Replace all instances of [ isset && '' !== ] with !empty
if ( !empty( $_GET['cat'] ) ) 
    $args['cat'] = sanitize_text_field( wp_unslash( $_GET['cat'] ) );

if ( !empty( $_GET['tag'] ) )
    $args['tag_id'] = sanitize_text_field( wp_unslash( $_GET['tag'] ) );

if ( !empty( $_GET['year'] ) || !empty( $_GET['month'] ) ) {
    $date_query = array();
    if ( !empty( $_GET['year'] ) )
        $date_query['year'] = sanitize_text_field( wp_unslash( $_GET['year'] ) );
    if ( !empty( $_GET['month'] ) )
        $date_query['month'] = sanitize_text_field( wp_unslash( $_GET['month'] ) );
    $args['date_query'] = array( $date_query );
}

if ( !empty( $_GET['post__not_in'] ) )
     $args['post__not_in'] = sanitize_text_field( wp_unslash( $_GET['post__not_in'] ) );

$the_query = new WP_Query( $args );

It seems a little weird to me that you'd need to unslash paired with sanitize, but if you feel it's necessary, I'll leave it in for the time being, otherwise, I'd probably only run sanitize.

As it pertains to AJAX, I haven't personally used no_found_rows, so I can't speak to that. The AJAX protocols I've written usually are paired with an input that has the current offset of "pages" of posts being shown.

2
  • The sanitization and unslashing are because I want to avoid phpcs errors, not a necessity per se. I tried with offset but with that or paged the results were off. I like the setting of arguments in the array the way you did it, didin't thought of setting it that way. Will test it out :)
    – dingo_d
    Nov 28, 2016 at 16:01
  • Works fine, I just had to add the $args['post_status'] = 'publish'; because it showed the posts that were in draft, on the front page. Thanks!
    – dingo_d
    Nov 29, 2016 at 7:03

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.