1

I have an expiry date ACF field 'post_end_date' which has been applied to multiple post types, including 'post'.

I'm trying to filter out any posts, across the entire site, where today's date is greater than the value 'post_end_date'; in other words the post has expired. I've checked that 'post_end_date' value returns a number in the same format as date('Ymd'). e.g.

echo date('Ymd'); // returns 20161128 for today
echo get_field('post_end_date'); // returns 20161127 for yesterday

I figured the best way would be to just do a numerical comparison between today's date and 'post_end_date' value.

This is my code:

  function expiry_filter($query) {

    if( !is_admin() && $query->is_main_query() ) :

      $today = $expire = date('Ymd');

      if ( get_field('post_end_date') ) :
        $expire = get_field('post_end_date');
      endif;

      $query->set( 'meta_query', array(
        array(
         'key'     => $expire,
         'value'   => $today,
         'compare' => '<',
         'type'    => 'NUMERIC'
        )
      ));

    endif;
  }
  add_action( 'pre_get_posts', 'expiry_filter' );

At this point, I was just trying to get it to work for the 'post' post type. I have checked that I haven't used the wrong 'compare' operator. I've tried with and without the $query->is_main_query() conditional.

The result I'm getting with the code above is ALL posts are being filtered out.

Can someone suggest what I might be doing wrong here?

Thanks in advance.

4
  • You should check your values. 'key' => $expire will result in 'key' => 20161128 or something. Shouldn't it be 'key' => 'post_end_date'? Nov 29, 2016 at 17:54
  • Good point @FabianMarz ! So, when making the adjustment I now get only the posts that should be filtered out showing with < as the comparator, which makes sense. So it is matching the meta_query now, but how do I invert it to remove those that match, rather than remove everything that doesn't match? Swapping compare operator to >= filters out everything Nov 29, 2016 at 18:49
  • >= should to the trick. Have you checked your values? get_field will refer to the current post which can lead to unexpected results as you hook in the main query. So maybe there is no post from today? Nov 29, 2016 at 18:56
  • OK. I follow you @FabianMarz. Last question: How do I adjust to include posts where post_end_date is not set? Or do I do an if ( get_field('post_end_date') ): around the $query->set? If you submit as an answer, I will mark your reply as the answer. Nov 29, 2016 at 19:07

2 Answers 2

0

As mentioned in the comments you an issue in your meta query, as you set the key to 20161126 or similar. Instead key should be filled with your meta key post_end_date. Meta query also support multiple arrays to combine your query to also include posts where the meta key is not set. The example would be something like the following:

function expiry_filter($query) {
  if( !is_admin() && $query->is_main_query() ) {
    $expire = get_field('post_end_date') ? : date('Ymd');
    $query->set( 'meta_query', [
      'relation' => 'OR',
      [
       'key'     => 'post_end_date',
       'value'   => $expire,
       'compare' => '>=',
       'type'    => 'NUMERIC',
      ],
      [
       'key'     => 'post_end_date',
       'compare' => 'NOT EXISTS',
      ],
    ]);
  }
}
add_action( 'pre_get_posts', 'expiry_filter' );
0
0

Have you tried using meta_key, meta_value and meta_compare?

function expiry_filter( $query ) {

    if ( ! is_admin() && $query->is_main_query() ) :

        $query->set( 'meta_key', 'post_end_date' );
        $query->set( 'meta_value', date('Ymd') );
        $query->set( 'meta_compare', '>' );

    endif;
}

add_action( 'pre_get_posts', 'expiry_filter' );

Or maybe trying to use the DATE type when using meta_query?

function expiry_filter( $query ) {

  if ( ! is_admin() && $query->is_main_query() ) :

      $query->set( 'meta_query', array(
          array(
              'key'     => 'post_end_date',
              'value'   => date( 'Ymd' ),
              'compare' => '>=',
              'type'    => 'DATE'
          )
      ) );

  endif;
}
add_action( 'pre_get_posts', 'expiry_filter' );

Or just using the cleaned up version of your function

function expiry_filter( $query ) {

  if ( ! is_admin() && $query->is_main_query() ) :

      $query->set( 'meta_query', array(
          array(
              'key'     => 'post_end_date',
              'value'   => date( 'Ymd' ),
              'compare' => '>',
              'type'    => 'NUMERIC'
          )
      ) );

  endif;
}
add_action( 'pre_get_posts', 'expiry_filter' );

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.