GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 9ed07b...3ea229 )
by Juliette
8s
created

ZT_Debug_Bar_Cron::load_textdomain()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 12
rs 9.4285
cc 3
eloc 8
nc 3
nop 1
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;
39
40
		/**
41
		 * Holds only the cron events initiated by WP core.
42
		 *
43
		 * @var array
44
		 */
45
		private $_core_crons;
46
47
		/**
48
		 * Holds the cron events created by plugins or themes.
49
		 *
50
		 * @var array
51
		 */
52
		private $_user_crons;
53
54
		/**
55
		 * Total number of cron events.
56
		 *
57
		 * @var int
58
		 */
59
		private $_total_crons = 0;
60
61
		/**
62
		 * Total number of cron events created by plugins and themes.
63
		 *
64
		 * @var int
65
		 */
66
		private $_total_user_crons = 0;
67
68
		/**
69
		 * Total number of WP core cron events.
70
		 *
71
		 * @var int
72
		 */
73
		private $_total_core_crons = 0;
74
75
		/**
76
		 * Whether cron is being executed or not.
77
		 *
78
		 * @var string
79
		 */
80
		private $_doing_cron = 'No';
81
82
		/**
83
		 * Lists all crons that are defined in WP Core.
84
		 *
85
		 * @var array
86
		 *
87
		 * @internal To find all, search WP trunk for `wp_schedule_(single_)?event`.
88
		 */
89
		private $_core_cron_hooks = array(
90
			'do_pings',
91
			'importer_scheduled_cleanup',     // WP 3.1+.
92
			'publish_future_post',
93
			'update_network_counts',          // WP 3.1+.
94
			'upgrader_scheduled_cleanup',     // WP 3.3+.
95
			'wp_maybe_auto_update',           // WP 3.7+.
96
			'wp_scheduled_auto_draft_delete', // WP 3.4+.
97
			'wp_scheduled_delete',            // WP 2.9+.
98
			'wp_split_shared_term_batch',     // WP 4.3+.
99
			'wp_update_plugins',
100
			'wp_update_themes',
101
			'wp_version_check',
102
		);
103
104
105
106
		/**
107
		 * Give the panel a title and set the enqueues.
108
		 *
109
		 * @return void
110
		 */
111
		public function init() {
112
			$this->load_textdomain( 'zt-debug-bar-cron' );
113
			$this->title( __( 'Cron', 'zt-debug-bar-cron' ) );
114
			add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts_styles' ) );
115
			add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts_styles' ) );
116
		}
117
118
119
		/**
120
		 * Load the plugin text strings.
121
		 *
122
		 * Compatible with use of the plugin in the must-use plugins directory.
123
		 *
124
		 * @param string $domain Text domain to load.
125
		 */
126
		protected function load_textdomain( $domain ) {
127
			if ( is_textdomain_loaded( $domain ) ) {
128
				return;
129
			}
130
131
			$lang_path = dirname( plugin_basename( __FILE__ ) ) . '/languages';
132
			if ( false === strpos( __FILE__, basename( WPMU_PLUGIN_DIR ) ) ) {
133
				load_plugin_textdomain( $domain, false, $lang_path );
134
			} else {
135
				load_muplugin_textdomain( $domain, $lang_path );
136
			}
137
		}
138
139
140
		/**
141
		 * Enqueue styles.
142
		 *
143
		 * @return void
144
		 */
145
		public function enqueue_scripts_styles() {
146
			$suffix = ( ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? '' : '.min' );
147
148
			wp_enqueue_style(
149
				self::DBCRON_NAME,
150
				plugins_url( 'css/' . self::DBCRON_NAME . $suffix . '.css', __FILE__ ),
151
				array( 'debug-bar' ),
152
				self::DBCRON_STYLES_VERSION
153
			);
154
		}
155
156
157
		/**
158
		 * Show the menu item in Debug Bar.
159
		 *
160
		 * @return void
161
		 */
162
		public function prerender() {
163
			$this->set_visible( true );
164
		}
165
166
167
		/**
168
		 * Show the contents of the page.
169
		 *
170
		 * @return void
171
		 */
