PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.26.1
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.26.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.26.1, at square/controllers/FrmSquareLiteEventsController.php

301 lines 7.4 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 wp_send_json_success();
59 }
60
61 /**
62 * @since 6.22
63 *
64 * @param array<string> $event_ids
65 *
66 * @return void
67 */
68 private function process_event_ids( $event_ids ) {
69 foreach ( $event_ids as $event_id ) {
70 if ( $this->should_skip_event( $event_id ) ) {
71 continue;
72 }
73
74 set_transient( 'frm_square_last_process_' . $event_id, time(), 60 );
75
76 $this->event = FrmSquareLiteConnectHelper::get_event( $event_id );
77
78 if ( is_object( $this->event ) ) {
79 $this->handle_event();
80 $this->track_handled_event( $event_id );
81 FrmSquareLiteConnectHelper::process_event( $event_id );
82 } else {
83 $this->count_failed_event( $event_id );
84 }
85 }
86 }
87
88 /**
89 * @since 6.22
90 *
91 * @param string $event_id
92 *
93 * @return bool True if the event should be skipped.
94 */
95 private function should_skip_event( $event_id ) {
96 if ( $this->last_attempt_to_process_event_is_too_recent( $event_id ) ) {
97 return true;
98 }
99
100 $option = get_option( self::$events_to_skip_option_name );
101
102 if ( ! is_array( $option ) ) {
103 return false;
104 }
105
106 return in_array( $event_id, $option, true );
107 }
108
109 /**
110 * @param string $event_id
111 *
112 * @return bool
113 */
114 private function last_attempt_to_process_event_is_too_recent( $event_id ) {
115 $last_process_attempt = get_transient( 'frm_square_last_process_' . $event_id );
116 return is_numeric( $last_process_attempt ) && $last_process_attempt > time() - 60;
117 }
118
119 /**
120 * @since 6.22
121 *
122 * @param string $event_id
123 *
124 * @return void
125 */
126 private function count_failed_event( $event_id ) {
127 $transient_name = 'frm_square_failed_event_' . $event_id;
128 $transient = get_transient( $transient_name );
129
130 if ( is_int( $transient ) ) {
131 $failed_count = $transient + 1;
132 } else {
133 $failed_count = 1;
134 }
135
136 $maximum_retries = 3;
137
138 if ( $failed_count >= $maximum_retries ) {
139 $this->track_handled_event( $event_id );
140 } else {
141 set_transient( $transient_name, $failed_count, 4 * DAY_IN_SECONDS );
142 }
143 }
144
145 /**
146 * Track an event to no longer process.
147 * This is called for successful events, and also for failed events after a number of retries.
148 *
149 * @since 6.22
150 *
151 * @param string $event_id
152 *
153 * @return void
154 */
155 private function track_handled_event( $event_id ) {
156 $option = get_option( self::$events_to_skip_option_name );
157
158 if ( is_array( $option ) ) {
159 if ( count( $option ) > 1000 ) {
160 // Prevent the option from getting too big by removing the front item before adding the next.
161 array_shift( $option );
162 }
163 } else {
164 $option = array();
165 }
166
167 $option[] = $event_id;
168 update_option( self::$events_to_skip_option_name, $option, false );
169 }
170
171 /**
172 * @return void
173 */
174 private function handle_event() {
175 switch ( $this->event->type ) {
176 case 'payment.created':
177 $payment_id = $this->event->data->id;
178 $subscription = FrmSquareLiteConnectHelper::get_subscription_id_for_payment( $payment_id );
179
180 if ( is_object( $subscription ) && isset( $subscription->id ) ) {
181 $subscription_id = $subscription->id;
182 $this->add_subscription_payment( $subscription_id );
183 }
184 break;
185 case 'payment.updated':
186 $payment_id = $this->event->data->id;
187 $frm_payment = new FrmTransLitePayment();
188 $payment = $frm_payment->get_one_by( $payment_id, 'receipt_id' );
189
190 if ( $payment ) {
191 $status = $this->event->data->object->payment->status;
192
193 if ( 'COMPLETED' === $status && 'complete' !== $payment->status ) {
194 $payment_values = (array) $payment;
195 $payment_values['status'] = 'complete';
196
197 $frm_payment->update( $payment->id, $payment_values );
198
199 FrmTransLiteActionsController::trigger_payment_status_change(
200 array(
201 'status' => 'complete',
202 'payment' => $payment,
203 )
204 );
205 }
206 return;
207 }
208 break;
209 case 'subscription.updated':
210 $subscription_id = $this->event->data->id;
211 $frm_sub = new FrmTransLiteSubscription();
212 $sub = $frm_sub->get_one_by( $subscription_id, 'sub_id' );
213
214 if ( $sub ) {
215 $status = $this->event->data->object->subscription->status;
216
217 if ( 'DEACTIVATED' === $status ) {
218 $status = 'canceled';
219 FrmTransLiteSubscriptionsController::change_subscription_status(
220 array(
221 'status' => $status,
222 'sub' => $sub,
223 )
224 );
225 }
226 }
227 break;
228 }//end switch
229 }
230
231 /**
232 * Add a payment row for the payments table.
233 *
234 * @param string $subscription_id The Square ID for the current subscription.
235 *
236 * @return void
237 */
238 private function add_subscription_payment( $subscription_id ) {
239 $payment_id = $this->event->data->id;
240
241 $frm_payment = new FrmTransLitePayment();
242 $payment = $frm_payment->get_one_by( $payment_id, 'receipt_id' );
243
244 if ( $payment ) {
245 // Avoid adding the same payment twice.
246 return;
247 }
248
249 $frm_sub = new FrmTransLiteSubscription();
250 $sub = $frm_sub->get_one_by( $subscription_id, 'sub_id' );
251
252 if ( ! $sub ) {
253 return;
254 }
255
256 $payment_object = $this->event->data->object->payment;
257
258 if ( 'JPY' === $payment_object->amount_money->currency ) {
259 // Japanese does not include the additional 2 digits.
260 $amount = $payment_object->amount_money->amount;
261 } else {
262 $amount = number_format( floatval( $payment_object->amount_money->amount ) / 100, 2 );
263 }
264
265 $begin_date = gmdate( 'Y-m-d' );
266 $expire_date = '0000-00-00';
267 $subscription = FrmSquareLiteConnectHelper::get_subscription( $sub->sub_id );
268
269 if ( is_object( $subscription ) ) {
270 if ( ! empty( $subscription->start_date ) ) {
271 $begin_date = gmdate( 'Y-m-d', strtotime( $subscription->start_date ) );
272 }
273
274 if ( ! empty( $subscription->charged_through_date ) ) {
275 $expire_date = gmdate( 'Y-m-d', strtotime( $subscription->charged_through_date ) );
276
277 $frm_sub->update(
278 $sub->id,
279 array( 'next_bill_date' => gmdate( 'Y-m-d', strtotime( $expire_date ) ) )
280 );
281 }
282 }
283
284 $frm_payment = new FrmTransLitePayment();
285 $frm_payment->create(
286 array(
287 'paysys' => 'square',
288 'amount' => $amount,
289 'status' => 'authorized',
290 'item_id' => $sub->item_id,
291 'action_id' => $sub->action_id,
292 'receipt_id' => $payment_id,
293 'sub_id' => $sub->id,
294 'test' => 'test' === FrmSquareLiteAppHelper::active_mode() ? 1 : 0,
295 'begin_date' => $begin_date,
296 'expire_date' => $expire_date,
297 )
298 );
299 }
300 }
301