WordPress: Query posts by date range - php

I'm working on pages in a WordPress site to show "Upcoming" and "Archived" events by date range using custom fields for event_start_date and event_end_date with the custom post type event. I'd like the "Upcoming" page to show posts for which the current date falls within this range and/or equals the start date or end date; and the "Archive" page to show events for which the current date is after the date range entirely. Thus, if today is October 10, and an event with the dates October 9-11 or October 10-12 would show on "Upcoming" and an event with any previous dates would show on the "Archived" page.
I'm including my queries below for both the upcoming and archive pages; the query for upcoming seems to be working ok, but in the archive page if the current date falls within the date range it will still show, and I'd like it to only show past events:
/* upcoming events query */
$event_args = array(
'post_type' => 'event',
'ignore_sticky_posts' => 1,
'posts_per_page' => 10,
'post_status' => 'publish',
'paged' => get_query_var( 'paged' ),
'orderby' => 'meta_value_num',
'order' => 'ASC',
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'event_start_date',
'type' => 'DATE',
'value' => current_time('Ymd'),
'compare' => '>=',
),
array(
'key' => 'event_end_date',
'type' => 'DATE',
'value' => current_time('Ymd'),
'compare' => '>=',
),
),
);
/* archived events query */
$event_args = array(
'post_type' => 'event',
'ignore_sticky_posts' => 1,
'posts_per_page' => 10,
'post_status' => 'publish',
'paged' => get_query_var( 'paged' ),
'orderby' => 'meta_value_num',
'order' => 'ASC',
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'event_start_date',
'type' => 'DATE',
'value' => current_time('Ymd'),
'compare' => '<',
),
array(
'key' => 'event_end_date',
'type' => 'DATE',
'value' => current_time('Ymd'),
'compare' => '<',
),
),
);
Thus, the meta_query for the upcoming events query seems to be working for all cases, but that for the archive page is not behaving as intended. Thank you for any assistance here, and please let me know if my question is unclear in any way. EDIT I initially neglected to mention that I also need to account for the scenario in which only a start date is entered, i.e. for single-day events, which is proving to be a sticking point for the archive page query.

In your archive query, you are using two meta_query conditions, I think the issue is with the first condition
First condition: event_start_date
array(
'key' => 'event_start_date',
'type' => 'DATE',
'value' => current_time('Ymd'),
'compare' => '<',
),
This will query all events if the event_start_date is less than current_time. Also consider that you are creating an OR relation.
Now, let's say today is Oct 10 and an even spans from Oct 9 to Oct 12, the above meta_query will include this event as well because the event_start_date is less than current_time. Make sense?
The solution will be to include meta_query for event_end_date only. This way, only events with ending date less than current_time will be queried.
/* archived events query */
$event_args = array(
'post_type' => 'event',
'ignore_sticky_posts' => 1,
'posts_per_page' => 10,
'post_status' => 'publish',
'paged' => get_query_var( 'paged' ),
'orderby' => 'meta_value_num',
'order' => 'ASC',
'meta_query' => array(
array(
'key' => 'event_end_date',
'type' => 'DATE',
'value' => current_time('Ymd'),
'compare' => '<',
),
),
);
Update:
Nested meta_query logic to handle single day past events as well.
/* archived events query */
$event_args = array(
'post_type' => 'event',
'ignore_sticky_posts' => 1,
'posts_per_page' => 10,
'post_status' => 'publish',
'paged' => get_query_var( 'paged' ),
'orderby' => 'meta_value_num',
'order' => 'ASC',
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'event_start_date',
'type' => 'DATE',
'value' => current_time('Ymd'),
'compare' => '<',
),
array(
'relation' => 'OR',
array(
'key' => 'event_end_date',
'type' => 'DATE',
'value' => current_time('Ymd'),
'compare' => '<',
),
array(
'key' => 'event_end_date',
'type' => 'DATE',
'value' => NULL,
'compare' => '=',
),
)
),
);

Related

WordPress Query order by two keys in dependency

