Completed
Branch feature/minor-refactoring (0da00e)
by Juliette
02:57 queued 14s
created

class-debug-bar-cron.php (11 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * Debug Bar Cron - Debug Bar Panel.
4
 *
5
 * @package     WordPress\Plugins\Debug Bar Cron
6
 * @author      Zack Tollman, Helen Hou-Sandi, Juliette Reinders Folmer
7
 * @link        https://github.com/tollmanz/debug-bar-cron
8
 * @version     0.1.2
9
 * @license     http://creativecommons.org/licenses/GPL/2.0/ GNU General Public License, version 2 or higher
10
 */
11
12
// Avoid direct calls to this file.
13
if ( ! function_exists( 'add_action' ) ) {
14
	header( 'Status: 403 Forbidden' );
15
	header( 'HTTP/1.1 403 Forbidden' );
16
	exit();
17
}
18
19
/**
20
 * The class in this file extends the functionality provided by the parent plugin "Debug Bar".
21
 */
22
if ( ! class_exists( 'ZT_Debug_Bar_Cron' ) && class_exists( 'Debug_Bar_Panel' ) ) {
23
24
	/**
25
	 * Add a new Debug Bar Panel.
26
	 */
27
	class ZT_Debug_Bar_Cron extends Debug_Bar_Panel {
28
29
		const DBCRON_STYLES_VERSION = '1.0';
30
31
		const DBCRON_NAME = 'debug-bar-cron';
32
33
		/**
34
		 * Holds all of the cron events.
35
		 *
36
		 * @var array
37
		 */
38
		private $_crons;
0 ignored issues
show
$_crons does not seem to conform to the naming convention (^[a-z][a-z_0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
39
40
		/**
41
		 * Holds only the cron events initiated by WP core.
42
		 *
43
		 * @var array
44
		 */
45
		private $_core_crons;
0 ignored issues
show
$_core_crons does not seem to conform to the naming convention (^[a-z][a-z_0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
46
47
		/**
48
		 * Holds the cron events created by plugins or themes.
49
		 *
50
		 * @var array
51
		 */
52
		private $_user_crons;
0 ignored issues
show
$_user_crons does not seem to conform to the naming convention (^[a-z][a-z_0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
53
54
		/**
55
		 * Total number of cron events.
56
		 *
57
		 * @var int
58
		 */
59
		private $_total_crons = 0;
0 ignored issues
show
$_total_crons does not seem to conform to the naming convention (^[a-z][a-z_0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
60
61
		/**
62
		 * Total number of cron events created by plugins and themes.
63
		 *
64
		 * @var int
65
		 */
66
		private $_total_user_crons = 0;
0 ignored issues
show
$_total_user_crons does not seem to conform to the naming convention (^[a-z][a-z_0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
67
68
		/**
69
		 * Total number of WP core cron events.
70
		 *
71
		 * @var int
72
		 */
73
		private $_total_core_crons = 0;
0 ignored issues
show
$_total_core_crons does not seem to conform to the naming convention (^[a-z][a-z_0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
74
75
		/**
76
		 * Whether cron is being executed or not.
77
		 *
78
		 * @var string
79
		 */
80
		private $_doing_cron = 'No';
0 ignored issues
show
$_doing_cron does not seem to conform to the naming convention (^[a-z][a-z_0-9]*$).

This check examines a number of code elements and verifies that they conform to the given naming conventions.

You can set conventions for local variables, abstract classes, utility classes, constant, properties, methods, parameters, interfaces, classes, exceptions and special methods.

Loading history...
81
82
83
		/**
84
		 * Give the panel a title and set the enqueues.
85
		 *
86
		 * @return void
87
		 */
88
		public function init() {
89
			load_plugin_textdomain( 'zt-debug-bar-cron', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
90
			$this->title( __( 'Cron', 'zt-debug-bar-cron' ) );
91
			add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts_styles' ) );
92
			add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts_styles' ) );
93
		}
94
95
96
		/**
97
		 * Enqueue styles.
98
		 *
99
		 * @return void
100
		 */
101
		public function enqueue_scripts_styles() {
102
			$suffix = ( ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min' );
103
104
			wp_enqueue_style(
105
				self::DBCRON_NAME,
106
				plugins_url( 'css/' . self::DBCRON_NAME . $suffix . '.css', __FILE__ ),
107
				array( 'debug-bar' ),
108
				self::DBCRON_STYLES_VERSION
109
			);
110
		}
111
112
113
		/**
114
		 * Show the menu item in Debug Bar.
115
		 *
116
		 * @return void
117
		 */
118
		public function prerender() {
119
			$this->set_visible( true );
120
		}
121
122
123
		/**
124
		 * Show the contents of the page.
125
		 *
126
		 * @return void
127
		 */
128
		public function render() {
129
			$this->get_crons();
130
131
			$this->_doing_cron = get_transient( 'doing_cron' ) ? __( 'Yes', 'zt-debug-bar-cron' ) : __( 'No', 'zt-debug-bar-cron' );
132
133
			// Get the time of the next event.
134
			$cron_times          = ( is_array( $this->_crons ) ? array_keys( $this->_crons ) : array() );
135
			$unix_time_next_cron = $cron_times[0];
136
			$time_next_cron      = date( 'Y-m-d H:i:s', $unix_time_next_cron );
137
138
			$human_time_next_cron = human_time_diff( $unix_time_next_cron );
139
140
			// Add a class if past current time and doing cron is not running.
141
			$times_class = ( time() > $unix_time_next_cron && 'No' === $this->_doing_cron ) ? ' past' : '';
142
143
			if ( ! class_exists( 'Debug_Bar_Pretty_Output' ) ) {
144
				require_once plugin_dir_path( __FILE__ ) . 'inc/debug-bar-pretty-output/class-debug-bar-pretty-output.php';
145
			}
146
147
			// Limit recursion depth if possible - method available since DBPO v1.4.
148
			if ( method_exists( 'Debug_Bar_Pretty_Output', 'limit_recursion' ) ) {
149
				Debug_Bar_Pretty_Output::limit_recursion( 2 );
150
			}
151
152
			echo '
153
			<div class="debug-bar-cron">
154
				<h2><span>', esc_html__( 'Total Events', 'zt-debug-bar-cron' ), ':</span>', intval( $this->_total_crons ), '</h2>
155
				<h2><span>', esc_html__( 'Core Events', 'zt-debug-bar-cron' ), ':</span>', intval( $this->_total_core_crons ), '</h2>
156
				<h2><span>', esc_html__( 'Custom Events', 'zt-debug-bar-cron' ), ':</span>', intval( $this->_total_user_crons ), '</h2>
157
				<h2><span>', esc_html__( 'Doing Cron', 'zt-debug-bar-cron' ), ':</span>', esc_html( $this->_doing_cron ), '</h2>
158
				<h2 class="times', esc_attr( $times_class ), '"><span>', esc_html__( 'Next Event', 'zt-debug-bar-cron' ), ':</span>
159
					', esc_html( $time_next_cron ), '<br />
160
					', intval( $unix_time_next_cron ), '<br />
161
					', esc_html( $this->display_past_time( $human_time_next_cron, $unix_time_next_cron ) ), '
162
				</h2>
163
				<h2><span>', esc_html__( 'Current Time', 'zt-debug-bar-cron' ), ':</span>', esc_html( date( 'H:i:s' ) ), '</h2>
164
165
				<div class="clear"></div>
166
167
				<h3>', esc_html__( 'Schedules', 'zt-debug-bar-cron' ), '</h3>';
168
169
			$this->display_schedules();
170
171
			echo '
172
				<h3>', esc_html__( 'Custom Events', 'zt-debug-bar-cron' ), '</h3>';
173
174 View Code Duplication
			if ( ! is_null( $this->_user_crons ) ) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
175
				$this->display_events( $this->_user_crons );
176
			} else {
177
				echo '
178
				<p>', esc_html__( 'No Custom Events scheduled.', 'zt-debug-bar-cron' ), '</p>';
179
			}
180
181
			echo '
182
				<h3>', esc_html__( 'Core Events', 'zt-debug-bar-cron' ), '</h3>';
183
184 View Code Duplication
			if ( ! is_null( $this->_core_crons ) ) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
185
				$this->display_events( $this->_core_crons );
186
			} else {
187
				echo '
188
				<p>', esc_html__( 'No Core Events scheduled.', 'zt-debug-bar-cron' ), '</p>';
189
			}
190
191
			echo '
192
			</div>';
193
194
			// Unset recursion depth limit if possible - method available since DBPO v1.4.
195
			if ( method_exists( 'Debug_Bar_Pretty_Output', 'unset_recursion_limit' ) ) {
196
				Debug_Bar_Pretty_Output::unset_recursion_limit();
197
			}
198
		}
199
200
201
		/**
202
		 * Gets all of the cron jobs.
203
		 *
204
		 * This function sorts the cron jobs into core crons, and custom crons. It also tallies
205
		 * a total count for the crons as this number is otherwise tough to get.
206
		 *
207
		 * @return array Array of crons.
208
		 */
209
		private function get_crons() {
210
			if ( ! is_null( $this->_crons ) ) {
211
				return $this->_crons;
212
			}
213
214
			if ( ! $crons = _get_cron_array() ) {
215
				return $this->_crons;
216
			}
217
218
			$this->_crons = $crons;
219
220
			// Lists all crons that are defined in WP Core.
221
			// @internal To find all, search WP trunk for `wp_schedule_(single_)?event`.
222
			$core_cron_hooks = array(
223
				'do_pings',
224
				'importer_scheduled_cleanup',     // WP 3.1+.
225
				'publish_future_post',
226
				'update_network_counts',          // WP 3.1+.
227
				'upgrader_scheduled_cleanup',     // WP 3.3+.
228
				'wp_maybe_auto_update',           // WP 3.7+.
229
				'wp_scheduled_auto_draft_delete', // WP 3.4+.
230
				'wp_scheduled_delete',            // WP 2.9+.
231
				'wp_split_shared_term_batch',     // WP 4.3+.
232
				'wp_update_plugins',
233
				'wp_update_themes',
234
				'wp_version_check',
235
			);
236
237
			// Sort and count crons.
238
			foreach ( $this->_crons as $time => $time_cron_array ) {
239
				foreach ( $time_cron_array as $hook => $data ) {
240
					$this->_total_crons++;
241
242
					if ( in_array( $hook, $core_cron_hooks, true ) ) {
243
						$this->_core_crons[ $time ][ $hook ] = $data;
244
						$this->_total_core_crons += count( $data );
0 ignored issues
show
Equals sign not aligned with surrounding assignments; expected 12 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
245
					} else {
246
						$this->_user_crons[ $time ][ $hook ] = $data;
247
						$this->_total_user_crons += count( $data );
0 ignored issues
show
Equals sign not aligned with surrounding assignments; expected 12 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
248
					}
249
				}
250
			}
251
252
			return $this->_crons;
253
		}
254
255
256
		/**
257
		 * Displays the events in an easy to read table.
258
		 *
259
		 * @param array $events Array of events.
260
		 *
261
		 * @return void|string Void on failure; table display of events on success.
262
		 */
263
		private function display_events( $events ) {
264
			if ( is_null( $events ) || empty( $events ) ) {
265
				return;
266
			}
267
268
			echo '
269
				<table class="zt-debug-bar-cron-event-table">
270
					<thead><tr>
271
						<th class="col1">', esc_html__( 'Next Execution', 'zt-debug-bar-cron' ), '</th>
272
						<th class="col2">', esc_html__( 'Hook', 'zt-debug-bar-cron' ), '</th>
273
						<th class="col3">', esc_html__( 'Interval Hook', 'zt-debug-bar-cron' ), '</th>
274
						<th class="col4">', esc_html__( 'Interval Value', 'zt-debug-bar-cron' ), '</th>
275
						<th class="col5">', esc_html__( 'Args', 'zt-debug-bar-cron' ), '</th>
276
					</tr></thead>
277
					<tbody>';
278
279
			foreach ( $events as $time => $time_cron_array ) {
280
				foreach ( $time_cron_array as $hook => $data ) {
281
					foreach ( $data as $hash => $info ) {
282
						echo '
283
						<tr>
284
							<td';
285
286
						// Add a class if past current time.
287
						if ( time() > $time && 'No' === $this->_doing_cron ) {
288
							echo ' class="past"';
289
						}
290
291
						echo '>
292
								', esc_html( date( 'Y-m-d H:i:s', $time ) ), '<br />
293
								', intval( $time ), '<br />
294
								', esc_html( $this->display_past_time( human_time_diff( $time ), $time ) ), '
295
							</td>
296
							<td>', esc_html( $hook ), '</td>';
297
298
299
						// Report the schedule.
300
						echo '
301
							<td>';
302
						if ( $info['schedule'] ) {
303
							echo esc_html( $info['schedule'] );
304
						} else {
305
							echo esc_html__( 'Single Event', 'zt-debug-bar-cron' );
306
						}
307
						echo '</td>';
308
309
						// Report the interval.
310
						echo '
311
							<td>';
312
						if ( isset( $info['interval'] ) ) {
313
							/* TRANSLATORS: %s is number of seconds. */
314
							printf( esc_html__( '%ss', 'zt-debug-bar-cron' ) . '<br />', intval( wp_strip_all_tags( $info['interval'] ) ) );
315
							/* TRANSLATORS: %s is number of minutes. */
316
							printf( esc_html__( '%sm', 'zt-debug-bar-cron' ) . '<br />', intval( wp_strip_all_tags( $info['interval'] ) / 60 ) );
317
							/* TRANSLATORS: %s is number of hours. */
318
							printf( esc_html__( '%sh', 'zt-debug-bar-cron' ), intval( wp_strip_all_tags( $info['interval'] ) / ( 60 * 60 ) ) );
319
						} else {
320
							echo esc_html__( 'Single Event', 'zt-debug-bar-cron' );
321
						}
322
						echo '</td>';
323
324
						// Report the args.
325
						echo '
326
							<td>';
327
						$this->display_cron_arguments( $info['args'] );
328
						echo '</td>
329
						</tr>';
330
					}
331
				}
332
			}
333
334
			echo '
335
					</tbody>
336
				</table>';
337
		}
338
339
340
		/**
341
		 * Displays the cron arguments in a readable format.
342
		 *
343
		 * @param mixed $args Cron argument(s).
344
		 *
345
		 * @return void
346
		 */
347
		private function display_cron_arguments( $args ) {
348
			// Arguments defaults to an empty array if no arguments are given.
349
			if ( is_array( $args ) && array() === $args ) {
350
				echo esc_html__( 'No Args', 'zt-debug-bar-cron' );
351
				return;
352
			}
353
354
			// Ok, we have an argument, let's pretty print it.
355
			if ( defined( 'Debug_Bar_Pretty_Output::VERSION' ) ) {
356
				echo Debug_Bar_Pretty_Output::get_output( $args, '', true ); // WPCS: XSS ok.
357
			} else {
358
				// An old version of the pretty output class was loaded.
359
				// Real possibility as there are several DB plugins using the pretty print class.
360
				Debug_Bar_Pretty_Output::output( $args, '', true );
361
			}
362
		}
363
364
365
		/**
366
		 * Displays all of the schedules defined.
367
		 *
368
		 * @return void
369
		 */
370
		private function display_schedules() {
371
			echo '
372
				<table class="zt-debug-bar-cron-event-table">
373
					<thead><tr>
374
						<th class="col1">', esc_html__( 'Interval Hook', 'zt-debug-bar-cron' ), '</th>
375
						<th class="col2">', esc_html__( 'Interval (S)', 'zt-debug-bar-cron' ), '</th>
376
						<th class="col3">', esc_html__( 'Interval (M)', 'zt-debug-bar-cron' ), '</th>
377
						<th class="col4">', esc_html__( 'Interval (H)', 'zt-debug-bar-cron' ), '</th>
378
						<th class="col5">', esc_html__( 'Display Name', 'zt-debug-bar-cron' ), '</th>
379
					</tr></thead>
380
					<tbody>';
381
382
383
			$schedules = wp_get_schedules();
384
			foreach ( $schedules as $interval_hook => $data ) {
385
				echo '
386
						<tr>
387
							<td>', esc_html( $interval_hook ), '</td>
388
							<td>', intval( wp_strip_all_tags( $data['interval'] ) ), '</td>
389
							<td>', intval( wp_strip_all_tags( $data['interval'] ) / 60 ), '</td>
390
							<td>', intval( wp_strip_all_tags( $data['interval'] ) / ( 60 * 60 ) ), '</td>
391
							<td>', esc_html( $data['display'] ) . '</td>
392
						</tr>';
393
			}
394
395
			echo '
396
					</tbody>
397
				</table>';
398
		}
399
400
401
		/**
402
		 * Compares time with current time and adds ' ago' if current time is greater than event time.
403
		 *
404
		 * @param string $human_time Human readable time difference.
405
		 * @param int    $time       Unix time of event.
406
		 *
407
		 * @return string
408
		 */
409
		private function display_past_time( $human_time, $time ) {
410
			if ( time() > $time ) {
411
				/* TRANSLATORS: %s is a human readable time difference. */
412
				return sprintf( __( '%s ago', 'zt-debug-bar-cron' ), $human_time );
413
			} else {
414
				return $human_time;
415
			}
416
		}
417
	} // End of class ZT_Debug_Bar_Cron.
418
419
} // End of if class_exists wrapper.
420