Completed
Branch feature/code-quality (3bbe70)
by Juliette
02:07
created

ZT_Debug_Bar_Cron::print_styles()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 4
rs 10
cc 3
eloc 3
nc 4
nop 0
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
Coding Style introduced by
$_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
Coding Style introduced by
$_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
Coding Style introduced by
$_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
Coding Style introduced by
$_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
		 * Whether cron is being executed or not.
63
		 *
64
		 * @var string
65
		 */
66
		private $_doing_cron = 'No';
0 ignored issues
show
Coding Style introduced by
$_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...
67
68
69
		/**
70
		 * Give the panel a title and set the enqueues.
71
		 *
72
		 * @return void
73
		 */
74
		public function init() {
75
			load_plugin_textdomain( 'zt-debug-bar-cron', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
76
			$this->title( __( 'Cron', 'zt-debug-bar-cron' ) );
77
			add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts_styles' ) );
78
			add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts_styles' ) );
79
		}
80
81
82
		/**
83
		 * Enqueue styles.
84
		 *
85
		 * @return void
86
		 */
87
		public function enqueue_scripts_styles() {
88
			$suffix = ( ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min' );
89
90
			wp_enqueue_style(
91
				self::DBCRON_NAME,
92
				plugins_url( 'css/' . self::DBCRON_NAME . $suffix . '.css', __FILE__ ),
93
				array( 'debug-bar' ),
94
				self::DBCRON_STYLES_VERSION
95
			);
96
		}
97
98
99
		/**
100
		 * Show the menu item in Debug Bar.
101
		 *
102
		 * @return void
103
		 */
104
		public function prerender() {
105
			$this->set_visible( true );
106
		}
107
108
109
		/**
110
		 * Show the contents of the page.
111
		 *
112
		 * @return void
113
		 */
114
		public function render() {
115
			$this->get_crons();
116
117
			$this->_doing_cron = get_transient( 'doing_cron' ) ? __( 'Yes', 'zt-debug-bar-cron' ) : __( 'No', 'zt-debug-bar-cron' );
118
119
			// Get the time of the next event.
120
			$cron_times          = ( is_array( $this->_crons ) ? array_keys( $this->_crons ) : array() );
121
			$unix_time_next_cron = $cron_times[0];
122
			$time_next_cron      = date( 'Y-m-d H:i:s', $unix_time_next_cron );
123
124
			$human_time_next_cron = human_time_diff( $unix_time_next_cron );
125
126
			// Add a class if past current time and doing cron is not running.
127
			$times_class = ( time() > $unix_time_next_cron && 'No' === $this->_doing_cron ) ? ' past' : '';
128
129
			echo '
130
			<div class="debug-bar-cron">
131
				<h2><span>', __( 'Total Events', 'zt-debug-bar-cron' ), ':</span>', (int) $this->_total_crons, '</h2>
132
				<h2><span>', __( 'Doing Cron', 'zt-debug-bar-cron' ), ':</span>', $this->_doing_cron, '</h2>
133
				<h2 class="times', esc_attr( $times_class ), '"><span>', __( 'Next Event', 'zt-debug-bar-cron' ), ':</span>
134
					', $time_next_cron, '<br />
135
					', $unix_time_next_cron, '<br />
136
					', $this->display_past_time( $human_time_next_cron, $unix_time_next_cron ), '
137
				</h2>
138
				<h2><span>', __( 'Current Time', 'zt-debug-bar-cron' ), ':</span>', date( 'H:i:s' ), '</h2>
139
140
				<div class="clear"></div>
141
				
142
				<h3>', __( 'Custom Events', 'zt-debug-bar-cron' ), '</h3>';
143
144 View Code Duplication
			if ( ! is_null( $this->_user_crons ) ) {
0 ignored issues
show
Duplication introduced by
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...
145
				$this->display_events( $this->_user_crons );
146
			} else {
147
				echo '
148
				<p>', __( 'No Custom Events scheduled.', 'zt-debug-bar-cron' ), '</p>';
149
			}
150
151
			echo '
152
				<h3>', __( 'Schedules', 'zt-debug-bar-cron' ), '</h3>';
153
154
			$this->display_schedules();
155
156
			echo '
157
				<h3>', __( 'Core Events', 'zt-debug-bar-cron' ), '</h3>';
158
159 View Code Duplication
			if ( ! is_null( $this->_core_crons ) ) {
0 ignored issues
show
Duplication introduced by
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...
160
				$this->display_events( $this->_core_crons );
161
			} else {
162
				echo '
163
				<p>', __( 'No Core Events scheduled.', 'zt-debug-bar-cron' ), '</p>';
164
			}
165
166
			echo '
167
			</div>';
168
		}
169
170
171
		/**
172
		 * Gets all of the cron jobs.
173
		 *
174
		 * This function sorts the cron jobs into core crons, and custom crons. It also tallies
175
		 * a total count for the crons as this number is otherwise tough to get.
176
		 *
177
		 * @return array Array of crons.
178
		 */
179
		private function get_crons() {
180
			if ( ! is_null( $this->_crons ) ) {
181
				return $this->_crons;
182
			}
183
184
			if ( ! $crons = _get_cron_array() ) {
185
				return $this->_crons;
186
			}
187
188
			$this->_crons = $crons;
189
190
			// Lists all crons that are defined in WP Core.
191
			// @internal To find all, search WP trunk for `wp_schedule_(single_)?event`.
192
			$core_cron_hooks = array(
193
				'do_pings',
194
				'importer_scheduled_cleanup',     // WP 3.1+.
195
				'publish_future_post',
196
				'update_network_counts',          // WP 3.1+.
197
				'upgrader_scheduled_cleanup',     // WP 3.3+.
198
				'wp_maybe_auto_update',           // WP 3.7+.
199
				'wp_scheduled_auto_draft_delete', // WP 3.4+.
200
				'wp_scheduled_delete',            // WP 2.9+.
201
				'wp_split_shared_term_batch',     // WP 4.3+.
202
				'wp_update_plugins',
203
				'wp_update_themes',
204
				'wp_version_check',
205
			);
206
207
			// Sort and count crons.
208
			foreach ( $this->_crons as $time => $time_cron_array ) {
209
				foreach ( $time_cron_array as $hook => $data ) {
210
					$this->_total_crons++;
211
212
					if ( in_array( $hook, $core_cron_hooks, true ) ) {
213
						$this->_core_crons[ $time ][ $hook ] = $data;
214
					} else {
215
						$this->_user_crons[ $time ][ $hook ] = $data;
216
					}
217
				}
218
			}
219
220
			return $this->_crons;
221
		}
222
223
224
		/**
225
		 * Displays the events in an easy to read table.
226
		 *
227
		 * @param array $events Array of events.
228
		 *
229
		 * @return void|string Void on failure; table display of events on success.
230
		 */
231
		private function display_events( $events ) {
232
			if ( is_null( $events ) || empty( $events ) ) {
233
				return;
234
			}
235
236
			echo '
237
				<table class="zt-debug-bar-cron-event-table" cellspacing="0">
238
					<thead><tr>
239
						<th class="col1">', __( 'Next Execution', 'zt-debug-bar-cron' ), '</th>
240
						<th class="col2">', __( 'Hook', 'zt-debug-bar-cron' ), '</th>
241
						<th class="col3">', __( 'Interval Hook', 'zt-debug-bar-cron' ), '</th>
242
						<th class="col4">', __( 'Interval Value', 'zt-debug-bar-cron' ), '</th>
243
						<th class="col5">', __( 'Args', 'zt-debug-bar-cron' ), '</th>
244
					</tr></thead>
245
					<tbody>';
246
247
			foreach ( $events as $time => $time_cron_array ) {
248
				foreach ( $time_cron_array as $hook => $data ) {
249
					// Add a class if past current time.
250
					$times_class = ( time() > $time && 'No' === $this->_doing_cron ) ? ' class="past"' : '';
251
252
					echo '
253
						<tr>
254
							<td', $times_class, '>
255
								', date( 'Y-m-d H:i:s', $time ), '<br />
256
								', $time, '<br />
257
								', $this->display_past_time( human_time_diff( $time ), $time ), '
258
							</td>
259
							<td>', wp_strip_all_tags( $hook ), '</td>';
260
261
					foreach ( $data as $hash => $info ) {
262
						// Report the schedule.
263
						echo '
264
							<td>';
265
						if ( $info['schedule'] ) {
266
							echo wp_strip_all_tags( $info['schedule'] );
267
						} else {
268
							echo esc_html__( 'Single Event', 'zt-debug-bar-cron' );
269
						}
270
						echo '</td>';
271
272
						// Report the interval.
273
						echo '
274
							<td>';
275
						if ( isset( $info['interval'] ) ) {
276
							/* TRANSLATORS: %s is number of seconds. */
277
							printf( esc_html__( '%ss', 'zt-debug-bar-cron' ) . '<br />', wp_strip_all_tags( $info['interval'] ) );
278
							/* TRANSLATORS: %s is number of minutes. */
279
							printf( esc_html__( '%sm', 'zt-debug-bar-cron' ) . '<br />', ( wp_strip_all_tags( $info['interval'] ) / 60 ) );
280
							/* TRANSLATORS: %s is number of hours. */
281
							printf( esc_html__( '%sh', 'zt-debug-bar-cron' ), ( wp_strip_all_tags( $info['interval'] ) / ( 60 * 60 ) ) );
282
						} else {
283
							echo esc_html__( 'Single Event', 'zt-debug-bar-cron' );
284
						}
285
						echo '</td>';
286
287
						// Report the args.
288
						echo '
289
							<td>';
290
						if ( is_array( $info['args'] ) && ! empty( $info['args'] ) ) {
291
							foreach ( $info['args'] as $key => $value ) {
292
								$this->display_cron_arguments( $key, $value );
293
							}
294
						} else if ( is_string( $info['args'] ) && '' !== $info['args'] ) {
295
							echo esc_html( $info['args'] );
296
						} else {
297
							echo esc_html__( 'No Args', 'zt-debug-bar-cron' );
298
						}
299
						echo '</td>';
300
					}
301
302
					echo '
303
						</tr>';
304
				}
305
			}
306
307
			echo '
308
					</tbody>
309
				</table>';
310
		}
311
312
313
		/**
314
		 * Displays the cron arguments in a readable format.
315
		 *
316
		 * @param int|string $key   Key of the array element.
317
		 * @param mixed      $value Cron argument(s).
318
		 * @param int        $depth Current recursion depth.
319
		 *
320
		 * @return void
321
		 */
322
		function display_cron_arguments( $key, $value, $depth = 0 ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
323
			if ( is_string( $value ) || is_int( $value ) ) {
324
				echo str_repeat( '&nbsp;', ( $depth * 2 ) ) . wp_strip_all_tags( $key ) . ' => ' . esc_html( $value ) . '<br />';
325
			} else if ( is_array( $value ) ) {
326
				if ( count( $value ) > 0 ) {
327
					echo str_repeat( '&nbsp;', ( $depth * 2 ) ) . wp_strip_all_tags( $key ) . ' => array(<br />';
328
					$depth++;
329
					foreach ( $value as $k => $v ) {
330
						$this->display_cron_arguments( $k, $v, $depth );
331
					}
332
					echo str_repeat( '&nbsp;', ( ( $depth - 1 ) * 2 ) ) . ')';
333
				} else {
334
					echo esc_html( 'Empty Array', 'zt-debug-bar-cron' );
335
				}
336
			}
337
		}
338
339
340
		/**
341
		 * Displays all of the schedules defined.
342
		 *
343
		 * @return void
344
		 */
345
		private function display_schedules() {
346
			echo '
347
				<table class="zt-debug-bar-cron-event-table" cellspacing="0">
348
					<thead><tr>
349
						<th class="col1">', __( 'Interval Hook', 'zt-debug-bar-cron' ), '</th>
350
						<th class="col2">', __( 'Interval (S)', 'zt-debug-bar-cron' ), '</th>
351
						<th class="col3">', __( 'Interval (M)', 'zt-debug-bar-cron' ), '</th>
352
						<th class="col4">', __( 'Interval (H)', 'zt-debug-bar-cron' ), '</th>
353
						<th class="col5">', __( 'Display Name', 'zt-debug-bar-cron' ), '</th>
354
					</tr></thead>
355
					<tbody>';
356
357
			foreach ( wp_get_schedules() as $interval_hook => $data ) {
358
				echo '
359
						<tr>
360
							<td>', esc_html( $interval_hook ), '</td>
361
							<td>', wp_strip_all_tags( $data['interval'] ), '</td>
362
							<td>', ( wp_strip_all_tags( $data['interval'] ) / 60 ), '</td>
363
							<td>', ( wp_strip_all_tags( $data['interval'] ) / ( 60 * 60 ) ), '</td>
364
							<td>', esc_html( $data['display'] ) . '</td>
365
						</tr>';
366
			}
367
368
			echo '
369
					</tbody>
370
				</table>';
371
		}
372
373
374
		/**
375
		 * Compares time with current time and adds ' ago' if current time is greater than event time.
376
		 *
377
		 * @param string $human_time Human readable time difference.
378
		 * @param int    $time       Unix time of event.
379
		 *
380
		 * @return string
381
		 */
382
		private function display_past_time( $human_time, $time ) {
383
			if ( time() > $time ) {
384
				/* TRANSLATORS: %s is a human readable time difference. */
385
				return sprintf( esc_html__( '%s ago', 'zt-debug-bar-cron' ), $human_time );
386
			} else {
387
				return $human_time;
388
			}
389
		}
390
	} // End of class ZT_Debug_Bar_Cron.
391
392
} // End of if class_exists wrapper.
393