class-internal-events.php 4.21 KB
Newer Older
1
2
<?php

3
namespace Automattic\WP\Cron_Control;
4

5
class Internal_Events extends Singleton {
6
7
8
9
10
11
12
13
14
15
16
17
18
	/**
	 * PLUGIN SETUP
	 */

	/**
	 * Class properties
	 */
	private $internal_jobs           = array();
	private $internal_jobs_schedules = array();

	/**
	 * Register hooks
	 */
19
	protected function class_init() {
20
		// Internal jobs variables
21
22
		$this->internal_jobs = array(
			array(
23
24
				'schedule' => 'a8c_cron_control_minute',
				'action'   => 'a8c_cron_control_force_publish_missed_schedules',
25
				'callback' => 'force_publish_missed_schedules',
26
27
			),
			array(
28
29
				'schedule' => 'a8c_cron_control_ten_minutes',
				'action'   => 'a8c_cron_control_confirm_scheduled_posts',
30
				'callback' => 'confirm_scheduled_posts',
31
			),
32
33
			array(
				'schedule' => 'daily',
34
				'action'   => 'a8c_cron_control_delete_cron_option',
35
				'callback' => 'delete_cron_option',
36
			),
37
38
39
		);

		$this->internal_jobs_schedules = array(
40
			'a8c_cron_control_minute' => array(
41
				'interval' => 1 * MINUTE_IN_SECONDS,
42
				'display' => __( 'Cron Control internal job - every minute', 'automattic-cron-control' ),
43
			),
44
			'a8c_cron_control_ten_minutes' => array(
45
				'interval' => 10 * MINUTE_IN_SECONDS,
46
				'display' => __( 'Cron Control internal job - every 10 minutes', 'automattic-cron-control' ),
47
48
			),
		);
49
50
51
52
53
54
55
56

		// Register hooks
		add_action( 'wp_loaded', array( $this, 'schedule_internal_events' ) );
		add_filter( 'cron_schedules', array( $this, 'register_internal_events_schedules' ) );

		foreach ( $this->internal_jobs as $internal_job ) {
			add_action( $internal_job['action'], array( $this, $internal_job['callback'] ) );
		}
57
58
59
60
61
62
63
64
65
66
67
68
69
	}

	/**
	 * Include custom schedules used for internal jobs
	 */
	public function register_internal_events_schedules( $schedules ) {
		return array_merge( $schedules, $this->internal_jobs_schedules );
	}

	/**
	 * Schedule internal jobs
	 */
	public function schedule_internal_events() {
70
		$when = strtotime( sprintf( '+%d seconds', JOB_QUEUE_WINDOW_IN_SECONDS ) );
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

		foreach ( $this->internal_jobs as $job_args ) {
			if ( ! wp_next_scheduled( $job_args['action'] ) ) {
				wp_schedule_event( $when, $job_args['schedule'], $job_args['action'] );
			}
		}
	}

	/**
	 * PLUGIN FUNCTIONALITY
	 */

	/**
	 * Events that are always run, regardless of how many jobs are queued
	 */
	public function is_internal_event( $action ) {
		return in_array( $action, wp_list_pluck( $this->internal_jobs, 'action' ) );
	}

	/**
	 * Published scheduled posts that miss their schedule
	 */
	public function force_publish_missed_schedules() {
		global $wpdb;

		$missed_posts = $wpdb->get_col( $wpdb->prepare( "SELECT ID FROM {$wpdb->posts} WHERE post_status = 'future' AND post_date <= %s LIMIT 100;", current_time( 'mysql', false ) ) );

		if ( ! empty( $missed_posts ) ) {
			foreach ( $missed_posts as $missed_post ) {
				check_and_publish_future_post( $missed_post );

102
				do_action( 'a8c_cron_control_published_post_that_missed_schedule', $missed_post );
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
			}
		}
	}

	/**
	 * Ensure scheduled posts have a corresponding cron job to publish them
	 */
	public function confirm_scheduled_posts() {
		global $wpdb;

		$future_posts = $wpdb->get_results( $wpdb->prepare( "SELECT ID, post_date FROM {$wpdb->posts} WHERE post_status = 'future' AND post_date > %s LIMIT 100;", current_time( 'mysql', false ) ) );

		if ( ! empty( $future_posts ) ) {
			foreach ( $future_posts as $future_post ) {
				$future_post->ID = absint( $future_post->ID );
				$gmt_time        = strtotime( get_gmt_from_date( $future_post->post_date ) . ' GMT' );
				$timestamp       = wp_next_scheduled( 'publish_future_post', array( $future_post->ID ) );

				if ( false === $timestamp ) {
					wp_schedule_single_event( $gmt_time, 'publish_future_post', array( $future_post->ID ) );

124
					do_action( 'a8c_cron_control_publish_scheduled', $future_post->ID );
125
126
127
128
				} elseif ( (int) $timestamp !== $gmt_time ) {
					wp_clear_scheduled_hook( 'publish_future_post', array( (int) $future_post->ID ) );
					wp_schedule_single_event( $gmt_time, 'publish_future_post', array( $future_post->ID ) );

129
					do_action( 'a8c_cron_control_publish_rescheduled', $future_post->ID );
130
131
132
133
				}
			}
		}
	}
134
135
136
137
138
139
140

	/**
	 * In case the cron option lingers, purge it
	 */
	public function delete_cron_option() {
		delete_option( 'cron' );
	}
141
142
143
}

Internal_Events::instance();