Passed
Push — master ( 495efb...ace576 )
by Brian
06:14 queued 01:46
created

ActionScheduler_ListTable::display_admin_notices()   C

Complexity

Conditions 14
Paths 41

Size

Total Lines 99
Code Lines 62

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 14
eloc 62
c 1
b 0
f 0
nc 41
nop 0
dl 0
loc 99
rs 6.2666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * Implements the admin view of the actions.
5
 * @codeCoverageIgnore
6
 */
7
class ActionScheduler_ListTable extends ActionScheduler_Abstract_ListTable {
8
9
	/**
10
	 * The package name.
11
	 *
12
	 * @var string
13
	 */
14
	protected $package = 'action-scheduler';
15
16
	/**
17
	 * Columns to show (name => label).
18
	 *
19
	 * @var array
20
	 */
21
	protected $columns = array();
22
23
	/**
24
	 * Actions (name => label).
25
	 *
26
	 * @var array
27
	 */
28
	protected $row_actions = array();
29
30
	/**
31
	 * The active data stores
32
	 *
33
	 * @var ActionScheduler_Store
34
	 */
35
	protected $store;
36
37
	/**
38
	 * A logger to use for getting action logs to display
39
	 *
40
	 * @var ActionScheduler_Logger
41
	 */
42
	protected $logger;
43
44
	/**
45
	 * A ActionScheduler_QueueRunner runner instance (or child class)
46
	 *
47
	 * @var ActionScheduler_QueueRunner
48
	 */
49
	protected $runner;
50
51
	/**
52
	 * Bulk actions. The key of the array is the method name of the implementation:
53
	 *
54
	 *     bulk_<key>(array $ids, string $sql_in).
55
	 *
56
	 * See the comments in the parent class for further details
57
	 *
58
	 * @var array
59
	 */
60
	protected $bulk_actions = array();
61
62
	/**
63
	 * Flag variable to render our notifications, if any, once.
64
	 *
65
	 * @var bool
66
	 */
67
	protected static $did_notification = false;
68
69
	/**
70
	 * Array of seconds for common time periods, like week or month, alongside an internationalised string representation, i.e. "Day" or "Days"
71
	 *
72
	 * @var array
73
	 */
74
	private static $time_periods;
75
76
	/**
77
	 * Sets the current data store object into `store->action` and initialises the object.
78
	 *
79
	 * @param ActionScheduler_Store $store
80
	 * @param ActionScheduler_Logger $logger
81
	 * @param ActionScheduler_QueueRunner $runner
82
	 */
83
	public function __construct( ActionScheduler_Store $store, ActionScheduler_Logger $logger, ActionScheduler_QueueRunner $runner ) {
84
85
		$this->store  = $store;
86
		$this->logger = $logger;
87
		$this->runner = $runner;
88
89
		$this->table_header = __( 'Scheduled Actions', 'action-scheduler' );
90
91
		$this->bulk_actions = array(
92
			'delete' => __( 'Delete', 'action-scheduler' ),
93
		);
94
95
		$this->columns = array(
96
			'hook'        => __( 'Hook', 'action-scheduler' ),
97
			'status'      => __( 'Status', 'action-scheduler' ),
98
			'args'        => __( 'Arguments', 'action-scheduler' ),
99
			'group'       => __( 'Group', 'action-scheduler' ),
100
			'recurrence'  => __( 'Recurrence', 'action-scheduler' ),
101
			'schedule'    => __( 'Scheduled Date', 'action-scheduler' ),
102
			'log_entries' => __( 'Log', 'action-scheduler' ),
103
		);
104
105
		$this->sort_by = array(
106
			'schedule',
107
			'hook',
108
			'group',
109
		);
110
111
		$this->search_by = array(
112
			'hook',
113
			'args',
114
			'claim_id',
115
		);
116
117
		$request_status = $this->get_request_status();
118
119
		if ( empty( $request_status ) ) {
120
			$this->sort_by[] = 'status';
121
		} elseif ( in_array( $request_status, array( 'in-progress', 'failed' ) ) ) {
122
			$this->columns  += array( 'claim_id' => __( 'Claim ID', 'action-scheduler' ) );
123
			$this->sort_by[] = 'claim_id';
124
		}
125
126
		$this->row_actions = array(
127
			'hook' => array(
128
				'run' => array(
129
					'name'  => __( 'Run', 'action-scheduler' ),
130
					'desc'  => __( 'Process the action now as if it were run as part of a queue', 'action-scheduler' ),
131
				),
132
				'cancel' => array(
133
					'name'  => __( 'Cancel', 'action-scheduler' ),
134
					'desc'  => __( 'Cancel the action now to avoid it being run in future', 'action-scheduler' ),
135
					'class' => 'cancel trash',
136
				),
137
			),
138
		);
139
140
		self::$time_periods = array(
141
			array(
142
				'seconds' => YEAR_IN_SECONDS,
143
				/* translators: %s: amount of time */
144
				'names'   => _n_noop( '%s year', '%s years', 'action-scheduler' ),
145
			),
146
			array(
147
				'seconds' => MONTH_IN_SECONDS,
148
				/* translators: %s: amount of time */
149
				'names'   => _n_noop( '%s month', '%s months', 'action-scheduler' ),
150
			),
151
			array(
152
				'seconds' => WEEK_IN_SECONDS,
153
				/* translators: %s: amount of time */
154
				'names'   => _n_noop( '%s week', '%s weeks', 'action-scheduler' ),
155
			),
156
			array(
157
				'seconds' => DAY_IN_SECONDS,
158
				/* translators: %s: amount of time */
159
				'names'   => _n_noop( '%s day', '%s days', 'action-scheduler' ),
160
			),
161
			array(
162
				'seconds' => HOUR_IN_SECONDS,
163
				/* translators: %s: amount of time */
164
				'names'   => _n_noop( '%s hour', '%s hours', 'action-scheduler' ),
165
			),
166
			array(
167
				'seconds' => MINUTE_IN_SECONDS,
168
				/* translators: %s: amount of time */
169
				'names'   => _n_noop( '%s minute', '%s minutes', 'action-scheduler' ),
170
			),
171
			array(
172
				'seconds' => 1,
173
				/* translators: %s: amount of time */
174
				'names'   => _n_noop( '%s second', '%s seconds', 'action-scheduler' ),
175
			),
176
		);
177
178
		parent::__construct( array(
179
			'singular' => 'action-scheduler',
180
			'plural'   => 'action-scheduler',
181
			'ajax'     => false,
182
		) );
183
	}
184
185
	/**
186
	 * Convert an interval of seconds into a two part human friendly string.
187
	 *
188
	 * The WordPress human_time_diff() function only calculates the time difference to one degree, meaning
189
	 * even if an action is 1 day and 11 hours away, it will display "1 day". This function goes one step
190
	 * further to display two degrees of accuracy.
191
	 *
192
	 * Inspired by the Crontrol::interval() function by Edward Dale: https://wordpress.org/plugins/wp-crontrol/
193
	 *
194
	 * @param int $interval A interval in seconds.
195
	 * @param int $periods_to_include Depth of time periods to include, e.g. for an interval of 70, and $periods_to_include of 2, both minutes and seconds would be included. With a value of 1, only minutes would be included.
196
	 * @return string A human friendly string representation of the interval.
197
	 */
198
	private static function human_interval( $interval, $periods_to_include = 2 ) {
199
200
		if ( $interval <= 0 ) {
201
			return __( 'Now!', 'action-scheduler' );
202
		}
203
204
		$output = '';
205
206
		for ( $time_period_index = 0, $periods_included = 0, $seconds_remaining = $interval; $time_period_index < count( self::$time_periods ) && $seconds_remaining > 0 && $periods_included < $periods_to_include; $time_period_index++ ) {
207
208
			$periods_in_interval = floor( $seconds_remaining / self::$time_periods[ $time_period_index ]['seconds'] );
209
210
			if ( $periods_in_interval > 0 ) {
211
				if ( ! empty( $output ) ) {
212
					$output .= ' ';
213
				}
214
				$output .= sprintf( _n( self::$time_periods[ $time_period_index ]['names'][0], self::$time_periods[ $time_period_index ]['names'][1], $periods_in_interval, 'action-scheduler' ), $periods_in_interval );
0 ignored issues
show
Bug introduced by
$periods_in_interval of type double is incompatible with the type integer expected by parameter $number of _n(). ( Ignorable by Annotation )

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

214
				$output .= sprintf( _n( self::$time_periods[ $time_period_index ]['names'][0], self::$time_periods[ $time_period_index ]['names'][1], /** @scrutinizer ignore-type */ $periods_in_interval, 'action-scheduler' ), $periods_in_interval );
Loading history...
215
				$seconds_remaining -= $periods_in_interval * self::$time_periods[ $time_period_index ]['seconds'];
216
				$periods_included++;
217
			}
218
		}
219
220
		return $output;
221
	}
222
223
	/**
224
	 * Returns the recurrence of an action or 'Non-repeating'. The output is human readable.
225
	 *
226
	 * @param ActionScheduler_Action $action
227
	 *
228
	 * @return string
229
	 */
230
	protected function get_recurrence( $action ) {
231
		$schedule = $action->get_schedule();
232
		if ( $schedule->is_recurring() ) {
233
			$recurrence = $schedule->get_recurrence();
0 ignored issues
show
Bug introduced by
The method get_recurrence() does not exist on ActionScheduler_Schedule. It seems like you code against a sub-type of ActionScheduler_Schedule such as ActionScheduler_CronSchedule or ActionScheduler_IntervalSchedule or ActionScheduler_Abstract_RecurringSchedule. ( Ignorable by Annotation )

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

233
			/** @scrutinizer ignore-call */ 
234
   $recurrence = $schedule->get_recurrence();
Loading history...
234
235
			if ( is_numeric( $recurrence ) ) {
236
				/* translators: %s: time interval */
237
				return sprintf( __( 'Every %s', 'action-scheduler' ), self::human_interval( $recurrence ) );
238
			} else {
239
				return $recurrence;
240
			}
241
		}
242
243
		return __( 'Non-repeating', 'action-scheduler' );
244
	}
245
246
	/**
247
	 * Serializes the argument of an action to render it in a human friendly format.
248
	 *
249
	 * @param array $row The array representation of the current row of the table
250
	 *
251
	 * @return string
252
	 */
253
	public function column_args( array $row ) {
254
		if ( empty( $row['args'] ) ) {
255
			return apply_filters( 'action_scheduler_list_table_column_args', '', $row );
256
		}
257
258
		$row_html = '<ul>';
259
		foreach ( $row['args'] as $key => $value ) {
260
			$row_html .= sprintf( '<li><code>%s => %s</code></li>', esc_html( var_export( $key, true ) ), esc_html( var_export( $value, true ) ) );
261
		}
262
		$row_html .= '</ul>';
263
264
		return apply_filters( 'action_scheduler_list_table_column_args', $row_html, $row );
265
	}
266
267
	/**
268
	 * Prints the logs entries inline. We do so to avoid loading Javascript and other hacks to show it in a modal.
269
	 *
270
	 * @param array $row Action array.
271
	 * @return string
272
	 */
273
	public function column_log_entries( array $row ) {
274
275
		$log_entries_html = '<ol>';
276
277
		$timezone = new DateTimezone( 'UTC' );
278
279
		foreach ( $row['log_entries'] as $log_entry ) {
280
			$log_entries_html .= $this->get_log_entry_html( $log_entry, $timezone );
281
		}
282
283
		$log_entries_html .= '</ol>';
284
285
		return $log_entries_html;
286
	}
287
288
	/**
289
	 * Prints the logs entries inline. We do so to avoid loading Javascript and other hacks to show it in a modal.
290
	 *
291
	 * @param ActionScheduler_LogEntry $log_entry
292
	 * @param DateTimezone $timezone
293
	 * @return string
294
	 */
295
	protected function get_log_entry_html( ActionScheduler_LogEntry $log_entry, DateTimezone $timezone ) {
296
		$date = $log_entry->get_date();
297
		$date->setTimezone( $timezone );
298
		return sprintf( '<li><strong>%s</strong><br/>%s</li>', esc_html( $date->format( 'Y-m-d H:i:s O' ) ), esc_html( $log_entry->get_message() ) );
299
	}
300
301
	/**
302
	 * Only display row actions for pending actions.
303
	 *
304
	 * @param array  $row         Row to render
305
	 * @param string $column_name Current row
306
	 *
307
	 * @return string
308
	 */
309
	protected function maybe_render_actions( $row, $column_name ) {
310
		if ( 'pending' === strtolower( $row['status'] ) ) {
311
			return parent::maybe_render_actions( $row, $column_name );
312
		}
313
314
		return '';
315
	}
316
317
	/**
318
	 * Renders admin notifications
319
	 *
320
	 * Notifications:
321
	 *  1. When the maximum number of tasks are being executed simultaneously.
322
	 *  2. Notifications when a task is manually executed.
323
	 *  3. Tables are missing.
324
	 */
325
	public function display_admin_notices() {
326
		global $wpdb;
327
328
		if ( ( is_a( $this->store, 'ActionScheduler_HybridStore' ) || is_a( $this->store, 'ActionScheduler_DBStore' ) ) && apply_filters( 'action_scheduler_enable_recreate_data_store', true ) ) {
329
			$table_list = array(
330
				'actionscheduler_actions',
331
				'actionscheduler_logs',
332
				'actionscheduler_groups',
333
				'actionscheduler_claims',
334
			);
335
336
			$found_tables = $wpdb->get_col( "SHOW TABLES LIKE '{$wpdb->prefix}actionscheduler%'" ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
337
			foreach ( $table_list as $table_name ) {
338
				if ( ! in_array( $wpdb->prefix . $table_name, $found_tables ) ) {
339
					$this->admin_notices[] = array(
340
						'class'   => 'error',
341
						'message' => __( 'It appears one or more database tables were missing. Attempting to re-create the missing table(s).' , 'action-scheduler' ),
342
					);
343
					$this->recreate_tables();
344
					parent::display_admin_notices();
345
346
					return;
347
				}
348
			}
349
		}
350
351
		if ( $this->runner->has_maximum_concurrent_batches() ) {
352
			$claim_count           = $this->store->get_claim_count();
353
			$this->admin_notices[] = array(
354
				'class'   => 'updated',
355
				'message' => sprintf(
356
					/* translators: %s: amount of claims */
357
					_n(
358
						'Maximum simultaneous queues already in progress (%s queue). No additional queues will begin processing until the current queues are complete.',
359
						'Maximum simultaneous queues already in progress (%s queues). No additional queues will begin processing until the current queues are complete.',
360
						$claim_count,
361
						'action-scheduler'
362
					),
363
					$claim_count
364
				),
365
			);
366
		} elseif ( $this->store->has_pending_actions_due() ) {
367
368
			$async_request_lock_expiration = ActionScheduler::lock()->get_expiration( 'async-request-runner' );
369
370
			// No lock set or lock expired
371
			if ( false === $async_request_lock_expiration || $async_request_lock_expiration < time() ) {
372
				$in_progress_url       = add_query_arg( 'status', 'in-progress', remove_query_arg( 'status' ) );
373
				/* translators: %s: process URL */
374
				$async_request_message = sprintf( __( 'A new queue has begun processing. <a href="%s">View actions in-progress &raquo;</a>', 'action-scheduler' ), esc_url( $in_progress_url ) );
375
			} else {
376
				/* translators: %d: seconds */
377
				$async_request_message = sprintf( __( 'The next queue will begin processing in approximately %d seconds.', 'action-scheduler' ), $async_request_lock_expiration - time() );
378
			}
379
380
			$this->admin_notices[] = array(
381
				'class'   => 'notice notice-info',
382
				'message' => $async_request_message,
383
			);
384
		}
385
386
		$notification = get_transient( 'action_scheduler_admin_notice' );
387
388
		if ( is_array( $notification ) ) {
389
			delete_transient( 'action_scheduler_admin_notice' );
390
391
			$action = $this->store->fetch_action( $notification['action_id'] );
392
			$action_hook_html = '<strong><code>' . $action->get_hook() . '</code></strong>';
393
			if ( 1 == $notification['success'] ) {
394
				$class = 'updated';
395
				switch ( $notification['row_action_type'] ) {
396
					case 'run' :
397
						/* translators: %s: action HTML */
398
						$action_message_html = sprintf( __( 'Successfully executed action: %s', 'action-scheduler' ), $action_hook_html );
399
						break;
400
					case 'cancel' :
401
						/* translators: %s: action HTML */
402
						$action_message_html = sprintf( __( 'Successfully canceled action: %s', 'action-scheduler' ), $action_hook_html );
403
						break;
404
					default :
405
						/* translators: %s: action HTML */
406
						$action_message_html = sprintf( __( 'Successfully processed change for action: %s', 'action-scheduler' ), $action_hook_html );
407
						break;
408
				}
409
			} else {
410
				$class = 'error';
411
				/* translators: 1: action HTML 2: action ID 3: error message */
412
				$action_message_html = sprintf( __( 'Could not process change for action: "%1$s" (ID: %2$d). Error: %3$s', 'action-scheduler' ), $action_hook_html, esc_html( $notification['action_id'] ), esc_html( $notification['error_message'] ) );
413
			}
414
415
			$action_message_html = apply_filters( 'action_scheduler_admin_notice_html', $action_message_html, $action, $notification );
416
417
			$this->admin_notices[] = array(
418
				'class'   => $class,
419
				'message' => $action_message_html,
420
			);
421
		}
422
423
		parent::display_admin_notices();
424
	}
425
426
	/**
427
	 * Prints the scheduled date in a human friendly format.
428
	 *
429
	 * @param array $row The array representation of the current row of the table
430
	 *
431
	 * @return string
432
	 */
433
	public function column_schedule( $row ) {
434
		return $this->get_schedule_display_string( $row['schedule'] );
435
	}
436
437
	/**
438
	 * Get the scheduled date in a human friendly format.
439
	 *
440
	 * @param ActionScheduler_Schedule $schedule
441
	 * @return string
442
	 */
443
	protected function get_schedule_display_string( ActionScheduler_Schedule $schedule ) {
444
445
		$schedule_display_string = '';
446
447
		if ( ! $schedule->get_date() ) {
0 ignored issues
show
Bug introduced by
The method get_date() does not exist on ActionScheduler_Schedule. It seems like you code against a sub-type of said class. However, the method does not exist in ActionScheduler_Schedule_Deprecated. Are you sure you never get one of those? ( Ignorable by Annotation )

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

447
		if ( ! $schedule->/** @scrutinizer ignore-call */ get_date() ) {
Loading history...
448
			return '0000-00-00 00:00:00';
449
		}
450
451
		$next_timestamp = $schedule->get_date()->getTimestamp();
452
453
		$schedule_display_string .= $schedule->get_date()->format( 'Y-m-d H:i:s O' );
454
		$schedule_display_string .= '<br/>';
455
456
		if ( gmdate( 'U' ) > $next_timestamp ) {
457
			/* translators: %s: date interval */
458
			$schedule_display_string .= sprintf( __( ' (%s ago)', 'action-scheduler' ), self::human_interval( gmdate( 'U' ) - $next_timestamp ) );
459
		} else {
460
			/* translators: %s: date interval */
461
			$schedule_display_string .= sprintf( __( ' (%s)', 'action-scheduler' ), self::human_interval( $next_timestamp - gmdate( 'U' ) ) );
462
		}
463
464
		return $schedule_display_string;
465
	}
466
467
	/**
468
	 * Bulk delete
469
	 *
470
	 * Deletes actions based on their ID. This is the handler for the bulk delete. It assumes the data
471
	 * properly validated by the callee and it will delete the actions without any extra validation.
472
	 *
473
	 * @param array $ids
474
	 * @param string $ids_sql Inherited and unused
475
	 */
476
	protected function bulk_delete( array $ids, $ids_sql ) {
477
		foreach ( $ids as $id ) {
478
			$this->store->delete_action( $id );
479
		}
480
	}
481
482
	/**
483
	 * Implements the logic behind running an action. ActionScheduler_Abstract_ListTable validates the request and their
484
	 * parameters are valid.
485
	 *
486
	 * @param int $action_id
487
	 */
488
	protected function row_action_cancel( $action_id ) {
489
		$this->process_row_action( $action_id, 'cancel' );
490
	}
491
492
	/**
493
	 * Implements the logic behind running an action. ActionScheduler_Abstract_ListTable validates the request and their
494
	 * parameters are valid.
495
	 *
496
	 * @param int $action_id
497
	 */
498
	protected function row_action_run( $action_id ) {
499
		$this->process_row_action( $action_id, 'run' );
500
	}
501
502
	/**
503
	 * Force the data store schema updates.
504
	 */
505
	protected function recreate_tables() {
506
		if ( is_a( $this->store, 'ActionScheduler_HybridStore' ) ) {
507
			$store = $this->store;
508
		} else {
509
			$store = new ActionScheduler_HybridStore();
510
		}
511
		add_action( 'action_scheduler/created_table', array( $store, 'set_autoincrement' ), 10, 2 );
512
513
		$store_schema  = new ActionScheduler_StoreSchema();
514
		$logger_schema = new ActionScheduler_LoggerSchema();
515
		$store_schema->register_tables( true );
516
		$logger_schema->register_tables( true );
517
518
		remove_action( 'action_scheduler/created_table', array( $store, 'set_autoincrement' ), 10 );
519
	}
520
	/**
521
	 * Implements the logic behind processing an action once an action link is clicked on the list table.
522
	 *
523
	 * @param int $action_id
524
	 * @param string $row_action_type The type of action to perform on the action.
525
	 */
526
	protected function process_row_action( $action_id, $row_action_type ) {
527
		try {
528
			switch ( $row_action_type ) {
529
				case 'run' :
530
					$this->runner->process_action( $action_id, 'Admin List Table' );
531
					break;
532
				case 'cancel' :
533
					$this->store->cancel_action( $action_id );
534
					break;
535
			}
536
			$success = 1;
537
			$error_message = '';
538
		} catch ( Exception $e ) {
539
			$success = 0;
540
			$error_message = $e->getMessage();
541
		}
542
543
		set_transient( 'action_scheduler_admin_notice', compact( 'action_id', 'success', 'error_message', 'row_action_type' ), 30 );
544
	}
545
546
	/**
547
	 * {@inheritDoc}
548
	 */
549
	public function prepare_items() {
550
		$this->prepare_column_headers();
551
552
		$per_page = $this->get_items_per_page( $this->package . '_items_per_page', $this->items_per_page );
553
		$query = array(
554
			'per_page' => $per_page,
555
			'offset'   => $this->get_items_offset(),
556
			'status'   => $this->get_request_status(),
557
			'orderby'  => $this->get_request_orderby(),
558
			'order'    => $this->get_request_order(),
559
			'search'   => $this->get_request_search_query(),
560
		);
561
562
		$this->items = array();
563
564
		$total_items = $this->store->query_actions( $query, 'count' );
565
566
		$status_labels = $this->store->get_status_labels();
567
568
		foreach ( $this->store->query_actions( $query ) as $action_id ) {
569
			try {
570
				$action = $this->store->fetch_action( $action_id );
571
			} catch ( Exception $e ) {
572
				continue;
573
			}
574
			if ( is_a( $action, 'ActionScheduler_NullAction' ) ) {
575
				continue;
576
			}
577
			$this->items[ $action_id ] = array(
578
				'ID'          => $action_id,
579
				'hook'        => $action->get_hook(),
580
				'status'      => $status_labels[ $this->store->get_status( $action_id ) ],
581
				'args'        => $action->get_args(),
582
				'group'       => $action->get_group(),
583
				'log_entries' => $this->logger->get_logs( $action_id ),
584
				'claim_id'    => $this->store->get_claim_id( $action_id ),
585
				'recurrence'  => $this->get_recurrence( $action ),
586
				'schedule'    => $action->get_schedule(),
587
			);
588
		}
589
590
		$this->set_pagination_args( array(
591
			'total_items' => $total_items,
592
			'per_page'    => $per_page,
593
			'total_pages' => ceil( $total_items / $per_page ),
594
		) );
595
	}
596
597
	/**
598
	 * Prints the available statuses so the user can click to filter.
599
	 */
600
	protected function display_filter_by_status() {
601
		$this->status_counts = $this->store->action_counts();
602
		parent::display_filter_by_status();
603
	}
604
605
	/**
606
	 * Get the text to display in the search box on the list table.
607
	 */
608
	protected function get_search_box_button_text() {
609
		return __( 'Search hook, args and claim ID', 'action-scheduler' );
610
	}
611
}
612