Passed
Pull Request — master (#280)
by Brian
05:07
created
libraries/action-scheduler/classes/ActionScheduler_wcSystemStatus.php 2 patches
Indentation   +120 added lines, -120 removed lines patch added patch discarded remove patch
@@ -5,95 +5,95 @@  discard block
 block discarded – undo
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
-	function __construct( $store ) {
16
-		$this->store = $store;
17
-	}
18
-
19
-	/**
20
-	 * Display action data, including number of actions grouped by status and the oldest & newest action in each status.
21
-	 *
22
-	 * Helpful to identify issues, like a clogged queue.
23
-	 */
24
-	public function render() {
25
-		$action_counts     = $this->store->action_counts();
26
-		$status_labels     = $this->store->get_status_labels();
27
-		$oldest_and_newest = $this->get_oldest_and_newest( array_keys( $status_labels ) );
28
-
29
-		$this->get_template( $status_labels, $action_counts, $oldest_and_newest );
30
-	}
31
-
32
-	/**
33
-	 * Get oldest and newest scheduled dates for a given set of statuses.
34
-	 *
35
-	 * @param array $status_keys Set of statuses to find oldest & newest action for.
36
-	 * @return array
37
-	 */
38
-	protected function get_oldest_and_newest( $status_keys ) {
39
-
40
-		$oldest_and_newest = array();
41
-
42
-		foreach ( $status_keys as $status ) {
43
-			$oldest_and_newest[ $status ] = array(
44
-				'oldest' => '–',
45
-				'newest' => '–',
46
-			);
47
-
48
-			if ( 'in-progress' === $status ) {
49
-				continue;
50
-			}
51
-
52
-			$oldest_and_newest[ $status ]['oldest'] = $this->get_action_status_date( $status, 'oldest' );
53
-			$oldest_and_newest[ $status ]['newest'] = $this->get_action_status_date( $status, 'newest' );
54
-		}
55
-
56
-		return $oldest_and_newest;
57
-	}
58
-
59
-	/**
60
-	 * Get oldest or newest scheduled date for a given status.
61
-	 *
62
-	 * @param string $status Action status label/name string.
63
-	 * @param string $date_type Oldest or Newest.
64
-	 * @return DateTime
65
-	 */
66
-	protected function get_action_status_date( $status, $date_type = 'oldest' ) {
67
-
68
-		$order = 'oldest' === $date_type ? 'ASC' : 'DESC';
69
-
70
-		$action = $this->store->query_actions( array(
71
-			'claimed'  => false,
72
-			'status'   => $status,
73
-			'per_page' => 1,
74
-			'order'    => $order,
75
-		) );
76
-
77
-		if ( ! empty( $action ) ) {
78
-			$date_object = $this->store->get_date( $action[0] );
79
-			$action_date = $date_object->format( 'Y-m-d H:i:s O' );
80
-		} else {
81
-			$action_date = '–';
82
-		}
83
-
84
-		return $action_date;
85
-	}
86
-
87
-	/**
88
-	 * Get oldest or newest scheduled date for a given status.
89
-	 *
90
-	 * @param array $status_labels Set of statuses to find oldest & newest action for.
91
-	 * @param array $action_counts Number of actions grouped by status.
92
-	 * @param array $oldest_and_newest Date of the oldest and newest action with each status.
93
-	 */
94
-	protected function get_template( $status_labels, $action_counts, $oldest_and_newest ) {
95
-		$as_version = ActionScheduler_Versions::instance()->latest_version();
96
-		?>
8
+    /**
9
+     * The active data stores
10
+     *
11
+     * @var ActionScheduler_Store
12
+     */
13
+    protected $store;
14
+
15
+    function __construct( $store ) {
16
+        $this->store = $store;
17
+    }
18
+
19
+    /**
20
+     * Display action data, including number of actions grouped by status and the oldest & newest action in each status.
21
+     *
22
+     * Helpful to identify issues, like a clogged queue.
23
+     */
24
+    public function render() {
25
+        $action_counts     = $this->store->action_counts();
26
+        $status_labels     = $this->store->get_status_labels();
27
+        $oldest_and_newest = $this->get_oldest_and_newest( array_keys( $status_labels ) );
28
+
29
+        $this->get_template( $status_labels, $action_counts, $oldest_and_newest );
30
+    }
31
+
32
+    /**
33
+     * Get oldest and newest scheduled dates for a given set of statuses.
34
+     *
35
+     * @param array $status_keys Set of statuses to find oldest & newest action for.
36
+     * @return array
37
+     */
38
+    protected function get_oldest_and_newest( $status_keys ) {
39
+
40
+        $oldest_and_newest = array();
41
+
42
+        foreach ( $status_keys as $status ) {
43
+            $oldest_and_newest[ $status ] = array(
44
+                'oldest' => '–',
45
+                'newest' => '–',
46
+            );
47
+
48
+            if ( 'in-progress' === $status ) {
49
+                continue;
50
+            }
51
+
52
+            $oldest_and_newest[ $status ]['oldest'] = $this->get_action_status_date( $status, 'oldest' );
53
+            $oldest_and_newest[ $status ]['newest'] = $this->get_action_status_date( $status, 'newest' );
54
+        }
55
+
56
+        return $oldest_and_newest;
57
+    }
58
+
59
+    /**
60
+     * Get oldest or newest scheduled date for a given status.
61
+     *
62
+     * @param string $status Action status label/name string.
63
+     * @param string $date_type Oldest or Newest.
64
+     * @return DateTime
65
+     */
66
+    protected function get_action_status_date( $status, $date_type = 'oldest' ) {
67
+
68
+        $order = 'oldest' === $date_type ? 'ASC' : 'DESC';
69
+
70
+        $action = $this->store->query_actions( array(
71
+            'claimed'  => false,
72
+            'status'   => $status,
73
+            'per_page' => 1,
74
+            'order'    => $order,
75
+        ) );
76
+
77
+        if ( ! empty( $action ) ) {
78
+            $date_object = $this->store->get_date( $action[0] );
79
+            $action_date = $date_object->format( 'Y-m-d H:i:s O' );
80
+        } else {
81
+            $action_date = '–';
82
+        }
83
+
84
+        return $action_date;
85
+    }
86
+
87
+    /**
88
+     * Get oldest or newest scheduled date for a given status.
89
+     *
90
+     * @param array $status_labels Set of statuses to find oldest & newest action for.
91
+     * @param array $action_counts Number of actions grouped by status.
92
+     * @param array $oldest_and_newest Date of the oldest and newest action with each status.
93
+     */
94
+    protected function get_template( $status_labels, $action_counts, $oldest_and_newest ) {
95
+        $as_version = ActionScheduler_Versions::instance()->latest_version();
96
+        ?>
97 97
 
98 98
 		<table class="wc_status_table widefat" cellspacing="0">
99 99
 			<thead>
@@ -114,39 +114,39 @@  discard block
 block discarded – undo
114 114
 			</thead>
115 115
 			<tbody>
116 116
 				<?php
117
-				foreach ( $action_counts as $status => $count ) {
118
-					// 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.
119
-					printf(
120
-						'<tr><td>%1$s</td><td>&nbsp;</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>',
121
-						esc_html( $status_labels[ $status ] ),
122
-						number_format_i18n( $count ),
123
-						$oldest_and_newest[ $status ]['oldest'],
124
-						$oldest_and_newest[ $status ]['newest']
125
-					);
126
-				}
127
-				?>
117
+                foreach ( $action_counts as $status => $count ) {
118
+                    // 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.
119
+                    printf(
120
+                        '<tr><td>%1$s</td><td>&nbsp;</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>',
121
+                        esc_html( $status_labels[ $status ] ),
122
+                        number_format_i18n( $count ),
123
+                        $oldest_and_newest[ $status ]['oldest'],
124
+                        $oldest_and_newest[ $status ]['newest']
125
+                    );
126
+                }
127
+                ?>
128 128
 			</tbody>
129 129
 		</table>
130 130
 
131 131
 		<?php
132
-	}
133
-
134
-	/**
135
-	 * is triggered when invoking inaccessible methods in an object context.
136
-	 *
137
-	 * @param string $name
138
-	 * @param array  $arguments
139
-	 *
140
-	 * @return mixed
141
-	 * @link https://php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.methods
142
-	 */
143
-	public function __call( $name, $arguments ) {
144
-		switch ( $name ) {
145
-			case 'print':
146
-				_deprecated_function( __CLASS__ . '::print()', '2.2.4', __CLASS__ . '::render()' );
147
-				return call_user_func_array( array( $this, 'render' ), $arguments );
148
-		}
149
-
150
-		return null;
151
-	}
132
+    }
133
+
134
+    /**
135
+     * is triggered when invoking inaccessible methods in an object context.
136
+     *
137
+     * @param string $name
138
+     * @param array  $arguments
139
+     *
140
+     * @return mixed
141
+     * @link https://php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.methods
142
+     */
143
+    public function __call( $name, $arguments ) {
144
+        switch ( $name ) {
145
+            case 'print':
146
+                _deprecated_function( __CLASS__ . '::print()', '2.2.4', __CLASS__ . '::render()' );
147
+                return call_user_func_array( array( $this, 'render' ), $arguments );
148
+        }
149
+
150
+        return null;
151
+    }
152 152
 }
Please login to merge, or discard this patch.
Spacing   +32 added lines, -32 removed lines patch added patch discarded remove patch
@@ -12,7 +12,7 @@  discard block
 block discarded – undo
12 12
 	 */
13 13
 	protected $store;
14 14
 
15
-	function __construct( $store ) {
15
+	function __construct($store) {
16 16
 		$this->store = $store;
17 17
 	}
18 18
 
@@ -24,9 +24,9 @@  discard block
 block discarded – undo
24 24
 	public function render() {
25 25
 		$action_counts     = $this->store->action_counts();
26 26
 		$status_labels     = $this->store->get_status_labels();
27
-		$oldest_and_newest = $this->get_oldest_and_newest( array_keys( $status_labels ) );
27
+		$oldest_and_newest = $this->get_oldest_and_newest(array_keys($status_labels));
28 28
 
29
-		$this->get_template( $status_labels, $action_counts, $oldest_and_newest );
29
+		$this->get_template($status_labels, $action_counts, $oldest_and_newest);
30 30
 	}
31 31
 
32 32
 	/**
@@ -35,22 +35,22 @@  discard block
 block discarded – undo
35 35
 	 * @param array $status_keys Set of statuses to find oldest & newest action for.
36 36
 	 * @return array
37 37
 	 */
38
-	protected function get_oldest_and_newest( $status_keys ) {
38
+	protected function get_oldest_and_newest($status_keys) {
39 39
 
40 40
 		$oldest_and_newest = array();
41 41
 
42
-		foreach ( $status_keys as $status ) {
43
-			$oldest_and_newest[ $status ] = array(
42
+		foreach ($status_keys as $status) {
43
+			$oldest_and_newest[$status] = array(
44 44
 				'oldest' => '&ndash;',
45 45
 				'newest' => '&ndash;',
46 46
 			);
47 47
 
48
-			if ( 'in-progress' === $status ) {
48
+			if ('in-progress' === $status) {
49 49
 				continue;
50 50
 			}
51 51
 
52
-			$oldest_and_newest[ $status ]['oldest'] = $this->get_action_status_date( $status, 'oldest' );
53
-			$oldest_and_newest[ $status ]['newest'] = $this->get_action_status_date( $status, 'newest' );
52
+			$oldest_and_newest[$status]['oldest'] = $this->get_action_status_date($status, 'oldest');
53
+			$oldest_and_newest[$status]['newest'] = $this->get_action_status_date($status, 'newest');
54 54
 		}
55 55
 
56 56
 		return $oldest_and_newest;
@@ -63,20 +63,20 @@  discard block
 block discarded – undo
63 63
 	 * @param string $date_type Oldest or Newest.
64 64
 	 * @return DateTime
65 65
 	 */
66
-	protected function get_action_status_date( $status, $date_type = 'oldest' ) {
66
+	protected function get_action_status_date($status, $date_type = 'oldest') {
67 67
 
68 68
 		$order = 'oldest' === $date_type ? 'ASC' : 'DESC';
69 69
 
70
-		$action = $this->store->query_actions( array(
70
+		$action = $this->store->query_actions(array(
71 71
 			'claimed'  => false,
72 72
 			'status'   => $status,
73 73
 			'per_page' => 1,
74 74
 			'order'    => $order,
75
-		) );
75
+		));
76 76
 
77
-		if ( ! empty( $action ) ) {
78
-			$date_object = $this->store->get_date( $action[0] );
79
-			$action_date = $date_object->format( 'Y-m-d H:i:s O' );
77
+		if (!empty($action)) {
78
+			$date_object = $this->store->get_date($action[0]);
79
+			$action_date = $date_object->format('Y-m-d H:i:s O');
80 80
 		} else {
81 81
 			$action_date = '&ndash;';
82 82
 		}
@@ -91,37 +91,37 @@  discard block
 block discarded – undo
91 91
 	 * @param array $action_counts Number of actions grouped by status.
92 92
 	 * @param array $oldest_and_newest Date of the oldest and newest action with each status.
93 93
 	 */
94
-	protected function get_template( $status_labels, $action_counts, $oldest_and_newest ) {
94
+	protected function get_template($status_labels, $action_counts, $oldest_and_newest) {
95 95
 		$as_version = ActionScheduler_Versions::instance()->latest_version();
96 96
 		?>
97 97
 
98 98
 		<table class="wc_status_table widefat" cellspacing="0">
99 99
 			<thead>
100 100
 				<tr>
101
-					<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 scheduled action counts.', 'action-scheduler' ) ); ?></h2></th>
101
+					<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 scheduled action counts.', 'action-scheduler')); ?></h2></th>
102 102
 				</tr>
103 103
 				<tr>
104
-					<td colspan="2" data-export-label="Version"><?php esc_html_e( 'Version:', 'action-scheduler' ); ?></td>
105
-					<td colspan="3"><?php echo esc_html( $as_version ); ?></td>
104
+					<td colspan="2" data-export-label="Version"><?php esc_html_e('Version:', 'action-scheduler'); ?></td>
105
+					<td colspan="3"><?php echo esc_html($as_version); ?></td>
106 106
 				</tr>
107 107
 				<tr>
108
-					<td><strong><?php esc_html_e( 'Action Status', 'action-scheduler' ); ?></strong></td>
108
+					<td><strong><?php esc_html_e('Action Status', 'action-scheduler'); ?></strong></td>
109 109
 					<td class="help">&nbsp;</td>
110
-					<td><strong><?php esc_html_e( 'Count', 'action-scheduler' ); ?></strong></td>
111
-					<td><strong><?php esc_html_e( 'Oldest Scheduled Date', 'action-scheduler' ); ?></strong></td>
112
-					<td><strong><?php esc_html_e( 'Newest Scheduled Date', 'action-scheduler' ); ?></strong></td>
110
+					<td><strong><?php esc_html_e('Count', 'action-scheduler'); ?></strong></td>
111
+					<td><strong><?php esc_html_e('Oldest Scheduled Date', 'action-scheduler'); ?></strong></td>
112
+					<td><strong><?php esc_html_e('Newest Scheduled Date', 'action-scheduler'); ?></strong></td>
113 113
 				</tr>
114 114
 			</thead>
115 115
 			<tbody>
116 116
 				<?php
117
-				foreach ( $action_counts as $status => $count ) {
117
+				foreach ($action_counts as $status => $count) {
118 118
 					// 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.
119 119
 					printf(
120 120
 						'<tr><td>%1$s</td><td>&nbsp;</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>',
121
-						esc_html( $status_labels[ $status ] ),
122
-						number_format_i18n( $count ),
123
-						$oldest_and_newest[ $status ]['oldest'],
124
-						$oldest_and_newest[ $status ]['newest']
121
+						esc_html($status_labels[$status]),
122
+						number_format_i18n($count),
123
+						$oldest_and_newest[$status]['oldest'],
124
+						$oldest_and_newest[$status]['newest']
125 125
 					);
126 126
 				}
127 127
 				?>
@@ -140,11 +140,11 @@  discard block
 block discarded – undo
140 140
 	 * @return mixed
141 141
 	 * @link https://php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.methods
142 142
 	 */
143
-	public function __call( $name, $arguments ) {
144
-		switch ( $name ) {
143
+	public function __call($name, $arguments) {
144
+		switch ($name) {
145 145
 			case 'print':
146
-				_deprecated_function( __CLASS__ . '::print()', '2.2.4', __CLASS__ . '::render()' );
147
-				return call_user_func_array( array( $this, 'render' ), $arguments );
146
+				_deprecated_function(__CLASS__ . '::print()', '2.2.4', __CLASS__ . '::render()');
147
+				return call_user_func_array(array($this, 'render'), $arguments);
148 148
 		}
149 149
 
150 150
 		return null;
Please login to merge, or discard this patch.
classes/data-stores/ActionScheduler_wpPostStore_PostStatusRegistrar.php 2 patches
Indentation   +44 added lines, -44 removed lines patch added patch discarded remove patch
@@ -5,54 +5,54 @@
 block discarded – undo
5 5
  * @codeCoverageIgnore
6 6
  */
7 7
 class ActionScheduler_wpPostStore_PostStatusRegistrar {
8
-	public function register() {
9
-		register_post_status( ActionScheduler_Store::STATUS_RUNNING, array_merge( $this->post_status_args(), $this->post_status_running_labels() ) );
10
-		register_post_status( ActionScheduler_Store::STATUS_FAILED, array_merge( $this->post_status_args(), $this->post_status_failed_labels() ) );
11
-	}
8
+    public function register() {
9
+        register_post_status( ActionScheduler_Store::STATUS_RUNNING, array_merge( $this->post_status_args(), $this->post_status_running_labels() ) );
10
+        register_post_status( ActionScheduler_Store::STATUS_FAILED, array_merge( $this->post_status_args(), $this->post_status_failed_labels() ) );
11
+    }
12 12
 
13
-	/**
14
-	 * Build the args array for the post type definition
15
-	 *
16
-	 * @return array
17
-	 */
18
-	protected function post_status_args() {
19
-		$args = array(
20
-			'public'                    => false,
21
-			'exclude_from_search'       => false,
22
-			'show_in_admin_all_list'    => true,
23
-			'show_in_admin_status_list' => true,
24
-		);
13
+    /**
14
+     * Build the args array for the post type definition
15
+     *
16
+     * @return array
17
+     */
18
+    protected function post_status_args() {
19
+        $args = array(
20
+            'public'                    => false,
21
+            'exclude_from_search'       => false,
22
+            'show_in_admin_all_list'    => true,
23
+            'show_in_admin_status_list' => true,
24
+        );
25 25
 
26
-		return apply_filters( 'action_scheduler_post_status_args', $args );
27
-	}
26
+        return apply_filters( 'action_scheduler_post_status_args', $args );
27
+    }
28 28
 
29
-	/**
30
-	 * Build the args array for the post type definition
31
-	 *
32
-	 * @return array
33
-	 */
34
-	protected function post_status_failed_labels() {
35
-		$labels = array(
36
-			'label'       => _x( 'Failed', 'post', 'action-scheduler' ),
37
-			/* translators: %s: count */
38
-			'label_count' => _n_noop( 'Failed <span class="count">(%s)</span>', 'Failed <span class="count">(%s)</span>', 'action-scheduler' ),
39
-		);
29
+    /**
30
+     * Build the args array for the post type definition
31
+     *
32
+     * @return array
33
+     */
34
+    protected function post_status_failed_labels() {
35
+        $labels = array(
36
+            'label'       => _x( 'Failed', 'post', 'action-scheduler' ),
37
+            /* translators: %s: count */
38
+            'label_count' => _n_noop( 'Failed <span class="count">(%s)</span>', 'Failed <span class="count">(%s)</span>', 'action-scheduler' ),
39
+        );
40 40
 
41
-		return apply_filters( 'action_scheduler_post_status_failed_labels', $labels );
42
-	}
41
+        return apply_filters( 'action_scheduler_post_status_failed_labels', $labels );
42
+    }
43 43
 
44
-	/**
45
-	 * Build the args array for the post type definition
46
-	 *
47
-	 * @return array
48
-	 */
49
-	protected function post_status_running_labels() {
50
-		$labels = array(
51
-			'label'       => _x( 'In-Progress', 'post', 'action-scheduler' ),
52
-			/* translators: %s: count */
53
-			'label_count' => _n_noop( 'In-Progress <span class="count">(%s)</span>', 'In-Progress <span class="count">(%s)</span>', 'action-scheduler' ),
54
-		);
44
+    /**
45
+     * Build the args array for the post type definition
46
+     *
47
+     * @return array
48
+     */
49
+    protected function post_status_running_labels() {
50
+        $labels = array(
51
+            'label'       => _x( 'In-Progress', 'post', 'action-scheduler' ),
52
+            /* translators: %s: count */
53
+            'label_count' => _n_noop( 'In-Progress <span class="count">(%s)</span>', 'In-Progress <span class="count">(%s)</span>', 'action-scheduler' ),
54
+        );
55 55
 
56
-		return apply_filters( 'action_scheduler_post_status_running_labels', $labels );
57
-	}
56
+        return apply_filters( 'action_scheduler_post_status_running_labels', $labels );
57
+    }
58 58
 }
Please login to merge, or discard this patch.
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -6,8 +6,8 @@  discard block
 block discarded – undo
6 6
  */
7 7
 class ActionScheduler_wpPostStore_PostStatusRegistrar {
8 8
 	public function register() {
9
-		register_post_status( ActionScheduler_Store::STATUS_RUNNING, array_merge( $this->post_status_args(), $this->post_status_running_labels() ) );
10
-		register_post_status( ActionScheduler_Store::STATUS_FAILED, array_merge( $this->post_status_args(), $this->post_status_failed_labels() ) );
9
+		register_post_status(ActionScheduler_Store::STATUS_RUNNING, array_merge($this->post_status_args(), $this->post_status_running_labels()));
10
+		register_post_status(ActionScheduler_Store::STATUS_FAILED, array_merge($this->post_status_args(), $this->post_status_failed_labels()));
11 11
 	}
12 12
 
13 13
 	/**
@@ -23,7 +23,7 @@  discard block
 block discarded – undo
23 23
 			'show_in_admin_status_list' => true,
24 24
 		);
25 25
 
26
-		return apply_filters( 'action_scheduler_post_status_args', $args );
26
+		return apply_filters('action_scheduler_post_status_args', $args);
27 27
 	}
28 28
 
29 29
 	/**
@@ -33,12 +33,12 @@  discard block
 block discarded – undo
33 33
 	 */
34 34
 	protected function post_status_failed_labels() {
35 35
 		$labels = array(
36
-			'label'       => _x( 'Failed', 'post', 'action-scheduler' ),
36
+			'label'       => _x('Failed', 'post', 'action-scheduler'),
37 37
 			/* translators: %s: count */
38
-			'label_count' => _n_noop( 'Failed <span class="count">(%s)</span>', 'Failed <span class="count">(%s)</span>', 'action-scheduler' ),
38
+			'label_count' => _n_noop('Failed <span class="count">(%s)</span>', 'Failed <span class="count">(%s)</span>', 'action-scheduler'),
39 39
 		);
40 40
 
41
-		return apply_filters( 'action_scheduler_post_status_failed_labels', $labels );
41
+		return apply_filters('action_scheduler_post_status_failed_labels', $labels);
42 42
 	}
43 43
 
44 44
 	/**
@@ -48,11 +48,11 @@  discard block
 block discarded – undo
48 48
 	 */
49 49
 	protected function post_status_running_labels() {
50 50
 		$labels = array(
51
-			'label'       => _x( 'In-Progress', 'post', 'action-scheduler' ),
51
+			'label'       => _x('In-Progress', 'post', 'action-scheduler'),
52 52
 			/* translators: %s: count */
53
-			'label_count' => _n_noop( 'In-Progress <span class="count">(%s)</span>', 'In-Progress <span class="count">(%s)</span>', 'action-scheduler' ),
53
+			'label_count' => _n_noop('In-Progress <span class="count">(%s)</span>', 'In-Progress <span class="count">(%s)</span>', 'action-scheduler'),
54 54
 		);
55 55
 
56
-		return apply_filters( 'action_scheduler_post_status_running_labels', $labels );
56
+		return apply_filters('action_scheduler_post_status_running_labels', $labels);
57 57
 	}
58 58
 }
Please login to merge, or discard this patch.
action-scheduler/classes/data-stores/ActionScheduler_HybridStore.php 2 patches
Indentation   +360 added lines, -360 removed lines patch added patch discarded remove patch
@@ -13,368 +13,368 @@
 block discarded – undo
13 13
  * @since 3.0.0
14 14
  */
15 15
 class ActionScheduler_HybridStore extends Store {
16
-	const DEMARKATION_OPTION = 'action_scheduler_hybrid_store_demarkation';
17
-
18
-	private $primary_store;
19
-	private $secondary_store;
20
-	private $migration_runner;
21
-
22
-	/**
23
-	 * @var int The dividing line between IDs of actions created
24
-	 *          by the primary and secondary stores.
25
-	 *
26
-	 * Methods that accept an action ID will compare the ID against
27
-	 * this to determine which store will contain that ID. In almost
28
-	 * all cases, the ID should come from the primary store, but if
29
-	 * client code is bypassing the API functions and fetching IDs
30
-	 * from elsewhere, then there is a chance that an unmigrated ID
31
-	 * might be requested.
32
-	 */
33
-	private $demarkation_id = 0;
34
-
35
-	/**
36
-	 * ActionScheduler_HybridStore constructor.
37
-	 *
38
-	 * @param Config $config Migration config object.
39
-	 */
40
-	public function __construct( Config $config = null ) {
41
-		$this->demarkation_id = (int) get_option( self::DEMARKATION_OPTION, 0 );
42
-		if ( empty( $config ) ) {
43
-			$config = Controller::instance()->get_migration_config_object();
44
-		}
45
-		$this->primary_store    = $config->get_destination_store();
46
-		$this->secondary_store  = $config->get_source_store();
47
-		$this->migration_runner = new Runner( $config );
48
-	}
49
-
50
-	/**
51
-	 * Initialize the table data store tables.
52
-	 *
53
-	 * @codeCoverageIgnore
54
-	 */
55
-	public function init() {
56
-		add_action( 'action_scheduler/created_table', [ $this, 'set_autoincrement' ], 10, 2 );
57
-		$this->primary_store->init();
58
-		$this->secondary_store->init();
59
-		remove_action( 'action_scheduler/created_table', [ $this, 'set_autoincrement' ], 10 );
60
-	}
61
-
62
-	/**
63
-	 * When the actions table is created, set its autoincrement
64
-	 * value to be one higher than the posts table to ensure that
65
-	 * there are no ID collisions.
66
-	 *
67
-	 * @param string $table_name
68
-	 * @param string $table_suffix
69
-	 *
70
-	 * @return void
71
-	 * @codeCoverageIgnore
72
-	 */
73
-	public function set_autoincrement( $table_name, $table_suffix ) {
74
-		if ( ActionScheduler_StoreSchema::ACTIONS_TABLE === $table_suffix ) {
75
-			if ( empty( $this->demarkation_id ) ) {
76
-				$this->demarkation_id = $this->set_demarkation_id();
77
-			}
78
-			/** @var \wpdb $wpdb */
79
-			global $wpdb;
80
-			$wpdb->insert(
81
-				$wpdb->{ActionScheduler_StoreSchema::ACTIONS_TABLE},
82
-				[
83
-					'action_id' => $this->demarkation_id,
84
-					'hook'      => '',
85
-					'status'    => '',
86
-				]
87
-			);
88
-			$wpdb->delete(
89
-				$wpdb->{ActionScheduler_StoreSchema::ACTIONS_TABLE},
90
-				[ 'action_id' => $this->demarkation_id ]
91
-			);
92
-		}
93
-	}
94
-
95
-	/**
96
-	 * Store the demarkation id in WP options.
97
-	 *
98
-	 * @param int $id The ID to set as the demarkation point between the two stores
99
-	 *                Leave null to use the next ID from the WP posts table.
100
-	 *
101
-	 * @return int The new ID.
102
-	 *
103
-	 * @codeCoverageIgnore
104
-	 */
105
-	private function set_demarkation_id( $id = null ) {
106
-		if ( empty( $id ) ) {
107
-			/** @var \wpdb $wpdb */
108
-			global $wpdb;
109
-			$id = (int) $wpdb->get_var( "SELECT MAX(ID) FROM $wpdb->posts" );
110
-			$id ++;
111
-		}
112
-		update_option( self::DEMARKATION_OPTION, $id );
113
-
114
-		return $id;
115
-	}
116
-
117
-	/**
118
-	 * Find the first matching action from the secondary store.
119
-	 * If it exists, migrate it to the primary store immediately.
120
-	 * After it migrates, the secondary store will logically contain
121
-	 * the next matching action, so return the result thence.
122
-	 *
123
-	 * @param string $hook
124
-	 * @param array  $params
125
-	 *
126
-	 * @return string
127
-	 */
128
-	public function find_action( $hook, $params = [] ) {
129
-		$found_unmigrated_action = $this->secondary_store->find_action( $hook, $params );
130
-		if ( ! empty( $found_unmigrated_action ) ) {
131
-			$this->migrate( [ $found_unmigrated_action ] );
132
-		}
133
-
134
-		return $this->primary_store->find_action( $hook, $params );
135
-	}
136
-
137
-	/**
138
-	 * Find actions matching the query in the secondary source first.
139
-	 * If any are found, migrate them immediately. Then the secondary
140
-	 * store will contain the canonical results.
141
-	 *
142
-	 * @param array $query
143
-	 * @param string $query_type Whether to select or count the results. Default, select.
144
-	 *
145
-	 * @return int[]
146
-	 */
147
-	public function query_actions( $query = [], $query_type = 'select' ) {
148
-		$found_unmigrated_actions = $this->secondary_store->query_actions( $query, 'select' );
149
-		if ( ! empty( $found_unmigrated_actions ) ) {
150
-			$this->migrate( $found_unmigrated_actions );
151
-		}
152
-
153
-		return $this->primary_store->query_actions( $query, $query_type );
154
-	}
155
-
156
-	/**
157
-	 * Get a count of all actions in the store, grouped by status
158
-	 *
159
-	 * @return array Set of 'status' => int $count pairs for statuses with 1 or more actions of that status.
160
-	 */
161
-	public function action_counts() {
162
-		$unmigrated_actions_count = $this->secondary_store->action_counts();
163
-		$migrated_actions_count   = $this->primary_store->action_counts();
164
-		$actions_count_by_status  = array();
165
-
166
-		foreach ( $this->get_status_labels() as $status_key => $status_label ) {
167
-
168
-			$count = 0;
169
-
170
-			if ( isset( $unmigrated_actions_count[ $status_key ] ) ) {
171
-				$count += $unmigrated_actions_count[ $status_key ];
172
-			}
173
-
174
-			if ( isset( $migrated_actions_count[ $status_key ] ) ) {
175
-				$count += $migrated_actions_count[ $status_key ];
176
-			}
177
-
178
-			$actions_count_by_status[ $status_key ] = $count;
179
-		}
180
-
181
-		$actions_count_by_status = array_filter( $actions_count_by_status );
182
-
183
-		return $actions_count_by_status;
184
-	}
185
-
186
-	/**
187
-	 * If any actions would have been claimed by the secondary store,
188
-	 * migrate them immediately, then ask the primary store for the
189
-	 * canonical claim.
190
-	 *
191
-	 * @param int           $max_actions
192
-	 * @param DateTime|null $before_date
193
-	 *
194
-	 * @return ActionScheduler_ActionClaim
195
-	 */
196
-	public function stake_claim( $max_actions = 10, DateTime $before_date = null, $hooks = array(), $group = '' ) {
197
-		$claim = $this->secondary_store->stake_claim( $max_actions, $before_date, $hooks, $group );
198
-
199
-		$claimed_actions = $claim->get_actions();
200
-		if ( ! empty( $claimed_actions ) ) {
201
-			$this->migrate( $claimed_actions );
202
-		}
203
-
204
-		$this->secondary_store->release_claim( $claim );
205
-
206
-		return $this->primary_store->stake_claim( $max_actions, $before_date, $hooks, $group );
207
-	}
208
-
209
-	/**
210
-	 * Migrate a list of actions to the table data store.
211
-	 *
212
-	 * @param array $action_ids List of action IDs.
213
-	 */
214
-	private function migrate( $action_ids ) {
215
-		$this->migration_runner->migrate_actions( $action_ids );
216
-	}
217
-
218
-	/**
219
-	 * Save an action to the primary store.
220
-	 *
221
-	 * @param ActionScheduler_Action $action Action object to be saved.
222
-	 * @param DateTime               $date Optional. Schedule date. Default null.
223
-	 */
224
-	public function save_action( ActionScheduler_Action $action, DateTime $date = null ) {
225
-		return $this->primary_store->save_action( $action, $date );
226
-	}
227
-
228
-	/**
229
-	 * Retrieve an existing action whether migrated or not.
230
-	 *
231
-	 * @param int $action_id Action ID.
232
-	 */
233
-	public function fetch_action( $action_id ) {
234
-		if ( $action_id < $this->demarkation_id ) {
235
-			return $this->secondary_store->fetch_action( $action_id );
236
-		} else {
237
-			return $this->primary_store->fetch_action( $action_id );
238
-		}
239
-	}
240
-
241
-	/**
242
-	 * Cancel an existing action whether migrated or not.
243
-	 *
244
-	 * @param int $action_id Action ID.
245
-	 */
246
-	public function cancel_action( $action_id ) {
247
-		if ( $action_id < $this->demarkation_id ) {
248
-			$this->secondary_store->cancel_action( $action_id );
249
-		} else {
250
-			$this->primary_store->cancel_action( $action_id );
251
-		}
252
-	}
253
-
254
-	/**
255
-	 * Delete an existing action whether migrated or not.
256
-	 *
257
-	 * @param int $action_id Action ID.
258
-	 */
259
-	public function delete_action( $action_id ) {
260
-		if ( $action_id < $this->demarkation_id ) {
261
-			$this->secondary_store->delete_action( $action_id );
262
-		} else {
263
-			$this->primary_store->delete_action( $action_id );
264
-		}
265
-	}
266
-
267
-	/**
268
-	 * Get the schedule date an existing action whether migrated or not.
269
-	 *
270
-	 * @param int $action_id Action ID.
271
-	 */
272
-	public function get_date( $action_id ) {
273
-		if ( $action_id < $this->demarkation_id ) {
274
-			return $this->secondary_store->get_date( $action_id );
275
-		} else {
276
-			return $this->primary_store->get_date( $action_id );
277
-		}
278
-	}
279
-
280
-	/**
281
-	 * Mark an existing action as failed whether migrated or not.
282
-	 *
283
-	 * @param int $action_id Action ID.
284
-	 */
285
-	public function mark_failure( $action_id ) {
286
-		if ( $action_id < $this->demarkation_id ) {
287
-			$this->secondary_store->mark_failure( $action_id );
288
-		} else {
289
-			$this->primary_store->mark_failure( $action_id );
290
-		}
291
-	}
292
-
293
-	/**
294
-	 * Log the execution of an existing action whether migrated or not.
295
-	 *
296
-	 * @param int $action_id Action ID.
297
-	 */
298
-	public function log_execution( $action_id ) {
299
-		if ( $action_id < $this->demarkation_id ) {
300
-			$this->secondary_store->log_execution( $action_id );
301
-		} else {
302
-			$this->primary_store->log_execution( $action_id );
303
-		}
304
-	}
305
-
306
-	/**
307
-	 * Mark an existing action complete whether migrated or not.
308
-	 *
309
-	 * @param int $action_id Action ID.
310
-	 */
311
-	public function mark_complete( $action_id ) {
312
-		if ( $action_id < $this->demarkation_id ) {
313
-			$this->secondary_store->mark_complete( $action_id );
314
-		} else {
315
-			$this->primary_store->mark_complete( $action_id );
316
-		}
317
-	}
318
-
319
-	/**
320
-	 * Get an existing action status whether migrated or not.
321
-	 *
322
-	 * @param int $action_id Action ID.
323
-	 */
324
-	public function get_status( $action_id ) {
325
-		if ( $action_id < $this->demarkation_id ) {
326
-			return $this->secondary_store->get_status( $action_id );
327
-		} else {
328
-			return $this->primary_store->get_status( $action_id );
329
-		}
330
-	}
331
-
332
-
333
-	/* * * * * * * * * * * * * * * * * * * * * * * * * * *
16
+    const DEMARKATION_OPTION = 'action_scheduler_hybrid_store_demarkation';
17
+
18
+    private $primary_store;
19
+    private $secondary_store;
20
+    private $migration_runner;
21
+
22
+    /**
23
+     * @var int The dividing line between IDs of actions created
24
+     *          by the primary and secondary stores.
25
+     *
26
+     * Methods that accept an action ID will compare the ID against
27
+     * this to determine which store will contain that ID. In almost
28
+     * all cases, the ID should come from the primary store, but if
29
+     * client code is bypassing the API functions and fetching IDs
30
+     * from elsewhere, then there is a chance that an unmigrated ID
31
+     * might be requested.
32
+     */
33
+    private $demarkation_id = 0;
34
+
35
+    /**
36
+     * ActionScheduler_HybridStore constructor.
37
+     *
38
+     * @param Config $config Migration config object.
39
+     */
40
+    public function __construct( Config $config = null ) {
41
+        $this->demarkation_id = (int) get_option( self::DEMARKATION_OPTION, 0 );
42
+        if ( empty( $config ) ) {
43
+            $config = Controller::instance()->get_migration_config_object();
44
+        }
45
+        $this->primary_store    = $config->get_destination_store();
46
+        $this->secondary_store  = $config->get_source_store();
47
+        $this->migration_runner = new Runner( $config );
48
+    }
49
+
50
+    /**
51
+     * Initialize the table data store tables.
52
+     *
53
+     * @codeCoverageIgnore
54
+     */
55
+    public function init() {
56
+        add_action( 'action_scheduler/created_table', [ $this, 'set_autoincrement' ], 10, 2 );
57
+        $this->primary_store->init();
58
+        $this->secondary_store->init();
59
+        remove_action( 'action_scheduler/created_table', [ $this, 'set_autoincrement' ], 10 );
60
+    }
61
+
62
+    /**
63
+     * When the actions table is created, set its autoincrement
64
+     * value to be one higher than the posts table to ensure that
65
+     * there are no ID collisions.
66
+     *
67
+     * @param string $table_name
68
+     * @param string $table_suffix
69
+     *
70
+     * @return void
71
+     * @codeCoverageIgnore
72
+     */
73
+    public function set_autoincrement( $table_name, $table_suffix ) {
74
+        if ( ActionScheduler_StoreSchema::ACTIONS_TABLE === $table_suffix ) {
75
+            if ( empty( $this->demarkation_id ) ) {
76
+                $this->demarkation_id = $this->set_demarkation_id();
77
+            }
78
+            /** @var \wpdb $wpdb */
79
+            global $wpdb;
80
+            $wpdb->insert(
81
+                $wpdb->{ActionScheduler_StoreSchema::ACTIONS_TABLE},
82
+                [
83
+                    'action_id' => $this->demarkation_id,
84
+                    'hook'      => '',
85
+                    'status'    => '',
86
+                ]
87
+            );
88
+            $wpdb->delete(
89
+                $wpdb->{ActionScheduler_StoreSchema::ACTIONS_TABLE},
90
+                [ 'action_id' => $this->demarkation_id ]
91
+            );
92
+        }
93
+    }
94
+
95
+    /**
96
+     * Store the demarkation id in WP options.
97
+     *
98
+     * @param int $id The ID to set as the demarkation point between the two stores
99
+     *                Leave null to use the next ID from the WP posts table.
100
+     *
101
+     * @return int The new ID.
102
+     *
103
+     * @codeCoverageIgnore
104
+     */
105
+    private function set_demarkation_id( $id = null ) {
106
+        if ( empty( $id ) ) {
107
+            /** @var \wpdb $wpdb */
108
+            global $wpdb;
109
+            $id = (int) $wpdb->get_var( "SELECT MAX(ID) FROM $wpdb->posts" );
110
+            $id ++;
111
+        }
112
+        update_option( self::DEMARKATION_OPTION, $id );
113
+
114
+        return $id;
115
+    }
116
+
117
+    /**
118
+     * Find the first matching action from the secondary store.
119
+     * If it exists, migrate it to the primary store immediately.
120
+     * After it migrates, the secondary store will logically contain
121
+     * the next matching action, so return the result thence.
122
+     *
123
+     * @param string $hook
124
+     * @param array  $params
125
+     *
126
+     * @return string
127
+     */
128
+    public function find_action( $hook, $params = [] ) {
129
+        $found_unmigrated_action = $this->secondary_store->find_action( $hook, $params );
130
+        if ( ! empty( $found_unmigrated_action ) ) {
131
+            $this->migrate( [ $found_unmigrated_action ] );
132
+        }
133
+
134
+        return $this->primary_store->find_action( $hook, $params );
135
+    }
136
+
137
+    /**
138
+     * Find actions matching the query in the secondary source first.
139
+     * If any are found, migrate them immediately. Then the secondary
140
+     * store will contain the canonical results.
141
+     *
142
+     * @param array $query
143
+     * @param string $query_type Whether to select or count the results. Default, select.
144
+     *
145
+     * @return int[]
146
+     */
147
+    public function query_actions( $query = [], $query_type = 'select' ) {
148
+        $found_unmigrated_actions = $this->secondary_store->query_actions( $query, 'select' );
149
+        if ( ! empty( $found_unmigrated_actions ) ) {
150
+            $this->migrate( $found_unmigrated_actions );
151
+        }
152
+
153
+        return $this->primary_store->query_actions( $query, $query_type );
154
+    }
155
+
156
+    /**
157
+     * Get a count of all actions in the store, grouped by status
158
+     *
159
+     * @return array Set of 'status' => int $count pairs for statuses with 1 or more actions of that status.
160
+     */
161
+    public function action_counts() {
162
+        $unmigrated_actions_count = $this->secondary_store->action_counts();
163
+        $migrated_actions_count   = $this->primary_store->action_counts();
164
+        $actions_count_by_status  = array();
165
+
166
+        foreach ( $this->get_status_labels() as $status_key => $status_label ) {
167
+
168
+            $count = 0;
169
+
170
+            if ( isset( $unmigrated_actions_count[ $status_key ] ) ) {
171
+                $count += $unmigrated_actions_count[ $status_key ];
172
+            }
173
+
174
+            if ( isset( $migrated_actions_count[ $status_key ] ) ) {
175
+                $count += $migrated_actions_count[ $status_key ];
176
+            }
177
+
178
+            $actions_count_by_status[ $status_key ] = $count;
179
+        }
180
+
181
+        $actions_count_by_status = array_filter( $actions_count_by_status );
182
+
183
+        return $actions_count_by_status;
184
+    }
185
+
186
+    /**
187
+     * If any actions would have been claimed by the secondary store,
188
+     * migrate them immediately, then ask the primary store for the
189
+     * canonical claim.
190
+     *
191
+     * @param int           $max_actions
192
+     * @param DateTime|null $before_date
193
+     *
194
+     * @return ActionScheduler_ActionClaim
195
+     */
196
+    public function stake_claim( $max_actions = 10, DateTime $before_date = null, $hooks = array(), $group = '' ) {
197
+        $claim = $this->secondary_store->stake_claim( $max_actions, $before_date, $hooks, $group );
198
+
199
+        $claimed_actions = $claim->get_actions();
200
+        if ( ! empty( $claimed_actions ) ) {
201
+            $this->migrate( $claimed_actions );
202
+        }
203
+
204
+        $this->secondary_store->release_claim( $claim );
205
+
206
+        return $this->primary_store->stake_claim( $max_actions, $before_date, $hooks, $group );
207
+    }
208
+
209
+    /**
210
+     * Migrate a list of actions to the table data store.
211
+     *
212
+     * @param array $action_ids List of action IDs.
213
+     */
214
+    private function migrate( $action_ids ) {
215
+        $this->migration_runner->migrate_actions( $action_ids );
216
+    }
217
+
218
+    /**
219
+     * Save an action to the primary store.
220
+     *
221
+     * @param ActionScheduler_Action $action Action object to be saved.
222
+     * @param DateTime               $date Optional. Schedule date. Default null.
223
+     */
224
+    public function save_action( ActionScheduler_Action $action, DateTime $date = null ) {
225
+        return $this->primary_store->save_action( $action, $date );
226
+    }
227
+
228
+    /**
229
+     * Retrieve an existing action whether migrated or not.
230
+     *
231
+     * @param int $action_id Action ID.
232
+     */
233
+    public function fetch_action( $action_id ) {
234
+        if ( $action_id < $this->demarkation_id ) {
235
+            return $this->secondary_store->fetch_action( $action_id );
236
+        } else {
237
+            return $this->primary_store->fetch_action( $action_id );
238
+        }
239
+    }
240
+
241
+    /**
242
+     * Cancel an existing action whether migrated or not.
243
+     *
244
+     * @param int $action_id Action ID.
245
+     */
246
+    public function cancel_action( $action_id ) {
247
+        if ( $action_id < $this->demarkation_id ) {
248
+            $this->secondary_store->cancel_action( $action_id );
249
+        } else {
250
+            $this->primary_store->cancel_action( $action_id );
251
+        }
252
+    }
253
+
254
+    /**
255
+     * Delete an existing action whether migrated or not.
256
+     *
257
+     * @param int $action_id Action ID.
258
+     */
259
+    public function delete_action( $action_id ) {
260
+        if ( $action_id < $this->demarkation_id ) {
261
+            $this->secondary_store->delete_action( $action_id );
262
+        } else {
263
+            $this->primary_store->delete_action( $action_id );
264
+        }
265
+    }
266
+
267
+    /**
268
+     * Get the schedule date an existing action whether migrated or not.
269
+     *
270
+     * @param int $action_id Action ID.
271
+     */
272
+    public function get_date( $action_id ) {
273
+        if ( $action_id < $this->demarkation_id ) {
274
+            return $this->secondary_store->get_date( $action_id );
275
+        } else {
276
+            return $this->primary_store->get_date( $action_id );
277
+        }
278
+    }
279
+
280
+    /**
281
+     * Mark an existing action as failed whether migrated or not.
282
+     *
283
+     * @param int $action_id Action ID.
284
+     */
285
+    public function mark_failure( $action_id ) {
286
+        if ( $action_id < $this->demarkation_id ) {
287
+            $this->secondary_store->mark_failure( $action_id );
288
+        } else {
289
+            $this->primary_store->mark_failure( $action_id );
290
+        }
291
+    }
292
+
293
+    /**
294
+     * Log the execution of an existing action whether migrated or not.
295
+     *
296
+     * @param int $action_id Action ID.
297
+     */
298
+    public function log_execution( $action_id ) {
299
+        if ( $action_id < $this->demarkation_id ) {
300
+            $this->secondary_store->log_execution( $action_id );
301
+        } else {
302
+            $this->primary_store->log_execution( $action_id );
303
+        }
304
+    }
305
+
306
+    /**
307
+     * Mark an existing action complete whether migrated or not.
308
+     *
309
+     * @param int $action_id Action ID.
310
+     */
311
+    public function mark_complete( $action_id ) {
312
+        if ( $action_id < $this->demarkation_id ) {
313
+            $this->secondary_store->mark_complete( $action_id );
314
+        } else {
315
+            $this->primary_store->mark_complete( $action_id );
316
+        }
317
+    }
318
+
319
+    /**
320
+     * Get an existing action status whether migrated or not.
321
+     *
322
+     * @param int $action_id Action ID.
323
+     */
324
+    public function get_status( $action_id ) {
325
+        if ( $action_id < $this->demarkation_id ) {
326
+            return $this->secondary_store->get_status( $action_id );
327
+        } else {
328
+            return $this->primary_store->get_status( $action_id );
329
+        }
330
+    }
331
+
332
+
333
+    /* * * * * * * * * * * * * * * * * * * * * * * * * * *
334 334
 	 * All claim-related functions should operate solely
335 335
 	 * on the primary store.
336 336
 	 * * * * * * * * * * * * * * * * * * * * * * * * * * */
337 337
 
338
-	/**
339
-	 * Get the claim count from the table data store.
340
-	 */
341
-	public function get_claim_count() {
342
-		return $this->primary_store->get_claim_count();
343
-	}
344
-
345
-	/**
346
-	 * Retrieve the claim ID for an action from the table data store.
347
-	 *
348
-	 * @param int $action_id Action ID.
349
-	 */
350
-	public function get_claim_id( $action_id ) {
351
-		return $this->primary_store->get_claim_id( $action_id );
352
-	}
353
-
354
-	/**
355
-	 * Release a claim in the table data store.
356
-	 *
357
-	 * @param ActionScheduler_ActionClaim $claim Claim object.
358
-	 */
359
-	public function release_claim( ActionScheduler_ActionClaim $claim ) {
360
-		$this->primary_store->release_claim( $claim );
361
-	}
362
-
363
-	/**
364
-	 * Release claims on an action in the table data store.
365
-	 *
366
-	 * @param int $action_id Action ID.
367
-	 */
368
-	public function unclaim_action( $action_id ) {
369
-		$this->primary_store->unclaim_action( $action_id );
370
-	}
371
-
372
-	/**
373
-	 * Retrieve a list of action IDs by claim.
374
-	 *
375
-	 * @param int $claim_id Claim ID.
376
-	 */
377
-	public function find_actions_by_claim_id( $claim_id ) {
378
-		return $this->primary_store->find_actions_by_claim_id( $claim_id );
379
-	}
338
+    /**
339
+     * Get the claim count from the table data store.
340
+     */
341
+    public function get_claim_count() {
342
+        return $this->primary_store->get_claim_count();
343
+    }
344
+
345
+    /**
346
+     * Retrieve the claim ID for an action from the table data store.
347
+     *
348
+     * @param int $action_id Action ID.
349
+     */
350
+    public function get_claim_id( $action_id ) {
351
+        return $this->primary_store->get_claim_id( $action_id );
352
+    }
353
+
354
+    /**
355
+     * Release a claim in the table data store.
356
+     *
357
+     * @param ActionScheduler_ActionClaim $claim Claim object.
358
+     */
359
+    public function release_claim( ActionScheduler_ActionClaim $claim ) {
360
+        $this->primary_store->release_claim( $claim );
361
+    }
362
+
363
+    /**
364
+     * Release claims on an action in the table data store.
365
+     *
366
+     * @param int $action_id Action ID.
367
+     */
368
+    public function unclaim_action( $action_id ) {
369
+        $this->primary_store->unclaim_action( $action_id );
370
+    }
371
+
372
+    /**
373
+     * Retrieve a list of action IDs by claim.
374
+     *
375
+     * @param int $claim_id Claim ID.
376
+     */
377
+    public function find_actions_by_claim_id( $claim_id ) {
378
+        return $this->primary_store->find_actions_by_claim_id( $claim_id );
379
+    }
380 380
 }
Please login to merge, or discard this patch.
Spacing   +82 added lines, -82 removed lines patch added patch discarded remove patch
@@ -37,14 +37,14 @@  discard block
 block discarded – undo
37 37
 	 *
38 38
 	 * @param Config $config Migration config object.
39 39
 	 */
40
-	public function __construct( Config $config = null ) {
41
-		$this->demarkation_id = (int) get_option( self::DEMARKATION_OPTION, 0 );
42
-		if ( empty( $config ) ) {
40
+	public function __construct(Config $config = null) {
41
+		$this->demarkation_id = (int) get_option(self::DEMARKATION_OPTION, 0);
42
+		if (empty($config)) {
43 43
 			$config = Controller::instance()->get_migration_config_object();
44 44
 		}
45 45
 		$this->primary_store    = $config->get_destination_store();
46 46
 		$this->secondary_store  = $config->get_source_store();
47
-		$this->migration_runner = new Runner( $config );
47
+		$this->migration_runner = new Runner($config);
48 48
 	}
49 49
 
50 50
 	/**
@@ -53,10 +53,10 @@  discard block
 block discarded – undo
53 53
 	 * @codeCoverageIgnore
54 54
 	 */
55 55
 	public function init() {
56
-		add_action( 'action_scheduler/created_table', [ $this, 'set_autoincrement' ], 10, 2 );
56
+		add_action('action_scheduler/created_table', [$this, 'set_autoincrement'], 10, 2);
57 57
 		$this->primary_store->init();
58 58
 		$this->secondary_store->init();
59
-		remove_action( 'action_scheduler/created_table', [ $this, 'set_autoincrement' ], 10 );
59
+		remove_action('action_scheduler/created_table', [$this, 'set_autoincrement'], 10);
60 60
 	}
61 61
 
62 62
 	/**
@@ -70,9 +70,9 @@  discard block
 block discarded – undo
70 70
 	 * @return void
71 71
 	 * @codeCoverageIgnore
72 72
 	 */
73
-	public function set_autoincrement( $table_name, $table_suffix ) {
74
-		if ( ActionScheduler_StoreSchema::ACTIONS_TABLE === $table_suffix ) {
75
-			if ( empty( $this->demarkation_id ) ) {
73
+	public function set_autoincrement($table_name, $table_suffix) {
74
+		if (ActionScheduler_StoreSchema::ACTIONS_TABLE === $table_suffix) {
75
+			if (empty($this->demarkation_id)) {
76 76
 				$this->demarkation_id = $this->set_demarkation_id();
77 77
 			}
78 78
 			/** @var \wpdb $wpdb */
@@ -87,7 +87,7 @@  discard block
 block discarded – undo
87 87
 			);
88 88
 			$wpdb->delete(
89 89
 				$wpdb->{ActionScheduler_StoreSchema::ACTIONS_TABLE},
90
-				[ 'action_id' => $this->demarkation_id ]
90
+				['action_id' => $this->demarkation_id]
91 91
 			);
92 92
 		}
93 93
 	}
@@ -102,14 +102,14 @@  discard block
 block discarded – undo
102 102
 	 *
103 103
 	 * @codeCoverageIgnore
104 104
 	 */
105
-	private function set_demarkation_id( $id = null ) {
106
-		if ( empty( $id ) ) {
105
+	private function set_demarkation_id($id = null) {
106
+		if (empty($id)) {
107 107
 			/** @var \wpdb $wpdb */
108 108
 			global $wpdb;
109
-			$id = (int) $wpdb->get_var( "SELECT MAX(ID) FROM $wpdb->posts" );
110
-			$id ++;
109
+			$id = (int) $wpdb->get_var("SELECT MAX(ID) FROM $wpdb->posts");
110
+			$id++;
111 111
 		}
112
-		update_option( self::DEMARKATION_OPTION, $id );
112
+		update_option(self::DEMARKATION_OPTION, $id);
113 113
 
114 114
 		return $id;
115 115
 	}
@@ -125,13 +125,13 @@  discard block
 block discarded – undo
125 125
 	 *
126 126
 	 * @return string
127 127
 	 */
128
-	public function find_action( $hook, $params = [] ) {
129
-		$found_unmigrated_action = $this->secondary_store->find_action( $hook, $params );
130
-		if ( ! empty( $found_unmigrated_action ) ) {
131
-			$this->migrate( [ $found_unmigrated_action ] );
128
+	public function find_action($hook, $params = []) {
129
+		$found_unmigrated_action = $this->secondary_store->find_action($hook, $params);
130
+		if (!empty($found_unmigrated_action)) {
131
+			$this->migrate([$found_unmigrated_action]);
132 132
 		}
133 133
 
134
-		return $this->primary_store->find_action( $hook, $params );
134
+		return $this->primary_store->find_action($hook, $params);
135 135
 	}
136 136
 
137 137
 	/**
@@ -144,13 +144,13 @@  discard block
 block discarded – undo
144 144
 	 *
145 145
 	 * @return int[]
146 146
 	 */
147
-	public function query_actions( $query = [], $query_type = 'select' ) {
148
-		$found_unmigrated_actions = $this->secondary_store->query_actions( $query, 'select' );
149
-		if ( ! empty( $found_unmigrated_actions ) ) {
150
-			$this->migrate( $found_unmigrated_actions );
147
+	public function query_actions($query = [], $query_type = 'select') {
148
+		$found_unmigrated_actions = $this->secondary_store->query_actions($query, 'select');
149
+		if (!empty($found_unmigrated_actions)) {
150
+			$this->migrate($found_unmigrated_actions);
151 151
 		}
152 152
 
153
-		return $this->primary_store->query_actions( $query, $query_type );
153
+		return $this->primary_store->query_actions($query, $query_type);
154 154
 	}
155 155
 
156 156
 	/**
@@ -163,22 +163,22 @@  discard block
 block discarded – undo
163 163
 		$migrated_actions_count   = $this->primary_store->action_counts();
164 164
 		$actions_count_by_status  = array();
165 165
 
166
-		foreach ( $this->get_status_labels() as $status_key => $status_label ) {
166
+		foreach ($this->get_status_labels() as $status_key => $status_label) {
167 167
 
168 168
 			$count = 0;
169 169
 
170
-			if ( isset( $unmigrated_actions_count[ $status_key ] ) ) {
171
-				$count += $unmigrated_actions_count[ $status_key ];
170
+			if (isset($unmigrated_actions_count[$status_key])) {
171
+				$count += $unmigrated_actions_count[$status_key];
172 172
 			}
173 173
 
174
-			if ( isset( $migrated_actions_count[ $status_key ] ) ) {
175
-				$count += $migrated_actions_count[ $status_key ];
174
+			if (isset($migrated_actions_count[$status_key])) {
175
+				$count += $migrated_actions_count[$status_key];
176 176
 			}
177 177
 
178
-			$actions_count_by_status[ $status_key ] = $count;
178
+			$actions_count_by_status[$status_key] = $count;
179 179
 		}
180 180
 
181
-		$actions_count_by_status = array_filter( $actions_count_by_status );
181
+		$actions_count_by_status = array_filter($actions_count_by_status);
182 182
 
183 183
 		return $actions_count_by_status;
184 184
 	}
@@ -193,17 +193,17 @@  discard block
 block discarded – undo
193 193
 	 *
194 194
 	 * @return ActionScheduler_ActionClaim
195 195
 	 */
196
-	public function stake_claim( $max_actions = 10, DateTime $before_date = null, $hooks = array(), $group = '' ) {
197
-		$claim = $this->secondary_store->stake_claim( $max_actions, $before_date, $hooks, $group );
196
+	public function stake_claim($max_actions = 10, DateTime $before_date = null, $hooks = array(), $group = '') {
197
+		$claim = $this->secondary_store->stake_claim($max_actions, $before_date, $hooks, $group);
198 198
 
199 199
 		$claimed_actions = $claim->get_actions();
200
-		if ( ! empty( $claimed_actions ) ) {
201
-			$this->migrate( $claimed_actions );
200
+		if (!empty($claimed_actions)) {
201
+			$this->migrate($claimed_actions);
202 202
 		}
203 203
 
204
-		$this->secondary_store->release_claim( $claim );
204
+		$this->secondary_store->release_claim($claim);
205 205
 
206
-		return $this->primary_store->stake_claim( $max_actions, $before_date, $hooks, $group );
206
+		return $this->primary_store->stake_claim($max_actions, $before_date, $hooks, $group);
207 207
 	}
208 208
 
209 209
 	/**
@@ -211,8 +211,8 @@  discard block
 block discarded – undo
211 211
 	 *
212 212
 	 * @param array $action_ids List of action IDs.
213 213
 	 */
214
-	private function migrate( $action_ids ) {
215
-		$this->migration_runner->migrate_actions( $action_ids );
214
+	private function migrate($action_ids) {
215
+		$this->migration_runner->migrate_actions($action_ids);
216 216
 	}
217 217
 
218 218
 	/**
@@ -221,8 +221,8 @@  discard block
 block discarded – undo
221 221
 	 * @param ActionScheduler_Action $action Action object to be saved.
222 222
 	 * @param DateTime               $date Optional. Schedule date. Default null.
223 223
 	 */
224
-	public function save_action( ActionScheduler_Action $action, DateTime $date = null ) {
225
-		return $this->primary_store->save_action( $action, $date );
224
+	public function save_action(ActionScheduler_Action $action, DateTime $date = null) {
225
+		return $this->primary_store->save_action($action, $date);
226 226
 	}
227 227
 
228 228
 	/**
@@ -230,11 +230,11 @@  discard block
 block discarded – undo
230 230
 	 *
231 231
 	 * @param int $action_id Action ID.
232 232
 	 */
233
-	public function fetch_action( $action_id ) {
234
-		if ( $action_id < $this->demarkation_id ) {
235
-			return $this->secondary_store->fetch_action( $action_id );
233
+	public function fetch_action($action_id) {
234
+		if ($action_id < $this->demarkation_id) {
235
+			return $this->secondary_store->fetch_action($action_id);
236 236
 		} else {
237
-			return $this->primary_store->fetch_action( $action_id );
237
+			return $this->primary_store->fetch_action($action_id);
238 238
 		}
239 239
 	}
240 240
 
@@ -243,11 +243,11 @@  discard block
 block discarded – undo
243 243
 	 *
244 244
 	 * @param int $action_id Action ID.
245 245
 	 */
246
-	public function cancel_action( $action_id ) {
247
-		if ( $action_id < $this->demarkation_id ) {
248
-			$this->secondary_store->cancel_action( $action_id );
246
+	public function cancel_action($action_id) {
247
+		if ($action_id < $this->demarkation_id) {
248
+			$this->secondary_store->cancel_action($action_id);
249 249
 		} else {
250
-			$this->primary_store->cancel_action( $action_id );
250
+			$this->primary_store->cancel_action($action_id);
251 251
 		}
252 252
 	}
253 253
 
@@ -256,11 +256,11 @@  discard block
 block discarded – undo
256 256
 	 *
257 257
 	 * @param int $action_id Action ID.
258 258
 	 */
259
-	public function delete_action( $action_id ) {
260
-		if ( $action_id < $this->demarkation_id ) {
261
-			$this->secondary_store->delete_action( $action_id );
259
+	public function delete_action($action_id) {
260
+		if ($action_id < $this->demarkation_id) {
261
+			$this->secondary_store->delete_action($action_id);
262 262
 		} else {
263
-			$this->primary_store->delete_action( $action_id );
263
+			$this->primary_store->delete_action($action_id);
264 264
 		}
265 265
 	}
266 266
 
@@ -269,11 +269,11 @@  discard block
 block discarded – undo
269 269
 	 *
270 270
 	 * @param int $action_id Action ID.
271 271
 	 */
272
-	public function get_date( $action_id ) {
273
-		if ( $action_id < $this->demarkation_id ) {
274
-			return $this->secondary_store->get_date( $action_id );
272
+	public function get_date($action_id) {
273
+		if ($action_id < $this->demarkation_id) {
274
+			return $this->secondary_store->get_date($action_id);
275 275
 		} else {
276
-			return $this->primary_store->get_date( $action_id );
276
+			return $this->primary_store->get_date($action_id);
277 277
 		}
278 278
 	}
279 279
 
@@ -282,11 +282,11 @@  discard block
 block discarded – undo
282 282
 	 *
283 283
 	 * @param int $action_id Action ID.
284 284
 	 */
285
-	public function mark_failure( $action_id ) {
286
-		if ( $action_id < $this->demarkation_id ) {
287
-			$this->secondary_store->mark_failure( $action_id );
285
+	public function mark_failure($action_id) {
286
+		if ($action_id < $this->demarkation_id) {
287
+			$this->secondary_store->mark_failure($action_id);
288 288
 		} else {
289
-			$this->primary_store->mark_failure( $action_id );
289
+			$this->primary_store->mark_failure($action_id);
290 290
 		}
291 291
 	}
292 292
 
@@ -295,11 +295,11 @@  discard block
 block discarded – undo
295 295
 	 *
296 296
 	 * @param int $action_id Action ID.
297 297
 	 */
298
-	public function log_execution( $action_id ) {
299
-		if ( $action_id < $this->demarkation_id ) {
300
-			$this->secondary_store->log_execution( $action_id );
298
+	public function log_execution($action_id) {
299
+		if ($action_id < $this->demarkation_id) {
300
+			$this->secondary_store->log_execution($action_id);
301 301
 		} else {
302
-			$this->primary_store->log_execution( $action_id );
302
+			$this->primary_store->log_execution($action_id);
303 303
 		}
304 304
 	}
305 305
 
@@ -308,11 +308,11 @@  discard block
 block discarded – undo
308 308
 	 *
309 309
 	 * @param int $action_id Action ID.
310 310
 	 */
311
-	public function mark_complete( $action_id ) {
312
-		if ( $action_id < $this->demarkation_id ) {
313
-			$this->secondary_store->mark_complete( $action_id );
311
+	public function mark_complete($action_id) {
312
+		if ($action_id < $this->demarkation_id) {
313
+			$this->secondary_store->mark_complete($action_id);
314 314
 		} else {
315
-			$this->primary_store->mark_complete( $action_id );
315
+			$this->primary_store->mark_complete($action_id);
316 316
 		}
317 317
 	}
318 318
 
@@ -321,11 +321,11 @@  discard block
 block discarded – undo
321 321
 	 *
322 322
 	 * @param int $action_id Action ID.
323 323
 	 */
324
-	public function get_status( $action_id ) {
325
-		if ( $action_id < $this->demarkation_id ) {
326
-			return $this->secondary_store->get_status( $action_id );
324
+	public function get_status($action_id) {
325
+		if ($action_id < $this->demarkation_id) {
326
+			return $this->secondary_store->get_status($action_id);
327 327
 		} else {
328
-			return $this->primary_store->get_status( $action_id );
328
+			return $this->primary_store->get_status($action_id);
329 329
 		}
330 330
 	}
331 331
 
@@ -347,8 +347,8 @@  discard block
 block discarded – undo
347 347
 	 *
348 348
 	 * @param int $action_id Action ID.
349 349
 	 */
350
-	public function get_claim_id( $action_id ) {
351
-		return $this->primary_store->get_claim_id( $action_id );
350
+	public function get_claim_id($action_id) {
351
+		return $this->primary_store->get_claim_id($action_id);
352 352
 	}
353 353
 
354 354
 	/**
@@ -356,8 +356,8 @@  discard block
 block discarded – undo
356 356
 	 *
357 357
 	 * @param ActionScheduler_ActionClaim $claim Claim object.
358 358
 	 */
359
-	public function release_claim( ActionScheduler_ActionClaim $claim ) {
360
-		$this->primary_store->release_claim( $claim );
359
+	public function release_claim(ActionScheduler_ActionClaim $claim) {
360
+		$this->primary_store->release_claim($claim);
361 361
 	}
362 362
 
363 363
 	/**
@@ -365,8 +365,8 @@  discard block
 block discarded – undo
365 365
 	 *
366 366
 	 * @param int $action_id Action ID.
367 367
 	 */
368
-	public function unclaim_action( $action_id ) {
369
-		$this->primary_store->unclaim_action( $action_id );
368
+	public function unclaim_action($action_id) {
369
+		$this->primary_store->unclaim_action($action_id);
370 370
 	}
371 371
 
372 372
 	/**
@@ -374,7 +374,7 @@  discard block
 block discarded – undo
374 374
 	 *
375 375
 	 * @param int $claim_id Claim ID.
376 376
 	 */
377
-	public function find_actions_by_claim_id( $claim_id ) {
378
-		return $this->primary_store->find_actions_by_claim_id( $claim_id );
377
+	public function find_actions_by_claim_id($claim_id) {
378
+		return $this->primary_store->find_actions_by_claim_id($claim_id);
379 379
 	}
380 380
 }
Please login to merge, or discard this patch.
libraries/action-scheduler/classes/data-stores/ActionScheduler_DBLogger.php 2 patches
Indentation   +134 added lines, -134 removed lines patch added patch discarded remove patch
@@ -9,138 +9,138 @@
 block discarded – undo
9 9
  */
10 10
 class ActionScheduler_DBLogger extends ActionScheduler_Logger {
11 11
 
12
-	/**
13
-	 * Add a record to an action log.
14
-	 *
15
-	 * @param int      $action_id Action ID.
16
-	 * @param string   $message Message to be saved in the log entry.
17
-	 * @param DateTime $date Timestamp of the log entry.
18
-	 *
19
-	 * @return int     The log entry ID.
20
-	 */
21
-	public function log( $action_id, $message, DateTime $date = null ) {
22
-		if ( empty( $date ) ) {
23
-			$date = as_get_datetime_object();
24
-		} else {
25
-			$date = clone $date;
26
-		}
27
-
28
-		$date_gmt = $date->format( 'Y-m-d H:i:s' );
29
-		ActionScheduler_TimezoneHelper::set_local_timezone( $date );
30
-		$date_local = $date->format( 'Y-m-d H:i:s' );
31
-
32
-		/** @var \wpdb $wpdb */
33
-		global $wpdb;
34
-		$wpdb->insert( $wpdb->actionscheduler_logs, [
35
-			'action_id'      => $action_id,
36
-			'message'        => $message,
37
-			'log_date_gmt'   => $date_gmt,
38
-			'log_date_local' => $date_local,
39
-		], [ '%d', '%s', '%s', '%s' ] );
40
-
41
-		return $wpdb->insert_id;
42
-	}
43
-
44
-	/**
45
-	 * Retrieve an action log entry.
46
-	 *
47
-	 * @param int $entry_id Log entry ID.
48
-	 *
49
-	 * @return ActionScheduler_LogEntry
50
-	 */
51
-	public function get_entry( $entry_id ) {
52
-		/** @var \wpdb $wpdb */
53
-		global $wpdb;
54
-		$entry = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->actionscheduler_logs} WHERE log_id=%d", $entry_id ) );
55
-
56
-		return $this->create_entry_from_db_record( $entry );
57
-	}
58
-
59
-	/**
60
-	 * Create an action log entry from a database record.
61
-	 *
62
-	 * @param object $record Log entry database record object.
63
-	 *
64
-	 * @return ActionScheduler_LogEntry
65
-	 */
66
-	private function create_entry_from_db_record( $record ) {
67
-		if ( empty( $record ) ) {
68
-			return new ActionScheduler_NullLogEntry();
69
-		}
70
-
71
-		$date = as_get_datetime_object( $record->log_date_gmt );
72
-
73
-		return new ActionScheduler_LogEntry( $record->action_id, $record->message, $date );
74
-	}
75
-
76
-	/**
77
-	 * Retrieve the an action's log entries from the database.
78
-	 *
79
-	 * @param int $action_id Action ID.
80
-	 *
81
-	 * @return ActionScheduler_LogEntry[]
82
-	 */
83
-	public function get_logs( $action_id ) {
84
-		/** @var \wpdb $wpdb */
85
-		global $wpdb;
86
-
87
-		$records = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->actionscheduler_logs} WHERE action_id=%d", $action_id ) );
88
-
89
-		return array_map( [ $this, 'create_entry_from_db_record' ], $records );
90
-	}
91
-
92
-	/**
93
-	 * Initialize the data store.
94
-	 *
95
-	 * @codeCoverageIgnore
96
-	 */
97
-	public function init() {
98
-
99
-		$table_maker = new ActionScheduler_LoggerSchema();
100
-		$table_maker->register_tables();
101
-
102
-		parent::init();
103
-
104
-		add_action( 'action_scheduler_deleted_action', [ $this, 'clear_deleted_action_logs' ], 10, 1 );
105
-	}
106
-
107
-	/**
108
-	 * Delete the action logs for an action.
109
-	 *
110
-	 * @param int $action_id Action ID.
111
-	 */
112
-	public function clear_deleted_action_logs( $action_id ) {
113
-		/** @var \wpdb $wpdb */
114
-		global $wpdb;
115
-		$wpdb->delete( $wpdb->actionscheduler_logs, [ 'action_id' => $action_id, ], [ '%d' ] );
116
-	}
117
-
118
-	/**
119
-	 * Bulk add cancel action log entries.
120
-	 *
121
-	 * @param array $action_ids List of action ID.
122
-	 */
123
-	public function bulk_log_cancel_actions( $action_ids ) {
124
-		if ( empty( $action_ids ) ) {
125
-			return;
126
-		}
127
-
128
-		/** @var \wpdb $wpdb */
129
-		global $wpdb;
130
-		$date     = as_get_datetime_object();
131
-		$date_gmt = $date->format( 'Y-m-d H:i:s' );
132
-		ActionScheduler_TimezoneHelper::set_local_timezone( $date );
133
-		$date_local = $date->format( 'Y-m-d H:i:s' );
134
-		$message    = __( 'action canceled', 'action-scheduler' );
135
-		$format     = '(%d, ' . $wpdb->prepare( '%s, %s, %s', $message, $date_gmt, $date_local ) . ')';
136
-		$sql_query  = "INSERT {$wpdb->actionscheduler_logs} (action_id, message, log_date_gmt, log_date_local) VALUES ";
137
-		$value_rows = [];
138
-
139
-		foreach ( $action_ids as $action_id ) {
140
-			$value_rows[] = $wpdb->prepare( $format, $action_id );
141
-		}
142
-		$sql_query .= implode( ',', $value_rows );
143
-
144
-		$wpdb->query( $sql_query );
145
-	}
12
+    /**
13
+     * Add a record to an action log.
14
+     *
15
+     * @param int      $action_id Action ID.
16
+     * @param string   $message Message to be saved in the log entry.
17
+     * @param DateTime $date Timestamp of the log entry.
18
+     *
19
+     * @return int     The log entry ID.
20
+     */
21
+    public function log( $action_id, $message, DateTime $date = null ) {
22
+        if ( empty( $date ) ) {
23
+            $date = as_get_datetime_object();
24
+        } else {
25
+            $date = clone $date;
26
+        }
27
+
28
+        $date_gmt = $date->format( 'Y-m-d H:i:s' );
29
+        ActionScheduler_TimezoneHelper::set_local_timezone( $date );
30
+        $date_local = $date->format( 'Y-m-d H:i:s' );
31
+
32
+        /** @var \wpdb $wpdb */
33
+        global $wpdb;
34
+        $wpdb->insert( $wpdb->actionscheduler_logs, [
35
+            'action_id'      => $action_id,
36
+            'message'        => $message,
37
+            'log_date_gmt'   => $date_gmt,
38
+            'log_date_local' => $date_local,
39
+        ], [ '%d', '%s', '%s', '%s' ] );
40
+
41
+        return $wpdb->insert_id;
42
+    }
43
+
44
+    /**
45
+     * Retrieve an action log entry.
46
+     *
47
+     * @param int $entry_id Log entry ID.
48
+     *
49
+     * @return ActionScheduler_LogEntry
50
+     */
51
+    public function get_entry( $entry_id ) {
52
+        /** @var \wpdb $wpdb */
53
+        global $wpdb;
54
+        $entry = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->actionscheduler_logs} WHERE log_id=%d", $entry_id ) );
55
+
56
+        return $this->create_entry_from_db_record( $entry );
57
+    }
58
+
59
+    /**
60
+     * Create an action log entry from a database record.
61
+     *
62
+     * @param object $record Log entry database record object.
63
+     *
64
+     * @return ActionScheduler_LogEntry
65
+     */
66
+    private function create_entry_from_db_record( $record ) {
67
+        if ( empty( $record ) ) {
68
+            return new ActionScheduler_NullLogEntry();
69
+        }
70
+
71
+        $date = as_get_datetime_object( $record->log_date_gmt );
72
+
73
+        return new ActionScheduler_LogEntry( $record->action_id, $record->message, $date );
74
+    }
75
+
76
+    /**
77
+     * Retrieve the an action's log entries from the database.
78
+     *
79
+     * @param int $action_id Action ID.
80
+     *
81
+     * @return ActionScheduler_LogEntry[]
82
+     */
83
+    public function get_logs( $action_id ) {
84
+        /** @var \wpdb $wpdb */
85
+        global $wpdb;
86
+
87
+        $records = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->actionscheduler_logs} WHERE action_id=%d", $action_id ) );
88
+
89
+        return array_map( [ $this, 'create_entry_from_db_record' ], $records );
90
+    }
91
+
92
+    /**
93
+     * Initialize the data store.
94
+     *
95
+     * @codeCoverageIgnore
96
+     */
97
+    public function init() {
98
+
99
+        $table_maker = new ActionScheduler_LoggerSchema();
100
+        $table_maker->register_tables();
101
+
102
+        parent::init();
103
+
104
+        add_action( 'action_scheduler_deleted_action', [ $this, 'clear_deleted_action_logs' ], 10, 1 );
105
+    }
106
+
107
+    /**
108
+     * Delete the action logs for an action.
109
+     *
110
+     * @param int $action_id Action ID.
111
+     */
112
+    public function clear_deleted_action_logs( $action_id ) {
113
+        /** @var \wpdb $wpdb */
114
+        global $wpdb;
115
+        $wpdb->delete( $wpdb->actionscheduler_logs, [ 'action_id' => $action_id, ], [ '%d' ] );
116
+    }
117
+
118
+    /**
119
+     * Bulk add cancel action log entries.
120
+     *
121
+     * @param array $action_ids List of action ID.
122
+     */
123
+    public function bulk_log_cancel_actions( $action_ids ) {
124
+        if ( empty( $action_ids ) ) {
125
+            return;
126
+        }
127
+
128
+        /** @var \wpdb $wpdb */
129
+        global $wpdb;
130
+        $date     = as_get_datetime_object();
131
+        $date_gmt = $date->format( 'Y-m-d H:i:s' );
132
+        ActionScheduler_TimezoneHelper::set_local_timezone( $date );
133
+        $date_local = $date->format( 'Y-m-d H:i:s' );
134
+        $message    = __( 'action canceled', 'action-scheduler' );
135
+        $format     = '(%d, ' . $wpdb->prepare( '%s, %s, %s', $message, $date_gmt, $date_local ) . ')';
136
+        $sql_query  = "INSERT {$wpdb->actionscheduler_logs} (action_id, message, log_date_gmt, log_date_local) VALUES ";
137
+        $value_rows = [];
138
+
139
+        foreach ( $action_ids as $action_id ) {
140
+            $value_rows[] = $wpdb->prepare( $format, $action_id );
141
+        }
142
+        $sql_query .= implode( ',', $value_rows );
143
+
144
+        $wpdb->query( $sql_query );
145
+    }
146 146
 }
Please login to merge, or discard this patch.
Spacing   +31 added lines, -31 removed lines patch added patch discarded remove patch
@@ -18,25 +18,25 @@  discard block
 block discarded – undo
18 18
 	 *
19 19
 	 * @return int     The log entry ID.
20 20
 	 */
21
-	public function log( $action_id, $message, DateTime $date = null ) {
22
-		if ( empty( $date ) ) {
21
+	public function log($action_id, $message, DateTime $date = null) {
22
+		if (empty($date)) {
23 23
 			$date = as_get_datetime_object();
24 24
 		} else {
25 25
 			$date = clone $date;
26 26
 		}
27 27
 
28
-		$date_gmt = $date->format( 'Y-m-d H:i:s' );
29
-		ActionScheduler_TimezoneHelper::set_local_timezone( $date );
30
-		$date_local = $date->format( 'Y-m-d H:i:s' );
28
+		$date_gmt = $date->format('Y-m-d H:i:s');
29
+		ActionScheduler_TimezoneHelper::set_local_timezone($date);
30
+		$date_local = $date->format('Y-m-d H:i:s');
31 31
 
32 32
 		/** @var \wpdb $wpdb */
33 33
 		global $wpdb;
34
-		$wpdb->insert( $wpdb->actionscheduler_logs, [
34
+		$wpdb->insert($wpdb->actionscheduler_logs, [
35 35
 			'action_id'      => $action_id,
36 36
 			'message'        => $message,
37 37
 			'log_date_gmt'   => $date_gmt,
38 38
 			'log_date_local' => $date_local,
39
-		], [ '%d', '%s', '%s', '%s' ] );
39
+		], ['%d', '%s', '%s', '%s']);
40 40
 
41 41
 		return $wpdb->insert_id;
42 42
 	}
@@ -48,12 +48,12 @@  discard block
 block discarded – undo
48 48
 	 *
49 49
 	 * @return ActionScheduler_LogEntry
50 50
 	 */
51
-	public function get_entry( $entry_id ) {
51
+	public function get_entry($entry_id) {
52 52
 		/** @var \wpdb $wpdb */
53 53
 		global $wpdb;
54
-		$entry = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->actionscheduler_logs} WHERE log_id=%d", $entry_id ) );
54
+		$entry = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->actionscheduler_logs} WHERE log_id=%d", $entry_id));
55 55
 
56
-		return $this->create_entry_from_db_record( $entry );
56
+		return $this->create_entry_from_db_record($entry);
57 57
 	}
58 58
 
59 59
 	/**
@@ -63,14 +63,14 @@  discard block
 block discarded – undo
63 63
 	 *
64 64
 	 * @return ActionScheduler_LogEntry
65 65
 	 */
66
-	private function create_entry_from_db_record( $record ) {
67
-		if ( empty( $record ) ) {
66
+	private function create_entry_from_db_record($record) {
67
+		if (empty($record)) {
68 68
 			return new ActionScheduler_NullLogEntry();
69 69
 		}
70 70
 
71
-		$date = as_get_datetime_object( $record->log_date_gmt );
71
+		$date = as_get_datetime_object($record->log_date_gmt);
72 72
 
73
-		return new ActionScheduler_LogEntry( $record->action_id, $record->message, $date );
73
+		return new ActionScheduler_LogEntry($record->action_id, $record->message, $date);
74 74
 	}
75 75
 
76 76
 	/**
@@ -80,13 +80,13 @@  discard block
 block discarded – undo
80 80
 	 *
81 81
 	 * @return ActionScheduler_LogEntry[]
82 82
 	 */
83
-	public function get_logs( $action_id ) {
83
+	public function get_logs($action_id) {
84 84
 		/** @var \wpdb $wpdb */
85 85
 		global $wpdb;
86 86
 
87
-		$records = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->actionscheduler_logs} WHERE action_id=%d", $action_id ) );
87
+		$records = $wpdb->get_results($wpdb->prepare("SELECT * FROM {$wpdb->actionscheduler_logs} WHERE action_id=%d", $action_id));
88 88
 
89
-		return array_map( [ $this, 'create_entry_from_db_record' ], $records );
89
+		return array_map([$this, 'create_entry_from_db_record'], $records);
90 90
 	}
91 91
 
92 92
 	/**
@@ -101,7 +101,7 @@  discard block
 block discarded – undo
101 101
 
102 102
 		parent::init();
103 103
 
104
-		add_action( 'action_scheduler_deleted_action', [ $this, 'clear_deleted_action_logs' ], 10, 1 );
104
+		add_action('action_scheduler_deleted_action', [$this, 'clear_deleted_action_logs'], 10, 1);
105 105
 	}
106 106
 
107 107
 	/**
@@ -109,10 +109,10 @@  discard block
 block discarded – undo
109 109
 	 *
110 110
 	 * @param int $action_id Action ID.
111 111
 	 */
112
-	public function clear_deleted_action_logs( $action_id ) {
112
+	public function clear_deleted_action_logs($action_id) {
113 113
 		/** @var \wpdb $wpdb */
114 114
 		global $wpdb;
115
-		$wpdb->delete( $wpdb->actionscheduler_logs, [ 'action_id' => $action_id, ], [ '%d' ] );
115
+		$wpdb->delete($wpdb->actionscheduler_logs, ['action_id' => $action_id, ], ['%d']);
116 116
 	}
117 117
 
118 118
 	/**
@@ -120,27 +120,27 @@  discard block
 block discarded – undo
120 120
 	 *
121 121
 	 * @param array $action_ids List of action ID.
122 122
 	 */
123
-	public function bulk_log_cancel_actions( $action_ids ) {
124
-		if ( empty( $action_ids ) ) {
123
+	public function bulk_log_cancel_actions($action_ids) {
124
+		if (empty($action_ids)) {
125 125
 			return;
126 126
 		}
127 127
 
128 128
 		/** @var \wpdb $wpdb */
129 129
 		global $wpdb;
130 130
 		$date     = as_get_datetime_object();
131
-		$date_gmt = $date->format( 'Y-m-d H:i:s' );
132
-		ActionScheduler_TimezoneHelper::set_local_timezone( $date );
133
-		$date_local = $date->format( 'Y-m-d H:i:s' );
134
-		$message    = __( 'action canceled', 'action-scheduler' );
135
-		$format     = '(%d, ' . $wpdb->prepare( '%s, %s, %s', $message, $date_gmt, $date_local ) . ')';
131
+		$date_gmt = $date->format('Y-m-d H:i:s');
132
+		ActionScheduler_TimezoneHelper::set_local_timezone($date);
133
+		$date_local = $date->format('Y-m-d H:i:s');
134
+		$message    = __('action canceled', 'action-scheduler');
135
+		$format     = '(%d, ' . $wpdb->prepare('%s, %s, %s', $message, $date_gmt, $date_local) . ')';
136 136
 		$sql_query  = "INSERT {$wpdb->actionscheduler_logs} (action_id, message, log_date_gmt, log_date_local) VALUES ";
137 137
 		$value_rows = [];
138 138
 
139
-		foreach ( $action_ids as $action_id ) {
140
-			$value_rows[] = $wpdb->prepare( $format, $action_id );
139
+		foreach ($action_ids as $action_id) {
140
+			$value_rows[] = $wpdb->prepare($format, $action_id);
141 141
 		}
142
-		$sql_query .= implode( ',', $value_rows );
142
+		$sql_query .= implode(',', $value_rows);
143 143
 
144
-		$wpdb->query( $sql_query );
144
+		$wpdb->query($sql_query);
145 145
 	}
146 146
 }
Please login to merge, or discard this patch.
classes/data-stores/ActionScheduler_wpPostStore_TaxonomyRegistrar.php 2 patches
Indentation   +16 added lines, -16 removed lines patch added patch discarded remove patch
@@ -5,22 +5,22 @@
 block discarded – undo
5 5
  * @codeCoverageIgnore
6 6
  */
7 7
 class ActionScheduler_wpPostStore_TaxonomyRegistrar {
8
-	public function register() {
9
-		register_taxonomy( ActionScheduler_wpPostStore::GROUP_TAXONOMY, ActionScheduler_wpPostStore::POST_TYPE, $this->taxonomy_args() );
10
-	}
8
+    public function register() {
9
+        register_taxonomy( ActionScheduler_wpPostStore::GROUP_TAXONOMY, ActionScheduler_wpPostStore::POST_TYPE, $this->taxonomy_args() );
10
+    }
11 11
 
12
-	protected function taxonomy_args() {
13
-		$args = array(
14
-			'label' => __( 'Action Group', 'action-scheduler' ),
15
-			'public' => false,
16
-			'hierarchical' => false,
17
-			'show_admin_column' => true,
18
-			'query_var' => false,
19
-			'rewrite' => false,
20
-		);
12
+    protected function taxonomy_args() {
13
+        $args = array(
14
+            'label' => __( 'Action Group', 'action-scheduler' ),
15
+            'public' => false,
16
+            'hierarchical' => false,
17
+            'show_admin_column' => true,
18
+            'query_var' => false,
19
+            'rewrite' => false,
20
+        );
21 21
 
22
-		$args = apply_filters( 'action_scheduler_taxonomy_args', $args );
23
-		return $args;
24
-	}
22
+        $args = apply_filters( 'action_scheduler_taxonomy_args', $args );
23
+        return $args;
24
+    }
25 25
 }
26
- 
27 26
\ No newline at end of file
27
+    
28 28
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -6,12 +6,12 @@  discard block
 block discarded – undo
6 6
  */
7 7
 class ActionScheduler_wpPostStore_TaxonomyRegistrar {
8 8
 	public function register() {
9
-		register_taxonomy( ActionScheduler_wpPostStore::GROUP_TAXONOMY, ActionScheduler_wpPostStore::POST_TYPE, $this->taxonomy_args() );
9
+		register_taxonomy(ActionScheduler_wpPostStore::GROUP_TAXONOMY, ActionScheduler_wpPostStore::POST_TYPE, $this->taxonomy_args());
10 10
 	}
11 11
 
12 12
 	protected function taxonomy_args() {
13 13
 		$args = array(
14
-			'label' => __( 'Action Group', 'action-scheduler' ),
14
+			'label' => __('Action Group', 'action-scheduler'),
15 15
 			'public' => false,
16 16
 			'hierarchical' => false,
17 17
 			'show_admin_column' => true,
@@ -19,7 +19,7 @@  discard block
 block discarded – undo
19 19
 			'rewrite' => false,
20 20
 		);
21 21
 
22
-		$args = apply_filters( 'action_scheduler_taxonomy_args', $args );
22
+		$args = apply_filters('action_scheduler_taxonomy_args', $args);
23 23
 		return $args;
24 24
 	}
25 25
 }
Please login to merge, or discard this patch.
classes/data-stores/ActionScheduler_wpPostStore_PostTypeRegistrar.php 2 patches
Indentation   +40 added lines, -40 removed lines patch added patch discarded remove patch
@@ -5,46 +5,46 @@
 block discarded – undo
5 5
  * @codeCoverageIgnore
6 6
  */
7 7
 class ActionScheduler_wpPostStore_PostTypeRegistrar {
8
-	public function register() {
9
-		register_post_type( ActionScheduler_wpPostStore::POST_TYPE, $this->post_type_args() );
10
-	}
8
+    public function register() {
9
+        register_post_type( ActionScheduler_wpPostStore::POST_TYPE, $this->post_type_args() );
10
+    }
11 11
 
12
-	/**
13
-	 * Build the args array for the post type definition
14
-	 *
15
-	 * @return array
16
-	 */
17
-	protected function post_type_args() {
18
-		$args = array(
19
-			'label' => __( 'Scheduled Actions', 'action-scheduler' ),
20
-			'description' => __( 'Scheduled actions are hooks triggered on a cetain date and time.', 'action-scheduler' ),
21
-			'public' => false,
22
-			'map_meta_cap' => true,
23
-			'hierarchical' => false,
24
-			'supports' => array('title', 'editor','comments'),
25
-			'rewrite' => false,
26
-			'query_var' => false,
27
-			'can_export' => true,
28
-			'ep_mask' => EP_NONE,
29
-			'labels' => array(
30
-				'name' => __( 'Scheduled Actions', 'action-scheduler' ),
31
-				'singular_name' => __( 'Scheduled Action', 'action-scheduler' ),
32
-				'menu_name' => _x( 'Scheduled Actions', 'Admin menu name', 'action-scheduler' ),
33
-				'add_new' => __( 'Add', 'action-scheduler' ),
34
-				'add_new_item' => __( 'Add New Scheduled Action', 'action-scheduler' ),
35
-				'edit' => __( 'Edit', 'action-scheduler' ),
36
-				'edit_item' => __( 'Edit Scheduled Action', 'action-scheduler' ),
37
-				'new_item' => __( 'New Scheduled Action', 'action-scheduler' ),
38
-				'view' => __( 'View Action', 'action-scheduler' ),
39
-				'view_item' => __( 'View Action', 'action-scheduler' ),
40
-				'search_items' => __( 'Search Scheduled Actions', 'action-scheduler' ),
41
-				'not_found' => __( 'No actions found', 'action-scheduler' ),
42
-				'not_found_in_trash' => __( 'No actions found in trash', 'action-scheduler' ),
43
-			),
44
-		);
12
+    /**
13
+     * Build the args array for the post type definition
14
+     *
15
+     * @return array
16
+     */
17
+    protected function post_type_args() {
18
+        $args = array(
19
+            'label' => __( 'Scheduled Actions', 'action-scheduler' ),
20
+            'description' => __( 'Scheduled actions are hooks triggered on a cetain date and time.', 'action-scheduler' ),
21
+            'public' => false,
22
+            'map_meta_cap' => true,
23
+            'hierarchical' => false,
24
+            'supports' => array('title', 'editor','comments'),
25
+            'rewrite' => false,
26
+            'query_var' => false,
27
+            'can_export' => true,
28
+            'ep_mask' => EP_NONE,
29
+            'labels' => array(
30
+                'name' => __( 'Scheduled Actions', 'action-scheduler' ),
31
+                'singular_name' => __( 'Scheduled Action', 'action-scheduler' ),
32
+                'menu_name' => _x( 'Scheduled Actions', 'Admin menu name', 'action-scheduler' ),
33
+                'add_new' => __( 'Add', 'action-scheduler' ),
34
+                'add_new_item' => __( 'Add New Scheduled Action', 'action-scheduler' ),
35
+                'edit' => __( 'Edit', 'action-scheduler' ),
36
+                'edit_item' => __( 'Edit Scheduled Action', 'action-scheduler' ),
37
+                'new_item' => __( 'New Scheduled Action', 'action-scheduler' ),
38
+                'view' => __( 'View Action', 'action-scheduler' ),
39
+                'view_item' => __( 'View Action', 'action-scheduler' ),
40
+                'search_items' => __( 'Search Scheduled Actions', 'action-scheduler' ),
41
+                'not_found' => __( 'No actions found', 'action-scheduler' ),
42
+                'not_found_in_trash' => __( 'No actions found in trash', 'action-scheduler' ),
43
+            ),
44
+        );
45 45
 
46
-		$args = apply_filters('action_scheduler_post_type_args', $args);
47
-		return $args;
48
-	}
46
+        $args = apply_filters('action_scheduler_post_type_args', $args);
47
+        return $args;
48
+    }
49 49
 }
50
- 
51 50
\ No newline at end of file
51
+    
52 52
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +17 added lines, -17 removed lines patch added patch discarded remove patch
@@ -6,7 +6,7 @@  discard block
 block discarded – undo
6 6
  */
7 7
 class ActionScheduler_wpPostStore_PostTypeRegistrar {
8 8
 	public function register() {
9
-		register_post_type( ActionScheduler_wpPostStore::POST_TYPE, $this->post_type_args() );
9
+		register_post_type(ActionScheduler_wpPostStore::POST_TYPE, $this->post_type_args());
10 10
 	}
11 11
 
12 12
 	/**
@@ -16,30 +16,30 @@  discard block
 block discarded – undo
16 16
 	 */
17 17
 	protected function post_type_args() {
18 18
 		$args = array(
19
-			'label' => __( 'Scheduled Actions', 'action-scheduler' ),
20
-			'description' => __( 'Scheduled actions are hooks triggered on a cetain date and time.', 'action-scheduler' ),
19
+			'label' => __('Scheduled Actions', 'action-scheduler'),
20
+			'description' => __('Scheduled actions are hooks triggered on a cetain date and time.', 'action-scheduler'),
21 21
 			'public' => false,
22 22
 			'map_meta_cap' => true,
23 23
 			'hierarchical' => false,
24
-			'supports' => array('title', 'editor','comments'),
24
+			'supports' => array('title', 'editor', 'comments'),
25 25
 			'rewrite' => false,
26 26
 			'query_var' => false,
27 27
 			'can_export' => true,
28 28
 			'ep_mask' => EP_NONE,
29 29
 			'labels' => array(
30
-				'name' => __( 'Scheduled Actions', 'action-scheduler' ),
31
-				'singular_name' => __( 'Scheduled Action', 'action-scheduler' ),
32
-				'menu_name' => _x( 'Scheduled Actions', 'Admin menu name', 'action-scheduler' ),
33
-				'add_new' => __( 'Add', 'action-scheduler' ),
34
-				'add_new_item' => __( 'Add New Scheduled Action', 'action-scheduler' ),
35
-				'edit' => __( 'Edit', 'action-scheduler' ),
36
-				'edit_item' => __( 'Edit Scheduled Action', 'action-scheduler' ),
37
-				'new_item' => __( 'New Scheduled Action', 'action-scheduler' ),
38
-				'view' => __( 'View Action', 'action-scheduler' ),
39
-				'view_item' => __( 'View Action', 'action-scheduler' ),
40
-				'search_items' => __( 'Search Scheduled Actions', 'action-scheduler' ),
41
-				'not_found' => __( 'No actions found', 'action-scheduler' ),
42
-				'not_found_in_trash' => __( 'No actions found in trash', 'action-scheduler' ),
30
+				'name' => __('Scheduled Actions', 'action-scheduler'),
31
+				'singular_name' => __('Scheduled Action', 'action-scheduler'),
32
+				'menu_name' => _x('Scheduled Actions', 'Admin menu name', 'action-scheduler'),
33
+				'add_new' => __('Add', 'action-scheduler'),
34
+				'add_new_item' => __('Add New Scheduled Action', 'action-scheduler'),
35
+				'edit' => __('Edit', 'action-scheduler'),
36
+				'edit_item' => __('Edit Scheduled Action', 'action-scheduler'),
37
+				'new_item' => __('New Scheduled Action', 'action-scheduler'),
38
+				'view' => __('View Action', 'action-scheduler'),
39
+				'view_item' => __('View Action', 'action-scheduler'),
40
+				'search_items' => __('Search Scheduled Actions', 'action-scheduler'),
41
+				'not_found' => __('No actions found', 'action-scheduler'),
42
+				'not_found_in_trash' => __('No actions found in trash', 'action-scheduler'),
43 43
 			),
44 44
 		);
45 45
 
Please login to merge, or discard this patch.
libraries/action-scheduler/classes/data-stores/ActionScheduler_DBStore.php 3 patches
Indentation   +833 added lines, -833 removed lines patch added patch discarded remove patch
@@ -9,837 +9,837 @@
 block discarded – undo
9 9
  */
10 10
 class ActionScheduler_DBStore extends ActionScheduler_Store {
11 11
 
12
-	/** @var int */
13
-	protected static $max_args_length = 8000;
14
-
15
-	/** @var int */
16
-	protected static $max_index_length = 191;
17
-
18
-	/**
19
-	 * Initialize the data store
20
-	 *
21
-	 * @codeCoverageIgnore
22
-	 */
23
-	public function init() {
24
-		$table_maker = new ActionScheduler_StoreSchema();
25
-		$table_maker->register_tables();
26
-	}
27
-
28
-	/**
29
-	 * Save an action.
30
-	 *
31
-	 * @param ActionScheduler_Action $action Action object.
32
-	 * @param DateTime               $date Optional schedule date. Default null.
33
-	 *
34
-	 * @return int Action ID.
35
-	 */
36
-	public function save_action( ActionScheduler_Action $action, \DateTime $date = null ) {
37
-		try {
38
-
39
-			$this->validate_action( $action );
40
-
41
-			/** @var \wpdb $wpdb */
42
-			global $wpdb;
43
-			$data = [
44
-				'hook'                 => $action->get_hook(),
45
-				'status'               => ( $action->is_finished() ? self::STATUS_COMPLETE : self::STATUS_PENDING ),
46
-				'scheduled_date_gmt'   => $this->get_scheduled_date_string( $action, $date ),
47
-				'scheduled_date_local' => $this->get_scheduled_date_string_local( $action, $date ),
48
-				'schedule'             => serialize( $action->get_schedule() ),
49
-				'group_id'             => $this->get_group_id( $action->get_group() ),
50
-			];
51
-			$args = wp_json_encode( $action->get_args() );
52
-			if ( strlen( $args ) <= static::$max_index_length ) {
53
-				$data['args'] = $args;
54
-			} else {
55
-				$data['args']          = $this->hash_args( $args );
56
-				$data['extended_args'] = $args;
57
-			}
58
-
59
-			$table_name = ! empty( $wpdb->actionscheduler_actions ) ? $wpdb->actionscheduler_actions : $wpdb->prefix . 'actionscheduler_actions';
60
-			$wpdb->insert( $table_name, $data );
61
-			$action_id = $wpdb->insert_id;
62
-
63
-			if ( is_wp_error( $action_id ) ) {
64
-				throw new RuntimeException( $action_id->get_error_message() );
65
-			}
66
-			elseif ( empty( $action_id ) ) {
67
-				throw new RuntimeException( $wpdb->last_error ? $wpdb->last_error : __( 'Database error.', 'action-scheduler' ) );
68
-			}
69
-
70
-			do_action( 'action_scheduler_stored_action', $action_id );
71
-
72
-			return $action_id;
73
-		} catch ( \Exception $e ) {
74
-			/* translators: %s: error message */
75
-			throw new \RuntimeException( sprintf( __( 'Error saving action: %s', 'action-scheduler' ), $e->getMessage() ), 0 );
76
-		}
77
-	}
78
-
79
-	/**
80
-	 * Generate a hash from json_encoded $args using MD5 as this isn't for security.
81
-	 *
82
-	 * @param string $args JSON encoded action args.
83
-	 * @return string
84
-	 */
85
-	protected function hash_args( $args ) {
86
-		return md5( $args );
87
-	}
88
-
89
-	/**
90
-	 * Get action args query param value from action args.
91
-	 *
92
-	 * @param array $args Action args.
93
-	 * @return string
94
-	 */
95
-	protected function get_args_for_query( $args ) {
96
-		$encoded = wp_json_encode( $args );
97
-		if ( strlen( $encoded ) <= static::$max_index_length ) {
98
-			return $encoded;
99
-		}
100
-		return $this->hash_args( $encoded );
101
-	}
102
-	/**
103
-	 * Get a group's ID based on its name/slug.
104
-	 *
105
-	 * @param string $slug The string name of a group.
106
-	 * @param bool $create_if_not_exists Whether to create the group if it does not already exist. Default, true - create the group.
107
-	 *
108
-	 * @return int The group's ID, if it exists or is created, or 0 if it does not exist and is not created.
109
-	 */
110
-	protected function get_group_id( $slug, $create_if_not_exists = true ) {
111
-		if ( empty( $slug ) ) {
112
-			return 0;
113
-		}
114
-		/** @var \wpdb $wpdb */
115
-		global $wpdb;
116
-		$group_id = (int) $wpdb->get_var( $wpdb->prepare( "SELECT group_id FROM {$wpdb->actionscheduler_groups} WHERE slug=%s", $slug ) );
117
-		if ( empty( $group_id ) && $create_if_not_exists ) {
118
-			$group_id = $this->create_group( $slug );
119
-		}
120
-
121
-		return $group_id;
122
-	}
123
-
124
-	/**
125
-	 * Create an action group.
126
-	 *
127
-	 * @param string $slug Group slug.
128
-	 *
129
-	 * @return int Group ID.
130
-	 */
131
-	protected function create_group( $slug ) {
132
-		/** @var \wpdb $wpdb */
133
-		global $wpdb;
134
-		$wpdb->insert( $wpdb->actionscheduler_groups, [ 'slug' => $slug ] );
135
-
136
-		return (int) $wpdb->insert_id;
137
-	}
138
-
139
-	/**
140
-	 * Retrieve an action.
141
-	 *
142
-	 * @param int $action_id Action ID.
143
-	 *
144
-	 * @return ActionScheduler_Action
145
-	 */
146
-	public function fetch_action( $action_id ) {
147
-		/** @var \wpdb $wpdb */
148
-		global $wpdb;
149
-		$data = $wpdb->get_row( $wpdb->prepare(
150
-			"SELECT a.*, g.slug AS `group` FROM {$wpdb->actionscheduler_actions} a LEFT JOIN {$wpdb->actionscheduler_groups} g ON a.group_id=g.group_id WHERE a.action_id=%d",
151
-			$action_id
152
-		) );
153
-
154
-		if ( empty( $data ) ) {
155
-			return $this->get_null_action();
156
-		}
157
-
158
-		if ( ! empty( $data->extended_args ) ) {
159
-			$data->args = $data->extended_args;
160
-			unset( $data->extended_args );
161
-		}
162
-
163
-		try {
164
-			$action = $this->make_action_from_db_record( $data );
165
-		} catch ( ActionScheduler_InvalidActionException $exception ) {
166
-			do_action( 'action_scheduler_failed_fetch_action', $action_id, $exception );
167
-			return $this->get_null_action();
168
-		}
169
-
170
-		return $action;
171
-	}
172
-
173
-	/**
174
-	 * Create a null action.
175
-	 *
176
-	 * @return ActionScheduler_NullAction
177
-	 */
178
-	protected function get_null_action() {
179
-		return new ActionScheduler_NullAction();
180
-	}
181
-
182
-	/**
183
-	 * Create an action from a database record.
184
-	 *
185
-	 * @param object $data Action database record.
186
-	 *
187
-	 * @return ActionScheduler_Action|ActionScheduler_CanceledAction|ActionScheduler_FinishedAction
188
-	 */
189
-	protected function make_action_from_db_record( $data ) {
190
-
191
-		$hook     = $data->hook;
192
-		$args     = json_decode( $data->args, true );
193
-		$schedule = unserialize( $data->schedule );
194
-
195
-		$this->validate_args( $args, $data->action_id );
196
-		$this->validate_schedule( $schedule, $data->action_id );
197
-
198
-		if ( empty( $schedule ) ) {
199
-			$schedule = new ActionScheduler_NullSchedule();
200
-		}
201
-		$group = $data->group ? $data->group : '';
202
-
203
-		return ActionScheduler::factory()->get_stored_action( $data->status, $data->hook, $args, $schedule, $group );
204
-	}
205
-
206
-	/**
207
-	 * Find an action.
208
-	 *
209
-	 * @param string $hook Action hook.
210
-	 * @param array  $params Parameters of the action to find.
211
-	 *
212
-	 * @return string|null ID of the next action matching the criteria or NULL if not found.
213
-	 */
214
-	public function find_action( $hook, $params = [] ) {
215
-		$params = wp_parse_args( $params, [
216
-			'args'   => null,
217
-			'status' => self::STATUS_PENDING,
218
-			'group'  => '',
219
-		] );
220
-
221
-		/** @var wpdb $wpdb */
222
-		global $wpdb;
223
-		$query = "SELECT a.action_id FROM {$wpdb->actionscheduler_actions} a";
224
-		$args  = [];
225
-		if ( ! empty( $params[ 'group' ] ) ) {
226
-			$query  .= " INNER JOIN {$wpdb->actionscheduler_groups} g ON g.group_id=a.group_id AND g.slug=%s";
227
-			$args[] = $params[ 'group' ];
228
-		}
229
-		$query  .= " WHERE a.hook=%s";
230
-		$args[] = $hook;
231
-		if ( ! is_null( $params[ 'args' ] ) ) {
232
-			$query  .= " AND a.args=%s";
233
-			$args[] = $this->get_args_for_query( $params[ 'args' ] );
234
-		}
235
-
236
-		$order = 'ASC';
237
-		if ( ! empty( $params[ 'status' ] ) ) {
238
-			$query  .= " AND a.status=%s";
239
-			$args[] = $params[ 'status' ];
240
-
241
-			if ( self::STATUS_PENDING == $params[ 'status' ] ) {
242
-				$order = 'ASC'; // Find the next action that matches.
243
-			} else {
244
-				$order = 'DESC'; // Find the most recent action that matches.
245
-			}
246
-		}
247
-
248
-		$query .= " ORDER BY scheduled_date_gmt $order LIMIT 1";
249
-
250
-		$query = $wpdb->prepare( $query, $args );
251
-
252
-		$id = $wpdb->get_var( $query );
253
-
254
-		return $id;
255
-	}
256
-
257
-	/**
258
-	 * Returns the SQL statement to query (or count) actions.
259
-	 *
260
-	 * @param array  $query Filtering options.
261
-	 * @param string $select_or_count  Whether the SQL should select and return the IDs or just the row count.
262
-	 *
263
-	 * @return string SQL statement already properly escaped.
264
-	 */
265
-	protected function get_query_actions_sql( array $query, $select_or_count = 'select' ) {
266
-
267
-		if ( ! in_array( $select_or_count, array( 'select', 'count' ) ) ) {
268
-			throw new InvalidArgumentException( __( 'Invalid value for select or count parameter. Cannot query actions.', 'action-scheduler' ) );
269
-		}
270
-
271
-		$query = wp_parse_args( $query, [
272
-			'hook'             => '',
273
-			'args'             => null,
274
-			'date'             => null,
275
-			'date_compare'     => '<=',
276
-			'modified'         => null,
277
-			'modified_compare' => '<=',
278
-			'group'            => '',
279
-			'status'           => '',
280
-			'claimed'          => null,
281
-			'per_page'         => 5,
282
-			'offset'           => 0,
283
-			'orderby'          => 'date',
284
-			'order'            => 'ASC',
285
-		] );
286
-
287
-		/** @var \wpdb $wpdb */
288
-		global $wpdb;
289
-		$sql  = ( 'count' === $select_or_count ) ? 'SELECT count(a.action_id)' : 'SELECT a.action_id';
290
-		$sql .= " FROM {$wpdb->actionscheduler_actions} a";
291
-		$sql_params = [];
292
-
293
-		if ( ! empty( $query[ 'group' ] ) || 'group' === $query[ 'orderby' ] ) {
294
-			$sql .= " LEFT JOIN {$wpdb->actionscheduler_groups} g ON g.group_id=a.group_id";
295
-		}
296
-
297
-		$sql .= " WHERE 1=1";
298
-
299
-		if ( ! empty( $query[ 'group' ] ) ) {
300
-			$sql          .= " AND g.slug=%s";
301
-			$sql_params[] = $query[ 'group' ];
302
-		}
303
-
304
-		if ( $query[ 'hook' ] ) {
305
-			$sql          .= " AND a.hook=%s";
306
-			$sql_params[] = $query[ 'hook' ];
307
-		}
308
-		if ( ! is_null( $query[ 'args' ] ) ) {
309
-			$sql          .= " AND a.args=%s";
310
-			$sql_params[] = $this->get_args_for_query( $query[ 'args' ] );
311
-		}
312
-
313
-		if ( $query[ 'status' ] ) {
314
-			$sql          .= " AND a.status=%s";
315
-			$sql_params[] = $query[ 'status' ];
316
-		}
317
-
318
-		if ( $query[ 'date' ] instanceof \DateTime ) {
319
-			$date = clone $query[ 'date' ];
320
-			$date->setTimezone( new \DateTimeZone( 'UTC' ) );
321
-			$date_string  = $date->format( 'Y-m-d H:i:s' );
322
-			$comparator   = $this->validate_sql_comparator( $query[ 'date_compare' ] );
323
-			$sql          .= " AND a.scheduled_date_gmt $comparator %s";
324
-			$sql_params[] = $date_string;
325
-		}
326
-
327
-		if ( $query[ 'modified' ] instanceof \DateTime ) {
328
-			$modified = clone $query[ 'modified' ];
329
-			$modified->setTimezone( new \DateTimeZone( 'UTC' ) );
330
-			$date_string  = $modified->format( 'Y-m-d H:i:s' );
331
-			$comparator   = $this->validate_sql_comparator( $query[ 'modified_compare' ] );
332
-			$sql          .= " AND a.last_attempt_gmt $comparator %s";
333
-			$sql_params[] = $date_string;
334
-		}
335
-
336
-		if ( $query[ 'claimed' ] === true ) {
337
-			$sql .= " AND a.claim_id != 0";
338
-		} elseif ( $query[ 'claimed' ] === false ) {
339
-			$sql .= " AND a.claim_id = 0";
340
-		} elseif ( ! is_null( $query[ 'claimed' ] ) ) {
341
-			$sql          .= " AND a.claim_id = %d";
342
-			$sql_params[] = $query[ 'claimed' ];
343
-		}
344
-
345
-		if ( ! empty( $query['search'] ) ) {
346
-			$sql .= " AND (a.hook LIKE %s OR (a.extended_args IS NULL AND a.args LIKE %s) OR a.extended_args LIKE %s";
347
-			for( $i = 0; $i < 3; $i++ ) {
348
-				$sql_params[] = sprintf( '%%%s%%', $query['search'] );
349
-			}
350
-
351
-			$search_claim_id = (int) $query['search'];
352
-			if ( $search_claim_id ) {
353
-				$sql .= ' OR a.claim_id = %d';
354
-				$sql_params[] = $search_claim_id;
355
-			}
356
-
357
-			$sql .= ')';
358
-		}
359
-
360
-		if ( 'select' === $select_or_count ) {
361
-			switch ( $query['orderby'] ) {
362
-				case 'hook':
363
-					$orderby = 'a.hook';
364
-					break;
365
-				case 'group':
366
-					$orderby = 'g.slug';
367
-					break;
368
-				case 'modified':
369
-					$orderby = 'a.last_attempt_gmt';
370
-					break;
371
-				case 'date':
372
-				default:
373
-					$orderby = 'a.scheduled_date_gmt';
374
-					break;
375
-			}
376
-			if ( strtoupper( $query[ 'order' ] ) == 'ASC' ) {
377
-				$order = 'ASC';
378
-			} else {
379
-				$order = 'DESC';
380
-			}
381
-			$sql .= " ORDER BY $orderby $order";
382
-			if ( $query[ 'per_page' ] > 0 ) {
383
-				$sql          .= " LIMIT %d, %d";
384
-				$sql_params[] = $query[ 'offset' ];
385
-				$sql_params[] = $query[ 'per_page' ];
386
-			}
387
-		}
388
-
389
-		if ( ! empty( $sql_params ) ) {
390
-			$sql = $wpdb->prepare( $sql, $sql_params );
391
-		}
392
-
393
-		return $sql;
394
-	}
395
-
396
-	/**
397
-	 * Query for action count of list of action IDs.
398
-	 *
399
-	 * @param array  $query Query parameters.
400
-	 * @param string $query_type Whether to select or count the results. Default, select.
401
-	 *
402
-	 * @return null|string|array The IDs of actions matching the query
403
-	 */
404
-	public function query_actions( $query = [], $query_type = 'select' ) {
405
-		/** @var wpdb $wpdb */
406
-		global $wpdb;
407
-
408
-		$sql = $this->get_query_actions_sql( $query, $query_type );
409
-
410
-		return ( 'count' === $query_type ) ? $wpdb->get_var( $sql ) : $wpdb->get_col( $sql );
411
-	}
412
-
413
-	/**
414
-	 * Get a count of all actions in the store, grouped by status.
415
-	 *
416
-	 * @return array Set of 'status' => int $count pairs for statuses with 1 or more actions of that status.
417
-	 */
418
-	public function action_counts() {
419
-		global $wpdb;
420
-
421
-		$sql  = "SELECT a.status, count(a.status) as 'count'";
422
-		$sql .= " FROM {$wpdb->actionscheduler_actions} a";
423
-		$sql .= " GROUP BY a.status";
424
-
425
-		$actions_count_by_status = array();
426
-		$action_stati_and_labels = $this->get_status_labels();
427
-
428
-		foreach ( $wpdb->get_results( $sql ) as $action_data ) {
429
-			// Ignore any actions with invalid status
430
-			if ( array_key_exists( $action_data->status, $action_stati_and_labels ) ) {
431
-				$actions_count_by_status[ $action_data->status ] = $action_data->count;
432
-			}
433
-		}
434
-
435
-		return $actions_count_by_status;
436
-	}
437
-
438
-	/**
439
-	 * Cancel an action.
440
-	 *
441
-	 * @param int $action_id Action ID.
442
-	 *
443
-	 * @return void
444
-	 */
445
-	public function cancel_action( $action_id ) {
446
-		/** @var \wpdb $wpdb */
447
-		global $wpdb;
448
-
449
-		$updated = $wpdb->update(
450
-			$wpdb->actionscheduler_actions,
451
-			[ 'status' => self::STATUS_CANCELED ],
452
-			[ 'action_id' => $action_id ],
453
-			[ '%s' ],
454
-			[ '%d' ]
455
-		);
456
-		if ( empty( $updated ) ) {
457
-			/* translators: %s: action ID */
458
-			throw new \InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) );
459
-		}
460
-		do_action( 'action_scheduler_canceled_action', $action_id );
461
-	}
462
-
463
-	/**
464
-	 * Cancel pending actions by hook.
465
-	 *
466
-	 * @since 3.0.0
467
-	 *
468
-	 * @param string $hook Hook name.
469
-	 *
470
-	 * @return void
471
-	 */
472
-	public function cancel_actions_by_hook( $hook ) {
473
-		$this->bulk_cancel_actions( [ 'hook' => $hook ] );
474
-	}
475
-
476
-	/**
477
-	 * Cancel pending actions by group.
478
-	 *
479
-	 * @param string $group Group slug.
480
-	 *
481
-	 * @return void
482
-	 */
483
-	public function cancel_actions_by_group( $group ) {
484
-		$this->bulk_cancel_actions( [ 'group' => $group ] );
485
-	}
486
-
487
-	/**
488
-	 * Bulk cancel actions.
489
-	 *
490
-	 * @since 3.0.0
491
-	 *
492
-	 * @param array $query_args Query parameters.
493
-	 */
494
-	protected function bulk_cancel_actions( $query_args ) {
495
-		/** @var \wpdb $wpdb */
496
-		global $wpdb;
497
-
498
-		if ( ! is_array( $query_args ) ) {
499
-			return;
500
-		}
501
-
502
-		// Don't cancel actions that are already canceled.
503
-		if ( isset( $query_args['status'] ) && $query_args['status'] == self::STATUS_CANCELED ) {
504
-			return;
505
-		}
506
-
507
-		$action_ids = true;
508
-		$query_args = wp_parse_args(
509
-			$query_args,
510
-			[
511
-				'per_page' => 1000,
512
-				'status' => self::STATUS_PENDING,
513
-			]
514
-		);
515
-
516
-		while ( $action_ids ) {
517
-			$action_ids = $this->query_actions( $query_args );
518
-			if ( empty( $action_ids ) ) {
519
-				break;
520
-			}
521
-
522
-			$format     = array_fill( 0, count( $action_ids ), '%d' );
523
-			$query_in   = '(' . implode( ',', $format ) . ')';
524
-			$parameters = $action_ids;
525
-			array_unshift( $parameters, self::STATUS_CANCELED );
526
-
527
-			$wpdb->query(
528
-				$wpdb->prepare( // wpcs: PreparedSQLPlaceholders replacement count ok.
529
-					"UPDATE {$wpdb->actionscheduler_actions} SET status = %s WHERE action_id IN {$query_in}",
530
-					$parameters
531
-				)
532
-			);
533
-
534
-			do_action( 'action_scheduler_bulk_cancel_actions', $action_ids );
535
-		}
536
-	}
537
-
538
-	/**
539
-	 * Delete an action.
540
-	 *
541
-	 * @param int $action_id Action ID.
542
-	 */
543
-	public function delete_action( $action_id ) {
544
-		/** @var \wpdb $wpdb */
545
-		global $wpdb;
546
-		$deleted = $wpdb->delete( $wpdb->actionscheduler_actions, [ 'action_id' => $action_id ], [ '%d' ] );
547
-		if ( empty( $deleted ) ) {
548
-			throw new \InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) );
549
-		}
550
-		do_action( 'action_scheduler_deleted_action', $action_id );
551
-	}
552
-
553
-	/**
554
-	 * Get the schedule date for an action.
555
-	 *
556
-	 * @param string $action_id Action ID.
557
-	 *
558
-	 * @throws \InvalidArgumentException
559
-	 * @return \DateTime The local date the action is scheduled to run, or the date that it ran.
560
-	 */
561
-	public function get_date( $action_id ) {
562
-		$date = $this->get_date_gmt( $action_id );
563
-		ActionScheduler_TimezoneHelper::set_local_timezone( $date );
564
-		return $date;
565
-	}
566
-
567
-	/**
568
-	 * Get the GMT schedule date for an action.
569
-	 *
570
-	 * @param int $action_id Action ID.
571
-	 *
572
-	 * @throws \InvalidArgumentException
573
-	 * @return \DateTime The GMT date the action is scheduled to run, or the date that it ran.
574
-	 */
575
-	protected function get_date_gmt( $action_id ) {
576
-		/** @var \wpdb $wpdb */
577
-		global $wpdb;
578
-		$record = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->actionscheduler_actions} WHERE action_id=%d", $action_id ) );
579
-		if ( empty( $record ) ) {
580
-			throw new \InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) );
581
-		}
582
-		if ( $record->status == self::STATUS_PENDING ) {
583
-			return as_get_datetime_object( $record->scheduled_date_gmt );
584
-		} else {
585
-			return as_get_datetime_object( $record->last_attempt_gmt );
586
-		}
587
-	}
588
-
589
-	/**
590
-	 * Stake a claim on actions.
591
-	 *
592
-	 * @param int       $max_actions Maximum number of action to include in claim.
593
-	 * @param \DateTime $before_date Jobs must be schedule before this date. Defaults to now.
594
-	 *
595
-	 * @return ActionScheduler_ActionClaim
596
-	 */
597
-	public function stake_claim( $max_actions = 10, \DateTime $before_date = null, $hooks = array(), $group = '' ) {
598
-		$claim_id = $this->generate_claim_id();
599
-		$this->claim_actions( $claim_id, $max_actions, $before_date, $hooks, $group );
600
-		$action_ids = $this->find_actions_by_claim_id( $claim_id );
601
-
602
-		return new ActionScheduler_ActionClaim( $claim_id, $action_ids );
603
-	}
604
-
605
-	/**
606
-	 * Generate a new action claim.
607
-	 *
608
-	 * @return int Claim ID.
609
-	 */
610
-	protected function generate_claim_id() {
611
-		/** @var \wpdb $wpdb */
612
-		global $wpdb;
613
-		$now = as_get_datetime_object();
614
-		$wpdb->insert( $wpdb->actionscheduler_claims, [ 'date_created_gmt' => $now->format( 'Y-m-d H:i:s' ) ] );
615
-
616
-		return $wpdb->insert_id;
617
-	}
618
-
619
-	/**
620
-	 * Mark actions claimed.
621
-	 *
622
-	 * @param string    $claim_id Claim Id.
623
-	 * @param int       $limit Number of action to include in claim.
624
-	 * @param \DateTime $before_date Should use UTC timezone.
625
-	 *
626
-	 * @return int The number of actions that were claimed.
627
-	 * @throws \RuntimeException
628
-	 */
629
-	protected function claim_actions( $claim_id, $limit, \DateTime $before_date = null, $hooks = array(), $group = '' ) {
630
-		/** @var \wpdb $wpdb */
631
-		global $wpdb;
632
-
633
-		$now  = as_get_datetime_object();
634
-		$date = is_null( $before_date ) ? $now : clone $before_date;
635
-
636
-		// can't use $wpdb->update() because of the <= condition
637
-		$update = "UPDATE {$wpdb->actionscheduler_actions} SET claim_id=%d, last_attempt_gmt=%s, last_attempt_local=%s";
638
-		$params = array(
639
-			$claim_id,
640
-			$now->format( 'Y-m-d H:i:s' ),
641
-			current_time( 'mysql' ),
642
-		);
643
-
644
-		$where    = "WHERE claim_id = 0 AND scheduled_date_gmt <= %s AND status=%s";
645
-		$params[] = $date->format( 'Y-m-d H:i:s' );
646
-		$params[] = self::STATUS_PENDING;
647
-
648
-		if ( ! empty( $hooks ) ) {
649
-			$placeholders = array_fill( 0, count( $hooks ), '%s' );
650
-			$where       .= ' AND hook IN (' . join( ', ', $placeholders ) . ')';
651
-			$params       = array_merge( $params, array_values( $hooks ) );
652
-		}
653
-
654
-		if ( ! empty( $group ) ) {
655
-
656
-			$group_id = $this->get_group_id( $group, false );
657
-
658
-			// throw exception if no matching group found, this matches ActionScheduler_wpPostStore's behaviour
659
-			if ( empty( $group_id ) ) {
660
-				/* translators: %s: group name */
661
-				throw new InvalidArgumentException( sprintf( __( 'The group "%s" does not exist.', 'action-scheduler' ), $group ) );
662
-			}
663
-
664
-			$where   .= ' AND group_id = %d';
665
-			$params[] = $group_id;
666
-		}
667
-
668
-		$order    = "ORDER BY attempts ASC, scheduled_date_gmt ASC, action_id ASC LIMIT %d";
669
-		$params[] = $limit;
670
-
671
-		$sql = $wpdb->prepare( "{$update} {$where} {$order}", $params );
672
-
673
-		$rows_affected = $wpdb->query( $sql );
674
-		if ( $rows_affected === false ) {
675
-			throw new \RuntimeException( __( 'Unable to claim actions. Database error.', 'action-scheduler' ) );
676
-		}
677
-
678
-		return (int) $rows_affected;
679
-	}
680
-
681
-	/**
682
-	 * Get the number of active claims.
683
-	 *
684
-	 * @return int
685
-	 */
686
-	public function get_claim_count() {
687
-		global $wpdb;
688
-
689
-		$sql = "SELECT COUNT(DISTINCT claim_id) FROM {$wpdb->actionscheduler_actions} WHERE claim_id != 0 AND status IN ( %s, %s)";
690
-		$sql = $wpdb->prepare( $sql, [ self::STATUS_PENDING, self::STATUS_RUNNING ] );
691
-
692
-		return (int) $wpdb->get_var( $sql );
693
-	}
694
-
695
-	/**
696
-	 * Return an action's claim ID, as stored in the claim_id column.
697
-	 *
698
-	 * @param string $action_id Action ID.
699
-	 * @return mixed
700
-	 */
701
-	public function get_claim_id( $action_id ) {
702
-		/** @var \wpdb $wpdb */
703
-		global $wpdb;
704
-
705
-		$sql = "SELECT claim_id FROM {$wpdb->actionscheduler_actions} WHERE action_id=%d";
706
-		$sql = $wpdb->prepare( $sql, $action_id );
707
-
708
-		return (int) $wpdb->get_var( $sql );
709
-	}
710
-
711
-	/**
712
-	 * Retrieve the action IDs of action in a claim.
713
-	 *
714
-	 * @param string $claim_id Claim ID.
715
-	 *
716
-	 * @return int[]
717
-	 */
718
-	public function find_actions_by_claim_id( $claim_id ) {
719
-		/** @var \wpdb $wpdb */
720
-		global $wpdb;
721
-
722
-		$sql = "SELECT action_id FROM {$wpdb->actionscheduler_actions} WHERE claim_id=%d";
723
-		$sql = $wpdb->prepare( $sql, $claim_id );
724
-
725
-		$action_ids = $wpdb->get_col( $sql );
726
-
727
-		return array_map( 'intval', $action_ids );
728
-	}
729
-
730
-	/**
731
-	 * Release actions from a claim and delete the claim.
732
-	 *
733
-	 * @param ActionScheduler_ActionClaim $claim Claim object.
734
-	 */
735
-	public function release_claim( ActionScheduler_ActionClaim $claim ) {
736
-		/** @var \wpdb $wpdb */
737
-		global $wpdb;
738
-		$wpdb->update( $wpdb->actionscheduler_actions, [ 'claim_id' => 0 ], [ 'claim_id' => $claim->get_id() ], [ '%d' ], [ '%d' ] );
739
-		$wpdb->delete( $wpdb->actionscheduler_claims, [ 'claim_id' => $claim->get_id() ], [ '%d' ] );
740
-	}
741
-
742
-	/**
743
-	 * Remove the claim from an action.
744
-	 *
745
-	 * @param int $action_id Action ID.
746
-	 *
747
-	 * @return void
748
-	 */
749
-	public function unclaim_action( $action_id ) {
750
-		/** @var \wpdb $wpdb */
751
-		global $wpdb;
752
-		$wpdb->update(
753
-			$wpdb->actionscheduler_actions,
754
-			[ 'claim_id' => 0 ],
755
-			[ 'action_id' => $action_id ],
756
-			[ '%s' ],
757
-			[ '%d' ]
758
-		);
759
-	}
760
-
761
-	/**
762
-	 * Mark an action as failed.
763
-	 *
764
-	 * @param int $action_id Action ID.
765
-	 */
766
-	public function mark_failure( $action_id ) {
767
-		/** @var \wpdb $wpdb */
768
-		global $wpdb;
769
-		$updated = $wpdb->update(
770
-			$wpdb->actionscheduler_actions,
771
-			[ 'status' => self::STATUS_FAILED ],
772
-			[ 'action_id' => $action_id ],
773
-			[ '%s' ],
774
-			[ '%d' ]
775
-		);
776
-		if ( empty( $updated ) ) {
777
-			throw new \InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) );
778
-		}
779
-	}
780
-
781
-	/**
782
-	 * Add execution message to action log.
783
-	 *
784
-	 * @param int $action_id Action ID.
785
-	 *
786
-	 * @return void
787
-	 */
788
-	public function log_execution( $action_id ) {
789
-		/** @var \wpdb $wpdb */
790
-		global $wpdb;
791
-
792
-		$sql = "UPDATE {$wpdb->actionscheduler_actions} SET attempts = attempts+1, status=%s, last_attempt_gmt = %s, last_attempt_local = %s WHERE action_id = %d";
793
-		$sql = $wpdb->prepare( $sql, self::STATUS_RUNNING, current_time( 'mysql', true ), current_time( 'mysql' ), $action_id );
794
-		$wpdb->query( $sql );
795
-	}
796
-
797
-	/**
798
-	 * Mark an action as complete.
799
-	 *
800
-	 * @param int $action_id Action ID.
801
-	 *
802
-	 * @return void
803
-	 */
804
-	public function mark_complete( $action_id ) {
805
-		/** @var \wpdb $wpdb */
806
-		global $wpdb;
807
-		$updated = $wpdb->update(
808
-			$wpdb->actionscheduler_actions,
809
-			[
810
-				'status'             => self::STATUS_COMPLETE,
811
-				'last_attempt_gmt'   => current_time( 'mysql', true ),
812
-				'last_attempt_local' => current_time( 'mysql' ),
813
-			],
814
-			[ 'action_id' => $action_id ],
815
-			[ '%s' ],
816
-			[ '%d' ]
817
-		);
818
-		if ( empty( $updated ) ) {
819
-			throw new \InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) );
820
-		}
821
-	}
822
-
823
-	/**
824
-	 * Get an action's status.
825
-	 *
826
-	 * @param int $action_id Action ID.
827
-	 *
828
-	 * @return string
829
-	 */
830
-	public function get_status( $action_id ) {
831
-		/** @var \wpdb $wpdb */
832
-		global $wpdb;
833
-		$sql    = "SELECT status FROM {$wpdb->actionscheduler_actions} WHERE action_id=%d";
834
-		$sql    = $wpdb->prepare( $sql, $action_id );
835
-		$status = $wpdb->get_var( $sql );
836
-
837
-		if ( $status === null ) {
838
-			throw new \InvalidArgumentException( __( 'Invalid action ID. No status found.', 'action-scheduler' ) );
839
-		} elseif ( empty( $status ) ) {
840
-			throw new \RuntimeException( __( 'Unknown status found for action.', 'action-scheduler' ) );
841
-		} else {
842
-			return $status;
843
-		}
844
-	}
12
+    /** @var int */
13
+    protected static $max_args_length = 8000;
14
+
15
+    /** @var int */
16
+    protected static $max_index_length = 191;
17
+
18
+    /**
19
+     * Initialize the data store
20
+     *
21
+     * @codeCoverageIgnore
22
+     */
23
+    public function init() {
24
+        $table_maker = new ActionScheduler_StoreSchema();
25
+        $table_maker->register_tables();
26
+    }
27
+
28
+    /**
29
+     * Save an action.
30
+     *
31
+     * @param ActionScheduler_Action $action Action object.
32
+     * @param DateTime               $date Optional schedule date. Default null.
33
+     *
34
+     * @return int Action ID.
35
+     */
36
+    public function save_action( ActionScheduler_Action $action, \DateTime $date = null ) {
37
+        try {
38
+
39
+            $this->validate_action( $action );
40
+
41
+            /** @var \wpdb $wpdb */
42
+            global $wpdb;
43
+            $data = [
44
+                'hook'                 => $action->get_hook(),
45
+                'status'               => ( $action->is_finished() ? self::STATUS_COMPLETE : self::STATUS_PENDING ),
46
+                'scheduled_date_gmt'   => $this->get_scheduled_date_string( $action, $date ),
47
+                'scheduled_date_local' => $this->get_scheduled_date_string_local( $action, $date ),
48
+                'schedule'             => serialize( $action->get_schedule() ),
49
+                'group_id'             => $this->get_group_id( $action->get_group() ),
50
+            ];
51
+            $args = wp_json_encode( $action->get_args() );
52
+            if ( strlen( $args ) <= static::$max_index_length ) {
53
+                $data['args'] = $args;
54
+            } else {
55
+                $data['args']          = $this->hash_args( $args );
56
+                $data['extended_args'] = $args;
57
+            }
58
+
59
+            $table_name = ! empty( $wpdb->actionscheduler_actions ) ? $wpdb->actionscheduler_actions : $wpdb->prefix . 'actionscheduler_actions';
60
+            $wpdb->insert( $table_name, $data );
61
+            $action_id = $wpdb->insert_id;
62
+
63
+            if ( is_wp_error( $action_id ) ) {
64
+                throw new RuntimeException( $action_id->get_error_message() );
65
+            }
66
+            elseif ( empty( $action_id ) ) {
67
+                throw new RuntimeException( $wpdb->last_error ? $wpdb->last_error : __( 'Database error.', 'action-scheduler' ) );
68
+            }
69
+
70
+            do_action( 'action_scheduler_stored_action', $action_id );
71
+
72
+            return $action_id;
73
+        } catch ( \Exception $e ) {
74
+            /* translators: %s: error message */
75
+            throw new \RuntimeException( sprintf( __( 'Error saving action: %s', 'action-scheduler' ), $e->getMessage() ), 0 );
76
+        }
77
+    }
78
+
79
+    /**
80
+     * Generate a hash from json_encoded $args using MD5 as this isn't for security.
81
+     *
82
+     * @param string $args JSON encoded action args.
83
+     * @return string
84
+     */
85
+    protected function hash_args( $args ) {
86
+        return md5( $args );
87
+    }
88
+
89
+    /**
90
+     * Get action args query param value from action args.
91
+     *
92
+     * @param array $args Action args.
93
+     * @return string
94
+     */
95
+    protected function get_args_for_query( $args ) {
96
+        $encoded = wp_json_encode( $args );
97
+        if ( strlen( $encoded ) <= static::$max_index_length ) {
98
+            return $encoded;
99
+        }
100
+        return $this->hash_args( $encoded );
101
+    }
102
+    /**
103
+     * Get a group's ID based on its name/slug.
104
+     *
105
+     * @param string $slug The string name of a group.
106
+     * @param bool $create_if_not_exists Whether to create the group if it does not already exist. Default, true - create the group.
107
+     *
108
+     * @return int The group's ID, if it exists or is created, or 0 if it does not exist and is not created.
109
+     */
110
+    protected function get_group_id( $slug, $create_if_not_exists = true ) {
111
+        if ( empty( $slug ) ) {
112
+            return 0;
113
+        }
114
+        /** @var \wpdb $wpdb */
115
+        global $wpdb;
116
+        $group_id = (int) $wpdb->get_var( $wpdb->prepare( "SELECT group_id FROM {$wpdb->actionscheduler_groups} WHERE slug=%s", $slug ) );
117
+        if ( empty( $group_id ) && $create_if_not_exists ) {
118
+            $group_id = $this->create_group( $slug );
119
+        }
120
+
121
+        return $group_id;
122
+    }
123
+
124
+    /**
125
+     * Create an action group.
126
+     *
127
+     * @param string $slug Group slug.
128
+     *
129
+     * @return int Group ID.
130
+     */
131
+    protected function create_group( $slug ) {
132
+        /** @var \wpdb $wpdb */
133
+        global $wpdb;
134
+        $wpdb->insert( $wpdb->actionscheduler_groups, [ 'slug' => $slug ] );
135
+
136
+        return (int) $wpdb->insert_id;
137
+    }
138
+
139
+    /**
140
+     * Retrieve an action.
141
+     *
142
+     * @param int $action_id Action ID.
143
+     *
144
+     * @return ActionScheduler_Action
145
+     */
146
+    public function fetch_action( $action_id ) {
147
+        /** @var \wpdb $wpdb */
148
+        global $wpdb;
149
+        $data = $wpdb->get_row( $wpdb->prepare(
150
+            "SELECT a.*, g.slug AS `group` FROM {$wpdb->actionscheduler_actions} a LEFT JOIN {$wpdb->actionscheduler_groups} g ON a.group_id=g.group_id WHERE a.action_id=%d",
151
+            $action_id
152
+        ) );
153
+
154
+        if ( empty( $data ) ) {
155
+            return $this->get_null_action();
156
+        }
157
+
158
+        if ( ! empty( $data->extended_args ) ) {
159
+            $data->args = $data->extended_args;
160
+            unset( $data->extended_args );
161
+        }
162
+
163
+        try {
164
+            $action = $this->make_action_from_db_record( $data );
165
+        } catch ( ActionScheduler_InvalidActionException $exception ) {
166
+            do_action( 'action_scheduler_failed_fetch_action', $action_id, $exception );
167
+            return $this->get_null_action();
168
+        }
169
+
170
+        return $action;
171
+    }
172
+
173
+    /**
174
+     * Create a null action.
175
+     *
176
+     * @return ActionScheduler_NullAction
177
+     */
178
+    protected function get_null_action() {
179
+        return new ActionScheduler_NullAction();
180
+    }
181
+
182
+    /**
183
+     * Create an action from a database record.
184
+     *
185
+     * @param object $data Action database record.
186
+     *
187
+     * @return ActionScheduler_Action|ActionScheduler_CanceledAction|ActionScheduler_FinishedAction
188
+     */
189
+    protected function make_action_from_db_record( $data ) {
190
+
191
+        $hook     = $data->hook;
192
+        $args     = json_decode( $data->args, true );
193
+        $schedule = unserialize( $data->schedule );
194
+
195
+        $this->validate_args( $args, $data->action_id );
196
+        $this->validate_schedule( $schedule, $data->action_id );
197
+
198
+        if ( empty( $schedule ) ) {
199
+            $schedule = new ActionScheduler_NullSchedule();
200
+        }
201
+        $group = $data->group ? $data->group : '';
202
+
203
+        return ActionScheduler::factory()->get_stored_action( $data->status, $data->hook, $args, $schedule, $group );
204
+    }
205
+
206
+    /**
207
+     * Find an action.
208
+     *
209
+     * @param string $hook Action hook.
210
+     * @param array  $params Parameters of the action to find.
211
+     *
212
+     * @return string|null ID of the next action matching the criteria or NULL if not found.
213
+     */
214
+    public function find_action( $hook, $params = [] ) {
215
+        $params = wp_parse_args( $params, [
216
+            'args'   => null,
217
+            'status' => self::STATUS_PENDING,
218
+            'group'  => '',
219
+        ] );
220
+
221
+        /** @var wpdb $wpdb */
222
+        global $wpdb;
223
+        $query = "SELECT a.action_id FROM {$wpdb->actionscheduler_actions} a";
224
+        $args  = [];
225
+        if ( ! empty( $params[ 'group' ] ) ) {
226
+            $query  .= " INNER JOIN {$wpdb->actionscheduler_groups} g ON g.group_id=a.group_id AND g.slug=%s";
227
+            $args[] = $params[ 'group' ];
228
+        }
229
+        $query  .= " WHERE a.hook=%s";
230
+        $args[] = $hook;
231
+        if ( ! is_null( $params[ 'args' ] ) ) {
232
+            $query  .= " AND a.args=%s";
233
+            $args[] = $this->get_args_for_query( $params[ 'args' ] );
234
+        }
235
+
236
+        $order = 'ASC';
237
+        if ( ! empty( $params[ 'status' ] ) ) {
238
+            $query  .= " AND a.status=%s";
239
+            $args[] = $params[ 'status' ];
240
+
241
+            if ( self::STATUS_PENDING == $params[ 'status' ] ) {
242
+                $order = 'ASC'; // Find the next action that matches.
243
+            } else {
244
+                $order = 'DESC'; // Find the most recent action that matches.
245
+            }
246
+        }
247
+
248
+        $query .= " ORDER BY scheduled_date_gmt $order LIMIT 1";
249
+
250
+        $query = $wpdb->prepare( $query, $args );
251
+
252
+        $id = $wpdb->get_var( $query );
253
+
254
+        return $id;
255
+    }
256
+
257
+    /**
258
+     * Returns the SQL statement to query (or count) actions.
259
+     *
260
+     * @param array  $query Filtering options.
261
+     * @param string $select_or_count  Whether the SQL should select and return the IDs or just the row count.
262
+     *
263
+     * @return string SQL statement already properly escaped.
264
+     */
265
+    protected function get_query_actions_sql( array $query, $select_or_count = 'select' ) {
266
+
267
+        if ( ! in_array( $select_or_count, array( 'select', 'count' ) ) ) {
268
+            throw new InvalidArgumentException( __( 'Invalid value for select or count parameter. Cannot query actions.', 'action-scheduler' ) );
269
+        }
270
+
271
+        $query = wp_parse_args( $query, [
272
+            'hook'             => '',
273
+            'args'             => null,
274
+            'date'             => null,
275
+            'date_compare'     => '<=',
276
+            'modified'         => null,
277
+            'modified_compare' => '<=',
278
+            'group'            => '',
279
+            'status'           => '',
280
+            'claimed'          => null,
281
+            'per_page'         => 5,
282
+            'offset'           => 0,
283
+            'orderby'          => 'date',
284
+            'order'            => 'ASC',
285
+        ] );
286
+
287
+        /** @var \wpdb $wpdb */
288
+        global $wpdb;
289
+        $sql  = ( 'count' === $select_or_count ) ? 'SELECT count(a.action_id)' : 'SELECT a.action_id';
290
+        $sql .= " FROM {$wpdb->actionscheduler_actions} a";
291
+        $sql_params = [];
292
+
293
+        if ( ! empty( $query[ 'group' ] ) || 'group' === $query[ 'orderby' ] ) {
294
+            $sql .= " LEFT JOIN {$wpdb->actionscheduler_groups} g ON g.group_id=a.group_id";
295
+        }
296
+
297
+        $sql .= " WHERE 1=1";
298
+
299
+        if ( ! empty( $query[ 'group' ] ) ) {
300
+            $sql          .= " AND g.slug=%s";
301
+            $sql_params[] = $query[ 'group' ];
302
+        }
303
+
304
+        if ( $query[ 'hook' ] ) {
305
+            $sql          .= " AND a.hook=%s";
306
+            $sql_params[] = $query[ 'hook' ];
307
+        }
308
+        if ( ! is_null( $query[ 'args' ] ) ) {
309
+            $sql          .= " AND a.args=%s";
310
+            $sql_params[] = $this->get_args_for_query( $query[ 'args' ] );
311
+        }
312
+
313
+        if ( $query[ 'status' ] ) {
314
+            $sql          .= " AND a.status=%s";
315
+            $sql_params[] = $query[ 'status' ];
316
+        }
317
+
318
+        if ( $query[ 'date' ] instanceof \DateTime ) {
319
+            $date = clone $query[ 'date' ];
320
+            $date->setTimezone( new \DateTimeZone( 'UTC' ) );
321
+            $date_string  = $date->format( 'Y-m-d H:i:s' );
322
+            $comparator   = $this->validate_sql_comparator( $query[ 'date_compare' ] );
323
+            $sql          .= " AND a.scheduled_date_gmt $comparator %s";
324
+            $sql_params[] = $date_string;
325
+        }
326
+
327
+        if ( $query[ 'modified' ] instanceof \DateTime ) {
328
+            $modified = clone $query[ 'modified' ];
329
+            $modified->setTimezone( new \DateTimeZone( 'UTC' ) );
330
+            $date_string  = $modified->format( 'Y-m-d H:i:s' );
331
+            $comparator   = $this->validate_sql_comparator( $query[ 'modified_compare' ] );
332
+            $sql          .= " AND a.last_attempt_gmt $comparator %s";
333
+            $sql_params[] = $date_string;
334
+        }
335
+
336
+        if ( $query[ 'claimed' ] === true ) {
337
+            $sql .= " AND a.claim_id != 0";
338
+        } elseif ( $query[ 'claimed' ] === false ) {
339
+            $sql .= " AND a.claim_id = 0";
340
+        } elseif ( ! is_null( $query[ 'claimed' ] ) ) {
341
+            $sql          .= " AND a.claim_id = %d";
342
+            $sql_params[] = $query[ 'claimed' ];
343
+        }
344
+
345
+        if ( ! empty( $query['search'] ) ) {
346
+            $sql .= " AND (a.hook LIKE %s OR (a.extended_args IS NULL AND a.args LIKE %s) OR a.extended_args LIKE %s";
347
+            for( $i = 0; $i < 3; $i++ ) {
348
+                $sql_params[] = sprintf( '%%%s%%', $query['search'] );
349
+            }
350
+
351
+            $search_claim_id = (int) $query['search'];
352
+            if ( $search_claim_id ) {
353
+                $sql .= ' OR a.claim_id = %d';
354
+                $sql_params[] = $search_claim_id;
355
+            }
356
+
357
+            $sql .= ')';
358
+        }
359
+
360
+        if ( 'select' === $select_or_count ) {
361
+            switch ( $query['orderby'] ) {
362
+                case 'hook':
363
+                    $orderby = 'a.hook';
364
+                    break;
365
+                case 'group':
366
+                    $orderby = 'g.slug';
367
+                    break;
368
+                case 'modified':
369
+                    $orderby = 'a.last_attempt_gmt';
370
+                    break;
371
+                case 'date':
372
+                default:
373
+                    $orderby = 'a.scheduled_date_gmt';
374
+                    break;
375
+            }
376
+            if ( strtoupper( $query[ 'order' ] ) == 'ASC' ) {
377
+                $order = 'ASC';
378
+            } else {
379
+                $order = 'DESC';
380
+            }
381
+            $sql .= " ORDER BY $orderby $order";
382
+            if ( $query[ 'per_page' ] > 0 ) {
383
+                $sql          .= " LIMIT %d, %d";
384
+                $sql_params[] = $query[ 'offset' ];
385
+                $sql_params[] = $query[ 'per_page' ];
386
+            }
387
+        }
388
+
389
+        if ( ! empty( $sql_params ) ) {
390
+            $sql = $wpdb->prepare( $sql, $sql_params );
391
+        }
392
+
393
+        return $sql;
394
+    }
395
+
396
+    /**
397
+     * Query for action count of list of action IDs.
398
+     *
399
+     * @param array  $query Query parameters.
400
+     * @param string $query_type Whether to select or count the results. Default, select.
401
+     *
402
+     * @return null|string|array The IDs of actions matching the query
403
+     */
404
+    public function query_actions( $query = [], $query_type = 'select' ) {
405
+        /** @var wpdb $wpdb */
406
+        global $wpdb;
407
+
408
+        $sql = $this->get_query_actions_sql( $query, $query_type );
409
+
410
+        return ( 'count' === $query_type ) ? $wpdb->get_var( $sql ) : $wpdb->get_col( $sql );
411
+    }
412
+
413
+    /**
414
+     * Get a count of all actions in the store, grouped by status.
415
+     *
416
+     * @return array Set of 'status' => int $count pairs for statuses with 1 or more actions of that status.
417
+     */
418
+    public function action_counts() {
419
+        global $wpdb;
420
+
421
+        $sql  = "SELECT a.status, count(a.status) as 'count'";
422
+        $sql .= " FROM {$wpdb->actionscheduler_actions} a";
423
+        $sql .= " GROUP BY a.status";
424
+
425
+        $actions_count_by_status = array();
426
+        $action_stati_and_labels = $this->get_status_labels();
427
+
428
+        foreach ( $wpdb->get_results( $sql ) as $action_data ) {
429
+            // Ignore any actions with invalid status
430
+            if ( array_key_exists( $action_data->status, $action_stati_and_labels ) ) {
431
+                $actions_count_by_status[ $action_data->status ] = $action_data->count;
432
+            }
433
+        }
434
+
435
+        return $actions_count_by_status;
436
+    }
437
+
438
+    /**
439
+     * Cancel an action.
440
+     *
441
+     * @param int $action_id Action ID.
442
+     *
443
+     * @return void
444
+     */
445
+    public function cancel_action( $action_id ) {
446
+        /** @var \wpdb $wpdb */
447
+        global $wpdb;
448
+
449
+        $updated = $wpdb->update(
450
+            $wpdb->actionscheduler_actions,
451
+            [ 'status' => self::STATUS_CANCELED ],
452
+            [ 'action_id' => $action_id ],
453
+            [ '%s' ],
454
+            [ '%d' ]
455
+        );
456
+        if ( empty( $updated ) ) {
457
+            /* translators: %s: action ID */
458
+            throw new \InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) );
459
+        }
460
+        do_action( 'action_scheduler_canceled_action', $action_id );
461
+    }
462
+
463
+    /**
464
+     * Cancel pending actions by hook.
465
+     *
466
+     * @since 3.0.0
467
+     *
468
+     * @param string $hook Hook name.
469
+     *
470
+     * @return void
471
+     */
472
+    public function cancel_actions_by_hook( $hook ) {
473
+        $this->bulk_cancel_actions( [ 'hook' => $hook ] );
474
+    }
475
+
476
+    /**
477
+     * Cancel pending actions by group.
478
+     *
479
+     * @param string $group Group slug.
480
+     *
481
+     * @return void
482
+     */
483
+    public function cancel_actions_by_group( $group ) {
484
+        $this->bulk_cancel_actions( [ 'group' => $group ] );
485
+    }
486
+
487
+    /**
488
+     * Bulk cancel actions.
489
+     *
490
+     * @since 3.0.0
491
+     *
492
+     * @param array $query_args Query parameters.
493
+     */
494
+    protected function bulk_cancel_actions( $query_args ) {
495
+        /** @var \wpdb $wpdb */
496
+        global $wpdb;
497
+
498
+        if ( ! is_array( $query_args ) ) {
499
+            return;
500
+        }
501
+
502
+        // Don't cancel actions that are already canceled.
503
+        if ( isset( $query_args['status'] ) && $query_args['status'] == self::STATUS_CANCELED ) {
504
+            return;
505
+        }
506
+
507
+        $action_ids = true;
508
+        $query_args = wp_parse_args(
509
+            $query_args,
510
+            [
511
+                'per_page' => 1000,
512
+                'status' => self::STATUS_PENDING,
513
+            ]
514
+        );
515
+
516
+        while ( $action_ids ) {
517
+            $action_ids = $this->query_actions( $query_args );
518
+            if ( empty( $action_ids ) ) {
519
+                break;
520
+            }
521
+
522
+            $format     = array_fill( 0, count( $action_ids ), '%d' );
523
+            $query_in   = '(' . implode( ',', $format ) . ')';
524
+            $parameters = $action_ids;
525
+            array_unshift( $parameters, self::STATUS_CANCELED );
526
+
527
+            $wpdb->query(
528
+                $wpdb->prepare( // wpcs: PreparedSQLPlaceholders replacement count ok.
529
+                    "UPDATE {$wpdb->actionscheduler_actions} SET status = %s WHERE action_id IN {$query_in}",
530
+                    $parameters
531
+                )
532
+            );
533
+
534
+            do_action( 'action_scheduler_bulk_cancel_actions', $action_ids );
535
+        }
536
+    }
537
+
538
+    /**
539
+     * Delete an action.
540
+     *
541
+     * @param int $action_id Action ID.
542
+     */
543
+    public function delete_action( $action_id ) {
544
+        /** @var \wpdb $wpdb */
545
+        global $wpdb;
546
+        $deleted = $wpdb->delete( $wpdb->actionscheduler_actions, [ 'action_id' => $action_id ], [ '%d' ] );
547
+        if ( empty( $deleted ) ) {
548
+            throw new \InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) );
549
+        }
550
+        do_action( 'action_scheduler_deleted_action', $action_id );
551
+    }
552
+
553
+    /**
554
+     * Get the schedule date for an action.
555
+     *
556
+     * @param string $action_id Action ID.
557
+     *
558
+     * @throws \InvalidArgumentException
559
+     * @return \DateTime The local date the action is scheduled to run, or the date that it ran.
560
+     */
561
+    public function get_date( $action_id ) {
562
+        $date = $this->get_date_gmt( $action_id );
563
+        ActionScheduler_TimezoneHelper::set_local_timezone( $date );
564
+        return $date;
565
+    }
566
+
567
+    /**
568
+     * Get the GMT schedule date for an action.
569
+     *
570
+     * @param int $action_id Action ID.
571
+     *
572
+     * @throws \InvalidArgumentException
573
+     * @return \DateTime The GMT date the action is scheduled to run, or the date that it ran.
574
+     */
575
+    protected function get_date_gmt( $action_id ) {
576
+        /** @var \wpdb $wpdb */
577
+        global $wpdb;
578
+        $record = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->actionscheduler_actions} WHERE action_id=%d", $action_id ) );
579
+        if ( empty( $record ) ) {
580
+            throw new \InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) );
581
+        }
582
+        if ( $record->status == self::STATUS_PENDING ) {
583
+            return as_get_datetime_object( $record->scheduled_date_gmt );
584
+        } else {
585
+            return as_get_datetime_object( $record->last_attempt_gmt );
586
+        }
587
+    }
588
+
589
+    /**
590
+     * Stake a claim on actions.
591
+     *
592
+     * @param int       $max_actions Maximum number of action to include in claim.
593
+     * @param \DateTime $before_date Jobs must be schedule before this date. Defaults to now.
594
+     *
595
+     * @return ActionScheduler_ActionClaim
596
+     */
597
+    public function stake_claim( $max_actions = 10, \DateTime $before_date = null, $hooks = array(), $group = '' ) {
598
+        $claim_id = $this->generate_claim_id();
599
+        $this->claim_actions( $claim_id, $max_actions, $before_date, $hooks, $group );
600
+        $action_ids = $this->find_actions_by_claim_id( $claim_id );
601
+
602
+        return new ActionScheduler_ActionClaim( $claim_id, $action_ids );
603
+    }
604
+
605
+    /**
606
+     * Generate a new action claim.
607
+     *
608
+     * @return int Claim ID.
609
+     */
610
+    protected function generate_claim_id() {
611
+        /** @var \wpdb $wpdb */
612
+        global $wpdb;
613
+        $now = as_get_datetime_object();
614
+        $wpdb->insert( $wpdb->actionscheduler_claims, [ 'date_created_gmt' => $now->format( 'Y-m-d H:i:s' ) ] );
615
+
616
+        return $wpdb->insert_id;
617
+    }
618
+
619
+    /**
620
+     * Mark actions claimed.
621
+     *
622
+     * @param string    $claim_id Claim Id.
623
+     * @param int       $limit Number of action to include in claim.
624
+     * @param \DateTime $before_date Should use UTC timezone.
625
+     *
626
+     * @return int The number of actions that were claimed.
627
+     * @throws \RuntimeException
628
+     */
629
+    protected function claim_actions( $claim_id, $limit, \DateTime $before_date = null, $hooks = array(), $group = '' ) {
630
+        /** @var \wpdb $wpdb */
631
+        global $wpdb;
632
+
633
+        $now  = as_get_datetime_object();
634
+        $date = is_null( $before_date ) ? $now : clone $before_date;
635
+
636
+        // can't use $wpdb->update() because of the <= condition
637
+        $update = "UPDATE {$wpdb->actionscheduler_actions} SET claim_id=%d, last_attempt_gmt=%s, last_attempt_local=%s";
638
+        $params = array(
639
+            $claim_id,
640
+            $now->format( 'Y-m-d H:i:s' ),
641
+            current_time( 'mysql' ),
642
+        );
643
+
644
+        $where    = "WHERE claim_id = 0 AND scheduled_date_gmt <= %s AND status=%s";
645
+        $params[] = $date->format( 'Y-m-d H:i:s' );
646
+        $params[] = self::STATUS_PENDING;
647
+
648
+        if ( ! empty( $hooks ) ) {
649
+            $placeholders = array_fill( 0, count( $hooks ), '%s' );
650
+            $where       .= ' AND hook IN (' . join( ', ', $placeholders ) . ')';
651
+            $params       = array_merge( $params, array_values( $hooks ) );
652
+        }
653
+
654
+        if ( ! empty( $group ) ) {
655
+
656
+            $group_id = $this->get_group_id( $group, false );
657
+
658
+            // throw exception if no matching group found, this matches ActionScheduler_wpPostStore's behaviour
659
+            if ( empty( $group_id ) ) {
660
+                /* translators: %s: group name */
661
+                throw new InvalidArgumentException( sprintf( __( 'The group "%s" does not exist.', 'action-scheduler' ), $group ) );
662
+            }
663
+
664
+            $where   .= ' AND group_id = %d';
665
+            $params[] = $group_id;
666
+        }
667
+
668
+        $order    = "ORDER BY attempts ASC, scheduled_date_gmt ASC, action_id ASC LIMIT %d";
669
+        $params[] = $limit;
670
+
671
+        $sql = $wpdb->prepare( "{$update} {$where} {$order}", $params );
672
+
673
+        $rows_affected = $wpdb->query( $sql );
674
+        if ( $rows_affected === false ) {
675
+            throw new \RuntimeException( __( 'Unable to claim actions. Database error.', 'action-scheduler' ) );
676
+        }
677
+
678
+        return (int) $rows_affected;
679
+    }
680
+
681
+    /**
682
+     * Get the number of active claims.
683
+     *
684
+     * @return int
685
+     */
686
+    public function get_claim_count() {
687
+        global $wpdb;
688
+
689
+        $sql = "SELECT COUNT(DISTINCT claim_id) FROM {$wpdb->actionscheduler_actions} WHERE claim_id != 0 AND status IN ( %s, %s)";
690
+        $sql = $wpdb->prepare( $sql, [ self::STATUS_PENDING, self::STATUS_RUNNING ] );
691
+
692
+        return (int) $wpdb->get_var( $sql );
693
+    }
694
+
695
+    /**
696
+     * Return an action's claim ID, as stored in the claim_id column.
697
+     *
698
+     * @param string $action_id Action ID.
699
+     * @return mixed
700
+     */
701
+    public function get_claim_id( $action_id ) {
702
+        /** @var \wpdb $wpdb */
703
+        global $wpdb;
704
+
705
+        $sql = "SELECT claim_id FROM {$wpdb->actionscheduler_actions} WHERE action_id=%d";
706
+        $sql = $wpdb->prepare( $sql, $action_id );
707
+
708
+        return (int) $wpdb->get_var( $sql );
709
+    }
710
+
711
+    /**
712
+     * Retrieve the action IDs of action in a claim.
713
+     *
714
+     * @param string $claim_id Claim ID.
715
+     *
716
+     * @return int[]
717
+     */
718
+    public function find_actions_by_claim_id( $claim_id ) {
719
+        /** @var \wpdb $wpdb */
720
+        global $wpdb;
721
+
722
+        $sql = "SELECT action_id FROM {$wpdb->actionscheduler_actions} WHERE claim_id=%d";
723
+        $sql = $wpdb->prepare( $sql, $claim_id );
724
+
725
+        $action_ids = $wpdb->get_col( $sql );
726
+
727
+        return array_map( 'intval', $action_ids );
728
+    }
729
+
730
+    /**
731
+     * Release actions from a claim and delete the claim.
732
+     *
733
+     * @param ActionScheduler_ActionClaim $claim Claim object.
734
+     */
735
+    public function release_claim( ActionScheduler_ActionClaim $claim ) {
736
+        /** @var \wpdb $wpdb */
737
+        global $wpdb;
738
+        $wpdb->update( $wpdb->actionscheduler_actions, [ 'claim_id' => 0 ], [ 'claim_id' => $claim->get_id() ], [ '%d' ], [ '%d' ] );
739
+        $wpdb->delete( $wpdb->actionscheduler_claims, [ 'claim_id' => $claim->get_id() ], [ '%d' ] );
740
+    }
741
+
742
+    /**
743
+     * Remove the claim from an action.
744
+     *
745
+     * @param int $action_id Action ID.
746
+     *
747
+     * @return void
748
+     */
749
+    public function unclaim_action( $action_id ) {
750
+        /** @var \wpdb $wpdb */
751
+        global $wpdb;
752
+        $wpdb->update(
753
+            $wpdb->actionscheduler_actions,
754
+            [ 'claim_id' => 0 ],
755
+            [ 'action_id' => $action_id ],
756
+            [ '%s' ],
757
+            [ '%d' ]
758
+        );
759
+    }
760
+
761
+    /**
762
+     * Mark an action as failed.
763
+     *
764
+     * @param int $action_id Action ID.
765
+     */
766
+    public function mark_failure( $action_id ) {
767
+        /** @var \wpdb $wpdb */
768
+        global $wpdb;
769
+        $updated = $wpdb->update(
770
+            $wpdb->actionscheduler_actions,
771
+            [ 'status' => self::STATUS_FAILED ],
772
+            [ 'action_id' => $action_id ],
773
+            [ '%s' ],
774
+            [ '%d' ]
775
+        );
776
+        if ( empty( $updated ) ) {
777
+            throw new \InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) );
778
+        }
779
+    }
780
+
781
+    /**
782
+     * Add execution message to action log.
783
+     *
784
+     * @param int $action_id Action ID.
785
+     *
786
+     * @return void
787
+     */
788
+    public function log_execution( $action_id ) {
789
+        /** @var \wpdb $wpdb */
790
+        global $wpdb;
791
+
792
+        $sql = "UPDATE {$wpdb->actionscheduler_actions} SET attempts = attempts+1, status=%s, last_attempt_gmt = %s, last_attempt_local = %s WHERE action_id = %d";
793
+        $sql = $wpdb->prepare( $sql, self::STATUS_RUNNING, current_time( 'mysql', true ), current_time( 'mysql' ), $action_id );
794
+        $wpdb->query( $sql );
795
+    }
796
+
797
+    /**
798
+     * Mark an action as complete.
799
+     *
800
+     * @param int $action_id Action ID.
801
+     *
802
+     * @return void
803
+     */
804
+    public function mark_complete( $action_id ) {
805
+        /** @var \wpdb $wpdb */
806
+        global $wpdb;
807
+        $updated = $wpdb->update(
808
+            $wpdb->actionscheduler_actions,
809
+            [
810
+                'status'             => self::STATUS_COMPLETE,
811
+                'last_attempt_gmt'   => current_time( 'mysql', true ),
812
+                'last_attempt_local' => current_time( 'mysql' ),
813
+            ],
814
+            [ 'action_id' => $action_id ],
815
+            [ '%s' ],
816
+            [ '%d' ]
817
+        );
818
+        if ( empty( $updated ) ) {
819
+            throw new \InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) );
820
+        }
821
+    }
822
+
823
+    /**
824
+     * Get an action's status.
825
+     *
826
+     * @param int $action_id Action ID.
827
+     *
828
+     * @return string
829
+     */
830
+    public function get_status( $action_id ) {
831
+        /** @var \wpdb $wpdb */
832
+        global $wpdb;
833
+        $sql    = "SELECT status FROM {$wpdb->actionscheduler_actions} WHERE action_id=%d";
834
+        $sql    = $wpdb->prepare( $sql, $action_id );
835
+        $status = $wpdb->get_var( $sql );
836
+
837
+        if ( $status === null ) {
838
+            throw new \InvalidArgumentException( __( 'Invalid action ID. No status found.', 'action-scheduler' ) );
839
+        } elseif ( empty( $status ) ) {
840
+            throw new \RuntimeException( __( 'Unknown status found for action.', 'action-scheduler' ) );
841
+        } else {
842
+            return $status;
843
+        }
844
+    }
845 845
 }
Please login to merge, or discard this patch.
Spacing   +219 added lines, -219 removed lines patch added patch discarded remove patch
@@ -33,46 +33,46 @@  discard block
 block discarded – undo
33 33
 	 *
34 34
 	 * @return int Action ID.
35 35
 	 */
36
-	public function save_action( ActionScheduler_Action $action, \DateTime $date = null ) {
36
+	public function save_action(ActionScheduler_Action $action, \DateTime $date = null) {
37 37
 		try {
38 38
 
39
-			$this->validate_action( $action );
39
+			$this->validate_action($action);
40 40
 
41 41
 			/** @var \wpdb $wpdb */
42 42
 			global $wpdb;
43 43
 			$data = [
44 44
 				'hook'                 => $action->get_hook(),
45
-				'status'               => ( $action->is_finished() ? self::STATUS_COMPLETE : self::STATUS_PENDING ),
46
-				'scheduled_date_gmt'   => $this->get_scheduled_date_string( $action, $date ),
47
-				'scheduled_date_local' => $this->get_scheduled_date_string_local( $action, $date ),
48
-				'schedule'             => serialize( $action->get_schedule() ),
49
-				'group_id'             => $this->get_group_id( $action->get_group() ),
45
+				'status'               => ($action->is_finished() ? self::STATUS_COMPLETE : self::STATUS_PENDING),
46
+				'scheduled_date_gmt'   => $this->get_scheduled_date_string($action, $date),
47
+				'scheduled_date_local' => $this->get_scheduled_date_string_local($action, $date),
48
+				'schedule'             => serialize($action->get_schedule()),
49
+				'group_id'             => $this->get_group_id($action->get_group()),
50 50
 			];
51
-			$args = wp_json_encode( $action->get_args() );
52
-			if ( strlen( $args ) <= static::$max_index_length ) {
51
+			$args = wp_json_encode($action->get_args());
52
+			if (strlen($args) <= static::$max_index_length) {
53 53
 				$data['args'] = $args;
54 54
 			} else {
55
-				$data['args']          = $this->hash_args( $args );
55
+				$data['args']          = $this->hash_args($args);
56 56
 				$data['extended_args'] = $args;
57 57
 			}
58 58
 
59
-			$table_name = ! empty( $wpdb->actionscheduler_actions ) ? $wpdb->actionscheduler_actions : $wpdb->prefix . 'actionscheduler_actions';
60
-			$wpdb->insert( $table_name, $data );
59
+			$table_name = !empty($wpdb->actionscheduler_actions) ? $wpdb->actionscheduler_actions : $wpdb->prefix . 'actionscheduler_actions';
60
+			$wpdb->insert($table_name, $data);
61 61
 			$action_id = $wpdb->insert_id;
62 62
 
63
-			if ( is_wp_error( $action_id ) ) {
64
-				throw new RuntimeException( $action_id->get_error_message() );
63
+			if (is_wp_error($action_id)) {
64
+				throw new RuntimeException($action_id->get_error_message());
65 65
 			}
66
-			elseif ( empty( $action_id ) ) {
67
-				throw new RuntimeException( $wpdb->last_error ? $wpdb->last_error : __( 'Database error.', 'action-scheduler' ) );
66
+			elseif (empty($action_id)) {
67
+				throw new RuntimeException($wpdb->last_error ? $wpdb->last_error : __('Database error.', 'action-scheduler'));
68 68
 			}
69 69
 
70
-			do_action( 'action_scheduler_stored_action', $action_id );
70
+			do_action('action_scheduler_stored_action', $action_id);
71 71
 
72 72
 			return $action_id;
73
-		} catch ( \Exception $e ) {
73
+		} catch (\Exception $e) {
74 74
 			/* translators: %s: error message */
75
-			throw new \RuntimeException( sprintf( __( 'Error saving action: %s', 'action-scheduler' ), $e->getMessage() ), 0 );
75
+			throw new \RuntimeException(sprintf(__('Error saving action: %s', 'action-scheduler'), $e->getMessage()), 0);
76 76
 		}
77 77
 	}
78 78
 
@@ -82,8 +82,8 @@  discard block
 block discarded – undo
82 82
 	 * @param string $args JSON encoded action args.
83 83
 	 * @return string
84 84
 	 */
85
-	protected function hash_args( $args ) {
86
-		return md5( $args );
85
+	protected function hash_args($args) {
86
+		return md5($args);
87 87
 	}
88 88
 
89 89
 	/**
@@ -92,12 +92,12 @@  discard block
 block discarded – undo
92 92
 	 * @param array $args Action args.
93 93
 	 * @return string
94 94
 	 */
95
-	protected function get_args_for_query( $args ) {
96
-		$encoded = wp_json_encode( $args );
97
-		if ( strlen( $encoded ) <= static::$max_index_length ) {
95
+	protected function get_args_for_query($args) {
96
+		$encoded = wp_json_encode($args);
97
+		if (strlen($encoded) <= static::$max_index_length) {
98 98
 			return $encoded;
99 99
 		}
100
-		return $this->hash_args( $encoded );
100
+		return $this->hash_args($encoded);
101 101
 	}
102 102
 	/**
103 103
 	 * Get a group's ID based on its name/slug.
@@ -107,15 +107,15 @@  discard block
 block discarded – undo
107 107
 	 *
108 108
 	 * @return int The group's ID, if it exists or is created, or 0 if it does not exist and is not created.
109 109
 	 */
110
-	protected function get_group_id( $slug, $create_if_not_exists = true ) {
111
-		if ( empty( $slug ) ) {
110
+	protected function get_group_id($slug, $create_if_not_exists = true) {
111
+		if (empty($slug)) {
112 112
 			return 0;
113 113
 		}
114 114
 		/** @var \wpdb $wpdb */
115 115
 		global $wpdb;
116
-		$group_id = (int) $wpdb->get_var( $wpdb->prepare( "SELECT group_id FROM {$wpdb->actionscheduler_groups} WHERE slug=%s", $slug ) );
117
-		if ( empty( $group_id ) && $create_if_not_exists ) {
118
-			$group_id = $this->create_group( $slug );
116
+		$group_id = (int) $wpdb->get_var($wpdb->prepare("SELECT group_id FROM {$wpdb->actionscheduler_groups} WHERE slug=%s", $slug));
117
+		if (empty($group_id) && $create_if_not_exists) {
118
+			$group_id = $this->create_group($slug);
119 119
 		}
120 120
 
121 121
 		return $group_id;
@@ -128,10 +128,10 @@  discard block
 block discarded – undo
128 128
 	 *
129 129
 	 * @return int Group ID.
130 130
 	 */
131
-	protected function create_group( $slug ) {
131
+	protected function create_group($slug) {
132 132
 		/** @var \wpdb $wpdb */
133 133
 		global $wpdb;
134
-		$wpdb->insert( $wpdb->actionscheduler_groups, [ 'slug' => $slug ] );
134
+		$wpdb->insert($wpdb->actionscheduler_groups, ['slug' => $slug]);
135 135
 
136 136
 		return (int) $wpdb->insert_id;
137 137
 	}
@@ -143,27 +143,27 @@  discard block
 block discarded – undo
143 143
 	 *
144 144
 	 * @return ActionScheduler_Action
145 145
 	 */
146
-	public function fetch_action( $action_id ) {
146
+	public function fetch_action($action_id) {
147 147
 		/** @var \wpdb $wpdb */
148 148
 		global $wpdb;
149
-		$data = $wpdb->get_row( $wpdb->prepare(
149
+		$data = $wpdb->get_row($wpdb->prepare(
150 150
 			"SELECT a.*, g.slug AS `group` FROM {$wpdb->actionscheduler_actions} a LEFT JOIN {$wpdb->actionscheduler_groups} g ON a.group_id=g.group_id WHERE a.action_id=%d",
151 151
 			$action_id
152
-		) );
152
+		));
153 153
 
154
-		if ( empty( $data ) ) {
154
+		if (empty($data)) {
155 155
 			return $this->get_null_action();
156 156
 		}
157 157
 
158
-		if ( ! empty( $data->extended_args ) ) {
158
+		if (!empty($data->extended_args)) {
159 159
 			$data->args = $data->extended_args;
160
-			unset( $data->extended_args );
160
+			unset($data->extended_args);
161 161
 		}
162 162
 
163 163
 		try {
164
-			$action = $this->make_action_from_db_record( $data );
165
-		} catch ( ActionScheduler_InvalidActionException $exception ) {
166
-			do_action( 'action_scheduler_failed_fetch_action', $action_id, $exception );
164
+			$action = $this->make_action_from_db_record($data);
165
+		} catch (ActionScheduler_InvalidActionException $exception) {
166
+			do_action('action_scheduler_failed_fetch_action', $action_id, $exception);
167 167
 			return $this->get_null_action();
168 168
 		}
169 169
 
@@ -186,21 +186,21 @@  discard block
 block discarded – undo
186 186
 	 *
187 187
 	 * @return ActionScheduler_Action|ActionScheduler_CanceledAction|ActionScheduler_FinishedAction
188 188
 	 */
189
-	protected function make_action_from_db_record( $data ) {
189
+	protected function make_action_from_db_record($data) {
190 190
 
191 191
 		$hook     = $data->hook;
192
-		$args     = json_decode( $data->args, true );
193
-		$schedule = unserialize( $data->schedule );
192
+		$args     = json_decode($data->args, true);
193
+		$schedule = unserialize($data->schedule);
194 194
 
195
-		$this->validate_args( $args, $data->action_id );
196
-		$this->validate_schedule( $schedule, $data->action_id );
195
+		$this->validate_args($args, $data->action_id);
196
+		$this->validate_schedule($schedule, $data->action_id);
197 197
 
198
-		if ( empty( $schedule ) ) {
198
+		if (empty($schedule)) {
199 199
 			$schedule = new ActionScheduler_NullSchedule();
200 200
 		}
201 201
 		$group = $data->group ? $data->group : '';
202 202
 
203
-		return ActionScheduler::factory()->get_stored_action( $data->status, $data->hook, $args, $schedule, $group );
203
+		return ActionScheduler::factory()->get_stored_action($data->status, $data->hook, $args, $schedule, $group);
204 204
 	}
205 205
 
206 206
 	/**
@@ -211,34 +211,34 @@  discard block
 block discarded – undo
211 211
 	 *
212 212
 	 * @return string|null ID of the next action matching the criteria or NULL if not found.
213 213
 	 */
214
-	public function find_action( $hook, $params = [] ) {
215
-		$params = wp_parse_args( $params, [
214
+	public function find_action($hook, $params = []) {
215
+		$params = wp_parse_args($params, [
216 216
 			'args'   => null,
217 217
 			'status' => self::STATUS_PENDING,
218 218
 			'group'  => '',
219
-		] );
219
+		]);
220 220
 
221 221
 		/** @var wpdb $wpdb */
222 222
 		global $wpdb;
223 223
 		$query = "SELECT a.action_id FROM {$wpdb->actionscheduler_actions} a";
224 224
 		$args  = [];
225
-		if ( ! empty( $params[ 'group' ] ) ) {
226
-			$query  .= " INNER JOIN {$wpdb->actionscheduler_groups} g ON g.group_id=a.group_id AND g.slug=%s";
227
-			$args[] = $params[ 'group' ];
225
+		if (!empty($params['group'])) {
226
+			$query .= " INNER JOIN {$wpdb->actionscheduler_groups} g ON g.group_id=a.group_id AND g.slug=%s";
227
+			$args[] = $params['group'];
228 228
 		}
229 229
 		$query  .= " WHERE a.hook=%s";
230 230
 		$args[] = $hook;
231
-		if ( ! is_null( $params[ 'args' ] ) ) {
232
-			$query  .= " AND a.args=%s";
233
-			$args[] = $this->get_args_for_query( $params[ 'args' ] );
231
+		if (!is_null($params['args'])) {
232
+			$query .= " AND a.args=%s";
233
+			$args[] = $this->get_args_for_query($params['args']);
234 234
 		}
235 235
 
236 236
 		$order = 'ASC';
237
-		if ( ! empty( $params[ 'status' ] ) ) {
238
-			$query  .= " AND a.status=%s";
239
-			$args[] = $params[ 'status' ];
237
+		if (!empty($params['status'])) {
238
+			$query .= " AND a.status=%s";
239
+			$args[] = $params['status'];
240 240
 
241
-			if ( self::STATUS_PENDING == $params[ 'status' ] ) {
241
+			if (self::STATUS_PENDING == $params['status']) {
242 242
 				$order = 'ASC'; // Find the next action that matches.
243 243
 			} else {
244 244
 				$order = 'DESC'; // Find the most recent action that matches.
@@ -247,9 +247,9 @@  discard block
 block discarded – undo
247 247
 
248 248
 		$query .= " ORDER BY scheduled_date_gmt $order LIMIT 1";
249 249
 
250
-		$query = $wpdb->prepare( $query, $args );
250
+		$query = $wpdb->prepare($query, $args);
251 251
 
252
-		$id = $wpdb->get_var( $query );
252
+		$id = $wpdb->get_var($query);
253 253
 
254 254
 		return $id;
255 255
 	}
@@ -262,13 +262,13 @@  discard block
 block discarded – undo
262 262
 	 *
263 263
 	 * @return string SQL statement already properly escaped.
264 264
 	 */
265
-	protected function get_query_actions_sql( array $query, $select_or_count = 'select' ) {
265
+	protected function get_query_actions_sql(array $query, $select_or_count = 'select') {
266 266
 
267
-		if ( ! in_array( $select_or_count, array( 'select', 'count' ) ) ) {
268
-			throw new InvalidArgumentException( __( 'Invalid value for select or count parameter. Cannot query actions.', 'action-scheduler' ) );
267
+		if (!in_array($select_or_count, array('select', 'count'))) {
268
+			throw new InvalidArgumentException(__('Invalid value for select or count parameter. Cannot query actions.', 'action-scheduler'));
269 269
 		}
270 270
 
271
-		$query = wp_parse_args( $query, [
271
+		$query = wp_parse_args($query, [
272 272
 			'hook'             => '',
273 273
 			'args'             => null,
274 274
 			'date'             => null,
@@ -282,74 +282,74 @@  discard block
 block discarded – undo
282 282
 			'offset'           => 0,
283 283
 			'orderby'          => 'date',
284 284
 			'order'            => 'ASC',
285
-		] );
285
+		]);
286 286
 
287 287
 		/** @var \wpdb $wpdb */
288 288
 		global $wpdb;
289
-		$sql  = ( 'count' === $select_or_count ) ? 'SELECT count(a.action_id)' : 'SELECT a.action_id';
289
+		$sql  = ('count' === $select_or_count) ? 'SELECT count(a.action_id)' : 'SELECT a.action_id';
290 290
 		$sql .= " FROM {$wpdb->actionscheduler_actions} a";
291 291
 		$sql_params = [];
292 292
 
293
-		if ( ! empty( $query[ 'group' ] ) || 'group' === $query[ 'orderby' ] ) {
293
+		if (!empty($query['group']) || 'group' === $query['orderby']) {
294 294
 			$sql .= " LEFT JOIN {$wpdb->actionscheduler_groups} g ON g.group_id=a.group_id";
295 295
 		}
296 296
 
297 297
 		$sql .= " WHERE 1=1";
298 298
 
299
-		if ( ! empty( $query[ 'group' ] ) ) {
300
-			$sql          .= " AND g.slug=%s";
301
-			$sql_params[] = $query[ 'group' ];
299
+		if (!empty($query['group'])) {
300
+			$sql .= " AND g.slug=%s";
301
+			$sql_params[] = $query['group'];
302 302
 		}
303 303
 
304
-		if ( $query[ 'hook' ] ) {
305
-			$sql          .= " AND a.hook=%s";
306
-			$sql_params[] = $query[ 'hook' ];
304
+		if ($query['hook']) {
305
+			$sql .= " AND a.hook=%s";
306
+			$sql_params[] = $query['hook'];
307 307
 		}
308
-		if ( ! is_null( $query[ 'args' ] ) ) {
309
-			$sql          .= " AND a.args=%s";
310
-			$sql_params[] = $this->get_args_for_query( $query[ 'args' ] );
308
+		if (!is_null($query['args'])) {
309
+			$sql .= " AND a.args=%s";
310
+			$sql_params[] = $this->get_args_for_query($query['args']);
311 311
 		}
312 312
 
313
-		if ( $query[ 'status' ] ) {
314
-			$sql          .= " AND a.status=%s";
315
-			$sql_params[] = $query[ 'status' ];
313
+		if ($query['status']) {
314
+			$sql .= " AND a.status=%s";
315
+			$sql_params[] = $query['status'];
316 316
 		}
317 317
 
318
-		if ( $query[ 'date' ] instanceof \DateTime ) {
319
-			$date = clone $query[ 'date' ];
320
-			$date->setTimezone( new \DateTimeZone( 'UTC' ) );
321
-			$date_string  = $date->format( 'Y-m-d H:i:s' );
322
-			$comparator   = $this->validate_sql_comparator( $query[ 'date_compare' ] );
323
-			$sql          .= " AND a.scheduled_date_gmt $comparator %s";
318
+		if ($query['date'] instanceof \DateTime) {
319
+			$date = clone $query['date'];
320
+			$date->setTimezone(new \DateTimeZone('UTC'));
321
+			$date_string  = $date->format('Y-m-d H:i:s');
322
+			$comparator   = $this->validate_sql_comparator($query['date_compare']);
323
+			$sql .= " AND a.scheduled_date_gmt $comparator %s";
324 324
 			$sql_params[] = $date_string;
325 325
 		}
326 326
 
327
-		if ( $query[ 'modified' ] instanceof \DateTime ) {
328
-			$modified = clone $query[ 'modified' ];
329
-			$modified->setTimezone( new \DateTimeZone( 'UTC' ) );
330
-			$date_string  = $modified->format( 'Y-m-d H:i:s' );
331
-			$comparator   = $this->validate_sql_comparator( $query[ 'modified_compare' ] );
332
-			$sql          .= " AND a.last_attempt_gmt $comparator %s";
327
+		if ($query['modified'] instanceof \DateTime) {
328
+			$modified = clone $query['modified'];
329
+			$modified->setTimezone(new \DateTimeZone('UTC'));
330
+			$date_string  = $modified->format('Y-m-d H:i:s');
331
+			$comparator   = $this->validate_sql_comparator($query['modified_compare']);
332
+			$sql .= " AND a.last_attempt_gmt $comparator %s";
333 333
 			$sql_params[] = $date_string;
334 334
 		}
335 335
 
336
-		if ( $query[ 'claimed' ] === true ) {
336
+		if ($query['claimed'] === true) {
337 337
 			$sql .= " AND a.claim_id != 0";
338
-		} elseif ( $query[ 'claimed' ] === false ) {
338
+		} elseif ($query['claimed'] === false) {
339 339
 			$sql .= " AND a.claim_id = 0";
340
-		} elseif ( ! is_null( $query[ 'claimed' ] ) ) {
341
-			$sql          .= " AND a.claim_id = %d";
342
-			$sql_params[] = $query[ 'claimed' ];
340
+		} elseif (!is_null($query['claimed'])) {
341
+			$sql .= " AND a.claim_id = %d";
342
+			$sql_params[] = $query['claimed'];
343 343
 		}
344 344
 
345
-		if ( ! empty( $query['search'] ) ) {
345
+		if (!empty($query['search'])) {
346 346
 			$sql .= " AND (a.hook LIKE %s OR (a.extended_args IS NULL AND a.args LIKE %s) OR a.extended_args LIKE %s";
347
-			for( $i = 0; $i < 3; $i++ ) {
348
-				$sql_params[] = sprintf( '%%%s%%', $query['search'] );
347
+			for ($i = 0; $i < 3; $i++) {
348
+				$sql_params[] = sprintf('%%%s%%', $query['search']);
349 349
 			}
350 350
 
351 351
 			$search_claim_id = (int) $query['search'];
352
-			if ( $search_claim_id ) {
352
+			if ($search_claim_id) {
353 353
 				$sql .= ' OR a.claim_id = %d';
354 354
 				$sql_params[] = $search_claim_id;
355 355
 			}
@@ -357,8 +357,8 @@  discard block
 block discarded – undo
357 357
 			$sql .= ')';
358 358
 		}
359 359
 
360
-		if ( 'select' === $select_or_count ) {
361
-			switch ( $query['orderby'] ) {
360
+		if ('select' === $select_or_count) {
361
+			switch ($query['orderby']) {
362 362
 				case 'hook':
363 363
 					$orderby = 'a.hook';
364 364
 					break;
@@ -373,21 +373,21 @@  discard block
 block discarded – undo
373 373
 					$orderby = 'a.scheduled_date_gmt';
374 374
 					break;
375 375
 			}
376
-			if ( strtoupper( $query[ 'order' ] ) == 'ASC' ) {
376
+			if (strtoupper($query['order']) == 'ASC') {
377 377
 				$order = 'ASC';
378 378
 			} else {
379 379
 				$order = 'DESC';
380 380
 			}
381 381
 			$sql .= " ORDER BY $orderby $order";
382
-			if ( $query[ 'per_page' ] > 0 ) {
383
-				$sql          .= " LIMIT %d, %d";
384
-				$sql_params[] = $query[ 'offset' ];
385
-				$sql_params[] = $query[ 'per_page' ];
382
+			if ($query['per_page'] > 0) {
383
+				$sql .= " LIMIT %d, %d";
384
+				$sql_params[] = $query['offset'];
385
+				$sql_params[] = $query['per_page'];
386 386
 			}
387 387
 		}
388 388
 
389
-		if ( ! empty( $sql_params ) ) {
390
-			$sql = $wpdb->prepare( $sql, $sql_params );
389
+		if (!empty($sql_params)) {
390
+			$sql = $wpdb->prepare($sql, $sql_params);
391 391
 		}
392 392
 
393 393
 		return $sql;
@@ -401,13 +401,13 @@  discard block
 block discarded – undo
401 401
 	 *
402 402
 	 * @return null|string|array The IDs of actions matching the query
403 403
 	 */
404
-	public function query_actions( $query = [], $query_type = 'select' ) {
404
+	public function query_actions($query = [], $query_type = 'select') {
405 405
 		/** @var wpdb $wpdb */
406 406
 		global $wpdb;
407 407
 
408
-		$sql = $this->get_query_actions_sql( $query, $query_type );
408
+		$sql = $this->get_query_actions_sql($query, $query_type);
409 409
 
410
-		return ( 'count' === $query_type ) ? $wpdb->get_var( $sql ) : $wpdb->get_col( $sql );
410
+		return ('count' === $query_type) ? $wpdb->get_var($sql) : $wpdb->get_col($sql);
411 411
 	}
412 412
 
413 413
 	/**
@@ -425,10 +425,10 @@  discard block
 block discarded – undo
425 425
 		$actions_count_by_status = array();
426 426
 		$action_stati_and_labels = $this->get_status_labels();
427 427
 
428
-		foreach ( $wpdb->get_results( $sql ) as $action_data ) {
428
+		foreach ($wpdb->get_results($sql) as $action_data) {
429 429
 			// Ignore any actions with invalid status
430
-			if ( array_key_exists( $action_data->status, $action_stati_and_labels ) ) {
431
-				$actions_count_by_status[ $action_data->status ] = $action_data->count;
430
+			if (array_key_exists($action_data->status, $action_stati_and_labels)) {
431
+				$actions_count_by_status[$action_data->status] = $action_data->count;
432 432
 			}
433 433
 		}
434 434
 
@@ -442,22 +442,22 @@  discard block
 block discarded – undo
442 442
 	 *
443 443
 	 * @return void
444 444
 	 */
445
-	public function cancel_action( $action_id ) {
445
+	public function cancel_action($action_id) {
446 446
 		/** @var \wpdb $wpdb */
447 447
 		global $wpdb;
448 448
 
449 449
 		$updated = $wpdb->update(
450 450
 			$wpdb->actionscheduler_actions,
451
-			[ 'status' => self::STATUS_CANCELED ],
452
-			[ 'action_id' => $action_id ],
453
-			[ '%s' ],
454
-			[ '%d' ]
451
+			['status' => self::STATUS_CANCELED],
452
+			['action_id' => $action_id],
453
+			['%s'],
454
+			['%d']
455 455
 		);
456
-		if ( empty( $updated ) ) {
456
+		if (empty($updated)) {
457 457
 			/* translators: %s: action ID */
458
-			throw new \InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) );
458
+			throw new \InvalidArgumentException(sprintf(__('Unidentified action %s', 'action-scheduler'), $action_id));
459 459
 		}
460
-		do_action( 'action_scheduler_canceled_action', $action_id );
460
+		do_action('action_scheduler_canceled_action', $action_id);
461 461
 	}
462 462
 
463 463
 	/**
@@ -469,8 +469,8 @@  discard block
 block discarded – undo
469 469
 	 *
470 470
 	 * @return void
471 471
 	 */
472
-	public function cancel_actions_by_hook( $hook ) {
473
-		$this->bulk_cancel_actions( [ 'hook' => $hook ] );
472
+	public function cancel_actions_by_hook($hook) {
473
+		$this->bulk_cancel_actions(['hook' => $hook]);
474 474
 	}
475 475
 
476 476
 	/**
@@ -480,8 +480,8 @@  discard block
 block discarded – undo
480 480
 	 *
481 481
 	 * @return void
482 482
 	 */
483
-	public function cancel_actions_by_group( $group ) {
484
-		$this->bulk_cancel_actions( [ 'group' => $group ] );
483
+	public function cancel_actions_by_group($group) {
484
+		$this->bulk_cancel_actions(['group' => $group]);
485 485
 	}
486 486
 
487 487
 	/**
@@ -491,16 +491,16 @@  discard block
 block discarded – undo
491 491
 	 *
492 492
 	 * @param array $query_args Query parameters.
493 493
 	 */
494
-	protected function bulk_cancel_actions( $query_args ) {
494
+	protected function bulk_cancel_actions($query_args) {
495 495
 		/** @var \wpdb $wpdb */
496 496
 		global $wpdb;
497 497
 
498
-		if ( ! is_array( $query_args ) ) {
498
+		if (!is_array($query_args)) {
499 499
 			return;
500 500
 		}
501 501
 
502 502
 		// Don't cancel actions that are already canceled.
503
-		if ( isset( $query_args['status'] ) && $query_args['status'] == self::STATUS_CANCELED ) {
503
+		if (isset($query_args['status']) && $query_args['status'] == self::STATUS_CANCELED) {
504 504
 			return;
505 505
 		}
506 506
 
@@ -513,16 +513,16 @@  discard block
 block discarded – undo
513 513
 			]
514 514
 		);
515 515
 
516
-		while ( $action_ids ) {
517
-			$action_ids = $this->query_actions( $query_args );
518
-			if ( empty( $action_ids ) ) {
516
+		while ($action_ids) {
517
+			$action_ids = $this->query_actions($query_args);
518
+			if (empty($action_ids)) {
519 519
 				break;
520 520
 			}
521 521
 
522
-			$format     = array_fill( 0, count( $action_ids ), '%d' );
523
-			$query_in   = '(' . implode( ',', $format ) . ')';
522
+			$format     = array_fill(0, count($action_ids), '%d');
523
+			$query_in   = '(' . implode(',', $format) . ')';
524 524
 			$parameters = $action_ids;
525
-			array_unshift( $parameters, self::STATUS_CANCELED );
525
+			array_unshift($parameters, self::STATUS_CANCELED);
526 526
 
527 527
 			$wpdb->query(
528 528
 				$wpdb->prepare( // wpcs: PreparedSQLPlaceholders replacement count ok.
@@ -531,7 +531,7 @@  discard block
 block discarded – undo
531 531
 				)
532 532
 			);
533 533
 
534
-			do_action( 'action_scheduler_bulk_cancel_actions', $action_ids );
534
+			do_action('action_scheduler_bulk_cancel_actions', $action_ids);
535 535
 		}
536 536
 	}
537 537
 
@@ -540,14 +540,14 @@  discard block
 block discarded – undo
540 540
 	 *
541 541
 	 * @param int $action_id Action ID.
542 542
 	 */
543
-	public function delete_action( $action_id ) {
543
+	public function delete_action($action_id) {
544 544
 		/** @var \wpdb $wpdb */
545 545
 		global $wpdb;
546
-		$deleted = $wpdb->delete( $wpdb->actionscheduler_actions, [ 'action_id' => $action_id ], [ '%d' ] );
547
-		if ( empty( $deleted ) ) {
548
-			throw new \InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) );
546
+		$deleted = $wpdb->delete($wpdb->actionscheduler_actions, ['action_id' => $action_id], ['%d']);
547
+		if (empty($deleted)) {
548
+			throw new \InvalidArgumentException(sprintf(__('Unidentified action %s', 'action-scheduler'), $action_id));
549 549
 		}
550
-		do_action( 'action_scheduler_deleted_action', $action_id );
550
+		do_action('action_scheduler_deleted_action', $action_id);
551 551
 	}
552 552
 
553 553
 	/**
@@ -558,9 +558,9 @@  discard block
 block discarded – undo
558 558
 	 * @throws \InvalidArgumentException
559 559
 	 * @return \DateTime The local date the action is scheduled to run, or the date that it ran.
560 560
 	 */
561
-	public function get_date( $action_id ) {
562
-		$date = $this->get_date_gmt( $action_id );
563
-		ActionScheduler_TimezoneHelper::set_local_timezone( $date );
561
+	public function get_date($action_id) {
562
+		$date = $this->get_date_gmt($action_id);
563
+		ActionScheduler_TimezoneHelper::set_local_timezone($date);
564 564
 		return $date;
565 565
 	}
566 566
 
@@ -572,17 +572,17 @@  discard block
 block discarded – undo
572 572
 	 * @throws \InvalidArgumentException
573 573
 	 * @return \DateTime The GMT date the action is scheduled to run, or the date that it ran.
574 574
 	 */
575
-	protected function get_date_gmt( $action_id ) {
575
+	protected function get_date_gmt($action_id) {
576 576
 		/** @var \wpdb $wpdb */
577 577
 		global $wpdb;
578
-		$record = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->actionscheduler_actions} WHERE action_id=%d", $action_id ) );
579
-		if ( empty( $record ) ) {
580
-			throw new \InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) );
578
+		$record = $wpdb->get_row($wpdb->prepare("SELECT * FROM {$wpdb->actionscheduler_actions} WHERE action_id=%d", $action_id));
579
+		if (empty($record)) {
580
+			throw new \InvalidArgumentException(sprintf(__('Unidentified action %s', 'action-scheduler'), $action_id));
581 581
 		}
582
-		if ( $record->status == self::STATUS_PENDING ) {
583
-			return as_get_datetime_object( $record->scheduled_date_gmt );
582
+		if ($record->status == self::STATUS_PENDING) {
583
+			return as_get_datetime_object($record->scheduled_date_gmt);
584 584
 		} else {
585
-			return as_get_datetime_object( $record->last_attempt_gmt );
585
+			return as_get_datetime_object($record->last_attempt_gmt);
586 586
 		}
587 587
 	}
588 588
 
@@ -594,12 +594,12 @@  discard block
 block discarded – undo
594 594
 	 *
595 595
 	 * @return ActionScheduler_ActionClaim
596 596
 	 */
597
-	public function stake_claim( $max_actions = 10, \DateTime $before_date = null, $hooks = array(), $group = '' ) {
597
+	public function stake_claim($max_actions = 10, \DateTime $before_date = null, $hooks = array(), $group = '') {
598 598
 		$claim_id = $this->generate_claim_id();
599
-		$this->claim_actions( $claim_id, $max_actions, $before_date, $hooks, $group );
600
-		$action_ids = $this->find_actions_by_claim_id( $claim_id );
599
+		$this->claim_actions($claim_id, $max_actions, $before_date, $hooks, $group);
600
+		$action_ids = $this->find_actions_by_claim_id($claim_id);
601 601
 
602
-		return new ActionScheduler_ActionClaim( $claim_id, $action_ids );
602
+		return new ActionScheduler_ActionClaim($claim_id, $action_ids);
603 603
 	}
604 604
 
605 605
 	/**
@@ -611,7 +611,7 @@  discard block
 block discarded – undo
611 611
 		/** @var \wpdb $wpdb */
612 612
 		global $wpdb;
613 613
 		$now = as_get_datetime_object();
614
-		$wpdb->insert( $wpdb->actionscheduler_claims, [ 'date_created_gmt' => $now->format( 'Y-m-d H:i:s' ) ] );
614
+		$wpdb->insert($wpdb->actionscheduler_claims, ['date_created_gmt' => $now->format('Y-m-d H:i:s')]);
615 615
 
616 616
 		return $wpdb->insert_id;
617 617
 	}
@@ -626,39 +626,39 @@  discard block
 block discarded – undo
626 626
 	 * @return int The number of actions that were claimed.
627 627
 	 * @throws \RuntimeException
628 628
 	 */
629
-	protected function claim_actions( $claim_id, $limit, \DateTime $before_date = null, $hooks = array(), $group = '' ) {
629
+	protected function claim_actions($claim_id, $limit, \DateTime $before_date = null, $hooks = array(), $group = '') {
630 630
 		/** @var \wpdb $wpdb */
631 631
 		global $wpdb;
632 632
 
633 633
 		$now  = as_get_datetime_object();
634
-		$date = is_null( $before_date ) ? $now : clone $before_date;
634
+		$date = is_null($before_date) ? $now : clone $before_date;
635 635
 
636 636
 		// can't use $wpdb->update() because of the <= condition
637 637
 		$update = "UPDATE {$wpdb->actionscheduler_actions} SET claim_id=%d, last_attempt_gmt=%s, last_attempt_local=%s";
638 638
 		$params = array(
639 639
 			$claim_id,
640
-			$now->format( 'Y-m-d H:i:s' ),
641
-			current_time( 'mysql' ),
640
+			$now->format('Y-m-d H:i:s'),
641
+			current_time('mysql'),
642 642
 		);
643 643
 
644 644
 		$where    = "WHERE claim_id = 0 AND scheduled_date_gmt <= %s AND status=%s";
645
-		$params[] = $date->format( 'Y-m-d H:i:s' );
645
+		$params[] = $date->format('Y-m-d H:i:s');
646 646
 		$params[] = self::STATUS_PENDING;
647 647
 
648
-		if ( ! empty( $hooks ) ) {
649
-			$placeholders = array_fill( 0, count( $hooks ), '%s' );
650
-			$where       .= ' AND hook IN (' . join( ', ', $placeholders ) . ')';
651
-			$params       = array_merge( $params, array_values( $hooks ) );
648
+		if (!empty($hooks)) {
649
+			$placeholders = array_fill(0, count($hooks), '%s');
650
+			$where       .= ' AND hook IN (' . join(', ', $placeholders) . ')';
651
+			$params       = array_merge($params, array_values($hooks));
652 652
 		}
653 653
 
654
-		if ( ! empty( $group ) ) {
654
+		if (!empty($group)) {
655 655
 
656
-			$group_id = $this->get_group_id( $group, false );
656
+			$group_id = $this->get_group_id($group, false);
657 657
 
658 658
 			// throw exception if no matching group found, this matches ActionScheduler_wpPostStore's behaviour
659
-			if ( empty( $group_id ) ) {
659
+			if (empty($group_id)) {
660 660
 				/* translators: %s: group name */
661
-				throw new InvalidArgumentException( sprintf( __( 'The group "%s" does not exist.', 'action-scheduler' ), $group ) );
661
+				throw new InvalidArgumentException(sprintf(__('The group "%s" does not exist.', 'action-scheduler'), $group));
662 662
 			}
663 663
 
664 664
 			$where   .= ' AND group_id = %d';
@@ -668,11 +668,11 @@  discard block
 block discarded – undo
668 668
 		$order    = "ORDER BY attempts ASC, scheduled_date_gmt ASC, action_id ASC LIMIT %d";
669 669
 		$params[] = $limit;
670 670
 
671
-		$sql = $wpdb->prepare( "{$update} {$where} {$order}", $params );
671
+		$sql = $wpdb->prepare("{$update} {$where} {$order}", $params);
672 672
 
673
-		$rows_affected = $wpdb->query( $sql );
674
-		if ( $rows_affected === false ) {
675
-			throw new \RuntimeException( __( 'Unable to claim actions. Database error.', 'action-scheduler' ) );
673
+		$rows_affected = $wpdb->query($sql);
674
+		if ($rows_affected === false) {
675
+			throw new \RuntimeException(__('Unable to claim actions. Database error.', 'action-scheduler'));
676 676
 		}
677 677
 
678 678
 		return (int) $rows_affected;
@@ -687,9 +687,9 @@  discard block
 block discarded – undo
687 687
 		global $wpdb;
688 688
 
689 689
 		$sql = "SELECT COUNT(DISTINCT claim_id) FROM {$wpdb->actionscheduler_actions} WHERE claim_id != 0 AND status IN ( %s, %s)";
690
-		$sql = $wpdb->prepare( $sql, [ self::STATUS_PENDING, self::STATUS_RUNNING ] );
690
+		$sql = $wpdb->prepare($sql, [self::STATUS_PENDING, self::STATUS_RUNNING]);
691 691
 
692
-		return (int) $wpdb->get_var( $sql );
692
+		return (int) $wpdb->get_var($sql);
693 693
 	}
694 694
 
695 695
 	/**
@@ -698,14 +698,14 @@  discard block
 block discarded – undo
698 698
 	 * @param string $action_id Action ID.
699 699
 	 * @return mixed
700 700
 	 */
701
-	public function get_claim_id( $action_id ) {
701
+	public function get_claim_id($action_id) {
702 702
 		/** @var \wpdb $wpdb */
703 703
 		global $wpdb;
704 704
 
705 705
 		$sql = "SELECT claim_id FROM {$wpdb->actionscheduler_actions} WHERE action_id=%d";
706
-		$sql = $wpdb->prepare( $sql, $action_id );
706
+		$sql = $wpdb->prepare($sql, $action_id);
707 707
 
708
-		return (int) $wpdb->get_var( $sql );
708
+		return (int) $wpdb->get_var($sql);
709 709
 	}
710 710
 
711 711
 	/**
@@ -715,16 +715,16 @@  discard block
 block discarded – undo
715 715
 	 *
716 716
 	 * @return int[]
717 717
 	 */
718
-	public function find_actions_by_claim_id( $claim_id ) {
718
+	public function find_actions_by_claim_id($claim_id) {
719 719
 		/** @var \wpdb $wpdb */
720 720
 		global $wpdb;
721 721
 
722 722
 		$sql = "SELECT action_id FROM {$wpdb->actionscheduler_actions} WHERE claim_id=%d";
723
-		$sql = $wpdb->prepare( $sql, $claim_id );
723
+		$sql = $wpdb->prepare($sql, $claim_id);
724 724
 
725
-		$action_ids = $wpdb->get_col( $sql );
725
+		$action_ids = $wpdb->get_col($sql);
726 726
 
727
-		return array_map( 'intval', $action_ids );
727
+		return array_map('intval', $action_ids);
728 728
 	}
729 729
 
730 730
 	/**
@@ -732,11 +732,11 @@  discard block
 block discarded – undo
732 732
 	 *
733 733
 	 * @param ActionScheduler_ActionClaim $claim Claim object.
734 734
 	 */
735
-	public function release_claim( ActionScheduler_ActionClaim $claim ) {
735
+	public function release_claim(ActionScheduler_ActionClaim $claim) {
736 736
 		/** @var \wpdb $wpdb */
737 737
 		global $wpdb;
738
-		$wpdb->update( $wpdb->actionscheduler_actions, [ 'claim_id' => 0 ], [ 'claim_id' => $claim->get_id() ], [ '%d' ], [ '%d' ] );
739
-		$wpdb->delete( $wpdb->actionscheduler_claims, [ 'claim_id' => $claim->get_id() ], [ '%d' ] );
738
+		$wpdb->update($wpdb->actionscheduler_actions, ['claim_id' => 0], ['claim_id' => $claim->get_id()], ['%d'], ['%d']);
739
+		$wpdb->delete($wpdb->actionscheduler_claims, ['claim_id' => $claim->get_id()], ['%d']);
740 740
 	}
741 741
 
742 742
 	/**
@@ -746,15 +746,15 @@  discard block
 block discarded – undo
746 746
 	 *
747 747
 	 * @return void
748 748
 	 */
749
-	public function unclaim_action( $action_id ) {
749
+	public function unclaim_action($action_id) {
750 750
 		/** @var \wpdb $wpdb */
751 751
 		global $wpdb;
752 752
 		$wpdb->update(
753 753
 			$wpdb->actionscheduler_actions,
754
-			[ 'claim_id' => 0 ],
755
-			[ 'action_id' => $action_id ],
756
-			[ '%s' ],
757
-			[ '%d' ]
754
+			['claim_id' => 0],
755
+			['action_id' => $action_id],
756
+			['%s'],
757
+			['%d']
758 758
 		);
759 759
 	}
760 760
 
@@ -763,18 +763,18 @@  discard block
 block discarded – undo
763 763
 	 *
764 764
 	 * @param int $action_id Action ID.
765 765
 	 */
766
-	public function mark_failure( $action_id ) {
766
+	public function mark_failure($action_id) {
767 767
 		/** @var \wpdb $wpdb */
768 768
 		global $wpdb;
769 769
 		$updated = $wpdb->update(
770 770
 			$wpdb->actionscheduler_actions,
771
-			[ 'status' => self::STATUS_FAILED ],
772
-			[ 'action_id' => $action_id ],
773
-			[ '%s' ],
774
-			[ '%d' ]
771
+			['status' => self::STATUS_FAILED],
772
+			['action_id' => $action_id],
773
+			['%s'],
774
+			['%d']
775 775
 		);
776
-		if ( empty( $updated ) ) {
777
-			throw new \InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) );
776
+		if (empty($updated)) {
777
+			throw new \InvalidArgumentException(sprintf(__('Unidentified action %s', 'action-scheduler'), $action_id));
778 778
 		}
779 779
 	}
780 780
 
@@ -785,13 +785,13 @@  discard block
 block discarded – undo
785 785
 	 *
786 786
 	 * @return void
787 787
 	 */
788
-	public function log_execution( $action_id ) {
788
+	public function log_execution($action_id) {
789 789
 		/** @var \wpdb $wpdb */
790 790
 		global $wpdb;
791 791
 
792 792
 		$sql = "UPDATE {$wpdb->actionscheduler_actions} SET attempts = attempts+1, status=%s, last_attempt_gmt = %s, last_attempt_local = %s WHERE action_id = %d";
793
-		$sql = $wpdb->prepare( $sql, self::STATUS_RUNNING, current_time( 'mysql', true ), current_time( 'mysql' ), $action_id );
794
-		$wpdb->query( $sql );
793
+		$sql = $wpdb->prepare($sql, self::STATUS_RUNNING, current_time('mysql', true), current_time('mysql'), $action_id);
794
+		$wpdb->query($sql);
795 795
 	}
796 796
 
797 797
 	/**
@@ -801,22 +801,22 @@  discard block
 block discarded – undo
801 801
 	 *
802 802
 	 * @return void
803 803
 	 */
804
-	public function mark_complete( $action_id ) {
804
+	public function mark_complete($action_id) {
805 805
 		/** @var \wpdb $wpdb */
806 806
 		global $wpdb;
807 807
 		$updated = $wpdb->update(
808 808
 			$wpdb->actionscheduler_actions,
809 809
 			[
810 810
 				'status'             => self::STATUS_COMPLETE,
811
-				'last_attempt_gmt'   => current_time( 'mysql', true ),
812
-				'last_attempt_local' => current_time( 'mysql' ),
811
+				'last_attempt_gmt'   => current_time('mysql', true),
812
+				'last_attempt_local' => current_time('mysql'),
813 813
 			],
814
-			[ 'action_id' => $action_id ],
815
-			[ '%s' ],
816
-			[ '%d' ]
814
+			['action_id' => $action_id],
815
+			['%s'],
816
+			['%d']
817 817
 		);
818
-		if ( empty( $updated ) ) {
819
-			throw new \InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) );
818
+		if (empty($updated)) {
819
+			throw new \InvalidArgumentException(sprintf(__('Unidentified action %s', 'action-scheduler'), $action_id));
820 820
 		}
821 821
 	}
822 822
 
@@ -827,17 +827,17 @@  discard block
 block discarded – undo
827 827
 	 *
828 828
 	 * @return string
829 829
 	 */
830
-	public function get_status( $action_id ) {
830
+	public function get_status($action_id) {
831 831
 		/** @var \wpdb $wpdb */
832 832
 		global $wpdb;
833 833
 		$sql    = "SELECT status FROM {$wpdb->actionscheduler_actions} WHERE action_id=%d";
834
-		$sql    = $wpdb->prepare( $sql, $action_id );
835
-		$status = $wpdb->get_var( $sql );
834
+		$sql    = $wpdb->prepare($sql, $action_id);
835
+		$status = $wpdb->get_var($sql);
836 836
 
837
-		if ( $status === null ) {
838
-			throw new \InvalidArgumentException( __( 'Invalid action ID. No status found.', 'action-scheduler' ) );
839
-		} elseif ( empty( $status ) ) {
840
-			throw new \RuntimeException( __( 'Unknown status found for action.', 'action-scheduler' ) );
837
+		if ($status === null) {
838
+			throw new \InvalidArgumentException(__('Invalid action ID. No status found.', 'action-scheduler'));
839
+		} elseif (empty($status)) {
840
+			throw new \RuntimeException(__('Unknown status found for action.', 'action-scheduler'));
841 841
 		} else {
842 842
 			return $status;
843 843
 		}
Please login to merge, or discard this patch.
Braces   +1 added lines, -2 removed lines patch added patch discarded remove patch
@@ -62,8 +62,7 @@
 block discarded – undo
62 62
 
63 63
 			if ( is_wp_error( $action_id ) ) {
64 64
 				throw new RuntimeException( $action_id->get_error_message() );
65
-			}
66
-			elseif ( empty( $action_id ) ) {
65
+			} elseif ( empty( $action_id ) ) {
67 66
 				throw new RuntimeException( $wpdb->last_error ? $wpdb->last_error : __( 'Database error.', 'action-scheduler' ) );
68 67
 			}
69 68
 
Please login to merge, or discard this patch.
action-scheduler/classes/data-stores/ActionScheduler_wpCommentLogger.php 2 patches
Indentation   +232 added lines, -232 removed lines patch added patch discarded remove patch
@@ -4,237 +4,237 @@
 block discarded – undo
4 4
  * Class ActionScheduler_wpCommentLogger
5 5
  */
6 6
 class ActionScheduler_wpCommentLogger extends ActionScheduler_Logger {
7
-	const AGENT = 'ActionScheduler';
8
-	const TYPE = 'action_log';
9
-
10
-	/**
11
-	 * @param string $action_id
12
-	 * @param string $message
13
-	 * @param DateTime $date
14
-	 *
15
-	 * @return string The log entry ID
16
-	 */
17
-	public function log( $action_id, $message, DateTime $date = NULL ) {
18
-		if ( empty($date) ) {
19
-			$date = as_get_datetime_object();
20
-		} else {
21
-			$date = as_get_datetime_object( clone $date );
22
-		}
23
-		$comment_id = $this->create_wp_comment( $action_id, $message, $date );
24
-		return $comment_id;
25
-	}
26
-
27
-	protected function create_wp_comment( $action_id, $message, DateTime $date ) {
28
-
29
-		$comment_date_gmt = $date->format('Y-m-d H:i:s');
30
-		ActionScheduler_TimezoneHelper::set_local_timezone( $date );
31
-		$comment_data = array(
32
-			'comment_post_ID' => $action_id,
33
-			'comment_date' => $date->format('Y-m-d H:i:s'),
34
-			'comment_date_gmt' => $comment_date_gmt,
35
-			'comment_author' => self::AGENT,
36
-			'comment_content' => $message,
37
-			'comment_agent' => self::AGENT,
38
-			'comment_type' => self::TYPE,
39
-		);
40
-		return wp_insert_comment($comment_data);
41
-	}
42
-
43
-	/**
44
-	 * @param string $entry_id
45
-	 *
46
-	 * @return ActionScheduler_LogEntry
47
-	 */
48
-	public function get_entry( $entry_id ) {
49
-		$comment = $this->get_comment( $entry_id );
50
-		if ( empty($comment) || $comment->comment_type != self::TYPE ) {
51
-			return new ActionScheduler_NullLogEntry();
52
-		}
53
-
54
-		$date = as_get_datetime_object( $comment->comment_date_gmt );
55
-		ActionScheduler_TimezoneHelper::set_local_timezone( $date );
56
-		return new ActionScheduler_LogEntry( $comment->comment_post_ID, $comment->comment_content, $date );
57
-	}
58
-
59
-	/**
60
-	 * @param string $action_id
61
-	 *
62
-	 * @return ActionScheduler_LogEntry[]
63
-	 */
64
-	public function get_logs( $action_id ) {
65
-		$status = 'all';
66
-		if ( get_post_status($action_id) == 'trash' ) {
67
-			$status = 'post-trashed';
68
-		}
69
-		$comments = get_comments(array(
70
-			'post_id' => $action_id,
71
-			'orderby' => 'comment_date_gmt',
72
-			'order' => 'ASC',
73
-			'type' => self::TYPE,
74
-			'status' => $status,
75
-		));
76
-		$logs = array();
77
-		foreach ( $comments as $c ) {
78
-			$entry = $this->get_entry( $c );
79
-			if ( !empty($entry) ) {
80
-				$logs[] = $entry;
81
-			}
82
-		}
83
-		return $logs;
84
-	}
85
-
86
-	protected function get_comment( $comment_id ) {
87
-		return get_comment( $comment_id );
88
-	}
89
-
90
-
91
-
92
-	/**
93
-	 * @param WP_Comment_Query $query
94
-	 */
95
-	public function filter_comment_queries( $query ) {
96
-		foreach ( array('ID', 'parent', 'post_author', 'post_name', 'post_parent', 'type', 'post_type', 'post_id', 'post_ID') as $key ) {
97
-			if ( !empty($query->query_vars[$key]) ) {
98
-				return; // don't slow down queries that wouldn't include action_log comments anyway
99
-			}
100
-		}
101
-		$query->query_vars['action_log_filter'] = TRUE;
102
-		add_filter( 'comments_clauses', array( $this, 'filter_comment_query_clauses' ), 10, 2 );
103
-	}
104
-
105
-	/**
106
-	 * @param array $clauses
107
-	 * @param WP_Comment_Query $query
108
-	 *
109
-	 * @return array
110
-	 */
111
-	public function filter_comment_query_clauses( $clauses, $query ) {
112
-		if ( !empty($query->query_vars['action_log_filter']) ) {
113
-			$clauses['where'] .= $this->get_where_clause();
114
-		}
115
-		return $clauses;
116
-	}
117
-
118
-	/**
119
-	 * Make sure Action Scheduler logs are excluded from comment feeds, which use WP_Query, not
120
-	 * the WP_Comment_Query class handled by @see self::filter_comment_queries().
121
-	 *
122
-	 * @param string $where
123
-	 * @param WP_Query $query
124
-	 *
125
-	 * @return string
126
-	 */
127
-	public function filter_comment_feed( $where, $query ) {
128
-		if ( is_comment_feed() ) {
129
-			$where .= $this->get_where_clause();
130
-		}
131
-		return $where;
132
-	}
133
-
134
-	/**
135
-	 * Return a SQL clause to exclude Action Scheduler comments.
136
-	 *
137
-	 * @return string
138
-	 */
139
-	protected function get_where_clause() {
140
-		global $wpdb;
141
-		return sprintf( " AND {$wpdb->comments}.comment_type != '%s'", self::TYPE );
142
-	}
143
-
144
-	/**
145
-	 * Remove action log entries from wp_count_comments()
146
-	 *
147
-	 * @param array $stats
148
-	 * @param int $post_id
149
-	 *
150
-	 * @return object
151
-	 */
152
-	public function filter_comment_count( $stats, $post_id ) {
153
-		global $wpdb;
154
-
155
-		if ( 0 === $post_id ) {
156
-			$stats = $this->get_comment_count();
157
-		}
158
-
159
-		return $stats;
160
-	}
161
-
162
-	/**
163
-	 * Retrieve the comment counts from our cache, or the database if the cached version isn't set.
164
-	 *
165
-	 * @return object
166
-	 */
167
-	protected function get_comment_count() {
168
-		global $wpdb;
169
-
170
-		$stats = get_transient( 'as_comment_count' );
171
-
172
-		if ( ! $stats ) {
173
-			$stats = array();
174
-
175
-			$count = $wpdb->get_results( "SELECT comment_approved, COUNT( * ) AS num_comments FROM {$wpdb->comments} WHERE comment_type NOT IN('order_note','action_log') GROUP BY comment_approved", ARRAY_A );
176
-
177
-			$total = 0;
178
-			$stats = array();
179
-			$approved = array( '0' => 'moderated', '1' => 'approved', 'spam' => 'spam', 'trash' => 'trash', 'post-trashed' => 'post-trashed' );
180
-
181
-			foreach ( (array) $count as $row ) {
182
-				// Don't count post-trashed toward totals
183
-				if ( 'post-trashed' != $row['comment_approved'] && 'trash' != $row['comment_approved'] ) {
184
-					$total += $row['num_comments'];
185
-				}
186
-				if ( isset( $approved[ $row['comment_approved'] ] ) ) {
187
-					$stats[ $approved[ $row['comment_approved'] ] ] = $row['num_comments'];
188
-				}
189
-			}
190
-
191
-			$stats['total_comments'] = $total;
192
-			$stats['all']            = $total;
193
-
194
-			foreach ( $approved as $key ) {
195
-				if ( empty( $stats[ $key ] ) ) {
196
-					$stats[ $key ] = 0;
197
-				}
198
-			}
199
-
200
-			$stats = (object) $stats;
201
-			set_transient( 'as_comment_count', $stats );
202
-		}
203
-
204
-		return $stats;
205
-	}
206
-
207
-	/**
208
-	 * Delete comment count cache whenever there is new comment or the status of a comment changes. Cache
209
-	 * will be regenerated next time ActionScheduler_wpCommentLogger::filter_comment_count() is called.
210
-	 */
211
-	public function delete_comment_count_cache() {
212
-		delete_transient( 'as_comment_count' );
213
-	}
214
-
215
-	/**
216
-	 * @codeCoverageIgnore
217
-	 */
218
-	public function init() {
219
-		add_action( 'action_scheduler_before_process_queue', array( $this, 'disable_comment_counting' ), 10, 0 );
220
-		add_action( 'action_scheduler_after_process_queue', array( $this, 'enable_comment_counting' ), 10, 0 );
221
-
222
-		parent::init();
223
-
224
-		add_action( 'pre_get_comments', array( $this, 'filter_comment_queries' ), 10, 1 );
225
-		add_action( 'wp_count_comments', array( $this, 'filter_comment_count' ), 20, 2 ); // run after WC_Comments::wp_count_comments() to make sure we exclude order notes and action logs
226
-		add_action( 'comment_feed_where', array( $this, 'filter_comment_feed' ), 10, 2 );
227
-
228
-		// Delete comments count cache whenever there is a new comment or a comment status changes
229
-		add_action( 'wp_insert_comment', array( $this, 'delete_comment_count_cache' ) );
230
-		add_action( 'wp_set_comment_status', array( $this, 'delete_comment_count_cache' ) );
231
-	}
232
-
233
-	public function disable_comment_counting() {
234
-		wp_defer_comment_counting(true);
235
-	}
236
-	public function enable_comment_counting() {
237
-		wp_defer_comment_counting(false);
238
-	}
7
+    const AGENT = 'ActionScheduler';
8
+    const TYPE = 'action_log';
9
+
10
+    /**
11
+     * @param string $action_id
12
+     * @param string $message
13
+     * @param DateTime $date
14
+     *
15
+     * @return string The log entry ID
16
+     */
17
+    public function log( $action_id, $message, DateTime $date = NULL ) {
18
+        if ( empty($date) ) {
19
+            $date = as_get_datetime_object();
20
+        } else {
21
+            $date = as_get_datetime_object( clone $date );
22
+        }
23
+        $comment_id = $this->create_wp_comment( $action_id, $message, $date );
24
+        return $comment_id;
25
+    }
26
+
27
+    protected function create_wp_comment( $action_id, $message, DateTime $date ) {
28
+
29
+        $comment_date_gmt = $date->format('Y-m-d H:i:s');
30
+        ActionScheduler_TimezoneHelper::set_local_timezone( $date );
31
+        $comment_data = array(
32
+            'comment_post_ID' => $action_id,
33
+            'comment_date' => $date->format('Y-m-d H:i:s'),
34
+            'comment_date_gmt' => $comment_date_gmt,
35
+            'comment_author' => self::AGENT,
36
+            'comment_content' => $message,
37
+            'comment_agent' => self::AGENT,
38
+            'comment_type' => self::TYPE,
39
+        );
40
+        return wp_insert_comment($comment_data);
41
+    }
42
+
43
+    /**
44
+     * @param string $entry_id
45
+     *
46
+     * @return ActionScheduler_LogEntry
47
+     */
48
+    public function get_entry( $entry_id ) {
49
+        $comment = $this->get_comment( $entry_id );
50
+        if ( empty($comment) || $comment->comment_type != self::TYPE ) {
51
+            return new ActionScheduler_NullLogEntry();
52
+        }
53
+
54
+        $date = as_get_datetime_object( $comment->comment_date_gmt );
55
+        ActionScheduler_TimezoneHelper::set_local_timezone( $date );
56
+        return new ActionScheduler_LogEntry( $comment->comment_post_ID, $comment->comment_content, $date );
57
+    }
58
+
59
+    /**
60
+     * @param string $action_id
61
+     *
62
+     * @return ActionScheduler_LogEntry[]
63
+     */
64
+    public function get_logs( $action_id ) {
65
+        $status = 'all';
66
+        if ( get_post_status($action_id) == 'trash' ) {
67
+            $status = 'post-trashed';
68
+        }
69
+        $comments = get_comments(array(
70
+            'post_id' => $action_id,
71
+            'orderby' => 'comment_date_gmt',
72
+            'order' => 'ASC',
73
+            'type' => self::TYPE,
74
+            'status' => $status,
75
+        ));
76
+        $logs = array();
77
+        foreach ( $comments as $c ) {
78
+            $entry = $this->get_entry( $c );
79
+            if ( !empty($entry) ) {
80
+                $logs[] = $entry;
81
+            }
82
+        }
83
+        return $logs;
84
+    }
85
+
86
+    protected function get_comment( $comment_id ) {
87
+        return get_comment( $comment_id );
88
+    }
89
+
90
+
91
+
92
+    /**
93
+     * @param WP_Comment_Query $query
94
+     */
95
+    public function filter_comment_queries( $query ) {
96
+        foreach ( array('ID', 'parent', 'post_author', 'post_name', 'post_parent', 'type', 'post_type', 'post_id', 'post_ID') as $key ) {
97
+            if ( !empty($query->query_vars[$key]) ) {
98
+                return; // don't slow down queries that wouldn't include action_log comments anyway
99
+            }
100
+        }
101
+        $query->query_vars['action_log_filter'] = TRUE;
102
+        add_filter( 'comments_clauses', array( $this, 'filter_comment_query_clauses' ), 10, 2 );
103
+    }
104
+
105
+    /**
106
+     * @param array $clauses
107
+     * @param WP_Comment_Query $query
108
+     *
109
+     * @return array
110
+     */
111
+    public function filter_comment_query_clauses( $clauses, $query ) {
112
+        if ( !empty($query->query_vars['action_log_filter']) ) {
113
+            $clauses['where'] .= $this->get_where_clause();
114
+        }
115
+        return $clauses;
116
+    }
117
+
118
+    /**
119
+     * Make sure Action Scheduler logs are excluded from comment feeds, which use WP_Query, not
120
+     * the WP_Comment_Query class handled by @see self::filter_comment_queries().
121
+     *
122
+     * @param string $where
123
+     * @param WP_Query $query
124
+     *
125
+     * @return string
126
+     */
127
+    public function filter_comment_feed( $where, $query ) {
128
+        if ( is_comment_feed() ) {
129
+            $where .= $this->get_where_clause();
130
+        }
131
+        return $where;
132
+    }
133
+
134
+    /**
135
+     * Return a SQL clause to exclude Action Scheduler comments.
136
+     *
137
+     * @return string
138
+     */
139
+    protected function get_where_clause() {
140
+        global $wpdb;
141
+        return sprintf( " AND {$wpdb->comments}.comment_type != '%s'", self::TYPE );
142
+    }
143
+
144
+    /**
145
+     * Remove action log entries from wp_count_comments()
146
+     *
147
+     * @param array $stats
148
+     * @param int $post_id
149
+     *
150
+     * @return object
151
+     */
152
+    public function filter_comment_count( $stats, $post_id ) {
153
+        global $wpdb;
154
+
155
+        if ( 0 === $post_id ) {
156
+            $stats = $this->get_comment_count();
157
+        }
158
+
159
+        return $stats;
160
+    }
161
+
162
+    /**
163
+     * Retrieve the comment counts from our cache, or the database if the cached version isn't set.
164
+     *
165
+     * @return object
166
+     */
167
+    protected function get_comment_count() {
168
+        global $wpdb;
169
+
170
+        $stats = get_transient( 'as_comment_count' );
171
+
172
+        if ( ! $stats ) {
173
+            $stats = array();
174
+
175
+            $count = $wpdb->get_results( "SELECT comment_approved, COUNT( * ) AS num_comments FROM {$wpdb->comments} WHERE comment_type NOT IN('order_note','action_log') GROUP BY comment_approved", ARRAY_A );
176
+
177
+            $total = 0;
178
+            $stats = array();
179
+            $approved = array( '0' => 'moderated', '1' => 'approved', 'spam' => 'spam', 'trash' => 'trash', 'post-trashed' => 'post-trashed' );
180
+
181
+            foreach ( (array) $count as $row ) {
182
+                // Don't count post-trashed toward totals
183
+                if ( 'post-trashed' != $row['comment_approved'] && 'trash' != $row['comment_approved'] ) {
184
+                    $total += $row['num_comments'];
185
+                }
186
+                if ( isset( $approved[ $row['comment_approved'] ] ) ) {
187
+                    $stats[ $approved[ $row['comment_approved'] ] ] = $row['num_comments'];
188
+                }
189
+            }
190
+
191
+            $stats['total_comments'] = $total;
192
+            $stats['all']            = $total;
193
+
194
+            foreach ( $approved as $key ) {
195
+                if ( empty( $stats[ $key ] ) ) {
196
+                    $stats[ $key ] = 0;
197
+                }
198
+            }
199
+
200
+            $stats = (object) $stats;
201
+            set_transient( 'as_comment_count', $stats );
202
+        }
203
+
204
+        return $stats;
205
+    }
206
+
207
+    /**
208
+     * Delete comment count cache whenever there is new comment or the status of a comment changes. Cache
209
+     * will be regenerated next time ActionScheduler_wpCommentLogger::filter_comment_count() is called.
210
+     */
211
+    public function delete_comment_count_cache() {
212
+        delete_transient( 'as_comment_count' );
213
+    }
214
+
215
+    /**
216
+     * @codeCoverageIgnore
217
+     */
218
+    public function init() {
219
+        add_action( 'action_scheduler_before_process_queue', array( $this, 'disable_comment_counting' ), 10, 0 );
220
+        add_action( 'action_scheduler_after_process_queue', array( $this, 'enable_comment_counting' ), 10, 0 );
221
+
222
+        parent::init();
223
+
224
+        add_action( 'pre_get_comments', array( $this, 'filter_comment_queries' ), 10, 1 );
225
+        add_action( 'wp_count_comments', array( $this, 'filter_comment_count' ), 20, 2 ); // run after WC_Comments::wp_count_comments() to make sure we exclude order notes and action logs
226
+        add_action( 'comment_feed_where', array( $this, 'filter_comment_feed' ), 10, 2 );
227
+
228
+        // Delete comments count cache whenever there is a new comment or a comment status changes
229
+        add_action( 'wp_insert_comment', array( $this, 'delete_comment_count_cache' ) );
230
+        add_action( 'wp_set_comment_status', array( $this, 'delete_comment_count_cache' ) );
231
+    }
232
+
233
+    public function disable_comment_counting() {
234
+        wp_defer_comment_counting(true);
235
+    }
236
+    public function enable_comment_counting() {
237
+        wp_defer_comment_counting(false);
238
+    }
239 239
 
240 240
 }
Please login to merge, or discard this patch.
Spacing   +50 added lines, -50 removed lines patch added patch discarded remove patch
@@ -14,20 +14,20 @@  discard block
 block discarded – undo
14 14
 	 *
15 15
 	 * @return string The log entry ID
16 16
 	 */
17
-	public function log( $action_id, $message, DateTime $date = NULL ) {
18
-		if ( empty($date) ) {
17
+	public function log($action_id, $message, DateTime $date = NULL) {
18
+		if (empty($date)) {
19 19
 			$date = as_get_datetime_object();
20 20
 		} else {
21
-			$date = as_get_datetime_object( clone $date );
21
+			$date = as_get_datetime_object(clone $date);
22 22
 		}
23
-		$comment_id = $this->create_wp_comment( $action_id, $message, $date );
23
+		$comment_id = $this->create_wp_comment($action_id, $message, $date);
24 24
 		return $comment_id;
25 25
 	}
26 26
 
27
-	protected function create_wp_comment( $action_id, $message, DateTime $date ) {
27
+	protected function create_wp_comment($action_id, $message, DateTime $date) {
28 28
 
29 29
 		$comment_date_gmt = $date->format('Y-m-d H:i:s');
30
-		ActionScheduler_TimezoneHelper::set_local_timezone( $date );
30
+		ActionScheduler_TimezoneHelper::set_local_timezone($date);
31 31
 		$comment_data = array(
32 32
 			'comment_post_ID' => $action_id,
33 33
 			'comment_date' => $date->format('Y-m-d H:i:s'),
@@ -45,15 +45,15 @@  discard block
 block discarded – undo
45 45
 	 *
46 46
 	 * @return ActionScheduler_LogEntry
47 47
 	 */
48
-	public function get_entry( $entry_id ) {
49
-		$comment = $this->get_comment( $entry_id );
50
-		if ( empty($comment) || $comment->comment_type != self::TYPE ) {
48
+	public function get_entry($entry_id) {
49
+		$comment = $this->get_comment($entry_id);
50
+		if (empty($comment) || $comment->comment_type != self::TYPE) {
51 51
 			return new ActionScheduler_NullLogEntry();
52 52
 		}
53 53
 
54
-		$date = as_get_datetime_object( $comment->comment_date_gmt );
55
-		ActionScheduler_TimezoneHelper::set_local_timezone( $date );
56
-		return new ActionScheduler_LogEntry( $comment->comment_post_ID, $comment->comment_content, $date );
54
+		$date = as_get_datetime_object($comment->comment_date_gmt);
55
+		ActionScheduler_TimezoneHelper::set_local_timezone($date);
56
+		return new ActionScheduler_LogEntry($comment->comment_post_ID, $comment->comment_content, $date);
57 57
 	}
58 58
 
59 59
 	/**
@@ -61,9 +61,9 @@  discard block
 block discarded – undo
61 61
 	 *
62 62
 	 * @return ActionScheduler_LogEntry[]
63 63
 	 */
64
-	public function get_logs( $action_id ) {
64
+	public function get_logs($action_id) {
65 65
 		$status = 'all';
66
-		if ( get_post_status($action_id) == 'trash' ) {
66
+		if (get_post_status($action_id) == 'trash') {
67 67
 			$status = 'post-trashed';
68 68
 		}
69 69
 		$comments = get_comments(array(
@@ -74,17 +74,17 @@  discard block
 block discarded – undo
74 74
 			'status' => $status,
75 75
 		));
76 76
 		$logs = array();
77
-		foreach ( $comments as $c ) {
78
-			$entry = $this->get_entry( $c );
79
-			if ( !empty($entry) ) {
77
+		foreach ($comments as $c) {
78
+			$entry = $this->get_entry($c);
79
+			if (!empty($entry)) {
80 80
 				$logs[] = $entry;
81 81
 			}
82 82
 		}
83 83
 		return $logs;
84 84
 	}
85 85
 
86
-	protected function get_comment( $comment_id ) {
87
-		return get_comment( $comment_id );
86
+	protected function get_comment($comment_id) {
87
+		return get_comment($comment_id);
88 88
 	}
89 89
 
90 90
 
@@ -92,14 +92,14 @@  discard block
 block discarded – undo
92 92
 	/**
93 93
 	 * @param WP_Comment_Query $query
94 94
 	 */
95
-	public function filter_comment_queries( $query ) {
96
-		foreach ( array('ID', 'parent', 'post_author', 'post_name', 'post_parent', 'type', 'post_type', 'post_id', 'post_ID') as $key ) {
97
-			if ( !empty($query->query_vars[$key]) ) {
95
+	public function filter_comment_queries($query) {
96
+		foreach (array('ID', 'parent', 'post_author', 'post_name', 'post_parent', 'type', 'post_type', 'post_id', 'post_ID') as $key) {
97
+			if (!empty($query->query_vars[$key])) {
98 98
 				return; // don't slow down queries that wouldn't include action_log comments anyway
99 99
 			}
100 100
 		}
101 101
 		$query->query_vars['action_log_filter'] = TRUE;
102
-		add_filter( 'comments_clauses', array( $this, 'filter_comment_query_clauses' ), 10, 2 );
102
+		add_filter('comments_clauses', array($this, 'filter_comment_query_clauses'), 10, 2);
103 103
 	}
104 104
 
105 105
 	/**
@@ -108,8 +108,8 @@  discard block
 block discarded – undo
108 108
 	 *
109 109
 	 * @return array
110 110
 	 */
111
-	public function filter_comment_query_clauses( $clauses, $query ) {
112
-		if ( !empty($query->query_vars['action_log_filter']) ) {
111
+	public function filter_comment_query_clauses($clauses, $query) {
112
+		if (!empty($query->query_vars['action_log_filter'])) {
113 113
 			$clauses['where'] .= $this->get_where_clause();
114 114
 		}
115 115
 		return $clauses;
@@ -124,8 +124,8 @@  discard block
 block discarded – undo
124 124
 	 *
125 125
 	 * @return string
126 126
 	 */
127
-	public function filter_comment_feed( $where, $query ) {
128
-		if ( is_comment_feed() ) {
127
+	public function filter_comment_feed($where, $query) {
128
+		if (is_comment_feed()) {
129 129
 			$where .= $this->get_where_clause();
130 130
 		}
131 131
 		return $where;
@@ -138,7 +138,7 @@  discard block
 block discarded – undo
138 138
 	 */
139 139
 	protected function get_where_clause() {
140 140
 		global $wpdb;
141
-		return sprintf( " AND {$wpdb->comments}.comment_type != '%s'", self::TYPE );
141
+		return sprintf(" AND {$wpdb->comments}.comment_type != '%s'", self::TYPE);
142 142
 	}
143 143
 
144 144
 	/**
@@ -149,10 +149,10 @@  discard block
 block discarded – undo
149 149
 	 *
150 150
 	 * @return object
151 151
 	 */
152
-	public function filter_comment_count( $stats, $post_id ) {
152
+	public function filter_comment_count($stats, $post_id) {
153 153
 		global $wpdb;
154 154
 
155
-		if ( 0 === $post_id ) {
155
+		if (0 === $post_id) {
156 156
 			$stats = $this->get_comment_count();
157 157
 		}
158 158
 
@@ -167,38 +167,38 @@  discard block
 block discarded – undo
167 167
 	protected function get_comment_count() {
168 168
 		global $wpdb;
169 169
 
170
-		$stats = get_transient( 'as_comment_count' );
170
+		$stats = get_transient('as_comment_count');
171 171
 
172
-		if ( ! $stats ) {
172
+		if (!$stats) {
173 173
 			$stats = array();
174 174
 
175
-			$count = $wpdb->get_results( "SELECT comment_approved, COUNT( * ) AS num_comments FROM {$wpdb->comments} WHERE comment_type NOT IN('order_note','action_log') GROUP BY comment_approved", ARRAY_A );
175
+			$count = $wpdb->get_results("SELECT comment_approved, COUNT( * ) AS num_comments FROM {$wpdb->comments} WHERE comment_type NOT IN('order_note','action_log') GROUP BY comment_approved", ARRAY_A);
176 176
 
177 177
 			$total = 0;
178 178
 			$stats = array();
179
-			$approved = array( '0' => 'moderated', '1' => 'approved', 'spam' => 'spam', 'trash' => 'trash', 'post-trashed' => 'post-trashed' );
179
+			$approved = array('0' => 'moderated', '1' => 'approved', 'spam' => 'spam', 'trash' => 'trash', 'post-trashed' => 'post-trashed');
180 180
 
181
-			foreach ( (array) $count as $row ) {
181
+			foreach ((array) $count as $row) {
182 182
 				// Don't count post-trashed toward totals
183
-				if ( 'post-trashed' != $row['comment_approved'] && 'trash' != $row['comment_approved'] ) {
183
+				if ('post-trashed' != $row['comment_approved'] && 'trash' != $row['comment_approved']) {
184 184
 					$total += $row['num_comments'];
185 185
 				}
186
-				if ( isset( $approved[ $row['comment_approved'] ] ) ) {
187
-					$stats[ $approved[ $row['comment_approved'] ] ] = $row['num_comments'];
186
+				if (isset($approved[$row['comment_approved']])) {
187
+					$stats[$approved[$row['comment_approved']]] = $row['num_comments'];
188 188
 				}
189 189
 			}
190 190
 
191 191
 			$stats['total_comments'] = $total;
192 192
 			$stats['all']            = $total;
193 193
 
194
-			foreach ( $approved as $key ) {
195
-				if ( empty( $stats[ $key ] ) ) {
196
-					$stats[ $key ] = 0;
194
+			foreach ($approved as $key) {
195
+				if (empty($stats[$key])) {
196
+					$stats[$key] = 0;
197 197
 				}
198 198
 			}
199 199
 
200 200
 			$stats = (object) $stats;
201
-			set_transient( 'as_comment_count', $stats );
201
+			set_transient('as_comment_count', $stats);
202 202
 		}
203 203
 
204 204
 		return $stats;
@@ -209,25 +209,25 @@  discard block
 block discarded – undo
209 209
 	 * will be regenerated next time ActionScheduler_wpCommentLogger::filter_comment_count() is called.
210 210
 	 */
211 211
 	public function delete_comment_count_cache() {
212
-		delete_transient( 'as_comment_count' );
212
+		delete_transient('as_comment_count');
213 213
 	}
214 214
 
215 215
 	/**
216 216
 	 * @codeCoverageIgnore
217 217
 	 */
218 218
 	public function init() {
219
-		add_action( 'action_scheduler_before_process_queue', array( $this, 'disable_comment_counting' ), 10, 0 );
220
-		add_action( 'action_scheduler_after_process_queue', array( $this, 'enable_comment_counting' ), 10, 0 );
219
+		add_action('action_scheduler_before_process_queue', array($this, 'disable_comment_counting'), 10, 0);
220
+		add_action('action_scheduler_after_process_queue', array($this, 'enable_comment_counting'), 10, 0);
221 221
 
222 222
 		parent::init();
223 223
 
224
-		add_action( 'pre_get_comments', array( $this, 'filter_comment_queries' ), 10, 1 );
225
-		add_action( 'wp_count_comments', array( $this, 'filter_comment_count' ), 20, 2 ); // run after WC_Comments::wp_count_comments() to make sure we exclude order notes and action logs
226
-		add_action( 'comment_feed_where', array( $this, 'filter_comment_feed' ), 10, 2 );
224
+		add_action('pre_get_comments', array($this, 'filter_comment_queries'), 10, 1);
225
+		add_action('wp_count_comments', array($this, 'filter_comment_count'), 20, 2); // run after WC_Comments::wp_count_comments() to make sure we exclude order notes and action logs
226
+		add_action('comment_feed_where', array($this, 'filter_comment_feed'), 10, 2);
227 227
 
228 228
 		// Delete comments count cache whenever there is a new comment or a comment status changes
229
-		add_action( 'wp_insert_comment', array( $this, 'delete_comment_count_cache' ) );
230
-		add_action( 'wp_set_comment_status', array( $this, 'delete_comment_count_cache' ) );
229
+		add_action('wp_insert_comment', array($this, 'delete_comment_count_cache'));
230
+		add_action('wp_set_comment_status', array($this, 'delete_comment_count_cache'));
231 231
 	}
232 232
 
233 233
 	public function disable_comment_counting() {
Please login to merge, or discard this patch.
action-scheduler/classes/data-stores/ActionScheduler_wpPostStore.php 2 patches
Indentation   +844 added lines, -844 removed lines patch added patch discarded remove patch
@@ -4,857 +4,857 @@
 block discarded – undo
4 4
  * Class ActionScheduler_wpPostStore
5 5
  */
6 6
 class ActionScheduler_wpPostStore extends ActionScheduler_Store {
7
-	const POST_TYPE = 'scheduled-action';
8
-	const GROUP_TAXONOMY = 'action-group';
9
-	const SCHEDULE_META_KEY = '_action_manager_schedule';
10
-	const DEPENDENCIES_MET = 'as-post-store-dependencies-met';
11
-
12
-	/** @var DateTimeZone */
13
-	protected $local_timezone = NULL;
14
-
15
-	public function save_action( ActionScheduler_Action $action, DateTime $scheduled_date = NULL ){
16
-		try {
17
-			$this->validate_action( $action );
18
-			$post_array = $this->create_post_array( $action, $scheduled_date );
19
-			$post_id = $this->save_post_array( $post_array );
20
-			$this->save_post_schedule( $post_id, $action->get_schedule() );
21
-			$this->save_action_group( $post_id, $action->get_group() );
22
-			do_action( 'action_scheduler_stored_action', $post_id );
23
-			return $post_id;
24
-		} catch ( Exception $e ) {
25
-			throw new RuntimeException( sprintf( __( 'Error saving action: %s', 'action-scheduler' ), $e->getMessage() ), 0 );
26
-		}
27
-	}
28
-
29
-	protected function create_post_array( ActionScheduler_Action $action, DateTime $scheduled_date = NULL ) {
30
-		$post = array(
31
-			'post_type' => self::POST_TYPE,
32
-			'post_title' => $action->get_hook(),
33
-			'post_content' => json_encode($action->get_args()),
34
-			'post_status' => ( $action->is_finished() ? 'publish' : 'pending' ),
35
-			'post_date_gmt' => $this->get_scheduled_date_string( $action, $scheduled_date ),
36
-			'post_date'     => $this->get_scheduled_date_string_local( $action, $scheduled_date ),
37
-		);
38
-		return $post;
39
-	}
40
-
41
-	protected function save_post_array( $post_array ) {
42
-		add_filter( 'wp_insert_post_data', array( $this, 'filter_insert_post_data' ), 10, 1 );
43
-		add_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10, 5 );
44
-
45
-		$has_kses = false !== has_filter( 'content_save_pre', 'wp_filter_post_kses' );
46
-
47
-		if ( $has_kses ) {
48
-			// Prevent KSES from corrupting JSON in post_content.
49
-			kses_remove_filters();
50
-		}
51
-
52
-		$post_id = wp_insert_post($post_array);
53
-
54
-		if ( $has_kses ) {
55
-			kses_init_filters();
56
-		}
57
-
58
-		remove_filter( 'wp_insert_post_data', array( $this, 'filter_insert_post_data' ), 10 );
59
-		remove_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10 );
60
-
61
-		if ( is_wp_error($post_id) || empty($post_id) ) {
62
-			throw new RuntimeException( __( 'Unable to save action.', 'action-scheduler' ) );
63
-		}
64
-		return $post_id;
65
-	}
66
-
67
-	public function filter_insert_post_data( $postdata ) {
68
-		if ( $postdata['post_type'] == self::POST_TYPE ) {
69
-			$postdata['post_author'] = 0;
70
-			if ( $postdata['post_status'] == 'future' ) {
71
-				$postdata['post_status'] = 'publish';
72
-			}
73
-		}
74
-		return $postdata;
75
-	}
76
-
77
-	/**
78
-	 * Create a (probably unique) post name for scheduled actions in a more performant manner than wp_unique_post_slug().
79
-	 *
80
-	 * When an action's post status is transitioned to something other than 'draft', 'pending' or 'auto-draft, like 'publish'
81
-	 * or 'failed' or 'trash', WordPress will find a unique slug (stored in post_name column) using the wp_unique_post_slug()
82
-	 * function. This is done to ensure URL uniqueness. The approach taken by wp_unique_post_slug() is to iterate over existing
83
-	 * post_name values that match, and append a number 1 greater than the largest. This makes sense when manually creating a
84
-	 * post from the Edit Post screen. It becomes a bottleneck when automatically processing thousands of actions, with a
85
-	 * database containing thousands of related post_name values.
86
-	 *
87
-	 * WordPress 5.1 introduces the 'pre_wp_unique_post_slug' filter for plugins to address this issue.
88
-	 *
89
-	 * We can short-circuit WordPress's wp_unique_post_slug() approach using the 'pre_wp_unique_post_slug' filter. This
90
-	 * method is available to be used as a callback on that filter. It provides a more scalable approach to generating a
91
-	 * post_name/slug that is probably unique. Because Action Scheduler never actually uses the post_name field, or an
92
-	 * action's slug, being probably unique is good enough.
93
-	 *
94
-	 * For more backstory on this issue, see:
95
-	 * - https://github.com/woocommerce/action-scheduler/issues/44 and
96
-	 * - https://core.trac.wordpress.org/ticket/21112
97
-	 *
98
-	 * @param string $override_slug Short-circuit return value.
99
-	 * @param string $slug          The desired slug (post_name).
100
-	 * @param int    $post_ID       Post ID.
101
-	 * @param string $post_status   The post status.
102
-	 * @param string $post_type     Post type.
103
-	 * @return string
104
-	 */
105
-	public function set_unique_post_slug( $override_slug, $slug, $post_ID, $post_status, $post_type ) {
106
-		if ( self::POST_TYPE == $post_type ) {
107
-			$override_slug = uniqid( self::POST_TYPE . '-', true ) . '-' . wp_generate_password( 32, false );
108
-		}
109
-		return $override_slug;
110
-	}
111
-
112
-	protected function save_post_schedule( $post_id, $schedule ) {
113
-		update_post_meta( $post_id, self::SCHEDULE_META_KEY, $schedule );
114
-	}
115
-
116
-	protected function save_action_group( $post_id, $group ) {
117
-		if ( empty($group) ) {
118
-			wp_set_object_terms( $post_id, array(), self::GROUP_TAXONOMY, FALSE );
119
-		} else {
120
-			wp_set_object_terms( $post_id, array($group), self::GROUP_TAXONOMY, FALSE );
121
-		}
122
-	}
123
-
124
-	public function fetch_action( $action_id ) {
125
-		$post = $this->get_post( $action_id );
126
-		if ( empty($post) || $post->post_type != self::POST_TYPE ) {
127
-			return $this->get_null_action();
128
-		}
129
-
130
-		try {
131
-			$action = $this->make_action_from_post( $post );
132
-		} catch ( ActionScheduler_InvalidActionException $exception ) {
133
-			do_action( 'action_scheduler_failed_fetch_action', $post->ID, $exception );
134
-			return $this->get_null_action();
135
-		}
136
-
137
-		return $action;
138
-	}
139
-
140
-	protected function get_post( $action_id ) {
141
-		if ( empty($action_id) ) {
142
-			return NULL;
143
-		}
144
-		return get_post($action_id);
145
-	}
146
-
147
-	protected function get_null_action() {
148
-		return new ActionScheduler_NullAction();
149
-	}
150
-
151
-	protected function make_action_from_post( $post ) {
152
-		$hook = $post->post_title;
153
-
154
-		$args = json_decode( $post->post_content, true );
155
-		$this->validate_args( $args, $post->ID );
156
-
157
-		$schedule = get_post_meta( $post->ID, self::SCHEDULE_META_KEY, true );
158
-		$this->validate_schedule( $schedule, $post->ID );
159
-
160
-		$group = wp_get_object_terms( $post->ID, self::GROUP_TAXONOMY, array('fields' => 'names') );
161
-		$group = empty( $group ) ? '' : reset($group);
162
-
163
-		return ActionScheduler::factory()->get_stored_action( $this->get_action_status_by_post_status( $post->post_status ), $hook, $args, $schedule, $group );
164
-	}
165
-
166
-	/**
167
-	 * @param string $post_status
168
-	 *
169
-	 * @throws InvalidArgumentException if $post_status not in known status fields returned by $this->get_status_labels()
170
-	 * @return string
171
-	 */
172
-	protected function get_action_status_by_post_status( $post_status ) {
173
-
174
-		switch ( $post_status ) {
175
-			case 'publish' :
176
-				$action_status = self::STATUS_COMPLETE;
177
-				break;
178
-			case 'trash' :
179
-				$action_status = self::STATUS_CANCELED;
180
-				break;
181
-			default :
182
-				if ( ! array_key_exists( $post_status, $this->get_status_labels() ) ) {
183
-					throw new InvalidArgumentException( sprintf( 'Invalid post status: "%s". No matching action status available.', $post_status ) );
184
-				}
185
-				$action_status = $post_status;
186
-				break;
187
-		}
188
-
189
-		return $action_status;
190
-	}
191
-
192
-	/**
193
-	 * @param string $action_status
194
-	 * @throws InvalidArgumentException if $post_status not in known status fields returned by $this->get_status_labels()
195
-	 * @return string
196
-	 */
197
-	protected function get_post_status_by_action_status( $action_status ) {
198
-
199
-		switch ( $action_status ) {
200
-			case self::STATUS_COMPLETE :
201
-				$post_status = 'publish';
202
-				break;
203
-			case self::STATUS_CANCELED :
204
-				$post_status = 'trash';
205
-				break;
206
-			default :
207
-				if ( ! array_key_exists( $action_status, $this->get_status_labels() ) ) {
208
-					throw new InvalidArgumentException( sprintf( 'Invalid action status: "%s".', $action_status ) );
209
-				}
210
-				$post_status = $action_status;
211
-				break;
212
-		}
213
-
214
-		return $post_status;
215
-	}
216
-
217
-	/**
218
-	 * @param string $hook
219
-	 * @param array $params
220
-	 *
221
-	 * @return string ID of the next action matching the criteria or NULL if not found
222
-	 */
223
-	public function find_action( $hook, $params = array() ) {
224
-		$params = wp_parse_args( $params, array(
225
-			'args' => NULL,
226
-			'status' => ActionScheduler_Store::STATUS_PENDING,
227
-			'group' => '',
228
-		));
229
-		/** @var wpdb $wpdb */
230
-		global $wpdb;
231
-		$query = "SELECT p.ID FROM {$wpdb->posts} p";
232
-		$args = array();
233
-		if ( !empty($params['group']) ) {
234
-			$query .= " INNER JOIN {$wpdb->term_relationships} tr ON tr.object_id=p.ID";
235
-			$query .= " INNER JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id=tt.term_taxonomy_id";
236
-			$query .= " INNER JOIN {$wpdb->terms} t ON tt.term_id=t.term_id AND t.slug=%s";
237
-			$args[] = $params['group'];
238
-		}
239
-		$query .= " WHERE p.post_title=%s";
240
-		$args[] = $hook;
241
-		$query .= " AND p.post_type=%s";
242
-		$args[] = self::POST_TYPE;
243
-		if ( !is_null($params['args']) ) {
244
-			$query .= " AND p.post_content=%s";
245
-			$args[] = json_encode($params['args']);
246
-		}
247
-
248
-		if ( ! empty( $params['status'] ) ) {
249
-			$query .= " AND p.post_status=%s";
250
-			$args[] = $this->get_post_status_by_action_status( $params['status'] );
251
-		}
252
-
253
-		switch ( $params['status'] ) {
254
-			case self::STATUS_COMPLETE:
255
-			case self::STATUS_RUNNING:
256
-			case self::STATUS_FAILED:
257
-				$order = 'DESC'; // Find the most recent action that matches
258
-				break;
259
-			case self::STATUS_PENDING:
260
-			default:
261
-				$order = 'ASC'; // Find the next action that matches
262
-				break;
263
-		}
264
-		$query .= " ORDER BY post_date_gmt $order LIMIT 1";
265
-
266
-		$query = $wpdb->prepare( $query, $args );
267
-
268
-		$id = $wpdb->get_var($query);
269
-		return $id;
270
-	}
271
-
272
-	/**
273
-	 * Returns the SQL statement to query (or count) actions.
274
-	 *
275
-	 * @param array $query Filtering options
276
-	 * @param string $select_or_count  Whether the SQL should select and return the IDs or just the row count
277
-	 * @throws InvalidArgumentException if $select_or_count not count or select
278
-	 * @return string SQL statement. The returned SQL is already properly escaped.
279
-	 */
280
-	protected function get_query_actions_sql( array $query, $select_or_count = 'select' ) {
281
-
282
-		if ( ! in_array( $select_or_count, array( 'select', 'count' ) ) ) {
283
-			throw new InvalidArgumentException( __( 'Invalid schedule. Cannot save action.', 'action-scheduler' ) );
284
-		}
285
-
286
-		$query = wp_parse_args( $query, array(
287
-			'hook' => '',
288
-			'args' => NULL,
289
-			'date' => NULL,
290
-			'date_compare' => '<=',
291
-			'modified' => NULL,
292
-			'modified_compare' => '<=',
293
-			'group' => '',
294
-			'status' => '',
295
-			'claimed' => NULL,
296
-			'per_page' => 5,
297
-			'offset' => 0,
298
-			'orderby' => 'date',
299
-			'order' => 'ASC',
300
-			'search' => '',
301
-		) );
302
-
303
-		/** @var wpdb $wpdb */
304
-		global $wpdb;
305
-		$sql  = ( 'count' === $select_or_count ) ? 'SELECT count(p.ID)' : 'SELECT p.ID ';
306
-		$sql .= "FROM {$wpdb->posts} p";
307
-		$sql_params = array();
308
-		if ( empty( $query['group'] ) && 'group' === $query['orderby'] ) {
309
-			$sql .= " LEFT JOIN {$wpdb->term_relationships} tr ON tr.object_id=p.ID";
310
-			$sql .= " LEFT JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id=tt.term_taxonomy_id";
311
-			$sql .= " LEFT JOIN {$wpdb->terms} t ON tt.term_id=t.term_id";
312
-		} elseif ( ! empty( $query['group'] ) ) {
313
-			$sql .= " INNER JOIN {$wpdb->term_relationships} tr ON tr.object_id=p.ID";
314
-			$sql .= " INNER JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id=tt.term_taxonomy_id";
315
-			$sql .= " INNER JOIN {$wpdb->terms} t ON tt.term_id=t.term_id";
316
-			$sql .= " AND t.slug=%s";
317
-			$sql_params[] = $query['group'];
318
-		}
319
-		$sql .= " WHERE post_type=%s";
320
-		$sql_params[] = self::POST_TYPE;
321
-		if ( $query['hook'] ) {
322
-			$sql .= " AND p.post_title=%s";
323
-			$sql_params[] = $query['hook'];
324
-		}
325
-		if ( !is_null($query['args']) ) {
326
-			$sql .= " AND p.post_content=%s";
327
-			$sql_params[] = json_encode($query['args']);
328
-		}
329
-
330
-		if ( ! empty( $query['status'] ) ) {
331
-			$sql .= " AND p.post_status=%s";
332
-			$sql_params[] = $this->get_post_status_by_action_status( $query['status'] );
333
-		}
334
-
335
-		if ( $query['date'] instanceof DateTime ) {
336
-			$date = clone $query['date'];
337
-			$date->setTimezone( new DateTimeZone('UTC') );
338
-			$date_string = $date->format('Y-m-d H:i:s');
339
-			$comparator = $this->validate_sql_comparator($query['date_compare']);
340
-			$sql .= " AND p.post_date_gmt $comparator %s";
341
-			$sql_params[] = $date_string;
342
-		}
343
-
344
-		if ( $query['modified'] instanceof DateTime ) {
345
-			$modified = clone $query['modified'];
346
-			$modified->setTimezone( new DateTimeZone('UTC') );
347
-			$date_string = $modified->format('Y-m-d H:i:s');
348
-			$comparator = $this->validate_sql_comparator($query['modified_compare']);
349
-			$sql .= " AND p.post_modified_gmt $comparator %s";
350
-			$sql_params[] = $date_string;
351
-		}
352
-
353
-		if ( $query['claimed'] === TRUE ) {
354
-			$sql .= " AND p.post_password != ''";
355
-		} elseif ( $query['claimed'] === FALSE ) {
356
-			$sql .= " AND p.post_password = ''";
357
-		} elseif ( !is_null($query['claimed']) ) {
358
-			$sql .= " AND p.post_password = %s";
359
-			$sql_params[] = $query['claimed'];
360
-		}
361
-
362
-		if ( ! empty( $query['search'] ) ) {
363
-			$sql .= " AND (p.post_title LIKE %s OR p.post_content LIKE %s OR p.post_password LIKE %s)";
364
-			for( $i = 0; $i < 3; $i++ ) {
365
-				$sql_params[] = sprintf( '%%%s%%', $query['search'] );
366
-			}
367
-		}
368
-
369
-		if ( 'select' === $select_or_count ) {
370
-			switch ( $query['orderby'] ) {
371
-				case 'hook':
372
-					$orderby = 'p.post_title';
373
-					break;
374
-				case 'group':
375
-					$orderby = 't.name';
376
-					break;
377
-				case 'status':
378
-					$orderby = 'p.post_status';
379
-					break;
380
-				case 'modified':
381
-					$orderby = 'p.post_modified';
382
-					break;
383
-				case 'claim_id':
384
-					$orderby = 'p.post_password';
385
-					break;
386
-				case 'schedule':
387
-				case 'date':
388
-				default:
389
-					$orderby = 'p.post_date_gmt';
390
-					break;
391
-			}
392
-			if ( 'ASC' === strtoupper( $query['order'] ) ) {
393
-				$order = 'ASC';
394
-			} else {
395
-				$order = 'DESC';
396
-			}
397
-			$sql .= " ORDER BY $orderby $order";
398
-			if ( $query['per_page'] > 0 ) {
399
-				$sql .= " LIMIT %d, %d";
400
-				$sql_params[] = $query['offset'];
401
-				$sql_params[] = $query['per_page'];
402
-			}
403
-		}
404
-
405
-		return $wpdb->prepare( $sql, $sql_params );
406
-	}
407
-
408
-	/**
409
-	 * @param array $query
410
-	 * @param string $query_type Whether to select or count the results. Default, select.
411
-	 * @return string|array The IDs of actions matching the query
412
-	 */
413
-	public function query_actions( $query = array(), $query_type = 'select' ) {
414
-		/** @var wpdb $wpdb */
415
-		global $wpdb;
416
-
417
-		$sql = $this->get_query_actions_sql( $query, $query_type );
418
-
419
-		return ( 'count' === $query_type ) ? $wpdb->get_var( $sql ) : $wpdb->get_col( $sql );
420
-	}
421
-
422
-	/**
423
-	 * Get a count of all actions in the store, grouped by status
424
-	 *
425
-	 * @return array
426
-	 */
427
-	public function action_counts() {
428
-
429
-		$action_counts_by_status = array();
430
-		$action_stati_and_labels = $this->get_status_labels();
431
-		$posts_count_by_status   = (array) wp_count_posts( self::POST_TYPE, 'readable' );
432
-
433
-		foreach ( $posts_count_by_status as $post_status_name => $count ) {
434
-
435
-			try {
436
-				$action_status_name = $this->get_action_status_by_post_status( $post_status_name );
437
-			} catch ( Exception $e ) {
438
-				// Ignore any post statuses that aren't for actions
439
-				continue;
440
-			}
441
-			if ( array_key_exists( $action_status_name, $action_stati_and_labels ) ) {
442
-				$action_counts_by_status[ $action_status_name ] = $count;
443
-			}
444
-		}
445
-
446
-		return $action_counts_by_status;
447
-	}
448
-
449
-	/**
450
-	 * @param string $action_id
451
-	 *
452
-	 * @throws InvalidArgumentException
453
-	 */
454
-	public function cancel_action( $action_id ) {
455
-		$post = get_post( $action_id );
456
-		if ( empty( $post ) || ( $post->post_type != self::POST_TYPE ) ) {
457
-			throw new InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) );
458
-		}
459
-		do_action( 'action_scheduler_canceled_action', $action_id );
460
-		add_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10, 5 );
461
-		wp_trash_post( $action_id );
462
-		remove_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10 );
463
-	}
464
-
465
-	public function delete_action( $action_id ) {
466
-		$post = get_post( $action_id );
467
-		if ( empty( $post ) || ( $post->post_type != self::POST_TYPE ) ) {
468
-			throw new InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) );
469
-		}
470
-		do_action( 'action_scheduler_deleted_action', $action_id );
471
-
472
-		wp_delete_post( $action_id, TRUE );
473
-	}
474
-
475
-	/**
476
-	 * @param string $action_id
477
-	 *
478
-	 * @throws InvalidArgumentException
479
-	 * @return ActionScheduler_DateTime The date the action is schedule to run, or the date that it ran.
480
-	 */
481
-	public function get_date( $action_id ) {
482
-		$next = $this->get_date_gmt( $action_id );
483
-		return ActionScheduler_TimezoneHelper::set_local_timezone( $next );
484
-	}
485
-
486
-	/**
487
-	 * @param string $action_id
488
-	 *
489
-	 * @throws InvalidArgumentException
490
-	 * @return ActionScheduler_DateTime The date the action is schedule to run, or the date that it ran.
491
-	 */
492
-	public function get_date_gmt( $action_id ) {
493
-		$post = get_post( $action_id );
494
-		if ( empty( $post ) || ( $post->post_type != self::POST_TYPE ) ) {
495
-			throw new InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) );
496
-		}
497
-		if ( $post->post_status == 'publish' ) {
498
-			return as_get_datetime_object( $post->post_modified_gmt );
499
-		} else {
500
-			return as_get_datetime_object( $post->post_date_gmt );
501
-		}
502
-	}
503
-
504
-	/**
505
-	 * @param int      $max_actions
506
-	 * @param DateTime $before_date Jobs must be schedule before this date. Defaults to now.
507
-	 * @param array    $hooks       Claim only actions with a hook or hooks.
508
-	 * @param string   $group       Claim only actions in the given group.
509
-	 *
510
-	 * @return ActionScheduler_ActionClaim
511
-	 * @throws RuntimeException When there is an error staking a claim.
512
-	 * @throws InvalidArgumentException When the given group is not valid.
513
-	 */
514
-	public function stake_claim( $max_actions = 10, DateTime $before_date = null, $hooks = array(), $group = '' ) {
515
-		$claim_id = $this->generate_claim_id();
516
-		$this->claim_actions( $claim_id, $max_actions, $before_date, $hooks, $group );
517
-		$action_ids = $this->find_actions_by_claim_id( $claim_id );
518
-
519
-		return new ActionScheduler_ActionClaim( $claim_id, $action_ids );
520
-	}
521
-
522
-	/**
523
-	 * @return int
524
-	 */
525
-	public function get_claim_count(){
526
-		global $wpdb;
527
-
528
-		$sql = "SELECT COUNT(DISTINCT post_password) FROM {$wpdb->posts} WHERE post_password != '' AND post_type = %s AND post_status IN ('in-progress','pending')";
529
-		$sql = $wpdb->prepare( $sql, array( self::POST_TYPE ) );
530
-
531
-		return $wpdb->get_var( $sql );
532
-	}
533
-
534
-	protected function generate_claim_id() {
535
-		$claim_id = md5(microtime(true) . rand(0,1000));
536
-		return substr($claim_id, 0, 20); // to fit in db field with 20 char limit
537
-	}
538
-
539
-	/**
540
-	 * @param string   $claim_id
541
-	 * @param int      $limit
542
-	 * @param DateTime $before_date Should use UTC timezone.
543
-	 * @param array    $hooks       Claim only actions with a hook or hooks.
544
-	 * @param string   $group       Claim only actions in the given group.
545
-	 *
546
-	 * @return int The number of actions that were claimed
547
-	 * @throws RuntimeException When there is a database error.
548
-	 * @throws InvalidArgumentException When the group is invalid.
549
-	 */
550
-	protected function claim_actions( $claim_id, $limit, DateTime $before_date = null, $hooks = array(), $group = '' ) {
551
-		// Set up initial variables.
552
-		$date      = null === $before_date ? as_get_datetime_object() : clone $before_date;
553
-		$limit_ids = ! empty( $group );
554
-		$ids       = $limit_ids ? $this->get_actions_by_group( $group, $limit, $date ) : array();
555
-
556
-		// If limiting by IDs and no posts found, then return early since we have nothing to update.
557
-		if ( $limit_ids && 0 === count( $ids ) ) {
558
-			return 0;
559
-		}
560
-
561
-		/** @var wpdb $wpdb */
562
-		global $wpdb;
563
-
564
-		/*
7
+    const POST_TYPE = 'scheduled-action';
8
+    const GROUP_TAXONOMY = 'action-group';
9
+    const SCHEDULE_META_KEY = '_action_manager_schedule';
10
+    const DEPENDENCIES_MET = 'as-post-store-dependencies-met';
11
+
12
+    /** @var DateTimeZone */
13
+    protected $local_timezone = NULL;
14
+
15
+    public function save_action( ActionScheduler_Action $action, DateTime $scheduled_date = NULL ){
16
+        try {
17
+            $this->validate_action( $action );
18
+            $post_array = $this->create_post_array( $action, $scheduled_date );
19
+            $post_id = $this->save_post_array( $post_array );
20
+            $this->save_post_schedule( $post_id, $action->get_schedule() );
21
+            $this->save_action_group( $post_id, $action->get_group() );
22
+            do_action( 'action_scheduler_stored_action', $post_id );
23
+            return $post_id;
24
+        } catch ( Exception $e ) {
25
+            throw new RuntimeException( sprintf( __( 'Error saving action: %s', 'action-scheduler' ), $e->getMessage() ), 0 );
26
+        }
27
+    }
28
+
29
+    protected function create_post_array( ActionScheduler_Action $action, DateTime $scheduled_date = NULL ) {
30
+        $post = array(
31
+            'post_type' => self::POST_TYPE,
32
+            'post_title' => $action->get_hook(),
33
+            'post_content' => json_encode($action->get_args()),
34
+            'post_status' => ( $action->is_finished() ? 'publish' : 'pending' ),
35
+            'post_date_gmt' => $this->get_scheduled_date_string( $action, $scheduled_date ),
36
+            'post_date'     => $this->get_scheduled_date_string_local( $action, $scheduled_date ),
37
+        );
38
+        return $post;
39
+    }
40
+
41
+    protected function save_post_array( $post_array ) {
42
+        add_filter( 'wp_insert_post_data', array( $this, 'filter_insert_post_data' ), 10, 1 );
43
+        add_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10, 5 );
44
+
45
+        $has_kses = false !== has_filter( 'content_save_pre', 'wp_filter_post_kses' );
46
+
47
+        if ( $has_kses ) {
48
+            // Prevent KSES from corrupting JSON in post_content.
49
+            kses_remove_filters();
50
+        }
51
+
52
+        $post_id = wp_insert_post($post_array);
53
+
54
+        if ( $has_kses ) {
55
+            kses_init_filters();
56
+        }
57
+
58
+        remove_filter( 'wp_insert_post_data', array( $this, 'filter_insert_post_data' ), 10 );
59
+        remove_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10 );
60
+
61
+        if ( is_wp_error($post_id) || empty($post_id) ) {
62
+            throw new RuntimeException( __( 'Unable to save action.', 'action-scheduler' ) );
63
+        }
64
+        return $post_id;
65
+    }
66
+
67
+    public function filter_insert_post_data( $postdata ) {
68
+        if ( $postdata['post_type'] == self::POST_TYPE ) {
69
+            $postdata['post_author'] = 0;
70
+            if ( $postdata['post_status'] == 'future' ) {
71
+                $postdata['post_status'] = 'publish';
72
+            }
73
+        }
74
+        return $postdata;
75
+    }
76
+
77
+    /**
78
+     * Create a (probably unique) post name for scheduled actions in a more performant manner than wp_unique_post_slug().
79
+     *
80
+     * When an action's post status is transitioned to something other than 'draft', 'pending' or 'auto-draft, like 'publish'
81
+     * or 'failed' or 'trash', WordPress will find a unique slug (stored in post_name column) using the wp_unique_post_slug()
82
+     * function. This is done to ensure URL uniqueness. The approach taken by wp_unique_post_slug() is to iterate over existing
83
+     * post_name values that match, and append a number 1 greater than the largest. This makes sense when manually creating a
84
+     * post from the Edit Post screen. It becomes a bottleneck when automatically processing thousands of actions, with a
85
+     * database containing thousands of related post_name values.
86
+     *
87
+     * WordPress 5.1 introduces the 'pre_wp_unique_post_slug' filter for plugins to address this issue.
88
+     *
89
+     * We can short-circuit WordPress's wp_unique_post_slug() approach using the 'pre_wp_unique_post_slug' filter. This
90
+     * method is available to be used as a callback on that filter. It provides a more scalable approach to generating a
91
+     * post_name/slug that is probably unique. Because Action Scheduler never actually uses the post_name field, or an
92
+     * action's slug, being probably unique is good enough.
93
+     *
94
+     * For more backstory on this issue, see:
95
+     * - https://github.com/woocommerce/action-scheduler/issues/44 and
96
+     * - https://core.trac.wordpress.org/ticket/21112
97
+     *
98
+     * @param string $override_slug Short-circuit return value.
99
+     * @param string $slug          The desired slug (post_name).
100
+     * @param int    $post_ID       Post ID.
101
+     * @param string $post_status   The post status.
102
+     * @param string $post_type     Post type.
103
+     * @return string
104
+     */
105
+    public function set_unique_post_slug( $override_slug, $slug, $post_ID, $post_status, $post_type ) {
106
+        if ( self::POST_TYPE == $post_type ) {
107
+            $override_slug = uniqid( self::POST_TYPE . '-', true ) . '-' . wp_generate_password( 32, false );
108
+        }
109
+        return $override_slug;
110
+    }
111
+
112
+    protected function save_post_schedule( $post_id, $schedule ) {
113
+        update_post_meta( $post_id, self::SCHEDULE_META_KEY, $schedule );
114
+    }
115
+
116
+    protected function save_action_group( $post_id, $group ) {
117
+        if ( empty($group) ) {
118
+            wp_set_object_terms( $post_id, array(), self::GROUP_TAXONOMY, FALSE );
119
+        } else {
120
+            wp_set_object_terms( $post_id, array($group), self::GROUP_TAXONOMY, FALSE );
121
+        }
122
+    }
123
+
124
+    public function fetch_action( $action_id ) {
125
+        $post = $this->get_post( $action_id );
126
+        if ( empty($post) || $post->post_type != self::POST_TYPE ) {
127
+            return $this->get_null_action();
128
+        }
129
+
130
+        try {
131
+            $action = $this->make_action_from_post( $post );
132
+        } catch ( ActionScheduler_InvalidActionException $exception ) {
133
+            do_action( 'action_scheduler_failed_fetch_action', $post->ID, $exception );
134
+            return $this->get_null_action();
135
+        }
136
+
137
+        return $action;
138
+    }
139
+
140
+    protected function get_post( $action_id ) {
141
+        if ( empty($action_id) ) {
142
+            return NULL;
143
+        }
144
+        return get_post($action_id);
145
+    }
146
+
147
+    protected function get_null_action() {
148
+        return new ActionScheduler_NullAction();
149
+    }
150
+
151
+    protected function make_action_from_post( $post ) {
152
+        $hook = $post->post_title;
153
+
154
+        $args = json_decode( $post->post_content, true );
155
+        $this->validate_args( $args, $post->ID );
156
+
157
+        $schedule = get_post_meta( $post->ID, self::SCHEDULE_META_KEY, true );
158
+        $this->validate_schedule( $schedule, $post->ID );
159
+
160
+        $group = wp_get_object_terms( $post->ID, self::GROUP_TAXONOMY, array('fields' => 'names') );
161
+        $group = empty( $group ) ? '' : reset($group);
162
+
163
+        return ActionScheduler::factory()->get_stored_action( $this->get_action_status_by_post_status( $post->post_status ), $hook, $args, $schedule, $group );
164
+    }
165
+
166
+    /**
167
+     * @param string $post_status
168
+     *
169
+     * @throws InvalidArgumentException if $post_status not in known status fields returned by $this->get_status_labels()
170
+     * @return string
171
+     */
172
+    protected function get_action_status_by_post_status( $post_status ) {
173
+
174
+        switch ( $post_status ) {
175
+            case 'publish' :
176
+                $action_status = self::STATUS_COMPLETE;
177
+                break;
178
+            case 'trash' :
179
+                $action_status = self::STATUS_CANCELED;
180
+                break;
181
+            default :
182
+                if ( ! array_key_exists( $post_status, $this->get_status_labels() ) ) {
183
+                    throw new InvalidArgumentException( sprintf( 'Invalid post status: "%s". No matching action status available.', $post_status ) );
184
+                }
185
+                $action_status = $post_status;
186
+                break;
187
+        }
188
+
189
+        return $action_status;
190
+    }
191
+
192
+    /**
193
+     * @param string $action_status
194
+     * @throws InvalidArgumentException if $post_status not in known status fields returned by $this->get_status_labels()
195
+     * @return string
196
+     */
197
+    protected function get_post_status_by_action_status( $action_status ) {
198
+
199
+        switch ( $action_status ) {
200
+            case self::STATUS_COMPLETE :
201
+                $post_status = 'publish';
202
+                break;
203
+            case self::STATUS_CANCELED :
204
+                $post_status = 'trash';
205
+                break;
206
+            default :
207
+                if ( ! array_key_exists( $action_status, $this->get_status_labels() ) ) {
208
+                    throw new InvalidArgumentException( sprintf( 'Invalid action status: "%s".', $action_status ) );
209
+                }
210
+                $post_status = $action_status;
211
+                break;
212
+        }
213
+
214
+        return $post_status;
215
+    }
216
+
217
+    /**
218
+     * @param string $hook
219
+     * @param array $params
220
+     *
221
+     * @return string ID of the next action matching the criteria or NULL if not found
222
+     */
223
+    public function find_action( $hook, $params = array() ) {
224
+        $params = wp_parse_args( $params, array(
225
+            'args' => NULL,
226
+            'status' => ActionScheduler_Store::STATUS_PENDING,
227
+            'group' => '',
228
+        ));
229
+        /** @var wpdb $wpdb */
230
+        global $wpdb;
231
+        $query = "SELECT p.ID FROM {$wpdb->posts} p";
232
+        $args = array();
233
+        if ( !empty($params['group']) ) {
234
+            $query .= " INNER JOIN {$wpdb->term_relationships} tr ON tr.object_id=p.ID";
235
+            $query .= " INNER JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id=tt.term_taxonomy_id";
236
+            $query .= " INNER JOIN {$wpdb->terms} t ON tt.term_id=t.term_id AND t.slug=%s";
237
+            $args[] = $params['group'];
238
+        }
239
+        $query .= " WHERE p.post_title=%s";
240
+        $args[] = $hook;
241
+        $query .= " AND p.post_type=%s";
242
+        $args[] = self::POST_TYPE;
243
+        if ( !is_null($params['args']) ) {
244
+            $query .= " AND p.post_content=%s";
245
+            $args[] = json_encode($params['args']);
246
+        }
247
+
248
+        if ( ! empty( $params['status'] ) ) {
249
+            $query .= " AND p.post_status=%s";
250
+            $args[] = $this->get_post_status_by_action_status( $params['status'] );
251
+        }
252
+
253
+        switch ( $params['status'] ) {
254
+            case self::STATUS_COMPLETE:
255
+            case self::STATUS_RUNNING:
256
+            case self::STATUS_FAILED:
257
+                $order = 'DESC'; // Find the most recent action that matches
258
+                break;
259
+            case self::STATUS_PENDING:
260
+            default:
261
+                $order = 'ASC'; // Find the next action that matches
262
+                break;
263
+        }
264
+        $query .= " ORDER BY post_date_gmt $order LIMIT 1";
265
+
266
+        $query = $wpdb->prepare( $query, $args );
267
+
268
+        $id = $wpdb->get_var($query);
269
+        return $id;
270
+    }
271
+
272
+    /**
273
+     * Returns the SQL statement to query (or count) actions.
274
+     *
275
+     * @param array $query Filtering options
276
+     * @param string $select_or_count  Whether the SQL should select and return the IDs or just the row count
277
+     * @throws InvalidArgumentException if $select_or_count not count or select
278
+     * @return string SQL statement. The returned SQL is already properly escaped.
279
+     */
280
+    protected function get_query_actions_sql( array $query, $select_or_count = 'select' ) {
281
+
282
+        if ( ! in_array( $select_or_count, array( 'select', 'count' ) ) ) {
283
+            throw new InvalidArgumentException( __( 'Invalid schedule. Cannot save action.', 'action-scheduler' ) );
284
+        }
285
+
286
+        $query = wp_parse_args( $query, array(
287
+            'hook' => '',
288
+            'args' => NULL,
289
+            'date' => NULL,
290
+            'date_compare' => '<=',
291
+            'modified' => NULL,
292
+            'modified_compare' => '<=',
293
+            'group' => '',
294
+            'status' => '',
295
+            'claimed' => NULL,
296
+            'per_page' => 5,
297
+            'offset' => 0,
298
+            'orderby' => 'date',
299
+            'order' => 'ASC',
300
+            'search' => '',
301
+        ) );
302
+
303
+        /** @var wpdb $wpdb */
304
+        global $wpdb;
305
+        $sql  = ( 'count' === $select_or_count ) ? 'SELECT count(p.ID)' : 'SELECT p.ID ';
306
+        $sql .= "FROM {$wpdb->posts} p";
307
+        $sql_params = array();
308
+        if ( empty( $query['group'] ) && 'group' === $query['orderby'] ) {
309
+            $sql .= " LEFT JOIN {$wpdb->term_relationships} tr ON tr.object_id=p.ID";
310
+            $sql .= " LEFT JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id=tt.term_taxonomy_id";
311
+            $sql .= " LEFT JOIN {$wpdb->terms} t ON tt.term_id=t.term_id";
312
+        } elseif ( ! empty( $query['group'] ) ) {
313
+            $sql .= " INNER JOIN {$wpdb->term_relationships} tr ON tr.object_id=p.ID";
314
+            $sql .= " INNER JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id=tt.term_taxonomy_id";
315
+            $sql .= " INNER JOIN {$wpdb->terms} t ON tt.term_id=t.term_id";
316
+            $sql .= " AND t.slug=%s";
317
+            $sql_params[] = $query['group'];
318
+        }
319
+        $sql .= " WHERE post_type=%s";
320
+        $sql_params[] = self::POST_TYPE;
321
+        if ( $query['hook'] ) {
322
+            $sql .= " AND p.post_title=%s";
323
+            $sql_params[] = $query['hook'];
324
+        }
325
+        if ( !is_null($query['args']) ) {
326
+            $sql .= " AND p.post_content=%s";
327
+            $sql_params[] = json_encode($query['args']);
328
+        }
329
+
330
+        if ( ! empty( $query['status'] ) ) {
331
+            $sql .= " AND p.post_status=%s";
332
+            $sql_params[] = $this->get_post_status_by_action_status( $query['status'] );
333
+        }
334
+
335
+        if ( $query['date'] instanceof DateTime ) {
336
+            $date = clone $query['date'];
337
+            $date->setTimezone( new DateTimeZone('UTC') );
338
+            $date_string = $date->format('Y-m-d H:i:s');
339
+            $comparator = $this->validate_sql_comparator($query['date_compare']);
340
+            $sql .= " AND p.post_date_gmt $comparator %s";
341
+            $sql_params[] = $date_string;
342
+        }
343
+
344
+        if ( $query['modified'] instanceof DateTime ) {
345
+            $modified = clone $query['modified'];
346
+            $modified->setTimezone( new DateTimeZone('UTC') );
347
+            $date_string = $modified->format('Y-m-d H:i:s');
348
+            $comparator = $this->validate_sql_comparator($query['modified_compare']);
349
+            $sql .= " AND p.post_modified_gmt $comparator %s";
350
+            $sql_params[] = $date_string;
351
+        }
352
+
353
+        if ( $query['claimed'] === TRUE ) {
354
+            $sql .= " AND p.post_password != ''";
355
+        } elseif ( $query['claimed'] === FALSE ) {
356
+            $sql .= " AND p.post_password = ''";
357
+        } elseif ( !is_null($query['claimed']) ) {
358
+            $sql .= " AND p.post_password = %s";
359
+            $sql_params[] = $query['claimed'];
360
+        }
361
+
362
+        if ( ! empty( $query['search'] ) ) {
363
+            $sql .= " AND (p.post_title LIKE %s OR p.post_content LIKE %s OR p.post_password LIKE %s)";
364
+            for( $i = 0; $i < 3; $i++ ) {
365
+                $sql_params[] = sprintf( '%%%s%%', $query['search'] );
366
+            }
367
+        }
368
+
369
+        if ( 'select' === $select_or_count ) {
370
+            switch ( $query['orderby'] ) {
371
+                case 'hook':
372
+                    $orderby = 'p.post_title';
373
+                    break;
374
+                case 'group':
375
+                    $orderby = 't.name';
376
+                    break;
377
+                case 'status':
378
+                    $orderby = 'p.post_status';
379
+                    break;
380
+                case 'modified':
381
+                    $orderby = 'p.post_modified';
382
+                    break;
383
+                case 'claim_id':
384
+                    $orderby = 'p.post_password';
385
+                    break;
386
+                case 'schedule':
387
+                case 'date':
388
+                default:
389
+                    $orderby = 'p.post_date_gmt';
390
+                    break;
391
+            }
392
+            if ( 'ASC' === strtoupper( $query['order'] ) ) {
393
+                $order = 'ASC';
394
+            } else {
395
+                $order = 'DESC';
396
+            }
397
+            $sql .= " ORDER BY $orderby $order";
398
+            if ( $query['per_page'] > 0 ) {
399
+                $sql .= " LIMIT %d, %d";
400
+                $sql_params[] = $query['offset'];
401
+                $sql_params[] = $query['per_page'];
402
+            }
403
+        }
404
+
405
+        return $wpdb->prepare( $sql, $sql_params );
406
+    }
407
+
408
+    /**
409
+     * @param array $query
410
+     * @param string $query_type Whether to select or count the results. Default, select.
411
+     * @return string|array The IDs of actions matching the query
412
+     */
413
+    public function query_actions( $query = array(), $query_type = 'select' ) {
414
+        /** @var wpdb $wpdb */
415
+        global $wpdb;
416
+
417
+        $sql = $this->get_query_actions_sql( $query, $query_type );
418
+
419
+        return ( 'count' === $query_type ) ? $wpdb->get_var( $sql ) : $wpdb->get_col( $sql );
420
+    }
421
+
422
+    /**
423
+     * Get a count of all actions in the store, grouped by status
424
+     *
425
+     * @return array
426
+     */
427
+    public function action_counts() {
428
+
429
+        $action_counts_by_status = array();
430
+        $action_stati_and_labels = $this->get_status_labels();
431
+        $posts_count_by_status   = (array) wp_count_posts( self::POST_TYPE, 'readable' );
432
+
433
+        foreach ( $posts_count_by_status as $post_status_name => $count ) {
434
+
435
+            try {
436
+                $action_status_name = $this->get_action_status_by_post_status( $post_status_name );
437
+            } catch ( Exception $e ) {
438
+                // Ignore any post statuses that aren't for actions
439
+                continue;
440
+            }
441
+            if ( array_key_exists( $action_status_name, $action_stati_and_labels ) ) {
442
+                $action_counts_by_status[ $action_status_name ] = $count;
443
+            }
444
+        }
445
+
446
+        return $action_counts_by_status;
447
+    }
448
+
449
+    /**
450
+     * @param string $action_id
451
+     *
452
+     * @throws InvalidArgumentException
453
+     */
454
+    public function cancel_action( $action_id ) {
455
+        $post = get_post( $action_id );
456
+        if ( empty( $post ) || ( $post->post_type != self::POST_TYPE ) ) {
457
+            throw new InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) );
458
+        }
459
+        do_action( 'action_scheduler_canceled_action', $action_id );
460
+        add_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10, 5 );
461
+        wp_trash_post( $action_id );
462
+        remove_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10 );
463
+    }
464
+
465
+    public function delete_action( $action_id ) {
466
+        $post = get_post( $action_id );
467
+        if ( empty( $post ) || ( $post->post_type != self::POST_TYPE ) ) {
468
+            throw new InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) );
469
+        }
470
+        do_action( 'action_scheduler_deleted_action', $action_id );
471
+
472
+        wp_delete_post( $action_id, TRUE );
473
+    }
474
+
475
+    /**
476
+     * @param string $action_id
477
+     *
478
+     * @throws InvalidArgumentException
479
+     * @return ActionScheduler_DateTime The date the action is schedule to run, or the date that it ran.
480
+     */
481
+    public function get_date( $action_id ) {
482
+        $next = $this->get_date_gmt( $action_id );
483
+        return ActionScheduler_TimezoneHelper::set_local_timezone( $next );
484
+    }
485
+
486
+    /**
487
+     * @param string $action_id
488
+     *
489
+     * @throws InvalidArgumentException
490
+     * @return ActionScheduler_DateTime The date the action is schedule to run, or the date that it ran.
491
+     */
492
+    public function get_date_gmt( $action_id ) {
493
+        $post = get_post( $action_id );
494
+        if ( empty( $post ) || ( $post->post_type != self::POST_TYPE ) ) {
495
+            throw new InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) );
496
+        }
497
+        if ( $post->post_status == 'publish' ) {
498
+            return as_get_datetime_object( $post->post_modified_gmt );
499
+        } else {
500
+            return as_get_datetime_object( $post->post_date_gmt );
501
+        }
502
+    }
503
+
504
+    /**
505
+     * @param int      $max_actions
506
+     * @param DateTime $before_date Jobs must be schedule before this date. Defaults to now.
507
+     * @param array    $hooks       Claim only actions with a hook or hooks.
508
+     * @param string   $group       Claim only actions in the given group.
509
+     *
510
+     * @return ActionScheduler_ActionClaim
511
+     * @throws RuntimeException When there is an error staking a claim.
512
+     * @throws InvalidArgumentException When the given group is not valid.
513
+     */
514
+    public function stake_claim( $max_actions = 10, DateTime $before_date = null, $hooks = array(), $group = '' ) {
515
+        $claim_id = $this->generate_claim_id();
516
+        $this->claim_actions( $claim_id, $max_actions, $before_date, $hooks, $group );
517
+        $action_ids = $this->find_actions_by_claim_id( $claim_id );
518
+
519
+        return new ActionScheduler_ActionClaim( $claim_id, $action_ids );
520
+    }
521
+
522
+    /**
523
+     * @return int
524
+     */
525
+    public function get_claim_count(){
526
+        global $wpdb;
527
+
528
+        $sql = "SELECT COUNT(DISTINCT post_password) FROM {$wpdb->posts} WHERE post_password != '' AND post_type = %s AND post_status IN ('in-progress','pending')";
529
+        $sql = $wpdb->prepare( $sql, array( self::POST_TYPE ) );
530
+
531
+        return $wpdb->get_var( $sql );
532
+    }
533
+
534
+    protected function generate_claim_id() {
535
+        $claim_id = md5(microtime(true) . rand(0,1000));
536
+        return substr($claim_id, 0, 20); // to fit in db field with 20 char limit
537
+    }
538
+
539
+    /**
540
+     * @param string   $claim_id
541
+     * @param int      $limit
542
+     * @param DateTime $before_date Should use UTC timezone.
543
+     * @param array    $hooks       Claim only actions with a hook or hooks.
544
+     * @param string   $group       Claim only actions in the given group.
545
+     *
546
+     * @return int The number of actions that were claimed
547
+     * @throws RuntimeException When there is a database error.
548
+     * @throws InvalidArgumentException When the group is invalid.
549
+     */
550
+    protected function claim_actions( $claim_id, $limit, DateTime $before_date = null, $hooks = array(), $group = '' ) {
551
+        // Set up initial variables.
552
+        $date      = null === $before_date ? as_get_datetime_object() : clone $before_date;
553
+        $limit_ids = ! empty( $group );
554
+        $ids       = $limit_ids ? $this->get_actions_by_group( $group, $limit, $date ) : array();
555
+
556
+        // If limiting by IDs and no posts found, then return early since we have nothing to update.
557
+        if ( $limit_ids && 0 === count( $ids ) ) {
558
+            return 0;
559
+        }
560
+
561
+        /** @var wpdb $wpdb */
562
+        global $wpdb;
563
+
564
+        /*
565 565
 		 * Build up custom query to update the affected posts. Parameters are built as a separate array
566 566
 		 * to make it easier to identify where they are in the query.
567 567
 		 *
568 568
 		 * We can't use $wpdb->update() here because of the "ID IN ..." clause.
569 569
 		 */
570
-		$update = "UPDATE {$wpdb->posts} SET post_password = %s, post_modified_gmt = %s, post_modified = %s";
571
-		$params = array(
572
-			$claim_id,
573
-			current_time( 'mysql', true ),
574
-			current_time( 'mysql' ),
575
-		);
576
-
577
-		// Build initial WHERE clause.
578
-		$where    = "WHERE post_type = %s AND post_status = %s AND post_password = ''";
579
-		$params[] = self::POST_TYPE;
580
-		$params[] = ActionScheduler_Store::STATUS_PENDING;
581
-
582
-		if ( ! empty( $hooks ) ) {
583
-			$placeholders = array_fill( 0, count( $hooks ), '%s' );
584
-			$where       .= ' AND post_title IN (' . join( ', ', $placeholders ) . ')';
585
-			$params       = array_merge( $params, array_values( $hooks ) );
586
-		}
587
-
588
-		/*
570
+        $update = "UPDATE {$wpdb->posts} SET post_password = %s, post_modified_gmt = %s, post_modified = %s";
571
+        $params = array(
572
+            $claim_id,
573
+            current_time( 'mysql', true ),
574
+            current_time( 'mysql' ),
575
+        );
576
+
577
+        // Build initial WHERE clause.
578
+        $where    = "WHERE post_type = %s AND post_status = %s AND post_password = ''";
579
+        $params[] = self::POST_TYPE;
580
+        $params[] = ActionScheduler_Store::STATUS_PENDING;
581
+
582
+        if ( ! empty( $hooks ) ) {
583
+            $placeholders = array_fill( 0, count( $hooks ), '%s' );
584
+            $where       .= ' AND post_title IN (' . join( ', ', $placeholders ) . ')';
585
+            $params       = array_merge( $params, array_values( $hooks ) );
586
+        }
587
+
588
+        /*
589 589
 		 * Add the IDs to the WHERE clause. IDs not escaped because they came directly from a prior DB query.
590 590
 		 *
591 591
 		 * If we're not limiting by IDs, then include the post_date_gmt clause.
592 592
 		 */
593
-		if ( $limit_ids ) {
594
-			$where .= ' AND ID IN (' . join( ',', $ids ) . ')';
595
-		} else {
596
-			$where .= ' AND post_date_gmt <= %s';
597
-			$params[] = $date->format( 'Y-m-d H:i:s' );
598
-		}
599
-
600
-		// Add the ORDER BY clause and,ms limit.
601
-		$order    = 'ORDER BY menu_order ASC, post_date_gmt ASC, ID ASC LIMIT %d';
602
-		$params[] = $limit;
603
-
604
-		// Run the query and gather results.
605
-		$rows_affected = $wpdb->query( $wpdb->prepare( "{$update} {$where} {$order}", $params ) );
606
-		if ( $rows_affected === false ) {
607
-			throw new RuntimeException( __( 'Unable to claim actions. Database error.', 'action-scheduler' ) );
608
-		}
609
-
610
-		return (int) $rows_affected;
611
-	}
612
-
613
-	/**
614
-	 * Get IDs of actions within a certain group and up to a certain date/time.
615
-	 *
616
-	 * @param string   $group The group to use in finding actions.
617
-	 * @param int      $limit The number of actions to retrieve.
618
-	 * @param DateTime $date  DateTime object representing cutoff time for actions. Actions retrieved will be
619
-	 *                        up to and including this DateTime.
620
-	 *
621
-	 * @return array IDs of actions in the appropriate group and before the appropriate time.
622
-	 * @throws InvalidArgumentException When the group does not exist.
623
-	 */
624
-	protected function get_actions_by_group( $group, $limit, DateTime $date ) {
625
-		// Ensure the group exists before continuing.
626
-		if ( ! term_exists( $group, self::GROUP_TAXONOMY )) {
627
-			throw new InvalidArgumentException( sprintf( __( 'The group "%s" does not exist.', 'action-scheduler' ), $group ) );
628
-		}
629
-
630
-		// Set up a query for post IDs to use later.
631
-		$query      = new WP_Query();
632
-		$query_args = array(
633
-			'fields'           => 'ids',
634
-			'post_type'        => self::POST_TYPE,
635
-			'post_status'      => ActionScheduler_Store::STATUS_PENDING,
636
-			'has_password'     => false,
637
-			'posts_per_page'   => $limit * 3,
638
-			'suppress_filters' => true,
639
-			'no_found_rows'    => true,
640
-			'orderby'          => array(
641
-				'menu_order' => 'ASC',
642
-				'date'       => 'ASC',
643
-				'ID'         => 'ASC',
644
-			),
645
-			'date_query'       => array(
646
-				'column' => 'post_date_gmt',
647
-				'before' => $date->format( 'Y-m-d H:i' ),
648
-				'inclusive' => true,
649
-			),
650
-			'tax_query' => array(
651
-				array(
652
-					'taxonomy'         => self::GROUP_TAXONOMY,
653
-					'field'            => 'slug',
654
-					'terms'            => $group,
655
-					'include_children' => false,
656
-				),
657
-			),
658
-		);
659
-
660
-		return $query->query( $query_args );
661
-	}
662
-
663
-	/**
664
-	 * @param string $claim_id
665
-	 * @return array
666
-	 */
667
-	public function find_actions_by_claim_id( $claim_id ) {
668
-		/** @var wpdb $wpdb */
669
-		global $wpdb;
670
-		$sql = "SELECT ID FROM {$wpdb->posts} WHERE post_type = %s AND post_password = %s";
671
-		$sql = $wpdb->prepare( $sql, array( self::POST_TYPE, $claim_id ) );
672
-		$action_ids = $wpdb->get_col( $sql );
673
-		return $action_ids;
674
-	}
675
-
676
-	public function release_claim( ActionScheduler_ActionClaim $claim ) {
677
-		$action_ids = $this->find_actions_by_claim_id( $claim->get_id() );
678
-		if ( empty( $action_ids ) ) {
679
-			return; // nothing to do
680
-		}
681
-		$action_id_string = implode( ',', array_map( 'intval', $action_ids ) );
682
-		/** @var wpdb $wpdb */
683
-		global $wpdb;
684
-		$sql = "UPDATE {$wpdb->posts} SET post_password = '' WHERE ID IN ($action_id_string) AND post_password = %s";
685
-		$sql = $wpdb->prepare( $sql, array( $claim->get_id() ) );
686
-		$result = $wpdb->query( $sql );
687
-		if ( $result === false ) {
688
-			/* translators: %s: claim ID */
689
-			throw new RuntimeException( sprintf( __( 'Unable to unlock claim %s. Database error.', 'action-scheduler' ), $claim->get_id() ) );
690
-		}
691
-	}
692
-
693
-	/**
694
-	 * @param string $action_id
695
-	 */
696
-	public function unclaim_action( $action_id ) {
697
-		/** @var wpdb $wpdb */
698
-		global $wpdb;
699
-		$sql = "UPDATE {$wpdb->posts} SET post_password = '' WHERE ID = %d AND post_type = %s";
700
-		$sql = $wpdb->prepare( $sql, $action_id, self::POST_TYPE );
701
-		$result = $wpdb->query( $sql );
702
-		if ( $result === false ) {
703
-			/* translators: %s: action ID */
704
-			throw new RuntimeException( sprintf( __( 'Unable to unlock claim on action %s. Database error.', 'action-scheduler' ), $action_id ) );
705
-		}
706
-	}
707
-
708
-	public function mark_failure( $action_id ) {
709
-		/** @var wpdb $wpdb */
710
-		global $wpdb;
711
-		$sql = "UPDATE {$wpdb->posts} SET post_status = %s WHERE ID = %d AND post_type = %s";
712
-		$sql = $wpdb->prepare( $sql, self::STATUS_FAILED, $action_id, self::POST_TYPE );
713
-		$result = $wpdb->query( $sql );
714
-		if ( $result === false ) {
715
-			/* translators: %s: action ID */
716
-			throw new RuntimeException( sprintf( __( 'Unable to mark failure on action %s. Database error.', 'action-scheduler' ), $action_id ) );
717
-		}
718
-	}
719
-
720
-	/**
721
-	 * Return an action's claim ID, as stored in the post password column
722
-	 *
723
-	 * @param string $action_id
724
-	 * @return mixed
725
-	 */
726
-	public function get_claim_id( $action_id ) {
727
-		return $this->get_post_column( $action_id, 'post_password' );
728
-	}
729
-
730
-	/**
731
-	 * Return an action's status, as stored in the post status column
732
-	 *
733
-	 * @param string $action_id
734
-	 * @return mixed
735
-	 */
736
-	public function get_status( $action_id ) {
737
-		$status = $this->get_post_column( $action_id, 'post_status' );
738
-
739
-		if ( $status === null ) {
740
-			throw new InvalidArgumentException( __( 'Invalid action ID. No status found.', 'action-scheduler' ) );
741
-		}
742
-
743
-		return $this->get_action_status_by_post_status( $status );
744
-	}
745
-
746
-	private function get_post_column( $action_id, $column_name ) {
747
-		/** @var \wpdb $wpdb */
748
-		global $wpdb;
749
-		return $wpdb->get_var( $wpdb->prepare( "SELECT {$column_name} FROM {$wpdb->posts} WHERE ID=%d AND post_type=%s", $action_id, self::POST_TYPE ) );
750
-	}
751
-
752
-	/**
753
-	 * @param string $action_id
754
-	 */
755
-	public function log_execution( $action_id ) {
756
-		/** @var wpdb $wpdb */
757
-		global $wpdb;
758
-
759
-		$sql = "UPDATE {$wpdb->posts} SET menu_order = menu_order+1, post_status=%s, post_modified_gmt = %s, post_modified = %s WHERE ID = %d AND post_type = %s";
760
-		$sql = $wpdb->prepare( $sql, self::STATUS_RUNNING, current_time('mysql', true), current_time('mysql'), $action_id, self::POST_TYPE );
761
-		$wpdb->query($sql);
762
-	}
763
-
764
-	/**
765
-	 * Record that an action was completed.
766
-	 *
767
-	 * @param int $action_id ID of the completed action.
768
-	 * @throws InvalidArgumentException|RuntimeException
769
-	 */
770
-	public function mark_complete( $action_id ) {
771
-		$post = get_post( $action_id );
772
-		if ( empty( $post ) || ( $post->post_type != self::POST_TYPE ) ) {
773
-			throw new InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) );
774
-		}
775
-		add_filter( 'wp_insert_post_data', array( $this, 'filter_insert_post_data' ), 10, 1 );
776
-		add_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10, 5 );
777
-		$result = wp_update_post(array(
778
-			'ID' => $action_id,
779
-			'post_status' => 'publish',
780
-		), TRUE);
781
-		remove_filter( 'wp_insert_post_data', array( $this, 'filter_insert_post_data' ), 10 );
782
-		remove_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10 );
783
-		if ( is_wp_error( $result ) ) {
784
-			throw new RuntimeException( $result->get_error_message() );
785
-		}
786
-	}
787
-
788
-	/**
789
-	 * Mark action as migrated when there is an error deleting the action.
790
-	 *
791
-	 * @param int $action_id Action ID.
792
-	 */
793
-	public function mark_migrated( $action_id ) {
794
-		wp_update_post(
795
-			array(
796
-				'ID'          => $action_id,
797
-				'post_status' => 'migrated'
798
-			)
799
-		);
800
-	}
801
-
802
-	/**
803
-	 * Determine whether the post store can be migrated.
804
-	 *
805
-	 * @return bool
806
-	 */
807
-	public function migration_dependencies_met( $setting ) {
808
-		global $wpdb;
809
-
810
-		$dependencies_met = get_transient( self::DEPENDENCIES_MET );
811
-		if ( empty( $dependencies_met ) ) {
812
-			$maximum_args_length = apply_filters( 'action_scheduler_maximum_args_length', 191 );
813
-			$found_action        = $wpdb->get_var(
814
-				$wpdb->prepare(
815
-					"SELECT ID FROM {$wpdb->posts} WHERE post_type = %s AND CHAR_LENGTH(post_content) > %d LIMIT 1",
816
-					$maximum_args_length,
817
-					self::POST_TYPE
818
-				)
819
-			);
820
-			$dependencies_met = $found_action ? 'no' : 'yes';
821
-			set_transient( self::DEPENDENCIES_MET, $dependencies_met, DAY_IN_SECONDS );
822
-		}
823
-
824
-		return 'yes' == $dependencies_met ? $setting : false;
825
-	}
826
-
827
-	/**
828
-	 * InnoDB indexes have a maximum size of 767 bytes by default, which is only 191 characters with utf8mb4.
829
-	 *
830
-	 * Previously, AS wasn't concerned about args length, as we used the (unindex) post_content column. However,
831
-	 * as we prepare to move to custom tables, and can use an indexed VARCHAR column instead, we want to warn
832
-	 * developers of this impending requirement.
833
-	 *
834
-	 * @param ActionScheduler_Action $action
835
-	 */
836
-	protected function validate_action( ActionScheduler_Action $action ) {
837
-		try {
838
-			parent::validate_action( $action );
839
-		} catch ( Exception $e ) {
840
-			$message = sprintf( __( '%s Support for strings longer than this will be removed in a future version.', 'action-scheduler' ), $e->getMessage() );
841
-			_doing_it_wrong( 'ActionScheduler_Action::$args', $message, '2.1.0' );
842
-		}
843
-	}
844
-
845
-	/**
846
-	 * @codeCoverageIgnore
847
-	 */
848
-	public function init() {
849
-		add_filter( 'action_scheduler_migration_dependencies_met', array( $this, 'migration_dependencies_met' ) );
850
-
851
-		$post_type_registrar = new ActionScheduler_wpPostStore_PostTypeRegistrar();
852
-		$post_type_registrar->register();
853
-
854
-		$post_status_registrar = new ActionScheduler_wpPostStore_PostStatusRegistrar();
855
-		$post_status_registrar->register();
856
-
857
-		$taxonomy_registrar = new ActionScheduler_wpPostStore_TaxonomyRegistrar();
858
-		$taxonomy_registrar->register();
859
-	}
593
+        if ( $limit_ids ) {
594
+            $where .= ' AND ID IN (' . join( ',', $ids ) . ')';
595
+        } else {
596
+            $where .= ' AND post_date_gmt <= %s';
597
+            $params[] = $date->format( 'Y-m-d H:i:s' );
598
+        }
599
+
600
+        // Add the ORDER BY clause and,ms limit.
601
+        $order    = 'ORDER BY menu_order ASC, post_date_gmt ASC, ID ASC LIMIT %d';
602
+        $params[] = $limit;
603
+
604
+        // Run the query and gather results.
605
+        $rows_affected = $wpdb->query( $wpdb->prepare( "{$update} {$where} {$order}", $params ) );
606
+        if ( $rows_affected === false ) {
607
+            throw new RuntimeException( __( 'Unable to claim actions. Database error.', 'action-scheduler' ) );
608
+        }
609
+
610
+        return (int) $rows_affected;
611
+    }
612
+
613
+    /**
614
+     * Get IDs of actions within a certain group and up to a certain date/time.
615
+     *
616
+     * @param string   $group The group to use in finding actions.
617
+     * @param int      $limit The number of actions to retrieve.
618
+     * @param DateTime $date  DateTime object representing cutoff time for actions. Actions retrieved will be
619
+     *                        up to and including this DateTime.
620
+     *
621
+     * @return array IDs of actions in the appropriate group and before the appropriate time.
622
+     * @throws InvalidArgumentException When the group does not exist.
623
+     */
624
+    protected function get_actions_by_group( $group, $limit, DateTime $date ) {
625
+        // Ensure the group exists before continuing.
626
+        if ( ! term_exists( $group, self::GROUP_TAXONOMY )) {
627
+            throw new InvalidArgumentException( sprintf( __( 'The group "%s" does not exist.', 'action-scheduler' ), $group ) );
628
+        }
629
+
630
+        // Set up a query for post IDs to use later.
631
+        $query      = new WP_Query();
632
+        $query_args = array(
633
+            'fields'           => 'ids',
634
+            'post_type'        => self::POST_TYPE,
635
+            'post_status'      => ActionScheduler_Store::STATUS_PENDING,
636
+            'has_password'     => false,
637
+            'posts_per_page'   => $limit * 3,
638
+            'suppress_filters' => true,
639
+            'no_found_rows'    => true,
640
+            'orderby'          => array(
641
+                'menu_order' => 'ASC',
642
+                'date'       => 'ASC',
643
+                'ID'         => 'ASC',
644
+            ),
645
+            'date_query'       => array(
646
+                'column' => 'post_date_gmt',
647
+                'before' => $date->format( 'Y-m-d H:i' ),
648
+                'inclusive' => true,
649
+            ),
650
+            'tax_query' => array(
651
+                array(
652
+                    'taxonomy'         => self::GROUP_TAXONOMY,
653
+                    'field'            => 'slug',
654
+                    'terms'            => $group,
655
+                    'include_children' => false,
656
+                ),
657
+            ),
658
+        );
659
+
660
+        return $query->query( $query_args );
661
+    }
662
+
663
+    /**
664
+     * @param string $claim_id
665
+     * @return array
666
+     */
667
+    public function find_actions_by_claim_id( $claim_id ) {
668
+        /** @var wpdb $wpdb */
669
+        global $wpdb;
670
+        $sql = "SELECT ID FROM {$wpdb->posts} WHERE post_type = %s AND post_password = %s";
671
+        $sql = $wpdb->prepare( $sql, array( self::POST_TYPE, $claim_id ) );
672
+        $action_ids = $wpdb->get_col( $sql );
673
+        return $action_ids;
674
+    }
675
+
676
+    public function release_claim( ActionScheduler_ActionClaim $claim ) {
677
+        $action_ids = $this->find_actions_by_claim_id( $claim->get_id() );
678
+        if ( empty( $action_ids ) ) {
679
+            return; // nothing to do
680
+        }
681
+        $action_id_string = implode( ',', array_map( 'intval', $action_ids ) );
682
+        /** @var wpdb $wpdb */
683
+        global $wpdb;
684
+        $sql = "UPDATE {$wpdb->posts} SET post_password = '' WHERE ID IN ($action_id_string) AND post_password = %s";
685
+        $sql = $wpdb->prepare( $sql, array( $claim->get_id() ) );
686
+        $result = $wpdb->query( $sql );
687
+        if ( $result === false ) {
688
+            /* translators: %s: claim ID */
689
+            throw new RuntimeException( sprintf( __( 'Unable to unlock claim %s. Database error.', 'action-scheduler' ), $claim->get_id() ) );
690
+        }
691
+    }
692
+
693
+    /**
694
+     * @param string $action_id
695
+     */
696
+    public function unclaim_action( $action_id ) {
697
+        /** @var wpdb $wpdb */
698
+        global $wpdb;
699
+        $sql = "UPDATE {$wpdb->posts} SET post_password = '' WHERE ID = %d AND post_type = %s";
700
+        $sql = $wpdb->prepare( $sql, $action_id, self::POST_TYPE );
701
+        $result = $wpdb->query( $sql );
702
+        if ( $result === false ) {
703
+            /* translators: %s: action ID */
704
+            throw new RuntimeException( sprintf( __( 'Unable to unlock claim on action %s. Database error.', 'action-scheduler' ), $action_id ) );
705
+        }
706
+    }
707
+
708
+    public function mark_failure( $action_id ) {
709
+        /** @var wpdb $wpdb */
710
+        global $wpdb;
711
+        $sql = "UPDATE {$wpdb->posts} SET post_status = %s WHERE ID = %d AND post_type = %s";
712
+        $sql = $wpdb->prepare( $sql, self::STATUS_FAILED, $action_id, self::POST_TYPE );
713
+        $result = $wpdb->query( $sql );
714
+        if ( $result === false ) {
715
+            /* translators: %s: action ID */
716
+            throw new RuntimeException( sprintf( __( 'Unable to mark failure on action %s. Database error.', 'action-scheduler' ), $action_id ) );
717
+        }
718
+    }
719
+
720
+    /**
721
+     * Return an action's claim ID, as stored in the post password column
722
+     *
723
+     * @param string $action_id
724
+     * @return mixed
725
+     */
726
+    public function get_claim_id( $action_id ) {
727
+        return $this->get_post_column( $action_id, 'post_password' );
728
+    }
729
+
730
+    /**
731
+     * Return an action's status, as stored in the post status column
732
+     *
733
+     * @param string $action_id
734
+     * @return mixed
735
+     */
736
+    public function get_status( $action_id ) {
737
+        $status = $this->get_post_column( $action_id, 'post_status' );
738
+
739
+        if ( $status === null ) {
740
+            throw new InvalidArgumentException( __( 'Invalid action ID. No status found.', 'action-scheduler' ) );
741
+        }
742
+
743
+        return $this->get_action_status_by_post_status( $status );
744
+    }
745
+
746
+    private function get_post_column( $action_id, $column_name ) {
747
+        /** @var \wpdb $wpdb */
748
+        global $wpdb;
749
+        return $wpdb->get_var( $wpdb->prepare( "SELECT {$column_name} FROM {$wpdb->posts} WHERE ID=%d AND post_type=%s", $action_id, self::POST_TYPE ) );
750
+    }
751
+
752
+    /**
753
+     * @param string $action_id
754
+     */
755
+    public function log_execution( $action_id ) {
756
+        /** @var wpdb $wpdb */
757
+        global $wpdb;
758
+
759
+        $sql = "UPDATE {$wpdb->posts} SET menu_order = menu_order+1, post_status=%s, post_modified_gmt = %s, post_modified = %s WHERE ID = %d AND post_type = %s";
760
+        $sql = $wpdb->prepare( $sql, self::STATUS_RUNNING, current_time('mysql', true), current_time('mysql'), $action_id, self::POST_TYPE );
761
+        $wpdb->query($sql);
762
+    }
763
+
764
+    /**
765
+     * Record that an action was completed.
766
+     *
767
+     * @param int $action_id ID of the completed action.
768
+     * @throws InvalidArgumentException|RuntimeException
769
+     */
770
+    public function mark_complete( $action_id ) {
771
+        $post = get_post( $action_id );
772
+        if ( empty( $post ) || ( $post->post_type != self::POST_TYPE ) ) {
773
+            throw new InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) );
774
+        }
775
+        add_filter( 'wp_insert_post_data', array( $this, 'filter_insert_post_data' ), 10, 1 );
776
+        add_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10, 5 );
777
+        $result = wp_update_post(array(
778
+            'ID' => $action_id,
779
+            'post_status' => 'publish',
780
+        ), TRUE);
781
+        remove_filter( 'wp_insert_post_data', array( $this, 'filter_insert_post_data' ), 10 );
782
+        remove_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10 );
783
+        if ( is_wp_error( $result ) ) {
784
+            throw new RuntimeException( $result->get_error_message() );
785
+        }
786
+    }
787
+
788
+    /**
789
+     * Mark action as migrated when there is an error deleting the action.
790
+     *
791
+     * @param int $action_id Action ID.
792
+     */
793
+    public function mark_migrated( $action_id ) {
794
+        wp_update_post(
795
+            array(
796
+                'ID'          => $action_id,
797
+                'post_status' => 'migrated'
798
+            )
799
+        );
800
+    }
801
+
802
+    /**
803
+     * Determine whether the post store can be migrated.
804
+     *
805
+     * @return bool
806
+     */
807
+    public function migration_dependencies_met( $setting ) {
808
+        global $wpdb;
809
+
810
+        $dependencies_met = get_transient( self::DEPENDENCIES_MET );
811
+        if ( empty( $dependencies_met ) ) {
812
+            $maximum_args_length = apply_filters( 'action_scheduler_maximum_args_length', 191 );
813
+            $found_action        = $wpdb->get_var(
814
+                $wpdb->prepare(
815
+                    "SELECT ID FROM {$wpdb->posts} WHERE post_type = %s AND CHAR_LENGTH(post_content) > %d LIMIT 1",
816
+                    $maximum_args_length,
817
+                    self::POST_TYPE
818
+                )
819
+            );
820
+            $dependencies_met = $found_action ? 'no' : 'yes';
821
+            set_transient( self::DEPENDENCIES_MET, $dependencies_met, DAY_IN_SECONDS );
822
+        }
823
+
824
+        return 'yes' == $dependencies_met ? $setting : false;
825
+    }
826
+
827
+    /**
828
+     * InnoDB indexes have a maximum size of 767 bytes by default, which is only 191 characters with utf8mb4.
829
+     *
830
+     * Previously, AS wasn't concerned about args length, as we used the (unindex) post_content column. However,
831
+     * as we prepare to move to custom tables, and can use an indexed VARCHAR column instead, we want to warn
832
+     * developers of this impending requirement.
833
+     *
834
+     * @param ActionScheduler_Action $action
835
+     */
836
+    protected function validate_action( ActionScheduler_Action $action ) {
837
+        try {
838
+            parent::validate_action( $action );
839
+        } catch ( Exception $e ) {
840
+            $message = sprintf( __( '%s Support for strings longer than this will be removed in a future version.', 'action-scheduler' ), $e->getMessage() );
841
+            _doing_it_wrong( 'ActionScheduler_Action::$args', $message, '2.1.0' );
842
+        }
843
+    }
844
+
845
+    /**
846
+     * @codeCoverageIgnore
847
+     */
848
+    public function init() {
849
+        add_filter( 'action_scheduler_migration_dependencies_met', array( $this, 'migration_dependencies_met' ) );
850
+
851
+        $post_type_registrar = new ActionScheduler_wpPostStore_PostTypeRegistrar();
852
+        $post_type_registrar->register();
853
+
854
+        $post_status_registrar = new ActionScheduler_wpPostStore_PostStatusRegistrar();
855
+        $post_status_registrar->register();
856
+
857
+        $taxonomy_registrar = new ActionScheduler_wpPostStore_TaxonomyRegistrar();
858
+        $taxonomy_registrar->register();
859
+    }
860 860
 }
Please login to merge, or discard this patch.
Spacing   +210 added lines, -210 removed lines patch added patch discarded remove patch
@@ -12,62 +12,62 @@  discard block
 block discarded – undo
12 12
 	/** @var DateTimeZone */
13 13
 	protected $local_timezone = NULL;
14 14
 
15
-	public function save_action( ActionScheduler_Action $action, DateTime $scheduled_date = NULL ){
15
+	public function save_action(ActionScheduler_Action $action, DateTime $scheduled_date = NULL) {
16 16
 		try {
17
-			$this->validate_action( $action );
18
-			$post_array = $this->create_post_array( $action, $scheduled_date );
19
-			$post_id = $this->save_post_array( $post_array );
20
-			$this->save_post_schedule( $post_id, $action->get_schedule() );
21
-			$this->save_action_group( $post_id, $action->get_group() );
22
-			do_action( 'action_scheduler_stored_action', $post_id );
17
+			$this->validate_action($action);
18
+			$post_array = $this->create_post_array($action, $scheduled_date);
19
+			$post_id = $this->save_post_array($post_array);
20
+			$this->save_post_schedule($post_id, $action->get_schedule());
21
+			$this->save_action_group($post_id, $action->get_group());
22
+			do_action('action_scheduler_stored_action', $post_id);
23 23
 			return $post_id;
24
-		} catch ( Exception $e ) {
25
-			throw new RuntimeException( sprintf( __( 'Error saving action: %s', 'action-scheduler' ), $e->getMessage() ), 0 );
24
+		} catch (Exception $e) {
25
+			throw new RuntimeException(sprintf(__('Error saving action: %s', 'action-scheduler'), $e->getMessage()), 0);
26 26
 		}
27 27
 	}
28 28
 
29
-	protected function create_post_array( ActionScheduler_Action $action, DateTime $scheduled_date = NULL ) {
29
+	protected function create_post_array(ActionScheduler_Action $action, DateTime $scheduled_date = NULL) {
30 30
 		$post = array(
31 31
 			'post_type' => self::POST_TYPE,
32 32
 			'post_title' => $action->get_hook(),
33 33
 			'post_content' => json_encode($action->get_args()),
34
-			'post_status' => ( $action->is_finished() ? 'publish' : 'pending' ),
35
-			'post_date_gmt' => $this->get_scheduled_date_string( $action, $scheduled_date ),
36
-			'post_date'     => $this->get_scheduled_date_string_local( $action, $scheduled_date ),
34
+			'post_status' => ($action->is_finished() ? 'publish' : 'pending'),
35
+			'post_date_gmt' => $this->get_scheduled_date_string($action, $scheduled_date),
36
+			'post_date'     => $this->get_scheduled_date_string_local($action, $scheduled_date),
37 37
 		);
38 38
 		return $post;
39 39
 	}
40 40
 
41
-	protected function save_post_array( $post_array ) {
42
-		add_filter( 'wp_insert_post_data', array( $this, 'filter_insert_post_data' ), 10, 1 );
43
-		add_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10, 5 );
41
+	protected function save_post_array($post_array) {
42
+		add_filter('wp_insert_post_data', array($this, 'filter_insert_post_data'), 10, 1);
43
+		add_filter('pre_wp_unique_post_slug', array($this, 'set_unique_post_slug'), 10, 5);
44 44
 
45
-		$has_kses = false !== has_filter( 'content_save_pre', 'wp_filter_post_kses' );
45
+		$has_kses = false !== has_filter('content_save_pre', 'wp_filter_post_kses');
46 46
 
47
-		if ( $has_kses ) {
47
+		if ($has_kses) {
48 48
 			// Prevent KSES from corrupting JSON in post_content.
49 49
 			kses_remove_filters();
50 50
 		}
51 51
 
52 52
 		$post_id = wp_insert_post($post_array);
53 53
 
54
-		if ( $has_kses ) {
54
+		if ($has_kses) {
55 55
 			kses_init_filters();
56 56
 		}
57 57
 
58
-		remove_filter( 'wp_insert_post_data', array( $this, 'filter_insert_post_data' ), 10 );
59
-		remove_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10 );
58
+		remove_filter('wp_insert_post_data', array($this, 'filter_insert_post_data'), 10);
59
+		remove_filter('pre_wp_unique_post_slug', array($this, 'set_unique_post_slug'), 10);
60 60
 
61
-		if ( is_wp_error($post_id) || empty($post_id) ) {
62
-			throw new RuntimeException( __( 'Unable to save action.', 'action-scheduler' ) );
61
+		if (is_wp_error($post_id) || empty($post_id)) {
62
+			throw new RuntimeException(__('Unable to save action.', 'action-scheduler'));
63 63
 		}
64 64
 		return $post_id;
65 65
 	}
66 66
 
67
-	public function filter_insert_post_data( $postdata ) {
68
-		if ( $postdata['post_type'] == self::POST_TYPE ) {
67
+	public function filter_insert_post_data($postdata) {
68
+		if ($postdata['post_type'] == self::POST_TYPE) {
69 69
 			$postdata['post_author'] = 0;
70
-			if ( $postdata['post_status'] == 'future' ) {
70
+			if ($postdata['post_status'] == 'future') {
71 71
 				$postdata['post_status'] = 'publish';
72 72
 			}
73 73
 		}
@@ -102,43 +102,43 @@  discard block
 block discarded – undo
102 102
 	 * @param string $post_type     Post type.
103 103
 	 * @return string
104 104
 	 */
105
-	public function set_unique_post_slug( $override_slug, $slug, $post_ID, $post_status, $post_type ) {
106
-		if ( self::POST_TYPE == $post_type ) {
107
-			$override_slug = uniqid( self::POST_TYPE . '-', true ) . '-' . wp_generate_password( 32, false );
105
+	public function set_unique_post_slug($override_slug, $slug, $post_ID, $post_status, $post_type) {
106
+		if (self::POST_TYPE == $post_type) {
107
+			$override_slug = uniqid(self::POST_TYPE . '-', true) . '-' . wp_generate_password(32, false);
108 108
 		}
109 109
 		return $override_slug;
110 110
 	}
111 111
 
112
-	protected function save_post_schedule( $post_id, $schedule ) {
113
-		update_post_meta( $post_id, self::SCHEDULE_META_KEY, $schedule );
112
+	protected function save_post_schedule($post_id, $schedule) {
113
+		update_post_meta($post_id, self::SCHEDULE_META_KEY, $schedule);
114 114
 	}
115 115
 
116
-	protected function save_action_group( $post_id, $group ) {
117
-		if ( empty($group) ) {
118
-			wp_set_object_terms( $post_id, array(), self::GROUP_TAXONOMY, FALSE );
116
+	protected function save_action_group($post_id, $group) {
117
+		if (empty($group)) {
118
+			wp_set_object_terms($post_id, array(), self::GROUP_TAXONOMY, FALSE);
119 119
 		} else {
120
-			wp_set_object_terms( $post_id, array($group), self::GROUP_TAXONOMY, FALSE );
120
+			wp_set_object_terms($post_id, array($group), self::GROUP_TAXONOMY, FALSE);
121 121
 		}
122 122
 	}
123 123
 
124
-	public function fetch_action( $action_id ) {
125
-		$post = $this->get_post( $action_id );
126
-		if ( empty($post) || $post->post_type != self::POST_TYPE ) {
124
+	public function fetch_action($action_id) {
125
+		$post = $this->get_post($action_id);
126
+		if (empty($post) || $post->post_type != self::POST_TYPE) {
127 127
 			return $this->get_null_action();
128 128
 		}
129 129
 
130 130
 		try {
131
-			$action = $this->make_action_from_post( $post );
132
-		} catch ( ActionScheduler_InvalidActionException $exception ) {
133
-			do_action( 'action_scheduler_failed_fetch_action', $post->ID, $exception );
131
+			$action = $this->make_action_from_post($post);
132
+		} catch (ActionScheduler_InvalidActionException $exception) {
133
+			do_action('action_scheduler_failed_fetch_action', $post->ID, $exception);
134 134
 			return $this->get_null_action();
135 135
 		}
136 136
 
137 137
 		return $action;
138 138
 	}
139 139
 
140
-	protected function get_post( $action_id ) {
141
-		if ( empty($action_id) ) {
140
+	protected function get_post($action_id) {
141
+		if (empty($action_id)) {
142 142
 			return NULL;
143 143
 		}
144 144
 		return get_post($action_id);
@@ -148,19 +148,19 @@  discard block
 block discarded – undo
148 148
 		return new ActionScheduler_NullAction();
149 149
 	}
150 150
 
151
-	protected function make_action_from_post( $post ) {
151
+	protected function make_action_from_post($post) {
152 152
 		$hook = $post->post_title;
153 153
 
154
-		$args = json_decode( $post->post_content, true );
155
-		$this->validate_args( $args, $post->ID );
154
+		$args = json_decode($post->post_content, true);
155
+		$this->validate_args($args, $post->ID);
156 156
 
157
-		$schedule = get_post_meta( $post->ID, self::SCHEDULE_META_KEY, true );
158
-		$this->validate_schedule( $schedule, $post->ID );
157
+		$schedule = get_post_meta($post->ID, self::SCHEDULE_META_KEY, true);
158
+		$this->validate_schedule($schedule, $post->ID);
159 159
 
160
-		$group = wp_get_object_terms( $post->ID, self::GROUP_TAXONOMY, array('fields' => 'names') );
161
-		$group = empty( $group ) ? '' : reset($group);
160
+		$group = wp_get_object_terms($post->ID, self::GROUP_TAXONOMY, array('fields' => 'names'));
161
+		$group = empty($group) ? '' : reset($group);
162 162
 
163
-		return ActionScheduler::factory()->get_stored_action( $this->get_action_status_by_post_status( $post->post_status ), $hook, $args, $schedule, $group );
163
+		return ActionScheduler::factory()->get_stored_action($this->get_action_status_by_post_status($post->post_status), $hook, $args, $schedule, $group);
164 164
 	}
165 165
 
166 166
 	/**
@@ -169,9 +169,9 @@  discard block
 block discarded – undo
169 169
 	 * @throws InvalidArgumentException if $post_status not in known status fields returned by $this->get_status_labels()
170 170
 	 * @return string
171 171
 	 */
172
-	protected function get_action_status_by_post_status( $post_status ) {
172
+	protected function get_action_status_by_post_status($post_status) {
173 173
 
174
-		switch ( $post_status ) {
174
+		switch ($post_status) {
175 175
 			case 'publish' :
176 176
 				$action_status = self::STATUS_COMPLETE;
177 177
 				break;
@@ -179,8 +179,8 @@  discard block
 block discarded – undo
179 179
 				$action_status = self::STATUS_CANCELED;
180 180
 				break;
181 181
 			default :
182
-				if ( ! array_key_exists( $post_status, $this->get_status_labels() ) ) {
183
-					throw new InvalidArgumentException( sprintf( 'Invalid post status: "%s". No matching action status available.', $post_status ) );
182
+				if (!array_key_exists($post_status, $this->get_status_labels())) {
183
+					throw new InvalidArgumentException(sprintf('Invalid post status: "%s". No matching action status available.', $post_status));
184 184
 				}
185 185
 				$action_status = $post_status;
186 186
 				break;
@@ -194,9 +194,9 @@  discard block
 block discarded – undo
194 194
 	 * @throws InvalidArgumentException if $post_status not in known status fields returned by $this->get_status_labels()
195 195
 	 * @return string
196 196
 	 */
197
-	protected function get_post_status_by_action_status( $action_status ) {
197
+	protected function get_post_status_by_action_status($action_status) {
198 198
 
199
-		switch ( $action_status ) {
199
+		switch ($action_status) {
200 200
 			case self::STATUS_COMPLETE :
201 201
 				$post_status = 'publish';
202 202
 				break;
@@ -204,8 +204,8 @@  discard block
 block discarded – undo
204 204
 				$post_status = 'trash';
205 205
 				break;
206 206
 			default :
207
-				if ( ! array_key_exists( $action_status, $this->get_status_labels() ) ) {
208
-					throw new InvalidArgumentException( sprintf( 'Invalid action status: "%s".', $action_status ) );
207
+				if (!array_key_exists($action_status, $this->get_status_labels())) {
208
+					throw new InvalidArgumentException(sprintf('Invalid action status: "%s".', $action_status));
209 209
 				}
210 210
 				$post_status = $action_status;
211 211
 				break;
@@ -220,8 +220,8 @@  discard block
 block discarded – undo
220 220
 	 *
221 221
 	 * @return string ID of the next action matching the criteria or NULL if not found
222 222
 	 */
223
-	public function find_action( $hook, $params = array() ) {
224
-		$params = wp_parse_args( $params, array(
223
+	public function find_action($hook, $params = array()) {
224
+		$params = wp_parse_args($params, array(
225 225
 			'args' => NULL,
226 226
 			'status' => ActionScheduler_Store::STATUS_PENDING,
227 227
 			'group' => '',
@@ -230,7 +230,7 @@  discard block
 block discarded – undo
230 230
 		global $wpdb;
231 231
 		$query = "SELECT p.ID FROM {$wpdb->posts} p";
232 232
 		$args = array();
233
-		if ( !empty($params['group']) ) {
233
+		if (!empty($params['group'])) {
234 234
 			$query .= " INNER JOIN {$wpdb->term_relationships} tr ON tr.object_id=p.ID";
235 235
 			$query .= " INNER JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id=tt.term_taxonomy_id";
236 236
 			$query .= " INNER JOIN {$wpdb->terms} t ON tt.term_id=t.term_id AND t.slug=%s";
@@ -240,17 +240,17 @@  discard block
 block discarded – undo
240 240
 		$args[] = $hook;
241 241
 		$query .= " AND p.post_type=%s";
242 242
 		$args[] = self::POST_TYPE;
243
-		if ( !is_null($params['args']) ) {
243
+		if (!is_null($params['args'])) {
244 244
 			$query .= " AND p.post_content=%s";
245 245
 			$args[] = json_encode($params['args']);
246 246
 		}
247 247
 
248
-		if ( ! empty( $params['status'] ) ) {
248
+		if (!empty($params['status'])) {
249 249
 			$query .= " AND p.post_status=%s";
250
-			$args[] = $this->get_post_status_by_action_status( $params['status'] );
250
+			$args[] = $this->get_post_status_by_action_status($params['status']);
251 251
 		}
252 252
 
253
-		switch ( $params['status'] ) {
253
+		switch ($params['status']) {
254 254
 			case self::STATUS_COMPLETE:
255 255
 			case self::STATUS_RUNNING:
256 256
 			case self::STATUS_FAILED:
@@ -263,7 +263,7 @@  discard block
 block discarded – undo
263 263
 		}
264 264
 		$query .= " ORDER BY post_date_gmt $order LIMIT 1";
265 265
 
266
-		$query = $wpdb->prepare( $query, $args );
266
+		$query = $wpdb->prepare($query, $args);
267 267
 
268 268
 		$id = $wpdb->get_var($query);
269 269
 		return $id;
@@ -277,13 +277,13 @@  discard block
 block discarded – undo
277 277
 	 * @throws InvalidArgumentException if $select_or_count not count or select
278 278
 	 * @return string SQL statement. The returned SQL is already properly escaped.
279 279
 	 */
280
-	protected function get_query_actions_sql( array $query, $select_or_count = 'select' ) {
280
+	protected function get_query_actions_sql(array $query, $select_or_count = 'select') {
281 281
 
282
-		if ( ! in_array( $select_or_count, array( 'select', 'count' ) ) ) {
283
-			throw new InvalidArgumentException( __( 'Invalid schedule. Cannot save action.', 'action-scheduler' ) );
282
+		if (!in_array($select_or_count, array('select', 'count'))) {
283
+			throw new InvalidArgumentException(__('Invalid schedule. Cannot save action.', 'action-scheduler'));
284 284
 		}
285 285
 
286
-		$query = wp_parse_args( $query, array(
286
+		$query = wp_parse_args($query, array(
287 287
 			'hook' => '',
288 288
 			'args' => NULL,
289 289
 			'date' => NULL,
@@ -298,18 +298,18 @@  discard block
 block discarded – undo
298 298
 			'orderby' => 'date',
299 299
 			'order' => 'ASC',
300 300
 			'search' => '',
301
-		) );
301
+		));
302 302
 
303 303
 		/** @var wpdb $wpdb */
304 304
 		global $wpdb;
305
-		$sql  = ( 'count' === $select_or_count ) ? 'SELECT count(p.ID)' : 'SELECT p.ID ';
305
+		$sql  = ('count' === $select_or_count) ? 'SELECT count(p.ID)' : 'SELECT p.ID ';
306 306
 		$sql .= "FROM {$wpdb->posts} p";
307 307
 		$sql_params = array();
308
-		if ( empty( $query['group'] ) && 'group' === $query['orderby'] ) {
308
+		if (empty($query['group']) && 'group' === $query['orderby']) {
309 309
 			$sql .= " LEFT JOIN {$wpdb->term_relationships} tr ON tr.object_id=p.ID";
310 310
 			$sql .= " LEFT JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id=tt.term_taxonomy_id";
311 311
 			$sql .= " LEFT JOIN {$wpdb->terms} t ON tt.term_id=t.term_id";
312
-		} elseif ( ! empty( $query['group'] ) ) {
312
+		} elseif (!empty($query['group'])) {
313 313
 			$sql .= " INNER JOIN {$wpdb->term_relationships} tr ON tr.object_id=p.ID";
314 314
 			$sql .= " INNER JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id=tt.term_taxonomy_id";
315 315
 			$sql .= " INNER JOIN {$wpdb->terms} t ON tt.term_id=t.term_id";
@@ -318,56 +318,56 @@  discard block
 block discarded – undo
318 318
 		}
319 319
 		$sql .= " WHERE post_type=%s";
320 320
 		$sql_params[] = self::POST_TYPE;
321
-		if ( $query['hook'] ) {
321
+		if ($query['hook']) {
322 322
 			$sql .= " AND p.post_title=%s";
323 323
 			$sql_params[] = $query['hook'];
324 324
 		}
325
-		if ( !is_null($query['args']) ) {
325
+		if (!is_null($query['args'])) {
326 326
 			$sql .= " AND p.post_content=%s";
327 327
 			$sql_params[] = json_encode($query['args']);
328 328
 		}
329 329
 
330
-		if ( ! empty( $query['status'] ) ) {
330
+		if (!empty($query['status'])) {
331 331
 			$sql .= " AND p.post_status=%s";
332
-			$sql_params[] = $this->get_post_status_by_action_status( $query['status'] );
332
+			$sql_params[] = $this->get_post_status_by_action_status($query['status']);
333 333
 		}
334 334
 
335
-		if ( $query['date'] instanceof DateTime ) {
335
+		if ($query['date'] instanceof DateTime) {
336 336
 			$date = clone $query['date'];
337
-			$date->setTimezone( new DateTimeZone('UTC') );
337
+			$date->setTimezone(new DateTimeZone('UTC'));
338 338
 			$date_string = $date->format('Y-m-d H:i:s');
339 339
 			$comparator = $this->validate_sql_comparator($query['date_compare']);
340 340
 			$sql .= " AND p.post_date_gmt $comparator %s";
341 341
 			$sql_params[] = $date_string;
342 342
 		}
343 343
 
344
-		if ( $query['modified'] instanceof DateTime ) {
344
+		if ($query['modified'] instanceof DateTime) {
345 345
 			$modified = clone $query['modified'];
346
-			$modified->setTimezone( new DateTimeZone('UTC') );
346
+			$modified->setTimezone(new DateTimeZone('UTC'));
347 347
 			$date_string = $modified->format('Y-m-d H:i:s');
348 348
 			$comparator = $this->validate_sql_comparator($query['modified_compare']);
349 349
 			$sql .= " AND p.post_modified_gmt $comparator %s";
350 350
 			$sql_params[] = $date_string;
351 351
 		}
352 352
 
353
-		if ( $query['claimed'] === TRUE ) {
353
+		if ($query['claimed'] === TRUE) {
354 354
 			$sql .= " AND p.post_password != ''";
355
-		} elseif ( $query['claimed'] === FALSE ) {
355
+		} elseif ($query['claimed'] === FALSE) {
356 356
 			$sql .= " AND p.post_password = ''";
357
-		} elseif ( !is_null($query['claimed']) ) {
357
+		} elseif (!is_null($query['claimed'])) {
358 358
 			$sql .= " AND p.post_password = %s";
359 359
 			$sql_params[] = $query['claimed'];
360 360
 		}
361 361
 
362
-		if ( ! empty( $query['search'] ) ) {
362
+		if (!empty($query['search'])) {
363 363
 			$sql .= " AND (p.post_title LIKE %s OR p.post_content LIKE %s OR p.post_password LIKE %s)";
364
-			for( $i = 0; $i < 3; $i++ ) {
365
-				$sql_params[] = sprintf( '%%%s%%', $query['search'] );
364
+			for ($i = 0; $i < 3; $i++) {
365
+				$sql_params[] = sprintf('%%%s%%', $query['search']);
366 366
 			}
367 367
 		}
368 368
 
369
-		if ( 'select' === $select_or_count ) {
370
-			switch ( $query['orderby'] ) {
369
+		if ('select' === $select_or_count) {
370
+			switch ($query['orderby']) {
371 371
 				case 'hook':
372 372
 					$orderby = 'p.post_title';
373 373
 					break;
@@ -389,20 +389,20 @@  discard block
 block discarded – undo
389 389
 					$orderby = 'p.post_date_gmt';
390 390
 					break;
391 391
 			}
392
-			if ( 'ASC' === strtoupper( $query['order'] ) ) {
392
+			if ('ASC' === strtoupper($query['order'])) {
393 393
 				$order = 'ASC';
394 394
 			} else {
395 395
 				$order = 'DESC';
396 396
 			}
397 397
 			$sql .= " ORDER BY $orderby $order";
398
-			if ( $query['per_page'] > 0 ) {
398
+			if ($query['per_page'] > 0) {
399 399
 				$sql .= " LIMIT %d, %d";
400 400
 				$sql_params[] = $query['offset'];
401 401
 				$sql_params[] = $query['per_page'];
402 402
 			}
403 403
 		}
404 404
 
405
-		return $wpdb->prepare( $sql, $sql_params );
405
+		return $wpdb->prepare($sql, $sql_params);
406 406
 	}
407 407
 
408 408
 	/**
@@ -410,13 +410,13 @@  discard block
 block discarded – undo
410 410
 	 * @param string $query_type Whether to select or count the results. Default, select.
411 411
 	 * @return string|array The IDs of actions matching the query
412 412
 	 */
413
-	public function query_actions( $query = array(), $query_type = 'select' ) {
413
+	public function query_actions($query = array(), $query_type = 'select') {
414 414
 		/** @var wpdb $wpdb */
415 415
 		global $wpdb;
416 416
 
417
-		$sql = $this->get_query_actions_sql( $query, $query_type );
417
+		$sql = $this->get_query_actions_sql($query, $query_type);
418 418
 
419
-		return ( 'count' === $query_type ) ? $wpdb->get_var( $sql ) : $wpdb->get_col( $sql );
419
+		return ('count' === $query_type) ? $wpdb->get_var($sql) : $wpdb->get_col($sql);
420 420
 	}
421 421
 
422 422
 	/**
@@ -428,18 +428,18 @@  discard block
 block discarded – undo
428 428
 
429 429
 		$action_counts_by_status = array();
430 430
 		$action_stati_and_labels = $this->get_status_labels();
431
-		$posts_count_by_status   = (array) wp_count_posts( self::POST_TYPE, 'readable' );
431
+		$posts_count_by_status   = (array) wp_count_posts(self::POST_TYPE, 'readable');
432 432
 
433
-		foreach ( $posts_count_by_status as $post_status_name => $count ) {
433
+		foreach ($posts_count_by_status as $post_status_name => $count) {
434 434
 
435 435
 			try {
436
-				$action_status_name = $this->get_action_status_by_post_status( $post_status_name );
437
-			} catch ( Exception $e ) {
436
+				$action_status_name = $this->get_action_status_by_post_status($post_status_name);
437
+			} catch (Exception $e) {
438 438
 				// Ignore any post statuses that aren't for actions
439 439
 				continue;
440 440
 			}
441
-			if ( array_key_exists( $action_status_name, $action_stati_and_labels ) ) {
442
-				$action_counts_by_status[ $action_status_name ] = $count;
441
+			if (array_key_exists($action_status_name, $action_stati_and_labels)) {
442
+				$action_counts_by_status[$action_status_name] = $count;
443 443
 			}
444 444
 		}
445 445
 
@@ -451,25 +451,25 @@  discard block
 block discarded – undo
451 451
 	 *
452 452
 	 * @throws InvalidArgumentException
453 453
 	 */
454
-	public function cancel_action( $action_id ) {
455
-		$post = get_post( $action_id );
456
-		if ( empty( $post ) || ( $post->post_type != self::POST_TYPE ) ) {
457
-			throw new InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) );
454
+	public function cancel_action($action_id) {
455
+		$post = get_post($action_id);
456
+		if (empty($post) || ($post->post_type != self::POST_TYPE)) {
457
+			throw new InvalidArgumentException(sprintf(__('Unidentified action %s', 'action-scheduler'), $action_id));
458 458
 		}
459
-		do_action( 'action_scheduler_canceled_action', $action_id );
460
-		add_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10, 5 );
461
-		wp_trash_post( $action_id );
462
-		remove_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10 );
459
+		do_action('action_scheduler_canceled_action', $action_id);
460
+		add_filter('pre_wp_unique_post_slug', array($this, 'set_unique_post_slug'), 10, 5);
461
+		wp_trash_post($action_id);
462
+		remove_filter('pre_wp_unique_post_slug', array($this, 'set_unique_post_slug'), 10);
463 463
 	}
464 464
 
465
-	public function delete_action( $action_id ) {
466
-		$post = get_post( $action_id );
467
-		if ( empty( $post ) || ( $post->post_type != self::POST_TYPE ) ) {
468
-			throw new InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) );
465
+	public function delete_action($action_id) {
466
+		$post = get_post($action_id);
467
+		if (empty($post) || ($post->post_type != self::POST_TYPE)) {
468
+			throw new InvalidArgumentException(sprintf(__('Unidentified action %s', 'action-scheduler'), $action_id));
469 469
 		}
470
-		do_action( 'action_scheduler_deleted_action', $action_id );
470
+		do_action('action_scheduler_deleted_action', $action_id);
471 471
 
472
-		wp_delete_post( $action_id, TRUE );
472
+		wp_delete_post($action_id, TRUE);
473 473
 	}
474 474
 
475 475
 	/**
@@ -478,9 +478,9 @@  discard block
 block discarded – undo
478 478
 	 * @throws InvalidArgumentException
479 479
 	 * @return ActionScheduler_DateTime The date the action is schedule to run, or the date that it ran.
480 480
 	 */
481
-	public function get_date( $action_id ) {
482
-		$next = $this->get_date_gmt( $action_id );
483
-		return ActionScheduler_TimezoneHelper::set_local_timezone( $next );
481
+	public function get_date($action_id) {
482
+		$next = $this->get_date_gmt($action_id);
483
+		return ActionScheduler_TimezoneHelper::set_local_timezone($next);
484 484
 	}
485 485
 
486 486
 	/**
@@ -489,15 +489,15 @@  discard block
 block discarded – undo
489 489
 	 * @throws InvalidArgumentException
490 490
 	 * @return ActionScheduler_DateTime The date the action is schedule to run, or the date that it ran.
491 491
 	 */
492
-	public function get_date_gmt( $action_id ) {
493
-		$post = get_post( $action_id );
494
-		if ( empty( $post ) || ( $post->post_type != self::POST_TYPE ) ) {
495
-			throw new InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) );
492
+	public function get_date_gmt($action_id) {
493
+		$post = get_post($action_id);
494
+		if (empty($post) || ($post->post_type != self::POST_TYPE)) {
495
+			throw new InvalidArgumentException(sprintf(__('Unidentified action %s', 'action-scheduler'), $action_id));
496 496
 		}
497
-		if ( $post->post_status == 'publish' ) {
498
-			return as_get_datetime_object( $post->post_modified_gmt );
497
+		if ($post->post_status == 'publish') {
498
+			return as_get_datetime_object($post->post_modified_gmt);
499 499
 		} else {
500
-			return as_get_datetime_object( $post->post_date_gmt );
500
+			return as_get_datetime_object($post->post_date_gmt);
501 501
 		}
502 502
 	}
503 503
 
@@ -511,28 +511,28 @@  discard block
 block discarded – undo
511 511
 	 * @throws RuntimeException When there is an error staking a claim.
512 512
 	 * @throws InvalidArgumentException When the given group is not valid.
513 513
 	 */
514
-	public function stake_claim( $max_actions = 10, DateTime $before_date = null, $hooks = array(), $group = '' ) {
514
+	public function stake_claim($max_actions = 10, DateTime $before_date = null, $hooks = array(), $group = '') {
515 515
 		$claim_id = $this->generate_claim_id();
516
-		$this->claim_actions( $claim_id, $max_actions, $before_date, $hooks, $group );
517
-		$action_ids = $this->find_actions_by_claim_id( $claim_id );
516
+		$this->claim_actions($claim_id, $max_actions, $before_date, $hooks, $group);
517
+		$action_ids = $this->find_actions_by_claim_id($claim_id);
518 518
 
519
-		return new ActionScheduler_ActionClaim( $claim_id, $action_ids );
519
+		return new ActionScheduler_ActionClaim($claim_id, $action_ids);
520 520
 	}
521 521
 
522 522
 	/**
523 523
 	 * @return int
524 524
 	 */
525
-	public function get_claim_count(){
525
+	public function get_claim_count() {
526 526
 		global $wpdb;
527 527
 
528 528
 		$sql = "SELECT COUNT(DISTINCT post_password) FROM {$wpdb->posts} WHERE post_password != '' AND post_type = %s AND post_status IN ('in-progress','pending')";
529
-		$sql = $wpdb->prepare( $sql, array( self::POST_TYPE ) );
529
+		$sql = $wpdb->prepare($sql, array(self::POST_TYPE));
530 530
 
531
-		return $wpdb->get_var( $sql );
531
+		return $wpdb->get_var($sql);
532 532
 	}
533 533
 
534 534
 	protected function generate_claim_id() {
535
-		$claim_id = md5(microtime(true) . rand(0,1000));
535
+		$claim_id = md5(microtime(true) . rand(0, 1000));
536 536
 		return substr($claim_id, 0, 20); // to fit in db field with 20 char limit
537 537
 	}
538 538
 
@@ -547,14 +547,14 @@  discard block
 block discarded – undo
547 547
 	 * @throws RuntimeException When there is a database error.
548 548
 	 * @throws InvalidArgumentException When the group is invalid.
549 549
 	 */
550
-	protected function claim_actions( $claim_id, $limit, DateTime $before_date = null, $hooks = array(), $group = '' ) {
550
+	protected function claim_actions($claim_id, $limit, DateTime $before_date = null, $hooks = array(), $group = '') {
551 551
 		// Set up initial variables.
552 552
 		$date      = null === $before_date ? as_get_datetime_object() : clone $before_date;
553
-		$limit_ids = ! empty( $group );
554
-		$ids       = $limit_ids ? $this->get_actions_by_group( $group, $limit, $date ) : array();
553
+		$limit_ids = !empty($group);
554
+		$ids       = $limit_ids ? $this->get_actions_by_group($group, $limit, $date) : array();
555 555
 
556 556
 		// If limiting by IDs and no posts found, then return early since we have nothing to update.
557
-		if ( $limit_ids && 0 === count( $ids ) ) {
557
+		if ($limit_ids && 0 === count($ids)) {
558 558
 			return 0;
559 559
 		}
560 560
 
@@ -570,8 +570,8 @@  discard block
 block discarded – undo
570 570
 		$update = "UPDATE {$wpdb->posts} SET post_password = %s, post_modified_gmt = %s, post_modified = %s";
571 571
 		$params = array(
572 572
 			$claim_id,
573
-			current_time( 'mysql', true ),
574
-			current_time( 'mysql' ),
573
+			current_time('mysql', true),
574
+			current_time('mysql'),
575 575
 		);
576 576
 
577 577
 		// Build initial WHERE clause.
@@ -579,10 +579,10 @@  discard block
 block discarded – undo
579 579
 		$params[] = self::POST_TYPE;
580 580
 		$params[] = ActionScheduler_Store::STATUS_PENDING;
581 581
 
582
-		if ( ! empty( $hooks ) ) {
583
-			$placeholders = array_fill( 0, count( $hooks ), '%s' );
584
-			$where       .= ' AND post_title IN (' . join( ', ', $placeholders ) . ')';
585
-			$params       = array_merge( $params, array_values( $hooks ) );
582
+		if (!empty($hooks)) {
583
+			$placeholders = array_fill(0, count($hooks), '%s');
584
+			$where       .= ' AND post_title IN (' . join(', ', $placeholders) . ')';
585
+			$params       = array_merge($params, array_values($hooks));
586 586
 		}
587 587
 
588 588
 		/*
@@ -590,11 +590,11 @@  discard block
 block discarded – undo
590 590
 		 *
591 591
 		 * If we're not limiting by IDs, then include the post_date_gmt clause.
592 592
 		 */
593
-		if ( $limit_ids ) {
594
-			$where .= ' AND ID IN (' . join( ',', $ids ) . ')';
593
+		if ($limit_ids) {
594
+			$where .= ' AND ID IN (' . join(',', $ids) . ')';
595 595
 		} else {
596 596
 			$where .= ' AND post_date_gmt <= %s';
597
-			$params[] = $date->format( 'Y-m-d H:i:s' );
597
+			$params[] = $date->format('Y-m-d H:i:s');
598 598
 		}
599 599
 
600 600
 		// Add the ORDER BY clause and,ms limit.
@@ -602,9 +602,9 @@  discard block
 block discarded – undo
602 602
 		$params[] = $limit;
603 603
 
604 604
 		// Run the query and gather results.
605
-		$rows_affected = $wpdb->query( $wpdb->prepare( "{$update} {$where} {$order}", $params ) );
606
-		if ( $rows_affected === false ) {
607
-			throw new RuntimeException( __( 'Unable to claim actions. Database error.', 'action-scheduler' ) );
605
+		$rows_affected = $wpdb->query($wpdb->prepare("{$update} {$where} {$order}", $params));
606
+		if ($rows_affected === false) {
607
+			throw new RuntimeException(__('Unable to claim actions. Database error.', 'action-scheduler'));
608 608
 		}
609 609
 
610 610
 		return (int) $rows_affected;
@@ -621,10 +621,10 @@  discard block
 block discarded – undo
621 621
 	 * @return array IDs of actions in the appropriate group and before the appropriate time.
622 622
 	 * @throws InvalidArgumentException When the group does not exist.
623 623
 	 */
624
-	protected function get_actions_by_group( $group, $limit, DateTime $date ) {
624
+	protected function get_actions_by_group($group, $limit, DateTime $date) {
625 625
 		// Ensure the group exists before continuing.
626
-		if ( ! term_exists( $group, self::GROUP_TAXONOMY )) {
627
-			throw new InvalidArgumentException( sprintf( __( 'The group "%s" does not exist.', 'action-scheduler' ), $group ) );
626
+		if (!term_exists($group, self::GROUP_TAXONOMY)) {
627
+			throw new InvalidArgumentException(sprintf(__('The group "%s" does not exist.', 'action-scheduler'), $group));
628 628
 		}
629 629
 
630 630
 		// Set up a query for post IDs to use later.
@@ -644,7 +644,7 @@  discard block
 block discarded – undo
644 644
 			),
645 645
 			'date_query'       => array(
646 646
 				'column' => 'post_date_gmt',
647
-				'before' => $date->format( 'Y-m-d H:i' ),
647
+				'before' => $date->format('Y-m-d H:i'),
648 648
 				'inclusive' => true,
649 649
 			),
650 650
 			'tax_query' => array(
@@ -657,63 +657,63 @@  discard block
 block discarded – undo
657 657
 			),
658 658
 		);
659 659
 
660
-		return $query->query( $query_args );
660
+		return $query->query($query_args);
661 661
 	}
662 662
 
663 663
 	/**
664 664
 	 * @param string $claim_id
665 665
 	 * @return array
666 666
 	 */
667
-	public function find_actions_by_claim_id( $claim_id ) {
667
+	public function find_actions_by_claim_id($claim_id) {
668 668
 		/** @var wpdb $wpdb */
669 669
 		global $wpdb;
670 670
 		$sql = "SELECT ID FROM {$wpdb->posts} WHERE post_type = %s AND post_password = %s";
671
-		$sql = $wpdb->prepare( $sql, array( self::POST_TYPE, $claim_id ) );
672
-		$action_ids = $wpdb->get_col( $sql );
671
+		$sql = $wpdb->prepare($sql, array(self::POST_TYPE, $claim_id));
672
+		$action_ids = $wpdb->get_col($sql);
673 673
 		return $action_ids;
674 674
 	}
675 675
 
676
-	public function release_claim( ActionScheduler_ActionClaim $claim ) {
677
-		$action_ids = $this->find_actions_by_claim_id( $claim->get_id() );
678
-		if ( empty( $action_ids ) ) {
676
+	public function release_claim(ActionScheduler_ActionClaim $claim) {
677
+		$action_ids = $this->find_actions_by_claim_id($claim->get_id());
678
+		if (empty($action_ids)) {
679 679
 			return; // nothing to do
680 680
 		}
681
-		$action_id_string = implode( ',', array_map( 'intval', $action_ids ) );
681
+		$action_id_string = implode(',', array_map('intval', $action_ids));
682 682
 		/** @var wpdb $wpdb */
683 683
 		global $wpdb;
684 684
 		$sql = "UPDATE {$wpdb->posts} SET post_password = '' WHERE ID IN ($action_id_string) AND post_password = %s";
685
-		$sql = $wpdb->prepare( $sql, array( $claim->get_id() ) );
686
-		$result = $wpdb->query( $sql );
687
-		if ( $result === false ) {
685
+		$sql = $wpdb->prepare($sql, array($claim->get_id()));
686
+		$result = $wpdb->query($sql);
687
+		if ($result === false) {
688 688
 			/* translators: %s: claim ID */
689
-			throw new RuntimeException( sprintf( __( 'Unable to unlock claim %s. Database error.', 'action-scheduler' ), $claim->get_id() ) );
689
+			throw new RuntimeException(sprintf(__('Unable to unlock claim %s. Database error.', 'action-scheduler'), $claim->get_id()));
690 690
 		}
691 691
 	}
692 692
 
693 693
 	/**
694 694
 	 * @param string $action_id
695 695
 	 */
696
-	public function unclaim_action( $action_id ) {
696
+	public function unclaim_action($action_id) {
697 697
 		/** @var wpdb $wpdb */
698 698
 		global $wpdb;
699 699
 		$sql = "UPDATE {$wpdb->posts} SET post_password = '' WHERE ID = %d AND post_type = %s";
700
-		$sql = $wpdb->prepare( $sql, $action_id, self::POST_TYPE );
701
-		$result = $wpdb->query( $sql );
702
-		if ( $result === false ) {
700
+		$sql = $wpdb->prepare($sql, $action_id, self::POST_TYPE);
701
+		$result = $wpdb->query($sql);
702
+		if ($result === false) {
703 703
 			/* translators: %s: action ID */
704
-			throw new RuntimeException( sprintf( __( 'Unable to unlock claim on action %s. Database error.', 'action-scheduler' ), $action_id ) );
704
+			throw new RuntimeException(sprintf(__('Unable to unlock claim on action %s. Database error.', 'action-scheduler'), $action_id));
705 705
 		}
706 706
 	}
707 707
 
708
-	public function mark_failure( $action_id ) {
708
+	public function mark_failure($action_id) {
709 709
 		/** @var wpdb $wpdb */
710 710
 		global $wpdb;
711 711
 		$sql = "UPDATE {$wpdb->posts} SET post_status = %s WHERE ID = %d AND post_type = %s";
712
-		$sql = $wpdb->prepare( $sql, self::STATUS_FAILED, $action_id, self::POST_TYPE );
713
-		$result = $wpdb->query( $sql );
714
-		if ( $result === false ) {
712
+		$sql = $wpdb->prepare($sql, self::STATUS_FAILED, $action_id, self::POST_TYPE);
713
+		$result = $wpdb->query($sql);
714
+		if ($result === false) {
715 715
 			/* translators: %s: action ID */
716
-			throw new RuntimeException( sprintf( __( 'Unable to mark failure on action %s. Database error.', 'action-scheduler' ), $action_id ) );
716
+			throw new RuntimeException(sprintf(__('Unable to mark failure on action %s. Database error.', 'action-scheduler'), $action_id));
717 717
 		}
718 718
 	}
719 719
 
@@ -723,8 +723,8 @@  discard block
 block discarded – undo
723 723
 	 * @param string $action_id
724 724
 	 * @return mixed
725 725
 	 */
726
-	public function get_claim_id( $action_id ) {
727
-		return $this->get_post_column( $action_id, 'post_password' );
726
+	public function get_claim_id($action_id) {
727
+		return $this->get_post_column($action_id, 'post_password');
728 728
 	}
729 729
 
730 730
 	/**
@@ -733,31 +733,31 @@  discard block
 block discarded – undo
733 733
 	 * @param string $action_id
734 734
 	 * @return mixed
735 735
 	 */
736
-	public function get_status( $action_id ) {
737
-		$status = $this->get_post_column( $action_id, 'post_status' );
736
+	public function get_status($action_id) {
737
+		$status = $this->get_post_column($action_id, 'post_status');
738 738
 
739
-		if ( $status === null ) {
740
-			throw new InvalidArgumentException( __( 'Invalid action ID. No status found.', 'action-scheduler' ) );
739
+		if ($status === null) {
740
+			throw new InvalidArgumentException(__('Invalid action ID. No status found.', 'action-scheduler'));
741 741
 		}
742 742
 
743
-		return $this->get_action_status_by_post_status( $status );
743
+		return $this->get_action_status_by_post_status($status);
744 744
 	}
745 745
 
746
-	private function get_post_column( $action_id, $column_name ) {
746
+	private function get_post_column($action_id, $column_name) {
747 747
 		/** @var \wpdb $wpdb */
748 748
 		global $wpdb;
749
-		return $wpdb->get_var( $wpdb->prepare( "SELECT {$column_name} FROM {$wpdb->posts} WHERE ID=%d AND post_type=%s", $action_id, self::POST_TYPE ) );
749
+		return $wpdb->get_var($wpdb->prepare("SELECT {$column_name} FROM {$wpdb->posts} WHERE ID=%d AND post_type=%s", $action_id, self::POST_TYPE));
750 750
 	}
751 751
 
752 752
 	/**
753 753
 	 * @param string $action_id
754 754
 	 */
755
-	public function log_execution( $action_id ) {
755
+	public function log_execution($action_id) {
756 756
 		/** @var wpdb $wpdb */
757 757
 		global $wpdb;
758 758
 
759 759
 		$sql = "UPDATE {$wpdb->posts} SET menu_order = menu_order+1, post_status=%s, post_modified_gmt = %s, post_modified = %s WHERE ID = %d AND post_type = %s";
760
-		$sql = $wpdb->prepare( $sql, self::STATUS_RUNNING, current_time('mysql', true), current_time('mysql'), $action_id, self::POST_TYPE );
760
+		$sql = $wpdb->prepare($sql, self::STATUS_RUNNING, current_time('mysql', true), current_time('mysql'), $action_id, self::POST_TYPE);
761 761
 		$wpdb->query($sql);
762 762
 	}
763 763
 
@@ -767,21 +767,21 @@  discard block
 block discarded – undo
767 767
 	 * @param int $action_id ID of the completed action.
768 768
 	 * @throws InvalidArgumentException|RuntimeException
769 769
 	 */
770
-	public function mark_complete( $action_id ) {
771
-		$post = get_post( $action_id );
772
-		if ( empty( $post ) || ( $post->post_type != self::POST_TYPE ) ) {
773
-			throw new InvalidArgumentException( sprintf( __( 'Unidentified action %s', 'action-scheduler' ), $action_id ) );
770
+	public function mark_complete($action_id) {
771
+		$post = get_post($action_id);
772
+		if (empty($post) || ($post->post_type != self::POST_TYPE)) {
773
+			throw new InvalidArgumentException(sprintf(__('Unidentified action %s', 'action-scheduler'), $action_id));
774 774
 		}
775
-		add_filter( 'wp_insert_post_data', array( $this, 'filter_insert_post_data' ), 10, 1 );
776
-		add_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10, 5 );
775
+		add_filter('wp_insert_post_data', array($this, 'filter_insert_post_data'), 10, 1);
776
+		add_filter('pre_wp_unique_post_slug', array($this, 'set_unique_post_slug'), 10, 5);
777 777
 		$result = wp_update_post(array(
778 778
 			'ID' => $action_id,
779 779
 			'post_status' => 'publish',
780 780
 		), TRUE);
781
-		remove_filter( 'wp_insert_post_data', array( $this, 'filter_insert_post_data' ), 10 );
782
-		remove_filter( 'pre_wp_unique_post_slug', array( $this, 'set_unique_post_slug' ), 10 );
783
-		if ( is_wp_error( $result ) ) {
784
-			throw new RuntimeException( $result->get_error_message() );
781
+		remove_filter('wp_insert_post_data', array($this, 'filter_insert_post_data'), 10);
782
+		remove_filter('pre_wp_unique_post_slug', array($this, 'set_unique_post_slug'), 10);
783
+		if (is_wp_error($result)) {
784
+			throw new RuntimeException($result->get_error_message());
785 785
 		}
786 786
 	}
787 787
 
@@ -790,7 +790,7 @@  discard block
 block discarded – undo
790 790
 	 *
791 791
 	 * @param int $action_id Action ID.
792 792
 	 */
793
-	public function mark_migrated( $action_id ) {
793
+	public function mark_migrated($action_id) {
794 794
 		wp_update_post(
795 795
 			array(
796 796
 				'ID'          => $action_id,
@@ -804,12 +804,12 @@  discard block
 block discarded – undo
804 804
 	 *
805 805
 	 * @return bool
806 806
 	 */
807
-	public function migration_dependencies_met( $setting ) {
807
+	public function migration_dependencies_met($setting) {
808 808
 		global $wpdb;
809 809
 
810
-		$dependencies_met = get_transient( self::DEPENDENCIES_MET );
811
-		if ( empty( $dependencies_met ) ) {
812
-			$maximum_args_length = apply_filters( 'action_scheduler_maximum_args_length', 191 );
810
+		$dependencies_met = get_transient(self::DEPENDENCIES_MET);
811
+		if (empty($dependencies_met)) {
812
+			$maximum_args_length = apply_filters('action_scheduler_maximum_args_length', 191);
813 813
 			$found_action        = $wpdb->get_var(
814 814
 				$wpdb->prepare(
815 815
 					"SELECT ID FROM {$wpdb->posts} WHERE post_type = %s AND CHAR_LENGTH(post_content) > %d LIMIT 1",
@@ -818,7 +818,7 @@  discard block
 block discarded – undo
818 818
 				)
819 819
 			);
820 820
 			$dependencies_met = $found_action ? 'no' : 'yes';
821
-			set_transient( self::DEPENDENCIES_MET, $dependencies_met, DAY_IN_SECONDS );
821
+			set_transient(self::DEPENDENCIES_MET, $dependencies_met, DAY_IN_SECONDS);
822 822
 		}
823 823
 
824 824
 		return 'yes' == $dependencies_met ? $setting : false;
@@ -833,12 +833,12 @@  discard block
 block discarded – undo
833 833
 	 *
834 834
 	 * @param ActionScheduler_Action $action
835 835
 	 */
836
-	protected function validate_action( ActionScheduler_Action $action ) {
836
+	protected function validate_action(ActionScheduler_Action $action) {
837 837
 		try {
838
-			parent::validate_action( $action );
839
-		} catch ( Exception $e ) {
840
-			$message = sprintf( __( '%s Support for strings longer than this will be removed in a future version.', 'action-scheduler' ), $e->getMessage() );
841
-			_doing_it_wrong( 'ActionScheduler_Action::$args', $message, '2.1.0' );
838
+			parent::validate_action($action);
839
+		} catch (Exception $e) {
840
+			$message = sprintf(__('%s Support for strings longer than this will be removed in a future version.', 'action-scheduler'), $e->getMessage());
841
+			_doing_it_wrong('ActionScheduler_Action::$args', $message, '2.1.0');
842 842
 		}
843 843
 	}
844 844
 
@@ -846,7 +846,7 @@  discard block
 block discarded – undo
846 846
 	 * @codeCoverageIgnore
847 847
 	 */
848 848
 	public function init() {
849
-		add_filter( 'action_scheduler_migration_dependencies_met', array( $this, 'migration_dependencies_met' ) );
849
+		add_filter('action_scheduler_migration_dependencies_met', array($this, 'migration_dependencies_met'));
850 850
 
851 851
 		$post_type_registrar = new ActionScheduler_wpPostStore_PostTypeRegistrar();
852 852
 		$post_type_registrar->register();
Please login to merge, or discard this patch.