PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.33.1
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.33.1
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
formidable / square / controllers / FrmSquareLiteEventsController.php

FrmSquareLiteEventsController.php in Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More 6.33.1, at square/controllers/FrmSquareLiteEventsController.php

293 lines 7.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 if ( ! defined( 'ABSPATH' ) ) {
3 die( 'You are not allowed to call this page directly.' );
4 }
5
6 class FrmSquareLiteEventsController {
7
8 /**
9 * @var string
10 */
11 public static $events_to_skip_option_name = 'frm_square_events_to_skip';
12
13 /**
14 * @var object|null
15 */
16 private $event;
17
18 /**
19 * Tell Square Connect API that the request came through by flushing early before processing.
20 * Flushing early allows the API to end the request earlier.
21 *
22 * @since 6.22
23 *
24 * @return void
25 */
26 private function flush_response() {
27 ob_start();
28
29 // Get the size of the output.
30 $size = ob_get_length();
31
32 // Disable compression (in case content length is compressed).
33 header( 'Content-Encoding: none' );
34
35 // Set the content length of the response.
36 header( 'Content-Length: ' . $size );
37
38 // Close the connection.
39 header( 'Connection: close' );
40
41 // Flush all output.
42 ob_end_flush();
43 @ob_flush();
44 flush();
45 }
46
47 /**
48 * @return void
49 */
50 public function process_events() {
51 $this->flush_response();
52
53 $unprocessed_event_ids = FrmSquareLiteConnectHelper::get_unprocessed_event_ids();
54
55 if ( $unprocessed_event_ids ) {
56 $this->process_event_ids( $unprocessed_event_ids );
57 }
58
59 wp_send_json_success();
60 }
61
62 /**
63 * @since 6.22
64 *
65 * @param array<string> $event_ids
66 *
67 * @return void
68 */
69 private function process_event_ids( $event_ids ) {
70 foreach ( $event_ids as $event_id ) {
71 if ( $this->should_skip_event( $event_id ) ) {
72 continue;
73 }
74
75 set_transient( 'frm_square_last_process_' . $event_id, time(), 60 );
76
77 $this->event = FrmSquareLiteConnectHelper::get_event( $event_id );
78
79 if ( ! is_object( $this->event ) ) {
80 $this->count_failed_event( $event_id );
81 continue;
82 }
83
84 $this->handle_event();
85 $this->track_handled_event( $event_id );
86 FrmSquareLiteConnectHelper::process_event( $event_id );
87 }
88 }
89
90 /**
91 * @since 6.22
92 *
93 * @param string $event_id
94 *
95 * @return bool True if the event should be skipped.
96 */
97 private function should_skip_event( $event_id ) {
98 if ( $this->last_attempt_to_process_event_is_too_recent( $event_id ) ) {
99 return true;
100 }
101
102 $option = get_option( self::$events_to_skip_option_name );
103
104 return is_array( $option ) && in_array( $event_id, $option, true );
105 }
106
107 /**
108 * @param string $event_id
109 *
110 * @return bool
111 */
112 private function last_attempt_to_process_event_is_too_recent( $event_id ) {
113 $last_process_attempt = get_transient( 'frm_square_last_process_' . $event_id );
114 return is_numeric( $last_process_attempt ) && $last_process_attempt > time() - 60;
115 }
116
117 /**
118 * @since 6.22
119 *
120 * @param string $event_id
121 *
122 * @return void
123 */
124 private function count_failed_event( $event_id ) {
125 $transient_name = 'frm_square_failed_event_' . $event_id;
126 $transient = get_transient( $transient_name );
127 $failed_count = is_int( $transient ) ? $transient + 1 : 1;
128 $maximum_retries = 3;
129
130 if ( $failed_count >= $maximum_retries ) {
131 $this->track_handled_event( $event_id );
132 } else {
133 set_transient( $transient_name, $failed_count, 4 * DAY_IN_SECONDS );
134 }
135 }
136
137 /**
138 * Track an event to no longer process.
139 * This is called for successful events, and also for failed events after a number of retries.
140 *
141 * @since 6.22
142 *
143 * @param string $event_id
144 *
145 * @return void
146 */
147 private function track_handled_event( $event_id ) {
148 $option = get_option( self::$events_to_skip_option_name );
149
150 if ( is_array( $option ) ) {
151 if ( count( $option ) > 1000 ) {
152 // Prevent the option from getting too big by removing the front item before adding the next.
153 array_shift( $option );
154 }
155 } else {
156 $option = array();
157 }
158
159 $option[] = $event_id;
160 update_option( self::$events_to_skip_option_name, $option, false );
161 }
162
163 /**
164 * @return void
165 */
166 private function handle_event() {
167 switch ( $this->event->type ) {
168 case 'payment.created':
169 $payment_id = $this->event->data->id;
170 $subscription = FrmSquareLiteConnectHelper::get_subscription_id_for_payment( $payment_id );
171
172 if ( is_object( $subscription ) && isset( $subscription->id ) ) {
173 $subscription_id = $subscription->id;
174 $this->add_subscription_payment( $subscription_id );
175 }
176 break;
177 case 'payment.updated':
178 $payment_id = $this->event->data->id;
179 $frm_payment = new FrmTransLitePayment();
180 $payment = $frm_payment->get_one_by( $payment_id, 'receipt_id' );
181
182 if ( $payment ) {
183 $status = $this->event->data->object->payment->status;
184
185 if ( 'COMPLETED' === $status && 'complete' !== $payment->status ) {
186 $payment_values = (array) $payment;
187 $payment_values['status'] = 'complete';
188
189 $frm_payment->update( $payment->id, $payment_values );
190
191 FrmTransLiteActionsController::trigger_payment_status_change(
192 array(
193 'status' => 'complete',
194 'payment' => $payment,
195 )
196 );
197 }
198
199 return;
200 }
201 break;
202 case 'subscription.updated':
203 $subscription_id = $this->event->data->id;
204 $frm_sub = new FrmTransLiteSubscription();
205 $sub = $frm_sub->get_one_by( $subscription_id, 'sub_id' );
206
207 if ( $sub ) {
208 $status = $this->event->data->object->subscription->status;
209
210 if ( 'DEACTIVATED' === $status ) {
211 $status = 'canceled';
212 FrmTransLiteSubscriptionsController::change_subscription_status(
213 array(
214 'status' => $status,
215 'sub' => $sub,
216 )
217 );
218 }
219 }
220 break;
221 }//end switch
222 }
223
224 /**
225 * Add a payment row for the payments table.
226 *
227 * @param string $subscription_id The Square ID for the current subscription.
228 *
229 * @return void
230 */
231 private function add_subscription_payment( $subscription_id ) {
232 $payment_id = $this->event->data->id;
233 $frm_payment = new FrmTransLitePayment();
234 $payment = $frm_payment->get_one_by( $payment_id, 'receipt_id' );
235
236 if ( $payment ) {
237 // Avoid adding the same payment twice.
238 return;
239 }
240
241 $frm_sub = new FrmTransLiteSubscription();
242 $sub = $frm_sub->get_one_by( $subscription_id, 'sub_id' );
243
244 if ( ! $sub ) {
245 return;
246 }
247
248 $payment_object = $this->event->data->object->payment;
249
250 if ( 'JPY' === $payment_object->amount_money->currency ) {
251 // Japanese does not include the additional 2 digits.
252 $amount = $payment_object->amount_money->amount;
253 } else {
254 $amount = number_format( floatval( $payment_object->amount_money->amount ) / 100, 2 );
255 }
256
257 $begin_date = gmdate( 'Y-m-d' );
258 $expire_date = '0000-00-00';
259 $subscription = FrmSquareLiteConnectHelper::get_subscription( $sub->sub_id );
260
261 if ( is_object( $subscription ) ) {
262 if ( ! empty( $subscription->start_date ) ) {
263 $begin_date = gmdate( 'Y-m-d', strtotime( $subscription->start_date ) );
264 }
265
266 if ( ! empty( $subscription->charged_through_date ) ) {
267 $expire_date = gmdate( 'Y-m-d', strtotime( $subscription->charged_through_date ) );
268
269 $frm_sub->update(
270 $sub->id,
271 array( 'next_bill_date' => gmdate( 'Y-m-d', strtotime( $expire_date ) ) )
272 );
273 }
274 }
275
276 $frm_payment = new FrmTransLitePayment();
277 $frm_payment->create(
278 array(
279 'paysys' => 'square',
280 'amount' => $amount,
281 'status' => 'authorized',
282 'item_id' => $sub->item_id,
283 'action_id' => $sub->action_id,
284 'receipt_id' => $payment_id,
285 'sub_id' => $sub->id,
286 'test' => 'test' === FrmSquareLiteAppHelper::active_mode() ? 1 : 0,
287 'begin_date' => $begin_date,
288 'expire_date' => $expire_date,
289 )
290 );
291 }
292 }
293