0

I'm using a pair of ACF date fields to create a query on a custom post type (event). I have a "Past Events" feed which is ignoring my usual technique for creating the following behaviour:

  • IF event (CPT) has an end_date value, check it is in the past
  • ELSE IF event does not have an end_date value, use the event_date value (required field) and check this is in the past

I’ve done this several times by nesting the two clauses in an OR relation, but in this case this isn’t working. Any event with an event_date value in the past is turning up in the “Past Events” query results, even when an end_date value is present and in the future.

Here’s the full query – it differs from my usual approach because it needs to filter out more options: event_type (radio button) and include_in_past_events (true/false).

date_default_timezone_set('Europe/London'); 
$past = date('Ymd', strtotime("-999 months")); 
$now = date('Ymd', strtotime("now")); 

$past_args = array(
 'post_type' => 'event',
 'meta_query' => array(
  'relation' => 'AND',
   array(
    'relation' => 'AND',
    array(
     'relation' => 'OR',
     // check to see if end date has been set
     array(
      'key' => 'end_date',
      'compare' => 'BETWEEN',
      'type' => 'NUMERIC',
      'value' => array($past, $now),
     ),
     // if no end date has been set use event/start date
     array(
      'key' => 'event_date',
      'compare' => 'BETWEEN',
      'type' => 'NUMERIC',
      'value' => array($past, $now),
     )
    ),
    array(
     'key' => 'event_type',
     'value' => array('Singlar', 'Multi-Day', 'Series'),
    )
   ),
   array(
    'key' => 'include_in_past_events',
    'value' => '1',
   )
  ),
  'meta_key'    => 'event_date',
  'orderby' => 'meta_value_num',
  'order' => 'DESC',
  'nopaging'    => false,
  'posts_per_page'=> '8'
 );

I can't work out why this isn't working for me, and would appreciate any insight.

Thanks!

0

1 Answer 1

0

Your current meta query embodies the logic

IF event_end IN range 
OR event_start IN range

You need to account for the conditions of event_end's presence separately:

IF event_end IN range
OR ( event_end NOT EXISTS AND event_start IN range )

Immediately adjacent nested clauses with the same AND/OR relation can be combined, which might make things a bit more readable.

a AND ( b AND ( c OR d ) ) === a AND b AND ( c OR d )
a OR ( b OR ( c AND d ) ) === a OR b OR ( c AND d )

You might also be able to name your clauses in order to order the results by which was used - but I haven't tested this.

All of the above in practice:

$past_args = array(
  'post_type'  => 'event',
  'meta_query' => array(
    'relation' => 'AND',
    array(
      'relation'   => 'OR',
      // check to see if end date has been set and is in range
      'end_clause' => array(
        'key'     => 'end_date',
        'compare' => 'BETWEEN',
        'type'    => 'NUMERIC',
        'value'   => array($past, $now),
      ),
      // if no end date has been set use event/start date
      array(
        'relation' => 'AND',
        array(
          'key'     => 'end_date',
          'compare' => 'NOT EXISTS',
        ),
        'start_clause' => array(
          'key'     => 'event_date',
          'compare' => 'BETWEEN',
          'type'    => 'NUMERIC',
          'value'   => array($past, $now),
        ),
      ),
    ),
    array(
      'key'   => 'event_type',
      'value' => array('Singlar', 'Multi-Day', 'Series'),
    ),
    array(
      'key'   => 'include_in_past_events',
      'value' => '1',
    )
  ),
  // 'meta_key'      => 'event_date',// not needed when ordering by clause name.
  'orderby'       => 'end_clause start_clause',
  'order'         => 'DESC',
  'nopaging'      => false,
  'posts_per_page'=> '8',
);
2
  • thank you so much – this is exactly what i have been trying to do. it works perfectly. i completely get why we have to check the end date doesn't exist, although now i am confused as to why it has worked in the past without that. a separate question! thanks for the clear, generous and helpful explanation.
    – mtm
    Commented Jun 25, 2021 at 16:13
  • Yeah, I got a little thrown off and spent some time considering that myself. I'm not really sure... I think the other way would work without it in the scenario that the absence of an event's end date implies that it's on-going, rather than that it had started and finished on the same day. But who knows :P
    – bosco
    Commented Jun 28, 2021 at 19:32

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.