Completed
Push — master ( 04e2c5...10745e )
by Ashley
01:49
created

Cron::init()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3.1406

Importance

Changes 0
Metric Value
cc 3
eloc 7
nc 3
nop 0
dl 0
loc 14
ccs 6
cts 8
cp 0.75
crap 3.1406
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace WP_Queue;
4
5
class Cron {
6
7
	/**
8
	 * @var string
9
	 */
10
	protected $id;
11
12
	/**
13
	 * @var Worker
14
	 */
15
	protected $worker;
16
17
	/**
18
	 * @var int
19
	 */
20
	protected $interval;
21
22
	/**
23
	 * Timestamp of when processing the queue started.
24
	 *
25
	 * @var int
26
	 */
27
	protected $start_time;
28
29
	/**
30
	 * Cron constructor.
31
	 *
32
	 * @param string $id
33
	 * @param Worker $worker
34
	 * @param int    $interval
35
	 */
36 1
	public function __construct( $id, $worker, $interval ) {
37 1
		$this->id       = $id;
38 1
		$this->worker   = $worker;
39 1
		$this->interval = $interval;
40 1
	}
41
42
	/**
43
	 * Is the cron queue worker enabled?
44
	 *
45
	 * @return bool
46
	 */
47 1
	protected function is_enabled() {
48 1
		if ( defined( 'DISABLE_WP_QUEUE_CRON' ) && DISABLE_WP_QUEUE_CRON ) {
0 ignored issues
show
Bug introduced by
The constant WP_Queue\DISABLE_WP_QUEUE_CRON was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
49
			return false;
50
		}
51
52 1
		return true;
53
	}
54
55
	/**
56
	 * Init cron class.
57
	 *
58
	 * @return bool
59
	 */
60 1
	public function init() {
61 1
		if ( ! $this->is_enabled() ) {
62
			return false;
63
		}
64
65 1
		add_filter( 'cron_schedules', array( $this, 'schedule_cron' ) );
66 1
		add_action( "wp_queue_worker_{$this->id}", array( $this, 'cron_worker' ) );
67
68 1
		if ( ! wp_next_scheduled( "wp_queue_worker_{$this->id}" ) ) {
1 ignored issue
show
Bug introduced by
The function wp_next_scheduled was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

68
		if ( ! /** @scrutinizer ignore-call */ wp_next_scheduled( "wp_queue_worker_{$this->id}" ) ) {
Loading history...
69
			// Schedule health check
70
			wp_schedule_event( time(), 'wp_queue_cron_interval', "wp_queue_worker_{$this->id}" );
0 ignored issues
show
Bug introduced by
The function wp_schedule_event was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

70
			/** @scrutinizer ignore-call */ wp_schedule_event( time(), 'wp_queue_cron_interval', "wp_queue_worker_{$this->id}" );
Loading history...
71
		}
72
73 1
		return true;
74
	}
75
76
	/**
77
	 * Add interval to cron schedules.
78
	 *
79
	 * @param array $schedules
80
	 *
81
	 * @return array
82
	 */
83
	public function schedule_cron( $schedules ) {
84
		$schedules["wp_queue_cron_interval_{$this->id}"] = array(
85
			'interval' => MINUTE_IN_SECONDS * $this->interval,
0 ignored issues
show
Bug introduced by
The constant WP_Queue\MINUTE_IN_SECONDS was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
86
			'display'  => sprintf( __( 'Every %d Minutes' ), $this->interval ),
87
		);
88
89
		return $schedules;
90
	}
91
92
	/**
93
	 * Process any jobs in the queue.
94
	 */
95
	public function cron_worker() {
96
		$this->start_time = time();
97
98
		while ( ! $this->time_exceeded() && ! $this->memory_exceeded() ) {
99
			if ( ! $this->worker->process() ) {
100
				break;
101
			}
102
		}
103
	}
104
105
	/**
106
	 * Memory exceeded
107
	 *
108
	 * Ensures the worker process never exceeds 80%
109
	 * of the maximum allowed PHP memory.
110
	 *
111
	 * @return bool
112
	 */
113
	protected function memory_exceeded() {
114
		$memory_limit   = $this->get_memory_limit() * 0.8; // 80% of max memory
115
		$current_memory = memory_get_usage( true );
116
		$return         = false;
117
118
		if ( $current_memory >= $memory_limit ) {
119
			$return = true;
120
		}
121
122
		return apply_filters( 'wp_queue_cron_memory_exceeded', $return );
123
	}
124
125
	/**
126
	 * Get memory limit.
127
	 *
128
	 * @return int
129
	 */
130
	protected function get_memory_limit() {
131
		if ( function_exists( 'ini_get' ) ) {
132
			$memory_limit = ini_get( 'memory_limit' );
133
		} else {
134
			$memory_limit = '256M';
135
		}
136
137
		if ( ! $memory_limit || - 1 == $memory_limit ) {
138
			// Unlimited, set to 1GB
139
			$memory_limit = '1000M';
140
		}
141
142
		return intval( $memory_limit ) * 1024 * 1024;
143
	}
144
145
	/**
146
	 * Time exceeded
147
	 *
148
	 * Ensures the worker never exceeds a sensible time limit (20s by default).
149
	 * A timeout limit of 30s is common on shared hosting.
150
	 *
151
	 * @return bool
152
	 */
153
	protected function time_exceeded() {
154
		$finish = $this->start_time + apply_filters( 'wp_queue_cron_time_limit', 20 ); // 20 seconds
155
		$return = false;
156
157
		if ( time() >= $finish ) {
158
			$return = true;
159
		}
160
161
		return apply_filters( 'wp_queue_cron_time_exceeded', $return );
162
	}
163
}