@@ -133,7 +133,7 @@ discard block |
||
133 | 133 | $this->request = EED_Single_Page_Checkout::getRequest(); |
134 | 134 | $this->_slug = 'payment_options'; |
135 | 135 | $this->_name = esc_html__('Payment Options', 'event_espresso'); |
136 | - $this->_template = SPCO_REG_STEPS_PATH . $this->_slug . '/payment_options_main.template.php'; |
|
136 | + $this->_template = SPCO_REG_STEPS_PATH.$this->_slug.'/payment_options_main.template.php'; |
|
137 | 137 | $this->checkout = $checkout; |
138 | 138 | $this->_reset_success_message(); |
139 | 139 | $this->set_instructions( |
@@ -188,7 +188,7 @@ discard block |
||
188 | 188 | */ |
189 | 189 | public function translate_js_strings() |
190 | 190 | { |
191 | - EE_Registry::$i18n_js_strings['no_payment_method'] = esc_html__( |
|
191 | + EE_Registry::$i18n_js_strings['no_payment_method'] = esc_html__( |
|
192 | 192 | 'Please select a method of payment in order to continue.', |
193 | 193 | 'event_espresso' |
194 | 194 | ); |
@@ -196,7 +196,7 @@ discard block |
||
196 | 196 | 'A valid method of payment could not be determined. Please refresh the page and try again.', |
197 | 197 | 'event_espresso' |
198 | 198 | ); |
199 | - EE_Registry::$i18n_js_strings['forwarding_to_offsite'] = esc_html__( |
|
199 | + EE_Registry::$i18n_js_strings['forwarding_to_offsite'] = esc_html__( |
|
200 | 200 | 'Forwarding to Secure Payment Provider.', |
201 | 201 | 'event_espresso' |
202 | 202 | ); |
@@ -217,7 +217,7 @@ discard block |
||
217 | 217 | { |
218 | 218 | $transaction = $this->checkout->transaction; |
219 | 219 | // if the transaction isn't set or nothing is owed on it, don't enqueue any JS |
220 | - if (! $transaction instanceof EE_Transaction || EEH_Money::compare_floats($transaction->remaining(), 0)) { |
|
220 | + if ( ! $transaction instanceof EE_Transaction || EEH_Money::compare_floats($transaction->remaining(), 0)) { |
|
221 | 221 | return; |
222 | 222 | } |
223 | 223 | foreach ( |
@@ -312,18 +312,18 @@ discard block |
||
312 | 312 | foreach ($registrations as $REG_ID => $registration) { |
313 | 313 | /** @var $registration EE_Registration */ |
314 | 314 | // has this registration lost it's space ? |
315 | - if (isset($ejected_registrations[ $REG_ID ])) { |
|
315 | + if (isset($ejected_registrations[$REG_ID])) { |
|
316 | 316 | if ($registration->event()->is_sold_out() || $registration->event()->is_sold_out(true)) { |
317 | - $sold_out_events[ $registration->event()->ID() ] = $registration->event(); |
|
317 | + $sold_out_events[$registration->event()->ID()] = $registration->event(); |
|
318 | 318 | } else { |
319 | - $insufficient_spaces_available[ $registration->event()->ID() ] = $registration->event(); |
|
319 | + $insufficient_spaces_available[$registration->event()->ID()] = $registration->event(); |
|
320 | 320 | } |
321 | 321 | continue; |
322 | 322 | } |
323 | 323 | // event requires admin approval |
324 | 324 | if ($registration->status_ID() === EEM_Registration::status_id_not_approved) { |
325 | 325 | // add event to list of events with pre-approval reg status |
326 | - $registrations_requiring_pre_approval[ $REG_ID ] = $registration; |
|
326 | + $registrations_requiring_pre_approval[$REG_ID] = $registration; |
|
327 | 327 | do_action( |
328 | 328 | 'AHEE__EE_SPCO_Reg_Step_Payment_Options__generate_reg_form__event_requires_pre_approval', |
329 | 329 | $registration->event(), |
@@ -340,7 +340,7 @@ discard block |
||
340 | 340 | ) |
341 | 341 | ) { |
342 | 342 | // add event to list of events that are sold out |
343 | - $sold_out_events[ $registration->event()->ID() ] = $registration->event(); |
|
343 | + $sold_out_events[$registration->event()->ID()] = $registration->event(); |
|
344 | 344 | do_action( |
345 | 345 | 'AHEE__EE_SPCO_Reg_Step_Payment_Options__generate_reg_form__sold_out_event', |
346 | 346 | $registration->event(), |
@@ -350,7 +350,7 @@ discard block |
||
350 | 350 | } |
351 | 351 | // are they allowed to pay now and is there monies owing? |
352 | 352 | if ($registration->owes_monies_and_can_pay()) { |
353 | - $registrations_requiring_payment[ $REG_ID ] = $registration; |
|
353 | + $registrations_requiring_payment[$REG_ID] = $registration; |
|
354 | 354 | do_action( |
355 | 355 | 'AHEE__EE_SPCO_Reg_Step_Payment_Options__generate_reg_form__event_requires_payment', |
356 | 356 | $registration->event(), |
@@ -361,28 +361,28 @@ discard block |
||
361 | 361 | && $registration->status_ID() !== EEM_Registration::status_id_not_approved |
362 | 362 | && $registration->ticket()->is_free() |
363 | 363 | ) { |
364 | - $registrations_for_free_events[ $registration->ticket()->ID() ] = $registration; |
|
364 | + $registrations_for_free_events[$registration->ticket()->ID()] = $registration; |
|
365 | 365 | } |
366 | 366 | } |
367 | 367 | $subsections = []; |
368 | 368 | // now decide which template to load |
369 | - if (! empty($sold_out_events)) { |
|
369 | + if ( ! empty($sold_out_events)) { |
|
370 | 370 | $subsections['sold_out_events'] = $this->_sold_out_events($sold_out_events); |
371 | 371 | } |
372 | - if (! empty($insufficient_spaces_available)) { |
|
372 | + if ( ! empty($insufficient_spaces_available)) { |
|
373 | 373 | $subsections['insufficient_space'] = $this->_insufficient_spaces_available( |
374 | 374 | $insufficient_spaces_available |
375 | 375 | ); |
376 | 376 | } |
377 | - if (! empty($registrations_requiring_pre_approval)) { |
|
377 | + if ( ! empty($registrations_requiring_pre_approval)) { |
|
378 | 378 | $subsections['registrations_requiring_pre_approval'] = $this->_registrations_requiring_pre_approval( |
379 | 379 | $registrations_requiring_pre_approval |
380 | 380 | ); |
381 | 381 | } |
382 | - if (! empty($registrations_for_free_events)) { |
|
382 | + if ( ! empty($registrations_for_free_events)) { |
|
383 | 383 | $subsections['no_payment_required'] = $this->_no_payment_required($registrations_for_free_events); |
384 | 384 | } |
385 | - if (! empty($registrations_requiring_payment)) { |
|
385 | + if ( ! empty($registrations_requiring_payment)) { |
|
386 | 386 | if ($this->checkout->amount_owing > 0) { |
387 | 387 | // autoload Line_Item_Display classes |
388 | 388 | EEH_Autoloader::register_line_item_filter_autoloaders(); |
@@ -403,7 +403,7 @@ discard block |
||
403 | 403 | ['registrations' => $registrations] |
404 | 404 | ) |
405 | 405 | ); |
406 | - $this->checkout->amount_owing = $filtered_line_item_tree->total(); |
|
406 | + $this->checkout->amount_owing = $filtered_line_item_tree->total(); |
|
407 | 407 | $this->_apply_registration_payments_to_amount_owing($registrations); |
408 | 408 | } |
409 | 409 | $no_payment_required = false; |
@@ -447,13 +447,13 @@ discard block |
||
447 | 447 | */ |
448 | 448 | public static function add_spco_line_item_filters(EE_Line_Item_Filter_Collection $line_item_filter_collection) |
449 | 449 | { |
450 | - if (! EE_Registry::instance()->SSN instanceof EE_Session) { |
|
450 | + if ( ! EE_Registry::instance()->SSN instanceof EE_Session) { |
|
451 | 451 | return $line_item_filter_collection; |
452 | 452 | } |
453 | - if (! EE_Registry::instance()->SSN->checkout() instanceof EE_Checkout) { |
|
453 | + if ( ! EE_Registry::instance()->SSN->checkout() instanceof EE_Checkout) { |
|
454 | 454 | return $line_item_filter_collection; |
455 | 455 | } |
456 | - if (! EE_Registry::instance()->SSN->checkout()->transaction instanceof EE_Transaction) { |
|
456 | + if ( ! EE_Registry::instance()->SSN->checkout()->transaction instanceof EE_Transaction) { |
|
457 | 457 | return $line_item_filter_collection; |
458 | 458 | } |
459 | 459 | $line_item_filter_collection->add( |
@@ -493,8 +493,8 @@ discard block |
||
493 | 493 | ); |
494 | 494 | foreach ($registrations as $REG_ID => $registration) { |
495 | 495 | // has this registration lost it's space ? |
496 | - if (isset($ejected_registrations[ $REG_ID ])) { |
|
497 | - unset($registrations[ $REG_ID ]); |
|
496 | + if (isset($ejected_registrations[$REG_ID])) { |
|
497 | + unset($registrations[$REG_ID]); |
|
498 | 498 | } |
499 | 499 | } |
500 | 500 | return $registrations; |
@@ -544,25 +544,25 @@ discard block |
||
544 | 544 | } |
545 | 545 | $EVT_ID = $registration->event_ID(); |
546 | 546 | $ticket = $registration->ticket(); |
547 | - if (! isset($tickets_remaining[ $ticket->ID() ])) { |
|
548 | - $tickets_remaining[ $ticket->ID() ] = $ticket->remaining(); |
|
547 | + if ( ! isset($tickets_remaining[$ticket->ID()])) { |
|
548 | + $tickets_remaining[$ticket->ID()] = $ticket->remaining(); |
|
549 | 549 | } |
550 | - if ($tickets_remaining[ $ticket->ID() ] > 0) { |
|
551 | - if (! isset($event_reg_count[ $EVT_ID ])) { |
|
552 | - $event_reg_count[ $EVT_ID ] = 0; |
|
550 | + if ($tickets_remaining[$ticket->ID()] > 0) { |
|
551 | + if ( ! isset($event_reg_count[$EVT_ID])) { |
|
552 | + $event_reg_count[$EVT_ID] = 0; |
|
553 | 553 | } |
554 | - $event_reg_count[ $EVT_ID ]++; |
|
555 | - if (! isset($event_spaces_remaining[ $EVT_ID ])) { |
|
556 | - $event_spaces_remaining[ $EVT_ID ] = $registration->event()->spaces_remaining_for_sale(); |
|
554 | + $event_reg_count[$EVT_ID]++; |
|
555 | + if ( ! isset($event_spaces_remaining[$EVT_ID])) { |
|
556 | + $event_spaces_remaining[$EVT_ID] = $registration->event()->spaces_remaining_for_sale(); |
|
557 | 557 | } |
558 | 558 | } |
559 | 559 | if ( |
560 | 560 | $revisit |
561 | - && ($tickets_remaining[ $ticket->ID() ] === 0 |
|
562 | - || $event_reg_count[ $EVT_ID ] > $event_spaces_remaining[ $EVT_ID ] |
|
561 | + && ($tickets_remaining[$ticket->ID()] === 0 |
|
562 | + || $event_reg_count[$EVT_ID] > $event_spaces_remaining[$EVT_ID] |
|
563 | 563 | ) |
564 | 564 | ) { |
565 | - $ejected_registrations[ $REG_ID ] = $registration->event(); |
|
565 | + $ejected_registrations[$REG_ID] = $registration->event(); |
|
566 | 566 | if ($registration->status_ID() !== EEM_Registration::status_id_wait_list) { |
567 | 567 | /** @type EE_Registration_Processor $registration_processor */ |
568 | 568 | $registration_processor = EE_Registry::instance()->load_class('Registration_Processor'); |
@@ -622,7 +622,7 @@ discard block |
||
622 | 622 | foreach ($sold_out_events_array as $sold_out_event) { |
623 | 623 | $sold_out_events .= EEH_HTML::li( |
624 | 624 | EEH_HTML::span( |
625 | - ' ' . $sold_out_event->name(), |
|
625 | + ' '.$sold_out_event->name(), |
|
626 | 626 | '', |
627 | 627 | 'dashicons dashicons-marker ee-icon-size-16 pink-text' |
628 | 628 | ) |
@@ -678,7 +678,7 @@ discard block |
||
678 | 678 | foreach ($insufficient_spaces_events_array as $event) { |
679 | 679 | if ($event instanceof EE_Event) { |
680 | 680 | $insufficient_space_events .= EEH_HTML::li( |
681 | - EEH_HTML::span(' ' . $event->name(), '', 'dashicons dashicons-marker ee-icon-size-16 pink-text') |
|
681 | + EEH_HTML::span(' '.$event->name(), '', 'dashicons dashicons-marker ee-icon-size-16 pink-text') |
|
682 | 682 | ); |
683 | 683 | } |
684 | 684 | } |
@@ -727,7 +727,7 @@ discard block |
||
727 | 727 | $events_requiring_pre_approval = []; |
728 | 728 | foreach ($registrations_requiring_pre_approval as $registration) { |
729 | 729 | if ($registration instanceof EE_Registration && $registration->event() instanceof EE_Event) { |
730 | - $events_requiring_pre_approval[ $registration->event()->ID() ] = EEH_HTML::li( |
|
730 | + $events_requiring_pre_approval[$registration->event()->ID()] = EEH_HTML::li( |
|
731 | 731 | EEH_HTML::span( |
732 | 732 | '', |
733 | 733 | '', |
@@ -867,7 +867,7 @@ discard block |
||
867 | 867 | { |
868 | 868 | return new EE_Form_Section_Proper( |
869 | 869 | [ |
870 | - 'html_id' => 'ee-' . $this->slug() . '-extra-hidden-inputs', |
|
870 | + 'html_id' => 'ee-'.$this->slug().'-extra-hidden-inputs', |
|
871 | 871 | 'layout_strategy' => new EE_Div_Per_Section_Layout(), |
872 | 872 | 'subsections' => [ |
873 | 873 | 'spco_no_payment_required' => new EE_Hidden_Input( |
@@ -906,7 +906,7 @@ discard block |
||
906 | 906 | $payments += $registration->registration_payments(); |
907 | 907 | } |
908 | 908 | } |
909 | - if (! empty($payments)) { |
|
909 | + if ( ! empty($payments)) { |
|
910 | 910 | foreach ($payments as $payment) { |
911 | 911 | if ($payment instanceof EE_Registration_Payment) { |
912 | 912 | $this->checkout->amount_owing -= $payment->amount(); |
@@ -995,7 +995,7 @@ discard block |
||
995 | 995 | ); |
996 | 996 | } |
997 | 997 | // switch up header depending on number of available payment methods |
998 | - $payment_method_header = count($this->checkout->available_payment_methods) > 1 |
|
998 | + $payment_method_header = count($this->checkout->available_payment_methods) > 1 |
|
999 | 999 | ? apply_filters( |
1000 | 1000 | 'FHEE__registration_page_payment_options__method_of_payment_hdr', |
1001 | 1001 | esc_html__('Please Select Your Method of Payment', 'event_espresso') |
@@ -1029,7 +1029,7 @@ discard block |
||
1029 | 1029 | $payment_method_button = EEH_HTML::img( |
1030 | 1030 | $payment_method->button_url(), |
1031 | 1031 | $payment_method->name(), |
1032 | - 'spco-payment-method-' . $payment_method->slug() . '-btn-img', |
|
1032 | + 'spco-payment-method-'.$payment_method->slug().'-btn-img', |
|
1033 | 1033 | 'spco-payment-method-btn-img' |
1034 | 1034 | ); |
1035 | 1035 | // check if any payment methods are set as default |
@@ -1037,15 +1037,15 @@ discard block |
||
1037 | 1037 | // open_by_default |
1038 | 1038 | if ( |
1039 | 1039 | ($this->checkout->selected_method_of_payment === $payment_method->slug()) |
1040 | - || (! $this->checkout->selected_method_of_payment && $payment_method->open_by_default()) |
|
1040 | + || ( ! $this->checkout->selected_method_of_payment && $payment_method->open_by_default()) |
|
1041 | 1041 | ) { |
1042 | 1042 | $this->checkout->selected_method_of_payment = $payment_method->slug(); |
1043 | 1043 | $this->_save_selected_method_of_payment(); |
1044 | - $default_payment_method_option[ $payment_method->slug() ] = $payment_method_button; |
|
1044 | + $default_payment_method_option[$payment_method->slug()] = $payment_method_button; |
|
1045 | 1045 | } else { |
1046 | - $available_payment_method_options[ $payment_method->slug() ] = $payment_method_button; |
|
1046 | + $available_payment_method_options[$payment_method->slug()] = $payment_method_button; |
|
1047 | 1047 | } |
1048 | - $payment_methods_billing_info[ $payment_method->slug() . '-info' ] = |
|
1048 | + $payment_methods_billing_info[$payment_method->slug().'-info'] = |
|
1049 | 1049 | $this->_payment_method_billing_info( |
1050 | 1050 | $payment_method |
1051 | 1051 | ); |
@@ -1058,7 +1058,7 @@ discard block |
||
1058 | 1058 | $available_payment_methods['available_payment_methods'] = $this->_available_payment_method_inputs( |
1059 | 1059 | $available_payment_method_options |
1060 | 1060 | ); |
1061 | - $available_payment_methods += $payment_methods_billing_info; |
|
1061 | + $available_payment_methods += $payment_methods_billing_info; |
|
1062 | 1062 | // build the available payment methods form |
1063 | 1063 | return new EE_Form_Section_Proper( |
1064 | 1064 | [ |
@@ -1081,7 +1081,7 @@ discard block |
||
1081 | 1081 | */ |
1082 | 1082 | protected function _get_available_payment_methods() |
1083 | 1083 | { |
1084 | - if (! empty($this->checkout->available_payment_methods)) { |
|
1084 | + if ( ! empty($this->checkout->available_payment_methods)) { |
|
1085 | 1085 | return $this->checkout->available_payment_methods; |
1086 | 1086 | } |
1087 | 1087 | $available_payment_methods = []; |
@@ -1093,7 +1093,7 @@ discard block |
||
1093 | 1093 | ); |
1094 | 1094 | foreach ($payment_methods as $payment_method) { |
1095 | 1095 | if ($payment_method instanceof EE_Payment_Method) { |
1096 | - $available_payment_methods[ $payment_method->slug() ] = $payment_method; |
|
1096 | + $available_payment_methods[$payment_method->slug()] = $payment_method; |
|
1097 | 1097 | } |
1098 | 1098 | } |
1099 | 1099 | return $available_payment_methods; |
@@ -1188,7 +1188,7 @@ discard block |
||
1188 | 1188 | ); |
1189 | 1189 | return new EE_Form_Section_Proper( |
1190 | 1190 | [ |
1191 | - 'html_id' => 'spco-payment-method-info-' . $payment_method->slug(), |
|
1191 | + 'html_id' => 'spco-payment-method-info-'.$payment_method->slug(), |
|
1192 | 1192 | 'html_class' => 'spco-payment-method-info-dv', |
1193 | 1193 | // only display the selected or default PM |
1194 | 1194 | 'html_style' => $currently_selected ? '' : 'display:none;', |
@@ -1217,7 +1217,7 @@ discard block |
||
1217 | 1217 | // how have they chosen to pay? |
1218 | 1218 | $this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment(true); |
1219 | 1219 | $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment(); |
1220 | - if (! $this->checkout->payment_method instanceof EE_Payment_Method) { |
|
1220 | + if ( ! $this->checkout->payment_method instanceof EE_Payment_Method) { |
|
1221 | 1221 | return false; |
1222 | 1222 | } |
1223 | 1223 | if ( |
@@ -1392,7 +1392,7 @@ discard block |
||
1392 | 1392 | */ |
1393 | 1393 | public function switch_payment_method() |
1394 | 1394 | { |
1395 | - if (! $this->_verify_payment_method_is_set()) { |
|
1395 | + if ( ! $this->_verify_payment_method_is_set()) { |
|
1396 | 1396 | return false; |
1397 | 1397 | } |
1398 | 1398 | if ( |
@@ -1528,7 +1528,7 @@ discard block |
||
1528 | 1528 | } |
1529 | 1529 | } |
1530 | 1530 | // verify payment method |
1531 | - if (! $this->checkout->payment_method instanceof EE_Payment_Method) { |
|
1531 | + if ( ! $this->checkout->payment_method instanceof EE_Payment_Method) { |
|
1532 | 1532 | // get payment method for selected method of payment |
1533 | 1533 | $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment(); |
1534 | 1534 | } |
@@ -1553,7 +1553,7 @@ discard block |
||
1553 | 1553 | */ |
1554 | 1554 | public function save_payer_details_via_ajax() |
1555 | 1555 | { |
1556 | - if (! $this->_verify_payment_method_is_set()) { |
|
1556 | + if ( ! $this->_verify_payment_method_is_set()) { |
|
1557 | 1557 | return; |
1558 | 1558 | } |
1559 | 1559 | // generate billing form for selected method of payment if it hasn't been done already |
@@ -1563,7 +1563,7 @@ discard block |
||
1563 | 1563 | ); |
1564 | 1564 | } |
1565 | 1565 | // generate primary attendee from payer info if applicable |
1566 | - if (! $this->checkout->transaction_has_primary_registrant()) { |
|
1566 | + if ( ! $this->checkout->transaction_has_primary_registrant()) { |
|
1567 | 1567 | $attendee = $this->_create_attendee_from_request_data(); |
1568 | 1568 | if ($attendee instanceof EE_Attendee) { |
1569 | 1569 | foreach ($this->checkout->transaction->registrations() as $registration) { |
@@ -1594,7 +1594,7 @@ discard block |
||
1594 | 1594 | { |
1595 | 1595 | // get State ID |
1596 | 1596 | $STA_ID = $this->request->getRequestParam('state'); |
1597 | - if (! empty($STA_ID)) { |
|
1597 | + if ( ! empty($STA_ID)) { |
|
1598 | 1598 | // can we get state object from name ? |
1599 | 1599 | EE_Registry::instance()->load_model('State'); |
1600 | 1600 | $state = EEM_State::instance()->get_col([['STA_name' => $STA_ID], 'limit' => 1], 'STA_ID'); |
@@ -1602,7 +1602,7 @@ discard block |
||
1602 | 1602 | } |
1603 | 1603 | // get Country ISO |
1604 | 1604 | $CNT_ISO = $this->request->getRequestParam('country'); |
1605 | - if (! empty($CNT_ISO)) { |
|
1605 | + if ( ! empty($CNT_ISO)) { |
|
1606 | 1606 | // can we get country object from name ? |
1607 | 1607 | EE_Registry::instance()->load_model('Country'); |
1608 | 1608 | $country = EEM_Country::instance()->get_col( |
@@ -1849,7 +1849,7 @@ discard block |
||
1849 | 1849 | private function _process_payment() |
1850 | 1850 | { |
1851 | 1851 | // basically confirm that the event hasn't sold out since they hit the page |
1852 | - if (! $this->_last_second_ticket_verifications()) { |
|
1852 | + if ( ! $this->_last_second_ticket_verifications()) { |
|
1853 | 1853 | return false; |
1854 | 1854 | } |
1855 | 1855 | // ya gotta make a choice man |
@@ -1860,7 +1860,7 @@ discard block |
||
1860 | 1860 | return false; |
1861 | 1861 | } |
1862 | 1862 | // get EE_Payment_Method object |
1863 | - if (! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()) { |
|
1863 | + if ( ! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()) { |
|
1864 | 1864 | return false; |
1865 | 1865 | } |
1866 | 1866 | // setup billing form |
@@ -1869,12 +1869,12 @@ discard block |
||
1869 | 1869 | $this->checkout->payment_method |
1870 | 1870 | ); |
1871 | 1871 | // bad billing form ? |
1872 | - if (! $this->_billing_form_is_valid()) { |
|
1872 | + if ( ! $this->_billing_form_is_valid()) { |
|
1873 | 1873 | return false; |
1874 | 1874 | } |
1875 | 1875 | } |
1876 | 1876 | // ensure primary registrant has been fully processed |
1877 | - if (! $this->_setup_primary_registrant_prior_to_payment()) { |
|
1877 | + if ( ! $this->_setup_primary_registrant_prior_to_payment()) { |
|
1878 | 1878 | return false; |
1879 | 1879 | } |
1880 | 1880 | // if session is close to expiring (under 10 minutes by default) |
@@ -1925,7 +1925,7 @@ discard block |
||
1925 | 1925 | protected function _last_second_ticket_verifications() |
1926 | 1926 | { |
1927 | 1927 | // don't bother re-validating if not a return visit |
1928 | - if (! $this->checkout->revisit) { |
|
1928 | + if ( ! $this->checkout->revisit) { |
|
1929 | 1929 | return true; |
1930 | 1930 | } |
1931 | 1931 | $registrations = $this->checkout->transaction->registrations(); |
@@ -1975,7 +1975,7 @@ discard block |
||
1975 | 1975 | $this->_get_payment_method_for_selected_method_of_payment() |
1976 | 1976 | ); |
1977 | 1977 | $html = $payment_method_billing_info->get_html(); |
1978 | - $html .= $this->checkout->redirect_form; |
|
1978 | + $html .= $this->checkout->redirect_form; |
|
1979 | 1979 | /** @var ResponseInterface $response */ |
1980 | 1980 | $response = LoaderFactory::getLoader()->getShared(ResponseInterface::class); |
1981 | 1981 | $response->addOutput($html); |
@@ -1991,7 +1991,7 @@ discard block |
||
1991 | 1991 | */ |
1992 | 1992 | private function _billing_form_is_valid() |
1993 | 1993 | { |
1994 | - if (! $this->checkout->payment_method->type_obj()->has_billing_form()) { |
|
1994 | + if ( ! $this->checkout->payment_method->type_obj()->has_billing_form()) { |
|
1995 | 1995 | return true; |
1996 | 1996 | } |
1997 | 1997 | if ($this->checkout->billing_form instanceof EE_Billing_Info_Form) { |
@@ -2109,7 +2109,7 @@ discard block |
||
2109 | 2109 | { |
2110 | 2110 | // convert billing form data into an attendee |
2111 | 2111 | $this->checkout->primary_attendee_obj = $this->checkout->billing_form->create_attendee_from_billing_form_data(); |
2112 | - if (! $this->checkout->primary_attendee_obj instanceof EE_Attendee) { |
|
2112 | + if ( ! $this->checkout->primary_attendee_obj instanceof EE_Attendee) { |
|
2113 | 2113 | EE_Error::add_error( |
2114 | 2114 | sprintf( |
2115 | 2115 | esc_html__( |
@@ -2126,7 +2126,7 @@ discard block |
||
2126 | 2126 | return false; |
2127 | 2127 | } |
2128 | 2128 | $primary_registration = $this->checkout->transaction->primary_registration(); |
2129 | - if (! $primary_registration instanceof EE_Registration) { |
|
2129 | + if ( ! $primary_registration instanceof EE_Registration) { |
|
2130 | 2130 | EE_Error::add_error( |
2131 | 2131 | sprintf( |
2132 | 2132 | esc_html__( |
@@ -2188,8 +2188,8 @@ discard block |
||
2188 | 2188 | return null; |
2189 | 2189 | } |
2190 | 2190 | // get EE_Payment_Method object |
2191 | - if (isset($this->checkout->available_payment_methods[ $this->checkout->selected_method_of_payment ])) { |
|
2192 | - $payment_method = $this->checkout->available_payment_methods[ $this->checkout->selected_method_of_payment ]; |
|
2191 | + if (isset($this->checkout->available_payment_methods[$this->checkout->selected_method_of_payment])) { |
|
2192 | + $payment_method = $this->checkout->available_payment_methods[$this->checkout->selected_method_of_payment]; |
|
2193 | 2193 | } else { |
2194 | 2194 | // load EEM_Payment_Method |
2195 | 2195 | EE_Registry::instance()->load_model('Payment_Method'); |
@@ -2197,7 +2197,7 @@ discard block |
||
2197 | 2197 | $payment_method = $EEM_Payment_Method->get_one_by_slug($this->checkout->selected_method_of_payment); |
2198 | 2198 | } |
2199 | 2199 | // verify $payment_method |
2200 | - if (! $payment_method instanceof EE_Payment_Method) { |
|
2200 | + if ( ! $payment_method instanceof EE_Payment_Method) { |
|
2201 | 2201 | // not a payment |
2202 | 2202 | EE_Error::add_error( |
2203 | 2203 | sprintf( |
@@ -2215,7 +2215,7 @@ discard block |
||
2215 | 2215 | return null; |
2216 | 2216 | } |
2217 | 2217 | // and verify it has a valid Payment_Method Type object |
2218 | - if (! $payment_method->type_obj() instanceof EE_PMT_Base) { |
|
2218 | + if ( ! $payment_method->type_obj() instanceof EE_PMT_Base) { |
|
2219 | 2219 | // not a payment |
2220 | 2220 | EE_Error::add_error( |
2221 | 2221 | sprintf( |
@@ -2253,7 +2253,7 @@ discard block |
||
2253 | 2253 | $payment = null; |
2254 | 2254 | $this->checkout->transaction->save(); |
2255 | 2255 | $payment_processor = EE_Registry::instance()->load_core('Payment_Processor'); |
2256 | - if (! $payment_processor instanceof EE_Payment_Processor) { |
|
2256 | + if ( ! $payment_processor instanceof EE_Payment_Processor) { |
|
2257 | 2257 | return false; |
2258 | 2258 | } |
2259 | 2259 | try { |
@@ -2355,7 +2355,7 @@ discard block |
||
2355 | 2355 | return true; |
2356 | 2356 | } |
2357 | 2357 | // verify payment object |
2358 | - if (! $payment instanceof EE_Payment) { |
|
2358 | + if ( ! $payment instanceof EE_Payment) { |
|
2359 | 2359 | // not a payment |
2360 | 2360 | EE_Error::add_error( |
2361 | 2361 | sprintf( |
@@ -2395,7 +2395,7 @@ discard block |
||
2395 | 2395 | return true; |
2396 | 2396 | // On-Site payment? |
2397 | 2397 | } elseif ($this->checkout->payment_method->is_on_site()) { |
2398 | - if (! $this->_process_payment_status($payment, EE_PMT_Base::onsite)) { |
|
2398 | + if ( ! $this->_process_payment_status($payment, EE_PMT_Base::onsite)) { |
|
2399 | 2399 | // $this->_setup_redirect_for_next_step(); |
2400 | 2400 | $this->checkout->continue_reg = false; |
2401 | 2401 | } |
@@ -2423,7 +2423,7 @@ discard block |
||
2423 | 2423 | EE_Registry::instance()->CFG->organization->get_pretty('email') |
2424 | 2424 | ); |
2425 | 2425 | if ($payment instanceof EE_Payment && $payment->gateway_response()) { |
2426 | - $error_message = $error_message . '<br/>' . $payment->gateway_response(); |
|
2426 | + $error_message = $error_message.'<br/>'.$payment->gateway_response(); |
|
2427 | 2427 | } |
2428 | 2428 | $this->checkout->continue_reg = false; |
2429 | 2429 | EE_Error::add_error( |
@@ -2510,7 +2510,7 @@ discard block |
||
2510 | 2510 | return false; |
2511 | 2511 | // bad payment |
2512 | 2512 | case EEM_Payment::status_id_failed: |
2513 | - if (! empty($msg)) { |
|
2513 | + if ( ! empty($msg)) { |
|
2514 | 2514 | EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__); |
2515 | 2515 | return false; |
2516 | 2516 | } |
@@ -2568,18 +2568,18 @@ discard block |
||
2568 | 2568 | // how have they chosen to pay? |
2569 | 2569 | $this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment(true); |
2570 | 2570 | // get EE_Payment_Method object |
2571 | - if (! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()) { |
|
2571 | + if ( ! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()) { |
|
2572 | 2572 | $this->checkout->continue_reg = false; |
2573 | 2573 | return false; |
2574 | 2574 | } |
2575 | - if (! $this->checkout->payment_method->is_off_site()) { |
|
2575 | + if ( ! $this->checkout->payment_method->is_off_site()) { |
|
2576 | 2576 | return false; |
2577 | 2577 | } |
2578 | 2578 | $this->_validate_offsite_return(); |
2579 | 2579 | // verify TXN |
2580 | 2580 | if ($this->checkout->transaction instanceof EE_Transaction) { |
2581 | 2581 | $gateway = $this->checkout->payment_method->type_obj()->get_gateway(); |
2582 | - if (! $gateway instanceof EE_Offsite_Gateway) { |
|
2582 | + if ( ! $gateway instanceof EE_Offsite_Gateway) { |
|
2583 | 2583 | $this->checkout->continue_reg = false; |
2584 | 2584 | return false; |
2585 | 2585 | } |
@@ -2593,7 +2593,7 @@ discard block |
||
2593 | 2593 | $this->checkout->payment = $payment; |
2594 | 2594 | // mark this reg step as completed, as long as gateway doesn't use a separate IPN request, |
2595 | 2595 | // because we will complete this step during the IPN processing then |
2596 | - if (! $this->handle_IPN_in_this_request()) { |
|
2596 | + if ( ! $this->handle_IPN_in_this_request()) { |
|
2597 | 2597 | $this->set_completed(); |
2598 | 2598 | } |
2599 | 2599 | return true; |
@@ -2696,13 +2696,13 @@ discard block |
||
2696 | 2696 | */ |
2697 | 2697 | private function _redirect_wayward_request(EE_Registration $primary_registrant) |
2698 | 2698 | { |
2699 | - if (! $primary_registrant instanceof EE_Registration) { |
|
2699 | + if ( ! $primary_registrant instanceof EE_Registration) { |
|
2700 | 2700 | // try redirecting based on the current TXN |
2701 | 2701 | $primary_registrant = $this->checkout->transaction instanceof EE_Transaction |
2702 | 2702 | ? $this->checkout->transaction->primary_registration() |
2703 | 2703 | : null; |
2704 | 2704 | } |
2705 | - if (! $primary_registrant instanceof EE_Registration) { |
|
2705 | + if ( ! $primary_registrant instanceof EE_Registration) { |
|
2706 | 2706 | EE_Error::add_error( |
2707 | 2707 | sprintf( |
2708 | 2708 | esc_html__( |
@@ -2773,7 +2773,7 @@ discard block |
||
2773 | 2773 | $payment = $this->checkout->transaction->last_payment(); |
2774 | 2774 | // $payment_source = 'last_payment after Exception'; |
2775 | 2775 | // but if we STILL don't have a payment object |
2776 | - if (! $payment instanceof EE_Payment) { |
|
2776 | + if ( ! $payment instanceof EE_Payment) { |
|
2777 | 2777 | // then we'll object ! ( not object like a thing... but object like what a lawyer says ! ) |
2778 | 2778 | $this->_handle_payment_processor_exception($e); |
2779 | 2779 | } |
@@ -19,2862 +19,2862 @@ |
||
19 | 19 | */ |
20 | 20 | class EE_SPCO_Reg_Step_Payment_Options extends EE_SPCO_Reg_Step |
21 | 21 | { |
22 | - /** |
|
23 | - * @var EE_Line_Item_Display $Line_Item_Display |
|
24 | - */ |
|
25 | - protected $line_item_display; |
|
26 | - |
|
27 | - /** |
|
28 | - * @var boolean $handle_IPN_in_this_request |
|
29 | - */ |
|
30 | - protected $handle_IPN_in_this_request = false; |
|
31 | - |
|
32 | - |
|
33 | - /** |
|
34 | - * set_hooks - for hooking into EE Core, other modules, etc |
|
35 | - * |
|
36 | - * @access public |
|
37 | - * @return void |
|
38 | - */ |
|
39 | - public static function set_hooks() |
|
40 | - { |
|
41 | - add_filter( |
|
42 | - 'FHEE__SPCO__EE_Line_Item_Filter_Collection', |
|
43 | - ['EE_SPCO_Reg_Step_Payment_Options', 'add_spco_line_item_filters'] |
|
44 | - ); |
|
45 | - add_action( |
|
46 | - 'wp_ajax_switch_spco_billing_form', |
|
47 | - ['EE_SPCO_Reg_Step_Payment_Options', 'switch_spco_billing_form'] |
|
48 | - ); |
|
49 | - add_action( |
|
50 | - 'wp_ajax_nopriv_switch_spco_billing_form', |
|
51 | - ['EE_SPCO_Reg_Step_Payment_Options', 'switch_spco_billing_form'] |
|
52 | - ); |
|
53 | - add_action('wp_ajax_save_payer_details', ['EE_SPCO_Reg_Step_Payment_Options', 'save_payer_details']); |
|
54 | - add_action( |
|
55 | - 'wp_ajax_nopriv_save_payer_details', |
|
56 | - ['EE_SPCO_Reg_Step_Payment_Options', 'save_payer_details'] |
|
57 | - ); |
|
58 | - add_action( |
|
59 | - 'wp_ajax_get_transaction_details_for_gateways', |
|
60 | - ['EE_SPCO_Reg_Step_Payment_Options', 'get_transaction_details'] |
|
61 | - ); |
|
62 | - add_action( |
|
63 | - 'wp_ajax_nopriv_get_transaction_details_for_gateways', |
|
64 | - ['EE_SPCO_Reg_Step_Payment_Options', 'get_transaction_details'] |
|
65 | - ); |
|
66 | - add_filter( |
|
67 | - 'FHEE__EED_Recaptcha___bypass_recaptcha__bypass_request_params_array', |
|
68 | - ['EE_SPCO_Reg_Step_Payment_Options', 'bypass_recaptcha_for_load_payment_method'], |
|
69 | - 10, |
|
70 | - 1 |
|
71 | - ); |
|
72 | - } |
|
73 | - |
|
74 | - |
|
75 | - /** |
|
76 | - * ajax switch_spco_billing_form |
|
77 | - * |
|
78 | - */ |
|
79 | - public static function switch_spco_billing_form() |
|
80 | - { |
|
81 | - EED_Single_Page_Checkout::process_ajax_request('switch_payment_method'); |
|
82 | - } |
|
83 | - |
|
84 | - |
|
85 | - /** |
|
86 | - * ajax save_payer_details |
|
87 | - * |
|
88 | - */ |
|
89 | - public static function save_payer_details() |
|
90 | - { |
|
91 | - EED_Single_Page_Checkout::process_ajax_request('save_payer_details_via_ajax'); |
|
92 | - } |
|
93 | - |
|
94 | - |
|
95 | - /** |
|
96 | - * ajax get_transaction_details |
|
97 | - * |
|
98 | - */ |
|
99 | - public static function get_transaction_details() |
|
100 | - { |
|
101 | - EED_Single_Page_Checkout::process_ajax_request('get_transaction_details_for_gateways'); |
|
102 | - } |
|
103 | - |
|
104 | - |
|
105 | - /** |
|
106 | - * bypass_recaptcha_for_load_payment_method |
|
107 | - * |
|
108 | - * @access public |
|
109 | - * @return array |
|
110 | - * @throws InvalidArgumentException |
|
111 | - * @throws InvalidDataTypeException |
|
112 | - * @throws InvalidInterfaceException |
|
113 | - */ |
|
114 | - public static function bypass_recaptcha_for_load_payment_method() |
|
115 | - { |
|
116 | - return [ |
|
117 | - 'EESID' => EE_Registry::instance()->SSN->id(), |
|
118 | - 'step' => 'payment_options', |
|
119 | - 'action' => 'spco_billing_form', |
|
120 | - ]; |
|
121 | - } |
|
122 | - |
|
123 | - |
|
124 | - /** |
|
125 | - * class constructor |
|
126 | - * |
|
127 | - * @access public |
|
128 | - * @param EE_Checkout $checkout |
|
129 | - */ |
|
130 | - public function __construct(EE_Checkout $checkout) |
|
131 | - { |
|
132 | - $this->request = EED_Single_Page_Checkout::getRequest(); |
|
133 | - $this->_slug = 'payment_options'; |
|
134 | - $this->_name = esc_html__('Payment Options', 'event_espresso'); |
|
135 | - $this->_template = SPCO_REG_STEPS_PATH . $this->_slug . '/payment_options_main.template.php'; |
|
136 | - $this->checkout = $checkout; |
|
137 | - $this->_reset_success_message(); |
|
138 | - $this->set_instructions( |
|
139 | - esc_html__( |
|
140 | - 'Please select a method of payment and provide any necessary billing information before proceeding.', |
|
141 | - 'event_espresso' |
|
142 | - ) |
|
143 | - ); |
|
144 | - } |
|
145 | - |
|
146 | - |
|
147 | - /** |
|
148 | - * @return null |
|
149 | - */ |
|
150 | - public function line_item_display() |
|
151 | - { |
|
152 | - return $this->line_item_display; |
|
153 | - } |
|
154 | - |
|
155 | - |
|
156 | - /** |
|
157 | - * @param null $line_item_display |
|
158 | - */ |
|
159 | - public function set_line_item_display($line_item_display) |
|
160 | - { |
|
161 | - $this->line_item_display = $line_item_display; |
|
162 | - } |
|
163 | - |
|
164 | - |
|
165 | - /** |
|
166 | - * @return boolean |
|
167 | - */ |
|
168 | - public function handle_IPN_in_this_request() |
|
169 | - { |
|
170 | - return $this->handle_IPN_in_this_request; |
|
171 | - } |
|
172 | - |
|
173 | - |
|
174 | - /** |
|
175 | - * @param boolean $handle_IPN_in_this_request |
|
176 | - */ |
|
177 | - public function set_handle_IPN_in_this_request($handle_IPN_in_this_request) |
|
178 | - { |
|
179 | - $this->handle_IPN_in_this_request = filter_var($handle_IPN_in_this_request, FILTER_VALIDATE_BOOLEAN); |
|
180 | - } |
|
181 | - |
|
182 | - |
|
183 | - /** |
|
184 | - * translate_js_strings |
|
185 | - * |
|
186 | - * @return void |
|
187 | - */ |
|
188 | - public function translate_js_strings() |
|
189 | - { |
|
190 | - EE_Registry::$i18n_js_strings['no_payment_method'] = esc_html__( |
|
191 | - 'Please select a method of payment in order to continue.', |
|
192 | - 'event_espresso' |
|
193 | - ); |
|
194 | - EE_Registry::$i18n_js_strings['invalid_payment_method'] = esc_html__( |
|
195 | - 'A valid method of payment could not be determined. Please refresh the page and try again.', |
|
196 | - 'event_espresso' |
|
197 | - ); |
|
198 | - EE_Registry::$i18n_js_strings['forwarding_to_offsite'] = esc_html__( |
|
199 | - 'Forwarding to Secure Payment Provider.', |
|
200 | - 'event_espresso' |
|
201 | - ); |
|
202 | - } |
|
203 | - |
|
204 | - |
|
205 | - /** |
|
206 | - * enqueue_styles_and_scripts |
|
207 | - * |
|
208 | - * @return void |
|
209 | - * @throws EE_Error |
|
210 | - * @throws InvalidArgumentException |
|
211 | - * @throws InvalidDataTypeException |
|
212 | - * @throws InvalidInterfaceException |
|
213 | - * @throws ReflectionException |
|
214 | - */ |
|
215 | - public function enqueue_styles_and_scripts() |
|
216 | - { |
|
217 | - $transaction = $this->checkout->transaction; |
|
218 | - // if the transaction isn't set or nothing is owed on it, don't enqueue any JS |
|
219 | - if (! $transaction instanceof EE_Transaction || EEH_Money::compare_floats($transaction->remaining(), 0)) { |
|
220 | - return; |
|
221 | - } |
|
222 | - foreach ( |
|
223 | - EEM_Payment_Method::instance()->get_all_for_transaction( |
|
224 | - $transaction, |
|
225 | - EEM_Payment_Method::scope_cart |
|
226 | - ) as $payment_method |
|
227 | - ) { |
|
228 | - $type_obj = $payment_method->type_obj(); |
|
229 | - if ($type_obj instanceof EE_PMT_Base) { |
|
230 | - $billing_form = $type_obj->generate_new_billing_form($transaction); |
|
231 | - if ($billing_form instanceof EE_Form_Section_Proper) { |
|
232 | - $billing_form->enqueue_js(); |
|
233 | - } |
|
234 | - } |
|
235 | - } |
|
236 | - } |
|
237 | - |
|
238 | - |
|
239 | - /** |
|
240 | - * initialize_reg_step |
|
241 | - * |
|
242 | - * @return bool |
|
243 | - * @throws EE_Error |
|
244 | - * @throws InvalidArgumentException |
|
245 | - * @throws ReflectionException |
|
246 | - * @throws InvalidDataTypeException |
|
247 | - * @throws InvalidInterfaceException |
|
248 | - */ |
|
249 | - public function initialize_reg_step() |
|
250 | - { |
|
251 | - // TODO: if /when we implement donations, then this will need overriding |
|
252 | - if ( |
|
253 | - // don't need payment options for: |
|
254 | - // registrations made via the admin |
|
255 | - // completed transactions |
|
256 | - // overpaid transactions |
|
257 | - // $ 0.00 transactions(no payment required) |
|
258 | - ! $this->checkout->payment_required() |
|
259 | - // but do NOT remove if current action being called belongs to this reg step |
|
260 | - && ! is_callable([$this, $this->checkout->action]) |
|
261 | - && ! $this->completed() |
|
262 | - ) { |
|
263 | - // and if so, then we no longer need the Payment Options step |
|
264 | - if ($this->is_current_step()) { |
|
265 | - $this->checkout->generate_reg_form = false; |
|
266 | - } |
|
267 | - $this->checkout->remove_reg_step($this->_slug); |
|
268 | - // DEBUG LOG |
|
269 | - // $this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ ); |
|
270 | - return false; |
|
271 | - } |
|
272 | - // load EEM_Payment_Method |
|
273 | - EE_Registry::instance()->load_model('Payment_Method'); |
|
274 | - // get all active payment methods |
|
275 | - $this->checkout->available_payment_methods = EEM_Payment_Method::instance()->get_all_for_transaction( |
|
276 | - $this->checkout->transaction, |
|
277 | - EEM_Payment_Method::scope_cart |
|
278 | - ); |
|
279 | - return true; |
|
280 | - } |
|
281 | - |
|
282 | - |
|
283 | - /** |
|
284 | - * @return EE_Form_Section_Proper |
|
285 | - * @throws EE_Error |
|
286 | - * @throws InvalidArgumentException |
|
287 | - * @throws ReflectionException |
|
288 | - * @throws EntityNotFoundException |
|
289 | - * @throws InvalidDataTypeException |
|
290 | - * @throws InvalidInterfaceException |
|
291 | - * @throws InvalidStatusException |
|
292 | - */ |
|
293 | - public function generate_reg_form() |
|
294 | - { |
|
295 | - // reset in case someone changes their mind |
|
296 | - $this->_reset_selected_method_of_payment(); |
|
297 | - // set some defaults |
|
298 | - $this->checkout->selected_method_of_payment = 'payments_closed'; |
|
299 | - $registrations_requiring_payment = []; |
|
300 | - $registrations_for_free_events = []; |
|
301 | - $registrations_requiring_pre_approval = []; |
|
302 | - $sold_out_events = []; |
|
303 | - $insufficient_spaces_available = []; |
|
304 | - $no_payment_required = true; |
|
305 | - // loop thru registrations to gather info |
|
306 | - $registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params); |
|
307 | - $ejected_registrations = EE_SPCO_Reg_Step_Payment_Options::find_registrations_that_lost_their_space( |
|
308 | - $registrations, |
|
309 | - $this->checkout->revisit |
|
310 | - ); |
|
311 | - foreach ($registrations as $REG_ID => $registration) { |
|
312 | - /** @var $registration EE_Registration */ |
|
313 | - // has this registration lost it's space ? |
|
314 | - if (isset($ejected_registrations[ $REG_ID ])) { |
|
315 | - if ($registration->event()->is_sold_out() || $registration->event()->is_sold_out(true)) { |
|
316 | - $sold_out_events[ $registration->event()->ID() ] = $registration->event(); |
|
317 | - } else { |
|
318 | - $insufficient_spaces_available[ $registration->event()->ID() ] = $registration->event(); |
|
319 | - } |
|
320 | - continue; |
|
321 | - } |
|
322 | - // event requires admin approval |
|
323 | - if ($registration->status_ID() === EEM_Registration::status_id_not_approved) { |
|
324 | - // add event to list of events with pre-approval reg status |
|
325 | - $registrations_requiring_pre_approval[ $REG_ID ] = $registration; |
|
326 | - do_action( |
|
327 | - 'AHEE__EE_SPCO_Reg_Step_Payment_Options__generate_reg_form__event_requires_pre_approval', |
|
328 | - $registration->event(), |
|
329 | - $this |
|
330 | - ); |
|
331 | - continue; |
|
332 | - } |
|
333 | - if ( |
|
334 | - $this->checkout->revisit |
|
335 | - && $registration->status_ID() !== EEM_Registration::status_id_approved |
|
336 | - && ( |
|
337 | - $registration->event()->is_sold_out() |
|
338 | - || $registration->event()->is_sold_out(true) |
|
339 | - ) |
|
340 | - ) { |
|
341 | - // add event to list of events that are sold out |
|
342 | - $sold_out_events[ $registration->event()->ID() ] = $registration->event(); |
|
343 | - do_action( |
|
344 | - 'AHEE__EE_SPCO_Reg_Step_Payment_Options__generate_reg_form__sold_out_event', |
|
345 | - $registration->event(), |
|
346 | - $this |
|
347 | - ); |
|
348 | - continue; |
|
349 | - } |
|
350 | - // are they allowed to pay now and is there monies owing? |
|
351 | - if ($registration->owes_monies_and_can_pay()) { |
|
352 | - $registrations_requiring_payment[ $REG_ID ] = $registration; |
|
353 | - do_action( |
|
354 | - 'AHEE__EE_SPCO_Reg_Step_Payment_Options__generate_reg_form__event_requires_payment', |
|
355 | - $registration->event(), |
|
356 | - $this |
|
357 | - ); |
|
358 | - } elseif ( |
|
359 | - ! $this->checkout->revisit |
|
360 | - && $registration->status_ID() !== EEM_Registration::status_id_not_approved |
|
361 | - && $registration->ticket()->is_free() |
|
362 | - ) { |
|
363 | - $registrations_for_free_events[ $registration->ticket()->ID() ] = $registration; |
|
364 | - } |
|
365 | - } |
|
366 | - $subsections = []; |
|
367 | - // now decide which template to load |
|
368 | - if (! empty($sold_out_events)) { |
|
369 | - $subsections['sold_out_events'] = $this->_sold_out_events($sold_out_events); |
|
370 | - } |
|
371 | - if (! empty($insufficient_spaces_available)) { |
|
372 | - $subsections['insufficient_space'] = $this->_insufficient_spaces_available( |
|
373 | - $insufficient_spaces_available |
|
374 | - ); |
|
375 | - } |
|
376 | - if (! empty($registrations_requiring_pre_approval)) { |
|
377 | - $subsections['registrations_requiring_pre_approval'] = $this->_registrations_requiring_pre_approval( |
|
378 | - $registrations_requiring_pre_approval |
|
379 | - ); |
|
380 | - } |
|
381 | - if (! empty($registrations_for_free_events)) { |
|
382 | - $subsections['no_payment_required'] = $this->_no_payment_required($registrations_for_free_events); |
|
383 | - } |
|
384 | - if (! empty($registrations_requiring_payment)) { |
|
385 | - if ($this->checkout->amount_owing > 0) { |
|
386 | - // autoload Line_Item_Display classes |
|
387 | - EEH_Autoloader::register_line_item_filter_autoloaders(); |
|
388 | - $line_item_filter_processor = new EE_Line_Item_Filter_Processor( |
|
389 | - apply_filters( |
|
390 | - 'FHEE__SPCO__EE_Line_Item_Filter_Collection', |
|
391 | - new EE_Line_Item_Filter_Collection() |
|
392 | - ), |
|
393 | - $this->checkout->cart->get_grand_total() |
|
394 | - ); |
|
395 | - /** @var EE_Line_Item $filtered_line_item_tree */ |
|
396 | - $filtered_line_item_tree = $line_item_filter_processor->process(); |
|
397 | - EEH_Autoloader::register_line_item_display_autoloaders(); |
|
398 | - $this->set_line_item_display(new EE_Line_Item_Display('spco')); |
|
399 | - $subsections['payment_options'] = $this->_display_payment_options( |
|
400 | - $this->line_item_display->display_line_item( |
|
401 | - $filtered_line_item_tree, |
|
402 | - ['registrations' => $registrations] |
|
403 | - ) |
|
404 | - ); |
|
405 | - $this->checkout->amount_owing = $filtered_line_item_tree->total(); |
|
406 | - $this->_apply_registration_payments_to_amount_owing($registrations); |
|
407 | - } |
|
408 | - $no_payment_required = false; |
|
409 | - } else { |
|
410 | - $this->_hide_reg_step_submit_button_if_revisit(); |
|
411 | - } |
|
412 | - $this->_save_selected_method_of_payment(); |
|
413 | - |
|
414 | - $subsections['default_hidden_inputs'] = $this->reg_step_hidden_inputs(); |
|
415 | - $subsections['extra_hidden_inputs'] = $this->_extra_hidden_inputs($no_payment_required); |
|
416 | - |
|
417 | - return new EE_Form_Section_Proper( |
|
418 | - [ |
|
419 | - 'name' => $this->reg_form_name(), |
|
420 | - 'html_id' => $this->reg_form_name(), |
|
421 | - 'subsections' => $subsections, |
|
422 | - 'layout_strategy' => new EE_No_Layout(), |
|
423 | - ] |
|
424 | - ); |
|
425 | - } |
|
426 | - |
|
427 | - |
|
428 | - /** |
|
429 | - * add line item filters required for this reg step |
|
430 | - * these filters are applied via this line in EE_SPCO_Reg_Step_Payment_Options::set_hooks(): |
|
431 | - * add_filter( 'FHEE__SPCO__EE_Line_Item_Filter_Collection', array( 'EE_SPCO_Reg_Step_Payment_Options', |
|
432 | - * 'add_spco_line_item_filters' ) ); so any code that wants to use the same set of filters during the |
|
433 | - * payment options reg step, can apply these filters via the following: apply_filters( |
|
434 | - * 'FHEE__SPCO__EE_Line_Item_Filter_Collection', new EE_Line_Item_Filter_Collection() ) or to an existing |
|
435 | - * filter collection by passing that instead of instantiating a new collection |
|
436 | - * |
|
437 | - * @param EE_Line_Item_Filter_Collection $line_item_filter_collection |
|
438 | - * @return EE_Line_Item_Filter_Collection |
|
439 | - * @throws EE_Error |
|
440 | - * @throws InvalidArgumentException |
|
441 | - * @throws ReflectionException |
|
442 | - * @throws EntityNotFoundException |
|
443 | - * @throws InvalidDataTypeException |
|
444 | - * @throws InvalidInterfaceException |
|
445 | - * @throws InvalidStatusException |
|
446 | - */ |
|
447 | - public static function add_spco_line_item_filters(EE_Line_Item_Filter_Collection $line_item_filter_collection) |
|
448 | - { |
|
449 | - if (! EE_Registry::instance()->SSN instanceof EE_Session) { |
|
450 | - return $line_item_filter_collection; |
|
451 | - } |
|
452 | - if (! EE_Registry::instance()->SSN->checkout() instanceof EE_Checkout) { |
|
453 | - return $line_item_filter_collection; |
|
454 | - } |
|
455 | - if (! EE_Registry::instance()->SSN->checkout()->transaction instanceof EE_Transaction) { |
|
456 | - return $line_item_filter_collection; |
|
457 | - } |
|
458 | - $line_item_filter_collection->add( |
|
459 | - new EE_Billable_Line_Item_Filter( |
|
460 | - EE_SPCO_Reg_Step_Payment_Options::remove_ejected_registrations( |
|
461 | - EE_Registry::instance()->SSN->checkout()->transaction->registrations( |
|
462 | - EE_Registry::instance()->SSN->checkout()->reg_cache_where_params |
|
463 | - ) |
|
464 | - ) |
|
465 | - ) |
|
466 | - ); |
|
467 | - $line_item_filter_collection->add(new EE_Non_Zero_Line_Item_Filter()); |
|
468 | - return $line_item_filter_collection; |
|
469 | - } |
|
470 | - |
|
471 | - |
|
472 | - /** |
|
473 | - * remove_ejected_registrations |
|
474 | - * if a registrant has lost their potential space at an event due to lack of payment, |
|
475 | - * then this method removes them from the list of registrations being paid for during this request |
|
476 | - * |
|
477 | - * @param EE_Registration[] $registrations |
|
478 | - * @return EE_Registration[] |
|
479 | - * @throws EE_Error |
|
480 | - * @throws InvalidArgumentException |
|
481 | - * @throws ReflectionException |
|
482 | - * @throws EntityNotFoundException |
|
483 | - * @throws InvalidDataTypeException |
|
484 | - * @throws InvalidInterfaceException |
|
485 | - * @throws InvalidStatusException |
|
486 | - */ |
|
487 | - public static function remove_ejected_registrations(array $registrations) |
|
488 | - { |
|
489 | - $ejected_registrations = EE_SPCO_Reg_Step_Payment_Options::find_registrations_that_lost_their_space( |
|
490 | - $registrations, |
|
491 | - EE_Registry::instance()->SSN->checkout()->revisit |
|
492 | - ); |
|
493 | - foreach ($registrations as $REG_ID => $registration) { |
|
494 | - // has this registration lost it's space ? |
|
495 | - if (isset($ejected_registrations[ $REG_ID ])) { |
|
496 | - unset($registrations[ $REG_ID ]); |
|
497 | - } |
|
498 | - } |
|
499 | - return $registrations; |
|
500 | - } |
|
501 | - |
|
502 | - |
|
503 | - /** |
|
504 | - * find_registrations_that_lost_their_space |
|
505 | - * If a registrant chooses an offline payment method like Invoice, |
|
506 | - * then no space is reserved for them at the event until they fully pay fo that site |
|
507 | - * (unless the event's default reg status is set to APPROVED) |
|
508 | - * if a registrant then later returns to pay, but the number of spaces available has been reduced due to sales, |
|
509 | - * then this method will determine which registrations have lost the ability to complete the reg process. |
|
510 | - * |
|
511 | - * @param EE_Registration[] $registrations |
|
512 | - * @param bool $revisit |
|
513 | - * @return array |
|
514 | - * @throws EE_Error |
|
515 | - * @throws InvalidArgumentException |
|
516 | - * @throws ReflectionException |
|
517 | - * @throws EntityNotFoundException |
|
518 | - * @throws InvalidDataTypeException |
|
519 | - * @throws InvalidInterfaceException |
|
520 | - * @throws InvalidStatusException |
|
521 | - */ |
|
522 | - public static function find_registrations_that_lost_their_space(array $registrations, $revisit = false) |
|
523 | - { |
|
524 | - // registrations per event |
|
525 | - $event_reg_count = []; |
|
526 | - // spaces left per event |
|
527 | - $event_spaces_remaining = []; |
|
528 | - // tickets left sorted by ID |
|
529 | - $tickets_remaining = []; |
|
530 | - // registrations that have lost their space |
|
531 | - $ejected_registrations = []; |
|
532 | - foreach ($registrations as $REG_ID => $registration) { |
|
533 | - if ( |
|
534 | - $registration->status_ID() === EEM_Registration::status_id_approved |
|
535 | - || apply_filters( |
|
536 | - 'FHEE__EE_SPCO_Reg_Step_Payment_Options__find_registrations_that_lost_their_space__allow_reg_payment', |
|
537 | - false, |
|
538 | - $registration, |
|
539 | - $revisit |
|
540 | - ) |
|
541 | - ) { |
|
542 | - continue; |
|
543 | - } |
|
544 | - $EVT_ID = $registration->event_ID(); |
|
545 | - $ticket = $registration->ticket(); |
|
546 | - if (! isset($tickets_remaining[ $ticket->ID() ])) { |
|
547 | - $tickets_remaining[ $ticket->ID() ] = $ticket->remaining(); |
|
548 | - } |
|
549 | - if ($tickets_remaining[ $ticket->ID() ] > 0) { |
|
550 | - if (! isset($event_reg_count[ $EVT_ID ])) { |
|
551 | - $event_reg_count[ $EVT_ID ] = 0; |
|
552 | - } |
|
553 | - $event_reg_count[ $EVT_ID ]++; |
|
554 | - if (! isset($event_spaces_remaining[ $EVT_ID ])) { |
|
555 | - $event_spaces_remaining[ $EVT_ID ] = $registration->event()->spaces_remaining_for_sale(); |
|
556 | - } |
|
557 | - } |
|
558 | - if ( |
|
559 | - $revisit |
|
560 | - && ($tickets_remaining[ $ticket->ID() ] === 0 |
|
561 | - || $event_reg_count[ $EVT_ID ] > $event_spaces_remaining[ $EVT_ID ] |
|
562 | - ) |
|
563 | - ) { |
|
564 | - $ejected_registrations[ $REG_ID ] = $registration->event(); |
|
565 | - if ($registration->status_ID() !== EEM_Registration::status_id_wait_list) { |
|
566 | - /** @type EE_Registration_Processor $registration_processor */ |
|
567 | - $registration_processor = EE_Registry::instance()->load_class('Registration_Processor'); |
|
568 | - // at this point, we should have enough details about the registrant to consider the registration |
|
569 | - // NOT incomplete |
|
570 | - $registration_processor->manually_update_registration_status( |
|
571 | - $registration, |
|
572 | - EEM_Registration::status_id_wait_list |
|
573 | - ); |
|
574 | - } |
|
575 | - } |
|
576 | - } |
|
577 | - return $ejected_registrations; |
|
578 | - } |
|
579 | - |
|
580 | - |
|
581 | - /** |
|
582 | - * _hide_reg_step_submit_button |
|
583 | - * removes the html for the reg step submit button |
|
584 | - * by replacing it with an empty string via filter callback |
|
585 | - * |
|
586 | - * @return void |
|
587 | - */ |
|
588 | - protected function _adjust_registration_status_if_event_old_sold() |
|
589 | - { |
|
590 | - } |
|
591 | - |
|
592 | - |
|
593 | - /** |
|
594 | - * _hide_reg_step_submit_button |
|
595 | - * removes the html for the reg step submit button |
|
596 | - * by replacing it with an empty string via filter callback |
|
597 | - * |
|
598 | - * @return void |
|
599 | - */ |
|
600 | - protected function _hide_reg_step_submit_button_if_revisit() |
|
601 | - { |
|
602 | - if ($this->checkout->revisit) { |
|
603 | - add_filter('FHEE__EE_SPCO_Reg_Step__reg_step_submit_button__sbmt_btn_html', '__return_empty_string'); |
|
604 | - } |
|
605 | - } |
|
606 | - |
|
607 | - |
|
608 | - /** |
|
609 | - * sold_out_events |
|
610 | - * displays notices regarding events that have sold out since hte registrant first signed up |
|
611 | - * |
|
612 | - * @param EE_Event[] $sold_out_events_array |
|
613 | - * @return EE_Form_Section_Proper |
|
614 | - * @throws EE_Error |
|
615 | - */ |
|
616 | - private function _sold_out_events($sold_out_events_array = []) |
|
617 | - { |
|
618 | - // set some defaults |
|
619 | - $this->checkout->selected_method_of_payment = 'events_sold_out'; |
|
620 | - $sold_out_events = ''; |
|
621 | - foreach ($sold_out_events_array as $sold_out_event) { |
|
622 | - $sold_out_events .= EEH_HTML::li( |
|
623 | - EEH_HTML::span( |
|
624 | - ' ' . $sold_out_event->name(), |
|
625 | - '', |
|
626 | - 'dashicons dashicons-marker ee-icon-size-16 pink-text' |
|
627 | - ) |
|
628 | - ); |
|
629 | - } |
|
630 | - return new EE_Form_Section_Proper( |
|
631 | - [ |
|
632 | - 'layout_strategy' => new EE_Template_Layout( |
|
633 | - [ |
|
634 | - 'layout_template_file' => SPCO_REG_STEPS_PATH |
|
635 | - . $this->_slug |
|
636 | - . '/sold_out_events.template.php', |
|
637 | - 'template_args' => apply_filters( |
|
638 | - 'FHEE__EE_SPCO_Reg_Step_Payment_Options___sold_out_events__template_args', |
|
639 | - [ |
|
640 | - 'sold_out_events' => $sold_out_events, |
|
641 | - 'sold_out_events_msg' => apply_filters( |
|
642 | - 'FHEE__EE_SPCO_Reg_Step_Payment_Options___sold_out_events__sold_out_events_msg', |
|
643 | - sprintf( |
|
644 | - esc_html__( |
|
645 | - 'It appears that the event you were about to make a payment for has sold out since you first registered. If you have already made a partial payment towards this event, please contact the event administrator for a refund.%3$s%3$s%1$sPlease note that availability can change at any time due to cancellations, so please check back again later if registration for this event(s) is important to you.%2$s', |
|
646 | - 'event_espresso' |
|
647 | - ), |
|
648 | - '<strong>', |
|
649 | - '</strong>', |
|
650 | - '<br />' |
|
651 | - ) |
|
652 | - ), |
|
653 | - ] |
|
654 | - ), |
|
655 | - ] |
|
656 | - ), |
|
657 | - ] |
|
658 | - ); |
|
659 | - } |
|
660 | - |
|
661 | - |
|
662 | - /** |
|
663 | - * _insufficient_spaces_available |
|
664 | - * displays notices regarding events that do not have enough remaining spaces |
|
665 | - * to satisfy the current number of registrations looking to pay |
|
666 | - * |
|
667 | - * @param EE_Event[] $insufficient_spaces_events_array |
|
668 | - * @return EE_Form_Section_Proper |
|
669 | - * @throws EE_Error |
|
670 | - * @throws ReflectionException |
|
671 | - */ |
|
672 | - private function _insufficient_spaces_available($insufficient_spaces_events_array = []) |
|
673 | - { |
|
674 | - // set some defaults |
|
675 | - $this->checkout->selected_method_of_payment = 'invoice'; |
|
676 | - $insufficient_space_events = ''; |
|
677 | - foreach ($insufficient_spaces_events_array as $event) { |
|
678 | - if ($event instanceof EE_Event) { |
|
679 | - $insufficient_space_events .= EEH_HTML::li( |
|
680 | - EEH_HTML::span(' ' . $event->name(), '', 'dashicons dashicons-marker ee-icon-size-16 pink-text') |
|
681 | - ); |
|
682 | - } |
|
683 | - } |
|
684 | - return new EE_Form_Section_Proper( |
|
685 | - [ |
|
686 | - 'subsections' => [ |
|
687 | - 'default_hidden_inputs' => $this->reg_step_hidden_inputs(), |
|
688 | - 'extra_hidden_inputs' => $this->_extra_hidden_inputs(), |
|
689 | - ], |
|
690 | - 'layout_strategy' => new EE_Template_Layout( |
|
691 | - [ |
|
692 | - 'layout_template_file' => SPCO_REG_STEPS_PATH |
|
693 | - . $this->_slug |
|
694 | - . '/sold_out_events.template.php', |
|
695 | - 'template_args' => apply_filters( |
|
696 | - 'FHEE__EE_SPCO_Reg_Step_Payment_Options___insufficient_spaces_available__template_args', |
|
697 | - [ |
|
698 | - 'sold_out_events' => $insufficient_space_events, |
|
699 | - 'sold_out_events_msg' => apply_filters( |
|
700 | - 'FHEE__EE_SPCO_Reg_Step_Payment_Options___insufficient_spaces_available__insufficient_space_msg', |
|
701 | - esc_html__( |
|
702 | - 'It appears that the event you were about to make a payment for has sold additional tickets since you first registered, and there are no longer enough spaces left to accommodate your selections. You may continue to pay and secure the available space(s) remaining, or simply cancel if you no longer wish to purchase. If you have already made a partial payment towards this event, please contact the event administrator for a refund.', |
|
703 | - 'event_espresso' |
|
704 | - ) |
|
705 | - ), |
|
706 | - ] |
|
707 | - ), |
|
708 | - ] |
|
709 | - ), |
|
710 | - ] |
|
711 | - ); |
|
712 | - } |
|
713 | - |
|
714 | - |
|
715 | - /** |
|
716 | - * registrations_requiring_pre_approval |
|
717 | - * |
|
718 | - * @param array $registrations_requiring_pre_approval |
|
719 | - * @return EE_Form_Section_Proper |
|
720 | - * @throws EE_Error |
|
721 | - * @throws EntityNotFoundException |
|
722 | - * @throws ReflectionException |
|
723 | - */ |
|
724 | - private function _registrations_requiring_pre_approval($registrations_requiring_pre_approval = []) |
|
725 | - { |
|
726 | - $events_requiring_pre_approval = []; |
|
727 | - foreach ($registrations_requiring_pre_approval as $registration) { |
|
728 | - if ($registration instanceof EE_Registration && $registration->event() instanceof EE_Event) { |
|
729 | - $events_requiring_pre_approval[ $registration->event()->ID() ] = EEH_HTML::li( |
|
730 | - EEH_HTML::span( |
|
731 | - '', |
|
732 | - '', |
|
733 | - 'dashicons dashicons-marker ee-icon-size-16 orange-text' |
|
734 | - ) |
|
735 | - . EEH_HTML::span($registration->event()->name(), '', 'orange-text') |
|
736 | - ); |
|
737 | - } |
|
738 | - } |
|
739 | - return new EE_Form_Section_Proper( |
|
740 | - [ |
|
741 | - 'layout_strategy' => new EE_Template_Layout( |
|
742 | - [ |
|
743 | - 'layout_template_file' => SPCO_REG_STEPS_PATH |
|
744 | - . $this->_slug |
|
745 | - . '/events_requiring_pre_approval.template.php', // layout_template |
|
746 | - 'template_args' => apply_filters( |
|
747 | - 'FHEE__EE_SPCO_Reg_Step_Payment_Options___sold_out_events__template_args', |
|
748 | - [ |
|
749 | - 'events_requiring_pre_approval' => implode('', $events_requiring_pre_approval), |
|
750 | - 'events_requiring_pre_approval_msg' => apply_filters( |
|
751 | - 'FHEE__EE_SPCO_Reg_Step_Payment_Options___events_requiring_pre_approval__events_requiring_pre_approval_msg', |
|
752 | - esc_html__( |
|
753 | - 'The following events do not require payment at this time and will not be billed during this transaction. Billing will only occur after the attendee has been approved by the event organizer. You will be notified when your registration has been processed. If this is a free event, then no billing will occur.', |
|
754 | - 'event_espresso' |
|
755 | - ) |
|
756 | - ), |
|
757 | - ] |
|
758 | - ), |
|
759 | - ] |
|
760 | - ), |
|
761 | - ] |
|
762 | - ); |
|
763 | - } |
|
764 | - |
|
765 | - |
|
766 | - /** |
|
767 | - * _no_payment_required |
|
768 | - * |
|
769 | - * @param EE_Event[] $registrations_for_free_events |
|
770 | - * @return EE_Form_Section_Proper |
|
771 | - * @throws EE_Error |
|
772 | - */ |
|
773 | - private function _no_payment_required($registrations_for_free_events = []) |
|
774 | - { |
|
775 | - // set some defaults |
|
776 | - $this->checkout->selected_method_of_payment = 'no_payment_required'; |
|
777 | - // generate no_payment_required form |
|
778 | - return new EE_Form_Section_Proper( |
|
779 | - [ |
|
780 | - 'layout_strategy' => new EE_Template_Layout( |
|
781 | - [ |
|
782 | - 'layout_template_file' => SPCO_REG_STEPS_PATH |
|
783 | - . $this->_slug |
|
784 | - . '/no_payment_required.template.php', // layout_template |
|
785 | - 'template_args' => apply_filters( |
|
786 | - 'FHEE__EE_SPCO_Reg_Step_Payment_Options___no_payment_required__template_args', |
|
787 | - [ |
|
788 | - 'revisit' => $this->checkout->revisit, |
|
789 | - 'registrations' => [], |
|
790 | - 'ticket_count' => [], |
|
791 | - 'registrations_for_free_events' => $registrations_for_free_events, |
|
792 | - 'no_payment_required_msg' => EEH_HTML::p( |
|
793 | - esc_html__('This is a free event, so no billing will occur.', 'event_espresso') |
|
794 | - ), |
|
795 | - ] |
|
796 | - ), |
|
797 | - ] |
|
798 | - ), |
|
799 | - ] |
|
800 | - ); |
|
801 | - } |
|
802 | - |
|
803 | - |
|
804 | - /** |
|
805 | - * _display_payment_options |
|
806 | - * |
|
807 | - * @param string $transaction_details |
|
808 | - * @return EE_Form_Section_Proper |
|
809 | - * @throws EE_Error |
|
810 | - * @throws InvalidArgumentException |
|
811 | - * @throws InvalidDataTypeException |
|
812 | - * @throws InvalidInterfaceException |
|
813 | - */ |
|
814 | - private function _display_payment_options($transaction_details = '') |
|
815 | - { |
|
816 | - // has method_of_payment been set by no-js user? |
|
817 | - $this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment(); |
|
818 | - // build payment options form |
|
819 | - return apply_filters( |
|
820 | - 'FHEE__EE_SPCO_Reg_Step_Payment_Options___display_payment_options__payment_options_form', |
|
821 | - new EE_Form_Section_Proper( |
|
822 | - [ |
|
823 | - 'subsections' => [ |
|
824 | - 'before_payment_options' => apply_filters( |
|
825 | - 'FHEE__EE_SPCO_Reg_Step_Payment_Options___display_payment_options__before_payment_options', |
|
826 | - new EE_Form_Section_Proper( |
|
827 | - ['layout_strategy' => new EE_Div_Per_Section_Layout()] |
|
828 | - ) |
|
829 | - ), |
|
830 | - 'payment_options' => $this->_setup_payment_options(), |
|
831 | - 'after_payment_options' => apply_filters( |
|
832 | - 'FHEE__EE_SPCO_Reg_Step_Payment_Options___display_payment_options__after_payment_options', |
|
833 | - new EE_Form_Section_Proper( |
|
834 | - ['layout_strategy' => new EE_Div_Per_Section_Layout()] |
|
835 | - ) |
|
836 | - ), |
|
837 | - ], |
|
838 | - 'layout_strategy' => new EE_Template_Layout( |
|
839 | - [ |
|
840 | - 'layout_template_file' => $this->_template, |
|
841 | - 'template_args' => apply_filters( |
|
842 | - 'FHEE__EE_SPCO_Reg_Step_Payment_Options___display_payment_options__template_args', |
|
843 | - [ |
|
844 | - 'reg_count' => $this->line_item_display->total_items(), |
|
845 | - 'transaction_details' => $transaction_details, |
|
846 | - 'available_payment_methods' => [], |
|
847 | - ] |
|
848 | - ), |
|
849 | - ] |
|
850 | - ), |
|
851 | - ] |
|
852 | - ) |
|
853 | - ); |
|
854 | - } |
|
855 | - |
|
856 | - |
|
857 | - /** |
|
858 | - * _extra_hidden_inputs |
|
859 | - * |
|
860 | - * @param bool $no_payment_required |
|
861 | - * @return EE_Form_Section_Proper |
|
862 | - * @throws EE_Error |
|
863 | - * @throws ReflectionException |
|
864 | - */ |
|
865 | - private function _extra_hidden_inputs($no_payment_required = true) |
|
866 | - { |
|
867 | - return new EE_Form_Section_Proper( |
|
868 | - [ |
|
869 | - 'html_id' => 'ee-' . $this->slug() . '-extra-hidden-inputs', |
|
870 | - 'layout_strategy' => new EE_Div_Per_Section_Layout(), |
|
871 | - 'subsections' => [ |
|
872 | - 'spco_no_payment_required' => new EE_Hidden_Input( |
|
873 | - [ |
|
874 | - 'normalization_strategy' => new EE_Boolean_Normalization(), |
|
875 | - 'html_name' => 'spco_no_payment_required', |
|
876 | - 'html_id' => 'spco-no-payment-required-payment_options', |
|
877 | - 'default' => $no_payment_required, |
|
878 | - ] |
|
879 | - ), |
|
880 | - 'spco_transaction_id' => new EE_Fixed_Hidden_Input( |
|
881 | - [ |
|
882 | - 'normalization_strategy' => new EE_Int_Normalization(), |
|
883 | - 'html_name' => 'spco_transaction_id', |
|
884 | - 'html_id' => 'spco-transaction-id', |
|
885 | - 'default' => $this->checkout->transaction->ID(), |
|
886 | - ] |
|
887 | - ), |
|
888 | - ], |
|
889 | - ] |
|
890 | - ); |
|
891 | - } |
|
892 | - |
|
893 | - |
|
894 | - /** |
|
895 | - * _apply_registration_payments_to_amount_owing |
|
896 | - * |
|
897 | - * @param array $registrations |
|
898 | - * @throws EE_Error |
|
899 | - */ |
|
900 | - protected function _apply_registration_payments_to_amount_owing(array $registrations) |
|
901 | - { |
|
902 | - $payments = []; |
|
903 | - foreach ($registrations as $registration) { |
|
904 | - if ($registration instanceof EE_Registration && $registration->owes_monies_and_can_pay()) { |
|
905 | - $payments += $registration->registration_payments(); |
|
906 | - } |
|
907 | - } |
|
908 | - if (! empty($payments)) { |
|
909 | - foreach ($payments as $payment) { |
|
910 | - if ($payment instanceof EE_Registration_Payment) { |
|
911 | - $this->checkout->amount_owing -= $payment->amount(); |
|
912 | - } |
|
913 | - } |
|
914 | - } |
|
915 | - } |
|
916 | - |
|
917 | - |
|
918 | - /** |
|
919 | - * _reset_selected_method_of_payment |
|
920 | - * |
|
921 | - * @access private |
|
922 | - * @param bool $force_reset |
|
923 | - * @return void |
|
924 | - * @throws InvalidArgumentException |
|
925 | - * @throws InvalidDataTypeException |
|
926 | - * @throws InvalidInterfaceException |
|
927 | - */ |
|
928 | - private function _reset_selected_method_of_payment($force_reset = false) |
|
929 | - { |
|
930 | - /** @var RequestInterface $request */ |
|
931 | - $request = LoaderFactory::getLoader()->getShared(RequestInterface::class); |
|
932 | - $reset_payment_method = $request->getRequestParam('reset_payment_method', $force_reset, 'bool'); |
|
933 | - if ($reset_payment_method) { |
|
934 | - $this->checkout->selected_method_of_payment = null; |
|
935 | - $this->checkout->payment_method = null; |
|
936 | - $this->checkout->billing_form = null; |
|
937 | - $this->_save_selected_method_of_payment(); |
|
938 | - } |
|
939 | - } |
|
940 | - |
|
941 | - |
|
942 | - /** |
|
943 | - * _save_selected_method_of_payment |
|
944 | - * stores the selected_method_of_payment in the session |
|
945 | - * so that it's available for all subsequent requests including AJAX |
|
946 | - * |
|
947 | - * @access private |
|
948 | - * @param string $selected_method_of_payment |
|
949 | - * @return void |
|
950 | - * @throws InvalidArgumentException |
|
951 | - * @throws InvalidDataTypeException |
|
952 | - * @throws InvalidInterfaceException |
|
953 | - */ |
|
954 | - private function _save_selected_method_of_payment($selected_method_of_payment = '') |
|
955 | - { |
|
956 | - $selected_method_of_payment = ! empty($selected_method_of_payment) |
|
957 | - ? $selected_method_of_payment |
|
958 | - : $this->checkout->selected_method_of_payment; |
|
959 | - EE_Registry::instance()->SSN->set_session_data( |
|
960 | - ['selected_method_of_payment' => $selected_method_of_payment] |
|
961 | - ); |
|
962 | - } |
|
963 | - |
|
964 | - |
|
965 | - /** |
|
966 | - * _setup_payment_options |
|
967 | - * |
|
968 | - * @return EE_Form_Section_Proper |
|
969 | - * @throws EE_Error |
|
970 | - * @throws InvalidArgumentException |
|
971 | - * @throws InvalidDataTypeException |
|
972 | - * @throws InvalidInterfaceException |
|
973 | - */ |
|
974 | - public function _setup_payment_options() |
|
975 | - { |
|
976 | - // load payment method classes |
|
977 | - $this->checkout->available_payment_methods = $this->_get_available_payment_methods(); |
|
978 | - if (empty($this->checkout->available_payment_methods)) { |
|
979 | - EE_Error::add_error( |
|
980 | - apply_filters( |
|
981 | - 'FHEE__EE_SPCO_Reg_Step_Payment_Options___setup_payment_options__error_message_no_payment_methods', |
|
982 | - sprintf( |
|
983 | - esc_html__( |
|
984 | - 'Sorry, you cannot complete your purchase because a payment method is not active.%1$s Please contact %2$s for assistance and provide a description of the problem.', |
|
985 | - 'event_espresso' |
|
986 | - ), |
|
987 | - '<br>', |
|
988 | - EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
989 | - ) |
|
990 | - ), |
|
991 | - __FILE__, |
|
992 | - __FUNCTION__, |
|
993 | - __LINE__ |
|
994 | - ); |
|
995 | - } |
|
996 | - // switch up header depending on number of available payment methods |
|
997 | - $payment_method_header = count($this->checkout->available_payment_methods) > 1 |
|
998 | - ? apply_filters( |
|
999 | - 'FHEE__registration_page_payment_options__method_of_payment_hdr', |
|
1000 | - esc_html__('Please Select Your Method of Payment', 'event_espresso') |
|
1001 | - ) |
|
1002 | - : apply_filters( |
|
1003 | - 'FHEE__registration_page_payment_options__method_of_payment_hdr', |
|
1004 | - esc_html__('Method of Payment', 'event_espresso') |
|
1005 | - ); |
|
1006 | - $available_payment_methods = [ |
|
1007 | - // display the "Payment Method" header |
|
1008 | - 'payment_method_header' => new EE_Form_Section_HTML( |
|
1009 | - apply_filters( |
|
1010 | - 'FHEE__EE_SPCO_Reg_Step_Payment_Options___setup_payment_options__payment_method_header', |
|
1011 | - EEH_HTML::h4($payment_method_header, 'method-of-payment-hdr'), |
|
1012 | - $payment_method_header |
|
1013 | - ) |
|
1014 | - ), |
|
1015 | - ]; |
|
1016 | - // the list of actual payment methods ( invoice, paypal, etc ) in a ( slug => HTML ) format |
|
1017 | - $available_payment_method_options = []; |
|
1018 | - $default_payment_method_option = []; |
|
1019 | - // additional instructions to be displayed and hidden below payment methods (adding a clearing div to start) |
|
1020 | - $payment_methods_billing_info = [ |
|
1021 | - new EE_Form_Section_HTML( |
|
1022 | - EEH_HTML::div('<br />', '', '', 'clear:both;') |
|
1023 | - ), |
|
1024 | - ]; |
|
1025 | - // loop through payment methods |
|
1026 | - foreach ($this->checkout->available_payment_methods as $payment_method) { |
|
1027 | - if ($payment_method instanceof EE_Payment_Method) { |
|
1028 | - $payment_method_button = EEH_HTML::img( |
|
1029 | - $payment_method->button_url(), |
|
1030 | - $payment_method->name(), |
|
1031 | - 'spco-payment-method-' . $payment_method->slug() . '-btn-img', |
|
1032 | - 'spco-payment-method-btn-img' |
|
1033 | - ); |
|
1034 | - // check if any payment methods are set as default |
|
1035 | - // if payment method is already selected OR nothing is selected and this payment method should be |
|
1036 | - // open_by_default |
|
1037 | - if ( |
|
1038 | - ($this->checkout->selected_method_of_payment === $payment_method->slug()) |
|
1039 | - || (! $this->checkout->selected_method_of_payment && $payment_method->open_by_default()) |
|
1040 | - ) { |
|
1041 | - $this->checkout->selected_method_of_payment = $payment_method->slug(); |
|
1042 | - $this->_save_selected_method_of_payment(); |
|
1043 | - $default_payment_method_option[ $payment_method->slug() ] = $payment_method_button; |
|
1044 | - } else { |
|
1045 | - $available_payment_method_options[ $payment_method->slug() ] = $payment_method_button; |
|
1046 | - } |
|
1047 | - $payment_methods_billing_info[ $payment_method->slug() . '-info' ] = |
|
1048 | - $this->_payment_method_billing_info( |
|
1049 | - $payment_method |
|
1050 | - ); |
|
1051 | - } |
|
1052 | - } |
|
1053 | - // prepend available_payment_method_options with default_payment_method_option so that it appears first in list |
|
1054 | - // of PMs |
|
1055 | - $available_payment_method_options = $default_payment_method_option + $available_payment_method_options; |
|
1056 | - // now generate the actual form inputs |
|
1057 | - $available_payment_methods['available_payment_methods'] = $this->_available_payment_method_inputs( |
|
1058 | - $available_payment_method_options |
|
1059 | - ); |
|
1060 | - $available_payment_methods += $payment_methods_billing_info; |
|
1061 | - // build the available payment methods form |
|
1062 | - return new EE_Form_Section_Proper( |
|
1063 | - [ |
|
1064 | - 'html_id' => 'spco-available-methods-of-payment-dv', |
|
1065 | - 'subsections' => $available_payment_methods, |
|
1066 | - 'layout_strategy' => new EE_Div_Per_Section_Layout(), |
|
1067 | - ] |
|
1068 | - ); |
|
1069 | - } |
|
1070 | - |
|
1071 | - |
|
1072 | - /** |
|
1073 | - * _get_available_payment_methods |
|
1074 | - * |
|
1075 | - * @return EE_Payment_Method[] |
|
1076 | - * @throws EE_Error |
|
1077 | - * @throws InvalidArgumentException |
|
1078 | - * @throws InvalidDataTypeException |
|
1079 | - * @throws InvalidInterfaceException |
|
1080 | - */ |
|
1081 | - protected function _get_available_payment_methods() |
|
1082 | - { |
|
1083 | - if (! empty($this->checkout->available_payment_methods)) { |
|
1084 | - return $this->checkout->available_payment_methods; |
|
1085 | - } |
|
1086 | - $available_payment_methods = []; |
|
1087 | - $EEM_Payment_Method = EEM_Payment_Method::instance(); |
|
1088 | - // get all active payment methods |
|
1089 | - $payment_methods = $EEM_Payment_Method->get_all_for_transaction( |
|
1090 | - $this->checkout->transaction, |
|
1091 | - EEM_Payment_Method::scope_cart |
|
1092 | - ); |
|
1093 | - foreach ($payment_methods as $payment_method) { |
|
1094 | - if ($payment_method instanceof EE_Payment_Method) { |
|
1095 | - $available_payment_methods[ $payment_method->slug() ] = $payment_method; |
|
1096 | - } |
|
1097 | - } |
|
1098 | - return $available_payment_methods; |
|
1099 | - } |
|
1100 | - |
|
1101 | - |
|
1102 | - /** |
|
1103 | - * _available_payment_method_inputs |
|
1104 | - * |
|
1105 | - * @access private |
|
1106 | - * @param array $available_payment_method_options |
|
1107 | - * @return EE_Form_Section_Proper |
|
1108 | - * @throws EE_Error |
|
1109 | - * @throws EE_Error |
|
1110 | - */ |
|
1111 | - private function _available_payment_method_inputs($available_payment_method_options = []) |
|
1112 | - { |
|
1113 | - // generate inputs |
|
1114 | - return new EE_Form_Section_Proper( |
|
1115 | - [ |
|
1116 | - 'html_id' => 'ee-available-payment-method-inputs', |
|
1117 | - 'layout_strategy' => new EE_Div_Per_Section_Layout(), |
|
1118 | - 'subsections' => [ |
|
1119 | - '' => new EE_Radio_Button_Input( |
|
1120 | - $available_payment_method_options, |
|
1121 | - [ |
|
1122 | - 'html_name' => 'selected_method_of_payment', |
|
1123 | - 'html_class' => 'spco-payment-method', |
|
1124 | - 'default' => $this->checkout->selected_method_of_payment, |
|
1125 | - 'label_size' => 11, |
|
1126 | - 'enforce_label_size' => true, |
|
1127 | - ] |
|
1128 | - ), |
|
1129 | - ], |
|
1130 | - ] |
|
1131 | - ); |
|
1132 | - } |
|
1133 | - |
|
1134 | - |
|
1135 | - /** |
|
1136 | - * _payment_method_billing_info |
|
1137 | - * |
|
1138 | - * @access private |
|
1139 | - * @param EE_Payment_Method $payment_method |
|
1140 | - * @return EE_Form_Section_Proper |
|
1141 | - * @throws EE_Error |
|
1142 | - * @throws InvalidArgumentException |
|
1143 | - * @throws InvalidDataTypeException |
|
1144 | - * @throws InvalidInterfaceException |
|
1145 | - */ |
|
1146 | - private function _payment_method_billing_info(EE_Payment_Method $payment_method) |
|
1147 | - { |
|
1148 | - $currently_selected = $this->checkout->selected_method_of_payment === $payment_method->slug(); |
|
1149 | - // generate the billing form for payment method |
|
1150 | - $billing_form = $currently_selected |
|
1151 | - ? $this->_get_billing_form_for_payment_method($payment_method) |
|
1152 | - : new EE_Form_Section_HTML(); |
|
1153 | - $this->checkout->billing_form = $currently_selected |
|
1154 | - ? $billing_form |
|
1155 | - : $this->checkout->billing_form; |
|
1156 | - // it's all in the details |
|
1157 | - $info_html = EEH_HTML::h3( |
|
1158 | - esc_html__('Important information regarding your payment', 'event_espresso'), |
|
1159 | - '', |
|
1160 | - 'spco-payment-method-hdr' |
|
1161 | - ); |
|
1162 | - // add some info regarding the step, either from what's saved in the admin, |
|
1163 | - // or a default string depending on whether the PM has a billing form or not |
|
1164 | - if ($payment_method->description()) { |
|
1165 | - $payment_method_info = $payment_method->description(); |
|
1166 | - } elseif ($billing_form instanceof EE_Billing_Info_Form) { |
|
1167 | - $payment_method_info = sprintf( |
|
1168 | - esc_html__( |
|
1169 | - 'Please provide the following billing information, then click the "%1$s" button below in order to proceed.', |
|
1170 | - 'event_espresso' |
|
1171 | - ), |
|
1172 | - $this->submit_button_text() |
|
1173 | - ); |
|
1174 | - } else { |
|
1175 | - $payment_method_info = sprintf( |
|
1176 | - esc_html__('Please click the "%1$s" button below in order to proceed.', 'event_espresso'), |
|
1177 | - $this->submit_button_text() |
|
1178 | - ); |
|
1179 | - } |
|
1180 | - $info_html .= EEH_HTML::div( |
|
1181 | - apply_filters( |
|
1182 | - 'FHEE__EE_SPCO_Reg_Step_Payment_Options___payment_method_billing_info__payment_method_info', |
|
1183 | - $payment_method_info |
|
1184 | - ), |
|
1185 | - '', |
|
1186 | - 'spco-payment-method-desc ee-attention' |
|
1187 | - ); |
|
1188 | - return new EE_Form_Section_Proper( |
|
1189 | - [ |
|
1190 | - 'html_id' => 'spco-payment-method-info-' . $payment_method->slug(), |
|
1191 | - 'html_class' => 'spco-payment-method-info-dv', |
|
1192 | - // only display the selected or default PM |
|
1193 | - 'html_style' => $currently_selected ? '' : 'display:none;', |
|
1194 | - 'layout_strategy' => new EE_Div_Per_Section_Layout(), |
|
1195 | - 'subsections' => [ |
|
1196 | - 'info' => new EE_Form_Section_HTML($info_html), |
|
1197 | - 'billing_form' => $currently_selected ? $billing_form : new EE_Form_Section_HTML(), |
|
1198 | - ], |
|
1199 | - ] |
|
1200 | - ); |
|
1201 | - } |
|
1202 | - |
|
1203 | - |
|
1204 | - /** |
|
1205 | - * get_billing_form_html_for_payment_method |
|
1206 | - * |
|
1207 | - * @return bool |
|
1208 | - * @throws EE_Error |
|
1209 | - * @throws InvalidArgumentException |
|
1210 | - * @throws ReflectionException |
|
1211 | - * @throws InvalidDataTypeException |
|
1212 | - * @throws InvalidInterfaceException |
|
1213 | - */ |
|
1214 | - public function get_billing_form_html_for_payment_method() |
|
1215 | - { |
|
1216 | - // how have they chosen to pay? |
|
1217 | - $this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment(true); |
|
1218 | - $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment(); |
|
1219 | - if (! $this->checkout->payment_method instanceof EE_Payment_Method) { |
|
1220 | - return false; |
|
1221 | - } |
|
1222 | - if ( |
|
1223 | - apply_filters( |
|
1224 | - 'FHEE__EE_SPCO_Reg_Step_Payment_Options__registration_checkout__selected_payment_method__display_success', |
|
1225 | - false |
|
1226 | - ) |
|
1227 | - ) { |
|
1228 | - EE_Error::add_success( |
|
1229 | - apply_filters( |
|
1230 | - 'FHEE__Single_Page_Checkout__registration_checkout__selected_payment_method', |
|
1231 | - sprintf( |
|
1232 | - esc_html__( |
|
1233 | - 'You have selected "%s" as your method of payment. Please note the important payment information below.', |
|
1234 | - 'event_espresso' |
|
1235 | - ), |
|
1236 | - $this->checkout->payment_method->name() |
|
1237 | - ) |
|
1238 | - ) |
|
1239 | - ); |
|
1240 | - } |
|
1241 | - // now generate billing form for selected method of payment |
|
1242 | - $payment_method_billing_form = $this->_get_billing_form_for_payment_method($this->checkout->payment_method); |
|
1243 | - // fill form with attendee info if applicable |
|
1244 | - if ( |
|
1245 | - $payment_method_billing_form instanceof EE_Billing_Attendee_Info_Form |
|
1246 | - && $this->checkout->transaction_has_primary_registrant() |
|
1247 | - ) { |
|
1248 | - $payment_method_billing_form->populate_from_attendee( |
|
1249 | - $this->checkout->transaction->primary_registration()->attendee() |
|
1250 | - ); |
|
1251 | - } |
|
1252 | - // and debug content |
|
1253 | - if ( |
|
1254 | - $payment_method_billing_form instanceof EE_Billing_Info_Form |
|
1255 | - && $this->checkout->payment_method->type_obj() instanceof EE_PMT_Base |
|
1256 | - ) { |
|
1257 | - $payment_method_billing_form = |
|
1258 | - $this->checkout->payment_method->type_obj()->apply_billing_form_debug_settings( |
|
1259 | - $payment_method_billing_form |
|
1260 | - ); |
|
1261 | - } |
|
1262 | - $billing_info = $payment_method_billing_form instanceof EE_Form_Section_Proper |
|
1263 | - ? $payment_method_billing_form->get_html() |
|
1264 | - : ''; |
|
1265 | - $this->checkout->json_response->set_return_data(['payment_method_info' => $billing_info]); |
|
1266 | - // localize validation rules for main form |
|
1267 | - $this->checkout->current_step->reg_form->localize_validation_rules(); |
|
1268 | - $this->checkout->json_response->add_validation_rules(EE_Form_Section_Proper::js_localization()); |
|
1269 | - return true; |
|
1270 | - } |
|
1271 | - |
|
1272 | - |
|
1273 | - /** |
|
1274 | - * _get_billing_form_for_payment_method |
|
1275 | - * |
|
1276 | - * @param EE_Payment_Method $payment_method |
|
1277 | - * @return EE_Billing_Info_Form|EE_Billing_Attendee_Info_Form|EE_Form_Section_HTML |
|
1278 | - * @throws EE_Error |
|
1279 | - * @throws InvalidArgumentException |
|
1280 | - * @throws InvalidDataTypeException |
|
1281 | - * @throws InvalidInterfaceException |
|
1282 | - */ |
|
1283 | - private function _get_billing_form_for_payment_method(EE_Payment_Method $payment_method) |
|
1284 | - { |
|
1285 | - $billing_form = $payment_method->type_obj()->billing_form( |
|
1286 | - $this->checkout->transaction, |
|
1287 | - ['amount_owing' => $this->checkout->amount_owing] |
|
1288 | - ); |
|
1289 | - if ($billing_form instanceof EE_Billing_Info_Form) { |
|
1290 | - if ( |
|
1291 | - apply_filters( |
|
1292 | - 'FHEE__EE_SPCO_Reg_Step_Payment_Options__registration_checkout__selected_payment_method__display_success', |
|
1293 | - false |
|
1294 | - ) |
|
1295 | - && $this->request->requestParamIsSet('payment_method') |
|
1296 | - ) { |
|
1297 | - EE_Error::add_success( |
|
1298 | - apply_filters( |
|
1299 | - 'FHEE__Single_Page_Checkout__registration_checkout__selected_payment_method', |
|
1300 | - sprintf( |
|
1301 | - esc_html__( |
|
1302 | - 'You have selected "%s" as your method of payment. Please note the important payment information below.', |
|
1303 | - 'event_espresso' |
|
1304 | - ), |
|
1305 | - $payment_method->name() |
|
1306 | - ) |
|
1307 | - ) |
|
1308 | - ); |
|
1309 | - } |
|
1310 | - return apply_filters( |
|
1311 | - 'FHEE__EE_SPCO_Reg_Step_Payment_Options___get_billing_form_for_payment_method__billing_form', |
|
1312 | - $billing_form, |
|
1313 | - $payment_method |
|
1314 | - ); |
|
1315 | - } |
|
1316 | - // no actual billing form, so return empty HTML form section |
|
1317 | - return new EE_Form_Section_HTML(); |
|
1318 | - } |
|
1319 | - |
|
1320 | - |
|
1321 | - /** |
|
1322 | - * _get_selected_method_of_payment |
|
1323 | - * |
|
1324 | - * @param boolean $required whether to throw an error if the "selected_method_of_payment" |
|
1325 | - * is not found in the incoming request |
|
1326 | - * @param string $request_param |
|
1327 | - * @return NULL|string |
|
1328 | - * @throws EE_Error |
|
1329 | - * @throws InvalidArgumentException |
|
1330 | - * @throws InvalidDataTypeException |
|
1331 | - * @throws InvalidInterfaceException |
|
1332 | - */ |
|
1333 | - private function _get_selected_method_of_payment( |
|
1334 | - $required = false, |
|
1335 | - $request_param = 'selected_method_of_payment' |
|
1336 | - ) { |
|
1337 | - // is selected_method_of_payment set in the request ? |
|
1338 | - $selected_method_of_payment = $this->request->getRequestParam($request_param); |
|
1339 | - if ($selected_method_of_payment) { |
|
1340 | - // sanitize it |
|
1341 | - $selected_method_of_payment = is_array($selected_method_of_payment) |
|
1342 | - ? array_shift($selected_method_of_payment) |
|
1343 | - : $selected_method_of_payment; |
|
1344 | - $selected_method_of_payment = sanitize_text_field($selected_method_of_payment); |
|
1345 | - // store it in the session so that it's available for all subsequent requests including AJAX |
|
1346 | - $this->_save_selected_method_of_payment($selected_method_of_payment); |
|
1347 | - } else { |
|
1348 | - // or is is set in the session ? |
|
1349 | - $selected_method_of_payment = EE_Registry::instance()->SSN->get_session_data( |
|
1350 | - 'selected_method_of_payment' |
|
1351 | - ); |
|
1352 | - } |
|
1353 | - // do ya really really gotta have it? |
|
1354 | - if (empty($selected_method_of_payment) && $required) { |
|
1355 | - EE_Error::add_error( |
|
1356 | - sprintf( |
|
1357 | - esc_html__( |
|
1358 | - 'The selected method of payment could not be determined.%sPlease ensure that you have selected one before proceeding.%sIf you continue to experience difficulties, then refresh your browser and try again, or contact %s for assistance.', |
|
1359 | - 'event_espresso' |
|
1360 | - ), |
|
1361 | - '<br/>', |
|
1362 | - '<br/>', |
|
1363 | - EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
1364 | - ), |
|
1365 | - __FILE__, |
|
1366 | - __FUNCTION__, |
|
1367 | - __LINE__ |
|
1368 | - ); |
|
1369 | - return null; |
|
1370 | - } |
|
1371 | - return $selected_method_of_payment; |
|
1372 | - } |
|
1373 | - |
|
1374 | - |
|
1375 | - |
|
1376 | - |
|
1377 | - |
|
1378 | - |
|
1379 | - /********************************************************************************************************/ |
|
1380 | - /*********************************** SWITCH PAYMENT METHOD ************************************/ |
|
1381 | - /********************************************************************************************************/ |
|
1382 | - /** |
|
1383 | - * switch_payment_method |
|
1384 | - * |
|
1385 | - * @return bool |
|
1386 | - * @throws EE_Error |
|
1387 | - * @throws InvalidArgumentException |
|
1388 | - * @throws InvalidDataTypeException |
|
1389 | - * @throws InvalidInterfaceException |
|
1390 | - * @throws ReflectionException |
|
1391 | - */ |
|
1392 | - public function switch_payment_method() |
|
1393 | - { |
|
1394 | - if (! $this->_verify_payment_method_is_set()) { |
|
1395 | - return false; |
|
1396 | - } |
|
1397 | - if ( |
|
1398 | - apply_filters( |
|
1399 | - 'FHEE__EE_SPCO_Reg_Step_Payment_Options__registration_checkout__selected_payment_method__display_success', |
|
1400 | - false |
|
1401 | - ) |
|
1402 | - ) { |
|
1403 | - EE_Error::add_success( |
|
1404 | - apply_filters( |
|
1405 | - 'FHEE__Single_Page_Checkout__registration_checkout__selected_payment_method', |
|
1406 | - sprintf( |
|
1407 | - esc_html__( |
|
1408 | - 'You have selected "%s" as your method of payment. Please note the important payment information below.', |
|
1409 | - 'event_espresso' |
|
1410 | - ), |
|
1411 | - $this->checkout->payment_method->name() |
|
1412 | - ) |
|
1413 | - ) |
|
1414 | - ); |
|
1415 | - } |
|
1416 | - // generate billing form for selected method of payment if it hasn't been done already |
|
1417 | - if ($this->checkout->payment_method->type_obj()->has_billing_form()) { |
|
1418 | - $this->checkout->billing_form = $this->_get_billing_form_for_payment_method( |
|
1419 | - $this->checkout->payment_method |
|
1420 | - ); |
|
1421 | - } |
|
1422 | - // fill form with attendee info if applicable |
|
1423 | - if ( |
|
1424 | - apply_filters( |
|
1425 | - 'FHEE__populate_billing_form_fields_from_attendee', |
|
1426 | - ( |
|
1427 | - $this->checkout->billing_form instanceof EE_Billing_Attendee_Info_Form |
|
1428 | - && $this->checkout->transaction_has_primary_registrant() |
|
1429 | - ), |
|
1430 | - $this->checkout->billing_form, |
|
1431 | - $this->checkout->transaction |
|
1432 | - ) |
|
1433 | - ) { |
|
1434 | - $this->checkout->billing_form->populate_from_attendee( |
|
1435 | - $this->checkout->transaction->primary_registration()->attendee() |
|
1436 | - ); |
|
1437 | - } |
|
1438 | - // and debug content |
|
1439 | - if ( |
|
1440 | - $this->checkout->billing_form instanceof EE_Billing_Info_Form |
|
1441 | - && $this->checkout->payment_method->type_obj() instanceof EE_PMT_Base |
|
1442 | - ) { |
|
1443 | - $this->checkout->billing_form = |
|
1444 | - $this->checkout->payment_method->type_obj()->apply_billing_form_debug_settings( |
|
1445 | - $this->checkout->billing_form |
|
1446 | - ); |
|
1447 | - } |
|
1448 | - // get html and validation rules for form |
|
1449 | - if ($this->checkout->billing_form instanceof EE_Form_Section_Proper) { |
|
1450 | - $this->checkout->json_response->set_return_data( |
|
1451 | - ['payment_method_info' => $this->checkout->billing_form->get_html()] |
|
1452 | - ); |
|
1453 | - // localize validation rules for main form |
|
1454 | - $this->checkout->billing_form->localize_validation_rules(true); |
|
1455 | - $this->checkout->json_response->add_validation_rules(EE_Form_Section_Proper::js_localization()); |
|
1456 | - } else { |
|
1457 | - $this->checkout->json_response->set_return_data(['payment_method_info' => '']); |
|
1458 | - } |
|
1459 | - // prevents advancement to next step |
|
1460 | - $this->checkout->continue_reg = false; |
|
1461 | - return true; |
|
1462 | - } |
|
1463 | - |
|
1464 | - |
|
1465 | - /** |
|
1466 | - * _verify_payment_method_is_set |
|
1467 | - * |
|
1468 | - * @return bool |
|
1469 | - * @throws EE_Error |
|
1470 | - * @throws InvalidArgumentException |
|
1471 | - * @throws ReflectionException |
|
1472 | - * @throws InvalidDataTypeException |
|
1473 | - * @throws InvalidInterfaceException |
|
1474 | - */ |
|
1475 | - protected function _verify_payment_method_is_set() |
|
1476 | - { |
|
1477 | - // generate billing form for selected method of payment if it hasn't been done already |
|
1478 | - if (empty($this->checkout->selected_method_of_payment)) { |
|
1479 | - // how have they chosen to pay? |
|
1480 | - $this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment(true); |
|
1481 | - } else { |
|
1482 | - // choose your own adventure based on method_of_payment |
|
1483 | - switch ($this->checkout->selected_method_of_payment) { |
|
1484 | - case 'events_sold_out': |
|
1485 | - EE_Error::add_attention( |
|
1486 | - apply_filters( |
|
1487 | - 'FHEE__EE_SPCO_Reg_Step_Payment_Options___verify_payment_method_is_set__sold_out_events_msg', |
|
1488 | - esc_html__( |
|
1489 | - 'It appears that the event you were about to make a payment for has sold out since this form first loaded. Please contact the event administrator if you believe this is an error.', |
|
1490 | - 'event_espresso' |
|
1491 | - ) |
|
1492 | - ), |
|
1493 | - __FILE__, |
|
1494 | - __FUNCTION__, |
|
1495 | - __LINE__ |
|
1496 | - ); |
|
1497 | - return false; |
|
1498 | - case 'payments_closed': |
|
1499 | - EE_Error::add_attention( |
|
1500 | - apply_filters( |
|
1501 | - 'FHEE__EE_SPCO_Reg_Step_Payment_Options___verify_payment_method_is_set__payments_closed_msg', |
|
1502 | - esc_html__( |
|
1503 | - 'It appears that the event you were about to make a payment for is not accepting payments at this time. Please contact the event administrator if you believe this is an error.', |
|
1504 | - 'event_espresso' |
|
1505 | - ) |
|
1506 | - ), |
|
1507 | - __FILE__, |
|
1508 | - __FUNCTION__, |
|
1509 | - __LINE__ |
|
1510 | - ); |
|
1511 | - return false; |
|
1512 | - case 'no_payment_required': |
|
1513 | - EE_Error::add_attention( |
|
1514 | - apply_filters( |
|
1515 | - 'FHEE__EE_SPCO_Reg_Step_Payment_Options___verify_payment_method_is_set__no_payment_required_msg', |
|
1516 | - esc_html__( |
|
1517 | - 'It appears that the event you were about to make a payment for does not require payment. Please contact the event administrator if you believe this is an error.', |
|
1518 | - 'event_espresso' |
|
1519 | - ) |
|
1520 | - ), |
|
1521 | - __FILE__, |
|
1522 | - __FUNCTION__, |
|
1523 | - __LINE__ |
|
1524 | - ); |
|
1525 | - return false; |
|
1526 | - default: |
|
1527 | - } |
|
1528 | - } |
|
1529 | - // verify payment method |
|
1530 | - if (! $this->checkout->payment_method instanceof EE_Payment_Method) { |
|
1531 | - // get payment method for selected method of payment |
|
1532 | - $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment(); |
|
1533 | - } |
|
1534 | - return $this->checkout->payment_method instanceof EE_Payment_Method; |
|
1535 | - } |
|
1536 | - |
|
1537 | - |
|
1538 | - |
|
1539 | - /********************************************************************************************************/ |
|
1540 | - /*************************************** SAVE PAYER DETAILS ****************************************/ |
|
1541 | - /********************************************************************************************************/ |
|
1542 | - /** |
|
1543 | - * save_payer_details_via_ajax |
|
1544 | - * |
|
1545 | - * @return void |
|
1546 | - * @throws EE_Error |
|
1547 | - * @throws InvalidArgumentException |
|
1548 | - * @throws ReflectionException |
|
1549 | - * @throws RuntimeException |
|
1550 | - * @throws InvalidDataTypeException |
|
1551 | - * @throws InvalidInterfaceException |
|
1552 | - */ |
|
1553 | - public function save_payer_details_via_ajax() |
|
1554 | - { |
|
1555 | - if (! $this->_verify_payment_method_is_set()) { |
|
1556 | - return; |
|
1557 | - } |
|
1558 | - // generate billing form for selected method of payment if it hasn't been done already |
|
1559 | - if ($this->checkout->payment_method->type_obj()->has_billing_form()) { |
|
1560 | - $this->checkout->billing_form = $this->_get_billing_form_for_payment_method( |
|
1561 | - $this->checkout->payment_method |
|
1562 | - ); |
|
1563 | - } |
|
1564 | - // generate primary attendee from payer info if applicable |
|
1565 | - if (! $this->checkout->transaction_has_primary_registrant()) { |
|
1566 | - $attendee = $this->_create_attendee_from_request_data(); |
|
1567 | - if ($attendee instanceof EE_Attendee) { |
|
1568 | - foreach ($this->checkout->transaction->registrations() as $registration) { |
|
1569 | - if ($registration->is_primary_registrant()) { |
|
1570 | - $this->checkout->primary_attendee_obj = $attendee; |
|
1571 | - $registration->_add_relation_to($attendee, 'Attendee'); |
|
1572 | - $registration->set_attendee_id($attendee->ID()); |
|
1573 | - $registration->update_cache_after_object_save('Attendee', $attendee); |
|
1574 | - } |
|
1575 | - } |
|
1576 | - } |
|
1577 | - } |
|
1578 | - } |
|
1579 | - |
|
1580 | - |
|
1581 | - /** |
|
1582 | - * create_attendee_from_request_data |
|
1583 | - * uses info from alternate GET or POST data (such as AJAX) to create a new attendee |
|
1584 | - * |
|
1585 | - * @return EE_Attendee |
|
1586 | - * @throws EE_Error |
|
1587 | - * @throws InvalidArgumentException |
|
1588 | - * @throws ReflectionException |
|
1589 | - * @throws InvalidDataTypeException |
|
1590 | - * @throws InvalidInterfaceException |
|
1591 | - */ |
|
1592 | - protected function _create_attendee_from_request_data() |
|
1593 | - { |
|
1594 | - // get State ID |
|
1595 | - $STA_ID = $this->request->getRequestParam('state'); |
|
1596 | - if (! empty($STA_ID)) { |
|
1597 | - // can we get state object from name ? |
|
1598 | - EE_Registry::instance()->load_model('State'); |
|
1599 | - $state = EEM_State::instance()->get_col([['STA_name' => $STA_ID], 'limit' => 1], 'STA_ID'); |
|
1600 | - $STA_ID = is_array($state) && ! empty($state) ? reset($state) : $STA_ID; |
|
1601 | - } |
|
1602 | - // get Country ISO |
|
1603 | - $CNT_ISO = $this->request->getRequestParam('country'); |
|
1604 | - if (! empty($CNT_ISO)) { |
|
1605 | - // can we get country object from name ? |
|
1606 | - EE_Registry::instance()->load_model('Country'); |
|
1607 | - $country = EEM_Country::instance()->get_col( |
|
1608 | - [['CNT_name' => $CNT_ISO], 'limit' => 1], |
|
1609 | - 'CNT_ISO' |
|
1610 | - ); |
|
1611 | - $CNT_ISO = is_array($country) && ! empty($country) ? reset($country) : $CNT_ISO; |
|
1612 | - } |
|
1613 | - // grab attendee data |
|
1614 | - $attendee_data = [ |
|
1615 | - 'ATT_fname' => $this->request->getRequestParam('first_name'), |
|
1616 | - 'ATT_lname' => $this->request->getRequestParam('last_name'), |
|
1617 | - 'ATT_email' => $this->request->getRequestParam('email'), |
|
1618 | - 'ATT_address' => $this->request->getRequestParam('address'), |
|
1619 | - 'ATT_address2' => $this->request->getRequestParam('address2'), |
|
1620 | - 'ATT_city' => $this->request->getRequestParam('city'), |
|
1621 | - 'STA_ID' => $STA_ID, |
|
1622 | - 'CNT_ISO' => $CNT_ISO, |
|
1623 | - 'ATT_zip' => $this->request->getRequestParam('zip'), |
|
1624 | - 'ATT_phone' => $this->request->getRequestParam('phone'), |
|
1625 | - ]; |
|
1626 | - // validate the email address since it is the most important piece of info |
|
1627 | - if (empty($attendee_data['ATT_email'])) { |
|
1628 | - EE_Error::add_error( |
|
1629 | - esc_html__('An invalid email address was submitted.', 'event_espresso'), |
|
1630 | - __FILE__, |
|
1631 | - __FUNCTION__, |
|
1632 | - __LINE__ |
|
1633 | - ); |
|
1634 | - } |
|
1635 | - // does this attendee already exist in the db ? we're searching using a combination of first name, last name, |
|
1636 | - // AND email address |
|
1637 | - if ( |
|
1638 | - ! empty($attendee_data['ATT_fname']) |
|
1639 | - && ! empty($attendee_data['ATT_lname']) |
|
1640 | - && ! empty($attendee_data['ATT_email']) |
|
1641 | - ) { |
|
1642 | - $existing_attendee = EEM_Attendee::instance()->find_existing_attendee( |
|
1643 | - [ |
|
1644 | - 'ATT_fname' => $attendee_data['ATT_fname'], |
|
1645 | - 'ATT_lname' => $attendee_data['ATT_lname'], |
|
1646 | - 'ATT_email' => $attendee_data['ATT_email'], |
|
1647 | - ] |
|
1648 | - ); |
|
1649 | - if ($existing_attendee instanceof EE_Attendee) { |
|
1650 | - return $existing_attendee; |
|
1651 | - } |
|
1652 | - } |
|
1653 | - // no existing attendee? kk let's create a new one |
|
1654 | - // kinda lame, but we need a first and last name to create an attendee, so use the email address if those |
|
1655 | - // don't exist |
|
1656 | - $attendee_data['ATT_fname'] = ! empty($attendee_data['ATT_fname']) |
|
1657 | - ? $attendee_data['ATT_fname'] |
|
1658 | - : $attendee_data['ATT_email']; |
|
1659 | - $attendee_data['ATT_lname'] = ! empty($attendee_data['ATT_lname']) |
|
1660 | - ? $attendee_data['ATT_lname'] |
|
1661 | - : $attendee_data['ATT_email']; |
|
1662 | - return EE_Attendee::new_instance($attendee_data); |
|
1663 | - } |
|
1664 | - |
|
1665 | - |
|
1666 | - |
|
1667 | - /********************************************************************************************************/ |
|
1668 | - /**************************************** PROCESS REG STEP *****************************************/ |
|
1669 | - /********************************************************************************************************/ |
|
1670 | - /** |
|
1671 | - * process_reg_step |
|
1672 | - * |
|
1673 | - * @return bool |
|
1674 | - * @throws EE_Error |
|
1675 | - * @throws InvalidArgumentException |
|
1676 | - * @throws ReflectionException |
|
1677 | - * @throws EntityNotFoundException |
|
1678 | - * @throws InvalidDataTypeException |
|
1679 | - * @throws InvalidInterfaceException |
|
1680 | - * @throws InvalidStatusException |
|
1681 | - */ |
|
1682 | - public function process_reg_step() |
|
1683 | - { |
|
1684 | - // how have they chosen to pay? |
|
1685 | - $this->checkout->selected_method_of_payment = $this->checkout->transaction->is_free() |
|
1686 | - ? 'no_payment_required' |
|
1687 | - : $this->_get_selected_method_of_payment(true); |
|
1688 | - // choose your own adventure based on method_of_payment |
|
1689 | - switch ($this->checkout->selected_method_of_payment) { |
|
1690 | - case 'events_sold_out': |
|
1691 | - $this->checkout->redirect = true; |
|
1692 | - $this->checkout->redirect_url = $this->checkout->cancel_page_url; |
|
1693 | - $this->checkout->json_response->set_redirect_url($this->checkout->redirect_url); |
|
1694 | - // mark this reg step as completed |
|
1695 | - $this->set_completed(); |
|
1696 | - return false; |
|
1697 | - |
|
1698 | - case 'payments_closed': |
|
1699 | - if ( |
|
1700 | - apply_filters( |
|
1701 | - 'FHEE__EE_SPCO_Reg_Step_Payment_Options__process_reg_step__payments_closed__display_success', |
|
1702 | - false |
|
1703 | - ) |
|
1704 | - ) { |
|
1705 | - EE_Error::add_success( |
|
1706 | - esc_html__('no payment required at this time.', 'event_espresso'), |
|
1707 | - __FILE__, |
|
1708 | - __FUNCTION__, |
|
1709 | - __LINE__ |
|
1710 | - ); |
|
1711 | - } |
|
1712 | - // mark this reg step as completed |
|
1713 | - $this->set_completed(); |
|
1714 | - return true; |
|
1715 | - |
|
1716 | - case 'no_payment_required': |
|
1717 | - if ( |
|
1718 | - apply_filters( |
|
1719 | - 'FHEE__EE_SPCO_Reg_Step_Payment_Options__process_reg_step__no_payment_required__display_success', |
|
1720 | - false |
|
1721 | - ) |
|
1722 | - ) { |
|
1723 | - EE_Error::add_success( |
|
1724 | - esc_html__('no payment required.', 'event_espresso'), |
|
1725 | - __FILE__, |
|
1726 | - __FUNCTION__, |
|
1727 | - __LINE__ |
|
1728 | - ); |
|
1729 | - } |
|
1730 | - // mark this reg step as completed |
|
1731 | - $this->set_completed(); |
|
1732 | - return true; |
|
1733 | - |
|
1734 | - default: |
|
1735 | - $registrations = EE_Registry::instance()->SSN->checkout()->transaction->registrations( |
|
1736 | - EE_Registry::instance()->SSN->checkout()->reg_cache_where_params |
|
1737 | - ); |
|
1738 | - $ejected_registrations = EE_SPCO_Reg_Step_Payment_Options::find_registrations_that_lost_their_space( |
|
1739 | - $registrations, |
|
1740 | - EE_Registry::instance()->SSN->checkout()->revisit |
|
1741 | - ); |
|
1742 | - // calculate difference between the two arrays |
|
1743 | - $registrations = array_diff($registrations, $ejected_registrations); |
|
1744 | - if (empty($registrations)) { |
|
1745 | - $this->_redirect_because_event_sold_out(); |
|
1746 | - return false; |
|
1747 | - } |
|
1748 | - $payment_successful = $this->_process_payment(); |
|
1749 | - if ($payment_successful) { |
|
1750 | - $this->checkout->continue_reg = true; |
|
1751 | - $this->_maybe_set_completed($this->checkout->payment_method); |
|
1752 | - } else { |
|
1753 | - $this->checkout->continue_reg = false; |
|
1754 | - } |
|
1755 | - return $payment_successful; |
|
1756 | - } |
|
1757 | - } |
|
1758 | - |
|
1759 | - |
|
1760 | - /** |
|
1761 | - * _redirect_because_event_sold_out |
|
1762 | - * |
|
1763 | - * @return void |
|
1764 | - */ |
|
1765 | - protected function _redirect_because_event_sold_out() |
|
1766 | - { |
|
1767 | - $this->checkout->continue_reg = false; |
|
1768 | - // set redirect URL |
|
1769 | - $this->checkout->redirect_url = add_query_arg( |
|
1770 | - ['e_reg_url_link' => $this->checkout->reg_url_link], |
|
1771 | - $this->checkout->current_step->reg_step_url() |
|
1772 | - ); |
|
1773 | - $this->checkout->json_response->set_redirect_url($this->checkout->redirect_url); |
|
1774 | - } |
|
1775 | - |
|
1776 | - |
|
1777 | - /** |
|
1778 | - * _maybe_set_completed |
|
1779 | - * |
|
1780 | - * @param EE_Payment_Method $payment_method |
|
1781 | - * @return void |
|
1782 | - * @throws EE_Error |
|
1783 | - */ |
|
1784 | - protected function _maybe_set_completed(EE_Payment_Method $payment_method) |
|
1785 | - { |
|
1786 | - switch ($payment_method->type_obj()->payment_occurs()) { |
|
1787 | - case EE_PMT_Base::offsite: |
|
1788 | - break; |
|
1789 | - case EE_PMT_Base::onsite: |
|
1790 | - case EE_PMT_Base::offline: |
|
1791 | - // mark this reg step as completed |
|
1792 | - $this->set_completed(); |
|
1793 | - break; |
|
1794 | - } |
|
1795 | - } |
|
1796 | - |
|
1797 | - |
|
1798 | - /** |
|
1799 | - * update_reg_step |
|
1800 | - * this is the final step after a user revisits the site to retry a payment |
|
1801 | - * |
|
1802 | - * @return bool |
|
1803 | - * @throws EE_Error |
|
1804 | - * @throws InvalidArgumentException |
|
1805 | - * @throws ReflectionException |
|
1806 | - * @throws EntityNotFoundException |
|
1807 | - * @throws InvalidDataTypeException |
|
1808 | - * @throws InvalidInterfaceException |
|
1809 | - * @throws InvalidStatusException |
|
1810 | - */ |
|
1811 | - public function update_reg_step() |
|
1812 | - { |
|
1813 | - $success = true; |
|
1814 | - // if payment required |
|
1815 | - if ($this->checkout->transaction->total() > 0) { |
|
1816 | - do_action( |
|
1817 | - 'AHEE__EE_Single_Page_Checkout__process_finalize_registration__before_gateway', |
|
1818 | - $this->checkout->transaction |
|
1819 | - ); |
|
1820 | - // attempt payment via payment method |
|
1821 | - $success = $this->process_reg_step(); |
|
1822 | - } |
|
1823 | - if ($success && ! $this->checkout->redirect) { |
|
1824 | - $this->checkout->cart->get_grand_total()->save_this_and_descendants_to_txn( |
|
1825 | - $this->checkout->transaction->ID() |
|
1826 | - ); |
|
1827 | - // set return URL |
|
1828 | - $this->checkout->redirect_url = add_query_arg( |
|
1829 | - ['e_reg_url_link' => $this->checkout->reg_url_link], |
|
1830 | - $this->checkout->thank_you_page_url |
|
1831 | - ); |
|
1832 | - } |
|
1833 | - return $success; |
|
1834 | - } |
|
1835 | - |
|
1836 | - |
|
1837 | - /** |
|
1838 | - * _process_payment |
|
1839 | - * |
|
1840 | - * @return bool |
|
1841 | - * @throws EE_Error |
|
1842 | - * @throws InvalidArgumentException |
|
1843 | - * @throws ReflectionException |
|
1844 | - * @throws RuntimeException |
|
1845 | - * @throws InvalidDataTypeException |
|
1846 | - * @throws InvalidInterfaceException |
|
1847 | - */ |
|
1848 | - private function _process_payment() |
|
1849 | - { |
|
1850 | - // basically confirm that the event hasn't sold out since they hit the page |
|
1851 | - if (! $this->_last_second_ticket_verifications()) { |
|
1852 | - return false; |
|
1853 | - } |
|
1854 | - // ya gotta make a choice man |
|
1855 | - if (empty($this->checkout->selected_method_of_payment)) { |
|
1856 | - $this->checkout->json_response->set_plz_select_method_of_payment( |
|
1857 | - esc_html__('Please select a method of payment before proceeding.', 'event_espresso') |
|
1858 | - ); |
|
1859 | - return false; |
|
1860 | - } |
|
1861 | - // get EE_Payment_Method object |
|
1862 | - if (! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()) { |
|
1863 | - return false; |
|
1864 | - } |
|
1865 | - // setup billing form |
|
1866 | - if ($this->checkout->payment_method->is_on_site()) { |
|
1867 | - $this->checkout->billing_form = $this->_get_billing_form_for_payment_method( |
|
1868 | - $this->checkout->payment_method |
|
1869 | - ); |
|
1870 | - // bad billing form ? |
|
1871 | - if (! $this->_billing_form_is_valid()) { |
|
1872 | - return false; |
|
1873 | - } |
|
1874 | - } |
|
1875 | - // ensure primary registrant has been fully processed |
|
1876 | - if (! $this->_setup_primary_registrant_prior_to_payment()) { |
|
1877 | - return false; |
|
1878 | - } |
|
1879 | - // if session is close to expiring (under 10 minutes by default) |
|
1880 | - if ((time() - EE_Registry::instance()->SSN->expiration()) < EE_Registry::instance()->SSN->extension()) { |
|
1881 | - // add some time to session expiration so that payment can be completed |
|
1882 | - EE_Registry::instance()->SSN->extend_expiration(); |
|
1883 | - } |
|
1884 | - /** @type EE_Transaction_Processor $transaction_processor */ |
|
1885 | - // $transaction_processor = EE_Registry::instance()->load_class( 'Transaction_Processor' ); |
|
1886 | - // in case a registrant leaves to an Off-Site Gateway and never returns, we want to approve any registrations |
|
1887 | - // for events with a default reg status of Approved |
|
1888 | - // $transaction_processor->toggle_registration_statuses_for_default_approved_events( |
|
1889 | - // $this->checkout->transaction, $this->checkout->reg_cache_where_params |
|
1890 | - // ); |
|
1891 | - // attempt payment |
|
1892 | - $payment = $this->_attempt_payment($this->checkout->payment_method); |
|
1893 | - // process results |
|
1894 | - $payment = $this->_validate_payment($payment); |
|
1895 | - $payment = $this->_post_payment_processing($payment); |
|
1896 | - // verify payment |
|
1897 | - if ($payment instanceof EE_Payment) { |
|
1898 | - // store that for later |
|
1899 | - $this->checkout->payment = $payment; |
|
1900 | - // we can also consider the TXN to not have been failed, so temporarily upgrade it's status to abandoned |
|
1901 | - $this->checkout->transaction->toggle_failed_transaction_status(); |
|
1902 | - $payment_status = $payment->status(); |
|
1903 | - return $payment_status === EEM_Payment::status_id_approved |
|
1904 | - || $payment_status === EEM_Payment::status_id_pending; |
|
1905 | - } |
|
1906 | - if ($payment === true) { |
|
1907 | - // please note that offline payment methods will NOT make a payment, |
|
1908 | - // but instead just mark themselves as the PMD_ID on the transaction, and return true |
|
1909 | - $this->checkout->payment = $payment; |
|
1910 | - return true; |
|
1911 | - } |
|
1912 | - // where's my money? |
|
1913 | - return false; |
|
1914 | - } |
|
1915 | - |
|
1916 | - |
|
1917 | - /** |
|
1918 | - * _last_second_ticket_verifications |
|
1919 | - * |
|
1920 | - * @return bool |
|
1921 | - * @throws EE_Error |
|
1922 | - * @throws ReflectionException |
|
1923 | - */ |
|
1924 | - protected function _last_second_ticket_verifications() |
|
1925 | - { |
|
1926 | - // don't bother re-validating if not a return visit |
|
1927 | - if (! $this->checkout->revisit) { |
|
1928 | - return true; |
|
1929 | - } |
|
1930 | - $registrations = $this->checkout->transaction->registrations(); |
|
1931 | - if (empty($registrations)) { |
|
1932 | - return false; |
|
1933 | - } |
|
1934 | - foreach ($registrations as $registration) { |
|
1935 | - if ($registration instanceof EE_Registration && ! $registration->is_approved()) { |
|
1936 | - $event = $registration->event_obj(); |
|
1937 | - if ($event instanceof EE_Event && $event->is_sold_out(true)) { |
|
1938 | - EE_Error::add_error( |
|
1939 | - apply_filters( |
|
1940 | - 'FHEE__EE_SPCO_Reg_Step_Payment_Options___last_second_ticket_verifications__sold_out_events_msg', |
|
1941 | - sprintf( |
|
1942 | - esc_html__( |
|
1943 | - 'It appears that the %1$s event that you were about to make a payment for has sold out since you first registered and/or arrived at this page. Please refresh the page and try again. If you have already made a partial payment towards this event, please contact the event administrator for a refund.', |
|
1944 | - 'event_espresso' |
|
1945 | - ), |
|
1946 | - $event->name() |
|
1947 | - ) |
|
1948 | - ), |
|
1949 | - __FILE__, |
|
1950 | - __FUNCTION__, |
|
1951 | - __LINE__ |
|
1952 | - ); |
|
1953 | - return false; |
|
1954 | - } |
|
1955 | - } |
|
1956 | - } |
|
1957 | - return true; |
|
1958 | - } |
|
1959 | - |
|
1960 | - |
|
1961 | - /** |
|
1962 | - * redirect_form |
|
1963 | - * |
|
1964 | - * @return bool |
|
1965 | - * @throws EE_Error |
|
1966 | - * @throws InvalidArgumentException |
|
1967 | - * @throws ReflectionException |
|
1968 | - * @throws InvalidDataTypeException |
|
1969 | - * @throws InvalidInterfaceException |
|
1970 | - */ |
|
1971 | - public function redirect_form() |
|
1972 | - { |
|
1973 | - $payment_method_billing_info = $this->_payment_method_billing_info( |
|
1974 | - $this->_get_payment_method_for_selected_method_of_payment() |
|
1975 | - ); |
|
1976 | - $html = $payment_method_billing_info->get_html(); |
|
1977 | - $html .= $this->checkout->redirect_form; |
|
1978 | - /** @var ResponseInterface $response */ |
|
1979 | - $response = LoaderFactory::getLoader()->getShared(ResponseInterface::class); |
|
1980 | - $response->addOutput($html); |
|
1981 | - return true; |
|
1982 | - } |
|
1983 | - |
|
1984 | - |
|
1985 | - /** |
|
1986 | - * _billing_form_is_valid |
|
1987 | - * |
|
1988 | - * @return bool |
|
1989 | - * @throws EE_Error |
|
1990 | - */ |
|
1991 | - private function _billing_form_is_valid() |
|
1992 | - { |
|
1993 | - if (! $this->checkout->payment_method->type_obj()->has_billing_form()) { |
|
1994 | - return true; |
|
1995 | - } |
|
1996 | - if ($this->checkout->billing_form instanceof EE_Billing_Info_Form) { |
|
1997 | - if ($this->checkout->billing_form->was_submitted()) { |
|
1998 | - $this->checkout->billing_form->receive_form_submission(); |
|
1999 | - if ($this->checkout->billing_form->is_valid()) { |
|
2000 | - return true; |
|
2001 | - } |
|
2002 | - $validation_errors = $this->checkout->billing_form->get_validation_errors_accumulated(); |
|
2003 | - $error_strings = []; |
|
2004 | - foreach ($validation_errors as $validation_error) { |
|
2005 | - if ($validation_error instanceof EE_Validation_Error) { |
|
2006 | - $form_section = $validation_error->get_form_section(); |
|
2007 | - if ($form_section instanceof EE_Form_Input_Base) { |
|
2008 | - $label = $form_section->html_label_text(); |
|
2009 | - } elseif ($form_section instanceof EE_Form_Section_Base) { |
|
2010 | - $label = $form_section->name(); |
|
2011 | - } else { |
|
2012 | - $label = esc_html__('Validation Error', 'event_espresso'); |
|
2013 | - } |
|
2014 | - $error_strings[] = sprintf('%1$s: %2$s', $label, $validation_error->getMessage()); |
|
2015 | - } |
|
2016 | - } |
|
2017 | - EE_Error::add_error( |
|
2018 | - sprintf( |
|
2019 | - esc_html__( |
|
2020 | - 'One or more billing form inputs are invalid and require correction before proceeding. %1$s %2$s', |
|
2021 | - 'event_espresso' |
|
2022 | - ), |
|
2023 | - '<br/>', |
|
2024 | - implode('<br/>', $error_strings) |
|
2025 | - ), |
|
2026 | - __FILE__, |
|
2027 | - __FUNCTION__, |
|
2028 | - __LINE__ |
|
2029 | - ); |
|
2030 | - } else { |
|
2031 | - EE_Error::add_error( |
|
2032 | - esc_html__( |
|
2033 | - 'The billing form was not submitted or something prevented it\'s submission.', |
|
2034 | - 'event_espresso' |
|
2035 | - ), |
|
2036 | - __FILE__, |
|
2037 | - __FUNCTION__, |
|
2038 | - __LINE__ |
|
2039 | - ); |
|
2040 | - } |
|
2041 | - } else { |
|
2042 | - EE_Error::add_error( |
|
2043 | - esc_html__( |
|
2044 | - 'The submitted billing form is invalid possibly due to a technical reason.', |
|
2045 | - 'event_espresso' |
|
2046 | - ), |
|
2047 | - __FILE__, |
|
2048 | - __FUNCTION__, |
|
2049 | - __LINE__ |
|
2050 | - ); |
|
2051 | - } |
|
2052 | - return false; |
|
2053 | - } |
|
2054 | - |
|
2055 | - |
|
2056 | - /** |
|
2057 | - * _setup_primary_registrant_prior_to_payment |
|
2058 | - * ensures that the primary registrant has a valid attendee object created with the critical details populated |
|
2059 | - * (first & last name & email) and that both the transaction object and primary registration object have been saved |
|
2060 | - * plz note that any other registrations will NOT be saved at this point (because they may not have any details |
|
2061 | - * yet) |
|
2062 | - * |
|
2063 | - * @return bool |
|
2064 | - * @throws EE_Error |
|
2065 | - * @throws InvalidArgumentException |
|
2066 | - * @throws ReflectionException |
|
2067 | - * @throws RuntimeException |
|
2068 | - * @throws InvalidDataTypeException |
|
2069 | - * @throws InvalidInterfaceException |
|
2070 | - */ |
|
2071 | - private function _setup_primary_registrant_prior_to_payment() |
|
2072 | - { |
|
2073 | - // check if transaction has a primary registrant and that it has a related Attendee object |
|
2074 | - // if not, then we need to at least gather some primary registrant data before attempting payment |
|
2075 | - if ( |
|
2076 | - $this->checkout->billing_form instanceof EE_Billing_Attendee_Info_Form |
|
2077 | - && ! $this->checkout->transaction_has_primary_registrant() |
|
2078 | - && ! $this->_capture_primary_registration_data_from_billing_form() |
|
2079 | - ) { |
|
2080 | - return false; |
|
2081 | - } |
|
2082 | - // because saving an object clears it's cache, we need to do the chevy shuffle |
|
2083 | - // grab the primary_registration object |
|
2084 | - $primary_registration = $this->checkout->transaction->primary_registration(); |
|
2085 | - // at this point we'll consider a TXN to not have been failed |
|
2086 | - $this->checkout->transaction->toggle_failed_transaction_status(); |
|
2087 | - // save the TXN ( which clears cached copy of primary_registration) |
|
2088 | - $this->checkout->transaction->save(); |
|
2089 | - // grab TXN ID and save it to the primary_registration |
|
2090 | - $primary_registration->set_transaction_id($this->checkout->transaction->ID()); |
|
2091 | - // save what we have so far |
|
2092 | - $primary_registration->save(); |
|
2093 | - return true; |
|
2094 | - } |
|
2095 | - |
|
2096 | - |
|
2097 | - /** |
|
2098 | - * _capture_primary_registration_data_from_billing_form |
|
2099 | - * |
|
2100 | - * @return bool |
|
2101 | - * @throws EE_Error |
|
2102 | - * @throws InvalidArgumentException |
|
2103 | - * @throws ReflectionException |
|
2104 | - * @throws InvalidDataTypeException |
|
2105 | - * @throws InvalidInterfaceException |
|
2106 | - */ |
|
2107 | - private function _capture_primary_registration_data_from_billing_form() |
|
2108 | - { |
|
2109 | - // convert billing form data into an attendee |
|
2110 | - $this->checkout->primary_attendee_obj = $this->checkout->billing_form->create_attendee_from_billing_form_data(); |
|
2111 | - if (! $this->checkout->primary_attendee_obj instanceof EE_Attendee) { |
|
2112 | - EE_Error::add_error( |
|
2113 | - sprintf( |
|
2114 | - esc_html__( |
|
2115 | - 'The billing form details could not be used for attendee details due to a technical issue.%sPlease try again or contact %s for assistance.', |
|
2116 | - 'event_espresso' |
|
2117 | - ), |
|
2118 | - '<br/>', |
|
2119 | - EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
2120 | - ), |
|
2121 | - __FILE__, |
|
2122 | - __FUNCTION__, |
|
2123 | - __LINE__ |
|
2124 | - ); |
|
2125 | - return false; |
|
2126 | - } |
|
2127 | - $primary_registration = $this->checkout->transaction->primary_registration(); |
|
2128 | - if (! $primary_registration instanceof EE_Registration) { |
|
2129 | - EE_Error::add_error( |
|
2130 | - sprintf( |
|
2131 | - esc_html__( |
|
2132 | - 'The primary registrant for this transaction could not be determined due to a technical issue.%sPlease try again or contact %s for assistance.', |
|
2133 | - 'event_espresso' |
|
2134 | - ), |
|
2135 | - '<br/>', |
|
2136 | - EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
2137 | - ), |
|
2138 | - __FILE__, |
|
2139 | - __FUNCTION__, |
|
2140 | - __LINE__ |
|
2141 | - ); |
|
2142 | - return false; |
|
2143 | - } |
|
2144 | - if ( |
|
2145 | - ! $primary_registration->_add_relation_to($this->checkout->primary_attendee_obj, 'Attendee') |
|
2146 | - instanceof |
|
2147 | - EE_Attendee |
|
2148 | - ) { |
|
2149 | - EE_Error::add_error( |
|
2150 | - sprintf( |
|
2151 | - esc_html__( |
|
2152 | - 'The primary registrant could not be associated with this transaction due to a technical issue.%sPlease try again or contact %s for assistance.', |
|
2153 | - 'event_espresso' |
|
2154 | - ), |
|
2155 | - '<br/>', |
|
2156 | - EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
2157 | - ), |
|
2158 | - __FILE__, |
|
2159 | - __FUNCTION__, |
|
2160 | - __LINE__ |
|
2161 | - ); |
|
2162 | - return false; |
|
2163 | - } |
|
2164 | - /** @type EE_Registration_Processor $registration_processor */ |
|
2165 | - $registration_processor = EE_Registry::instance()->load_class('Registration_Processor'); |
|
2166 | - // at this point, we should have enough details about the registrant to consider the registration NOT incomplete |
|
2167 | - $registration_processor->toggle_incomplete_registration_status_to_default($primary_registration); |
|
2168 | - return true; |
|
2169 | - } |
|
2170 | - |
|
2171 | - |
|
2172 | - /** |
|
2173 | - * _get_payment_method_for_selected_method_of_payment |
|
2174 | - * retrieves a valid payment method |
|
2175 | - * |
|
2176 | - * @return EE_Payment_Method |
|
2177 | - * @throws EE_Error |
|
2178 | - * @throws InvalidArgumentException |
|
2179 | - * @throws ReflectionException |
|
2180 | - * @throws InvalidDataTypeException |
|
2181 | - * @throws InvalidInterfaceException |
|
2182 | - */ |
|
2183 | - private function _get_payment_method_for_selected_method_of_payment() |
|
2184 | - { |
|
2185 | - if ($this->checkout->selected_method_of_payment === 'events_sold_out') { |
|
2186 | - $this->_redirect_because_event_sold_out(); |
|
2187 | - return null; |
|
2188 | - } |
|
2189 | - // get EE_Payment_Method object |
|
2190 | - if (isset($this->checkout->available_payment_methods[ $this->checkout->selected_method_of_payment ])) { |
|
2191 | - $payment_method = $this->checkout->available_payment_methods[ $this->checkout->selected_method_of_payment ]; |
|
2192 | - } else { |
|
2193 | - // load EEM_Payment_Method |
|
2194 | - EE_Registry::instance()->load_model('Payment_Method'); |
|
2195 | - $EEM_Payment_Method = EEM_Payment_Method::instance(); |
|
2196 | - $payment_method = $EEM_Payment_Method->get_one_by_slug($this->checkout->selected_method_of_payment); |
|
2197 | - } |
|
2198 | - // verify $payment_method |
|
2199 | - if (! $payment_method instanceof EE_Payment_Method) { |
|
2200 | - // not a payment |
|
2201 | - EE_Error::add_error( |
|
2202 | - sprintf( |
|
2203 | - esc_html__( |
|
2204 | - 'The selected method of payment could not be determined due to a technical issue.%sPlease try again or contact %s for assistance.', |
|
2205 | - 'event_espresso' |
|
2206 | - ), |
|
2207 | - '<br/>', |
|
2208 | - EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
2209 | - ), |
|
2210 | - __FILE__, |
|
2211 | - __FUNCTION__, |
|
2212 | - __LINE__ |
|
2213 | - ); |
|
2214 | - return null; |
|
2215 | - } |
|
2216 | - // and verify it has a valid Payment_Method Type object |
|
2217 | - if (! $payment_method->type_obj() instanceof EE_PMT_Base) { |
|
2218 | - // not a payment |
|
2219 | - EE_Error::add_error( |
|
2220 | - sprintf( |
|
2221 | - esc_html__( |
|
2222 | - 'A valid payment method could not be determined due to a technical issue.%sPlease try again or contact %s for assistance.', |
|
2223 | - 'event_espresso' |
|
2224 | - ), |
|
2225 | - '<br/>', |
|
2226 | - EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
2227 | - ), |
|
2228 | - __FILE__, |
|
2229 | - __FUNCTION__, |
|
2230 | - __LINE__ |
|
2231 | - ); |
|
2232 | - return null; |
|
2233 | - } |
|
2234 | - return $payment_method; |
|
2235 | - } |
|
2236 | - |
|
2237 | - |
|
2238 | - /** |
|
2239 | - * _attempt_payment |
|
2240 | - * |
|
2241 | - * @access private |
|
2242 | - * @type EE_Payment_Method $payment_method |
|
2243 | - * @return mixed EE_Payment | boolean |
|
2244 | - * @throws EE_Error |
|
2245 | - * @throws InvalidArgumentException |
|
2246 | - * @throws ReflectionException |
|
2247 | - * @throws InvalidDataTypeException |
|
2248 | - * @throws InvalidInterfaceException |
|
2249 | - */ |
|
2250 | - private function _attempt_payment(EE_Payment_Method $payment_method) |
|
2251 | - { |
|
2252 | - $payment = null; |
|
2253 | - $this->checkout->transaction->save(); |
|
2254 | - $payment_processor = EE_Registry::instance()->load_core('Payment_Processor'); |
|
2255 | - if (! $payment_processor instanceof EE_Payment_Processor) { |
|
2256 | - return false; |
|
2257 | - } |
|
2258 | - try { |
|
2259 | - $payment_processor->set_revisit($this->checkout->revisit); |
|
2260 | - // generate payment object |
|
2261 | - $payment = $payment_processor->process_payment( |
|
2262 | - $payment_method, |
|
2263 | - $this->checkout->transaction, |
|
2264 | - $this->checkout->amount_owing, |
|
2265 | - $this->checkout->billing_form instanceof EE_Billing_Info_Form |
|
2266 | - ? $this->checkout->billing_form |
|
2267 | - : null, |
|
2268 | - $this->_get_return_url($payment_method), |
|
2269 | - 'CART', |
|
2270 | - $this->checkout->admin_request, |
|
2271 | - true, |
|
2272 | - $this->reg_step_url() |
|
2273 | - ); |
|
2274 | - } catch (Exception $e) { |
|
2275 | - $this->_handle_payment_processor_exception($e); |
|
2276 | - } |
|
2277 | - return $payment; |
|
2278 | - } |
|
2279 | - |
|
2280 | - |
|
2281 | - /** |
|
2282 | - * _handle_payment_processor_exception |
|
2283 | - * |
|
2284 | - * @param Exception $e |
|
2285 | - * @return void |
|
2286 | - * @throws EE_Error |
|
2287 | - * @throws InvalidArgumentException |
|
2288 | - * @throws InvalidDataTypeException |
|
2289 | - * @throws InvalidInterfaceException |
|
2290 | - */ |
|
2291 | - protected function _handle_payment_processor_exception(Exception $e) |
|
2292 | - { |
|
2293 | - EE_Error::add_error( |
|
2294 | - sprintf( |
|
2295 | - esc_html__( |
|
2296 | - 'The payment could not br processed due to a technical issue.%1$sPlease try again or contact %2$s for assistance.||The following Exception was thrown in %4$s on line %5$s:%1$s%3$s', |
|
2297 | - 'event_espresso' |
|
2298 | - ), |
|
2299 | - '<br/>', |
|
2300 | - EE_Registry::instance()->CFG->organization->get_pretty('email'), |
|
2301 | - $e->getMessage(), |
|
2302 | - $e->getFile(), |
|
2303 | - $e->getLine() |
|
2304 | - ), |
|
2305 | - __FILE__, |
|
2306 | - __FUNCTION__, |
|
2307 | - __LINE__ |
|
2308 | - ); |
|
2309 | - } |
|
2310 | - |
|
2311 | - |
|
2312 | - /** |
|
2313 | - * _get_return_url |
|
2314 | - * |
|
2315 | - * @param EE_Payment_Method $payment_method |
|
2316 | - * @return string |
|
2317 | - * @throws EE_Error |
|
2318 | - * @throws ReflectionException |
|
2319 | - */ |
|
2320 | - protected function _get_return_url(EE_Payment_Method $payment_method) |
|
2321 | - { |
|
2322 | - $return_url = ''; |
|
2323 | - switch ($payment_method->type_obj()->payment_occurs()) { |
|
2324 | - case EE_PMT_Base::offsite: |
|
2325 | - $return_url = add_query_arg( |
|
2326 | - [ |
|
2327 | - 'action' => 'process_gateway_response', |
|
2328 | - 'selected_method_of_payment' => $this->checkout->selected_method_of_payment, |
|
2329 | - 'spco_txn' => $this->checkout->transaction->ID(), |
|
2330 | - ], |
|
2331 | - $this->reg_step_url() |
|
2332 | - ); |
|
2333 | - break; |
|
2334 | - case EE_PMT_Base::onsite: |
|
2335 | - case EE_PMT_Base::offline: |
|
2336 | - $return_url = $this->checkout->next_step->reg_step_url(); |
|
2337 | - break; |
|
2338 | - } |
|
2339 | - return $return_url; |
|
2340 | - } |
|
2341 | - |
|
2342 | - |
|
2343 | - /** |
|
2344 | - * _validate_payment |
|
2345 | - * |
|
2346 | - * @param EE_Payment $payment |
|
2347 | - * @return EE_Payment|FALSE |
|
2348 | - * @throws EE_Error |
|
2349 | - * @throws InvalidArgumentException |
|
2350 | - * @throws InvalidDataTypeException |
|
2351 | - * @throws InvalidInterfaceException |
|
2352 | - */ |
|
2353 | - private function _validate_payment($payment = null) |
|
2354 | - { |
|
2355 | - if ($this->checkout->payment_method->is_off_line()) { |
|
2356 | - return true; |
|
2357 | - } |
|
2358 | - // verify payment object |
|
2359 | - if (! $payment instanceof EE_Payment) { |
|
2360 | - // not a payment |
|
2361 | - EE_Error::add_error( |
|
2362 | - sprintf( |
|
2363 | - esc_html__( |
|
2364 | - 'A valid payment was not generated due to a technical issue.%1$sPlease try again or contact %2$s for assistance.', |
|
2365 | - 'event_espresso' |
|
2366 | - ), |
|
2367 | - '<br/>', |
|
2368 | - EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
2369 | - ), |
|
2370 | - __FILE__, |
|
2371 | - __FUNCTION__, |
|
2372 | - __LINE__ |
|
2373 | - ); |
|
2374 | - return false; |
|
2375 | - } |
|
2376 | - return $payment; |
|
2377 | - } |
|
2378 | - |
|
2379 | - |
|
2380 | - /** |
|
2381 | - * _post_payment_processing |
|
2382 | - * |
|
2383 | - * @param EE_Payment|bool $payment |
|
2384 | - * @return bool |
|
2385 | - * @throws EE_Error |
|
2386 | - * @throws InvalidArgumentException |
|
2387 | - * @throws InvalidDataTypeException |
|
2388 | - * @throws InvalidInterfaceException |
|
2389 | - * @throws ReflectionException |
|
2390 | - */ |
|
2391 | - private function _post_payment_processing($payment = null) |
|
2392 | - { |
|
2393 | - // Off-Line payment? |
|
2394 | - if ($payment === true) { |
|
2395 | - // $this->_setup_redirect_for_next_step(); |
|
2396 | - return true; |
|
2397 | - // On-Site payment? |
|
2398 | - } elseif ($this->checkout->payment_method->is_on_site()) { |
|
2399 | - if (! $this->_process_payment_status($payment, EE_PMT_Base::onsite)) { |
|
2400 | - // $this->_setup_redirect_for_next_step(); |
|
2401 | - $this->checkout->continue_reg = false; |
|
2402 | - } |
|
2403 | - // Off-Site payment? |
|
2404 | - } elseif ($this->checkout->payment_method->is_off_site()) { |
|
2405 | - // if a payment object was made and it specifies a redirect url, then we'll setup that redirect info |
|
2406 | - if ($payment instanceof EE_Payment && $payment->redirect_url()) { |
|
2407 | - do_action('AHEE_log', __CLASS__, __FUNCTION__, $payment->redirect_url(), '$payment->redirect_url()'); |
|
2408 | - $this->checkout->redirect = true; |
|
2409 | - $this->checkout->redirect_form = $payment->redirect_form(); |
|
2410 | - $this->checkout->redirect_url = $this->reg_step_url('redirect_form'); |
|
2411 | - // set JSON response |
|
2412 | - $this->checkout->json_response->set_redirect_form($this->checkout->redirect_form); |
|
2413 | - // and lastly, let's bump the payment status to pending |
|
2414 | - $payment->set_status(EEM_Payment::status_id_pending); |
|
2415 | - $payment->save(); |
|
2416 | - } else { |
|
2417 | - // we couldn't redirect the user. Let's tell them why. |
|
2418 | - $error_message = sprintf( |
|
2419 | - esc_html__( |
|
2420 | - 'It appears the Off Site Payment Method was not configured properly.%sPlease try again or contact %s for assistance.', |
|
2421 | - 'event_espresso' |
|
2422 | - ), |
|
2423 | - '<br/>', |
|
2424 | - EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
2425 | - ); |
|
2426 | - if ($payment instanceof EE_Payment && $payment->gateway_response()) { |
|
2427 | - $error_message = $error_message . '<br/>' . $payment->gateway_response(); |
|
2428 | - } |
|
2429 | - $this->checkout->continue_reg = false; |
|
2430 | - EE_Error::add_error( |
|
2431 | - $error_message, |
|
2432 | - __FILE__, |
|
2433 | - __FUNCTION__, |
|
2434 | - __LINE__ |
|
2435 | - ); |
|
2436 | - } |
|
2437 | - } else { |
|
2438 | - // ummm ya... not Off-Line, not On-Site, not off-Site ???? |
|
2439 | - $this->checkout->continue_reg = false; |
|
2440 | - return false; |
|
2441 | - } |
|
2442 | - return $payment; |
|
2443 | - } |
|
2444 | - |
|
2445 | - |
|
2446 | - /** |
|
2447 | - * _process_payment_status |
|
2448 | - * |
|
2449 | - * @type EE_Payment $payment |
|
2450 | - * @param string $payment_occurs |
|
2451 | - * @return bool |
|
2452 | - * @throws EE_Error |
|
2453 | - * @throws InvalidArgumentException |
|
2454 | - * @throws InvalidDataTypeException |
|
2455 | - * @throws InvalidInterfaceException |
|
2456 | - */ |
|
2457 | - private function _process_payment_status($payment, $payment_occurs = EE_PMT_Base::offline) |
|
2458 | - { |
|
2459 | - // off-line payment? carry on |
|
2460 | - if ($payment_occurs === EE_PMT_Base::offline) { |
|
2461 | - return true; |
|
2462 | - } |
|
2463 | - // verify payment validity |
|
2464 | - if ($payment instanceof EE_Payment) { |
|
2465 | - do_action('AHEE_log', __CLASS__, __FUNCTION__, $payment->status(), '$payment->status()'); |
|
2466 | - $msg = $payment->gateway_response(); |
|
2467 | - // check results |
|
2468 | - switch ($payment->status()) { |
|
2469 | - // good payment |
|
2470 | - case EEM_Payment::status_id_approved: |
|
2471 | - EE_Error::add_success( |
|
2472 | - esc_html__('Your payment was processed successfully.', 'event_espresso'), |
|
2473 | - __FILE__, |
|
2474 | - __FUNCTION__, |
|
2475 | - __LINE__ |
|
2476 | - ); |
|
2477 | - return true; |
|
2478 | - // slow payment |
|
2479 | - case EEM_Payment::status_id_pending: |
|
2480 | - if (empty($msg)) { |
|
2481 | - $msg = esc_html__( |
|
2482 | - 'Your payment appears to have been processed successfully, but the Instant Payment Notification has not yet been received. It should arrive shortly.', |
|
2483 | - 'event_espresso' |
|
2484 | - ); |
|
2485 | - } |
|
2486 | - EE_Error::add_success($msg, __FILE__, __FUNCTION__, __LINE__); |
|
2487 | - return true; |
|
2488 | - // don't wanna payment |
|
2489 | - case EEM_Payment::status_id_cancelled: |
|
2490 | - if (empty($msg)) { |
|
2491 | - $msg = _n( |
|
2492 | - 'Payment cancelled. Please try again.', |
|
2493 | - 'Payment cancelled. Please try again or select another method of payment.', |
|
2494 | - count($this->checkout->available_payment_methods), |
|
2495 | - 'event_espresso' |
|
2496 | - ); |
|
2497 | - } |
|
2498 | - EE_Error::add_attention($msg, __FILE__, __FUNCTION__, __LINE__); |
|
2499 | - return false; |
|
2500 | - // not enough payment |
|
2501 | - case EEM_Payment::status_id_declined: |
|
2502 | - if (empty($msg)) { |
|
2503 | - $msg = _n( |
|
2504 | - 'We\'re sorry but your payment was declined. Please try again.', |
|
2505 | - 'We\'re sorry but your payment was declined. Please try again or select another method of payment.', |
|
2506 | - count($this->checkout->available_payment_methods), |
|
2507 | - 'event_espresso' |
|
2508 | - ); |
|
2509 | - } |
|
2510 | - EE_Error::add_attention($msg, __FILE__, __FUNCTION__, __LINE__); |
|
2511 | - return false; |
|
2512 | - // bad payment |
|
2513 | - case EEM_Payment::status_id_failed: |
|
2514 | - if (! empty($msg)) { |
|
2515 | - EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__); |
|
2516 | - return false; |
|
2517 | - } |
|
2518 | - // default to error below |
|
2519 | - break; |
|
2520 | - } |
|
2521 | - } |
|
2522 | - // off-site payment gateway responses are too unreliable, so let's just assume that |
|
2523 | - // the payment processing is just running slower than the registrant's request |
|
2524 | - if ($payment_occurs === EE_PMT_Base::offsite) { |
|
2525 | - return true; |
|
2526 | - } |
|
2527 | - EE_Error::add_error( |
|
2528 | - sprintf( |
|
2529 | - esc_html__( |
|
2530 | - 'Your payment could not be processed successfully due to a technical issue.%sPlease try again or contact %s for assistance.', |
|
2531 | - 'event_espresso' |
|
2532 | - ), |
|
2533 | - '<br/>', |
|
2534 | - EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
2535 | - ), |
|
2536 | - __FILE__, |
|
2537 | - __FUNCTION__, |
|
2538 | - __LINE__ |
|
2539 | - ); |
|
2540 | - return false; |
|
2541 | - } |
|
2542 | - |
|
2543 | - |
|
2544 | - |
|
2545 | - |
|
2546 | - |
|
2547 | - |
|
2548 | - /********************************************************************************************************/ |
|
2549 | - /********************************** PROCESS GATEWAY RESPONSE **********************************/ |
|
2550 | - /********************************************************************************************************/ |
|
2551 | - /** |
|
2552 | - * process_gateway_response |
|
2553 | - * this is the return point for Off-Site Payment Methods |
|
2554 | - * It will attempt to "handle the IPN" if it appears that this has not already occurred, |
|
2555 | - * otherwise, it will load up the last payment made for the TXN. |
|
2556 | - * If the payment retrieved looks good, it will then either: |
|
2557 | - * complete the current step and allow advancement to the next reg step |
|
2558 | - * or present the payment options again |
|
2559 | - * |
|
2560 | - * @return bool |
|
2561 | - * @throws EE_Error |
|
2562 | - * @throws InvalidArgumentException |
|
2563 | - * @throws ReflectionException |
|
2564 | - * @throws InvalidDataTypeException |
|
2565 | - * @throws InvalidInterfaceException |
|
2566 | - */ |
|
2567 | - public function process_gateway_response() |
|
2568 | - { |
|
2569 | - // how have they chosen to pay? |
|
2570 | - $this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment(true); |
|
2571 | - // get EE_Payment_Method object |
|
2572 | - if (! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()) { |
|
2573 | - $this->checkout->continue_reg = false; |
|
2574 | - return false; |
|
2575 | - } |
|
2576 | - if (! $this->checkout->payment_method->is_off_site()) { |
|
2577 | - return false; |
|
2578 | - } |
|
2579 | - $this->_validate_offsite_return(); |
|
2580 | - // verify TXN |
|
2581 | - if ($this->checkout->transaction instanceof EE_Transaction) { |
|
2582 | - $gateway = $this->checkout->payment_method->type_obj()->get_gateway(); |
|
2583 | - if (! $gateway instanceof EE_Offsite_Gateway) { |
|
2584 | - $this->checkout->continue_reg = false; |
|
2585 | - return false; |
|
2586 | - } |
|
2587 | - $payment = $this->_process_off_site_payment($gateway); |
|
2588 | - $payment = $this->_process_cancelled_payments($payment); |
|
2589 | - $payment = $this->_validate_payment($payment); |
|
2590 | - // if payment was not declined by the payment gateway or cancelled by the registrant |
|
2591 | - if ($this->_process_payment_status($payment, EE_PMT_Base::offsite)) { |
|
2592 | - // $this->_setup_redirect_for_next_step(); |
|
2593 | - // store that for later |
|
2594 | - $this->checkout->payment = $payment; |
|
2595 | - // mark this reg step as completed, as long as gateway doesn't use a separate IPN request, |
|
2596 | - // because we will complete this step during the IPN processing then |
|
2597 | - if (! $this->handle_IPN_in_this_request()) { |
|
2598 | - $this->set_completed(); |
|
2599 | - } |
|
2600 | - return true; |
|
2601 | - } |
|
2602 | - } |
|
2603 | - // DEBUG LOG |
|
2604 | - // $this->checkout->log( |
|
2605 | - // __CLASS__, |
|
2606 | - // __FUNCTION__, |
|
2607 | - // __LINE__, |
|
2608 | - // array('payment' => $payment) |
|
2609 | - // ); |
|
2610 | - $this->checkout->continue_reg = false; |
|
2611 | - return false; |
|
2612 | - } |
|
2613 | - |
|
2614 | - |
|
2615 | - /** |
|
2616 | - * _validate_return |
|
2617 | - * |
|
2618 | - * @return void |
|
2619 | - * @throws EE_Error |
|
2620 | - * @throws InvalidArgumentException |
|
2621 | - * @throws InvalidDataTypeException |
|
2622 | - * @throws InvalidInterfaceException |
|
2623 | - * @throws ReflectionException |
|
2624 | - */ |
|
2625 | - private function _validate_offsite_return() |
|
2626 | - { |
|
2627 | - $TXN_ID = $this->request->getRequestParam('spco_txn', 0, 'int'); |
|
2628 | - if ($TXN_ID !== $this->checkout->transaction->ID()) { |
|
2629 | - // Houston... we might have a problem |
|
2630 | - $invalid_TXN = false; |
|
2631 | - // first gather some info |
|
2632 | - $valid_TXN = EEM_Transaction::instance()->get_one_by_ID($TXN_ID); |
|
2633 | - $primary_registrant = $valid_TXN instanceof EE_Transaction |
|
2634 | - ? $valid_TXN->primary_registration() |
|
2635 | - : null; |
|
2636 | - // let's start by retrieving the cart for this TXN |
|
2637 | - $cart = $this->checkout->get_cart_for_transaction($this->checkout->transaction); |
|
2638 | - if ($cart instanceof EE_Cart) { |
|
2639 | - // verify that the current cart has tickets |
|
2640 | - $tickets = $cart->get_tickets(); |
|
2641 | - if (empty($tickets)) { |
|
2642 | - $invalid_TXN = true; |
|
2643 | - } |
|
2644 | - } else { |
|
2645 | - $invalid_TXN = true; |
|
2646 | - } |
|
2647 | - $valid_TXN_SID = $primary_registrant instanceof EE_Registration |
|
2648 | - ? $primary_registrant->session_ID() |
|
2649 | - : null; |
|
2650 | - // validate current Session ID and compare against valid TXN session ID |
|
2651 | - if ( |
|
2652 | - $invalid_TXN // if this is already true, then skip other checks |
|
2653 | - || EE_Session::instance()->id() === null |
|
2654 | - || ( |
|
2655 | - // WARNING !!! |
|
2656 | - // this could be PayPal sending back duplicate requests (ya they do that) |
|
2657 | - // or it **could** mean someone is simply registering AGAIN after having just done so |
|
2658 | - // so now we need to determine if this current TXN looks valid or not |
|
2659 | - // and whether this reg step has even been started ? |
|
2660 | - EE_Session::instance()->id() === $valid_TXN_SID |
|
2661 | - // really? you're half way through this reg step, but you never started it ? |
|
2662 | - && $this->checkout->transaction->reg_step_completed($this->slug()) === false |
|
2663 | - ) |
|
2664 | - ) { |
|
2665 | - $invalid_TXN = true; |
|
2666 | - } |
|
2667 | - if ($invalid_TXN) { |
|
2668 | - // is the valid TXN completed ? |
|
2669 | - if ($valid_TXN instanceof EE_Transaction) { |
|
2670 | - // has this step even been started ? |
|
2671 | - $reg_step_completed = $valid_TXN->reg_step_completed($this->slug()); |
|
2672 | - if ($reg_step_completed !== false && $reg_step_completed !== true) { |
|
2673 | - // so it **looks** like this is a double request from PayPal |
|
2674 | - // so let's try to pick up where we left off |
|
2675 | - $this->checkout->transaction = $valid_TXN; |
|
2676 | - $this->checkout->refresh_all_entities(true); |
|
2677 | - return; |
|
2678 | - } |
|
2679 | - } |
|
2680 | - // you appear to be lost? |
|
2681 | - $this->_redirect_wayward_request($primary_registrant); |
|
2682 | - } |
|
2683 | - } |
|
2684 | - } |
|
2685 | - |
|
2686 | - |
|
2687 | - /** |
|
2688 | - * _redirect_wayward_request |
|
2689 | - * |
|
2690 | - * @param EE_Registration|null $primary_registrant |
|
2691 | - * @return void |
|
2692 | - * @throws EE_Error |
|
2693 | - * @throws InvalidArgumentException |
|
2694 | - * @throws InvalidDataTypeException |
|
2695 | - * @throws InvalidInterfaceException |
|
2696 | - * @throws ReflectionException |
|
2697 | - */ |
|
2698 | - private function _redirect_wayward_request(EE_Registration $primary_registrant) |
|
2699 | - { |
|
2700 | - if (! $primary_registrant instanceof EE_Registration) { |
|
2701 | - // try redirecting based on the current TXN |
|
2702 | - $primary_registrant = $this->checkout->transaction instanceof EE_Transaction |
|
2703 | - ? $this->checkout->transaction->primary_registration() |
|
2704 | - : null; |
|
2705 | - } |
|
2706 | - if (! $primary_registrant instanceof EE_Registration) { |
|
2707 | - EE_Error::add_error( |
|
2708 | - sprintf( |
|
2709 | - esc_html__( |
|
2710 | - 'Invalid information was received from the Off-Site Payment Processor and your Transaction details could not be retrieved from the database.%1$sPlease try again or contact %2$s for assistance.', |
|
2711 | - 'event_espresso' |
|
2712 | - ), |
|
2713 | - '<br/>', |
|
2714 | - EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
2715 | - ), |
|
2716 | - __FILE__, |
|
2717 | - __FUNCTION__, |
|
2718 | - __LINE__ |
|
2719 | - ); |
|
2720 | - return; |
|
2721 | - } |
|
2722 | - // make sure transaction is not locked |
|
2723 | - $this->checkout->transaction->unlock(); |
|
2724 | - wp_safe_redirect( |
|
2725 | - add_query_arg( |
|
2726 | - [ |
|
2727 | - 'e_reg_url_link' => $primary_registrant->reg_url_link(), |
|
2728 | - ], |
|
2729 | - $this->checkout->thank_you_page_url |
|
2730 | - ) |
|
2731 | - ); |
|
2732 | - exit(); |
|
2733 | - } |
|
2734 | - |
|
2735 | - |
|
2736 | - /** |
|
2737 | - * _process_off_site_payment |
|
2738 | - * |
|
2739 | - * @param EE_Offsite_Gateway $gateway |
|
2740 | - * @return EE_Payment |
|
2741 | - * @throws EE_Error |
|
2742 | - * @throws InvalidArgumentException |
|
2743 | - * @throws InvalidDataTypeException |
|
2744 | - * @throws InvalidInterfaceException |
|
2745 | - * @throws ReflectionException |
|
2746 | - */ |
|
2747 | - private function _process_off_site_payment(EE_Offsite_Gateway $gateway) |
|
2748 | - { |
|
2749 | - try { |
|
2750 | - $request = LoaderFactory::getLoader()->getShared(RequestInterface::class); |
|
2751 | - $request_data = $request->requestParams(); |
|
2752 | - // if gateway uses_separate_IPN_request, then we don't have to process the IPN manually |
|
2753 | - $this->set_handle_IPN_in_this_request( |
|
2754 | - $gateway->handle_IPN_in_this_request($request_data, false) |
|
2755 | - ); |
|
2756 | - if ($this->handle_IPN_in_this_request()) { |
|
2757 | - // get payment details and process results |
|
2758 | - /** @type EE_Payment_Processor $payment_processor */ |
|
2759 | - $payment_processor = EE_Registry::instance()->load_core('Payment_Processor'); |
|
2760 | - $payment = $payment_processor->process_ipn( |
|
2761 | - $request_data, |
|
2762 | - $this->checkout->transaction, |
|
2763 | - $this->checkout->payment_method, |
|
2764 | - true, |
|
2765 | - false |
|
2766 | - ); |
|
2767 | - // $payment_source = 'process_ipn'; |
|
2768 | - } else { |
|
2769 | - $payment = $this->checkout->transaction->last_payment(); |
|
2770 | - // $payment_source = 'last_payment'; |
|
2771 | - } |
|
2772 | - } catch (Exception $e) { |
|
2773 | - // let's just eat the exception and try to move on using any previously set payment info |
|
2774 | - $payment = $this->checkout->transaction->last_payment(); |
|
2775 | - // $payment_source = 'last_payment after Exception'; |
|
2776 | - // but if we STILL don't have a payment object |
|
2777 | - if (! $payment instanceof EE_Payment) { |
|
2778 | - // then we'll object ! ( not object like a thing... but object like what a lawyer says ! ) |
|
2779 | - $this->_handle_payment_processor_exception($e); |
|
2780 | - } |
|
2781 | - } |
|
2782 | - return $payment; |
|
2783 | - } |
|
2784 | - |
|
2785 | - |
|
2786 | - /** |
|
2787 | - * _process_cancelled_payments |
|
2788 | - * just makes sure that the payment status gets updated correctly |
|
2789 | - * so tha tan error isn't generated during payment validation |
|
2790 | - * |
|
2791 | - * @param EE_Payment $payment |
|
2792 | - * @return EE_Payment|null |
|
2793 | - * @throws EE_Error |
|
2794 | - */ |
|
2795 | - private function _process_cancelled_payments($payment = null) |
|
2796 | - { |
|
2797 | - if ( |
|
2798 | - $payment instanceof EE_Payment |
|
2799 | - && $this->request->requestParamIsSet('ee_cancel_payment') |
|
2800 | - && $payment->status() === EEM_Payment::status_id_failed |
|
2801 | - ) { |
|
2802 | - $payment->set_status(EEM_Payment::status_id_cancelled); |
|
2803 | - } |
|
2804 | - return $payment; |
|
2805 | - } |
|
2806 | - |
|
2807 | - |
|
2808 | - /** |
|
2809 | - * get_transaction_details_for_gateways |
|
2810 | - * |
|
2811 | - * @access public |
|
2812 | - * @return void |
|
2813 | - * @throws EE_Error |
|
2814 | - * @throws InvalidArgumentException |
|
2815 | - * @throws ReflectionException |
|
2816 | - * @throws InvalidDataTypeException |
|
2817 | - * @throws InvalidInterfaceException |
|
2818 | - */ |
|
2819 | - public function get_transaction_details_for_gateways() |
|
2820 | - { |
|
2821 | - $txn_details = []; |
|
2822 | - // ya gotta make a choice man |
|
2823 | - if (empty($this->checkout->selected_method_of_payment)) { |
|
2824 | - $txn_details = [ |
|
2825 | - 'error' => esc_html__('Please select a method of payment before proceeding.', 'event_espresso'), |
|
2826 | - ]; |
|
2827 | - } |
|
2828 | - // get EE_Payment_Method object |
|
2829 | - if ( |
|
2830 | - empty($txn_details) |
|
2831 | - && ! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment() |
|
2832 | - ) { |
|
2833 | - $txn_details = [ |
|
2834 | - 'selected_method_of_payment' => $this->checkout->selected_method_of_payment, |
|
2835 | - 'error' => esc_html__( |
|
2836 | - 'A valid Payment Method could not be determined.', |
|
2837 | - 'event_espresso' |
|
2838 | - ), |
|
2839 | - ]; |
|
2840 | - } |
|
2841 | - if (empty($txn_details) && $this->checkout->transaction instanceof EE_Transaction) { |
|
2842 | - $return_url = $this->_get_return_url($this->checkout->payment_method); |
|
2843 | - $txn_details = [ |
|
2844 | - 'TXN_ID' => $this->checkout->transaction->ID(), |
|
2845 | - 'TXN_timestamp' => $this->checkout->transaction->datetime(), |
|
2846 | - 'TXN_total' => $this->checkout->transaction->total(), |
|
2847 | - 'TXN_paid' => $this->checkout->transaction->paid(), |
|
2848 | - 'TXN_reg_steps' => $this->checkout->transaction->reg_steps(), |
|
2849 | - 'STS_ID' => $this->checkout->transaction->status_ID(), |
|
2850 | - 'PMD_ID' => $this->checkout->transaction->payment_method_ID(), |
|
2851 | - 'payment_amount' => $this->checkout->amount_owing, |
|
2852 | - 'return_url' => $return_url, |
|
2853 | - 'cancel_url' => add_query_arg(['ee_cancel_payment' => true], $return_url), |
|
2854 | - 'notify_url' => EE_Config::instance()->core->txn_page_url( |
|
2855 | - [ |
|
2856 | - 'e_reg_url_link' => $this->checkout->transaction->primary_registration()->reg_url_link(), |
|
2857 | - 'ee_payment_method' => $this->checkout->payment_method->slug(), |
|
2858 | - ] |
|
2859 | - ), |
|
2860 | - ]; |
|
2861 | - } |
|
2862 | - echo wp_json_encode($txn_details); |
|
2863 | - exit(); |
|
2864 | - } |
|
2865 | - |
|
2866 | - |
|
2867 | - /** |
|
2868 | - * __sleep |
|
2869 | - * to conserve db space, let's remove the reg_form and the EE_Checkout object from EE_SPCO_Reg_Step objects upon |
|
2870 | - * serialization EE_Checkout will handle the reimplementation of itself upon waking, but we won't bother with the |
|
2871 | - * reg form, because if needed, it will be regenerated anyways |
|
2872 | - * |
|
2873 | - * @return array |
|
2874 | - */ |
|
2875 | - public function __sleep() |
|
2876 | - { |
|
2877 | - // remove the reg form and the checkout |
|
2878 | - return array_diff(array_keys(get_object_vars($this)), ['reg_form', 'checkout', 'line_item_display']); |
|
2879 | - } |
|
22 | + /** |
|
23 | + * @var EE_Line_Item_Display $Line_Item_Display |
|
24 | + */ |
|
25 | + protected $line_item_display; |
|
26 | + |
|
27 | + /** |
|
28 | + * @var boolean $handle_IPN_in_this_request |
|
29 | + */ |
|
30 | + protected $handle_IPN_in_this_request = false; |
|
31 | + |
|
32 | + |
|
33 | + /** |
|
34 | + * set_hooks - for hooking into EE Core, other modules, etc |
|
35 | + * |
|
36 | + * @access public |
|
37 | + * @return void |
|
38 | + */ |
|
39 | + public static function set_hooks() |
|
40 | + { |
|
41 | + add_filter( |
|
42 | + 'FHEE__SPCO__EE_Line_Item_Filter_Collection', |
|
43 | + ['EE_SPCO_Reg_Step_Payment_Options', 'add_spco_line_item_filters'] |
|
44 | + ); |
|
45 | + add_action( |
|
46 | + 'wp_ajax_switch_spco_billing_form', |
|
47 | + ['EE_SPCO_Reg_Step_Payment_Options', 'switch_spco_billing_form'] |
|
48 | + ); |
|
49 | + add_action( |
|
50 | + 'wp_ajax_nopriv_switch_spco_billing_form', |
|
51 | + ['EE_SPCO_Reg_Step_Payment_Options', 'switch_spco_billing_form'] |
|
52 | + ); |
|
53 | + add_action('wp_ajax_save_payer_details', ['EE_SPCO_Reg_Step_Payment_Options', 'save_payer_details']); |
|
54 | + add_action( |
|
55 | + 'wp_ajax_nopriv_save_payer_details', |
|
56 | + ['EE_SPCO_Reg_Step_Payment_Options', 'save_payer_details'] |
|
57 | + ); |
|
58 | + add_action( |
|
59 | + 'wp_ajax_get_transaction_details_for_gateways', |
|
60 | + ['EE_SPCO_Reg_Step_Payment_Options', 'get_transaction_details'] |
|
61 | + ); |
|
62 | + add_action( |
|
63 | + 'wp_ajax_nopriv_get_transaction_details_for_gateways', |
|
64 | + ['EE_SPCO_Reg_Step_Payment_Options', 'get_transaction_details'] |
|
65 | + ); |
|
66 | + add_filter( |
|
67 | + 'FHEE__EED_Recaptcha___bypass_recaptcha__bypass_request_params_array', |
|
68 | + ['EE_SPCO_Reg_Step_Payment_Options', 'bypass_recaptcha_for_load_payment_method'], |
|
69 | + 10, |
|
70 | + 1 |
|
71 | + ); |
|
72 | + } |
|
73 | + |
|
74 | + |
|
75 | + /** |
|
76 | + * ajax switch_spco_billing_form |
|
77 | + * |
|
78 | + */ |
|
79 | + public static function switch_spco_billing_form() |
|
80 | + { |
|
81 | + EED_Single_Page_Checkout::process_ajax_request('switch_payment_method'); |
|
82 | + } |
|
83 | + |
|
84 | + |
|
85 | + /** |
|
86 | + * ajax save_payer_details |
|
87 | + * |
|
88 | + */ |
|
89 | + public static function save_payer_details() |
|
90 | + { |
|
91 | + EED_Single_Page_Checkout::process_ajax_request('save_payer_details_via_ajax'); |
|
92 | + } |
|
93 | + |
|
94 | + |
|
95 | + /** |
|
96 | + * ajax get_transaction_details |
|
97 | + * |
|
98 | + */ |
|
99 | + public static function get_transaction_details() |
|
100 | + { |
|
101 | + EED_Single_Page_Checkout::process_ajax_request('get_transaction_details_for_gateways'); |
|
102 | + } |
|
103 | + |
|
104 | + |
|
105 | + /** |
|
106 | + * bypass_recaptcha_for_load_payment_method |
|
107 | + * |
|
108 | + * @access public |
|
109 | + * @return array |
|
110 | + * @throws InvalidArgumentException |
|
111 | + * @throws InvalidDataTypeException |
|
112 | + * @throws InvalidInterfaceException |
|
113 | + */ |
|
114 | + public static function bypass_recaptcha_for_load_payment_method() |
|
115 | + { |
|
116 | + return [ |
|
117 | + 'EESID' => EE_Registry::instance()->SSN->id(), |
|
118 | + 'step' => 'payment_options', |
|
119 | + 'action' => 'spco_billing_form', |
|
120 | + ]; |
|
121 | + } |
|
122 | + |
|
123 | + |
|
124 | + /** |
|
125 | + * class constructor |
|
126 | + * |
|
127 | + * @access public |
|
128 | + * @param EE_Checkout $checkout |
|
129 | + */ |
|
130 | + public function __construct(EE_Checkout $checkout) |
|
131 | + { |
|
132 | + $this->request = EED_Single_Page_Checkout::getRequest(); |
|
133 | + $this->_slug = 'payment_options'; |
|
134 | + $this->_name = esc_html__('Payment Options', 'event_espresso'); |
|
135 | + $this->_template = SPCO_REG_STEPS_PATH . $this->_slug . '/payment_options_main.template.php'; |
|
136 | + $this->checkout = $checkout; |
|
137 | + $this->_reset_success_message(); |
|
138 | + $this->set_instructions( |
|
139 | + esc_html__( |
|
140 | + 'Please select a method of payment and provide any necessary billing information before proceeding.', |
|
141 | + 'event_espresso' |
|
142 | + ) |
|
143 | + ); |
|
144 | + } |
|
145 | + |
|
146 | + |
|
147 | + /** |
|
148 | + * @return null |
|
149 | + */ |
|
150 | + public function line_item_display() |
|
151 | + { |
|
152 | + return $this->line_item_display; |
|
153 | + } |
|
154 | + |
|
155 | + |
|
156 | + /** |
|
157 | + * @param null $line_item_display |
|
158 | + */ |
|
159 | + public function set_line_item_display($line_item_display) |
|
160 | + { |
|
161 | + $this->line_item_display = $line_item_display; |
|
162 | + } |
|
163 | + |
|
164 | + |
|
165 | + /** |
|
166 | + * @return boolean |
|
167 | + */ |
|
168 | + public function handle_IPN_in_this_request() |
|
169 | + { |
|
170 | + return $this->handle_IPN_in_this_request; |
|
171 | + } |
|
172 | + |
|
173 | + |
|
174 | + /** |
|
175 | + * @param boolean $handle_IPN_in_this_request |
|
176 | + */ |
|
177 | + public function set_handle_IPN_in_this_request($handle_IPN_in_this_request) |
|
178 | + { |
|
179 | + $this->handle_IPN_in_this_request = filter_var($handle_IPN_in_this_request, FILTER_VALIDATE_BOOLEAN); |
|
180 | + } |
|
181 | + |
|
182 | + |
|
183 | + /** |
|
184 | + * translate_js_strings |
|
185 | + * |
|
186 | + * @return void |
|
187 | + */ |
|
188 | + public function translate_js_strings() |
|
189 | + { |
|
190 | + EE_Registry::$i18n_js_strings['no_payment_method'] = esc_html__( |
|
191 | + 'Please select a method of payment in order to continue.', |
|
192 | + 'event_espresso' |
|
193 | + ); |
|
194 | + EE_Registry::$i18n_js_strings['invalid_payment_method'] = esc_html__( |
|
195 | + 'A valid method of payment could not be determined. Please refresh the page and try again.', |
|
196 | + 'event_espresso' |
|
197 | + ); |
|
198 | + EE_Registry::$i18n_js_strings['forwarding_to_offsite'] = esc_html__( |
|
199 | + 'Forwarding to Secure Payment Provider.', |
|
200 | + 'event_espresso' |
|
201 | + ); |
|
202 | + } |
|
203 | + |
|
204 | + |
|
205 | + /** |
|
206 | + * enqueue_styles_and_scripts |
|
207 | + * |
|
208 | + * @return void |
|
209 | + * @throws EE_Error |
|
210 | + * @throws InvalidArgumentException |
|
211 | + * @throws InvalidDataTypeException |
|
212 | + * @throws InvalidInterfaceException |
|
213 | + * @throws ReflectionException |
|
214 | + */ |
|
215 | + public function enqueue_styles_and_scripts() |
|
216 | + { |
|
217 | + $transaction = $this->checkout->transaction; |
|
218 | + // if the transaction isn't set or nothing is owed on it, don't enqueue any JS |
|
219 | + if (! $transaction instanceof EE_Transaction || EEH_Money::compare_floats($transaction->remaining(), 0)) { |
|
220 | + return; |
|
221 | + } |
|
222 | + foreach ( |
|
223 | + EEM_Payment_Method::instance()->get_all_for_transaction( |
|
224 | + $transaction, |
|
225 | + EEM_Payment_Method::scope_cart |
|
226 | + ) as $payment_method |
|
227 | + ) { |
|
228 | + $type_obj = $payment_method->type_obj(); |
|
229 | + if ($type_obj instanceof EE_PMT_Base) { |
|
230 | + $billing_form = $type_obj->generate_new_billing_form($transaction); |
|
231 | + if ($billing_form instanceof EE_Form_Section_Proper) { |
|
232 | + $billing_form->enqueue_js(); |
|
233 | + } |
|
234 | + } |
|
235 | + } |
|
236 | + } |
|
237 | + |
|
238 | + |
|
239 | + /** |
|
240 | + * initialize_reg_step |
|
241 | + * |
|
242 | + * @return bool |
|
243 | + * @throws EE_Error |
|
244 | + * @throws InvalidArgumentException |
|
245 | + * @throws ReflectionException |
|
246 | + * @throws InvalidDataTypeException |
|
247 | + * @throws InvalidInterfaceException |
|
248 | + */ |
|
249 | + public function initialize_reg_step() |
|
250 | + { |
|
251 | + // TODO: if /when we implement donations, then this will need overriding |
|
252 | + if ( |
|
253 | + // don't need payment options for: |
|
254 | + // registrations made via the admin |
|
255 | + // completed transactions |
|
256 | + // overpaid transactions |
|
257 | + // $ 0.00 transactions(no payment required) |
|
258 | + ! $this->checkout->payment_required() |
|
259 | + // but do NOT remove if current action being called belongs to this reg step |
|
260 | + && ! is_callable([$this, $this->checkout->action]) |
|
261 | + && ! $this->completed() |
|
262 | + ) { |
|
263 | + // and if so, then we no longer need the Payment Options step |
|
264 | + if ($this->is_current_step()) { |
|
265 | + $this->checkout->generate_reg_form = false; |
|
266 | + } |
|
267 | + $this->checkout->remove_reg_step($this->_slug); |
|
268 | + // DEBUG LOG |
|
269 | + // $this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ ); |
|
270 | + return false; |
|
271 | + } |
|
272 | + // load EEM_Payment_Method |
|
273 | + EE_Registry::instance()->load_model('Payment_Method'); |
|
274 | + // get all active payment methods |
|
275 | + $this->checkout->available_payment_methods = EEM_Payment_Method::instance()->get_all_for_transaction( |
|
276 | + $this->checkout->transaction, |
|
277 | + EEM_Payment_Method::scope_cart |
|
278 | + ); |
|
279 | + return true; |
|
280 | + } |
|
281 | + |
|
282 | + |
|
283 | + /** |
|
284 | + * @return EE_Form_Section_Proper |
|
285 | + * @throws EE_Error |
|
286 | + * @throws InvalidArgumentException |
|
287 | + * @throws ReflectionException |
|
288 | + * @throws EntityNotFoundException |
|
289 | + * @throws InvalidDataTypeException |
|
290 | + * @throws InvalidInterfaceException |
|
291 | + * @throws InvalidStatusException |
|
292 | + */ |
|
293 | + public function generate_reg_form() |
|
294 | + { |
|
295 | + // reset in case someone changes their mind |
|
296 | + $this->_reset_selected_method_of_payment(); |
|
297 | + // set some defaults |
|
298 | + $this->checkout->selected_method_of_payment = 'payments_closed'; |
|
299 | + $registrations_requiring_payment = []; |
|
300 | + $registrations_for_free_events = []; |
|
301 | + $registrations_requiring_pre_approval = []; |
|
302 | + $sold_out_events = []; |
|
303 | + $insufficient_spaces_available = []; |
|
304 | + $no_payment_required = true; |
|
305 | + // loop thru registrations to gather info |
|
306 | + $registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params); |
|
307 | + $ejected_registrations = EE_SPCO_Reg_Step_Payment_Options::find_registrations_that_lost_their_space( |
|
308 | + $registrations, |
|
309 | + $this->checkout->revisit |
|
310 | + ); |
|
311 | + foreach ($registrations as $REG_ID => $registration) { |
|
312 | + /** @var $registration EE_Registration */ |
|
313 | + // has this registration lost it's space ? |
|
314 | + if (isset($ejected_registrations[ $REG_ID ])) { |
|
315 | + if ($registration->event()->is_sold_out() || $registration->event()->is_sold_out(true)) { |
|
316 | + $sold_out_events[ $registration->event()->ID() ] = $registration->event(); |
|
317 | + } else { |
|
318 | + $insufficient_spaces_available[ $registration->event()->ID() ] = $registration->event(); |
|
319 | + } |
|
320 | + continue; |
|
321 | + } |
|
322 | + // event requires admin approval |
|
323 | + if ($registration->status_ID() === EEM_Registration::status_id_not_approved) { |
|
324 | + // add event to list of events with pre-approval reg status |
|
325 | + $registrations_requiring_pre_approval[ $REG_ID ] = $registration; |
|
326 | + do_action( |
|
327 | + 'AHEE__EE_SPCO_Reg_Step_Payment_Options__generate_reg_form__event_requires_pre_approval', |
|
328 | + $registration->event(), |
|
329 | + $this |
|
330 | + ); |
|
331 | + continue; |
|
332 | + } |
|
333 | + if ( |
|
334 | + $this->checkout->revisit |
|
335 | + && $registration->status_ID() !== EEM_Registration::status_id_approved |
|
336 | + && ( |
|
337 | + $registration->event()->is_sold_out() |
|
338 | + || $registration->event()->is_sold_out(true) |
|
339 | + ) |
|
340 | + ) { |
|
341 | + // add event to list of events that are sold out |
|
342 | + $sold_out_events[ $registration->event()->ID() ] = $registration->event(); |
|
343 | + do_action( |
|
344 | + 'AHEE__EE_SPCO_Reg_Step_Payment_Options__generate_reg_form__sold_out_event', |
|
345 | + $registration->event(), |
|
346 | + $this |
|
347 | + ); |
|
348 | + continue; |
|
349 | + } |
|
350 | + // are they allowed to pay now and is there monies owing? |
|
351 | + if ($registration->owes_monies_and_can_pay()) { |
|
352 | + $registrations_requiring_payment[ $REG_ID ] = $registration; |
|
353 | + do_action( |
|
354 | + 'AHEE__EE_SPCO_Reg_Step_Payment_Options__generate_reg_form__event_requires_payment', |
|
355 | + $registration->event(), |
|
356 | + $this |
|
357 | + ); |
|
358 | + } elseif ( |
|
359 | + ! $this->checkout->revisit |
|
360 | + && $registration->status_ID() !== EEM_Registration::status_id_not_approved |
|
361 | + && $registration->ticket()->is_free() |
|
362 | + ) { |
|
363 | + $registrations_for_free_events[ $registration->ticket()->ID() ] = $registration; |
|
364 | + } |
|
365 | + } |
|
366 | + $subsections = []; |
|
367 | + // now decide which template to load |
|
368 | + if (! empty($sold_out_events)) { |
|
369 | + $subsections['sold_out_events'] = $this->_sold_out_events($sold_out_events); |
|
370 | + } |
|
371 | + if (! empty($insufficient_spaces_available)) { |
|
372 | + $subsections['insufficient_space'] = $this->_insufficient_spaces_available( |
|
373 | + $insufficient_spaces_available |
|
374 | + ); |
|
375 | + } |
|
376 | + if (! empty($registrations_requiring_pre_approval)) { |
|
377 | + $subsections['registrations_requiring_pre_approval'] = $this->_registrations_requiring_pre_approval( |
|
378 | + $registrations_requiring_pre_approval |
|
379 | + ); |
|
380 | + } |
|
381 | + if (! empty($registrations_for_free_events)) { |
|
382 | + $subsections['no_payment_required'] = $this->_no_payment_required($registrations_for_free_events); |
|
383 | + } |
|
384 | + if (! empty($registrations_requiring_payment)) { |
|
385 | + if ($this->checkout->amount_owing > 0) { |
|
386 | + // autoload Line_Item_Display classes |
|
387 | + EEH_Autoloader::register_line_item_filter_autoloaders(); |
|
388 | + $line_item_filter_processor = new EE_Line_Item_Filter_Processor( |
|
389 | + apply_filters( |
|
390 | + 'FHEE__SPCO__EE_Line_Item_Filter_Collection', |
|
391 | + new EE_Line_Item_Filter_Collection() |
|
392 | + ), |
|
393 | + $this->checkout->cart->get_grand_total() |
|
394 | + ); |
|
395 | + /** @var EE_Line_Item $filtered_line_item_tree */ |
|
396 | + $filtered_line_item_tree = $line_item_filter_processor->process(); |
|
397 | + EEH_Autoloader::register_line_item_display_autoloaders(); |
|
398 | + $this->set_line_item_display(new EE_Line_Item_Display('spco')); |
|
399 | + $subsections['payment_options'] = $this->_display_payment_options( |
|
400 | + $this->line_item_display->display_line_item( |
|
401 | + $filtered_line_item_tree, |
|
402 | + ['registrations' => $registrations] |
|
403 | + ) |
|
404 | + ); |
|
405 | + $this->checkout->amount_owing = $filtered_line_item_tree->total(); |
|
406 | + $this->_apply_registration_payments_to_amount_owing($registrations); |
|
407 | + } |
|
408 | + $no_payment_required = false; |
|
409 | + } else { |
|
410 | + $this->_hide_reg_step_submit_button_if_revisit(); |
|
411 | + } |
|
412 | + $this->_save_selected_method_of_payment(); |
|
413 | + |
|
414 | + $subsections['default_hidden_inputs'] = $this->reg_step_hidden_inputs(); |
|
415 | + $subsections['extra_hidden_inputs'] = $this->_extra_hidden_inputs($no_payment_required); |
|
416 | + |
|
417 | + return new EE_Form_Section_Proper( |
|
418 | + [ |
|
419 | + 'name' => $this->reg_form_name(), |
|
420 | + 'html_id' => $this->reg_form_name(), |
|
421 | + 'subsections' => $subsections, |
|
422 | + 'layout_strategy' => new EE_No_Layout(), |
|
423 | + ] |
|
424 | + ); |
|
425 | + } |
|
426 | + |
|
427 | + |
|
428 | + /** |
|
429 | + * add line item filters required for this reg step |
|
430 | + * these filters are applied via this line in EE_SPCO_Reg_Step_Payment_Options::set_hooks(): |
|
431 | + * add_filter( 'FHEE__SPCO__EE_Line_Item_Filter_Collection', array( 'EE_SPCO_Reg_Step_Payment_Options', |
|
432 | + * 'add_spco_line_item_filters' ) ); so any code that wants to use the same set of filters during the |
|
433 | + * payment options reg step, can apply these filters via the following: apply_filters( |
|
434 | + * 'FHEE__SPCO__EE_Line_Item_Filter_Collection', new EE_Line_Item_Filter_Collection() ) or to an existing |
|
435 | + * filter collection by passing that instead of instantiating a new collection |
|
436 | + * |
|
437 | + * @param EE_Line_Item_Filter_Collection $line_item_filter_collection |
|
438 | + * @return EE_Line_Item_Filter_Collection |
|
439 | + * @throws EE_Error |
|
440 | + * @throws InvalidArgumentException |
|
441 | + * @throws ReflectionException |
|
442 | + * @throws EntityNotFoundException |
|
443 | + * @throws InvalidDataTypeException |
|
444 | + * @throws InvalidInterfaceException |
|
445 | + * @throws InvalidStatusException |
|
446 | + */ |
|
447 | + public static function add_spco_line_item_filters(EE_Line_Item_Filter_Collection $line_item_filter_collection) |
|
448 | + { |
|
449 | + if (! EE_Registry::instance()->SSN instanceof EE_Session) { |
|
450 | + return $line_item_filter_collection; |
|
451 | + } |
|
452 | + if (! EE_Registry::instance()->SSN->checkout() instanceof EE_Checkout) { |
|
453 | + return $line_item_filter_collection; |
|
454 | + } |
|
455 | + if (! EE_Registry::instance()->SSN->checkout()->transaction instanceof EE_Transaction) { |
|
456 | + return $line_item_filter_collection; |
|
457 | + } |
|
458 | + $line_item_filter_collection->add( |
|
459 | + new EE_Billable_Line_Item_Filter( |
|
460 | + EE_SPCO_Reg_Step_Payment_Options::remove_ejected_registrations( |
|
461 | + EE_Registry::instance()->SSN->checkout()->transaction->registrations( |
|
462 | + EE_Registry::instance()->SSN->checkout()->reg_cache_where_params |
|
463 | + ) |
|
464 | + ) |
|
465 | + ) |
|
466 | + ); |
|
467 | + $line_item_filter_collection->add(new EE_Non_Zero_Line_Item_Filter()); |
|
468 | + return $line_item_filter_collection; |
|
469 | + } |
|
470 | + |
|
471 | + |
|
472 | + /** |
|
473 | + * remove_ejected_registrations |
|
474 | + * if a registrant has lost their potential space at an event due to lack of payment, |
|
475 | + * then this method removes them from the list of registrations being paid for during this request |
|
476 | + * |
|
477 | + * @param EE_Registration[] $registrations |
|
478 | + * @return EE_Registration[] |
|
479 | + * @throws EE_Error |
|
480 | + * @throws InvalidArgumentException |
|
481 | + * @throws ReflectionException |
|
482 | + * @throws EntityNotFoundException |
|
483 | + * @throws InvalidDataTypeException |
|
484 | + * @throws InvalidInterfaceException |
|
485 | + * @throws InvalidStatusException |
|
486 | + */ |
|
487 | + public static function remove_ejected_registrations(array $registrations) |
|
488 | + { |
|
489 | + $ejected_registrations = EE_SPCO_Reg_Step_Payment_Options::find_registrations_that_lost_their_space( |
|
490 | + $registrations, |
|
491 | + EE_Registry::instance()->SSN->checkout()->revisit |
|
492 | + ); |
|
493 | + foreach ($registrations as $REG_ID => $registration) { |
|
494 | + // has this registration lost it's space ? |
|
495 | + if (isset($ejected_registrations[ $REG_ID ])) { |
|
496 | + unset($registrations[ $REG_ID ]); |
|
497 | + } |
|
498 | + } |
|
499 | + return $registrations; |
|
500 | + } |
|
501 | + |
|
502 | + |
|
503 | + /** |
|
504 | + * find_registrations_that_lost_their_space |
|
505 | + * If a registrant chooses an offline payment method like Invoice, |
|
506 | + * then no space is reserved for them at the event until they fully pay fo that site |
|
507 | + * (unless the event's default reg status is set to APPROVED) |
|
508 | + * if a registrant then later returns to pay, but the number of spaces available has been reduced due to sales, |
|
509 | + * then this method will determine which registrations have lost the ability to complete the reg process. |
|
510 | + * |
|
511 | + * @param EE_Registration[] $registrations |
|
512 | + * @param bool $revisit |
|
513 | + * @return array |
|
514 | + * @throws EE_Error |
|
515 | + * @throws InvalidArgumentException |
|
516 | + * @throws ReflectionException |
|
517 | + * @throws EntityNotFoundException |
|
518 | + * @throws InvalidDataTypeException |
|
519 | + * @throws InvalidInterfaceException |
|
520 | + * @throws InvalidStatusException |
|
521 | + */ |
|
522 | + public static function find_registrations_that_lost_their_space(array $registrations, $revisit = false) |
|
523 | + { |
|
524 | + // registrations per event |
|
525 | + $event_reg_count = []; |
|
526 | + // spaces left per event |
|
527 | + $event_spaces_remaining = []; |
|
528 | + // tickets left sorted by ID |
|
529 | + $tickets_remaining = []; |
|
530 | + // registrations that have lost their space |
|
531 | + $ejected_registrations = []; |
|
532 | + foreach ($registrations as $REG_ID => $registration) { |
|
533 | + if ( |
|
534 | + $registration->status_ID() === EEM_Registration::status_id_approved |
|
535 | + || apply_filters( |
|
536 | + 'FHEE__EE_SPCO_Reg_Step_Payment_Options__find_registrations_that_lost_their_space__allow_reg_payment', |
|
537 | + false, |
|
538 | + $registration, |
|
539 | + $revisit |
|
540 | + ) |
|
541 | + ) { |
|
542 | + continue; |
|
543 | + } |
|
544 | + $EVT_ID = $registration->event_ID(); |
|
545 | + $ticket = $registration->ticket(); |
|
546 | + if (! isset($tickets_remaining[ $ticket->ID() ])) { |
|
547 | + $tickets_remaining[ $ticket->ID() ] = $ticket->remaining(); |
|
548 | + } |
|
549 | + if ($tickets_remaining[ $ticket->ID() ] > 0) { |
|
550 | + if (! isset($event_reg_count[ $EVT_ID ])) { |
|
551 | + $event_reg_count[ $EVT_ID ] = 0; |
|
552 | + } |
|
553 | + $event_reg_count[ $EVT_ID ]++; |
|
554 | + if (! isset($event_spaces_remaining[ $EVT_ID ])) { |
|
555 | + $event_spaces_remaining[ $EVT_ID ] = $registration->event()->spaces_remaining_for_sale(); |
|
556 | + } |
|
557 | + } |
|
558 | + if ( |
|
559 | + $revisit |
|
560 | + && ($tickets_remaining[ $ticket->ID() ] === 0 |
|
561 | + || $event_reg_count[ $EVT_ID ] > $event_spaces_remaining[ $EVT_ID ] |
|
562 | + ) |
|
563 | + ) { |
|
564 | + $ejected_registrations[ $REG_ID ] = $registration->event(); |
|
565 | + if ($registration->status_ID() !== EEM_Registration::status_id_wait_list) { |
|
566 | + /** @type EE_Registration_Processor $registration_processor */ |
|
567 | + $registration_processor = EE_Registry::instance()->load_class('Registration_Processor'); |
|
568 | + // at this point, we should have enough details about the registrant to consider the registration |
|
569 | + // NOT incomplete |
|
570 | + $registration_processor->manually_update_registration_status( |
|
571 | + $registration, |
|
572 | + EEM_Registration::status_id_wait_list |
|
573 | + ); |
|
574 | + } |
|
575 | + } |
|
576 | + } |
|
577 | + return $ejected_registrations; |
|
578 | + } |
|
579 | + |
|
580 | + |
|
581 | + /** |
|
582 | + * _hide_reg_step_submit_button |
|
583 | + * removes the html for the reg step submit button |
|
584 | + * by replacing it with an empty string via filter callback |
|
585 | + * |
|
586 | + * @return void |
|
587 | + */ |
|
588 | + protected function _adjust_registration_status_if_event_old_sold() |
|
589 | + { |
|
590 | + } |
|
591 | + |
|
592 | + |
|
593 | + /** |
|
594 | + * _hide_reg_step_submit_button |
|
595 | + * removes the html for the reg step submit button |
|
596 | + * by replacing it with an empty string via filter callback |
|
597 | + * |
|
598 | + * @return void |
|
599 | + */ |
|
600 | + protected function _hide_reg_step_submit_button_if_revisit() |
|
601 | + { |
|
602 | + if ($this->checkout->revisit) { |
|
603 | + add_filter('FHEE__EE_SPCO_Reg_Step__reg_step_submit_button__sbmt_btn_html', '__return_empty_string'); |
|
604 | + } |
|
605 | + } |
|
606 | + |
|
607 | + |
|
608 | + /** |
|
609 | + * sold_out_events |
|
610 | + * displays notices regarding events that have sold out since hte registrant first signed up |
|
611 | + * |
|
612 | + * @param EE_Event[] $sold_out_events_array |
|
613 | + * @return EE_Form_Section_Proper |
|
614 | + * @throws EE_Error |
|
615 | + */ |
|
616 | + private function _sold_out_events($sold_out_events_array = []) |
|
617 | + { |
|
618 | + // set some defaults |
|
619 | + $this->checkout->selected_method_of_payment = 'events_sold_out'; |
|
620 | + $sold_out_events = ''; |
|
621 | + foreach ($sold_out_events_array as $sold_out_event) { |
|
622 | + $sold_out_events .= EEH_HTML::li( |
|
623 | + EEH_HTML::span( |
|
624 | + ' ' . $sold_out_event->name(), |
|
625 | + '', |
|
626 | + 'dashicons dashicons-marker ee-icon-size-16 pink-text' |
|
627 | + ) |
|
628 | + ); |
|
629 | + } |
|
630 | + return new EE_Form_Section_Proper( |
|
631 | + [ |
|
632 | + 'layout_strategy' => new EE_Template_Layout( |
|
633 | + [ |
|
634 | + 'layout_template_file' => SPCO_REG_STEPS_PATH |
|
635 | + . $this->_slug |
|
636 | + . '/sold_out_events.template.php', |
|
637 | + 'template_args' => apply_filters( |
|
638 | + 'FHEE__EE_SPCO_Reg_Step_Payment_Options___sold_out_events__template_args', |
|
639 | + [ |
|
640 | + 'sold_out_events' => $sold_out_events, |
|
641 | + 'sold_out_events_msg' => apply_filters( |
|
642 | + 'FHEE__EE_SPCO_Reg_Step_Payment_Options___sold_out_events__sold_out_events_msg', |
|
643 | + sprintf( |
|
644 | + esc_html__( |
|
645 | + 'It appears that the event you were about to make a payment for has sold out since you first registered. If you have already made a partial payment towards this event, please contact the event administrator for a refund.%3$s%3$s%1$sPlease note that availability can change at any time due to cancellations, so please check back again later if registration for this event(s) is important to you.%2$s', |
|
646 | + 'event_espresso' |
|
647 | + ), |
|
648 | + '<strong>', |
|
649 | + '</strong>', |
|
650 | + '<br />' |
|
651 | + ) |
|
652 | + ), |
|
653 | + ] |
|
654 | + ), |
|
655 | + ] |
|
656 | + ), |
|
657 | + ] |
|
658 | + ); |
|
659 | + } |
|
660 | + |
|
661 | + |
|
662 | + /** |
|
663 | + * _insufficient_spaces_available |
|
664 | + * displays notices regarding events that do not have enough remaining spaces |
|
665 | + * to satisfy the current number of registrations looking to pay |
|
666 | + * |
|
667 | + * @param EE_Event[] $insufficient_spaces_events_array |
|
668 | + * @return EE_Form_Section_Proper |
|
669 | + * @throws EE_Error |
|
670 | + * @throws ReflectionException |
|
671 | + */ |
|
672 | + private function _insufficient_spaces_available($insufficient_spaces_events_array = []) |
|
673 | + { |
|
674 | + // set some defaults |
|
675 | + $this->checkout->selected_method_of_payment = 'invoice'; |
|
676 | + $insufficient_space_events = ''; |
|
677 | + foreach ($insufficient_spaces_events_array as $event) { |
|
678 | + if ($event instanceof EE_Event) { |
|
679 | + $insufficient_space_events .= EEH_HTML::li( |
|
680 | + EEH_HTML::span(' ' . $event->name(), '', 'dashicons dashicons-marker ee-icon-size-16 pink-text') |
|
681 | + ); |
|
682 | + } |
|
683 | + } |
|
684 | + return new EE_Form_Section_Proper( |
|
685 | + [ |
|
686 | + 'subsections' => [ |
|
687 | + 'default_hidden_inputs' => $this->reg_step_hidden_inputs(), |
|
688 | + 'extra_hidden_inputs' => $this->_extra_hidden_inputs(), |
|
689 | + ], |
|
690 | + 'layout_strategy' => new EE_Template_Layout( |
|
691 | + [ |
|
692 | + 'layout_template_file' => SPCO_REG_STEPS_PATH |
|
693 | + . $this->_slug |
|
694 | + . '/sold_out_events.template.php', |
|
695 | + 'template_args' => apply_filters( |
|
696 | + 'FHEE__EE_SPCO_Reg_Step_Payment_Options___insufficient_spaces_available__template_args', |
|
697 | + [ |
|
698 | + 'sold_out_events' => $insufficient_space_events, |
|
699 | + 'sold_out_events_msg' => apply_filters( |
|
700 | + 'FHEE__EE_SPCO_Reg_Step_Payment_Options___insufficient_spaces_available__insufficient_space_msg', |
|
701 | + esc_html__( |
|
702 | + 'It appears that the event you were about to make a payment for has sold additional tickets since you first registered, and there are no longer enough spaces left to accommodate your selections. You may continue to pay and secure the available space(s) remaining, or simply cancel if you no longer wish to purchase. If you have already made a partial payment towards this event, please contact the event administrator for a refund.', |
|
703 | + 'event_espresso' |
|
704 | + ) |
|
705 | + ), |
|
706 | + ] |
|
707 | + ), |
|
708 | + ] |
|
709 | + ), |
|
710 | + ] |
|
711 | + ); |
|
712 | + } |
|
713 | + |
|
714 | + |
|
715 | + /** |
|
716 | + * registrations_requiring_pre_approval |
|
717 | + * |
|
718 | + * @param array $registrations_requiring_pre_approval |
|
719 | + * @return EE_Form_Section_Proper |
|
720 | + * @throws EE_Error |
|
721 | + * @throws EntityNotFoundException |
|
722 | + * @throws ReflectionException |
|
723 | + */ |
|
724 | + private function _registrations_requiring_pre_approval($registrations_requiring_pre_approval = []) |
|
725 | + { |
|
726 | + $events_requiring_pre_approval = []; |
|
727 | + foreach ($registrations_requiring_pre_approval as $registration) { |
|
728 | + if ($registration instanceof EE_Registration && $registration->event() instanceof EE_Event) { |
|
729 | + $events_requiring_pre_approval[ $registration->event()->ID() ] = EEH_HTML::li( |
|
730 | + EEH_HTML::span( |
|
731 | + '', |
|
732 | + '', |
|
733 | + 'dashicons dashicons-marker ee-icon-size-16 orange-text' |
|
734 | + ) |
|
735 | + . EEH_HTML::span($registration->event()->name(), '', 'orange-text') |
|
736 | + ); |
|
737 | + } |
|
738 | + } |
|
739 | + return new EE_Form_Section_Proper( |
|
740 | + [ |
|
741 | + 'layout_strategy' => new EE_Template_Layout( |
|
742 | + [ |
|
743 | + 'layout_template_file' => SPCO_REG_STEPS_PATH |
|
744 | + . $this->_slug |
|
745 | + . '/events_requiring_pre_approval.template.php', // layout_template |
|
746 | + 'template_args' => apply_filters( |
|
747 | + 'FHEE__EE_SPCO_Reg_Step_Payment_Options___sold_out_events__template_args', |
|
748 | + [ |
|
749 | + 'events_requiring_pre_approval' => implode('', $events_requiring_pre_approval), |
|
750 | + 'events_requiring_pre_approval_msg' => apply_filters( |
|
751 | + 'FHEE__EE_SPCO_Reg_Step_Payment_Options___events_requiring_pre_approval__events_requiring_pre_approval_msg', |
|
752 | + esc_html__( |
|
753 | + 'The following events do not require payment at this time and will not be billed during this transaction. Billing will only occur after the attendee has been approved by the event organizer. You will be notified when your registration has been processed. If this is a free event, then no billing will occur.', |
|
754 | + 'event_espresso' |
|
755 | + ) |
|
756 | + ), |
|
757 | + ] |
|
758 | + ), |
|
759 | + ] |
|
760 | + ), |
|
761 | + ] |
|
762 | + ); |
|
763 | + } |
|
764 | + |
|
765 | + |
|
766 | + /** |
|
767 | + * _no_payment_required |
|
768 | + * |
|
769 | + * @param EE_Event[] $registrations_for_free_events |
|
770 | + * @return EE_Form_Section_Proper |
|
771 | + * @throws EE_Error |
|
772 | + */ |
|
773 | + private function _no_payment_required($registrations_for_free_events = []) |
|
774 | + { |
|
775 | + // set some defaults |
|
776 | + $this->checkout->selected_method_of_payment = 'no_payment_required'; |
|
777 | + // generate no_payment_required form |
|
778 | + return new EE_Form_Section_Proper( |
|
779 | + [ |
|
780 | + 'layout_strategy' => new EE_Template_Layout( |
|
781 | + [ |
|
782 | + 'layout_template_file' => SPCO_REG_STEPS_PATH |
|
783 | + . $this->_slug |
|
784 | + . '/no_payment_required.template.php', // layout_template |
|
785 | + 'template_args' => apply_filters( |
|
786 | + 'FHEE__EE_SPCO_Reg_Step_Payment_Options___no_payment_required__template_args', |
|
787 | + [ |
|
788 | + 'revisit' => $this->checkout->revisit, |
|
789 | + 'registrations' => [], |
|
790 | + 'ticket_count' => [], |
|
791 | + 'registrations_for_free_events' => $registrations_for_free_events, |
|
792 | + 'no_payment_required_msg' => EEH_HTML::p( |
|
793 | + esc_html__('This is a free event, so no billing will occur.', 'event_espresso') |
|
794 | + ), |
|
795 | + ] |
|
796 | + ), |
|
797 | + ] |
|
798 | + ), |
|
799 | + ] |
|
800 | + ); |
|
801 | + } |
|
802 | + |
|
803 | + |
|
804 | + /** |
|
805 | + * _display_payment_options |
|
806 | + * |
|
807 | + * @param string $transaction_details |
|
808 | + * @return EE_Form_Section_Proper |
|
809 | + * @throws EE_Error |
|
810 | + * @throws InvalidArgumentException |
|
811 | + * @throws InvalidDataTypeException |
|
812 | + * @throws InvalidInterfaceException |
|
813 | + */ |
|
814 | + private function _display_payment_options($transaction_details = '') |
|
815 | + { |
|
816 | + // has method_of_payment been set by no-js user? |
|
817 | + $this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment(); |
|
818 | + // build payment options form |
|
819 | + return apply_filters( |
|
820 | + 'FHEE__EE_SPCO_Reg_Step_Payment_Options___display_payment_options__payment_options_form', |
|
821 | + new EE_Form_Section_Proper( |
|
822 | + [ |
|
823 | + 'subsections' => [ |
|
824 | + 'before_payment_options' => apply_filters( |
|
825 | + 'FHEE__EE_SPCO_Reg_Step_Payment_Options___display_payment_options__before_payment_options', |
|
826 | + new EE_Form_Section_Proper( |
|
827 | + ['layout_strategy' => new EE_Div_Per_Section_Layout()] |
|
828 | + ) |
|
829 | + ), |
|
830 | + 'payment_options' => $this->_setup_payment_options(), |
|
831 | + 'after_payment_options' => apply_filters( |
|
832 | + 'FHEE__EE_SPCO_Reg_Step_Payment_Options___display_payment_options__after_payment_options', |
|
833 | + new EE_Form_Section_Proper( |
|
834 | + ['layout_strategy' => new EE_Div_Per_Section_Layout()] |
|
835 | + ) |
|
836 | + ), |
|
837 | + ], |
|
838 | + 'layout_strategy' => new EE_Template_Layout( |
|
839 | + [ |
|
840 | + 'layout_template_file' => $this->_template, |
|
841 | + 'template_args' => apply_filters( |
|
842 | + 'FHEE__EE_SPCO_Reg_Step_Payment_Options___display_payment_options__template_args', |
|
843 | + [ |
|
844 | + 'reg_count' => $this->line_item_display->total_items(), |
|
845 | + 'transaction_details' => $transaction_details, |
|
846 | + 'available_payment_methods' => [], |
|
847 | + ] |
|
848 | + ), |
|
849 | + ] |
|
850 | + ), |
|
851 | + ] |
|
852 | + ) |
|
853 | + ); |
|
854 | + } |
|
855 | + |
|
856 | + |
|
857 | + /** |
|
858 | + * _extra_hidden_inputs |
|
859 | + * |
|
860 | + * @param bool $no_payment_required |
|
861 | + * @return EE_Form_Section_Proper |
|
862 | + * @throws EE_Error |
|
863 | + * @throws ReflectionException |
|
864 | + */ |
|
865 | + private function _extra_hidden_inputs($no_payment_required = true) |
|
866 | + { |
|
867 | + return new EE_Form_Section_Proper( |
|
868 | + [ |
|
869 | + 'html_id' => 'ee-' . $this->slug() . '-extra-hidden-inputs', |
|
870 | + 'layout_strategy' => new EE_Div_Per_Section_Layout(), |
|
871 | + 'subsections' => [ |
|
872 | + 'spco_no_payment_required' => new EE_Hidden_Input( |
|
873 | + [ |
|
874 | + 'normalization_strategy' => new EE_Boolean_Normalization(), |
|
875 | + 'html_name' => 'spco_no_payment_required', |
|
876 | + 'html_id' => 'spco-no-payment-required-payment_options', |
|
877 | + 'default' => $no_payment_required, |
|
878 | + ] |
|
879 | + ), |
|
880 | + 'spco_transaction_id' => new EE_Fixed_Hidden_Input( |
|
881 | + [ |
|
882 | + 'normalization_strategy' => new EE_Int_Normalization(), |
|
883 | + 'html_name' => 'spco_transaction_id', |
|
884 | + 'html_id' => 'spco-transaction-id', |
|
885 | + 'default' => $this->checkout->transaction->ID(), |
|
886 | + ] |
|
887 | + ), |
|
888 | + ], |
|
889 | + ] |
|
890 | + ); |
|
891 | + } |
|
892 | + |
|
893 | + |
|
894 | + /** |
|
895 | + * _apply_registration_payments_to_amount_owing |
|
896 | + * |
|
897 | + * @param array $registrations |
|
898 | + * @throws EE_Error |
|
899 | + */ |
|
900 | + protected function _apply_registration_payments_to_amount_owing(array $registrations) |
|
901 | + { |
|
902 | + $payments = []; |
|
903 | + foreach ($registrations as $registration) { |
|
904 | + if ($registration instanceof EE_Registration && $registration->owes_monies_and_can_pay()) { |
|
905 | + $payments += $registration->registration_payments(); |
|
906 | + } |
|
907 | + } |
|
908 | + if (! empty($payments)) { |
|
909 | + foreach ($payments as $payment) { |
|
910 | + if ($payment instanceof EE_Registration_Payment) { |
|
911 | + $this->checkout->amount_owing -= $payment->amount(); |
|
912 | + } |
|
913 | + } |
|
914 | + } |
|
915 | + } |
|
916 | + |
|
917 | + |
|
918 | + /** |
|
919 | + * _reset_selected_method_of_payment |
|
920 | + * |
|
921 | + * @access private |
|
922 | + * @param bool $force_reset |
|
923 | + * @return void |
|
924 | + * @throws InvalidArgumentException |
|
925 | + * @throws InvalidDataTypeException |
|
926 | + * @throws InvalidInterfaceException |
|
927 | + */ |
|
928 | + private function _reset_selected_method_of_payment($force_reset = false) |
|
929 | + { |
|
930 | + /** @var RequestInterface $request */ |
|
931 | + $request = LoaderFactory::getLoader()->getShared(RequestInterface::class); |
|
932 | + $reset_payment_method = $request->getRequestParam('reset_payment_method', $force_reset, 'bool'); |
|
933 | + if ($reset_payment_method) { |
|
934 | + $this->checkout->selected_method_of_payment = null; |
|
935 | + $this->checkout->payment_method = null; |
|
936 | + $this->checkout->billing_form = null; |
|
937 | + $this->_save_selected_method_of_payment(); |
|
938 | + } |
|
939 | + } |
|
940 | + |
|
941 | + |
|
942 | + /** |
|
943 | + * _save_selected_method_of_payment |
|
944 | + * stores the selected_method_of_payment in the session |
|
945 | + * so that it's available for all subsequent requests including AJAX |
|
946 | + * |
|
947 | + * @access private |
|
948 | + * @param string $selected_method_of_payment |
|
949 | + * @return void |
|
950 | + * @throws InvalidArgumentException |
|
951 | + * @throws InvalidDataTypeException |
|
952 | + * @throws InvalidInterfaceException |
|
953 | + */ |
|
954 | + private function _save_selected_method_of_payment($selected_method_of_payment = '') |
|
955 | + { |
|
956 | + $selected_method_of_payment = ! empty($selected_method_of_payment) |
|
957 | + ? $selected_method_of_payment |
|
958 | + : $this->checkout->selected_method_of_payment; |
|
959 | + EE_Registry::instance()->SSN->set_session_data( |
|
960 | + ['selected_method_of_payment' => $selected_method_of_payment] |
|
961 | + ); |
|
962 | + } |
|
963 | + |
|
964 | + |
|
965 | + /** |
|
966 | + * _setup_payment_options |
|
967 | + * |
|
968 | + * @return EE_Form_Section_Proper |
|
969 | + * @throws EE_Error |
|
970 | + * @throws InvalidArgumentException |
|
971 | + * @throws InvalidDataTypeException |
|
972 | + * @throws InvalidInterfaceException |
|
973 | + */ |
|
974 | + public function _setup_payment_options() |
|
975 | + { |
|
976 | + // load payment method classes |
|
977 | + $this->checkout->available_payment_methods = $this->_get_available_payment_methods(); |
|
978 | + if (empty($this->checkout->available_payment_methods)) { |
|
979 | + EE_Error::add_error( |
|
980 | + apply_filters( |
|
981 | + 'FHEE__EE_SPCO_Reg_Step_Payment_Options___setup_payment_options__error_message_no_payment_methods', |
|
982 | + sprintf( |
|
983 | + esc_html__( |
|
984 | + 'Sorry, you cannot complete your purchase because a payment method is not active.%1$s Please contact %2$s for assistance and provide a description of the problem.', |
|
985 | + 'event_espresso' |
|
986 | + ), |
|
987 | + '<br>', |
|
988 | + EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
989 | + ) |
|
990 | + ), |
|
991 | + __FILE__, |
|
992 | + __FUNCTION__, |
|
993 | + __LINE__ |
|
994 | + ); |
|
995 | + } |
|
996 | + // switch up header depending on number of available payment methods |
|
997 | + $payment_method_header = count($this->checkout->available_payment_methods) > 1 |
|
998 | + ? apply_filters( |
|
999 | + 'FHEE__registration_page_payment_options__method_of_payment_hdr', |
|
1000 | + esc_html__('Please Select Your Method of Payment', 'event_espresso') |
|
1001 | + ) |
|
1002 | + : apply_filters( |
|
1003 | + 'FHEE__registration_page_payment_options__method_of_payment_hdr', |
|
1004 | + esc_html__('Method of Payment', 'event_espresso') |
|
1005 | + ); |
|
1006 | + $available_payment_methods = [ |
|
1007 | + // display the "Payment Method" header |
|
1008 | + 'payment_method_header' => new EE_Form_Section_HTML( |
|
1009 | + apply_filters( |
|
1010 | + 'FHEE__EE_SPCO_Reg_Step_Payment_Options___setup_payment_options__payment_method_header', |
|
1011 | + EEH_HTML::h4($payment_method_header, 'method-of-payment-hdr'), |
|
1012 | + $payment_method_header |
|
1013 | + ) |
|
1014 | + ), |
|
1015 | + ]; |
|
1016 | + // the list of actual payment methods ( invoice, paypal, etc ) in a ( slug => HTML ) format |
|
1017 | + $available_payment_method_options = []; |
|
1018 | + $default_payment_method_option = []; |
|
1019 | + // additional instructions to be displayed and hidden below payment methods (adding a clearing div to start) |
|
1020 | + $payment_methods_billing_info = [ |
|
1021 | + new EE_Form_Section_HTML( |
|
1022 | + EEH_HTML::div('<br />', '', '', 'clear:both;') |
|
1023 | + ), |
|
1024 | + ]; |
|
1025 | + // loop through payment methods |
|
1026 | + foreach ($this->checkout->available_payment_methods as $payment_method) { |
|
1027 | + if ($payment_method instanceof EE_Payment_Method) { |
|
1028 | + $payment_method_button = EEH_HTML::img( |
|
1029 | + $payment_method->button_url(), |
|
1030 | + $payment_method->name(), |
|
1031 | + 'spco-payment-method-' . $payment_method->slug() . '-btn-img', |
|
1032 | + 'spco-payment-method-btn-img' |
|
1033 | + ); |
|
1034 | + // check if any payment methods are set as default |
|
1035 | + // if payment method is already selected OR nothing is selected and this payment method should be |
|
1036 | + // open_by_default |
|
1037 | + if ( |
|
1038 | + ($this->checkout->selected_method_of_payment === $payment_method->slug()) |
|
1039 | + || (! $this->checkout->selected_method_of_payment && $payment_method->open_by_default()) |
|
1040 | + ) { |
|
1041 | + $this->checkout->selected_method_of_payment = $payment_method->slug(); |
|
1042 | + $this->_save_selected_method_of_payment(); |
|
1043 | + $default_payment_method_option[ $payment_method->slug() ] = $payment_method_button; |
|
1044 | + } else { |
|
1045 | + $available_payment_method_options[ $payment_method->slug() ] = $payment_method_button; |
|
1046 | + } |
|
1047 | + $payment_methods_billing_info[ $payment_method->slug() . '-info' ] = |
|
1048 | + $this->_payment_method_billing_info( |
|
1049 | + $payment_method |
|
1050 | + ); |
|
1051 | + } |
|
1052 | + } |
|
1053 | + // prepend available_payment_method_options with default_payment_method_option so that it appears first in list |
|
1054 | + // of PMs |
|
1055 | + $available_payment_method_options = $default_payment_method_option + $available_payment_method_options; |
|
1056 | + // now generate the actual form inputs |
|
1057 | + $available_payment_methods['available_payment_methods'] = $this->_available_payment_method_inputs( |
|
1058 | + $available_payment_method_options |
|
1059 | + ); |
|
1060 | + $available_payment_methods += $payment_methods_billing_info; |
|
1061 | + // build the available payment methods form |
|
1062 | + return new EE_Form_Section_Proper( |
|
1063 | + [ |
|
1064 | + 'html_id' => 'spco-available-methods-of-payment-dv', |
|
1065 | + 'subsections' => $available_payment_methods, |
|
1066 | + 'layout_strategy' => new EE_Div_Per_Section_Layout(), |
|
1067 | + ] |
|
1068 | + ); |
|
1069 | + } |
|
1070 | + |
|
1071 | + |
|
1072 | + /** |
|
1073 | + * _get_available_payment_methods |
|
1074 | + * |
|
1075 | + * @return EE_Payment_Method[] |
|
1076 | + * @throws EE_Error |
|
1077 | + * @throws InvalidArgumentException |
|
1078 | + * @throws InvalidDataTypeException |
|
1079 | + * @throws InvalidInterfaceException |
|
1080 | + */ |
|
1081 | + protected function _get_available_payment_methods() |
|
1082 | + { |
|
1083 | + if (! empty($this->checkout->available_payment_methods)) { |
|
1084 | + return $this->checkout->available_payment_methods; |
|
1085 | + } |
|
1086 | + $available_payment_methods = []; |
|
1087 | + $EEM_Payment_Method = EEM_Payment_Method::instance(); |
|
1088 | + // get all active payment methods |
|
1089 | + $payment_methods = $EEM_Payment_Method->get_all_for_transaction( |
|
1090 | + $this->checkout->transaction, |
|
1091 | + EEM_Payment_Method::scope_cart |
|
1092 | + ); |
|
1093 | + foreach ($payment_methods as $payment_method) { |
|
1094 | + if ($payment_method instanceof EE_Payment_Method) { |
|
1095 | + $available_payment_methods[ $payment_method->slug() ] = $payment_method; |
|
1096 | + } |
|
1097 | + } |
|
1098 | + return $available_payment_methods; |
|
1099 | + } |
|
1100 | + |
|
1101 | + |
|
1102 | + /** |
|
1103 | + * _available_payment_method_inputs |
|
1104 | + * |
|
1105 | + * @access private |
|
1106 | + * @param array $available_payment_method_options |
|
1107 | + * @return EE_Form_Section_Proper |
|
1108 | + * @throws EE_Error |
|
1109 | + * @throws EE_Error |
|
1110 | + */ |
|
1111 | + private function _available_payment_method_inputs($available_payment_method_options = []) |
|
1112 | + { |
|
1113 | + // generate inputs |
|
1114 | + return new EE_Form_Section_Proper( |
|
1115 | + [ |
|
1116 | + 'html_id' => 'ee-available-payment-method-inputs', |
|
1117 | + 'layout_strategy' => new EE_Div_Per_Section_Layout(), |
|
1118 | + 'subsections' => [ |
|
1119 | + '' => new EE_Radio_Button_Input( |
|
1120 | + $available_payment_method_options, |
|
1121 | + [ |
|
1122 | + 'html_name' => 'selected_method_of_payment', |
|
1123 | + 'html_class' => 'spco-payment-method', |
|
1124 | + 'default' => $this->checkout->selected_method_of_payment, |
|
1125 | + 'label_size' => 11, |
|
1126 | + 'enforce_label_size' => true, |
|
1127 | + ] |
|
1128 | + ), |
|
1129 | + ], |
|
1130 | + ] |
|
1131 | + ); |
|
1132 | + } |
|
1133 | + |
|
1134 | + |
|
1135 | + /** |
|
1136 | + * _payment_method_billing_info |
|
1137 | + * |
|
1138 | + * @access private |
|
1139 | + * @param EE_Payment_Method $payment_method |
|
1140 | + * @return EE_Form_Section_Proper |
|
1141 | + * @throws EE_Error |
|
1142 | + * @throws InvalidArgumentException |
|
1143 | + * @throws InvalidDataTypeException |
|
1144 | + * @throws InvalidInterfaceException |
|
1145 | + */ |
|
1146 | + private function _payment_method_billing_info(EE_Payment_Method $payment_method) |
|
1147 | + { |
|
1148 | + $currently_selected = $this->checkout->selected_method_of_payment === $payment_method->slug(); |
|
1149 | + // generate the billing form for payment method |
|
1150 | + $billing_form = $currently_selected |
|
1151 | + ? $this->_get_billing_form_for_payment_method($payment_method) |
|
1152 | + : new EE_Form_Section_HTML(); |
|
1153 | + $this->checkout->billing_form = $currently_selected |
|
1154 | + ? $billing_form |
|
1155 | + : $this->checkout->billing_form; |
|
1156 | + // it's all in the details |
|
1157 | + $info_html = EEH_HTML::h3( |
|
1158 | + esc_html__('Important information regarding your payment', 'event_espresso'), |
|
1159 | + '', |
|
1160 | + 'spco-payment-method-hdr' |
|
1161 | + ); |
|
1162 | + // add some info regarding the step, either from what's saved in the admin, |
|
1163 | + // or a default string depending on whether the PM has a billing form or not |
|
1164 | + if ($payment_method->description()) { |
|
1165 | + $payment_method_info = $payment_method->description(); |
|
1166 | + } elseif ($billing_form instanceof EE_Billing_Info_Form) { |
|
1167 | + $payment_method_info = sprintf( |
|
1168 | + esc_html__( |
|
1169 | + 'Please provide the following billing information, then click the "%1$s" button below in order to proceed.', |
|
1170 | + 'event_espresso' |
|
1171 | + ), |
|
1172 | + $this->submit_button_text() |
|
1173 | + ); |
|
1174 | + } else { |
|
1175 | + $payment_method_info = sprintf( |
|
1176 | + esc_html__('Please click the "%1$s" button below in order to proceed.', 'event_espresso'), |
|
1177 | + $this->submit_button_text() |
|
1178 | + ); |
|
1179 | + } |
|
1180 | + $info_html .= EEH_HTML::div( |
|
1181 | + apply_filters( |
|
1182 | + 'FHEE__EE_SPCO_Reg_Step_Payment_Options___payment_method_billing_info__payment_method_info', |
|
1183 | + $payment_method_info |
|
1184 | + ), |
|
1185 | + '', |
|
1186 | + 'spco-payment-method-desc ee-attention' |
|
1187 | + ); |
|
1188 | + return new EE_Form_Section_Proper( |
|
1189 | + [ |
|
1190 | + 'html_id' => 'spco-payment-method-info-' . $payment_method->slug(), |
|
1191 | + 'html_class' => 'spco-payment-method-info-dv', |
|
1192 | + // only display the selected or default PM |
|
1193 | + 'html_style' => $currently_selected ? '' : 'display:none;', |
|
1194 | + 'layout_strategy' => new EE_Div_Per_Section_Layout(), |
|
1195 | + 'subsections' => [ |
|
1196 | + 'info' => new EE_Form_Section_HTML($info_html), |
|
1197 | + 'billing_form' => $currently_selected ? $billing_form : new EE_Form_Section_HTML(), |
|
1198 | + ], |
|
1199 | + ] |
|
1200 | + ); |
|
1201 | + } |
|
1202 | + |
|
1203 | + |
|
1204 | + /** |
|
1205 | + * get_billing_form_html_for_payment_method |
|
1206 | + * |
|
1207 | + * @return bool |
|
1208 | + * @throws EE_Error |
|
1209 | + * @throws InvalidArgumentException |
|
1210 | + * @throws ReflectionException |
|
1211 | + * @throws InvalidDataTypeException |
|
1212 | + * @throws InvalidInterfaceException |
|
1213 | + */ |
|
1214 | + public function get_billing_form_html_for_payment_method() |
|
1215 | + { |
|
1216 | + // how have they chosen to pay? |
|
1217 | + $this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment(true); |
|
1218 | + $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment(); |
|
1219 | + if (! $this->checkout->payment_method instanceof EE_Payment_Method) { |
|
1220 | + return false; |
|
1221 | + } |
|
1222 | + if ( |
|
1223 | + apply_filters( |
|
1224 | + 'FHEE__EE_SPCO_Reg_Step_Payment_Options__registration_checkout__selected_payment_method__display_success', |
|
1225 | + false |
|
1226 | + ) |
|
1227 | + ) { |
|
1228 | + EE_Error::add_success( |
|
1229 | + apply_filters( |
|
1230 | + 'FHEE__Single_Page_Checkout__registration_checkout__selected_payment_method', |
|
1231 | + sprintf( |
|
1232 | + esc_html__( |
|
1233 | + 'You have selected "%s" as your method of payment. Please note the important payment information below.', |
|
1234 | + 'event_espresso' |
|
1235 | + ), |
|
1236 | + $this->checkout->payment_method->name() |
|
1237 | + ) |
|
1238 | + ) |
|
1239 | + ); |
|
1240 | + } |
|
1241 | + // now generate billing form for selected method of payment |
|
1242 | + $payment_method_billing_form = $this->_get_billing_form_for_payment_method($this->checkout->payment_method); |
|
1243 | + // fill form with attendee info if applicable |
|
1244 | + if ( |
|
1245 | + $payment_method_billing_form instanceof EE_Billing_Attendee_Info_Form |
|
1246 | + && $this->checkout->transaction_has_primary_registrant() |
|
1247 | + ) { |
|
1248 | + $payment_method_billing_form->populate_from_attendee( |
|
1249 | + $this->checkout->transaction->primary_registration()->attendee() |
|
1250 | + ); |
|
1251 | + } |
|
1252 | + // and debug content |
|
1253 | + if ( |
|
1254 | + $payment_method_billing_form instanceof EE_Billing_Info_Form |
|
1255 | + && $this->checkout->payment_method->type_obj() instanceof EE_PMT_Base |
|
1256 | + ) { |
|
1257 | + $payment_method_billing_form = |
|
1258 | + $this->checkout->payment_method->type_obj()->apply_billing_form_debug_settings( |
|
1259 | + $payment_method_billing_form |
|
1260 | + ); |
|
1261 | + } |
|
1262 | + $billing_info = $payment_method_billing_form instanceof EE_Form_Section_Proper |
|
1263 | + ? $payment_method_billing_form->get_html() |
|
1264 | + : ''; |
|
1265 | + $this->checkout->json_response->set_return_data(['payment_method_info' => $billing_info]); |
|
1266 | + // localize validation rules for main form |
|
1267 | + $this->checkout->current_step->reg_form->localize_validation_rules(); |
|
1268 | + $this->checkout->json_response->add_validation_rules(EE_Form_Section_Proper::js_localization()); |
|
1269 | + return true; |
|
1270 | + } |
|
1271 | + |
|
1272 | + |
|
1273 | + /** |
|
1274 | + * _get_billing_form_for_payment_method |
|
1275 | + * |
|
1276 | + * @param EE_Payment_Method $payment_method |
|
1277 | + * @return EE_Billing_Info_Form|EE_Billing_Attendee_Info_Form|EE_Form_Section_HTML |
|
1278 | + * @throws EE_Error |
|
1279 | + * @throws InvalidArgumentException |
|
1280 | + * @throws InvalidDataTypeException |
|
1281 | + * @throws InvalidInterfaceException |
|
1282 | + */ |
|
1283 | + private function _get_billing_form_for_payment_method(EE_Payment_Method $payment_method) |
|
1284 | + { |
|
1285 | + $billing_form = $payment_method->type_obj()->billing_form( |
|
1286 | + $this->checkout->transaction, |
|
1287 | + ['amount_owing' => $this->checkout->amount_owing] |
|
1288 | + ); |
|
1289 | + if ($billing_form instanceof EE_Billing_Info_Form) { |
|
1290 | + if ( |
|
1291 | + apply_filters( |
|
1292 | + 'FHEE__EE_SPCO_Reg_Step_Payment_Options__registration_checkout__selected_payment_method__display_success', |
|
1293 | + false |
|
1294 | + ) |
|
1295 | + && $this->request->requestParamIsSet('payment_method') |
|
1296 | + ) { |
|
1297 | + EE_Error::add_success( |
|
1298 | + apply_filters( |
|
1299 | + 'FHEE__Single_Page_Checkout__registration_checkout__selected_payment_method', |
|
1300 | + sprintf( |
|
1301 | + esc_html__( |
|
1302 | + 'You have selected "%s" as your method of payment. Please note the important payment information below.', |
|
1303 | + 'event_espresso' |
|
1304 | + ), |
|
1305 | + $payment_method->name() |
|
1306 | + ) |
|
1307 | + ) |
|
1308 | + ); |
|
1309 | + } |
|
1310 | + return apply_filters( |
|
1311 | + 'FHEE__EE_SPCO_Reg_Step_Payment_Options___get_billing_form_for_payment_method__billing_form', |
|
1312 | + $billing_form, |
|
1313 | + $payment_method |
|
1314 | + ); |
|
1315 | + } |
|
1316 | + // no actual billing form, so return empty HTML form section |
|
1317 | + return new EE_Form_Section_HTML(); |
|
1318 | + } |
|
1319 | + |
|
1320 | + |
|
1321 | + /** |
|
1322 | + * _get_selected_method_of_payment |
|
1323 | + * |
|
1324 | + * @param boolean $required whether to throw an error if the "selected_method_of_payment" |
|
1325 | + * is not found in the incoming request |
|
1326 | + * @param string $request_param |
|
1327 | + * @return NULL|string |
|
1328 | + * @throws EE_Error |
|
1329 | + * @throws InvalidArgumentException |
|
1330 | + * @throws InvalidDataTypeException |
|
1331 | + * @throws InvalidInterfaceException |
|
1332 | + */ |
|
1333 | + private function _get_selected_method_of_payment( |
|
1334 | + $required = false, |
|
1335 | + $request_param = 'selected_method_of_payment' |
|
1336 | + ) { |
|
1337 | + // is selected_method_of_payment set in the request ? |
|
1338 | + $selected_method_of_payment = $this->request->getRequestParam($request_param); |
|
1339 | + if ($selected_method_of_payment) { |
|
1340 | + // sanitize it |
|
1341 | + $selected_method_of_payment = is_array($selected_method_of_payment) |
|
1342 | + ? array_shift($selected_method_of_payment) |
|
1343 | + : $selected_method_of_payment; |
|
1344 | + $selected_method_of_payment = sanitize_text_field($selected_method_of_payment); |
|
1345 | + // store it in the session so that it's available for all subsequent requests including AJAX |
|
1346 | + $this->_save_selected_method_of_payment($selected_method_of_payment); |
|
1347 | + } else { |
|
1348 | + // or is is set in the session ? |
|
1349 | + $selected_method_of_payment = EE_Registry::instance()->SSN->get_session_data( |
|
1350 | + 'selected_method_of_payment' |
|
1351 | + ); |
|
1352 | + } |
|
1353 | + // do ya really really gotta have it? |
|
1354 | + if (empty($selected_method_of_payment) && $required) { |
|
1355 | + EE_Error::add_error( |
|
1356 | + sprintf( |
|
1357 | + esc_html__( |
|
1358 | + 'The selected method of payment could not be determined.%sPlease ensure that you have selected one before proceeding.%sIf you continue to experience difficulties, then refresh your browser and try again, or contact %s for assistance.', |
|
1359 | + 'event_espresso' |
|
1360 | + ), |
|
1361 | + '<br/>', |
|
1362 | + '<br/>', |
|
1363 | + EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
1364 | + ), |
|
1365 | + __FILE__, |
|
1366 | + __FUNCTION__, |
|
1367 | + __LINE__ |
|
1368 | + ); |
|
1369 | + return null; |
|
1370 | + } |
|
1371 | + return $selected_method_of_payment; |
|
1372 | + } |
|
1373 | + |
|
1374 | + |
|
1375 | + |
|
1376 | + |
|
1377 | + |
|
1378 | + |
|
1379 | + /********************************************************************************************************/ |
|
1380 | + /*********************************** SWITCH PAYMENT METHOD ************************************/ |
|
1381 | + /********************************************************************************************************/ |
|
1382 | + /** |
|
1383 | + * switch_payment_method |
|
1384 | + * |
|
1385 | + * @return bool |
|
1386 | + * @throws EE_Error |
|
1387 | + * @throws InvalidArgumentException |
|
1388 | + * @throws InvalidDataTypeException |
|
1389 | + * @throws InvalidInterfaceException |
|
1390 | + * @throws ReflectionException |
|
1391 | + */ |
|
1392 | + public function switch_payment_method() |
|
1393 | + { |
|
1394 | + if (! $this->_verify_payment_method_is_set()) { |
|
1395 | + return false; |
|
1396 | + } |
|
1397 | + if ( |
|
1398 | + apply_filters( |
|
1399 | + 'FHEE__EE_SPCO_Reg_Step_Payment_Options__registration_checkout__selected_payment_method__display_success', |
|
1400 | + false |
|
1401 | + ) |
|
1402 | + ) { |
|
1403 | + EE_Error::add_success( |
|
1404 | + apply_filters( |
|
1405 | + 'FHEE__Single_Page_Checkout__registration_checkout__selected_payment_method', |
|
1406 | + sprintf( |
|
1407 | + esc_html__( |
|
1408 | + 'You have selected "%s" as your method of payment. Please note the important payment information below.', |
|
1409 | + 'event_espresso' |
|
1410 | + ), |
|
1411 | + $this->checkout->payment_method->name() |
|
1412 | + ) |
|
1413 | + ) |
|
1414 | + ); |
|
1415 | + } |
|
1416 | + // generate billing form for selected method of payment if it hasn't been done already |
|
1417 | + if ($this->checkout->payment_method->type_obj()->has_billing_form()) { |
|
1418 | + $this->checkout->billing_form = $this->_get_billing_form_for_payment_method( |
|
1419 | + $this->checkout->payment_method |
|
1420 | + ); |
|
1421 | + } |
|
1422 | + // fill form with attendee info if applicable |
|
1423 | + if ( |
|
1424 | + apply_filters( |
|
1425 | + 'FHEE__populate_billing_form_fields_from_attendee', |
|
1426 | + ( |
|
1427 | + $this->checkout->billing_form instanceof EE_Billing_Attendee_Info_Form |
|
1428 | + && $this->checkout->transaction_has_primary_registrant() |
|
1429 | + ), |
|
1430 | + $this->checkout->billing_form, |
|
1431 | + $this->checkout->transaction |
|
1432 | + ) |
|
1433 | + ) { |
|
1434 | + $this->checkout->billing_form->populate_from_attendee( |
|
1435 | + $this->checkout->transaction->primary_registration()->attendee() |
|
1436 | + ); |
|
1437 | + } |
|
1438 | + // and debug content |
|
1439 | + if ( |
|
1440 | + $this->checkout->billing_form instanceof EE_Billing_Info_Form |
|
1441 | + && $this->checkout->payment_method->type_obj() instanceof EE_PMT_Base |
|
1442 | + ) { |
|
1443 | + $this->checkout->billing_form = |
|
1444 | + $this->checkout->payment_method->type_obj()->apply_billing_form_debug_settings( |
|
1445 | + $this->checkout->billing_form |
|
1446 | + ); |
|
1447 | + } |
|
1448 | + // get html and validation rules for form |
|
1449 | + if ($this->checkout->billing_form instanceof EE_Form_Section_Proper) { |
|
1450 | + $this->checkout->json_response->set_return_data( |
|
1451 | + ['payment_method_info' => $this->checkout->billing_form->get_html()] |
|
1452 | + ); |
|
1453 | + // localize validation rules for main form |
|
1454 | + $this->checkout->billing_form->localize_validation_rules(true); |
|
1455 | + $this->checkout->json_response->add_validation_rules(EE_Form_Section_Proper::js_localization()); |
|
1456 | + } else { |
|
1457 | + $this->checkout->json_response->set_return_data(['payment_method_info' => '']); |
|
1458 | + } |
|
1459 | + // prevents advancement to next step |
|
1460 | + $this->checkout->continue_reg = false; |
|
1461 | + return true; |
|
1462 | + } |
|
1463 | + |
|
1464 | + |
|
1465 | + /** |
|
1466 | + * _verify_payment_method_is_set |
|
1467 | + * |
|
1468 | + * @return bool |
|
1469 | + * @throws EE_Error |
|
1470 | + * @throws InvalidArgumentException |
|
1471 | + * @throws ReflectionException |
|
1472 | + * @throws InvalidDataTypeException |
|
1473 | + * @throws InvalidInterfaceException |
|
1474 | + */ |
|
1475 | + protected function _verify_payment_method_is_set() |
|
1476 | + { |
|
1477 | + // generate billing form for selected method of payment if it hasn't been done already |
|
1478 | + if (empty($this->checkout->selected_method_of_payment)) { |
|
1479 | + // how have they chosen to pay? |
|
1480 | + $this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment(true); |
|
1481 | + } else { |
|
1482 | + // choose your own adventure based on method_of_payment |
|
1483 | + switch ($this->checkout->selected_method_of_payment) { |
|
1484 | + case 'events_sold_out': |
|
1485 | + EE_Error::add_attention( |
|
1486 | + apply_filters( |
|
1487 | + 'FHEE__EE_SPCO_Reg_Step_Payment_Options___verify_payment_method_is_set__sold_out_events_msg', |
|
1488 | + esc_html__( |
|
1489 | + 'It appears that the event you were about to make a payment for has sold out since this form first loaded. Please contact the event administrator if you believe this is an error.', |
|
1490 | + 'event_espresso' |
|
1491 | + ) |
|
1492 | + ), |
|
1493 | + __FILE__, |
|
1494 | + __FUNCTION__, |
|
1495 | + __LINE__ |
|
1496 | + ); |
|
1497 | + return false; |
|
1498 | + case 'payments_closed': |
|
1499 | + EE_Error::add_attention( |
|
1500 | + apply_filters( |
|
1501 | + 'FHEE__EE_SPCO_Reg_Step_Payment_Options___verify_payment_method_is_set__payments_closed_msg', |
|
1502 | + esc_html__( |
|
1503 | + 'It appears that the event you were about to make a payment for is not accepting payments at this time. Please contact the event administrator if you believe this is an error.', |
|
1504 | + 'event_espresso' |
|
1505 | + ) |
|
1506 | + ), |
|
1507 | + __FILE__, |
|
1508 | + __FUNCTION__, |
|
1509 | + __LINE__ |
|
1510 | + ); |
|
1511 | + return false; |
|
1512 | + case 'no_payment_required': |
|
1513 | + EE_Error::add_attention( |
|
1514 | + apply_filters( |
|
1515 | + 'FHEE__EE_SPCO_Reg_Step_Payment_Options___verify_payment_method_is_set__no_payment_required_msg', |
|
1516 | + esc_html__( |
|
1517 | + 'It appears that the event you were about to make a payment for does not require payment. Please contact the event administrator if you believe this is an error.', |
|
1518 | + 'event_espresso' |
|
1519 | + ) |
|
1520 | + ), |
|
1521 | + __FILE__, |
|
1522 | + __FUNCTION__, |
|
1523 | + __LINE__ |
|
1524 | + ); |
|
1525 | + return false; |
|
1526 | + default: |
|
1527 | + } |
|
1528 | + } |
|
1529 | + // verify payment method |
|
1530 | + if (! $this->checkout->payment_method instanceof EE_Payment_Method) { |
|
1531 | + // get payment method for selected method of payment |
|
1532 | + $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment(); |
|
1533 | + } |
|
1534 | + return $this->checkout->payment_method instanceof EE_Payment_Method; |
|
1535 | + } |
|
1536 | + |
|
1537 | + |
|
1538 | + |
|
1539 | + /********************************************************************************************************/ |
|
1540 | + /*************************************** SAVE PAYER DETAILS ****************************************/ |
|
1541 | + /********************************************************************************************************/ |
|
1542 | + /** |
|
1543 | + * save_payer_details_via_ajax |
|
1544 | + * |
|
1545 | + * @return void |
|
1546 | + * @throws EE_Error |
|
1547 | + * @throws InvalidArgumentException |
|
1548 | + * @throws ReflectionException |
|
1549 | + * @throws RuntimeException |
|
1550 | + * @throws InvalidDataTypeException |
|
1551 | + * @throws InvalidInterfaceException |
|
1552 | + */ |
|
1553 | + public function save_payer_details_via_ajax() |
|
1554 | + { |
|
1555 | + if (! $this->_verify_payment_method_is_set()) { |
|
1556 | + return; |
|
1557 | + } |
|
1558 | + // generate billing form for selected method of payment if it hasn't been done already |
|
1559 | + if ($this->checkout->payment_method->type_obj()->has_billing_form()) { |
|
1560 | + $this->checkout->billing_form = $this->_get_billing_form_for_payment_method( |
|
1561 | + $this->checkout->payment_method |
|
1562 | + ); |
|
1563 | + } |
|
1564 | + // generate primary attendee from payer info if applicable |
|
1565 | + if (! $this->checkout->transaction_has_primary_registrant()) { |
|
1566 | + $attendee = $this->_create_attendee_from_request_data(); |
|
1567 | + if ($attendee instanceof EE_Attendee) { |
|
1568 | + foreach ($this->checkout->transaction->registrations() as $registration) { |
|
1569 | + if ($registration->is_primary_registrant()) { |
|
1570 | + $this->checkout->primary_attendee_obj = $attendee; |
|
1571 | + $registration->_add_relation_to($attendee, 'Attendee'); |
|
1572 | + $registration->set_attendee_id($attendee->ID()); |
|
1573 | + $registration->update_cache_after_object_save('Attendee', $attendee); |
|
1574 | + } |
|
1575 | + } |
|
1576 | + } |
|
1577 | + } |
|
1578 | + } |
|
1579 | + |
|
1580 | + |
|
1581 | + /** |
|
1582 | + * create_attendee_from_request_data |
|
1583 | + * uses info from alternate GET or POST data (such as AJAX) to create a new attendee |
|
1584 | + * |
|
1585 | + * @return EE_Attendee |
|
1586 | + * @throws EE_Error |
|
1587 | + * @throws InvalidArgumentException |
|
1588 | + * @throws ReflectionException |
|
1589 | + * @throws InvalidDataTypeException |
|
1590 | + * @throws InvalidInterfaceException |
|
1591 | + */ |
|
1592 | + protected function _create_attendee_from_request_data() |
|
1593 | + { |
|
1594 | + // get State ID |
|
1595 | + $STA_ID = $this->request->getRequestParam('state'); |
|
1596 | + if (! empty($STA_ID)) { |
|
1597 | + // can we get state object from name ? |
|
1598 | + EE_Registry::instance()->load_model('State'); |
|
1599 | + $state = EEM_State::instance()->get_col([['STA_name' => $STA_ID], 'limit' => 1], 'STA_ID'); |
|
1600 | + $STA_ID = is_array($state) && ! empty($state) ? reset($state) : $STA_ID; |
|
1601 | + } |
|
1602 | + // get Country ISO |
|
1603 | + $CNT_ISO = $this->request->getRequestParam('country'); |
|
1604 | + if (! empty($CNT_ISO)) { |
|
1605 | + // can we get country object from name ? |
|
1606 | + EE_Registry::instance()->load_model('Country'); |
|
1607 | + $country = EEM_Country::instance()->get_col( |
|
1608 | + [['CNT_name' => $CNT_ISO], 'limit' => 1], |
|
1609 | + 'CNT_ISO' |
|
1610 | + ); |
|
1611 | + $CNT_ISO = is_array($country) && ! empty($country) ? reset($country) : $CNT_ISO; |
|
1612 | + } |
|
1613 | + // grab attendee data |
|
1614 | + $attendee_data = [ |
|
1615 | + 'ATT_fname' => $this->request->getRequestParam('first_name'), |
|
1616 | + 'ATT_lname' => $this->request->getRequestParam('last_name'), |
|
1617 | + 'ATT_email' => $this->request->getRequestParam('email'), |
|
1618 | + 'ATT_address' => $this->request->getRequestParam('address'), |
|
1619 | + 'ATT_address2' => $this->request->getRequestParam('address2'), |
|
1620 | + 'ATT_city' => $this->request->getRequestParam('city'), |
|
1621 | + 'STA_ID' => $STA_ID, |
|
1622 | + 'CNT_ISO' => $CNT_ISO, |
|
1623 | + 'ATT_zip' => $this->request->getRequestParam('zip'), |
|
1624 | + 'ATT_phone' => $this->request->getRequestParam('phone'), |
|
1625 | + ]; |
|
1626 | + // validate the email address since it is the most important piece of info |
|
1627 | + if (empty($attendee_data['ATT_email'])) { |
|
1628 | + EE_Error::add_error( |
|
1629 | + esc_html__('An invalid email address was submitted.', 'event_espresso'), |
|
1630 | + __FILE__, |
|
1631 | + __FUNCTION__, |
|
1632 | + __LINE__ |
|
1633 | + ); |
|
1634 | + } |
|
1635 | + // does this attendee already exist in the db ? we're searching using a combination of first name, last name, |
|
1636 | + // AND email address |
|
1637 | + if ( |
|
1638 | + ! empty($attendee_data['ATT_fname']) |
|
1639 | + && ! empty($attendee_data['ATT_lname']) |
|
1640 | + && ! empty($attendee_data['ATT_email']) |
|
1641 | + ) { |
|
1642 | + $existing_attendee = EEM_Attendee::instance()->find_existing_attendee( |
|
1643 | + [ |
|
1644 | + 'ATT_fname' => $attendee_data['ATT_fname'], |
|
1645 | + 'ATT_lname' => $attendee_data['ATT_lname'], |
|
1646 | + 'ATT_email' => $attendee_data['ATT_email'], |
|
1647 | + ] |
|
1648 | + ); |
|
1649 | + if ($existing_attendee instanceof EE_Attendee) { |
|
1650 | + return $existing_attendee; |
|
1651 | + } |
|
1652 | + } |
|
1653 | + // no existing attendee? kk let's create a new one |
|
1654 | + // kinda lame, but we need a first and last name to create an attendee, so use the email address if those |
|
1655 | + // don't exist |
|
1656 | + $attendee_data['ATT_fname'] = ! empty($attendee_data['ATT_fname']) |
|
1657 | + ? $attendee_data['ATT_fname'] |
|
1658 | + : $attendee_data['ATT_email']; |
|
1659 | + $attendee_data['ATT_lname'] = ! empty($attendee_data['ATT_lname']) |
|
1660 | + ? $attendee_data['ATT_lname'] |
|
1661 | + : $attendee_data['ATT_email']; |
|
1662 | + return EE_Attendee::new_instance($attendee_data); |
|
1663 | + } |
|
1664 | + |
|
1665 | + |
|
1666 | + |
|
1667 | + /********************************************************************************************************/ |
|
1668 | + /**************************************** PROCESS REG STEP *****************************************/ |
|
1669 | + /********************************************************************************************************/ |
|
1670 | + /** |
|
1671 | + * process_reg_step |
|
1672 | + * |
|
1673 | + * @return bool |
|
1674 | + * @throws EE_Error |
|
1675 | + * @throws InvalidArgumentException |
|
1676 | + * @throws ReflectionException |
|
1677 | + * @throws EntityNotFoundException |
|
1678 | + * @throws InvalidDataTypeException |
|
1679 | + * @throws InvalidInterfaceException |
|
1680 | + * @throws InvalidStatusException |
|
1681 | + */ |
|
1682 | + public function process_reg_step() |
|
1683 | + { |
|
1684 | + // how have they chosen to pay? |
|
1685 | + $this->checkout->selected_method_of_payment = $this->checkout->transaction->is_free() |
|
1686 | + ? 'no_payment_required' |
|
1687 | + : $this->_get_selected_method_of_payment(true); |
|
1688 | + // choose your own adventure based on method_of_payment |
|
1689 | + switch ($this->checkout->selected_method_of_payment) { |
|
1690 | + case 'events_sold_out': |
|
1691 | + $this->checkout->redirect = true; |
|
1692 | + $this->checkout->redirect_url = $this->checkout->cancel_page_url; |
|
1693 | + $this->checkout->json_response->set_redirect_url($this->checkout->redirect_url); |
|
1694 | + // mark this reg step as completed |
|
1695 | + $this->set_completed(); |
|
1696 | + return false; |
|
1697 | + |
|
1698 | + case 'payments_closed': |
|
1699 | + if ( |
|
1700 | + apply_filters( |
|
1701 | + 'FHEE__EE_SPCO_Reg_Step_Payment_Options__process_reg_step__payments_closed__display_success', |
|
1702 | + false |
|
1703 | + ) |
|
1704 | + ) { |
|
1705 | + EE_Error::add_success( |
|
1706 | + esc_html__('no payment required at this time.', 'event_espresso'), |
|
1707 | + __FILE__, |
|
1708 | + __FUNCTION__, |
|
1709 | + __LINE__ |
|
1710 | + ); |
|
1711 | + } |
|
1712 | + // mark this reg step as completed |
|
1713 | + $this->set_completed(); |
|
1714 | + return true; |
|
1715 | + |
|
1716 | + case 'no_payment_required': |
|
1717 | + if ( |
|
1718 | + apply_filters( |
|
1719 | + 'FHEE__EE_SPCO_Reg_Step_Payment_Options__process_reg_step__no_payment_required__display_success', |
|
1720 | + false |
|
1721 | + ) |
|
1722 | + ) { |
|
1723 | + EE_Error::add_success( |
|
1724 | + esc_html__('no payment required.', 'event_espresso'), |
|
1725 | + __FILE__, |
|
1726 | + __FUNCTION__, |
|
1727 | + __LINE__ |
|
1728 | + ); |
|
1729 | + } |
|
1730 | + // mark this reg step as completed |
|
1731 | + $this->set_completed(); |
|
1732 | + return true; |
|
1733 | + |
|
1734 | + default: |
|
1735 | + $registrations = EE_Registry::instance()->SSN->checkout()->transaction->registrations( |
|
1736 | + EE_Registry::instance()->SSN->checkout()->reg_cache_where_params |
|
1737 | + ); |
|
1738 | + $ejected_registrations = EE_SPCO_Reg_Step_Payment_Options::find_registrations_that_lost_their_space( |
|
1739 | + $registrations, |
|
1740 | + EE_Registry::instance()->SSN->checkout()->revisit |
|
1741 | + ); |
|
1742 | + // calculate difference between the two arrays |
|
1743 | + $registrations = array_diff($registrations, $ejected_registrations); |
|
1744 | + if (empty($registrations)) { |
|
1745 | + $this->_redirect_because_event_sold_out(); |
|
1746 | + return false; |
|
1747 | + } |
|
1748 | + $payment_successful = $this->_process_payment(); |
|
1749 | + if ($payment_successful) { |
|
1750 | + $this->checkout->continue_reg = true; |
|
1751 | + $this->_maybe_set_completed($this->checkout->payment_method); |
|
1752 | + } else { |
|
1753 | + $this->checkout->continue_reg = false; |
|
1754 | + } |
|
1755 | + return $payment_successful; |
|
1756 | + } |
|
1757 | + } |
|
1758 | + |
|
1759 | + |
|
1760 | + /** |
|
1761 | + * _redirect_because_event_sold_out |
|
1762 | + * |
|
1763 | + * @return void |
|
1764 | + */ |
|
1765 | + protected function _redirect_because_event_sold_out() |
|
1766 | + { |
|
1767 | + $this->checkout->continue_reg = false; |
|
1768 | + // set redirect URL |
|
1769 | + $this->checkout->redirect_url = add_query_arg( |
|
1770 | + ['e_reg_url_link' => $this->checkout->reg_url_link], |
|
1771 | + $this->checkout->current_step->reg_step_url() |
|
1772 | + ); |
|
1773 | + $this->checkout->json_response->set_redirect_url($this->checkout->redirect_url); |
|
1774 | + } |
|
1775 | + |
|
1776 | + |
|
1777 | + /** |
|
1778 | + * _maybe_set_completed |
|
1779 | + * |
|
1780 | + * @param EE_Payment_Method $payment_method |
|
1781 | + * @return void |
|
1782 | + * @throws EE_Error |
|
1783 | + */ |
|
1784 | + protected function _maybe_set_completed(EE_Payment_Method $payment_method) |
|
1785 | + { |
|
1786 | + switch ($payment_method->type_obj()->payment_occurs()) { |
|
1787 | + case EE_PMT_Base::offsite: |
|
1788 | + break; |
|
1789 | + case EE_PMT_Base::onsite: |
|
1790 | + case EE_PMT_Base::offline: |
|
1791 | + // mark this reg step as completed |
|
1792 | + $this->set_completed(); |
|
1793 | + break; |
|
1794 | + } |
|
1795 | + } |
|
1796 | + |
|
1797 | + |
|
1798 | + /** |
|
1799 | + * update_reg_step |
|
1800 | + * this is the final step after a user revisits the site to retry a payment |
|
1801 | + * |
|
1802 | + * @return bool |
|
1803 | + * @throws EE_Error |
|
1804 | + * @throws InvalidArgumentException |
|
1805 | + * @throws ReflectionException |
|
1806 | + * @throws EntityNotFoundException |
|
1807 | + * @throws InvalidDataTypeException |
|
1808 | + * @throws InvalidInterfaceException |
|
1809 | + * @throws InvalidStatusException |
|
1810 | + */ |
|
1811 | + public function update_reg_step() |
|
1812 | + { |
|
1813 | + $success = true; |
|
1814 | + // if payment required |
|
1815 | + if ($this->checkout->transaction->total() > 0) { |
|
1816 | + do_action( |
|
1817 | + 'AHEE__EE_Single_Page_Checkout__process_finalize_registration__before_gateway', |
|
1818 | + $this->checkout->transaction |
|
1819 | + ); |
|
1820 | + // attempt payment via payment method |
|
1821 | + $success = $this->process_reg_step(); |
|
1822 | + } |
|
1823 | + if ($success && ! $this->checkout->redirect) { |
|
1824 | + $this->checkout->cart->get_grand_total()->save_this_and_descendants_to_txn( |
|
1825 | + $this->checkout->transaction->ID() |
|
1826 | + ); |
|
1827 | + // set return URL |
|
1828 | + $this->checkout->redirect_url = add_query_arg( |
|
1829 | + ['e_reg_url_link' => $this->checkout->reg_url_link], |
|
1830 | + $this->checkout->thank_you_page_url |
|
1831 | + ); |
|
1832 | + } |
|
1833 | + return $success; |
|
1834 | + } |
|
1835 | + |
|
1836 | + |
|
1837 | + /** |
|
1838 | + * _process_payment |
|
1839 | + * |
|
1840 | + * @return bool |
|
1841 | + * @throws EE_Error |
|
1842 | + * @throws InvalidArgumentException |
|
1843 | + * @throws ReflectionException |
|
1844 | + * @throws RuntimeException |
|
1845 | + * @throws InvalidDataTypeException |
|
1846 | + * @throws InvalidInterfaceException |
|
1847 | + */ |
|
1848 | + private function _process_payment() |
|
1849 | + { |
|
1850 | + // basically confirm that the event hasn't sold out since they hit the page |
|
1851 | + if (! $this->_last_second_ticket_verifications()) { |
|
1852 | + return false; |
|
1853 | + } |
|
1854 | + // ya gotta make a choice man |
|
1855 | + if (empty($this->checkout->selected_method_of_payment)) { |
|
1856 | + $this->checkout->json_response->set_plz_select_method_of_payment( |
|
1857 | + esc_html__('Please select a method of payment before proceeding.', 'event_espresso') |
|
1858 | + ); |
|
1859 | + return false; |
|
1860 | + } |
|
1861 | + // get EE_Payment_Method object |
|
1862 | + if (! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()) { |
|
1863 | + return false; |
|
1864 | + } |
|
1865 | + // setup billing form |
|
1866 | + if ($this->checkout->payment_method->is_on_site()) { |
|
1867 | + $this->checkout->billing_form = $this->_get_billing_form_for_payment_method( |
|
1868 | + $this->checkout->payment_method |
|
1869 | + ); |
|
1870 | + // bad billing form ? |
|
1871 | + if (! $this->_billing_form_is_valid()) { |
|
1872 | + return false; |
|
1873 | + } |
|
1874 | + } |
|
1875 | + // ensure primary registrant has been fully processed |
|
1876 | + if (! $this->_setup_primary_registrant_prior_to_payment()) { |
|
1877 | + return false; |
|
1878 | + } |
|
1879 | + // if session is close to expiring (under 10 minutes by default) |
|
1880 | + if ((time() - EE_Registry::instance()->SSN->expiration()) < EE_Registry::instance()->SSN->extension()) { |
|
1881 | + // add some time to session expiration so that payment can be completed |
|
1882 | + EE_Registry::instance()->SSN->extend_expiration(); |
|
1883 | + } |
|
1884 | + /** @type EE_Transaction_Processor $transaction_processor */ |
|
1885 | + // $transaction_processor = EE_Registry::instance()->load_class( 'Transaction_Processor' ); |
|
1886 | + // in case a registrant leaves to an Off-Site Gateway and never returns, we want to approve any registrations |
|
1887 | + // for events with a default reg status of Approved |
|
1888 | + // $transaction_processor->toggle_registration_statuses_for_default_approved_events( |
|
1889 | + // $this->checkout->transaction, $this->checkout->reg_cache_where_params |
|
1890 | + // ); |
|
1891 | + // attempt payment |
|
1892 | + $payment = $this->_attempt_payment($this->checkout->payment_method); |
|
1893 | + // process results |
|
1894 | + $payment = $this->_validate_payment($payment); |
|
1895 | + $payment = $this->_post_payment_processing($payment); |
|
1896 | + // verify payment |
|
1897 | + if ($payment instanceof EE_Payment) { |
|
1898 | + // store that for later |
|
1899 | + $this->checkout->payment = $payment; |
|
1900 | + // we can also consider the TXN to not have been failed, so temporarily upgrade it's status to abandoned |
|
1901 | + $this->checkout->transaction->toggle_failed_transaction_status(); |
|
1902 | + $payment_status = $payment->status(); |
|
1903 | + return $payment_status === EEM_Payment::status_id_approved |
|
1904 | + || $payment_status === EEM_Payment::status_id_pending; |
|
1905 | + } |
|
1906 | + if ($payment === true) { |
|
1907 | + // please note that offline payment methods will NOT make a payment, |
|
1908 | + // but instead just mark themselves as the PMD_ID on the transaction, and return true |
|
1909 | + $this->checkout->payment = $payment; |
|
1910 | + return true; |
|
1911 | + } |
|
1912 | + // where's my money? |
|
1913 | + return false; |
|
1914 | + } |
|
1915 | + |
|
1916 | + |
|
1917 | + /** |
|
1918 | + * _last_second_ticket_verifications |
|
1919 | + * |
|
1920 | + * @return bool |
|
1921 | + * @throws EE_Error |
|
1922 | + * @throws ReflectionException |
|
1923 | + */ |
|
1924 | + protected function _last_second_ticket_verifications() |
|
1925 | + { |
|
1926 | + // don't bother re-validating if not a return visit |
|
1927 | + if (! $this->checkout->revisit) { |
|
1928 | + return true; |
|
1929 | + } |
|
1930 | + $registrations = $this->checkout->transaction->registrations(); |
|
1931 | + if (empty($registrations)) { |
|
1932 | + return false; |
|
1933 | + } |
|
1934 | + foreach ($registrations as $registration) { |
|
1935 | + if ($registration instanceof EE_Registration && ! $registration->is_approved()) { |
|
1936 | + $event = $registration->event_obj(); |
|
1937 | + if ($event instanceof EE_Event && $event->is_sold_out(true)) { |
|
1938 | + EE_Error::add_error( |
|
1939 | + apply_filters( |
|
1940 | + 'FHEE__EE_SPCO_Reg_Step_Payment_Options___last_second_ticket_verifications__sold_out_events_msg', |
|
1941 | + sprintf( |
|
1942 | + esc_html__( |
|
1943 | + 'It appears that the %1$s event that you were about to make a payment for has sold out since you first registered and/or arrived at this page. Please refresh the page and try again. If you have already made a partial payment towards this event, please contact the event administrator for a refund.', |
|
1944 | + 'event_espresso' |
|
1945 | + ), |
|
1946 | + $event->name() |
|
1947 | + ) |
|
1948 | + ), |
|
1949 | + __FILE__, |
|
1950 | + __FUNCTION__, |
|
1951 | + __LINE__ |
|
1952 | + ); |
|
1953 | + return false; |
|
1954 | + } |
|
1955 | + } |
|
1956 | + } |
|
1957 | + return true; |
|
1958 | + } |
|
1959 | + |
|
1960 | + |
|
1961 | + /** |
|
1962 | + * redirect_form |
|
1963 | + * |
|
1964 | + * @return bool |
|
1965 | + * @throws EE_Error |
|
1966 | + * @throws InvalidArgumentException |
|
1967 | + * @throws ReflectionException |
|
1968 | + * @throws InvalidDataTypeException |
|
1969 | + * @throws InvalidInterfaceException |
|
1970 | + */ |
|
1971 | + public function redirect_form() |
|
1972 | + { |
|
1973 | + $payment_method_billing_info = $this->_payment_method_billing_info( |
|
1974 | + $this->_get_payment_method_for_selected_method_of_payment() |
|
1975 | + ); |
|
1976 | + $html = $payment_method_billing_info->get_html(); |
|
1977 | + $html .= $this->checkout->redirect_form; |
|
1978 | + /** @var ResponseInterface $response */ |
|
1979 | + $response = LoaderFactory::getLoader()->getShared(ResponseInterface::class); |
|
1980 | + $response->addOutput($html); |
|
1981 | + return true; |
|
1982 | + } |
|
1983 | + |
|
1984 | + |
|
1985 | + /** |
|
1986 | + * _billing_form_is_valid |
|
1987 | + * |
|
1988 | + * @return bool |
|
1989 | + * @throws EE_Error |
|
1990 | + */ |
|
1991 | + private function _billing_form_is_valid() |
|
1992 | + { |
|
1993 | + if (! $this->checkout->payment_method->type_obj()->has_billing_form()) { |
|
1994 | + return true; |
|
1995 | + } |
|
1996 | + if ($this->checkout->billing_form instanceof EE_Billing_Info_Form) { |
|
1997 | + if ($this->checkout->billing_form->was_submitted()) { |
|
1998 | + $this->checkout->billing_form->receive_form_submission(); |
|
1999 | + if ($this->checkout->billing_form->is_valid()) { |
|
2000 | + return true; |
|
2001 | + } |
|
2002 | + $validation_errors = $this->checkout->billing_form->get_validation_errors_accumulated(); |
|
2003 | + $error_strings = []; |
|
2004 | + foreach ($validation_errors as $validation_error) { |
|
2005 | + if ($validation_error instanceof EE_Validation_Error) { |
|
2006 | + $form_section = $validation_error->get_form_section(); |
|
2007 | + if ($form_section instanceof EE_Form_Input_Base) { |
|
2008 | + $label = $form_section->html_label_text(); |
|
2009 | + } elseif ($form_section instanceof EE_Form_Section_Base) { |
|
2010 | + $label = $form_section->name(); |
|
2011 | + } else { |
|
2012 | + $label = esc_html__('Validation Error', 'event_espresso'); |
|
2013 | + } |
|
2014 | + $error_strings[] = sprintf('%1$s: %2$s', $label, $validation_error->getMessage()); |
|
2015 | + } |
|
2016 | + } |
|
2017 | + EE_Error::add_error( |
|
2018 | + sprintf( |
|
2019 | + esc_html__( |
|
2020 | + 'One or more billing form inputs are invalid and require correction before proceeding. %1$s %2$s', |
|
2021 | + 'event_espresso' |
|
2022 | + ), |
|
2023 | + '<br/>', |
|
2024 | + implode('<br/>', $error_strings) |
|
2025 | + ), |
|
2026 | + __FILE__, |
|
2027 | + __FUNCTION__, |
|
2028 | + __LINE__ |
|
2029 | + ); |
|
2030 | + } else { |
|
2031 | + EE_Error::add_error( |
|
2032 | + esc_html__( |
|
2033 | + 'The billing form was not submitted or something prevented it\'s submission.', |
|
2034 | + 'event_espresso' |
|
2035 | + ), |
|
2036 | + __FILE__, |
|
2037 | + __FUNCTION__, |
|
2038 | + __LINE__ |
|
2039 | + ); |
|
2040 | + } |
|
2041 | + } else { |
|
2042 | + EE_Error::add_error( |
|
2043 | + esc_html__( |
|
2044 | + 'The submitted billing form is invalid possibly due to a technical reason.', |
|
2045 | + 'event_espresso' |
|
2046 | + ), |
|
2047 | + __FILE__, |
|
2048 | + __FUNCTION__, |
|
2049 | + __LINE__ |
|
2050 | + ); |
|
2051 | + } |
|
2052 | + return false; |
|
2053 | + } |
|
2054 | + |
|
2055 | + |
|
2056 | + /** |
|
2057 | + * _setup_primary_registrant_prior_to_payment |
|
2058 | + * ensures that the primary registrant has a valid attendee object created with the critical details populated |
|
2059 | + * (first & last name & email) and that both the transaction object and primary registration object have been saved |
|
2060 | + * plz note that any other registrations will NOT be saved at this point (because they may not have any details |
|
2061 | + * yet) |
|
2062 | + * |
|
2063 | + * @return bool |
|
2064 | + * @throws EE_Error |
|
2065 | + * @throws InvalidArgumentException |
|
2066 | + * @throws ReflectionException |
|
2067 | + * @throws RuntimeException |
|
2068 | + * @throws InvalidDataTypeException |
|
2069 | + * @throws InvalidInterfaceException |
|
2070 | + */ |
|
2071 | + private function _setup_primary_registrant_prior_to_payment() |
|
2072 | + { |
|
2073 | + // check if transaction has a primary registrant and that it has a related Attendee object |
|
2074 | + // if not, then we need to at least gather some primary registrant data before attempting payment |
|
2075 | + if ( |
|
2076 | + $this->checkout->billing_form instanceof EE_Billing_Attendee_Info_Form |
|
2077 | + && ! $this->checkout->transaction_has_primary_registrant() |
|
2078 | + && ! $this->_capture_primary_registration_data_from_billing_form() |
|
2079 | + ) { |
|
2080 | + return false; |
|
2081 | + } |
|
2082 | + // because saving an object clears it's cache, we need to do the chevy shuffle |
|
2083 | + // grab the primary_registration object |
|
2084 | + $primary_registration = $this->checkout->transaction->primary_registration(); |
|
2085 | + // at this point we'll consider a TXN to not have been failed |
|
2086 | + $this->checkout->transaction->toggle_failed_transaction_status(); |
|
2087 | + // save the TXN ( which clears cached copy of primary_registration) |
|
2088 | + $this->checkout->transaction->save(); |
|
2089 | + // grab TXN ID and save it to the primary_registration |
|
2090 | + $primary_registration->set_transaction_id($this->checkout->transaction->ID()); |
|
2091 | + // save what we have so far |
|
2092 | + $primary_registration->save(); |
|
2093 | + return true; |
|
2094 | + } |
|
2095 | + |
|
2096 | + |
|
2097 | + /** |
|
2098 | + * _capture_primary_registration_data_from_billing_form |
|
2099 | + * |
|
2100 | + * @return bool |
|
2101 | + * @throws EE_Error |
|
2102 | + * @throws InvalidArgumentException |
|
2103 | + * @throws ReflectionException |
|
2104 | + * @throws InvalidDataTypeException |
|
2105 | + * @throws InvalidInterfaceException |
|
2106 | + */ |
|
2107 | + private function _capture_primary_registration_data_from_billing_form() |
|
2108 | + { |
|
2109 | + // convert billing form data into an attendee |
|
2110 | + $this->checkout->primary_attendee_obj = $this->checkout->billing_form->create_attendee_from_billing_form_data(); |
|
2111 | + if (! $this->checkout->primary_attendee_obj instanceof EE_Attendee) { |
|
2112 | + EE_Error::add_error( |
|
2113 | + sprintf( |
|
2114 | + esc_html__( |
|
2115 | + 'The billing form details could not be used for attendee details due to a technical issue.%sPlease try again or contact %s for assistance.', |
|
2116 | + 'event_espresso' |
|
2117 | + ), |
|
2118 | + '<br/>', |
|
2119 | + EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
2120 | + ), |
|
2121 | + __FILE__, |
|
2122 | + __FUNCTION__, |
|
2123 | + __LINE__ |
|
2124 | + ); |
|
2125 | + return false; |
|
2126 | + } |
|
2127 | + $primary_registration = $this->checkout->transaction->primary_registration(); |
|
2128 | + if (! $primary_registration instanceof EE_Registration) { |
|
2129 | + EE_Error::add_error( |
|
2130 | + sprintf( |
|
2131 | + esc_html__( |
|
2132 | + 'The primary registrant for this transaction could not be determined due to a technical issue.%sPlease try again or contact %s for assistance.', |
|
2133 | + 'event_espresso' |
|
2134 | + ), |
|
2135 | + '<br/>', |
|
2136 | + EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
2137 | + ), |
|
2138 | + __FILE__, |
|
2139 | + __FUNCTION__, |
|
2140 | + __LINE__ |
|
2141 | + ); |
|
2142 | + return false; |
|
2143 | + } |
|
2144 | + if ( |
|
2145 | + ! $primary_registration->_add_relation_to($this->checkout->primary_attendee_obj, 'Attendee') |
|
2146 | + instanceof |
|
2147 | + EE_Attendee |
|
2148 | + ) { |
|
2149 | + EE_Error::add_error( |
|
2150 | + sprintf( |
|
2151 | + esc_html__( |
|
2152 | + 'The primary registrant could not be associated with this transaction due to a technical issue.%sPlease try again or contact %s for assistance.', |
|
2153 | + 'event_espresso' |
|
2154 | + ), |
|
2155 | + '<br/>', |
|
2156 | + EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
2157 | + ), |
|
2158 | + __FILE__, |
|
2159 | + __FUNCTION__, |
|
2160 | + __LINE__ |
|
2161 | + ); |
|
2162 | + return false; |
|
2163 | + } |
|
2164 | + /** @type EE_Registration_Processor $registration_processor */ |
|
2165 | + $registration_processor = EE_Registry::instance()->load_class('Registration_Processor'); |
|
2166 | + // at this point, we should have enough details about the registrant to consider the registration NOT incomplete |
|
2167 | + $registration_processor->toggle_incomplete_registration_status_to_default($primary_registration); |
|
2168 | + return true; |
|
2169 | + } |
|
2170 | + |
|
2171 | + |
|
2172 | + /** |
|
2173 | + * _get_payment_method_for_selected_method_of_payment |
|
2174 | + * retrieves a valid payment method |
|
2175 | + * |
|
2176 | + * @return EE_Payment_Method |
|
2177 | + * @throws EE_Error |
|
2178 | + * @throws InvalidArgumentException |
|
2179 | + * @throws ReflectionException |
|
2180 | + * @throws InvalidDataTypeException |
|
2181 | + * @throws InvalidInterfaceException |
|
2182 | + */ |
|
2183 | + private function _get_payment_method_for_selected_method_of_payment() |
|
2184 | + { |
|
2185 | + if ($this->checkout->selected_method_of_payment === 'events_sold_out') { |
|
2186 | + $this->_redirect_because_event_sold_out(); |
|
2187 | + return null; |
|
2188 | + } |
|
2189 | + // get EE_Payment_Method object |
|
2190 | + if (isset($this->checkout->available_payment_methods[ $this->checkout->selected_method_of_payment ])) { |
|
2191 | + $payment_method = $this->checkout->available_payment_methods[ $this->checkout->selected_method_of_payment ]; |
|
2192 | + } else { |
|
2193 | + // load EEM_Payment_Method |
|
2194 | + EE_Registry::instance()->load_model('Payment_Method'); |
|
2195 | + $EEM_Payment_Method = EEM_Payment_Method::instance(); |
|
2196 | + $payment_method = $EEM_Payment_Method->get_one_by_slug($this->checkout->selected_method_of_payment); |
|
2197 | + } |
|
2198 | + // verify $payment_method |
|
2199 | + if (! $payment_method instanceof EE_Payment_Method) { |
|
2200 | + // not a payment |
|
2201 | + EE_Error::add_error( |
|
2202 | + sprintf( |
|
2203 | + esc_html__( |
|
2204 | + 'The selected method of payment could not be determined due to a technical issue.%sPlease try again or contact %s for assistance.', |
|
2205 | + 'event_espresso' |
|
2206 | + ), |
|
2207 | + '<br/>', |
|
2208 | + EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
2209 | + ), |
|
2210 | + __FILE__, |
|
2211 | + __FUNCTION__, |
|
2212 | + __LINE__ |
|
2213 | + ); |
|
2214 | + return null; |
|
2215 | + } |
|
2216 | + // and verify it has a valid Payment_Method Type object |
|
2217 | + if (! $payment_method->type_obj() instanceof EE_PMT_Base) { |
|
2218 | + // not a payment |
|
2219 | + EE_Error::add_error( |
|
2220 | + sprintf( |
|
2221 | + esc_html__( |
|
2222 | + 'A valid payment method could not be determined due to a technical issue.%sPlease try again or contact %s for assistance.', |
|
2223 | + 'event_espresso' |
|
2224 | + ), |
|
2225 | + '<br/>', |
|
2226 | + EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
2227 | + ), |
|
2228 | + __FILE__, |
|
2229 | + __FUNCTION__, |
|
2230 | + __LINE__ |
|
2231 | + ); |
|
2232 | + return null; |
|
2233 | + } |
|
2234 | + return $payment_method; |
|
2235 | + } |
|
2236 | + |
|
2237 | + |
|
2238 | + /** |
|
2239 | + * _attempt_payment |
|
2240 | + * |
|
2241 | + * @access private |
|
2242 | + * @type EE_Payment_Method $payment_method |
|
2243 | + * @return mixed EE_Payment | boolean |
|
2244 | + * @throws EE_Error |
|
2245 | + * @throws InvalidArgumentException |
|
2246 | + * @throws ReflectionException |
|
2247 | + * @throws InvalidDataTypeException |
|
2248 | + * @throws InvalidInterfaceException |
|
2249 | + */ |
|
2250 | + private function _attempt_payment(EE_Payment_Method $payment_method) |
|
2251 | + { |
|
2252 | + $payment = null; |
|
2253 | + $this->checkout->transaction->save(); |
|
2254 | + $payment_processor = EE_Registry::instance()->load_core('Payment_Processor'); |
|
2255 | + if (! $payment_processor instanceof EE_Payment_Processor) { |
|
2256 | + return false; |
|
2257 | + } |
|
2258 | + try { |
|
2259 | + $payment_processor->set_revisit($this->checkout->revisit); |
|
2260 | + // generate payment object |
|
2261 | + $payment = $payment_processor->process_payment( |
|
2262 | + $payment_method, |
|
2263 | + $this->checkout->transaction, |
|
2264 | + $this->checkout->amount_owing, |
|
2265 | + $this->checkout->billing_form instanceof EE_Billing_Info_Form |
|
2266 | + ? $this->checkout->billing_form |
|
2267 | + : null, |
|
2268 | + $this->_get_return_url($payment_method), |
|
2269 | + 'CART', |
|
2270 | + $this->checkout->admin_request, |
|
2271 | + true, |
|
2272 | + $this->reg_step_url() |
|
2273 | + ); |
|
2274 | + } catch (Exception $e) { |
|
2275 | + $this->_handle_payment_processor_exception($e); |
|
2276 | + } |
|
2277 | + return $payment; |
|
2278 | + } |
|
2279 | + |
|
2280 | + |
|
2281 | + /** |
|
2282 | + * _handle_payment_processor_exception |
|
2283 | + * |
|
2284 | + * @param Exception $e |
|
2285 | + * @return void |
|
2286 | + * @throws EE_Error |
|
2287 | + * @throws InvalidArgumentException |
|
2288 | + * @throws InvalidDataTypeException |
|
2289 | + * @throws InvalidInterfaceException |
|
2290 | + */ |
|
2291 | + protected function _handle_payment_processor_exception(Exception $e) |
|
2292 | + { |
|
2293 | + EE_Error::add_error( |
|
2294 | + sprintf( |
|
2295 | + esc_html__( |
|
2296 | + 'The payment could not br processed due to a technical issue.%1$sPlease try again or contact %2$s for assistance.||The following Exception was thrown in %4$s on line %5$s:%1$s%3$s', |
|
2297 | + 'event_espresso' |
|
2298 | + ), |
|
2299 | + '<br/>', |
|
2300 | + EE_Registry::instance()->CFG->organization->get_pretty('email'), |
|
2301 | + $e->getMessage(), |
|
2302 | + $e->getFile(), |
|
2303 | + $e->getLine() |
|
2304 | + ), |
|
2305 | + __FILE__, |
|
2306 | + __FUNCTION__, |
|
2307 | + __LINE__ |
|
2308 | + ); |
|
2309 | + } |
|
2310 | + |
|
2311 | + |
|
2312 | + /** |
|
2313 | + * _get_return_url |
|
2314 | + * |
|
2315 | + * @param EE_Payment_Method $payment_method |
|
2316 | + * @return string |
|
2317 | + * @throws EE_Error |
|
2318 | + * @throws ReflectionException |
|
2319 | + */ |
|
2320 | + protected function _get_return_url(EE_Payment_Method $payment_method) |
|
2321 | + { |
|
2322 | + $return_url = ''; |
|
2323 | + switch ($payment_method->type_obj()->payment_occurs()) { |
|
2324 | + case EE_PMT_Base::offsite: |
|
2325 | + $return_url = add_query_arg( |
|
2326 | + [ |
|
2327 | + 'action' => 'process_gateway_response', |
|
2328 | + 'selected_method_of_payment' => $this->checkout->selected_method_of_payment, |
|
2329 | + 'spco_txn' => $this->checkout->transaction->ID(), |
|
2330 | + ], |
|
2331 | + $this->reg_step_url() |
|
2332 | + ); |
|
2333 | + break; |
|
2334 | + case EE_PMT_Base::onsite: |
|
2335 | + case EE_PMT_Base::offline: |
|
2336 | + $return_url = $this->checkout->next_step->reg_step_url(); |
|
2337 | + break; |
|
2338 | + } |
|
2339 | + return $return_url; |
|
2340 | + } |
|
2341 | + |
|
2342 | + |
|
2343 | + /** |
|
2344 | + * _validate_payment |
|
2345 | + * |
|
2346 | + * @param EE_Payment $payment |
|
2347 | + * @return EE_Payment|FALSE |
|
2348 | + * @throws EE_Error |
|
2349 | + * @throws InvalidArgumentException |
|
2350 | + * @throws InvalidDataTypeException |
|
2351 | + * @throws InvalidInterfaceException |
|
2352 | + */ |
|
2353 | + private function _validate_payment($payment = null) |
|
2354 | + { |
|
2355 | + if ($this->checkout->payment_method->is_off_line()) { |
|
2356 | + return true; |
|
2357 | + } |
|
2358 | + // verify payment object |
|
2359 | + if (! $payment instanceof EE_Payment) { |
|
2360 | + // not a payment |
|
2361 | + EE_Error::add_error( |
|
2362 | + sprintf( |
|
2363 | + esc_html__( |
|
2364 | + 'A valid payment was not generated due to a technical issue.%1$sPlease try again or contact %2$s for assistance.', |
|
2365 | + 'event_espresso' |
|
2366 | + ), |
|
2367 | + '<br/>', |
|
2368 | + EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
2369 | + ), |
|
2370 | + __FILE__, |
|
2371 | + __FUNCTION__, |
|
2372 | + __LINE__ |
|
2373 | + ); |
|
2374 | + return false; |
|
2375 | + } |
|
2376 | + return $payment; |
|
2377 | + } |
|
2378 | + |
|
2379 | + |
|
2380 | + /** |
|
2381 | + * _post_payment_processing |
|
2382 | + * |
|
2383 | + * @param EE_Payment|bool $payment |
|
2384 | + * @return bool |
|
2385 | + * @throws EE_Error |
|
2386 | + * @throws InvalidArgumentException |
|
2387 | + * @throws InvalidDataTypeException |
|
2388 | + * @throws InvalidInterfaceException |
|
2389 | + * @throws ReflectionException |
|
2390 | + */ |
|
2391 | + private function _post_payment_processing($payment = null) |
|
2392 | + { |
|
2393 | + // Off-Line payment? |
|
2394 | + if ($payment === true) { |
|
2395 | + // $this->_setup_redirect_for_next_step(); |
|
2396 | + return true; |
|
2397 | + // On-Site payment? |
|
2398 | + } elseif ($this->checkout->payment_method->is_on_site()) { |
|
2399 | + if (! $this->_process_payment_status($payment, EE_PMT_Base::onsite)) { |
|
2400 | + // $this->_setup_redirect_for_next_step(); |
|
2401 | + $this->checkout->continue_reg = false; |
|
2402 | + } |
|
2403 | + // Off-Site payment? |
|
2404 | + } elseif ($this->checkout->payment_method->is_off_site()) { |
|
2405 | + // if a payment object was made and it specifies a redirect url, then we'll setup that redirect info |
|
2406 | + if ($payment instanceof EE_Payment && $payment->redirect_url()) { |
|
2407 | + do_action('AHEE_log', __CLASS__, __FUNCTION__, $payment->redirect_url(), '$payment->redirect_url()'); |
|
2408 | + $this->checkout->redirect = true; |
|
2409 | + $this->checkout->redirect_form = $payment->redirect_form(); |
|
2410 | + $this->checkout->redirect_url = $this->reg_step_url('redirect_form'); |
|
2411 | + // set JSON response |
|
2412 | + $this->checkout->json_response->set_redirect_form($this->checkout->redirect_form); |
|
2413 | + // and lastly, let's bump the payment status to pending |
|
2414 | + $payment->set_status(EEM_Payment::status_id_pending); |
|
2415 | + $payment->save(); |
|
2416 | + } else { |
|
2417 | + // we couldn't redirect the user. Let's tell them why. |
|
2418 | + $error_message = sprintf( |
|
2419 | + esc_html__( |
|
2420 | + 'It appears the Off Site Payment Method was not configured properly.%sPlease try again or contact %s for assistance.', |
|
2421 | + 'event_espresso' |
|
2422 | + ), |
|
2423 | + '<br/>', |
|
2424 | + EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
2425 | + ); |
|
2426 | + if ($payment instanceof EE_Payment && $payment->gateway_response()) { |
|
2427 | + $error_message = $error_message . '<br/>' . $payment->gateway_response(); |
|
2428 | + } |
|
2429 | + $this->checkout->continue_reg = false; |
|
2430 | + EE_Error::add_error( |
|
2431 | + $error_message, |
|
2432 | + __FILE__, |
|
2433 | + __FUNCTION__, |
|
2434 | + __LINE__ |
|
2435 | + ); |
|
2436 | + } |
|
2437 | + } else { |
|
2438 | + // ummm ya... not Off-Line, not On-Site, not off-Site ???? |
|
2439 | + $this->checkout->continue_reg = false; |
|
2440 | + return false; |
|
2441 | + } |
|
2442 | + return $payment; |
|
2443 | + } |
|
2444 | + |
|
2445 | + |
|
2446 | + /** |
|
2447 | + * _process_payment_status |
|
2448 | + * |
|
2449 | + * @type EE_Payment $payment |
|
2450 | + * @param string $payment_occurs |
|
2451 | + * @return bool |
|
2452 | + * @throws EE_Error |
|
2453 | + * @throws InvalidArgumentException |
|
2454 | + * @throws InvalidDataTypeException |
|
2455 | + * @throws InvalidInterfaceException |
|
2456 | + */ |
|
2457 | + private function _process_payment_status($payment, $payment_occurs = EE_PMT_Base::offline) |
|
2458 | + { |
|
2459 | + // off-line payment? carry on |
|
2460 | + if ($payment_occurs === EE_PMT_Base::offline) { |
|
2461 | + return true; |
|
2462 | + } |
|
2463 | + // verify payment validity |
|
2464 | + if ($payment instanceof EE_Payment) { |
|
2465 | + do_action('AHEE_log', __CLASS__, __FUNCTION__, $payment->status(), '$payment->status()'); |
|
2466 | + $msg = $payment->gateway_response(); |
|
2467 | + // check results |
|
2468 | + switch ($payment->status()) { |
|
2469 | + // good payment |
|
2470 | + case EEM_Payment::status_id_approved: |
|
2471 | + EE_Error::add_success( |
|
2472 | + esc_html__('Your payment was processed successfully.', 'event_espresso'), |
|
2473 | + __FILE__, |
|
2474 | + __FUNCTION__, |
|
2475 | + __LINE__ |
|
2476 | + ); |
|
2477 | + return true; |
|
2478 | + // slow payment |
|
2479 | + case EEM_Payment::status_id_pending: |
|
2480 | + if (empty($msg)) { |
|
2481 | + $msg = esc_html__( |
|
2482 | + 'Your payment appears to have been processed successfully, but the Instant Payment Notification has not yet been received. It should arrive shortly.', |
|
2483 | + 'event_espresso' |
|
2484 | + ); |
|
2485 | + } |
|
2486 | + EE_Error::add_success($msg, __FILE__, __FUNCTION__, __LINE__); |
|
2487 | + return true; |
|
2488 | + // don't wanna payment |
|
2489 | + case EEM_Payment::status_id_cancelled: |
|
2490 | + if (empty($msg)) { |
|
2491 | + $msg = _n( |
|
2492 | + 'Payment cancelled. Please try again.', |
|
2493 | + 'Payment cancelled. Please try again or select another method of payment.', |
|
2494 | + count($this->checkout->available_payment_methods), |
|
2495 | + 'event_espresso' |
|
2496 | + ); |
|
2497 | + } |
|
2498 | + EE_Error::add_attention($msg, __FILE__, __FUNCTION__, __LINE__); |
|
2499 | + return false; |
|
2500 | + // not enough payment |
|
2501 | + case EEM_Payment::status_id_declined: |
|
2502 | + if (empty($msg)) { |
|
2503 | + $msg = _n( |
|
2504 | + 'We\'re sorry but your payment was declined. Please try again.', |
|
2505 | + 'We\'re sorry but your payment was declined. Please try again or select another method of payment.', |
|
2506 | + count($this->checkout->available_payment_methods), |
|
2507 | + 'event_espresso' |
|
2508 | + ); |
|
2509 | + } |
|
2510 | + EE_Error::add_attention($msg, __FILE__, __FUNCTION__, __LINE__); |
|
2511 | + return false; |
|
2512 | + // bad payment |
|
2513 | + case EEM_Payment::status_id_failed: |
|
2514 | + if (! empty($msg)) { |
|
2515 | + EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__); |
|
2516 | + return false; |
|
2517 | + } |
|
2518 | + // default to error below |
|
2519 | + break; |
|
2520 | + } |
|
2521 | + } |
|
2522 | + // off-site payment gateway responses are too unreliable, so let's just assume that |
|
2523 | + // the payment processing is just running slower than the registrant's request |
|
2524 | + if ($payment_occurs === EE_PMT_Base::offsite) { |
|
2525 | + return true; |
|
2526 | + } |
|
2527 | + EE_Error::add_error( |
|
2528 | + sprintf( |
|
2529 | + esc_html__( |
|
2530 | + 'Your payment could not be processed successfully due to a technical issue.%sPlease try again or contact %s for assistance.', |
|
2531 | + 'event_espresso' |
|
2532 | + ), |
|
2533 | + '<br/>', |
|
2534 | + EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
2535 | + ), |
|
2536 | + __FILE__, |
|
2537 | + __FUNCTION__, |
|
2538 | + __LINE__ |
|
2539 | + ); |
|
2540 | + return false; |
|
2541 | + } |
|
2542 | + |
|
2543 | + |
|
2544 | + |
|
2545 | + |
|
2546 | + |
|
2547 | + |
|
2548 | + /********************************************************************************************************/ |
|
2549 | + /********************************** PROCESS GATEWAY RESPONSE **********************************/ |
|
2550 | + /********************************************************************************************************/ |
|
2551 | + /** |
|
2552 | + * process_gateway_response |
|
2553 | + * this is the return point for Off-Site Payment Methods |
|
2554 | + * It will attempt to "handle the IPN" if it appears that this has not already occurred, |
|
2555 | + * otherwise, it will load up the last payment made for the TXN. |
|
2556 | + * If the payment retrieved looks good, it will then either: |
|
2557 | + * complete the current step and allow advancement to the next reg step |
|
2558 | + * or present the payment options again |
|
2559 | + * |
|
2560 | + * @return bool |
|
2561 | + * @throws EE_Error |
|
2562 | + * @throws InvalidArgumentException |
|
2563 | + * @throws ReflectionException |
|
2564 | + * @throws InvalidDataTypeException |
|
2565 | + * @throws InvalidInterfaceException |
|
2566 | + */ |
|
2567 | + public function process_gateway_response() |
|
2568 | + { |
|
2569 | + // how have they chosen to pay? |
|
2570 | + $this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment(true); |
|
2571 | + // get EE_Payment_Method object |
|
2572 | + if (! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()) { |
|
2573 | + $this->checkout->continue_reg = false; |
|
2574 | + return false; |
|
2575 | + } |
|
2576 | + if (! $this->checkout->payment_method->is_off_site()) { |
|
2577 | + return false; |
|
2578 | + } |
|
2579 | + $this->_validate_offsite_return(); |
|
2580 | + // verify TXN |
|
2581 | + if ($this->checkout->transaction instanceof EE_Transaction) { |
|
2582 | + $gateway = $this->checkout->payment_method->type_obj()->get_gateway(); |
|
2583 | + if (! $gateway instanceof EE_Offsite_Gateway) { |
|
2584 | + $this->checkout->continue_reg = false; |
|
2585 | + return false; |
|
2586 | + } |
|
2587 | + $payment = $this->_process_off_site_payment($gateway); |
|
2588 | + $payment = $this->_process_cancelled_payments($payment); |
|
2589 | + $payment = $this->_validate_payment($payment); |
|
2590 | + // if payment was not declined by the payment gateway or cancelled by the registrant |
|
2591 | + if ($this->_process_payment_status($payment, EE_PMT_Base::offsite)) { |
|
2592 | + // $this->_setup_redirect_for_next_step(); |
|
2593 | + // store that for later |
|
2594 | + $this->checkout->payment = $payment; |
|
2595 | + // mark this reg step as completed, as long as gateway doesn't use a separate IPN request, |
|
2596 | + // because we will complete this step during the IPN processing then |
|
2597 | + if (! $this->handle_IPN_in_this_request()) { |
|
2598 | + $this->set_completed(); |
|
2599 | + } |
|
2600 | + return true; |
|
2601 | + } |
|
2602 | + } |
|
2603 | + // DEBUG LOG |
|
2604 | + // $this->checkout->log( |
|
2605 | + // __CLASS__, |
|
2606 | + // __FUNCTION__, |
|
2607 | + // __LINE__, |
|
2608 | + // array('payment' => $payment) |
|
2609 | + // ); |
|
2610 | + $this->checkout->continue_reg = false; |
|
2611 | + return false; |
|
2612 | + } |
|
2613 | + |
|
2614 | + |
|
2615 | + /** |
|
2616 | + * _validate_return |
|
2617 | + * |
|
2618 | + * @return void |
|
2619 | + * @throws EE_Error |
|
2620 | + * @throws InvalidArgumentException |
|
2621 | + * @throws InvalidDataTypeException |
|
2622 | + * @throws InvalidInterfaceException |
|
2623 | + * @throws ReflectionException |
|
2624 | + */ |
|
2625 | + private function _validate_offsite_return() |
|
2626 | + { |
|
2627 | + $TXN_ID = $this->request->getRequestParam('spco_txn', 0, 'int'); |
|
2628 | + if ($TXN_ID !== $this->checkout->transaction->ID()) { |
|
2629 | + // Houston... we might have a problem |
|
2630 | + $invalid_TXN = false; |
|
2631 | + // first gather some info |
|
2632 | + $valid_TXN = EEM_Transaction::instance()->get_one_by_ID($TXN_ID); |
|
2633 | + $primary_registrant = $valid_TXN instanceof EE_Transaction |
|
2634 | + ? $valid_TXN->primary_registration() |
|
2635 | + : null; |
|
2636 | + // let's start by retrieving the cart for this TXN |
|
2637 | + $cart = $this->checkout->get_cart_for_transaction($this->checkout->transaction); |
|
2638 | + if ($cart instanceof EE_Cart) { |
|
2639 | + // verify that the current cart has tickets |
|
2640 | + $tickets = $cart->get_tickets(); |
|
2641 | + if (empty($tickets)) { |
|
2642 | + $invalid_TXN = true; |
|
2643 | + } |
|
2644 | + } else { |
|
2645 | + $invalid_TXN = true; |
|
2646 | + } |
|
2647 | + $valid_TXN_SID = $primary_registrant instanceof EE_Registration |
|
2648 | + ? $primary_registrant->session_ID() |
|
2649 | + : null; |
|
2650 | + // validate current Session ID and compare against valid TXN session ID |
|
2651 | + if ( |
|
2652 | + $invalid_TXN // if this is already true, then skip other checks |
|
2653 | + || EE_Session::instance()->id() === null |
|
2654 | + || ( |
|
2655 | + // WARNING !!! |
|
2656 | + // this could be PayPal sending back duplicate requests (ya they do that) |
|
2657 | + // or it **could** mean someone is simply registering AGAIN after having just done so |
|
2658 | + // so now we need to determine if this current TXN looks valid or not |
|
2659 | + // and whether this reg step has even been started ? |
|
2660 | + EE_Session::instance()->id() === $valid_TXN_SID |
|
2661 | + // really? you're half way through this reg step, but you never started it ? |
|
2662 | + && $this->checkout->transaction->reg_step_completed($this->slug()) === false |
|
2663 | + ) |
|
2664 | + ) { |
|
2665 | + $invalid_TXN = true; |
|
2666 | + } |
|
2667 | + if ($invalid_TXN) { |
|
2668 | + // is the valid TXN completed ? |
|
2669 | + if ($valid_TXN instanceof EE_Transaction) { |
|
2670 | + // has this step even been started ? |
|
2671 | + $reg_step_completed = $valid_TXN->reg_step_completed($this->slug()); |
|
2672 | + if ($reg_step_completed !== false && $reg_step_completed !== true) { |
|
2673 | + // so it **looks** like this is a double request from PayPal |
|
2674 | + // so let's try to pick up where we left off |
|
2675 | + $this->checkout->transaction = $valid_TXN; |
|
2676 | + $this->checkout->refresh_all_entities(true); |
|
2677 | + return; |
|
2678 | + } |
|
2679 | + } |
|
2680 | + // you appear to be lost? |
|
2681 | + $this->_redirect_wayward_request($primary_registrant); |
|
2682 | + } |
|
2683 | + } |
|
2684 | + } |
|
2685 | + |
|
2686 | + |
|
2687 | + /** |
|
2688 | + * _redirect_wayward_request |
|
2689 | + * |
|
2690 | + * @param EE_Registration|null $primary_registrant |
|
2691 | + * @return void |
|
2692 | + * @throws EE_Error |
|
2693 | + * @throws InvalidArgumentException |
|
2694 | + * @throws InvalidDataTypeException |
|
2695 | + * @throws InvalidInterfaceException |
|
2696 | + * @throws ReflectionException |
|
2697 | + */ |
|
2698 | + private function _redirect_wayward_request(EE_Registration $primary_registrant) |
|
2699 | + { |
|
2700 | + if (! $primary_registrant instanceof EE_Registration) { |
|
2701 | + // try redirecting based on the current TXN |
|
2702 | + $primary_registrant = $this->checkout->transaction instanceof EE_Transaction |
|
2703 | + ? $this->checkout->transaction->primary_registration() |
|
2704 | + : null; |
|
2705 | + } |
|
2706 | + if (! $primary_registrant instanceof EE_Registration) { |
|
2707 | + EE_Error::add_error( |
|
2708 | + sprintf( |
|
2709 | + esc_html__( |
|
2710 | + 'Invalid information was received from the Off-Site Payment Processor and your Transaction details could not be retrieved from the database.%1$sPlease try again or contact %2$s for assistance.', |
|
2711 | + 'event_espresso' |
|
2712 | + ), |
|
2713 | + '<br/>', |
|
2714 | + EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
2715 | + ), |
|
2716 | + __FILE__, |
|
2717 | + __FUNCTION__, |
|
2718 | + __LINE__ |
|
2719 | + ); |
|
2720 | + return; |
|
2721 | + } |
|
2722 | + // make sure transaction is not locked |
|
2723 | + $this->checkout->transaction->unlock(); |
|
2724 | + wp_safe_redirect( |
|
2725 | + add_query_arg( |
|
2726 | + [ |
|
2727 | + 'e_reg_url_link' => $primary_registrant->reg_url_link(), |
|
2728 | + ], |
|
2729 | + $this->checkout->thank_you_page_url |
|
2730 | + ) |
|
2731 | + ); |
|
2732 | + exit(); |
|
2733 | + } |
|
2734 | + |
|
2735 | + |
|
2736 | + /** |
|
2737 | + * _process_off_site_payment |
|
2738 | + * |
|
2739 | + * @param EE_Offsite_Gateway $gateway |
|
2740 | + * @return EE_Payment |
|
2741 | + * @throws EE_Error |
|
2742 | + * @throws InvalidArgumentException |
|
2743 | + * @throws InvalidDataTypeException |
|
2744 | + * @throws InvalidInterfaceException |
|
2745 | + * @throws ReflectionException |
|
2746 | + */ |
|
2747 | + private function _process_off_site_payment(EE_Offsite_Gateway $gateway) |
|
2748 | + { |
|
2749 | + try { |
|
2750 | + $request = LoaderFactory::getLoader()->getShared(RequestInterface::class); |
|
2751 | + $request_data = $request->requestParams(); |
|
2752 | + // if gateway uses_separate_IPN_request, then we don't have to process the IPN manually |
|
2753 | + $this->set_handle_IPN_in_this_request( |
|
2754 | + $gateway->handle_IPN_in_this_request($request_data, false) |
|
2755 | + ); |
|
2756 | + if ($this->handle_IPN_in_this_request()) { |
|
2757 | + // get payment details and process results |
|
2758 | + /** @type EE_Payment_Processor $payment_processor */ |
|
2759 | + $payment_processor = EE_Registry::instance()->load_core('Payment_Processor'); |
|
2760 | + $payment = $payment_processor->process_ipn( |
|
2761 | + $request_data, |
|
2762 | + $this->checkout->transaction, |
|
2763 | + $this->checkout->payment_method, |
|
2764 | + true, |
|
2765 | + false |
|
2766 | + ); |
|
2767 | + // $payment_source = 'process_ipn'; |
|
2768 | + } else { |
|
2769 | + $payment = $this->checkout->transaction->last_payment(); |
|
2770 | + // $payment_source = 'last_payment'; |
|
2771 | + } |
|
2772 | + } catch (Exception $e) { |
|
2773 | + // let's just eat the exception and try to move on using any previously set payment info |
|
2774 | + $payment = $this->checkout->transaction->last_payment(); |
|
2775 | + // $payment_source = 'last_payment after Exception'; |
|
2776 | + // but if we STILL don't have a payment object |
|
2777 | + if (! $payment instanceof EE_Payment) { |
|
2778 | + // then we'll object ! ( not object like a thing... but object like what a lawyer says ! ) |
|
2779 | + $this->_handle_payment_processor_exception($e); |
|
2780 | + } |
|
2781 | + } |
|
2782 | + return $payment; |
|
2783 | + } |
|
2784 | + |
|
2785 | + |
|
2786 | + /** |
|
2787 | + * _process_cancelled_payments |
|
2788 | + * just makes sure that the payment status gets updated correctly |
|
2789 | + * so tha tan error isn't generated during payment validation |
|
2790 | + * |
|
2791 | + * @param EE_Payment $payment |
|
2792 | + * @return EE_Payment|null |
|
2793 | + * @throws EE_Error |
|
2794 | + */ |
|
2795 | + private function _process_cancelled_payments($payment = null) |
|
2796 | + { |
|
2797 | + if ( |
|
2798 | + $payment instanceof EE_Payment |
|
2799 | + && $this->request->requestParamIsSet('ee_cancel_payment') |
|
2800 | + && $payment->status() === EEM_Payment::status_id_failed |
|
2801 | + ) { |
|
2802 | + $payment->set_status(EEM_Payment::status_id_cancelled); |
|
2803 | + } |
|
2804 | + return $payment; |
|
2805 | + } |
|
2806 | + |
|
2807 | + |
|
2808 | + /** |
|
2809 | + * get_transaction_details_for_gateways |
|
2810 | + * |
|
2811 | + * @access public |
|
2812 | + * @return void |
|
2813 | + * @throws EE_Error |
|
2814 | + * @throws InvalidArgumentException |
|
2815 | + * @throws ReflectionException |
|
2816 | + * @throws InvalidDataTypeException |
|
2817 | + * @throws InvalidInterfaceException |
|
2818 | + */ |
|
2819 | + public function get_transaction_details_for_gateways() |
|
2820 | + { |
|
2821 | + $txn_details = []; |
|
2822 | + // ya gotta make a choice man |
|
2823 | + if (empty($this->checkout->selected_method_of_payment)) { |
|
2824 | + $txn_details = [ |
|
2825 | + 'error' => esc_html__('Please select a method of payment before proceeding.', 'event_espresso'), |
|
2826 | + ]; |
|
2827 | + } |
|
2828 | + // get EE_Payment_Method object |
|
2829 | + if ( |
|
2830 | + empty($txn_details) |
|
2831 | + && ! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment() |
|
2832 | + ) { |
|
2833 | + $txn_details = [ |
|
2834 | + 'selected_method_of_payment' => $this->checkout->selected_method_of_payment, |
|
2835 | + 'error' => esc_html__( |
|
2836 | + 'A valid Payment Method could not be determined.', |
|
2837 | + 'event_espresso' |
|
2838 | + ), |
|
2839 | + ]; |
|
2840 | + } |
|
2841 | + if (empty($txn_details) && $this->checkout->transaction instanceof EE_Transaction) { |
|
2842 | + $return_url = $this->_get_return_url($this->checkout->payment_method); |
|
2843 | + $txn_details = [ |
|
2844 | + 'TXN_ID' => $this->checkout->transaction->ID(), |
|
2845 | + 'TXN_timestamp' => $this->checkout->transaction->datetime(), |
|
2846 | + 'TXN_total' => $this->checkout->transaction->total(), |
|
2847 | + 'TXN_paid' => $this->checkout->transaction->paid(), |
|
2848 | + 'TXN_reg_steps' => $this->checkout->transaction->reg_steps(), |
|
2849 | + 'STS_ID' => $this->checkout->transaction->status_ID(), |
|
2850 | + 'PMD_ID' => $this->checkout->transaction->payment_method_ID(), |
|
2851 | + 'payment_amount' => $this->checkout->amount_owing, |
|
2852 | + 'return_url' => $return_url, |
|
2853 | + 'cancel_url' => add_query_arg(['ee_cancel_payment' => true], $return_url), |
|
2854 | + 'notify_url' => EE_Config::instance()->core->txn_page_url( |
|
2855 | + [ |
|
2856 | + 'e_reg_url_link' => $this->checkout->transaction->primary_registration()->reg_url_link(), |
|
2857 | + 'ee_payment_method' => $this->checkout->payment_method->slug(), |
|
2858 | + ] |
|
2859 | + ), |
|
2860 | + ]; |
|
2861 | + } |
|
2862 | + echo wp_json_encode($txn_details); |
|
2863 | + exit(); |
|
2864 | + } |
|
2865 | + |
|
2866 | + |
|
2867 | + /** |
|
2868 | + * __sleep |
|
2869 | + * to conserve db space, let's remove the reg_form and the EE_Checkout object from EE_SPCO_Reg_Step objects upon |
|
2870 | + * serialization EE_Checkout will handle the reimplementation of itself upon waking, but we won't bother with the |
|
2871 | + * reg form, because if needed, it will be regenerated anyways |
|
2872 | + * |
|
2873 | + * @return array |
|
2874 | + */ |
|
2875 | + public function __sleep() |
|
2876 | + { |
|
2877 | + // remove the reg form and the checkout |
|
2878 | + return array_diff(array_keys(get_object_vars($this)), ['reg_form', 'checkout', 'line_item_display']); |
|
2879 | + } |
|
2880 | 2880 | } |
@@ -94,16 +94,16 @@ |
||
94 | 94 | ? $this->_extra_data['template']['question_list'] |
95 | 95 | : $template; |
96 | 96 | $ans_result = ''; |
97 | - $answers = ! empty($this->_extra_data['data']->registrations[ $reg_obj->ID() ]['ans_objs']) |
|
98 | - ? $this->_extra_data['data']->registrations[ $reg_obj->ID() ]['ans_objs'] |
|
97 | + $answers = ! empty($this->_extra_data['data']->registrations[$reg_obj->ID()]['ans_objs']) |
|
98 | + ? $this->_extra_data['data']->registrations[$reg_obj->ID()]['ans_objs'] |
|
99 | 99 | : []; |
100 | 100 | $questions = ! empty($this->_extra_data['data']->questions) |
101 | 101 | ? $this->_extra_data['data']->questions |
102 | 102 | : []; |
103 | 103 | foreach ($answers as $answer) { |
104 | 104 | // first see if the question is in our $questions array. If not then try to get from answer object |
105 | - $question = isset($questions[ $answer->ID() ]) |
|
106 | - ? $questions[ $answer->ID() ] |
|
105 | + $question = isset($questions[$answer->ID()]) |
|
106 | + ? $questions[$answer->ID()] |
|
107 | 107 | : null; |
108 | 108 | $question = ! $question instanceof EE_Question |
109 | 109 | ? $answer->question() |
@@ -15,113 +15,113 @@ |
||
15 | 15 | */ |
16 | 16 | class EE_Question_List_Shortcodes extends EE_Shortcodes |
17 | 17 | { |
18 | - public function __construct() |
|
19 | - { |
|
20 | - parent::__construct(); |
|
21 | - } |
|
18 | + public function __construct() |
|
19 | + { |
|
20 | + parent::__construct(); |
|
21 | + } |
|
22 | 22 | |
23 | 23 | |
24 | - protected function _init_props() |
|
25 | - { |
|
26 | - $this->label = esc_html__('Questions and Answers Shortcodes', 'event_espresso'); |
|
27 | - $this->description = esc_html__('All shortcodes related to custom questions and answers', 'event_espresso'); |
|
28 | - $this->_shortcodes = [ |
|
29 | - '[QUESTION_LIST]' => esc_html__( |
|
30 | - 'This is used to indicate where you want the list of questions and answers to show for the registrant. You place this within the "[attendee_list]" field.', |
|
31 | - 'event_espresso' |
|
32 | - ), |
|
33 | - ]; |
|
34 | - } |
|
24 | + protected function _init_props() |
|
25 | + { |
|
26 | + $this->label = esc_html__('Questions and Answers Shortcodes', 'event_espresso'); |
|
27 | + $this->description = esc_html__('All shortcodes related to custom questions and answers', 'event_espresso'); |
|
28 | + $this->_shortcodes = [ |
|
29 | + '[QUESTION_LIST]' => esc_html__( |
|
30 | + 'This is used to indicate where you want the list of questions and answers to show for the registrant. You place this within the "[attendee_list]" field.', |
|
31 | + 'event_espresso' |
|
32 | + ), |
|
33 | + ]; |
|
34 | + } |
|
35 | 35 | |
36 | 36 | |
37 | - /** |
|
38 | - * @param string $shortcode |
|
39 | - * @return string |
|
40 | - * @throws EE_Error |
|
41 | - * @throws ReflectionException |
|
42 | - */ |
|
43 | - protected function _parser($shortcode) |
|
44 | - { |
|
45 | - switch ($shortcode) { |
|
46 | - case '[QUESTION_LIST]': |
|
47 | - return $this->_get_question_list(); |
|
48 | - } |
|
49 | - return ''; |
|
50 | - } |
|
37 | + /** |
|
38 | + * @param string $shortcode |
|
39 | + * @return string |
|
40 | + * @throws EE_Error |
|
41 | + * @throws ReflectionException |
|
42 | + */ |
|
43 | + protected function _parser($shortcode) |
|
44 | + { |
|
45 | + switch ($shortcode) { |
|
46 | + case '[QUESTION_LIST]': |
|
47 | + return $this->_get_question_list(); |
|
48 | + } |
|
49 | + return ''; |
|
50 | + } |
|
51 | 51 | |
52 | 52 | |
53 | - /** |
|
54 | - * @return string |
|
55 | - * @throws EE_Error |
|
56 | - * @throws ReflectionException |
|
57 | - */ |
|
58 | - protected function _get_question_list() |
|
59 | - { |
|
60 | - $this->_validate_list_requirements(); |
|
53 | + /** |
|
54 | + * @return string |
|
55 | + * @throws EE_Error |
|
56 | + * @throws ReflectionException |
|
57 | + */ |
|
58 | + protected function _get_question_list() |
|
59 | + { |
|
60 | + $this->_validate_list_requirements(); |
|
61 | 61 | |
62 | - // for when [QUESTION_LIST] is used in the [attendee_list] field. |
|
63 | - if ($this->_data['data'] instanceof EE_Registration) { |
|
64 | - return $this->_get_question_answer_list_for_attendee(); |
|
65 | - } |
|
62 | + // for when [QUESTION_LIST] is used in the [attendee_list] field. |
|
63 | + if ($this->_data['data'] instanceof EE_Registration) { |
|
64 | + return $this->_get_question_answer_list_for_attendee(); |
|
65 | + } |
|
66 | 66 | |
67 | - // for when [QUESTION_LIST] is used in the main content field. |
|
68 | - if ( |
|
69 | - $this->_data['data'] instanceof EE_Messages_Addressee |
|
70 | - && $this->_data['data']->reg_obj instanceof EE_Registration |
|
71 | - ) { |
|
72 | - return $this->_get_question_answer_list_for_attendee($this->_data['data']->reg_obj); |
|
73 | - } |
|
74 | - return ''; |
|
75 | - } |
|
67 | + // for when [QUESTION_LIST] is used in the main content field. |
|
68 | + if ( |
|
69 | + $this->_data['data'] instanceof EE_Messages_Addressee |
|
70 | + && $this->_data['data']->reg_obj instanceof EE_Registration |
|
71 | + ) { |
|
72 | + return $this->_get_question_answer_list_for_attendee($this->_data['data']->reg_obj); |
|
73 | + } |
|
74 | + return ''; |
|
75 | + } |
|
76 | 76 | |
77 | 77 | |
78 | - /** |
|
79 | - * Note when we parse the "[question_list]" shortcode for attendees we're actually going to retrieve the list of |
|
80 | - * answers for that attendee since that is what we really need (we can derive the questions from the answers); |
|
81 | - * |
|
82 | - * @param null $reg_obj |
|
83 | - * @return string parsed template. |
|
84 | - * @throws EE_Error |
|
85 | - * @throws ReflectionException |
|
86 | - */ |
|
87 | - private function _get_question_answer_list_for_attendee($reg_obj = null) |
|
88 | - { |
|
89 | - $valid_shortcodes = ['question']; |
|
90 | - $reg_obj = $reg_obj instanceof EE_Registration |
|
91 | - ? $reg_obj |
|
92 | - : $this->_data['data']; |
|
93 | - $template = is_array($this->_data['template']) && isset($this->_data['template']['question_list']) |
|
94 | - ? $this->_data['template']['question_list'] |
|
95 | - : ''; |
|
96 | - $template = empty($template) && isset($this->_extra_data['template']['question_list']) |
|
97 | - ? $this->_extra_data['template']['question_list'] |
|
98 | - : $template; |
|
99 | - $ans_result = ''; |
|
100 | - $answers = ! empty($this->_extra_data['data']->registrations[ $reg_obj->ID() ]['ans_objs']) |
|
101 | - ? $this->_extra_data['data']->registrations[ $reg_obj->ID() ]['ans_objs'] |
|
102 | - : []; |
|
103 | - $questions = ! empty($this->_extra_data['data']->questions) |
|
104 | - ? $this->_extra_data['data']->questions |
|
105 | - : []; |
|
106 | - foreach ($answers as $answer) { |
|
107 | - // first see if the question is in our $questions array. If not then try to get from answer object |
|
108 | - $question = isset($questions[ $answer->ID() ]) |
|
109 | - ? $questions[ $answer->ID() ] |
|
110 | - : null; |
|
111 | - $question = ! $question instanceof EE_Question |
|
112 | - ? $answer->question() |
|
113 | - : $question; |
|
114 | - if ($question instanceof EE_Question and $question->admin_only()) { |
|
115 | - continue; |
|
116 | - } |
|
117 | - $ans_result .= $this->_shortcode_helper->parse_question_list_template( |
|
118 | - $template, |
|
119 | - $answer, |
|
120 | - $valid_shortcodes, |
|
121 | - $this->_extra_data |
|
122 | - ); |
|
123 | - } |
|
78 | + /** |
|
79 | + * Note when we parse the "[question_list]" shortcode for attendees we're actually going to retrieve the list of |
|
80 | + * answers for that attendee since that is what we really need (we can derive the questions from the answers); |
|
81 | + * |
|
82 | + * @param null $reg_obj |
|
83 | + * @return string parsed template. |
|
84 | + * @throws EE_Error |
|
85 | + * @throws ReflectionException |
|
86 | + */ |
|
87 | + private function _get_question_answer_list_for_attendee($reg_obj = null) |
|
88 | + { |
|
89 | + $valid_shortcodes = ['question']; |
|
90 | + $reg_obj = $reg_obj instanceof EE_Registration |
|
91 | + ? $reg_obj |
|
92 | + : $this->_data['data']; |
|
93 | + $template = is_array($this->_data['template']) && isset($this->_data['template']['question_list']) |
|
94 | + ? $this->_data['template']['question_list'] |
|
95 | + : ''; |
|
96 | + $template = empty($template) && isset($this->_extra_data['template']['question_list']) |
|
97 | + ? $this->_extra_data['template']['question_list'] |
|
98 | + : $template; |
|
99 | + $ans_result = ''; |
|
100 | + $answers = ! empty($this->_extra_data['data']->registrations[ $reg_obj->ID() ]['ans_objs']) |
|
101 | + ? $this->_extra_data['data']->registrations[ $reg_obj->ID() ]['ans_objs'] |
|
102 | + : []; |
|
103 | + $questions = ! empty($this->_extra_data['data']->questions) |
|
104 | + ? $this->_extra_data['data']->questions |
|
105 | + : []; |
|
106 | + foreach ($answers as $answer) { |
|
107 | + // first see if the question is in our $questions array. If not then try to get from answer object |
|
108 | + $question = isset($questions[ $answer->ID() ]) |
|
109 | + ? $questions[ $answer->ID() ] |
|
110 | + : null; |
|
111 | + $question = ! $question instanceof EE_Question |
|
112 | + ? $answer->question() |
|
113 | + : $question; |
|
114 | + if ($question instanceof EE_Question and $question->admin_only()) { |
|
115 | + continue; |
|
116 | + } |
|
117 | + $ans_result .= $this->_shortcode_helper->parse_question_list_template( |
|
118 | + $template, |
|
119 | + $answer, |
|
120 | + $valid_shortcodes, |
|
121 | + $this->_extra_data |
|
122 | + ); |
|
123 | + } |
|
124 | 124 | |
125 | - return $ans_result; |
|
126 | - } |
|
125 | + return $ans_result; |
|
126 | + } |
|
127 | 127 | } |
@@ -69,7 +69,7 @@ discard block |
||
69 | 69 | ) { |
70 | 70 | $new_value_maybe_array = []; |
71 | 71 | foreach ($original_value_maybe_array as $array_key => $array_item) { |
72 | - $new_value_maybe_array[ $array_key ] = ModelDataTranslator::prepareFieldValueFromJson( |
|
72 | + $new_value_maybe_array[$array_key] = ModelDataTranslator::prepareFieldValueFromJson( |
|
73 | 73 | $field_obj, |
74 | 74 | $array_item, |
75 | 75 | $requested_version, |
@@ -103,7 +103,7 @@ discard block |
||
103 | 103 | if (is_array($original_value_maybe_array)) { |
104 | 104 | $new_value = []; |
105 | 105 | foreach ($original_value_maybe_array as $key => $value) { |
106 | - $new_value[ $key ] = ModelDataTranslator::prepareFieldValuesForJson( |
|
106 | + $new_value[$key] = ModelDataTranslator::prepareFieldValuesForJson( |
|
107 | 107 | $field_obj, |
108 | 108 | $value, |
109 | 109 | $request_version |
@@ -244,7 +244,7 @@ discard block |
||
244 | 244 | '0', |
245 | 245 | STR_PAD_LEFT |
246 | 246 | ); |
247 | - return $original_timestamp . $offset_sign . $offset_string; |
|
247 | + return $original_timestamp.$offset_sign.$offset_string; |
|
248 | 248 | } |
249 | 249 | |
250 | 250 | |
@@ -323,7 +323,7 @@ discard block |
||
323 | 323 | // first, check if its a MySQL timestamp in GMT |
324 | 324 | $datetime_obj = DateTime::createFromFormat('Y-m-d H:i:s', $original_value); |
325 | 325 | } |
326 | - if (! $datetime_obj instanceof DateTime) { |
|
326 | + if ( ! $datetime_obj instanceof DateTime) { |
|
327 | 327 | // so it's not a unix timestamp or a MySQL timestamp. Maybe its in the field's date/time format? |
328 | 328 | $datetime_obj = $field_obj->prepare_for_set($original_value); |
329 | 329 | } |
@@ -349,7 +349,7 @@ discard block |
||
349 | 349 | $original_value, |
350 | 350 | $field_obj->get_name(), |
351 | 351 | $field_obj->get_model_name(), |
352 | - $field_obj->get_time_format() . ' ' . $field_obj->get_time_format() |
|
352 | + $field_obj->get_time_format().' '.$field_obj->get_time_format() |
|
353 | 353 | ) |
354 | 354 | ); |
355 | 355 | } |
@@ -363,7 +363,7 @@ discard block |
||
363 | 363 | } |
364 | 364 | // are we about to send an object? just don't. We have no good way to represent it in JSON. |
365 | 365 | // can't just check using is_object() because that missed PHP incomplete objects |
366 | - if (! ModelDataTranslator::isRepresentableInJson($new_value)) { |
|
366 | + if ( ! ModelDataTranslator::isRepresentableInJson($new_value)) { |
|
367 | 367 | $new_value = [ |
368 | 368 | 'error_code' => 'php_object_not_return', |
369 | 369 | 'error_message' => esc_html__( |
@@ -414,7 +414,7 @@ discard block |
||
414 | 414 | if ($query_param_meta->getField() instanceof EE_Model_Field_Base) { |
415 | 415 | $translated_value = $query_param_meta->determineConditionsQueryParameterValue(); |
416 | 416 | if ( |
417 | - (isset($query_param_for_models[ $query_param_meta->getQueryParamKey() ]) |
|
417 | + (isset($query_param_for_models[$query_param_meta->getQueryParamKey()]) |
|
418 | 418 | && $query_param_meta->isGmtField()) |
419 | 419 | || $translated_value === null |
420 | 420 | ) { |
@@ -423,11 +423,11 @@ discard block |
||
423 | 423 | // OR we couldn't create a translated value from their input |
424 | 424 | continue; |
425 | 425 | } |
426 | - $query_param_for_models[ $query_param_meta->getQueryParamKey() ] = $translated_value; |
|
426 | + $query_param_for_models[$query_param_meta->getQueryParamKey()] = $translated_value; |
|
427 | 427 | } else { |
428 | 428 | $nested_query_params = $query_param_meta->determineNestedConditionQueryParameters(); |
429 | 429 | if ($nested_query_params) { |
430 | - $query_param_for_models[ $query_param_meta->getQueryParamKey() ] = $nested_query_params; |
|
430 | + $query_param_for_models[$query_param_meta->getQueryParamKey()] = $nested_query_params; |
|
431 | 431 | } |
432 | 432 | } |
433 | 433 | } |
@@ -457,7 +457,7 @@ discard block |
||
457 | 457 | */ |
458 | 458 | public static function removeGmtFromFieldName($field_name) |
459 | 459 | { |
460 | - if (! ModelDataTranslator::isGmtDateFieldName($field_name)) { |
|
460 | + if ( ! ModelDataTranslator::isGmtDateFieldName($field_name)) { |
|
461 | 461 | return $field_name; |
462 | 462 | } |
463 | 463 | $query_param_sans_stars = ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey( |
@@ -500,7 +500,7 @@ discard block |
||
500 | 500 | { |
501 | 501 | $new_array = []; |
502 | 502 | foreach ($field_names as $key => $field_name) { |
503 | - $new_array[ $key ] = ModelDataTranslator::prepareFieldNameFromJson($field_name); |
|
503 | + $new_array[$key] = ModelDataTranslator::prepareFieldNameFromJson($field_name); |
|
504 | 504 | } |
505 | 505 | return $new_array; |
506 | 506 | } |
@@ -517,7 +517,7 @@ discard block |
||
517 | 517 | { |
518 | 518 | $new_array = []; |
519 | 519 | foreach ($field_names_as_keys as $field_name => $value) { |
520 | - $new_array[ ModelDataTranslator::prepareFieldNameFromJson($field_name) ] = $value; |
|
520 | + $new_array[ModelDataTranslator::prepareFieldNameFromJson($field_name)] = $value; |
|
521 | 521 | } |
522 | 522 | return $new_array; |
523 | 523 | } |
@@ -613,10 +613,10 @@ discard block |
||
613 | 613 | $requested_version |
614 | 614 | ); |
615 | 615 | } |
616 | - $query_param_for_models[ $query_param_key ] = $translated_value; |
|
616 | + $query_param_for_models[$query_param_key] = $translated_value; |
|
617 | 617 | } else { |
618 | 618 | // so it's not for a field, assume it's a logic query param key |
619 | - $query_param_for_models[ $query_param_key ] = |
|
619 | + $query_param_for_models[$query_param_key] = |
|
620 | 620 | ModelDataTranslator::prepareConditionsQueryParamsForRestApi( |
621 | 621 | $query_param_value, |
622 | 622 | $model, |
@@ -668,11 +668,11 @@ discard block |
||
668 | 668 | ); |
669 | 669 | } |
670 | 670 | $number_of_parts = count($query_param_parts); |
671 | - $last_query_param_part = $query_param_parts[ count($query_param_parts) - 1 ]; |
|
671 | + $last_query_param_part = $query_param_parts[count($query_param_parts) - 1]; |
|
672 | 672 | $field_name = $last_query_param_part; |
673 | 673 | if ($number_of_parts !== 1) { |
674 | 674 | // the last part is the column name, and there are only 2parts. therefore... |
675 | - $model = EE_Registry::instance()->load_model($query_param_parts[ $number_of_parts - 2 ]); |
|
675 | + $model = EE_Registry::instance()->load_model($query_param_parts[$number_of_parts - 2]); |
|
676 | 676 | } |
677 | 677 | try { |
678 | 678 | return $model->field_settings_for($field_name, false); |
@@ -38,658 +38,658 @@ |
||
38 | 38 | */ |
39 | 39 | class ModelDataTranslator |
40 | 40 | { |
41 | - /** |
|
42 | - * We used to use -1 for infinity in the rest api, but that's ambiguous for |
|
43 | - * fields that COULD contain -1; so we use null |
|
44 | - */ |
|
45 | - const EE_INF_IN_REST = null; |
|
46 | - |
|
47 | - |
|
48 | - /** |
|
49 | - * Prepares a possible array of input values from JSON for use by the models |
|
50 | - * |
|
51 | - * @param EE_Model_Field_Base $field_obj |
|
52 | - * @param mixed $original_value_maybe_array |
|
53 | - * @param string $requested_version |
|
54 | - * @param string $timezone_string treat values as being in this timezone |
|
55 | - * @return mixed |
|
56 | - * @throws RestException |
|
57 | - * @throws EE_Error |
|
58 | - */ |
|
59 | - public static function prepareFieldValuesFromJson( |
|
60 | - $field_obj, |
|
61 | - $original_value_maybe_array, |
|
62 | - $requested_version, |
|
63 | - $timezone_string = 'UTC' |
|
64 | - ) { |
|
65 | - if ( |
|
66 | - is_array($original_value_maybe_array) |
|
67 | - && ! $field_obj instanceof EE_Serialized_Text_Field |
|
68 | - ) { |
|
69 | - $new_value_maybe_array = []; |
|
70 | - foreach ($original_value_maybe_array as $array_key => $array_item) { |
|
71 | - $new_value_maybe_array[ $array_key ] = ModelDataTranslator::prepareFieldValueFromJson( |
|
72 | - $field_obj, |
|
73 | - $array_item, |
|
74 | - $requested_version, |
|
75 | - $timezone_string |
|
76 | - ); |
|
77 | - } |
|
78 | - } else { |
|
79 | - $new_value_maybe_array = ModelDataTranslator::prepareFieldValueFromJson( |
|
80 | - $field_obj, |
|
81 | - $original_value_maybe_array, |
|
82 | - $requested_version, |
|
83 | - $timezone_string |
|
84 | - ); |
|
85 | - } |
|
86 | - return $new_value_maybe_array; |
|
87 | - } |
|
88 | - |
|
89 | - |
|
90 | - /** |
|
91 | - * Prepares an array of field values FOR use in JSON/REST API |
|
92 | - * |
|
93 | - * @param EE_Model_Field_Base $field_obj |
|
94 | - * @param mixed $original_value_maybe_array |
|
95 | - * @param string $request_version (eg 4.8.36) |
|
96 | - * @return array|int|string |
|
97 | - * @throws EE_Error |
|
98 | - * @throws EE_Error |
|
99 | - */ |
|
100 | - public static function prepareFieldValuesForJson($field_obj, $original_value_maybe_array, $request_version) |
|
101 | - { |
|
102 | - if (is_array($original_value_maybe_array)) { |
|
103 | - $new_value = []; |
|
104 | - foreach ($original_value_maybe_array as $key => $value) { |
|
105 | - $new_value[ $key ] = ModelDataTranslator::prepareFieldValuesForJson( |
|
106 | - $field_obj, |
|
107 | - $value, |
|
108 | - $request_version |
|
109 | - ); |
|
110 | - } |
|
111 | - } else { |
|
112 | - $new_value = ModelDataTranslator::prepareFieldValueForJson( |
|
113 | - $field_obj, |
|
114 | - $original_value_maybe_array, |
|
115 | - $request_version |
|
116 | - ); |
|
117 | - } |
|
118 | - return $new_value; |
|
119 | - } |
|
120 | - |
|
121 | - |
|
122 | - /** |
|
123 | - * Prepares incoming data from the json or request parameters for the models' |
|
124 | - * "$query_params". |
|
125 | - * |
|
126 | - * @param EE_Model_Field_Base $field_obj |
|
127 | - * @param mixed $original_value |
|
128 | - * @param string $requested_version |
|
129 | - * @param string $timezone_string treat values as being in this timezone |
|
130 | - * @return mixed |
|
131 | - * @throws RestException |
|
132 | - * @throws DomainException |
|
133 | - * @throws EE_Error |
|
134 | - */ |
|
135 | - public static function prepareFieldValueFromJson( |
|
136 | - $field_obj, |
|
137 | - $original_value, |
|
138 | - $requested_version, |
|
139 | - $timezone_string = 'UTC' |
|
140 | - ) { |
|
141 | - // check if they accidentally submitted an error value. If so throw an exception |
|
142 | - if ( |
|
143 | - is_array($original_value) |
|
144 | - && isset($original_value['error_code'], $original_value['error_message']) |
|
145 | - ) { |
|
146 | - throw new RestException( |
|
147 | - 'rest_submitted_error_value', |
|
148 | - sprintf( |
|
149 | - esc_html__( |
|
150 | - 'You tried to submit a JSON error object as a value for %1$s. That\'s not allowed.', |
|
151 | - 'event_espresso' |
|
152 | - ), |
|
153 | - $field_obj->get_name() |
|
154 | - ), |
|
155 | - [ |
|
156 | - 'status' => 400, |
|
157 | - ] |
|
158 | - ); |
|
159 | - } |
|
160 | - // double-check for serialized PHP. We never accept serialized PHP. No way Jose. |
|
161 | - ModelDataTranslator::throwExceptionIfContainsSerializedData($original_value); |
|
162 | - $timezone_string = |
|
163 | - $timezone_string !== '' |
|
164 | - ? $timezone_string |
|
165 | - : get_option('timezone_string', ''); |
|
166 | - // walk through the submitted data and double-check for serialized PHP. We never accept serialized PHP. No |
|
167 | - // way Jose. |
|
168 | - ModelDataTranslator::throwExceptionIfContainsSerializedData($original_value); |
|
169 | - if ( |
|
170 | - $field_obj instanceof EE_Infinite_Integer_Field |
|
171 | - && in_array($original_value, [null, ''], true) |
|
172 | - ) { |
|
173 | - $new_value = EE_INF; |
|
174 | - } elseif ($field_obj instanceof EE_Datetime_Field) { |
|
175 | - $new_value = rest_parse_date( |
|
176 | - self::getTimestampWithTimezoneOffset($original_value, $field_obj, $timezone_string) |
|
177 | - ); |
|
178 | - if ($new_value === false) { |
|
179 | - throw new RestException( |
|
180 | - 'invalid_format_for_timestamp', |
|
181 | - sprintf( |
|
182 | - esc_html__( |
|
183 | - 'Timestamps received on a request as the value for Date and Time fields must be in %1$s/%2$s format. The timestamp provided (%3$s) is not that format.', |
|
184 | - 'event_espresso' |
|
185 | - ), |
|
186 | - 'RFC3339', |
|
187 | - 'ISO8601', |
|
188 | - $original_value |
|
189 | - ), |
|
190 | - [ |
|
191 | - 'status' => 400, |
|
192 | - ] |
|
193 | - ); |
|
194 | - } |
|
195 | - } elseif ($field_obj instanceof EE_Boolean_Field) { |
|
196 | - // Interpreted the strings "false", "true", "on", "off" appropriately. |
|
197 | - $new_value = filter_var($original_value, FILTER_VALIDATE_BOOLEAN); |
|
198 | - } else { |
|
199 | - $new_value = $original_value; |
|
200 | - } |
|
201 | - return $new_value; |
|
202 | - } |
|
203 | - |
|
204 | - |
|
205 | - /** |
|
206 | - * This checks if the incoming timestamp has timezone information already on it and if it doesn't then adds timezone |
|
207 | - * information via details obtained from the host site. |
|
208 | - * |
|
209 | - * @param string $original_timestamp |
|
210 | - * @param EE_Datetime_Field $datetime_field |
|
211 | - * @param $timezone_string |
|
212 | - * @return string |
|
213 | - * @throws DomainException |
|
214 | - */ |
|
215 | - private static function getTimestampWithTimezoneOffset( |
|
216 | - $original_timestamp, |
|
217 | - EE_Datetime_Field $datetime_field, |
|
218 | - $timezone_string |
|
219 | - ) { |
|
220 | - // already have timezone information? |
|
221 | - if (preg_match('/Z|([+-])(\d{2}:\d{2})/', $original_timestamp)) { |
|
222 | - // yes, we're ignoring the timezone. |
|
223 | - return $original_timestamp; |
|
224 | - } |
|
225 | - // need to append timezone |
|
226 | - list($offset_sign, $offset_secs) = self::parseTimezoneOffset( |
|
227 | - $datetime_field->get_timezone_offset( |
|
228 | - new DateTimeZone($timezone_string), |
|
229 | - $original_timestamp |
|
230 | - ) |
|
231 | - ); |
|
232 | - $offset_string = |
|
233 | - str_pad( |
|
234 | - floor($offset_secs / HOUR_IN_SECONDS), |
|
235 | - 2, |
|
236 | - '0', |
|
237 | - STR_PAD_LEFT |
|
238 | - ) |
|
239 | - . ':' |
|
240 | - . str_pad( |
|
241 | - ($offset_secs % HOUR_IN_SECONDS) / MINUTE_IN_SECONDS, |
|
242 | - 2, |
|
243 | - '0', |
|
244 | - STR_PAD_LEFT |
|
245 | - ); |
|
246 | - return $original_timestamp . $offset_sign . $offset_string; |
|
247 | - } |
|
248 | - |
|
249 | - |
|
250 | - /** |
|
251 | - * Throws an exception if $data is a serialized PHP string (or somehow an actually PHP object, although I don't |
|
252 | - * think that can happen). If $data is an array, recurses into its keys and values |
|
253 | - * |
|
254 | - * @param mixed $data |
|
255 | - * @return void |
|
256 | - * @throws RestException |
|
257 | - */ |
|
258 | - public static function throwExceptionIfContainsSerializedData($data) |
|
259 | - { |
|
260 | - if (is_array($data)) { |
|
261 | - foreach ($data as $key => $value) { |
|
262 | - ModelDataTranslator::throwExceptionIfContainsSerializedData($key); |
|
263 | - ModelDataTranslator::throwExceptionIfContainsSerializedData($value); |
|
264 | - } |
|
265 | - } else { |
|
266 | - if (is_serialized($data) || is_object($data)) { |
|
267 | - throw new RestException( |
|
268 | - 'serialized_data_submission_prohibited', |
|
269 | - esc_html__( |
|
270 | - // @codingStandardsIgnoreStart |
|
271 | - 'You tried to submit a string of serialized text. Serialized PHP is prohibited over the EE4 REST API.', |
|
272 | - // @codingStandardsIgnoreEnd |
|
273 | - 'event_espresso' |
|
274 | - ) |
|
275 | - ); |
|
276 | - } |
|
277 | - } |
|
278 | - } |
|
279 | - |
|
280 | - |
|
281 | - /** |
|
282 | - * determines what's going on with them timezone strings |
|
283 | - * |
|
284 | - * @param int $timezone_offset |
|
285 | - * @return array |
|
286 | - */ |
|
287 | - private static function parseTimezoneOffset($timezone_offset) |
|
288 | - { |
|
289 | - $first_char = substr((string) $timezone_offset, 0, 1); |
|
290 | - if ($first_char === '+' || $first_char === '-') { |
|
291 | - $offset_sign = $first_char; |
|
292 | - $offset_secs = substr((string) $timezone_offset, 1); |
|
293 | - } else { |
|
294 | - $offset_sign = '+'; |
|
295 | - $offset_secs = $timezone_offset; |
|
296 | - } |
|
297 | - return [$offset_sign, $offset_secs]; |
|
298 | - } |
|
299 | - |
|
300 | - |
|
301 | - /** |
|
302 | - * Prepares a field's value for display in the API |
|
303 | - * |
|
304 | - * @param EE_Model_Field_Base $field_obj |
|
305 | - * @param mixed $original_value |
|
306 | - * @param string $requested_version |
|
307 | - * @return mixed |
|
308 | - * @throws EE_Error |
|
309 | - * @throws EE_Error |
|
310 | - */ |
|
311 | - public static function prepareFieldValueForJson($field_obj, $original_value, $requested_version) |
|
312 | - { |
|
313 | - if ($original_value === EE_INF) { |
|
314 | - $new_value = ModelDataTranslator::EE_INF_IN_REST; |
|
315 | - } elseif ($field_obj instanceof EE_Datetime_Field) { |
|
316 | - if (is_string($original_value)) { |
|
317 | - // did they submit a string of a unix timestamp? |
|
318 | - if (is_numeric($original_value)) { |
|
319 | - $datetime_obj = new DateTime(); |
|
320 | - $datetime_obj->setTimestamp((int) $original_value); |
|
321 | - } else { |
|
322 | - // first, check if its a MySQL timestamp in GMT |
|
323 | - $datetime_obj = DateTime::createFromFormat('Y-m-d H:i:s', $original_value); |
|
324 | - } |
|
325 | - if (! $datetime_obj instanceof DateTime) { |
|
326 | - // so it's not a unix timestamp or a MySQL timestamp. Maybe its in the field's date/time format? |
|
327 | - $datetime_obj = $field_obj->prepare_for_set($original_value); |
|
328 | - } |
|
329 | - $original_value = $datetime_obj; |
|
330 | - } |
|
331 | - if ($original_value instanceof DateTime) { |
|
332 | - $new_value = $original_value->format('Y-m-d H:i:s'); |
|
333 | - } elseif (is_int($original_value) || is_float($original_value)) { |
|
334 | - $new_value = date('Y-m-d H:i:s', $original_value); |
|
335 | - } elseif ($original_value === null || $original_value === '') { |
|
336 | - $new_value = null; |
|
337 | - } else { |
|
338 | - // so it's not a datetime object, unix timestamp (as string or int), |
|
339 | - // MySQL timestamp, or even a string in the field object's format. So no idea what it is |
|
340 | - throw new EE_Error( |
|
341 | - sprintf( |
|
342 | - esc_html__( |
|
343 | - // @codingStandardsIgnoreStart |
|
344 | - 'The value "%1$s" for the field "%2$s" on model "%3$s" could not be understood. It should be a PHP DateTime, unix timestamp, MySQL date, or string in the format "%4$s".', |
|
345 | - // @codingStandardsIgnoreEnd |
|
346 | - 'event_espresso' |
|
347 | - ), |
|
348 | - $original_value, |
|
349 | - $field_obj->get_name(), |
|
350 | - $field_obj->get_model_name(), |
|
351 | - $field_obj->get_time_format() . ' ' . $field_obj->get_time_format() |
|
352 | - ) |
|
353 | - ); |
|
354 | - } |
|
355 | - if ($new_value !== null) { |
|
356 | - $new_value = mysql2date('Y-m-d\TH:i:s', $new_value, false); |
|
357 | - } |
|
358 | - } else { |
|
359 | - $new_value = $original_value; |
|
360 | - } |
|
361 | - // are we about to send an object? just don't. We have no good way to represent it in JSON. |
|
362 | - // can't just check using is_object() because that missed PHP incomplete objects |
|
363 | - if (! ModelDataTranslator::isRepresentableInJson($new_value)) { |
|
364 | - $new_value = [ |
|
365 | - 'error_code' => 'php_object_not_return', |
|
366 | - 'error_message' => esc_html__( |
|
367 | - 'The value of this field in the database is a PHP object, which can\'t be represented in JSON.', |
|
368 | - 'event_espresso' |
|
369 | - ), |
|
370 | - ]; |
|
371 | - } |
|
372 | - return apply_filters( |
|
373 | - 'FHEE__EventEspresso\core\libraries\rest_api\Model_Data_Translator__prepare_field_for_rest_api', |
|
374 | - $new_value, |
|
375 | - $field_obj, |
|
376 | - $original_value, |
|
377 | - $requested_version |
|
378 | - ); |
|
379 | - } |
|
380 | - |
|
381 | - |
|
382 | - /** |
|
383 | - * Prepares condition-query-parameters (like what's in where and having) from |
|
384 | - * the format expected in the API to use in the models |
|
385 | - * |
|
386 | - * @param array $inputted_query_params_of_this_type |
|
387 | - * @param EEM_Base $model |
|
388 | - * @param string $requested_version |
|
389 | - * @param boolean $writing whether this data will be written to the DB, or if we're just building a query. |
|
390 | - * If we're writing to the DB, we don't expect any operators, or any logic query |
|
391 | - * parameters, and we also won't accept serialized data unless the current user has |
|
392 | - * unfiltered_html. |
|
393 | - * @return array |
|
394 | - * @throws DomainException |
|
395 | - * @throws EE_Error |
|
396 | - * @throws RestException |
|
397 | - * @throws InvalidDataTypeException |
|
398 | - * @throws InvalidInterfaceException |
|
399 | - * @throws InvalidArgumentException |
|
400 | - */ |
|
401 | - public static function prepareConditionsQueryParamsForModels( |
|
402 | - $inputted_query_params_of_this_type, |
|
403 | - EEM_Base $model, |
|
404 | - $requested_version, |
|
405 | - $writing = false |
|
406 | - ) { |
|
407 | - $query_param_for_models = []; |
|
408 | - $context = new RestIncomingQueryParamContext($model, $requested_version, $writing); |
|
409 | - foreach ($inputted_query_params_of_this_type as $query_param_key => $query_param_value) { |
|
410 | - $query_param_meta = new RestIncomingQueryParamMetadata($query_param_key, $query_param_value, $context); |
|
411 | - if ($query_param_meta->getField() instanceof EE_Model_Field_Base) { |
|
412 | - $translated_value = $query_param_meta->determineConditionsQueryParameterValue(); |
|
413 | - if ( |
|
414 | - (isset($query_param_for_models[ $query_param_meta->getQueryParamKey() ]) |
|
415 | - && $query_param_meta->isGmtField()) |
|
416 | - || $translated_value === null |
|
417 | - ) { |
|
418 | - // they have already provided a non-gmt field, ignore the gmt one. That's what WP core |
|
419 | - // currently does (they might change it though). See https://core.trac.wordpress.org/ticket/39954 |
|
420 | - // OR we couldn't create a translated value from their input |
|
421 | - continue; |
|
422 | - } |
|
423 | - $query_param_for_models[ $query_param_meta->getQueryParamKey() ] = $translated_value; |
|
424 | - } else { |
|
425 | - $nested_query_params = $query_param_meta->determineNestedConditionQueryParameters(); |
|
426 | - if ($nested_query_params) { |
|
427 | - $query_param_for_models[ $query_param_meta->getQueryParamKey() ] = $nested_query_params; |
|
428 | - } |
|
429 | - } |
|
430 | - } |
|
431 | - return $query_param_for_models; |
|
432 | - } |
|
433 | - |
|
434 | - |
|
435 | - /** |
|
436 | - * Mostly checks if the last 4 characters are "_gmt", indicating its a |
|
437 | - * gmt date field name |
|
438 | - * |
|
439 | - * @param string $field_name |
|
440 | - * @return boolean |
|
441 | - */ |
|
442 | - public static function isGmtDateFieldName($field_name) |
|
443 | - { |
|
444 | - $field_name = ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey($field_name); |
|
445 | - return substr($field_name, -4, 4) === '_gmt'; |
|
446 | - } |
|
447 | - |
|
448 | - |
|
449 | - /** |
|
450 | - * Removes the last "_gmt" part of a field name (and if there is no "_gmt" at the end, leave it alone) |
|
451 | - * |
|
452 | - * @param string $field_name |
|
453 | - * @return string |
|
454 | - */ |
|
455 | - public static function removeGmtFromFieldName($field_name) |
|
456 | - { |
|
457 | - if (! ModelDataTranslator::isGmtDateFieldName($field_name)) { |
|
458 | - return $field_name; |
|
459 | - } |
|
460 | - $query_param_sans_stars = ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey( |
|
461 | - $field_name |
|
462 | - ); |
|
463 | - $query_param_sans_gmt_and_sans_stars = substr( |
|
464 | - $query_param_sans_stars, |
|
465 | - 0, |
|
466 | - strrpos( |
|
467 | - $field_name, |
|
468 | - '_gmt' |
|
469 | - ) |
|
470 | - ); |
|
471 | - return str_replace($query_param_sans_stars, $query_param_sans_gmt_and_sans_stars, $field_name); |
|
472 | - } |
|
473 | - |
|
474 | - |
|
475 | - /** |
|
476 | - * Takes a field name from the REST API and prepares it for the model querying |
|
477 | - * |
|
478 | - * @param string $field_name |
|
479 | - * @return string |
|
480 | - */ |
|
481 | - public static function prepareFieldNameFromJson($field_name) |
|
482 | - { |
|
483 | - if (ModelDataTranslator::isGmtDateFieldName($field_name)) { |
|
484 | - return ModelDataTranslator::removeGmtFromFieldName($field_name); |
|
485 | - } |
|
486 | - return $field_name; |
|
487 | - } |
|
488 | - |
|
489 | - |
|
490 | - /** |
|
491 | - * Takes array of field names from REST API and prepares for models |
|
492 | - * |
|
493 | - * @param array $field_names |
|
494 | - * @return array of field names (possibly include model prefixes) |
|
495 | - */ |
|
496 | - public static function prepareFieldNamesFromJson(array $field_names) |
|
497 | - { |
|
498 | - $new_array = []; |
|
499 | - foreach ($field_names as $key => $field_name) { |
|
500 | - $new_array[ $key ] = ModelDataTranslator::prepareFieldNameFromJson($field_name); |
|
501 | - } |
|
502 | - return $new_array; |
|
503 | - } |
|
504 | - |
|
505 | - |
|
506 | - /** |
|
507 | - * Takes array where array keys are field names (possibly with model path prefixes) |
|
508 | - * from the REST API and prepares them for model querying |
|
509 | - * |
|
510 | - * @param array $field_names_as_keys |
|
511 | - * @return array |
|
512 | - */ |
|
513 | - public static function prepareFieldNamesInArrayKeysFromJson(array $field_names_as_keys) |
|
514 | - { |
|
515 | - $new_array = []; |
|
516 | - foreach ($field_names_as_keys as $field_name => $value) { |
|
517 | - $new_array[ ModelDataTranslator::prepareFieldNameFromJson($field_name) ] = $value; |
|
518 | - } |
|
519 | - return $new_array; |
|
520 | - } |
|
521 | - |
|
522 | - |
|
523 | - /** |
|
524 | - * Prepares an array of model query params for use in the REST API |
|
525 | - * |
|
526 | - * @param array $model_query_params |
|
527 | - * @param EEM_Base $model |
|
528 | - * @param string $requested_version eg "4.8.36". If null is provided, defaults to the latest release of the EE4 |
|
529 | - * REST API |
|
530 | - * @return array which can be passed into the EE4 REST API when querying a model resource |
|
531 | - * @throws EE_Error |
|
532 | - * @throws ReflectionException |
|
533 | - */ |
|
534 | - public static function prepareQueryParamsForRestApi( |
|
535 | - array $model_query_params, |
|
536 | - EEM_Base $model, |
|
537 | - $requested_version = null |
|
538 | - ) { |
|
539 | - if ($requested_version === null) { |
|
540 | - $requested_version = EED_Core_Rest_Api::latest_rest_api_version(); |
|
541 | - } |
|
542 | - $rest_query_params = $model_query_params; |
|
543 | - if (isset($model_query_params[0])) { |
|
544 | - $rest_query_params['where'] = ModelDataTranslator::prepareConditionsQueryParamsForRestApi( |
|
545 | - $model_query_params[0], |
|
546 | - $model, |
|
547 | - $requested_version |
|
548 | - ); |
|
549 | - unset($rest_query_params[0]); |
|
550 | - } |
|
551 | - if (isset($model_query_params['having'])) { |
|
552 | - $rest_query_params['having'] = ModelDataTranslator::prepareConditionsQueryParamsForRestApi( |
|
553 | - $model_query_params['having'], |
|
554 | - $model, |
|
555 | - $requested_version |
|
556 | - ); |
|
557 | - } |
|
558 | - return apply_filters( |
|
559 | - 'FHEE__EventEspresso\core\libraries\rest_api\Model_Data_Translator__prepare_query_params_for_rest_api', |
|
560 | - $rest_query_params, |
|
561 | - $model_query_params, |
|
562 | - $model, |
|
563 | - $requested_version |
|
564 | - ); |
|
565 | - } |
|
566 | - |
|
567 | - |
|
568 | - /** |
|
569 | - * Prepares all the sub-conditions query parameters (eg having or where conditions) for use in the rest api |
|
570 | - * |
|
571 | - * @param array $inputted_query_params_of_this_type eg like the "where" or "having" conditions query params |
|
572 | - * @param EEM_Base $model |
|
573 | - * @param string $requested_version eg "4.8.36" |
|
574 | - * @return array ready for use in the rest api query params |
|
575 | - * @throws EE_Error |
|
576 | - * @throws RestException if somehow a PHP object were in the query params' values,*@throws |
|
577 | - * @throws ReflectionException |
|
578 | - * ReflectionException |
|
579 | - * (which would be really unusual) |
|
580 | - * @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions |
|
581 | - */ |
|
582 | - public static function prepareConditionsQueryParamsForRestApi( |
|
583 | - $inputted_query_params_of_this_type, |
|
584 | - EEM_Base $model, |
|
585 | - $requested_version |
|
586 | - ) { |
|
587 | - $query_param_for_models = []; |
|
588 | - foreach ($inputted_query_params_of_this_type as $query_param_key => $query_param_value) { |
|
589 | - $field = ModelDataTranslator::deduceFieldFromQueryParam( |
|
590 | - ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey($query_param_key), |
|
591 | - $model |
|
592 | - ); |
|
593 | - if ($field instanceof EE_Model_Field_Base) { |
|
594 | - // did they specify an operator? |
|
595 | - if (is_array($query_param_value)) { |
|
596 | - $op = $query_param_value[0]; |
|
597 | - $translated_value = [$op]; |
|
598 | - if (isset($query_param_value[1])) { |
|
599 | - $value = $query_param_value[1]; |
|
600 | - $translated_value[1] = ModelDataTranslator::prepareFieldValuesForJson( |
|
601 | - $field, |
|
602 | - $value, |
|
603 | - $requested_version |
|
604 | - ); |
|
605 | - } |
|
606 | - } else { |
|
607 | - $translated_value = ModelDataTranslator::prepareFieldValueForJson( |
|
608 | - $field, |
|
609 | - $query_param_value, |
|
610 | - $requested_version |
|
611 | - ); |
|
612 | - } |
|
613 | - $query_param_for_models[ $query_param_key ] = $translated_value; |
|
614 | - } else { |
|
615 | - // so it's not for a field, assume it's a logic query param key |
|
616 | - $query_param_for_models[ $query_param_key ] = |
|
617 | - ModelDataTranslator::prepareConditionsQueryParamsForRestApi( |
|
618 | - $query_param_value, |
|
619 | - $model, |
|
620 | - $requested_version |
|
621 | - ); |
|
622 | - } |
|
623 | - } |
|
624 | - return $query_param_for_models; |
|
625 | - } |
|
626 | - |
|
627 | - |
|
628 | - /** |
|
629 | - * @param $condition_query_param_key |
|
630 | - * @return string |
|
631 | - */ |
|
632 | - public static function removeStarsAndAnythingAfterFromConditionQueryParamKey($condition_query_param_key) |
|
633 | - { |
|
634 | - $pos_of_star = strpos($condition_query_param_key, '*'); |
|
635 | - if ($pos_of_star === false) { |
|
636 | - return $condition_query_param_key; |
|
637 | - } |
|
638 | - return substr($condition_query_param_key, 0, $pos_of_star); |
|
639 | - } |
|
640 | - |
|
641 | - |
|
642 | - /** |
|
643 | - * Takes the input parameter and finds the model field that it indicates. |
|
644 | - * |
|
645 | - * @param string $query_param_name like Registration.Transaction.TXN_ID, Event.Datetime.start_time, or REG_ID |
|
646 | - * @param EEM_Base $model |
|
647 | - * @return EE_Model_Field_Base |
|
648 | - * @throws EE_Error |
|
649 | - * @throws ReflectionException |
|
650 | - */ |
|
651 | - public static function deduceFieldFromQueryParam($query_param_name, EEM_Base $model) |
|
652 | - { |
|
653 | - // ok, now proceed with deducing which part is the model's name, and which is the field's name |
|
654 | - // which will help us find the database table and column |
|
655 | - $query_param_parts = explode('.', $query_param_name); |
|
656 | - if (empty($query_param_parts)) { |
|
657 | - throw new EE_Error( |
|
658 | - sprintf( |
|
659 | - esc_html__( |
|
660 | - '_extract_column_name is empty when trying to extract column and table name from %s', |
|
661 | - 'event_espresso' |
|
662 | - ), |
|
663 | - $query_param_name |
|
664 | - ) |
|
665 | - ); |
|
666 | - } |
|
667 | - $number_of_parts = count($query_param_parts); |
|
668 | - $last_query_param_part = $query_param_parts[ count($query_param_parts) - 1 ]; |
|
669 | - $field_name = $last_query_param_part; |
|
670 | - if ($number_of_parts !== 1) { |
|
671 | - // the last part is the column name, and there are only 2parts. therefore... |
|
672 | - $model = EE_Registry::instance()->load_model($query_param_parts[ $number_of_parts - 2 ]); |
|
673 | - } |
|
674 | - try { |
|
675 | - return $model->field_settings_for($field_name, false); |
|
676 | - } catch (EE_Error $e) { |
|
677 | - return null; |
|
678 | - } |
|
679 | - } |
|
680 | - |
|
681 | - |
|
682 | - /** |
|
683 | - * Returns true if $data can be easily represented in JSON. |
|
684 | - * Basically, objects and resources can't be represented in JSON easily. |
|
685 | - * |
|
686 | - * @param mixed $data |
|
687 | - * @return bool |
|
688 | - */ |
|
689 | - protected static function isRepresentableInJson($data) |
|
690 | - { |
|
691 | - return is_scalar($data) |
|
692 | - || is_array($data) |
|
693 | - || is_null($data); |
|
694 | - } |
|
41 | + /** |
|
42 | + * We used to use -1 for infinity in the rest api, but that's ambiguous for |
|
43 | + * fields that COULD contain -1; so we use null |
|
44 | + */ |
|
45 | + const EE_INF_IN_REST = null; |
|
46 | + |
|
47 | + |
|
48 | + /** |
|
49 | + * Prepares a possible array of input values from JSON for use by the models |
|
50 | + * |
|
51 | + * @param EE_Model_Field_Base $field_obj |
|
52 | + * @param mixed $original_value_maybe_array |
|
53 | + * @param string $requested_version |
|
54 | + * @param string $timezone_string treat values as being in this timezone |
|
55 | + * @return mixed |
|
56 | + * @throws RestException |
|
57 | + * @throws EE_Error |
|
58 | + */ |
|
59 | + public static function prepareFieldValuesFromJson( |
|
60 | + $field_obj, |
|
61 | + $original_value_maybe_array, |
|
62 | + $requested_version, |
|
63 | + $timezone_string = 'UTC' |
|
64 | + ) { |
|
65 | + if ( |
|
66 | + is_array($original_value_maybe_array) |
|
67 | + && ! $field_obj instanceof EE_Serialized_Text_Field |
|
68 | + ) { |
|
69 | + $new_value_maybe_array = []; |
|
70 | + foreach ($original_value_maybe_array as $array_key => $array_item) { |
|
71 | + $new_value_maybe_array[ $array_key ] = ModelDataTranslator::prepareFieldValueFromJson( |
|
72 | + $field_obj, |
|
73 | + $array_item, |
|
74 | + $requested_version, |
|
75 | + $timezone_string |
|
76 | + ); |
|
77 | + } |
|
78 | + } else { |
|
79 | + $new_value_maybe_array = ModelDataTranslator::prepareFieldValueFromJson( |
|
80 | + $field_obj, |
|
81 | + $original_value_maybe_array, |
|
82 | + $requested_version, |
|
83 | + $timezone_string |
|
84 | + ); |
|
85 | + } |
|
86 | + return $new_value_maybe_array; |
|
87 | + } |
|
88 | + |
|
89 | + |
|
90 | + /** |
|
91 | + * Prepares an array of field values FOR use in JSON/REST API |
|
92 | + * |
|
93 | + * @param EE_Model_Field_Base $field_obj |
|
94 | + * @param mixed $original_value_maybe_array |
|
95 | + * @param string $request_version (eg 4.8.36) |
|
96 | + * @return array|int|string |
|
97 | + * @throws EE_Error |
|
98 | + * @throws EE_Error |
|
99 | + */ |
|
100 | + public static function prepareFieldValuesForJson($field_obj, $original_value_maybe_array, $request_version) |
|
101 | + { |
|
102 | + if (is_array($original_value_maybe_array)) { |
|
103 | + $new_value = []; |
|
104 | + foreach ($original_value_maybe_array as $key => $value) { |
|
105 | + $new_value[ $key ] = ModelDataTranslator::prepareFieldValuesForJson( |
|
106 | + $field_obj, |
|
107 | + $value, |
|
108 | + $request_version |
|
109 | + ); |
|
110 | + } |
|
111 | + } else { |
|
112 | + $new_value = ModelDataTranslator::prepareFieldValueForJson( |
|
113 | + $field_obj, |
|
114 | + $original_value_maybe_array, |
|
115 | + $request_version |
|
116 | + ); |
|
117 | + } |
|
118 | + return $new_value; |
|
119 | + } |
|
120 | + |
|
121 | + |
|
122 | + /** |
|
123 | + * Prepares incoming data from the json or request parameters for the models' |
|
124 | + * "$query_params". |
|
125 | + * |
|
126 | + * @param EE_Model_Field_Base $field_obj |
|
127 | + * @param mixed $original_value |
|
128 | + * @param string $requested_version |
|
129 | + * @param string $timezone_string treat values as being in this timezone |
|
130 | + * @return mixed |
|
131 | + * @throws RestException |
|
132 | + * @throws DomainException |
|
133 | + * @throws EE_Error |
|
134 | + */ |
|
135 | + public static function prepareFieldValueFromJson( |
|
136 | + $field_obj, |
|
137 | + $original_value, |
|
138 | + $requested_version, |
|
139 | + $timezone_string = 'UTC' |
|
140 | + ) { |
|
141 | + // check if they accidentally submitted an error value. If so throw an exception |
|
142 | + if ( |
|
143 | + is_array($original_value) |
|
144 | + && isset($original_value['error_code'], $original_value['error_message']) |
|
145 | + ) { |
|
146 | + throw new RestException( |
|
147 | + 'rest_submitted_error_value', |
|
148 | + sprintf( |
|
149 | + esc_html__( |
|
150 | + 'You tried to submit a JSON error object as a value for %1$s. That\'s not allowed.', |
|
151 | + 'event_espresso' |
|
152 | + ), |
|
153 | + $field_obj->get_name() |
|
154 | + ), |
|
155 | + [ |
|
156 | + 'status' => 400, |
|
157 | + ] |
|
158 | + ); |
|
159 | + } |
|
160 | + // double-check for serialized PHP. We never accept serialized PHP. No way Jose. |
|
161 | + ModelDataTranslator::throwExceptionIfContainsSerializedData($original_value); |
|
162 | + $timezone_string = |
|
163 | + $timezone_string !== '' |
|
164 | + ? $timezone_string |
|
165 | + : get_option('timezone_string', ''); |
|
166 | + // walk through the submitted data and double-check for serialized PHP. We never accept serialized PHP. No |
|
167 | + // way Jose. |
|
168 | + ModelDataTranslator::throwExceptionIfContainsSerializedData($original_value); |
|
169 | + if ( |
|
170 | + $field_obj instanceof EE_Infinite_Integer_Field |
|
171 | + && in_array($original_value, [null, ''], true) |
|
172 | + ) { |
|
173 | + $new_value = EE_INF; |
|
174 | + } elseif ($field_obj instanceof EE_Datetime_Field) { |
|
175 | + $new_value = rest_parse_date( |
|
176 | + self::getTimestampWithTimezoneOffset($original_value, $field_obj, $timezone_string) |
|
177 | + ); |
|
178 | + if ($new_value === false) { |
|
179 | + throw new RestException( |
|
180 | + 'invalid_format_for_timestamp', |
|
181 | + sprintf( |
|
182 | + esc_html__( |
|
183 | + 'Timestamps received on a request as the value for Date and Time fields must be in %1$s/%2$s format. The timestamp provided (%3$s) is not that format.', |
|
184 | + 'event_espresso' |
|
185 | + ), |
|
186 | + 'RFC3339', |
|
187 | + 'ISO8601', |
|
188 | + $original_value |
|
189 | + ), |
|
190 | + [ |
|
191 | + 'status' => 400, |
|
192 | + ] |
|
193 | + ); |
|
194 | + } |
|
195 | + } elseif ($field_obj instanceof EE_Boolean_Field) { |
|
196 | + // Interpreted the strings "false", "true", "on", "off" appropriately. |
|
197 | + $new_value = filter_var($original_value, FILTER_VALIDATE_BOOLEAN); |
|
198 | + } else { |
|
199 | + $new_value = $original_value; |
|
200 | + } |
|
201 | + return $new_value; |
|
202 | + } |
|
203 | + |
|
204 | + |
|
205 | + /** |
|
206 | + * This checks if the incoming timestamp has timezone information already on it and if it doesn't then adds timezone |
|
207 | + * information via details obtained from the host site. |
|
208 | + * |
|
209 | + * @param string $original_timestamp |
|
210 | + * @param EE_Datetime_Field $datetime_field |
|
211 | + * @param $timezone_string |
|
212 | + * @return string |
|
213 | + * @throws DomainException |
|
214 | + */ |
|
215 | + private static function getTimestampWithTimezoneOffset( |
|
216 | + $original_timestamp, |
|
217 | + EE_Datetime_Field $datetime_field, |
|
218 | + $timezone_string |
|
219 | + ) { |
|
220 | + // already have timezone information? |
|
221 | + if (preg_match('/Z|([+-])(\d{2}:\d{2})/', $original_timestamp)) { |
|
222 | + // yes, we're ignoring the timezone. |
|
223 | + return $original_timestamp; |
|
224 | + } |
|
225 | + // need to append timezone |
|
226 | + list($offset_sign, $offset_secs) = self::parseTimezoneOffset( |
|
227 | + $datetime_field->get_timezone_offset( |
|
228 | + new DateTimeZone($timezone_string), |
|
229 | + $original_timestamp |
|
230 | + ) |
|
231 | + ); |
|
232 | + $offset_string = |
|
233 | + str_pad( |
|
234 | + floor($offset_secs / HOUR_IN_SECONDS), |
|
235 | + 2, |
|
236 | + '0', |
|
237 | + STR_PAD_LEFT |
|
238 | + ) |
|
239 | + . ':' |
|
240 | + . str_pad( |
|
241 | + ($offset_secs % HOUR_IN_SECONDS) / MINUTE_IN_SECONDS, |
|
242 | + 2, |
|
243 | + '0', |
|
244 | + STR_PAD_LEFT |
|
245 | + ); |
|
246 | + return $original_timestamp . $offset_sign . $offset_string; |
|
247 | + } |
|
248 | + |
|
249 | + |
|
250 | + /** |
|
251 | + * Throws an exception if $data is a serialized PHP string (or somehow an actually PHP object, although I don't |
|
252 | + * think that can happen). If $data is an array, recurses into its keys and values |
|
253 | + * |
|
254 | + * @param mixed $data |
|
255 | + * @return void |
|
256 | + * @throws RestException |
|
257 | + */ |
|
258 | + public static function throwExceptionIfContainsSerializedData($data) |
|
259 | + { |
|
260 | + if (is_array($data)) { |
|
261 | + foreach ($data as $key => $value) { |
|
262 | + ModelDataTranslator::throwExceptionIfContainsSerializedData($key); |
|
263 | + ModelDataTranslator::throwExceptionIfContainsSerializedData($value); |
|
264 | + } |
|
265 | + } else { |
|
266 | + if (is_serialized($data) || is_object($data)) { |
|
267 | + throw new RestException( |
|
268 | + 'serialized_data_submission_prohibited', |
|
269 | + esc_html__( |
|
270 | + // @codingStandardsIgnoreStart |
|
271 | + 'You tried to submit a string of serialized text. Serialized PHP is prohibited over the EE4 REST API.', |
|
272 | + // @codingStandardsIgnoreEnd |
|
273 | + 'event_espresso' |
|
274 | + ) |
|
275 | + ); |
|
276 | + } |
|
277 | + } |
|
278 | + } |
|
279 | + |
|
280 | + |
|
281 | + /** |
|
282 | + * determines what's going on with them timezone strings |
|
283 | + * |
|
284 | + * @param int $timezone_offset |
|
285 | + * @return array |
|
286 | + */ |
|
287 | + private static function parseTimezoneOffset($timezone_offset) |
|
288 | + { |
|
289 | + $first_char = substr((string) $timezone_offset, 0, 1); |
|
290 | + if ($first_char === '+' || $first_char === '-') { |
|
291 | + $offset_sign = $first_char; |
|
292 | + $offset_secs = substr((string) $timezone_offset, 1); |
|
293 | + } else { |
|
294 | + $offset_sign = '+'; |
|
295 | + $offset_secs = $timezone_offset; |
|
296 | + } |
|
297 | + return [$offset_sign, $offset_secs]; |
|
298 | + } |
|
299 | + |
|
300 | + |
|
301 | + /** |
|
302 | + * Prepares a field's value for display in the API |
|
303 | + * |
|
304 | + * @param EE_Model_Field_Base $field_obj |
|
305 | + * @param mixed $original_value |
|
306 | + * @param string $requested_version |
|
307 | + * @return mixed |
|
308 | + * @throws EE_Error |
|
309 | + * @throws EE_Error |
|
310 | + */ |
|
311 | + public static function prepareFieldValueForJson($field_obj, $original_value, $requested_version) |
|
312 | + { |
|
313 | + if ($original_value === EE_INF) { |
|
314 | + $new_value = ModelDataTranslator::EE_INF_IN_REST; |
|
315 | + } elseif ($field_obj instanceof EE_Datetime_Field) { |
|
316 | + if (is_string($original_value)) { |
|
317 | + // did they submit a string of a unix timestamp? |
|
318 | + if (is_numeric($original_value)) { |
|
319 | + $datetime_obj = new DateTime(); |
|
320 | + $datetime_obj->setTimestamp((int) $original_value); |
|
321 | + } else { |
|
322 | + // first, check if its a MySQL timestamp in GMT |
|
323 | + $datetime_obj = DateTime::createFromFormat('Y-m-d H:i:s', $original_value); |
|
324 | + } |
|
325 | + if (! $datetime_obj instanceof DateTime) { |
|
326 | + // so it's not a unix timestamp or a MySQL timestamp. Maybe its in the field's date/time format? |
|
327 | + $datetime_obj = $field_obj->prepare_for_set($original_value); |
|
328 | + } |
|
329 | + $original_value = $datetime_obj; |
|
330 | + } |
|
331 | + if ($original_value instanceof DateTime) { |
|
332 | + $new_value = $original_value->format('Y-m-d H:i:s'); |
|
333 | + } elseif (is_int($original_value) || is_float($original_value)) { |
|
334 | + $new_value = date('Y-m-d H:i:s', $original_value); |
|
335 | + } elseif ($original_value === null || $original_value === '') { |
|
336 | + $new_value = null; |
|
337 | + } else { |
|
338 | + // so it's not a datetime object, unix timestamp (as string or int), |
|
339 | + // MySQL timestamp, or even a string in the field object's format. So no idea what it is |
|
340 | + throw new EE_Error( |
|
341 | + sprintf( |
|
342 | + esc_html__( |
|
343 | + // @codingStandardsIgnoreStart |
|
344 | + 'The value "%1$s" for the field "%2$s" on model "%3$s" could not be understood. It should be a PHP DateTime, unix timestamp, MySQL date, or string in the format "%4$s".', |
|
345 | + // @codingStandardsIgnoreEnd |
|
346 | + 'event_espresso' |
|
347 | + ), |
|
348 | + $original_value, |
|
349 | + $field_obj->get_name(), |
|
350 | + $field_obj->get_model_name(), |
|
351 | + $field_obj->get_time_format() . ' ' . $field_obj->get_time_format() |
|
352 | + ) |
|
353 | + ); |
|
354 | + } |
|
355 | + if ($new_value !== null) { |
|
356 | + $new_value = mysql2date('Y-m-d\TH:i:s', $new_value, false); |
|
357 | + } |
|
358 | + } else { |
|
359 | + $new_value = $original_value; |
|
360 | + } |
|
361 | + // are we about to send an object? just don't. We have no good way to represent it in JSON. |
|
362 | + // can't just check using is_object() because that missed PHP incomplete objects |
|
363 | + if (! ModelDataTranslator::isRepresentableInJson($new_value)) { |
|
364 | + $new_value = [ |
|
365 | + 'error_code' => 'php_object_not_return', |
|
366 | + 'error_message' => esc_html__( |
|
367 | + 'The value of this field in the database is a PHP object, which can\'t be represented in JSON.', |
|
368 | + 'event_espresso' |
|
369 | + ), |
|
370 | + ]; |
|
371 | + } |
|
372 | + return apply_filters( |
|
373 | + 'FHEE__EventEspresso\core\libraries\rest_api\Model_Data_Translator__prepare_field_for_rest_api', |
|
374 | + $new_value, |
|
375 | + $field_obj, |
|
376 | + $original_value, |
|
377 | + $requested_version |
|
378 | + ); |
|
379 | + } |
|
380 | + |
|
381 | + |
|
382 | + /** |
|
383 | + * Prepares condition-query-parameters (like what's in where and having) from |
|
384 | + * the format expected in the API to use in the models |
|
385 | + * |
|
386 | + * @param array $inputted_query_params_of_this_type |
|
387 | + * @param EEM_Base $model |
|
388 | + * @param string $requested_version |
|
389 | + * @param boolean $writing whether this data will be written to the DB, or if we're just building a query. |
|
390 | + * If we're writing to the DB, we don't expect any operators, or any logic query |
|
391 | + * parameters, and we also won't accept serialized data unless the current user has |
|
392 | + * unfiltered_html. |
|
393 | + * @return array |
|
394 | + * @throws DomainException |
|
395 | + * @throws EE_Error |
|
396 | + * @throws RestException |
|
397 | + * @throws InvalidDataTypeException |
|
398 | + * @throws InvalidInterfaceException |
|
399 | + * @throws InvalidArgumentException |
|
400 | + */ |
|
401 | + public static function prepareConditionsQueryParamsForModels( |
|
402 | + $inputted_query_params_of_this_type, |
|
403 | + EEM_Base $model, |
|
404 | + $requested_version, |
|
405 | + $writing = false |
|
406 | + ) { |
|
407 | + $query_param_for_models = []; |
|
408 | + $context = new RestIncomingQueryParamContext($model, $requested_version, $writing); |
|
409 | + foreach ($inputted_query_params_of_this_type as $query_param_key => $query_param_value) { |
|
410 | + $query_param_meta = new RestIncomingQueryParamMetadata($query_param_key, $query_param_value, $context); |
|
411 | + if ($query_param_meta->getField() instanceof EE_Model_Field_Base) { |
|
412 | + $translated_value = $query_param_meta->determineConditionsQueryParameterValue(); |
|
413 | + if ( |
|
414 | + (isset($query_param_for_models[ $query_param_meta->getQueryParamKey() ]) |
|
415 | + && $query_param_meta->isGmtField()) |
|
416 | + || $translated_value === null |
|
417 | + ) { |
|
418 | + // they have already provided a non-gmt field, ignore the gmt one. That's what WP core |
|
419 | + // currently does (they might change it though). See https://core.trac.wordpress.org/ticket/39954 |
|
420 | + // OR we couldn't create a translated value from their input |
|
421 | + continue; |
|
422 | + } |
|
423 | + $query_param_for_models[ $query_param_meta->getQueryParamKey() ] = $translated_value; |
|
424 | + } else { |
|
425 | + $nested_query_params = $query_param_meta->determineNestedConditionQueryParameters(); |
|
426 | + if ($nested_query_params) { |
|
427 | + $query_param_for_models[ $query_param_meta->getQueryParamKey() ] = $nested_query_params; |
|
428 | + } |
|
429 | + } |
|
430 | + } |
|
431 | + return $query_param_for_models; |
|
432 | + } |
|
433 | + |
|
434 | + |
|
435 | + /** |
|
436 | + * Mostly checks if the last 4 characters are "_gmt", indicating its a |
|
437 | + * gmt date field name |
|
438 | + * |
|
439 | + * @param string $field_name |
|
440 | + * @return boolean |
|
441 | + */ |
|
442 | + public static function isGmtDateFieldName($field_name) |
|
443 | + { |
|
444 | + $field_name = ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey($field_name); |
|
445 | + return substr($field_name, -4, 4) === '_gmt'; |
|
446 | + } |
|
447 | + |
|
448 | + |
|
449 | + /** |
|
450 | + * Removes the last "_gmt" part of a field name (and if there is no "_gmt" at the end, leave it alone) |
|
451 | + * |
|
452 | + * @param string $field_name |
|
453 | + * @return string |
|
454 | + */ |
|
455 | + public static function removeGmtFromFieldName($field_name) |
|
456 | + { |
|
457 | + if (! ModelDataTranslator::isGmtDateFieldName($field_name)) { |
|
458 | + return $field_name; |
|
459 | + } |
|
460 | + $query_param_sans_stars = ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey( |
|
461 | + $field_name |
|
462 | + ); |
|
463 | + $query_param_sans_gmt_and_sans_stars = substr( |
|
464 | + $query_param_sans_stars, |
|
465 | + 0, |
|
466 | + strrpos( |
|
467 | + $field_name, |
|
468 | + '_gmt' |
|
469 | + ) |
|
470 | + ); |
|
471 | + return str_replace($query_param_sans_stars, $query_param_sans_gmt_and_sans_stars, $field_name); |
|
472 | + } |
|
473 | + |
|
474 | + |
|
475 | + /** |
|
476 | + * Takes a field name from the REST API and prepares it for the model querying |
|
477 | + * |
|
478 | + * @param string $field_name |
|
479 | + * @return string |
|
480 | + */ |
|
481 | + public static function prepareFieldNameFromJson($field_name) |
|
482 | + { |
|
483 | + if (ModelDataTranslator::isGmtDateFieldName($field_name)) { |
|
484 | + return ModelDataTranslator::removeGmtFromFieldName($field_name); |
|
485 | + } |
|
486 | + return $field_name; |
|
487 | + } |
|
488 | + |
|
489 | + |
|
490 | + /** |
|
491 | + * Takes array of field names from REST API and prepares for models |
|
492 | + * |
|
493 | + * @param array $field_names |
|
494 | + * @return array of field names (possibly include model prefixes) |
|
495 | + */ |
|
496 | + public static function prepareFieldNamesFromJson(array $field_names) |
|
497 | + { |
|
498 | + $new_array = []; |
|
499 | + foreach ($field_names as $key => $field_name) { |
|
500 | + $new_array[ $key ] = ModelDataTranslator::prepareFieldNameFromJson($field_name); |
|
501 | + } |
|
502 | + return $new_array; |
|
503 | + } |
|
504 | + |
|
505 | + |
|
506 | + /** |
|
507 | + * Takes array where array keys are field names (possibly with model path prefixes) |
|
508 | + * from the REST API and prepares them for model querying |
|
509 | + * |
|
510 | + * @param array $field_names_as_keys |
|
511 | + * @return array |
|
512 | + */ |
|
513 | + public static function prepareFieldNamesInArrayKeysFromJson(array $field_names_as_keys) |
|
514 | + { |
|
515 | + $new_array = []; |
|
516 | + foreach ($field_names_as_keys as $field_name => $value) { |
|
517 | + $new_array[ ModelDataTranslator::prepareFieldNameFromJson($field_name) ] = $value; |
|
518 | + } |
|
519 | + return $new_array; |
|
520 | + } |
|
521 | + |
|
522 | + |
|
523 | + /** |
|
524 | + * Prepares an array of model query params for use in the REST API |
|
525 | + * |
|
526 | + * @param array $model_query_params |
|
527 | + * @param EEM_Base $model |
|
528 | + * @param string $requested_version eg "4.8.36". If null is provided, defaults to the latest release of the EE4 |
|
529 | + * REST API |
|
530 | + * @return array which can be passed into the EE4 REST API when querying a model resource |
|
531 | + * @throws EE_Error |
|
532 | + * @throws ReflectionException |
|
533 | + */ |
|
534 | + public static function prepareQueryParamsForRestApi( |
|
535 | + array $model_query_params, |
|
536 | + EEM_Base $model, |
|
537 | + $requested_version = null |
|
538 | + ) { |
|
539 | + if ($requested_version === null) { |
|
540 | + $requested_version = EED_Core_Rest_Api::latest_rest_api_version(); |
|
541 | + } |
|
542 | + $rest_query_params = $model_query_params; |
|
543 | + if (isset($model_query_params[0])) { |
|
544 | + $rest_query_params['where'] = ModelDataTranslator::prepareConditionsQueryParamsForRestApi( |
|
545 | + $model_query_params[0], |
|
546 | + $model, |
|
547 | + $requested_version |
|
548 | + ); |
|
549 | + unset($rest_query_params[0]); |
|
550 | + } |
|
551 | + if (isset($model_query_params['having'])) { |
|
552 | + $rest_query_params['having'] = ModelDataTranslator::prepareConditionsQueryParamsForRestApi( |
|
553 | + $model_query_params['having'], |
|
554 | + $model, |
|
555 | + $requested_version |
|
556 | + ); |
|
557 | + } |
|
558 | + return apply_filters( |
|
559 | + 'FHEE__EventEspresso\core\libraries\rest_api\Model_Data_Translator__prepare_query_params_for_rest_api', |
|
560 | + $rest_query_params, |
|
561 | + $model_query_params, |
|
562 | + $model, |
|
563 | + $requested_version |
|
564 | + ); |
|
565 | + } |
|
566 | + |
|
567 | + |
|
568 | + /** |
|
569 | + * Prepares all the sub-conditions query parameters (eg having or where conditions) for use in the rest api |
|
570 | + * |
|
571 | + * @param array $inputted_query_params_of_this_type eg like the "where" or "having" conditions query params |
|
572 | + * @param EEM_Base $model |
|
573 | + * @param string $requested_version eg "4.8.36" |
|
574 | + * @return array ready for use in the rest api query params |
|
575 | + * @throws EE_Error |
|
576 | + * @throws RestException if somehow a PHP object were in the query params' values,*@throws |
|
577 | + * @throws ReflectionException |
|
578 | + * ReflectionException |
|
579 | + * (which would be really unusual) |
|
580 | + * @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions |
|
581 | + */ |
|
582 | + public static function prepareConditionsQueryParamsForRestApi( |
|
583 | + $inputted_query_params_of_this_type, |
|
584 | + EEM_Base $model, |
|
585 | + $requested_version |
|
586 | + ) { |
|
587 | + $query_param_for_models = []; |
|
588 | + foreach ($inputted_query_params_of_this_type as $query_param_key => $query_param_value) { |
|
589 | + $field = ModelDataTranslator::deduceFieldFromQueryParam( |
|
590 | + ModelDataTranslator::removeStarsAndAnythingAfterFromConditionQueryParamKey($query_param_key), |
|
591 | + $model |
|
592 | + ); |
|
593 | + if ($field instanceof EE_Model_Field_Base) { |
|
594 | + // did they specify an operator? |
|
595 | + if (is_array($query_param_value)) { |
|
596 | + $op = $query_param_value[0]; |
|
597 | + $translated_value = [$op]; |
|
598 | + if (isset($query_param_value[1])) { |
|
599 | + $value = $query_param_value[1]; |
|
600 | + $translated_value[1] = ModelDataTranslator::prepareFieldValuesForJson( |
|
601 | + $field, |
|
602 | + $value, |
|
603 | + $requested_version |
|
604 | + ); |
|
605 | + } |
|
606 | + } else { |
|
607 | + $translated_value = ModelDataTranslator::prepareFieldValueForJson( |
|
608 | + $field, |
|
609 | + $query_param_value, |
|
610 | + $requested_version |
|
611 | + ); |
|
612 | + } |
|
613 | + $query_param_for_models[ $query_param_key ] = $translated_value; |
|
614 | + } else { |
|
615 | + // so it's not for a field, assume it's a logic query param key |
|
616 | + $query_param_for_models[ $query_param_key ] = |
|
617 | + ModelDataTranslator::prepareConditionsQueryParamsForRestApi( |
|
618 | + $query_param_value, |
|
619 | + $model, |
|
620 | + $requested_version |
|
621 | + ); |
|
622 | + } |
|
623 | + } |
|
624 | + return $query_param_for_models; |
|
625 | + } |
|
626 | + |
|
627 | + |
|
628 | + /** |
|
629 | + * @param $condition_query_param_key |
|
630 | + * @return string |
|
631 | + */ |
|
632 | + public static function removeStarsAndAnythingAfterFromConditionQueryParamKey($condition_query_param_key) |
|
633 | + { |
|
634 | + $pos_of_star = strpos($condition_query_param_key, '*'); |
|
635 | + if ($pos_of_star === false) { |
|
636 | + return $condition_query_param_key; |
|
637 | + } |
|
638 | + return substr($condition_query_param_key, 0, $pos_of_star); |
|
639 | + } |
|
640 | + |
|
641 | + |
|
642 | + /** |
|
643 | + * Takes the input parameter and finds the model field that it indicates. |
|
644 | + * |
|
645 | + * @param string $query_param_name like Registration.Transaction.TXN_ID, Event.Datetime.start_time, or REG_ID |
|
646 | + * @param EEM_Base $model |
|
647 | + * @return EE_Model_Field_Base |
|
648 | + * @throws EE_Error |
|
649 | + * @throws ReflectionException |
|
650 | + */ |
|
651 | + public static function deduceFieldFromQueryParam($query_param_name, EEM_Base $model) |
|
652 | + { |
|
653 | + // ok, now proceed with deducing which part is the model's name, and which is the field's name |
|
654 | + // which will help us find the database table and column |
|
655 | + $query_param_parts = explode('.', $query_param_name); |
|
656 | + if (empty($query_param_parts)) { |
|
657 | + throw new EE_Error( |
|
658 | + sprintf( |
|
659 | + esc_html__( |
|
660 | + '_extract_column_name is empty when trying to extract column and table name from %s', |
|
661 | + 'event_espresso' |
|
662 | + ), |
|
663 | + $query_param_name |
|
664 | + ) |
|
665 | + ); |
|
666 | + } |
|
667 | + $number_of_parts = count($query_param_parts); |
|
668 | + $last_query_param_part = $query_param_parts[ count($query_param_parts) - 1 ]; |
|
669 | + $field_name = $last_query_param_part; |
|
670 | + if ($number_of_parts !== 1) { |
|
671 | + // the last part is the column name, and there are only 2parts. therefore... |
|
672 | + $model = EE_Registry::instance()->load_model($query_param_parts[ $number_of_parts - 2 ]); |
|
673 | + } |
|
674 | + try { |
|
675 | + return $model->field_settings_for($field_name, false); |
|
676 | + } catch (EE_Error $e) { |
|
677 | + return null; |
|
678 | + } |
|
679 | + } |
|
680 | + |
|
681 | + |
|
682 | + /** |
|
683 | + * Returns true if $data can be easily represented in JSON. |
|
684 | + * Basically, objects and resources can't be represented in JSON easily. |
|
685 | + * |
|
686 | + * @param mixed $data |
|
687 | + * @return bool |
|
688 | + */ |
|
689 | + protected static function isRepresentableInJson($data) |
|
690 | + { |
|
691 | + return is_scalar($data) |
|
692 | + || is_array($data) |
|
693 | + || is_null($data); |
|
694 | + } |
|
695 | 695 | } |
@@ -114,7 +114,7 @@ discard block |
||
114 | 114 | ? null |
115 | 115 | : $this->_data; |
116 | 116 | |
117 | - if (! $registration instanceof EE_Registration) { |
|
117 | + if ( ! $registration instanceof EE_Registration) { |
|
118 | 118 | // let's attempt to get the txn_id for the error message. |
119 | 119 | $txn_id = isset($this->_extra->txn) && $this->_extra->txn instanceof EE_Transaction |
120 | 120 | ? $this->_extra->txn->ID() |
@@ -131,12 +131,12 @@ discard block |
||
131 | 131 | } |
132 | 132 | |
133 | 133 | // attendee obj for this registration |
134 | - $attendee = isset($this->_extra->registrations[ $registration->ID() ]['att_obj']) |
|
135 | - ? $this->_extra->registrations[ $registration->ID() ]['att_obj'] |
|
134 | + $attendee = isset($this->_extra->registrations[$registration->ID()]['att_obj']) |
|
135 | + ? $this->_extra->registrations[$registration->ID()]['att_obj'] |
|
136 | 136 | : null; |
137 | 137 | |
138 | - if (! $attendee instanceof EE_Attendee) { |
|
139 | - $msg = esc_html__( |
|
138 | + if ( ! $attendee instanceof EE_Attendee) { |
|
139 | + $msg = esc_html__( |
|
140 | 140 | 'There is no EE_Attendee object in the data sent to the EE_Attendee_Shortcode parser for the messages system.', |
141 | 141 | 'event_espresso' |
142 | 142 | ); |
@@ -15,192 +15,192 @@ |
||
15 | 15 | */ |
16 | 16 | class EE_Attendee_Shortcodes extends EE_Shortcodes |
17 | 17 | { |
18 | - /** |
|
19 | - * hold all extra data. |
|
20 | - * |
|
21 | - * @var array |
|
22 | - */ |
|
23 | - protected $_extra; |
|
24 | - |
|
25 | - |
|
26 | - /** |
|
27 | - * EE_Attendee_Shortcodes constructor. |
|
28 | - */ |
|
29 | - public function __construct() |
|
30 | - { |
|
31 | - parent::__construct(); |
|
32 | - } |
|
33 | - |
|
34 | - |
|
35 | - protected function _init_props() |
|
36 | - { |
|
37 | - $this->label = esc_html__('Attendee Shortcodes', 'event_espresso'); |
|
38 | - $this->description = esc_html__('All shortcodes specific to attendee related data', 'event_espresso'); |
|
39 | - $this->_shortcodes = [ |
|
40 | - '[FNAME]' => esc_html__('First Name of an attendee.', 'event_espresso'), |
|
41 | - '[LNAME]' => esc_html__('Last Name of an attendee.', 'event_espresso'), |
|
42 | - '[ATTENDEE_EMAIL]' => esc_html__('Email address for the attendee.', 'event_espresso'), |
|
43 | - '[EDIT_ATTENDEE_LINK]' => esc_html__( |
|
44 | - 'Edit Registration Link (typically you\'d only use this for messages going to event administrators)', |
|
45 | - 'event_espresso' |
|
46 | - ), |
|
47 | - '[REGISTRATION_ID]' => esc_html__( |
|
48 | - 'Unique Registration ID for the registration', |
|
49 | - 'event_espresso' |
|
50 | - ), |
|
51 | - '[REGISTRATION_CODE]' => esc_html__( |
|
52 | - 'Unique Registration Code for the registration', |
|
53 | - 'event_espresso' |
|
54 | - ), |
|
55 | - '[REGISTRATION_STATUS_ID]' => esc_html__( |
|
56 | - 'Parses to the registration status for the attendee', |
|
57 | - 'event_espresso' |
|
58 | - ), |
|
59 | - '[REGISTRATION_STATUS_LABEL]' => esc_html__( |
|
60 | - 'Parses to the status label for the registrant', |
|
61 | - 'event_espresso' |
|
62 | - ), |
|
63 | - '[REGISTRATION_TOTAL_AMOUNT_PAID]' => esc_html__( |
|
64 | - 'Parses to the total amount paid for this registration.', |
|
65 | - 'event_espresso' |
|
66 | - ), |
|
67 | - '[FRONTEND_EDIT_REG_LINK]' => esc_html__( |
|
68 | - 'Generates a link for the given registration to edit this registration details on the frontend.', |
|
69 | - 'event_espresso' |
|
70 | - ), |
|
71 | - '[PHONE_NUMBER]' => esc_html__( |
|
72 | - 'The Phone Number for the Registration.', |
|
73 | - 'event_espresso' |
|
74 | - ), |
|
75 | - '[ADDRESS]' => esc_html__('The Address for the Registration', 'event_espresso'), |
|
76 | - '[ADDRESS2]' => esc_html__( |
|
77 | - 'Whatever was in the address 2 field for the registration.', |
|
78 | - 'event_espresso' |
|
79 | - ), |
|
80 | - '[CITY]' => esc_html__('The city for the registration.', 'event_espresso'), |
|
81 | - '[ZIP_PC]' => esc_html__( |
|
82 | - 'The ZIP (or Postal) Code for the Registration.', |
|
83 | - 'event_espresso' |
|
84 | - ), |
|
85 | - '[ADDRESS_STATE]' => esc_html__( |
|
86 | - 'The state/province for the registration.', |
|
87 | - 'event_espresso' |
|
88 | - ), |
|
89 | - '[COUNTRY]' => esc_html__('The country for the registration.', 'event_espresso'), |
|
90 | - ]; |
|
91 | - } |
|
92 | - |
|
93 | - |
|
94 | - /** |
|
95 | - * handles shortcode parsing |
|
96 | - * |
|
97 | - * @access protected |
|
98 | - * @param string $shortcode the shortcode to be parsed. |
|
99 | - * @return string |
|
100 | - * @throws EE_Error |
|
101 | - * @throws ReflectionException |
|
102 | - */ |
|
103 | - protected function _parser($shortcode) |
|
104 | - { |
|
105 | - |
|
106 | - |
|
107 | - $this->_extra = ! empty($this->_extra_data) && $this->_extra_data['data'] instanceof EE_Messages_Addressee |
|
108 | - ? $this->_extra_data['data'] |
|
109 | - : null; |
|
110 | - |
|
111 | - // incoming object should only be a registration object. |
|
112 | - $registration = ! $this->_data instanceof EE_Registration |
|
113 | - ? null |
|
114 | - : $this->_data; |
|
115 | - |
|
116 | - if (! $registration instanceof EE_Registration) { |
|
117 | - // let's attempt to get the txn_id for the error message. |
|
118 | - $txn_id = isset($this->_extra->txn) && $this->_extra->txn instanceof EE_Transaction |
|
119 | - ? $this->_extra->txn->ID() |
|
120 | - : esc_html__('Unknown', 'event_espresso'); |
|
121 | - $msg = esc_html__( |
|
122 | - 'There is no EE_Registration object in the data sent to the EE_Attendee Shortcode Parser for the messages system.', |
|
123 | - 'event_espresso' |
|
124 | - ); |
|
125 | - $dev_msg = sprintf( |
|
126 | - esc_html__('The transaction ID for this request is: %s', 'event_espresso'), |
|
127 | - $txn_id |
|
128 | - ); |
|
129 | - throw new EE_Error("{$msg}||{$msg} {$dev_msg}"); |
|
130 | - } |
|
131 | - |
|
132 | - // attendee obj for this registration |
|
133 | - $attendee = isset($this->_extra->registrations[ $registration->ID() ]['att_obj']) |
|
134 | - ? $this->_extra->registrations[ $registration->ID() ]['att_obj'] |
|
135 | - : null; |
|
136 | - |
|
137 | - if (! $attendee instanceof EE_Attendee) { |
|
138 | - $msg = esc_html__( |
|
139 | - 'There is no EE_Attendee object in the data sent to the EE_Attendee_Shortcode parser for the messages system.', |
|
140 | - 'event_espresso' |
|
141 | - ); |
|
142 | - $dev_msg = sprintf( |
|
143 | - esc_html__('The registration ID for this request is: %s', 'event_espresso'), |
|
144 | - $registration->ID() |
|
145 | - ); |
|
146 | - throw new EE_Error("{$msg}||{$msg} {$dev_msg}"); |
|
147 | - } |
|
148 | - |
|
149 | - switch ($shortcode) { |
|
150 | - case '[FNAME]': |
|
151 | - return $attendee->fname(); |
|
152 | - |
|
153 | - case '[LNAME]': |
|
154 | - return $attendee->lname(); |
|
155 | - |
|
156 | - case '[ATTENDEE_EMAIL]': |
|
157 | - return $attendee->email(); |
|
158 | - |
|
159 | - case '[EDIT_ATTENDEE_LINK]': |
|
160 | - return $registration->get_admin_edit_url(); |
|
161 | - |
|
162 | - case '[REGISTRATION_CODE]': |
|
163 | - return $registration->reg_code(); |
|
164 | - |
|
165 | - case '[REGISTRATION_ID]': |
|
166 | - return $registration->ID(); |
|
167 | - |
|
168 | - case '[FRONTEND_EDIT_REG_LINK]': |
|
169 | - return $registration->edit_attendee_information_url(); |
|
170 | - |
|
171 | - case '[PHONE_NUMBER]': |
|
172 | - return $attendee->phone(); |
|
173 | - |
|
174 | - case '[ADDRESS]': |
|
175 | - return $attendee->address(); |
|
176 | - |
|
177 | - case '[ADDRESS2]': |
|
178 | - return $attendee->address2(); |
|
179 | - |
|
180 | - case '[CITY]': |
|
181 | - return $attendee->city(); |
|
182 | - |
|
183 | - case '[ZIP_PC]': |
|
184 | - return $attendee->zip(); |
|
185 | - |
|
186 | - case '[ADDRESS_STATE]': |
|
187 | - $state_obj = $attendee->state_obj(); |
|
188 | - return $state_obj instanceof EE_State ? $state_obj->name() : ''; |
|
189 | - |
|
190 | - case '[COUNTRY]': |
|
191 | - $country_obj = $attendee->country_obj(); |
|
192 | - return $country_obj instanceof EE_Country ? $country_obj->name() : ''; |
|
193 | - |
|
194 | - case '[REGISTRATION_STATUS_ID]': |
|
195 | - return $registration->status_ID(); |
|
196 | - |
|
197 | - case '[REGISTRATION_STATUS_LABEL]': |
|
198 | - return $registration->pretty_status(); |
|
199 | - |
|
200 | - case '[REGISTRATION_TOTAL_AMOUNT_PAID]': |
|
201 | - return $registration->pretty_paid(); |
|
202 | - } |
|
203 | - |
|
204 | - return ''; |
|
205 | - } |
|
18 | + /** |
|
19 | + * hold all extra data. |
|
20 | + * |
|
21 | + * @var array |
|
22 | + */ |
|
23 | + protected $_extra; |
|
24 | + |
|
25 | + |
|
26 | + /** |
|
27 | + * EE_Attendee_Shortcodes constructor. |
|
28 | + */ |
|
29 | + public function __construct() |
|
30 | + { |
|
31 | + parent::__construct(); |
|
32 | + } |
|
33 | + |
|
34 | + |
|
35 | + protected function _init_props() |
|
36 | + { |
|
37 | + $this->label = esc_html__('Attendee Shortcodes', 'event_espresso'); |
|
38 | + $this->description = esc_html__('All shortcodes specific to attendee related data', 'event_espresso'); |
|
39 | + $this->_shortcodes = [ |
|
40 | + '[FNAME]' => esc_html__('First Name of an attendee.', 'event_espresso'), |
|
41 | + '[LNAME]' => esc_html__('Last Name of an attendee.', 'event_espresso'), |
|
42 | + '[ATTENDEE_EMAIL]' => esc_html__('Email address for the attendee.', 'event_espresso'), |
|
43 | + '[EDIT_ATTENDEE_LINK]' => esc_html__( |
|
44 | + 'Edit Registration Link (typically you\'d only use this for messages going to event administrators)', |
|
45 | + 'event_espresso' |
|
46 | + ), |
|
47 | + '[REGISTRATION_ID]' => esc_html__( |
|
48 | + 'Unique Registration ID for the registration', |
|
49 | + 'event_espresso' |
|
50 | + ), |
|
51 | + '[REGISTRATION_CODE]' => esc_html__( |
|
52 | + 'Unique Registration Code for the registration', |
|
53 | + 'event_espresso' |
|
54 | + ), |
|
55 | + '[REGISTRATION_STATUS_ID]' => esc_html__( |
|
56 | + 'Parses to the registration status for the attendee', |
|
57 | + 'event_espresso' |
|
58 | + ), |
|
59 | + '[REGISTRATION_STATUS_LABEL]' => esc_html__( |
|
60 | + 'Parses to the status label for the registrant', |
|
61 | + 'event_espresso' |
|
62 | + ), |
|
63 | + '[REGISTRATION_TOTAL_AMOUNT_PAID]' => esc_html__( |
|
64 | + 'Parses to the total amount paid for this registration.', |
|
65 | + 'event_espresso' |
|
66 | + ), |
|
67 | + '[FRONTEND_EDIT_REG_LINK]' => esc_html__( |
|
68 | + 'Generates a link for the given registration to edit this registration details on the frontend.', |
|
69 | + 'event_espresso' |
|
70 | + ), |
|
71 | + '[PHONE_NUMBER]' => esc_html__( |
|
72 | + 'The Phone Number for the Registration.', |
|
73 | + 'event_espresso' |
|
74 | + ), |
|
75 | + '[ADDRESS]' => esc_html__('The Address for the Registration', 'event_espresso'), |
|
76 | + '[ADDRESS2]' => esc_html__( |
|
77 | + 'Whatever was in the address 2 field for the registration.', |
|
78 | + 'event_espresso' |
|
79 | + ), |
|
80 | + '[CITY]' => esc_html__('The city for the registration.', 'event_espresso'), |
|
81 | + '[ZIP_PC]' => esc_html__( |
|
82 | + 'The ZIP (or Postal) Code for the Registration.', |
|
83 | + 'event_espresso' |
|
84 | + ), |
|
85 | + '[ADDRESS_STATE]' => esc_html__( |
|
86 | + 'The state/province for the registration.', |
|
87 | + 'event_espresso' |
|
88 | + ), |
|
89 | + '[COUNTRY]' => esc_html__('The country for the registration.', 'event_espresso'), |
|
90 | + ]; |
|
91 | + } |
|
92 | + |
|
93 | + |
|
94 | + /** |
|
95 | + * handles shortcode parsing |
|
96 | + * |
|
97 | + * @access protected |
|
98 | + * @param string $shortcode the shortcode to be parsed. |
|
99 | + * @return string |
|
100 | + * @throws EE_Error |
|
101 | + * @throws ReflectionException |
|
102 | + */ |
|
103 | + protected function _parser($shortcode) |
|
104 | + { |
|
105 | + |
|
106 | + |
|
107 | + $this->_extra = ! empty($this->_extra_data) && $this->_extra_data['data'] instanceof EE_Messages_Addressee |
|
108 | + ? $this->_extra_data['data'] |
|
109 | + : null; |
|
110 | + |
|
111 | + // incoming object should only be a registration object. |
|
112 | + $registration = ! $this->_data instanceof EE_Registration |
|
113 | + ? null |
|
114 | + : $this->_data; |
|
115 | + |
|
116 | + if (! $registration instanceof EE_Registration) { |
|
117 | + // let's attempt to get the txn_id for the error message. |
|
118 | + $txn_id = isset($this->_extra->txn) && $this->_extra->txn instanceof EE_Transaction |
|
119 | + ? $this->_extra->txn->ID() |
|
120 | + : esc_html__('Unknown', 'event_espresso'); |
|
121 | + $msg = esc_html__( |
|
122 | + 'There is no EE_Registration object in the data sent to the EE_Attendee Shortcode Parser for the messages system.', |
|
123 | + 'event_espresso' |
|
124 | + ); |
|
125 | + $dev_msg = sprintf( |
|
126 | + esc_html__('The transaction ID for this request is: %s', 'event_espresso'), |
|
127 | + $txn_id |
|
128 | + ); |
|
129 | + throw new EE_Error("{$msg}||{$msg} {$dev_msg}"); |
|
130 | + } |
|
131 | + |
|
132 | + // attendee obj for this registration |
|
133 | + $attendee = isset($this->_extra->registrations[ $registration->ID() ]['att_obj']) |
|
134 | + ? $this->_extra->registrations[ $registration->ID() ]['att_obj'] |
|
135 | + : null; |
|
136 | + |
|
137 | + if (! $attendee instanceof EE_Attendee) { |
|
138 | + $msg = esc_html__( |
|
139 | + 'There is no EE_Attendee object in the data sent to the EE_Attendee_Shortcode parser for the messages system.', |
|
140 | + 'event_espresso' |
|
141 | + ); |
|
142 | + $dev_msg = sprintf( |
|
143 | + esc_html__('The registration ID for this request is: %s', 'event_espresso'), |
|
144 | + $registration->ID() |
|
145 | + ); |
|
146 | + throw new EE_Error("{$msg}||{$msg} {$dev_msg}"); |
|
147 | + } |
|
148 | + |
|
149 | + switch ($shortcode) { |
|
150 | + case '[FNAME]': |
|
151 | + return $attendee->fname(); |
|
152 | + |
|
153 | + case '[LNAME]': |
|
154 | + return $attendee->lname(); |
|
155 | + |
|
156 | + case '[ATTENDEE_EMAIL]': |
|
157 | + return $attendee->email(); |
|
158 | + |
|
159 | + case '[EDIT_ATTENDEE_LINK]': |
|
160 | + return $registration->get_admin_edit_url(); |
|
161 | + |
|
162 | + case '[REGISTRATION_CODE]': |
|
163 | + return $registration->reg_code(); |
|
164 | + |
|
165 | + case '[REGISTRATION_ID]': |
|
166 | + return $registration->ID(); |
|
167 | + |
|
168 | + case '[FRONTEND_EDIT_REG_LINK]': |
|
169 | + return $registration->edit_attendee_information_url(); |
|
170 | + |
|
171 | + case '[PHONE_NUMBER]': |
|
172 | + return $attendee->phone(); |
|
173 | + |
|
174 | + case '[ADDRESS]': |
|
175 | + return $attendee->address(); |
|
176 | + |
|
177 | + case '[ADDRESS2]': |
|
178 | + return $attendee->address2(); |
|
179 | + |
|
180 | + case '[CITY]': |
|
181 | + return $attendee->city(); |
|
182 | + |
|
183 | + case '[ZIP_PC]': |
|
184 | + return $attendee->zip(); |
|
185 | + |
|
186 | + case '[ADDRESS_STATE]': |
|
187 | + $state_obj = $attendee->state_obj(); |
|
188 | + return $state_obj instanceof EE_State ? $state_obj->name() : ''; |
|
189 | + |
|
190 | + case '[COUNTRY]': |
|
191 | + $country_obj = $attendee->country_obj(); |
|
192 | + return $country_obj instanceof EE_Country ? $country_obj->name() : ''; |
|
193 | + |
|
194 | + case '[REGISTRATION_STATUS_ID]': |
|
195 | + return $registration->status_ID(); |
|
196 | + |
|
197 | + case '[REGISTRATION_STATUS_LABEL]': |
|
198 | + return $registration->pretty_status(); |
|
199 | + |
|
200 | + case '[REGISTRATION_TOTAL_AMOUNT_PAID]': |
|
201 | + return $registration->pretty_paid(); |
|
202 | + } |
|
203 | + |
|
204 | + return ''; |
|
205 | + } |
|
206 | 206 | } |
@@ -159,7 +159,7 @@ discard block |
||
159 | 159 | $att_result = ''; |
160 | 160 | $registrations = |
161 | 161 | isset($this->_extra_data['data']->tickets) |
162 | - ? $this->_extra_data['data']->tickets[ $ticket->ID() ]['reg_objs'] |
|
162 | + ? $this->_extra_data['data']->tickets[$ticket->ID()]['reg_objs'] |
|
163 | 163 | : []; |
164 | 164 | |
165 | 165 | // each attendee in this case should be an attendee object. |
@@ -185,7 +185,7 @@ discard block |
||
185 | 185 | private function _get_registrations_from_event(EE_Event $event) |
186 | 186 | { |
187 | 187 | return isset($this->_extra_data['data']->events) |
188 | - ? $this->_extra_data['data']->events[ $event->ID() ]['reg_objs'] |
|
188 | + ? $this->_extra_data['data']->events[$event->ID()]['reg_objs'] |
|
189 | 189 | : []; |
190 | 190 | } |
191 | 191 | } |
@@ -18,167 +18,167 @@ |
||
18 | 18 | */ |
19 | 19 | class EE_Attendee_List_Shortcodes extends EE_Shortcodes |
20 | 20 | { |
21 | - protected function _init_props() |
|
22 | - { |
|
23 | - $this->label = esc_html__('Attendee List Shortcodes', 'event_espresso'); |
|
24 | - $this->description = esc_html__('All shortcodes specific to attendee lists', 'event_espresso'); |
|
25 | - $this->_shortcodes = [ |
|
26 | - '[ATTENDEE_LIST]' => esc_html__('Will output a list of attendees', 'event_espresso'), |
|
27 | - ]; |
|
28 | - } |
|
29 | - |
|
30 | - |
|
31 | - /** |
|
32 | - * @param string $shortcode |
|
33 | - * @return string |
|
34 | - * @throws EE_Error |
|
35 | - * @throws ReflectionException |
|
36 | - */ |
|
37 | - protected function _parser($shortcode) |
|
38 | - { |
|
39 | - switch ($shortcode) { |
|
40 | - case '[ATTENDEE_LIST]': |
|
41 | - return $this->_get_attendee_list(); |
|
42 | - } |
|
43 | - return ''; |
|
44 | - } |
|
45 | - |
|
46 | - |
|
47 | - /** |
|
48 | - * figure out what the incoming data is and then return the appropriate parsed value. |
|
49 | - * |
|
50 | - * @return string |
|
51 | - * @throws EE_Error |
|
52 | - * @throws ReflectionException |
|
53 | - */ |
|
54 | - private function _get_attendee_list() |
|
55 | - { |
|
56 | - $this->_validate_list_requirements(); |
|
57 | - |
|
58 | - if ($this->_data['data'] instanceof EE_Messages_Addressee) { |
|
59 | - return $this->_get_attendee_list_for_main(); |
|
60 | - } |
|
61 | - if ($this->_data['data'] instanceof EE_Event) { |
|
62 | - return $this->_get_attendee_list_for_event(); |
|
63 | - } |
|
64 | - if ($this->_data['data'] instanceof EE_Ticket) { |
|
65 | - return $this->_get_registration_list_for_ticket(); |
|
66 | - } |
|
67 | - // prevent recursive loop |
|
68 | - return ''; |
|
69 | - } |
|
70 | - |
|
71 | - |
|
72 | - /** |
|
73 | - * This returns the parsed attendee list for main template; |
|
74 | - */ |
|
75 | - private function _get_attendee_list_for_main() |
|
76 | - { |
|
77 | - $valid_shortcodes = ['attendee', 'event_list', 'ticket_list', 'question_list', 'recipient_details']; |
|
78 | - $template = $this->_data['template']; |
|
79 | - $data = $this->_data['data']; |
|
80 | - $attendees = ''; |
|
81 | - |
|
82 | - |
|
83 | - // now we need to loop through the attendee list and send data to the EE_Parser helper. |
|
84 | - foreach ($data->reg_objs as $registration) { |
|
85 | - $attendees .= $this->_shortcode_helper->parse_attendee_list_template( |
|
86 | - $template, |
|
87 | - $registration, |
|
88 | - $valid_shortcodes, |
|
89 | - $this->_extra_data |
|
90 | - ); |
|
91 | - } |
|
92 | - |
|
93 | - return $attendees; |
|
94 | - } |
|
95 | - |
|
96 | - |
|
97 | - /** |
|
98 | - * return parsed list of attendees for an event |
|
99 | - * |
|
100 | - * @return string |
|
101 | - * @throws EE_Error |
|
102 | - * @throws ReflectionException |
|
103 | - */ |
|
104 | - private function _get_attendee_list_for_event() |
|
105 | - { |
|
106 | - $valid_shortcodes = ['attendee', 'ticket_list', 'question_list', 'recipient_details']; |
|
107 | - $template = is_array($this->_data['template']) && isset($this->_data['template']['attendee_list']) |
|
108 | - ? $this->_data['template']['attendee_list'] |
|
109 | - : $this->_extra_data['template']['attendee_list']; |
|
110 | - $event = $this->_data['data']; |
|
111 | - |
|
112 | - // let's remove any existing [EVENT_LIST] shortcode from the attendee list template so that we don't get recursion. |
|
113 | - $template = str_replace('[EVENT_LIST]', '', $template); |
|
114 | - |
|
115 | - // here we're setting up the attendees for the attendee_list template for THIS event. |
|
116 | - $att_result = ''; |
|
117 | - $registrations = $this->_get_registrations_from_event($event); |
|
118 | - |
|
119 | - // each attendee in this case should be an attendee object. |
|
120 | - foreach ($registrations as $registration) { |
|
121 | - $att_result .= $this->_shortcode_helper->parse_attendee_list_template( |
|
122 | - $template, |
|
123 | - $registration, |
|
124 | - $valid_shortcodes, |
|
125 | - $this->_extra_data |
|
126 | - ); |
|
127 | - } |
|
128 | - |
|
129 | - return $att_result; |
|
130 | - } |
|
131 | - |
|
132 | - |
|
133 | - /** |
|
134 | - * return parsed list of attendees for a ticket |
|
135 | - * |
|
136 | - * @return string |
|
137 | - */ |
|
138 | - private function _get_registration_list_for_ticket() |
|
139 | - { |
|
140 | - $valid_shortcodes = ['attendee', 'event_list', 'question_list', 'recipient_details']; |
|
141 | - $template = is_array($this->_data['template']) && isset($this->_data['template']['attendee_list']) |
|
142 | - ? $this->_data['template']['attendee_list'] |
|
143 | - : $this->_extra_data['template']['attendee_list']; |
|
144 | - $ticket = $this->_data['data']; |
|
145 | - |
|
146 | - // let's remove any existing [TICKET_LIST] (or related) shortcode from the attendee list template so that we don't get recursion. |
|
147 | - $template = str_replace('[TICKET_LIST]', '', $template); |
|
148 | - $template = str_replace('[RECIPIENT_TICKET_LIST]', '', $template); |
|
149 | - $template = str_replace('[PRIMARY_REGISTRANT_TICKET_LIST]', '', $template); |
|
150 | - |
|
151 | - // here we're setting up the attendees for the attendee_list template for THIS ticket. |
|
152 | - $att_result = ''; |
|
153 | - $registrations = |
|
154 | - isset($this->_extra_data['data']->tickets) |
|
155 | - ? $this->_extra_data['data']->tickets[ $ticket->ID() ]['reg_objs'] |
|
156 | - : []; |
|
157 | - |
|
158 | - // each attendee in this case should be an attendee object. |
|
159 | - foreach ($registrations as $registration) { |
|
160 | - $att_result .= $this->_shortcode_helper->parse_attendee_list_template( |
|
161 | - $template, |
|
162 | - $registration, |
|
163 | - $valid_shortcodes, |
|
164 | - $this->_extra_data |
|
165 | - ); |
|
166 | - } |
|
167 | - |
|
168 | - return $att_result; |
|
169 | - } |
|
170 | - |
|
171 | - |
|
172 | - /** |
|
173 | - * @param EE_Event $event |
|
174 | - * @return array|mixed |
|
175 | - * @throws EE_Error |
|
176 | - * @throws ReflectionException |
|
177 | - */ |
|
178 | - private function _get_registrations_from_event(EE_Event $event) |
|
179 | - { |
|
180 | - return isset($this->_extra_data['data']->events) |
|
181 | - ? $this->_extra_data['data']->events[ $event->ID() ]['reg_objs'] |
|
182 | - : []; |
|
183 | - } |
|
21 | + protected function _init_props() |
|
22 | + { |
|
23 | + $this->label = esc_html__('Attendee List Shortcodes', 'event_espresso'); |
|
24 | + $this->description = esc_html__('All shortcodes specific to attendee lists', 'event_espresso'); |
|
25 | + $this->_shortcodes = [ |
|
26 | + '[ATTENDEE_LIST]' => esc_html__('Will output a list of attendees', 'event_espresso'), |
|
27 | + ]; |
|
28 | + } |
|
29 | + |
|
30 | + |
|
31 | + /** |
|
32 | + * @param string $shortcode |
|
33 | + * @return string |
|
34 | + * @throws EE_Error |
|
35 | + * @throws ReflectionException |
|
36 | + */ |
|
37 | + protected function _parser($shortcode) |
|
38 | + { |
|
39 | + switch ($shortcode) { |
|
40 | + case '[ATTENDEE_LIST]': |
|
41 | + return $this->_get_attendee_list(); |
|
42 | + } |
|
43 | + return ''; |
|
44 | + } |
|
45 | + |
|
46 | + |
|
47 | + /** |
|
48 | + * figure out what the incoming data is and then return the appropriate parsed value. |
|
49 | + * |
|
50 | + * @return string |
|
51 | + * @throws EE_Error |
|
52 | + * @throws ReflectionException |
|
53 | + */ |
|
54 | + private function _get_attendee_list() |
|
55 | + { |
|
56 | + $this->_validate_list_requirements(); |
|
57 | + |
|
58 | + if ($this->_data['data'] instanceof EE_Messages_Addressee) { |
|
59 | + return $this->_get_attendee_list_for_main(); |
|
60 | + } |
|
61 | + if ($this->_data['data'] instanceof EE_Event) { |
|
62 | + return $this->_get_attendee_list_for_event(); |
|
63 | + } |
|
64 | + if ($this->_data['data'] instanceof EE_Ticket) { |
|
65 | + return $this->_get_registration_list_for_ticket(); |
|
66 | + } |
|
67 | + // prevent recursive loop |
|
68 | + return ''; |
|
69 | + } |
|
70 | + |
|
71 | + |
|
72 | + /** |
|
73 | + * This returns the parsed attendee list for main template; |
|
74 | + */ |
|
75 | + private function _get_attendee_list_for_main() |
|
76 | + { |
|
77 | + $valid_shortcodes = ['attendee', 'event_list', 'ticket_list', 'question_list', 'recipient_details']; |
|
78 | + $template = $this->_data['template']; |
|
79 | + $data = $this->_data['data']; |
|
80 | + $attendees = ''; |
|
81 | + |
|
82 | + |
|
83 | + // now we need to loop through the attendee list and send data to the EE_Parser helper. |
|
84 | + foreach ($data->reg_objs as $registration) { |
|
85 | + $attendees .= $this->_shortcode_helper->parse_attendee_list_template( |
|
86 | + $template, |
|
87 | + $registration, |
|
88 | + $valid_shortcodes, |
|
89 | + $this->_extra_data |
|
90 | + ); |
|
91 | + } |
|
92 | + |
|
93 | + return $attendees; |
|
94 | + } |
|
95 | + |
|
96 | + |
|
97 | + /** |
|
98 | + * return parsed list of attendees for an event |
|
99 | + * |
|
100 | + * @return string |
|
101 | + * @throws EE_Error |
|
102 | + * @throws ReflectionException |
|
103 | + */ |
|
104 | + private function _get_attendee_list_for_event() |
|
105 | + { |
|
106 | + $valid_shortcodes = ['attendee', 'ticket_list', 'question_list', 'recipient_details']; |
|
107 | + $template = is_array($this->_data['template']) && isset($this->_data['template']['attendee_list']) |
|
108 | + ? $this->_data['template']['attendee_list'] |
|
109 | + : $this->_extra_data['template']['attendee_list']; |
|
110 | + $event = $this->_data['data']; |
|
111 | + |
|
112 | + // let's remove any existing [EVENT_LIST] shortcode from the attendee list template so that we don't get recursion. |
|
113 | + $template = str_replace('[EVENT_LIST]', '', $template); |
|
114 | + |
|
115 | + // here we're setting up the attendees for the attendee_list template for THIS event. |
|
116 | + $att_result = ''; |
|
117 | + $registrations = $this->_get_registrations_from_event($event); |
|
118 | + |
|
119 | + // each attendee in this case should be an attendee object. |
|
120 | + foreach ($registrations as $registration) { |
|
121 | + $att_result .= $this->_shortcode_helper->parse_attendee_list_template( |
|
122 | + $template, |
|
123 | + $registration, |
|
124 | + $valid_shortcodes, |
|
125 | + $this->_extra_data |
|
126 | + ); |
|
127 | + } |
|
128 | + |
|
129 | + return $att_result; |
|
130 | + } |
|
131 | + |
|
132 | + |
|
133 | + /** |
|
134 | + * return parsed list of attendees for a ticket |
|
135 | + * |
|
136 | + * @return string |
|
137 | + */ |
|
138 | + private function _get_registration_list_for_ticket() |
|
139 | + { |
|
140 | + $valid_shortcodes = ['attendee', 'event_list', 'question_list', 'recipient_details']; |
|
141 | + $template = is_array($this->_data['template']) && isset($this->_data['template']['attendee_list']) |
|
142 | + ? $this->_data['template']['attendee_list'] |
|
143 | + : $this->_extra_data['template']['attendee_list']; |
|
144 | + $ticket = $this->_data['data']; |
|
145 | + |
|
146 | + // let's remove any existing [TICKET_LIST] (or related) shortcode from the attendee list template so that we don't get recursion. |
|
147 | + $template = str_replace('[TICKET_LIST]', '', $template); |
|
148 | + $template = str_replace('[RECIPIENT_TICKET_LIST]', '', $template); |
|
149 | + $template = str_replace('[PRIMARY_REGISTRANT_TICKET_LIST]', '', $template); |
|
150 | + |
|
151 | + // here we're setting up the attendees for the attendee_list template for THIS ticket. |
|
152 | + $att_result = ''; |
|
153 | + $registrations = |
|
154 | + isset($this->_extra_data['data']->tickets) |
|
155 | + ? $this->_extra_data['data']->tickets[ $ticket->ID() ]['reg_objs'] |
|
156 | + : []; |
|
157 | + |
|
158 | + // each attendee in this case should be an attendee object. |
|
159 | + foreach ($registrations as $registration) { |
|
160 | + $att_result .= $this->_shortcode_helper->parse_attendee_list_template( |
|
161 | + $template, |
|
162 | + $registration, |
|
163 | + $valid_shortcodes, |
|
164 | + $this->_extra_data |
|
165 | + ); |
|
166 | + } |
|
167 | + |
|
168 | + return $att_result; |
|
169 | + } |
|
170 | + |
|
171 | + |
|
172 | + /** |
|
173 | + * @param EE_Event $event |
|
174 | + * @return array|mixed |
|
175 | + * @throws EE_Error |
|
176 | + * @throws ReflectionException |
|
177 | + */ |
|
178 | + private function _get_registrations_from_event(EE_Event $event) |
|
179 | + { |
|
180 | + return isset($this->_extra_data['data']->events) |
|
181 | + ? $this->_extra_data['data']->events[ $event->ID() ]['reg_objs'] |
|
182 | + : []; |
|
183 | + } |
|
184 | 184 | } |
@@ -7,10 +7,10 @@ discard block |
||
7 | 7 | ?> |
8 | 8 | <h2><?php esc_html_e('Event Registration Data', 'event_espresso'); ?></h2> |
9 | 9 | <p><?php |
10 | - esc_html_e( |
|
11 | - 'We collect information about you during event registration. This information may include but is not limited to:', |
|
12 | - 'event_espresso' |
|
13 | - ); ?></p> |
|
10 | + esc_html_e( |
|
11 | + 'We collect information about you during event registration. This information may include but is not limited to:', |
|
12 | + 'event_espresso' |
|
13 | + ); ?></p> |
|
14 | 14 | <ul> |
15 | 15 | <li><?php esc_html_e('Your names', 'event_espresso'); ?></li> |
16 | 16 | <li><?php esc_html_e('Billing address', 'event_espresso'); ?></li> |
@@ -18,16 +18,16 @@ discard block |
||
18 | 18 | <li><?php esc_html_e('Email address', 'event_espresso'); ?></li> |
19 | 19 | <li><?php esc_html_e('Phone number', 'event_espresso'); ?></li> |
20 | 20 | <li><?php |
21 | - esc_html_e( |
|
22 | - 'Location and traffic data (including partial IP address and browser type)', |
|
23 | - 'event_espresso' |
|
24 | - ); ?> |
|
21 | + esc_html_e( |
|
22 | + 'Location and traffic data (including partial IP address and browser type)', |
|
23 | + 'event_espresso' |
|
24 | + ); ?> |
|
25 | 25 | </li> |
26 | 26 | <li><?php |
27 | - esc_html_e( |
|
28 | - 'Any other details that might be requested from you for the purpose of processing your registration or ticket purchase', |
|
29 | - 'event_espresso' |
|
30 | - ); ?> |
|
27 | + esc_html_e( |
|
28 | + 'Any other details that might be requested from you for the purpose of processing your registration or ticket purchase', |
|
29 | + 'event_espresso' |
|
30 | + ); ?> |
|
31 | 31 | </li> |
32 | 32 | </ul> |
33 | 33 | |
@@ -36,101 +36,101 @@ discard block |
||
36 | 36 | <li><?php esc_html_e('Send you important account/purchase/service information.', 'event_espresso'); ?></li> |
37 | 37 | <li><?php esc_html_e('Respond to your queries, refund requests, or complaints.', 'event_espresso'); ?></li> |
38 | 38 | <li><?php |
39 | - esc_html_e( |
|
40 | - 'Process payments and prevent fraudulent transactions. We do this on the basis of our legitimate business interests.', |
|
41 | - 'event_espresso' |
|
42 | - ); ?></li> |
|
39 | + esc_html_e( |
|
40 | + 'Process payments and prevent fraudulent transactions. We do this on the basis of our legitimate business interests.', |
|
41 | + 'event_espresso' |
|
42 | + ); ?></li> |
|
43 | 43 | <li><?php |
44 | - esc_html_e( |
|
45 | - 'Set up and administer your account, provide technical and customer support, and to verify your identity.', |
|
46 | - 'event_espresso' |
|
47 | - ); ?></li> |
|
44 | + esc_html_e( |
|
45 | + 'Set up and administer your account, provide technical and customer support, and to verify your identity.', |
|
46 | + 'event_espresso' |
|
47 | + ); ?></li> |
|
48 | 48 | </ul> |
49 | 49 | |
50 | 50 | <?php if (! empty($active_onsite_payment_methods) || ! empty($active_offsite_payment_methods)) { ?> |
51 | 51 | <h2><?php esc_html_e('Billing Information', 'event_espresso'); ?> </h2> |
52 | 52 | <?php |
53 | - // if onsite or offsite payment methods are active |
|
54 | - if (! empty($active_onsite_payment_methods)) { ?> |
|
53 | + // if onsite or offsite payment methods are active |
|
54 | + if (! empty($active_onsite_payment_methods)) { ?> |
|
55 | 55 | <p><?php |
56 | - esc_html_e( |
|
57 | - 'In order to process payments, we collect billing information on-site. Sensitive billing information is not stored on our server, but may be handled while in-transit to the payment processing server.', |
|
58 | - 'event_espresso' |
|
59 | - ); ?></p> |
|
56 | + esc_html_e( |
|
57 | + 'In order to process payments, we collect billing information on-site. Sensitive billing information is not stored on our server, but may be handled while in-transit to the payment processing server.', |
|
58 | + 'event_espresso' |
|
59 | + ); ?></p> |
|
60 | 60 | <p><?php |
61 | - printf( |
|
62 | - esc_html_x( |
|
63 | - 'Please see the privacy policy of %1$s.', |
|
64 | - 'Please see the privacy policy of PayPal Pro', |
|
65 | - 'event_espresso' |
|
66 | - ), |
|
67 | - implode( |
|
68 | - ', ', |
|
69 | - array_merge( |
|
70 | - $active_onsite_payment_methods, |
|
71 | - $active_offsite_payment_methods |
|
72 | - ) |
|
73 | - ) |
|
74 | - ); ?></p> |
|
61 | + printf( |
|
62 | + esc_html_x( |
|
63 | + 'Please see the privacy policy of %1$s.', |
|
64 | + 'Please see the privacy policy of PayPal Pro', |
|
65 | + 'event_espresso' |
|
66 | + ), |
|
67 | + implode( |
|
68 | + ', ', |
|
69 | + array_merge( |
|
70 | + $active_onsite_payment_methods, |
|
71 | + $active_offsite_payment_methods |
|
72 | + ) |
|
73 | + ) |
|
74 | + ); ?></p> |
|
75 | 75 | <p><?php |
76 | - esc_html_e( |
|
77 | - 'Masked billing information may be stored on our servers (eg only the last 4 digits of credit card numbers are stored: **** **** **** 1234).', |
|
78 | - 'event_espresso' |
|
79 | - ); ?></p> |
|
76 | + esc_html_e( |
|
77 | + 'Masked billing information may be stored on our servers (eg only the last 4 digits of credit card numbers are stored: **** **** **** 1234).', |
|
78 | + 'event_espresso' |
|
79 | + ); ?></p> |
|
80 | 80 | <?php } elseif (! empty($active_offsite_payment_methods)) { // IF OFFSITE PAYMENT METHOD ACTIVE ?> |
81 | 81 | <p><?php |
82 | - printf( |
|
83 | - esc_html_x( |
|
84 | - 'Billing information is sent directly to the payment processor, and is not handled by our servers. Please see the privacy policy of %1$s.', |
|
85 | - 'Billing information is sent directly to the payment processor, and is not handled by our servers. Please see the privacy policy of PayPal Pro.', |
|
86 | - 'event_espresso' |
|
87 | - ), |
|
88 | - implode(', ', $active_offsite_payment_methods) |
|
89 | - ); ?></p> |
|
82 | + printf( |
|
83 | + esc_html_x( |
|
84 | + 'Billing information is sent directly to the payment processor, and is not handled by our servers. Please see the privacy policy of %1$s.', |
|
85 | + 'Billing information is sent directly to the payment processor, and is not handled by our servers. Please see the privacy policy of PayPal Pro.', |
|
86 | + 'event_espresso' |
|
87 | + ), |
|
88 | + implode(', ', $active_offsite_payment_methods) |
|
89 | + ); ?></p> |
|
90 | 90 | <?php } ?> |
91 | 91 | <h2><?php esc_html_e('Payment Logging', 'event_espresso'); ?></h2> |
92 | 92 | <p><?php |
93 | - esc_html_e( |
|
94 | - 'Site administrators may keep a log of communications with the payment processors in order to verify payments are being processed correctly. These logs are automatically deleted after a week.', |
|
95 | - 'event_espresso' |
|
96 | - ); ?></p> |
|
93 | + esc_html_e( |
|
94 | + 'Site administrators may keep a log of communications with the payment processors in order to verify payments are being processed correctly. These logs are automatically deleted after a week.', |
|
95 | + 'event_espresso' |
|
96 | + ); ?></p> |
|
97 | 97 | <?php } ?> |
98 | 98 | |
99 | 99 | <h2><?php esc_html_e('Event Registration Cookies', 'event_espresso'); ?></h2> |
100 | 100 | <p><?php |
101 | - printf( |
|
102 | - esc_html_x( |
|
103 | - 'When you begin registering for an event and select a ticket quantity, a cookie will be used to track your registration. This cookie lasts %1$s.', |
|
104 | - 'When you begin registering for an event and select a ticket quantity, a cookie will be used to track your registration. This cookie lasts 2 hours.', |
|
105 | - 'event_espresso' |
|
106 | - ), |
|
107 | - $session_lifespan |
|
108 | - ); ?></p> |
|
101 | + printf( |
|
102 | + esc_html_x( |
|
103 | + 'When you begin registering for an event and select a ticket quantity, a cookie will be used to track your registration. This cookie lasts %1$s.', |
|
104 | + 'When you begin registering for an event and select a ticket quantity, a cookie will be used to track your registration. This cookie lasts 2 hours.', |
|
105 | + 'event_espresso' |
|
106 | + ), |
|
107 | + $session_lifespan |
|
108 | + ); ?></p> |
|
109 | 109 | |
110 | 110 | <h2><?php esc_html_e('Email History Data', 'event_espresso'); ?></h2> |
111 | 111 | <p><?php |
112 | - esc_html_e( |
|
113 | - 'We keep a record of the emails sent to you. This is to ensure communication is successfully sent and its information is accurate.', |
|
114 | - 'event_espresso' |
|
115 | - ); ?></p> |
|
112 | + esc_html_e( |
|
113 | + 'We keep a record of the emails sent to you. This is to ensure communication is successfully sent and its information is accurate.', |
|
114 | + 'event_espresso' |
|
115 | + ); ?></p> |
|
116 | 116 | |
117 | 117 | <h2><?php esc_html_e('Event Check-In Record', 'event_espresso'); ?></h2> |
118 | 118 | <p><?php |
119 | - esc_html_e( |
|
120 | - 'When you attend an event, an event manager may record the time you check in or out of the event.', |
|
121 | - 'event_espresso' |
|
122 | - ); ?></p> |
|
119 | + esc_html_e( |
|
120 | + 'When you attend an event, an event manager may record the time you check in or out of the event.', |
|
121 | + 'event_espresso' |
|
122 | + ); ?></p> |
|
123 | 123 | |
124 | 124 | <h2><?php esc_html_e('Event Registration Data Retention', 'event_espresso'); ?></h2> |
125 | 125 | <p><?php |
126 | - esc_html_e( |
|
127 | - 'Personal data is stored at least until the date of the event, and may be kept indefinitely in case of future registrations.', |
|
128 | - 'event_espresso' |
|
129 | - ); ?></p> |
|
126 | + esc_html_e( |
|
127 | + 'Personal data is stored at least until the date of the event, and may be kept indefinitely in case of future registrations.', |
|
128 | + 'event_espresso' |
|
129 | + ); ?></p> |
|
130 | 130 | |
131 | 131 | <h2><?php esc_html_e('Event Registration Data Erasure and Export', 'event_espresso'); ?></h2> |
132 | 132 | <p><?php |
133 | - esc_html_e( |
|
134 | - 'You have the right to request your personal data be sent to you electronically, and the right to request your registration data be erased after the event. To do so, please contact the event manager or site administrator.', |
|
135 | - 'event_espresso' |
|
136 | - ); ?></p> |
|
133 | + esc_html_e( |
|
134 | + 'You have the right to request your personal data be sent to you electronically, and the right to request your registration data be erased after the event. To do so, please contact the event manager or site administrator.', |
|
135 | + 'event_espresso' |
|
136 | + ); ?></p> |
@@ -47,11 +47,11 @@ discard block |
||
47 | 47 | ); ?></li> |
48 | 48 | </ul> |
49 | 49 | |
50 | -<?php if (! empty($active_onsite_payment_methods) || ! empty($active_offsite_payment_methods)) { ?> |
|
50 | +<?php if ( ! empty($active_onsite_payment_methods) || ! empty($active_offsite_payment_methods)) { ?> |
|
51 | 51 | <h2><?php esc_html_e('Billing Information', 'event_espresso'); ?> </h2> |
52 | 52 | <?php |
53 | 53 | // if onsite or offsite payment methods are active |
54 | - if (! empty($active_onsite_payment_methods)) { ?> |
|
54 | + if ( ! empty($active_onsite_payment_methods)) { ?> |
|
55 | 55 | <p><?php |
56 | 56 | esc_html_e( |
57 | 57 | 'In order to process payments, we collect billing information on-site. Sensitive billing information is not stored on our server, but may be handled while in-transit to the payment processing server.', |
@@ -77,7 +77,7 @@ discard block |
||
77 | 77 | 'Masked billing information may be stored on our servers (eg only the last 4 digits of credit card numbers are stored: **** **** **** 1234).', |
78 | 78 | 'event_espresso' |
79 | 79 | ); ?></p> |
80 | - <?php } elseif (! empty($active_offsite_payment_methods)) { // IF OFFSITE PAYMENT METHOD ACTIVE ?> |
|
80 | + <?php } elseif ( ! empty($active_offsite_payment_methods)) { // IF OFFSITE PAYMENT METHOD ACTIVE ?> |
|
81 | 81 | <p><?php |
82 | 82 | printf( |
83 | 83 | esc_html_x( |
@@ -11,48 +11,48 @@ |
||
11 | 11 | * @version 4+ |
12 | 12 | */ |
13 | 13 | if (have_posts()) : |
14 | - if (apply_filters('FHEE__archive_espresso_events_template__show_header', true)) : ?> |
|
14 | + if (apply_filters('FHEE__archive_espresso_events_template__show_header', true)) : ?> |
|
15 | 15 | <header class="page-header"> |
16 | 16 | <h1 class="page-title"> |
17 | 17 | <?php |
18 | - if (is_day()) : |
|
19 | - printf(esc_html__('Today\'s Events: %s', 'event_espresso'), get_the_date()); |
|
20 | - elseif (is_month()) : |
|
21 | - printf( |
|
22 | - esc_html__('Events This Month: %s', 'event_espresso'), |
|
23 | - get_the_date(_x('F Y', 'monthly archives date format', 'event_espresso')) |
|
24 | - ); |
|
25 | - elseif (is_year()) : |
|
26 | - printf( |
|
27 | - esc_html__('Events This Year: %s', 'event_espresso'), |
|
28 | - get_the_date(_x('Y', 'yearly archives date format', 'event_espresso')) |
|
29 | - ); |
|
30 | - else : |
|
31 | - echo apply_filters( |
|
32 | - 'FHEE__archive_espresso_events_template__upcoming_events_h1', |
|
33 | - esc_html__('Upcoming Events', 'event_espresso') |
|
34 | - ); |
|
35 | - endif; |
|
36 | - ?> |
|
18 | + if (is_day()) : |
|
19 | + printf(esc_html__('Today\'s Events: %s', 'event_espresso'), get_the_date()); |
|
20 | + elseif (is_month()) : |
|
21 | + printf( |
|
22 | + esc_html__('Events This Month: %s', 'event_espresso'), |
|
23 | + get_the_date(_x('F Y', 'monthly archives date format', 'event_espresso')) |
|
24 | + ); |
|
25 | + elseif (is_year()) : |
|
26 | + printf( |
|
27 | + esc_html__('Events This Year: %s', 'event_espresso'), |
|
28 | + get_the_date(_x('Y', 'yearly archives date format', 'event_espresso')) |
|
29 | + ); |
|
30 | + else : |
|
31 | + echo apply_filters( |
|
32 | + 'FHEE__archive_espresso_events_template__upcoming_events_h1', |
|
33 | + esc_html__('Upcoming Events', 'event_espresso') |
|
34 | + ); |
|
35 | + endif; |
|
36 | + ?> |
|
37 | 37 | </h1> |
38 | 38 | |
39 | 39 | </header><!-- .page-header --> |
40 | 40 | |
41 | 41 | <?php |
42 | - endif; |
|
43 | - // allow other stuff |
|
44 | - do_action('AHEE__archive_espresso_events_template__before_loop'); |
|
45 | - // Start the Loop. |
|
46 | - while (have_posts()) : the_post(); |
|
47 | - // Include the post TYPE-specific template for the content. |
|
48 | - espresso_get_template_part('content', 'espresso_events-shortcode'); |
|
49 | - endwhile; |
|
50 | - // Previous/next page navigation. |
|
51 | - espresso_pagination(); |
|
52 | - // allow moar other stuff |
|
53 | - do_action('AHEE__archive_espresso_events_template__after_loop'); |
|
42 | + endif; |
|
43 | + // allow other stuff |
|
44 | + do_action('AHEE__archive_espresso_events_template__before_loop'); |
|
45 | + // Start the Loop. |
|
46 | + while (have_posts()) : the_post(); |
|
47 | + // Include the post TYPE-specific template for the content. |
|
48 | + espresso_get_template_part('content', 'espresso_events-shortcode'); |
|
49 | + endwhile; |
|
50 | + // Previous/next page navigation. |
|
51 | + espresso_pagination(); |
|
52 | + // allow moar other stuff |
|
53 | + do_action('AHEE__archive_espresso_events_template__after_loop'); |
|
54 | 54 | else : |
55 | - // If no content, include the "No posts found" template. |
|
56 | - espresso_get_template_part('content', 'none'); |
|
55 | + // If no content, include the "No posts found" template. |
|
56 | + espresso_get_template_part('content', 'none'); |
|
57 | 57 | endif; |
58 | 58 |
@@ -27,11 +27,13 @@ discard block |
||
27 | 27 | esc_html__('Events This Year: %s', 'event_espresso'), |
28 | 28 | get_the_date(_x('Y', 'yearly archives date format', 'event_espresso')) |
29 | 29 | ); |
30 | - else : |
|
30 | + else { |
|
31 | + : |
|
31 | 32 | echo apply_filters( |
32 | 33 | 'FHEE__archive_espresso_events_template__upcoming_events_h1', |
33 | 34 | esc_html__('Upcoming Events', 'event_espresso') |
34 | 35 | ); |
36 | + } |
|
35 | 37 | endif; |
36 | 38 | ?> |
37 | 39 | </h1> |
@@ -51,8 +53,10 @@ discard block |
||
51 | 53 | espresso_pagination(); |
52 | 54 | // allow moar other stuff |
53 | 55 | do_action('AHEE__archive_espresso_events_template__after_loop'); |
54 | -else : |
|
56 | +else { |
|
57 | + : |
|
55 | 58 | // If no content, include the "No posts found" template. |
56 | 59 | espresso_get_template_part('content', 'none'); |
60 | +} |
|
57 | 61 | endif; |
58 | 62 |
@@ -9,9 +9,9 @@ discard block |
||
9 | 9 | * @ link http://www.eventespresso.com |
10 | 10 | * @ version 4+ |
11 | 11 | */ |
12 | -define( 'EE_THEME_FUNCTIONS_LOADED', TRUE ); |
|
12 | +define('EE_THEME_FUNCTIONS_LOADED', TRUE); |
|
13 | 13 | |
14 | -if ( ! function_exists( 'espresso_pagination' ) ) { |
|
14 | +if ( ! function_exists('espresso_pagination')) { |
|
15 | 15 | /** |
16 | 16 | * espresso_pagination |
17 | 17 | * |
@@ -23,21 +23,21 @@ discard block |
||
23 | 23 | $big = 999999999; // need an unlikely integer |
24 | 24 | $pagination = paginate_links( |
25 | 25 | array( |
26 | - 'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ), |
|
26 | + 'base' => str_replace($big, '%#%', esc_url(get_pagenum_link($big))), |
|
27 | 27 | 'format' => '?paged=%#%', |
28 | - 'current' => max( 1, get_query_var( 'paged' ) ), |
|
28 | + 'current' => max(1, get_query_var('paged')), |
|
29 | 29 | 'total' => $wp_query->max_num_pages, |
30 | 30 | 'show_all' => true, |
31 | 31 | 'end_size' => 10, |
32 | 32 | 'mid_size' => 6, |
33 | 33 | 'prev_next' => true, |
34 | - 'prev_text' => esc_html__( '‹ PREV', 'event_espresso' ), |
|
35 | - 'next_text' => esc_html__( 'NEXT ›', 'event_espresso' ), |
|
34 | + 'prev_text' => esc_html__('‹ PREV', 'event_espresso'), |
|
35 | + 'next_text' => esc_html__('NEXT ›', 'event_espresso'), |
|
36 | 36 | 'type' => 'plain', |
37 | 37 | 'add_args' => false, |
38 | 38 | 'add_fragment' => '' |
39 | 39 | ) |
40 | 40 | ); |
41 | - echo ! empty( $pagination ) ? '<div class="ee-pagination-dv ee-clear-float">' . $pagination . '</div>' : ''; |
|
41 | + echo ! empty($pagination) ? '<div class="ee-pagination-dv ee-clear-float">'.$pagination.'</div>' : ''; |
|
42 | 42 | } |
43 | 43 | } |
44 | 44 | \ No newline at end of file |
@@ -31,14 +31,14 @@ discard block |
||
31 | 31 | { |
32 | 32 | $filtered_reg_status = null; |
33 | 33 | |
34 | - if (! is_array($data) && $data instanceof EE_Registration) { |
|
34 | + if ( ! is_array($data) && $data instanceof EE_Registration) { |
|
35 | 35 | $this->reg_obj = $data; |
36 | 36 | } else { |
37 | 37 | $this->reg_obj = is_array($data) && isset($data[0]) && $data[0] instanceof EE_Registration ? $data[0] : null; |
38 | 38 | $filtered_reg_status = is_array($data) && ! empty($data[1]) ? $data[1] : null; |
39 | 39 | } |
40 | 40 | |
41 | - if (! $this->reg_obj instanceof EE_Registration) { |
|
41 | + if ( ! $this->reg_obj instanceof EE_Registration) { |
|
42 | 42 | throw new EE_Error( |
43 | 43 | sprintf( |
44 | 44 | esc_html__('%1$s requires the incoming data argument to be an instance of %2$s or an array where the first value is an instance of %2$s', 'event_espresso'), |
@@ -66,16 +66,16 @@ discard block |
||
66 | 66 | public static function convert_data_for_persistent_storage($data) |
67 | 67 | { |
68 | 68 | $prepped_data = array(); |
69 | - if (! is_array($data) && $data instanceof EE_Registration) { |
|
69 | + if ( ! is_array($data) && $data instanceof EE_Registration) { |
|
70 | 70 | $prepped_data['Registration'] = $data->ID(); |
71 | 71 | return $prepped_data; |
72 | - } elseif (! is_array($data)) { |
|
72 | + } elseif ( ! is_array($data)) { |
|
73 | 73 | return array(); |
74 | 74 | } else { |
75 | 75 | if ($data[0] instanceof EE_Registration) { |
76 | 76 | $prepped_data['Registration'] = $data[0]; |
77 | 77 | } |
78 | - if (! empty($data[1])) { |
|
78 | + if ( ! empty($data[1])) { |
|
79 | 79 | $prepped_data['filter'] = $data[1]; |
80 | 80 | } |
81 | 81 | } |
@@ -121,7 +121,7 @@ discard block |
||
121 | 121 | $this->txn = $this->reg_obj->transaction(); |
122 | 122 | // possible session stuff? |
123 | 123 | $session = $this->txn->session_data(); |
124 | - $session_data = $session instanceof EE_Session ? $session->get_session_data() : array(); |
|
124 | + $session_data = $session instanceof EE_Session ? $session->get_session_data() : array(); |
|
125 | 125 | |
126 | 126 | // other data from the session (if possible) |
127 | 127 | $this->user_id = isset($session_data['user_id']) ? $session_data['user_id'] : ''; |
@@ -15,137 +15,137 @@ |
||
15 | 15 | */ |
16 | 16 | class EE_Messages_REG_incoming_data extends EE_Messages_incoming_data |
17 | 17 | { |
18 | - /** |
|
19 | - * For the constructor of this special preview class. |
|
20 | - * |
|
21 | - * The data is expected to be an array that came from the request data |
|
22 | - * and should have at least one property from the list looked for. |
|
23 | - * |
|
24 | - * @param EE_Registration|array $data |
|
25 | - * @throws \EE_Error |
|
26 | - */ |
|
27 | - public function __construct($data) |
|
28 | - { |
|
29 | - $filtered_reg_status = null; |
|
30 | - |
|
31 | - if (! is_array($data) && $data instanceof EE_Registration) { |
|
32 | - $this->reg_obj = $data; |
|
33 | - } else { |
|
34 | - $this->reg_obj = is_array($data) && isset($data[0]) && $data[0] instanceof EE_Registration ? $data[0] : null; |
|
35 | - $filtered_reg_status = is_array($data) && ! empty($data[1]) ? $data[1] : null; |
|
36 | - } |
|
37 | - |
|
38 | - if (! $this->reg_obj instanceof EE_Registration) { |
|
39 | - throw new EE_Error( |
|
40 | - sprintf( |
|
41 | - esc_html__('%1$s requires the incoming data argument to be an instance of %2$s or an array where the first value is an instance of %2$s', 'event_espresso'), |
|
42 | - 'EE_Messages_REG_incoming_data', |
|
43 | - 'EE_Registration' |
|
44 | - ) |
|
45 | - ); |
|
46 | - } |
|
47 | - |
|
48 | - $data = array( |
|
49 | - 'reg_obj' => $this->reg_obj, |
|
50 | - 'filtered_reg_status' => $filtered_reg_status |
|
51 | - ); |
|
52 | - |
|
53 | - parent::__construct($data); |
|
54 | - } |
|
55 | - |
|
56 | - /** |
|
57 | - * Returns database safe representation of the data later used to when instantiating this object. |
|
58 | - * |
|
59 | - * @param mixed $data The incoming data to be prepped. |
|
60 | - * |
|
61 | - * @return array The prepped data for db |
|
62 | - */ |
|
63 | - public static function convert_data_for_persistent_storage($data) |
|
64 | - { |
|
65 | - $prepped_data = array(); |
|
66 | - if (! is_array($data) && $data instanceof EE_Registration) { |
|
67 | - $prepped_data['Registration'] = $data->ID(); |
|
68 | - return $prepped_data; |
|
69 | - } elseif (! is_array($data)) { |
|
70 | - return array(); |
|
71 | - } else { |
|
72 | - if ($data[0] instanceof EE_Registration) { |
|
73 | - $prepped_data['Registration'] = $data[0]; |
|
74 | - } |
|
75 | - if (! empty($data[1])) { |
|
76 | - $prepped_data['filter'] = $data[1]; |
|
77 | - } |
|
78 | - } |
|
79 | - |
|
80 | - return $prepped_data; |
|
81 | - } |
|
82 | - |
|
83 | - /** |
|
84 | - * Data that has been stored in persistent storage that was prepped by _convert_data_for_persistent_storage |
|
85 | - * can be sent into this method and converted back into the format used for instantiating with this data handler. |
|
86 | - * |
|
87 | - * @param $data |
|
88 | - * |
|
89 | - * @return mixed |
|
90 | - */ |
|
91 | - public static function convert_data_from_persistent_storage($data) |
|
92 | - { |
|
93 | - $registration = null; |
|
94 | - // $data['Registration'] could be either an ID (back compat) or a registration object (prepped using old system). |
|
95 | - if (isset($data['Registration'])) { |
|
96 | - $registration = $data['Registration'] instanceof EE_Registration |
|
97 | - ? $data['Registration'] |
|
98 | - : EEM_Registration::instance()->get_one_by_ID($data['Registration']); |
|
99 | - } |
|
100 | - $prepped_data = array( |
|
101 | - 0 => $registration, |
|
102 | - 1 => isset($data['filter']) ? $data['filter'] : null |
|
103 | - ); |
|
104 | - return $prepped_data; |
|
105 | - } |
|
106 | - |
|
107 | - |
|
108 | - /** |
|
109 | - * This will just setup the _events property in the expected format. |
|
110 | - * @return void |
|
111 | - */ |
|
112 | - protected function _setup_data() |
|
113 | - { |
|
114 | - |
|
115 | - // now let's loop and set up the _events property. At the same time we'll set up attendee properties. |
|
116 | - $this->filtered_reg_status = $this->_data['filtered_reg_status']; |
|
117 | - // get txn |
|
118 | - $this->txn = $this->reg_obj->transaction(); |
|
119 | - // possible session stuff? |
|
120 | - $session = $this->txn->session_data(); |
|
121 | - $session_data = $session instanceof EE_Session ? $session->get_session_data() : array(); |
|
122 | - |
|
123 | - // other data from the session (if possible) |
|
124 | - $this->user_id = isset($session_data['user_id']) ? $session_data['user_id'] : ''; |
|
125 | - $this->ip_address = isset($session_data['ip_address']) ? $session_data['ip_address'] : ''; |
|
126 | - $this->user_agent = isset($session_data['user_agent']) ? $session_data['user_agent'] : ''; |
|
127 | - $this->init_access = $this->last_access = ''; |
|
128 | - |
|
129 | - $this->payment = $this->txn->get_first_related('Payment'); |
|
130 | - // if there is no payments associated with the transaction |
|
131 | - // then we just create a default payment object for potential parsing. |
|
132 | - $this->payment = empty($this->payment) |
|
133 | - ? EE_Payment::new_instance( |
|
134 | - array( |
|
135 | - 'STS_ID' => EEM_Payment::status_id_pending, |
|
136 | - 'PAY_timestamp' => time(), |
|
137 | - 'PMD_ID' => $this->txn->payment_method_ID(), |
|
138 | - 'PAY_gateway_response' => $this->txn->gateway_response_on_transaction(), |
|
139 | - ) |
|
140 | - ) |
|
141 | - : $this->payment; |
|
142 | - |
|
143 | - |
|
144 | - // get reg_objs for txn |
|
145 | - $this->reg_objs = $this->txn->registrations(); |
|
146 | - |
|
147 | - // now we can set things up like we do for other handlers |
|
148 | - |
|
149 | - $this->_assemble_data(); |
|
150 | - } |
|
18 | + /** |
|
19 | + * For the constructor of this special preview class. |
|
20 | + * |
|
21 | + * The data is expected to be an array that came from the request data |
|
22 | + * and should have at least one property from the list looked for. |
|
23 | + * |
|
24 | + * @param EE_Registration|array $data |
|
25 | + * @throws \EE_Error |
|
26 | + */ |
|
27 | + public function __construct($data) |
|
28 | + { |
|
29 | + $filtered_reg_status = null; |
|
30 | + |
|
31 | + if (! is_array($data) && $data instanceof EE_Registration) { |
|
32 | + $this->reg_obj = $data; |
|
33 | + } else { |
|
34 | + $this->reg_obj = is_array($data) && isset($data[0]) && $data[0] instanceof EE_Registration ? $data[0] : null; |
|
35 | + $filtered_reg_status = is_array($data) && ! empty($data[1]) ? $data[1] : null; |
|
36 | + } |
|
37 | + |
|
38 | + if (! $this->reg_obj instanceof EE_Registration) { |
|
39 | + throw new EE_Error( |
|
40 | + sprintf( |
|
41 | + esc_html__('%1$s requires the incoming data argument to be an instance of %2$s or an array where the first value is an instance of %2$s', 'event_espresso'), |
|
42 | + 'EE_Messages_REG_incoming_data', |
|
43 | + 'EE_Registration' |
|
44 | + ) |
|
45 | + ); |
|
46 | + } |
|
47 | + |
|
48 | + $data = array( |
|
49 | + 'reg_obj' => $this->reg_obj, |
|
50 | + 'filtered_reg_status' => $filtered_reg_status |
|
51 | + ); |
|
52 | + |
|
53 | + parent::__construct($data); |
|
54 | + } |
|
55 | + |
|
56 | + /** |
|
57 | + * Returns database safe representation of the data later used to when instantiating this object. |
|
58 | + * |
|
59 | + * @param mixed $data The incoming data to be prepped. |
|
60 | + * |
|
61 | + * @return array The prepped data for db |
|
62 | + */ |
|
63 | + public static function convert_data_for_persistent_storage($data) |
|
64 | + { |
|
65 | + $prepped_data = array(); |
|
66 | + if (! is_array($data) && $data instanceof EE_Registration) { |
|
67 | + $prepped_data['Registration'] = $data->ID(); |
|
68 | + return $prepped_data; |
|
69 | + } elseif (! is_array($data)) { |
|
70 | + return array(); |
|
71 | + } else { |
|
72 | + if ($data[0] instanceof EE_Registration) { |
|
73 | + $prepped_data['Registration'] = $data[0]; |
|
74 | + } |
|
75 | + if (! empty($data[1])) { |
|
76 | + $prepped_data['filter'] = $data[1]; |
|
77 | + } |
|
78 | + } |
|
79 | + |
|
80 | + return $prepped_data; |
|
81 | + } |
|
82 | + |
|
83 | + /** |
|
84 | + * Data that has been stored in persistent storage that was prepped by _convert_data_for_persistent_storage |
|
85 | + * can be sent into this method and converted back into the format used for instantiating with this data handler. |
|
86 | + * |
|
87 | + * @param $data |
|
88 | + * |
|
89 | + * @return mixed |
|
90 | + */ |
|
91 | + public static function convert_data_from_persistent_storage($data) |
|
92 | + { |
|
93 | + $registration = null; |
|
94 | + // $data['Registration'] could be either an ID (back compat) or a registration object (prepped using old system). |
|
95 | + if (isset($data['Registration'])) { |
|
96 | + $registration = $data['Registration'] instanceof EE_Registration |
|
97 | + ? $data['Registration'] |
|
98 | + : EEM_Registration::instance()->get_one_by_ID($data['Registration']); |
|
99 | + } |
|
100 | + $prepped_data = array( |
|
101 | + 0 => $registration, |
|
102 | + 1 => isset($data['filter']) ? $data['filter'] : null |
|
103 | + ); |
|
104 | + return $prepped_data; |
|
105 | + } |
|
106 | + |
|
107 | + |
|
108 | + /** |
|
109 | + * This will just setup the _events property in the expected format. |
|
110 | + * @return void |
|
111 | + */ |
|
112 | + protected function _setup_data() |
|
113 | + { |
|
114 | + |
|
115 | + // now let's loop and set up the _events property. At the same time we'll set up attendee properties. |
|
116 | + $this->filtered_reg_status = $this->_data['filtered_reg_status']; |
|
117 | + // get txn |
|
118 | + $this->txn = $this->reg_obj->transaction(); |
|
119 | + // possible session stuff? |
|
120 | + $session = $this->txn->session_data(); |
|
121 | + $session_data = $session instanceof EE_Session ? $session->get_session_data() : array(); |
|
122 | + |
|
123 | + // other data from the session (if possible) |
|
124 | + $this->user_id = isset($session_data['user_id']) ? $session_data['user_id'] : ''; |
|
125 | + $this->ip_address = isset($session_data['ip_address']) ? $session_data['ip_address'] : ''; |
|
126 | + $this->user_agent = isset($session_data['user_agent']) ? $session_data['user_agent'] : ''; |
|
127 | + $this->init_access = $this->last_access = ''; |
|
128 | + |
|
129 | + $this->payment = $this->txn->get_first_related('Payment'); |
|
130 | + // if there is no payments associated with the transaction |
|
131 | + // then we just create a default payment object for potential parsing. |
|
132 | + $this->payment = empty($this->payment) |
|
133 | + ? EE_Payment::new_instance( |
|
134 | + array( |
|
135 | + 'STS_ID' => EEM_Payment::status_id_pending, |
|
136 | + 'PAY_timestamp' => time(), |
|
137 | + 'PMD_ID' => $this->txn->payment_method_ID(), |
|
138 | + 'PAY_gateway_response' => $this->txn->gateway_response_on_transaction(), |
|
139 | + ) |
|
140 | + ) |
|
141 | + : $this->payment; |
|
142 | + |
|
143 | + |
|
144 | + // get reg_objs for txn |
|
145 | + $this->reg_objs = $this->txn->registrations(); |
|
146 | + |
|
147 | + // now we can set things up like we do for other handlers |
|
148 | + |
|
149 | + $this->_assemble_data(); |
|
150 | + } |
|
151 | 151 | } |