PluginProbe ʕ •ᴥ•ʔ
OttoKit: All-in-One Automation Platform / 1.0.73
OttoKit: All-in-One Automation Platform v1.0.73
1.1.31 1.1.30 1.1.29 1.1.28 1.1.27 1.1.9 trunk 1.0.10 1.0.11 1.0.12 1.0.13 1.0.14 1.0.15 1.0.16 1.0.17 1.0.18 1.0.19 1.0.20 1.0.21 1.0.22 1.0.23 1.0.24 1.0.25 1.0.26 1.0.27 1.0.28 1.0.29 1.0.30 1.0.31 1.0.32 1.0.33 1.0.34 1.0.35 1.0.36 1.0.37 1.0.38 1.0.39 1.0.40 1.0.41 1.0.42 1.0.43 1.0.44 1.0.45 1.0.46 1.0.47 1.0.48 1.0.49 1.0.50 1.0.51 1.0.52 1.0.53 1.0.54 1.0.55 1.0.56 1.0.57 1.0.58 1.0.59 1.0.60 1.0.61 1.0.62 1.0.63 1.0.64 1.0.65 1.0.66 1.0.67 1.0.68 1.0.69 1.0.7 1.0.70 1.0.71 1.0.72 1.0.73 1.0.74 1.0.75 1.0.76 1.0.77 1.0.78 1.0.79 1.0.8 1.0.80 1.0.81 1.0.82 1.0.83 1.0.84 1.0.85 1.0.86 1.0.87 1.0.88 1.0.89 1.0.9 1.0.90 1.1.0 1.1.1 1.1.10 1.1.11 1.1.12 1.1.13 1.1.14 1.1.15 1.1.16 1.1.17 1.1.18 1.1.19 1.1.2 1.1.20 1.1.21 1.1.22 1.1.23 1.1.24 1.1.25 1.1.26 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8
suretriggers / src / Controllers / WebhookRequestsController.php
suretriggers / src / Controllers Last commit date
AuthController.php 1 year ago AutomationController.php 3 years ago EventController.php 3 years ago GlobalSearchController.php 1 year ago IntegrationsController.php 2 years ago OptionController.php 3 years ago RestController.php 1 year ago RoutesController.php 3 years ago SettingsController.php 3 years ago WebhookRequestsController.php 1 year ago
WebhookRequestsController.php
301 lines
1 <?php
2 /**
3 * WebhookRequestsController.
4 * php version 5.6
5 *
6 * @category WebhookRequestsController
7 * @package SureTriggers
8 * @author BSF <username@example.com>
9 * @license https://www.gnu.org/licenses/gpl-3.0.html GPLv3
10 * @link https://www.brainstormforce.com/
11 * @since 1.0.0
12 */
13
14 namespace SureTriggers\Controllers;
15
16 use SureTriggers\Traits\SingletonLoader;
17 use SureTriggers\Models\SaasApiToken;
18
19 /**
20 * WebhookRequestsController- Store Webhook requests and retry for failed.
21 *
22 * @category WebhookRequestsController
23 * @package SureTriggers
24 * @author BSF <username@example.com>
25 * @license https://www.gnu.org/licenses/gpl-3.0.html GPLv3
26 * @link https://www.brainstormforce.com/
27 * @since 1.0.0
28 *
29 * @psalm-suppress UndefinedTrait
30 */
31 class WebhookRequestsController {
32
33 use SingletonLoader;
34
35 /**
36 * Webhook Requests Table name.
37 *
38 * @var string
39 */
40 protected static $name = 'suretriggers_webhook_requests';
41
42 /**
43 * Initialise data.
44 */
45 public function __construct() {
46 add_action( 'suretriggers_retry_failed_requests', [ $this, 'suretriggers_retry_failed_trigger_requests' ] );
47 add_action( 'suretriggers_webhook_requests_cleanup_logs', [ $this, 'suretriggers_cleanup_requests_logs' ] );
48 add_filter( 'cron_schedules', [ $this, 'suretriggers_custom_cron_schedule' ] );
49 }
50
51 /**
52 * Get the table name.
53 *
54 * @return string
55 */
56 public static function get_table_name() {
57 global $wpdb;
58 return $wpdb->prefix . self::$name;
59 }
60
61 /**
62 * Adds a custom cron schedule for every 30 minutes.
63 *
64 * @param array $schedules An array of non-default cron schedules.
65 * @return array Filtered array of non-default cron schedules.
66 */
67 public static function suretriggers_custom_cron_schedule( $schedules ) {
68 $schedules['suretriggers_retry_cron_schedule'] = [
69 'interval' => 30 * MINUTE_IN_SECONDS,
70 'display' => __( 'Every 30 minutes', 'suretriggers' ),
71 ];
72 return $schedules;
73 }
74
75 /**
76 * Custom table for storing of webhook requests logs.
77 *
78 * @return void
79 */
80 public static function suretriggers_webhook_request_log_table() {
81 global $wpdb;
82 $table_name = self::get_table_name();
83 $charset_collate = $wpdb->get_charset_collate();
84
85 $sql = "CREATE TABLE $table_name (
86 id mediumint(9) NOT NULL AUTO_INCREMENT,
87 request_method varchar(255) NULL,
88 request_url varchar(255) NOT NULL,
89 request_data longtext NOT NULL,
90 response_code int(3) NOT NULL,
91 status varchar(20) NOT NULL,
92 error_info varchar(255) NOT NULL,
93 retry_attempts int(3) DEFAULT 0,
94 processed_at datetime NULL,
95 created_at datetime,
96 updated_at datetime ON UPDATE CURRENT_TIMESTAMP,
97 PRIMARY KEY (id)
98 ) $charset_collate;";
99
100 require_once ABSPATH . 'wp-admin/includes/upgrade.php';
101 dbDelta( $sql );
102 }
103
104 /**
105 * Setup cron to retry failed webhook requests and cleanup logs for Triggers.
106 *
107 * @return void
108 */
109 public static function suretriggers_setup_custom_cron() {
110 // Retry failed requests.
111 if ( ! wp_next_scheduled( 'suretriggers_retry_failed_requests' ) ) {
112 wp_schedule_event( time(), 'suretriggers_retry_cron_schedule', 'suretriggers_retry_failed_requests' );
113 }
114
115 // Clean up log requests that are older than 15 days.
116 if ( ! wp_next_scheduled( 'suretriggers_webhook_requests_cleanup_logs' ) ) {
117 wp_schedule_event( time(), 'daily', 'suretriggers_webhook_requests_cleanup_logs' );
118 }
119 }
120
121 /**
122 * Log Request handler.
123 *
124 * @param string $data Request data.
125 * @param int $response_code Response Code.
126 * @param string $error_info Error Info.
127 *
128 * @return void
129 */
130 public static function suretriggers_log_request( $data, $response_code, $error_info ) {
131 global $wpdb;
132 // Store the data in request logs.
133 $wpdb->insert(
134 self::get_table_name(),
135 [
136 'request_method' => 'POST',
137 'request_url' => SURE_TRIGGERS_WEBHOOK_SERVER_URL . '/wordpress/webhook',
138 'request_data' => $data,
139 'response_code' => $response_code,
140 'status' => ( 200 === $response_code ) ? 'success' : 'failed',
141 'error_info' => $error_info,
142 'retry_attempts' => 0,
143 'processed_at' => null,
144 'created_at' => current_time( 'mysql' ),
145 'updated_at' => current_time( 'mysql' ),
146 ]
147 );
148 }
149
150 /**
151 * Update Failed Webhook Request handler via cron.
152 *
153 * @return void
154 */
155 public static function suretriggers_retry_failed_trigger_requests() {
156 global $wpdb;
157 $table_name = self::get_table_name();
158
159 // Select all failed requests that haven't exceeded retry attempts.
160 $failed_requests = $wpdb->get_results(
161 $wpdb->prepare(
162 "SELECT * FROM {$table_name} WHERE status = %s AND retry_attempts < %d", //phpcs:ignore
163 'failed',
164 5
165 ),
166 ARRAY_A
167 );
168
169 foreach ( $failed_requests as $request ) {
170 $data = json_decode( $request['request_data'], true );
171 if ( is_array( $data ) ) {
172 $data['headers']['Authorization'] = 'Bearer ' . SaasApiToken::get();
173 $response = wp_remote_post( $request['request_url'], $data );
174 $response_code = wp_remote_retrieve_response_code( $response );
175 $error_info = wp_remote_retrieve_body( $response );
176 if ( 405 === $response_code ) {
177 $error_info = wp_remote_retrieve_response_message( $response );
178 }
179 if ( 0 === $response_code ) {
180 $error_info = __( 'Service not available', 'suretriggers' );
181 }
182 // Update the request if failed with the new response.
183 $wpdb->update(
184 $table_name,
185 [
186 'request_method' => $request['request_method'],
187 'request_url' => $request['request_url'],
188 'request_data' => $request['request_data'],
189 'response_code' => $response_code,
190 'status' => ( 200 === $response_code ) ? 'success' : 'failed',
191 'error_info' => $error_info,
192 'retry_attempts' => $request['retry_attempts'] + 1,
193 'processed_at' => current_time( 'mysql' ),
194 'updated_at' => current_time( 'mysql' ),
195 ],
196 [ 'id' => $request['id'] ]
197 );
198 }
199 }
200 }
201
202 /**
203 * Update Failed Webhook Request handler via Retry button.
204 *
205 * @param int $id ID.
206 *
207 * @return bool
208 */
209 public static function suretriggers_retry_trigger_request( $id ) {
210 global $wpdb;
211 $table_name = self::get_table_name();
212 $failed_requests = $wpdb->get_row(
213 $wpdb->prepare(
214 "SELECT * FROM {$table_name} WHERE id = %d", //phpcs:ignore
215 $id
216 ),
217 ARRAY_A
218 );
219
220 $data = json_decode( $failed_requests['request_data'], true );
221 if ( is_array( $data ) ) {
222 $data['headers']['Authorization'] = 'Bearer ' . SaasApiToken::get();
223 $response = wp_remote_post( $failed_requests['request_url'], $data );
224 $response_code = wp_remote_retrieve_response_code( $response );
225 $error_info = wp_remote_retrieve_body( $response );
226 if ( 405 === wp_remote_retrieve_response_code( $response ) ) {
227 $error_info = wp_remote_retrieve_response_message( $response );
228 }
229 if ( 0 === wp_remote_retrieve_response_code( $response ) ) {
230 $error_info = __( 'Service not available', 'suretriggers' );
231 }
232 $wpdb->update(
233 $table_name,
234 [
235 'request_method' => $failed_requests['request_method'],
236 'request_url' => $failed_requests['request_url'],
237 'request_data' => $failed_requests['request_data'],
238 'response_code' => $response_code,
239 'status' => ( 200 === $response_code ) ? 'success' : 'failed',
240 'error_info' => $error_info,
241 'retry_attempts' => $failed_requests['retry_attempts'] + 1,
242 'processed_at' => current_time( 'mysql' ),
243 'updated_at' => current_time( 'mysql' ),
244 ],
245 [ 'id' => $id ]
246 );
247 return true;
248 }
249 return false;
250 }
251
252 /**
253 * Delete failed webhook requests log that are 15 days older.
254 * Delete success webhook requests log that are 3 days older.
255 *
256 * @return void
257 */
258 public static function suretriggers_cleanup_requests_logs() {
259 global $wpdb;
260 $table_name = self::get_table_name();
261 $wpdb->query( $wpdb->prepare( "DELETE FROM {$table_name} WHERE status = %s AND created_at < NOW() - INTERVAL %d DAY", 'failed', 15 ) ); //phpcs:ignore
262 $wpdb->query( $wpdb->prepare( "DELETE FROM {$table_name} WHERE status = %s AND created_at < NOW() - INTERVAL %d DAY", 'success', 3 ) ); //phpcs:ignore
263 }
264
265 /**
266 * Unschedule the event on plugin deletion.
267 *
268 * @return void
269 */
270 public static function suretriggers_remove_table_retry_cron() {
271 // Clear custom scheduled cron created.
272 wp_clear_scheduled_hook( 'suretriggers_retry_cron_schedule' );
273
274 // Remove retry cron schedule on plugin deletion.
275 $retry_failed_requests = wp_next_scheduled( 'suretriggers_retry_failed_requests' );
276 if ( $retry_failed_requests ) {
277 wp_unschedule_event( $retry_failed_requests, 'suretriggers_retry_failed_requests' );
278 }
279
280 // Remove clean up cron schedule.
281 $webhook_requests_cleanup = wp_next_scheduled( 'suretriggers_webhook_requests_cleanup_logs' );
282 if ( $webhook_requests_cleanup ) {
283 wp_unschedule_event( $webhook_requests_cleanup, 'suretriggers_webhook_requests_cleanup_logs' );
284 }
285
286 // Delete table on plugin delete.
287 global $wpdb;
288 $table_name = self::get_table_name();
289 // Drop the custom table.
290 $table_exists = $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table_name ) );
291 if ( $table_exists ) {
292 require_once ABSPATH . 'wp-admin/includes/upgrade.php';
293 $sql = "DROP TABLE IF EXISTS $table_name";
294 dbDelta( $sql );
295 }
296 }
297
298 }
299
300 WebhookRequestsController::get_instance();
301