class-internal-events.php 4.35 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
<?php

namespace WP_Cron_Control_Revisited;

class Internal_Events {
	/**
	 * Class instance
	 */
	private static $__instance = null;

	public static function instance() {
		if ( ! is_a( self::$__instance, __CLASS__ ) ) {
			self::$__instance = new self;
		}

		return self::$__instance;
	}

	/**
	 * PLUGIN SETUP
	 */

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

	/**
	 * Register hooks
	 */
	private function __construct() {
		$this->prepare();

		add_action( 'wp_loaded', array( $this, 'schedule_internal_events' ) );
		add_filter( 'cron_schedules', array( $this, 'register_internal_events_schedules' ) );
		add_action( 'wpccrij_force_publish_missed_schedules', array( $this, 'force_publish_missed_schedules' ) );
		add_action( 'wpccrij_confirm_scheduled_posts', array( $this, 'confirm_scheduled_posts' ) );
	}

	/**
	 * Set additional variables required for plugin functionality
	 */
	private function prepare() {
		// Internal jobs
		$this->internal_jobs = array(
			array(
				'schedule' => 'wpccrij_minute',
				'action'   => 'wpccrij_force_publish_missed_schedules',
			),
			array(
				'schedule' => 'wpccrij_ten_minutes',
				'action'   => 'wpccrij_confirm_scheduled_posts',
			),
		);

		$this->internal_jobs_schedules = array(
			'wpccrij_minute' => array(
				'interval' => 1 * MINUTE_IN_SECONDS,
				'display' => __( 'WP Cron Control Revisited internal job - every minute', 'wp-cron-control-revisited' ),
			),
			'wpccrij_ten_minutes' => array(
				'interval' => 10 * MINUTE_IN_SECONDS,
				'display' => __( 'WP Cron Control Revisited internal job - every 10 minutes', 'wp-cron-control-revisited' ),
			),
		);
	}

	/**
	 * 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() {
80
		$when = strtotime( sprintf( '+%d seconds', get_plugin_var( 'job_queue_window_in_seconds' ) ) );
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155

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

	/**
	 * Allow specific events to be blocked perpetually
	 */
	public function is_blocked_event( $action ) {
		$blocked_hooks = array();

		return in_array( $action, $blocked_hooks );
	}

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

Internal_Events::instance();