172
		public function render() {
173
			$this->get_crons();
174
175
			$this->_doing_cron = get_transient( 'doing_cron' ) ? __( 'Yes', 'zt-debug-bar-cron' ) : __( 'No', 'zt-debug-bar-cron' );
176
177
			// Get the time of the next event.
178
			$cron_times          = ( is_array( $this->_crons ) ? array_keys( $this->_crons ) : array() );
179
			$unix_time_next_cron = (int) $cron_times[0];
180
			$time_next_cron      = date( 'Y-m-d H:i:s', $unix_time_next_cron );
181
182
			$human_time_next_cron = human_time_diff( $unix_time_next_cron );
183
184
			// Add a class if past current time and doing cron is not running.
185
			$times_class = $this->is_time_in_past( $unix_time_next_cron ) ? ' past' : '';
186
187
			$this->load_debug_bar_pretty_output();
188
189
			echo // WPCS: XSS ok.
190
			'
191
			<div class="debug-bar-cron">
192
				<h2><span>', esc_html__( 'Total Events', 'zt-debug-bar-cron' ), ':</span>', $this->_total_crons, '</h2>
193
				<h2><span>', esc_html__( 'Core Events', 'zt-debug-bar-cron' ), ':</span>', $this->_total_core_crons, '</h2>
194
				<h2><span>', esc_html__( 'Custom Events', 'zt-debug-bar-cron' ), ':</span>', $this->_total_user_crons, '</h2>
195
				<h2><span>', esc_html__( 'Doing Cron', 'zt-debug-bar-cron' ), ':</span>', esc_html( $this->_doing_cron ), '</h2>
196
				<h2 class="times', esc_attr( $times_class ), '"><span>', esc_html__( 'Next Event', 'zt-debug-bar-cron' ), ':</span>
197
					', esc_html( $time_next_cron ), '<br />
198
					', $unix_time_next_cron, '<br />
199
					', esc_html( $this->display_past_time( $human_time_next_cron, $unix_time_next_cron ) ), '
200
				</h2>
201
				<h2><span>', esc_html__( 'Current Time', 'zt-debug-bar-cron' ), ':</span>', esc_html( date( 'H:i:s' ) ), '</h2>
202
203
				<div class="clear"></div>
204
205
				<h3>', esc_html__( 'Schedules', 'zt-debug-bar-cron' ), '</h3>';
206
207
			$this->display_schedules();
208
209
			echo '
210
				<h3>', esc_html__( 'Custom Events', 'zt-debug-bar-cron' ), '</h3>';
211
212
			$this->display_events( $this->_user_crons, __( 'No Custom Events scheduled.', 'zt-debug-bar-cron' ) );
213
214
			echo '
215
				<h3>', esc_html__( 'Core Events', 'zt-debug-bar-cron' ), '</h3>';
216
217
			$this->display_events( $this->_core_crons, __( 'No Core Events scheduled.', 'zt-debug-bar-cron' ) );
218
219
			echo '
220
			</div>';
221
222
			$this->reset_debug_bar_pretty_output();
223
		}
224
225
226
		/**
227
		 * Gets all of the cron jobs.
228
		 *
229
		 * @return array|null Array of crons.
230
		 */
231
		private function get_crons() {
232
			if ( is_array( $this->_crons ) ) {
233
				return $this->_crons;
234
			}
235
236
			$crons = _get_cron_array();
237
			if ( is_array( $crons ) && ! empty( $crons ) ) {
238
				$this->_crons = $crons;
239
				$this->sort_count_crons();
240
			}
241
242
			return $this->_crons;
243
		}
244
245
246
		/**
247
		 * Sort and count crons.
248
		 *
249
		 * This function sorts the cron jobs into core crons, and custom crons. It also tallies
250
		 * a total count for the crons as this number is otherwise tough to get.
251
		 */
252
		private function sort_count_crons() {
253
			foreach ( $this->_crons as $time => $time_cron_array ) {
254
				foreach ( $time_cron_array as $hook => $data ) {
255
					$this->_total_crons += count( $data );
256
257
					if ( in_array( $hook, $this->_core_cron_hooks, true ) ) {
258
						$this->_core_crons[ $time ][ $hook ] = $data;
259
						$this->_total_core_crons            += count( $data );
260
					} else {
261
						$this->_user_crons[ $time ][ $hook ] = $data;
262
						$this->_total_user_crons            += count( $data );
263
					}
264
				}
265
			}
266
		}
267
268
269
		/**
270
		 * Displays the events in an easy to read table.
271
		 *
272
		 * @param array  $events        Array of events.
273
		 * @param string $no_events_msg Message to display if there are no events.
274
		 */
