I am a bit stuck with setting up this date query. I am using a dropdown select box to allow the user to choose which date archive they want to view. It works for the months, but when I select the year option it will only show 1 month from that year. I am also allowing the category to be queried, but I don't think that is affecting the date query.

I know that I'm going wrong somewhere, but I can't pinpoint the problem exactly.

 <?php $cat_query = array(array('relation' => 'AND'));

    if( isset( $_GET['category'] ) && $_GET['category'] ){

        $cat_area_query = array( 'taxonomy' => 'category', 'field' => 'slug', 'terms' => $_GET['category'],'operator' => 'IN', );
        $cat_query[] = $cat_area_query;

    if( $cat_query && $cat_query ){
        $cat_query['relation'] = 'AND'
    $m = get_the_time('m');
    $y = get_the_time('Y');

    $args = array(
        'post_type'      => array('post'),
        'post_status'    => 'publish',
        'tax_query'      => $cat_query,
        'orderby'        => 'date',
        'order'              => 'desc',
          'date_query' => array(
           'relation' => 'OR',
            'year'  => $y,
            'month' => $m,
            'compare'   => '=',
       $posts_query = new WP_Query( $args);?>

1 Answer 1


You have not stated how the selection works, but you need to have some kind of conditional set when a specific month is selected and when a year archive is selected. I also do not know where get_the_time comes in or its relevance to the query.

But anyways, there are some other really big issues that I would like to discuss as well. You are using non-sanitized input values from the URL. This is really a huge security risks and one of the number one spots which hackers use to hack your site. GOLDEN RULE: NEVER EVER trust any input values coming from anywhere or anyone, not even from yourself. In your example, it is really easy to pass malicious code to your category parameter through the URL, and because you do not validate and escape it, this code has the freedom to do whatever it does, and one hacker jumps up and down because he have destroyed another site

In stead of using $_GET['category'], you can simply use filter_input which validates the parameter and either returns the value or false if the parameter is not set. You also have the added bonus of sanitizing the input via the filter's third parameter. Because this is a slug, we will use FILTER_SANITIZE_STRING

When you create a tax_query, you do not need to set the relation parameter on a single array, furthermore, the default is AND, so you do not need to set it

You would also want to set your parameters according to condition. Here is an example of your code: (Note: This is untested and need PHP 5.4+)

    $category_slug = filter_input( 
        INPUT_GET, // Global variable to use, in this case it will be a $_GET variable
        'category', // Name or the parameter to get value from
        FILTER_SANITIZE_STRING // Use the FILTER_SANITIZE_STRING filter to sanitize the returned value
    // Check if $category_slug has a vlaue, if so, set the tax_query
    $cat_area_query = [];
    if( $category_slug ){
        $cat_area_query = [
                'taxonomy' => 'category', 
                'field'    => 'slug', 
                'terms'    => $category_slug // No need to sanitize, the value is already sanitized
                // The operator is set to IN by default

    $date_query = [];
    // I have kept the month and year values the same as in your question though I doubt if this is correct
    $m = filter_var( get_the_time( 'm' ), FILTER_VALIDATE_INT ); // Sanitize and validate value as an integer
    $y = filter_var( get_the_time( 'Y' ), FILTER_VALIDATE_INT ); // Sanitize and validate value as an integer
    if ( 'some_condition_for_month' ) {
        $date_query = [
                'year'  => $y,
                'month' => $m
    } elseif ( 'some_condition_for_year' ) {
        $date_query = [
                'year' => $y,

    $args = [
        // The post_type and post_status parameters are set by default to 'post' and 'publish'
        // orderby 'date' is default
        'order'      => 'desc',
        'tax_query'  => $cat_area_query,
        'date_query' => $date_query
    $posts_query = new WP_Query( $args );
  • 1
    I like the "not even from yourself" part. Sometimes we are our own worst enemy ;-)
    – birgire
    Commented Sep 25, 2015 at 14:32
  • @birgire that is such a proven fact over and over again, ;-) Commented Sep 25, 2015 at 15:14
  • @Gennie I'm glad you found it helpful, always happy to try and help. Enjoy :-) Commented Sep 25, 2015 at 15:15

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.