PluginProbe ʕ •ᴥ•ʔ
JetFormBuilder — Dynamic Blocks Form Builder / 1.5.4
JetFormBuilder — Dynamic Blocks Form Builder v1.5.4
3.6.3.1 3.6.3 3.6.2.2 3.6.2.1 3.6.2 3.6.1.1 3.6.1 3.6.0.1 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.4.1 1.4.2 1.4.3 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.1.0 2.1.1 2.1.10 2.1.11 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 3.0.0 3.0.0.1 3.0.0.2 3.0.0.3 3.0.1 3.0.1.1 3.0.2 3.0.3 3.0.4 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.0.1 3.1.1 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.3.2 3.3.3 3.3.3.1 3.3.4 3.3.4.1 3.3.4.2 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.4.5 3.4.5.1 3.4.5.2 3.4.6 3.4.7 3.4.7.1 3.5.0 3.5.1 3.5.1.1 3.5.1.2 3.5.2 3.5.2.1 3.5.3 3.5.4 3.5.5 3.5.6 3.5.6.1 3.5.6.2 3.5.6.3 3.6.0
jetformbuilder / includes / gateways / base-gateway.php
jetformbuilder / includes / gateways Last commit date
paypal 4 years ago base-gateway.php 4 years ago gateway-manager.php 4 years ago gateways-editor-data.php 4 years ago
base-gateway.php
460 lines
1 <?php
2
3
4 namespace Jet_Form_Builder\Gateways;
5
6
7 use Jet_Form_Builder\Actions\Action_Handler;
8 use Jet_Form_Builder\Admin\Tabs_Handlers\Tab_Handler_Manager;
9 use Jet_Form_Builder\Classes\Tools;
10 use Jet_Form_Builder\Exceptions\Action_Exception;
11 use Jet_Form_Builder\Exceptions\Gateway_Exception;
12 use Jet_Form_Builder\Form_Messages\Manager;
13 use Jet_Form_Builder\Form_Response\Response;
14 use Jet_Form_Builder\Form_Response\Types\Reload_Response;
15 use Jet_Form_Builder\Gateways\Gateway_Manager as GM;
16
17 /**
18 * @property Action_Handler action_handler
19 *
20 * Class Base_Gateway
21 * @package Jet_Form_Builder\Gateways
22 */
23 abstract class Base_Gateway {
24
25 const GATEWAY_META_KEY = '_jet_gateway_data';
26
27 const SUCCESS_TYPE = 'success';
28 const FAILED_TYPE = 'cancel';
29
30 protected $payment_id;
31 protected $payment_token;
32 protected $data;
33 protected $action_handler;
34 protected $order_id;
35 protected $gateways_meta;
36 protected $price_field;
37 protected $price;
38 protected $options;
39 protected $redirect;
40 protected $order_token;
41
42 protected $payment_instance = array();
43 protected $token_query_name;
44
45 protected $removed_query_args_on_payment = array(
46 GM::PAYMENT_TYPE_PARAM,
47 'order_token',
48 'status',
49 'PayerID'
50 );
51
52 /**
53 * Returns current gateway ID
54 *
55 * @return [type] [description]
56 */
57 abstract public function get_id();
58
59 /**
60 * Returns current gateway name
61 *
62 * @return [type] [description]
63 */
64 abstract public function get_name();
65
66 abstract protected function options_list();
67
68 abstract public function after_actions( Action_Handler $action_handler );
69
70 abstract protected function set_gateway_data_on_result();
71
72 abstract protected function failed_statuses();
73
74 abstract protected function retrieve_payment_instance();
75
76 abstract protected function retrieve_gateway_meta();
77
78 public function set_payment_instance() {
79 $this->payment_instance = $this->retrieve_payment_instance();
80 }
81
82 /**
83 * Store payment status into order and show success/failed message
84 * @return [type] [description]
85 */
86 public function on_success_payment() {
87 $this->set_gateway_data_on_result();
88 $this->data['date'] = date_i18n( 'F j, Y, H:i' );
89
90 $this->data['gateway'] = $this->get_name();
91
92 update_post_meta( $this->payment_id, self::GATEWAY_META_KEY, wp_json_encode( $this->data ) );
93
94 $this->try_do_actions();
95
96 $this->send_response( array(
97 'status' => $this->get_status_on_payment( $this->data['status'] ),
98 ) );
99 }
100
101 public function get_status_on_payment( $status ) {
102 if ( ! $status || in_array( $status, $this->failed_statuses() ) ) {
103 $message = Manager::dynamic_error( $this->get_meta_message( 'failed' ) );
104 } else {
105 $message = Manager::dynamic_success( $this->get_meta_message( 'success' ) );
106 }
107 $message = stripcslashes( $message );
108
109 return $message;
110 }
111
112 public function get_meta_message( $type ) {
113 if ( isset( $this->gateways_meta['messages'] ) && isset( $this->gateways_meta['messages'][ $type ] ) ) {
114 return $this->apply_macros( $this->gateways_meta['messages'][ $type ] );
115 }
116
117 return Gateway_Manager::instance()->default_messages()[ $type ];
118 }
119
120 /**
121 * Execute actions or something else when payment is success
122 *
123 * @return [type] [description]
124 */
125 protected function try_do_actions() {
126 try {
127 if ( in_array( $this->data['status'], $this->failed_statuses() ) ) {
128 $this->process_status( 'failed' );
129 } else {
130 $this->process_status( 'success' );
131 }
132 } catch ( Action_Exception $exception ) {
133 $this->send_response( array(
134 'status' => $exception->get_form_status(),
135 ) );
136 }
137 }
138
139 private function send_response( $args = array() ) {
140 ( new Response( $this->get_response_manager() ) )->init( $args )->send();
141 }
142
143 private function get_response_manager() {
144 global $wp;
145
146 return new Reload_Response( array(
147 'refer' => home_url( $wp->request ),
148 'remove_args' => $this->removed_query_args_on_payment,
149 ) );
150 }
151
152 /**
153 * Process status notification and enqueue message
154 *
155 * @param string $type [description]
156 *
157 * @return void [type] [description]
158 * @throws Action_Exception
159 */
160 public function process_status( $type = 'success' ) {
161
162 $settings = $this->gateways_meta;
163
164 $keep_these = isset( $settings[ 'notifications_' . $type ] ) ? $settings[ 'notifications_' . $type ] : array();
165
166 do_action( 'jet-form-builder/gateways/on-payment-' . $type, $this );
167
168 if ( ! empty( $keep_these ) ) {
169 $notifications = ( new Action_Handler() )->set_form_id( $this->data['form_id'] );
170 $notifications->add_request( $this->data['form_data'] );
171
172 $notifications->unregister_action( 'redirect_to_page' );
173
174 $all = $notifications->get_all();
175
176 if ( empty( $all ) ) {
177 return;
178 }
179
180 foreach ( $all as $index => $notification ) {
181 $this->maybe_unregister_action( $notifications, $index, $keep_these );
182 }
183
184 if ( empty( $notifications->form_actions ) ) {
185 return;
186 }
187
188 $notifications->run_actions();
189 }
190
191 }
192
193 final public function set_payment_token() {
194 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
195 if ( empty( $this->token_query_name ) || empty( $_GET[ $this->token_query_name ] ) ) {
196 throw new Gateway_Exception( 'Empty payment token.' );
197 }
198
199 $this->payment_token = $this->get_payment_token();
200
201 if ( empty( $this->payment_token ) ) {
202 throw new Gateway_Exception( 'Invalid payment token.' );
203 }
204
205 return $this;
206 }
207
208
209 final public function set_gateways_meta() {
210 $row_data = $this->get_form_data();
211
212 $this->payment_id = $row_data['post_id'];
213 $this->data = Tools::decode_unserializable( $row_data['meta_value'] );
214
215 return $this;
216 }
217
218 final public function set_form_gateways_meta() {
219 $data = $this->retrieve_gateway_meta();
220
221 if ( isset( $data[ $this->get_id() ]['use_global'] ) && $data[ $this->get_id() ]['use_global'] ) {
222 $data[ $this->get_id() ] = array_merge( $data[ $this->get_id() ], Tab_Handler_Manager::instance()->tab( $this->get_id() )->on_load() );
223 }
224
225 $this->gateways_meta = $data;
226
227 return $this;
228 }
229
230 final protected function set_order_token() {
231 $this->order_token = $this->query_order_token( $this->order_id, $this->action_handler->form_id );
232
233 if ( ! $this->order_token ) {
234 throw new Gateway_Exception( 'Invalid token', $this->order_token );
235 }
236 }
237
238 public function get_payment_token() {
239 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
240 return sanitize_text_field( wp_unslash( $_GET[ $this->token_query_name ] ?? '' ) );
241 }
242
243 public function get_payment_id() {
244 return absint( explode( '-', $this->payment_token )[0] );
245 }
246
247 /**
248 * Prevent unnecessary notifications processing before form is send.
249 *
250 * @param $action_handler
251 *
252 * @param $keep_these
253 *
254 * @return void [description]
255 */
256 public function before_actions( Action_Handler $action_handler, $keep_these ) {
257 if ( empty( $action_handler->get_all() ) ) {
258 return;
259 }
260 $meta = Gateway_Manager::instance()->gateways();
261
262 foreach ( $action_handler->get_all() as $index => $action ) {
263 $action_order = isset( $meta['action_order'] ) ? (int) $meta['action_order'] : 0;
264
265 if ( 'insert_post' === $action->get_id() && $action_order === $action->_id ) {
266 continue;
267 }
268
269 if ( 'redirect_to_page' === $action->get_id() ) {
270 $action_handler->unregister_action( $action->get_id() );
271 $this->redirect = $action;
272 }
273
274 if ( ! array_key_exists( $index, $keep_these ) ) {
275 $action_handler->unregister_action( $index );
276 }
277 $this->maybe_unregister_action( $action_handler, $index, $keep_these );
278 }
279 }
280
281 /**
282 * Returns form data by payment ID
283 *
284 * @param [type] $payment [description]
285 *
286 * @return [type] [description]
287 */
288 public function get_form_by_payment_token( $payment = null ) {
289
290 if ( ! $payment ) {
291 return;
292 }
293
294 global $wpdb;
295 $sql = "SELECT * FROM $wpdb->postmeta WHERE meta_key = '" . self::GATEWAY_META_KEY . "' AND meta_value LIKE '%$payment%';";
296
297 return $wpdb->get_row( $sql, ARRAY_A );
298 }
299
300 protected function set_order_id() {
301 $inserted_id = empty( $this->gateways_meta['action_order'] ) ? 0 : $this->gateways_meta['action_order'];
302 $inserted_id = $this->action_handler->get_inserted_post_id( $inserted_id );
303
304 if ( ! $inserted_id ) {
305 throw new Gateway_Exception( 'There is not inserted_post_id' );
306 }
307
308 $this->order_id = $inserted_id;
309 }
310
311
312 protected function set_price_field() {
313 if ( isset( $this->gateways_meta['price_field'] ) && ! empty( $this->gateways_meta['price_field'] ) ) {
314 $this->price_field = Tools::sanitize_text_field( $this->gateways_meta['price_field'] );
315 }
316
317 $this->price_field = apply_filters( 'jet-form-builder/gateways/price-field', $this->price_field, $this->action_handler );
318
319 if ( ! $this->price_field ) {
320 throw new Gateway_Exception( 'Invalid price field' );
321 }
322 }
323
324 protected function set_price_from_filed() {
325 if ( isset( $this->action_handler->request_data[ $this->price_field ] ) ) {
326 $this->price = $this->get_price( $this->action_handler->request_data[ $this->price_field ] );
327 }
328
329 if ( ! $this->price ) {
330 throw new Gateway_Exception( 'Empty price field' );
331 }
332 }
333
334 /**
335 * @throws Gateway_Exception
336 */
337 protected function set_current_gateway_options() {
338 $gateway = $this->gateways_meta[ $this->get_id() ];
339
340 foreach ( $this->options_list() as $name => $option ) {
341 $is_required = isset( $option['required'] )
342 ? filter_var( $option['required'], FILTER_VALIDATE_BOOLEAN )
343 : true;
344
345 if ( $is_required && ( ! isset( $gateway[ $name ] ) || empty( $gateway[ $name ] ) ) ) {
346 throw new Gateway_Exception( 'Invalid gateway options', $name );
347 }
348 $this->options[ $name ] = sanitize_text_field( $gateway[ $name ] );
349 }
350 }
351
352 protected function set_gateway_data( Action_Handler $action_handler ) {
353 $this->gateways_meta = GM::instance()->gateways();
354 $this->action_handler = $action_handler;
355
356 try {
357 $this->set_order_id();
358 $this->set_price_field();
359 $this->set_price_from_filed();
360 $this->set_current_gateway_options();
361 $this->set_order_token();
362
363 } catch ( Gateway_Exception $exception ) {
364 return false;
365 }
366
367 return true;
368 }
369
370 protected function get_price( $price ) {
371 return (float) $price;
372 }
373
374 protected function get_refer_url( $type, array $additional_args = array() ) {
375
376 $success_redirect = ! empty( $this->gateways_meta['use_success_redirect'] ) ? $this->gateways_meta['use_success_redirect'] : false;
377 $success_redirect = filter_var( $success_redirect, FILTER_VALIDATE_BOOLEAN );
378 $refer = $this->action_handler->request_data['__refer'];
379
380 if ( $success_redirect && $this->redirect && 'success' === $type ) {
381 $settings = $this->redirect->settings;
382
383 $type = ! empty( $settings['redirect_type'] ) ? $settings['redirect_type'] : 'static_page';
384
385 if ( 'static_page' === $type ) {
386 $to_page = ! empty( $settings['redirect_page'] ) ? $settings['redirect_page'] : false;
387 $refer = ! empty( $to_page ) ? get_permalink( $to_page ) : false;
388 } else {
389 $refer = ! empty( $settings['redirect_url'] ) ? $settings['redirect_url'] : false;
390 }
391 }
392
393 return add_query_arg(
394 array_merge(
395 array( GM::PAYMENT_TYPE_PARAM => $this->get_id() ),
396 $additional_args
397 ),
398 $refer
399 );
400 }
401
402 abstract protected function query_order_token( $order_id, $form_id );
403
404 protected function get_form_data() {
405 return $this->get_form_by_payment_token( $this->payment_token );
406 }
407
408 public function options( $param = false ) {
409 $labels = array();
410
411 if ( ! $param ) {
412 return $this->options_list();
413 }
414 foreach ( $this->options_list() as $name => $option ) {
415 $labels[ $name ] = $option[ $param ];
416 }
417
418 return $labels;
419 }
420
421 /**
422 * Apply macros in string
423 *
424 * @return [type] [description]
425 */
426 public function apply_macros( $string = null ) {
427
428 return preg_replace_callback( '/%(.*?)%/', function ( $matches ) {
429 switch ( $matches[1] ) {
430 case 'gateway_amount':
431 $amount = ! empty( $this->data['amount'] ) ? $this->data['amount'] : false;
432
433 return ! empty( $amount ) ? $amount['value'] . ' ' . $amount['currency_code'] : 0;
434
435 case 'gateway_status':
436 return ! empty( $this->data['status'] ) ? $this->data['status'] : '';
437
438 default:
439 $form_data = ! empty( $this->data['form_data'] ) ? $this->data['form_data'] : array();
440
441 return ! empty( $form_data[ $matches[1] ] ) ? $form_data[ $matches[1] ] : '';
442 }
443
444 }, $string );
445 }
446
447 private function maybe_unregister_action( Action_Handler $handler, $index, $keep_these ) {
448 if ( ! array_key_exists( $index, $keep_these )
449 || ! isset( $keep_these[ $index ]['active'] )
450 || ! $keep_these[ $index ]['active']
451 ) {
452 $handler->unregister_action( $index );
453 }
454 }
455
456 public function property( $prop ) {
457 return $this->$prop;
458 }
459
460 }