275
		private function display_events( $events, $no_events_msg ) {
276
			// Exit early if no events found.
277
			if ( ! is_array( $events ) || empty( $events ) ) {
278
				echo '
279
				<p>', esc_html( $no_events_msg ), '</p>';
280
				return;
281
			}
282
283
			echo '
284
				<table class="zt-debug-bar-cron-table zt-debug-bar-cron-event-table">
285
					<thead><tr>
286
						<th class="col1">', esc_html__( 'Next Execution', 'zt-debug-bar-cron' ), '</th>
287
						<th class="col2">', esc_html__( 'Hook', 'zt-debug-bar-cron' ), '</th>
288
						<th class="col3">', esc_html__( 'Interval Hook', 'zt-debug-bar-cron' ), '</th>
289
						<th class="col4">', esc_html__( 'Interval Value', 'zt-debug-bar-cron' ), '</th>
290
						<th class="col5">', esc_html__( 'Args', 'zt-debug-bar-cron' ), '</th>
291
					</tr></thead>
292
					<tbody>';
293
294
			foreach ( $events as $time => $time_cron_array ) {
295
				$time        = (int) $time;
296
				$event_count = $this->get_arg_set_count( $time_cron_array );
297
				$show_time   = true;
298
299
				foreach ( $time_cron_array as $hook => $data ) {
300
					$row_attributes = $this->get_event_row_attributes( $time, $hook );
301
					$arg_set_count  = count( $data );
302
					$show_hook      = true;
303
304
					foreach ( $data as $hash => $info ) {
305
						echo // WPCS: xss ok.
306
						'
307
						<tr', $row_attributes, '>';
308
309
						if ( true === $show_time ) {
310
							$this->display_event_time( $time, $event_count );
311
							$show_time = false;
312
						}
313
314
						if ( true === $show_hook ) {
315
							$this->display_event_hook( $hook, $arg_set_count );
316
							$show_hook = false;
317
						}
318
319
						// Report the schedule.
320
						echo '
321
							<td>';
322
						$this->display_event_schedule( $info );
323
						echo '</td>';
324
325
						// Report the interval.
326
						echo '
327
							<td class="intervals">';
328
						$this->display_event_intervals( $info );
329
						echo '</td>';
330
331
						// Report the args.
332
						echo '
333
							<td>';
334
						$this->display_event_cron_arguments( $info['args'] );
335
						echo '</td>
336
						</tr>';
337
					}
338
					unset( $hash, $info );
339
				}
340
				unset( $hook, $data, $row_attributes, $arg_set_count, $show_hook );
341
			}
342
			unset( $time, $time_cron_array, $hook_count, $show_time );
343
344
			echo '
345
					</tbody>
346
				</table>';
347
		}
348
349
350
		/**
351
		 * Count the number of argument sets for a cron time.
352
		 *
353
		 * @param array $hook_array Array of hooks with argument sets.
354
		 *
355
		 * @return int
356
		 */
357
		private function get_arg_set_count( $hook_array ) {
358
			$count = 0;
359
			foreach ( $hook_array as $set ) {
360
				$count += count( $set );
361
			}
362
			return $count;
363
		}
364
365
366
		/**
367
		 * Create a HTML attribute string for an event row.
368
		 *
369
		 * @param int    $time Unix timestamp.
370
		 * @param string $hook Action hook for the cron job.
371
		 *
372
		 * @return string
373
		 */
374
		private function get_event_row_attributes( $time, $hook ) {
375
			$attributes = '';
376
			$classes    = array();
377
378
			// Add a class if past current time.
379
			if ( $this->is_time_in_past( $time ) ) {
380
				$classes[] = 'past';
381
			}
382
383
			// Verify if any events are hooked in.
384
			if ( false === has_action( $hook ) ) {
385
				/* TRANSLATORS: This text will display as a tooltip. %1$s will be replaced by a line break. */
386
				$attributes .= ' title="' . sprintf( esc_attr__( 'No actions are hooked into this event at this time.%1$sThe most likely reason for this is that a plugin or theme was de-activated or uninstalled and didn\'t clean up after itself.%1$sHowever, a number of plugins also use the best practice of lean loading and only hook in conditionally, so check carefully if you intend to remove this event.', 'zt-debug-bar-cron' ), "\n" ) . '"';
387
				$classes[]   = 'empty-event';
388
			}
389
390
			if ( ! empty( $classes ) ) {
391
				$attributes .= ' class="' . implode( ' ', $classes ) . '"';
392
			}
393
394
			return $attributes;
395
		}
396
397
398
		/**
399
		 * Display the timing for the event as a date, timestamp and human readable time difference.
400
		 *
401
		 * @param int $time        Timestamp.
402
		 * @param int $event_count Number of events running at this time.
403
		 */
