@@ -10,7 +10,7 @@ |
||
10 | 10 | * |
11 | 11 | * @param null $date The date & time to run the action. |
12 | 12 | */ |
13 | - public function __construct( DateTime $date = null ) { |
|
13 | + public function __construct(DateTime $date = null) { |
|
14 | 14 | $this->scheduled_date = null; |
15 | 15 | } |
16 | 16 |
@@ -5,25 +5,25 @@ |
||
5 | 5 | */ |
6 | 6 | class ActionScheduler_NullSchedule extends ActionScheduler_SimpleSchedule { |
7 | 7 | |
8 | - /** |
|
9 | - * Make the $date param optional and default to null. |
|
10 | - * |
|
11 | - * @param null $date The date & time to run the action. |
|
12 | - */ |
|
13 | - public function __construct( DateTime $date = null ) { |
|
14 | - $this->scheduled_date = null; |
|
15 | - } |
|
8 | + /** |
|
9 | + * Make the $date param optional and default to null. |
|
10 | + * |
|
11 | + * @param null $date The date & time to run the action. |
|
12 | + */ |
|
13 | + public function __construct( DateTime $date = null ) { |
|
14 | + $this->scheduled_date = null; |
|
15 | + } |
|
16 | 16 | |
17 | - /** |
|
18 | - * This schedule has no scheduled DateTime, so we need to override the parent __sleep() |
|
19 | - * |
|
20 | - * @return array |
|
21 | - */ |
|
22 | - public function __sleep() { |
|
23 | - return array(); |
|
24 | - } |
|
17 | + /** |
|
18 | + * This schedule has no scheduled DateTime, so we need to override the parent __sleep() |
|
19 | + * |
|
20 | + * @return array |
|
21 | + */ |
|
22 | + public function __sleep() { |
|
23 | + return array(); |
|
24 | + } |
|
25 | 25 | |
26 | - public function __wakeup() { |
|
27 | - $this->scheduled_date = null; |
|
28 | - } |
|
26 | + public function __wakeup() { |
|
27 | + $this->scheduled_date = null; |
|
28 | + } |
|
29 | 29 | } |
@@ -9,39 +9,39 @@ |
||
9 | 9 | */ |
10 | 10 | class ActionScheduler_InvalidActionException extends \InvalidArgumentException implements ActionScheduler_Exception { |
11 | 11 | |
12 | - /** |
|
13 | - * Create a new exception when the action's schedule cannot be fetched. |
|
14 | - * |
|
15 | - * @param string $action_id The action ID with bad args. |
|
16 | - * @return static |
|
17 | - */ |
|
18 | - public static function from_schedule( $action_id, $schedule ) { |
|
19 | - $message = sprintf( |
|
20 | - /* translators: 1: action ID 2: schedule */ |
|
21 | - __( 'Action [%1$s] has an invalid schedule: %2$s', 'action-scheduler' ), |
|
22 | - $action_id, |
|
23 | - var_export( $schedule, true ) |
|
24 | - ); |
|
12 | + /** |
|
13 | + * Create a new exception when the action's schedule cannot be fetched. |
|
14 | + * |
|
15 | + * @param string $action_id The action ID with bad args. |
|
16 | + * @return static |
|
17 | + */ |
|
18 | + public static function from_schedule( $action_id, $schedule ) { |
|
19 | + $message = sprintf( |
|
20 | + /* translators: 1: action ID 2: schedule */ |
|
21 | + __( 'Action [%1$s] has an invalid schedule: %2$s', 'action-scheduler' ), |
|
22 | + $action_id, |
|
23 | + var_export( $schedule, true ) |
|
24 | + ); |
|
25 | 25 | |
26 | - return new static( $message ); |
|
27 | - } |
|
26 | + return new static( $message ); |
|
27 | + } |
|
28 | 28 | |
29 | - /** |
|
30 | - * Create a new exception when the action's args cannot be decoded to an array. |
|
31 | - * |
|
32 | - * @author Jeremy Pry |
|
33 | - * |
|
34 | - * @param string $action_id The action ID with bad args. |
|
35 | - * @return static |
|
36 | - */ |
|
37 | - public static function from_decoding_args( $action_id, $args = array() ) { |
|
38 | - $message = sprintf( |
|
39 | - /* translators: 1: action ID 2: arguments */ |
|
40 | - __( 'Action [%1$s] has invalid arguments. It cannot be JSON decoded to an array. $args = %2$s', 'action-scheduler' ), |
|
41 | - $action_id, |
|
42 | - var_export( $args, true ) |
|
43 | - ); |
|
29 | + /** |
|
30 | + * Create a new exception when the action's args cannot be decoded to an array. |
|
31 | + * |
|
32 | + * @author Jeremy Pry |
|
33 | + * |
|
34 | + * @param string $action_id The action ID with bad args. |
|
35 | + * @return static |
|
36 | + */ |
|
37 | + public static function from_decoding_args( $action_id, $args = array() ) { |
|
38 | + $message = sprintf( |
|
39 | + /* translators: 1: action ID 2: arguments */ |
|
40 | + __( 'Action [%1$s] has invalid arguments. It cannot be JSON decoded to an array. $args = %2$s', 'action-scheduler' ), |
|
41 | + $action_id, |
|
42 | + var_export( $args, true ) |
|
43 | + ); |
|
44 | 44 | |
45 | - return new static( $message ); |
|
46 | - } |
|
45 | + return new static( $message ); |
|
46 | + } |
|
47 | 47 | } |
@@ -15,15 +15,15 @@ discard block |
||
15 | 15 | * @param string $action_id The action ID with bad args. |
16 | 16 | * @return static |
17 | 17 | */ |
18 | - public static function from_schedule( $action_id, $schedule ) { |
|
18 | + public static function from_schedule($action_id, $schedule) { |
|
19 | 19 | $message = sprintf( |
20 | 20 | /* translators: 1: action ID 2: schedule */ |
21 | - __( 'Action [%1$s] has an invalid schedule: %2$s', 'action-scheduler' ), |
|
21 | + __('Action [%1$s] has an invalid schedule: %2$s', 'action-scheduler'), |
|
22 | 22 | $action_id, |
23 | - var_export( $schedule, true ) |
|
23 | + var_export($schedule, true) |
|
24 | 24 | ); |
25 | 25 | |
26 | - return new static( $message ); |
|
26 | + return new static($message); |
|
27 | 27 | } |
28 | 28 | |
29 | 29 | /** |
@@ -34,14 +34,14 @@ discard block |
||
34 | 34 | * @param string $action_id The action ID with bad args. |
35 | 35 | * @return static |
36 | 36 | */ |
37 | - public static function from_decoding_args( $action_id, $args = array() ) { |
|
37 | + public static function from_decoding_args($action_id, $args = array()) { |
|
38 | 38 | $message = sprintf( |
39 | 39 | /* translators: 1: action ID 2: arguments */ |
40 | - __( 'Action [%1$s] has invalid arguments. It cannot be JSON decoded to an array. $args = %2$s', 'action-scheduler' ), |
|
40 | + __('Action [%1$s] has invalid arguments. It cannot be JSON decoded to an array. $args = %2$s', 'action-scheduler'), |
|
41 | 41 | $action_id, |
42 | - var_export( $args, true ) |
|
42 | + var_export($args, true) |
|
43 | 43 | ); |
44 | 44 | |
45 | - return new static( $message ); |
|
45 | + return new static($message); |
|
46 | 46 | } |
47 | 47 | } |
@@ -9,41 +9,41 @@ |
||
9 | 9 | */ |
10 | 10 | class ActionScheduler_OptionLock extends ActionScheduler_Lock { |
11 | 11 | |
12 | - /** |
|
13 | - * Set a lock using options for a given amount of time (60 seconds by default). |
|
14 | - * |
|
15 | - * Using an autoloaded option avoids running database queries or other resource intensive tasks |
|
16 | - * on frequently triggered hooks, like 'init' or 'shutdown'. |
|
17 | - * |
|
18 | - * For example, ActionScheduler_QueueRunner->maybe_dispatch_async_request() uses a lock to avoid |
|
19 | - * calling ActionScheduler_QueueRunner->has_maximum_concurrent_batches() every time the 'shutdown', |
|
20 | - * hook is triggered, because that method calls ActionScheduler_QueueRunner->store->get_claim_count() |
|
21 | - * to find the current number of claims in the database. |
|
22 | - * |
|
23 | - * @param string $lock_type A string to identify different lock types. |
|
24 | - * @bool True if lock value has changed, false if not or if set failed. |
|
25 | - */ |
|
26 | - public function set( $lock_type ) { |
|
27 | - return update_option( $this->get_key( $lock_type ), time() + $this->get_duration( $lock_type ) ); |
|
28 | - } |
|
12 | + /** |
|
13 | + * Set a lock using options for a given amount of time (60 seconds by default). |
|
14 | + * |
|
15 | + * Using an autoloaded option avoids running database queries or other resource intensive tasks |
|
16 | + * on frequently triggered hooks, like 'init' or 'shutdown'. |
|
17 | + * |
|
18 | + * For example, ActionScheduler_QueueRunner->maybe_dispatch_async_request() uses a lock to avoid |
|
19 | + * calling ActionScheduler_QueueRunner->has_maximum_concurrent_batches() every time the 'shutdown', |
|
20 | + * hook is triggered, because that method calls ActionScheduler_QueueRunner->store->get_claim_count() |
|
21 | + * to find the current number of claims in the database. |
|
22 | + * |
|
23 | + * @param string $lock_type A string to identify different lock types. |
|
24 | + * @bool True if lock value has changed, false if not or if set failed. |
|
25 | + */ |
|
26 | + public function set( $lock_type ) { |
|
27 | + return update_option( $this->get_key( $lock_type ), time() + $this->get_duration( $lock_type ) ); |
|
28 | + } |
|
29 | 29 | |
30 | - /** |
|
31 | - * If a lock is set, return the timestamp it was set to expiry. |
|
32 | - * |
|
33 | - * @param string $lock_type A string to identify different lock types. |
|
34 | - * @return bool|int False if no lock is set, otherwise the timestamp for when the lock is set to expire. |
|
35 | - */ |
|
36 | - public function get_expiration( $lock_type ) { |
|
37 | - return get_option( $this->get_key( $lock_type ) ); |
|
38 | - } |
|
30 | + /** |
|
31 | + * If a lock is set, return the timestamp it was set to expiry. |
|
32 | + * |
|
33 | + * @param string $lock_type A string to identify different lock types. |
|
34 | + * @return bool|int False if no lock is set, otherwise the timestamp for when the lock is set to expire. |
|
35 | + */ |
|
36 | + public function get_expiration( $lock_type ) { |
|
37 | + return get_option( $this->get_key( $lock_type ) ); |
|
38 | + } |
|
39 | 39 | |
40 | - /** |
|
41 | - * Get the key to use for storing the lock in the transient |
|
42 | - * |
|
43 | - * @param string $lock_type A string to identify different lock types. |
|
44 | - * @return string |
|
45 | - */ |
|
46 | - protected function get_key( $lock_type ) { |
|
47 | - return sprintf( 'action_scheduler_lock_%s', $lock_type ); |
|
48 | - } |
|
40 | + /** |
|
41 | + * Get the key to use for storing the lock in the transient |
|
42 | + * |
|
43 | + * @param string $lock_type A string to identify different lock types. |
|
44 | + * @return string |
|
45 | + */ |
|
46 | + protected function get_key( $lock_type ) { |
|
47 | + return sprintf( 'action_scheduler_lock_%s', $lock_type ); |
|
48 | + } |
|
49 | 49 | } |
@@ -23,8 +23,8 @@ discard block |
||
23 | 23 | * @param string $lock_type A string to identify different lock types. |
24 | 24 | * @bool True if lock value has changed, false if not or if set failed. |
25 | 25 | */ |
26 | - public function set( $lock_type ) { |
|
27 | - return update_option( $this->get_key( $lock_type ), time() + $this->get_duration( $lock_type ) ); |
|
26 | + public function set($lock_type) { |
|
27 | + return update_option($this->get_key($lock_type), time() + $this->get_duration($lock_type)); |
|
28 | 28 | } |
29 | 29 | |
30 | 30 | /** |
@@ -33,8 +33,8 @@ discard block |
||
33 | 33 | * @param string $lock_type A string to identify different lock types. |
34 | 34 | * @return bool|int False if no lock is set, otherwise the timestamp for when the lock is set to expire. |
35 | 35 | */ |
36 | - public function get_expiration( $lock_type ) { |
|
37 | - return get_option( $this->get_key( $lock_type ) ); |
|
36 | + public function get_expiration($lock_type) { |
|
37 | + return get_option($this->get_key($lock_type)); |
|
38 | 38 | } |
39 | 39 | |
40 | 40 | /** |
@@ -43,7 +43,7 @@ discard block |
||
43 | 43 | * @param string $lock_type A string to identify different lock types. |
44 | 44 | * @return string |
45 | 45 | */ |
46 | - protected function get_key( $lock_type ) { |
|
47 | - return sprintf( 'action_scheduler_lock_%s', $lock_type ); |
|
46 | + protected function get_key($lock_type) { |
|
47 | + return sprintf('action_scheduler_lock_%s', $lock_type); |
|
48 | 48 | } |
49 | 49 | } |
@@ -10,88 +10,88 @@ |
||
10 | 10 | */ |
11 | 11 | class ActionScheduler_AsyncRequest_QueueRunner extends WP_Async_Request { |
12 | 12 | |
13 | - /** |
|
14 | - * Data store for querying actions |
|
15 | - * |
|
16 | - * @var ActionScheduler_Store |
|
17 | - * @access protected |
|
18 | - */ |
|
19 | - protected $store; |
|
20 | - |
|
21 | - /** |
|
22 | - * Prefix for ajax hooks |
|
23 | - * |
|
24 | - * @var string |
|
25 | - * @access protected |
|
26 | - */ |
|
27 | - protected $prefix = 'as'; |
|
28 | - |
|
29 | - /** |
|
30 | - * Action for ajax hooks |
|
31 | - * |
|
32 | - * @var string |
|
33 | - * @access protected |
|
34 | - */ |
|
35 | - protected $action = 'async_request_queue_runner'; |
|
36 | - |
|
37 | - /** |
|
38 | - * Initiate new async request |
|
39 | - */ |
|
40 | - public function __construct( ActionScheduler_Store $store ) { |
|
41 | - parent::__construct(); |
|
42 | - $this->store = $store; |
|
43 | - } |
|
44 | - |
|
45 | - /** |
|
46 | - * Handle async requests |
|
47 | - * |
|
48 | - * Run a queue, and maybe dispatch another async request to run another queue |
|
49 | - * if there are still pending actions after completing a queue in this request. |
|
50 | - */ |
|
51 | - protected function handle() { |
|
52 | - do_action( 'action_scheduler_run_queue', 'Async Request' ); // run a queue in the same way as WP Cron, but declare the Async Request context |
|
53 | - |
|
54 | - $sleep_seconds = $this->get_sleep_seconds(); |
|
55 | - |
|
56 | - if ( $sleep_seconds ) { |
|
57 | - sleep( $sleep_seconds ); |
|
58 | - } |
|
59 | - |
|
60 | - $this->maybe_dispatch(); |
|
61 | - } |
|
62 | - |
|
63 | - /** |
|
64 | - * If the async request runner is needed and allowed to run, dispatch a request. |
|
65 | - */ |
|
66 | - public function maybe_dispatch() { |
|
67 | - if ( ! $this->allow() ) { |
|
68 | - return; |
|
69 | - } |
|
70 | - |
|
71 | - $this->dispatch(); |
|
72 | - ActionScheduler_QueueRunner::instance()->unhook_dispatch_async_request(); |
|
73 | - } |
|
74 | - |
|
75 | - /** |
|
76 | - * Only allow async requests when needed. |
|
77 | - * |
|
78 | - * Also allow 3rd party code to disable running actions via async requests. |
|
79 | - */ |
|
80 | - protected function allow() { |
|
81 | - |
|
82 | - if ( ! has_action( 'action_scheduler_run_queue' ) || ActionScheduler::runner()->has_maximum_concurrent_batches() || ! $this->store->has_pending_actions_due() ) { |
|
83 | - $allow = false; |
|
84 | - } else { |
|
85 | - $allow = true; |
|
86 | - } |
|
87 | - |
|
88 | - return apply_filters( 'action_scheduler_allow_async_request_runner', $allow ); |
|
89 | - } |
|
90 | - |
|
91 | - /** |
|
92 | - * Chaining async requests can crash MySQL. A brief sleep call in PHP prevents that. |
|
93 | - */ |
|
94 | - protected function get_sleep_seconds() { |
|
95 | - return apply_filters( 'action_scheduler_async_request_sleep_seconds', 5, $this ); |
|
96 | - } |
|
13 | + /** |
|
14 | + * Data store for querying actions |
|
15 | + * |
|
16 | + * @var ActionScheduler_Store |
|
17 | + * @access protected |
|
18 | + */ |
|
19 | + protected $store; |
|
20 | + |
|
21 | + /** |
|
22 | + * Prefix for ajax hooks |
|
23 | + * |
|
24 | + * @var string |
|
25 | + * @access protected |
|
26 | + */ |
|
27 | + protected $prefix = 'as'; |
|
28 | + |
|
29 | + /** |
|
30 | + * Action for ajax hooks |
|
31 | + * |
|
32 | + * @var string |
|
33 | + * @access protected |
|
34 | + */ |
|
35 | + protected $action = 'async_request_queue_runner'; |
|
36 | + |
|
37 | + /** |
|
38 | + * Initiate new async request |
|
39 | + */ |
|
40 | + public function __construct( ActionScheduler_Store $store ) { |
|
41 | + parent::__construct(); |
|
42 | + $this->store = $store; |
|
43 | + } |
|
44 | + |
|
45 | + /** |
|
46 | + * Handle async requests |
|
47 | + * |
|
48 | + * Run a queue, and maybe dispatch another async request to run another queue |
|
49 | + * if there are still pending actions after completing a queue in this request. |
|
50 | + */ |
|
51 | + protected function handle() { |
|
52 | + do_action( 'action_scheduler_run_queue', 'Async Request' ); // run a queue in the same way as WP Cron, but declare the Async Request context |
|
53 | + |
|
54 | + $sleep_seconds = $this->get_sleep_seconds(); |
|
55 | + |
|
56 | + if ( $sleep_seconds ) { |
|
57 | + sleep( $sleep_seconds ); |
|
58 | + } |
|
59 | + |
|
60 | + $this->maybe_dispatch(); |
|
61 | + } |
|
62 | + |
|
63 | + /** |
|
64 | + * If the async request runner is needed and allowed to run, dispatch a request. |
|
65 | + */ |
|
66 | + public function maybe_dispatch() { |
|
67 | + if ( ! $this->allow() ) { |
|
68 | + return; |
|
69 | + } |
|
70 | + |
|
71 | + $this->dispatch(); |
|
72 | + ActionScheduler_QueueRunner::instance()->unhook_dispatch_async_request(); |
|
73 | + } |
|
74 | + |
|
75 | + /** |
|
76 | + * Only allow async requests when needed. |
|
77 | + * |
|
78 | + * Also allow 3rd party code to disable running actions via async requests. |
|
79 | + */ |
|
80 | + protected function allow() { |
|
81 | + |
|
82 | + if ( ! has_action( 'action_scheduler_run_queue' ) || ActionScheduler::runner()->has_maximum_concurrent_batches() || ! $this->store->has_pending_actions_due() ) { |
|
83 | + $allow = false; |
|
84 | + } else { |
|
85 | + $allow = true; |
|
86 | + } |
|
87 | + |
|
88 | + return apply_filters( 'action_scheduler_allow_async_request_runner', $allow ); |
|
89 | + } |
|
90 | + |
|
91 | + /** |
|
92 | + * Chaining async requests can crash MySQL. A brief sleep call in PHP prevents that. |
|
93 | + */ |
|
94 | + protected function get_sleep_seconds() { |
|
95 | + return apply_filters( 'action_scheduler_async_request_sleep_seconds', 5, $this ); |
|
96 | + } |
|
97 | 97 | } |
@@ -3,7 +3,7 @@ discard block |
||
3 | 3 | * ActionScheduler_AsyncRequest_QueueRunner |
4 | 4 | */ |
5 | 5 | |
6 | -defined( 'ABSPATH' ) || exit; |
|
6 | +defined('ABSPATH') || exit; |
|
7 | 7 | |
8 | 8 | /** |
9 | 9 | * ActionScheduler_AsyncRequest_QueueRunner class. |
@@ -37,7 +37,7 @@ discard block |
||
37 | 37 | /** |
38 | 38 | * Initiate new async request |
39 | 39 | */ |
40 | - public function __construct( ActionScheduler_Store $store ) { |
|
40 | + public function __construct(ActionScheduler_Store $store) { |
|
41 | 41 | parent::__construct(); |
42 | 42 | $this->store = $store; |
43 | 43 | } |
@@ -49,12 +49,12 @@ discard block |
||
49 | 49 | * if there are still pending actions after completing a queue in this request. |
50 | 50 | */ |
51 | 51 | protected function handle() { |
52 | - do_action( 'action_scheduler_run_queue', 'Async Request' ); // run a queue in the same way as WP Cron, but declare the Async Request context |
|
52 | + do_action('action_scheduler_run_queue', 'Async Request'); // run a queue in the same way as WP Cron, but declare the Async Request context |
|
53 | 53 | |
54 | 54 | $sleep_seconds = $this->get_sleep_seconds(); |
55 | 55 | |
56 | - if ( $sleep_seconds ) { |
|
57 | - sleep( $sleep_seconds ); |
|
56 | + if ($sleep_seconds) { |
|
57 | + sleep($sleep_seconds); |
|
58 | 58 | } |
59 | 59 | |
60 | 60 | $this->maybe_dispatch(); |
@@ -64,7 +64,7 @@ discard block |
||
64 | 64 | * If the async request runner is needed and allowed to run, dispatch a request. |
65 | 65 | */ |
66 | 66 | public function maybe_dispatch() { |
67 | - if ( ! $this->allow() ) { |
|
67 | + if ( ! $this->allow()) { |
|
68 | 68 | return; |
69 | 69 | } |
70 | 70 | |
@@ -79,19 +79,19 @@ discard block |
||
79 | 79 | */ |
80 | 80 | protected function allow() { |
81 | 81 | |
82 | - if ( ! has_action( 'action_scheduler_run_queue' ) || ActionScheduler::runner()->has_maximum_concurrent_batches() || ! $this->store->has_pending_actions_due() ) { |
|
82 | + if ( ! has_action('action_scheduler_run_queue') || ActionScheduler::runner()->has_maximum_concurrent_batches() || ! $this->store->has_pending_actions_due()) { |
|
83 | 83 | $allow = false; |
84 | 84 | } else { |
85 | 85 | $allow = true; |
86 | 86 | } |
87 | 87 | |
88 | - return apply_filters( 'action_scheduler_allow_async_request_runner', $allow ); |
|
88 | + return apply_filters('action_scheduler_allow_async_request_runner', $allow); |
|
89 | 89 | } |
90 | 90 | |
91 | 91 | /** |
92 | 92 | * Chaining async requests can crash MySQL. A brief sleep call in PHP prevents that. |
93 | 93 | */ |
94 | 94 | protected function get_sleep_seconds() { |
95 | - return apply_filters( 'action_scheduler_async_request_sleep_seconds', 5, $this ); |
|
95 | + return apply_filters('action_scheduler_async_request_sleep_seconds', 5, $this); |
|
96 | 96 | } |
97 | 97 | } |
@@ -7,73 +7,73 @@ |
||
7 | 7 | */ |
8 | 8 | class ActionScheduler_DateTime extends DateTime { |
9 | 9 | |
10 | - /** |
|
11 | - * UTC offset. |
|
12 | - * |
|
13 | - * Only used when a timezone is not set. When a timezone string is |
|
14 | - * used, this will be set to 0. |
|
15 | - * |
|
16 | - * @var int |
|
17 | - */ |
|
18 | - protected $utcOffset = 0; |
|
10 | + /** |
|
11 | + * UTC offset. |
|
12 | + * |
|
13 | + * Only used when a timezone is not set. When a timezone string is |
|
14 | + * used, this will be set to 0. |
|
15 | + * |
|
16 | + * @var int |
|
17 | + */ |
|
18 | + protected $utcOffset = 0; |
|
19 | 19 | |
20 | - /** |
|
21 | - * Get the unix timestamp of the current object. |
|
22 | - * |
|
23 | - * Missing in PHP 5.2 so just here so it can be supported consistently. |
|
24 | - * |
|
25 | - * @return int |
|
26 | - */ |
|
27 | - #[\ReturnTypeWillChange] |
|
28 | - public function getTimestamp() { |
|
29 | - return method_exists( 'DateTime', 'getTimestamp' ) ? parent::getTimestamp() : $this->format( 'U' ); |
|
30 | - } |
|
20 | + /** |
|
21 | + * Get the unix timestamp of the current object. |
|
22 | + * |
|
23 | + * Missing in PHP 5.2 so just here so it can be supported consistently. |
|
24 | + * |
|
25 | + * @return int |
|
26 | + */ |
|
27 | + #[\ReturnTypeWillChange] |
|
28 | + public function getTimestamp() { |
|
29 | + return method_exists( 'DateTime', 'getTimestamp' ) ? parent::getTimestamp() : $this->format( 'U' ); |
|
30 | + } |
|
31 | 31 | |
32 | - /** |
|
33 | - * Set the UTC offset. |
|
34 | - * |
|
35 | - * This represents a fixed offset instead of a timezone setting. |
|
36 | - * |
|
37 | - * @param $offset |
|
38 | - */ |
|
39 | - public function setUtcOffset( $offset ) { |
|
40 | - $this->utcOffset = intval( $offset ); |
|
41 | - } |
|
32 | + /** |
|
33 | + * Set the UTC offset. |
|
34 | + * |
|
35 | + * This represents a fixed offset instead of a timezone setting. |
|
36 | + * |
|
37 | + * @param $offset |
|
38 | + */ |
|
39 | + public function setUtcOffset( $offset ) { |
|
40 | + $this->utcOffset = intval( $offset ); |
|
41 | + } |
|
42 | 42 | |
43 | - /** |
|
44 | - * Returns the timezone offset. |
|
45 | - * |
|
46 | - * @return int |
|
47 | - * @link http://php.net/manual/en/datetime.getoffset.php |
|
48 | - */ |
|
49 | - #[\ReturnTypeWillChange] |
|
50 | - public function getOffset() { |
|
51 | - return $this->utcOffset ? $this->utcOffset : parent::getOffset(); |
|
52 | - } |
|
43 | + /** |
|
44 | + * Returns the timezone offset. |
|
45 | + * |
|
46 | + * @return int |
|
47 | + * @link http://php.net/manual/en/datetime.getoffset.php |
|
48 | + */ |
|
49 | + #[\ReturnTypeWillChange] |
|
50 | + public function getOffset() { |
|
51 | + return $this->utcOffset ? $this->utcOffset : parent::getOffset(); |
|
52 | + } |
|
53 | 53 | |
54 | - /** |
|
55 | - * Set the TimeZone associated with the DateTime |
|
56 | - * |
|
57 | - * @param DateTimeZone $timezone |
|
58 | - * |
|
59 | - * @return static |
|
60 | - * @link http://php.net/manual/en/datetime.settimezone.php |
|
61 | - */ |
|
62 | - #[\ReturnTypeWillChange] |
|
63 | - public function setTimezone( $timezone ) { |
|
64 | - $this->utcOffset = 0; |
|
65 | - parent::setTimezone( $timezone ); |
|
54 | + /** |
|
55 | + * Set the TimeZone associated with the DateTime |
|
56 | + * |
|
57 | + * @param DateTimeZone $timezone |
|
58 | + * |
|
59 | + * @return static |
|
60 | + * @link http://php.net/manual/en/datetime.settimezone.php |
|
61 | + */ |
|
62 | + #[\ReturnTypeWillChange] |
|
63 | + public function setTimezone( $timezone ) { |
|
64 | + $this->utcOffset = 0; |
|
65 | + parent::setTimezone( $timezone ); |
|
66 | 66 | |
67 | - return $this; |
|
68 | - } |
|
67 | + return $this; |
|
68 | + } |
|
69 | 69 | |
70 | - /** |
|
71 | - * Get the timestamp with the WordPress timezone offset added or subtracted. |
|
72 | - * |
|
73 | - * @since 3.0.0 |
|
74 | - * @return int |
|
75 | - */ |
|
76 | - public function getOffsetTimestamp() { |
|
77 | - return $this->getTimestamp() + $this->getOffset(); |
|
78 | - } |
|
70 | + /** |
|
71 | + * Get the timestamp with the WordPress timezone offset added or subtracted. |
|
72 | + * |
|
73 | + * @since 3.0.0 |
|
74 | + * @return int |
|
75 | + */ |
|
76 | + public function getOffsetTimestamp() { |
|
77 | + return $this->getTimestamp() + $this->getOffset(); |
|
78 | + } |
|
79 | 79 | } |
@@ -26,7 +26,7 @@ discard block |
||
26 | 26 | */ |
27 | 27 | #[\ReturnTypeWillChange] |
28 | 28 | public function getTimestamp() { |
29 | - return method_exists( 'DateTime', 'getTimestamp' ) ? parent::getTimestamp() : $this->format( 'U' ); |
|
29 | + return method_exists('DateTime', 'getTimestamp') ? parent::getTimestamp() : $this->format('U'); |
|
30 | 30 | } |
31 | 31 | |
32 | 32 | /** |
@@ -36,8 +36,8 @@ discard block |
||
36 | 36 | * |
37 | 37 | * @param $offset |
38 | 38 | */ |
39 | - public function setUtcOffset( $offset ) { |
|
40 | - $this->utcOffset = intval( $offset ); |
|
39 | + public function setUtcOffset($offset) { |
|
40 | + $this->utcOffset = intval($offset); |
|
41 | 41 | } |
42 | 42 | |
43 | 43 | /** |
@@ -60,9 +60,9 @@ discard block |
||
60 | 60 | * @link http://php.net/manual/en/datetime.settimezone.php |
61 | 61 | */ |
62 | 62 | #[\ReturnTypeWillChange] |
63 | - public function setTimezone( $timezone ) { |
|
63 | + public function setTimezone($timezone) { |
|
64 | 64 | $this->utcOffset = 0; |
65 | - parent::setTimezone( $timezone ); |
|
65 | + parent::setTimezone($timezone); |
|
66 | 66 | |
67 | 67 | return $this; |
68 | 68 | } |
@@ -5,105 +5,105 @@ discard block |
||
5 | 5 | */ |
6 | 6 | class ActionScheduler_wcSystemStatus { |
7 | 7 | |
8 | - /** |
|
9 | - * The active data stores |
|
10 | - * |
|
11 | - * @var ActionScheduler_Store |
|
12 | - */ |
|
13 | - protected $store; |
|
14 | - |
|
15 | - /** |
|
16 | - * Constructor method for ActionScheduler_wcSystemStatus. |
|
17 | - * |
|
18 | - * @param ActionScheduler_Store $store Active store object. |
|
19 | - * |
|
20 | - * @return void |
|
21 | - */ |
|
22 | - public function __construct( $store ) { |
|
23 | - $this->store = $store; |
|
24 | - } |
|
25 | - |
|
26 | - /** |
|
27 | - * Display action data, including number of actions grouped by status and the oldest & newest action in each status. |
|
28 | - * |
|
29 | - * Helpful to identify issues, like a clogged queue. |
|
30 | - */ |
|
31 | - public function render() { |
|
32 | - $action_counts = $this->store->action_counts(); |
|
33 | - $status_labels = $this->store->get_status_labels(); |
|
34 | - $oldest_and_newest = $this->get_oldest_and_newest( array_keys( $status_labels ) ); |
|
35 | - |
|
36 | - $this->get_template( $status_labels, $action_counts, $oldest_and_newest ); |
|
37 | - } |
|
38 | - |
|
39 | - /** |
|
40 | - * Get oldest and newest scheduled dates for a given set of statuses. |
|
41 | - * |
|
42 | - * @param array $status_keys Set of statuses to find oldest & newest action for. |
|
43 | - * @return array |
|
44 | - */ |
|
45 | - protected function get_oldest_and_newest( $status_keys ) { |
|
46 | - |
|
47 | - $oldest_and_newest = array(); |
|
48 | - |
|
49 | - foreach ( $status_keys as $status ) { |
|
50 | - $oldest_and_newest[ $status ] = array( |
|
51 | - 'oldest' => '–', |
|
52 | - 'newest' => '–', |
|
53 | - ); |
|
54 | - |
|
55 | - if ( 'in-progress' === $status ) { |
|
56 | - continue; |
|
57 | - } |
|
58 | - |
|
59 | - $oldest_and_newest[ $status ]['oldest'] = $this->get_action_status_date( $status, 'oldest' ); |
|
60 | - $oldest_and_newest[ $status ]['newest'] = $this->get_action_status_date( $status, 'newest' ); |
|
61 | - } |
|
62 | - |
|
63 | - return $oldest_and_newest; |
|
64 | - } |
|
65 | - |
|
66 | - /** |
|
67 | - * Get oldest or newest scheduled date for a given status. |
|
68 | - * |
|
69 | - * @param string $status Action status label/name string. |
|
70 | - * @param string $date_type Oldest or Newest. |
|
71 | - * @return DateTime |
|
72 | - */ |
|
73 | - protected function get_action_status_date( $status, $date_type = 'oldest' ) { |
|
74 | - |
|
75 | - $order = 'oldest' === $date_type ? 'ASC' : 'DESC'; |
|
76 | - |
|
77 | - $action = $this->store->query_actions( |
|
78 | - array( |
|
79 | - 'claimed' => false, |
|
80 | - 'status' => $status, |
|
81 | - 'per_page' => 1, |
|
82 | - 'order' => $order, |
|
83 | - ) |
|
84 | - ); |
|
85 | - |
|
86 | - if ( ! empty( $action ) ) { |
|
87 | - $date_object = $this->store->get_date( $action[0] ); |
|
88 | - $action_date = $date_object->format( 'Y-m-d H:i:s O' ); |
|
89 | - } else { |
|
90 | - $action_date = '–'; |
|
91 | - } |
|
92 | - |
|
93 | - return $action_date; |
|
94 | - } |
|
95 | - |
|
96 | - /** |
|
97 | - * Get oldest or newest scheduled date for a given status. |
|
98 | - * |
|
99 | - * @param array $status_labels Set of statuses to find oldest & newest action for. |
|
100 | - * @param array $action_counts Number of actions grouped by status. |
|
101 | - * @param array $oldest_and_newest Date of the oldest and newest action with each status. |
|
102 | - */ |
|
103 | - protected function get_template( $status_labels, $action_counts, $oldest_and_newest ) { |
|
104 | - $as_version = ActionScheduler_Versions::instance()->latest_version(); |
|
105 | - $as_datastore = get_class( ActionScheduler_Store::instance() ); |
|
106 | - ?> |
|
8 | + /** |
|
9 | + * The active data stores |
|
10 | + * |
|
11 | + * @var ActionScheduler_Store |
|
12 | + */ |
|
13 | + protected $store; |
|
14 | + |
|
15 | + /** |
|
16 | + * Constructor method for ActionScheduler_wcSystemStatus. |
|
17 | + * |
|
18 | + * @param ActionScheduler_Store $store Active store object. |
|
19 | + * |
|
20 | + * @return void |
|
21 | + */ |
|
22 | + public function __construct( $store ) { |
|
23 | + $this->store = $store; |
|
24 | + } |
|
25 | + |
|
26 | + /** |
|
27 | + * Display action data, including number of actions grouped by status and the oldest & newest action in each status. |
|
28 | + * |
|
29 | + * Helpful to identify issues, like a clogged queue. |
|
30 | + */ |
|
31 | + public function render() { |
|
32 | + $action_counts = $this->store->action_counts(); |
|
33 | + $status_labels = $this->store->get_status_labels(); |
|
34 | + $oldest_and_newest = $this->get_oldest_and_newest( array_keys( $status_labels ) ); |
|
35 | + |
|
36 | + $this->get_template( $status_labels, $action_counts, $oldest_and_newest ); |
|
37 | + } |
|
38 | + |
|
39 | + /** |
|
40 | + * Get oldest and newest scheduled dates for a given set of statuses. |
|
41 | + * |
|
42 | + * @param array $status_keys Set of statuses to find oldest & newest action for. |
|
43 | + * @return array |
|
44 | + */ |
|
45 | + protected function get_oldest_and_newest( $status_keys ) { |
|
46 | + |
|
47 | + $oldest_and_newest = array(); |
|
48 | + |
|
49 | + foreach ( $status_keys as $status ) { |
|
50 | + $oldest_and_newest[ $status ] = array( |
|
51 | + 'oldest' => '–', |
|
52 | + 'newest' => '–', |
|
53 | + ); |
|
54 | + |
|
55 | + if ( 'in-progress' === $status ) { |
|
56 | + continue; |
|
57 | + } |
|
58 | + |
|
59 | + $oldest_and_newest[ $status ]['oldest'] = $this->get_action_status_date( $status, 'oldest' ); |
|
60 | + $oldest_and_newest[ $status ]['newest'] = $this->get_action_status_date( $status, 'newest' ); |
|
61 | + } |
|
62 | + |
|
63 | + return $oldest_and_newest; |
|
64 | + } |
|
65 | + |
|
66 | + /** |
|
67 | + * Get oldest or newest scheduled date for a given status. |
|
68 | + * |
|
69 | + * @param string $status Action status label/name string. |
|
70 | + * @param string $date_type Oldest or Newest. |
|
71 | + * @return DateTime |
|
72 | + */ |
|
73 | + protected function get_action_status_date( $status, $date_type = 'oldest' ) { |
|
74 | + |
|
75 | + $order = 'oldest' === $date_type ? 'ASC' : 'DESC'; |
|
76 | + |
|
77 | + $action = $this->store->query_actions( |
|
78 | + array( |
|
79 | + 'claimed' => false, |
|
80 | + 'status' => $status, |
|
81 | + 'per_page' => 1, |
|
82 | + 'order' => $order, |
|
83 | + ) |
|
84 | + ); |
|
85 | + |
|
86 | + if ( ! empty( $action ) ) { |
|
87 | + $date_object = $this->store->get_date( $action[0] ); |
|
88 | + $action_date = $date_object->format( 'Y-m-d H:i:s O' ); |
|
89 | + } else { |
|
90 | + $action_date = '–'; |
|
91 | + } |
|
92 | + |
|
93 | + return $action_date; |
|
94 | + } |
|
95 | + |
|
96 | + /** |
|
97 | + * Get oldest or newest scheduled date for a given status. |
|
98 | + * |
|
99 | + * @param array $status_labels Set of statuses to find oldest & newest action for. |
|
100 | + * @param array $action_counts Number of actions grouped by status. |
|
101 | + * @param array $oldest_and_newest Date of the oldest and newest action with each status. |
|
102 | + */ |
|
103 | + protected function get_template( $status_labels, $action_counts, $oldest_and_newest ) { |
|
104 | + $as_version = ActionScheduler_Versions::instance()->latest_version(); |
|
105 | + $as_datastore = get_class( ActionScheduler_Store::instance() ); |
|
106 | + ?> |
|
107 | 107 | |
108 | 108 | <table class="wc_status_table widefat" cellspacing="0"> |
109 | 109 | <thead> |
@@ -128,39 +128,39 @@ discard block |
||
128 | 128 | </thead> |
129 | 129 | <tbody> |
130 | 130 | <?php |
131 | - foreach ( $action_counts as $status => $count ) { |
|
132 | - // WC uses the 3rd column for export, so we need to display more data in that (hidden when viewed as part of the table) and add an empty 2nd column. |
|
133 | - printf( |
|
134 | - '<tr><td>%1$s</td><td> </td><td>%2$s<span style="display: none;">, Oldest: %3$s, Newest: %4$s</span></td><td>%3$s</td><td>%4$s</td></tr>', |
|
135 | - esc_html( $status_labels[ $status ] ), |
|
136 | - esc_html( number_format_i18n( $count ) ), |
|
137 | - esc_html( $oldest_and_newest[ $status ]['oldest'] ), |
|
138 | - esc_html( $oldest_and_newest[ $status ]['newest'] ) |
|
139 | - ); |
|
140 | - } |
|
141 | - ?> |
|
131 | + foreach ( $action_counts as $status => $count ) { |
|
132 | + // WC uses the 3rd column for export, so we need to display more data in that (hidden when viewed as part of the table) and add an empty 2nd column. |
|
133 | + printf( |
|
134 | + '<tr><td>%1$s</td><td> </td><td>%2$s<span style="display: none;">, Oldest: %3$s, Newest: %4$s</span></td><td>%3$s</td><td>%4$s</td></tr>', |
|
135 | + esc_html( $status_labels[ $status ] ), |
|
136 | + esc_html( number_format_i18n( $count ) ), |
|
137 | + esc_html( $oldest_and_newest[ $status ]['oldest'] ), |
|
138 | + esc_html( $oldest_and_newest[ $status ]['newest'] ) |
|
139 | + ); |
|
140 | + } |
|
141 | + ?> |
|
142 | 142 | </tbody> |
143 | 143 | </table> |
144 | 144 | |
145 | 145 | <?php |
146 | - } |
|
147 | - |
|
148 | - /** |
|
149 | - * Is triggered when invoking inaccessible methods in an object context. |
|
150 | - * |
|
151 | - * @param string $name Name of method called. |
|
152 | - * @param array $arguments Parameters to invoke the method with. |
|
153 | - * |
|
154 | - * @return mixed |
|
155 | - * @link https://php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.methods |
|
156 | - */ |
|
157 | - public function __call( $name, $arguments ) { |
|
158 | - switch ( $name ) { |
|
159 | - case 'print': |
|
160 | - _deprecated_function( __CLASS__ . '::print()', '2.2.4', __CLASS__ . '::render()' ); |
|
161 | - return call_user_func_array( array( $this, 'render' ), $arguments ); |
|
162 | - } |
|
163 | - |
|
164 | - return null; |
|
165 | - } |
|
146 | + } |
|
147 | + |
|
148 | + /** |
|
149 | + * Is triggered when invoking inaccessible methods in an object context. |
|
150 | + * |
|
151 | + * @param string $name Name of method called. |
|
152 | + * @param array $arguments Parameters to invoke the method with. |
|
153 | + * |
|
154 | + * @return mixed |
|
155 | + * @link https://php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.methods |
|
156 | + */ |
|
157 | + public function __call( $name, $arguments ) { |
|
158 | + switch ( $name ) { |
|
159 | + case 'print': |
|
160 | + _deprecated_function( __CLASS__ . '::print()', '2.2.4', __CLASS__ . '::render()' ); |
|
161 | + return call_user_func_array( array( $this, 'render' ), $arguments ); |
|
162 | + } |
|
163 | + |
|
164 | + return null; |
|
165 | + } |
|
166 | 166 | } |
@@ -19,7 +19,7 @@ discard block |
||
19 | 19 | * |
20 | 20 | * @return void |
21 | 21 | */ |
22 | - public function __construct( $store ) { |
|
22 | + public function __construct($store) { |
|
23 | 23 | $this->store = $store; |
24 | 24 | } |
25 | 25 | |
@@ -31,9 +31,9 @@ discard block |
||
31 | 31 | public function render() { |
32 | 32 | $action_counts = $this->store->action_counts(); |
33 | 33 | $status_labels = $this->store->get_status_labels(); |
34 | - $oldest_and_newest = $this->get_oldest_and_newest( array_keys( $status_labels ) ); |
|
34 | + $oldest_and_newest = $this->get_oldest_and_newest(array_keys($status_labels)); |
|
35 | 35 | |
36 | - $this->get_template( $status_labels, $action_counts, $oldest_and_newest ); |
|
36 | + $this->get_template($status_labels, $action_counts, $oldest_and_newest); |
|
37 | 37 | } |
38 | 38 | |
39 | 39 | /** |
@@ -42,22 +42,22 @@ discard block |
||
42 | 42 | * @param array $status_keys Set of statuses to find oldest & newest action for. |
43 | 43 | * @return array |
44 | 44 | */ |
45 | - protected function get_oldest_and_newest( $status_keys ) { |
|
45 | + protected function get_oldest_and_newest($status_keys) { |
|
46 | 46 | |
47 | 47 | $oldest_and_newest = array(); |
48 | 48 | |
49 | - foreach ( $status_keys as $status ) { |
|
50 | - $oldest_and_newest[ $status ] = array( |
|
49 | + foreach ($status_keys as $status) { |
|
50 | + $oldest_and_newest[$status] = array( |
|
51 | 51 | 'oldest' => '–', |
52 | 52 | 'newest' => '–', |
53 | 53 | ); |
54 | 54 | |
55 | - if ( 'in-progress' === $status ) { |
|
55 | + if ('in-progress' === $status) { |
|
56 | 56 | continue; |
57 | 57 | } |
58 | 58 | |
59 | - $oldest_and_newest[ $status ]['oldest'] = $this->get_action_status_date( $status, 'oldest' ); |
|
60 | - $oldest_and_newest[ $status ]['newest'] = $this->get_action_status_date( $status, 'newest' ); |
|
59 | + $oldest_and_newest[$status]['oldest'] = $this->get_action_status_date($status, 'oldest'); |
|
60 | + $oldest_and_newest[$status]['newest'] = $this->get_action_status_date($status, 'newest'); |
|
61 | 61 | } |
62 | 62 | |
63 | 63 | return $oldest_and_newest; |
@@ -70,7 +70,7 @@ discard block |
||
70 | 70 | * @param string $date_type Oldest or Newest. |
71 | 71 | * @return DateTime |
72 | 72 | */ |
73 | - protected function get_action_status_date( $status, $date_type = 'oldest' ) { |
|
73 | + protected function get_action_status_date($status, $date_type = 'oldest') { |
|
74 | 74 | |
75 | 75 | $order = 'oldest' === $date_type ? 'ASC' : 'DESC'; |
76 | 76 | |
@@ -83,9 +83,9 @@ discard block |
||
83 | 83 | ) |
84 | 84 | ); |
85 | 85 | |
86 | - if ( ! empty( $action ) ) { |
|
87 | - $date_object = $this->store->get_date( $action[0] ); |
|
88 | - $action_date = $date_object->format( 'Y-m-d H:i:s O' ); |
|
86 | + if ( ! empty($action)) { |
|
87 | + $date_object = $this->store->get_date($action[0]); |
|
88 | + $action_date = $date_object->format('Y-m-d H:i:s O'); |
|
89 | 89 | } else { |
90 | 90 | $action_date = '–'; |
91 | 91 | } |
@@ -100,42 +100,42 @@ discard block |
||
100 | 100 | * @param array $action_counts Number of actions grouped by status. |
101 | 101 | * @param array $oldest_and_newest Date of the oldest and newest action with each status. |
102 | 102 | */ |
103 | - protected function get_template( $status_labels, $action_counts, $oldest_and_newest ) { |
|
103 | + protected function get_template($status_labels, $action_counts, $oldest_and_newest) { |
|
104 | 104 | $as_version = ActionScheduler_Versions::instance()->latest_version(); |
105 | - $as_datastore = get_class( ActionScheduler_Store::instance() ); |
|
105 | + $as_datastore = get_class(ActionScheduler_Store::instance()); |
|
106 | 106 | ?> |
107 | 107 | |
108 | 108 | <table class="wc_status_table widefat" cellspacing="0"> |
109 | 109 | <thead> |
110 | 110 | <tr> |
111 | - <th colspan="5" data-export-label="Action Scheduler"><h2><?php esc_html_e( 'Action Scheduler', 'action-scheduler' ); ?><?php echo wc_help_tip( esc_html__( 'This section shows details of Action Scheduler.', 'action-scheduler' ) ); ?></h2></th> |
|
111 | + <th colspan="5" data-export-label="Action Scheduler"><h2><?php esc_html_e('Action Scheduler', 'action-scheduler'); ?><?php echo wc_help_tip(esc_html__('This section shows details of Action Scheduler.', 'action-scheduler')); ?></h2></th> |
|
112 | 112 | </tr> |
113 | 113 | <tr> |
114 | - <td colspan="2" data-export-label="Version"><?php esc_html_e( 'Version:', 'action-scheduler' ); ?></td> |
|
115 | - <td colspan="3"><?php echo esc_html( $as_version ); ?></td> |
|
114 | + <td colspan="2" data-export-label="Version"><?php esc_html_e('Version:', 'action-scheduler'); ?></td> |
|
115 | + <td colspan="3"><?php echo esc_html($as_version); ?></td> |
|
116 | 116 | </tr> |
117 | 117 | <tr> |
118 | - <td colspan="2" data-export-label="Data store"><?php esc_html_e( 'Data store:', 'action-scheduler' ); ?></td> |
|
119 | - <td colspan="3"><?php echo esc_html( $as_datastore ); ?></td> |
|
118 | + <td colspan="2" data-export-label="Data store"><?php esc_html_e('Data store:', 'action-scheduler'); ?></td> |
|
119 | + <td colspan="3"><?php echo esc_html($as_datastore); ?></td> |
|
120 | 120 | </tr> |
121 | 121 | <tr> |
122 | - <td><strong><?php esc_html_e( 'Action Status', 'action-scheduler' ); ?></strong></td> |
|
122 | + <td><strong><?php esc_html_e('Action Status', 'action-scheduler'); ?></strong></td> |
|
123 | 123 | <td class="help"> </td> |
124 | - <td><strong><?php esc_html_e( 'Count', 'action-scheduler' ); ?></strong></td> |
|
125 | - <td><strong><?php esc_html_e( 'Oldest Scheduled Date', 'action-scheduler' ); ?></strong></td> |
|
126 | - <td><strong><?php esc_html_e( 'Newest Scheduled Date', 'action-scheduler' ); ?></strong></td> |
|
124 | + <td><strong><?php esc_html_e('Count', 'action-scheduler'); ?></strong></td> |
|
125 | + <td><strong><?php esc_html_e('Oldest Scheduled Date', 'action-scheduler'); ?></strong></td> |
|
126 | + <td><strong><?php esc_html_e('Newest Scheduled Date', 'action-scheduler'); ?></strong></td> |
|
127 | 127 | </tr> |
128 | 128 | </thead> |
129 | 129 | <tbody> |
130 | 130 | <?php |
131 | - foreach ( $action_counts as $status => $count ) { |
|
131 | + foreach ($action_counts as $status => $count) { |
|
132 | 132 | // WC uses the 3rd column for export, so we need to display more data in that (hidden when viewed as part of the table) and add an empty 2nd column. |
133 | 133 | printf( |
134 | 134 | '<tr><td>%1$s</td><td> </td><td>%2$s<span style="display: none;">, Oldest: %3$s, Newest: %4$s</span></td><td>%3$s</td><td>%4$s</td></tr>', |
135 | - esc_html( $status_labels[ $status ] ), |
|
136 | - esc_html( number_format_i18n( $count ) ), |
|
137 | - esc_html( $oldest_and_newest[ $status ]['oldest'] ), |
|
138 | - esc_html( $oldest_and_newest[ $status ]['newest'] ) |
|
135 | + esc_html($status_labels[$status]), |
|
136 | + esc_html(number_format_i18n($count)), |
|
137 | + esc_html($oldest_and_newest[$status]['oldest']), |
|
138 | + esc_html($oldest_and_newest[$status]['newest']) |
|
139 | 139 | ); |
140 | 140 | } |
141 | 141 | ?> |
@@ -154,11 +154,11 @@ discard block |
||
154 | 154 | * @return mixed |
155 | 155 | * @link https://php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.methods |
156 | 156 | */ |
157 | - public function __call( $name, $arguments ) { |
|
158 | - switch ( $name ) { |
|
157 | + public function __call($name, $arguments) { |
|
158 | + switch ($name) { |
|
159 | 159 | case 'print': |
160 | - _deprecated_function( __CLASS__ . '::print()', '2.2.4', __CLASS__ . '::render()' ); |
|
161 | - return call_user_func_array( array( $this, 'render' ), $arguments ); |
|
160 | + _deprecated_function(__CLASS__.'::print()', '2.2.4', __CLASS__.'::render()'); |
|
161 | + return call_user_func_array(array($this, 'render'), $arguments); |
|
162 | 162 | } |
163 | 163 | |
164 | 164 | return null; |
@@ -1,7 +1,7 @@ discard block |
||
1 | 1 | <?php |
2 | 2 | |
3 | 3 | if ( ! class_exists( 'WP_List_Table' ) ) { |
4 | - require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php'; |
|
4 | + require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php'; |
|
5 | 5 | } |
6 | 6 | |
7 | 7 | /** |
@@ -23,744 +23,744 @@ discard block |
||
23 | 23 | */ |
24 | 24 | abstract class ActionScheduler_Abstract_ListTable extends WP_List_Table { |
25 | 25 | |
26 | - /** |
|
27 | - * The table name |
|
28 | - * |
|
29 | - * @var string |
|
30 | - */ |
|
31 | - protected $table_name; |
|
32 | - |
|
33 | - /** |
|
34 | - * Package name, used to get options from WP_List_Table::get_items_per_page. |
|
35 | - * |
|
36 | - * @var string |
|
37 | - */ |
|
38 | - protected $package; |
|
39 | - |
|
40 | - /** |
|
41 | - * How many items do we render per page? |
|
42 | - * |
|
43 | - * @var int |
|
44 | - */ |
|
45 | - protected $items_per_page = 10; |
|
46 | - |
|
47 | - /** |
|
48 | - * Enables search in this table listing. If this array |
|
49 | - * is empty it means the listing is not searchable. |
|
50 | - * |
|
51 | - * @var array |
|
52 | - */ |
|
53 | - protected $search_by = array(); |
|
54 | - |
|
55 | - /** |
|
56 | - * Columns to show in the table listing. It is a key => value pair. The |
|
57 | - * key must much the table column name and the value is the label, which is |
|
58 | - * automatically translated. |
|
59 | - * |
|
60 | - * @var array |
|
61 | - */ |
|
62 | - protected $columns = array(); |
|
63 | - |
|
64 | - /** |
|
65 | - * Defines the row-actions. It expects an array where the key |
|
66 | - * is the column name and the value is an array of actions. |
|
67 | - * |
|
68 | - * The array of actions are key => value, where key is the method name |
|
69 | - * (with the prefix row_action_<key>) and the value is the label |
|
70 | - * and title. |
|
71 | - * |
|
72 | - * @var array |
|
73 | - */ |
|
74 | - protected $row_actions = array(); |
|
75 | - |
|
76 | - /** |
|
77 | - * The Primary key of our table |
|
78 | - * |
|
79 | - * @var string |
|
80 | - */ |
|
81 | - protected $ID = 'ID'; |
|
82 | - |
|
83 | - /** |
|
84 | - * Enables sorting, it expects an array |
|
85 | - * of columns (the column names are the values) |
|
86 | - * |
|
87 | - * @var array |
|
88 | - */ |
|
89 | - protected $sort_by = array(); |
|
90 | - |
|
91 | - /** |
|
92 | - * The default sort order |
|
93 | - * |
|
94 | - * @var string |
|
95 | - */ |
|
96 | - protected $filter_by = array(); |
|
97 | - |
|
98 | - /** |
|
99 | - * The status name => count combinations for this table's items. Used to display status filters. |
|
100 | - * |
|
101 | - * @var array |
|
102 | - */ |
|
103 | - protected $status_counts = array(); |
|
104 | - |
|
105 | - /** |
|
106 | - * Notices to display when loading the table. Array of arrays of form array( 'class' => {updated|error}, 'message' => 'This is the notice text display.' ). |
|
107 | - * |
|
108 | - * @var array |
|
109 | - */ |
|
110 | - protected $admin_notices = array(); |
|
111 | - |
|
112 | - /** |
|
113 | - * Localised string displayed in the <h1> element above the able. |
|
114 | - * |
|
115 | - * @var string |
|
116 | - */ |
|
117 | - protected $table_header; |
|
118 | - |
|
119 | - /** |
|
120 | - * Enables bulk actions. It must be an array where the key is the action name |
|
121 | - * and the value is the label (which is translated automatically). It is important |
|
122 | - * to notice that it will check that the method exists (`bulk_$name`) and will throw |
|
123 | - * an exception if it does not exists. |
|
124 | - * |
|
125 | - * This class will automatically check if the current request has a bulk action, will do the |
|
126 | - * validations and afterwards will execute the bulk method, with two arguments. The first argument |
|
127 | - * is the array with primary keys, the second argument is a string with a list of the primary keys, |
|
128 | - * escaped and ready to use (with `IN`). |
|
129 | - * |
|
130 | - * @var array |
|
131 | - */ |
|
132 | - protected $bulk_actions = array(); |
|
133 | - |
|
134 | - /** |
|
135 | - * Makes translation easier, it basically just wraps |
|
136 | - * `_x` with some default (the package name). |
|
137 | - * |
|
138 | - * @param string $text The new text to translate. |
|
139 | - * @param string $context The context of the text. |
|
140 | - * @return string|void The translated text. |
|
141 | - * |
|
142 | - * @deprecated 3.0.0 Use `_x()` instead. |
|
143 | - */ |
|
144 | - protected function translate( $text, $context = '' ) { |
|
145 | - return $text; |
|
146 | - } |
|
147 | - |
|
148 | - /** |
|
149 | - * Reads `$this->bulk_actions` and returns an array that WP_List_Table understands. It |
|
150 | - * also validates that the bulk method handler exists. It throws an exception because |
|
151 | - * this is a library meant for developers and missing a bulk method is a development-time error. |
|
152 | - * |
|
153 | - * @return array |
|
154 | - * |
|
155 | - * @throws RuntimeException Throws RuntimeException when the bulk action does not have a callback method. |
|
156 | - */ |
|
157 | - protected function get_bulk_actions() { |
|
158 | - $actions = array(); |
|
159 | - |
|
160 | - foreach ( $this->bulk_actions as $action => $label ) { |
|
161 | - if ( ! is_callable( array( $this, 'bulk_' . $action ) ) ) { |
|
162 | - throw new RuntimeException( "The bulk action $action does not have a callback method" ); |
|
163 | - } |
|
164 | - |
|
165 | - $actions[ $action ] = $label; |
|
166 | - } |
|
167 | - |
|
168 | - return $actions; |
|
169 | - } |
|
170 | - |
|
171 | - /** |
|
172 | - * Checks if the current request has a bulk action. If that is the case it will validate and will |
|
173 | - * execute the bulk method handler. Regardless if the action is valid or not it will redirect to |
|
174 | - * the previous page removing the current arguments that makes this request a bulk action. |
|
175 | - */ |
|
176 | - protected function process_bulk_action() { |
|
177 | - global $wpdb; |
|
178 | - // Detect when a bulk action is being triggered. |
|
179 | - $action = $this->current_action(); |
|
180 | - if ( ! $action ) { |
|
181 | - return; |
|
182 | - } |
|
183 | - |
|
184 | - check_admin_referer( 'bulk-' . $this->_args['plural'] ); |
|
185 | - |
|
186 | - $method = 'bulk_' . $action; |
|
187 | - if ( array_key_exists( $action, $this->bulk_actions ) && is_callable( array( $this, $method ) ) && ! empty( $_GET['ID'] ) && is_array( $_GET['ID'] ) ) { |
|
188 | - $ids_sql = '(' . implode( ',', array_fill( 0, count( $_GET['ID'] ), '%s' ) ) . ')'; |
|
189 | - $id = array_map( 'absint', $_GET['ID'] ); |
|
190 | - $this->$method( $id, $wpdb->prepare( $ids_sql, $id ) ); //phpcs:ignore WordPress.DB.PreparedSQL |
|
191 | - } |
|
192 | - |
|
193 | - if ( isset( $_SERVER['REQUEST_URI'] ) ) { |
|
194 | - wp_safe_redirect( |
|
195 | - remove_query_arg( |
|
196 | - array( '_wp_http_referer', '_wpnonce', 'ID', 'action', 'action2' ), |
|
197 | - esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) |
|
198 | - ) |
|
199 | - ); |
|
200 | - exit; |
|
201 | - } |
|
202 | - } |
|
203 | - |
|
204 | - /** |
|
205 | - * Default code for deleting entries. |
|
206 | - * validated already by process_bulk_action() |
|
207 | - * |
|
208 | - * @param array $ids ids of the items to delete. |
|
209 | - * @param string $ids_sql the sql for the ids. |
|
210 | - * @return void |
|
211 | - */ |
|
212 | - protected function bulk_delete( array $ids, $ids_sql ) { |
|
213 | - $store = ActionScheduler::store(); |
|
214 | - foreach ( $ids as $action_id ) { |
|
215 | - $store->delete( $action_id ); |
|
216 | - } |
|
217 | - } |
|
218 | - |
|
219 | - /** |
|
220 | - * Prepares the _column_headers property which is used by WP_Table_List at rendering. |
|
221 | - * It merges the columns and the sortable columns. |
|
222 | - */ |
|
223 | - protected function prepare_column_headers() { |
|
224 | - $this->_column_headers = array( |
|
225 | - $this->get_columns(), |
|
226 | - get_hidden_columns( $this->screen ), |
|
227 | - $this->get_sortable_columns(), |
|
228 | - ); |
|
229 | - } |
|
230 | - |
|
231 | - /** |
|
232 | - * Reads $this->sort_by and returns the columns name in a format that WP_Table_List |
|
233 | - * expects |
|
234 | - */ |
|
235 | - public function get_sortable_columns() { |
|
236 | - $sort_by = array(); |
|
237 | - foreach ( $this->sort_by as $column ) { |
|
238 | - $sort_by[ $column ] = array( $column, true ); |
|
239 | - } |
|
240 | - return $sort_by; |
|
241 | - } |
|
242 | - |
|
243 | - /** |
|
244 | - * Returns the columns names for rendering. It adds a checkbox for selecting everything |
|
245 | - * as the first column |
|
246 | - */ |
|
247 | - public function get_columns() { |
|
248 | - $columns = array_merge( |
|
249 | - array( 'cb' => '<input type="checkbox" />' ), |
|
250 | - $this->columns |
|
251 | - ); |
|
252 | - |
|
253 | - return $columns; |
|
254 | - } |
|
255 | - |
|
256 | - /** |
|
257 | - * Get prepared LIMIT clause for items query |
|
258 | - * |
|
259 | - * @global wpdb $wpdb |
|
260 | - * |
|
261 | - * @return string Prepared LIMIT clause for items query. |
|
262 | - */ |
|
263 | - protected function get_items_query_limit() { |
|
264 | - global $wpdb; |
|
265 | - |
|
266 | - $per_page = $this->get_items_per_page( $this->get_per_page_option_name(), $this->items_per_page ); |
|
267 | - return $wpdb->prepare( 'LIMIT %d', $per_page ); |
|
268 | - } |
|
269 | - |
|
270 | - /** |
|
271 | - * Returns the number of items to offset/skip for this current view. |
|
272 | - * |
|
273 | - * @return int |
|
274 | - */ |
|
275 | - protected function get_items_offset() { |
|
276 | - $per_page = $this->get_items_per_page( $this->get_per_page_option_name(), $this->items_per_page ); |
|
277 | - $current_page = $this->get_pagenum(); |
|
278 | - if ( 1 < $current_page ) { |
|
279 | - $offset = $per_page * ( $current_page - 1 ); |
|
280 | - } else { |
|
281 | - $offset = 0; |
|
282 | - } |
|
283 | - |
|
284 | - return $offset; |
|
285 | - } |
|
286 | - |
|
287 | - /** |
|
288 | - * Get prepared OFFSET clause for items query |
|
289 | - * |
|
290 | - * @global wpdb $wpdb |
|
291 | - * |
|
292 | - * @return string Prepared OFFSET clause for items query. |
|
293 | - */ |
|
294 | - protected function get_items_query_offset() { |
|
295 | - global $wpdb; |
|
296 | - |
|
297 | - return $wpdb->prepare( 'OFFSET %d', $this->get_items_offset() ); |
|
298 | - } |
|
299 | - |
|
300 | - /** |
|
301 | - * Prepares the ORDER BY sql statement. It uses `$this->sort_by` to know which |
|
302 | - * columns are sortable. This requests validates the orderby $_GET parameter is a valid |
|
303 | - * column and sortable. It will also use order (ASC|DESC) using DESC by default. |
|
304 | - */ |
|
305 | - protected function get_items_query_order() { |
|
306 | - if ( empty( $this->sort_by ) ) { |
|
307 | - return ''; |
|
308 | - } |
|
309 | - |
|
310 | - $orderby = esc_sql( $this->get_request_orderby() ); |
|
311 | - $order = esc_sql( $this->get_request_order() ); |
|
312 | - |
|
313 | - return "ORDER BY {$orderby} {$order}"; |
|
314 | - } |
|
315 | - |
|
316 | - /** |
|
317 | - * Return the sortable column specified for this request to order the results by, if any. |
|
318 | - * |
|
319 | - * @return string |
|
320 | - */ |
|
321 | - protected function get_request_orderby() { |
|
322 | - |
|
323 | - $valid_sortable_columns = array_values( $this->sort_by ); |
|
324 | - |
|
325 | - if ( ! empty( $_GET['orderby'] ) && in_array( $_GET['orderby'], $valid_sortable_columns, true ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
326 | - $orderby = sanitize_text_field( wp_unslash( $_GET['orderby'] ) ); //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
327 | - } else { |
|
328 | - $orderby = $valid_sortable_columns[0]; |
|
329 | - } |
|
330 | - |
|
331 | - return $orderby; |
|
332 | - } |
|
333 | - |
|
334 | - /** |
|
335 | - * Return the sortable column order specified for this request. |
|
336 | - * |
|
337 | - * @return string |
|
338 | - */ |
|
339 | - protected function get_request_order() { |
|
340 | - |
|
341 | - if ( ! empty( $_GET['order'] ) && 'desc' === strtolower( sanitize_text_field( wp_unslash( $_GET['order'] ) ) ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
342 | - $order = 'DESC'; |
|
343 | - } else { |
|
344 | - $order = 'ASC'; |
|
345 | - } |
|
346 | - |
|
347 | - return $order; |
|
348 | - } |
|
349 | - |
|
350 | - /** |
|
351 | - * Return the status filter for this request, if any. |
|
352 | - * |
|
353 | - * @return string |
|
354 | - */ |
|
355 | - protected function get_request_status() { |
|
356 | - $status = ( ! empty( $_GET['status'] ) ) ? sanitize_text_field( wp_unslash( $_GET['status'] ) ) : ''; //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
357 | - return $status; |
|
358 | - } |
|
359 | - |
|
360 | - /** |
|
361 | - * Return the search filter for this request, if any. |
|
362 | - * |
|
363 | - * @return string |
|
364 | - */ |
|
365 | - protected function get_request_search_query() { |
|
366 | - $search_query = ( ! empty( $_GET['s'] ) ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : ''; //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
367 | - return $search_query; |
|
368 | - } |
|
369 | - |
|
370 | - /** |
|
371 | - * Process and return the columns name. This is meant for using with SQL, this means it |
|
372 | - * always includes the primary key. |
|
373 | - * |
|
374 | - * @return array |
|
375 | - */ |
|
376 | - protected function get_table_columns() { |
|
377 | - $columns = array_keys( $this->columns ); |
|
378 | - if ( ! in_array( $this->ID, $columns, true ) ) { |
|
379 | - $columns[] = $this->ID; |
|
380 | - } |
|
381 | - |
|
382 | - return $columns; |
|
383 | - } |
|
384 | - |
|
385 | - /** |
|
386 | - * Check if the current request is doing a "full text" search. If that is the case |
|
387 | - * prepares the SQL to search texts using LIKE. |
|
388 | - * |
|
389 | - * If the current request does not have any search or if this list table does not support |
|
390 | - * that feature it will return an empty string. |
|
391 | - * |
|
392 | - * @return string |
|
393 | - */ |
|
394 | - protected function get_items_query_search() { |
|
395 | - global $wpdb; |
|
396 | - |
|
397 | - if ( empty( $_GET['s'] ) || empty( $this->search_by ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
398 | - return ''; |
|
399 | - } |
|
400 | - |
|
401 | - $search_string = sanitize_text_field( wp_unslash( $_GET['s'] ) ); //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
402 | - |
|
403 | - $filter = array(); |
|
404 | - foreach ( $this->search_by as $column ) { |
|
405 | - $wild = '%'; |
|
406 | - $sql_like = $wild . $wpdb->esc_like( $search_string ) . $wild; |
|
407 | - $filter[] = $wpdb->prepare( '`' . $column . '` LIKE %s', $sql_like ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.DB.PreparedSQL.NotPrepared |
|
408 | - } |
|
409 | - return implode( ' OR ', $filter ); |
|
410 | - } |
|
411 | - |
|
412 | - /** |
|
413 | - * Prepares the SQL to filter rows by the options defined at `$this->filter_by`. Before trusting |
|
414 | - * any data sent by the user it validates that it is a valid option. |
|
415 | - */ |
|
416 | - protected function get_items_query_filters() { |
|
417 | - global $wpdb; |
|
418 | - |
|
419 | - if ( ! $this->filter_by || empty( $_GET['filter_by'] ) || ! is_array( $_GET['filter_by'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
420 | - return ''; |
|
421 | - } |
|
422 | - |
|
423 | - $filter = array(); |
|
424 | - |
|
425 | - foreach ( $this->filter_by as $column => $options ) { |
|
426 | - if ( empty( $_GET['filter_by'][ $column ] ) || empty( $options[ $_GET['filter_by'][ $column ] ] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
427 | - continue; |
|
428 | - } |
|
429 | - |
|
430 | - $filter[] = $wpdb->prepare( "`$column` = %s", sanitize_text_field( wp_unslash( $_GET['filter_by'][ $column ] ) ) ); //phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.DB.PreparedSQL.InterpolatedNotPrepared |
|
431 | - } |
|
432 | - |
|
433 | - return implode( ' AND ', $filter ); |
|
434 | - |
|
435 | - } |
|
436 | - |
|
437 | - /** |
|
438 | - * Prepares the data to feed WP_Table_List. |
|
439 | - * |
|
440 | - * This has the core for selecting, sorting and filting data. To keep the code simple |
|
441 | - * its logic is split among many methods (get_items_query_*). |
|
442 | - * |
|
443 | - * Beside populating the items this function will also count all the records that matches |
|
444 | - * the filtering criteria and will do fill the pagination variables. |
|
445 | - */ |
|
446 | - public function prepare_items() { |
|
447 | - global $wpdb; |
|
448 | - |
|
449 | - $this->process_bulk_action(); |
|
450 | - |
|
451 | - $this->process_row_actions(); |
|
452 | - |
|
453 | - if ( ! empty( $_REQUEST['_wp_http_referer'] && ! empty( $_SERVER['REQUEST_URI'] ) ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
454 | - // _wp_http_referer is used only on bulk actions, we remove it to keep the $_GET shorter |
|
455 | - wp_safe_redirect( remove_query_arg( array( '_wp_http_referer', '_wpnonce' ), esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) ) ); |
|
456 | - exit; |
|
457 | - } |
|
458 | - |
|
459 | - $this->prepare_column_headers(); |
|
460 | - |
|
461 | - $limit = $this->get_items_query_limit(); |
|
462 | - $offset = $this->get_items_query_offset(); |
|
463 | - $order = $this->get_items_query_order(); |
|
464 | - $where = array_filter( |
|
465 | - array( |
|
466 | - $this->get_items_query_search(), |
|
467 | - $this->get_items_query_filters(), |
|
468 | - ) |
|
469 | - ); |
|
470 | - $columns = '`' . implode( '`, `', $this->get_table_columns() ) . '`'; |
|
471 | - |
|
472 | - if ( ! empty( $where ) ) { |
|
473 | - $where = 'WHERE (' . implode( ') AND (', $where ) . ')'; |
|
474 | - } else { |
|
475 | - $where = ''; |
|
476 | - } |
|
477 | - |
|
478 | - $sql = "SELECT $columns FROM {$this->table_name} {$where} {$order} {$limit} {$offset}"; |
|
479 | - |
|
480 | - $this->set_items( $wpdb->get_results( $sql, ARRAY_A ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared |
|
481 | - |
|
482 | - $query_count = "SELECT COUNT({$this->ID}) FROM {$this->table_name} {$where}"; |
|
483 | - $total_items = $wpdb->get_var( $query_count ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared |
|
484 | - $per_page = $this->get_items_per_page( $this->get_per_page_option_name(), $this->items_per_page ); |
|
485 | - $this->set_pagination_args( |
|
486 | - array( |
|
487 | - 'total_items' => $total_items, |
|
488 | - 'per_page' => $per_page, |
|
489 | - 'total_pages' => ceil( $total_items / $per_page ), |
|
490 | - ) |
|
491 | - ); |
|
492 | - } |
|
493 | - |
|
494 | - /** |
|
495 | - * Display the table. |
|
496 | - * |
|
497 | - * @param string $which The name of the table. |
|
498 | - */ |
|
499 | - public function extra_tablenav( $which ) { |
|
500 | - if ( ! $this->filter_by || 'top' !== $which ) { |
|
501 | - return; |
|
502 | - } |
|
503 | - |
|
504 | - echo '<div class="alignleft actions">'; |
|
505 | - |
|
506 | - foreach ( $this->filter_by as $id => $options ) { |
|
507 | - $default = ! empty( $_GET['filter_by'][ $id ] ) ? sanitize_text_field( wp_unslash( $_GET['filter_by'][ $id ] ) ) : ''; //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
508 | - if ( empty( $options[ $default ] ) ) { |
|
509 | - $default = ''; |
|
510 | - } |
|
511 | - |
|
512 | - echo '<select name="filter_by[' . esc_attr( $id ) . ']" class="first" id="filter-by-' . esc_attr( $id ) . '">'; |
|
513 | - |
|
514 | - foreach ( $options as $value => $label ) { |
|
515 | - echo '<option value="' . esc_attr( $value ) . '" ' . esc_html( $value === $default ? 'selected' : '' ) . '>' |
|
516 | - . esc_html( $label ) |
|
517 | - . '</option>'; |
|
518 | - } |
|
519 | - |
|
520 | - echo '</select>'; |
|
521 | - } |
|
522 | - |
|
523 | - submit_button( esc_html__( 'Filter', 'action-scheduler' ), '', 'filter_action', false, array( 'id' => 'post-query-submit' ) ); |
|
524 | - echo '</div>'; |
|
525 | - } |
|
526 | - |
|
527 | - /** |
|
528 | - * Set the data for displaying. It will attempt to unserialize (There is a chance that some columns |
|
529 | - * are serialized). This can be override in child classes for futher data transformation. |
|
530 | - * |
|
531 | - * @param array $items Items array. |
|
532 | - */ |
|
533 | - protected function set_items( array $items ) { |
|
534 | - $this->items = array(); |
|
535 | - foreach ( $items as $item ) { |
|
536 | - $this->items[ $item[ $this->ID ] ] = array_map( 'maybe_unserialize', $item ); |
|
537 | - } |
|
538 | - } |
|
539 | - |
|
540 | - /** |
|
541 | - * Renders the checkbox for each row, this is the first column and it is named ID regardless |
|
542 | - * of how the primary key is named (to keep the code simpler). The bulk actions will do the proper |
|
543 | - * name transformation though using `$this->ID`. |
|
544 | - * |
|
545 | - * @param array $row The row to render. |
|
546 | - */ |
|
547 | - public function column_cb( $row ) { |
|
548 | - return '<input name="ID[]" type="checkbox" value="' . esc_attr( $row[ $this->ID ] ) . '" />'; |
|
549 | - } |
|
550 | - |
|
551 | - /** |
|
552 | - * Renders the row-actions. |
|
553 | - * |
|
554 | - * This method renders the action menu, it reads the definition from the $row_actions property, |
|
555 | - * and it checks that the row action method exists before rendering it. |
|
556 | - * |
|
557 | - * @param array $row Row to be rendered. |
|
558 | - * @param string $column_name Column name. |
|
559 | - * @return string |
|
560 | - */ |
|
561 | - protected function maybe_render_actions( $row, $column_name ) { |
|
562 | - if ( empty( $this->row_actions[ $column_name ] ) ) { |
|
563 | - return; |
|
564 | - } |
|
565 | - |
|
566 | - $row_id = $row[ $this->ID ]; |
|
567 | - |
|
568 | - $actions = '<div class="row-actions">'; |
|
569 | - $action_count = 0; |
|
570 | - foreach ( $this->row_actions[ $column_name ] as $action_key => $action ) { |
|
571 | - |
|
572 | - $action_count++; |
|
573 | - |
|
574 | - if ( ! method_exists( $this, 'row_action_' . $action_key ) ) { |
|
575 | - continue; |
|
576 | - } |
|
577 | - |
|
578 | - $action_link = ! empty( $action['link'] ) ? $action['link'] : add_query_arg( |
|
579 | - array( |
|
580 | - 'row_action' => $action_key, |
|
581 | - 'row_id' => $row_id, |
|
582 | - 'nonce' => wp_create_nonce( $action_key . '::' . $row_id ), |
|
583 | - ) |
|
584 | - ); |
|
585 | - $span_class = ! empty( $action['class'] ) ? $action['class'] : $action_key; |
|
586 | - $separator = ( $action_count < count( $this->row_actions[ $column_name ] ) ) ? ' | ' : ''; |
|
587 | - |
|
588 | - $actions .= sprintf( '<span class="%s">', esc_attr( $span_class ) ); |
|
589 | - $actions .= sprintf( '<a href="%1$s" title="%2$s">%3$s</a>', esc_url( $action_link ), esc_attr( $action['desc'] ), esc_html( $action['name'] ) ); |
|
590 | - $actions .= sprintf( '%s</span>', $separator ); |
|
591 | - } |
|
592 | - $actions .= '</div>'; |
|
593 | - return $actions; |
|
594 | - } |
|
595 | - |
|
596 | - /** |
|
597 | - * Process the bulk actions. |
|
598 | - * |
|
599 | - * @return void |
|
600 | - */ |
|
601 | - protected function process_row_actions() { |
|
602 | - $parameters = array( 'row_action', 'row_id', 'nonce' ); |
|
603 | - foreach ( $parameters as $parameter ) { |
|
604 | - if ( empty( $_REQUEST[ $parameter ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
605 | - return; |
|
606 | - } |
|
607 | - } |
|
608 | - |
|
609 | - $action = sanitize_text_field( wp_unslash( $_REQUEST['row_action'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotValidated |
|
610 | - $row_id = sanitize_text_field( wp_unslash( $_REQUEST['row_id'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotValidated |
|
611 | - $nonce = sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotValidated |
|
612 | - $method = 'row_action_' . $action; // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
613 | - |
|
614 | - if ( wp_verify_nonce( $nonce, $action . '::' . $row_id ) && method_exists( $this, $method ) ) { |
|
615 | - $this->$method( sanitize_text_field( wp_unslash( $row_id ) ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
616 | - } |
|
617 | - |
|
618 | - if ( isset( $_SERVER['REQUEST_URI'] ) ) { |
|
619 | - wp_safe_redirect( |
|
620 | - remove_query_arg( |
|
621 | - array( 'row_id', 'row_action', 'nonce' ), |
|
622 | - esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) |
|
623 | - ) |
|
624 | - ); |
|
625 | - exit; |
|
626 | - } |
|
627 | - } |
|
628 | - |
|
629 | - /** |
|
630 | - * Default column formatting, it will escape everythig for security. |
|
631 | - * |
|
632 | - * @param array $item The item array. |
|
633 | - * @param string $column_name Column name to display. |
|
634 | - * |
|
635 | - * @return string |
|
636 | - */ |
|
637 | - public function column_default( $item, $column_name ) { |
|
638 | - $column_html = esc_html( $item[ $column_name ] ); |
|
639 | - $column_html .= $this->maybe_render_actions( $item, $column_name ); |
|
640 | - return $column_html; |
|
641 | - } |
|
642 | - |
|
643 | - /** |
|
644 | - * Display the table heading and search query, if any |
|
645 | - */ |
|
646 | - protected function display_header() { |
|
647 | - echo '<h1 class="wp-heading-inline">' . esc_attr( $this->table_header ) . '</h1>'; |
|
648 | - if ( $this->get_request_search_query() ) { |
|
649 | - /* translators: %s: search query */ |
|
650 | - echo '<span class="subtitle">' . esc_attr( sprintf( __( 'Search results for "%s"', 'action-scheduler' ), $this->get_request_search_query() ) ) . '</span>'; |
|
651 | - } |
|
652 | - echo '<hr class="wp-header-end">'; |
|
653 | - } |
|
654 | - |
|
655 | - /** |
|
656 | - * Display the table heading and search query, if any |
|
657 | - */ |
|
658 | - protected function display_admin_notices() { |
|
659 | - foreach ( $this->admin_notices as $notice ) { |
|
660 | - echo '<div id="message" class="' . esc_attr( $notice['class'] ) . '">'; |
|
661 | - echo ' <p>' . wp_kses_post( $notice['message'] ) . '</p>'; |
|
662 | - echo '</div>'; |
|
663 | - } |
|
664 | - } |
|
665 | - |
|
666 | - /** |
|
667 | - * Prints the available statuses so the user can click to filter. |
|
668 | - */ |
|
669 | - protected function display_filter_by_status() { |
|
670 | - |
|
671 | - $status_list_items = array(); |
|
672 | - $request_status = $this->get_request_status(); |
|
673 | - |
|
674 | - // Helper to set 'all' filter when not set on status counts passed in. |
|
675 | - if ( ! isset( $this->status_counts['all'] ) ) { |
|
676 | - $this->status_counts = array( 'all' => array_sum( $this->status_counts ) ) + $this->status_counts; |
|
677 | - } |
|
678 | - |
|
679 | - foreach ( $this->status_counts as $status_name => $count ) { |
|
680 | - |
|
681 | - if ( 0 === $count ) { |
|
682 | - continue; |
|
683 | - } |
|
684 | - |
|
685 | - if ( $status_name === $request_status || ( empty( $request_status ) && 'all' === $status_name ) ) { |
|
686 | - $status_list_item = '<li class="%1$s"><a href="%2$s" class="current">%3$s</a> (%4$d)</li>'; |
|
687 | - } else { |
|
688 | - $status_list_item = '<li class="%1$s"><a href="%2$s">%3$s</a> (%4$d)</li>'; |
|
689 | - } |
|
690 | - |
|
691 | - $status_filter_url = ( 'all' === $status_name ) ? remove_query_arg( 'status' ) : add_query_arg( 'status', $status_name ); |
|
692 | - $status_filter_url = remove_query_arg( array( 'paged', 's' ), $status_filter_url ); |
|
693 | - $status_list_items[] = sprintf( $status_list_item, esc_attr( $status_name ), esc_url( $status_filter_url ), esc_html( ucfirst( $status_name ) ), absint( $count ) ); |
|
694 | - } |
|
695 | - |
|
696 | - if ( $status_list_items ) { |
|
697 | - echo '<ul class="subsubsub">'; |
|
698 | - echo implode( " | \n", $status_list_items ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
|
699 | - echo '</ul>'; |
|
700 | - } |
|
701 | - } |
|
702 | - |
|
703 | - /** |
|
704 | - * Renders the table list, we override the original class to render the table inside a form |
|
705 | - * and to render any needed HTML (like the search box). By doing so the callee of a function can simple |
|
706 | - * forget about any extra HTML. |
|
707 | - */ |
|
708 | - protected function display_table() { |
|
709 | - echo '<form id="' . esc_attr( $this->_args['plural'] ) . '-filter" method="get">'; |
|
710 | - foreach ( $_GET as $key => $value ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
711 | - if ( '_' === $key[0] || 'paged' === $key || 'ID' === $key ) { |
|
712 | - continue; |
|
713 | - } |
|
714 | - echo '<input type="hidden" name="' . esc_attr( $key ) . '" value="' . esc_attr( $value ) . '" />'; |
|
715 | - } |
|
716 | - if ( ! empty( $this->search_by ) ) { |
|
717 | - echo $this->search_box( $this->get_search_box_button_text(), 'plugin' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
|
718 | - } |
|
719 | - parent::display(); |
|
720 | - echo '</form>'; |
|
721 | - } |
|
722 | - |
|
723 | - /** |
|
724 | - * Process any pending actions. |
|
725 | - */ |
|
726 | - public function process_actions() { |
|
727 | - $this->process_bulk_action(); |
|
728 | - $this->process_row_actions(); |
|
729 | - |
|
730 | - if ( ! empty( $_REQUEST['_wp_http_referer'] ) && ! empty( $_SERVER['REQUEST_URI'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
731 | - // _wp_http_referer is used only on bulk actions, we remove it to keep the $_GET shorter |
|
732 | - wp_safe_redirect( remove_query_arg( array( '_wp_http_referer', '_wpnonce' ), esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) ) ); |
|
733 | - exit; |
|
734 | - } |
|
735 | - } |
|
736 | - |
|
737 | - /** |
|
738 | - * Render the list table page, including header, notices, status filters and table. |
|
739 | - */ |
|
740 | - public function display_page() { |
|
741 | - $this->prepare_items(); |
|
742 | - |
|
743 | - echo '<div class="wrap">'; |
|
744 | - $this->display_header(); |
|
745 | - $this->display_admin_notices(); |
|
746 | - $this->display_filter_by_status(); |
|
747 | - $this->display_table(); |
|
748 | - echo '</div>'; |
|
749 | - } |
|
750 | - |
|
751 | - /** |
|
752 | - * Get the text to display in the search box on the list table. |
|
753 | - */ |
|
754 | - protected function get_search_box_placeholder() { |
|
755 | - return esc_html__( 'Search', 'action-scheduler' ); |
|
756 | - } |
|
757 | - |
|
758 | - /** |
|
759 | - * Gets the screen per_page option name. |
|
760 | - * |
|
761 | - * @return string |
|
762 | - */ |
|
763 | - protected function get_per_page_option_name() { |
|
764 | - return $this->package . '_items_per_page'; |
|
765 | - } |
|
26 | + /** |
|
27 | + * The table name |
|
28 | + * |
|
29 | + * @var string |
|
30 | + */ |
|
31 | + protected $table_name; |
|
32 | + |
|
33 | + /** |
|
34 | + * Package name, used to get options from WP_List_Table::get_items_per_page. |
|
35 | + * |
|
36 | + * @var string |
|
37 | + */ |
|
38 | + protected $package; |
|
39 | + |
|
40 | + /** |
|
41 | + * How many items do we render per page? |
|
42 | + * |
|
43 | + * @var int |
|
44 | + */ |
|
45 | + protected $items_per_page = 10; |
|
46 | + |
|
47 | + /** |
|
48 | + * Enables search in this table listing. If this array |
|
49 | + * is empty it means the listing is not searchable. |
|
50 | + * |
|
51 | + * @var array |
|
52 | + */ |
|
53 | + protected $search_by = array(); |
|
54 | + |
|
55 | + /** |
|
56 | + * Columns to show in the table listing. It is a key => value pair. The |
|
57 | + * key must much the table column name and the value is the label, which is |
|
58 | + * automatically translated. |
|
59 | + * |
|
60 | + * @var array |
|
61 | + */ |
|
62 | + protected $columns = array(); |
|
63 | + |
|
64 | + /** |
|
65 | + * Defines the row-actions. It expects an array where the key |
|
66 | + * is the column name and the value is an array of actions. |
|
67 | + * |
|
68 | + * The array of actions are key => value, where key is the method name |
|
69 | + * (with the prefix row_action_<key>) and the value is the label |
|
70 | + * and title. |
|
71 | + * |
|
72 | + * @var array |
|
73 | + */ |
|
74 | + protected $row_actions = array(); |
|
75 | + |
|
76 | + /** |
|
77 | + * The Primary key of our table |
|
78 | + * |
|
79 | + * @var string |
|
80 | + */ |
|
81 | + protected $ID = 'ID'; |
|
82 | + |
|
83 | + /** |
|
84 | + * Enables sorting, it expects an array |
|
85 | + * of columns (the column names are the values) |
|
86 | + * |
|
87 | + * @var array |
|
88 | + */ |
|
89 | + protected $sort_by = array(); |
|
90 | + |
|
91 | + /** |
|
92 | + * The default sort order |
|
93 | + * |
|
94 | + * @var string |
|
95 | + */ |
|
96 | + protected $filter_by = array(); |
|
97 | + |
|
98 | + /** |
|
99 | + * The status name => count combinations for this table's items. Used to display status filters. |
|
100 | + * |
|
101 | + * @var array |
|
102 | + */ |
|
103 | + protected $status_counts = array(); |
|
104 | + |
|
105 | + /** |
|
106 | + * Notices to display when loading the table. Array of arrays of form array( 'class' => {updated|error}, 'message' => 'This is the notice text display.' ). |
|
107 | + * |
|
108 | + * @var array |
|
109 | + */ |
|
110 | + protected $admin_notices = array(); |
|
111 | + |
|
112 | + /** |
|
113 | + * Localised string displayed in the <h1> element above the able. |
|
114 | + * |
|
115 | + * @var string |
|
116 | + */ |
|
117 | + protected $table_header; |
|
118 | + |
|
119 | + /** |
|
120 | + * Enables bulk actions. It must be an array where the key is the action name |
|
121 | + * and the value is the label (which is translated automatically). It is important |
|
122 | + * to notice that it will check that the method exists (`bulk_$name`) and will throw |
|
123 | + * an exception if it does not exists. |
|
124 | + * |
|
125 | + * This class will automatically check if the current request has a bulk action, will do the |
|
126 | + * validations and afterwards will execute the bulk method, with two arguments. The first argument |
|
127 | + * is the array with primary keys, the second argument is a string with a list of the primary keys, |
|
128 | + * escaped and ready to use (with `IN`). |
|
129 | + * |
|
130 | + * @var array |
|
131 | + */ |
|
132 | + protected $bulk_actions = array(); |
|
133 | + |
|
134 | + /** |
|
135 | + * Makes translation easier, it basically just wraps |
|
136 | + * `_x` with some default (the package name). |
|
137 | + * |
|
138 | + * @param string $text The new text to translate. |
|
139 | + * @param string $context The context of the text. |
|
140 | + * @return string|void The translated text. |
|
141 | + * |
|
142 | + * @deprecated 3.0.0 Use `_x()` instead. |
|
143 | + */ |
|
144 | + protected function translate( $text, $context = '' ) { |
|
145 | + return $text; |
|
146 | + } |
|
147 | + |
|
148 | + /** |
|
149 | + * Reads `$this->bulk_actions` and returns an array that WP_List_Table understands. It |
|
150 | + * also validates that the bulk method handler exists. It throws an exception because |
|
151 | + * this is a library meant for developers and missing a bulk method is a development-time error. |
|
152 | + * |
|
153 | + * @return array |
|
154 | + * |
|
155 | + * @throws RuntimeException Throws RuntimeException when the bulk action does not have a callback method. |
|
156 | + */ |
|
157 | + protected function get_bulk_actions() { |
|
158 | + $actions = array(); |
|
159 | + |
|
160 | + foreach ( $this->bulk_actions as $action => $label ) { |
|
161 | + if ( ! is_callable( array( $this, 'bulk_' . $action ) ) ) { |
|
162 | + throw new RuntimeException( "The bulk action $action does not have a callback method" ); |
|
163 | + } |
|
164 | + |
|
165 | + $actions[ $action ] = $label; |
|
166 | + } |
|
167 | + |
|
168 | + return $actions; |
|
169 | + } |
|
170 | + |
|
171 | + /** |
|
172 | + * Checks if the current request has a bulk action. If that is the case it will validate and will |
|
173 | + * execute the bulk method handler. Regardless if the action is valid or not it will redirect to |
|
174 | + * the previous page removing the current arguments that makes this request a bulk action. |
|
175 | + */ |
|
176 | + protected function process_bulk_action() { |
|
177 | + global $wpdb; |
|
178 | + // Detect when a bulk action is being triggered. |
|
179 | + $action = $this->current_action(); |
|
180 | + if ( ! $action ) { |
|
181 | + return; |
|
182 | + } |
|
183 | + |
|
184 | + check_admin_referer( 'bulk-' . $this->_args['plural'] ); |
|
185 | + |
|
186 | + $method = 'bulk_' . $action; |
|
187 | + if ( array_key_exists( $action, $this->bulk_actions ) && is_callable( array( $this, $method ) ) && ! empty( $_GET['ID'] ) && is_array( $_GET['ID'] ) ) { |
|
188 | + $ids_sql = '(' . implode( ',', array_fill( 0, count( $_GET['ID'] ), '%s' ) ) . ')'; |
|
189 | + $id = array_map( 'absint', $_GET['ID'] ); |
|
190 | + $this->$method( $id, $wpdb->prepare( $ids_sql, $id ) ); //phpcs:ignore WordPress.DB.PreparedSQL |
|
191 | + } |
|
192 | + |
|
193 | + if ( isset( $_SERVER['REQUEST_URI'] ) ) { |
|
194 | + wp_safe_redirect( |
|
195 | + remove_query_arg( |
|
196 | + array( '_wp_http_referer', '_wpnonce', 'ID', 'action', 'action2' ), |
|
197 | + esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) |
|
198 | + ) |
|
199 | + ); |
|
200 | + exit; |
|
201 | + } |
|
202 | + } |
|
203 | + |
|
204 | + /** |
|
205 | + * Default code for deleting entries. |
|
206 | + * validated already by process_bulk_action() |
|
207 | + * |
|
208 | + * @param array $ids ids of the items to delete. |
|
209 | + * @param string $ids_sql the sql for the ids. |
|
210 | + * @return void |
|
211 | + */ |
|
212 | + protected function bulk_delete( array $ids, $ids_sql ) { |
|
213 | + $store = ActionScheduler::store(); |
|
214 | + foreach ( $ids as $action_id ) { |
|
215 | + $store->delete( $action_id ); |
|
216 | + } |
|
217 | + } |
|
218 | + |
|
219 | + /** |
|
220 | + * Prepares the _column_headers property which is used by WP_Table_List at rendering. |
|
221 | + * It merges the columns and the sortable columns. |
|
222 | + */ |
|
223 | + protected function prepare_column_headers() { |
|
224 | + $this->_column_headers = array( |
|
225 | + $this->get_columns(), |
|
226 | + get_hidden_columns( $this->screen ), |
|
227 | + $this->get_sortable_columns(), |
|
228 | + ); |
|
229 | + } |
|
230 | + |
|
231 | + /** |
|
232 | + * Reads $this->sort_by and returns the columns name in a format that WP_Table_List |
|
233 | + * expects |
|
234 | + */ |
|
235 | + public function get_sortable_columns() { |
|
236 | + $sort_by = array(); |
|
237 | + foreach ( $this->sort_by as $column ) { |
|
238 | + $sort_by[ $column ] = array( $column, true ); |
|
239 | + } |
|
240 | + return $sort_by; |
|
241 | + } |
|
242 | + |
|
243 | + /** |
|
244 | + * Returns the columns names for rendering. It adds a checkbox for selecting everything |
|
245 | + * as the first column |
|
246 | + */ |
|
247 | + public function get_columns() { |
|
248 | + $columns = array_merge( |
|
249 | + array( 'cb' => '<input type="checkbox" />' ), |
|
250 | + $this->columns |
|
251 | + ); |
|
252 | + |
|
253 | + return $columns; |
|
254 | + } |
|
255 | + |
|
256 | + /** |
|
257 | + * Get prepared LIMIT clause for items query |
|
258 | + * |
|
259 | + * @global wpdb $wpdb |
|
260 | + * |
|
261 | + * @return string Prepared LIMIT clause for items query. |
|
262 | + */ |
|
263 | + protected function get_items_query_limit() { |
|
264 | + global $wpdb; |
|
265 | + |
|
266 | + $per_page = $this->get_items_per_page( $this->get_per_page_option_name(), $this->items_per_page ); |
|
267 | + return $wpdb->prepare( 'LIMIT %d', $per_page ); |
|
268 | + } |
|
269 | + |
|
270 | + /** |
|
271 | + * Returns the number of items to offset/skip for this current view. |
|
272 | + * |
|
273 | + * @return int |
|
274 | + */ |
|
275 | + protected function get_items_offset() { |
|
276 | + $per_page = $this->get_items_per_page( $this->get_per_page_option_name(), $this->items_per_page ); |
|
277 | + $current_page = $this->get_pagenum(); |
|
278 | + if ( 1 < $current_page ) { |
|
279 | + $offset = $per_page * ( $current_page - 1 ); |
|
280 | + } else { |
|
281 | + $offset = 0; |
|
282 | + } |
|
283 | + |
|
284 | + return $offset; |
|
285 | + } |
|
286 | + |
|
287 | + /** |
|
288 | + * Get prepared OFFSET clause for items query |
|
289 | + * |
|
290 | + * @global wpdb $wpdb |
|
291 | + * |
|
292 | + * @return string Prepared OFFSET clause for items query. |
|
293 | + */ |
|
294 | + protected function get_items_query_offset() { |
|
295 | + global $wpdb; |
|
296 | + |
|
297 | + return $wpdb->prepare( 'OFFSET %d', $this->get_items_offset() ); |
|
298 | + } |
|
299 | + |
|
300 | + /** |
|
301 | + * Prepares the ORDER BY sql statement. It uses `$this->sort_by` to know which |
|
302 | + * columns are sortable. This requests validates the orderby $_GET parameter is a valid |
|
303 | + * column and sortable. It will also use order (ASC|DESC) using DESC by default. |
|
304 | + */ |
|
305 | + protected function get_items_query_order() { |
|
306 | + if ( empty( $this->sort_by ) ) { |
|
307 | + return ''; |
|
308 | + } |
|
309 | + |
|
310 | + $orderby = esc_sql( $this->get_request_orderby() ); |
|
311 | + $order = esc_sql( $this->get_request_order() ); |
|
312 | + |
|
313 | + return "ORDER BY {$orderby} {$order}"; |
|
314 | + } |
|
315 | + |
|
316 | + /** |
|
317 | + * Return the sortable column specified for this request to order the results by, if any. |
|
318 | + * |
|
319 | + * @return string |
|
320 | + */ |
|
321 | + protected function get_request_orderby() { |
|
322 | + |
|
323 | + $valid_sortable_columns = array_values( $this->sort_by ); |
|
324 | + |
|
325 | + if ( ! empty( $_GET['orderby'] ) && in_array( $_GET['orderby'], $valid_sortable_columns, true ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
326 | + $orderby = sanitize_text_field( wp_unslash( $_GET['orderby'] ) ); //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
327 | + } else { |
|
328 | + $orderby = $valid_sortable_columns[0]; |
|
329 | + } |
|
330 | + |
|
331 | + return $orderby; |
|
332 | + } |
|
333 | + |
|
334 | + /** |
|
335 | + * Return the sortable column order specified for this request. |
|
336 | + * |
|
337 | + * @return string |
|
338 | + */ |
|
339 | + protected function get_request_order() { |
|
340 | + |
|
341 | + if ( ! empty( $_GET['order'] ) && 'desc' === strtolower( sanitize_text_field( wp_unslash( $_GET['order'] ) ) ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
342 | + $order = 'DESC'; |
|
343 | + } else { |
|
344 | + $order = 'ASC'; |
|
345 | + } |
|
346 | + |
|
347 | + return $order; |
|
348 | + } |
|
349 | + |
|
350 | + /** |
|
351 | + * Return the status filter for this request, if any. |
|
352 | + * |
|
353 | + * @return string |
|
354 | + */ |
|
355 | + protected function get_request_status() { |
|
356 | + $status = ( ! empty( $_GET['status'] ) ) ? sanitize_text_field( wp_unslash( $_GET['status'] ) ) : ''; //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
357 | + return $status; |
|
358 | + } |
|
359 | + |
|
360 | + /** |
|
361 | + * Return the search filter for this request, if any. |
|
362 | + * |
|
363 | + * @return string |
|
364 | + */ |
|
365 | + protected function get_request_search_query() { |
|
366 | + $search_query = ( ! empty( $_GET['s'] ) ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : ''; //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
367 | + return $search_query; |
|
368 | + } |
|
369 | + |
|
370 | + /** |
|
371 | + * Process and return the columns name. This is meant for using with SQL, this means it |
|
372 | + * always includes the primary key. |
|
373 | + * |
|
374 | + * @return array |
|
375 | + */ |
|
376 | + protected function get_table_columns() { |
|
377 | + $columns = array_keys( $this->columns ); |
|
378 | + if ( ! in_array( $this->ID, $columns, true ) ) { |
|
379 | + $columns[] = $this->ID; |
|
380 | + } |
|
381 | + |
|
382 | + return $columns; |
|
383 | + } |
|
384 | + |
|
385 | + /** |
|
386 | + * Check if the current request is doing a "full text" search. If that is the case |
|
387 | + * prepares the SQL to search texts using LIKE. |
|
388 | + * |
|
389 | + * If the current request does not have any search or if this list table does not support |
|
390 | + * that feature it will return an empty string. |
|
391 | + * |
|
392 | + * @return string |
|
393 | + */ |
|
394 | + protected function get_items_query_search() { |
|
395 | + global $wpdb; |
|
396 | + |
|
397 | + if ( empty( $_GET['s'] ) || empty( $this->search_by ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
398 | + return ''; |
|
399 | + } |
|
400 | + |
|
401 | + $search_string = sanitize_text_field( wp_unslash( $_GET['s'] ) ); //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
402 | + |
|
403 | + $filter = array(); |
|
404 | + foreach ( $this->search_by as $column ) { |
|
405 | + $wild = '%'; |
|
406 | + $sql_like = $wild . $wpdb->esc_like( $search_string ) . $wild; |
|
407 | + $filter[] = $wpdb->prepare( '`' . $column . '` LIKE %s', $sql_like ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.DB.PreparedSQL.NotPrepared |
|
408 | + } |
|
409 | + return implode( ' OR ', $filter ); |
|
410 | + } |
|
411 | + |
|
412 | + /** |
|
413 | + * Prepares the SQL to filter rows by the options defined at `$this->filter_by`. Before trusting |
|
414 | + * any data sent by the user it validates that it is a valid option. |
|
415 | + */ |
|
416 | + protected function get_items_query_filters() { |
|
417 | + global $wpdb; |
|
418 | + |
|
419 | + if ( ! $this->filter_by || empty( $_GET['filter_by'] ) || ! is_array( $_GET['filter_by'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
420 | + return ''; |
|
421 | + } |
|
422 | + |
|
423 | + $filter = array(); |
|
424 | + |
|
425 | + foreach ( $this->filter_by as $column => $options ) { |
|
426 | + if ( empty( $_GET['filter_by'][ $column ] ) || empty( $options[ $_GET['filter_by'][ $column ] ] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
427 | + continue; |
|
428 | + } |
|
429 | + |
|
430 | + $filter[] = $wpdb->prepare( "`$column` = %s", sanitize_text_field( wp_unslash( $_GET['filter_by'][ $column ] ) ) ); //phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.DB.PreparedSQL.InterpolatedNotPrepared |
|
431 | + } |
|
432 | + |
|
433 | + return implode( ' AND ', $filter ); |
|
434 | + |
|
435 | + } |
|
436 | + |
|
437 | + /** |
|
438 | + * Prepares the data to feed WP_Table_List. |
|
439 | + * |
|
440 | + * This has the core for selecting, sorting and filting data. To keep the code simple |
|
441 | + * its logic is split among many methods (get_items_query_*). |
|
442 | + * |
|
443 | + * Beside populating the items this function will also count all the records that matches |
|
444 | + * the filtering criteria and will do fill the pagination variables. |
|
445 | + */ |
|
446 | + public function prepare_items() { |
|
447 | + global $wpdb; |
|
448 | + |
|
449 | + $this->process_bulk_action(); |
|
450 | + |
|
451 | + $this->process_row_actions(); |
|
452 | + |
|
453 | + if ( ! empty( $_REQUEST['_wp_http_referer'] && ! empty( $_SERVER['REQUEST_URI'] ) ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
454 | + // _wp_http_referer is used only on bulk actions, we remove it to keep the $_GET shorter |
|
455 | + wp_safe_redirect( remove_query_arg( array( '_wp_http_referer', '_wpnonce' ), esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) ) ); |
|
456 | + exit; |
|
457 | + } |
|
458 | + |
|
459 | + $this->prepare_column_headers(); |
|
460 | + |
|
461 | + $limit = $this->get_items_query_limit(); |
|
462 | + $offset = $this->get_items_query_offset(); |
|
463 | + $order = $this->get_items_query_order(); |
|
464 | + $where = array_filter( |
|
465 | + array( |
|
466 | + $this->get_items_query_search(), |
|
467 | + $this->get_items_query_filters(), |
|
468 | + ) |
|
469 | + ); |
|
470 | + $columns = '`' . implode( '`, `', $this->get_table_columns() ) . '`'; |
|
471 | + |
|
472 | + if ( ! empty( $where ) ) { |
|
473 | + $where = 'WHERE (' . implode( ') AND (', $where ) . ')'; |
|
474 | + } else { |
|
475 | + $where = ''; |
|
476 | + } |
|
477 | + |
|
478 | + $sql = "SELECT $columns FROM {$this->table_name} {$where} {$order} {$limit} {$offset}"; |
|
479 | + |
|
480 | + $this->set_items( $wpdb->get_results( $sql, ARRAY_A ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared |
|
481 | + |
|
482 | + $query_count = "SELECT COUNT({$this->ID}) FROM {$this->table_name} {$where}"; |
|
483 | + $total_items = $wpdb->get_var( $query_count ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared |
|
484 | + $per_page = $this->get_items_per_page( $this->get_per_page_option_name(), $this->items_per_page ); |
|
485 | + $this->set_pagination_args( |
|
486 | + array( |
|
487 | + 'total_items' => $total_items, |
|
488 | + 'per_page' => $per_page, |
|
489 | + 'total_pages' => ceil( $total_items / $per_page ), |
|
490 | + ) |
|
491 | + ); |
|
492 | + } |
|
493 | + |
|
494 | + /** |
|
495 | + * Display the table. |
|
496 | + * |
|
497 | + * @param string $which The name of the table. |
|
498 | + */ |
|
499 | + public function extra_tablenav( $which ) { |
|
500 | + if ( ! $this->filter_by || 'top' !== $which ) { |
|
501 | + return; |
|
502 | + } |
|
503 | + |
|
504 | + echo '<div class="alignleft actions">'; |
|
505 | + |
|
506 | + foreach ( $this->filter_by as $id => $options ) { |
|
507 | + $default = ! empty( $_GET['filter_by'][ $id ] ) ? sanitize_text_field( wp_unslash( $_GET['filter_by'][ $id ] ) ) : ''; //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
508 | + if ( empty( $options[ $default ] ) ) { |
|
509 | + $default = ''; |
|
510 | + } |
|
511 | + |
|
512 | + echo '<select name="filter_by[' . esc_attr( $id ) . ']" class="first" id="filter-by-' . esc_attr( $id ) . '">'; |
|
513 | + |
|
514 | + foreach ( $options as $value => $label ) { |
|
515 | + echo '<option value="' . esc_attr( $value ) . '" ' . esc_html( $value === $default ? 'selected' : '' ) . '>' |
|
516 | + . esc_html( $label ) |
|
517 | + . '</option>'; |
|
518 | + } |
|
519 | + |
|
520 | + echo '</select>'; |
|
521 | + } |
|
522 | + |
|
523 | + submit_button( esc_html__( 'Filter', 'action-scheduler' ), '', 'filter_action', false, array( 'id' => 'post-query-submit' ) ); |
|
524 | + echo '</div>'; |
|
525 | + } |
|
526 | + |
|
527 | + /** |
|
528 | + * Set the data for displaying. It will attempt to unserialize (There is a chance that some columns |
|
529 | + * are serialized). This can be override in child classes for futher data transformation. |
|
530 | + * |
|
531 | + * @param array $items Items array. |
|
532 | + */ |
|
533 | + protected function set_items( array $items ) { |
|
534 | + $this->items = array(); |
|
535 | + foreach ( $items as $item ) { |
|
536 | + $this->items[ $item[ $this->ID ] ] = array_map( 'maybe_unserialize', $item ); |
|
537 | + } |
|
538 | + } |
|
539 | + |
|
540 | + /** |
|
541 | + * Renders the checkbox for each row, this is the first column and it is named ID regardless |
|
542 | + * of how the primary key is named (to keep the code simpler). The bulk actions will do the proper |
|
543 | + * name transformation though using `$this->ID`. |
|
544 | + * |
|
545 | + * @param array $row The row to render. |
|
546 | + */ |
|
547 | + public function column_cb( $row ) { |
|
548 | + return '<input name="ID[]" type="checkbox" value="' . esc_attr( $row[ $this->ID ] ) . '" />'; |
|
549 | + } |
|
550 | + |
|
551 | + /** |
|
552 | + * Renders the row-actions. |
|
553 | + * |
|
554 | + * This method renders the action menu, it reads the definition from the $row_actions property, |
|
555 | + * and it checks that the row action method exists before rendering it. |
|
556 | + * |
|
557 | + * @param array $row Row to be rendered. |
|
558 | + * @param string $column_name Column name. |
|
559 | + * @return string |
|
560 | + */ |
|
561 | + protected function maybe_render_actions( $row, $column_name ) { |
|
562 | + if ( empty( $this->row_actions[ $column_name ] ) ) { |
|
563 | + return; |
|
564 | + } |
|
565 | + |
|
566 | + $row_id = $row[ $this->ID ]; |
|
567 | + |
|
568 | + $actions = '<div class="row-actions">'; |
|
569 | + $action_count = 0; |
|
570 | + foreach ( $this->row_actions[ $column_name ] as $action_key => $action ) { |
|
571 | + |
|
572 | + $action_count++; |
|
573 | + |
|
574 | + if ( ! method_exists( $this, 'row_action_' . $action_key ) ) { |
|
575 | + continue; |
|
576 | + } |
|
577 | + |
|
578 | + $action_link = ! empty( $action['link'] ) ? $action['link'] : add_query_arg( |
|
579 | + array( |
|
580 | + 'row_action' => $action_key, |
|
581 | + 'row_id' => $row_id, |
|
582 | + 'nonce' => wp_create_nonce( $action_key . '::' . $row_id ), |
|
583 | + ) |
|
584 | + ); |
|
585 | + $span_class = ! empty( $action['class'] ) ? $action['class'] : $action_key; |
|
586 | + $separator = ( $action_count < count( $this->row_actions[ $column_name ] ) ) ? ' | ' : ''; |
|
587 | + |
|
588 | + $actions .= sprintf( '<span class="%s">', esc_attr( $span_class ) ); |
|
589 | + $actions .= sprintf( '<a href="%1$s" title="%2$s">%3$s</a>', esc_url( $action_link ), esc_attr( $action['desc'] ), esc_html( $action['name'] ) ); |
|
590 | + $actions .= sprintf( '%s</span>', $separator ); |
|
591 | + } |
|
592 | + $actions .= '</div>'; |
|
593 | + return $actions; |
|
594 | + } |
|
595 | + |
|
596 | + /** |
|
597 | + * Process the bulk actions. |
|
598 | + * |
|
599 | + * @return void |
|
600 | + */ |
|
601 | + protected function process_row_actions() { |
|
602 | + $parameters = array( 'row_action', 'row_id', 'nonce' ); |
|
603 | + foreach ( $parameters as $parameter ) { |
|
604 | + if ( empty( $_REQUEST[ $parameter ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
605 | + return; |
|
606 | + } |
|
607 | + } |
|
608 | + |
|
609 | + $action = sanitize_text_field( wp_unslash( $_REQUEST['row_action'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotValidated |
|
610 | + $row_id = sanitize_text_field( wp_unslash( $_REQUEST['row_id'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotValidated |
|
611 | + $nonce = sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotValidated |
|
612 | + $method = 'row_action_' . $action; // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
613 | + |
|
614 | + if ( wp_verify_nonce( $nonce, $action . '::' . $row_id ) && method_exists( $this, $method ) ) { |
|
615 | + $this->$method( sanitize_text_field( wp_unslash( $row_id ) ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
616 | + } |
|
617 | + |
|
618 | + if ( isset( $_SERVER['REQUEST_URI'] ) ) { |
|
619 | + wp_safe_redirect( |
|
620 | + remove_query_arg( |
|
621 | + array( 'row_id', 'row_action', 'nonce' ), |
|
622 | + esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) |
|
623 | + ) |
|
624 | + ); |
|
625 | + exit; |
|
626 | + } |
|
627 | + } |
|
628 | + |
|
629 | + /** |
|
630 | + * Default column formatting, it will escape everythig for security. |
|
631 | + * |
|
632 | + * @param array $item The item array. |
|
633 | + * @param string $column_name Column name to display. |
|
634 | + * |
|
635 | + * @return string |
|
636 | + */ |
|
637 | + public function column_default( $item, $column_name ) { |
|
638 | + $column_html = esc_html( $item[ $column_name ] ); |
|
639 | + $column_html .= $this->maybe_render_actions( $item, $column_name ); |
|
640 | + return $column_html; |
|
641 | + } |
|
642 | + |
|
643 | + /** |
|
644 | + * Display the table heading and search query, if any |
|
645 | + */ |
|
646 | + protected function display_header() { |
|
647 | + echo '<h1 class="wp-heading-inline">' . esc_attr( $this->table_header ) . '</h1>'; |
|
648 | + if ( $this->get_request_search_query() ) { |
|
649 | + /* translators: %s: search query */ |
|
650 | + echo '<span class="subtitle">' . esc_attr( sprintf( __( 'Search results for "%s"', 'action-scheduler' ), $this->get_request_search_query() ) ) . '</span>'; |
|
651 | + } |
|
652 | + echo '<hr class="wp-header-end">'; |
|
653 | + } |
|
654 | + |
|
655 | + /** |
|
656 | + * Display the table heading and search query, if any |
|
657 | + */ |
|
658 | + protected function display_admin_notices() { |
|
659 | + foreach ( $this->admin_notices as $notice ) { |
|
660 | + echo '<div id="message" class="' . esc_attr( $notice['class'] ) . '">'; |
|
661 | + echo ' <p>' . wp_kses_post( $notice['message'] ) . '</p>'; |
|
662 | + echo '</div>'; |
|
663 | + } |
|
664 | + } |
|
665 | + |
|
666 | + /** |
|
667 | + * Prints the available statuses so the user can click to filter. |
|
668 | + */ |
|
669 | + protected function display_filter_by_status() { |
|
670 | + |
|
671 | + $status_list_items = array(); |
|
672 | + $request_status = $this->get_request_status(); |
|
673 | + |
|
674 | + // Helper to set 'all' filter when not set on status counts passed in. |
|
675 | + if ( ! isset( $this->status_counts['all'] ) ) { |
|
676 | + $this->status_counts = array( 'all' => array_sum( $this->status_counts ) ) + $this->status_counts; |
|
677 | + } |
|
678 | + |
|
679 | + foreach ( $this->status_counts as $status_name => $count ) { |
|
680 | + |
|
681 | + if ( 0 === $count ) { |
|
682 | + continue; |
|
683 | + } |
|
684 | + |
|
685 | + if ( $status_name === $request_status || ( empty( $request_status ) && 'all' === $status_name ) ) { |
|
686 | + $status_list_item = '<li class="%1$s"><a href="%2$s" class="current">%3$s</a> (%4$d)</li>'; |
|
687 | + } else { |
|
688 | + $status_list_item = '<li class="%1$s"><a href="%2$s">%3$s</a> (%4$d)</li>'; |
|
689 | + } |
|
690 | + |
|
691 | + $status_filter_url = ( 'all' === $status_name ) ? remove_query_arg( 'status' ) : add_query_arg( 'status', $status_name ); |
|
692 | + $status_filter_url = remove_query_arg( array( 'paged', 's' ), $status_filter_url ); |
|
693 | + $status_list_items[] = sprintf( $status_list_item, esc_attr( $status_name ), esc_url( $status_filter_url ), esc_html( ucfirst( $status_name ) ), absint( $count ) ); |
|
694 | + } |
|
695 | + |
|
696 | + if ( $status_list_items ) { |
|
697 | + echo '<ul class="subsubsub">'; |
|
698 | + echo implode( " | \n", $status_list_items ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
|
699 | + echo '</ul>'; |
|
700 | + } |
|
701 | + } |
|
702 | + |
|
703 | + /** |
|
704 | + * Renders the table list, we override the original class to render the table inside a form |
|
705 | + * and to render any needed HTML (like the search box). By doing so the callee of a function can simple |
|
706 | + * forget about any extra HTML. |
|
707 | + */ |
|
708 | + protected function display_table() { |
|
709 | + echo '<form id="' . esc_attr( $this->_args['plural'] ) . '-filter" method="get">'; |
|
710 | + foreach ( $_GET as $key => $value ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
711 | + if ( '_' === $key[0] || 'paged' === $key || 'ID' === $key ) { |
|
712 | + continue; |
|
713 | + } |
|
714 | + echo '<input type="hidden" name="' . esc_attr( $key ) . '" value="' . esc_attr( $value ) . '" />'; |
|
715 | + } |
|
716 | + if ( ! empty( $this->search_by ) ) { |
|
717 | + echo $this->search_box( $this->get_search_box_button_text(), 'plugin' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
|
718 | + } |
|
719 | + parent::display(); |
|
720 | + echo '</form>'; |
|
721 | + } |
|
722 | + |
|
723 | + /** |
|
724 | + * Process any pending actions. |
|
725 | + */ |
|
726 | + public function process_actions() { |
|
727 | + $this->process_bulk_action(); |
|
728 | + $this->process_row_actions(); |
|
729 | + |
|
730 | + if ( ! empty( $_REQUEST['_wp_http_referer'] ) && ! empty( $_SERVER['REQUEST_URI'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
731 | + // _wp_http_referer is used only on bulk actions, we remove it to keep the $_GET shorter |
|
732 | + wp_safe_redirect( remove_query_arg( array( '_wp_http_referer', '_wpnonce' ), esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) ) ); |
|
733 | + exit; |
|
734 | + } |
|
735 | + } |
|
736 | + |
|
737 | + /** |
|
738 | + * Render the list table page, including header, notices, status filters and table. |
|
739 | + */ |
|
740 | + public function display_page() { |
|
741 | + $this->prepare_items(); |
|
742 | + |
|
743 | + echo '<div class="wrap">'; |
|
744 | + $this->display_header(); |
|
745 | + $this->display_admin_notices(); |
|
746 | + $this->display_filter_by_status(); |
|
747 | + $this->display_table(); |
|
748 | + echo '</div>'; |
|
749 | + } |
|
750 | + |
|
751 | + /** |
|
752 | + * Get the text to display in the search box on the list table. |
|
753 | + */ |
|
754 | + protected function get_search_box_placeholder() { |
|
755 | + return esc_html__( 'Search', 'action-scheduler' ); |
|
756 | + } |
|
757 | + |
|
758 | + /** |
|
759 | + * Gets the screen per_page option name. |
|
760 | + * |
|
761 | + * @return string |
|
762 | + */ |
|
763 | + protected function get_per_page_option_name() { |
|
764 | + return $this->package . '_items_per_page'; |
|
765 | + } |
|
766 | 766 | } |
@@ -1,7 +1,7 @@ discard block |
||
1 | 1 | <?php |
2 | 2 | |
3 | -if ( ! class_exists( 'WP_List_Table' ) ) { |
|
4 | - require_once ABSPATH . 'wp-admin/includes/class-wp-list-table.php'; |
|
3 | +if ( ! class_exists('WP_List_Table')) { |
|
4 | + require_once ABSPATH.'wp-admin/includes/class-wp-list-table.php'; |
|
5 | 5 | } |
6 | 6 | |
7 | 7 | /** |
@@ -141,7 +141,7 @@ discard block |
||
141 | 141 | * |
142 | 142 | * @deprecated 3.0.0 Use `_x()` instead. |
143 | 143 | */ |
144 | - protected function translate( $text, $context = '' ) { |
|
144 | + protected function translate($text, $context = '') { |
|
145 | 145 | return $text; |
146 | 146 | } |
147 | 147 | |
@@ -157,12 +157,12 @@ discard block |
||
157 | 157 | protected function get_bulk_actions() { |
158 | 158 | $actions = array(); |
159 | 159 | |
160 | - foreach ( $this->bulk_actions as $action => $label ) { |
|
161 | - if ( ! is_callable( array( $this, 'bulk_' . $action ) ) ) { |
|
162 | - throw new RuntimeException( "The bulk action $action does not have a callback method" ); |
|
160 | + foreach ($this->bulk_actions as $action => $label) { |
|
161 | + if ( ! is_callable(array($this, 'bulk_'.$action))) { |
|
162 | + throw new RuntimeException("The bulk action $action does not have a callback method"); |
|
163 | 163 | } |
164 | 164 | |
165 | - $actions[ $action ] = $label; |
|
165 | + $actions[$action] = $label; |
|
166 | 166 | } |
167 | 167 | |
168 | 168 | return $actions; |
@@ -177,24 +177,24 @@ discard block |
||
177 | 177 | global $wpdb; |
178 | 178 | // Detect when a bulk action is being triggered. |
179 | 179 | $action = $this->current_action(); |
180 | - if ( ! $action ) { |
|
180 | + if ( ! $action) { |
|
181 | 181 | return; |
182 | 182 | } |
183 | 183 | |
184 | - check_admin_referer( 'bulk-' . $this->_args['plural'] ); |
|
184 | + check_admin_referer('bulk-'.$this->_args['plural']); |
|
185 | 185 | |
186 | - $method = 'bulk_' . $action; |
|
187 | - if ( array_key_exists( $action, $this->bulk_actions ) && is_callable( array( $this, $method ) ) && ! empty( $_GET['ID'] ) && is_array( $_GET['ID'] ) ) { |
|
188 | - $ids_sql = '(' . implode( ',', array_fill( 0, count( $_GET['ID'] ), '%s' ) ) . ')'; |
|
189 | - $id = array_map( 'absint', $_GET['ID'] ); |
|
190 | - $this->$method( $id, $wpdb->prepare( $ids_sql, $id ) ); //phpcs:ignore WordPress.DB.PreparedSQL |
|
186 | + $method = 'bulk_'.$action; |
|
187 | + if (array_key_exists($action, $this->bulk_actions) && is_callable(array($this, $method)) && ! empty($_GET['ID']) && is_array($_GET['ID'])) { |
|
188 | + $ids_sql = '('.implode(',', array_fill(0, count($_GET['ID']), '%s')).')'; |
|
189 | + $id = array_map('absint', $_GET['ID']); |
|
190 | + $this->$method($id, $wpdb->prepare($ids_sql, $id)); //phpcs:ignore WordPress.DB.PreparedSQL |
|
191 | 191 | } |
192 | 192 | |
193 | - if ( isset( $_SERVER['REQUEST_URI'] ) ) { |
|
193 | + if (isset($_SERVER['REQUEST_URI'])) { |
|
194 | 194 | wp_safe_redirect( |
195 | 195 | remove_query_arg( |
196 | - array( '_wp_http_referer', '_wpnonce', 'ID', 'action', 'action2' ), |
|
197 | - esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) |
|
196 | + array('_wp_http_referer', '_wpnonce', 'ID', 'action', 'action2'), |
|
197 | + esc_url_raw(wp_unslash($_SERVER['REQUEST_URI'])) |
|
198 | 198 | ) |
199 | 199 | ); |
200 | 200 | exit; |
@@ -209,10 +209,10 @@ discard block |
||
209 | 209 | * @param string $ids_sql the sql for the ids. |
210 | 210 | * @return void |
211 | 211 | */ |
212 | - protected function bulk_delete( array $ids, $ids_sql ) { |
|
212 | + protected function bulk_delete(array $ids, $ids_sql) { |
|
213 | 213 | $store = ActionScheduler::store(); |
214 | - foreach ( $ids as $action_id ) { |
|
215 | - $store->delete( $action_id ); |
|
214 | + foreach ($ids as $action_id) { |
|
215 | + $store->delete($action_id); |
|
216 | 216 | } |
217 | 217 | } |
218 | 218 | |
@@ -223,7 +223,7 @@ discard block |
||
223 | 223 | protected function prepare_column_headers() { |
224 | 224 | $this->_column_headers = array( |
225 | 225 | $this->get_columns(), |
226 | - get_hidden_columns( $this->screen ), |
|
226 | + get_hidden_columns($this->screen), |
|
227 | 227 | $this->get_sortable_columns(), |
228 | 228 | ); |
229 | 229 | } |
@@ -234,8 +234,8 @@ discard block |
||
234 | 234 | */ |
235 | 235 | public function get_sortable_columns() { |
236 | 236 | $sort_by = array(); |
237 | - foreach ( $this->sort_by as $column ) { |
|
238 | - $sort_by[ $column ] = array( $column, true ); |
|
237 | + foreach ($this->sort_by as $column) { |
|
238 | + $sort_by[$column] = array($column, true); |
|
239 | 239 | } |
240 | 240 | return $sort_by; |
241 | 241 | } |
@@ -246,7 +246,7 @@ discard block |
||
246 | 246 | */ |
247 | 247 | public function get_columns() { |
248 | 248 | $columns = array_merge( |
249 | - array( 'cb' => '<input type="checkbox" />' ), |
|
249 | + array('cb' => '<input type="checkbox" />'), |
|
250 | 250 | $this->columns |
251 | 251 | ); |
252 | 252 | |
@@ -263,8 +263,8 @@ discard block |
||
263 | 263 | protected function get_items_query_limit() { |
264 | 264 | global $wpdb; |
265 | 265 | |
266 | - $per_page = $this->get_items_per_page( $this->get_per_page_option_name(), $this->items_per_page ); |
|
267 | - return $wpdb->prepare( 'LIMIT %d', $per_page ); |
|
266 | + $per_page = $this->get_items_per_page($this->get_per_page_option_name(), $this->items_per_page); |
|
267 | + return $wpdb->prepare('LIMIT %d', $per_page); |
|
268 | 268 | } |
269 | 269 | |
270 | 270 | /** |
@@ -273,10 +273,10 @@ discard block |
||
273 | 273 | * @return int |
274 | 274 | */ |
275 | 275 | protected function get_items_offset() { |
276 | - $per_page = $this->get_items_per_page( $this->get_per_page_option_name(), $this->items_per_page ); |
|
276 | + $per_page = $this->get_items_per_page($this->get_per_page_option_name(), $this->items_per_page); |
|
277 | 277 | $current_page = $this->get_pagenum(); |
278 | - if ( 1 < $current_page ) { |
|
279 | - $offset = $per_page * ( $current_page - 1 ); |
|
278 | + if (1 < $current_page) { |
|
279 | + $offset = $per_page * ($current_page - 1); |
|
280 | 280 | } else { |
281 | 281 | $offset = 0; |
282 | 282 | } |
@@ -294,7 +294,7 @@ discard block |
||
294 | 294 | protected function get_items_query_offset() { |
295 | 295 | global $wpdb; |
296 | 296 | |
297 | - return $wpdb->prepare( 'OFFSET %d', $this->get_items_offset() ); |
|
297 | + return $wpdb->prepare('OFFSET %d', $this->get_items_offset()); |
|
298 | 298 | } |
299 | 299 | |
300 | 300 | /** |
@@ -303,12 +303,12 @@ discard block |
||
303 | 303 | * column and sortable. It will also use order (ASC|DESC) using DESC by default. |
304 | 304 | */ |
305 | 305 | protected function get_items_query_order() { |
306 | - if ( empty( $this->sort_by ) ) { |
|
306 | + if (empty($this->sort_by)) { |
|
307 | 307 | return ''; |
308 | 308 | } |
309 | 309 | |
310 | - $orderby = esc_sql( $this->get_request_orderby() ); |
|
311 | - $order = esc_sql( $this->get_request_order() ); |
|
310 | + $orderby = esc_sql($this->get_request_orderby()); |
|
311 | + $order = esc_sql($this->get_request_order()); |
|
312 | 312 | |
313 | 313 | return "ORDER BY {$orderby} {$order}"; |
314 | 314 | } |
@@ -320,10 +320,10 @@ discard block |
||
320 | 320 | */ |
321 | 321 | protected function get_request_orderby() { |
322 | 322 | |
323 | - $valid_sortable_columns = array_values( $this->sort_by ); |
|
323 | + $valid_sortable_columns = array_values($this->sort_by); |
|
324 | 324 | |
325 | - if ( ! empty( $_GET['orderby'] ) && in_array( $_GET['orderby'], $valid_sortable_columns, true ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
326 | - $orderby = sanitize_text_field( wp_unslash( $_GET['orderby'] ) ); //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
325 | + if ( ! empty($_GET['orderby']) && in_array($_GET['orderby'], $valid_sortable_columns, true)) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
326 | + $orderby = sanitize_text_field(wp_unslash($_GET['orderby'])); //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
327 | 327 | } else { |
328 | 328 | $orderby = $valid_sortable_columns[0]; |
329 | 329 | } |
@@ -338,7 +338,7 @@ discard block |
||
338 | 338 | */ |
339 | 339 | protected function get_request_order() { |
340 | 340 | |
341 | - if ( ! empty( $_GET['order'] ) && 'desc' === strtolower( sanitize_text_field( wp_unslash( $_GET['order'] ) ) ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
341 | + if ( ! empty($_GET['order']) && 'desc' === strtolower(sanitize_text_field(wp_unslash($_GET['order'])))) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
342 | 342 | $order = 'DESC'; |
343 | 343 | } else { |
344 | 344 | $order = 'ASC'; |
@@ -353,7 +353,7 @@ discard block |
||
353 | 353 | * @return string |
354 | 354 | */ |
355 | 355 | protected function get_request_status() { |
356 | - $status = ( ! empty( $_GET['status'] ) ) ? sanitize_text_field( wp_unslash( $_GET['status'] ) ) : ''; //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
356 | + $status = ( ! empty($_GET['status'])) ? sanitize_text_field(wp_unslash($_GET['status'])) : ''; //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
357 | 357 | return $status; |
358 | 358 | } |
359 | 359 | |
@@ -363,7 +363,7 @@ discard block |
||
363 | 363 | * @return string |
364 | 364 | */ |
365 | 365 | protected function get_request_search_query() { |
366 | - $search_query = ( ! empty( $_GET['s'] ) ) ? sanitize_text_field( wp_unslash( $_GET['s'] ) ) : ''; //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
366 | + $search_query = ( ! empty($_GET['s'])) ? sanitize_text_field(wp_unslash($_GET['s'])) : ''; //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
367 | 367 | return $search_query; |
368 | 368 | } |
369 | 369 | |
@@ -374,8 +374,8 @@ discard block |
||
374 | 374 | * @return array |
375 | 375 | */ |
376 | 376 | protected function get_table_columns() { |
377 | - $columns = array_keys( $this->columns ); |
|
378 | - if ( ! in_array( $this->ID, $columns, true ) ) { |
|
377 | + $columns = array_keys($this->columns); |
|
378 | + if ( ! in_array($this->ID, $columns, true)) { |
|
379 | 379 | $columns[] = $this->ID; |
380 | 380 | } |
381 | 381 | |
@@ -394,19 +394,19 @@ discard block |
||
394 | 394 | protected function get_items_query_search() { |
395 | 395 | global $wpdb; |
396 | 396 | |
397 | - if ( empty( $_GET['s'] ) || empty( $this->search_by ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
397 | + if (empty($_GET['s']) || empty($this->search_by)) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
398 | 398 | return ''; |
399 | 399 | } |
400 | 400 | |
401 | - $search_string = sanitize_text_field( wp_unslash( $_GET['s'] ) ); //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
401 | + $search_string = sanitize_text_field(wp_unslash($_GET['s'])); //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
402 | 402 | |
403 | 403 | $filter = array(); |
404 | - foreach ( $this->search_by as $column ) { |
|
404 | + foreach ($this->search_by as $column) { |
|
405 | 405 | $wild = '%'; |
406 | - $sql_like = $wild . $wpdb->esc_like( $search_string ) . $wild; |
|
407 | - $filter[] = $wpdb->prepare( '`' . $column . '` LIKE %s', $sql_like ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.DB.PreparedSQL.NotPrepared |
|
406 | + $sql_like = $wild.$wpdb->esc_like($search_string).$wild; |
|
407 | + $filter[] = $wpdb->prepare('`'.$column.'` LIKE %s', $sql_like); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.DB.PreparedSQL.NotPrepared |
|
408 | 408 | } |
409 | - return implode( ' OR ', $filter ); |
|
409 | + return implode(' OR ', $filter); |
|
410 | 410 | } |
411 | 411 | |
412 | 412 | /** |
@@ -416,21 +416,21 @@ discard block |
||
416 | 416 | protected function get_items_query_filters() { |
417 | 417 | global $wpdb; |
418 | 418 | |
419 | - if ( ! $this->filter_by || empty( $_GET['filter_by'] ) || ! is_array( $_GET['filter_by'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
419 | + if ( ! $this->filter_by || empty($_GET['filter_by']) || ! is_array($_GET['filter_by'])) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
420 | 420 | return ''; |
421 | 421 | } |
422 | 422 | |
423 | 423 | $filter = array(); |
424 | 424 | |
425 | - foreach ( $this->filter_by as $column => $options ) { |
|
426 | - if ( empty( $_GET['filter_by'][ $column ] ) || empty( $options[ $_GET['filter_by'][ $column ] ] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
425 | + foreach ($this->filter_by as $column => $options) { |
|
426 | + if (empty($_GET['filter_by'][$column]) || empty($options[$_GET['filter_by'][$column]])) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
427 | 427 | continue; |
428 | 428 | } |
429 | 429 | |
430 | - $filter[] = $wpdb->prepare( "`$column` = %s", sanitize_text_field( wp_unslash( $_GET['filter_by'][ $column ] ) ) ); //phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.DB.PreparedSQL.InterpolatedNotPrepared |
|
430 | + $filter[] = $wpdb->prepare("`$column` = %s", sanitize_text_field(wp_unslash($_GET['filter_by'][$column]))); //phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.DB.PreparedSQL.InterpolatedNotPrepared |
|
431 | 431 | } |
432 | 432 | |
433 | - return implode( ' AND ', $filter ); |
|
433 | + return implode(' AND ', $filter); |
|
434 | 434 | |
435 | 435 | } |
436 | 436 | |
@@ -450,9 +450,9 @@ discard block |
||
450 | 450 | |
451 | 451 | $this->process_row_actions(); |
452 | 452 | |
453 | - if ( ! empty( $_REQUEST['_wp_http_referer'] && ! empty( $_SERVER['REQUEST_URI'] ) ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
453 | + if ( ! empty($_REQUEST['_wp_http_referer'] && ! empty($_SERVER['REQUEST_URI']))) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
454 | 454 | // _wp_http_referer is used only on bulk actions, we remove it to keep the $_GET shorter |
455 | - wp_safe_redirect( remove_query_arg( array( '_wp_http_referer', '_wpnonce' ), esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) ) ); |
|
455 | + wp_safe_redirect(remove_query_arg(array('_wp_http_referer', '_wpnonce'), esc_url_raw(wp_unslash($_SERVER['REQUEST_URI'])))); |
|
456 | 456 | exit; |
457 | 457 | } |
458 | 458 | |
@@ -467,26 +467,26 @@ discard block |
||
467 | 467 | $this->get_items_query_filters(), |
468 | 468 | ) |
469 | 469 | ); |
470 | - $columns = '`' . implode( '`, `', $this->get_table_columns() ) . '`'; |
|
470 | + $columns = '`'.implode('`, `', $this->get_table_columns()).'`'; |
|
471 | 471 | |
472 | - if ( ! empty( $where ) ) { |
|
473 | - $where = 'WHERE (' . implode( ') AND (', $where ) . ')'; |
|
472 | + if ( ! empty($where)) { |
|
473 | + $where = 'WHERE ('.implode(') AND (', $where).')'; |
|
474 | 474 | } else { |
475 | 475 | $where = ''; |
476 | 476 | } |
477 | 477 | |
478 | 478 | $sql = "SELECT $columns FROM {$this->table_name} {$where} {$order} {$limit} {$offset}"; |
479 | 479 | |
480 | - $this->set_items( $wpdb->get_results( $sql, ARRAY_A ) ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared |
|
480 | + $this->set_items($wpdb->get_results($sql, ARRAY_A)); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared |
|
481 | 481 | |
482 | 482 | $query_count = "SELECT COUNT({$this->ID}) FROM {$this->table_name} {$where}"; |
483 | - $total_items = $wpdb->get_var( $query_count ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared |
|
484 | - $per_page = $this->get_items_per_page( $this->get_per_page_option_name(), $this->items_per_page ); |
|
483 | + $total_items = $wpdb->get_var($query_count); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared |
|
484 | + $per_page = $this->get_items_per_page($this->get_per_page_option_name(), $this->items_per_page); |
|
485 | 485 | $this->set_pagination_args( |
486 | 486 | array( |
487 | 487 | 'total_items' => $total_items, |
488 | 488 | 'per_page' => $per_page, |
489 | - 'total_pages' => ceil( $total_items / $per_page ), |
|
489 | + 'total_pages' => ceil($total_items / $per_page), |
|
490 | 490 | ) |
491 | 491 | ); |
492 | 492 | } |
@@ -496,31 +496,31 @@ discard block |
||
496 | 496 | * |
497 | 497 | * @param string $which The name of the table. |
498 | 498 | */ |
499 | - public function extra_tablenav( $which ) { |
|
500 | - if ( ! $this->filter_by || 'top' !== $which ) { |
|
499 | + public function extra_tablenav($which) { |
|
500 | + if ( ! $this->filter_by || 'top' !== $which) { |
|
501 | 501 | return; |
502 | 502 | } |
503 | 503 | |
504 | 504 | echo '<div class="alignleft actions">'; |
505 | 505 | |
506 | - foreach ( $this->filter_by as $id => $options ) { |
|
507 | - $default = ! empty( $_GET['filter_by'][ $id ] ) ? sanitize_text_field( wp_unslash( $_GET['filter_by'][ $id ] ) ) : ''; //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
508 | - if ( empty( $options[ $default ] ) ) { |
|
506 | + foreach ($this->filter_by as $id => $options) { |
|
507 | + $default = ! empty($_GET['filter_by'][$id]) ? sanitize_text_field(wp_unslash($_GET['filter_by'][$id])) : ''; //phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
508 | + if (empty($options[$default])) { |
|
509 | 509 | $default = ''; |
510 | 510 | } |
511 | 511 | |
512 | - echo '<select name="filter_by[' . esc_attr( $id ) . ']" class="first" id="filter-by-' . esc_attr( $id ) . '">'; |
|
512 | + echo '<select name="filter_by['.esc_attr($id).']" class="first" id="filter-by-'.esc_attr($id).'">'; |
|
513 | 513 | |
514 | - foreach ( $options as $value => $label ) { |
|
515 | - echo '<option value="' . esc_attr( $value ) . '" ' . esc_html( $value === $default ? 'selected' : '' ) . '>' |
|
516 | - . esc_html( $label ) |
|
514 | + foreach ($options as $value => $label) { |
|
515 | + echo '<option value="'.esc_attr($value).'" '.esc_html($value === $default ? 'selected' : '').'>' |
|
516 | + . esc_html($label) |
|
517 | 517 | . '</option>'; |
518 | 518 | } |
519 | 519 | |
520 | 520 | echo '</select>'; |
521 | 521 | } |
522 | 522 | |
523 | - submit_button( esc_html__( 'Filter', 'action-scheduler' ), '', 'filter_action', false, array( 'id' => 'post-query-submit' ) ); |
|
523 | + submit_button(esc_html__('Filter', 'action-scheduler'), '', 'filter_action', false, array('id' => 'post-query-submit')); |
|
524 | 524 | echo '</div>'; |
525 | 525 | } |
526 | 526 | |
@@ -530,10 +530,10 @@ discard block |
||
530 | 530 | * |
531 | 531 | * @param array $items Items array. |
532 | 532 | */ |
533 | - protected function set_items( array $items ) { |
|
533 | + protected function set_items(array $items) { |
|
534 | 534 | $this->items = array(); |
535 | - foreach ( $items as $item ) { |
|
536 | - $this->items[ $item[ $this->ID ] ] = array_map( 'maybe_unserialize', $item ); |
|
535 | + foreach ($items as $item) { |
|
536 | + $this->items[$item[$this->ID]] = array_map('maybe_unserialize', $item); |
|
537 | 537 | } |
538 | 538 | } |
539 | 539 | |
@@ -544,8 +544,8 @@ discard block |
||
544 | 544 | * |
545 | 545 | * @param array $row The row to render. |
546 | 546 | */ |
547 | - public function column_cb( $row ) { |
|
548 | - return '<input name="ID[]" type="checkbox" value="' . esc_attr( $row[ $this->ID ] ) . '" />'; |
|
547 | + public function column_cb($row) { |
|
548 | + return '<input name="ID[]" type="checkbox" value="'.esc_attr($row[$this->ID]).'" />'; |
|
549 | 549 | } |
550 | 550 | |
551 | 551 | /** |
@@ -558,36 +558,36 @@ discard block |
||
558 | 558 | * @param string $column_name Column name. |
559 | 559 | * @return string |
560 | 560 | */ |
561 | - protected function maybe_render_actions( $row, $column_name ) { |
|
562 | - if ( empty( $this->row_actions[ $column_name ] ) ) { |
|
561 | + protected function maybe_render_actions($row, $column_name) { |
|
562 | + if (empty($this->row_actions[$column_name])) { |
|
563 | 563 | return; |
564 | 564 | } |
565 | 565 | |
566 | - $row_id = $row[ $this->ID ]; |
|
566 | + $row_id = $row[$this->ID]; |
|
567 | 567 | |
568 | 568 | $actions = '<div class="row-actions">'; |
569 | 569 | $action_count = 0; |
570 | - foreach ( $this->row_actions[ $column_name ] as $action_key => $action ) { |
|
570 | + foreach ($this->row_actions[$column_name] as $action_key => $action) { |
|
571 | 571 | |
572 | 572 | $action_count++; |
573 | 573 | |
574 | - if ( ! method_exists( $this, 'row_action_' . $action_key ) ) { |
|
574 | + if ( ! method_exists($this, 'row_action_'.$action_key)) { |
|
575 | 575 | continue; |
576 | 576 | } |
577 | 577 | |
578 | - $action_link = ! empty( $action['link'] ) ? $action['link'] : add_query_arg( |
|
578 | + $action_link = ! empty($action['link']) ? $action['link'] : add_query_arg( |
|
579 | 579 | array( |
580 | 580 | 'row_action' => $action_key, |
581 | 581 | 'row_id' => $row_id, |
582 | - 'nonce' => wp_create_nonce( $action_key . '::' . $row_id ), |
|
582 | + 'nonce' => wp_create_nonce($action_key.'::'.$row_id), |
|
583 | 583 | ) |
584 | 584 | ); |
585 | - $span_class = ! empty( $action['class'] ) ? $action['class'] : $action_key; |
|
586 | - $separator = ( $action_count < count( $this->row_actions[ $column_name ] ) ) ? ' | ' : ''; |
|
585 | + $span_class = ! empty($action['class']) ? $action['class'] : $action_key; |
|
586 | + $separator = ($action_count < count($this->row_actions[$column_name])) ? ' | ' : ''; |
|
587 | 587 | |
588 | - $actions .= sprintf( '<span class="%s">', esc_attr( $span_class ) ); |
|
589 | - $actions .= sprintf( '<a href="%1$s" title="%2$s">%3$s</a>', esc_url( $action_link ), esc_attr( $action['desc'] ), esc_html( $action['name'] ) ); |
|
590 | - $actions .= sprintf( '%s</span>', $separator ); |
|
588 | + $actions .= sprintf('<span class="%s">', esc_attr($span_class)); |
|
589 | + $actions .= sprintf('<a href="%1$s" title="%2$s">%3$s</a>', esc_url($action_link), esc_attr($action['desc']), esc_html($action['name'])); |
|
590 | + $actions .= sprintf('%s</span>', $separator); |
|
591 | 591 | } |
592 | 592 | $actions .= '</div>'; |
593 | 593 | return $actions; |
@@ -599,27 +599,27 @@ discard block |
||
599 | 599 | * @return void |
600 | 600 | */ |
601 | 601 | protected function process_row_actions() { |
602 | - $parameters = array( 'row_action', 'row_id', 'nonce' ); |
|
603 | - foreach ( $parameters as $parameter ) { |
|
604 | - if ( empty( $_REQUEST[ $parameter ] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
602 | + $parameters = array('row_action', 'row_id', 'nonce'); |
|
603 | + foreach ($parameters as $parameter) { |
|
604 | + if (empty($_REQUEST[$parameter])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
605 | 605 | return; |
606 | 606 | } |
607 | 607 | } |
608 | 608 | |
609 | - $action = sanitize_text_field( wp_unslash( $_REQUEST['row_action'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotValidated |
|
610 | - $row_id = sanitize_text_field( wp_unslash( $_REQUEST['row_id'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotValidated |
|
611 | - $nonce = sanitize_text_field( wp_unslash( $_REQUEST['nonce'] ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotValidated |
|
612 | - $method = 'row_action_' . $action; // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
609 | + $action = sanitize_text_field(wp_unslash($_REQUEST['row_action'])); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotValidated |
|
610 | + $row_id = sanitize_text_field(wp_unslash($_REQUEST['row_id'])); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotValidated |
|
611 | + $nonce = sanitize_text_field(wp_unslash($_REQUEST['nonce'])); // phpcs:ignore WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput.InputNotValidated |
|
612 | + $method = 'row_action_'.$action; // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
613 | 613 | |
614 | - if ( wp_verify_nonce( $nonce, $action . '::' . $row_id ) && method_exists( $this, $method ) ) { |
|
615 | - $this->$method( sanitize_text_field( wp_unslash( $row_id ) ) ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
614 | + if (wp_verify_nonce($nonce, $action.'::'.$row_id) && method_exists($this, $method)) { |
|
615 | + $this->$method(sanitize_text_field(wp_unslash($row_id))); // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
616 | 616 | } |
617 | 617 | |
618 | - if ( isset( $_SERVER['REQUEST_URI'] ) ) { |
|
618 | + if (isset($_SERVER['REQUEST_URI'])) { |
|
619 | 619 | wp_safe_redirect( |
620 | 620 | remove_query_arg( |
621 | - array( 'row_id', 'row_action', 'nonce' ), |
|
622 | - esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) |
|
621 | + array('row_id', 'row_action', 'nonce'), |
|
622 | + esc_url_raw(wp_unslash($_SERVER['REQUEST_URI'])) |
|
623 | 623 | ) |
624 | 624 | ); |
625 | 625 | exit; |
@@ -634,9 +634,9 @@ discard block |
||
634 | 634 | * |
635 | 635 | * @return string |
636 | 636 | */ |
637 | - public function column_default( $item, $column_name ) { |
|
638 | - $column_html = esc_html( $item[ $column_name ] ); |
|
639 | - $column_html .= $this->maybe_render_actions( $item, $column_name ); |
|
637 | + public function column_default($item, $column_name) { |
|
638 | + $column_html = esc_html($item[$column_name]); |
|
639 | + $column_html .= $this->maybe_render_actions($item, $column_name); |
|
640 | 640 | return $column_html; |
641 | 641 | } |
642 | 642 | |
@@ -644,10 +644,10 @@ discard block |
||
644 | 644 | * Display the table heading and search query, if any |
645 | 645 | */ |
646 | 646 | protected function display_header() { |
647 | - echo '<h1 class="wp-heading-inline">' . esc_attr( $this->table_header ) . '</h1>'; |
|
648 | - if ( $this->get_request_search_query() ) { |
|
647 | + echo '<h1 class="wp-heading-inline">'.esc_attr($this->table_header).'</h1>'; |
|
648 | + if ($this->get_request_search_query()) { |
|
649 | 649 | /* translators: %s: search query */ |
650 | - echo '<span class="subtitle">' . esc_attr( sprintf( __( 'Search results for "%s"', 'action-scheduler' ), $this->get_request_search_query() ) ) . '</span>'; |
|
650 | + echo '<span class="subtitle">'.esc_attr(sprintf(__('Search results for "%s"', 'action-scheduler'), $this->get_request_search_query())).'</span>'; |
|
651 | 651 | } |
652 | 652 | echo '<hr class="wp-header-end">'; |
653 | 653 | } |
@@ -656,9 +656,9 @@ discard block |
||
656 | 656 | * Display the table heading and search query, if any |
657 | 657 | */ |
658 | 658 | protected function display_admin_notices() { |
659 | - foreach ( $this->admin_notices as $notice ) { |
|
660 | - echo '<div id="message" class="' . esc_attr( $notice['class'] ) . '">'; |
|
661 | - echo ' <p>' . wp_kses_post( $notice['message'] ) . '</p>'; |
|
659 | + foreach ($this->admin_notices as $notice) { |
|
660 | + echo '<div id="message" class="'.esc_attr($notice['class']).'">'; |
|
661 | + echo ' <p>'.wp_kses_post($notice['message']).'</p>'; |
|
662 | 662 | echo '</div>'; |
663 | 663 | } |
664 | 664 | } |
@@ -672,30 +672,30 @@ discard block |
||
672 | 672 | $request_status = $this->get_request_status(); |
673 | 673 | |
674 | 674 | // Helper to set 'all' filter when not set on status counts passed in. |
675 | - if ( ! isset( $this->status_counts['all'] ) ) { |
|
676 | - $this->status_counts = array( 'all' => array_sum( $this->status_counts ) ) + $this->status_counts; |
|
675 | + if ( ! isset($this->status_counts['all'])) { |
|
676 | + $this->status_counts = array('all' => array_sum($this->status_counts)) + $this->status_counts; |
|
677 | 677 | } |
678 | 678 | |
679 | - foreach ( $this->status_counts as $status_name => $count ) { |
|
679 | + foreach ($this->status_counts as $status_name => $count) { |
|
680 | 680 | |
681 | - if ( 0 === $count ) { |
|
681 | + if (0 === $count) { |
|
682 | 682 | continue; |
683 | 683 | } |
684 | 684 | |
685 | - if ( $status_name === $request_status || ( empty( $request_status ) && 'all' === $status_name ) ) { |
|
685 | + if ($status_name === $request_status || (empty($request_status) && 'all' === $status_name)) { |
|
686 | 686 | $status_list_item = '<li class="%1$s"><a href="%2$s" class="current">%3$s</a> (%4$d)</li>'; |
687 | 687 | } else { |
688 | 688 | $status_list_item = '<li class="%1$s"><a href="%2$s">%3$s</a> (%4$d)</li>'; |
689 | 689 | } |
690 | 690 | |
691 | - $status_filter_url = ( 'all' === $status_name ) ? remove_query_arg( 'status' ) : add_query_arg( 'status', $status_name ); |
|
692 | - $status_filter_url = remove_query_arg( array( 'paged', 's' ), $status_filter_url ); |
|
693 | - $status_list_items[] = sprintf( $status_list_item, esc_attr( $status_name ), esc_url( $status_filter_url ), esc_html( ucfirst( $status_name ) ), absint( $count ) ); |
|
691 | + $status_filter_url = ('all' === $status_name) ? remove_query_arg('status') : add_query_arg('status', $status_name); |
|
692 | + $status_filter_url = remove_query_arg(array('paged', 's'), $status_filter_url); |
|
693 | + $status_list_items[] = sprintf($status_list_item, esc_attr($status_name), esc_url($status_filter_url), esc_html(ucfirst($status_name)), absint($count)); |
|
694 | 694 | } |
695 | 695 | |
696 | - if ( $status_list_items ) { |
|
696 | + if ($status_list_items) { |
|
697 | 697 | echo '<ul class="subsubsub">'; |
698 | - echo implode( " | \n", $status_list_items ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
|
698 | + echo implode(" | \n", $status_list_items); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
|
699 | 699 | echo '</ul>'; |
700 | 700 | } |
701 | 701 | } |
@@ -706,15 +706,15 @@ discard block |
||
706 | 706 | * forget about any extra HTML. |
707 | 707 | */ |
708 | 708 | protected function display_table() { |
709 | - echo '<form id="' . esc_attr( $this->_args['plural'] ) . '-filter" method="get">'; |
|
710 | - foreach ( $_GET as $key => $value ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
711 | - if ( '_' === $key[0] || 'paged' === $key || 'ID' === $key ) { |
|
709 | + echo '<form id="'.esc_attr($this->_args['plural']).'-filter" method="get">'; |
|
710 | + foreach ($_GET as $key => $value) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
711 | + if ('_' === $key[0] || 'paged' === $key || 'ID' === $key) { |
|
712 | 712 | continue; |
713 | 713 | } |
714 | - echo '<input type="hidden" name="' . esc_attr( $key ) . '" value="' . esc_attr( $value ) . '" />'; |
|
714 | + echo '<input type="hidden" name="'.esc_attr($key).'" value="'.esc_attr($value).'" />'; |
|
715 | 715 | } |
716 | - if ( ! empty( $this->search_by ) ) { |
|
717 | - echo $this->search_box( $this->get_search_box_button_text(), 'plugin' ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
|
716 | + if ( ! empty($this->search_by)) { |
|
717 | + echo $this->search_box($this->get_search_box_button_text(), 'plugin'); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped |
|
718 | 718 | } |
719 | 719 | parent::display(); |
720 | 720 | echo '</form>'; |
@@ -727,9 +727,9 @@ discard block |
||
727 | 727 | $this->process_bulk_action(); |
728 | 728 | $this->process_row_actions(); |
729 | 729 | |
730 | - if ( ! empty( $_REQUEST['_wp_http_referer'] ) && ! empty( $_SERVER['REQUEST_URI'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
730 | + if ( ! empty($_REQUEST['_wp_http_referer']) && ! empty($_SERVER['REQUEST_URI'])) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended |
|
731 | 731 | // _wp_http_referer is used only on bulk actions, we remove it to keep the $_GET shorter |
732 | - wp_safe_redirect( remove_query_arg( array( '_wp_http_referer', '_wpnonce' ), esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) ) ) ); |
|
732 | + wp_safe_redirect(remove_query_arg(array('_wp_http_referer', '_wpnonce'), esc_url_raw(wp_unslash($_SERVER['REQUEST_URI'])))); |
|
733 | 733 | exit; |
734 | 734 | } |
735 | 735 | } |
@@ -752,7 +752,7 @@ discard block |
||
752 | 752 | * Get the text to display in the search box on the list table. |
753 | 753 | */ |
754 | 754 | protected function get_search_box_placeholder() { |
755 | - return esc_html__( 'Search', 'action-scheduler' ); |
|
755 | + return esc_html__('Search', 'action-scheduler'); |
|
756 | 756 | } |
757 | 757 | |
758 | 758 | /** |
@@ -761,6 +761,6 @@ discard block |
||
761 | 761 | * @return string |
762 | 762 | */ |
763 | 763 | protected function get_per_page_option_name() { |
764 | - return $this->package . '_items_per_page'; |
|
764 | + return $this->package.'_items_per_page'; |
|
765 | 765 | } |
766 | 766 | } |
@@ -22,7 +22,7 @@ discard block |
||
22 | 22 | /** |
23 | 23 | * @param DateTime $date The date & time to run the action. |
24 | 24 | */ |
25 | - public function __construct( DateTime $date ) { |
|
25 | + public function __construct(DateTime $date) { |
|
26 | 26 | $this->scheduled_date = $date; |
27 | 27 | } |
28 | 28 | |
@@ -39,7 +39,7 @@ discard block |
||
39 | 39 | * @param DateTime $after |
40 | 40 | * @return DateTime |
41 | 41 | */ |
42 | - abstract protected function calculate_next( DateTime $after ); |
|
42 | + abstract protected function calculate_next(DateTime $after); |
|
43 | 43 | |
44 | 44 | /** |
45 | 45 | * Get the next date & time when this schedule should run after a given date & time. |
@@ -47,10 +47,10 @@ discard block |
||
47 | 47 | * @param DateTime $after |
48 | 48 | * @return DateTime|null |
49 | 49 | */ |
50 | - public function get_next( DateTime $after ) { |
|
50 | + public function get_next(DateTime $after) { |
|
51 | 51 | $after = clone $after; |
52 | - if ( $after > $this->scheduled_date ) { |
|
53 | - $after = $this->calculate_next( $after ); |
|
52 | + if ($after > $this->scheduled_date) { |
|
53 | + $after = $this->calculate_next($after); |
|
54 | 54 | return $after; |
55 | 55 | } |
56 | 56 | return clone $this->scheduled_date; |
@@ -77,7 +77,7 @@ discard block |
||
77 | 77 | } |
78 | 78 | |
79 | 79 | public function __wakeup() { |
80 | - $this->scheduled_date = as_get_datetime_object( $this->scheduled_timestamp ); |
|
81 | - unset( $this->scheduled_timestamp ); |
|
80 | + $this->scheduled_date = as_get_datetime_object($this->scheduled_timestamp); |
|
81 | + unset($this->scheduled_timestamp); |
|
82 | 82 | } |
83 | 83 | } |
@@ -5,80 +5,80 @@ |
||
5 | 5 | */ |
6 | 6 | abstract class ActionScheduler_Abstract_Schedule extends ActionScheduler_Schedule_Deprecated { |
7 | 7 | |
8 | - /** |
|
9 | - * The date & time the schedule is set to run. |
|
10 | - * |
|
11 | - * @var DateTime |
|
12 | - */ |
|
13 | - private $scheduled_date = null; |
|
8 | + /** |
|
9 | + * The date & time the schedule is set to run. |
|
10 | + * |
|
11 | + * @var DateTime |
|
12 | + */ |
|
13 | + private $scheduled_date = null; |
|
14 | 14 | |
15 | - /** |
|
16 | - * Timestamp equivalent of @see $this->scheduled_date |
|
17 | - * |
|
18 | - * @var int |
|
19 | - */ |
|
20 | - protected $scheduled_timestamp = null; |
|
15 | + /** |
|
16 | + * Timestamp equivalent of @see $this->scheduled_date |
|
17 | + * |
|
18 | + * @var int |
|
19 | + */ |
|
20 | + protected $scheduled_timestamp = null; |
|
21 | 21 | |
22 | - /** |
|
23 | - * @param DateTime $date The date & time to run the action. |
|
24 | - */ |
|
25 | - public function __construct( DateTime $date ) { |
|
26 | - $this->scheduled_date = $date; |
|
27 | - } |
|
22 | + /** |
|
23 | + * @param DateTime $date The date & time to run the action. |
|
24 | + */ |
|
25 | + public function __construct( DateTime $date ) { |
|
26 | + $this->scheduled_date = $date; |
|
27 | + } |
|
28 | 28 | |
29 | - /** |
|
30 | - * Check if a schedule should recur. |
|
31 | - * |
|
32 | - * @return bool |
|
33 | - */ |
|
34 | - abstract public function is_recurring(); |
|
29 | + /** |
|
30 | + * Check if a schedule should recur. |
|
31 | + * |
|
32 | + * @return bool |
|
33 | + */ |
|
34 | + abstract public function is_recurring(); |
|
35 | 35 | |
36 | - /** |
|
37 | - * Calculate when the next instance of this schedule would run based on a given date & time. |
|
38 | - * |
|
39 | - * @param DateTime $after |
|
40 | - * @return DateTime |
|
41 | - */ |
|
42 | - abstract protected function calculate_next( DateTime $after ); |
|
36 | + /** |
|
37 | + * Calculate when the next instance of this schedule would run based on a given date & time. |
|
38 | + * |
|
39 | + * @param DateTime $after |
|
40 | + * @return DateTime |
|
41 | + */ |
|
42 | + abstract protected function calculate_next( DateTime $after ); |
|
43 | 43 | |
44 | - /** |
|
45 | - * Get the next date & time when this schedule should run after a given date & time. |
|
46 | - * |
|
47 | - * @param DateTime $after |
|
48 | - * @return DateTime|null |
|
49 | - */ |
|
50 | - public function get_next( DateTime $after ) { |
|
51 | - $after = clone $after; |
|
52 | - if ( $after > $this->scheduled_date ) { |
|
53 | - $after = $this->calculate_next( $after ); |
|
54 | - return $after; |
|
55 | - } |
|
56 | - return clone $this->scheduled_date; |
|
57 | - } |
|
44 | + /** |
|
45 | + * Get the next date & time when this schedule should run after a given date & time. |
|
46 | + * |
|
47 | + * @param DateTime $after |
|
48 | + * @return DateTime|null |
|
49 | + */ |
|
50 | + public function get_next( DateTime $after ) { |
|
51 | + $after = clone $after; |
|
52 | + if ( $after > $this->scheduled_date ) { |
|
53 | + $after = $this->calculate_next( $after ); |
|
54 | + return $after; |
|
55 | + } |
|
56 | + return clone $this->scheduled_date; |
|
57 | + } |
|
58 | 58 | |
59 | - /** |
|
60 | - * Get the date & time the schedule is set to run. |
|
61 | - * |
|
62 | - * @return DateTime|null |
|
63 | - */ |
|
64 | - public function get_date() { |
|
65 | - return $this->scheduled_date; |
|
66 | - } |
|
59 | + /** |
|
60 | + * Get the date & time the schedule is set to run. |
|
61 | + * |
|
62 | + * @return DateTime|null |
|
63 | + */ |
|
64 | + public function get_date() { |
|
65 | + return $this->scheduled_date; |
|
66 | + } |
|
67 | 67 | |
68 | - /** |
|
69 | - * For PHP 5.2 compat, since DateTime objects can't be serialized |
|
70 | - * |
|
71 | - * @return array |
|
72 | - */ |
|
73 | - public function __sleep() { |
|
74 | - $this->scheduled_timestamp = $this->scheduled_date->getTimestamp(); |
|
75 | - return array( |
|
76 | - 'scheduled_timestamp', |
|
77 | - ); |
|
78 | - } |
|
68 | + /** |
|
69 | + * For PHP 5.2 compat, since DateTime objects can't be serialized |
|
70 | + * |
|
71 | + * @return array |
|
72 | + */ |
|
73 | + public function __sleep() { |
|
74 | + $this->scheduled_timestamp = $this->scheduled_date->getTimestamp(); |
|
75 | + return array( |
|
76 | + 'scheduled_timestamp', |
|
77 | + ); |
|
78 | + } |
|
79 | 79 | |
80 | - public function __wakeup() { |
|
81 | - $this->scheduled_date = as_get_datetime_object( $this->scheduled_timestamp ); |
|
82 | - unset( $this->scheduled_timestamp ); |
|
83 | - } |
|
80 | + public function __wakeup() { |
|
81 | + $this->scheduled_date = as_get_datetime_object( $this->scheduled_timestamp ); |
|
82 | + unset( $this->scheduled_timestamp ); |
|
83 | + } |
|
84 | 84 | } |
@@ -5,184 +5,184 @@ |
||
5 | 5 | */ |
6 | 6 | class ActionScheduler_WPCLI_Scheduler_command extends WP_CLI_Command { |
7 | 7 | |
8 | - /** |
|
9 | - * Force tables schema creation for Action Scheduler |
|
10 | - * |
|
11 | - * ## OPTIONS |
|
12 | - * |
|
13 | - * @param array $args Positional arguments. |
|
14 | - * @param array $assoc_args Keyed arguments. |
|
15 | - * |
|
16 | - * @subcommand fix-schema |
|
17 | - */ |
|
18 | - public function fix_schema( $args, $assoc_args ) { |
|
19 | - $schema_classes = array( ActionScheduler_LoggerSchema::class, ActionScheduler_StoreSchema::class ); |
|
20 | - |
|
21 | - foreach ( $schema_classes as $classname ) { |
|
22 | - if ( is_subclass_of( $classname, ActionScheduler_Abstract_Schema::class ) ) { |
|
23 | - $obj = new $classname(); |
|
24 | - $obj->init(); |
|
25 | - $obj->register_tables( true ); |
|
26 | - |
|
27 | - WP_CLI::success( |
|
28 | - sprintf( |
|
29 | - /* translators: %s refers to the schema name*/ |
|
30 | - __( 'Registered schema for %s', 'action-scheduler' ), |
|
31 | - $classname |
|
32 | - ) |
|
33 | - ); |
|
34 | - } |
|
35 | - } |
|
36 | - } |
|
37 | - |
|
38 | - /** |
|
39 | - * Run the Action Scheduler |
|
40 | - * |
|
41 | - * ## OPTIONS |
|
42 | - * |
|
43 | - * [--batch-size=<size>] |
|
44 | - * : The maximum number of actions to run. Defaults to 100. |
|
45 | - * |
|
46 | - * [--batches=<size>] |
|
47 | - * : Limit execution to a number of batches. Defaults to 0, meaning batches will continue being executed until all actions are complete. |
|
48 | - * |
|
49 | - * [--cleanup-batch-size=<size>] |
|
50 | - * : The maximum number of actions to clean up. Defaults to the value of --batch-size. |
|
51 | - * |
|
52 | - * [--hooks=<hooks>] |
|
53 | - * : Only run actions with the specified hook. Omitting this option runs actions with any hook. Define multiple hooks as a comma separated string (without spaces), e.g. `--hooks=hook_one,hook_two,hook_three` |
|
54 | - * |
|
55 | - * [--group=<group>] |
|
56 | - * : Only run actions from the specified group. Omitting this option runs actions from all groups. |
|
57 | - * |
|
58 | - * [--free-memory-on=<count>] |
|
59 | - * : The number of actions to process between freeing memory. 0 disables freeing memory. Default 50. |
|
60 | - * |
|
61 | - * [--pause=<seconds>] |
|
62 | - * : The number of seconds to pause when freeing memory. Default no pause. |
|
63 | - * |
|
64 | - * [--force] |
|
65 | - * : Whether to force execution despite the maximum number of concurrent processes being exceeded. |
|
66 | - * |
|
67 | - * @param array $args Positional arguments. |
|
68 | - * @param array $assoc_args Keyed arguments. |
|
69 | - * @throws \WP_CLI\ExitException When an error occurs. |
|
70 | - * |
|
71 | - * @subcommand run |
|
72 | - */ |
|
73 | - public function run( $args, $assoc_args ) { |
|
74 | - // Handle passed arguments. |
|
75 | - $batch = absint( \WP_CLI\Utils\get_flag_value( $assoc_args, 'batch-size', 100 ) ); |
|
76 | - $batches = absint( \WP_CLI\Utils\get_flag_value( $assoc_args, 'batches', 0 ) ); |
|
77 | - $clean = absint( \WP_CLI\Utils\get_flag_value( $assoc_args, 'cleanup-batch-size', $batch ) ); |
|
78 | - $hooks = explode( ',', WP_CLI\Utils\get_flag_value( $assoc_args, 'hooks', '' ) ); |
|
79 | - $hooks = array_filter( array_map( 'trim', $hooks ) ); |
|
80 | - $group = \WP_CLI\Utils\get_flag_value( $assoc_args, 'group', '' ); |
|
81 | - $free_on = \WP_CLI\Utils\get_flag_value( $assoc_args, 'free-memory-on', 50 ); |
|
82 | - $sleep = \WP_CLI\Utils\get_flag_value( $assoc_args, 'pause', 0 ); |
|
83 | - $force = \WP_CLI\Utils\get_flag_value( $assoc_args, 'force', false ); |
|
84 | - |
|
85 | - ActionScheduler_DataController::set_free_ticks( $free_on ); |
|
86 | - ActionScheduler_DataController::set_sleep_time( $sleep ); |
|
87 | - |
|
88 | - $batches_completed = 0; |
|
89 | - $actions_completed = 0; |
|
90 | - $unlimited = $batches === 0; |
|
91 | - |
|
92 | - try { |
|
93 | - // Custom queue cleaner instance. |
|
94 | - $cleaner = new ActionScheduler_QueueCleaner( null, $clean ); |
|
95 | - |
|
96 | - // Get the queue runner instance |
|
97 | - $runner = new ActionScheduler_WPCLI_QueueRunner( null, null, $cleaner ); |
|
98 | - |
|
99 | - // Determine how many tasks will be run in the first batch. |
|
100 | - $total = $runner->setup( $batch, $hooks, $group, $force ); |
|
101 | - |
|
102 | - // Run actions for as long as possible. |
|
103 | - while ( $total > 0 ) { |
|
104 | - $this->print_total_actions( $total ); |
|
105 | - $actions_completed += $runner->run(); |
|
106 | - $batches_completed++; |
|
107 | - |
|
108 | - // Maybe set up tasks for the next batch. |
|
109 | - $total = ( $unlimited || $batches_completed < $batches ) ? $runner->setup( $batch, $hooks, $group, $force ) : 0; |
|
110 | - } |
|
111 | - } catch ( Exception $e ) { |
|
112 | - $this->print_error( $e ); |
|
113 | - } |
|
114 | - |
|
115 | - $this->print_total_batches( $batches_completed ); |
|
116 | - $this->print_success( $actions_completed ); |
|
117 | - } |
|
118 | - |
|
119 | - /** |
|
120 | - * Print WP CLI message about how many actions are about to be processed. |
|
121 | - * |
|
122 | - * @author Jeremy Pry |
|
123 | - * |
|
124 | - * @param int $total |
|
125 | - */ |
|
126 | - protected function print_total_actions( $total ) { |
|
127 | - WP_CLI::log( |
|
128 | - sprintf( |
|
129 | - /* translators: %d refers to how many scheduled taks were found to run */ |
|
130 | - _n( 'Found %d scheduled task', 'Found %d scheduled tasks', $total, 'action-scheduler' ), |
|
131 | - number_format_i18n( $total ) |
|
132 | - ) |
|
133 | - ); |
|
134 | - } |
|
135 | - |
|
136 | - /** |
|
137 | - * Print WP CLI message about how many batches of actions were processed. |
|
138 | - * |
|
139 | - * @author Jeremy Pry |
|
140 | - * |
|
141 | - * @param int $batches_completed |
|
142 | - */ |
|
143 | - protected function print_total_batches( $batches_completed ) { |
|
144 | - WP_CLI::log( |
|
145 | - sprintf( |
|
146 | - /* translators: %d refers to the total number of batches executed */ |
|
147 | - _n( '%d batch executed.', '%d batches executed.', $batches_completed, 'action-scheduler' ), |
|
148 | - number_format_i18n( $batches_completed ) |
|
149 | - ) |
|
150 | - ); |
|
151 | - } |
|
152 | - |
|
153 | - /** |
|
154 | - * Convert an exception into a WP CLI error. |
|
155 | - * |
|
156 | - * @author Jeremy Pry |
|
157 | - * |
|
158 | - * @param Exception $e The error object. |
|
159 | - * |
|
160 | - * @throws \WP_CLI\ExitException |
|
161 | - */ |
|
162 | - protected function print_error( Exception $e ) { |
|
163 | - WP_CLI::error( |
|
164 | - sprintf( |
|
165 | - /* translators: %s refers to the exception error message */ |
|
166 | - __( 'There was an error running the action scheduler: %s', 'action-scheduler' ), |
|
167 | - $e->getMessage() |
|
168 | - ) |
|
169 | - ); |
|
170 | - } |
|
171 | - |
|
172 | - /** |
|
173 | - * Print a success message with the number of completed actions. |
|
174 | - * |
|
175 | - * @author Jeremy Pry |
|
176 | - * |
|
177 | - * @param int $actions_completed |
|
178 | - */ |
|
179 | - protected function print_success( $actions_completed ) { |
|
180 | - WP_CLI::success( |
|
181 | - sprintf( |
|
182 | - /* translators: %d refers to the total number of taskes completed */ |
|
183 | - _n( '%d scheduled task completed.', '%d scheduled tasks completed.', $actions_completed, 'action-scheduler' ), |
|
184 | - number_format_i18n( $actions_completed ) |
|
185 | - ) |
|
186 | - ); |
|
187 | - } |
|
8 | + /** |
|
9 | + * Force tables schema creation for Action Scheduler |
|
10 | + * |
|
11 | + * ## OPTIONS |
|
12 | + * |
|
13 | + * @param array $args Positional arguments. |
|
14 | + * @param array $assoc_args Keyed arguments. |
|
15 | + * |
|
16 | + * @subcommand fix-schema |
|
17 | + */ |
|
18 | + public function fix_schema( $args, $assoc_args ) { |
|
19 | + $schema_classes = array( ActionScheduler_LoggerSchema::class, ActionScheduler_StoreSchema::class ); |
|
20 | + |
|
21 | + foreach ( $schema_classes as $classname ) { |
|
22 | + if ( is_subclass_of( $classname, ActionScheduler_Abstract_Schema::class ) ) { |
|
23 | + $obj = new $classname(); |
|
24 | + $obj->init(); |
|
25 | + $obj->register_tables( true ); |
|
26 | + |
|
27 | + WP_CLI::success( |
|
28 | + sprintf( |
|
29 | + /* translators: %s refers to the schema name*/ |
|
30 | + __( 'Registered schema for %s', 'action-scheduler' ), |
|
31 | + $classname |
|
32 | + ) |
|
33 | + ); |
|
34 | + } |
|
35 | + } |
|
36 | + } |
|
37 | + |
|
38 | + /** |
|
39 | + * Run the Action Scheduler |
|
40 | + * |
|
41 | + * ## OPTIONS |
|
42 | + * |
|
43 | + * [--batch-size=<size>] |
|
44 | + * : The maximum number of actions to run. Defaults to 100. |
|
45 | + * |
|
46 | + * [--batches=<size>] |
|
47 | + * : Limit execution to a number of batches. Defaults to 0, meaning batches will continue being executed until all actions are complete. |
|
48 | + * |
|
49 | + * [--cleanup-batch-size=<size>] |
|
50 | + * : The maximum number of actions to clean up. Defaults to the value of --batch-size. |
|
51 | + * |
|
52 | + * [--hooks=<hooks>] |
|
53 | + * : Only run actions with the specified hook. Omitting this option runs actions with any hook. Define multiple hooks as a comma separated string (without spaces), e.g. `--hooks=hook_one,hook_two,hook_three` |
|
54 | + * |
|
55 | + * [--group=<group>] |
|
56 | + * : Only run actions from the specified group. Omitting this option runs actions from all groups. |
|
57 | + * |
|
58 | + * [--free-memory-on=<count>] |
|
59 | + * : The number of actions to process between freeing memory. 0 disables freeing memory. Default 50. |
|
60 | + * |
|
61 | + * [--pause=<seconds>] |
|
62 | + * : The number of seconds to pause when freeing memory. Default no pause. |
|
63 | + * |
|
64 | + * [--force] |
|
65 | + * : Whether to force execution despite the maximum number of concurrent processes being exceeded. |
|
66 | + * |
|
67 | + * @param array $args Positional arguments. |
|
68 | + * @param array $assoc_args Keyed arguments. |
|
69 | + * @throws \WP_CLI\ExitException When an error occurs. |
|
70 | + * |
|
71 | + * @subcommand run |
|
72 | + */ |
|
73 | + public function run( $args, $assoc_args ) { |
|
74 | + // Handle passed arguments. |
|
75 | + $batch = absint( \WP_CLI\Utils\get_flag_value( $assoc_args, 'batch-size', 100 ) ); |
|
76 | + $batches = absint( \WP_CLI\Utils\get_flag_value( $assoc_args, 'batches', 0 ) ); |
|
77 | + $clean = absint( \WP_CLI\Utils\get_flag_value( $assoc_args, 'cleanup-batch-size', $batch ) ); |
|
78 | + $hooks = explode( ',', WP_CLI\Utils\get_flag_value( $assoc_args, 'hooks', '' ) ); |
|
79 | + $hooks = array_filter( array_map( 'trim', $hooks ) ); |
|
80 | + $group = \WP_CLI\Utils\get_flag_value( $assoc_args, 'group', '' ); |
|
81 | + $free_on = \WP_CLI\Utils\get_flag_value( $assoc_args, 'free-memory-on', 50 ); |
|
82 | + $sleep = \WP_CLI\Utils\get_flag_value( $assoc_args, 'pause', 0 ); |
|
83 | + $force = \WP_CLI\Utils\get_flag_value( $assoc_args, 'force', false ); |
|
84 | + |
|
85 | + ActionScheduler_DataController::set_free_ticks( $free_on ); |
|
86 | + ActionScheduler_DataController::set_sleep_time( $sleep ); |
|
87 | + |
|
88 | + $batches_completed = 0; |
|
89 | + $actions_completed = 0; |
|
90 | + $unlimited = $batches === 0; |
|
91 | + |
|
92 | + try { |
|
93 | + // Custom queue cleaner instance. |
|
94 | + $cleaner = new ActionScheduler_QueueCleaner( null, $clean ); |
|
95 | + |
|
96 | + // Get the queue runner instance |
|
97 | + $runner = new ActionScheduler_WPCLI_QueueRunner( null, null, $cleaner ); |
|
98 | + |
|
99 | + // Determine how many tasks will be run in the first batch. |
|
100 | + $total = $runner->setup( $batch, $hooks, $group, $force ); |
|
101 | + |
|
102 | + // Run actions for as long as possible. |
|
103 | + while ( $total > 0 ) { |
|
104 | + $this->print_total_actions( $total ); |
|
105 | + $actions_completed += $runner->run(); |
|
106 | + $batches_completed++; |
|
107 | + |
|
108 | + // Maybe set up tasks for the next batch. |
|
109 | + $total = ( $unlimited || $batches_completed < $batches ) ? $runner->setup( $batch, $hooks, $group, $force ) : 0; |
|
110 | + } |
|
111 | + } catch ( Exception $e ) { |
|
112 | + $this->print_error( $e ); |
|
113 | + } |
|
114 | + |
|
115 | + $this->print_total_batches( $batches_completed ); |
|
116 | + $this->print_success( $actions_completed ); |
|
117 | + } |
|
118 | + |
|
119 | + /** |
|
120 | + * Print WP CLI message about how many actions are about to be processed. |
|
121 | + * |
|
122 | + * @author Jeremy Pry |
|
123 | + * |
|
124 | + * @param int $total |
|
125 | + */ |
|
126 | + protected function print_total_actions( $total ) { |
|
127 | + WP_CLI::log( |
|
128 | + sprintf( |
|
129 | + /* translators: %d refers to how many scheduled taks were found to run */ |
|
130 | + _n( 'Found %d scheduled task', 'Found %d scheduled tasks', $total, 'action-scheduler' ), |
|
131 | + number_format_i18n( $total ) |
|
132 | + ) |
|
133 | + ); |
|
134 | + } |
|
135 | + |
|
136 | + /** |
|
137 | + * Print WP CLI message about how many batches of actions were processed. |
|
138 | + * |
|
139 | + * @author Jeremy Pry |
|
140 | + * |
|
141 | + * @param int $batches_completed |
|
142 | + */ |
|
143 | + protected function print_total_batches( $batches_completed ) { |
|
144 | + WP_CLI::log( |
|
145 | + sprintf( |
|
146 | + /* translators: %d refers to the total number of batches executed */ |
|
147 | + _n( '%d batch executed.', '%d batches executed.', $batches_completed, 'action-scheduler' ), |
|
148 | + number_format_i18n( $batches_completed ) |
|
149 | + ) |
|
150 | + ); |
|
151 | + } |
|
152 | + |
|
153 | + /** |
|
154 | + * Convert an exception into a WP CLI error. |
|
155 | + * |
|
156 | + * @author Jeremy Pry |
|
157 | + * |
|
158 | + * @param Exception $e The error object. |
|
159 | + * |
|
160 | + * @throws \WP_CLI\ExitException |
|
161 | + */ |
|
162 | + protected function print_error( Exception $e ) { |
|
163 | + WP_CLI::error( |
|
164 | + sprintf( |
|
165 | + /* translators: %s refers to the exception error message */ |
|
166 | + __( 'There was an error running the action scheduler: %s', 'action-scheduler' ), |
|
167 | + $e->getMessage() |
|
168 | + ) |
|
169 | + ); |
|
170 | + } |
|
171 | + |
|
172 | + /** |
|
173 | + * Print a success message with the number of completed actions. |
|
174 | + * |
|
175 | + * @author Jeremy Pry |
|
176 | + * |
|
177 | + * @param int $actions_completed |
|
178 | + */ |
|
179 | + protected function print_success( $actions_completed ) { |
|
180 | + WP_CLI::success( |
|
181 | + sprintf( |
|
182 | + /* translators: %d refers to the total number of taskes completed */ |
|
183 | + _n( '%d scheduled task completed.', '%d scheduled tasks completed.', $actions_completed, 'action-scheduler' ), |
|
184 | + number_format_i18n( $actions_completed ) |
|
185 | + ) |
|
186 | + ); |
|
187 | + } |
|
188 | 188 | } |
@@ -15,19 +15,19 @@ discard block |
||
15 | 15 | * |
16 | 16 | * @subcommand fix-schema |
17 | 17 | */ |
18 | - public function fix_schema( $args, $assoc_args ) { |
|
19 | - $schema_classes = array( ActionScheduler_LoggerSchema::class, ActionScheduler_StoreSchema::class ); |
|
18 | + public function fix_schema($args, $assoc_args) { |
|
19 | + $schema_classes = array(ActionScheduler_LoggerSchema::class, ActionScheduler_StoreSchema::class); |
|
20 | 20 | |
21 | - foreach ( $schema_classes as $classname ) { |
|
22 | - if ( is_subclass_of( $classname, ActionScheduler_Abstract_Schema::class ) ) { |
|
21 | + foreach ($schema_classes as $classname) { |
|
22 | + if (is_subclass_of($classname, ActionScheduler_Abstract_Schema::class)) { |
|
23 | 23 | $obj = new $classname(); |
24 | 24 | $obj->init(); |
25 | - $obj->register_tables( true ); |
|
25 | + $obj->register_tables(true); |
|
26 | 26 | |
27 | 27 | WP_CLI::success( |
28 | 28 | sprintf( |
29 | 29 | /* translators: %s refers to the schema name*/ |
30 | - __( 'Registered schema for %s', 'action-scheduler' ), |
|
30 | + __('Registered schema for %s', 'action-scheduler'), |
|
31 | 31 | $classname |
32 | 32 | ) |
33 | 33 | ); |
@@ -70,20 +70,20 @@ discard block |
||
70 | 70 | * |
71 | 71 | * @subcommand run |
72 | 72 | */ |
73 | - public function run( $args, $assoc_args ) { |
|
73 | + public function run($args, $assoc_args) { |
|
74 | 74 | // Handle passed arguments. |
75 | - $batch = absint( \WP_CLI\Utils\get_flag_value( $assoc_args, 'batch-size', 100 ) ); |
|
76 | - $batches = absint( \WP_CLI\Utils\get_flag_value( $assoc_args, 'batches', 0 ) ); |
|
77 | - $clean = absint( \WP_CLI\Utils\get_flag_value( $assoc_args, 'cleanup-batch-size', $batch ) ); |
|
78 | - $hooks = explode( ',', WP_CLI\Utils\get_flag_value( $assoc_args, 'hooks', '' ) ); |
|
79 | - $hooks = array_filter( array_map( 'trim', $hooks ) ); |
|
80 | - $group = \WP_CLI\Utils\get_flag_value( $assoc_args, 'group', '' ); |
|
81 | - $free_on = \WP_CLI\Utils\get_flag_value( $assoc_args, 'free-memory-on', 50 ); |
|
82 | - $sleep = \WP_CLI\Utils\get_flag_value( $assoc_args, 'pause', 0 ); |
|
83 | - $force = \WP_CLI\Utils\get_flag_value( $assoc_args, 'force', false ); |
|
84 | - |
|
85 | - ActionScheduler_DataController::set_free_ticks( $free_on ); |
|
86 | - ActionScheduler_DataController::set_sleep_time( $sleep ); |
|
75 | + $batch = absint(\WP_CLI\Utils\get_flag_value($assoc_args, 'batch-size', 100)); |
|
76 | + $batches = absint(\WP_CLI\Utils\get_flag_value($assoc_args, 'batches', 0)); |
|
77 | + $clean = absint(\WP_CLI\Utils\get_flag_value($assoc_args, 'cleanup-batch-size', $batch)); |
|
78 | + $hooks = explode(',', WP_CLI\Utils\get_flag_value($assoc_args, 'hooks', '')); |
|
79 | + $hooks = array_filter(array_map('trim', $hooks)); |
|
80 | + $group = \WP_CLI\Utils\get_flag_value($assoc_args, 'group', ''); |
|
81 | + $free_on = \WP_CLI\Utils\get_flag_value($assoc_args, 'free-memory-on', 50); |
|
82 | + $sleep = \WP_CLI\Utils\get_flag_value($assoc_args, 'pause', 0); |
|
83 | + $force = \WP_CLI\Utils\get_flag_value($assoc_args, 'force', false); |
|
84 | + |
|
85 | + ActionScheduler_DataController::set_free_ticks($free_on); |
|
86 | + ActionScheduler_DataController::set_sleep_time($sleep); |
|
87 | 87 | |
88 | 88 | $batches_completed = 0; |
89 | 89 | $actions_completed = 0; |
@@ -91,29 +91,29 @@ discard block |
||
91 | 91 | |
92 | 92 | try { |
93 | 93 | // Custom queue cleaner instance. |
94 | - $cleaner = new ActionScheduler_QueueCleaner( null, $clean ); |
|
94 | + $cleaner = new ActionScheduler_QueueCleaner(null, $clean); |
|
95 | 95 | |
96 | 96 | // Get the queue runner instance |
97 | - $runner = new ActionScheduler_WPCLI_QueueRunner( null, null, $cleaner ); |
|
97 | + $runner = new ActionScheduler_WPCLI_QueueRunner(null, null, $cleaner); |
|
98 | 98 | |
99 | 99 | // Determine how many tasks will be run in the first batch. |
100 | - $total = $runner->setup( $batch, $hooks, $group, $force ); |
|
100 | + $total = $runner->setup($batch, $hooks, $group, $force); |
|
101 | 101 | |
102 | 102 | // Run actions for as long as possible. |
103 | - while ( $total > 0 ) { |
|
104 | - $this->print_total_actions( $total ); |
|
103 | + while ($total > 0) { |
|
104 | + $this->print_total_actions($total); |
|
105 | 105 | $actions_completed += $runner->run(); |
106 | 106 | $batches_completed++; |
107 | 107 | |
108 | 108 | // Maybe set up tasks for the next batch. |
109 | - $total = ( $unlimited || $batches_completed < $batches ) ? $runner->setup( $batch, $hooks, $group, $force ) : 0; |
|
109 | + $total = ($unlimited || $batches_completed < $batches) ? $runner->setup($batch, $hooks, $group, $force) : 0; |
|
110 | 110 | } |
111 | - } catch ( Exception $e ) { |
|
112 | - $this->print_error( $e ); |
|
111 | + } catch (Exception $e) { |
|
112 | + $this->print_error($e); |
|
113 | 113 | } |
114 | 114 | |
115 | - $this->print_total_batches( $batches_completed ); |
|
116 | - $this->print_success( $actions_completed ); |
|
115 | + $this->print_total_batches($batches_completed); |
|
116 | + $this->print_success($actions_completed); |
|
117 | 117 | } |
118 | 118 | |
119 | 119 | /** |
@@ -123,12 +123,12 @@ discard block |
||
123 | 123 | * |
124 | 124 | * @param int $total |
125 | 125 | */ |
126 | - protected function print_total_actions( $total ) { |
|
126 | + protected function print_total_actions($total) { |
|
127 | 127 | WP_CLI::log( |
128 | 128 | sprintf( |
129 | 129 | /* translators: %d refers to how many scheduled taks were found to run */ |
130 | - _n( 'Found %d scheduled task', 'Found %d scheduled tasks', $total, 'action-scheduler' ), |
|
131 | - number_format_i18n( $total ) |
|
130 | + _n('Found %d scheduled task', 'Found %d scheduled tasks', $total, 'action-scheduler'), |
|
131 | + number_format_i18n($total) |
|
132 | 132 | ) |
133 | 133 | ); |
134 | 134 | } |
@@ -140,12 +140,12 @@ discard block |
||
140 | 140 | * |
141 | 141 | * @param int $batches_completed |
142 | 142 | */ |
143 | - protected function print_total_batches( $batches_completed ) { |
|
143 | + protected function print_total_batches($batches_completed) { |
|
144 | 144 | WP_CLI::log( |
145 | 145 | sprintf( |
146 | 146 | /* translators: %d refers to the total number of batches executed */ |
147 | - _n( '%d batch executed.', '%d batches executed.', $batches_completed, 'action-scheduler' ), |
|
148 | - number_format_i18n( $batches_completed ) |
|
147 | + _n('%d batch executed.', '%d batches executed.', $batches_completed, 'action-scheduler'), |
|
148 | + number_format_i18n($batches_completed) |
|
149 | 149 | ) |
150 | 150 | ); |
151 | 151 | } |
@@ -159,11 +159,11 @@ discard block |
||
159 | 159 | * |
160 | 160 | * @throws \WP_CLI\ExitException |
161 | 161 | */ |
162 | - protected function print_error( Exception $e ) { |
|
162 | + protected function print_error(Exception $e) { |
|
163 | 163 | WP_CLI::error( |
164 | 164 | sprintf( |
165 | 165 | /* translators: %s refers to the exception error message */ |
166 | - __( 'There was an error running the action scheduler: %s', 'action-scheduler' ), |
|
166 | + __('There was an error running the action scheduler: %s', 'action-scheduler'), |
|
167 | 167 | $e->getMessage() |
168 | 168 | ) |
169 | 169 | ); |
@@ -176,12 +176,12 @@ discard block |
||
176 | 176 | * |
177 | 177 | * @param int $actions_completed |
178 | 178 | */ |
179 | - protected function print_success( $actions_completed ) { |
|
179 | + protected function print_success($actions_completed) { |
|
180 | 180 | WP_CLI::success( |
181 | 181 | sprintf( |
182 | 182 | /* translators: %d refers to the total number of taskes completed */ |
183 | - _n( '%d scheduled task completed.', '%d scheduled tasks completed.', $actions_completed, 'action-scheduler' ), |
|
184 | - number_format_i18n( $actions_completed ) |
|
183 | + _n('%d scheduled task completed.', '%d scheduled tasks completed.', $actions_completed, 'action-scheduler'), |
|
184 | + number_format_i18n($actions_completed) |
|
185 | 185 | ) |
186 | 186 | ); |
187 | 187 | } |