Support

Account

Home Forums General Issues Publish / Expire posts based on ACF date picker field

Solved

Publish / Expire posts based on ACF date picker field

  • Hi guys. Longtime ACF user here.

    Having an issue creating functions to publish and expire posts based on ACF date picker fields. Have tried all of the examples out here in the forums and elsewhere on the web, of which there are two types: those that use cron jobs and those that target transients.

    For the cron job examples, my cron fires, no errors in error log, yet nothing happens on the backend, i.e. code doesn’t execute. There are a number of variations on this code, and right now I’m at

    add_action( 'wp', 'publish_coupons_yo' );
    
    function publish_coupons_yo () {
        if ( ! wp_next_scheduled( 'publish_coupon_function' ) ) {
            wp_schedule_event( time(), 'hourly', 'publish_coupon_function'); //hourly for testing
        }
    }
    add_action( 'publish_coupon_function', 'publish_coupon_function_callback' );
    
    function publish_coupon_function_callback() {
    
        $date = date('Ymd'); // matches the date in DB
        $args = array(
            'post_type' => 'coupon', 
            'posts_per_page' => -1,
            'post_status' => 'draft',
            'meta_query' => array( 
              'relation' => 'OR',
                array (
                   'key'     => 'publish_coupon_date',
                   'value' => $date, 
                   'compare' => '=' 
                ),
              array (
                'key' => 'publish_coupon_date',
                'value' => $date,
                'compare' => '<'
              )
            ) // end meta_query
          ); // end $args
    
    $publishquery = new WP_Query($args);
      // if posts are returned, loop over them and set active flag to false
      if ($publishquery->have_posts()) {
        global $post;
        if( !is_object($post) ) 
         return;
        while ($publishquery->have_posts()) {
          $publishquery->the_post();
          wp_transition_post_status('publish', 'draft', $post->ID);
        } // end while have_posts
        
        wp_reset_postdata();
      } // end if have_posts
    } // end function
    

    No dice.

    Then there’s the transient function code out there, such as from this ACF forum thread and this gist

    // Expire events
    if ($expireTransient = get_transient($post->ID) === false) {
    	set_transient($post->ID, 'set for 1 minutes', 1 * MINUTE_IN_SECONDS );
    	$today = date('Y-m-d H:i:s', current_time('timestamp', 0));
    	$args = array(
    		'post_type' => 'events',
    		'posts_per_page' => 200,
    		'post_status' => 'publish',
    		'meta_query' => array(
    			array(
    				'key' => 'end_date_time',
    				'value' => $today,
    				'compare' => '<='
    			)
    		)
    	);
    	$posts = get_posts($args);
    	foreach( $posts as $post ) {
    		if(get_field('end_date_time', $post->ID)) {
    			$postdata = array(
    				'ID' => $post->ID,
    				'post_status' => 'draft'
    			);
    			wp_update_post($postdata);
    		}
    	}
    }

    This code dates back to 2016. As someone commented recently on the gist, this code throws an error PHP Notice: Trying to get property ‘post_type’ of non-object, and PHP Notice: Trying to get property ‘ID’ of non-object. Someone also posted the same problem to stackoverflow without a helpful response from anyone.

    I’m wondering if since these example codes are from a few years ago, if they are out of date now in 2020. No combination or tweaking of either of these has worked for me and I’ve been trying now for a couple of weeks. Any thoughts or consideration on these snips would be most appreciated, thanks in advance.

  • Well, still not sure why any of the code examples in the ACF forums like this post Expire post to draft or this post Expire Posts on Datepicker field
    aren’t working.

    Here’s what finally worked for me:
    Publish based on datepicker field “publish_coupon_date”

    add_action( 'wp', 'publish_coupons_daily' );
    function publish_coupons_daily() {
        if ( ! wp_next_scheduled( 'publish_coupons' ) ) {
            wp_schedule_event( strtotime('07:02:00'), 'daily', 'publish_coupons');//runs at or after 12:02am local time, server time is in UTC
        }
    }
    add_action( 'publish_coupons', 'publish_coupons_function' );
    
    function publish_coupons_function() {
        
        $date_default_timezone_set('America/Los_Angeles'); // ensures the comparison happens based on local timezone, not on server UTC time, so they don't get published too soon
        $today = date('Ymd');
        $args = array(
            'post_type' => array('coupon'), // post types you want to check
            'post_status' => 'draft', 
            'posts_per_page' => -1 
        );
        $posts = get_posts($args);
        
        foreach($posts as $p){
                
            $publishdate = get_field('publish_coupon_date', $p->ID, false, false); // get the raw date from the db. false, false will convert to Ymd while allowing you to use any date format output choice on the field
    
                if (($publishdate > $today) || ($publishdate = $today)) { 
                    //if date is today OR prior to today
                    $postdata = array(
                        'ID' => $p->ID,
                        'post_status' => 'publish'
                    );
                    wp_update_post($postdata);
                 }      
        }
    }

    and expiring posts from datepicker field “expire_coupon_date”

    add_action( 'wp', 'expire_events_daily' );
    function expire_events_daily() {
        if ( ! wp_next_scheduled( 'delete_expired_events' ) ) {
            wp_schedule_event( strtotime('07:01:00'), 'daily', 'delete_expired_events'); //runs at or after 12:01am local time, server time is in UTC
        }
    }
    add_action( 'delete_expired_events', 'expire_coupon_function' );
    
    function expire_coupon_function() {
        date_default_timezone_set('America/Los_Angeles'); // see other note, we set this to ensure it expires on local time, not server time
        $today = date('Ymd');
        $args = array(
            'post_type' => array('coupon'), 
            'post_status' => 'publish',
            'posts_per_page' => -1 
        );
        $posts = get_posts($args);
        
        foreach($posts as $p){
                
            $expiredate = get_field('expire_coupon_date', $p->ID, false, false); // get the raw date from the db. false, false will convert to Ymd while allowing you to use any date format output choice on the field itself
    
                if (($expiredate < $today) && ($expiredate != "")) { // if date is less than today, but also not empty to accomodate the coupons that don't expire
                    $postdata = array(
                        'ID' => $p->ID,
                        'post_status' => 'draft'
                    );
                    wp_update_post($postdata);
                 }      
        }
    }

    have fun kiddies.

  • Cheers for this code, worked for my needs except for the

    $date_default_timezone_set

    it was throwing an error when the cron ran saying the variable wasn’t defined. My needs aren’t that time critical, an around about that time/day will do so I just removed them both and all good.

    Note that the second variable, in the above example for the expiring back to a draft is missing the $ at the start (wasn’t the cause of my error as I’m aware).

    I was at a loss on what to do when clients will inadvertently set a publish date in the future, then hit the publish button and of course contact me asking why its already published. Figure I will hide the publish button with CSS and beef up the Save as Draft text link to be button looking, should do the trick I’m hoping

    Thanks again for the post.

    Mac

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

You must be logged in to reply to this topic.