404
		private function display_event_time( $time, $event_count ) {
405
			$row_span = ( $event_count > 1 ) ? ' rowspan="' . $event_count . '"' : '';
406
407
			echo // WPCS: xss ok.
408
			'
409
			<td' . $row_span . '>
410
				', date( 'Y-m-d H:i:s', $time ), '<br />
411
				', $time, '<br />
412
				', esc_html( $this->display_past_time( human_time_diff( $time ), $time ) ), '
413
			</td>';
414
		}
415
416
417
		/**
418
		 * Display the name of the cron job event hook.
419
		 *
420
		 * @param string $hook          Hook name.
421
		 * @param int    $arg_set_count Number of events running at this time and on this hook.
422
		 */
423
		private function display_event_hook( $hook, $arg_set_count ) {
424
			$row_span = ( $arg_set_count > 1 ) ? ' rowspan="' . $arg_set_count . '"' : '';
425
426
			echo // WPCS: xss ok.
427
			'
428
			<td' . $row_span . '>', esc_html( $hook ), '</td>';
429
		}
430
431
432
		/**
433
		 * Displays the the event schedule name for recurring events or else 'single event'.
434
		 *
435
		 * @param array $info Event info array.
436
		 */
437
		private function display_event_schedule( $info ) {
438
			if ( ! empty( $info['schedule'] ) ) {
439
				echo esc_html( $info['schedule'] );
440
			} else {
441
				echo esc_html__( 'Single Event', 'zt-debug-bar-cron' );
442
			}
443
		}
444
445
446
		/**
447
		 * Displays the event interval in seconds, minutes and hours.
448
		 *
449
		 * @param array $info Event info array.
450
		 */
451
		private function display_event_intervals( $info ) {
452
			if ( ! empty( $info['interval'] ) ) {
453
				$interval = (int) $info['interval'];
454
				/* TRANSLATORS: %s is number of seconds. */
455
				printf( esc_html__( '%ss', 'zt-debug-bar-cron' ) . '<br />', $interval ); // WPCS: XSS ok.
456
				/* TRANSLATORS: %s is number of minutes. */
457
				printf( esc_html__( '%sm', 'zt-debug-bar-cron' ) . '<br />', $this->get_minutes( $interval ) ); // WPCS: XSS ok.
458
				/* TRANSLATORS: %s is number of hours. */
459
				printf( esc_html__( '%sh', 'zt-debug-bar-cron' ), $this->get_hours( $interval ) ); // WPCS: XSS ok.
460
				unset( $interval );
461
			} else {
462
				echo esc_html__( 'Single Event', 'zt-debug-bar-cron' );
463
			}
464
		}
465
466
467
		/**
468
		 * Displays the cron arguments in a readable format.
469
		 *
470
		 * @param mixed $args Cron argument(s).
471
		 *
472
		 * @return void
473
		 */
474
		private function display_event_cron_arguments( $args ) {
475
			// Arguments defaults to an empty array if no arguments are given.
476
			if ( is_array( $args ) && array() === $args ) {
477
				echo esc_html__( 'No Args', 'zt-debug-bar-cron' );
478
				return;
479
			}
480
481
			// Ok, we have an argument, let's pretty print it.
482
			$this->print_pretty_output( $args );
483
		}
484
485
486
		/**
487
		 * Displays all of the schedules defined.
488
		 *
489
		 * @return void
490
		 */
491
		private function display_schedules() {
492
			echo '
493
				<table class="zt-debug-bar-cron-table zt-debug-bar-cron-schedule-table">
494
					<thead><tr>
495
						<th class="col1">', esc_html__( 'Interval Hook', 'zt-debug-bar-cron' ), '</th>
496
						<th class="col2">', esc_html__( 'Interval (S)', 'zt-debug-bar-cron' ), '</th>
497
						<th class="col3">', esc_html__( 'Interval (M)', 'zt-debug-bar-cron' ), '</th>
498
						<th class="col4">', esc_html__( 'Interval (H)', 'zt-debug-bar-cron' ), '</th>
499
						<th class="col5">', esc_html__( 'Display Name', 'zt-debug-bar-cron' ), '</th>
500
					</tr></thead>
501
					<tbody>';
502
503
504
			$schedules = wp_get_schedules();
505
			ksort( $schedules );
506
			uasort( $schedules, array( $this, 'schedules_sorting' ) );
507
			foreach ( $schedules as $interval_hook => $data ) {
508
				$interval = (int) $data['interval'];
509
				echo // WPCS: XSS ok.
510
				'
511
						<tr>
512
							<td>', esc_html( $interval_hook ), '</td>
513
							<td>', $interval, '</td>
514
							<td>', $this->get_minutes( $interval ), '</td>
515
							<td>', $this->get_hours( $interval ), '</td>
516
							<td>', esc_html( $data['display'] ) . '</td>
517
						</tr>';
518
			}
519
520
			echo '
521
					</tbody>
522
				</table>';
523
		}