I sort a query by a customfield start_date (form type Ymd). The sorting should always be descending from new to old. If there are multiple entries for the date on one day, the entries should be sorted by the order of publication.
I tried it with the (post) date, ID, menu_order but it never works in all cases.
The start_date may be a different day than the post date.
Is there any query way?
Or do I have to add hours and minutes to the news_start_date field?
Or maybe switch to the post date over all, but this means in this backend flow a big lost of elegance.
$meta_query = array(
'relation' => 'AND',
array(
'key' => 'news_start_date',
'value' => $today,
'compare' => '<=',
'type' => 'DATE'
),
array(
'relation' => 'OR',
array (
'relation' => 'AND',
array(
'key' => 'news_start_date',
'value' => $expire_date,
'compare' => '>=',
'type' => 'DATE'
),
array(
'key' => 'news_end_date',
'compare' => 'NOT EXISTS'
),
),
array (
'relation' => 'AND',
array(
'key' => 'news_end_date',
'compare' => 'EXISTS'
),
array(
'key' => 'news_end_date',
'value' => $today,
'compare' => '>=',
'type' => 'DATE'
),
),
),
);
$args = array(
'post_type' => 'news',
'meta_query' => $meta_query,
'posts_per_page' => $news_count,
'meta_key' => 'news_start_date',
'orderby' => 'meta_value',
'orderby' => array(
'meta_value' => 'DESC',
'ID' => 'DESC',
//'menu_order' => 'DESC',
//'date' => 'DESC',
//'publish_date' => 'DESC',
),
'order' => 'DESC',
'post__not_in' => $sticky_posts,
'ignore_sticky_posts' => true,
'cache_results' => true,
'update_post_meta_cache' => true,
'no_found_rows' => true,
'suppress_filters' => false,
);
I tried the others fields but there was never a 100% correct order

How do I use multiple comparison operators in a keyed array?

I'm using a custom post type for events, and trying to display events happening between now and 30 days from now. Pulling all the dates correctly, but I can't seem to get a range of dates into my comparison operators. Here's where I am:
$posts = get_posts(array(
'posts_per_page' => -1,
'post_type' => 'event',
'meta_query' => array(
array(
'key' => 'event_date',
'compare' => '<',
'value' => $nextMonthDate,
'type' => 'DATETIME'
)
),
'orderby' => 'meta_value',
'order' => 'ASC',
'meta_key' => 'event_date',
'meta_type' => 'DATETIME'
));
I also have a $date_now variable. Essentially I need an if (event_date >= $date_now && event_date < $nextMonthDate), but in this array, which I apparently need to use to pull other post data.
Thanks!
You can use multiple meta_query conditions as well. I think the following following snippet will help you achieve your expected filter. But didn't test it
$posts = get_posts(array(
'posts_per_page' => -1,
'post_type' => 'event',
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'event_date',
'value' => $now,
'type' => 'DATETIME',
'compare' => '>=',
),
array(
'key' => 'event_date',
'value' => $nextMonthDate,
'type' => 'DATETIME',
'compare' => '<',
),
),
'orderby' => 'meta_value',
'order' => 'ASC',
'meta_key' => 'event_date',
'meta_type' => 'DATETIME',
));
Note the $now I used, just pass on the current date there.
Extra
I think you can also use BETWEEN as compare operator and pass on an array of two items where first one is min and second one is maximum. I am not sure if this will work with DATETIME type or not but it surely does work with NUMERIC types.
$posts = get_posts(array(
'posts_per_page' => -1,
'post_type' => 'event',
'meta_query' => array(
array(
'key' => 'event_date',
'value' => array( $now, $nextMonthDate ),
'type' => 'DATETIME'
'compare' => 'BETWEEN',
),
),
'orderby' => 'meta_value',
'order' => 'ASC',
'meta_key' => 'event_date',
'meta_type' => 'DATETIME',
));

WP_Query exlude posts where meta_key => DeletedDate is older than

