• Resolved amedic

    (@amedic)


    I have this code to change the category of the post depending on the date from the Advanced Custom Fields field:

    function set_expiry_date( $post_id ) {
    
      // See if an event_end_date or event_date has been entered and if not then end the function
      if( get_post_meta( $post_id, $key = 'expire_date', $single = true ) ) {
    
        // Get the end date of the event in unix grenwich mean time
        $acf_end_date = get_post_meta( $post_id, $key = 'expire_date', $single = true );
    
      } else {
    
        // No start or end date. Lets delete any CRON jobs related to this post and end the function.
        wp_clear_scheduled_hook( 'closed', array( $post_id ) );
        return;
    
      }
    
      // Convert our date to the correct format
      $unix_acf_end_date = strtotime( $acf_end_date );
      $gmt_end_date = gmdate( 'Ymd', $unix_acf_end_date );
      $unix_gmt_end_date = strtotime( $gmt_end_date );
    
      // Get the number of seconds in a day
      $delay = 24 * 60 * 60; //24 hours * 60 minutes * 60 seconds
    
      // Add 1 day to the end date to get the day after the event
      $day_after_event = $unix_gmt_end_date + $delay;
    
      // Temporarily remove from 'Past Event' category
      // wp_remove_object_terms( $post_id, 'active', 'category' );
    
      // If a CRON job exists with this post_id them remove it
      wp_clear_scheduled_hook( 'closed', array( $post_id ) );
      // Add the new CRON job to run the day after the event with the post_id as an argument
    
      $current_date = date('Ymd');
      $current_date = strtotime($current_date);
      if ($day_after_event >= $current_date) {
      	wp_schedule_single_event( $day_after_event , 'closed', array( $post_id ) );
      }
    
    }
    
    // Hook into the save_post_{post-type} function to create/update the cron job everytime an event is saved.
    add_action( 'save_post', 'set_expiry_date', 20 );
    
    // Create a function that adds the post to the past-events category
    function set_past_event_category( $post_id ){
    
      // Set the post category to 'Past Event'
     	wp_set_post_categories( $post_id, array( 5 ) );
    	//wp_remove_object_terms( $post_id, 'active', 'category' );
    
    }
    
    // Hook into the make_past_event CRON job so that the set_past_event_category function runs when the CRON job is fired.
    add_action( 'closed', 'set_past_event_category' );

    Cron event is added only when I update the post. It is not added when I publish the post. Does anybody see where is the problem?

    Thanks!

    • This topic was modified 4 years, 1 month ago by amedic.
Viewing 2 replies - 1 through 2 (of 2 total)
  • Moderator bcworkz

    (@bcworkz)

    I think you’ve encountered a race condition. When “save_post” fires, the code to set related post meta has yet to complete. It’s a multi-threaded process. PHP continues while data is being written. Writing data is relatively slow. Thus there is not yet post meta to get on initial publish, so your callback terminates early.

    Maybe if getting post meta fails, see if there is needed data in $_POST. Only if neither has data should the callback terminate early. I’ve heard that WP core devs will be correcting this by having “save_post” wait for all DB writes to complete. I’ve no idea how that is accomplished, but you could implement something similar if you can learn how they’re doing it. Or wait until the revision hits. Scheduled for 5.8 IIRC.

    Thread Starter amedic

    (@amedic)

    Thanks for the explanation. I’ll wait for the update.

Viewing 2 replies - 1 through 2 (of 2 total)
  • The topic ‘Cron even is working on update but not on publish’ is closed to new replies.