Completed
Branch models-cleanup/model-relations (f59c0d)
by
unknown
71:29 queued 62:36
created
reg_steps/payment_options/EE_SPCO_Reg_Step_Payment_Options.class.php 3 patches
Doc Comments   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -145,7 +145,7 @@  discard block
 block discarded – undo
145 145
 
146 146
 
147 147
     /**
148
-     * @return null
148
+     * @return EE_Line_Item_Display
149 149
      */
150 150
     public function line_item_display()
151 151
     {
@@ -154,7 +154,7 @@  discard block
 block discarded – undo
154 154
 
155 155
 
156 156
     /**
157
-     * @param null $line_item_display
157
+     * @param EE_Line_Item_Display $line_item_display
158 158
      */
159 159
     public function set_line_item_display($line_item_display)
160 160
     {
@@ -882,7 +882,7 @@  discard block
 block discarded – undo
882 882
      *    _apply_registration_payments_to_amount_owing
883 883
      *
884 884
      * @access protected
885
-     * @param array $registrations
885
+     * @param EE_Base_Class[] $registrations
886 886
      * @throws EE_Error
887 887
      */
888 888
     protected function _apply_registration_payments_to_amount_owing(array $registrations)
@@ -1188,7 +1188,7 @@  discard block
 block discarded – undo
1188 1188
      * get_billing_form_html_for_payment_method
1189 1189
      *
1190 1190
      * @access public
1191
-     * @return string
1191
+     * @return boolean
1192 1192
      * @throws EE_Error
1193 1193
      * @throws InvalidArgumentException
1194 1194
      * @throws ReflectionException
@@ -1255,7 +1255,7 @@  discard block
 block discarded – undo
1255 1255
      *
1256 1256
      * @access private
1257 1257
      * @param EE_Payment_Method $payment_method
1258
-     * @return EE_Billing_Info_Form|EE_Form_Section_HTML
1258
+     * @return EE_Billing_Info_Form
1259 1259
      * @throws EE_Error
1260 1260
      * @throws InvalidArgumentException
1261 1261
      * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
@@ -1364,7 +1364,7 @@  discard block
 block discarded – undo
1364 1364
      * switch_payment_method
1365 1365
      *
1366 1366
      * @access public
1367
-     * @return string
1367
+     * @return boolean
1368 1368
      * @throws EE_Error
1369 1369
      * @throws InvalidArgumentException
1370 1370
      * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
@@ -1643,7 +1643,7 @@  discard block
 block discarded – undo
1643 1643
     /**
1644 1644
      * process_reg_step
1645 1645
      *
1646
-     * @return bool
1646
+     * @return null|boolean
1647 1647
      * @throws EE_Error
1648 1648
      * @throws InvalidArgumentException
1649 1649
      * @throws ReflectionException
@@ -1774,7 +1774,7 @@  discard block
 block discarded – undo
1774 1774
      *    update_reg_step
1775 1775
      *    this is the final step after a user  revisits the site to retry a payment
1776 1776
      *
1777
-     * @return bool
1777
+     * @return null|boolean
1778 1778
      * @throws EE_Error
1779 1779
      * @throws InvalidArgumentException
1780 1780
      * @throws ReflectionException
@@ -2221,7 +2221,7 @@  discard block
 block discarded – undo
2221 2221
      *
2222 2222
      * @access    private
2223 2223
      * @type    EE_Payment_Method $payment_method
2224
-     * @return mixed EE_Payment | boolean
2224
+     * @return EE_Payment|null EE_Payment | boolean
2225 2225
      * @throws EE_Error
2226 2226
      * @throws InvalidArgumentException
2227 2227
      * @throws ReflectionException
@@ -2546,7 +2546,7 @@  discard block
 block discarded – undo
2546 2546
      *        or present the payment options again
2547 2547
      *
2548 2548
      * @access private
2549
-     * @return EE_Payment|FALSE
2549
+     * @return boolean
2550 2550
      * @throws EE_Error
2551 2551
      * @throws InvalidArgumentException
2552 2552
      * @throws ReflectionException
@@ -2686,8 +2686,8 @@  discard block
 block discarded – undo
2686 2686
      * _redirect_wayward_request
2687 2687
      *
2688 2688
      * @access private
2689
-     * @param \EE_Registration|null $primary_registrant
2690
-     * @return bool
2689
+     * @param EE_Registration $primary_registrant
2690
+     * @return false|null
2691 2691
      * @throws EE_Error
2692 2692
      * @throws InvalidArgumentException
2693 2693
      * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
Please login to merge, or discard this patch.
Indentation   +2916 added lines, -2916 removed lines patch added patch discarded remove patch
@@ -12,2921 +12,2921 @@
 block discarded – undo
12 12
 class EE_SPCO_Reg_Step_Payment_Options extends EE_SPCO_Reg_Step
13 13
 {
14 14
 
15
-    /**
16
-     * @access protected
17
-     * @var EE_Line_Item_Display $Line_Item_Display
18
-     */
19
-    protected $line_item_display;
20
-
21
-    /**
22
-     * @access protected
23
-     * @var boolean $handle_IPN_in_this_request
24
-     */
25
-    protected $handle_IPN_in_this_request = false;
26
-
27
-
28
-    /**
29
-     *    set_hooks - for hooking into EE Core, other modules, etc
30
-     *
31
-     * @access    public
32
-     * @return    void
33
-     */
34
-    public static function set_hooks()
35
-    {
36
-        add_filter(
37
-            'FHEE__SPCO__EE_Line_Item_Filter_Collection',
38
-            array('EE_SPCO_Reg_Step_Payment_Options', 'add_spco_line_item_filters')
39
-        );
40
-        add_action(
41
-            'wp_ajax_switch_spco_billing_form',
42
-            array('EE_SPCO_Reg_Step_Payment_Options', 'switch_spco_billing_form')
43
-        );
44
-        add_action(
45
-            'wp_ajax_nopriv_switch_spco_billing_form',
46
-            array('EE_SPCO_Reg_Step_Payment_Options', 'switch_spco_billing_form')
47
-        );
48
-        add_action('wp_ajax_save_payer_details', array('EE_SPCO_Reg_Step_Payment_Options', 'save_payer_details'));
49
-        add_action(
50
-            'wp_ajax_nopriv_save_payer_details',
51
-            array('EE_SPCO_Reg_Step_Payment_Options', 'save_payer_details')
52
-        );
53
-        add_action(
54
-            'wp_ajax_get_transaction_details_for_gateways',
55
-            array('EE_SPCO_Reg_Step_Payment_Options', 'get_transaction_details')
56
-        );
57
-        add_action(
58
-            'wp_ajax_nopriv_get_transaction_details_for_gateways',
59
-            array('EE_SPCO_Reg_Step_Payment_Options', 'get_transaction_details')
60
-        );
61
-        add_filter(
62
-            'FHEE__EED_Recaptcha___bypass_recaptcha__bypass_request_params_array',
63
-            array('EE_SPCO_Reg_Step_Payment_Options', 'bypass_recaptcha_for_load_payment_method'),
64
-            10,
65
-            1
66
-        );
67
-    }
68
-
69
-
70
-    /**
71
-     *    ajax switch_spco_billing_form
72
-     *
73
-     * @throws \EE_Error
74
-     */
75
-    public static function switch_spco_billing_form()
76
-    {
77
-        EED_Single_Page_Checkout::process_ajax_request('switch_payment_method');
78
-    }
79
-
80
-
81
-    /**
82
-     *    ajax save_payer_details
83
-     *
84
-     * @throws \EE_Error
85
-     */
86
-    public static function save_payer_details()
87
-    {
88
-        EED_Single_Page_Checkout::process_ajax_request('save_payer_details_via_ajax');
89
-    }
90
-
91
-
92
-    /**
93
-     *    ajax get_transaction_details
94
-     *
95
-     * @throws \EE_Error
96
-     */
97
-    public static function get_transaction_details()
98
-    {
99
-        EED_Single_Page_Checkout::process_ajax_request('get_transaction_details_for_gateways');
100
-    }
101
-
102
-
103
-    /**
104
-     * bypass_recaptcha_for_load_payment_method
105
-     *
106
-     * @access public
107
-     * @return array
108
-     * @throws InvalidArgumentException
109
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
110
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
111
-     */
112
-    public static function bypass_recaptcha_for_load_payment_method()
113
-    {
114
-        return array(
115
-            'EESID'  => EE_Registry::instance()->SSN->id(),
116
-            'step'   => 'payment_options',
117
-            'action' => 'spco_billing_form',
118
-        );
119
-    }
120
-
121
-
122
-    /**
123
-     *    class constructor
124
-     *
125
-     * @access    public
126
-     * @param    EE_Checkout $checkout
127
-     */
128
-    public function __construct(EE_Checkout $checkout)
129
-    {
130
-        $this->_slug = 'payment_options';
131
-        $this->_name = esc_html__('Payment Options', 'event_espresso');
132
-        $this->_template = SPCO_REG_STEPS_PATH . $this->_slug . '/payment_options_main.template.php';
133
-        $this->checkout = $checkout;
134
-        $this->_reset_success_message();
135
-        $this->set_instructions(
136
-            esc_html__(
137
-                'Please select a method of payment and provide any necessary billing information before proceeding.',
138
-                'event_espresso'
139
-            )
140
-        );
141
-    }
142
-
143
-
144
-    /**
145
-     * @return null
146
-     */
147
-    public function line_item_display()
148
-    {
149
-        return $this->line_item_display;
150
-    }
151
-
152
-
153
-    /**
154
-     * @param null $line_item_display
155
-     */
156
-    public function set_line_item_display($line_item_display)
157
-    {
158
-        $this->line_item_display = $line_item_display;
159
-    }
160
-
161
-
162
-    /**
163
-     * @return boolean
164
-     */
165
-    public function handle_IPN_in_this_request()
166
-    {
167
-        return $this->handle_IPN_in_this_request;
168
-    }
169
-
170
-
171
-    /**
172
-     * @param boolean $handle_IPN_in_this_request
173
-     */
174
-    public function set_handle_IPN_in_this_request($handle_IPN_in_this_request)
175
-    {
176
-        $this->handle_IPN_in_this_request = filter_var($handle_IPN_in_this_request, FILTER_VALIDATE_BOOLEAN);
177
-    }
178
-
179
-
180
-    /**
181
-     * translate_js_strings
182
-     *
183
-     * @return void
184
-     */
185
-    public function translate_js_strings()
186
-    {
187
-        EE_Registry::$i18n_js_strings['no_payment_method'] = esc_html__(
188
-            'Please select a method of payment in order to continue.',
189
-            'event_espresso'
190
-        );
191
-        EE_Registry::$i18n_js_strings['invalid_payment_method'] = esc_html__(
192
-            'A valid method of payment could not be determined. Please refresh the page and try again.',
193
-            'event_espresso'
194
-        );
195
-        EE_Registry::$i18n_js_strings['forwarding_to_offsite'] = esc_html__(
196
-            'Forwarding to Secure Payment Provider.',
197
-            'event_espresso'
198
-        );
199
-    }
200
-
201
-
202
-    /**
203
-     * enqueue_styles_and_scripts
204
-     *
205
-     * @return void
206
-     * @throws EE_Error
207
-     * @throws InvalidArgumentException
208
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
209
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
210
-     */
211
-    public function enqueue_styles_and_scripts()
212
-    {
213
-        $transaction = $this->checkout->transaction;
214
-        // if the transaction isn't set or nothing is owed on it, don't enqueue any JS
215
-        if (! $transaction instanceof EE_Transaction || EEH_Money::compare_floats($transaction->remaining(), 0)) {
216
-            return;
217
-        }
218
-        foreach (
219
-            EEM_Payment_Method::instance()->get_all_for_transaction(
220
-                $transaction,
221
-                EEM_Payment_Method::scope_cart
222
-            ) as $payment_method
223
-        ) {
224
-            $type_obj = $payment_method->type_obj();
225
-            if ($type_obj instanceof EE_PMT_Base) {
226
-                $billing_form = $type_obj->generate_new_billing_form($transaction);
227
-                if ($billing_form instanceof EE_Form_Section_Proper) {
228
-                    $billing_form->enqueue_js();
229
-                }
230
-            }
231
-        }
232
-    }
233
-
234
-
235
-    /**
236
-     * initialize_reg_step
237
-     *
238
-     * @return bool
239
-     * @throws EE_Error
240
-     * @throws InvalidArgumentException
241
-     * @throws ReflectionException
242
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
243
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
244
-     */
245
-    public function initialize_reg_step()
246
-    {
247
-        // TODO: if /when we implement donations, then this will need overriding
248
-        if (
15
+	/**
16
+	 * @access protected
17
+	 * @var EE_Line_Item_Display $Line_Item_Display
18
+	 */
19
+	protected $line_item_display;
20
+
21
+	/**
22
+	 * @access protected
23
+	 * @var boolean $handle_IPN_in_this_request
24
+	 */
25
+	protected $handle_IPN_in_this_request = false;
26
+
27
+
28
+	/**
29
+	 *    set_hooks - for hooking into EE Core, other modules, etc
30
+	 *
31
+	 * @access    public
32
+	 * @return    void
33
+	 */
34
+	public static function set_hooks()
35
+	{
36
+		add_filter(
37
+			'FHEE__SPCO__EE_Line_Item_Filter_Collection',
38
+			array('EE_SPCO_Reg_Step_Payment_Options', 'add_spco_line_item_filters')
39
+		);
40
+		add_action(
41
+			'wp_ajax_switch_spco_billing_form',
42
+			array('EE_SPCO_Reg_Step_Payment_Options', 'switch_spco_billing_form')
43
+		);
44
+		add_action(
45
+			'wp_ajax_nopriv_switch_spco_billing_form',
46
+			array('EE_SPCO_Reg_Step_Payment_Options', 'switch_spco_billing_form')
47
+		);
48
+		add_action('wp_ajax_save_payer_details', array('EE_SPCO_Reg_Step_Payment_Options', 'save_payer_details'));
49
+		add_action(
50
+			'wp_ajax_nopriv_save_payer_details',
51
+			array('EE_SPCO_Reg_Step_Payment_Options', 'save_payer_details')
52
+		);
53
+		add_action(
54
+			'wp_ajax_get_transaction_details_for_gateways',
55
+			array('EE_SPCO_Reg_Step_Payment_Options', 'get_transaction_details')
56
+		);
57
+		add_action(
58
+			'wp_ajax_nopriv_get_transaction_details_for_gateways',
59
+			array('EE_SPCO_Reg_Step_Payment_Options', 'get_transaction_details')
60
+		);
61
+		add_filter(
62
+			'FHEE__EED_Recaptcha___bypass_recaptcha__bypass_request_params_array',
63
+			array('EE_SPCO_Reg_Step_Payment_Options', 'bypass_recaptcha_for_load_payment_method'),
64
+			10,
65
+			1
66
+		);
67
+	}
68
+
69
+
70
+	/**
71
+	 *    ajax switch_spco_billing_form
72
+	 *
73
+	 * @throws \EE_Error
74
+	 */
75
+	public static function switch_spco_billing_form()
76
+	{
77
+		EED_Single_Page_Checkout::process_ajax_request('switch_payment_method');
78
+	}
79
+
80
+
81
+	/**
82
+	 *    ajax save_payer_details
83
+	 *
84
+	 * @throws \EE_Error
85
+	 */
86
+	public static function save_payer_details()
87
+	{
88
+		EED_Single_Page_Checkout::process_ajax_request('save_payer_details_via_ajax');
89
+	}
90
+
91
+
92
+	/**
93
+	 *    ajax get_transaction_details
94
+	 *
95
+	 * @throws \EE_Error
96
+	 */
97
+	public static function get_transaction_details()
98
+	{
99
+		EED_Single_Page_Checkout::process_ajax_request('get_transaction_details_for_gateways');
100
+	}
101
+
102
+
103
+	/**
104
+	 * bypass_recaptcha_for_load_payment_method
105
+	 *
106
+	 * @access public
107
+	 * @return array
108
+	 * @throws InvalidArgumentException
109
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
110
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
111
+	 */
112
+	public static function bypass_recaptcha_for_load_payment_method()
113
+	{
114
+		return array(
115
+			'EESID'  => EE_Registry::instance()->SSN->id(),
116
+			'step'   => 'payment_options',
117
+			'action' => 'spco_billing_form',
118
+		);
119
+	}
120
+
121
+
122
+	/**
123
+	 *    class constructor
124
+	 *
125
+	 * @access    public
126
+	 * @param    EE_Checkout $checkout
127
+	 */
128
+	public function __construct(EE_Checkout $checkout)
129
+	{
130
+		$this->_slug = 'payment_options';
131
+		$this->_name = esc_html__('Payment Options', 'event_espresso');
132
+		$this->_template = SPCO_REG_STEPS_PATH . $this->_slug . '/payment_options_main.template.php';
133
+		$this->checkout = $checkout;
134
+		$this->_reset_success_message();
135
+		$this->set_instructions(
136
+			esc_html__(
137
+				'Please select a method of payment and provide any necessary billing information before proceeding.',
138
+				'event_espresso'
139
+			)
140
+		);
141
+	}
142
+
143
+
144
+	/**
145
+	 * @return null
146
+	 */
147
+	public function line_item_display()
148
+	{
149
+		return $this->line_item_display;
150
+	}
151
+
152
+
153
+	/**
154
+	 * @param null $line_item_display
155
+	 */
156
+	public function set_line_item_display($line_item_display)
157
+	{
158
+		$this->line_item_display = $line_item_display;
159
+	}
160
+
161
+
162
+	/**
163
+	 * @return boolean
164
+	 */
165
+	public function handle_IPN_in_this_request()
166
+	{
167
+		return $this->handle_IPN_in_this_request;
168
+	}
169
+
170
+
171
+	/**
172
+	 * @param boolean $handle_IPN_in_this_request
173
+	 */
174
+	public function set_handle_IPN_in_this_request($handle_IPN_in_this_request)
175
+	{
176
+		$this->handle_IPN_in_this_request = filter_var($handle_IPN_in_this_request, FILTER_VALIDATE_BOOLEAN);
177
+	}
178
+
179
+
180
+	/**
181
+	 * translate_js_strings
182
+	 *
183
+	 * @return void
184
+	 */
185
+	public function translate_js_strings()
186
+	{
187
+		EE_Registry::$i18n_js_strings['no_payment_method'] = esc_html__(
188
+			'Please select a method of payment in order to continue.',
189
+			'event_espresso'
190
+		);
191
+		EE_Registry::$i18n_js_strings['invalid_payment_method'] = esc_html__(
192
+			'A valid method of payment could not be determined. Please refresh the page and try again.',
193
+			'event_espresso'
194
+		);
195
+		EE_Registry::$i18n_js_strings['forwarding_to_offsite'] = esc_html__(
196
+			'Forwarding to Secure Payment Provider.',
197
+			'event_espresso'
198
+		);
199
+	}
200
+
201
+
202
+	/**
203
+	 * enqueue_styles_and_scripts
204
+	 *
205
+	 * @return void
206
+	 * @throws EE_Error
207
+	 * @throws InvalidArgumentException
208
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
209
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
210
+	 */
211
+	public function enqueue_styles_and_scripts()
212
+	{
213
+		$transaction = $this->checkout->transaction;
214
+		// if the transaction isn't set or nothing is owed on it, don't enqueue any JS
215
+		if (! $transaction instanceof EE_Transaction || EEH_Money::compare_floats($transaction->remaining(), 0)) {
216
+			return;
217
+		}
218
+		foreach (
219
+			EEM_Payment_Method::instance()->get_all_for_transaction(
220
+				$transaction,
221
+				EEM_Payment_Method::scope_cart
222
+			) as $payment_method
223
+		) {
224
+			$type_obj = $payment_method->type_obj();
225
+			if ($type_obj instanceof EE_PMT_Base) {
226
+				$billing_form = $type_obj->generate_new_billing_form($transaction);
227
+				if ($billing_form instanceof EE_Form_Section_Proper) {
228
+					$billing_form->enqueue_js();
229
+				}
230
+			}
231
+		}
232
+	}
233
+
234
+
235
+	/**
236
+	 * initialize_reg_step
237
+	 *
238
+	 * @return bool
239
+	 * @throws EE_Error
240
+	 * @throws InvalidArgumentException
241
+	 * @throws ReflectionException
242
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
243
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
244
+	 */
245
+	public function initialize_reg_step()
246
+	{
247
+		// TODO: if /when we implement donations, then this will need overriding
248
+		if (
249 249
 // don't need payment options for:
250
-            // registrations made via the admin
251
-            // completed transactions
252
-            // overpaid transactions
253
-            // $ 0.00 transactions(no payment required)
254
-            ! $this->checkout->payment_required()
255
-            // but do NOT remove if current action being called belongs to this reg step
256
-            && ! is_callable(array($this, $this->checkout->action))
257
-            && ! $this->completed()
258
-        ) {
259
-            // and if so, then we no longer need the Payment Options step
260
-            if ($this->is_current_step()) {
261
-                $this->checkout->generate_reg_form = false;
262
-            }
263
-            $this->checkout->remove_reg_step($this->_slug);
264
-            // DEBUG LOG
265
-            // $this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ );
266
-            return false;
267
-        }
268
-        // load EEM_Payment_Method
269
-        EE_Registry::instance()->load_model('Payment_Method');
270
-        // get all active payment methods
271
-        $this->checkout->available_payment_methods = EEM_Payment_Method::instance()->get_all_for_transaction(
272
-            $this->checkout->transaction,
273
-            EEM_Payment_Method::scope_cart
274
-        );
275
-        return true;
276
-    }
277
-
278
-
279
-    /**
280
-     * @return EE_Form_Section_Proper
281
-     * @throws EE_Error
282
-     * @throws InvalidArgumentException
283
-     * @throws ReflectionException
284
-     * @throws \EventEspresso\core\exceptions\EntityNotFoundException
285
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
286
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
287
-     * @throws \EventEspresso\core\exceptions\InvalidStatusException
288
-     */
289
-    public function generate_reg_form()
290
-    {
291
-        // reset in case someone changes their mind
292
-        $this->_reset_selected_method_of_payment();
293
-        // set some defaults
294
-        $this->checkout->selected_method_of_payment = 'payments_closed';
295
-        $registrations_requiring_payment = array();
296
-        $registrations_for_free_events = array();
297
-        $registrations_requiring_pre_approval = array();
298
-        $sold_out_events = array();
299
-        $insufficient_spaces_available = array();
300
-        $no_payment_required = true;
301
-        // loop thru registrations to gather info
302
-        $registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params);
303
-        $ejected_registrations = EE_SPCO_Reg_Step_Payment_Options::find_registrations_that_lost_their_space(
304
-            $registrations,
305
-            $this->checkout->revisit
306
-        );
307
-        foreach ($registrations as $REG_ID => $registration) {
308
-            /** @var $registration EE_Registration */
309
-            // has this registration lost it's space ?
310
-            if (isset($ejected_registrations[ $REG_ID ])) {
311
-                if ($registration->event()->is_sold_out() || $registration->event()->is_sold_out(true)) {
312
-                    $sold_out_events[ $registration->event()->ID() ] = $registration->event();
313
-                } else {
314
-                    $insufficient_spaces_available[ $registration->event()->ID() ] = $registration->event();
315
-                }
316
-                continue;
317
-            }
318
-            // event requires admin approval
319
-            if ($registration->status_ID() === EEM_Registration::status_id_not_approved) {
320
-                // add event to list of events with pre-approval reg status
321
-                $registrations_requiring_pre_approval[ $REG_ID ] = $registration;
322
-                do_action(
323
-                    'AHEE__EE_SPCO_Reg_Step_Payment_Options__generate_reg_form__event_requires_pre_approval',
324
-                    $registration->event(),
325
-                    $this
326
-                );
327
-                continue;
328
-            }
329
-            if (
330
-                $this->checkout->revisit
331
-                && $registration->status_ID() !== EEM_Registration::status_id_approved
332
-                && (
333
-                    $registration->event()->is_sold_out()
334
-                    || $registration->event()->is_sold_out(true)
335
-                )
336
-            ) {
337
-                // add event to list of events that are sold out
338
-                $sold_out_events[ $registration->event()->ID() ] = $registration->event();
339
-                do_action(
340
-                    'AHEE__EE_SPCO_Reg_Step_Payment_Options__generate_reg_form__sold_out_event',
341
-                    $registration->event(),
342
-                    $this
343
-                );
344
-                continue;
345
-            }
346
-            // are they allowed to pay now and is there monies owing?
347
-            if ($registration->owes_monies_and_can_pay()) {
348
-                $registrations_requiring_payment[ $REG_ID ] = $registration;
349
-                do_action(
350
-                    'AHEE__EE_SPCO_Reg_Step_Payment_Options__generate_reg_form__event_requires_payment',
351
-                    $registration->event(),
352
-                    $this
353
-                );
354
-            } elseif (
355
-                ! $this->checkout->revisit
356
-                      && $registration->status_ID() !== EEM_Registration::status_id_not_approved
357
-                      && $registration->ticket()->is_free()
358
-            ) {
359
-                $registrations_for_free_events[ $registration->ticket()->ID() ] = $registration;
360
-            }
361
-        }
362
-        $subsections = array();
363
-        // now decide which template to load
364
-        if (! empty($sold_out_events)) {
365
-            $subsections['sold_out_events'] = $this->_sold_out_events($sold_out_events);
366
-        }
367
-        if (! empty($insufficient_spaces_available)) {
368
-            $subsections['insufficient_space'] = $this->_insufficient_spaces_available(
369
-                $insufficient_spaces_available
370
-            );
371
-        }
372
-        if (! empty($registrations_requiring_pre_approval)) {
373
-            $subsections['registrations_requiring_pre_approval'] = $this->_registrations_requiring_pre_approval(
374
-                $registrations_requiring_pre_approval
375
-            );
376
-        }
377
-        if (! empty($registrations_for_free_events)) {
378
-            $subsections['no_payment_required'] = $this->_no_payment_required($registrations_for_free_events);
379
-        }
380
-        if (! empty($registrations_requiring_payment)) {
381
-            if ($this->checkout->amount_owing > 0) {
382
-                // autoload Line_Item_Display classes
383
-                EEH_Autoloader::register_line_item_filter_autoloaders();
384
-                $line_item_filter_processor = new EE_Line_Item_Filter_Processor(
385
-                    apply_filters(
386
-                        'FHEE__SPCO__EE_Line_Item_Filter_Collection',
387
-                        new EE_Line_Item_Filter_Collection()
388
-                    ),
389
-                    $this->checkout->cart->get_grand_total()
390
-                );
391
-                /** @var EE_Line_Item $filtered_line_item_tree */
392
-                $filtered_line_item_tree = $line_item_filter_processor->process();
393
-                EEH_Autoloader::register_line_item_display_autoloaders();
394
-                $this->set_line_item_display(new EE_Line_Item_Display('spco'));
395
-                $subsections['payment_options'] = $this->_display_payment_options(
396
-                    $this->line_item_display->display_line_item(
397
-                        $filtered_line_item_tree,
398
-                        array('registrations' => $registrations)
399
-                    )
400
-                );
401
-                $this->checkout->amount_owing = $filtered_line_item_tree->total();
402
-                $this->_apply_registration_payments_to_amount_owing($registrations);
403
-            }
404
-            $no_payment_required = false;
405
-        } else {
406
-            $this->_hide_reg_step_submit_button_if_revisit();
407
-        }
408
-        $this->_save_selected_method_of_payment();
409
-
410
-        $subsections['default_hidden_inputs'] = $this->reg_step_hidden_inputs();
411
-        $subsections['extra_hidden_inputs'] = $this->_extra_hidden_inputs($no_payment_required);
412
-
413
-        return new EE_Form_Section_Proper(
414
-            array(
415
-                'name'            => $this->reg_form_name(),
416
-                'html_id'         => $this->reg_form_name(),
417
-                'subsections'     => $subsections,
418
-                'layout_strategy' => new EE_No_Layout(),
419
-            )
420
-        );
421
-    }
422
-
423
-
424
-    /**
425
-     * add line item filters required for this reg step
426
-     * these filters are applied via this line in EE_SPCO_Reg_Step_Payment_Options::set_hooks():
427
-     *        add_filter( 'FHEE__SPCO__EE_Line_Item_Filter_Collection', array( 'EE_SPCO_Reg_Step_Payment_Options',
428
-     *        'add_spco_line_item_filters' ) ); so any code that wants to use the same set of filters during the
429
-     *        payment options reg step, can apply these filters via the following: apply_filters(
430
-     *        'FHEE__SPCO__EE_Line_Item_Filter_Collection', new EE_Line_Item_Filter_Collection() ) or to an existing
431
-     *        filter collection by passing that instead of instantiating a new collection
432
-     *
433
-     * @param \EE_Line_Item_Filter_Collection $line_item_filter_collection
434
-     * @return EE_Line_Item_Filter_Collection
435
-     * @throws EE_Error
436
-     * @throws InvalidArgumentException
437
-     * @throws ReflectionException
438
-     * @throws \EventEspresso\core\exceptions\EntityNotFoundException
439
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
440
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
441
-     * @throws \EventEspresso\core\exceptions\InvalidStatusException
442
-     */
443
-    public static function add_spco_line_item_filters(EE_Line_Item_Filter_Collection $line_item_filter_collection)
444
-    {
445
-        if (! EE_Registry::instance()->SSN instanceof EE_Session) {
446
-            return $line_item_filter_collection;
447
-        }
448
-        if (! EE_Registry::instance()->SSN->checkout() instanceof EE_Checkout) {
449
-            return $line_item_filter_collection;
450
-        }
451
-        if (! EE_Registry::instance()->SSN->checkout()->transaction instanceof EE_Transaction) {
452
-            return $line_item_filter_collection;
453
-        }
454
-        $line_item_filter_collection->add(
455
-            new EE_Billable_Line_Item_Filter(
456
-                EE_SPCO_Reg_Step_Payment_Options::remove_ejected_registrations(
457
-                    EE_Registry::instance()->SSN->checkout()->transaction->registrations(
458
-                        EE_Registry::instance()->SSN->checkout()->reg_cache_where_params
459
-                    )
460
-                )
461
-            )
462
-        );
463
-        $line_item_filter_collection->add(new EE_Non_Zero_Line_Item_Filter());
464
-        return $line_item_filter_collection;
465
-    }
466
-
467
-
468
-    /**
469
-     * remove_ejected_registrations
470
-     * if a registrant has lost their potential space at an event due to lack of payment,
471
-     * then this method removes them from the list of registrations being paid for during this request
472
-     *
473
-     * @param \EE_Registration[] $registrations
474
-     * @return EE_Registration[]
475
-     * @throws EE_Error
476
-     * @throws InvalidArgumentException
477
-     * @throws ReflectionException
478
-     * @throws \EventEspresso\core\exceptions\EntityNotFoundException
479
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
480
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
481
-     * @throws \EventEspresso\core\exceptions\InvalidStatusException
482
-     */
483
-    public static function remove_ejected_registrations(array $registrations)
484
-    {
485
-        $ejected_registrations = EE_SPCO_Reg_Step_Payment_Options::find_registrations_that_lost_their_space(
486
-            $registrations,
487
-            EE_Registry::instance()->SSN->checkout()->revisit
488
-        );
489
-        foreach ($registrations as $REG_ID => $registration) {
490
-            // has this registration lost it's space ?
491
-            if (isset($ejected_registrations[ $REG_ID ])) {
492
-                unset($registrations[ $REG_ID ]);
493
-                continue;
494
-            }
495
-        }
496
-        return $registrations;
497
-    }
498
-
499
-
500
-    /**
501
-     * find_registrations_that_lost_their_space
502
-     * If a registrant chooses an offline payment method like Invoice,
503
-     * then no space is reserved for them at the event until they fully pay fo that site
504
-     * (unless the event's default reg status is set to APPROVED)
505
-     * if a registrant then later returns to pay, but the number of spaces available has been reduced due to sales,
506
-     * then this method will determine which registrations have lost the ability to complete the reg process.
507
-     *
508
-     * @param \EE_Registration[] $registrations
509
-     * @param bool               $revisit
510
-     * @return array
511
-     * @throws EE_Error
512
-     * @throws InvalidArgumentException
513
-     * @throws ReflectionException
514
-     * @throws \EventEspresso\core\exceptions\EntityNotFoundException
515
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
516
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
517
-     * @throws \EventEspresso\core\exceptions\InvalidStatusException
518
-     */
519
-    public static function find_registrations_that_lost_their_space(array $registrations, $revisit = false)
520
-    {
521
-        // registrations per event
522
-        $event_reg_count = array();
523
-        // spaces left per event
524
-        $event_spaces_remaining = array();
525
-        // tickets left sorted by ID
526
-        $tickets_remaining = array();
527
-        // registrations that have lost their space
528
-        $ejected_registrations = array();
529
-        foreach ($registrations as $REG_ID => $registration) {
530
-            if (
531
-                $registration->status_ID() === EEM_Registration::status_id_approved
532
-                || apply_filters(
533
-                    'FHEE__EE_SPCO_Reg_Step_Payment_Options__find_registrations_that_lost_their_space__allow_reg_payment',
534
-                    false,
535
-                    $registration,
536
-                    $revisit
537
-                )
538
-            ) {
539
-                continue;
540
-            }
541
-            $EVT_ID = $registration->event_ID();
542
-            $ticket = $registration->ticket();
543
-            if (! isset($tickets_remaining[ $ticket->ID() ])) {
544
-                $tickets_remaining[ $ticket->ID() ] = $ticket->remaining();
545
-            }
546
-            if ($tickets_remaining[ $ticket->ID() ] > 0) {
547
-                if (! isset($event_reg_count[ $EVT_ID ])) {
548
-                    $event_reg_count[ $EVT_ID ] = 0;
549
-                }
550
-                $event_reg_count[ $EVT_ID ]++;
551
-                if (! isset($event_spaces_remaining[ $EVT_ID ])) {
552
-                    $event_spaces_remaining[ $EVT_ID ] = $registration->event()->spaces_remaining_for_sale();
553
-                }
554
-            }
555
-            if (
556
-                $revisit
557
-                && ($tickets_remaining[ $ticket->ID() ] === 0
558
-                    || $event_reg_count[ $EVT_ID ] > $event_spaces_remaining[ $EVT_ID ]
559
-                )
560
-            ) {
561
-                $ejected_registrations[ $REG_ID ] = $registration->event();
562
-                if ($registration->status_ID() !== EEM_Registration::status_id_wait_list) {
563
-                    /** @type EE_Registration_Processor $registration_processor */
564
-                    $registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
565
-                    // at this point, we should have enough details about the registrant to consider the registration
566
-                    // NOT incomplete
567
-                    $registration_processor->manually_update_registration_status(
568
-                        $registration,
569
-                        EEM_Registration::status_id_wait_list
570
-                    );
571
-                }
572
-            }
573
-        }
574
-        return $ejected_registrations;
575
-    }
576
-
577
-
578
-    /**
579
-     * _hide_reg_step_submit_button
580
-     * removes the html for the reg step submit button
581
-     * by replacing it with an empty string via filter callback
582
-     *
583
-     * @return void
584
-     */
585
-    protected function _adjust_registration_status_if_event_old_sold()
586
-    {
587
-    }
588
-
589
-
590
-    /**
591
-     * _hide_reg_step_submit_button
592
-     * removes the html for the reg step submit button
593
-     * by replacing it with an empty string via filter callback
594
-     *
595
-     * @return void
596
-     */
597
-    protected function _hide_reg_step_submit_button_if_revisit()
598
-    {
599
-        if ($this->checkout->revisit) {
600
-            add_filter('FHEE__EE_SPCO_Reg_Step__reg_step_submit_button__sbmt_btn_html', '__return_empty_string');
601
-        }
602
-    }
603
-
604
-
605
-    /**
606
-     * sold_out_events
607
-     * displays notices regarding events that have sold out since hte registrant first signed up
608
-     *
609
-     * @param \EE_Event[] $sold_out_events_array
610
-     * @return \EE_Form_Section_Proper
611
-     * @throws \EE_Error
612
-     */
613
-    private function _sold_out_events($sold_out_events_array = array())
614
-    {
615
-        // set some defaults
616
-        $this->checkout->selected_method_of_payment = 'events_sold_out';
617
-        $sold_out_events = '';
618
-        foreach ($sold_out_events_array as $sold_out_event) {
619
-            $sold_out_events .= EEH_HTML::li(
620
-                EEH_HTML::span(
621
-                    '  ' . $sold_out_event->name(),
622
-                    '',
623
-                    'dashicons dashicons-marker ee-icon-size-16 pink-text'
624
-                )
625
-            );
626
-        }
627
-        return new EE_Form_Section_Proper(
628
-            array(
629
-                'layout_strategy' => new EE_Template_Layout(
630
-                    array(
631
-                        'layout_template_file' => SPCO_REG_STEPS_PATH
632
-                                                  . $this->_slug
633
-                                                  . '/sold_out_events.template.php',
634
-                        'template_args'        => apply_filters(
635
-                            'FHEE__EE_SPCO_Reg_Step_Payment_Options___sold_out_events__template_args',
636
-                            array(
637
-                                'sold_out_events'     => $sold_out_events,
638
-                                'sold_out_events_msg' => apply_filters(
639
-                                    'FHEE__EE_SPCO_Reg_Step_Payment_Options___sold_out_events__sold_out_events_msg',
640
-                                    sprintf(
641
-                                        esc_html__(
642
-                                            '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',
643
-                                            'event_espresso'
644
-                                        ),
645
-                                        '<strong>',
646
-                                        '</strong>',
647
-                                        '<br />'
648
-                                    )
649
-                                ),
650
-                            )
651
-                        ),
652
-                    )
653
-                ),
654
-            )
655
-        );
656
-    }
657
-
658
-
659
-    /**
660
-     * _insufficient_spaces_available
661
-     * displays notices regarding events that do not have enough remaining spaces
662
-     * to satisfy the current number of registrations looking to pay
663
-     *
664
-     * @param \EE_Event[] $insufficient_spaces_events_array
665
-     * @return \EE_Form_Section_Proper
666
-     * @throws \EE_Error
667
-     */
668
-    private function _insufficient_spaces_available($insufficient_spaces_events_array = array())
669
-    {
670
-        // set some defaults
671
-        $this->checkout->selected_method_of_payment = 'invoice';
672
-        $insufficient_space_events = '';
673
-        foreach ($insufficient_spaces_events_array as $event) {
674
-            if ($event instanceof EE_Event) {
675
-                $insufficient_space_events .= EEH_HTML::li(
676
-                    EEH_HTML::span(' ' . $event->name(), '', 'dashicons dashicons-marker ee-icon-size-16 pink-text')
677
-                );
678
-            }
679
-        }
680
-        return new EE_Form_Section_Proper(
681
-            array(
682
-                'subsections'     => array(
683
-                    'default_hidden_inputs' => $this->reg_step_hidden_inputs(),
684
-                    'extra_hidden_inputs'   => $this->_extra_hidden_inputs(),
685
-                ),
686
-                'layout_strategy' => new EE_Template_Layout(
687
-                    array(
688
-                        'layout_template_file' => SPCO_REG_STEPS_PATH
689
-                                                  . $this->_slug
690
-                                                  . '/sold_out_events.template.php',
691
-                        'template_args'        => apply_filters(
692
-                            'FHEE__EE_SPCO_Reg_Step_Payment_Options___insufficient_spaces_available__template_args',
693
-                            array(
694
-                                'sold_out_events'     => $insufficient_space_events,
695
-                                'sold_out_events_msg' => apply_filters(
696
-                                    'FHEE__EE_SPCO_Reg_Step_Payment_Options___insufficient_spaces_available__insufficient_space_msg',
697
-                                    esc_html__(
698
-                                        '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.',
699
-                                        'event_espresso'
700
-                                    )
701
-                                ),
702
-                            )
703
-                        ),
704
-                    )
705
-                ),
706
-            )
707
-        );
708
-    }
709
-
710
-
711
-    /**
712
-     * registrations_requiring_pre_approval
713
-     *
714
-     * @param array $registrations_requiring_pre_approval
715
-     * @return EE_Form_Section_Proper
716
-     * @throws EE_Error
717
-     * @throws \EventEspresso\core\exceptions\EntityNotFoundException
718
-     */
719
-    private function _registrations_requiring_pre_approval($registrations_requiring_pre_approval = array())
720
-    {
721
-        $events_requiring_pre_approval = array();
722
-        foreach ($registrations_requiring_pre_approval as $registration) {
723
-            if ($registration instanceof EE_Registration && $registration->event() instanceof EE_Event) {
724
-                $events_requiring_pre_approval[ $registration->event()->ID() ] = EEH_HTML::li(
725
-                    EEH_HTML::span(
726
-                        '',
727
-                        '',
728
-                        'dashicons dashicons-marker ee-icon-size-16 orange-text'
729
-                    )
730
-                    . EEH_HTML::span($registration->event()->name(), '', 'orange-text')
731
-                );
732
-            }
733
-        }
734
-        return new EE_Form_Section_Proper(
735
-            array(
736
-                'layout_strategy' => new EE_Template_Layout(
737
-                    array(
738
-                        'layout_template_file' => SPCO_REG_STEPS_PATH
739
-                                                  . $this->_slug
740
-                                                  . '/events_requiring_pre_approval.template.php', // layout_template
741
-                        'template_args'        => apply_filters(
742
-                            'FHEE__EE_SPCO_Reg_Step_Payment_Options___sold_out_events__template_args',
743
-                            array(
744
-                                'events_requiring_pre_approval'     => implode('', $events_requiring_pre_approval),
745
-                                'events_requiring_pre_approval_msg' => apply_filters(
746
-                                    'FHEE__EE_SPCO_Reg_Step_Payment_Options___events_requiring_pre_approval__events_requiring_pre_approval_msg',
747
-                                    esc_html__(
748
-                                        '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.',
749
-                                        'event_espresso'
750
-                                    )
751
-                                ),
752
-                            )
753
-                        ),
754
-                    )
755
-                ),
756
-            )
757
-        );
758
-    }
759
-
760
-
761
-    /**
762
-     * _no_payment_required
763
-     *
764
-     * @param \EE_Event[] $registrations_for_free_events
765
-     * @return \EE_Form_Section_Proper
766
-     * @throws \EE_Error
767
-     */
768
-    private function _no_payment_required($registrations_for_free_events = array())
769
-    {
770
-        // set some defaults
771
-        $this->checkout->selected_method_of_payment = 'no_payment_required';
772
-        // generate no_payment_required form
773
-        return new EE_Form_Section_Proper(
774
-            array(
775
-                'layout_strategy' => new EE_Template_Layout(
776
-                    array(
777
-                        'layout_template_file' => SPCO_REG_STEPS_PATH
778
-                                                  . $this->_slug
779
-                                                  . '/no_payment_required.template.php', // layout_template
780
-                        'template_args'        => apply_filters(
781
-                            'FHEE__EE_SPCO_Reg_Step_Payment_Options___no_payment_required__template_args',
782
-                            array(
783
-                                'revisit'                       => $this->checkout->revisit,
784
-                                'registrations'                 => array(),
785
-                                'ticket_count'                  => array(),
786
-                                'registrations_for_free_events' => $registrations_for_free_events,
787
-                                'no_payment_required_msg'       => EEH_HTML::p(
788
-                                    esc_html__('This is a free event, so no billing will occur.', 'event_espresso')
789
-                                ),
790
-                            )
791
-                        ),
792
-                    )
793
-                ),
794
-            )
795
-        );
796
-    }
797
-
798
-
799
-    /**
800
-     * _display_payment_options
801
-     *
802
-     * @param string $transaction_details
803
-     * @return EE_Form_Section_Proper
804
-     * @throws EE_Error
805
-     * @throws InvalidArgumentException
806
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
807
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
808
-     */
809
-    private function _display_payment_options($transaction_details = '')
810
-    {
811
-        // has method_of_payment been set by no-js user?
812
-        $this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment();
813
-        // build payment options form
814
-        return apply_filters(
815
-            'FHEE__EE_SPCO_Reg_Step_Payment_Options___display_payment_options__payment_options_form',
816
-            new EE_Form_Section_Proper(
817
-                array(
818
-                    'subsections'     => array(
819
-                        'before_payment_options' => apply_filters(
820
-                            'FHEE__EE_SPCO_Reg_Step_Payment_Options___display_payment_options__before_payment_options',
821
-                            new EE_Form_Section_Proper(
822
-                                array('layout_strategy' => new EE_Div_Per_Section_Layout())
823
-                            )
824
-                        ),
825
-                        'payment_options'        => $this->_setup_payment_options(),
826
-                        'after_payment_options'  => apply_filters(
827
-                            'FHEE__EE_SPCO_Reg_Step_Payment_Options___display_payment_options__after_payment_options',
828
-                            new EE_Form_Section_Proper(
829
-                                array('layout_strategy' => new EE_Div_Per_Section_Layout())
830
-                            )
831
-                        ),
832
-                    ),
833
-                    'layout_strategy' => new EE_Template_Layout(
834
-                        array(
835
-                            'layout_template_file' => $this->_template,
836
-                            'template_args'        => apply_filters(
837
-                                'FHEE__EE_SPCO_Reg_Step_Payment_Options___display_payment_options__template_args',
838
-                                array(
839
-                                    'reg_count'                 => $this->line_item_display->total_items(),
840
-                                    'transaction_details'       => $transaction_details,
841
-                                    'available_payment_methods' => array(),
842
-                                )
843
-                            ),
844
-                        )
845
-                    ),
846
-                )
847
-            )
848
-        );
849
-    }
850
-
851
-
852
-    /**
853
-     * _extra_hidden_inputs
854
-     *
855
-     * @param bool $no_payment_required
856
-     * @return \EE_Form_Section_Proper
857
-     * @throws \EE_Error
858
-     */
859
-    private function _extra_hidden_inputs($no_payment_required = true)
860
-    {
861
-        return new EE_Form_Section_Proper(
862
-            array(
863
-                'html_id'         => 'ee-' . $this->slug() . '-extra-hidden-inputs',
864
-                'layout_strategy' => new EE_Div_Per_Section_Layout(),
865
-                'subsections'     => array(
866
-                    'spco_no_payment_required' => new EE_Hidden_Input(
867
-                        array(
868
-                            'normalization_strategy' => new EE_Boolean_Normalization(),
869
-                            'html_name'              => 'spco_no_payment_required',
870
-                            'html_id'                => 'spco-no-payment-required-payment_options',
871
-                            'default'                => $no_payment_required,
872
-                        )
873
-                    ),
874
-                    'spco_transaction_id'      => new EE_Fixed_Hidden_Input(
875
-                        array(
876
-                            'normalization_strategy' => new EE_Int_Normalization(),
877
-                            'html_name'              => 'spco_transaction_id',
878
-                            'html_id'                => 'spco-transaction-id',
879
-                            'default'                => $this->checkout->transaction->ID(),
880
-                        )
881
-                    ),
882
-                ),
883
-            )
884
-        );
885
-    }
886
-
887
-
888
-    /**
889
-     *    _apply_registration_payments_to_amount_owing
890
-     *
891
-     * @access protected
892
-     * @param array $registrations
893
-     * @throws EE_Error
894
-     */
895
-    protected function _apply_registration_payments_to_amount_owing(array $registrations)
896
-    {
897
-        $payments = array();
898
-        foreach ($registrations as $registration) {
899
-            if ($registration instanceof EE_Registration && $registration->owes_monies_and_can_pay()) {
900
-                $payments += $registration->registration_payments();
901
-            }
902
-        }
903
-        if (! empty($payments)) {
904
-            foreach ($payments as $payment) {
905
-                if ($payment instanceof EE_Registration_Payment) {
906
-                    $this->checkout->amount_owing -= $payment->amount();
907
-                }
908
-            }
909
-        }
910
-    }
911
-
912
-
913
-    /**
914
-     *    _reset_selected_method_of_payment
915
-     *
916
-     * @access    private
917
-     * @param    bool $force_reset
918
-     * @return void
919
-     * @throws InvalidArgumentException
920
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
921
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
922
-     */
923
-    private function _reset_selected_method_of_payment($force_reset = false)
924
-    {
925
-        $reset_payment_method = $force_reset
926
-            ? true
927
-            : sanitize_text_field(EE_Registry::instance()->REQ->get('reset_payment_method', false));
928
-        if ($reset_payment_method) {
929
-            $this->checkout->selected_method_of_payment = null;
930
-            $this->checkout->payment_method = null;
931
-            $this->checkout->billing_form = null;
932
-            $this->_save_selected_method_of_payment();
933
-        }
934
-    }
935
-
936
-
937
-    /**
938
-     * _save_selected_method_of_payment
939
-     * stores the selected_method_of_payment in the session
940
-     * so that it's available for all subsequent requests including AJAX
941
-     *
942
-     * @access        private
943
-     * @param string $selected_method_of_payment
944
-     * @return void
945
-     * @throws InvalidArgumentException
946
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
947
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
948
-     */
949
-    private function _save_selected_method_of_payment($selected_method_of_payment = '')
950
-    {
951
-        $selected_method_of_payment = ! empty($selected_method_of_payment)
952
-            ? $selected_method_of_payment
953
-            : $this->checkout->selected_method_of_payment;
954
-        EE_Registry::instance()->SSN->set_session_data(
955
-            array('selected_method_of_payment' => $selected_method_of_payment)
956
-        );
957
-    }
958
-
959
-
960
-    /**
961
-     * _setup_payment_options
962
-     *
963
-     * @return EE_Form_Section_Proper
964
-     * @throws EE_Error
965
-     * @throws InvalidArgumentException
966
-     * @throws ReflectionException
967
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
968
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
969
-     */
970
-    public function _setup_payment_options()
971
-    {
972
-        // load payment method classes
973
-        $this->checkout->available_payment_methods = $this->_get_available_payment_methods();
974
-        if (empty($this->checkout->available_payment_methods)) {
975
-            EE_Error::add_error(
976
-                apply_filters(
977
-                    'FHEE__EE_SPCO_Reg_Step_Payment_Options___setup_payment_options__error_message_no_payment_methods',
978
-                    sprintf(
979
-                        esc_html__(
980
-                            '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.',
981
-                            'event_espresso'
982
-                        ),
983
-                        '<br>',
984
-                        EE_Registry::instance()->CFG->organization->get_pretty('email')
985
-                    )
986
-                ),
987
-                __FILE__,
988
-                __FUNCTION__,
989
-                __LINE__
990
-            );
991
-        }
992
-        // switch up header depending on number of available payment methods
993
-        $payment_method_header = count($this->checkout->available_payment_methods) > 1
994
-            ? apply_filters(
995
-                'FHEE__registration_page_payment_options__method_of_payment_hdr',
996
-                esc_html__('Please Select Your Method of Payment', 'event_espresso')
997
-            )
998
-            : apply_filters(
999
-                'FHEE__registration_page_payment_options__method_of_payment_hdr',
1000
-                esc_html__('Method of Payment', 'event_espresso')
1001
-            );
1002
-        $available_payment_methods = array(
1003
-            // display the "Payment Method" header
1004
-            'payment_method_header' => new EE_Form_Section_HTML(
1005
-                apply_filters(
1006
-                    'FHEE__EE_SPCO_Reg_Step_Payment_Options___setup_payment_options__payment_method_header',
1007
-                    EEH_HTML::h4($payment_method_header, 'method-of-payment-hdr'),
1008
-                    $payment_method_header
1009
-                )
1010
-            ),
1011
-        );
1012
-        // the list of actual payment methods ( invoice, paypal, etc ) in a  ( slug => HTML )  format
1013
-        $available_payment_method_options = array();
1014
-        $default_payment_method_option = array();
1015
-        // additional instructions to be displayed and hidden below payment methods (adding a clearing div to start)
1016
-        $payment_methods_billing_info = array(
1017
-            new EE_Form_Section_HTML(
1018
-                EEH_HTML::div('<br />', '', '', 'clear:both;')
1019
-            ),
1020
-        );
1021
-        // loop through payment methods
1022
-        foreach ($this->checkout->available_payment_methods as $payment_method) {
1023
-            if ($payment_method instanceof EE_Payment_Method) {
1024
-                $payment_method_button = EEH_HTML::img(
1025
-                    $payment_method->button_url(),
1026
-                    $payment_method->name(),
1027
-                    'spco-payment-method-' . $payment_method->slug() . '-btn-img',
1028
-                    'spco-payment-method-btn-img'
1029
-                );
1030
-                // check if any payment methods are set as default
1031
-                // if payment method is already selected OR nothing is selected and this payment method should be
1032
-                // open_by_default
1033
-                if (
1034
-                    ($this->checkout->selected_method_of_payment === $payment_method->slug())
1035
-                    || (! $this->checkout->selected_method_of_payment && $payment_method->open_by_default())
1036
-                ) {
1037
-                    $this->checkout->selected_method_of_payment = $payment_method->slug();
1038
-                    $this->_save_selected_method_of_payment();
1039
-                    $default_payment_method_option[ $payment_method->slug() ] = $payment_method_button;
1040
-                } else {
1041
-                    $available_payment_method_options[ $payment_method->slug() ] = $payment_method_button;
1042
-                }
1043
-                $payment_methods_billing_info[ $payment_method->slug(
1044
-                ) . '-info' ] = $this->_payment_method_billing_info(
1045
-                    $payment_method
1046
-                );
1047
-            }
1048
-        }
1049
-        // prepend available_payment_method_options with default_payment_method_option so that it appears first in list
1050
-        // of PMs
1051
-        $available_payment_method_options = $default_payment_method_option + $available_payment_method_options;
1052
-        // now generate the actual form  inputs
1053
-        $available_payment_methods['available_payment_methods'] = $this->_available_payment_method_inputs(
1054
-            $available_payment_method_options
1055
-        );
1056
-        $available_payment_methods += $payment_methods_billing_info;
1057
-        // build the available payment methods form
1058
-        return new EE_Form_Section_Proper(
1059
-            array(
1060
-                'html_id'         => 'spco-available-methods-of-payment-dv',
1061
-                'subsections'     => $available_payment_methods,
1062
-                'layout_strategy' => new EE_Div_Per_Section_Layout(),
1063
-            )
1064
-        );
1065
-    }
1066
-
1067
-
1068
-    /**
1069
-     * _get_available_payment_methods
1070
-     *
1071
-     * @return EE_Payment_Method[]
1072
-     * @throws EE_Error
1073
-     * @throws InvalidArgumentException
1074
-     * @throws ReflectionException
1075
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1076
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1077
-     */
1078
-    protected function _get_available_payment_methods()
1079
-    {
1080
-        if (! empty($this->checkout->available_payment_methods)) {
1081
-            return $this->checkout->available_payment_methods;
1082
-        }
1083
-        $available_payment_methods = array();
1084
-        // load EEM_Payment_Method
1085
-        EE_Registry::instance()->load_model('Payment_Method');
1086
-        /** @type EEM_Payment_Method $EEM_Payment_Method */
1087
-        $EEM_Payment_Method = EE_Registry::instance()->LIB->EEM_Payment_Method;
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
-     */
1109
-    private function _available_payment_method_inputs($available_payment_method_options = array())
1110
-    {
1111
-        // generate inputs
1112
-        return new EE_Form_Section_Proper(
1113
-            array(
1114
-                'html_id'         => 'ee-available-payment-method-inputs',
1115
-                'layout_strategy' => new EE_Div_Per_Section_Layout(),
1116
-                'subsections'     => array(
1117
-                    '' => new EE_Radio_Button_Input(
1118
-                        $available_payment_method_options,
1119
-                        array(
1120
-                            'html_name'          => 'selected_method_of_payment',
1121
-                            'html_class'         => 'spco-payment-method',
1122
-                            'default'            => $this->checkout->selected_method_of_payment,
1123
-                            'label_size'         => 11,
1124
-                            'enforce_label_size' => true,
1125
-                        )
1126
-                    ),
1127
-                ),
1128
-            )
1129
-        );
1130
-    }
1131
-
1132
-
1133
-    /**
1134
-     *    _payment_method_billing_info
1135
-     *
1136
-     * @access    private
1137
-     * @param    EE_Payment_Method $payment_method
1138
-     * @return EE_Form_Section_Proper
1139
-     * @throws EE_Error
1140
-     * @throws InvalidArgumentException
1141
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1142
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1143
-     */
1144
-    private function _payment_method_billing_info(EE_Payment_Method $payment_method)
1145
-    {
1146
-        $currently_selected = $this->checkout->selected_method_of_payment === $payment_method->slug()
1147
-            ? true
1148
-            : false;
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
-            array(
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'     => array(
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
-     * @access public
1208
-     * @return string
1209
-     * @throws EE_Error
1210
-     * @throws InvalidArgumentException
1211
-     * @throws ReflectionException
1212
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1213
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1214
-     */
1215
-    public function get_billing_form_html_for_payment_method()
1216
-    {
1217
-        // how have they chosen to pay?
1218
-        $this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment(true);
1219
-        $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment();
1220
-        if (! $this->checkout->payment_method instanceof EE_Payment_Method) {
1221
-            return false;
1222
-        }
1223
-        if (
1224
-            apply_filters(
1225
-                'FHEE__EE_SPCO_Reg_Step_Payment_Options__registration_checkout__selected_payment_method__display_success',
1226
-                false
1227
-            )
1228
-        ) {
1229
-            EE_Error::add_success(
1230
-                apply_filters(
1231
-                    'FHEE__Single_Page_Checkout__registration_checkout__selected_payment_method',
1232
-                    sprintf(
1233
-                        esc_html__(
1234
-                            'You have selected "%s" as your method of payment. Please note the important payment information below.',
1235
-                            'event_espresso'
1236
-                        ),
1237
-                        $this->checkout->payment_method->name()
1238
-                    )
1239
-                )
1240
-            );
1241
-        }
1242
-        // now generate billing form for selected method of payment
1243
-        $payment_method_billing_form = $this->_get_billing_form_for_payment_method($this->checkout->payment_method);
1244
-        // fill form with attendee info if applicable
1245
-        if (
1246
-            $payment_method_billing_form instanceof EE_Billing_Attendee_Info_Form
1247
-            && $this->checkout->transaction_has_primary_registrant()
1248
-        ) {
1249
-            $payment_method_billing_form->populate_from_attendee(
1250
-                $this->checkout->transaction->primary_registration()->attendee()
1251
-            );
1252
-        }
1253
-        // and debug content
1254
-        if (
1255
-            $payment_method_billing_form instanceof EE_Billing_Info_Form
1256
-            && $this->checkout->payment_method->type_obj() instanceof EE_PMT_Base
1257
-        ) {
1258
-            $payment_method_billing_form =
1259
-                $this->checkout->payment_method->type_obj()->apply_billing_form_debug_settings(
1260
-                    $payment_method_billing_form
1261
-                );
1262
-        }
1263
-        $billing_info = $payment_method_billing_form instanceof EE_Form_Section_Proper
1264
-            ? $payment_method_billing_form->get_html()
1265
-            : '';
1266
-        $this->checkout->json_response->set_return_data(array('payment_method_info' => $billing_info));
1267
-        // localize validation rules for main form
1268
-        $this->checkout->current_step->reg_form->localize_validation_rules();
1269
-        $this->checkout->json_response->add_validation_rules(EE_Form_Section_Proper::js_localization());
1270
-        return true;
1271
-    }
1272
-
1273
-
1274
-    /**
1275
-     * _get_billing_form_for_payment_method
1276
-     *
1277
-     * @access private
1278
-     * @param EE_Payment_Method $payment_method
1279
-     * @return EE_Billing_Info_Form|EE_Form_Section_HTML
1280
-     * @throws EE_Error
1281
-     * @throws InvalidArgumentException
1282
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1283
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1284
-     */
1285
-    private function _get_billing_form_for_payment_method(EE_Payment_Method $payment_method)
1286
-    {
1287
-        $billing_form = $payment_method->type_obj()->billing_form(
1288
-            $this->checkout->transaction,
1289
-            array('amount_owing' => $this->checkout->amount_owing)
1290
-        );
1291
-        if ($billing_form instanceof EE_Billing_Info_Form) {
1292
-            if (
1293
-                apply_filters(
1294
-                    'FHEE__EE_SPCO_Reg_Step_Payment_Options__registration_checkout__selected_payment_method__display_success',
1295
-                    false
1296
-                )
1297
-                && EE_Registry::instance()->REQ->is_set('payment_method')
1298
-            ) {
1299
-                EE_Error::add_success(
1300
-                    apply_filters(
1301
-                        'FHEE__Single_Page_Checkout__registration_checkout__selected_payment_method',
1302
-                        sprintf(
1303
-                            esc_html__(
1304
-                                'You have selected "%s" as your method of payment. Please note the important payment information below.',
1305
-                                'event_espresso'
1306
-                            ),
1307
-                            $payment_method->name()
1308
-                        )
1309
-                    )
1310
-                );
1311
-            }
1312
-            return apply_filters(
1313
-                'FHEE__EE_SPCO_Reg_Step_Payment_Options___get_billing_form_for_payment_method__billing_form',
1314
-                $billing_form,
1315
-                $payment_method
1316
-            );
1317
-        }
1318
-        // no actual billing form, so return empty HTML form section
1319
-        return new EE_Form_Section_HTML();
1320
-    }
1321
-
1322
-
1323
-    /**
1324
-     * _get_selected_method_of_payment
1325
-     *
1326
-     * @access private
1327
-     * @param boolean $required whether to throw an error if the "selected_method_of_payment"
1328
-     *                          is not found in the incoming request
1329
-     * @param string  $request_param
1330
-     * @return NULL|string
1331
-     * @throws EE_Error
1332
-     * @throws InvalidArgumentException
1333
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1334
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1335
-     */
1336
-    private function _get_selected_method_of_payment(
1337
-        $required = false,
1338
-        $request_param = 'selected_method_of_payment'
1339
-    ) {
1340
-        // is selected_method_of_payment set in the request ?
1341
-        $selected_method_of_payment = EE_Registry::instance()->REQ->get($request_param, false);
1342
-        if ($selected_method_of_payment) {
1343
-            // sanitize it
1344
-            $selected_method_of_payment = is_array($selected_method_of_payment)
1345
-                ? array_shift($selected_method_of_payment)
1346
-                : $selected_method_of_payment;
1347
-            $selected_method_of_payment = sanitize_text_field($selected_method_of_payment);
1348
-            // store it in the session so that it's available for all subsequent requests including AJAX
1349
-            $this->_save_selected_method_of_payment($selected_method_of_payment);
1350
-        } else {
1351
-            // or is is set in the session ?
1352
-            $selected_method_of_payment = EE_Registry::instance()->SSN->get_session_data(
1353
-                'selected_method_of_payment'
1354
-            );
1355
-        }
1356
-        // do ya really really gotta have it?
1357
-        if (empty($selected_method_of_payment) && $required) {
1358
-            EE_Error::add_error(
1359
-                sprintf(
1360
-                    esc_html__(
1361
-                        '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.',
1362
-                        'event_espresso'
1363
-                    ),
1364
-                    '<br/>',
1365
-                    '<br/>',
1366
-                    EE_Registry::instance()->CFG->organization->get_pretty('email')
1367
-                ),
1368
-                __FILE__,
1369
-                __FUNCTION__,
1370
-                __LINE__
1371
-            );
1372
-            return null;
1373
-        }
1374
-        return $selected_method_of_payment;
1375
-    }
1376
-
1377
-
1378
-
1379
-
1380
-
1381
-
1382
-    /********************************************************************************************************/
1383
-    /***********************************  SWITCH PAYMENT METHOD  ************************************/
1384
-    /********************************************************************************************************/
1385
-    /**
1386
-     * switch_payment_method
1387
-     *
1388
-     * @access public
1389
-     * @return string
1390
-     * @throws EE_Error
1391
-     * @throws InvalidArgumentException
1392
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1393
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1394
-     */
1395
-    public function switch_payment_method()
1396
-    {
1397
-        if (! $this->_verify_payment_method_is_set()) {
1398
-            return false;
1399
-        }
1400
-        if (
1401
-            apply_filters(
1402
-                'FHEE__EE_SPCO_Reg_Step_Payment_Options__registration_checkout__selected_payment_method__display_success',
1403
-                false
1404
-            )
1405
-        ) {
1406
-            EE_Error::add_success(
1407
-                apply_filters(
1408
-                    'FHEE__Single_Page_Checkout__registration_checkout__selected_payment_method',
1409
-                    sprintf(
1410
-                        esc_html__(
1411
-                            'You have selected "%s" as your method of payment. Please note the important payment information below.',
1412
-                            'event_espresso'
1413
-                        ),
1414
-                        $this->checkout->payment_method->name()
1415
-                    )
1416
-                )
1417
-            );
1418
-        }
1419
-        // generate billing form for selected method of payment if it hasn't been done already
1420
-        if ($this->checkout->payment_method->type_obj()->has_billing_form()) {
1421
-            $this->checkout->billing_form = $this->_get_billing_form_for_payment_method(
1422
-                $this->checkout->payment_method
1423
-            );
1424
-        }
1425
-        // fill form with attendee info if applicable
1426
-        if (
1427
-            apply_filters(
1428
-                'FHEE__populate_billing_form_fields_from_attendee',
1429
-                (
1430
-                $this->checkout->billing_form instanceof EE_Billing_Attendee_Info_Form
1431
-                && $this->checkout->transaction_has_primary_registrant()
1432
-                ),
1433
-                $this->checkout->billing_form,
1434
-                $this->checkout->transaction
1435
-            )
1436
-        ) {
1437
-            $this->checkout->billing_form->populate_from_attendee(
1438
-                $this->checkout->transaction->primary_registration()->attendee()
1439
-            );
1440
-        }
1441
-        // and debug content
1442
-        if (
1443
-            $this->checkout->billing_form instanceof EE_Billing_Info_Form
1444
-            && $this->checkout->payment_method->type_obj() instanceof EE_PMT_Base
1445
-        ) {
1446
-            $this->checkout->billing_form =
1447
-                $this->checkout->payment_method->type_obj()->apply_billing_form_debug_settings(
1448
-                    $this->checkout->billing_form
1449
-                );
1450
-        }
1451
-        // get html and validation rules for form
1452
-        if ($this->checkout->billing_form instanceof EE_Form_Section_Proper) {
1453
-            $this->checkout->json_response->set_return_data(
1454
-                array('payment_method_info' => $this->checkout->billing_form->get_html())
1455
-            );
1456
-            // localize validation rules for main form
1457
-            $this->checkout->billing_form->localize_validation_rules(true);
1458
-            $this->checkout->json_response->add_validation_rules(EE_Form_Section_Proper::js_localization());
1459
-        } else {
1460
-            $this->checkout->json_response->set_return_data(array('payment_method_info' => ''));
1461
-        }
1462
-        // prevents advancement to next step
1463
-        $this->checkout->continue_reg = false;
1464
-        return true;
1465
-    }
1466
-
1467
-
1468
-    /**
1469
-     * _verify_payment_method_is_set
1470
-     *
1471
-     * @return bool
1472
-     * @throws EE_Error
1473
-     * @throws InvalidArgumentException
1474
-     * @throws ReflectionException
1475
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1476
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1477
-     */
1478
-    protected function _verify_payment_method_is_set()
1479
-    {
1480
-        // generate billing form for selected method of payment if it hasn't been done already
1481
-        if (empty($this->checkout->selected_method_of_payment)) {
1482
-            // how have they chosen to pay?
1483
-            $this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment(true);
1484
-        } else {
1485
-            // choose your own adventure based on method_of_payment
1486
-            switch ($this->checkout->selected_method_of_payment) {
1487
-                case 'events_sold_out':
1488
-                    EE_Error::add_attention(
1489
-                        apply_filters(
1490
-                            'FHEE__EE_SPCO_Reg_Step_Payment_Options___verify_payment_method_is_set__sold_out_events_msg',
1491
-                            esc_html__(
1492
-                                '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.',
1493
-                                'event_espresso'
1494
-                            )
1495
-                        ),
1496
-                        __FILE__,
1497
-                        __FUNCTION__,
1498
-                        __LINE__
1499
-                    );
1500
-                    return false;
1501
-                    break;
1502
-                case 'payments_closed':
1503
-                    EE_Error::add_attention(
1504
-                        apply_filters(
1505
-                            'FHEE__EE_SPCO_Reg_Step_Payment_Options___verify_payment_method_is_set__payments_closed_msg',
1506
-                            esc_html__(
1507
-                                '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.',
1508
-                                'event_espresso'
1509
-                            )
1510
-                        ),
1511
-                        __FILE__,
1512
-                        __FUNCTION__,
1513
-                        __LINE__
1514
-                    );
1515
-                    return false;
1516
-                    break;
1517
-                case 'no_payment_required':
1518
-                    EE_Error::add_attention(
1519
-                        apply_filters(
1520
-                            'FHEE__EE_SPCO_Reg_Step_Payment_Options___verify_payment_method_is_set__no_payment_required_msg',
1521
-                            esc_html__(
1522
-                                '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.',
1523
-                                'event_espresso'
1524
-                            )
1525
-                        ),
1526
-                        __FILE__,
1527
-                        __FUNCTION__,
1528
-                        __LINE__
1529
-                    );
1530
-                    return false;
1531
-                    break;
1532
-                default:
1533
-            }
1534
-        }
1535
-        // verify payment method
1536
-        if (! $this->checkout->payment_method instanceof EE_Payment_Method) {
1537
-            // get payment method for selected method of payment
1538
-            $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment();
1539
-        }
1540
-        return $this->checkout->payment_method instanceof EE_Payment_Method ? true : false;
1541
-    }
1542
-
1543
-
1544
-
1545
-    /********************************************************************************************************/
1546
-    /***************************************  SAVE PAYER DETAILS  ****************************************/
1547
-    /********************************************************************************************************/
1548
-    /**
1549
-     * save_payer_details_via_ajax
1550
-     *
1551
-     * @return void
1552
-     * @throws EE_Error
1553
-     * @throws InvalidArgumentException
1554
-     * @throws ReflectionException
1555
-     * @throws RuntimeException
1556
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1557
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1558
-     */
1559
-    public function save_payer_details_via_ajax()
1560
-    {
1561
-        if (! $this->_verify_payment_method_is_set()) {
1562
-            return;
1563
-        }
1564
-        // generate billing form for selected method of payment if it hasn't been done already
1565
-        if ($this->checkout->payment_method->type_obj()->has_billing_form()) {
1566
-            $this->checkout->billing_form = $this->_get_billing_form_for_payment_method(
1567
-                $this->checkout->payment_method
1568
-            );
1569
-        }
1570
-        // generate primary attendee from payer info if applicable
1571
-        if (! $this->checkout->transaction_has_primary_registrant()) {
1572
-            $attendee = $this->_create_attendee_from_request_data();
1573
-            if ($attendee instanceof EE_Attendee) {
1574
-                foreach ($this->checkout->transaction->registrations() as $registration) {
1575
-                    if ($registration->is_primary_registrant()) {
1576
-                        $this->checkout->primary_attendee_obj = $attendee;
1577
-                        $registration->_add_relation_to($attendee, 'Attendee');
1578
-                        $registration->set_attendee_id($attendee->ID());
1579
-                        $registration->update_cache_after_object_save('Attendee', $attendee);
1580
-                    }
1581
-                }
1582
-            }
1583
-        }
1584
-    }
1585
-
1586
-
1587
-    /**
1588
-     * create_attendee_from_request_data
1589
-     * uses info from alternate GET or POST data (such as AJAX) to create a new attendee
1590
-     *
1591
-     * @return EE_Attendee
1592
-     * @throws EE_Error
1593
-     * @throws InvalidArgumentException
1594
-     * @throws ReflectionException
1595
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1596
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1597
-     */
1598
-    protected function _create_attendee_from_request_data()
1599
-    {
1600
-        // get State ID
1601
-        $STA_ID = ! empty($_REQUEST['state']) ? sanitize_text_field($_REQUEST['state']) : '';
1602
-        if (! empty($STA_ID)) {
1603
-            // can we get state object from name ?
1604
-            EE_Registry::instance()->load_model('State');
1605
-            $state = EEM_State::instance()->get_col(array(array('STA_name' => $STA_ID), 'limit' => 1), 'STA_ID');
1606
-            $STA_ID = is_array($state) && ! empty($state) ? reset($state) : $STA_ID;
1607
-        }
1608
-        // get Country ISO
1609
-        $CNT_ISO = ! empty($_REQUEST['country']) ? sanitize_text_field($_REQUEST['country']) : '';
1610
-        if (! empty($CNT_ISO)) {
1611
-            // can we get country object from name ?
1612
-            EE_Registry::instance()->load_model('Country');
1613
-            $country = EEM_Country::instance()->get_col(
1614
-                array(array('CNT_name' => $CNT_ISO), 'limit' => 1),
1615
-                'CNT_ISO'
1616
-            );
1617
-            $CNT_ISO = is_array($country) && ! empty($country) ? reset($country) : $CNT_ISO;
1618
-        }
1619
-        // grab attendee data
1620
-        $attendee_data = array(
1621
-            'ATT_fname'    => ! empty($_REQUEST['first_name']) ? sanitize_text_field($_REQUEST['first_name']) : '',
1622
-            'ATT_lname'    => ! empty($_REQUEST['last_name']) ? sanitize_text_field($_REQUEST['last_name']) : '',
1623
-            'ATT_email'    => ! empty($_REQUEST['email']) ? sanitize_email($_REQUEST['email']) : '',
1624
-            'ATT_address'  => ! empty($_REQUEST['address']) ? sanitize_text_field($_REQUEST['address']) : '',
1625
-            'ATT_address2' => ! empty($_REQUEST['address2']) ? sanitize_text_field($_REQUEST['address2']) : '',
1626
-            'ATT_city'     => ! empty($_REQUEST['city']) ? sanitize_text_field($_REQUEST['city']) : '',
1627
-            'STA_ID'       => $STA_ID,
1628
-            'CNT_ISO'      => $CNT_ISO,
1629
-            'ATT_zip'      => ! empty($_REQUEST['zip']) ? sanitize_text_field($_REQUEST['zip']) : '',
1630
-            'ATT_phone'    => ! empty($_REQUEST['phone']) ? sanitize_text_field($_REQUEST['phone']) : '',
1631
-        );
1632
-        // validate the email address since it is the most important piece of info
1633
-        if (empty($attendee_data['ATT_email']) || $attendee_data['ATT_email'] !== $_REQUEST['email']) {
1634
-            EE_Error::add_error(
1635
-                esc_html__('An invalid email address was submitted.', 'event_espresso'),
1636
-                __FILE__,
1637
-                __FUNCTION__,
1638
-                __LINE__
1639
-            );
1640
-        }
1641
-        // does this attendee already exist in the db ? we're searching using a combination of first name, last name,
1642
-        // AND email address
1643
-        if (
1644
-            ! empty($attendee_data['ATT_fname'])
1645
-            && ! empty($attendee_data['ATT_lname'])
1646
-            && ! empty($attendee_data['ATT_email'])
1647
-        ) {
1648
-            $existing_attendee = EE_Registry::instance()->LIB->EEM_Attendee->find_existing_attendee(
1649
-                array(
1650
-                    'ATT_fname' => $attendee_data['ATT_fname'],
1651
-                    'ATT_lname' => $attendee_data['ATT_lname'],
1652
-                    'ATT_email' => $attendee_data['ATT_email'],
1653
-                )
1654
-            );
1655
-            if ($existing_attendee instanceof EE_Attendee) {
1656
-                return $existing_attendee;
1657
-            }
1658
-        }
1659
-        // no existing attendee? kk let's create a new one
1660
-        // kinda lame, but we need a first and last name to create an attendee, so use the email address if those
1661
-        // don't exist
1662
-        $attendee_data['ATT_fname'] = ! empty($attendee_data['ATT_fname'])
1663
-            ? $attendee_data['ATT_fname']
1664
-            : $attendee_data['ATT_email'];
1665
-        $attendee_data['ATT_lname'] = ! empty($attendee_data['ATT_lname'])
1666
-            ? $attendee_data['ATT_lname']
1667
-            : $attendee_data['ATT_email'];
1668
-        return EE_Attendee::new_instance($attendee_data);
1669
-    }
1670
-
1671
-
1672
-
1673
-    /********************************************************************************************************/
1674
-    /****************************************  PROCESS REG STEP  *****************************************/
1675
-    /********************************************************************************************************/
1676
-    /**
1677
-     * process_reg_step
1678
-     *
1679
-     * @return bool
1680
-     * @throws EE_Error
1681
-     * @throws InvalidArgumentException
1682
-     * @throws ReflectionException
1683
-     * @throws \EventEspresso\core\exceptions\EntityNotFoundException
1684
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1685
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1686
-     * @throws \EventEspresso\core\exceptions\InvalidStatusException
1687
-     */
1688
-    public function process_reg_step()
1689
-    {
1690
-        // how have they chosen to pay?
1691
-        $this->checkout->selected_method_of_payment = $this->checkout->transaction->is_free()
1692
-            ? 'no_payment_required'
1693
-            : $this->_get_selected_method_of_payment(true);
1694
-        // choose your own adventure based on method_of_payment
1695
-        switch ($this->checkout->selected_method_of_payment) {
1696
-            case 'events_sold_out':
1697
-                $this->checkout->redirect = true;
1698
-                $this->checkout->redirect_url = $this->checkout->cancel_page_url;
1699
-                $this->checkout->json_response->set_redirect_url($this->checkout->redirect_url);
1700
-                // mark this reg step as completed
1701
-                $this->set_completed();
1702
-                return false;
1703
-                break;
1704
-
1705
-            case 'payments_closed':
1706
-                if (
1707
-                    apply_filters(
1708
-                        'FHEE__EE_SPCO_Reg_Step_Payment_Options__process_reg_step__payments_closed__display_success',
1709
-                        false
1710
-                    )
1711
-                ) {
1712
-                    EE_Error::add_success(
1713
-                        esc_html__('no payment required at this time.', 'event_espresso'),
1714
-                        __FILE__,
1715
-                        __FUNCTION__,
1716
-                        __LINE__
1717
-                    );
1718
-                }
1719
-                // mark this reg step as completed
1720
-                $this->set_completed();
1721
-                return true;
1722
-                break;
1723
-
1724
-            case 'no_payment_required':
1725
-                if (
1726
-                    apply_filters(
1727
-                        'FHEE__EE_SPCO_Reg_Step_Payment_Options__process_reg_step__no_payment_required__display_success',
1728
-                        false
1729
-                    )
1730
-                ) {
1731
-                    EE_Error::add_success(
1732
-                        esc_html__('no payment required.', 'event_espresso'),
1733
-                        __FILE__,
1734
-                        __FUNCTION__,
1735
-                        __LINE__
1736
-                    );
1737
-                }
1738
-                // mark this reg step as completed
1739
-                $this->set_completed();
1740
-                return true;
1741
-                break;
1742
-
1743
-            default:
1744
-                $registrations = EE_Registry::instance()->SSN->checkout()->transaction->registrations(
1745
-                    EE_Registry::instance()->SSN->checkout()->reg_cache_where_params
1746
-                );
1747
-                $ejected_registrations = EE_SPCO_Reg_Step_Payment_Options::find_registrations_that_lost_their_space(
1748
-                    $registrations,
1749
-                    EE_Registry::instance()->SSN->checkout()->revisit
1750
-                );
1751
-                // calculate difference between the two arrays
1752
-                $registrations = array_diff($registrations, $ejected_registrations);
1753
-                if (empty($registrations)) {
1754
-                    $this->_redirect_because_event_sold_out();
1755
-                    return false;
1756
-                }
1757
-                $payment_successful = $this->_process_payment();
1758
-                if ($payment_successful) {
1759
-                    $this->checkout->continue_reg = true;
1760
-                    $this->_maybe_set_completed($this->checkout->payment_method);
1761
-                } else {
1762
-                    $this->checkout->continue_reg = false;
1763
-                }
1764
-                return $payment_successful;
1765
-        }
1766
-    }
1767
-
1768
-
1769
-    /**
1770
-     * _redirect_because_event_sold_out
1771
-     *
1772
-     * @access protected
1773
-     * @return void
1774
-     */
1775
-    protected function _redirect_because_event_sold_out()
1776
-    {
1777
-        $this->checkout->continue_reg = false;
1778
-        // set redirect URL
1779
-        $this->checkout->redirect_url = add_query_arg(
1780
-            array('e_reg_url_link' => $this->checkout->reg_url_link),
1781
-            $this->checkout->current_step->reg_step_url()
1782
-        );
1783
-        $this->checkout->json_response->set_redirect_url($this->checkout->redirect_url);
1784
-    }
1785
-
1786
-
1787
-    /**
1788
-     * _maybe_set_completed
1789
-     *
1790
-     * @access protected
1791
-     * @param \EE_Payment_Method $payment_method
1792
-     * @return void
1793
-     * @throws \EE_Error
1794
-     */
1795
-    protected function _maybe_set_completed(EE_Payment_Method $payment_method)
1796
-    {
1797
-        switch ($payment_method->type_obj()->payment_occurs()) {
1798
-            case EE_PMT_Base::offsite:
1799
-                break;
1800
-            case EE_PMT_Base::onsite:
1801
-            case EE_PMT_Base::offline:
1802
-                // mark this reg step as completed
1803
-                $this->set_completed();
1804
-                break;
1805
-        }
1806
-    }
1807
-
1808
-
1809
-    /**
1810
-     *    update_reg_step
1811
-     *    this is the final step after a user  revisits the site to retry a payment
1812
-     *
1813
-     * @return bool
1814
-     * @throws EE_Error
1815
-     * @throws InvalidArgumentException
1816
-     * @throws ReflectionException
1817
-     * @throws \EventEspresso\core\exceptions\EntityNotFoundException
1818
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1819
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1820
-     * @throws \EventEspresso\core\exceptions\InvalidStatusException
1821
-     */
1822
-    public function update_reg_step()
1823
-    {
1824
-        $success = true;
1825
-        // if payment required
1826
-        if ($this->checkout->transaction->total() > 0) {
1827
-            do_action(
1828
-                'AHEE__EE_Single_Page_Checkout__process_finalize_registration__before_gateway',
1829
-                $this->checkout->transaction
1830
-            );
1831
-            // attempt payment via payment method
1832
-            $success = $this->process_reg_step();
1833
-        }
1834
-        if ($success && ! $this->checkout->redirect) {
1835
-            $this->checkout->cart->get_grand_total()->save_this_and_descendants_to_txn(
1836
-                $this->checkout->transaction->ID()
1837
-            );
1838
-            // set return URL
1839
-            $this->checkout->redirect_url = add_query_arg(
1840
-                array('e_reg_url_link' => $this->checkout->reg_url_link),
1841
-                $this->checkout->thank_you_page_url
1842
-            );
1843
-        }
1844
-        return $success;
1845
-    }
1846
-
1847
-
1848
-    /**
1849
-     *    _process_payment
1850
-     *
1851
-     * @access private
1852
-     * @return bool
1853
-     * @throws EE_Error
1854
-     * @throws InvalidArgumentException
1855
-     * @throws ReflectionException
1856
-     * @throws RuntimeException
1857
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1858
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1859
-     */
1860
-    private function _process_payment()
1861
-    {
1862
-        // basically confirm that the event hasn't sold out since they hit the page
1863
-        if (! $this->_last_second_ticket_verifications()) {
1864
-            return false;
1865
-        }
1866
-        // ya gotta make a choice man
1867
-        if (empty($this->checkout->selected_method_of_payment)) {
1868
-            $this->checkout->json_response->set_plz_select_method_of_payment(
1869
-                esc_html__('Please select a method of payment before proceeding.', 'event_espresso')
1870
-            );
1871
-            return false;
1872
-        }
1873
-        // get EE_Payment_Method object
1874
-        if (! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()) {
1875
-            return false;
1876
-        }
1877
-        // setup billing form
1878
-        if ($this->checkout->payment_method->is_on_site()) {
1879
-            $this->checkout->billing_form = $this->_get_billing_form_for_payment_method(
1880
-                $this->checkout->payment_method
1881
-            );
1882
-            // bad billing form ?
1883
-            if (! $this->_billing_form_is_valid()) {
1884
-                return false;
1885
-            }
1886
-        }
1887
-        // ensure primary registrant has been fully processed
1888
-        if (! $this->_setup_primary_registrant_prior_to_payment()) {
1889
-            return false;
1890
-        }
1891
-        // if session is close to expiring (under 10 minutes by default)
1892
-        if ((time() - EE_Registry::instance()->SSN->expiration()) < EE_Registry::instance()->SSN->extension()) {
1893
-            // add some time to session expiration so that payment can be completed
1894
-            EE_Registry::instance()->SSN->extend_expiration();
1895
-        }
1896
-        /** @type EE_Transaction_Processor $transaction_processor */
1897
-        // $transaction_processor = EE_Registry::instance()->load_class( 'Transaction_Processor' );
1898
-        // in case a registrant leaves to an Off-Site Gateway and never returns, we want to approve any registrations
1899
-        // for events with a default reg status of Approved
1900
-        // $transaction_processor->toggle_registration_statuses_for_default_approved_events(
1901
-        //      $this->checkout->transaction, $this->checkout->reg_cache_where_params
1902
-        // );
1903
-        // attempt payment
1904
-        $payment = $this->_attempt_payment($this->checkout->payment_method);
1905
-        // process results
1906
-        $payment = $this->_validate_payment($payment);
1907
-        $payment = $this->_post_payment_processing($payment);
1908
-        // verify payment
1909
-        if ($payment instanceof EE_Payment) {
1910
-            // store that for later
1911
-            $this->checkout->payment = $payment;
1912
-            // we can also consider the TXN to not have been failed, so temporarily upgrade it's status to abandoned
1913
-            $this->checkout->transaction->toggle_failed_transaction_status();
1914
-            $payment_status = $payment->status();
1915
-            if (
1916
-                $payment_status === EEM_Payment::status_id_approved
1917
-                || $payment_status === EEM_Payment::status_id_pending
1918
-            ) {
1919
-                return true;
1920
-            } else {
1921
-                return false;
1922
-            }
1923
-        } elseif ($payment === true) {
1924
-            // please note that offline payment methods will NOT make a payment,
1925
-            // but instead just mark themselves as the PMD_ID on the transaction, and return true
1926
-            $this->checkout->payment = $payment;
1927
-            return true;
1928
-        }
1929
-        // where's my money?
1930
-        return false;
1931
-    }
1932
-
1933
-
1934
-    /**
1935
-     * _last_second_ticket_verifications
1936
-     *
1937
-     * @access public
1938
-     * @return bool
1939
-     * @throws EE_Error
1940
-     */
1941
-    protected function _last_second_ticket_verifications()
1942
-    {
1943
-        // don't bother re-validating if not a return visit
1944
-        if (! $this->checkout->revisit) {
1945
-            return true;
1946
-        }
1947
-        $registrations = $this->checkout->transaction->registrations();
1948
-        if (empty($registrations)) {
1949
-            return false;
1950
-        }
1951
-        foreach ($registrations as $registration) {
1952
-            if ($registration instanceof EE_Registration && ! $registration->is_approved()) {
1953
-                $event = $registration->event_obj();
1954
-                if ($event instanceof EE_Event && $event->is_sold_out(true)) {
1955
-                    EE_Error::add_error(
1956
-                        apply_filters(
1957
-                            'FHEE__EE_SPCO_Reg_Step_Payment_Options___last_second_ticket_verifications__sold_out_events_msg',
1958
-                            sprintf(
1959
-                                esc_html__(
1960
-                                    '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.',
1961
-                                    'event_espresso'
1962
-                                ),
1963
-                                $event->name()
1964
-                            )
1965
-                        ),
1966
-                        __FILE__,
1967
-                        __FUNCTION__,
1968
-                        __LINE__
1969
-                    );
1970
-                    return false;
1971
-                }
1972
-            }
1973
-        }
1974
-        return true;
1975
-    }
1976
-
1977
-
1978
-    /**
1979
-     * redirect_form
1980
-     *
1981
-     * @access public
1982
-     * @return bool
1983
-     * @throws EE_Error
1984
-     * @throws InvalidArgumentException
1985
-     * @throws ReflectionException
1986
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1987
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1988
-     */
1989
-    public function redirect_form()
1990
-    {
1991
-        $payment_method_billing_info = $this->_payment_method_billing_info(
1992
-            $this->_get_payment_method_for_selected_method_of_payment()
1993
-        );
1994
-        $html = $payment_method_billing_info->get_html();
1995
-        $html .= $this->checkout->redirect_form;
1996
-        EE_Registry::instance()->REQ->add_output($html);
1997
-        return true;
1998
-    }
1999
-
2000
-
2001
-    /**
2002
-     * _billing_form_is_valid
2003
-     *
2004
-     * @access private
2005
-     * @return bool
2006
-     * @throws \EE_Error
2007
-     */
2008
-    private function _billing_form_is_valid()
2009
-    {
2010
-        if (! $this->checkout->payment_method->type_obj()->has_billing_form()) {
2011
-            return true;
2012
-        }
2013
-        if ($this->checkout->billing_form instanceof EE_Billing_Info_Form) {
2014
-            if ($this->checkout->billing_form->was_submitted()) {
2015
-                $this->checkout->billing_form->receive_form_submission();
2016
-                if ($this->checkout->billing_form->is_valid()) {
2017
-                    return true;
2018
-                }
2019
-                $validation_errors = $this->checkout->billing_form->get_validation_errors_accumulated();
2020
-                $error_strings = array();
2021
-                foreach ($validation_errors as $validation_error) {
2022
-                    if ($validation_error instanceof EE_Validation_Error) {
2023
-                        $form_section = $validation_error->get_form_section();
2024
-                        if ($form_section instanceof EE_Form_Input_Base) {
2025
-                            $label = $form_section->html_label_text();
2026
-                        } elseif ($form_section instanceof EE_Form_Section_Base) {
2027
-                            $label = $form_section->name();
2028
-                        } else {
2029
-                            $label = esc_html__('Validation Error', 'event_espresso');
2030
-                        }
2031
-                        $error_strings[] = sprintf('%1$s: %2$s', $label, $validation_error->getMessage());
2032
-                    }
2033
-                }
2034
-                EE_Error::add_error(
2035
-                    sprintf(
2036
-                        esc_html__(
2037
-                            'One or more billing form inputs are invalid and require correction before proceeding. %1$s %2$s',
2038
-                            'event_espresso'
2039
-                        ),
2040
-                        '<br/>',
2041
-                        implode('<br/>', $error_strings)
2042
-                    ),
2043
-                    __FILE__,
2044
-                    __FUNCTION__,
2045
-                    __LINE__
2046
-                );
2047
-            } else {
2048
-                EE_Error::add_error(
2049
-                    esc_html__(
2050
-                        'The billing form was not submitted or something prevented it\'s submission.',
2051
-                        'event_espresso'
2052
-                    ),
2053
-                    __FILE__,
2054
-                    __FUNCTION__,
2055
-                    __LINE__
2056
-                );
2057
-            }
2058
-        } else {
2059
-            EE_Error::add_error(
2060
-                esc_html__(
2061
-                    'The submitted billing form is invalid possibly due to a technical reason.',
2062
-                    'event_espresso'
2063
-                ),
2064
-                __FILE__,
2065
-                __FUNCTION__,
2066
-                __LINE__
2067
-            );
2068
-        }
2069
-        return false;
2070
-    }
2071
-
2072
-
2073
-    /**
2074
-     * _setup_primary_registrant_prior_to_payment
2075
-     * ensures that the primary registrant has a valid attendee object created with the critical details populated
2076
-     * (first & last name & email) and that both the transaction object and primary registration object have been saved
2077
-     * plz note that any other registrations will NOT be saved at this point (because they may not have any details
2078
-     * yet)
2079
-     *
2080
-     * @access private
2081
-     * @return bool
2082
-     * @throws EE_Error
2083
-     * @throws InvalidArgumentException
2084
-     * @throws ReflectionException
2085
-     * @throws RuntimeException
2086
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2087
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2088
-     */
2089
-    private function _setup_primary_registrant_prior_to_payment()
2090
-    {
2091
-        // check if transaction has a primary registrant and that it has a related Attendee object
2092
-        // if not, then we need to at least gather some primary registrant data before attempting payment
2093
-        if (
2094
-            $this->checkout->billing_form instanceof EE_Billing_Attendee_Info_Form
2095
-            && ! $this->checkout->transaction_has_primary_registrant()
2096
-            && ! $this->_capture_primary_registration_data_from_billing_form()
2097
-        ) {
2098
-            return false;
2099
-        }
2100
-        // because saving an object clears it's cache, we need to do the chevy shuffle
2101
-        // grab the primary_registration object
2102
-        $primary_registration = $this->checkout->transaction->primary_registration();
2103
-        // at this point we'll consider a TXN to not have been failed
2104
-        $this->checkout->transaction->toggle_failed_transaction_status();
2105
-        // save the TXN ( which clears cached copy of primary_registration)
2106
-        $this->checkout->transaction->save();
2107
-        // grab TXN ID and save it to the primary_registration
2108
-        $primary_registration->set_transaction_id($this->checkout->transaction->ID());
2109
-        // save what we have so far
2110
-        $primary_registration->save();
2111
-        return true;
2112
-    }
2113
-
2114
-
2115
-    /**
2116
-     * _capture_primary_registration_data_from_billing_form
2117
-     *
2118
-     * @access private
2119
-     * @return bool
2120
-     * @throws EE_Error
2121
-     * @throws InvalidArgumentException
2122
-     * @throws ReflectionException
2123
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2124
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2125
-     */
2126
-    private function _capture_primary_registration_data_from_billing_form()
2127
-    {
2128
-        // convert billing form data into an attendee
2129
-        $this->checkout->primary_attendee_obj = $this->checkout->billing_form->create_attendee_from_billing_form_data();
2130
-        if (! $this->checkout->primary_attendee_obj instanceof EE_Attendee) {
2131
-            EE_Error::add_error(
2132
-                sprintf(
2133
-                    esc_html__(
2134
-                        'The billing form details could not be used for attendee details due to a technical issue.%sPlease try again or contact %s for assistance.',
2135
-                        'event_espresso'
2136
-                    ),
2137
-                    '<br/>',
2138
-                    EE_Registry::instance()->CFG->organization->get_pretty('email')
2139
-                ),
2140
-                __FILE__,
2141
-                __FUNCTION__,
2142
-                __LINE__
2143
-            );
2144
-            return false;
2145
-        }
2146
-        $primary_registration = $this->checkout->transaction->primary_registration();
2147
-        if (! $primary_registration instanceof EE_Registration) {
2148
-            EE_Error::add_error(
2149
-                sprintf(
2150
-                    esc_html__(
2151
-                        'The primary registrant for this transaction could not be determined due to a technical issue.%sPlease try again or contact %s for assistance.',
2152
-                        'event_espresso'
2153
-                    ),
2154
-                    '<br/>',
2155
-                    EE_Registry::instance()->CFG->organization->get_pretty('email')
2156
-                ),
2157
-                __FILE__,
2158
-                __FUNCTION__,
2159
-                __LINE__
2160
-            );
2161
-            return false;
2162
-        }
2163
-        if (
2164
-            ! $primary_registration->_add_relation_to($this->checkout->primary_attendee_obj, 'Attendee')
2165
-              instanceof
2166
-              EE_Attendee
2167
-        ) {
2168
-            EE_Error::add_error(
2169
-                sprintf(
2170
-                    esc_html__(
2171
-                        'The primary registrant could not be associated with this transaction due to a technical issue.%sPlease try again or contact %s for assistance.',
2172
-                        'event_espresso'
2173
-                    ),
2174
-                    '<br/>',
2175
-                    EE_Registry::instance()->CFG->organization->get_pretty('email')
2176
-                ),
2177
-                __FILE__,
2178
-                __FUNCTION__,
2179
-                __LINE__
2180
-            );
2181
-            return false;
2182
-        }
2183
-        /** @type EE_Registration_Processor $registration_processor */
2184
-        $registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
2185
-        // at this point, we should have enough details about the registrant to consider the registration NOT incomplete
2186
-        $registration_processor->toggle_incomplete_registration_status_to_default($primary_registration);
2187
-        return true;
2188
-    }
2189
-
2190
-
2191
-    /**
2192
-     * _get_payment_method_for_selected_method_of_payment
2193
-     * retrieves a valid payment method
2194
-     *
2195
-     * @access public
2196
-     * @return EE_Payment_Method
2197
-     * @throws EE_Error
2198
-     * @throws InvalidArgumentException
2199
-     * @throws ReflectionException
2200
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2201
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2202
-     */
2203
-    private function _get_payment_method_for_selected_method_of_payment()
2204
-    {
2205
-        if ($this->checkout->selected_method_of_payment === 'events_sold_out') {
2206
-            $this->_redirect_because_event_sold_out();
2207
-            return null;
2208
-        }
2209
-        // get EE_Payment_Method object
2210
-        if (isset($this->checkout->available_payment_methods[ $this->checkout->selected_method_of_payment ])) {
2211
-            $payment_method = $this->checkout->available_payment_methods[ $this->checkout->selected_method_of_payment ];
2212
-        } else {
2213
-            // load EEM_Payment_Method
2214
-            EE_Registry::instance()->load_model('Payment_Method');
2215
-            /** @type EEM_Payment_Method $EEM_Payment_Method */
2216
-            $EEM_Payment_Method = EE_Registry::instance()->LIB->EEM_Payment_Method;
2217
-            $payment_method = $EEM_Payment_Method->get_one_by_slug($this->checkout->selected_method_of_payment);
2218
-        }
2219
-        // verify $payment_method
2220
-        if (! $payment_method instanceof EE_Payment_Method) {
2221
-            // not a payment
2222
-            EE_Error::add_error(
2223
-                sprintf(
2224
-                    esc_html__(
2225
-                        'The selected method of payment could not be determined due to a technical issue.%sPlease try again or contact %s for assistance.',
2226
-                        'event_espresso'
2227
-                    ),
2228
-                    '<br/>',
2229
-                    EE_Registry::instance()->CFG->organization->get_pretty('email')
2230
-                ),
2231
-                __FILE__,
2232
-                __FUNCTION__,
2233
-                __LINE__
2234
-            );
2235
-            return null;
2236
-        }
2237
-        // and verify it has a valid Payment_Method Type object
2238
-        if (! $payment_method->type_obj() instanceof EE_PMT_Base) {
2239
-            // not a payment
2240
-            EE_Error::add_error(
2241
-                sprintf(
2242
-                    esc_html__(
2243
-                        'A valid payment method could not be determined due to a technical issue.%sPlease try again or contact %s for assistance.',
2244
-                        'event_espresso'
2245
-                    ),
2246
-                    '<br/>',
2247
-                    EE_Registry::instance()->CFG->organization->get_pretty('email')
2248
-                ),
2249
-                __FILE__,
2250
-                __FUNCTION__,
2251
-                __LINE__
2252
-            );
2253
-            return null;
2254
-        }
2255
-        return $payment_method;
2256
-    }
2257
-
2258
-
2259
-    /**
2260
-     *    _attempt_payment
2261
-     *
2262
-     * @access    private
2263
-     * @type    EE_Payment_Method $payment_method
2264
-     * @return mixed EE_Payment | boolean
2265
-     * @throws EE_Error
2266
-     * @throws InvalidArgumentException
2267
-     * @throws ReflectionException
2268
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2269
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2270
-     */
2271
-    private function _attempt_payment(EE_Payment_Method $payment_method)
2272
-    {
2273
-        $payment = null;
2274
-        $this->checkout->transaction->save();
2275
-        $payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
2276
-        if (! $payment_processor instanceof EE_Payment_Processor) {
2277
-            return false;
2278
-        }
2279
-        try {
2280
-            $payment_processor->set_revisit($this->checkout->revisit);
2281
-            // generate payment object
2282
-            $payment = $payment_processor->process_payment(
2283
-                $payment_method,
2284
-                $this->checkout->transaction,
2285
-                $this->checkout->amount_owing,
2286
-                $this->checkout->billing_form,
2287
-                $this->_get_return_url($payment_method),
2288
-                'CART',
2289
-                $this->checkout->admin_request,
2290
-                true,
2291
-                $this->reg_step_url()
2292
-            );
2293
-        } catch (Exception $e) {
2294
-            $this->_handle_payment_processor_exception($e);
2295
-        }
2296
-        return $payment;
2297
-    }
2298
-
2299
-
2300
-    /**
2301
-     * _handle_payment_processor_exception
2302
-     *
2303
-     * @access protected
2304
-     * @param \Exception $e
2305
-     * @return void
2306
-     * @throws EE_Error
2307
-     * @throws InvalidArgumentException
2308
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2309
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2310
-     */
2311
-    protected function _handle_payment_processor_exception(Exception $e)
2312
-    {
2313
-        EE_Error::add_error(
2314
-            sprintf(
2315
-                esc_html__(
2316
-                    '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',
2317
-                    'event_espresso'
2318
-                ),
2319
-                '<br/>',
2320
-                EE_Registry::instance()->CFG->organization->get_pretty('email'),
2321
-                $e->getMessage(),
2322
-                $e->getFile(),
2323
-                $e->getLine()
2324
-            ),
2325
-            __FILE__,
2326
-            __FUNCTION__,
2327
-            __LINE__
2328
-        );
2329
-    }
2330
-
2331
-
2332
-    /**
2333
-     * _get_return_url
2334
-     *
2335
-     * @access protected
2336
-     * @param \EE_Payment_Method $payment_method
2337
-     * @return string
2338
-     * @throws \EE_Error
2339
-     */
2340
-    protected function _get_return_url(EE_Payment_Method $payment_method)
2341
-    {
2342
-        $return_url = '';
2343
-        switch ($payment_method->type_obj()->payment_occurs()) {
2344
-            case EE_PMT_Base::offsite:
2345
-                $return_url = add_query_arg(
2346
-                    array(
2347
-                        'action'                     => 'process_gateway_response',
2348
-                        'selected_method_of_payment' => $this->checkout->selected_method_of_payment,
2349
-                        'spco_txn'                   => $this->checkout->transaction->ID(),
2350
-                    ),
2351
-                    $this->reg_step_url()
2352
-                );
2353
-                break;
2354
-            case EE_PMT_Base::onsite:
2355
-            case EE_PMT_Base::offline:
2356
-                $return_url = $this->checkout->next_step->reg_step_url();
2357
-                break;
2358
-        }
2359
-        return $return_url;
2360
-    }
2361
-
2362
-
2363
-    /**
2364
-     * _validate_payment
2365
-     *
2366
-     * @access private
2367
-     * @param EE_Payment $payment
2368
-     * @return EE_Payment|FALSE
2369
-     * @throws EE_Error
2370
-     * @throws InvalidArgumentException
2371
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2372
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2373
-     */
2374
-    private function _validate_payment($payment = null)
2375
-    {
2376
-        if ($this->checkout->payment_method->is_off_line()) {
2377
-            return true;
2378
-        }
2379
-        // verify payment object
2380
-        if (! $payment instanceof EE_Payment) {
2381
-            // not a payment
2382
-            EE_Error::add_error(
2383
-                sprintf(
2384
-                    esc_html__(
2385
-                        'A valid payment was not generated due to a technical issue.%1$sPlease try again or contact %2$s for assistance.',
2386
-                        'event_espresso'
2387
-                    ),
2388
-                    '<br/>',
2389
-                    EE_Registry::instance()->CFG->organization->get_pretty('email')
2390
-                ),
2391
-                __FILE__,
2392
-                __FUNCTION__,
2393
-                __LINE__
2394
-            );
2395
-            return false;
2396
-        }
2397
-        return $payment;
2398
-    }
2399
-
2400
-
2401
-    /**
2402
-     * _post_payment_processing
2403
-     *
2404
-     * @access private
2405
-     * @param EE_Payment|bool $payment
2406
-     * @return bool
2407
-     * @throws EE_Error
2408
-     * @throws InvalidArgumentException
2409
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2410
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2411
-     */
2412
-    private function _post_payment_processing($payment = null)
2413
-    {
2414
-        // Off-Line payment?
2415
-        if ($payment === true) {
2416
-            // $this->_setup_redirect_for_next_step();
2417
-            return true;
2418
-            // On-Site payment?
2419
-        } elseif ($this->checkout->payment_method->is_on_site()) {
2420
-            if (! $this->_process_payment_status($payment, EE_PMT_Base::onsite)) {
2421
-                // $this->_setup_redirect_for_next_step();
2422
-                $this->checkout->continue_reg = false;
2423
-            }
2424
-            // Off-Site payment?
2425
-        } elseif ($this->checkout->payment_method->is_off_site()) {
2426
-            // if a payment object was made and it specifies a redirect url, then we'll setup that redirect info
2427
-            if ($payment instanceof EE_Payment && $payment->redirect_url()) {
2428
-                do_action('AHEE_log', __CLASS__, __FUNCTION__, $payment->redirect_url(), '$payment->redirect_url()');
2429
-                $this->checkout->redirect = true;
2430
-                $this->checkout->redirect_form = $payment->redirect_form();
2431
-                $this->checkout->redirect_url = $this->reg_step_url('redirect_form');
2432
-                // set JSON response
2433
-                $this->checkout->json_response->set_redirect_form($this->checkout->redirect_form);
2434
-                // and lastly, let's bump the payment status to pending
2435
-                $payment->set_status(EEM_Payment::status_id_pending);
2436
-                $payment->save();
2437
-            } else {
2438
-                // we couldn't redirect the user. Let's tell them why.
2439
-                $error_message = sprintf(
2440
-                    esc_html__(
2441
-                        'It appears the Off Site Payment Method was not configured properly.%sPlease try again or contact %s for assistance.',
2442
-                        'event_espresso'
2443
-                    ),
2444
-                    '<br/>',
2445
-                    EE_Registry::instance()->CFG->organization->get_pretty('email')
2446
-                );
2447
-                if ($payment instanceof EE_Payment && $payment->gateway_response()) {
2448
-                    $error_message = $error_message . '<br/>' . $payment->gateway_response();
2449
-                }
2450
-                $this->checkout->continue_reg = false;
2451
-                EE_Error::add_error(
2452
-                    $error_message,
2453
-                    __FILE__,
2454
-                    __FUNCTION__,
2455
-                    __LINE__
2456
-                );
2457
-            }
2458
-        } else {
2459
-            // ummm ya... not Off-Line, not On-Site, not off-Site ????
2460
-            $this->checkout->continue_reg = false;
2461
-            return false;
2462
-        }
2463
-        return $payment;
2464
-    }
2465
-
2466
-
2467
-    /**
2468
-     *    _process_payment_status
2469
-     *
2470
-     * @access private
2471
-     * @type    EE_Payment $payment
2472
-     * @param string       $payment_occurs
2473
-     * @return bool
2474
-     * @throws EE_Error
2475
-     * @throws InvalidArgumentException
2476
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2477
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2478
-     */
2479
-    private function _process_payment_status($payment, $payment_occurs = EE_PMT_Base::offline)
2480
-    {
2481
-        // off-line payment? carry on
2482
-        if ($payment_occurs === EE_PMT_Base::offline) {
2483
-            return true;
2484
-        }
2485
-        // verify payment validity
2486
-        if ($payment instanceof EE_Payment) {
2487
-            do_action('AHEE_log', __CLASS__, __FUNCTION__, $payment->status(), '$payment->status()');
2488
-            $msg = $payment->gateway_response();
2489
-            // check results
2490
-            switch ($payment->status()) {
2491
-                // good payment
2492
-                case EEM_Payment::status_id_approved:
2493
-                    EE_Error::add_success(
2494
-                        esc_html__('Your payment was processed successfully.', 'event_espresso'),
2495
-                        __FILE__,
2496
-                        __FUNCTION__,
2497
-                        __LINE__
2498
-                    );
2499
-                    return true;
2500
-                    break;
2501
-                // slow payment
2502
-                case EEM_Payment::status_id_pending:
2503
-                    if (empty($msg)) {
2504
-                        $msg = esc_html__(
2505
-                            'Your payment appears to have been processed successfully, but the Instant Payment Notification has not yet been received. It should arrive shortly.',
2506
-                            'event_espresso'
2507
-                        );
2508
-                    }
2509
-                    EE_Error::add_success($msg, __FILE__, __FUNCTION__, __LINE__);
2510
-                    return true;
2511
-                    break;
2512
-                // don't wanna payment
2513
-                case EEM_Payment::status_id_cancelled:
2514
-                    if (empty($msg)) {
2515
-                        $msg = _n(
2516
-                            'Payment cancelled. Please try again.',
2517
-                            'Payment cancelled. Please try again or select another method of payment.',
2518
-                            count($this->checkout->available_payment_methods),
2519
-                            'event_espresso'
2520
-                        );
2521
-                    }
2522
-                    EE_Error::add_attention($msg, __FILE__, __FUNCTION__, __LINE__);
2523
-                    return false;
2524
-                    break;
2525
-                // not enough payment
2526
-                case EEM_Payment::status_id_declined:
2527
-                    if (empty($msg)) {
2528
-                        $msg = _n(
2529
-                            'We\'re sorry but your payment was declined. Please try again.',
2530
-                            'We\'re sorry but your payment was declined. Please try again or select another method of payment.',
2531
-                            count($this->checkout->available_payment_methods),
2532
-                            'event_espresso'
2533
-                        );
2534
-                    }
2535
-                    EE_Error::add_attention($msg, __FILE__, __FUNCTION__, __LINE__);
2536
-                    return false;
2537
-                    break;
2538
-                // bad payment
2539
-                case EEM_Payment::status_id_failed:
2540
-                    if (! empty($msg)) {
2541
-                        EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2542
-                        return false;
2543
-                    }
2544
-                    // default to error below
2545
-                    break;
2546
-            }
2547
-        }
2548
-        // off-site payment gateway responses are too unreliable, so let's just assume that
2549
-        // the payment processing is just running slower than the registrant's request
2550
-        if ($payment_occurs === EE_PMT_Base::offsite) {
2551
-            return true;
2552
-        }
2553
-        EE_Error::add_error(
2554
-            sprintf(
2555
-                esc_html__(
2556
-                    'Your payment could not be processed successfully due to a technical issue.%sPlease try again or contact %s for assistance.',
2557
-                    'event_espresso'
2558
-                ),
2559
-                '<br/>',
2560
-                EE_Registry::instance()->CFG->organization->get_pretty('email')
2561
-            ),
2562
-            __FILE__,
2563
-            __FUNCTION__,
2564
-            __LINE__
2565
-        );
2566
-        return false;
2567
-    }
2568
-
2569
-
2570
-
2571
-
2572
-
2573
-
2574
-    /********************************************************************************************************/
2575
-    /**********************************  PROCESS GATEWAY RESPONSE  **********************************/
2576
-    /********************************************************************************************************/
2577
-    /**
2578
-     * process_gateway_response
2579
-     * this is the return point for Off-Site Payment Methods
2580
-     * It will attempt to "handle the IPN" if it appears that this has not already occurred,
2581
-     * otherwise, it will load up the last payment made for the TXN.
2582
-     * If the payment retrieved looks good, it will then either:
2583
-     *    complete the current step and allow advancement to the next reg step
2584
-     *        or present the payment options again
2585
-     *
2586
-     * @access private
2587
-     * @return EE_Payment|FALSE
2588
-     * @throws EE_Error
2589
-     * @throws InvalidArgumentException
2590
-     * @throws ReflectionException
2591
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2592
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2593
-     * @throws \EventEspresso\core\exceptions\InvalidSessionDataException
2594
-     */
2595
-    public function process_gateway_response()
2596
-    {
2597
-        $payment = null;
2598
-        // how have they chosen to pay?
2599
-        $this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment(true);
2600
-        // get EE_Payment_Method object
2601
-        if (! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()) {
2602
-            $this->checkout->continue_reg = false;
2603
-            return false;
2604
-        }
2605
-        if (! $this->checkout->payment_method->is_off_site()) {
2606
-            return false;
2607
-        }
2608
-        $this->_validate_offsite_return();
2609
-        // DEBUG LOG
2610
-        // $this->checkout->log(
2611
-        //     __CLASS__,
2612
-        //     __FUNCTION__,
2613
-        //     __LINE__,
2614
-        //     array(
2615
-        //         'selected_method_of_payment' => $this->checkout->selected_method_of_payment,
2616
-        //         'payment_method'             => $this->checkout->payment_method,
2617
-        //     ),
2618
-        //     true
2619
-        // );
2620
-        // verify TXN
2621
-        if ($this->checkout->transaction instanceof EE_Transaction) {
2622
-            $gateway = $this->checkout->payment_method->type_obj()->get_gateway();
2623
-            if (! $gateway instanceof EE_Offsite_Gateway) {
2624
-                $this->checkout->continue_reg = false;
2625
-                return false;
2626
-            }
2627
-            $payment = $this->_process_off_site_payment($gateway);
2628
-            $payment = $this->_process_cancelled_payments($payment);
2629
-            $payment = $this->_validate_payment($payment);
2630
-            // if payment was not declined by the payment gateway or cancelled by the registrant
2631
-            if ($this->_process_payment_status($payment, EE_PMT_Base::offsite)) {
2632
-                // $this->_setup_redirect_for_next_step();
2633
-                // store that for later
2634
-                $this->checkout->payment = $payment;
2635
-                // mark this reg step as completed, as long as gateway doesn't use a separate IPN request,
2636
-                // because we will complete this step during the IPN processing then
2637
-                if ($gateway instanceof EE_Offsite_Gateway && ! $this->handle_IPN_in_this_request()) {
2638
-                    $this->set_completed();
2639
-                }
2640
-                return true;
2641
-            }
2642
-        }
2643
-        // DEBUG LOG
2644
-        // $this->checkout->log(
2645
-        //     __CLASS__,
2646
-        //     __FUNCTION__,
2647
-        //     __LINE__,
2648
-        //     array('payment' => $payment)
2649
-        // );
2650
-        $this->checkout->continue_reg = false;
2651
-        return false;
2652
-    }
2653
-
2654
-
2655
-    /**
2656
-     * _validate_return
2657
-     *
2658
-     * @access private
2659
-     * @return void
2660
-     * @throws EE_Error
2661
-     * @throws InvalidArgumentException
2662
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2663
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2664
-     * @throws \EventEspresso\core\exceptions\InvalidSessionDataException
2665
-     */
2666
-    private function _validate_offsite_return()
2667
-    {
2668
-        $TXN_ID = (int) EE_Registry::instance()->REQ->get('spco_txn', 0);
2669
-        if ($TXN_ID !== $this->checkout->transaction->ID()) {
2670
-            // Houston... we might have a problem
2671
-            $invalid_TXN = false;
2672
-            // first gather some info
2673
-            $valid_TXN = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2674
-            $primary_registrant = $valid_TXN instanceof EE_Transaction
2675
-                ? $valid_TXN->primary_registration()
2676
-                : null;
2677
-            // let's start by retrieving the cart for this TXN
2678
-            $cart = $this->checkout->get_cart_for_transaction($this->checkout->transaction);
2679
-            if ($cart instanceof EE_Cart) {
2680
-                // verify that the current cart has tickets
2681
-                $tickets = $cart->get_tickets();
2682
-                if (empty($tickets)) {
2683
-                    $invalid_TXN = true;
2684
-                }
2685
-            } else {
2686
-                $invalid_TXN = true;
2687
-            }
2688
-            $valid_TXN_SID = $primary_registrant instanceof EE_Registration
2689
-                ? $primary_registrant->session_ID()
2690
-                : null;
2691
-            // validate current Session ID and compare against valid TXN session ID
2692
-            if (
2693
-                $invalid_TXN // if this is already true, then skip other checks
2694
-                || EE_Session::instance()->id() === null
2695
-                || (
2696
-                    // WARNING !!!
2697
-                    // this could be PayPal sending back duplicate requests (ya they do that)
2698
-                    // or it **could** mean someone is simply registering AGAIN after having just done so
2699
-                    // so now we need to determine if this current TXN looks valid or not
2700
-                    // and whether this reg step has even been started ?
2701
-                    EE_Session::instance()->id() === $valid_TXN_SID
2702
-                    // really? you're half way through this reg step, but you never started it ?
2703
-                    && $this->checkout->transaction->reg_step_completed($this->slug()) === false
2704
-                )
2705
-            ) {
2706
-                $invalid_TXN = true;
2707
-            }
2708
-            if ($invalid_TXN) {
2709
-                // is the valid TXN completed ?
2710
-                if ($valid_TXN instanceof EE_Transaction) {
2711
-                    // has this step even been started ?
2712
-                    $reg_step_completed = $valid_TXN->reg_step_completed($this->slug());
2713
-                    if ($reg_step_completed !== false && $reg_step_completed !== true) {
2714
-                        // so it **looks** like this is a double request from PayPal
2715
-                        // so let's try to pick up where we left off
2716
-                        $this->checkout->transaction = $valid_TXN;
2717
-                        $this->checkout->refresh_all_entities(true);
2718
-                        return;
2719
-                    }
2720
-                }
2721
-                // you appear to be lost?
2722
-                $this->_redirect_wayward_request($primary_registrant);
2723
-            }
2724
-        }
2725
-    }
2726
-
2727
-
2728
-    /**
2729
-     * _redirect_wayward_request
2730
-     *
2731
-     * @access private
2732
-     * @param \EE_Registration|null $primary_registrant
2733
-     * @return bool
2734
-     * @throws EE_Error
2735
-     * @throws InvalidArgumentException
2736
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2737
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2738
-     */
2739
-    private function _redirect_wayward_request(EE_Registration $primary_registrant)
2740
-    {
2741
-        if (! $primary_registrant instanceof EE_Registration) {
2742
-            // try redirecting based on the current TXN
2743
-            $primary_registrant = $this->checkout->transaction instanceof EE_Transaction
2744
-                ? $this->checkout->transaction->primary_registration()
2745
-                : null;
2746
-        }
2747
-        if (! $primary_registrant instanceof EE_Registration) {
2748
-            EE_Error::add_error(
2749
-                sprintf(
2750
-                    esc_html__(
2751
-                        '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.',
2752
-                        'event_espresso'
2753
-                    ),
2754
-                    '<br/>',
2755
-                    EE_Registry::instance()->CFG->organization->get_pretty('email')
2756
-                ),
2757
-                __FILE__,
2758
-                __FUNCTION__,
2759
-                __LINE__
2760
-            );
2761
-            return false;
2762
-        }
2763
-        // make sure transaction is not locked
2764
-        $this->checkout->transaction->unlock();
2765
-        wp_safe_redirect(
2766
-            add_query_arg(
2767
-                array(
2768
-                    'e_reg_url_link' => $primary_registrant->reg_url_link(),
2769
-                ),
2770
-                $this->checkout->thank_you_page_url
2771
-            )
2772
-        );
2773
-        exit();
2774
-    }
2775
-
2776
-
2777
-    /**
2778
-     * _process_off_site_payment
2779
-     *
2780
-     * @access private
2781
-     * @param \EE_Offsite_Gateway $gateway
2782
-     * @return EE_Payment
2783
-     * @throws EE_Error
2784
-     * @throws InvalidArgumentException
2785
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2786
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2787
-     */
2788
-    private function _process_off_site_payment(EE_Offsite_Gateway $gateway)
2789
-    {
2790
-        try {
2791
-            $request_data = \EE_Registry::instance()->REQ->params();
2792
-            // if gateway uses_separate_IPN_request, then we don't have to process the IPN manually
2793
-            $this->set_handle_IPN_in_this_request(
2794
-                $gateway->handle_IPN_in_this_request($request_data, false)
2795
-            );
2796
-            if ($this->handle_IPN_in_this_request()) {
2797
-                // get payment details and process results
2798
-                /** @type EE_Payment_Processor $payment_processor */
2799
-                $payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
2800
-                $payment = $payment_processor->process_ipn(
2801
-                    $request_data,
2802
-                    $this->checkout->transaction,
2803
-                    $this->checkout->payment_method,
2804
-                    true,
2805
-                    false
2806
-                );
2807
-                // $payment_source = 'process_ipn';
2808
-            } else {
2809
-                $payment = $this->checkout->transaction->last_payment();
2810
-                // $payment_source = 'last_payment';
2811
-            }
2812
-        } catch (Exception $e) {
2813
-            // let's just eat the exception and try to move on using any previously set payment info
2814
-            $payment = $this->checkout->transaction->last_payment();
2815
-            // $payment_source = 'last_payment after Exception';
2816
-            // but if we STILL don't have a payment object
2817
-            if (! $payment instanceof EE_Payment) {
2818
-                // then we'll object ! ( not object like a thing... but object like what a lawyer says ! )
2819
-                $this->_handle_payment_processor_exception($e);
2820
-            }
2821
-        }
2822
-        // DEBUG LOG
2823
-        // $this->checkout->log(
2824
-        //     __CLASS__,
2825
-        //     __FUNCTION__,
2826
-        //     __LINE__,
2827
-        //     array(
2828
-        //         'process_ipn_payment' => $payment,
2829
-        //         'payment_source'      => $payment_source,
2830
-        //     )
2831
-        // );
2832
-        return $payment;
2833
-    }
2834
-
2835
-
2836
-    /**
2837
-     * _process_cancelled_payments
2838
-     * just makes sure that the payment status gets updated correctly
2839
-     * so tha tan error isn't generated during payment validation
2840
-     *
2841
-     * @access private
2842
-     * @param EE_Payment $payment
2843
-     * @return EE_Payment | FALSE
2844
-     * @throws \EE_Error
2845
-     */
2846
-    private function _process_cancelled_payments($payment = null)
2847
-    {
2848
-        if (
2849
-            $payment instanceof EE_Payment
2850
-            && isset($_REQUEST['ee_cancel_payment'])
2851
-            && $payment->status() === EEM_Payment::status_id_failed
2852
-        ) {
2853
-            $payment->set_status(EEM_Payment::status_id_cancelled);
2854
-        }
2855
-        return $payment;
2856
-    }
2857
-
2858
-
2859
-    /**
2860
-     *    get_transaction_details_for_gateways
2861
-     *
2862
-     * @access    public
2863
-     * @return int
2864
-     * @throws EE_Error
2865
-     * @throws InvalidArgumentException
2866
-     * @throws ReflectionException
2867
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2868
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2869
-     */
2870
-    public function get_transaction_details_for_gateways()
2871
-    {
2872
-        $txn_details = array();
2873
-        // ya gotta make a choice man
2874
-        if (empty($this->checkout->selected_method_of_payment)) {
2875
-            $txn_details = array(
2876
-                'error' => esc_html__('Please select a method of payment before proceeding.', 'event_espresso'),
2877
-            );
2878
-        }
2879
-        // get EE_Payment_Method object
2880
-        if (
2881
-            empty($txn_details)
2882
-            &&
2883
-            ! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()
2884
-        ) {
2885
-            $txn_details = array(
2886
-                'selected_method_of_payment' => $this->checkout->selected_method_of_payment,
2887
-                'error'                      => esc_html__(
2888
-                    'A valid Payment Method could not be determined.',
2889
-                    'event_espresso'
2890
-                ),
2891
-            );
2892
-        }
2893
-        if (empty($txn_details) && $this->checkout->transaction instanceof EE_Transaction) {
2894
-            $return_url = $this->_get_return_url($this->checkout->payment_method);
2895
-            $txn_details = array(
2896
-                'TXN_ID'         => $this->checkout->transaction->ID(),
2897
-                'TXN_timestamp'  => $this->checkout->transaction->datetime(),
2898
-                'TXN_total'      => $this->checkout->transaction->total(),
2899
-                'TXN_paid'       => $this->checkout->transaction->paid(),
2900
-                'TXN_reg_steps'  => $this->checkout->transaction->reg_steps(),
2901
-                'STS_ID'         => $this->checkout->transaction->status_ID(),
2902
-                'PMD_ID'         => $this->checkout->transaction->payment_method_ID(),
2903
-                'payment_amount' => $this->checkout->amount_owing,
2904
-                'return_url'     => $return_url,
2905
-                'cancel_url'     => add_query_arg(array('ee_cancel_payment' => true), $return_url),
2906
-                'notify_url'     => EE_Config::instance()->core->txn_page_url(
2907
-                    array(
2908
-                        'e_reg_url_link'    => $this->checkout->transaction->primary_registration()->reg_url_link(),
2909
-                        'ee_payment_method' => $this->checkout->payment_method->slug(),
2910
-                    )
2911
-                ),
2912
-            );
2913
-        }
2914
-        echo wp_json_encode($txn_details);
2915
-        exit();
2916
-    }
2917
-
2918
-
2919
-    /**
2920
-     *    __sleep
2921
-     * to conserve db space, let's remove the reg_form and the EE_Checkout object from EE_SPCO_Reg_Step objects upon
2922
-     * serialization EE_Checkout will handle the reimplementation of itself upon waking, but we won't bother with the
2923
-     * reg form, because if needed, it will be regenerated anyways
2924
-     *
2925
-     * @return array
2926
-     */
2927
-    public function __sleep()
2928
-    {
2929
-        // remove the reg form and the checkout
2930
-        return array_diff(array_keys(get_object_vars($this)), array('reg_form', 'checkout', 'line_item_display'));
2931
-    }
250
+			// registrations made via the admin
251
+			// completed transactions
252
+			// overpaid transactions
253
+			// $ 0.00 transactions(no payment required)
254
+			! $this->checkout->payment_required()
255
+			// but do NOT remove if current action being called belongs to this reg step
256
+			&& ! is_callable(array($this, $this->checkout->action))
257
+			&& ! $this->completed()
258
+		) {
259
+			// and if so, then we no longer need the Payment Options step
260
+			if ($this->is_current_step()) {
261
+				$this->checkout->generate_reg_form = false;
262
+			}
263
+			$this->checkout->remove_reg_step($this->_slug);
264
+			// DEBUG LOG
265
+			// $this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ );
266
+			return false;
267
+		}
268
+		// load EEM_Payment_Method
269
+		EE_Registry::instance()->load_model('Payment_Method');
270
+		// get all active payment methods
271
+		$this->checkout->available_payment_methods = EEM_Payment_Method::instance()->get_all_for_transaction(
272
+			$this->checkout->transaction,
273
+			EEM_Payment_Method::scope_cart
274
+		);
275
+		return true;
276
+	}
277
+
278
+
279
+	/**
280
+	 * @return EE_Form_Section_Proper
281
+	 * @throws EE_Error
282
+	 * @throws InvalidArgumentException
283
+	 * @throws ReflectionException
284
+	 * @throws \EventEspresso\core\exceptions\EntityNotFoundException
285
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
286
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
287
+	 * @throws \EventEspresso\core\exceptions\InvalidStatusException
288
+	 */
289
+	public function generate_reg_form()
290
+	{
291
+		// reset in case someone changes their mind
292
+		$this->_reset_selected_method_of_payment();
293
+		// set some defaults
294
+		$this->checkout->selected_method_of_payment = 'payments_closed';
295
+		$registrations_requiring_payment = array();
296
+		$registrations_for_free_events = array();
297
+		$registrations_requiring_pre_approval = array();
298
+		$sold_out_events = array();
299
+		$insufficient_spaces_available = array();
300
+		$no_payment_required = true;
301
+		// loop thru registrations to gather info
302
+		$registrations = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params);
303
+		$ejected_registrations = EE_SPCO_Reg_Step_Payment_Options::find_registrations_that_lost_their_space(
304
+			$registrations,
305
+			$this->checkout->revisit
306
+		);
307
+		foreach ($registrations as $REG_ID => $registration) {
308
+			/** @var $registration EE_Registration */
309
+			// has this registration lost it's space ?
310
+			if (isset($ejected_registrations[ $REG_ID ])) {
311
+				if ($registration->event()->is_sold_out() || $registration->event()->is_sold_out(true)) {
312
+					$sold_out_events[ $registration->event()->ID() ] = $registration->event();
313
+				} else {
314
+					$insufficient_spaces_available[ $registration->event()->ID() ] = $registration->event();
315
+				}
316
+				continue;
317
+			}
318
+			// event requires admin approval
319
+			if ($registration->status_ID() === EEM_Registration::status_id_not_approved) {
320
+				// add event to list of events with pre-approval reg status
321
+				$registrations_requiring_pre_approval[ $REG_ID ] = $registration;
322
+				do_action(
323
+					'AHEE__EE_SPCO_Reg_Step_Payment_Options__generate_reg_form__event_requires_pre_approval',
324
+					$registration->event(),
325
+					$this
326
+				);
327
+				continue;
328
+			}
329
+			if (
330
+				$this->checkout->revisit
331
+				&& $registration->status_ID() !== EEM_Registration::status_id_approved
332
+				&& (
333
+					$registration->event()->is_sold_out()
334
+					|| $registration->event()->is_sold_out(true)
335
+				)
336
+			) {
337
+				// add event to list of events that are sold out
338
+				$sold_out_events[ $registration->event()->ID() ] = $registration->event();
339
+				do_action(
340
+					'AHEE__EE_SPCO_Reg_Step_Payment_Options__generate_reg_form__sold_out_event',
341
+					$registration->event(),
342
+					$this
343
+				);
344
+				continue;
345
+			}
346
+			// are they allowed to pay now and is there monies owing?
347
+			if ($registration->owes_monies_and_can_pay()) {
348
+				$registrations_requiring_payment[ $REG_ID ] = $registration;
349
+				do_action(
350
+					'AHEE__EE_SPCO_Reg_Step_Payment_Options__generate_reg_form__event_requires_payment',
351
+					$registration->event(),
352
+					$this
353
+				);
354
+			} elseif (
355
+				! $this->checkout->revisit
356
+					  && $registration->status_ID() !== EEM_Registration::status_id_not_approved
357
+					  && $registration->ticket()->is_free()
358
+			) {
359
+				$registrations_for_free_events[ $registration->ticket()->ID() ] = $registration;
360
+			}
361
+		}
362
+		$subsections = array();
363
+		// now decide which template to load
364
+		if (! empty($sold_out_events)) {
365
+			$subsections['sold_out_events'] = $this->_sold_out_events($sold_out_events);
366
+		}
367
+		if (! empty($insufficient_spaces_available)) {
368
+			$subsections['insufficient_space'] = $this->_insufficient_spaces_available(
369
+				$insufficient_spaces_available
370
+			);
371
+		}
372
+		if (! empty($registrations_requiring_pre_approval)) {
373
+			$subsections['registrations_requiring_pre_approval'] = $this->_registrations_requiring_pre_approval(
374
+				$registrations_requiring_pre_approval
375
+			);
376
+		}
377
+		if (! empty($registrations_for_free_events)) {
378
+			$subsections['no_payment_required'] = $this->_no_payment_required($registrations_for_free_events);
379
+		}
380
+		if (! empty($registrations_requiring_payment)) {
381
+			if ($this->checkout->amount_owing > 0) {
382
+				// autoload Line_Item_Display classes
383
+				EEH_Autoloader::register_line_item_filter_autoloaders();
384
+				$line_item_filter_processor = new EE_Line_Item_Filter_Processor(
385
+					apply_filters(
386
+						'FHEE__SPCO__EE_Line_Item_Filter_Collection',
387
+						new EE_Line_Item_Filter_Collection()
388
+					),
389
+					$this->checkout->cart->get_grand_total()
390
+				);
391
+				/** @var EE_Line_Item $filtered_line_item_tree */
392
+				$filtered_line_item_tree = $line_item_filter_processor->process();
393
+				EEH_Autoloader::register_line_item_display_autoloaders();
394
+				$this->set_line_item_display(new EE_Line_Item_Display('spco'));
395
+				$subsections['payment_options'] = $this->_display_payment_options(
396
+					$this->line_item_display->display_line_item(
397
+						$filtered_line_item_tree,
398
+						array('registrations' => $registrations)
399
+					)
400
+				);
401
+				$this->checkout->amount_owing = $filtered_line_item_tree->total();
402
+				$this->_apply_registration_payments_to_amount_owing($registrations);
403
+			}
404
+			$no_payment_required = false;
405
+		} else {
406
+			$this->_hide_reg_step_submit_button_if_revisit();
407
+		}
408
+		$this->_save_selected_method_of_payment();
409
+
410
+		$subsections['default_hidden_inputs'] = $this->reg_step_hidden_inputs();
411
+		$subsections['extra_hidden_inputs'] = $this->_extra_hidden_inputs($no_payment_required);
412
+
413
+		return new EE_Form_Section_Proper(
414
+			array(
415
+				'name'            => $this->reg_form_name(),
416
+				'html_id'         => $this->reg_form_name(),
417
+				'subsections'     => $subsections,
418
+				'layout_strategy' => new EE_No_Layout(),
419
+			)
420
+		);
421
+	}
422
+
423
+
424
+	/**
425
+	 * add line item filters required for this reg step
426
+	 * these filters are applied via this line in EE_SPCO_Reg_Step_Payment_Options::set_hooks():
427
+	 *        add_filter( 'FHEE__SPCO__EE_Line_Item_Filter_Collection', array( 'EE_SPCO_Reg_Step_Payment_Options',
428
+	 *        'add_spco_line_item_filters' ) ); so any code that wants to use the same set of filters during the
429
+	 *        payment options reg step, can apply these filters via the following: apply_filters(
430
+	 *        'FHEE__SPCO__EE_Line_Item_Filter_Collection', new EE_Line_Item_Filter_Collection() ) or to an existing
431
+	 *        filter collection by passing that instead of instantiating a new collection
432
+	 *
433
+	 * @param \EE_Line_Item_Filter_Collection $line_item_filter_collection
434
+	 * @return EE_Line_Item_Filter_Collection
435
+	 * @throws EE_Error
436
+	 * @throws InvalidArgumentException
437
+	 * @throws ReflectionException
438
+	 * @throws \EventEspresso\core\exceptions\EntityNotFoundException
439
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
440
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
441
+	 * @throws \EventEspresso\core\exceptions\InvalidStatusException
442
+	 */
443
+	public static function add_spco_line_item_filters(EE_Line_Item_Filter_Collection $line_item_filter_collection)
444
+	{
445
+		if (! EE_Registry::instance()->SSN instanceof EE_Session) {
446
+			return $line_item_filter_collection;
447
+		}
448
+		if (! EE_Registry::instance()->SSN->checkout() instanceof EE_Checkout) {
449
+			return $line_item_filter_collection;
450
+		}
451
+		if (! EE_Registry::instance()->SSN->checkout()->transaction instanceof EE_Transaction) {
452
+			return $line_item_filter_collection;
453
+		}
454
+		$line_item_filter_collection->add(
455
+			new EE_Billable_Line_Item_Filter(
456
+				EE_SPCO_Reg_Step_Payment_Options::remove_ejected_registrations(
457
+					EE_Registry::instance()->SSN->checkout()->transaction->registrations(
458
+						EE_Registry::instance()->SSN->checkout()->reg_cache_where_params
459
+					)
460
+				)
461
+			)
462
+		);
463
+		$line_item_filter_collection->add(new EE_Non_Zero_Line_Item_Filter());
464
+		return $line_item_filter_collection;
465
+	}
466
+
467
+
468
+	/**
469
+	 * remove_ejected_registrations
470
+	 * if a registrant has lost their potential space at an event due to lack of payment,
471
+	 * then this method removes them from the list of registrations being paid for during this request
472
+	 *
473
+	 * @param \EE_Registration[] $registrations
474
+	 * @return EE_Registration[]
475
+	 * @throws EE_Error
476
+	 * @throws InvalidArgumentException
477
+	 * @throws ReflectionException
478
+	 * @throws \EventEspresso\core\exceptions\EntityNotFoundException
479
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
480
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
481
+	 * @throws \EventEspresso\core\exceptions\InvalidStatusException
482
+	 */
483
+	public static function remove_ejected_registrations(array $registrations)
484
+	{
485
+		$ejected_registrations = EE_SPCO_Reg_Step_Payment_Options::find_registrations_that_lost_their_space(
486
+			$registrations,
487
+			EE_Registry::instance()->SSN->checkout()->revisit
488
+		);
489
+		foreach ($registrations as $REG_ID => $registration) {
490
+			// has this registration lost it's space ?
491
+			if (isset($ejected_registrations[ $REG_ID ])) {
492
+				unset($registrations[ $REG_ID ]);
493
+				continue;
494
+			}
495
+		}
496
+		return $registrations;
497
+	}
498
+
499
+
500
+	/**
501
+	 * find_registrations_that_lost_their_space
502
+	 * If a registrant chooses an offline payment method like Invoice,
503
+	 * then no space is reserved for them at the event until they fully pay fo that site
504
+	 * (unless the event's default reg status is set to APPROVED)
505
+	 * if a registrant then later returns to pay, but the number of spaces available has been reduced due to sales,
506
+	 * then this method will determine which registrations have lost the ability to complete the reg process.
507
+	 *
508
+	 * @param \EE_Registration[] $registrations
509
+	 * @param bool               $revisit
510
+	 * @return array
511
+	 * @throws EE_Error
512
+	 * @throws InvalidArgumentException
513
+	 * @throws ReflectionException
514
+	 * @throws \EventEspresso\core\exceptions\EntityNotFoundException
515
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
516
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
517
+	 * @throws \EventEspresso\core\exceptions\InvalidStatusException
518
+	 */
519
+	public static function find_registrations_that_lost_their_space(array $registrations, $revisit = false)
520
+	{
521
+		// registrations per event
522
+		$event_reg_count = array();
523
+		// spaces left per event
524
+		$event_spaces_remaining = array();
525
+		// tickets left sorted by ID
526
+		$tickets_remaining = array();
527
+		// registrations that have lost their space
528
+		$ejected_registrations = array();
529
+		foreach ($registrations as $REG_ID => $registration) {
530
+			if (
531
+				$registration->status_ID() === EEM_Registration::status_id_approved
532
+				|| apply_filters(
533
+					'FHEE__EE_SPCO_Reg_Step_Payment_Options__find_registrations_that_lost_their_space__allow_reg_payment',
534
+					false,
535
+					$registration,
536
+					$revisit
537
+				)
538
+			) {
539
+				continue;
540
+			}
541
+			$EVT_ID = $registration->event_ID();
542
+			$ticket = $registration->ticket();
543
+			if (! isset($tickets_remaining[ $ticket->ID() ])) {
544
+				$tickets_remaining[ $ticket->ID() ] = $ticket->remaining();
545
+			}
546
+			if ($tickets_remaining[ $ticket->ID() ] > 0) {
547
+				if (! isset($event_reg_count[ $EVT_ID ])) {
548
+					$event_reg_count[ $EVT_ID ] = 0;
549
+				}
550
+				$event_reg_count[ $EVT_ID ]++;
551
+				if (! isset($event_spaces_remaining[ $EVT_ID ])) {
552
+					$event_spaces_remaining[ $EVT_ID ] = $registration->event()->spaces_remaining_for_sale();
553
+				}
554
+			}
555
+			if (
556
+				$revisit
557
+				&& ($tickets_remaining[ $ticket->ID() ] === 0
558
+					|| $event_reg_count[ $EVT_ID ] > $event_spaces_remaining[ $EVT_ID ]
559
+				)
560
+			) {
561
+				$ejected_registrations[ $REG_ID ] = $registration->event();
562
+				if ($registration->status_ID() !== EEM_Registration::status_id_wait_list) {
563
+					/** @type EE_Registration_Processor $registration_processor */
564
+					$registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
565
+					// at this point, we should have enough details about the registrant to consider the registration
566
+					// NOT incomplete
567
+					$registration_processor->manually_update_registration_status(
568
+						$registration,
569
+						EEM_Registration::status_id_wait_list
570
+					);
571
+				}
572
+			}
573
+		}
574
+		return $ejected_registrations;
575
+	}
576
+
577
+
578
+	/**
579
+	 * _hide_reg_step_submit_button
580
+	 * removes the html for the reg step submit button
581
+	 * by replacing it with an empty string via filter callback
582
+	 *
583
+	 * @return void
584
+	 */
585
+	protected function _adjust_registration_status_if_event_old_sold()
586
+	{
587
+	}
588
+
589
+
590
+	/**
591
+	 * _hide_reg_step_submit_button
592
+	 * removes the html for the reg step submit button
593
+	 * by replacing it with an empty string via filter callback
594
+	 *
595
+	 * @return void
596
+	 */
597
+	protected function _hide_reg_step_submit_button_if_revisit()
598
+	{
599
+		if ($this->checkout->revisit) {
600
+			add_filter('FHEE__EE_SPCO_Reg_Step__reg_step_submit_button__sbmt_btn_html', '__return_empty_string');
601
+		}
602
+	}
603
+
604
+
605
+	/**
606
+	 * sold_out_events
607
+	 * displays notices regarding events that have sold out since hte registrant first signed up
608
+	 *
609
+	 * @param \EE_Event[] $sold_out_events_array
610
+	 * @return \EE_Form_Section_Proper
611
+	 * @throws \EE_Error
612
+	 */
613
+	private function _sold_out_events($sold_out_events_array = array())
614
+	{
615
+		// set some defaults
616
+		$this->checkout->selected_method_of_payment = 'events_sold_out';
617
+		$sold_out_events = '';
618
+		foreach ($sold_out_events_array as $sold_out_event) {
619
+			$sold_out_events .= EEH_HTML::li(
620
+				EEH_HTML::span(
621
+					'  ' . $sold_out_event->name(),
622
+					'',
623
+					'dashicons dashicons-marker ee-icon-size-16 pink-text'
624
+				)
625
+			);
626
+		}
627
+		return new EE_Form_Section_Proper(
628
+			array(
629
+				'layout_strategy' => new EE_Template_Layout(
630
+					array(
631
+						'layout_template_file' => SPCO_REG_STEPS_PATH
632
+												  . $this->_slug
633
+												  . '/sold_out_events.template.php',
634
+						'template_args'        => apply_filters(
635
+							'FHEE__EE_SPCO_Reg_Step_Payment_Options___sold_out_events__template_args',
636
+							array(
637
+								'sold_out_events'     => $sold_out_events,
638
+								'sold_out_events_msg' => apply_filters(
639
+									'FHEE__EE_SPCO_Reg_Step_Payment_Options___sold_out_events__sold_out_events_msg',
640
+									sprintf(
641
+										esc_html__(
642
+											'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',
643
+											'event_espresso'
644
+										),
645
+										'<strong>',
646
+										'</strong>',
647
+										'<br />'
648
+									)
649
+								),
650
+							)
651
+						),
652
+					)
653
+				),
654
+			)
655
+		);
656
+	}
657
+
658
+
659
+	/**
660
+	 * _insufficient_spaces_available
661
+	 * displays notices regarding events that do not have enough remaining spaces
662
+	 * to satisfy the current number of registrations looking to pay
663
+	 *
664
+	 * @param \EE_Event[] $insufficient_spaces_events_array
665
+	 * @return \EE_Form_Section_Proper
666
+	 * @throws \EE_Error
667
+	 */
668
+	private function _insufficient_spaces_available($insufficient_spaces_events_array = array())
669
+	{
670
+		// set some defaults
671
+		$this->checkout->selected_method_of_payment = 'invoice';
672
+		$insufficient_space_events = '';
673
+		foreach ($insufficient_spaces_events_array as $event) {
674
+			if ($event instanceof EE_Event) {
675
+				$insufficient_space_events .= EEH_HTML::li(
676
+					EEH_HTML::span(' ' . $event->name(), '', 'dashicons dashicons-marker ee-icon-size-16 pink-text')
677
+				);
678
+			}
679
+		}
680
+		return new EE_Form_Section_Proper(
681
+			array(
682
+				'subsections'     => array(
683
+					'default_hidden_inputs' => $this->reg_step_hidden_inputs(),
684
+					'extra_hidden_inputs'   => $this->_extra_hidden_inputs(),
685
+				),
686
+				'layout_strategy' => new EE_Template_Layout(
687
+					array(
688
+						'layout_template_file' => SPCO_REG_STEPS_PATH
689
+												  . $this->_slug
690
+												  . '/sold_out_events.template.php',
691
+						'template_args'        => apply_filters(
692
+							'FHEE__EE_SPCO_Reg_Step_Payment_Options___insufficient_spaces_available__template_args',
693
+							array(
694
+								'sold_out_events'     => $insufficient_space_events,
695
+								'sold_out_events_msg' => apply_filters(
696
+									'FHEE__EE_SPCO_Reg_Step_Payment_Options___insufficient_spaces_available__insufficient_space_msg',
697
+									esc_html__(
698
+										'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.',
699
+										'event_espresso'
700
+									)
701
+								),
702
+							)
703
+						),
704
+					)
705
+				),
706
+			)
707
+		);
708
+	}
709
+
710
+
711
+	/**
712
+	 * registrations_requiring_pre_approval
713
+	 *
714
+	 * @param array $registrations_requiring_pre_approval
715
+	 * @return EE_Form_Section_Proper
716
+	 * @throws EE_Error
717
+	 * @throws \EventEspresso\core\exceptions\EntityNotFoundException
718
+	 */
719
+	private function _registrations_requiring_pre_approval($registrations_requiring_pre_approval = array())
720
+	{
721
+		$events_requiring_pre_approval = array();
722
+		foreach ($registrations_requiring_pre_approval as $registration) {
723
+			if ($registration instanceof EE_Registration && $registration->event() instanceof EE_Event) {
724
+				$events_requiring_pre_approval[ $registration->event()->ID() ] = EEH_HTML::li(
725
+					EEH_HTML::span(
726
+						'',
727
+						'',
728
+						'dashicons dashicons-marker ee-icon-size-16 orange-text'
729
+					)
730
+					. EEH_HTML::span($registration->event()->name(), '', 'orange-text')
731
+				);
732
+			}
733
+		}
734
+		return new EE_Form_Section_Proper(
735
+			array(
736
+				'layout_strategy' => new EE_Template_Layout(
737
+					array(
738
+						'layout_template_file' => SPCO_REG_STEPS_PATH
739
+												  . $this->_slug
740
+												  . '/events_requiring_pre_approval.template.php', // layout_template
741
+						'template_args'        => apply_filters(
742
+							'FHEE__EE_SPCO_Reg_Step_Payment_Options___sold_out_events__template_args',
743
+							array(
744
+								'events_requiring_pre_approval'     => implode('', $events_requiring_pre_approval),
745
+								'events_requiring_pre_approval_msg' => apply_filters(
746
+									'FHEE__EE_SPCO_Reg_Step_Payment_Options___events_requiring_pre_approval__events_requiring_pre_approval_msg',
747
+									esc_html__(
748
+										'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.',
749
+										'event_espresso'
750
+									)
751
+								),
752
+							)
753
+						),
754
+					)
755
+				),
756
+			)
757
+		);
758
+	}
759
+
760
+
761
+	/**
762
+	 * _no_payment_required
763
+	 *
764
+	 * @param \EE_Event[] $registrations_for_free_events
765
+	 * @return \EE_Form_Section_Proper
766
+	 * @throws \EE_Error
767
+	 */
768
+	private function _no_payment_required($registrations_for_free_events = array())
769
+	{
770
+		// set some defaults
771
+		$this->checkout->selected_method_of_payment = 'no_payment_required';
772
+		// generate no_payment_required form
773
+		return new EE_Form_Section_Proper(
774
+			array(
775
+				'layout_strategy' => new EE_Template_Layout(
776
+					array(
777
+						'layout_template_file' => SPCO_REG_STEPS_PATH
778
+												  . $this->_slug
779
+												  . '/no_payment_required.template.php', // layout_template
780
+						'template_args'        => apply_filters(
781
+							'FHEE__EE_SPCO_Reg_Step_Payment_Options___no_payment_required__template_args',
782
+							array(
783
+								'revisit'                       => $this->checkout->revisit,
784
+								'registrations'                 => array(),
785
+								'ticket_count'                  => array(),
786
+								'registrations_for_free_events' => $registrations_for_free_events,
787
+								'no_payment_required_msg'       => EEH_HTML::p(
788
+									esc_html__('This is a free event, so no billing will occur.', 'event_espresso')
789
+								),
790
+							)
791
+						),
792
+					)
793
+				),
794
+			)
795
+		);
796
+	}
797
+
798
+
799
+	/**
800
+	 * _display_payment_options
801
+	 *
802
+	 * @param string $transaction_details
803
+	 * @return EE_Form_Section_Proper
804
+	 * @throws EE_Error
805
+	 * @throws InvalidArgumentException
806
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
807
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
808
+	 */
809
+	private function _display_payment_options($transaction_details = '')
810
+	{
811
+		// has method_of_payment been set by no-js user?
812
+		$this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment();
813
+		// build payment options form
814
+		return apply_filters(
815
+			'FHEE__EE_SPCO_Reg_Step_Payment_Options___display_payment_options__payment_options_form',
816
+			new EE_Form_Section_Proper(
817
+				array(
818
+					'subsections'     => array(
819
+						'before_payment_options' => apply_filters(
820
+							'FHEE__EE_SPCO_Reg_Step_Payment_Options___display_payment_options__before_payment_options',
821
+							new EE_Form_Section_Proper(
822
+								array('layout_strategy' => new EE_Div_Per_Section_Layout())
823
+							)
824
+						),
825
+						'payment_options'        => $this->_setup_payment_options(),
826
+						'after_payment_options'  => apply_filters(
827
+							'FHEE__EE_SPCO_Reg_Step_Payment_Options___display_payment_options__after_payment_options',
828
+							new EE_Form_Section_Proper(
829
+								array('layout_strategy' => new EE_Div_Per_Section_Layout())
830
+							)
831
+						),
832
+					),
833
+					'layout_strategy' => new EE_Template_Layout(
834
+						array(
835
+							'layout_template_file' => $this->_template,
836
+							'template_args'        => apply_filters(
837
+								'FHEE__EE_SPCO_Reg_Step_Payment_Options___display_payment_options__template_args',
838
+								array(
839
+									'reg_count'                 => $this->line_item_display->total_items(),
840
+									'transaction_details'       => $transaction_details,
841
+									'available_payment_methods' => array(),
842
+								)
843
+							),
844
+						)
845
+					),
846
+				)
847
+			)
848
+		);
849
+	}
850
+
851
+
852
+	/**
853
+	 * _extra_hidden_inputs
854
+	 *
855
+	 * @param bool $no_payment_required
856
+	 * @return \EE_Form_Section_Proper
857
+	 * @throws \EE_Error
858
+	 */
859
+	private function _extra_hidden_inputs($no_payment_required = true)
860
+	{
861
+		return new EE_Form_Section_Proper(
862
+			array(
863
+				'html_id'         => 'ee-' . $this->slug() . '-extra-hidden-inputs',
864
+				'layout_strategy' => new EE_Div_Per_Section_Layout(),
865
+				'subsections'     => array(
866
+					'spco_no_payment_required' => new EE_Hidden_Input(
867
+						array(
868
+							'normalization_strategy' => new EE_Boolean_Normalization(),
869
+							'html_name'              => 'spco_no_payment_required',
870
+							'html_id'                => 'spco-no-payment-required-payment_options',
871
+							'default'                => $no_payment_required,
872
+						)
873
+					),
874
+					'spco_transaction_id'      => new EE_Fixed_Hidden_Input(
875
+						array(
876
+							'normalization_strategy' => new EE_Int_Normalization(),
877
+							'html_name'              => 'spco_transaction_id',
878
+							'html_id'                => 'spco-transaction-id',
879
+							'default'                => $this->checkout->transaction->ID(),
880
+						)
881
+					),
882
+				),
883
+			)
884
+		);
885
+	}
886
+
887
+
888
+	/**
889
+	 *    _apply_registration_payments_to_amount_owing
890
+	 *
891
+	 * @access protected
892
+	 * @param array $registrations
893
+	 * @throws EE_Error
894
+	 */
895
+	protected function _apply_registration_payments_to_amount_owing(array $registrations)
896
+	{
897
+		$payments = array();
898
+		foreach ($registrations as $registration) {
899
+			if ($registration instanceof EE_Registration && $registration->owes_monies_and_can_pay()) {
900
+				$payments += $registration->registration_payments();
901
+			}
902
+		}
903
+		if (! empty($payments)) {
904
+			foreach ($payments as $payment) {
905
+				if ($payment instanceof EE_Registration_Payment) {
906
+					$this->checkout->amount_owing -= $payment->amount();
907
+				}
908
+			}
909
+		}
910
+	}
911
+
912
+
913
+	/**
914
+	 *    _reset_selected_method_of_payment
915
+	 *
916
+	 * @access    private
917
+	 * @param    bool $force_reset
918
+	 * @return void
919
+	 * @throws InvalidArgumentException
920
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
921
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
922
+	 */
923
+	private function _reset_selected_method_of_payment($force_reset = false)
924
+	{
925
+		$reset_payment_method = $force_reset
926
+			? true
927
+			: sanitize_text_field(EE_Registry::instance()->REQ->get('reset_payment_method', false));
928
+		if ($reset_payment_method) {
929
+			$this->checkout->selected_method_of_payment = null;
930
+			$this->checkout->payment_method = null;
931
+			$this->checkout->billing_form = null;
932
+			$this->_save_selected_method_of_payment();
933
+		}
934
+	}
935
+
936
+
937
+	/**
938
+	 * _save_selected_method_of_payment
939
+	 * stores the selected_method_of_payment in the session
940
+	 * so that it's available for all subsequent requests including AJAX
941
+	 *
942
+	 * @access        private
943
+	 * @param string $selected_method_of_payment
944
+	 * @return void
945
+	 * @throws InvalidArgumentException
946
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
947
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
948
+	 */
949
+	private function _save_selected_method_of_payment($selected_method_of_payment = '')
950
+	{
951
+		$selected_method_of_payment = ! empty($selected_method_of_payment)
952
+			? $selected_method_of_payment
953
+			: $this->checkout->selected_method_of_payment;
954
+		EE_Registry::instance()->SSN->set_session_data(
955
+			array('selected_method_of_payment' => $selected_method_of_payment)
956
+		);
957
+	}
958
+
959
+
960
+	/**
961
+	 * _setup_payment_options
962
+	 *
963
+	 * @return EE_Form_Section_Proper
964
+	 * @throws EE_Error
965
+	 * @throws InvalidArgumentException
966
+	 * @throws ReflectionException
967
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
968
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
969
+	 */
970
+	public function _setup_payment_options()
971
+	{
972
+		// load payment method classes
973
+		$this->checkout->available_payment_methods = $this->_get_available_payment_methods();
974
+		if (empty($this->checkout->available_payment_methods)) {
975
+			EE_Error::add_error(
976
+				apply_filters(
977
+					'FHEE__EE_SPCO_Reg_Step_Payment_Options___setup_payment_options__error_message_no_payment_methods',
978
+					sprintf(
979
+						esc_html__(
980
+							'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.',
981
+							'event_espresso'
982
+						),
983
+						'<br>',
984
+						EE_Registry::instance()->CFG->organization->get_pretty('email')
985
+					)
986
+				),
987
+				__FILE__,
988
+				__FUNCTION__,
989
+				__LINE__
990
+			);
991
+		}
992
+		// switch up header depending on number of available payment methods
993
+		$payment_method_header = count($this->checkout->available_payment_methods) > 1
994
+			? apply_filters(
995
+				'FHEE__registration_page_payment_options__method_of_payment_hdr',
996
+				esc_html__('Please Select Your Method of Payment', 'event_espresso')
997
+			)
998
+			: apply_filters(
999
+				'FHEE__registration_page_payment_options__method_of_payment_hdr',
1000
+				esc_html__('Method of Payment', 'event_espresso')
1001
+			);
1002
+		$available_payment_methods = array(
1003
+			// display the "Payment Method" header
1004
+			'payment_method_header' => new EE_Form_Section_HTML(
1005
+				apply_filters(
1006
+					'FHEE__EE_SPCO_Reg_Step_Payment_Options___setup_payment_options__payment_method_header',
1007
+					EEH_HTML::h4($payment_method_header, 'method-of-payment-hdr'),
1008
+					$payment_method_header
1009
+				)
1010
+			),
1011
+		);
1012
+		// the list of actual payment methods ( invoice, paypal, etc ) in a  ( slug => HTML )  format
1013
+		$available_payment_method_options = array();
1014
+		$default_payment_method_option = array();
1015
+		// additional instructions to be displayed and hidden below payment methods (adding a clearing div to start)
1016
+		$payment_methods_billing_info = array(
1017
+			new EE_Form_Section_HTML(
1018
+				EEH_HTML::div('<br />', '', '', 'clear:both;')
1019
+			),
1020
+		);
1021
+		// loop through payment methods
1022
+		foreach ($this->checkout->available_payment_methods as $payment_method) {
1023
+			if ($payment_method instanceof EE_Payment_Method) {
1024
+				$payment_method_button = EEH_HTML::img(
1025
+					$payment_method->button_url(),
1026
+					$payment_method->name(),
1027
+					'spco-payment-method-' . $payment_method->slug() . '-btn-img',
1028
+					'spco-payment-method-btn-img'
1029
+				);
1030
+				// check if any payment methods are set as default
1031
+				// if payment method is already selected OR nothing is selected and this payment method should be
1032
+				// open_by_default
1033
+				if (
1034
+					($this->checkout->selected_method_of_payment === $payment_method->slug())
1035
+					|| (! $this->checkout->selected_method_of_payment && $payment_method->open_by_default())
1036
+				) {
1037
+					$this->checkout->selected_method_of_payment = $payment_method->slug();
1038
+					$this->_save_selected_method_of_payment();
1039
+					$default_payment_method_option[ $payment_method->slug() ] = $payment_method_button;
1040
+				} else {
1041
+					$available_payment_method_options[ $payment_method->slug() ] = $payment_method_button;
1042
+				}
1043
+				$payment_methods_billing_info[ $payment_method->slug(
1044
+				) . '-info' ] = $this->_payment_method_billing_info(
1045
+					$payment_method
1046
+				);
1047
+			}
1048
+		}
1049
+		// prepend available_payment_method_options with default_payment_method_option so that it appears first in list
1050
+		// of PMs
1051
+		$available_payment_method_options = $default_payment_method_option + $available_payment_method_options;
1052
+		// now generate the actual form  inputs
1053
+		$available_payment_methods['available_payment_methods'] = $this->_available_payment_method_inputs(
1054
+			$available_payment_method_options
1055
+		);
1056
+		$available_payment_methods += $payment_methods_billing_info;
1057
+		// build the available payment methods form
1058
+		return new EE_Form_Section_Proper(
1059
+			array(
1060
+				'html_id'         => 'spco-available-methods-of-payment-dv',
1061
+				'subsections'     => $available_payment_methods,
1062
+				'layout_strategy' => new EE_Div_Per_Section_Layout(),
1063
+			)
1064
+		);
1065
+	}
1066
+
1067
+
1068
+	/**
1069
+	 * _get_available_payment_methods
1070
+	 *
1071
+	 * @return EE_Payment_Method[]
1072
+	 * @throws EE_Error
1073
+	 * @throws InvalidArgumentException
1074
+	 * @throws ReflectionException
1075
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1076
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1077
+	 */
1078
+	protected function _get_available_payment_methods()
1079
+	{
1080
+		if (! empty($this->checkout->available_payment_methods)) {
1081
+			return $this->checkout->available_payment_methods;
1082
+		}
1083
+		$available_payment_methods = array();
1084
+		// load EEM_Payment_Method
1085
+		EE_Registry::instance()->load_model('Payment_Method');
1086
+		/** @type EEM_Payment_Method $EEM_Payment_Method */
1087
+		$EEM_Payment_Method = EE_Registry::instance()->LIB->EEM_Payment_Method;
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
+	 */
1109
+	private function _available_payment_method_inputs($available_payment_method_options = array())
1110
+	{
1111
+		// generate inputs
1112
+		return new EE_Form_Section_Proper(
1113
+			array(
1114
+				'html_id'         => 'ee-available-payment-method-inputs',
1115
+				'layout_strategy' => new EE_Div_Per_Section_Layout(),
1116
+				'subsections'     => array(
1117
+					'' => new EE_Radio_Button_Input(
1118
+						$available_payment_method_options,
1119
+						array(
1120
+							'html_name'          => 'selected_method_of_payment',
1121
+							'html_class'         => 'spco-payment-method',
1122
+							'default'            => $this->checkout->selected_method_of_payment,
1123
+							'label_size'         => 11,
1124
+							'enforce_label_size' => true,
1125
+						)
1126
+					),
1127
+				),
1128
+			)
1129
+		);
1130
+	}
1131
+
1132
+
1133
+	/**
1134
+	 *    _payment_method_billing_info
1135
+	 *
1136
+	 * @access    private
1137
+	 * @param    EE_Payment_Method $payment_method
1138
+	 * @return EE_Form_Section_Proper
1139
+	 * @throws EE_Error
1140
+	 * @throws InvalidArgumentException
1141
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1142
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1143
+	 */
1144
+	private function _payment_method_billing_info(EE_Payment_Method $payment_method)
1145
+	{
1146
+		$currently_selected = $this->checkout->selected_method_of_payment === $payment_method->slug()
1147
+			? true
1148
+			: false;
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
+			array(
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'     => array(
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
+	 * @access public
1208
+	 * @return string
1209
+	 * @throws EE_Error
1210
+	 * @throws InvalidArgumentException
1211
+	 * @throws ReflectionException
1212
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1213
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1214
+	 */
1215
+	public function get_billing_form_html_for_payment_method()
1216
+	{
1217
+		// how have they chosen to pay?
1218
+		$this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment(true);
1219
+		$this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment();
1220
+		if (! $this->checkout->payment_method instanceof EE_Payment_Method) {
1221
+			return false;
1222
+		}
1223
+		if (
1224
+			apply_filters(
1225
+				'FHEE__EE_SPCO_Reg_Step_Payment_Options__registration_checkout__selected_payment_method__display_success',
1226
+				false
1227
+			)
1228
+		) {
1229
+			EE_Error::add_success(
1230
+				apply_filters(
1231
+					'FHEE__Single_Page_Checkout__registration_checkout__selected_payment_method',
1232
+					sprintf(
1233
+						esc_html__(
1234
+							'You have selected "%s" as your method of payment. Please note the important payment information below.',
1235
+							'event_espresso'
1236
+						),
1237
+						$this->checkout->payment_method->name()
1238
+					)
1239
+				)
1240
+			);
1241
+		}
1242
+		// now generate billing form for selected method of payment
1243
+		$payment_method_billing_form = $this->_get_billing_form_for_payment_method($this->checkout->payment_method);
1244
+		// fill form with attendee info if applicable
1245
+		if (
1246
+			$payment_method_billing_form instanceof EE_Billing_Attendee_Info_Form
1247
+			&& $this->checkout->transaction_has_primary_registrant()
1248
+		) {
1249
+			$payment_method_billing_form->populate_from_attendee(
1250
+				$this->checkout->transaction->primary_registration()->attendee()
1251
+			);
1252
+		}
1253
+		// and debug content
1254
+		if (
1255
+			$payment_method_billing_form instanceof EE_Billing_Info_Form
1256
+			&& $this->checkout->payment_method->type_obj() instanceof EE_PMT_Base
1257
+		) {
1258
+			$payment_method_billing_form =
1259
+				$this->checkout->payment_method->type_obj()->apply_billing_form_debug_settings(
1260
+					$payment_method_billing_form
1261
+				);
1262
+		}
1263
+		$billing_info = $payment_method_billing_form instanceof EE_Form_Section_Proper
1264
+			? $payment_method_billing_form->get_html()
1265
+			: '';
1266
+		$this->checkout->json_response->set_return_data(array('payment_method_info' => $billing_info));
1267
+		// localize validation rules for main form
1268
+		$this->checkout->current_step->reg_form->localize_validation_rules();
1269
+		$this->checkout->json_response->add_validation_rules(EE_Form_Section_Proper::js_localization());
1270
+		return true;
1271
+	}
1272
+
1273
+
1274
+	/**
1275
+	 * _get_billing_form_for_payment_method
1276
+	 *
1277
+	 * @access private
1278
+	 * @param EE_Payment_Method $payment_method
1279
+	 * @return EE_Billing_Info_Form|EE_Form_Section_HTML
1280
+	 * @throws EE_Error
1281
+	 * @throws InvalidArgumentException
1282
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1283
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1284
+	 */
1285
+	private function _get_billing_form_for_payment_method(EE_Payment_Method $payment_method)
1286
+	{
1287
+		$billing_form = $payment_method->type_obj()->billing_form(
1288
+			$this->checkout->transaction,
1289
+			array('amount_owing' => $this->checkout->amount_owing)
1290
+		);
1291
+		if ($billing_form instanceof EE_Billing_Info_Form) {
1292
+			if (
1293
+				apply_filters(
1294
+					'FHEE__EE_SPCO_Reg_Step_Payment_Options__registration_checkout__selected_payment_method__display_success',
1295
+					false
1296
+				)
1297
+				&& EE_Registry::instance()->REQ->is_set('payment_method')
1298
+			) {
1299
+				EE_Error::add_success(
1300
+					apply_filters(
1301
+						'FHEE__Single_Page_Checkout__registration_checkout__selected_payment_method',
1302
+						sprintf(
1303
+							esc_html__(
1304
+								'You have selected "%s" as your method of payment. Please note the important payment information below.',
1305
+								'event_espresso'
1306
+							),
1307
+							$payment_method->name()
1308
+						)
1309
+					)
1310
+				);
1311
+			}
1312
+			return apply_filters(
1313
+				'FHEE__EE_SPCO_Reg_Step_Payment_Options___get_billing_form_for_payment_method__billing_form',
1314
+				$billing_form,
1315
+				$payment_method
1316
+			);
1317
+		}
1318
+		// no actual billing form, so return empty HTML form section
1319
+		return new EE_Form_Section_HTML();
1320
+	}
1321
+
1322
+
1323
+	/**
1324
+	 * _get_selected_method_of_payment
1325
+	 *
1326
+	 * @access private
1327
+	 * @param boolean $required whether to throw an error if the "selected_method_of_payment"
1328
+	 *                          is not found in the incoming request
1329
+	 * @param string  $request_param
1330
+	 * @return NULL|string
1331
+	 * @throws EE_Error
1332
+	 * @throws InvalidArgumentException
1333
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1334
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1335
+	 */
1336
+	private function _get_selected_method_of_payment(
1337
+		$required = false,
1338
+		$request_param = 'selected_method_of_payment'
1339
+	) {
1340
+		// is selected_method_of_payment set in the request ?
1341
+		$selected_method_of_payment = EE_Registry::instance()->REQ->get($request_param, false);
1342
+		if ($selected_method_of_payment) {
1343
+			// sanitize it
1344
+			$selected_method_of_payment = is_array($selected_method_of_payment)
1345
+				? array_shift($selected_method_of_payment)
1346
+				: $selected_method_of_payment;
1347
+			$selected_method_of_payment = sanitize_text_field($selected_method_of_payment);
1348
+			// store it in the session so that it's available for all subsequent requests including AJAX
1349
+			$this->_save_selected_method_of_payment($selected_method_of_payment);
1350
+		} else {
1351
+			// or is is set in the session ?
1352
+			$selected_method_of_payment = EE_Registry::instance()->SSN->get_session_data(
1353
+				'selected_method_of_payment'
1354
+			);
1355
+		}
1356
+		// do ya really really gotta have it?
1357
+		if (empty($selected_method_of_payment) && $required) {
1358
+			EE_Error::add_error(
1359
+				sprintf(
1360
+					esc_html__(
1361
+						'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.',
1362
+						'event_espresso'
1363
+					),
1364
+					'<br/>',
1365
+					'<br/>',
1366
+					EE_Registry::instance()->CFG->organization->get_pretty('email')
1367
+				),
1368
+				__FILE__,
1369
+				__FUNCTION__,
1370
+				__LINE__
1371
+			);
1372
+			return null;
1373
+		}
1374
+		return $selected_method_of_payment;
1375
+	}
1376
+
1377
+
1378
+
1379
+
1380
+
1381
+
1382
+	/********************************************************************************************************/
1383
+	/***********************************  SWITCH PAYMENT METHOD  ************************************/
1384
+	/********************************************************************************************************/
1385
+	/**
1386
+	 * switch_payment_method
1387
+	 *
1388
+	 * @access public
1389
+	 * @return string
1390
+	 * @throws EE_Error
1391
+	 * @throws InvalidArgumentException
1392
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1393
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1394
+	 */
1395
+	public function switch_payment_method()
1396
+	{
1397
+		if (! $this->_verify_payment_method_is_set()) {
1398
+			return false;
1399
+		}
1400
+		if (
1401
+			apply_filters(
1402
+				'FHEE__EE_SPCO_Reg_Step_Payment_Options__registration_checkout__selected_payment_method__display_success',
1403
+				false
1404
+			)
1405
+		) {
1406
+			EE_Error::add_success(
1407
+				apply_filters(
1408
+					'FHEE__Single_Page_Checkout__registration_checkout__selected_payment_method',
1409
+					sprintf(
1410
+						esc_html__(
1411
+							'You have selected "%s" as your method of payment. Please note the important payment information below.',
1412
+							'event_espresso'
1413
+						),
1414
+						$this->checkout->payment_method->name()
1415
+					)
1416
+				)
1417
+			);
1418
+		}
1419
+		// generate billing form for selected method of payment if it hasn't been done already
1420
+		if ($this->checkout->payment_method->type_obj()->has_billing_form()) {
1421
+			$this->checkout->billing_form = $this->_get_billing_form_for_payment_method(
1422
+				$this->checkout->payment_method
1423
+			);
1424
+		}
1425
+		// fill form with attendee info if applicable
1426
+		if (
1427
+			apply_filters(
1428
+				'FHEE__populate_billing_form_fields_from_attendee',
1429
+				(
1430
+				$this->checkout->billing_form instanceof EE_Billing_Attendee_Info_Form
1431
+				&& $this->checkout->transaction_has_primary_registrant()
1432
+				),
1433
+				$this->checkout->billing_form,
1434
+				$this->checkout->transaction
1435
+			)
1436
+		) {
1437
+			$this->checkout->billing_form->populate_from_attendee(
1438
+				$this->checkout->transaction->primary_registration()->attendee()
1439
+			);
1440
+		}
1441
+		// and debug content
1442
+		if (
1443
+			$this->checkout->billing_form instanceof EE_Billing_Info_Form
1444
+			&& $this->checkout->payment_method->type_obj() instanceof EE_PMT_Base
1445
+		) {
1446
+			$this->checkout->billing_form =
1447
+				$this->checkout->payment_method->type_obj()->apply_billing_form_debug_settings(
1448
+					$this->checkout->billing_form
1449
+				);
1450
+		}
1451
+		// get html and validation rules for form
1452
+		if ($this->checkout->billing_form instanceof EE_Form_Section_Proper) {
1453
+			$this->checkout->json_response->set_return_data(
1454
+				array('payment_method_info' => $this->checkout->billing_form->get_html())
1455
+			);
1456
+			// localize validation rules for main form
1457
+			$this->checkout->billing_form->localize_validation_rules(true);
1458
+			$this->checkout->json_response->add_validation_rules(EE_Form_Section_Proper::js_localization());
1459
+		} else {
1460
+			$this->checkout->json_response->set_return_data(array('payment_method_info' => ''));
1461
+		}
1462
+		// prevents advancement to next step
1463
+		$this->checkout->continue_reg = false;
1464
+		return true;
1465
+	}
1466
+
1467
+
1468
+	/**
1469
+	 * _verify_payment_method_is_set
1470
+	 *
1471
+	 * @return bool
1472
+	 * @throws EE_Error
1473
+	 * @throws InvalidArgumentException
1474
+	 * @throws ReflectionException
1475
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1476
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1477
+	 */
1478
+	protected function _verify_payment_method_is_set()
1479
+	{
1480
+		// generate billing form for selected method of payment if it hasn't been done already
1481
+		if (empty($this->checkout->selected_method_of_payment)) {
1482
+			// how have they chosen to pay?
1483
+			$this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment(true);
1484
+		} else {
1485
+			// choose your own adventure based on method_of_payment
1486
+			switch ($this->checkout->selected_method_of_payment) {
1487
+				case 'events_sold_out':
1488
+					EE_Error::add_attention(
1489
+						apply_filters(
1490
+							'FHEE__EE_SPCO_Reg_Step_Payment_Options___verify_payment_method_is_set__sold_out_events_msg',
1491
+							esc_html__(
1492
+								'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.',
1493
+								'event_espresso'
1494
+							)
1495
+						),
1496
+						__FILE__,
1497
+						__FUNCTION__,
1498
+						__LINE__
1499
+					);
1500
+					return false;
1501
+					break;
1502
+				case 'payments_closed':
1503
+					EE_Error::add_attention(
1504
+						apply_filters(
1505
+							'FHEE__EE_SPCO_Reg_Step_Payment_Options___verify_payment_method_is_set__payments_closed_msg',
1506
+							esc_html__(
1507
+								'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.',
1508
+								'event_espresso'
1509
+							)
1510
+						),
1511
+						__FILE__,
1512
+						__FUNCTION__,
1513
+						__LINE__
1514
+					);
1515
+					return false;
1516
+					break;
1517
+				case 'no_payment_required':
1518
+					EE_Error::add_attention(
1519
+						apply_filters(
1520
+							'FHEE__EE_SPCO_Reg_Step_Payment_Options___verify_payment_method_is_set__no_payment_required_msg',
1521
+							esc_html__(
1522
+								'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.',
1523
+								'event_espresso'
1524
+							)
1525
+						),
1526
+						__FILE__,
1527
+						__FUNCTION__,
1528
+						__LINE__
1529
+					);
1530
+					return false;
1531
+					break;
1532
+				default:
1533
+			}
1534
+		}
1535
+		// verify payment method
1536
+		if (! $this->checkout->payment_method instanceof EE_Payment_Method) {
1537
+			// get payment method for selected method of payment
1538
+			$this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment();
1539
+		}
1540
+		return $this->checkout->payment_method instanceof EE_Payment_Method ? true : false;
1541
+	}
1542
+
1543
+
1544
+
1545
+	/********************************************************************************************************/
1546
+	/***************************************  SAVE PAYER DETAILS  ****************************************/
1547
+	/********************************************************************************************************/
1548
+	/**
1549
+	 * save_payer_details_via_ajax
1550
+	 *
1551
+	 * @return void
1552
+	 * @throws EE_Error
1553
+	 * @throws InvalidArgumentException
1554
+	 * @throws ReflectionException
1555
+	 * @throws RuntimeException
1556
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1557
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1558
+	 */
1559
+	public function save_payer_details_via_ajax()
1560
+	{
1561
+		if (! $this->_verify_payment_method_is_set()) {
1562
+			return;
1563
+		}
1564
+		// generate billing form for selected method of payment if it hasn't been done already
1565
+		if ($this->checkout->payment_method->type_obj()->has_billing_form()) {
1566
+			$this->checkout->billing_form = $this->_get_billing_form_for_payment_method(
1567
+				$this->checkout->payment_method
1568
+			);
1569
+		}
1570
+		// generate primary attendee from payer info if applicable
1571
+		if (! $this->checkout->transaction_has_primary_registrant()) {
1572
+			$attendee = $this->_create_attendee_from_request_data();
1573
+			if ($attendee instanceof EE_Attendee) {
1574
+				foreach ($this->checkout->transaction->registrations() as $registration) {
1575
+					if ($registration->is_primary_registrant()) {
1576
+						$this->checkout->primary_attendee_obj = $attendee;
1577
+						$registration->_add_relation_to($attendee, 'Attendee');
1578
+						$registration->set_attendee_id($attendee->ID());
1579
+						$registration->update_cache_after_object_save('Attendee', $attendee);
1580
+					}
1581
+				}
1582
+			}
1583
+		}
1584
+	}
1585
+
1586
+
1587
+	/**
1588
+	 * create_attendee_from_request_data
1589
+	 * uses info from alternate GET or POST data (such as AJAX) to create a new attendee
1590
+	 *
1591
+	 * @return EE_Attendee
1592
+	 * @throws EE_Error
1593
+	 * @throws InvalidArgumentException
1594
+	 * @throws ReflectionException
1595
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1596
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1597
+	 */
1598
+	protected function _create_attendee_from_request_data()
1599
+	{
1600
+		// get State ID
1601
+		$STA_ID = ! empty($_REQUEST['state']) ? sanitize_text_field($_REQUEST['state']) : '';
1602
+		if (! empty($STA_ID)) {
1603
+			// can we get state object from name ?
1604
+			EE_Registry::instance()->load_model('State');
1605
+			$state = EEM_State::instance()->get_col(array(array('STA_name' => $STA_ID), 'limit' => 1), 'STA_ID');
1606
+			$STA_ID = is_array($state) && ! empty($state) ? reset($state) : $STA_ID;
1607
+		}
1608
+		// get Country ISO
1609
+		$CNT_ISO = ! empty($_REQUEST['country']) ? sanitize_text_field($_REQUEST['country']) : '';
1610
+		if (! empty($CNT_ISO)) {
1611
+			// can we get country object from name ?
1612
+			EE_Registry::instance()->load_model('Country');
1613
+			$country = EEM_Country::instance()->get_col(
1614
+				array(array('CNT_name' => $CNT_ISO), 'limit' => 1),
1615
+				'CNT_ISO'
1616
+			);
1617
+			$CNT_ISO = is_array($country) && ! empty($country) ? reset($country) : $CNT_ISO;
1618
+		}
1619
+		// grab attendee data
1620
+		$attendee_data = array(
1621
+			'ATT_fname'    => ! empty($_REQUEST['first_name']) ? sanitize_text_field($_REQUEST['first_name']) : '',
1622
+			'ATT_lname'    => ! empty($_REQUEST['last_name']) ? sanitize_text_field($_REQUEST['last_name']) : '',
1623
+			'ATT_email'    => ! empty($_REQUEST['email']) ? sanitize_email($_REQUEST['email']) : '',
1624
+			'ATT_address'  => ! empty($_REQUEST['address']) ? sanitize_text_field($_REQUEST['address']) : '',
1625
+			'ATT_address2' => ! empty($_REQUEST['address2']) ? sanitize_text_field($_REQUEST['address2']) : '',
1626
+			'ATT_city'     => ! empty($_REQUEST['city']) ? sanitize_text_field($_REQUEST['city']) : '',
1627
+			'STA_ID'       => $STA_ID,
1628
+			'CNT_ISO'      => $CNT_ISO,
1629
+			'ATT_zip'      => ! empty($_REQUEST['zip']) ? sanitize_text_field($_REQUEST['zip']) : '',
1630
+			'ATT_phone'    => ! empty($_REQUEST['phone']) ? sanitize_text_field($_REQUEST['phone']) : '',
1631
+		);
1632
+		// validate the email address since it is the most important piece of info
1633
+		if (empty($attendee_data['ATT_email']) || $attendee_data['ATT_email'] !== $_REQUEST['email']) {
1634
+			EE_Error::add_error(
1635
+				esc_html__('An invalid email address was submitted.', 'event_espresso'),
1636
+				__FILE__,
1637
+				__FUNCTION__,
1638
+				__LINE__
1639
+			);
1640
+		}
1641
+		// does this attendee already exist in the db ? we're searching using a combination of first name, last name,
1642
+		// AND email address
1643
+		if (
1644
+			! empty($attendee_data['ATT_fname'])
1645
+			&& ! empty($attendee_data['ATT_lname'])
1646
+			&& ! empty($attendee_data['ATT_email'])
1647
+		) {
1648
+			$existing_attendee = EE_Registry::instance()->LIB->EEM_Attendee->find_existing_attendee(
1649
+				array(
1650
+					'ATT_fname' => $attendee_data['ATT_fname'],
1651
+					'ATT_lname' => $attendee_data['ATT_lname'],
1652
+					'ATT_email' => $attendee_data['ATT_email'],
1653
+				)
1654
+			);
1655
+			if ($existing_attendee instanceof EE_Attendee) {
1656
+				return $existing_attendee;
1657
+			}
1658
+		}
1659
+		// no existing attendee? kk let's create a new one
1660
+		// kinda lame, but we need a first and last name to create an attendee, so use the email address if those
1661
+		// don't exist
1662
+		$attendee_data['ATT_fname'] = ! empty($attendee_data['ATT_fname'])
1663
+			? $attendee_data['ATT_fname']
1664
+			: $attendee_data['ATT_email'];
1665
+		$attendee_data['ATT_lname'] = ! empty($attendee_data['ATT_lname'])
1666
+			? $attendee_data['ATT_lname']
1667
+			: $attendee_data['ATT_email'];
1668
+		return EE_Attendee::new_instance($attendee_data);
1669
+	}
1670
+
1671
+
1672
+
1673
+	/********************************************************************************************************/
1674
+	/****************************************  PROCESS REG STEP  *****************************************/
1675
+	/********************************************************************************************************/
1676
+	/**
1677
+	 * process_reg_step
1678
+	 *
1679
+	 * @return bool
1680
+	 * @throws EE_Error
1681
+	 * @throws InvalidArgumentException
1682
+	 * @throws ReflectionException
1683
+	 * @throws \EventEspresso\core\exceptions\EntityNotFoundException
1684
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1685
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1686
+	 * @throws \EventEspresso\core\exceptions\InvalidStatusException
1687
+	 */
1688
+	public function process_reg_step()
1689
+	{
1690
+		// how have they chosen to pay?
1691
+		$this->checkout->selected_method_of_payment = $this->checkout->transaction->is_free()
1692
+			? 'no_payment_required'
1693
+			: $this->_get_selected_method_of_payment(true);
1694
+		// choose your own adventure based on method_of_payment
1695
+		switch ($this->checkout->selected_method_of_payment) {
1696
+			case 'events_sold_out':
1697
+				$this->checkout->redirect = true;
1698
+				$this->checkout->redirect_url = $this->checkout->cancel_page_url;
1699
+				$this->checkout->json_response->set_redirect_url($this->checkout->redirect_url);
1700
+				// mark this reg step as completed
1701
+				$this->set_completed();
1702
+				return false;
1703
+				break;
1704
+
1705
+			case 'payments_closed':
1706
+				if (
1707
+					apply_filters(
1708
+						'FHEE__EE_SPCO_Reg_Step_Payment_Options__process_reg_step__payments_closed__display_success',
1709
+						false
1710
+					)
1711
+				) {
1712
+					EE_Error::add_success(
1713
+						esc_html__('no payment required at this time.', 'event_espresso'),
1714
+						__FILE__,
1715
+						__FUNCTION__,
1716
+						__LINE__
1717
+					);
1718
+				}
1719
+				// mark this reg step as completed
1720
+				$this->set_completed();
1721
+				return true;
1722
+				break;
1723
+
1724
+			case 'no_payment_required':
1725
+				if (
1726
+					apply_filters(
1727
+						'FHEE__EE_SPCO_Reg_Step_Payment_Options__process_reg_step__no_payment_required__display_success',
1728
+						false
1729
+					)
1730
+				) {
1731
+					EE_Error::add_success(
1732
+						esc_html__('no payment required.', 'event_espresso'),
1733
+						__FILE__,
1734
+						__FUNCTION__,
1735
+						__LINE__
1736
+					);
1737
+				}
1738
+				// mark this reg step as completed
1739
+				$this->set_completed();
1740
+				return true;
1741
+				break;
1742
+
1743
+			default:
1744
+				$registrations = EE_Registry::instance()->SSN->checkout()->transaction->registrations(
1745
+					EE_Registry::instance()->SSN->checkout()->reg_cache_where_params
1746
+				);
1747
+				$ejected_registrations = EE_SPCO_Reg_Step_Payment_Options::find_registrations_that_lost_their_space(
1748
+					$registrations,
1749
+					EE_Registry::instance()->SSN->checkout()->revisit
1750
+				);
1751
+				// calculate difference between the two arrays
1752
+				$registrations = array_diff($registrations, $ejected_registrations);
1753
+				if (empty($registrations)) {
1754
+					$this->_redirect_because_event_sold_out();
1755
+					return false;
1756
+				}
1757
+				$payment_successful = $this->_process_payment();
1758
+				if ($payment_successful) {
1759
+					$this->checkout->continue_reg = true;
1760
+					$this->_maybe_set_completed($this->checkout->payment_method);
1761
+				} else {
1762
+					$this->checkout->continue_reg = false;
1763
+				}
1764
+				return $payment_successful;
1765
+		}
1766
+	}
1767
+
1768
+
1769
+	/**
1770
+	 * _redirect_because_event_sold_out
1771
+	 *
1772
+	 * @access protected
1773
+	 * @return void
1774
+	 */
1775
+	protected function _redirect_because_event_sold_out()
1776
+	{
1777
+		$this->checkout->continue_reg = false;
1778
+		// set redirect URL
1779
+		$this->checkout->redirect_url = add_query_arg(
1780
+			array('e_reg_url_link' => $this->checkout->reg_url_link),
1781
+			$this->checkout->current_step->reg_step_url()
1782
+		);
1783
+		$this->checkout->json_response->set_redirect_url($this->checkout->redirect_url);
1784
+	}
1785
+
1786
+
1787
+	/**
1788
+	 * _maybe_set_completed
1789
+	 *
1790
+	 * @access protected
1791
+	 * @param \EE_Payment_Method $payment_method
1792
+	 * @return void
1793
+	 * @throws \EE_Error
1794
+	 */
1795
+	protected function _maybe_set_completed(EE_Payment_Method $payment_method)
1796
+	{
1797
+		switch ($payment_method->type_obj()->payment_occurs()) {
1798
+			case EE_PMT_Base::offsite:
1799
+				break;
1800
+			case EE_PMT_Base::onsite:
1801
+			case EE_PMT_Base::offline:
1802
+				// mark this reg step as completed
1803
+				$this->set_completed();
1804
+				break;
1805
+		}
1806
+	}
1807
+
1808
+
1809
+	/**
1810
+	 *    update_reg_step
1811
+	 *    this is the final step after a user  revisits the site to retry a payment
1812
+	 *
1813
+	 * @return bool
1814
+	 * @throws EE_Error
1815
+	 * @throws InvalidArgumentException
1816
+	 * @throws ReflectionException
1817
+	 * @throws \EventEspresso\core\exceptions\EntityNotFoundException
1818
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1819
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1820
+	 * @throws \EventEspresso\core\exceptions\InvalidStatusException
1821
+	 */
1822
+	public function update_reg_step()
1823
+	{
1824
+		$success = true;
1825
+		// if payment required
1826
+		if ($this->checkout->transaction->total() > 0) {
1827
+			do_action(
1828
+				'AHEE__EE_Single_Page_Checkout__process_finalize_registration__before_gateway',
1829
+				$this->checkout->transaction
1830
+			);
1831
+			// attempt payment via payment method
1832
+			$success = $this->process_reg_step();
1833
+		}
1834
+		if ($success && ! $this->checkout->redirect) {
1835
+			$this->checkout->cart->get_grand_total()->save_this_and_descendants_to_txn(
1836
+				$this->checkout->transaction->ID()
1837
+			);
1838
+			// set return URL
1839
+			$this->checkout->redirect_url = add_query_arg(
1840
+				array('e_reg_url_link' => $this->checkout->reg_url_link),
1841
+				$this->checkout->thank_you_page_url
1842
+			);
1843
+		}
1844
+		return $success;
1845
+	}
1846
+
1847
+
1848
+	/**
1849
+	 *    _process_payment
1850
+	 *
1851
+	 * @access private
1852
+	 * @return bool
1853
+	 * @throws EE_Error
1854
+	 * @throws InvalidArgumentException
1855
+	 * @throws ReflectionException
1856
+	 * @throws RuntimeException
1857
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1858
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1859
+	 */
1860
+	private function _process_payment()
1861
+	{
1862
+		// basically confirm that the event hasn't sold out since they hit the page
1863
+		if (! $this->_last_second_ticket_verifications()) {
1864
+			return false;
1865
+		}
1866
+		// ya gotta make a choice man
1867
+		if (empty($this->checkout->selected_method_of_payment)) {
1868
+			$this->checkout->json_response->set_plz_select_method_of_payment(
1869
+				esc_html__('Please select a method of payment before proceeding.', 'event_espresso')
1870
+			);
1871
+			return false;
1872
+		}
1873
+		// get EE_Payment_Method object
1874
+		if (! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()) {
1875
+			return false;
1876
+		}
1877
+		// setup billing form
1878
+		if ($this->checkout->payment_method->is_on_site()) {
1879
+			$this->checkout->billing_form = $this->_get_billing_form_for_payment_method(
1880
+				$this->checkout->payment_method
1881
+			);
1882
+			// bad billing form ?
1883
+			if (! $this->_billing_form_is_valid()) {
1884
+				return false;
1885
+			}
1886
+		}
1887
+		// ensure primary registrant has been fully processed
1888
+		if (! $this->_setup_primary_registrant_prior_to_payment()) {
1889
+			return false;
1890
+		}
1891
+		// if session is close to expiring (under 10 minutes by default)
1892
+		if ((time() - EE_Registry::instance()->SSN->expiration()) < EE_Registry::instance()->SSN->extension()) {
1893
+			// add some time to session expiration so that payment can be completed
1894
+			EE_Registry::instance()->SSN->extend_expiration();
1895
+		}
1896
+		/** @type EE_Transaction_Processor $transaction_processor */
1897
+		// $transaction_processor = EE_Registry::instance()->load_class( 'Transaction_Processor' );
1898
+		// in case a registrant leaves to an Off-Site Gateway and never returns, we want to approve any registrations
1899
+		// for events with a default reg status of Approved
1900
+		// $transaction_processor->toggle_registration_statuses_for_default_approved_events(
1901
+		//      $this->checkout->transaction, $this->checkout->reg_cache_where_params
1902
+		// );
1903
+		// attempt payment
1904
+		$payment = $this->_attempt_payment($this->checkout->payment_method);
1905
+		// process results
1906
+		$payment = $this->_validate_payment($payment);
1907
+		$payment = $this->_post_payment_processing($payment);
1908
+		// verify payment
1909
+		if ($payment instanceof EE_Payment) {
1910
+			// store that for later
1911
+			$this->checkout->payment = $payment;
1912
+			// we can also consider the TXN to not have been failed, so temporarily upgrade it's status to abandoned
1913
+			$this->checkout->transaction->toggle_failed_transaction_status();
1914
+			$payment_status = $payment->status();
1915
+			if (
1916
+				$payment_status === EEM_Payment::status_id_approved
1917
+				|| $payment_status === EEM_Payment::status_id_pending
1918
+			) {
1919
+				return true;
1920
+			} else {
1921
+				return false;
1922
+			}
1923
+		} elseif ($payment === true) {
1924
+			// please note that offline payment methods will NOT make a payment,
1925
+			// but instead just mark themselves as the PMD_ID on the transaction, and return true
1926
+			$this->checkout->payment = $payment;
1927
+			return true;
1928
+		}
1929
+		// where's my money?
1930
+		return false;
1931
+	}
1932
+
1933
+
1934
+	/**
1935
+	 * _last_second_ticket_verifications
1936
+	 *
1937
+	 * @access public
1938
+	 * @return bool
1939
+	 * @throws EE_Error
1940
+	 */
1941
+	protected function _last_second_ticket_verifications()
1942
+	{
1943
+		// don't bother re-validating if not a return visit
1944
+		if (! $this->checkout->revisit) {
1945
+			return true;
1946
+		}
1947
+		$registrations = $this->checkout->transaction->registrations();
1948
+		if (empty($registrations)) {
1949
+			return false;
1950
+		}
1951
+		foreach ($registrations as $registration) {
1952
+			if ($registration instanceof EE_Registration && ! $registration->is_approved()) {
1953
+				$event = $registration->event_obj();
1954
+				if ($event instanceof EE_Event && $event->is_sold_out(true)) {
1955
+					EE_Error::add_error(
1956
+						apply_filters(
1957
+							'FHEE__EE_SPCO_Reg_Step_Payment_Options___last_second_ticket_verifications__sold_out_events_msg',
1958
+							sprintf(
1959
+								esc_html__(
1960
+									'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.',
1961
+									'event_espresso'
1962
+								),
1963
+								$event->name()
1964
+							)
1965
+						),
1966
+						__FILE__,
1967
+						__FUNCTION__,
1968
+						__LINE__
1969
+					);
1970
+					return false;
1971
+				}
1972
+			}
1973
+		}
1974
+		return true;
1975
+	}
1976
+
1977
+
1978
+	/**
1979
+	 * redirect_form
1980
+	 *
1981
+	 * @access public
1982
+	 * @return bool
1983
+	 * @throws EE_Error
1984
+	 * @throws InvalidArgumentException
1985
+	 * @throws ReflectionException
1986
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
1987
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
1988
+	 */
1989
+	public function redirect_form()
1990
+	{
1991
+		$payment_method_billing_info = $this->_payment_method_billing_info(
1992
+			$this->_get_payment_method_for_selected_method_of_payment()
1993
+		);
1994
+		$html = $payment_method_billing_info->get_html();
1995
+		$html .= $this->checkout->redirect_form;
1996
+		EE_Registry::instance()->REQ->add_output($html);
1997
+		return true;
1998
+	}
1999
+
2000
+
2001
+	/**
2002
+	 * _billing_form_is_valid
2003
+	 *
2004
+	 * @access private
2005
+	 * @return bool
2006
+	 * @throws \EE_Error
2007
+	 */
2008
+	private function _billing_form_is_valid()
2009
+	{
2010
+		if (! $this->checkout->payment_method->type_obj()->has_billing_form()) {
2011
+			return true;
2012
+		}
2013
+		if ($this->checkout->billing_form instanceof EE_Billing_Info_Form) {
2014
+			if ($this->checkout->billing_form->was_submitted()) {
2015
+				$this->checkout->billing_form->receive_form_submission();
2016
+				if ($this->checkout->billing_form->is_valid()) {
2017
+					return true;
2018
+				}
2019
+				$validation_errors = $this->checkout->billing_form->get_validation_errors_accumulated();
2020
+				$error_strings = array();
2021
+				foreach ($validation_errors as $validation_error) {
2022
+					if ($validation_error instanceof EE_Validation_Error) {
2023
+						$form_section = $validation_error->get_form_section();
2024
+						if ($form_section instanceof EE_Form_Input_Base) {
2025
+							$label = $form_section->html_label_text();
2026
+						} elseif ($form_section instanceof EE_Form_Section_Base) {
2027
+							$label = $form_section->name();
2028
+						} else {
2029
+							$label = esc_html__('Validation Error', 'event_espresso');
2030
+						}
2031
+						$error_strings[] = sprintf('%1$s: %2$s', $label, $validation_error->getMessage());
2032
+					}
2033
+				}
2034
+				EE_Error::add_error(
2035
+					sprintf(
2036
+						esc_html__(
2037
+							'One or more billing form inputs are invalid and require correction before proceeding. %1$s %2$s',
2038
+							'event_espresso'
2039
+						),
2040
+						'<br/>',
2041
+						implode('<br/>', $error_strings)
2042
+					),
2043
+					__FILE__,
2044
+					__FUNCTION__,
2045
+					__LINE__
2046
+				);
2047
+			} else {
2048
+				EE_Error::add_error(
2049
+					esc_html__(
2050
+						'The billing form was not submitted or something prevented it\'s submission.',
2051
+						'event_espresso'
2052
+					),
2053
+					__FILE__,
2054
+					__FUNCTION__,
2055
+					__LINE__
2056
+				);
2057
+			}
2058
+		} else {
2059
+			EE_Error::add_error(
2060
+				esc_html__(
2061
+					'The submitted billing form is invalid possibly due to a technical reason.',
2062
+					'event_espresso'
2063
+				),
2064
+				__FILE__,
2065
+				__FUNCTION__,
2066
+				__LINE__
2067
+			);
2068
+		}
2069
+		return false;
2070
+	}
2071
+
2072
+
2073
+	/**
2074
+	 * _setup_primary_registrant_prior_to_payment
2075
+	 * ensures that the primary registrant has a valid attendee object created with the critical details populated
2076
+	 * (first & last name & email) and that both the transaction object and primary registration object have been saved
2077
+	 * plz note that any other registrations will NOT be saved at this point (because they may not have any details
2078
+	 * yet)
2079
+	 *
2080
+	 * @access private
2081
+	 * @return bool
2082
+	 * @throws EE_Error
2083
+	 * @throws InvalidArgumentException
2084
+	 * @throws ReflectionException
2085
+	 * @throws RuntimeException
2086
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2087
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2088
+	 */
2089
+	private function _setup_primary_registrant_prior_to_payment()
2090
+	{
2091
+		// check if transaction has a primary registrant and that it has a related Attendee object
2092
+		// if not, then we need to at least gather some primary registrant data before attempting payment
2093
+		if (
2094
+			$this->checkout->billing_form instanceof EE_Billing_Attendee_Info_Form
2095
+			&& ! $this->checkout->transaction_has_primary_registrant()
2096
+			&& ! $this->_capture_primary_registration_data_from_billing_form()
2097
+		) {
2098
+			return false;
2099
+		}
2100
+		// because saving an object clears it's cache, we need to do the chevy shuffle
2101
+		// grab the primary_registration object
2102
+		$primary_registration = $this->checkout->transaction->primary_registration();
2103
+		// at this point we'll consider a TXN to not have been failed
2104
+		$this->checkout->transaction->toggle_failed_transaction_status();
2105
+		// save the TXN ( which clears cached copy of primary_registration)
2106
+		$this->checkout->transaction->save();
2107
+		// grab TXN ID and save it to the primary_registration
2108
+		$primary_registration->set_transaction_id($this->checkout->transaction->ID());
2109
+		// save what we have so far
2110
+		$primary_registration->save();
2111
+		return true;
2112
+	}
2113
+
2114
+
2115
+	/**
2116
+	 * _capture_primary_registration_data_from_billing_form
2117
+	 *
2118
+	 * @access private
2119
+	 * @return bool
2120
+	 * @throws EE_Error
2121
+	 * @throws InvalidArgumentException
2122
+	 * @throws ReflectionException
2123
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2124
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2125
+	 */
2126
+	private function _capture_primary_registration_data_from_billing_form()
2127
+	{
2128
+		// convert billing form data into an attendee
2129
+		$this->checkout->primary_attendee_obj = $this->checkout->billing_form->create_attendee_from_billing_form_data();
2130
+		if (! $this->checkout->primary_attendee_obj instanceof EE_Attendee) {
2131
+			EE_Error::add_error(
2132
+				sprintf(
2133
+					esc_html__(
2134
+						'The billing form details could not be used for attendee details due to a technical issue.%sPlease try again or contact %s for assistance.',
2135
+						'event_espresso'
2136
+					),
2137
+					'<br/>',
2138
+					EE_Registry::instance()->CFG->organization->get_pretty('email')
2139
+				),
2140
+				__FILE__,
2141
+				__FUNCTION__,
2142
+				__LINE__
2143
+			);
2144
+			return false;
2145
+		}
2146
+		$primary_registration = $this->checkout->transaction->primary_registration();
2147
+		if (! $primary_registration instanceof EE_Registration) {
2148
+			EE_Error::add_error(
2149
+				sprintf(
2150
+					esc_html__(
2151
+						'The primary registrant for this transaction could not be determined due to a technical issue.%sPlease try again or contact %s for assistance.',
2152
+						'event_espresso'
2153
+					),
2154
+					'<br/>',
2155
+					EE_Registry::instance()->CFG->organization->get_pretty('email')
2156
+				),
2157
+				__FILE__,
2158
+				__FUNCTION__,
2159
+				__LINE__
2160
+			);
2161
+			return false;
2162
+		}
2163
+		if (
2164
+			! $primary_registration->_add_relation_to($this->checkout->primary_attendee_obj, 'Attendee')
2165
+			  instanceof
2166
+			  EE_Attendee
2167
+		) {
2168
+			EE_Error::add_error(
2169
+				sprintf(
2170
+					esc_html__(
2171
+						'The primary registrant could not be associated with this transaction due to a technical issue.%sPlease try again or contact %s for assistance.',
2172
+						'event_espresso'
2173
+					),
2174
+					'<br/>',
2175
+					EE_Registry::instance()->CFG->organization->get_pretty('email')
2176
+				),
2177
+				__FILE__,
2178
+				__FUNCTION__,
2179
+				__LINE__
2180
+			);
2181
+			return false;
2182
+		}
2183
+		/** @type EE_Registration_Processor $registration_processor */
2184
+		$registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
2185
+		// at this point, we should have enough details about the registrant to consider the registration NOT incomplete
2186
+		$registration_processor->toggle_incomplete_registration_status_to_default($primary_registration);
2187
+		return true;
2188
+	}
2189
+
2190
+
2191
+	/**
2192
+	 * _get_payment_method_for_selected_method_of_payment
2193
+	 * retrieves a valid payment method
2194
+	 *
2195
+	 * @access public
2196
+	 * @return EE_Payment_Method
2197
+	 * @throws EE_Error
2198
+	 * @throws InvalidArgumentException
2199
+	 * @throws ReflectionException
2200
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2201
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2202
+	 */
2203
+	private function _get_payment_method_for_selected_method_of_payment()
2204
+	{
2205
+		if ($this->checkout->selected_method_of_payment === 'events_sold_out') {
2206
+			$this->_redirect_because_event_sold_out();
2207
+			return null;
2208
+		}
2209
+		// get EE_Payment_Method object
2210
+		if (isset($this->checkout->available_payment_methods[ $this->checkout->selected_method_of_payment ])) {
2211
+			$payment_method = $this->checkout->available_payment_methods[ $this->checkout->selected_method_of_payment ];
2212
+		} else {
2213
+			// load EEM_Payment_Method
2214
+			EE_Registry::instance()->load_model('Payment_Method');
2215
+			/** @type EEM_Payment_Method $EEM_Payment_Method */
2216
+			$EEM_Payment_Method = EE_Registry::instance()->LIB->EEM_Payment_Method;
2217
+			$payment_method = $EEM_Payment_Method->get_one_by_slug($this->checkout->selected_method_of_payment);
2218
+		}
2219
+		// verify $payment_method
2220
+		if (! $payment_method instanceof EE_Payment_Method) {
2221
+			// not a payment
2222
+			EE_Error::add_error(
2223
+				sprintf(
2224
+					esc_html__(
2225
+						'The selected method of payment could not be determined due to a technical issue.%sPlease try again or contact %s for assistance.',
2226
+						'event_espresso'
2227
+					),
2228
+					'<br/>',
2229
+					EE_Registry::instance()->CFG->organization->get_pretty('email')
2230
+				),
2231
+				__FILE__,
2232
+				__FUNCTION__,
2233
+				__LINE__
2234
+			);
2235
+			return null;
2236
+		}
2237
+		// and verify it has a valid Payment_Method Type object
2238
+		if (! $payment_method->type_obj() instanceof EE_PMT_Base) {
2239
+			// not a payment
2240
+			EE_Error::add_error(
2241
+				sprintf(
2242
+					esc_html__(
2243
+						'A valid payment method could not be determined due to a technical issue.%sPlease try again or contact %s for assistance.',
2244
+						'event_espresso'
2245
+					),
2246
+					'<br/>',
2247
+					EE_Registry::instance()->CFG->organization->get_pretty('email')
2248
+				),
2249
+				__FILE__,
2250
+				__FUNCTION__,
2251
+				__LINE__
2252
+			);
2253
+			return null;
2254
+		}
2255
+		return $payment_method;
2256
+	}
2257
+
2258
+
2259
+	/**
2260
+	 *    _attempt_payment
2261
+	 *
2262
+	 * @access    private
2263
+	 * @type    EE_Payment_Method $payment_method
2264
+	 * @return mixed EE_Payment | boolean
2265
+	 * @throws EE_Error
2266
+	 * @throws InvalidArgumentException
2267
+	 * @throws ReflectionException
2268
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2269
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2270
+	 */
2271
+	private function _attempt_payment(EE_Payment_Method $payment_method)
2272
+	{
2273
+		$payment = null;
2274
+		$this->checkout->transaction->save();
2275
+		$payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
2276
+		if (! $payment_processor instanceof EE_Payment_Processor) {
2277
+			return false;
2278
+		}
2279
+		try {
2280
+			$payment_processor->set_revisit($this->checkout->revisit);
2281
+			// generate payment object
2282
+			$payment = $payment_processor->process_payment(
2283
+				$payment_method,
2284
+				$this->checkout->transaction,
2285
+				$this->checkout->amount_owing,
2286
+				$this->checkout->billing_form,
2287
+				$this->_get_return_url($payment_method),
2288
+				'CART',
2289
+				$this->checkout->admin_request,
2290
+				true,
2291
+				$this->reg_step_url()
2292
+			);
2293
+		} catch (Exception $e) {
2294
+			$this->_handle_payment_processor_exception($e);
2295
+		}
2296
+		return $payment;
2297
+	}
2298
+
2299
+
2300
+	/**
2301
+	 * _handle_payment_processor_exception
2302
+	 *
2303
+	 * @access protected
2304
+	 * @param \Exception $e
2305
+	 * @return void
2306
+	 * @throws EE_Error
2307
+	 * @throws InvalidArgumentException
2308
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2309
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2310
+	 */
2311
+	protected function _handle_payment_processor_exception(Exception $e)
2312
+	{
2313
+		EE_Error::add_error(
2314
+			sprintf(
2315
+				esc_html__(
2316
+					'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',
2317
+					'event_espresso'
2318
+				),
2319
+				'<br/>',
2320
+				EE_Registry::instance()->CFG->organization->get_pretty('email'),
2321
+				$e->getMessage(),
2322
+				$e->getFile(),
2323
+				$e->getLine()
2324
+			),
2325
+			__FILE__,
2326
+			__FUNCTION__,
2327
+			__LINE__
2328
+		);
2329
+	}
2330
+
2331
+
2332
+	/**
2333
+	 * _get_return_url
2334
+	 *
2335
+	 * @access protected
2336
+	 * @param \EE_Payment_Method $payment_method
2337
+	 * @return string
2338
+	 * @throws \EE_Error
2339
+	 */
2340
+	protected function _get_return_url(EE_Payment_Method $payment_method)
2341
+	{
2342
+		$return_url = '';
2343
+		switch ($payment_method->type_obj()->payment_occurs()) {
2344
+			case EE_PMT_Base::offsite:
2345
+				$return_url = add_query_arg(
2346
+					array(
2347
+						'action'                     => 'process_gateway_response',
2348
+						'selected_method_of_payment' => $this->checkout->selected_method_of_payment,
2349
+						'spco_txn'                   => $this->checkout->transaction->ID(),
2350
+					),
2351
+					$this->reg_step_url()
2352
+				);
2353
+				break;
2354
+			case EE_PMT_Base::onsite:
2355
+			case EE_PMT_Base::offline:
2356
+				$return_url = $this->checkout->next_step->reg_step_url();
2357
+				break;
2358
+		}
2359
+		return $return_url;
2360
+	}
2361
+
2362
+
2363
+	/**
2364
+	 * _validate_payment
2365
+	 *
2366
+	 * @access private
2367
+	 * @param EE_Payment $payment
2368
+	 * @return EE_Payment|FALSE
2369
+	 * @throws EE_Error
2370
+	 * @throws InvalidArgumentException
2371
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2372
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2373
+	 */
2374
+	private function _validate_payment($payment = null)
2375
+	{
2376
+		if ($this->checkout->payment_method->is_off_line()) {
2377
+			return true;
2378
+		}
2379
+		// verify payment object
2380
+		if (! $payment instanceof EE_Payment) {
2381
+			// not a payment
2382
+			EE_Error::add_error(
2383
+				sprintf(
2384
+					esc_html__(
2385
+						'A valid payment was not generated due to a technical issue.%1$sPlease try again or contact %2$s for assistance.',
2386
+						'event_espresso'
2387
+					),
2388
+					'<br/>',
2389
+					EE_Registry::instance()->CFG->organization->get_pretty('email')
2390
+				),
2391
+				__FILE__,
2392
+				__FUNCTION__,
2393
+				__LINE__
2394
+			);
2395
+			return false;
2396
+		}
2397
+		return $payment;
2398
+	}
2399
+
2400
+
2401
+	/**
2402
+	 * _post_payment_processing
2403
+	 *
2404
+	 * @access private
2405
+	 * @param EE_Payment|bool $payment
2406
+	 * @return bool
2407
+	 * @throws EE_Error
2408
+	 * @throws InvalidArgumentException
2409
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2410
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2411
+	 */
2412
+	private function _post_payment_processing($payment = null)
2413
+	{
2414
+		// Off-Line payment?
2415
+		if ($payment === true) {
2416
+			// $this->_setup_redirect_for_next_step();
2417
+			return true;
2418
+			// On-Site payment?
2419
+		} elseif ($this->checkout->payment_method->is_on_site()) {
2420
+			if (! $this->_process_payment_status($payment, EE_PMT_Base::onsite)) {
2421
+				// $this->_setup_redirect_for_next_step();
2422
+				$this->checkout->continue_reg = false;
2423
+			}
2424
+			// Off-Site payment?
2425
+		} elseif ($this->checkout->payment_method->is_off_site()) {
2426
+			// if a payment object was made and it specifies a redirect url, then we'll setup that redirect info
2427
+			if ($payment instanceof EE_Payment && $payment->redirect_url()) {
2428
+				do_action('AHEE_log', __CLASS__, __FUNCTION__, $payment->redirect_url(), '$payment->redirect_url()');
2429
+				$this->checkout->redirect = true;
2430
+				$this->checkout->redirect_form = $payment->redirect_form();
2431
+				$this->checkout->redirect_url = $this->reg_step_url('redirect_form');
2432
+				// set JSON response
2433
+				$this->checkout->json_response->set_redirect_form($this->checkout->redirect_form);
2434
+				// and lastly, let's bump the payment status to pending
2435
+				$payment->set_status(EEM_Payment::status_id_pending);
2436
+				$payment->save();
2437
+			} else {
2438
+				// we couldn't redirect the user. Let's tell them why.
2439
+				$error_message = sprintf(
2440
+					esc_html__(
2441
+						'It appears the Off Site Payment Method was not configured properly.%sPlease try again or contact %s for assistance.',
2442
+						'event_espresso'
2443
+					),
2444
+					'<br/>',
2445
+					EE_Registry::instance()->CFG->organization->get_pretty('email')
2446
+				);
2447
+				if ($payment instanceof EE_Payment && $payment->gateway_response()) {
2448
+					$error_message = $error_message . '<br/>' . $payment->gateway_response();
2449
+				}
2450
+				$this->checkout->continue_reg = false;
2451
+				EE_Error::add_error(
2452
+					$error_message,
2453
+					__FILE__,
2454
+					__FUNCTION__,
2455
+					__LINE__
2456
+				);
2457
+			}
2458
+		} else {
2459
+			// ummm ya... not Off-Line, not On-Site, not off-Site ????
2460
+			$this->checkout->continue_reg = false;
2461
+			return false;
2462
+		}
2463
+		return $payment;
2464
+	}
2465
+
2466
+
2467
+	/**
2468
+	 *    _process_payment_status
2469
+	 *
2470
+	 * @access private
2471
+	 * @type    EE_Payment $payment
2472
+	 * @param string       $payment_occurs
2473
+	 * @return bool
2474
+	 * @throws EE_Error
2475
+	 * @throws InvalidArgumentException
2476
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2477
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2478
+	 */
2479
+	private function _process_payment_status($payment, $payment_occurs = EE_PMT_Base::offline)
2480
+	{
2481
+		// off-line payment? carry on
2482
+		if ($payment_occurs === EE_PMT_Base::offline) {
2483
+			return true;
2484
+		}
2485
+		// verify payment validity
2486
+		if ($payment instanceof EE_Payment) {
2487
+			do_action('AHEE_log', __CLASS__, __FUNCTION__, $payment->status(), '$payment->status()');
2488
+			$msg = $payment->gateway_response();
2489
+			// check results
2490
+			switch ($payment->status()) {
2491
+				// good payment
2492
+				case EEM_Payment::status_id_approved:
2493
+					EE_Error::add_success(
2494
+						esc_html__('Your payment was processed successfully.', 'event_espresso'),
2495
+						__FILE__,
2496
+						__FUNCTION__,
2497
+						__LINE__
2498
+					);
2499
+					return true;
2500
+					break;
2501
+				// slow payment
2502
+				case EEM_Payment::status_id_pending:
2503
+					if (empty($msg)) {
2504
+						$msg = esc_html__(
2505
+							'Your payment appears to have been processed successfully, but the Instant Payment Notification has not yet been received. It should arrive shortly.',
2506
+							'event_espresso'
2507
+						);
2508
+					}
2509
+					EE_Error::add_success($msg, __FILE__, __FUNCTION__, __LINE__);
2510
+					return true;
2511
+					break;
2512
+				// don't wanna payment
2513
+				case EEM_Payment::status_id_cancelled:
2514
+					if (empty($msg)) {
2515
+						$msg = _n(
2516
+							'Payment cancelled. Please try again.',
2517
+							'Payment cancelled. Please try again or select another method of payment.',
2518
+							count($this->checkout->available_payment_methods),
2519
+							'event_espresso'
2520
+						);
2521
+					}
2522
+					EE_Error::add_attention($msg, __FILE__, __FUNCTION__, __LINE__);
2523
+					return false;
2524
+					break;
2525
+				// not enough payment
2526
+				case EEM_Payment::status_id_declined:
2527
+					if (empty($msg)) {
2528
+						$msg = _n(
2529
+							'We\'re sorry but your payment was declined. Please try again.',
2530
+							'We\'re sorry but your payment was declined. Please try again or select another method of payment.',
2531
+							count($this->checkout->available_payment_methods),
2532
+							'event_espresso'
2533
+						);
2534
+					}
2535
+					EE_Error::add_attention($msg, __FILE__, __FUNCTION__, __LINE__);
2536
+					return false;
2537
+					break;
2538
+				// bad payment
2539
+				case EEM_Payment::status_id_failed:
2540
+					if (! empty($msg)) {
2541
+						EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2542
+						return false;
2543
+					}
2544
+					// default to error below
2545
+					break;
2546
+			}
2547
+		}
2548
+		// off-site payment gateway responses are too unreliable, so let's just assume that
2549
+		// the payment processing is just running slower than the registrant's request
2550
+		if ($payment_occurs === EE_PMT_Base::offsite) {
2551
+			return true;
2552
+		}
2553
+		EE_Error::add_error(
2554
+			sprintf(
2555
+				esc_html__(
2556
+					'Your payment could not be processed successfully due to a technical issue.%sPlease try again or contact %s for assistance.',
2557
+					'event_espresso'
2558
+				),
2559
+				'<br/>',
2560
+				EE_Registry::instance()->CFG->organization->get_pretty('email')
2561
+			),
2562
+			__FILE__,
2563
+			__FUNCTION__,
2564
+			__LINE__
2565
+		);
2566
+		return false;
2567
+	}
2568
+
2569
+
2570
+
2571
+
2572
+
2573
+
2574
+	/********************************************************************************************************/
2575
+	/**********************************  PROCESS GATEWAY RESPONSE  **********************************/
2576
+	/********************************************************************************************************/
2577
+	/**
2578
+	 * process_gateway_response
2579
+	 * this is the return point for Off-Site Payment Methods
2580
+	 * It will attempt to "handle the IPN" if it appears that this has not already occurred,
2581
+	 * otherwise, it will load up the last payment made for the TXN.
2582
+	 * If the payment retrieved looks good, it will then either:
2583
+	 *    complete the current step and allow advancement to the next reg step
2584
+	 *        or present the payment options again
2585
+	 *
2586
+	 * @access private
2587
+	 * @return EE_Payment|FALSE
2588
+	 * @throws EE_Error
2589
+	 * @throws InvalidArgumentException
2590
+	 * @throws ReflectionException
2591
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2592
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2593
+	 * @throws \EventEspresso\core\exceptions\InvalidSessionDataException
2594
+	 */
2595
+	public function process_gateway_response()
2596
+	{
2597
+		$payment = null;
2598
+		// how have they chosen to pay?
2599
+		$this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment(true);
2600
+		// get EE_Payment_Method object
2601
+		if (! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()) {
2602
+			$this->checkout->continue_reg = false;
2603
+			return false;
2604
+		}
2605
+		if (! $this->checkout->payment_method->is_off_site()) {
2606
+			return false;
2607
+		}
2608
+		$this->_validate_offsite_return();
2609
+		// DEBUG LOG
2610
+		// $this->checkout->log(
2611
+		//     __CLASS__,
2612
+		//     __FUNCTION__,
2613
+		//     __LINE__,
2614
+		//     array(
2615
+		//         'selected_method_of_payment' => $this->checkout->selected_method_of_payment,
2616
+		//         'payment_method'             => $this->checkout->payment_method,
2617
+		//     ),
2618
+		//     true
2619
+		// );
2620
+		// verify TXN
2621
+		if ($this->checkout->transaction instanceof EE_Transaction) {
2622
+			$gateway = $this->checkout->payment_method->type_obj()->get_gateway();
2623
+			if (! $gateway instanceof EE_Offsite_Gateway) {
2624
+				$this->checkout->continue_reg = false;
2625
+				return false;
2626
+			}
2627
+			$payment = $this->_process_off_site_payment($gateway);
2628
+			$payment = $this->_process_cancelled_payments($payment);
2629
+			$payment = $this->_validate_payment($payment);
2630
+			// if payment was not declined by the payment gateway or cancelled by the registrant
2631
+			if ($this->_process_payment_status($payment, EE_PMT_Base::offsite)) {
2632
+				// $this->_setup_redirect_for_next_step();
2633
+				// store that for later
2634
+				$this->checkout->payment = $payment;
2635
+				// mark this reg step as completed, as long as gateway doesn't use a separate IPN request,
2636
+				// because we will complete this step during the IPN processing then
2637
+				if ($gateway instanceof EE_Offsite_Gateway && ! $this->handle_IPN_in_this_request()) {
2638
+					$this->set_completed();
2639
+				}
2640
+				return true;
2641
+			}
2642
+		}
2643
+		// DEBUG LOG
2644
+		// $this->checkout->log(
2645
+		//     __CLASS__,
2646
+		//     __FUNCTION__,
2647
+		//     __LINE__,
2648
+		//     array('payment' => $payment)
2649
+		// );
2650
+		$this->checkout->continue_reg = false;
2651
+		return false;
2652
+	}
2653
+
2654
+
2655
+	/**
2656
+	 * _validate_return
2657
+	 *
2658
+	 * @access private
2659
+	 * @return void
2660
+	 * @throws EE_Error
2661
+	 * @throws InvalidArgumentException
2662
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2663
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2664
+	 * @throws \EventEspresso\core\exceptions\InvalidSessionDataException
2665
+	 */
2666
+	private function _validate_offsite_return()
2667
+	{
2668
+		$TXN_ID = (int) EE_Registry::instance()->REQ->get('spco_txn', 0);
2669
+		if ($TXN_ID !== $this->checkout->transaction->ID()) {
2670
+			// Houston... we might have a problem
2671
+			$invalid_TXN = false;
2672
+			// first gather some info
2673
+			$valid_TXN = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2674
+			$primary_registrant = $valid_TXN instanceof EE_Transaction
2675
+				? $valid_TXN->primary_registration()
2676
+				: null;
2677
+			// let's start by retrieving the cart for this TXN
2678
+			$cart = $this->checkout->get_cart_for_transaction($this->checkout->transaction);
2679
+			if ($cart instanceof EE_Cart) {
2680
+				// verify that the current cart has tickets
2681
+				$tickets = $cart->get_tickets();
2682
+				if (empty($tickets)) {
2683
+					$invalid_TXN = true;
2684
+				}
2685
+			} else {
2686
+				$invalid_TXN = true;
2687
+			}
2688
+			$valid_TXN_SID = $primary_registrant instanceof EE_Registration
2689
+				? $primary_registrant->session_ID()
2690
+				: null;
2691
+			// validate current Session ID and compare against valid TXN session ID
2692
+			if (
2693
+				$invalid_TXN // if this is already true, then skip other checks
2694
+				|| EE_Session::instance()->id() === null
2695
+				|| (
2696
+					// WARNING !!!
2697
+					// this could be PayPal sending back duplicate requests (ya they do that)
2698
+					// or it **could** mean someone is simply registering AGAIN after having just done so
2699
+					// so now we need to determine if this current TXN looks valid or not
2700
+					// and whether this reg step has even been started ?
2701
+					EE_Session::instance()->id() === $valid_TXN_SID
2702
+					// really? you're half way through this reg step, but you never started it ?
2703
+					&& $this->checkout->transaction->reg_step_completed($this->slug()) === false
2704
+				)
2705
+			) {
2706
+				$invalid_TXN = true;
2707
+			}
2708
+			if ($invalid_TXN) {
2709
+				// is the valid TXN completed ?
2710
+				if ($valid_TXN instanceof EE_Transaction) {
2711
+					// has this step even been started ?
2712
+					$reg_step_completed = $valid_TXN->reg_step_completed($this->slug());
2713
+					if ($reg_step_completed !== false && $reg_step_completed !== true) {
2714
+						// so it **looks** like this is a double request from PayPal
2715
+						// so let's try to pick up where we left off
2716
+						$this->checkout->transaction = $valid_TXN;
2717
+						$this->checkout->refresh_all_entities(true);
2718
+						return;
2719
+					}
2720
+				}
2721
+				// you appear to be lost?
2722
+				$this->_redirect_wayward_request($primary_registrant);
2723
+			}
2724
+		}
2725
+	}
2726
+
2727
+
2728
+	/**
2729
+	 * _redirect_wayward_request
2730
+	 *
2731
+	 * @access private
2732
+	 * @param \EE_Registration|null $primary_registrant
2733
+	 * @return bool
2734
+	 * @throws EE_Error
2735
+	 * @throws InvalidArgumentException
2736
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2737
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2738
+	 */
2739
+	private function _redirect_wayward_request(EE_Registration $primary_registrant)
2740
+	{
2741
+		if (! $primary_registrant instanceof EE_Registration) {
2742
+			// try redirecting based on the current TXN
2743
+			$primary_registrant = $this->checkout->transaction instanceof EE_Transaction
2744
+				? $this->checkout->transaction->primary_registration()
2745
+				: null;
2746
+		}
2747
+		if (! $primary_registrant instanceof EE_Registration) {
2748
+			EE_Error::add_error(
2749
+				sprintf(
2750
+					esc_html__(
2751
+						'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.',
2752
+						'event_espresso'
2753
+					),
2754
+					'<br/>',
2755
+					EE_Registry::instance()->CFG->organization->get_pretty('email')
2756
+				),
2757
+				__FILE__,
2758
+				__FUNCTION__,
2759
+				__LINE__
2760
+			);
2761
+			return false;
2762
+		}
2763
+		// make sure transaction is not locked
2764
+		$this->checkout->transaction->unlock();
2765
+		wp_safe_redirect(
2766
+			add_query_arg(
2767
+				array(
2768
+					'e_reg_url_link' => $primary_registrant->reg_url_link(),
2769
+				),
2770
+				$this->checkout->thank_you_page_url
2771
+			)
2772
+		);
2773
+		exit();
2774
+	}
2775
+
2776
+
2777
+	/**
2778
+	 * _process_off_site_payment
2779
+	 *
2780
+	 * @access private
2781
+	 * @param \EE_Offsite_Gateway $gateway
2782
+	 * @return EE_Payment
2783
+	 * @throws EE_Error
2784
+	 * @throws InvalidArgumentException
2785
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2786
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2787
+	 */
2788
+	private function _process_off_site_payment(EE_Offsite_Gateway $gateway)
2789
+	{
2790
+		try {
2791
+			$request_data = \EE_Registry::instance()->REQ->params();
2792
+			// if gateway uses_separate_IPN_request, then we don't have to process the IPN manually
2793
+			$this->set_handle_IPN_in_this_request(
2794
+				$gateway->handle_IPN_in_this_request($request_data, false)
2795
+			);
2796
+			if ($this->handle_IPN_in_this_request()) {
2797
+				// get payment details and process results
2798
+				/** @type EE_Payment_Processor $payment_processor */
2799
+				$payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
2800
+				$payment = $payment_processor->process_ipn(
2801
+					$request_data,
2802
+					$this->checkout->transaction,
2803
+					$this->checkout->payment_method,
2804
+					true,
2805
+					false
2806
+				);
2807
+				// $payment_source = 'process_ipn';
2808
+			} else {
2809
+				$payment = $this->checkout->transaction->last_payment();
2810
+				// $payment_source = 'last_payment';
2811
+			}
2812
+		} catch (Exception $e) {
2813
+			// let's just eat the exception and try to move on using any previously set payment info
2814
+			$payment = $this->checkout->transaction->last_payment();
2815
+			// $payment_source = 'last_payment after Exception';
2816
+			// but if we STILL don't have a payment object
2817
+			if (! $payment instanceof EE_Payment) {
2818
+				// then we'll object ! ( not object like a thing... but object like what a lawyer says ! )
2819
+				$this->_handle_payment_processor_exception($e);
2820
+			}
2821
+		}
2822
+		// DEBUG LOG
2823
+		// $this->checkout->log(
2824
+		//     __CLASS__,
2825
+		//     __FUNCTION__,
2826
+		//     __LINE__,
2827
+		//     array(
2828
+		//         'process_ipn_payment' => $payment,
2829
+		//         'payment_source'      => $payment_source,
2830
+		//     )
2831
+		// );
2832
+		return $payment;
2833
+	}
2834
+
2835
+
2836
+	/**
2837
+	 * _process_cancelled_payments
2838
+	 * just makes sure that the payment status gets updated correctly
2839
+	 * so tha tan error isn't generated during payment validation
2840
+	 *
2841
+	 * @access private
2842
+	 * @param EE_Payment $payment
2843
+	 * @return EE_Payment | FALSE
2844
+	 * @throws \EE_Error
2845
+	 */
2846
+	private function _process_cancelled_payments($payment = null)
2847
+	{
2848
+		if (
2849
+			$payment instanceof EE_Payment
2850
+			&& isset($_REQUEST['ee_cancel_payment'])
2851
+			&& $payment->status() === EEM_Payment::status_id_failed
2852
+		) {
2853
+			$payment->set_status(EEM_Payment::status_id_cancelled);
2854
+		}
2855
+		return $payment;
2856
+	}
2857
+
2858
+
2859
+	/**
2860
+	 *    get_transaction_details_for_gateways
2861
+	 *
2862
+	 * @access    public
2863
+	 * @return int
2864
+	 * @throws EE_Error
2865
+	 * @throws InvalidArgumentException
2866
+	 * @throws ReflectionException
2867
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2868
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2869
+	 */
2870
+	public function get_transaction_details_for_gateways()
2871
+	{
2872
+		$txn_details = array();
2873
+		// ya gotta make a choice man
2874
+		if (empty($this->checkout->selected_method_of_payment)) {
2875
+			$txn_details = array(
2876
+				'error' => esc_html__('Please select a method of payment before proceeding.', 'event_espresso'),
2877
+			);
2878
+		}
2879
+		// get EE_Payment_Method object
2880
+		if (
2881
+			empty($txn_details)
2882
+			&&
2883
+			! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()
2884
+		) {
2885
+			$txn_details = array(
2886
+				'selected_method_of_payment' => $this->checkout->selected_method_of_payment,
2887
+				'error'                      => esc_html__(
2888
+					'A valid Payment Method could not be determined.',
2889
+					'event_espresso'
2890
+				),
2891
+			);
2892
+		}
2893
+		if (empty($txn_details) && $this->checkout->transaction instanceof EE_Transaction) {
2894
+			$return_url = $this->_get_return_url($this->checkout->payment_method);
2895
+			$txn_details = array(
2896
+				'TXN_ID'         => $this->checkout->transaction->ID(),
2897
+				'TXN_timestamp'  => $this->checkout->transaction->datetime(),
2898
+				'TXN_total'      => $this->checkout->transaction->total(),
2899
+				'TXN_paid'       => $this->checkout->transaction->paid(),
2900
+				'TXN_reg_steps'  => $this->checkout->transaction->reg_steps(),
2901
+				'STS_ID'         => $this->checkout->transaction->status_ID(),
2902
+				'PMD_ID'         => $this->checkout->transaction->payment_method_ID(),
2903
+				'payment_amount' => $this->checkout->amount_owing,
2904
+				'return_url'     => $return_url,
2905
+				'cancel_url'     => add_query_arg(array('ee_cancel_payment' => true), $return_url),
2906
+				'notify_url'     => EE_Config::instance()->core->txn_page_url(
2907
+					array(
2908
+						'e_reg_url_link'    => $this->checkout->transaction->primary_registration()->reg_url_link(),
2909
+						'ee_payment_method' => $this->checkout->payment_method->slug(),
2910
+					)
2911
+				),
2912
+			);
2913
+		}
2914
+		echo wp_json_encode($txn_details);
2915
+		exit();
2916
+	}
2917
+
2918
+
2919
+	/**
2920
+	 *    __sleep
2921
+	 * to conserve db space, let's remove the reg_form and the EE_Checkout object from EE_SPCO_Reg_Step objects upon
2922
+	 * serialization EE_Checkout will handle the reimplementation of itself upon waking, but we won't bother with the
2923
+	 * reg form, because if needed, it will be regenerated anyways
2924
+	 *
2925
+	 * @return array
2926
+	 */
2927
+	public function __sleep()
2928
+	{
2929
+		// remove the reg form and the checkout
2930
+		return array_diff(array_keys(get_object_vars($this)), array('reg_form', 'checkout', 'line_item_display'));
2931
+	}
2932 2932
 }
Please login to merge, or discard this patch.
Spacing   +74 added lines, -74 removed lines patch added patch discarded remove patch
@@ -129,7 +129,7 @@  discard block
 block discarded – undo
129 129
     {
130 130
         $this->_slug = 'payment_options';
131 131
         $this->_name = esc_html__('Payment Options', 'event_espresso');
132
-        $this->_template = SPCO_REG_STEPS_PATH . $this->_slug . '/payment_options_main.template.php';
132
+        $this->_template = SPCO_REG_STEPS_PATH.$this->_slug.'/payment_options_main.template.php';
133 133
         $this->checkout = $checkout;
134 134
         $this->_reset_success_message();
135 135
         $this->set_instructions(
@@ -212,7 +212,7 @@  discard block
 block discarded – undo
212 212
     {
213 213
         $transaction = $this->checkout->transaction;
214 214
         // if the transaction isn't set or nothing is owed on it, don't enqueue any JS
215
-        if (! $transaction instanceof EE_Transaction || EEH_Money::compare_floats($transaction->remaining(), 0)) {
215
+        if ( ! $transaction instanceof EE_Transaction || EEH_Money::compare_floats($transaction->remaining(), 0)) {
216 216
             return;
217 217
         }
218 218
         foreach (
@@ -307,18 +307,18 @@  discard block
 block discarded – undo
307 307
         foreach ($registrations as $REG_ID => $registration) {
308 308
             /** @var $registration EE_Registration */
309 309
             // has this registration lost it's space ?
310
-            if (isset($ejected_registrations[ $REG_ID ])) {
310
+            if (isset($ejected_registrations[$REG_ID])) {
311 311
                 if ($registration->event()->is_sold_out() || $registration->event()->is_sold_out(true)) {
312
-                    $sold_out_events[ $registration->event()->ID() ] = $registration->event();
312
+                    $sold_out_events[$registration->event()->ID()] = $registration->event();
313 313
                 } else {
314
-                    $insufficient_spaces_available[ $registration->event()->ID() ] = $registration->event();
314
+                    $insufficient_spaces_available[$registration->event()->ID()] = $registration->event();
315 315
                 }
316 316
                 continue;
317 317
             }
318 318
             // event requires admin approval
319 319
             if ($registration->status_ID() === EEM_Registration::status_id_not_approved) {
320 320
                 // add event to list of events with pre-approval reg status
321
-                $registrations_requiring_pre_approval[ $REG_ID ] = $registration;
321
+                $registrations_requiring_pre_approval[$REG_ID] = $registration;
322 322
                 do_action(
323 323
                     'AHEE__EE_SPCO_Reg_Step_Payment_Options__generate_reg_form__event_requires_pre_approval',
324 324
                     $registration->event(),
@@ -335,7 +335,7 @@  discard block
 block discarded – undo
335 335
                 )
336 336
             ) {
337 337
                 // add event to list of events that are sold out
338
-                $sold_out_events[ $registration->event()->ID() ] = $registration->event();
338
+                $sold_out_events[$registration->event()->ID()] = $registration->event();
339 339
                 do_action(
340 340
                     'AHEE__EE_SPCO_Reg_Step_Payment_Options__generate_reg_form__sold_out_event',
341 341
                     $registration->event(),
@@ -345,7 +345,7 @@  discard block
 block discarded – undo
345 345
             }
346 346
             // are they allowed to pay now and is there monies owing?
347 347
             if ($registration->owes_monies_and_can_pay()) {
348
-                $registrations_requiring_payment[ $REG_ID ] = $registration;
348
+                $registrations_requiring_payment[$REG_ID] = $registration;
349 349
                 do_action(
350 350
                     'AHEE__EE_SPCO_Reg_Step_Payment_Options__generate_reg_form__event_requires_payment',
351 351
                     $registration->event(),
@@ -356,28 +356,28 @@  discard block
 block discarded – undo
356 356
                       && $registration->status_ID() !== EEM_Registration::status_id_not_approved
357 357
                       && $registration->ticket()->is_free()
358 358
             ) {
359
-                $registrations_for_free_events[ $registration->ticket()->ID() ] = $registration;
359
+                $registrations_for_free_events[$registration->ticket()->ID()] = $registration;
360 360
             }
361 361
         }
362 362
         $subsections = array();
363 363
         // now decide which template to load
364
-        if (! empty($sold_out_events)) {
364
+        if ( ! empty($sold_out_events)) {
365 365
             $subsections['sold_out_events'] = $this->_sold_out_events($sold_out_events);
366 366
         }
367
-        if (! empty($insufficient_spaces_available)) {
367
+        if ( ! empty($insufficient_spaces_available)) {
368 368
             $subsections['insufficient_space'] = $this->_insufficient_spaces_available(
369 369
                 $insufficient_spaces_available
370 370
             );
371 371
         }
372
-        if (! empty($registrations_requiring_pre_approval)) {
372
+        if ( ! empty($registrations_requiring_pre_approval)) {
373 373
             $subsections['registrations_requiring_pre_approval'] = $this->_registrations_requiring_pre_approval(
374 374
                 $registrations_requiring_pre_approval
375 375
             );
376 376
         }
377
-        if (! empty($registrations_for_free_events)) {
377
+        if ( ! empty($registrations_for_free_events)) {
378 378
             $subsections['no_payment_required'] = $this->_no_payment_required($registrations_for_free_events);
379 379
         }
380
-        if (! empty($registrations_requiring_payment)) {
380
+        if ( ! empty($registrations_requiring_payment)) {
381 381
             if ($this->checkout->amount_owing > 0) {
382 382
                 // autoload Line_Item_Display classes
383 383
                 EEH_Autoloader::register_line_item_filter_autoloaders();
@@ -442,13 +442,13 @@  discard block
 block discarded – undo
442 442
      */
443 443
     public static function add_spco_line_item_filters(EE_Line_Item_Filter_Collection $line_item_filter_collection)
444 444
     {
445
-        if (! EE_Registry::instance()->SSN instanceof EE_Session) {
445
+        if ( ! EE_Registry::instance()->SSN instanceof EE_Session) {
446 446
             return $line_item_filter_collection;
447 447
         }
448
-        if (! EE_Registry::instance()->SSN->checkout() instanceof EE_Checkout) {
448
+        if ( ! EE_Registry::instance()->SSN->checkout() instanceof EE_Checkout) {
449 449
             return $line_item_filter_collection;
450 450
         }
451
-        if (! EE_Registry::instance()->SSN->checkout()->transaction instanceof EE_Transaction) {
451
+        if ( ! EE_Registry::instance()->SSN->checkout()->transaction instanceof EE_Transaction) {
452 452
             return $line_item_filter_collection;
453 453
         }
454 454
         $line_item_filter_collection->add(
@@ -488,8 +488,8 @@  discard block
 block discarded – undo
488 488
         );
489 489
         foreach ($registrations as $REG_ID => $registration) {
490 490
             // has this registration lost it's space ?
491
-            if (isset($ejected_registrations[ $REG_ID ])) {
492
-                unset($registrations[ $REG_ID ]);
491
+            if (isset($ejected_registrations[$REG_ID])) {
492
+                unset($registrations[$REG_ID]);
493 493
                 continue;
494 494
             }
495 495
         }
@@ -540,25 +540,25 @@  discard block
 block discarded – undo
540 540
             }
541 541
             $EVT_ID = $registration->event_ID();
542 542
             $ticket = $registration->ticket();
543
-            if (! isset($tickets_remaining[ $ticket->ID() ])) {
544
-                $tickets_remaining[ $ticket->ID() ] = $ticket->remaining();
543
+            if ( ! isset($tickets_remaining[$ticket->ID()])) {
544
+                $tickets_remaining[$ticket->ID()] = $ticket->remaining();
545 545
             }
546
-            if ($tickets_remaining[ $ticket->ID() ] > 0) {
547
-                if (! isset($event_reg_count[ $EVT_ID ])) {
548
-                    $event_reg_count[ $EVT_ID ] = 0;
546
+            if ($tickets_remaining[$ticket->ID()] > 0) {
547
+                if ( ! isset($event_reg_count[$EVT_ID])) {
548
+                    $event_reg_count[$EVT_ID] = 0;
549 549
                 }
550
-                $event_reg_count[ $EVT_ID ]++;
551
-                if (! isset($event_spaces_remaining[ $EVT_ID ])) {
552
-                    $event_spaces_remaining[ $EVT_ID ] = $registration->event()->spaces_remaining_for_sale();
550
+                $event_reg_count[$EVT_ID]++;
551
+                if ( ! isset($event_spaces_remaining[$EVT_ID])) {
552
+                    $event_spaces_remaining[$EVT_ID] = $registration->event()->spaces_remaining_for_sale();
553 553
                 }
554 554
             }
555 555
             if (
556 556
                 $revisit
557
-                && ($tickets_remaining[ $ticket->ID() ] === 0
558
-                    || $event_reg_count[ $EVT_ID ] > $event_spaces_remaining[ $EVT_ID ]
557
+                && ($tickets_remaining[$ticket->ID()] === 0
558
+                    || $event_reg_count[$EVT_ID] > $event_spaces_remaining[$EVT_ID]
559 559
                 )
560 560
             ) {
561
-                $ejected_registrations[ $REG_ID ] = $registration->event();
561
+                $ejected_registrations[$REG_ID] = $registration->event();
562 562
                 if ($registration->status_ID() !== EEM_Registration::status_id_wait_list) {
563 563
                     /** @type EE_Registration_Processor $registration_processor */
564 564
                     $registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
@@ -618,7 +618,7 @@  discard block
 block discarded – undo
618 618
         foreach ($sold_out_events_array as $sold_out_event) {
619 619
             $sold_out_events .= EEH_HTML::li(
620 620
                 EEH_HTML::span(
621
-                    '  ' . $sold_out_event->name(),
621
+                    '  '.$sold_out_event->name(),
622 622
                     '',
623 623
                     'dashicons dashicons-marker ee-icon-size-16 pink-text'
624 624
                 )
@@ -673,7 +673,7 @@  discard block
 block discarded – undo
673 673
         foreach ($insufficient_spaces_events_array as $event) {
674 674
             if ($event instanceof EE_Event) {
675 675
                 $insufficient_space_events .= EEH_HTML::li(
676
-                    EEH_HTML::span(' ' . $event->name(), '', 'dashicons dashicons-marker ee-icon-size-16 pink-text')
676
+                    EEH_HTML::span(' '.$event->name(), '', 'dashicons dashicons-marker ee-icon-size-16 pink-text')
677 677
                 );
678 678
             }
679 679
         }
@@ -721,7 +721,7 @@  discard block
 block discarded – undo
721 721
         $events_requiring_pre_approval = array();
722 722
         foreach ($registrations_requiring_pre_approval as $registration) {
723 723
             if ($registration instanceof EE_Registration && $registration->event() instanceof EE_Event) {
724
-                $events_requiring_pre_approval[ $registration->event()->ID() ] = EEH_HTML::li(
724
+                $events_requiring_pre_approval[$registration->event()->ID()] = EEH_HTML::li(
725 725
                     EEH_HTML::span(
726 726
                         '',
727 727
                         '',
@@ -860,7 +860,7 @@  discard block
 block discarded – undo
860 860
     {
861 861
         return new EE_Form_Section_Proper(
862 862
             array(
863
-                'html_id'         => 'ee-' . $this->slug() . '-extra-hidden-inputs',
863
+                'html_id'         => 'ee-'.$this->slug().'-extra-hidden-inputs',
864 864
                 'layout_strategy' => new EE_Div_Per_Section_Layout(),
865 865
                 'subsections'     => array(
866 866
                     'spco_no_payment_required' => new EE_Hidden_Input(
@@ -900,7 +900,7 @@  discard block
 block discarded – undo
900 900
                 $payments += $registration->registration_payments();
901 901
             }
902 902
         }
903
-        if (! empty($payments)) {
903
+        if ( ! empty($payments)) {
904 904
             foreach ($payments as $payment) {
905 905
                 if ($payment instanceof EE_Registration_Payment) {
906 906
                     $this->checkout->amount_owing -= $payment->amount();
@@ -1024,7 +1024,7 @@  discard block
 block discarded – undo
1024 1024
                 $payment_method_button = EEH_HTML::img(
1025 1025
                     $payment_method->button_url(),
1026 1026
                     $payment_method->name(),
1027
-                    'spco-payment-method-' . $payment_method->slug() . '-btn-img',
1027
+                    'spco-payment-method-'.$payment_method->slug().'-btn-img',
1028 1028
                     'spco-payment-method-btn-img'
1029 1029
                 );
1030 1030
                 // check if any payment methods are set as default
@@ -1032,16 +1032,16 @@  discard block
 block discarded – undo
1032 1032
                 // open_by_default
1033 1033
                 if (
1034 1034
                     ($this->checkout->selected_method_of_payment === $payment_method->slug())
1035
-                    || (! $this->checkout->selected_method_of_payment && $payment_method->open_by_default())
1035
+                    || ( ! $this->checkout->selected_method_of_payment && $payment_method->open_by_default())
1036 1036
                 ) {
1037 1037
                     $this->checkout->selected_method_of_payment = $payment_method->slug();
1038 1038
                     $this->_save_selected_method_of_payment();
1039
-                    $default_payment_method_option[ $payment_method->slug() ] = $payment_method_button;
1039
+                    $default_payment_method_option[$payment_method->slug()] = $payment_method_button;
1040 1040
                 } else {
1041
-                    $available_payment_method_options[ $payment_method->slug() ] = $payment_method_button;
1041
+                    $available_payment_method_options[$payment_method->slug()] = $payment_method_button;
1042 1042
                 }
1043
-                $payment_methods_billing_info[ $payment_method->slug(
1044
-                ) . '-info' ] = $this->_payment_method_billing_info(
1043
+                $payment_methods_billing_info[$payment_method->slug(
1044
+                ).'-info'] = $this->_payment_method_billing_info(
1045 1045
                     $payment_method
1046 1046
                 );
1047 1047
             }
@@ -1077,7 +1077,7 @@  discard block
 block discarded – undo
1077 1077
      */
1078 1078
     protected function _get_available_payment_methods()
1079 1079
     {
1080
-        if (! empty($this->checkout->available_payment_methods)) {
1080
+        if ( ! empty($this->checkout->available_payment_methods)) {
1081 1081
             return $this->checkout->available_payment_methods;
1082 1082
         }
1083 1083
         $available_payment_methods = array();
@@ -1092,7 +1092,7 @@  discard block
 block discarded – undo
1092 1092
         );
1093 1093
         foreach ($payment_methods as $payment_method) {
1094 1094
             if ($payment_method instanceof EE_Payment_Method) {
1095
-                $available_payment_methods[ $payment_method->slug() ] = $payment_method;
1095
+                $available_payment_methods[$payment_method->slug()] = $payment_method;
1096 1096
             }
1097 1097
         }
1098 1098
         return $available_payment_methods;
@@ -1187,7 +1187,7 @@  discard block
 block discarded – undo
1187 1187
         );
1188 1188
         return new EE_Form_Section_Proper(
1189 1189
             array(
1190
-                'html_id'         => 'spco-payment-method-info-' . $payment_method->slug(),
1190
+                'html_id'         => 'spco-payment-method-info-'.$payment_method->slug(),
1191 1191
                 'html_class'      => 'spco-payment-method-info-dv',
1192 1192
                 // only display the selected or default PM
1193 1193
                 'html_style'      => $currently_selected ? '' : 'display:none;',
@@ -1217,7 +1217,7 @@  discard block
 block discarded – undo
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 (
@@ -1394,7 +1394,7 @@  discard block
 block discarded – undo
1394 1394
      */
1395 1395
     public function switch_payment_method()
1396 1396
     {
1397
-        if (! $this->_verify_payment_method_is_set()) {
1397
+        if ( ! $this->_verify_payment_method_is_set()) {
1398 1398
             return false;
1399 1399
         }
1400 1400
         if (
@@ -1533,7 +1533,7 @@  discard block
 block discarded – undo
1533 1533
             }
1534 1534
         }
1535 1535
         // verify payment method
1536
-        if (! $this->checkout->payment_method instanceof EE_Payment_Method) {
1536
+        if ( ! $this->checkout->payment_method instanceof EE_Payment_Method) {
1537 1537
             // get payment method for selected method of payment
1538 1538
             $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment();
1539 1539
         }
@@ -1558,7 +1558,7 @@  discard block
 block discarded – undo
1558 1558
      */
1559 1559
     public function save_payer_details_via_ajax()
1560 1560
     {
1561
-        if (! $this->_verify_payment_method_is_set()) {
1561
+        if ( ! $this->_verify_payment_method_is_set()) {
1562 1562
             return;
1563 1563
         }
1564 1564
         // generate billing form for selected method of payment if it hasn't been done already
@@ -1568,7 +1568,7 @@  discard block
 block discarded – undo
1568 1568
             );
1569 1569
         }
1570 1570
         // generate primary attendee from payer info if applicable
1571
-        if (! $this->checkout->transaction_has_primary_registrant()) {
1571
+        if ( ! $this->checkout->transaction_has_primary_registrant()) {
1572 1572
             $attendee = $this->_create_attendee_from_request_data();
1573 1573
             if ($attendee instanceof EE_Attendee) {
1574 1574
                 foreach ($this->checkout->transaction->registrations() as $registration) {
@@ -1599,7 +1599,7 @@  discard block
 block discarded – undo
1599 1599
     {
1600 1600
         // get State ID
1601 1601
         $STA_ID = ! empty($_REQUEST['state']) ? sanitize_text_field($_REQUEST['state']) : '';
1602
-        if (! empty($STA_ID)) {
1602
+        if ( ! empty($STA_ID)) {
1603 1603
             // can we get state object from name ?
1604 1604
             EE_Registry::instance()->load_model('State');
1605 1605
             $state = EEM_State::instance()->get_col(array(array('STA_name' => $STA_ID), 'limit' => 1), 'STA_ID');
@@ -1607,7 +1607,7 @@  discard block
 block discarded – undo
1607 1607
         }
1608 1608
         // get Country ISO
1609 1609
         $CNT_ISO = ! empty($_REQUEST['country']) ? sanitize_text_field($_REQUEST['country']) : '';
1610
-        if (! empty($CNT_ISO)) {
1610
+        if ( ! empty($CNT_ISO)) {
1611 1611
             // can we get country object from name ?
1612 1612
             EE_Registry::instance()->load_model('Country');
1613 1613
             $country = EEM_Country::instance()->get_col(
@@ -1860,7 +1860,7 @@  discard block
 block discarded – undo
1860 1860
     private function _process_payment()
1861 1861
     {
1862 1862
         // basically confirm that the event hasn't sold out since they hit the page
1863
-        if (! $this->_last_second_ticket_verifications()) {
1863
+        if ( ! $this->_last_second_ticket_verifications()) {
1864 1864
             return false;
1865 1865
         }
1866 1866
         // ya gotta make a choice man
@@ -1871,7 +1871,7 @@  discard block
 block discarded – undo
1871 1871
             return false;
1872 1872
         }
1873 1873
         // get EE_Payment_Method object
1874
-        if (! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()) {
1874
+        if ( ! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()) {
1875 1875
             return false;
1876 1876
         }
1877 1877
         // setup billing form
@@ -1880,12 +1880,12 @@  discard block
 block discarded – undo
1880 1880
                 $this->checkout->payment_method
1881 1881
             );
1882 1882
             // bad billing form ?
1883
-            if (! $this->_billing_form_is_valid()) {
1883
+            if ( ! $this->_billing_form_is_valid()) {
1884 1884
                 return false;
1885 1885
             }
1886 1886
         }
1887 1887
         // ensure primary registrant has been fully processed
1888
-        if (! $this->_setup_primary_registrant_prior_to_payment()) {
1888
+        if ( ! $this->_setup_primary_registrant_prior_to_payment()) {
1889 1889
             return false;
1890 1890
         }
1891 1891
         // if session is close to expiring (under 10 minutes by default)
@@ -1941,7 +1941,7 @@  discard block
 block discarded – undo
1941 1941
     protected function _last_second_ticket_verifications()
1942 1942
     {
1943 1943
         // don't bother re-validating if not a return visit
1944
-        if (! $this->checkout->revisit) {
1944
+        if ( ! $this->checkout->revisit) {
1945 1945
             return true;
1946 1946
         }
1947 1947
         $registrations = $this->checkout->transaction->registrations();
@@ -2007,7 +2007,7 @@  discard block
 block discarded – undo
2007 2007
      */
2008 2008
     private function _billing_form_is_valid()
2009 2009
     {
2010
-        if (! $this->checkout->payment_method->type_obj()->has_billing_form()) {
2010
+        if ( ! $this->checkout->payment_method->type_obj()->has_billing_form()) {
2011 2011
             return true;
2012 2012
         }
2013 2013
         if ($this->checkout->billing_form instanceof EE_Billing_Info_Form) {
@@ -2127,7 +2127,7 @@  discard block
 block discarded – undo
2127 2127
     {
2128 2128
         // convert billing form data into an attendee
2129 2129
         $this->checkout->primary_attendee_obj = $this->checkout->billing_form->create_attendee_from_billing_form_data();
2130
-        if (! $this->checkout->primary_attendee_obj instanceof EE_Attendee) {
2130
+        if ( ! $this->checkout->primary_attendee_obj instanceof EE_Attendee) {
2131 2131
             EE_Error::add_error(
2132 2132
                 sprintf(
2133 2133
                     esc_html__(
@@ -2144,7 +2144,7 @@  discard block
 block discarded – undo
2144 2144
             return false;
2145 2145
         }
2146 2146
         $primary_registration = $this->checkout->transaction->primary_registration();
2147
-        if (! $primary_registration instanceof EE_Registration) {
2147
+        if ( ! $primary_registration instanceof EE_Registration) {
2148 2148
             EE_Error::add_error(
2149 2149
                 sprintf(
2150 2150
                     esc_html__(
@@ -2207,8 +2207,8 @@  discard block
 block discarded – undo
2207 2207
             return null;
2208 2208
         }
2209 2209
         // get EE_Payment_Method object
2210
-        if (isset($this->checkout->available_payment_methods[ $this->checkout->selected_method_of_payment ])) {
2211
-            $payment_method = $this->checkout->available_payment_methods[ $this->checkout->selected_method_of_payment ];
2210
+        if (isset($this->checkout->available_payment_methods[$this->checkout->selected_method_of_payment])) {
2211
+            $payment_method = $this->checkout->available_payment_methods[$this->checkout->selected_method_of_payment];
2212 2212
         } else {
2213 2213
             // load EEM_Payment_Method
2214 2214
             EE_Registry::instance()->load_model('Payment_Method');
@@ -2217,7 +2217,7 @@  discard block
 block discarded – undo
2217 2217
             $payment_method = $EEM_Payment_Method->get_one_by_slug($this->checkout->selected_method_of_payment);
2218 2218
         }
2219 2219
         // verify $payment_method
2220
-        if (! $payment_method instanceof EE_Payment_Method) {
2220
+        if ( ! $payment_method instanceof EE_Payment_Method) {
2221 2221
             // not a payment
2222 2222
             EE_Error::add_error(
2223 2223
                 sprintf(
@@ -2235,7 +2235,7 @@  discard block
 block discarded – undo
2235 2235
             return null;
2236 2236
         }
2237 2237
         // and verify it has a valid Payment_Method Type object
2238
-        if (! $payment_method->type_obj() instanceof EE_PMT_Base) {
2238
+        if ( ! $payment_method->type_obj() instanceof EE_PMT_Base) {
2239 2239
             // not a payment
2240 2240
             EE_Error::add_error(
2241 2241
                 sprintf(
@@ -2273,7 +2273,7 @@  discard block
 block discarded – undo
2273 2273
         $payment = null;
2274 2274
         $this->checkout->transaction->save();
2275 2275
         $payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
2276
-        if (! $payment_processor instanceof EE_Payment_Processor) {
2276
+        if ( ! $payment_processor instanceof EE_Payment_Processor) {
2277 2277
             return false;
2278 2278
         }
2279 2279
         try {
@@ -2377,7 +2377,7 @@  discard block
 block discarded – undo
2377 2377
             return true;
2378 2378
         }
2379 2379
         // verify payment object
2380
-        if (! $payment instanceof EE_Payment) {
2380
+        if ( ! $payment instanceof EE_Payment) {
2381 2381
             // not a payment
2382 2382
             EE_Error::add_error(
2383 2383
                 sprintf(
@@ -2417,7 +2417,7 @@  discard block
 block discarded – undo
2417 2417
             return true;
2418 2418
             // On-Site payment?
2419 2419
         } elseif ($this->checkout->payment_method->is_on_site()) {
2420
-            if (! $this->_process_payment_status($payment, EE_PMT_Base::onsite)) {
2420
+            if ( ! $this->_process_payment_status($payment, EE_PMT_Base::onsite)) {
2421 2421
                 // $this->_setup_redirect_for_next_step();
2422 2422
                 $this->checkout->continue_reg = false;
2423 2423
             }
@@ -2445,7 +2445,7 @@  discard block
 block discarded – undo
2445 2445
                     EE_Registry::instance()->CFG->organization->get_pretty('email')
2446 2446
                 );
2447 2447
                 if ($payment instanceof EE_Payment && $payment->gateway_response()) {
2448
-                    $error_message = $error_message . '<br/>' . $payment->gateway_response();
2448
+                    $error_message = $error_message.'<br/>'.$payment->gateway_response();
2449 2449
                 }
2450 2450
                 $this->checkout->continue_reg = false;
2451 2451
                 EE_Error::add_error(
@@ -2537,7 +2537,7 @@  discard block
 block discarded – undo
2537 2537
                     break;
2538 2538
                 // bad payment
2539 2539
                 case EEM_Payment::status_id_failed:
2540
-                    if (! empty($msg)) {
2540
+                    if ( ! empty($msg)) {
2541 2541
                         EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2542 2542
                         return false;
2543 2543
                     }
@@ -2598,11 +2598,11 @@  discard block
 block discarded – undo
2598 2598
         // how have they chosen to pay?
2599 2599
         $this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment(true);
2600 2600
         // get EE_Payment_Method object
2601
-        if (! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()) {
2601
+        if ( ! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()) {
2602 2602
             $this->checkout->continue_reg = false;
2603 2603
             return false;
2604 2604
         }
2605
-        if (! $this->checkout->payment_method->is_off_site()) {
2605
+        if ( ! $this->checkout->payment_method->is_off_site()) {
2606 2606
             return false;
2607 2607
         }
2608 2608
         $this->_validate_offsite_return();
@@ -2620,7 +2620,7 @@  discard block
 block discarded – undo
2620 2620
         // verify TXN
2621 2621
         if ($this->checkout->transaction instanceof EE_Transaction) {
2622 2622
             $gateway = $this->checkout->payment_method->type_obj()->get_gateway();
2623
-            if (! $gateway instanceof EE_Offsite_Gateway) {
2623
+            if ( ! $gateway instanceof EE_Offsite_Gateway) {
2624 2624
                 $this->checkout->continue_reg = false;
2625 2625
                 return false;
2626 2626
             }
@@ -2738,13 +2738,13 @@  discard block
 block discarded – undo
2738 2738
      */
2739 2739
     private function _redirect_wayward_request(EE_Registration $primary_registrant)
2740 2740
     {
2741
-        if (! $primary_registrant instanceof EE_Registration) {
2741
+        if ( ! $primary_registrant instanceof EE_Registration) {
2742 2742
             // try redirecting based on the current TXN
2743 2743
             $primary_registrant = $this->checkout->transaction instanceof EE_Transaction
2744 2744
                 ? $this->checkout->transaction->primary_registration()
2745 2745
                 : null;
2746 2746
         }
2747
-        if (! $primary_registrant instanceof EE_Registration) {
2747
+        if ( ! $primary_registrant instanceof EE_Registration) {
2748 2748
             EE_Error::add_error(
2749 2749
                 sprintf(
2750 2750
                     esc_html__(
@@ -2814,7 +2814,7 @@  discard block
 block discarded – undo
2814 2814
             $payment = $this->checkout->transaction->last_payment();
2815 2815
             // $payment_source = 'last_payment after Exception';
2816 2816
             // but if we STILL don't have a payment object
2817
-            if (! $payment instanceof EE_Payment) {
2817
+            if ( ! $payment instanceof EE_Payment) {
2818 2818
                 // then we'll object ! ( not object like a thing... but object like what a lawyer says ! )
2819 2819
                 $this->_handle_payment_processor_exception($e);
2820 2820
             }
Please login to merge, or discard this patch.
core/db_classes/EE_Message_Template_Group.class.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -211,7 +211,7 @@
 block discarded – undo
211 211
      * appropriately.
212 212
      *
213 213
      * @throws EE_Error
214
-     * @return EE_message_type|false if exception thrown.
214
+     * @return null|EE_message_type if exception thrown.
215 215
      */
216 216
     public function message_type_obj()
217 217
     {
Please login to merge, or discard this patch.
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -48,7 +48,7 @@  discard block
 block discarded – undo
48 48
      */
49 49
     public function set_message_type($message_type = false)
50 50
     {
51
-        if (! $message_type) {
51
+        if ( ! $message_type) {
52 52
             throw new EE_Error(esc_html__('Missing required value for the message_type parameter', 'event_espresso'));
53 53
         }
54 54
         $this->set('MTP_message_type', $message_type);
@@ -61,7 +61,7 @@  discard block
 block discarded – undo
61 61
      */
62 62
     public function set_messenger($messenger = false)
63 63
     {
64
-        if (! $messenger) {
64
+        if ( ! $messenger) {
65 65
             throw new EE_Error(esc_html__('Missing required value for the messenger parameter', 'event_espresso'));
66 66
         }
67 67
         $this->set('MTP_messenger', $messenger);
@@ -74,7 +74,7 @@  discard block
 block discarded – undo
74 74
      */
75 75
     public function set_group_template_id($GRP_ID = false)
76 76
     {
77
-        if (! $GRP_ID) {
77
+        if ( ! $GRP_ID) {
78 78
             throw new EE_Error(
79 79
                 esc_html__(
80 80
                     'Missing required value for the message template group id',
@@ -290,7 +290,7 @@  discard block
 block discarded – undo
290 290
         }
291 291
         // note contexts could have CHECKBOX fields per context. So we return the objects indexed by context AND field.
292 292
         foreach ($mtps as $mtp) {
293
-            $mtps_arr[ $mtp->get('MTP_context') ][ $mtp->get('MTP_template_field') ] = $mtp;
293
+            $mtps_arr[$mtp->get('MTP_context')][$mtp->get('MTP_template_field')] = $mtp;
294 294
         }
295 295
         return $mtps_arr;
296 296
     }
@@ -430,7 +430,7 @@  discard block
 block discarded – undo
430 430
     public function deactivate_context($context)
431 431
     {
432 432
         $this->validate_context($context);
433
-        return $this->update_extra_meta(self::ACTIVE_CONTEXT_RECORD_META_KEY_PREFIX . $context, false);
433
+        return $this->update_extra_meta(self::ACTIVE_CONTEXT_RECORD_META_KEY_PREFIX.$context, false);
434 434
     }
435 435
 
436 436
 
@@ -445,7 +445,7 @@  discard block
 block discarded – undo
445 445
     public function activate_context($context)
446 446
     {
447 447
         $this->validate_context($context);
448
-        return $this->update_extra_meta(self::ACTIVE_CONTEXT_RECORD_META_KEY_PREFIX . $context, true);
448
+        return $this->update_extra_meta(self::ACTIVE_CONTEXT_RECORD_META_KEY_PREFIX.$context, true);
449 449
     }
450 450
 
451 451
 
@@ -465,7 +465,7 @@  discard block
 block discarded – undo
465 465
     {
466 466
         $this->validate_context($context);
467 467
         return filter_var(
468
-            $this->get_extra_meta(self::ACTIVE_CONTEXT_RECORD_META_KEY_PREFIX . $context, true, true),
468
+            $this->get_extra_meta(self::ACTIVE_CONTEXT_RECORD_META_KEY_PREFIX.$context, true, true),
469 469
             FILTER_VALIDATE_BOOLEAN
470 470
         );
471 471
     }
@@ -481,7 +481,7 @@  discard block
 block discarded – undo
481 481
     public function validate_context($context)
482 482
     {
483 483
         $contexts = $this->contexts_config();
484
-        if (! isset($contexts[ $context ])) {
484
+        if ( ! isset($contexts[$context])) {
485 485
             throw new InvalidIdentifierException(
486 486
                 '',
487 487
                 '',
Please login to merge, or discard this patch.
Indentation   +483 added lines, -483 removed lines patch added patch discarded remove patch
@@ -13,487 +13,487 @@
 block discarded – undo
13 13
 class EE_Message_Template_Group extends EE_Soft_Delete_Base_Class
14 14
 {
15 15
 
16
-    /**
17
-     * Extra Meta key prefix for whether a given context for this message tmeplate group is active or not.
18
-     */
19
-    const ACTIVE_CONTEXT_RECORD_META_KEY_PREFIX = 'active_context_';
20
-
21
-    /**
22
-     * @param array  $props_n_values
23
-     * @param string $timezone
24
-     * @return EE_Message_Template_Group|mixed
25
-     * @throws EE_Error
26
-     */
27
-    public static function new_instance($props_n_values = array(), $timezone = '')
28
-    {
29
-        $has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone);
30
-        return $has_object ? $has_object : new self($props_n_values, false, $timezone);
31
-    }
32
-
33
-
34
-    /**
35
-     * @param array  $props_n_values
36
-     * @param string $timezone
37
-     * @return EE_Message_Template_Group
38
-     */
39
-    public static function new_instance_from_db($props_n_values = array(), $timezone = '')
40
-    {
41
-        return new self($props_n_values, true, $timezone);
42
-    }
43
-
44
-
45
-    /**
46
-     * @param bool $message_type
47
-     * @throws EE_Error
48
-     */
49
-    public function set_message_type($message_type = false)
50
-    {
51
-        if (! $message_type) {
52
-            throw new EE_Error(esc_html__('Missing required value for the message_type parameter', 'event_espresso'));
53
-        }
54
-        $this->set('MTP_message_type', $message_type);
55
-    }
56
-
57
-
58
-    /**
59
-     * @param bool $messenger
60
-     * @throws EE_Error
61
-     */
62
-    public function set_messenger($messenger = false)
63
-    {
64
-        if (! $messenger) {
65
-            throw new EE_Error(esc_html__('Missing required value for the messenger parameter', 'event_espresso'));
66
-        }
67
-        $this->set('MTP_messenger', $messenger);
68
-    }
69
-
70
-
71
-    /**
72
-     * @param bool $GRP_ID
73
-     * @throws EE_Error
74
-     */
75
-    public function set_group_template_id($GRP_ID = false)
76
-    {
77
-        if (! $GRP_ID) {
78
-            throw new EE_Error(
79
-                esc_html__(
80
-                    'Missing required value for the message template group id',
81
-                    'event_espresso'
82
-                )
83
-            );
84
-        }
85
-        $this->set('GRP_ID', $GRP_ID);
86
-    }
87
-
88
-
89
-    /**
90
-     * get Group ID
91
-     *
92
-     * @access public
93
-     * @return int
94
-     * @throws EE_Error
95
-     */
96
-    public function GRP_ID()
97
-    {
98
-        return $this->get('GRP_ID');
99
-    }
100
-
101
-
102
-    /**
103
-     * get User ID
104
-     *
105
-     * @access public
106
-     * @return int
107
-     * @throws EE_Error
108
-     */
109
-    public function user()
110
-    {
111
-        $user_id = $this->get('MTP_user_id');
112
-        return empty($user_id) ? get_current_user_id() : $user_id;
113
-    }
114
-
115
-
116
-    /**
117
-     * Wrapper for the user function() (preserve backward compat)
118
-     *
119
-     * @since  4.5.0
120
-     * @return int
121
-     * @throws EE_Error
122
-     */
123
-    public function wp_user()
124
-    {
125
-        return $this->user();
126
-    }
127
-
128
-
129
-    /**
130
-     * This simply returns a count of all related events to this message template group
131
-     *
132
-     * @return int
133
-     */
134
-    public function count_events()
135
-    {
136
-        return $this->count_related('Event');
137
-    }
138
-
139
-
140
-    /**
141
-     * returns the name saved in the db for this template
142
-     *
143
-     * @return string
144
-     * @throws EE_Error
145
-     */
146
-    public function name()
147
-    {
148
-        return $this->get('MTP_name');
149
-    }
150
-
151
-
152
-    /**
153
-     * Returns the description saved in the db for this template group
154
-     *
155
-     * @return string
156
-     * @throws EE_Error
157
-     */
158
-    public function description()
159
-    {
160
-        return $this->get('MTP_description');
161
-    }
162
-
163
-
164
-    /**
165
-     * returns all related EE_Message_Template objects
166
-     *
167
-     * @param  array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
168
-     * @return EE_Message_Template[]
169
-     * @throws EE_Error
170
-     */
171
-    public function message_templates($query_params = array())
172
-    {
173
-        return $this->get_many_related('Message_Template', $query_params);
174
-    }
175
-
176
-
177
-    /**
178
-     * get Message Messenger
179
-     *
180
-     * @access public
181
-     * @return string
182
-     * @throws EE_Error
183
-     */
184
-    public function messenger()
185
-    {
186
-        return $this->get('MTP_messenger');
187
-    }
188
-
189
-
190
-    /**
191
-     * get Message Messenger OBJECT
192
-     * If an attempt to get the corresponding messenger object fails, then we set this message
193
-     * template group to inactive, and save to db.  Then return null so client code can handle
194
-     * appropriately.
195
-     *
196
-     * @return EE_messenger
197
-     * @throws EE_Error
198
-     */
199
-    public function messenger_obj()
200
-    {
201
-        $messenger = $this->messenger();
202
-        try {
203
-            $messenger = EEH_MSG_Template::messenger_obj($messenger);
204
-        } catch (EE_Error $e) {
205
-            // if an exception was thrown then let's deactivate this message template group because it means there is no
206
-            // class for this messenger in this group.
207
-            $this->set('MTP_is_active', false);
208
-            $this->save();
209
-            return null;
210
-        }
211
-        return $messenger;
212
-    }
213
-
214
-
215
-    /**
216
-     * get Message Type
217
-     *
218
-     * @access public
219
-     * @return string
220
-     * @throws EE_Error
221
-     */
222
-    public function message_type()
223
-    {
224
-        return $this->get('MTP_message_type');
225
-    }
226
-
227
-
228
-    /**
229
-     * get Message type OBJECT
230
-     * If an attempt to get the corresponding message type object fails, then we set this message
231
-     * template group to inactive, and save to db.  Then return null so client code can handle
232
-     * appropriately.
233
-     *
234
-     * @throws EE_Error
235
-     * @return EE_message_type|false if exception thrown.
236
-     */
237
-    public function message_type_obj()
238
-    {
239
-        $message_type = $this->message_type();
240
-        try {
241
-            $message_type = EEH_MSG_Template::message_type_obj($message_type);
242
-        } catch (EE_Error $e) {
243
-            // if an exception was thrown then let's deactivate this message template group because it means there is no
244
-            // class for the message type in this group.
245
-            $this->set('MTP_is_active', false);
246
-            $this->save();
247
-            return null;
248
-        }
249
-        return $message_type;
250
-    }
251
-
252
-
253
-    /**
254
-     * @return array
255
-     * @throws EE_Error
256
-     */
257
-    public function contexts_config()
258
-    {
259
-        return $this->message_type_obj()->get_contexts();
260
-    }
261
-
262
-
263
-    /**
264
-     * This returns the context_label for contexts as set in the message type object
265
-     * Note this is an array with singular and plural keys
266
-     *
267
-     * @access public
268
-     * @return array labels for "context"
269
-     * @throws EE_Error
270
-     */
271
-    public function context_label()
272
-    {
273
-        $obj = $this->message_type_obj();
274
-        return $obj->get_context_label();
275
-    }
276
-
277
-
278
-    /**
279
-     * This returns an array of EE_Message_Template objects indexed by context and field.
280
-     *
281
-     * @return array ()
282
-     * @throws EE_Error
283
-     */
284
-    public function context_templates()
285
-    {
286
-        $mtps_arr = array();
287
-        $mtps = $this->get_many_related('Message_Template');
288
-        if (empty($mtps)) {
289
-            return array();
290
-        }
291
-        // note contexts could have CHECKBOX fields per context. So we return the objects indexed by context AND field.
292
-        foreach ($mtps as $mtp) {
293
-            $mtps_arr[ $mtp->get('MTP_context') ][ $mtp->get('MTP_template_field') ] = $mtp;
294
-        }
295
-        return $mtps_arr;
296
-    }
297
-
298
-
299
-    /**
300
-     * this returns if the template group this template belongs to is global
301
-     *
302
-     * @return bool true if it is, false if it isn't
303
-     * @throws EE_Error
304
-     */
305
-    public function is_global()
306
-    {
307
-        return $this->get('MTP_is_global');
308
-    }
309
-
310
-
311
-    /**
312
-     * this returns if the template group this template belongs to is active (i.e. turned "on" or not)
313
-     *
314
-     * @return bool true if it is, false if it isn't
315
-     * @throws EE_Error
316
-     */
317
-    public function is_active()
318
-    {
319
-        return $this->get('MTP_is_active');
320
-    }
321
-
322
-
323
-    /**
324
-     * This will return an array of shortcodes => labels from the messenger and message_type objects associated with
325
-     * this template.
326
-     *
327
-     * @since 4.3.0
328
-     * @uses  EEH_MSG_Template::get_shortcodes()
329
-     * @param string $context what context we're going to return shortcodes for
330
-     * @param array  $fields  what fields we're returning valid shortcodes for.  If empty then we assume all fields are
331
-     *                        to be returned.
332
-     * @param bool   $merged  If TRUE then we don't return shortcodes indexed by field but instead an array of the
333
-     *                        unique shortcodes for all the given (or all) fields.
334
-     * @return mixed (array|bool) an array of shortcodes in the format array( '[shortcode] => 'label') OR FALSE if no
335
-     *                        shortcodes found.
336
-     * @throws EE_Error
337
-     */
338
-    public function get_shortcodes($context, $fields = array(), $merged = false)
339
-    {
340
-        $messenger = $this->messenger();
341
-        $message_type = $this->message_type();
342
-        return EEH_MSG_Template::get_shortcodes($message_type, $messenger, $fields, $context, $merged);
343
-    }
344
-
345
-
346
-    /**
347
-     * This just gets the template pack name assigned to this message template group.  If it's not set, then we just
348
-     * use the default template pack.
349
-     *
350
-     * @since 4.5.0
351
-     * @return string
352
-     * @throws EE_Error
353
-     */
354
-    public function get_template_pack_name()
355
-    {
356
-        return $this->get_extra_meta('MTP_template_pack', true, 'default');
357
-    }
358
-
359
-
360
-    /**
361
-     * This returns the specific template pack object referenced by the template pack name attached to this message
362
-     * template group.  If no template pack is assigned then the default template pack is retrieved.
363
-     *
364
-     * @since 4.5.0
365
-     * @return EE_Messages_Template_Pack
366
-     * @throws EE_Error
367
-     * @throws InvalidArgumentException
368
-     * @throws ReflectionException
369
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
370
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
371
-     */
372
-    public function get_template_pack()
373
-    {
374
-        $pack_name = $this->get_template_pack_name();
375
-        EE_Registry::instance()->load_helper('MSG_Template');
376
-        return EEH_MSG_Template::get_template_pack($pack_name);
377
-    }
378
-
379
-
380
-    /**
381
-     * This retrieves the template variation assigned to this message template group.  If it's not set, then we just
382
-     * use the default template variation.
383
-     *
384
-     * @since 4.5.0
385
-     * @return string
386
-     * @throws EE_Error
387
-     */
388
-    public function get_template_pack_variation()
389
-    {
390
-        return $this->get_extra_meta('MTP_variation', true, 'default');
391
-    }
392
-
393
-
394
-    /**
395
-     * This just sets the template pack name attached to this message template group.
396
-     *
397
-     * @since 4.5.0
398
-     * @param string $template_pack_name What message template pack is assigned.
399
-     * @return int
400
-     * @throws EE_Error
401
-     */
402
-    public function set_template_pack_name($template_pack_name)
403
-    {
404
-        return $this->update_extra_meta('MTP_template_pack', $template_pack_name);
405
-    }
406
-
407
-
408
-    /**
409
-     * This just sets the template pack variation attached to this message template group.
410
-     *
411
-     * @since 4.5.0
412
-     * @param string $variation What variation is being set on the message template group.
413
-     * @return int
414
-     * @throws EE_Error
415
-     */
416
-    public function set_template_pack_variation($variation)
417
-    {
418
-        return $this->update_extra_meta('MTP_variation', $variation);
419
-    }
420
-
421
-
422
-    /**
423
-     * Deactivates the given context.
424
-     *
425
-     * @param $context
426
-     * @return bool|int
427
-     * @throws EE_Error
428
-     * @throws InvalidIdentifierException
429
-     */
430
-    public function deactivate_context($context)
431
-    {
432
-        $this->validate_context($context);
433
-        return $this->update_extra_meta(self::ACTIVE_CONTEXT_RECORD_META_KEY_PREFIX . $context, false);
434
-    }
435
-
436
-
437
-    /**
438
-     * Activates the given context.
439
-     *
440
-     * @param $context
441
-     * @return bool|int
442
-     * @throws EE_Error
443
-     * @throws InvalidIdentifierException
444
-     */
445
-    public function activate_context($context)
446
-    {
447
-        $this->validate_context($context);
448
-        return $this->update_extra_meta(self::ACTIVE_CONTEXT_RECORD_META_KEY_PREFIX . $context, true);
449
-    }
450
-
451
-
452
-    /**
453
-     * Returns whether the context is active or not.
454
-     * Note, this will default to true if the extra meta record doesn't exist.
455
-     * Also, this does NOT account for whether the "To" field is empty or not. Some messengers may allow the "To" field
456
-     * to be empty (@see EE_Messenger::allow_empty_to_field()) so an empty "To" field is not always an indicator of
457
-     * whether a context is "active" or not.
458
-     *
459
-     * @param $context
460
-     * @return bool
461
-     * @throws EE_Error
462
-     * @throws InvalidIdentifierException
463
-     */
464
-    public function is_context_active($context)
465
-    {
466
-        $this->validate_context($context);
467
-        return filter_var(
468
-            $this->get_extra_meta(self::ACTIVE_CONTEXT_RECORD_META_KEY_PREFIX . $context, true, true),
469
-            FILTER_VALIDATE_BOOLEAN
470
-        );
471
-    }
472
-
473
-
474
-    /**
475
-     * Validates the incoming context to verify it matches a registered context for the related message type.
476
-     *
477
-     * @param string $context
478
-     * @throws EE_Error
479
-     * @throws InvalidIdentifierException
480
-     */
481
-    public function validate_context($context)
482
-    {
483
-        $contexts = $this->contexts_config();
484
-        if (! isset($contexts[ $context ])) {
485
-            throw new InvalidIdentifierException(
486
-                '',
487
-                '',
488
-                sprintf(
489
-                    esc_html__(
490
-                        'An invalid string identifying a context was provided.  "%1$s" was received, and one of "%2$s" was expected.',
491
-                        'event_espresso'
492
-                    ),
493
-                    $context,
494
-                    implode(',', array_keys($contexts))
495
-                )
496
-            );
497
-        }
498
-    }
16
+	/**
17
+	 * Extra Meta key prefix for whether a given context for this message tmeplate group is active or not.
18
+	 */
19
+	const ACTIVE_CONTEXT_RECORD_META_KEY_PREFIX = 'active_context_';
20
+
21
+	/**
22
+	 * @param array  $props_n_values
23
+	 * @param string $timezone
24
+	 * @return EE_Message_Template_Group|mixed
25
+	 * @throws EE_Error
26
+	 */
27
+	public static function new_instance($props_n_values = array(), $timezone = '')
28
+	{
29
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone);
30
+		return $has_object ? $has_object : new self($props_n_values, false, $timezone);
31
+	}
32
+
33
+
34
+	/**
35
+	 * @param array  $props_n_values
36
+	 * @param string $timezone
37
+	 * @return EE_Message_Template_Group
38
+	 */
39
+	public static function new_instance_from_db($props_n_values = array(), $timezone = '')
40
+	{
41
+		return new self($props_n_values, true, $timezone);
42
+	}
43
+
44
+
45
+	/**
46
+	 * @param bool $message_type
47
+	 * @throws EE_Error
48
+	 */
49
+	public function set_message_type($message_type = false)
50
+	{
51
+		if (! $message_type) {
52
+			throw new EE_Error(esc_html__('Missing required value for the message_type parameter', 'event_espresso'));
53
+		}
54
+		$this->set('MTP_message_type', $message_type);
55
+	}
56
+
57
+
58
+	/**
59
+	 * @param bool $messenger
60
+	 * @throws EE_Error
61
+	 */
62
+	public function set_messenger($messenger = false)
63
+	{
64
+		if (! $messenger) {
65
+			throw new EE_Error(esc_html__('Missing required value for the messenger parameter', 'event_espresso'));
66
+		}
67
+		$this->set('MTP_messenger', $messenger);
68
+	}
69
+
70
+
71
+	/**
72
+	 * @param bool $GRP_ID
73
+	 * @throws EE_Error
74
+	 */
75
+	public function set_group_template_id($GRP_ID = false)
76
+	{
77
+		if (! $GRP_ID) {
78
+			throw new EE_Error(
79
+				esc_html__(
80
+					'Missing required value for the message template group id',
81
+					'event_espresso'
82
+				)
83
+			);
84
+		}
85
+		$this->set('GRP_ID', $GRP_ID);
86
+	}
87
+
88
+
89
+	/**
90
+	 * get Group ID
91
+	 *
92
+	 * @access public
93
+	 * @return int
94
+	 * @throws EE_Error
95
+	 */
96
+	public function GRP_ID()
97
+	{
98
+		return $this->get('GRP_ID');
99
+	}
100
+
101
+
102
+	/**
103
+	 * get User ID
104
+	 *
105
+	 * @access public
106
+	 * @return int
107
+	 * @throws EE_Error
108
+	 */
109
+	public function user()
110
+	{
111
+		$user_id = $this->get('MTP_user_id');
112
+		return empty($user_id) ? get_current_user_id() : $user_id;
113
+	}
114
+
115
+
116
+	/**
117
+	 * Wrapper for the user function() (preserve backward compat)
118
+	 *
119
+	 * @since  4.5.0
120
+	 * @return int
121
+	 * @throws EE_Error
122
+	 */
123
+	public function wp_user()
124
+	{
125
+		return $this->user();
126
+	}
127
+
128
+
129
+	/**
130
+	 * This simply returns a count of all related events to this message template group
131
+	 *
132
+	 * @return int
133
+	 */
134
+	public function count_events()
135
+	{
136
+		return $this->count_related('Event');
137
+	}
138
+
139
+
140
+	/**
141
+	 * returns the name saved in the db for this template
142
+	 *
143
+	 * @return string
144
+	 * @throws EE_Error
145
+	 */
146
+	public function name()
147
+	{
148
+		return $this->get('MTP_name');
149
+	}
150
+
151
+
152
+	/**
153
+	 * Returns the description saved in the db for this template group
154
+	 *
155
+	 * @return string
156
+	 * @throws EE_Error
157
+	 */
158
+	public function description()
159
+	{
160
+		return $this->get('MTP_description');
161
+	}
162
+
163
+
164
+	/**
165
+	 * returns all related EE_Message_Template objects
166
+	 *
167
+	 * @param  array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
168
+	 * @return EE_Message_Template[]
169
+	 * @throws EE_Error
170
+	 */
171
+	public function message_templates($query_params = array())
172
+	{
173
+		return $this->get_many_related('Message_Template', $query_params);
174
+	}
175
+
176
+
177
+	/**
178
+	 * get Message Messenger
179
+	 *
180
+	 * @access public
181
+	 * @return string
182
+	 * @throws EE_Error
183
+	 */
184
+	public function messenger()
185
+	{
186
+		return $this->get('MTP_messenger');
187
+	}
188
+
189
+
190
+	/**
191
+	 * get Message Messenger OBJECT
192
+	 * If an attempt to get the corresponding messenger object fails, then we set this message
193
+	 * template group to inactive, and save to db.  Then return null so client code can handle
194
+	 * appropriately.
195
+	 *
196
+	 * @return EE_messenger
197
+	 * @throws EE_Error
198
+	 */
199
+	public function messenger_obj()
200
+	{
201
+		$messenger = $this->messenger();
202
+		try {
203
+			$messenger = EEH_MSG_Template::messenger_obj($messenger);
204
+		} catch (EE_Error $e) {
205
+			// if an exception was thrown then let's deactivate this message template group because it means there is no
206
+			// class for this messenger in this group.
207
+			$this->set('MTP_is_active', false);
208
+			$this->save();
209
+			return null;
210
+		}
211
+		return $messenger;
212
+	}
213
+
214
+
215
+	/**
216
+	 * get Message Type
217
+	 *
218
+	 * @access public
219
+	 * @return string
220
+	 * @throws EE_Error
221
+	 */
222
+	public function message_type()
223
+	{
224
+		return $this->get('MTP_message_type');
225
+	}
226
+
227
+
228
+	/**
229
+	 * get Message type OBJECT
230
+	 * If an attempt to get the corresponding message type object fails, then we set this message
231
+	 * template group to inactive, and save to db.  Then return null so client code can handle
232
+	 * appropriately.
233
+	 *
234
+	 * @throws EE_Error
235
+	 * @return EE_message_type|false if exception thrown.
236
+	 */
237
+	public function message_type_obj()
238
+	{
239
+		$message_type = $this->message_type();
240
+		try {
241
+			$message_type = EEH_MSG_Template::message_type_obj($message_type);
242
+		} catch (EE_Error $e) {
243
+			// if an exception was thrown then let's deactivate this message template group because it means there is no
244
+			// class for the message type in this group.
245
+			$this->set('MTP_is_active', false);
246
+			$this->save();
247
+			return null;
248
+		}
249
+		return $message_type;
250
+	}
251
+
252
+
253
+	/**
254
+	 * @return array
255
+	 * @throws EE_Error
256
+	 */
257
+	public function contexts_config()
258
+	{
259
+		return $this->message_type_obj()->get_contexts();
260
+	}
261
+
262
+
263
+	/**
264
+	 * This returns the context_label for contexts as set in the message type object
265
+	 * Note this is an array with singular and plural keys
266
+	 *
267
+	 * @access public
268
+	 * @return array labels for "context"
269
+	 * @throws EE_Error
270
+	 */
271
+	public function context_label()
272
+	{
273
+		$obj = $this->message_type_obj();
274
+		return $obj->get_context_label();
275
+	}
276
+
277
+
278
+	/**
279
+	 * This returns an array of EE_Message_Template objects indexed by context and field.
280
+	 *
281
+	 * @return array ()
282
+	 * @throws EE_Error
283
+	 */
284
+	public function context_templates()
285
+	{
286
+		$mtps_arr = array();
287
+		$mtps = $this->get_many_related('Message_Template');
288
+		if (empty($mtps)) {
289
+			return array();
290
+		}
291
+		// note contexts could have CHECKBOX fields per context. So we return the objects indexed by context AND field.
292
+		foreach ($mtps as $mtp) {
293
+			$mtps_arr[ $mtp->get('MTP_context') ][ $mtp->get('MTP_template_field') ] = $mtp;
294
+		}
295
+		return $mtps_arr;
296
+	}
297
+
298
+
299
+	/**
300
+	 * this returns if the template group this template belongs to is global
301
+	 *
302
+	 * @return bool true if it is, false if it isn't
303
+	 * @throws EE_Error
304
+	 */
305
+	public function is_global()
306
+	{
307
+		return $this->get('MTP_is_global');
308
+	}
309
+
310
+
311
+	/**
312
+	 * this returns if the template group this template belongs to is active (i.e. turned "on" or not)
313
+	 *
314
+	 * @return bool true if it is, false if it isn't
315
+	 * @throws EE_Error
316
+	 */
317
+	public function is_active()
318
+	{
319
+		return $this->get('MTP_is_active');
320
+	}
321
+
322
+
323
+	/**
324
+	 * This will return an array of shortcodes => labels from the messenger and message_type objects associated with
325
+	 * this template.
326
+	 *
327
+	 * @since 4.3.0
328
+	 * @uses  EEH_MSG_Template::get_shortcodes()
329
+	 * @param string $context what context we're going to return shortcodes for
330
+	 * @param array  $fields  what fields we're returning valid shortcodes for.  If empty then we assume all fields are
331
+	 *                        to be returned.
332
+	 * @param bool   $merged  If TRUE then we don't return shortcodes indexed by field but instead an array of the
333
+	 *                        unique shortcodes for all the given (or all) fields.
334
+	 * @return mixed (array|bool) an array of shortcodes in the format array( '[shortcode] => 'label') OR FALSE if no
335
+	 *                        shortcodes found.
336
+	 * @throws EE_Error
337
+	 */
338
+	public function get_shortcodes($context, $fields = array(), $merged = false)
339
+	{
340
+		$messenger = $this->messenger();
341
+		$message_type = $this->message_type();
342
+		return EEH_MSG_Template::get_shortcodes($message_type, $messenger, $fields, $context, $merged);
343
+	}
344
+
345
+
346
+	/**
347
+	 * This just gets the template pack name assigned to this message template group.  If it's not set, then we just
348
+	 * use the default template pack.
349
+	 *
350
+	 * @since 4.5.0
351
+	 * @return string
352
+	 * @throws EE_Error
353
+	 */
354
+	public function get_template_pack_name()
355
+	{
356
+		return $this->get_extra_meta('MTP_template_pack', true, 'default');
357
+	}
358
+
359
+
360
+	/**
361
+	 * This returns the specific template pack object referenced by the template pack name attached to this message
362
+	 * template group.  If no template pack is assigned then the default template pack is retrieved.
363
+	 *
364
+	 * @since 4.5.0
365
+	 * @return EE_Messages_Template_Pack
366
+	 * @throws EE_Error
367
+	 * @throws InvalidArgumentException
368
+	 * @throws ReflectionException
369
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
370
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
371
+	 */
372
+	public function get_template_pack()
373
+	{
374
+		$pack_name = $this->get_template_pack_name();
375
+		EE_Registry::instance()->load_helper('MSG_Template');
376
+		return EEH_MSG_Template::get_template_pack($pack_name);
377
+	}
378
+
379
+
380
+	/**
381
+	 * This retrieves the template variation assigned to this message template group.  If it's not set, then we just
382
+	 * use the default template variation.
383
+	 *
384
+	 * @since 4.5.0
385
+	 * @return string
386
+	 * @throws EE_Error
387
+	 */
388
+	public function get_template_pack_variation()
389
+	{
390
+		return $this->get_extra_meta('MTP_variation', true, 'default');
391
+	}
392
+
393
+
394
+	/**
395
+	 * This just sets the template pack name attached to this message template group.
396
+	 *
397
+	 * @since 4.5.0
398
+	 * @param string $template_pack_name What message template pack is assigned.
399
+	 * @return int
400
+	 * @throws EE_Error
401
+	 */
402
+	public function set_template_pack_name($template_pack_name)
403
+	{
404
+		return $this->update_extra_meta('MTP_template_pack', $template_pack_name);
405
+	}
406
+
407
+
408
+	/**
409
+	 * This just sets the template pack variation attached to this message template group.
410
+	 *
411
+	 * @since 4.5.0
412
+	 * @param string $variation What variation is being set on the message template group.
413
+	 * @return int
414
+	 * @throws EE_Error
415
+	 */
416
+	public function set_template_pack_variation($variation)
417
+	{
418
+		return $this->update_extra_meta('MTP_variation', $variation);
419
+	}
420
+
421
+
422
+	/**
423
+	 * Deactivates the given context.
424
+	 *
425
+	 * @param $context
426
+	 * @return bool|int
427
+	 * @throws EE_Error
428
+	 * @throws InvalidIdentifierException
429
+	 */
430
+	public function deactivate_context($context)
431
+	{
432
+		$this->validate_context($context);
433
+		return $this->update_extra_meta(self::ACTIVE_CONTEXT_RECORD_META_KEY_PREFIX . $context, false);
434
+	}
435
+
436
+
437
+	/**
438
+	 * Activates the given context.
439
+	 *
440
+	 * @param $context
441
+	 * @return bool|int
442
+	 * @throws EE_Error
443
+	 * @throws InvalidIdentifierException
444
+	 */
445
+	public function activate_context($context)
446
+	{
447
+		$this->validate_context($context);
448
+		return $this->update_extra_meta(self::ACTIVE_CONTEXT_RECORD_META_KEY_PREFIX . $context, true);
449
+	}
450
+
451
+
452
+	/**
453
+	 * Returns whether the context is active or not.
454
+	 * Note, this will default to true if the extra meta record doesn't exist.
455
+	 * Also, this does NOT account for whether the "To" field is empty or not. Some messengers may allow the "To" field
456
+	 * to be empty (@see EE_Messenger::allow_empty_to_field()) so an empty "To" field is not always an indicator of
457
+	 * whether a context is "active" or not.
458
+	 *
459
+	 * @param $context
460
+	 * @return bool
461
+	 * @throws EE_Error
462
+	 * @throws InvalidIdentifierException
463
+	 */
464
+	public function is_context_active($context)
465
+	{
466
+		$this->validate_context($context);
467
+		return filter_var(
468
+			$this->get_extra_meta(self::ACTIVE_CONTEXT_RECORD_META_KEY_PREFIX . $context, true, true),
469
+			FILTER_VALIDATE_BOOLEAN
470
+		);
471
+	}
472
+
473
+
474
+	/**
475
+	 * Validates the incoming context to verify it matches a registered context for the related message type.
476
+	 *
477
+	 * @param string $context
478
+	 * @throws EE_Error
479
+	 * @throws InvalidIdentifierException
480
+	 */
481
+	public function validate_context($context)
482
+	{
483
+		$contexts = $this->contexts_config();
484
+		if (! isset($contexts[ $context ])) {
485
+			throw new InvalidIdentifierException(
486
+				'',
487
+				'',
488
+				sprintf(
489
+					esc_html__(
490
+						'An invalid string identifying a context was provided.  "%1$s" was received, and one of "%2$s" was expected.',
491
+						'event_espresso'
492
+					),
493
+					$context,
494
+					implode(',', array_keys($contexts))
495
+				)
496
+			);
497
+		}
498
+	}
499 499
 }
Please login to merge, or discard this patch.
messages/templates/ee_msg_editor_active_context_element.template.php 1 patch
Indentation   +18 added lines, -18 removed lines patch added patch discarded remove patch
@@ -10,22 +10,22 @@  discard block
 block discarded – undo
10 10
  * @var int    $message_template_group_id The ID for the message template group this context belongs to.
11 11
  */
12 12
 $active_message = sprintf(
13
-    esc_html__(
14
-        'The template for %1$s is currently %2$sactive%3$s.',
15
-        'event_espresso'
16
-    ),
17
-    $context_label,
18
-    '<strong>',
19
-    '</strong>'
13
+	esc_html__(
14
+		'The template for %1$s is currently %2$sactive%3$s.',
15
+		'event_espresso'
16
+	),
17
+	$context_label,
18
+	'<strong>',
19
+	'</strong>'
20 20
 );
21 21
 $inactive_message = sprintf(
22
-    esc_html__(
23
-        'The template for %1$s is currently %2$sinactive%3$s.',
24
-        'event_espresso'
25
-    ),
26
-    $context_label,
27
-    '<strong>',
28
-    '</strong>'
22
+	esc_html__(
23
+		'The template for %1$s is currently %2$sinactive%3$s.',
24
+		'event_espresso'
25
+	),
26
+	$context_label,
27
+	'<strong>',
28
+	'</strong>'
29 29
 );
30 30
 ?>
31 31
 <div class="context-active-control-container">
@@ -34,8 +34,8 @@  discard block
 block discarded – undo
34 34
         <span id="on-off-nonce-<?php echo $context; ?>" class="hidden"><?php echo $nonce; ?></span>
35 35
         <span class="ee-on-off-toggle-label">
36 36
             <?php
37
-            echo $is_active ? $active_message : $inactive_message;
38
-            ?>
37
+			echo $is_active ? $active_message : $inactive_message;
38
+			?>
39 39
         </span>
40 40
         <div class="hidden js-data">
41 41
             <span class="ee-active-message"><?php echo $active_message; ?></span>
@@ -43,8 +43,8 @@  discard block
 block discarded – undo
43 43
         </div>
44 44
         <div class="switch">
45 45
             <?php
46
-            $checked = $is_active ? ' checked="checked"' : '';
47
-            ?>
46
+			$checked = $is_active ? ' checked="checked"' : '';
47
+			?>
48 48
             <input data-grpid="<?php echo $message_template_group_id; ?>" id="ee-on-off-toggle-<?php echo $context; ?>" type="checkbox" class="ee-on-off-toggle ee-toggle-round-flat"<?php echo $checked; ?> value="<?php echo $on_off_action; ?>">
49 49
             <label for="ee-on-off-toggle-<?php echo $context; ?>"></label>
50 50
         </div>
Please login to merge, or discard this patch.
public/Espresso_Arabica_2014/functions.php 1 patch
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -9,9 +9,9 @@  discard block
 block discarded – undo
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
 block discarded – undo
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'    => __( '&lsaquo; PREV', 'event_espresso' ),
35
-				'next_text'    => __( 'NEXT &rsaquo;', 'event_espresso' ),
34
+				'prev_text'    => __('&lsaquo; PREV', 'event_espresso'),
35
+				'next_text'    => __('NEXT &rsaquo;', '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
Please login to merge, or discard this patch.
admin_pages/messages/help_tabs/messages_settings_messengers.help_tab.php 2 patches
Indentation   +50 added lines, -50 removed lines patch added patch discarded remove patch
@@ -3,79 +3,79 @@
 block discarded – undo
3 3
 </p>
4 4
 <p>
5 5
     <?php esc_html_e(
6
-        'You can select Messengers via the tabs across the top of the settings page. The available messengers you see depends on what version of Event Espresso you have and what addons are installed. Every install include an "Email" messenger tab.  When you click one of those tabs it will display that messenger.',
7
-        'event_espresso'
8
-    ); ?>
6
+		'You can select Messengers via the tabs across the top of the settings page. The available messengers you see depends on what version of Event Espresso you have and what addons are installed. Every install include an "Email" messenger tab.  When you click one of those tabs it will display that messenger.',
7
+		'event_espresso'
8
+	); ?>
9 9
 </p>
10 10
 <p>
11 11
     <?php esc_html_e(
12
-        'There are two ways to determine whether a messenger is active or not.  The first way is via the messenger tab itself.',
13
-        'event_espresso'
14
-    ); ?>
12
+		'There are two ways to determine whether a messenger is active or not.  The first way is via the messenger tab itself.',
13
+		'event_espresso'
14
+	); ?>
15 15
 </p>
16 16
 <p>
17 17
     <?php printf(
18
-        esc_html__(
19
-            'The green colored gear %s indicates that this messenger is currently active.',
20
-            'event_espresso'
21
-        ),
22
-        '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-active.png' . '"'
23
-        . ' alt="' . esc_attr__('Active Email Tab', 'event_espresso') . '" />'
24
-    );
25
-    printf(
26
-        esc_html__(
27
-            ' The white colored gear %s indicates the messenger is inactive. This is very helpful for seeing at a glance all the messengers that are active when you first view the page.',
28
-            'event_espresso'
29
-        ),
30
-        '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-inactive.png'
31
-        . '" alt="' . esc_attr__('Inactive Email Tab', 'event_espresso') . '" />'
32
-    ); ?>
18
+		esc_html__(
19
+			'The green colored gear %s indicates that this messenger is currently active.',
20
+			'event_espresso'
21
+		),
22
+		'<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-active.png' . '"'
23
+		. ' alt="' . esc_attr__('Active Email Tab', 'event_espresso') . '" />'
24
+	);
25
+	printf(
26
+		esc_html__(
27
+			' The white colored gear %s indicates the messenger is inactive. This is very helpful for seeing at a glance all the messengers that are active when you first view the page.',
28
+			'event_espresso'
29
+		),
30
+		'<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-inactive.png'
31
+		. '" alt="' . esc_attr__('Inactive Email Tab', 'event_espresso') . '" />'
32
+	); ?>
33 33
 </p>
34 34
 <p>
35 35
     <?php esc_html_e(
36
-        'The second way to determine whether a messenger is active or not is via the "on/off" button in the top right corner of the active messenger displayed content:',
37
-        'event_espresso'
38
-    ); ?>
36
+		'The second way to determine whether a messenger is active or not is via the "on/off" button in the top right corner of the active messenger displayed content:',
37
+		'event_espresso'
38
+	); ?>
39 39
 </p>
40 40
 <p>
41 41
     <?php printf(
42
-        esc_html__(
43
-            '%1$s means of course that the messenger is active and %2$s means the messenger is inactive.',
44
-            'event_espresso'
45
-        ),
46
-        '<div class="switch">'
47
-            . '<input class="ee-on-off-toggle ee-toggle-round-flat" type="checkbox" checked="checked" disabled>'
48
-            . '<label for="ee-on-off-toggle-on"></label>'
49
-        . '</div>',
50
-        '<div class="switch">'
51
-            . '<input class="ee-on-off-toggle ee-toggle-round-flat" type="checkbox" disabled>'
52
-            . '<label for="ee-on-off-toggle-on"></label>'
53
-        . '</div>'
54
-    ); ?>
42
+		esc_html__(
43
+			'%1$s means of course that the messenger is active and %2$s means the messenger is inactive.',
44
+			'event_espresso'
45
+		),
46
+		'<div class="switch">'
47
+			. '<input class="ee-on-off-toggle ee-toggle-round-flat" type="checkbox" checked="checked" disabled>'
48
+			. '<label for="ee-on-off-toggle-on"></label>'
49
+		. '</div>',
50
+		'<div class="switch">'
51
+			. '<input class="ee-on-off-toggle ee-toggle-round-flat" type="checkbox" disabled>'
52
+			. '<label for="ee-on-off-toggle-on"></label>'
53
+		. '</div>'
54
+	); ?>
55 55
 </p>
56 56
 <p>
57 57
     <?php
58
-        esc_html_e(
59
-            'The on/off toggle is also what you use to activate or deactivate a messenger.',
60
-            'event_espresso'
61
-        ); ?>
58
+		esc_html_e(
59
+			'The on/off toggle is also what you use to activate or deactivate a messenger.',
60
+			'event_espresso'
61
+		); ?>
62 62
 </p>
63 63
 <p>
64 64
     <?php esc_html_e(
65
-        'What happens when you click the toggle to activate is the messenger is activated and the system determines what default message types are activated with the messenger.  Then, if there are any default settings for either the messenger or message types those settings are saved.  Next, the system will generate any default templates (if none have been generated before, if there are previously generated templates then they are reactivated).  Finally, you will see the display change to reflect that the messenger is active. If the messenger has settings you can modify them then. Any message types that have settings will also automatically expand so you can see the default settings and make any changes as necessary to fit your needs. Usually the defaults are sufficient however.',
66
-        'event_espresso'
67
-    ); ?>
65
+		'What happens when you click the toggle to activate is the messenger is activated and the system determines what default message types are activated with the messenger.  Then, if there are any default settings for either the messenger or message types those settings are saved.  Next, the system will generate any default templates (if none have been generated before, if there are previously generated templates then they are reactivated).  Finally, you will see the display change to reflect that the messenger is active. If the messenger has settings you can modify them then. Any message types that have settings will also automatically expand so you can see the default settings and make any changes as necessary to fit your needs. Usually the defaults are sufficient however.',
66
+		'event_espresso'
67
+	); ?>
68 68
 </p>
69 69
 <p>
70 70
     <?php esc_html_e(
71
-        'When you deactivate a messenger, the system will first check if there are any custom event templates for that messenger. If there are you will be unable to deactivate the messenger. This is a fail safe to make sure you know that no messages will go out for those specific events so you don\'t accidentally deactivate.  If this check passes, then the system will deactivate any global templates for that messenger (note the templates are not erased, they just become inactive, so if you decide to reactivate the messenger later all your customizations are preserved). Then the display will change to reflect the deactivation.',
72
-        'event_espresso'
73
-    ); ?>
71
+		'When you deactivate a messenger, the system will first check if there are any custom event templates for that messenger. If there are you will be unable to deactivate the messenger. This is a fail safe to make sure you know that no messages will go out for those specific events so you don\'t accidentally deactivate.  If this check passes, then the system will deactivate any global templates for that messenger (note the templates are not erased, they just become inactive, so if you decide to reactivate the messenger later all your customizations are preserved). Then the display will change to reflect the deactivation.',
72
+		'event_espresso'
73
+	); ?>
74 74
 </p>
75 75
 <p>
76 76
     <strong><?php esc_html_e('Important', 'event_espresso'); ?></strong><br/>
77 77
     <?php esc_html_e(
78
-        'Although customizations made to global templates are preserved when a messenger is deactivated, any settings for that messenger (or the message types that were attached to it) are lost on deactivation.  Also, once you deactivate a messenger, no more messages will be delivered using that messenger for any of your events.',
79
-        'event_espresso'
80
-    ); ?>
78
+		'Although customizations made to global templates are preserved when a messenger is deactivated, any settings for that messenger (or the message types that were attached to it) are lost on deactivation.  Also, once you deactivate a messenger, no more messages will be delivered using that messenger for any of your events.',
79
+		'event_espresso'
80
+	); ?>
81 81
 </p>
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -19,16 +19,16 @@
 block discarded – undo
19 19
             'The green colored gear %s indicates that this messenger is currently active.',
20 20
             'event_espresso'
21 21
         ),
22
-        '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-active.png' . '"'
23
-        . ' alt="' . esc_attr__('Active Email Tab', 'event_espresso') . '" />'
22
+        '<img class="inline-text" src="'.EE_MSG_ASSETS_URL.'images/email-tab-active.png'.'"'
23
+        . ' alt="'.esc_attr__('Active Email Tab', 'event_espresso').'" />'
24 24
     );
25 25
     printf(
26 26
         esc_html__(
27 27
             ' The white colored gear %s indicates the messenger is inactive. This is very helpful for seeing at a glance all the messengers that are active when you first view the page.',
28 28
             'event_espresso'
29 29
         ),
30
-        '<img class="inline-text" src="' . EE_MSG_ASSETS_URL . 'images/email-tab-inactive.png'
31
-        . '" alt="' . esc_attr__('Inactive Email Tab', 'event_espresso') . '" />'
30
+        '<img class="inline-text" src="'.EE_MSG_ASSETS_URL.'images/email-tab-inactive.png'
31
+        . '" alt="'.esc_attr__('Inactive Email Tab', 'event_espresso').'" />'
32 32
     ); ?>
33 33
 </p>
34 34
 <p>
Please login to merge, or discard this patch.
core/libraries/shortcodes/EE_Venue_Shortcodes.lib.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -176,7 +176,7 @@
 block discarded – undo
176 176
     /**
177 177
      * This retrieves the EE_Venue from the available data object.
178 178
      *
179
-     * @return EE_Venue|null
179
+     * @return EE_Base_Class|null
180 180
      * @throws EE_Error
181 181
      * @throws EntityNotFoundException
182 182
      */
Please login to merge, or discard this patch.
Indentation   +311 added lines, -311 removed lines patch added patch discarded remove patch
@@ -17,315 +17,315 @@
 block discarded – undo
17 17
 {
18 18
 
19 19
 
20
-    /**
21
-     * Will hold the EE_Event if available
22
-     *
23
-     * @var EE_Event
24
-     */
25
-    protected $_event;
26
-
27
-    /**
28
-     * Will hold the EE_Venue if available
29
-     *
30
-     * @var EE_Venue
31
-     */
32
-    protected $_venue;
33
-
34
-
35
-    /**
36
-     * Initialize properties
37
-     */
38
-    protected function _init_props()
39
-    {
40
-        $this->label = esc_html__('Venue Shortcodes', 'event_espresso');
41
-        $this->description = esc_html__('All shortcodes specific to venue related data', 'event_espresso');
42
-        $this->_shortcodes = array(
43
-            '[VENUE_TITLE]'             => esc_html__('The title for the event venue', 'event_espresso'),
44
-            '[VENUE_DESCRIPTION]'       => esc_html__('The description for the event venue', 'event_espresso'),
45
-            '[VENUE_URL]'               => esc_html__('A url to a webpage for the venue', 'event_espresso'),
46
-            '[VENUE_DETAILS_URL]'       => sprintf(
47
-                esc_html__(
48
-                    'This shortcode outputs the url or website address to the venue details page on this website. This differs from %s which outputs what is entered in the "url" field in the venue details page.',
49
-                    'event_espresso'
50
-                ),
51
-                '[VENUE_URL]'
52
-            ),
53
-            '[VENUE_IMAGE]'             => esc_html__('An image representing the event venue', 'event_espresso'),
54
-            '[VENUE_PHONE]'             => esc_html__('The phone number for the venue', 'event_espresso'),
55
-            '[VENUE_ADDRESS]'           => esc_html__('The address for the venue', 'event_espresso'),
56
-            '[VENUE_ADDRESS2]'          => esc_html__('Address 2 for the venue', 'event_espresso'),
57
-            '[VENUE_CITY]'              => esc_html__('The city the venue is in', 'event_espresso'),
58
-            '[VENUE_STATE]'             => esc_html__('The state the venue is located in', 'event_espresso'),
59
-            '[VENUE_COUNTRY]'           => esc_html__('The country the venue is located in', 'event_espresso'),
60
-            '[VENUE_FORMATTED_ADDRESS]' => esc_html__(
61
-                'This just outputs the venue address in a semantic address format.',
62
-                'event_espresso'
63
-            ),
64
-            '[VENUE_ZIP]'               => esc_html__('The zip code for the venue address', 'event_espresso'),
65
-            '[VENUE_META_*]'            => esc_html__(
66
-                'This is a special dynamic shortcode. After the "*", add the exact name for your custom field, if there is a value set for that custom field within the venue then it will be output in place of this shortcode.',
67
-                'event_espresso'
68
-            ),
69
-            '[GOOGLE_MAP_URL]'          => esc_html__(
70
-                'URL for the google map associated with the venue.',
71
-                'event_espresso'
72
-            ),
73
-            '[GOOGLE_MAP_LINK]'         => esc_html__('Link to a google map for the venue', 'event_espresso'),
74
-            '[GOOGLE_MAP_IMAGE]'        => esc_html__('Google map for venue wrapped in image tags', 'event_espresso'),
75
-        );
76
-    }
77
-
78
-
79
-    /**
80
-     * Parse incoming shortcode
81
-     *
82
-     * @param string $shortcode
83
-     * @return string
84
-     * @throws EE_Error
85
-     * @throws EntityNotFoundException
86
-     */
87
-    protected function _parser($shortcode)
88
-    {
89
-        $this->_venue = $this->_get_venue();
90
-        // If there is no venue object by now then get out.
91
-        if (! $this->_venue instanceof EE_Venue) {
92
-            return '';
93
-        }
94
-
95
-        switch ($shortcode) {
96
-            case '[VENUE_TITLE]':
97
-                return $this->_venue('title');
98
-                break;
99
-
100
-            case '[VENUE_DESCRIPTION]':
101
-                return $this->_venue('description');
102
-                break;
103
-
104
-            case '[VENUE_URL]':
105
-                return $this->_venue('url');
106
-                break;
107
-
108
-            case '[VENUE_IMAGE]':
109
-                return $this->_venue('image');
110
-                break;
111
-
112
-            case '[VENUE_PHONE]':
113
-                return $this->_venue('phone');
114
-                break;
115
-
116
-            case '[VENUE_ADDRESS]':
117
-                return $this->_venue('address');
118
-                break;
119
-
120
-            case '[VENUE_ADDRESS2]':
121
-                return $this->_venue('address2');
122
-                break;
123
-
124
-            case '[VENUE_CITY]':
125
-                return $this->_venue('city');
126
-                break;
127
-
128
-            case '[VENUE_COUNTRY]':
129
-                return $this->_venue('country');
130
-                break;
131
-
132
-            case '[VENUE_STATE]':
133
-                return $this->_venue('state');
134
-                break;
135
-
136
-            case '[VENUE_ZIP]':
137
-                return $this->_venue('zip');
138
-                break;
139
-
140
-            case '[VENUE_FORMATTED_ADDRESS]':
141
-                return $this->_venue('formatted_address');
142
-                break;
143
-
144
-            case '[GOOGLE_MAP_URL]':
145
-                return $this->_venue('gmap_url');
146
-                break;
147
-
148
-            case '[GOOGLE_MAP_LINK]':
149
-                return $this->_venue('gmap_link');
150
-                break;
151
-
152
-            case '[GOOGLE_MAP_IMAGE]':
153
-                return $this->_venue('gmap_link_img');
154
-                break;
155
-
156
-            case '[VENUE_DETAILS_URL]':
157
-                return $this->_venue('permalink');
158
-                break;
159
-        }
160
-
161
-        if (strpos($shortcode, '[VENUE_META_*') !== false) {
162
-            $shortcode = str_replace('[VENUE_META_*', '', $shortcode);
163
-            $shortcode = trim(str_replace(']', '', $shortcode));
164
-
165
-            // pull the meta value from the venue post
166
-            $venue_meta = $this->_venue->get_post_meta($shortcode, true);
167
-
168
-            return ! empty($venue_meta) ? $venue_meta : '';
169
-        }
170
-    }
171
-
172
-    /**
173
-     * This retrieves the EE_Venue from the available data object.
174
-     *
175
-     * @return EE_Venue|null
176
-     * @throws EE_Error
177
-     * @throws EntityNotFoundException
178
-     */
179
-    private function _get_venue()
180
-    {
181
-
182
-        // we need the EE_Event object to get the venue.
183
-        $this->_event = $this->_data instanceof EE_Event ? $this->_data : null;
184
-
185
-        // if no event, then let's see if there is a reg_obj.  If there IS, then we'll try and grab the event from the
186
-        // reg_obj instead.
187
-        if (! $this->_event instanceof EE_Event) {
188
-            $aee = $this->_data instanceof EE_Messages_Addressee ? $this->_data : null;
189
-            $aee = $this->_extra_data instanceof EE_Messages_Addressee ? $this->_extra_data : $aee;
190
-
191
-            $this->_event = $aee instanceof EE_Messages_Addressee && $aee->reg_obj instanceof EE_Registration
192
-                ? $aee->reg_obj->event()
193
-                : null;
194
-
195
-            // if still empty do we have a ticket data item?
196
-            $this->_event = ! $this->_event instanceof EE_Event
197
-                            && $this->_data instanceof EE_Ticket
198
-                            && $this->_extra_data['data'] instanceof EE_Messages_Addressee
199
-                ? $this->_extra_data['data']->tickets[ $this->_data->ID() ]['EE_Event']
200
-                : $this->_event;
201
-
202
-            // if STILL empty event, let's try to get the first event in the list of events via EE_Messages_Addressee
203
-            // and use that.
204
-            $this->_event = ! $this->_event instanceof EE_Event && $aee instanceof EE_Messages_Addressee
205
-                ? reset($aee->events)
206
-                : $this->_event;
207
-        }
208
-
209
-        // If we have an event object use it to pull the venue.
210
-        if ($this->_event instanceof EE_Event) {
211
-            return $this->_event->get_first_related('Venue');
212
-        }
213
-
214
-        return null;
215
-    }
216
-
217
-    /**
218
-     * This retrieves the specified venue information
219
-     *
220
-     * @param string $field What Venue field to retrieve
221
-     * @return string What was retrieved!
222
-     * @throws EE_Error
223
-     * @throws EntityNotFoundException
224
-     */
225
-    private function _venue($field)
226
-    {
227
-
228
-        if (! $this->_venue instanceof EE_Venue) {
229
-            return '';
230
-        } //no venue so get out.
231
-
232
-        switch ($field) {
233
-            case 'title':
234
-                return $this->_venue->get('VNU_name');
235
-                break;
236
-
237
-            case 'description':
238
-                return $this->_venue->get('VNU_desc');
239
-                break;
240
-
241
-            case 'url':
242
-                $url = $this->_venue->get('VNU_url');
243
-                return empty($url) ? $this->_venue->get_permalink() : $url;
244
-                break;
245
-
246
-            case 'permalink':
247
-                return $this->_venue->get_permalink();
248
-                break;
249
-
250
-            case 'image':
251
-                return '<img src="' . $this->_venue->feature_image_url(array(200, 200,))
252
-                       . '" alt="' . sprintf(
253
-                           esc_attr__('%s Feature Image', 'event_espresso'),
254
-                           $this->_venue->get('VNU_name')
255
-                       ) . '" />';
256
-                break;
257
-
258
-            case 'phone':
259
-                return $this->_venue->get('VNU_phone');
260
-                break;
261
-
262
-            case 'address':
263
-                return $this->_venue->get('VNU_address');
264
-                break;
265
-
266
-            case 'address2':
267
-                return $this->_venue->get('VNU_address2');
268
-                break;
269
-
270
-            case 'city':
271
-                return $this->_venue->get('VNU_city');
272
-                break;
273
-
274
-            case 'state':
275
-                $state = $this->_venue->state_obj();
276
-                return is_object($state) ? $state->get('STA_name') : '';
277
-                break;
278
-
279
-            case 'country':
280
-                $country = $this->_venue->country_obj();
281
-                return is_object($country) ? $country->get('CNT_name') : '';
282
-                break;
283
-
284
-            case 'zip':
285
-                return $this->_venue->get('VNU_zip');
286
-                break;
287
-
288
-            case 'formatted_address':
289
-                return EEH_Address::format($this->_venue);
290
-                break;
291
-
292
-            case 'gmap_link':
293
-            case 'gmap_url':
294
-            case 'gmap_link_img':
295
-                $atts = $this->get_map_attributes($this->_venue, $field);
296
-                return EEH_Maps::google_map_link($atts);
297
-                break;
298
-        }
299
-        return '';
300
-    }
301
-
302
-
303
-    /**
304
-     * Generates the attributes for retrieving a google_map artifact.
305
-     *
306
-     * @param EE_Venue $venue
307
-     * @param string   $field
308
-     * @return array
309
-     * @throws EE_Error
310
-     */
311
-    protected function get_map_attributes(EE_Venue $venue, $field = 'gmap_link')
312
-    {
313
-        $state = $venue->state_obj();
314
-        $country = $venue->country_obj();
315
-        $atts = array(
316
-            'id'      => $venue->ID(),
317
-            'address' => $venue->get('VNU_address'),
318
-            'city'    => $venue->get('VNU_city'),
319
-            'state'   => is_object($state) ? $state->get('STA_name') : '',
320
-            'zip'     => $venue->get('VNU_zip'),
321
-            'country' => is_object($country) ? $country->get('CNT_name') : '',
322
-            'type'    => $field === 'gmap_link' ? 'url' : 'map',
323
-            'map_w'   => 200,
324
-            'map_h'   => 200,
325
-        );
326
-        if ($field === 'gmap_url') {
327
-            $atts['type'] = 'url_only';
328
-        }
329
-        return $atts;
330
-    }
20
+	/**
21
+	 * Will hold the EE_Event if available
22
+	 *
23
+	 * @var EE_Event
24
+	 */
25
+	protected $_event;
26
+
27
+	/**
28
+	 * Will hold the EE_Venue if available
29
+	 *
30
+	 * @var EE_Venue
31
+	 */
32
+	protected $_venue;
33
+
34
+
35
+	/**
36
+	 * Initialize properties
37
+	 */
38
+	protected function _init_props()
39
+	{
40
+		$this->label = esc_html__('Venue Shortcodes', 'event_espresso');
41
+		$this->description = esc_html__('All shortcodes specific to venue related data', 'event_espresso');
42
+		$this->_shortcodes = array(
43
+			'[VENUE_TITLE]'             => esc_html__('The title for the event venue', 'event_espresso'),
44
+			'[VENUE_DESCRIPTION]'       => esc_html__('The description for the event venue', 'event_espresso'),
45
+			'[VENUE_URL]'               => esc_html__('A url to a webpage for the venue', 'event_espresso'),
46
+			'[VENUE_DETAILS_URL]'       => sprintf(
47
+				esc_html__(
48
+					'This shortcode outputs the url or website address to the venue details page on this website. This differs from %s which outputs what is entered in the "url" field in the venue details page.',
49
+					'event_espresso'
50
+				),
51
+				'[VENUE_URL]'
52
+			),
53
+			'[VENUE_IMAGE]'             => esc_html__('An image representing the event venue', 'event_espresso'),
54
+			'[VENUE_PHONE]'             => esc_html__('The phone number for the venue', 'event_espresso'),
55
+			'[VENUE_ADDRESS]'           => esc_html__('The address for the venue', 'event_espresso'),
56
+			'[VENUE_ADDRESS2]'          => esc_html__('Address 2 for the venue', 'event_espresso'),
57
+			'[VENUE_CITY]'              => esc_html__('The city the venue is in', 'event_espresso'),
58
+			'[VENUE_STATE]'             => esc_html__('The state the venue is located in', 'event_espresso'),
59
+			'[VENUE_COUNTRY]'           => esc_html__('The country the venue is located in', 'event_espresso'),
60
+			'[VENUE_FORMATTED_ADDRESS]' => esc_html__(
61
+				'This just outputs the venue address in a semantic address format.',
62
+				'event_espresso'
63
+			),
64
+			'[VENUE_ZIP]'               => esc_html__('The zip code for the venue address', 'event_espresso'),
65
+			'[VENUE_META_*]'            => esc_html__(
66
+				'This is a special dynamic shortcode. After the "*", add the exact name for your custom field, if there is a value set for that custom field within the venue then it will be output in place of this shortcode.',
67
+				'event_espresso'
68
+			),
69
+			'[GOOGLE_MAP_URL]'          => esc_html__(
70
+				'URL for the google map associated with the venue.',
71
+				'event_espresso'
72
+			),
73
+			'[GOOGLE_MAP_LINK]'         => esc_html__('Link to a google map for the venue', 'event_espresso'),
74
+			'[GOOGLE_MAP_IMAGE]'        => esc_html__('Google map for venue wrapped in image tags', 'event_espresso'),
75
+		);
76
+	}
77
+
78
+
79
+	/**
80
+	 * Parse incoming shortcode
81
+	 *
82
+	 * @param string $shortcode
83
+	 * @return string
84
+	 * @throws EE_Error
85
+	 * @throws EntityNotFoundException
86
+	 */
87
+	protected function _parser($shortcode)
88
+	{
89
+		$this->_venue = $this->_get_venue();
90
+		// If there is no venue object by now then get out.
91
+		if (! $this->_venue instanceof EE_Venue) {
92
+			return '';
93
+		}
94
+
95
+		switch ($shortcode) {
96
+			case '[VENUE_TITLE]':
97
+				return $this->_venue('title');
98
+				break;
99
+
100
+			case '[VENUE_DESCRIPTION]':
101
+				return $this->_venue('description');
102
+				break;
103
+
104
+			case '[VENUE_URL]':
105
+				return $this->_venue('url');
106
+				break;
107
+
108
+			case '[VENUE_IMAGE]':
109
+				return $this->_venue('image');
110
+				break;
111
+
112
+			case '[VENUE_PHONE]':
113
+				return $this->_venue('phone');
114
+				break;
115
+
116
+			case '[VENUE_ADDRESS]':
117
+				return $this->_venue('address');
118
+				break;
119
+
120
+			case '[VENUE_ADDRESS2]':
121
+				return $this->_venue('address2');
122
+				break;
123
+
124
+			case '[VENUE_CITY]':
125
+				return $this->_venue('city');
126
+				break;
127
+
128
+			case '[VENUE_COUNTRY]':
129
+				return $this->_venue('country');
130
+				break;
131
+
132
+			case '[VENUE_STATE]':
133
+				return $this->_venue('state');
134
+				break;
135
+
136
+			case '[VENUE_ZIP]':
137
+				return $this->_venue('zip');
138
+				break;
139
+
140
+			case '[VENUE_FORMATTED_ADDRESS]':
141
+				return $this->_venue('formatted_address');
142
+				break;
143
+
144
+			case '[GOOGLE_MAP_URL]':
145
+				return $this->_venue('gmap_url');
146
+				break;
147
+
148
+			case '[GOOGLE_MAP_LINK]':
149
+				return $this->_venue('gmap_link');
150
+				break;
151
+
152
+			case '[GOOGLE_MAP_IMAGE]':
153
+				return $this->_venue('gmap_link_img');
154
+				break;
155
+
156
+			case '[VENUE_DETAILS_URL]':
157
+				return $this->_venue('permalink');
158
+				break;
159
+		}
160
+
161
+		if (strpos($shortcode, '[VENUE_META_*') !== false) {
162
+			$shortcode = str_replace('[VENUE_META_*', '', $shortcode);
163
+			$shortcode = trim(str_replace(']', '', $shortcode));
164
+
165
+			// pull the meta value from the venue post
166
+			$venue_meta = $this->_venue->get_post_meta($shortcode, true);
167
+
168
+			return ! empty($venue_meta) ? $venue_meta : '';
169
+		}
170
+	}
171
+
172
+	/**
173
+	 * This retrieves the EE_Venue from the available data object.
174
+	 *
175
+	 * @return EE_Venue|null
176
+	 * @throws EE_Error
177
+	 * @throws EntityNotFoundException
178
+	 */
179
+	private function _get_venue()
180
+	{
181
+
182
+		// we need the EE_Event object to get the venue.
183
+		$this->_event = $this->_data instanceof EE_Event ? $this->_data : null;
184
+
185
+		// if no event, then let's see if there is a reg_obj.  If there IS, then we'll try and grab the event from the
186
+		// reg_obj instead.
187
+		if (! $this->_event instanceof EE_Event) {
188
+			$aee = $this->_data instanceof EE_Messages_Addressee ? $this->_data : null;
189
+			$aee = $this->_extra_data instanceof EE_Messages_Addressee ? $this->_extra_data : $aee;
190
+
191
+			$this->_event = $aee instanceof EE_Messages_Addressee && $aee->reg_obj instanceof EE_Registration
192
+				? $aee->reg_obj->event()
193
+				: null;
194
+
195
+			// if still empty do we have a ticket data item?
196
+			$this->_event = ! $this->_event instanceof EE_Event
197
+							&& $this->_data instanceof EE_Ticket
198
+							&& $this->_extra_data['data'] instanceof EE_Messages_Addressee
199
+				? $this->_extra_data['data']->tickets[ $this->_data->ID() ]['EE_Event']
200
+				: $this->_event;
201
+
202
+			// if STILL empty event, let's try to get the first event in the list of events via EE_Messages_Addressee
203
+			// and use that.
204
+			$this->_event = ! $this->_event instanceof EE_Event && $aee instanceof EE_Messages_Addressee
205
+				? reset($aee->events)
206
+				: $this->_event;
207
+		}
208
+
209
+		// If we have an event object use it to pull the venue.
210
+		if ($this->_event instanceof EE_Event) {
211
+			return $this->_event->get_first_related('Venue');
212
+		}
213
+
214
+		return null;
215
+	}
216
+
217
+	/**
218
+	 * This retrieves the specified venue information
219
+	 *
220
+	 * @param string $field What Venue field to retrieve
221
+	 * @return string What was retrieved!
222
+	 * @throws EE_Error
223
+	 * @throws EntityNotFoundException
224
+	 */
225
+	private function _venue($field)
226
+	{
227
+
228
+		if (! $this->_venue instanceof EE_Venue) {
229
+			return '';
230
+		} //no venue so get out.
231
+
232
+		switch ($field) {
233
+			case 'title':
234
+				return $this->_venue->get('VNU_name');
235
+				break;
236
+
237
+			case 'description':
238
+				return $this->_venue->get('VNU_desc');
239
+				break;
240
+
241
+			case 'url':
242
+				$url = $this->_venue->get('VNU_url');
243
+				return empty($url) ? $this->_venue->get_permalink() : $url;
244
+				break;
245
+
246
+			case 'permalink':
247
+				return $this->_venue->get_permalink();
248
+				break;
249
+
250
+			case 'image':
251
+				return '<img src="' . $this->_venue->feature_image_url(array(200, 200,))
252
+					   . '" alt="' . sprintf(
253
+						   esc_attr__('%s Feature Image', 'event_espresso'),
254
+						   $this->_venue->get('VNU_name')
255
+					   ) . '" />';
256
+				break;
257
+
258
+			case 'phone':
259
+				return $this->_venue->get('VNU_phone');
260
+				break;
261
+
262
+			case 'address':
263
+				return $this->_venue->get('VNU_address');
264
+				break;
265
+
266
+			case 'address2':
267
+				return $this->_venue->get('VNU_address2');
268
+				break;
269
+
270
+			case 'city':
271
+				return $this->_venue->get('VNU_city');
272
+				break;
273
+
274
+			case 'state':
275
+				$state = $this->_venue->state_obj();
276
+				return is_object($state) ? $state->get('STA_name') : '';
277
+				break;
278
+
279
+			case 'country':
280
+				$country = $this->_venue->country_obj();
281
+				return is_object($country) ? $country->get('CNT_name') : '';
282
+				break;
283
+
284
+			case 'zip':
285
+				return $this->_venue->get('VNU_zip');
286
+				break;
287
+
288
+			case 'formatted_address':
289
+				return EEH_Address::format($this->_venue);
290
+				break;
291
+
292
+			case 'gmap_link':
293
+			case 'gmap_url':
294
+			case 'gmap_link_img':
295
+				$atts = $this->get_map_attributes($this->_venue, $field);
296
+				return EEH_Maps::google_map_link($atts);
297
+				break;
298
+		}
299
+		return '';
300
+	}
301
+
302
+
303
+	/**
304
+	 * Generates the attributes for retrieving a google_map artifact.
305
+	 *
306
+	 * @param EE_Venue $venue
307
+	 * @param string   $field
308
+	 * @return array
309
+	 * @throws EE_Error
310
+	 */
311
+	protected function get_map_attributes(EE_Venue $venue, $field = 'gmap_link')
312
+	{
313
+		$state = $venue->state_obj();
314
+		$country = $venue->country_obj();
315
+		$atts = array(
316
+			'id'      => $venue->ID(),
317
+			'address' => $venue->get('VNU_address'),
318
+			'city'    => $venue->get('VNU_city'),
319
+			'state'   => is_object($state) ? $state->get('STA_name') : '',
320
+			'zip'     => $venue->get('VNU_zip'),
321
+			'country' => is_object($country) ? $country->get('CNT_name') : '',
322
+			'type'    => $field === 'gmap_link' ? 'url' : 'map',
323
+			'map_w'   => 200,
324
+			'map_h'   => 200,
325
+		);
326
+		if ($field === 'gmap_url') {
327
+			$atts['type'] = 'url_only';
328
+		}
329
+		return $atts;
330
+	}
331 331
 }
Please login to merge, or discard this patch.
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -88,7 +88,7 @@  discard block
 block discarded – undo
88 88
     {
89 89
         $this->_venue = $this->_get_venue();
90 90
         // If there is no venue object by now then get out.
91
-        if (! $this->_venue instanceof EE_Venue) {
91
+        if ( ! $this->_venue instanceof EE_Venue) {
92 92
             return '';
93 93
         }
94 94
 
@@ -184,7 +184,7 @@  discard block
 block discarded – undo
184 184
 
185 185
         // if no event, then let's see if there is a reg_obj.  If there IS, then we'll try and grab the event from the
186 186
         // reg_obj instead.
187
-        if (! $this->_event instanceof EE_Event) {
187
+        if ( ! $this->_event instanceof EE_Event) {
188 188
             $aee = $this->_data instanceof EE_Messages_Addressee ? $this->_data : null;
189 189
             $aee = $this->_extra_data instanceof EE_Messages_Addressee ? $this->_extra_data : $aee;
190 190
 
@@ -196,7 +196,7 @@  discard block
 block discarded – undo
196 196
             $this->_event = ! $this->_event instanceof EE_Event
197 197
                             && $this->_data instanceof EE_Ticket
198 198
                             && $this->_extra_data['data'] instanceof EE_Messages_Addressee
199
-                ? $this->_extra_data['data']->tickets[ $this->_data->ID() ]['EE_Event']
199
+                ? $this->_extra_data['data']->tickets[$this->_data->ID()]['EE_Event']
200 200
                 : $this->_event;
201 201
 
202 202
             // if STILL empty event, let's try to get the first event in the list of events via EE_Messages_Addressee
@@ -225,7 +225,7 @@  discard block
 block discarded – undo
225 225
     private function _venue($field)
226 226
     {
227 227
 
228
-        if (! $this->_venue instanceof EE_Venue) {
228
+        if ( ! $this->_venue instanceof EE_Venue) {
229 229
             return '';
230 230
         } //no venue so get out.
231 231
 
@@ -248,11 +248,11 @@  discard block
 block discarded – undo
248 248
                 break;
249 249
 
250 250
             case 'image':
251
-                return '<img src="' . $this->_venue->feature_image_url(array(200, 200,))
252
-                       . '" alt="' . sprintf(
251
+                return '<img src="'.$this->_venue->feature_image_url(array(200, 200,))
252
+                       . '" alt="'.sprintf(
253 253
                            esc_attr__('%s Feature Image', 'event_espresso'),
254 254
                            $this->_venue->get('VNU_name')
255
-                       ) . '" />';
255
+                       ).'" />';
256 256
                 break;
257 257
 
258 258
             case 'phone':
Please login to merge, or discard this patch.
core/libraries/form_sections/inputs/EE_Radio_Button_Input.input.php 1 patch
Indentation   +17 added lines, -17 removed lines patch added patch discarded remove patch
@@ -15,22 +15,22 @@
 block discarded – undo
15 15
 class EE_Radio_Button_Input extends EE_Form_Input_With_Options_Base
16 16
 {
17 17
 
18
-    /**
19
-     * @param array $answer_options
20
-     * @param array $input_settings
21
-     */
22
-    public function __construct($answer_options, $input_settings = array())
23
-    {
24
-        $this->_set_display_strategy(new EE_Radio_Button_Display_Strategy());
25
-        $this->_add_validation_strategy(
26
-            new EE_Enum_Validation_Strategy(
27
-                isset($input_settings['validation_error_message'])
28
-                    ? $input_settings['validation_error_message']
29
-                    : null
30
-            )
31
-        );
32
-        $this->_multiple_selections = false;
33
-        parent::__construct($answer_options, $input_settings);
34
-    }
18
+	/**
19
+	 * @param array $answer_options
20
+	 * @param array $input_settings
21
+	 */
22
+	public function __construct($answer_options, $input_settings = array())
23
+	{
24
+		$this->_set_display_strategy(new EE_Radio_Button_Display_Strategy());
25
+		$this->_add_validation_strategy(
26
+			new EE_Enum_Validation_Strategy(
27
+				isset($input_settings['validation_error_message'])
28
+					? $input_settings['validation_error_message']
29
+					: null
30
+			)
31
+		);
32
+		$this->_multiple_selections = false;
33
+		parent::__construct($answer_options, $input_settings);
34
+	}
35 35
 
36 36
 }
Please login to merge, or discard this patch.
core/libraries/form_sections/inputs/EE_Datepicker_Input.php 2 patches
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -29,7 +29,7 @@  discard block
 block discarded – undo
29 29
             )
30 30
         );
31 31
         parent::__construct($input_settings);
32
-        $this->set_html_class($this->html_class() . ' datepicker');
32
+        $this->set_html_class($this->html_class().' datepicker');
33 33
         // add some style and make it dance
34 34
         add_action('wp_enqueue_scripts', array('EE_Datepicker_Input', 'enqueue_styles_and_scripts'));
35 35
         add_action('admin_enqueue_scripts', array('EE_Datepicker_Input', 'enqueue_styles_and_scripts'));
@@ -48,7 +48,7 @@  discard block
 block discarded – undo
48 48
         // load css
49 49
         wp_register_style(
50 50
             'espresso-ui-theme',
51
-            EE_GLOBAL_ASSETS_URL . 'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
51
+            EE_GLOBAL_ASSETS_URL.'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
52 52
             array(),
53 53
             EVENT_ESPRESSO_VERSION
54 54
         );
Please login to merge, or discard this patch.
Indentation   +38 added lines, -38 removed lines patch added patch discarded remove patch
@@ -10,45 +10,45 @@
 block discarded – undo
10 10
 class EE_Datepicker_Input extends EE_Form_Input_Base
11 11
 {
12 12
 
13
-    /**
14
-     * @param array $input_settings
15
-     */
16
-    public function __construct($input_settings = array())
17
-    {
18
-        $this->_set_display_strategy(new EE_Text_Input_Display_Strategy('datepicker'));
19
-        $this->_set_normalization_strategy(new EE_Text_Normalization());
20
-        // we could do better for validation, but at least verify its plaintext
21
-        $this->_add_validation_strategy(
22
-            new EE_Plaintext_Validation_Strategy(
23
-                isset($input_settings['validation_error_message'])
24
-                    ? $input_settings['validation_error_message']
25
-                    : null
26
-            )
27
-        );
28
-        parent::__construct($input_settings);
29
-        $this->set_html_class($this->html_class() . ' datepicker');
30
-        // add some style and make it dance
31
-        add_action('wp_enqueue_scripts', array('EE_Datepicker_Input', 'enqueue_styles_and_scripts'));
32
-        add_action('admin_enqueue_scripts', array('EE_Datepicker_Input', 'enqueue_styles_and_scripts'));
33
-    }
13
+	/**
14
+	 * @param array $input_settings
15
+	 */
16
+	public function __construct($input_settings = array())
17
+	{
18
+		$this->_set_display_strategy(new EE_Text_Input_Display_Strategy('datepicker'));
19
+		$this->_set_normalization_strategy(new EE_Text_Normalization());
20
+		// we could do better for validation, but at least verify its plaintext
21
+		$this->_add_validation_strategy(
22
+			new EE_Plaintext_Validation_Strategy(
23
+				isset($input_settings['validation_error_message'])
24
+					? $input_settings['validation_error_message']
25
+					: null
26
+			)
27
+		);
28
+		parent::__construct($input_settings);
29
+		$this->set_html_class($this->html_class() . ' datepicker');
30
+		// add some style and make it dance
31
+		add_action('wp_enqueue_scripts', array('EE_Datepicker_Input', 'enqueue_styles_and_scripts'));
32
+		add_action('admin_enqueue_scripts', array('EE_Datepicker_Input', 'enqueue_styles_and_scripts'));
33
+	}
34 34
 
35 35
 
36 36
 
37
-    /**
38
-     *    enqueue_styles_and_scripts
39
-     *
40
-     * @access        public
41
-     * @return        void
42
-     */
43
-    public static function enqueue_styles_and_scripts()
44
-    {
45
-        // load css
46
-        wp_register_style(
47
-            'espresso-ui-theme',
48
-            EE_GLOBAL_ASSETS_URL . 'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
49
-            array(),
50
-            EVENT_ESPRESSO_VERSION
51
-        );
52
-        wp_enqueue_style('espresso-ui-theme');
53
-    }
37
+	/**
38
+	 *    enqueue_styles_and_scripts
39
+	 *
40
+	 * @access        public
41
+	 * @return        void
42
+	 */
43
+	public static function enqueue_styles_and_scripts()
44
+	{
45
+		// load css
46
+		wp_register_style(
47
+			'espresso-ui-theme',
48
+			EE_GLOBAL_ASSETS_URL . 'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
49
+			array(),
50
+			EVENT_ESPRESSO_VERSION
51
+		);
52
+		wp_enqueue_style('espresso-ui-theme');
53
+	}
54 54
 }
Please login to merge, or discard this patch.
public/Espresso_Arabica_2014/loop-espresso_event_attendees.php 3 patches
Indentation   +18 added lines, -18 removed lines patch added patch discarded remove patch
@@ -22,15 +22,15 @@  discard block
 block discarded – undo
22 22
 
23 23
 <div class="event-attendees">
24 24
     <?php do_action_ref_array(
25
-        'AHEE__loop-espresso_event_attendees__before',
26
-        array(
27
-            $contacts,
28
-            $event,
29
-            $datetime,
30
-            $ticket,
31
-            $show_gravatar,
32
-        )
33
-    ); ?>
25
+		'AHEE__loop-espresso_event_attendees__before',
26
+		array(
27
+			$contacts,
28
+			$event,
29
+			$datetime,
30
+			$ticket,
31
+			$show_gravatar,
32
+		)
33
+	); ?>
34 34
 	<?php if ( $contacts ) : ?>
35 35
 		<ul class="event-attendees-list">
36 36
 			<?php foreach( $contacts as $contact ) :
@@ -47,13 +47,13 @@  discard block
 block discarded – undo
47 47
 		<p><?php echo $no_attendees_message; ?></p>
48 48
 	<?php endif; ?>
49 49
     <?php do_action_ref_array(
50
-        'AHEE__loop-espresso_event_attendees__after',
51
-        array(
52
-            $contacts,
53
-            $event,
54
-            $datetime,
55
-            $ticket,
56
-            $show_gravatar,
57
-        )
58
-    ); ?>
50
+		'AHEE__loop-espresso_event_attendees__after',
51
+		array(
52
+			$contacts,
53
+			$event,
54
+			$datetime,
55
+			$ticket,
56
+			$show_gravatar,
57
+		)
58
+	); ?>
59 59
 </div>
60 60
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -15,7 +15,7 @@  discard block
 block discarded – undo
15 15
  * @type bool       $show_gravatar  whether to show gravatar or not.
16 16
  */
17 17
 
18
-$no_attendees_message =  apply_filters( 'FHEE__loop-espresso_attendees-shortcode__template__no_attendees_message', __('No Attendees Yet', 'event_espresso' ) );
18
+$no_attendees_message = apply_filters('FHEE__loop-espresso_attendees-shortcode__template__no_attendees_message', __('No Attendees Yet', 'event_espresso'));
19 19
 
20 20
 
21 21
 ?>
@@ -31,16 +31,16 @@  discard block
 block discarded – undo
31 31
             $show_gravatar,
32 32
         )
33 33
     ); ?>
34
-	<?php if ( $contacts ) : ?>
34
+	<?php if ($contacts) : ?>
35 35
 		<ul class="event-attendees-list">
36
-			<?php foreach( $contacts as $contact ) :
37
-				EEH_Template::get_template_part( 'content', 'espresso_event_attendees', array( 
36
+			<?php foreach ($contacts as $contact) :
37
+				EEH_Template::get_template_part('content', 'espresso_event_attendees', array( 
38 38
 					'contact'       => $contact, 
39 39
 					'event'         => $event,
40 40
 					'datetime'      => $datetime,
41 41
 					'ticket'        => $ticket,
42 42
 					'show_gravatar' => $show_gravatar 
43
-				) );
43
+				));
44 44
 				endforeach; ?>
45 45
 		</ul>
46 46
 	<?php else : ?>
Please login to merge, or discard this patch.
Braces   +5 added lines, -2 removed lines patch added patch discarded remove patch
@@ -43,8 +43,11 @@
 block discarded – undo
43 43
 				) );
44 44
 				endforeach; ?>
45 45
 		</ul>
46
-	<?php else : ?>
47
-		<p><?php echo $no_attendees_message; ?></p>
46
+	<?php else {
47
+	: ?>
48
+		<p><?php echo $no_attendees_message;
49
+}
50
+?></p>
48 51
 	<?php endif; ?>
49 52
     <?php do_action_ref_array(
50 53
         'AHEE__loop-espresso_event_attendees__after',
Please login to merge, or discard this patch.