Support

Account

Home Forums General Issues Events Manager and ACF

Solved

Events Manager and ACF

  • I am using Advanced Custom fields relationship query to pull in a set of posts and events together on the homepage of my website. These are time sensitive posts and events. The posts have expiration dates on them and get converted to drafts, and then I have a filter on my ACF relationship to only show published posts. This function works perfect, but because past events are still published events, past events are showing up in my query. I need to have posts and events combined. Is there a way to only show future events in my ACF relationship query?

    This is the function:

    
    function relationship_options_filter($options, $field, $the_post) {
    	$options['post_status'] = array('publish');
    	return $options;
    }
    add_filter('acf/fields/relationship/query', 'relationship_options_filter', 10, 3);
    

    This is the ACF relationship query code

    
    <?php foreach($home_blocks as $r): ?>
    							<?php if ($r->post_status == 'publish'): ?>
    								<div class="slide">
    								<article class="image-post">												<?php													global $post;													$post = $r;													setup_postdata($post);												?>
    										<?php the_post_thumbnail('thumbnail_368x184'); ?>												<div class="caption">
    											<h1><?php the_title(); ?></h1>
    												<?php dynamic_excerpt(100) ?>
    												<a href="<?php the_permalink(); ?>" class="more"><?php _e('+ read more'); ?></a>
    
  • Is there a custom field that you’re using to set the expiration date?

    In your loop where you’re displaying the posts you need to check this field or what you’re using to set the expiration date and compare it to the current date to decide if it should be shown or not.

  • In events manager, the events dont actually “expire”, they get archived and the events manager code is set up to only show events in the future. That’s where I am running into trouble.

    I’m handy with php, not great at it, so im having trouble connecting the EM code into the WP query.

  • Is this the plugin you’re talking about https://wordpress.org/plugins/events-manager/ or is it another one?

  • This plugin saves the end date in a custom field named ‘_end_ts’ which is a timestamp. Unfortunately, I don’t know of a safe way to filter this to your existing filter, but it is possible to filter the values saved in this field and to remove the unwanted relationships when loading the field value. This would have the added side benefit of automatically removing expired events the next time the post with the relationship field is edited, if you don’t want that then you can make it only happen in the front end

    
    add_filter(
      'acf/load_value/name=YOUR_FIELD_NAME_HERE',
      'remove_expired_events_form_YOUR_FIELD_NAME_HERE',
      10, 3 
    );
    function remove_expired_events_form_YOUR_FIELD_NAME_HERE($value, $post_id, $field) {
      // if you want to have this run in the admin
      // remove this check
      if (is_admin()) {
        return $value;
      }
      if (!is_array($value) || !count($value)) {
        // bail early, no related events
        return $value;
      }
      $count = count($value);
      $now = time();
      for ($i=0; $i<$count; $i++) {
        $expire = intval(get_post_meta($value[$i], '_end_ts', 0));
        if ($expire < $now) {
          unset($value[$i]);
        }
      }
      return $value;
    }
    

    Your other choice would be to create a WP pre_get_posts filter that could do the same thing. https://codex.wordpress.org/Plugin_API/Action_Reference/pre_get_posts. This would probably work faster but I’m not sure if there’d be any side effects.

    
    add_action('pre_get_posts', 'no_expired_events', 0);
    function no_expired_events($query) {
      if (is_admin()) {
        return;
      }
      if ($query->query_vars['post_type'] == 'event') {
        $meta_query = array(
          array(
            'key' => '_end_ts',
            'value' => time(),
            'compare' => '>',
            'type' => 'TIME'
          )
        );
        $query->set('meta_query', $meta_query);
      }
    }
    
  • That first filter sounds great, however, when I add it, it complete removes the ACF field section from the frontend.

  • I’m using ACF pro, does that make a difference?

  • I made an adjustment. It appears that the values in the array are strings at this point and they need to be integers.

    
    add_filter(
      'acf/load_value/name=YOUR_FIELD_NAME_HERE',
      'remove_expired_events_form_YOUR_FIELD_NAME_HERE',
      10, 3 
    );
    function remove_expired_events_form_YOUR_FIELD_NAME_HERE($value, $post_id, $field) {
      var_dump($value);
      if (!is_array($value) || !count($value)) {
        // bail early
        return $value;
      }
      $count = count($value);
      $now = time();
      for ($i=0; $i<$count; $i++) {
        // adjusted this line
        $expire = intval(get_post_meta(intval($value[$i]), '_end_ts', 0));
        if ($expire < $now) {
          unset($value[$i]);
        }
      }
      return $value;
    }
    
  • I get this on the front end

    array(6) { [0]=> string(3) “175” [1]=> string(3) “216” [2]=> string(3) “536” [3]=> string(3) “173” [4]=> string(3) “225” [5]=> string(3) “528” }

  • Remove the first line of the function, it was for debugging, forgot to remove it.

    
    var_dump($value);
    
  • it now is just removing the field completely again.

  • okay, I had a duh moment, been working with get_option all day.

    
    add_filter(
      'acf/load_value/name=YOUR_FIELD_NAME_HERE',
      'remove_expired_events_form_YOUR_FIELD_NAME_HERE',
      10, 3 
    );
    function remove_expired_events_form_YOUR_FIELD_NAME_HERE($value, $post_id, $field) {
      if (!is_array($value) || !count($value)) {
        // bail early
        return $value;
      }
      $count = count($value);
      $now = time();
      for ($i=0; $i<$count; $i++) {
        // adjusted this line again, change 0 to true
        $expire = intval(get_post_meta(intval($value[$i]), '_end_ts', true));
        if ($expire < $now) {
          unset($value[$i]);
        }
      }
      return $value;
    }
    
  • that worked perfect with the events, however I have regular posts mixed in with my relationship field. That code made all of the posts go away, and it only showed non expired events.

    Can that code be set to only work with event post types, not regular wordpress posts.

  • 
    
    add_filter(
      'acf/load_value/name=YOUR_FIELD_NAME_HERE',
      'remove_expired_events_form_YOUR_FIELD_NAME_HERE',
      10, 3 
    );
    function remove_expired_events_form_YOUR_FIELD_NAME_HERE($value, $post_id, $field) {
    	//return $value;
      if (!is_array($value) || !count($value)) {
        // bail early
        return $value;
      }
      $count = count($value);
      $now = time();
      for ($i=0; $i<$count; $i++) {
    		$post_type = get_post_type(intval($value[$i]));
        $expire = intval(get_post_meta(intval($value[$i]), '_end_ts', true));
        if ($post_type == 'event' && $expire < $now) {
          unset($value[$i]);
        }
      }
      return $value;
    }
    
  • THANK YOU THANK YOU THANK YOU!!!!

Viewing 16 posts - 1 through 16 (of 16 total)

The topic ‘Events Manager and ACF’ is closed to new replies.