524
525
		/**
526
		 * Sorting method for cron scheldules. Order by schedules interval.
527
		 *
528
		 * @param array $a First element of comparison pair.
529
		 * @param array $b Second element of comparison pair.
530
		 *
531
		 * @return int Return 1 if $a argument 'interval' greater then $b argument 'interval', 0 if both intervals equivalent and -1 otherwise.
532
		 */
533
		private function schedules_sorting( $a, $b ) {
534
			if ( (int) $a['interval'] === (int) $b['interval'] ) {
535
				return 0;
536
			} else {
537
				return ( ( (int) $a['interval'] > (int) $b['interval'] ) ? 1 : -1 );
538
			}
539
		}
540
541
		/**
542
		 * Verify if a given timestamp is in the past or the future.
543
		 *
544
		 * @param int $time Unix timestamp.
545
		 *
546
		 * @return bool True if the time has passed, false otherwise.
547
		 */
548
		private function is_time_in_past( $time ) {
549
			return ( time() > $time && 'No' === $this->_doing_cron );
550
		}
551
552
553
		/**
554
		 * Transform a time in seconds to minutes rounded to 2 decimals.
555
		 *
556
		 * @param int $time Unix timestamp.
557
		 *
558
		 * @return int|float
559
		 */
560
		private function get_minutes( $time ) {
561
			return round( ( (int) $time / 60 ), 2 );
562
		}
563
564
565
		/**
566
		 * Transform a time in seconds to hours rounded to 2 decimals.
567
		 *
568
		 * @param int $time Unix timestamp.
569
		 *
570
		 * @return int|float
571
		 */
572
		private function get_hours( $time ) {
573
			return round( ( (int) $time / 3600 ), 2 );
574
		}
575
576
577
		/**
578
		 * Compares time with current time and adds ' ago' if current time is greater than event time.
579
		 *
580
		 * @param string $human_time Human readable time difference.
581
		 * @param int    $time       Unix time of event.
582
		 *
583
		 * @return string
584
		 */
585
		private function display_past_time( $human_time, $time ) {
586
			if ( time() > $time ) {
587
				/* TRANSLATORS: %s is a human readable time difference. */
588
				return sprintf( __( '%s ago', 'zt-debug-bar-cron' ), $human_time );
589
			} else {
590
				return $human_time;
591
			}
592
		}
593
594
595
		/**
596
		 * Load the pretty output class & set the recursion limit.
597
		 */
598
		private function load_debug_bar_pretty_output() {
599
			if ( ! class_exists( 'Debug_Bar_Pretty_Output' ) ) {
600
				require_once plugin_dir_path( __FILE__ ) . 'inc/debug-bar-pretty-output/class-debug-bar-pretty-output.php';
601
			}
602
603
			// Limit recursion depth if possible - method available since DBPO v1.4.
604
			if ( method_exists( 'Debug_Bar_Pretty_Output', 'limit_recursion' ) ) {
605
				Debug_Bar_Pretty_Output::limit_recursion( 2 );
606
			}
607
		}
608
609
610
		/**
611
		 * Print any type of variable with colour coding and a variable type indication.
612
		 *
613
		 * @param mixed $variable The variable to print.
614
		 */
615
		private function print_pretty_output( $variable ) {
616
			if ( defined( 'Debug_Bar_Pretty_Output::VERSION' ) ) {
617
				echo Debug_Bar_Pretty_Output::get_output( $variable, '', true ); // WPCS: XSS ok.
618
			} else {
619
				// An old version of the pretty output class was loaded.
620
				// Real possibility as there are several DB plugins using the pretty print class.
621
				Debug_Bar_Pretty_Output::output( $variable, '', true );
622
			}
623
		}
624
625
626
		/**
627
		 * Unset recursion depth limit for the pretty output class.
628
		 *
629
		 * @internal Method available since DBPO v1.4.
630
		 */
631
		private function reset_debug_bar_pretty_output() {
632
			if ( method_exists( 'Debug_Bar_Pretty_Output', 'unset_recursion_limit' ) ) {
633
				Debug_Bar_Pretty_Output::unset_recursion_limit();
634
			}
635
		}
636
	} // End of class ZT_Debug_Bar_Cron.
637
638
} // End of if class_exists wrapper.
639