I created a custom post_type and need to configure my WP_Query a bit in archive.php.
In my archive.php I would like to retrieve all posts that do NOT have a date in meta_key => DeletedDate and is older than 2 weeks.
So, if a car has a date in meta_key => DeletedDate that is older than 2 weeks from today, it should be excluded from the WP_Query
My $args:
$today = strtotime('-1 weeks');
$args=array(
'posts_per_page' => -1,
'post_type' => 'vehicle',
'orderby' => 'title',
'order' => 'ASC',
'post_status' => 'publish',
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'DeletedDate',
'value' => $today,
'compare' => '<=',
),
array(
'key' => 'DeletedDate',
'value' => null,
'compare' => '=',
)
),
);
query_posts($args);
Hope it makes sense.

Don't display WordPress posts if time has passed using WP_Query

I have a custom post type of schedule which I can add 'events' with a custom field of Timeslot. This custom field is a repeater using ACF Pro.
It contains a date, start time and end time. Date picker and time pickers respectively.
On the homepage I have an image slider that pulls in the artwork and event title and only display 'todays' events, in time order.
What I want to do now is to not show events that have passed. So if the current time is 14:00pm for example, the all shows that ended before that time will not show. If the show started at 13:00pm and ends at 15:00pm though, that show will still show, and will appear first. I hope that makes sense?!
Here is my WP_Query so far but after a few attempts, I cannot figure out how to modify it to work as required:
<?php
$args = array(
'post_type' => 'schedule',
'posts_per_page' => '-1',
'meta_query' => array(
'relation' => 'AND',
'date_clause' => array(
'key' => 'schedule_time_slot_%_schedule_show_date',
'compare' => '=',
'value' => $day,
),
'time_clause' => array(
'key' => 'schedule_time_slot_%_schedule_show_start_time',
'compare' => 'EXISTS',
),
),
'orderby' => array(
'date_clause' => 'ASC',
'time_clause' => 'ASC',
)
);
<?php
$args = array(
'post_type' => 'schedule',
'posts_per_page' => '-1',
'meta_query' => array(
'relation' => 'AND',
'date_clause' => array(
'key' => 'schedule_time_slot_%_schedule_show_date',
'compare' => '=',
'value' => $day,
),
'time_clause' => array(
'key' => 'schedule_time_slot_%_schedule_show_start_time',
'compare' => '>=',
'value' => time(),
),
),
'orderby' => array(
'date_clause' => 'ASC',
'time_clause' => 'ASC',
)
);
Note the change in the time_clause argument. So only show time_clause when it equals or is later than the time now.

Date issue in custom post type loop (wordpress)

I am using a custom post type with custom date fields to display tour dates on a page. Some of the posts have both a "from" and "to" date (because they last for more than one day) and some only have "from" (because they're only one day), and I want all future or current tour dates to be displayed.
It's all working perfectly, except for some reason the posts that only have a "from" date stop showing if that date is in 2016 or later. It doesn't make any sense to me!
Here are the args:
$today = date('Ymd');
$tour_args = array(
'post_type' => 'tour_date',
'posts_per_page' => -1,
'orderby' => 'meta_value',
'meta_key' => 'tour-date-from',
'order' => 'ASC',
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'tour-date-from',
'value' => $today,
'compare' => '<=',
),
array(
'key' => 'tour-date-to',
'value' => $today,
'compare' => '>=',
),
),
);
This is now solved. The problem was that I needed to specify the meta type. I also needed to take out the 'meta_key' line and therefore amend the 'orderby' line to look for the right value.
$today = date('Ymd');
$tour_args = array(
'post_type' => 'tour_date',
'posts_per_page' => -1,
'orderby' => 'tour-date-from',
'order' => 'ASC',
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'tour-date-to',
'value' => $today,
'compare' => '>=',
'type' => 'NUMERIC'
),
array(
'key' => 'tour-date-from',
'value' => $today,
'compare' => '<=',
'type' => 'NUMERIC'
),
),
);

Categories