class-internal-events.php 4.12 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
23
24
		$this->internal_jobs = array(
			array(
				'schedule' => 'wpccrij_minute',
				'action'   => 'wpccrij_force_publish_missed_schedules',
25
				'callback' => 'force_publish_missed_schedules',
26
27
28
29
			),
			array(
				'schedule' => 'wpccrij_ten_minutes',
				'action'   => 'wpccrij_confirm_scheduled_posts',
30
				'callback' => 'confirm_scheduled_posts',
31
			),
32
33
34
			array(
				'schedule' => 'daily',
				'action'   => 'wpccrij_delete_cron_option',
35
				'callback' => 'delete_cron_option',
36
			),
37
38
39
40
41
		);

		$this->internal_jobs_schedules = array(
			'wpccrij_minute' => array(
				'interval' => 1 * MINUTE_IN_SECONDS,
42
				'display' => __( 'Cron Control internal job - every minute', 'automattic-cron-control' ),
43
44
45
			),
			'wpccrij_ten_minutes' => array(
				'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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133

		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 );

				do_action( 'wpccr_published_post_that_missed_schedule', $missed_post );
			}
		}
	}

	/**
	 * 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 ) );

					do_action( 'wpccr_publish_scheduled', $future_post->ID );
				} 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 ) );

					do_action( 'wpccr_publish_rescheduled', $future_post->ID );
				}
			}
		}
	}
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();