0

Here is what I am trying to accomplish: turn off a True/False Advanced Custom Fields(ACF) option on a post if the current date is on or past a selected date on the same post. Also after that code, turn off a Sample Lesson True/False option inside of the lessons attached to the current post.

At first, all I had was the update_sample_child_lessons function with an 'init' action (i.e.add_action( 'init', 'update_sample_child_lessons' );), but that seemed to only run when I clicked update on the post. It did work and everything switched over, but it only ran when I manually clicked Update on the post. So then I did a little research and found that a Cron job should do the trick if I want the code to run automatically without me having to click update, but for some reason I can't seem to get it to work.

So if you know of a way to accomplish what I am trying to do with the code below, or with other code that is completely different, any suggestions or help would be much appreciated.

//CRON JOB TO RUN EVERYDAY
function myprefix_custom_cron_schedule( $schedules ) {
    $schedules['every_day'] = array(
        'interval' => 86400, //24 HOURS IN SECONDS
        'display'  => __( 'Every 24 hours' ),
    );
    return $schedules;
}
add_filter( 'cron_schedules', 'myprefix_custom_cron_schedule' );

if ( ! wp_next_scheduled( 'myprefix_cron_hook' ) ) {
    wp_schedule_event( time(), 'every_day', 'myprefix_cron_hook' );
}
//AUTOMATICALLY ADJUSTS SAMPLE LESSON FREE OPTIONS AND FREE BANNER IF DATE IS PASSED
add_action( 'myprefix_cron_hook', 'update_sample_child_lessons' );
function update_sample_child_lessons() {
  $allcourses = array(
    'post_type' => 'sfwd-courses', //CUSTOM POST TYPE: COURSES
    'posts_per_page' => -1 //QUERY ALL OF THEM
  );
  $query = new WP_Query($allcourses);

  if ($query->have_posts()) {
    global $post;
    if ( ( in_array( $post->post_type, array( 'sfwd-courses' ), true ) )) { //ONLY DO ACTION IF ON CPT OF COURSES
      while ($query->have_posts()) {
        $query->the_post();
        $course_id = learndash_get_course_id( $post->ID ); //GET THE COURSE ID
        $free = get_field('display_free_lessons', $course_id); //GET THE FREE COURSE OPTION (TRUE/FALSE TICKER)
        if (!empty($free)) { //ONLY DO REST OF CODE IF FREE OPTION IS TURNED ON
          $freeDate = get_field('free_until', $course_id); //GET THE DATE FIELD THAT THE COURSE IS FREE UNTIL
          $currentDate = date('Ymd'); //GET CURRENT DATE
          $diff = strtotime($freeDate) - strtotime($currentDate); //GET THE DIFFERENCE BETWEEN THE TWO DATES
          if ($diff <= 0) { //ONLY DO REST OF CODE IF DATE DIFFERENCE IS LESS THAN OR EQUAL TO ZERO
            $value = '';
            update_field('display_free_lessons', $value, $course_id); //UPDATES THE FREE OPTION FIELD TO FALSE(OR NOTHING)

            //LESSON CODE
            $lessons = array_slice(learndash_course_get_lessons($course_id), 1); //GET ALL THE LESSONS FROM THE COURSE EXCEPT FOR THE FIRST ONE
            foreach ($lessons as $lesson) {
              $lessonID = $lesson->ID; //GET THE LESSON ID
              $lesson_meta = get_post_meta($lessonID); //GET THE METADATA FOR THE LESSON
              if ( is_array( $lesson_meta ) ) {
                foreach ( $lesson_meta as $meta_key => $meta_value ) {
                  if ( '_sfwd-lessons' === $meta_key ) {
                    $lesson_settings = maybe_unserialize( $meta_value[0] ); //SOME OF THE ARRAYS ARE SERIALIZED, SO UNSERIALIZE IF NEEDED
                    if ( isset( $lesson_settings['sfwd-lessons_sample_lesson'] ) ) {
                      $lesson_settings['sfwd-lessons_sample_lesson'] = ''; //TURN OFF THE SAMPLE LESSON OPTION ON THE LESSONS
                    }
                    update_post_meta( $lessonID, $meta_key, $lesson_settings );
                  }
                }
              }
            } //END FOREACH
          } //END IF DIFF IS 0
        wp_reset_postdata();
        } 
      }
    }
  }
}
iamgroot
  • 21
  • 6
  • What you mentioned about running a cron job is the correct way to do it. Bear in mind, a cron will only run when someone accesses the site, so it won't necessarily run automatically everyday. An alternate / less eloquent design would be to have an action attached the init function that looks for specific $_GET variables and when provided, runs the script. You could then use an external cron service (something like easycron.com) to then access that URL once per day. Again less, eloquent, but would ensure it runs once a day. – Luke Chaffey Sep 09 '22 at 02:05

1 Answers1

1

Thanks for the comment @Luke Chaffey, I was actually able to figure it out after finding I had my cron actions reversed. Below is the final code that I got working so that it runs every day at 12am:

//CRON JOB TO RUN EVERYDAY
function custom_cron_schedule( $schedules ) {
 $schedules['every_day'] = array(
       'interval' => 86400,
       'display'  => __( 'Every 24 hours' ),
   );
   return $schedules;
   }

add_filter( 'cron_schedules', 'custom_cron_schedule' );
$ve = get_option('gmt_offset') > 0 ? '-' : '+';
  if ( ! wp_next_scheduled('cron_sample_lesson' ) ) {
   wp_schedule_event(strtotime('00:00 tomorrow ' . $ve . 
   absint(get_option('gmt_offset')) . ' HOURS'), 'daily','cron_sample_lesson' );
  }

add_action('cron_sample_lesson', 'update_sample_child_lessons' );
function update_sample_child_lessons() {...
iamgroot
  • 21
  • 6