automatewoo/includes/Jobs/Midnight.php
fei-source 47d3c9a8b6 Update to v6.2.2
Source: GrootMade/Festinger Vault
2026-03-15 08:31:15 +08:00

155 lines
4.2 KiB
PHP

<?php
namespace AutomateWoo\Jobs;
use AutomateWoo\DateTime;
defined( 'ABSPATH' ) || exit;
/**
* Initializes a Job running every day at Midnight
* which just triggers the hook `automatewoo_midnight`.
*
* This Job is essential for running Custom Date Time Workflows recurrently.
* The correctness of the Midnight Job time is based on the site timezone, so the changes on the Timezone will
* update also this Job. There is another Job CheckMidnightJob doing this.
*
* @since 6.0.0
*/
class Midnight extends AbstractRecurringOneTimeActionSchedulerJob {
/**
* Update the last run in database.
*
* @param array $item We don't process any item for this Job
*/
protected function process_item( array $item ) {
$this->update_midnight_job_last_run();
}
/**
* Gets the name of this Job
*
* @return string The name of this Job
*/
public function get_name() {
return 'automatewoo_midnight';
}
/**
* Get the start hook name for this Job.
* In midnight job we want to use just the `{job_name}` for compatibility.
*/
public function get_process_item_hook() {
return $this->get_name();
}
/**
* Gets the interval for this Job in seconds.
*
* @return int The interval for this Job in seconds.
*/
public function get_interval() {
return JobService::ONE_DAY_INTERVAL;
}
/**
* We are overriding schedule_recurring() here since we need a specific midnight time to run the job.
*
* So this function calculates the next midnight in the site's timezone and schedules the midnight
* job based on that date.
*
* Notice we get "now" instead of "tomorrow", to avoid issues with custom time of day triggers.
* These triggers could skip 1 day if we don't run the midnight cron immediately when adding it.
*/
public function schedule_recurring() {
$date = new DateTime( 'now' );
$date->convert_to_site_time();
$date->set_time_to_day_start();
$date->convert_to_utc_time();
$this->schedule_midnight_job( $date );
}
/**
* Schedules a Midnight Job with a specific start date.
*
* @param DateTime $date The start date for the Midnight Job
*/
public function schedule_midnight_job( DateTime $date ) {
if ( ! $this->is_scheduled() ) {
$this->action_scheduler->schedule_recurring_action(
$date->getTimestamp(),
$this->get_interval(),
$this->get_schedule_hook()
);
}
}
/**
* Update the last run date of the midnight job to now.
*
* Store last run in site time as Y-m-d.
*
* This is stored as site time because the goal of the midnight cron event is to run once per day
* in the site's timezone. Storing in site time means we can handle DST timezone changes better.
*/
public function update_midnight_job_last_run() {
$now = new DateTime();
$now->convert_to_site_time();
update_option( 'automatewoo_midnight_cron_last_run', $now->format( 'Y-m-d' ), false );
}
/**
* Get the last run date of the midnight job in site time.
*
* @return DateTime|false The last run normalized date. False if the midnight job didn't run .
*/
public function get_midnight_job_last_run() {
$last_run = get_option( 'automatewoo_midnight_cron_last_run' );
return $last_run ? aw_normalize_date( $last_run ) : false;
}
/**
* Did the midnight job run today (in local time)?
* Also returns true if midnight job has run for tomorrow. E.g. in the case of DST changes.
*
* @return bool
*/
public function should_midnight_job_run_today() {
$last_run = $this->get_midnight_job_last_run();
if ( ! $last_run ) {
return true;
}
$last_run->set_time_to_day_end();
$now = new DateTime();
$now->convert_to_site_time();
// Return false if cron has run today or even for tomorrow
return $now > $last_run;
}
/**
* Check if the Midnight Job is correctly setup.
* The Midnight Job is correctly setup if the action scheduled time (in site's timezone) is set at midnight.
*
* @return bool True if the Midnight Job is correctly setup
*/
public function is_midnight_job_correct() {
$action_timestamp = $this->get_schedule();
if ( ! $action_timestamp ) {
return false;
}
$date = new DateTime();
$date->setTimestamp( $action_timestamp );
$date->convert_to_site_time();
return $date->format( 'Hi' ) === '0000';
}
}