Completed
Branch master (76375f)
by
unknown
10:42 queued 05:22
created
PaymentMethods/PayPalCommerce/modules/EED_PayPalOnboard.module.php 1 patch
Indentation   +656 added lines, -656 removed lines patch added patch discarded remove patch
@@ -21,660 +21,660 @@
 block discarded – undo
21 21
  */
22 22
 class EED_PayPalOnboard extends EED_Module
23 23
 {
24
-    /**
25
-     * @return EED_Module
26
-     * @throws EE_Error
27
-     * @throws ReflectionException
28
-     */
29
-    public static function instance(): EED_Module
30
-    {
31
-        return parent::get_instance(__CLASS__);
32
-    }
33
-
34
-
35
-    /**
36
-     * Run - initial module setup.
37
-     *
38
-     * @param WP $WP
39
-     * @return void
40
-     */
41
-    public function run($WP)
42
-    {
43
-    }
44
-
45
-
46
-    /**
47
-     * For hooking into EE Admin Core and other modules.
48
-     *
49
-     * @return void
50
-     */
51
-    public static function set_hooks_admin(): void
52
-    {
53
-        if (DbStatus::isOnline()) {
54
-            // Get onboarding URL.
55
-            add_action('wp_ajax_eeaPpGetOnboardingUrl', [__CLASS__, 'getOnboardingUrl']);
56
-            // Catch the return/redirect from PayPal onboarding page.
57
-            add_action('init', [__CLASS__, 'updateOnboardingStatus'], 10);
58
-            // Return the connection/onboard status.
59
-            add_action('wp_ajax_eeaPpGetOnboardStatus', [__CLASS__, 'getOnboardStatus']);
60
-            // Revoke access.
61
-            add_action('wp_ajax_eeaPpOffboard', [__CLASS__, 'offboard']);
62
-            // Admin notice.
63
-            add_action('admin_init', [__CLASS__, 'adminNotice']);
64
-        }
65
-    }
66
-
67
-
68
-    /**
69
-     * Get the onboarding URL.
70
-     * (AJAX)
71
-     *
72
-     * @return void
73
-     */
74
-    public static function getOnboardingUrl(): void
75
-    {
76
-        $signup_link = '';
77
-        try {
78
-            $paypal_pm = EED_PayPalCommerce::getPaymentMethod();
79
-            if (! $paypal_pm instanceof EE_Payment_Method) {
80
-                PayPalLogger::errorLogAndExit(
81
-                    esc_html__('No payment method.', 'event_espresso'),
82
-                    EED_Module::getRequest()->postParams(),
83
-                    $paypal_pm
84
-                );
85
-            }
86
-            PayPalExtraMetaManager::updateDebugMode($paypal_pm, EED_Module::getRequest()->postParams());
87
-            // $signup_link   = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_ONBOARDING_URL);
88
-            // $token_expired = EED_PayPalOnboard::partnerAccessTokenExpired($paypal_pm);
89
-            // if (! $signup_link || $token_expired) {
90
-            $signup_link = EED_PayPalOnboard::requestOnboardingUrl($paypal_pm);
91
-            // }
92
-            if (! $signup_link) {
93
-                $err_msg = esc_html__('Error! Could not generate a sign-up link.', 'event_espresso');
94
-                PayPalLogger::errorLogAndExit($err_msg, ['signup_link' => $signup_link], $paypal_pm);
95
-            }
96
-            PayPalExtraMetaManager::savePmOption($paypal_pm, Domain::META_KEY_ONBOARDING_URL, $signup_link);
97
-        } catch (Exception $exception) {
98
-            PayPalLogger::errorLogAndExit($exception->getMessage());
99
-        }
100
-        // Is it empty (can happen if we didn't get the URL through the API).
101
-        $signup_link = $signup_link ? $signup_link . '?&displayMode=minibrowser' : '#';
102
-        wp_send_json(
103
-            [
104
-                'signup_link' => $signup_link,
105
-            ]
106
-        );
107
-    }
108
-
109
-
110
-    /**
111
-     * Request the sign-up link from PayPal.
112
-     *
113
-     * @param EE_Payment_Method $paypal_pm
114
-     * @param bool              $one_time_request
115
-     * @return string
116
-     * @throws EE_Error
117
-     * @throws Exception
118
-     */
119
-    public static function requestOnboardingUrl(EE_Payment_Method $paypal_pm, bool $one_time_request = false): string
120
-    {
121
-        $signup_link = '';
122
-        // Get the access token.
123
-        $access_token = EED_PayPalOnboard::getPartnerAccessToken($paypal_pm);
124
-        if (! $access_token) {
125
-            $err_msg = esc_html__('Error! No access token.', 'event_espresso');
126
-            PayPalLogger::errorLog($err_msg, ['access_token' => $access_token], $paypal_pm);
127
-            return '';
128
-        }
129
-        // Request the access token.
130
-        $body_params = EED_PayPalOnboard::signupLinkRequestBody($paypal_pm);
131
-        $bn_code     = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_BN_CODE);
132
-        $post_params = [
133
-            'method'  => 'POST',
134
-            'headers' => [
135
-                'User-Agent'                    => sanitize_text_field($_SERVER['HTTP_USER_AGENT']),
136
-                'Content-Type'                  => 'application/json',
137
-                'Authorization'                 => 'Bearer ' . $access_token,
138
-                'PayPal-Partner-Attribution-Id' => $bn_code,
139
-            ],
140
-            'body'    => $body_params,
141
-        ];
142
-        $request_url = Domain::getPayPalApiUrl($paypal_pm) . '/v2/customer/partner-referrals';
143
-        $response    = EED_PayPalOnboard::sendRequest($paypal_pm, $request_url, $post_params);
144
-        // Check the data we received.
145
-        if (isset($response['error']) || empty($response['links'])) {
146
-            // Did the original access token get replaced by any chance ?
147
-            if (! $one_time_request
148
-                && ! empty($response['message'])
149
-                && $response['message'] === 'Access Token not found in cache'
150
-            ) {
151
-                // Clear all PM metadata and try getting the access token One more time.
152
-                PayPalExtraMetaManager::deleteAllData($paypal_pm);
153
-                return EED_PayPalOnboard::requestOnboardingUrl($paypal_pm, true);
154
-            }
155
-            $err_msg = esc_html__('Incoming sign-up link parameter validation failed.', 'event_espresso');
156
-            PayPalLogger::errorLog($err_msg, $response, $paypal_pm);
157
-            return '';
158
-        }
159
-        // Now retrieve that sign-up link.
160
-        foreach ($response['links'] as $link) {
161
-            if ($link['rel'] === 'action_url') {
162
-                $signup_link = $link['href'] ?? '';
163
-            }
164
-        }
165
-        return $signup_link;
166
-    }
167
-
168
-
169
-    /**
170
-     * Get the return URL.
171
-     *
172
-     * @param EE_Payment_Method $paypal_pm
173
-     * @return string
174
-     * @throws Exception
175
-     */
176
-    public static function signupLinkRequestBody(EE_Payment_Method $paypal_pm): string
177
-    {
178
-        $identifier_string = new OneTimeString($paypal_pm->debug_mode());
179
-        $tracking_id       = $identifier_string->value();
180
-        $request           = LoaderFactory::getLoader()->getShared(RequestInterface::class);
181
-        $checkout_type     = $request->getRequestParam('checkout_type', 'EXPRESS_CHECKOUT');
182
-        // Save the identifier for future use.
183
-        PayPalExtraMetaManager::savePmOption($paypal_pm, Domain::META_KEY_TRACKING_ID, $tracking_id);
184
-        // Assemble the return URL.
185
-        $return_url = EED_PayPalOnboard::getReturnUrl($paypal_pm);
186
-        return json_encode([
187
-            'tracking_id'             => $tracking_id,
188
-            'operations'              => [
189
-                [
190
-                    'operation'                  => 'API_INTEGRATION',
191
-                    'api_integration_preference' => [
192
-                        'rest_api_integration' => [
193
-                            'integration_method'  => 'PAYPAL',
194
-                            'integration_type'    => 'THIRD_PARTY',
195
-                            'third_party_details' => [
196
-                                'features' => ['PAYMENT', 'REFUND', 'PARTNER_FEE'],
197
-                            ],
198
-                        ],
199
-                    ],
200
-                ],
201
-            ],
202
-            'products'                => [$checkout_type],
203
-            'legal_consents'          => [
204
-                [
205
-                    'type'    => 'SHARE_DATA_CONSENT',
206
-                    'granted' => true,
207
-                ],
208
-            ],
209
-            'partner_config_override' => [
210
-                'return_url' => $return_url,
211
-            ],
212
-        ]);
213
-    }
214
-
215
-
216
-    /**
217
-     * Get the return URL.
218
-     *
219
-     * @param EE_Payment_Method $paypal_pm
220
-     * @return string
221
-     * @throws EE_Error
222
-     * @throws ReflectionException
223
-     */
224
-    public static function getReturnUrl(EE_Payment_Method $paypal_pm): string
225
-    {
226
-        $wp_nonce = EED_Module::getRequest()->getRequestParam('wp_nonce');
227
-        $nonce    = wp_create_nonce(Domain::NONCE_NAME_ONBOARDING_RETURN);
228
-        return add_query_arg(
229
-            [
230
-                'page'                        => 'espresso_payment_settings',
231
-                'webhook_action'              => 'eepPpcMerchantOnboard',
232
-                'payment_method'              => $paypal_pm->slug(),
233
-                '_wpnonce'                    => $wp_nonce,
234
-                'nonce'                       => $nonce,
235
-                Domain::META_KEY_SANDBOX_MODE => $paypal_pm->debug_mode() ? '1' : '0',
236
-            ],
237
-            admin_url('admin.php')
238
-        );
239
-    }
240
-
241
-
242
-    /**
243
-     * Redirect to the payment method (PP) settings home page.
244
-     *
245
-     * @return void
246
-     */
247
-    public static function redirectToPmSettingsHome(): void
248
-    {
249
-        $get_params = EED_Module::getRequest()->getParams();
250
-        if (empty($get_params['payment_method'])) {
251
-            // Simply do not redirect.
252
-            return;
253
-        }
254
-        $args_to_add = [
255
-            'page'           => 'espresso_payment_settings',
256
-            'payment_method' => $get_params['payment_method'],
257
-        ];
258
-        if (isset($get_params['sandbox_mode'])) {
259
-            $args_to_add[ Domain::META_KEY_SANDBOX_MODE ] = $get_params['sandbox_mode'];
260
-        }
261
-        $home_url = add_query_arg($args_to_add, admin_url('admin.php'));
262
-        wp_redirect($home_url);
263
-        exit;
264
-    }
265
-
266
-
267
-    /**
268
-     * Check user’s onboarding status.
269
-     * This will handle the user return from the auth page and also check the status via the API.
270
-     *
271
-     * @return void
272
-     * @throws EE_Error
273
-     * @throws ReflectionException
274
-     */
275
-    public static function updateOnboardingStatus(): void
276
-    {
277
-        // Check if this is the webhook from PayPal.
278
-        if (! isset($_GET['webhook_action'], $_GET['nonce'])
279
-            || $_GET['webhook_action'] !== 'eepPpcMerchantOnboard'
280
-        ) {
281
-            return;  // Ignore.
282
-        }
283
-        $get_params = EED_Module::getRequest()->getParams();
284
-        // Get the payment method.
285
-        $paypal_pm = EED_PayPalCommerce::getPaymentMethod();
286
-        // Check the response (GET) parameters.
287
-        if (! EED_PayPalOnboard::onboardingStatusResponseValid($get_params, $paypal_pm)) {
288
-            // Missing parameters. Can't proceed.
289
-            PayPalLogger::errorLog(
290
-                esc_html__('Missing required onboarding parameters.', 'event_espresso'),
291
-                $get_params,
292
-                $paypal_pm
293
-            );
294
-            EED_PayPalOnboard::redirectToPmSettingsHome();
295
-            return;
296
-        }
297
-        // Check on the onboarding status (recommended by PP).
298
-        $onboarding_status = EED_PayPalOnboard::trackSellerOnboarding(
299
-            $paypal_pm,
300
-            $get_params[ Domain::META_KEY_SELLER_MERCHANT_ID ]
301
-        );
302
-        if (! isset($onboarding_status['valid']) || ! $onboarding_status['valid']) {
303
-            PayPalLogger::errorLog(
304
-                $onboarding_status['message'],
305
-                array_merge($get_params, $onboarding_status),
306
-                $paypal_pm
307
-            );
308
-            EED_PayPalOnboard::redirectToPmSettingsHome();
309
-            return;
310
-        }
311
-        // Start saving the setup and info.
312
-        PayPalExtraMetaManager::parseAndSaveOptions($paypal_pm, $onboarding_status);
313
-        // Save the credentials.
314
-        PayPalExtraMetaManager::saveSellerApiCredentials($paypal_pm, $get_params);
315
-        // If onboarded successfully, remove the onboarding URL.
316
-        PayPalExtraMetaManager::deletePmOption($paypal_pm, Domain::META_KEY_ONBOARDING_URL);
317
-        // Also clen GET params by redirecting, because PP auto redirects to the return_url on closing the onboarding window.
318
-        EED_PayPalOnboard::redirectToPmSettingsHome();
319
-    }
320
-
321
-
322
-    /**
323
-     * Check if all required parameters for the onboarding status check are present.
324
-     *
325
-     * @param array $data
326
-     * @param mixed $paypal_pm
327
-     * @return bool
328
-     */
329
-    public static function onboardingStatusResponseValid(array $data, $paypal_pm): bool
330
-    {
331
-        // Check that we have all the required parameters and the nonce is ok.
332
-        if ($paypal_pm instanceof EE_Payment_Method
333
-            && wp_verify_nonce($data['nonce'], Domain::NONCE_NAME_ONBOARDING_RETURN)
334
-            && ! empty($data[ Domain::API_PARAM_PARTNER_ID ])
335
-            && ! empty($data[ Domain::META_KEY_SELLER_MERCHANT_ID ])
336
-            && isset($data[ Domain::API_PARAM_EMAIL_CONFIRMED ])
337
-        ) {
338
-            return true;
339
-        }
340
-        return false;
341
-    }
342
-
343
-
344
-    /**
345
-     * Get partner access token.
346
-     *
347
-     * @param EE_Payment_Method $paypal_pm
348
-     * @return string
349
-     * @throws EE_Error
350
-     * @throws ReflectionException
351
-     */
352
-    public static function getPartnerAccessToken(EE_Payment_Method $paypal_pm): string
353
-    {
354
-        // Do we have it saved ?
355
-        $access_token = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_ACCESS_TOKEN);
356
-        $expired      = EED_PayPalOnboard::partnerAccessTokenExpired($paypal_pm);
357
-        // If we don't have it, request/update it.
358
-        if (! $access_token || $expired) {
359
-            return EED_PayPalOnboard::requestPartnerAccessToken($paypal_pm);
360
-        }
361
-        // Access token is saved as encrypted, so return decrypted.
362
-        return $access_token;
363
-    }
364
-
365
-
366
-    /**
367
-     * Get partner access token.
368
-     *
369
-     * @param EE_Payment_Method $paypal_pm
370
-     * @return bool
371
-     */
372
-    public static function partnerAccessTokenExpired(EE_Payment_Method $paypal_pm): bool
373
-    {
374
-        $expires_at = (int) PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_TOKEN_EXPIRES_IN);
375
-        if (! $expires_at) {
376
-            return true;
377
-        }
378
-        // Validate the token expiration date.
379
-        $now          = time();
380
-        $minutes_left = round(($expires_at - $now) / 60);
381
-        // Count as expired if less than 60 minutes till expiration left.
382
-        if ($minutes_left <= 60) {
383
-            return true;
384
-        }
385
-        return false;
386
-    }
387
-
388
-
389
-    /**
390
-     * Request the partner access token from PayPal and save/update it.
391
-     *
392
-     * @param EE_Payment_Method $paypal_pm
393
-     * @return string
394
-     * @throws EE_Error
395
-     * @throws ReflectionException
396
-     */
397
-    public static function requestPartnerAccessToken(EE_Payment_Method $paypal_pm): string
398
-    {
399
-        $nonce = wp_create_nonce('eea_pp_commerce_get_access_token');
400
-        // Request the access token.
401
-        $post_args = [
402
-            'method' => 'POST',
403
-            'body'   => [
404
-                'nonce'                       => $nonce,
405
-                'api_version'                 => 'v1',
406
-                Domain::META_KEY_SANDBOX_MODE => $paypal_pm->debug_mode() ? '1' : '0',
407
-            ],
408
-        ];
409
-        if (defined('LOCAL_MIDDLEMAN_SERVER')) {
410
-            $post_args['sslverify'] = Manager::verifySSL();
411
-        }
412
-        $post_url = EED_PayPalOnboard::getMiddlemanBaseUrl($paypal_pm) . 'get_token';
413
-        $response = EED_PayPalOnboard::sendRequest($paypal_pm, $post_url, $post_args);
414
-        if (isset($response['error'])) {
415
-            return '';
416
-        }
417
-        // Check the data we received.
418
-        if (! EED_PayPalOnboard::partnerTokenResponseValid($response, $paypal_pm)) {
419
-            return '';
420
-        }
421
-        // If we are here all seems to be ok. Save the token and it's data.
422
-        $saved = PayPalExtraMetaManager::savePartnerAccessToken($paypal_pm, $response);
423
-        if (! $saved) {
424
-            return '';
425
-        }
426
-        return $response['access_token'];
427
-    }
428
-
429
-
430
-    /**
431
-     * Request seller onboarding status from PayPal.
432
-     *
433
-     * @param EE_Payment_Method $paypal_pm
434
-     * @param string            $merchant_id
435
-     * @return array
436
-     */
437
-    public static function trackSellerOnboarding(EE_Payment_Method $paypal_pm, string $merchant_id): array
438
-    {
439
-        $track_onboarding = EED_PayPalOnboard::getTrackOnboardingApi($paypal_pm, $merchant_id);
440
-        if (! $track_onboarding instanceof TrackSellerOnboarding) {
441
-            $err_msg = esc_html__('Failed to track seller onboarding.', 'event_espresso');
442
-            return ['error' => 'TRACK_ONBOARDING_FAILED', 'message' => $err_msg];
443
-        }
444
-        return $track_onboarding->isValid();
445
-    }
446
-
447
-
448
-    /**
449
-     * Returns the Track Seller Onboarding API.
450
-     *
451
-     * @param EE_Payment_Method $paypal_pm
452
-     * @param string            $merchant_id
453
-     * @return TrackSellerOnboarding|null
454
-     * @throws EE_Error
455
-     * @throws ReflectionException
456
-     */
457
-    public static function getTrackOnboardingApi(
458
-        EE_Payment_Method $paypal_pm,
459
-        string            $merchant_id
460
-    ): ?TrackSellerOnboarding {
461
-        $partner_id = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_PARTNER_MERCHANT_ID);
462
-        $paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm);
463
-        if (! $paypal_api instanceof PayPalApi || ! $partner_id) {
464
-            return null;
465
-        }
466
-        return new TrackSellerOnboarding($paypal_api, $partner_id, $merchant_id, $paypal_pm->debug_mode());
467
-    }
468
-
469
-
470
-    /**
471
-     * Check the onboard status and return the result.
472
-     * (AJAX)
473
-     *
474
-     * @return void
475
-     */
476
-    public static function getOnboardStatus(): void
477
-    {
478
-        $paypal_pm = EED_PayPalCommerce::getPaymentMethod();
479
-        if (! $paypal_pm instanceof EE_Payment_Method) {
480
-            $err_msg = esc_html__('Could not specify the payment method.', 'event_espresso');
481
-            PayPalLogger::errorLog($err_msg, EED_Module::getRequest()->postParams(), $paypal_pm);
482
-            wp_send_json(['on_board' => false]);
483
-        }
484
-        try {
485
-            $seller_id = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_SELLER_MERCHANT_ID) ?? '--';
486
-        } catch (Exception $e) {
487
-            $seller_id = '--';
488
-        }
489
-        wp_send_json(
490
-            [
491
-                'on_board'  => EED_PayPalOnboard::isOnboard($paypal_pm),
492
-                'seller_id' => $seller_id,
493
-            ]
494
-        );
495
-    }
496
-
497
-
498
-    /**
499
-     * De-authorize the seller. Remove all API credentials.
500
-     * (AJAX)
501
-     *
502
-     * @return void
503
-     */
504
-    public static function offboard(): void
505
-    {
506
-        $paypal_pm = EED_PayPalCommerce::getPaymentMethod();
507
-        if (! $paypal_pm instanceof EE_Payment_Method) {
508
-            wp_send_json([
509
-                'error'   => 'INVALID_PM',
510
-                'message' => esc_html__(
511
-                    'Invalid payment method. Please refresh the page and try again.',
512
-                    'event_espresso'
513
-                ),
514
-            ]);
515
-        }
516
-        PayPalExtraMetaManager::deleteAllData($paypal_pm);
517
-        wp_send_json(['success' => true]);
518
-    }
519
-
520
-
521
-    /**
522
-     * Checks if already onboard.
523
-     *
524
-     * @param EE_Payment_Method $payment_method
525
-     * @return boolean
526
-     */
527
-    public static function isOnboard(EE_Payment_Method $payment_method): bool
528
-    {
529
-        $pp_meta_data = PayPalExtraMetaManager::getAllData($payment_method);
530
-        return
531
-            // onborded with a third party integration ?
532
-            (! empty($pp_meta_data[ Domain::META_KEY_SELLER_MERCHANT_ID ])
533
-                && ! empty($pp_meta_data[ Domain::META_KEY_ACCESS_TOKEN ])
534
-            )
535
-            // or with the first party integration ?
536
-            || (! empty($pp_meta_data[ Domain::META_KEY_CLIENT_ID ])
537
-                && ! empty($pp_meta_data[ Domain::META_KEY_CLIENT_SECRET ])
538
-                && ! empty($pp_meta_data[ Domain::META_KEY_PAYER_ID ])
539
-            );
540
-    }
541
-
542
-
543
-    /**
544
-     * Send a request and return a decoded response body.
545
-     *
546
-     * @param EE_Payment_Method $paypal_pm
547
-     * @param string            $request_url
548
-     * @param array             $request_args
549
-     * @return array
550
-     */
551
-    public static function sendRequest(EE_Payment_Method $paypal_pm, string $request_url, array $request_args): array
552
-    {
553
-        $error_return = ['error' => true];
554
-        $response     = wp_remote_request($request_url, $request_args);
555
-        if (is_wp_error($response)) {
556
-            $message = $response->get_error_message();
557
-            PayPalLogger::errorLog($message, [$request_url, $request_args, $response], $paypal_pm);
558
-            $error_return['message'] = $message;
559
-            return $error_return;
560
-        }
561
-        $response_body = (isset($response['body']) && $response['body']) ? json_decode($response['body'], true) : [];
562
-        if (empty($response_body) || isset($response_body['error'])) {
563
-            $message = $response_body['error_description']
564
-                       ?? sprintf(
565
-                           esc_html__('Unknown response received while sending a request to: %1$s', 'event_espresso'),
566
-                           $request_url
567
-                       );
568
-            PayPalLogger::errorLog($message, [$request_url, $request_args, $response], $paypal_pm);
569
-            $error_return['message'] = $message;
570
-            return $error_return;
571
-        }
572
-        return $response_body;
573
-    }
574
-
575
-
576
-    /**
577
-     * Check the response for a partner token request.
578
-     *
579
-     * @param                   $response
580
-     * @param EE_Payment_Method $paypal_pm
581
-     * @return bool
582
-     */
583
-    public static function partnerTokenResponseValid($response, EE_Payment_Method $paypal_pm): bool
584
-    {
585
-        // Check the data we received.
586
-        if (
587
-            empty($response['nonce'])
588
-            || ! wp_verify_nonce($response['nonce'], 'eea_pp_commerce_get_access_token')
589
-            || empty($response['access_token'])
590
-            || empty($response['app_id'])
591
-            || empty($response['expires_in'])
592
-            || empty($response['partner_client_id'])
593
-            || empty($response['partner_merchant_id'])
594
-        ) {
595
-            // This is an error.
596
-            $err_msg = esc_html__('Incoming parameter validation failed.', 'event_espresso');
597
-            PayPalLogger::errorLog($err_msg, (array) $response, $paypal_pm);
598
-            return false;
599
-        }
600
-        return true;
601
-    }
602
-
603
-
604
-    /**
605
-     * Returns the base URL to the middleman server.
606
-     * If LOCAL_MIDDLEMAN_SERVER is defined, requests will be sent to connect.eventespresso.test
607
-     *
608
-     * @param EE_Payment_Method $payment_method
609
-     * @return string
610
-     * @throws EE_Error
611
-     * @throws ReflectionException
612
-     */
613
-    public static function getMiddlemanBaseUrl(EE_Payment_Method $payment_method): string
614
-    {
615
-        $target = defined('LOCAL_MIDDLEMAN_SERVER') ? 'test' : 'com';
616
-        // If this PM is used under different provider accounts, you might need an account indicator.
617
-        $account = defined('EE_PAYPAL_COMMERCE_ACCOUNT_INDICATOR') ? EE_PAYPAL_COMMERCE_ACCOUNT_INDICATOR : '';
618
-        $postfix = $payment_method->debug_mode() ? '_sandbox' : '';
619
-        $path    = 'paypal_commerce' . $account . $postfix;
620
-        return 'https://connect.eventespresso.' . $target . '/' . $path . '/';
621
-    }
622
-
623
-
624
-    /**
625
-     * This Payment Method admin notices.
626
-     *
627
-     * @return void
628
-     * @throws EE_Error
629
-     * @throws ReflectionException
630
-     */
631
-    public static function adminNotice()
632
-    {
633
-        // Show the notice if PayPal Commerce PM is active but merchant is not onboard.
634
-        $pp_commerce = EEM_Payment_Method::instance()->get_one_by_slug('paypalcheckout');
635
-        if ($pp_commerce instanceof EE_Payment_Method
636
-            && $pp_commerce->active()
637
-            && ! EED_PayPalOnboard::isOnboard($pp_commerce)
638
-        ) {
639
-            add_action('admin_notices', [__CLASS__, 'notOnboardNotice']);
640
-        }
641
-    }
642
-
643
-
644
-    /**
645
-     * Contents of the not onboard admin notice.
646
-     *
647
-     * @return void
648
-     * @throws EE_Error
649
-     * @throws ReflectionException
650
-     */
651
-    public static function notOnboardNotice()
652
-    {
653
-        $open_anchor = $close_anchor = '';
654
-        $pp_commerce = EEM_Payment_Method::instance()->get_one_by_slug('paypalcheckout');
655
-        if ($pp_commerce instanceof EE_Payment_Method) {
656
-            $pm_page = add_query_arg(
657
-                [
658
-                    'page'           => 'espresso_payment_settings',
659
-                    'webhook_action' => 'eepPpcMerchantOnboard',
660
-                    'payment_method' => $pp_commerce->slug(),
661
-                ],
662
-                admin_url('admin.php')
663
-            );
664
-            $open_anchor  = "<a href='$pm_page'>";
665
-            $close_anchor = "</a>";
666
-        }
667
-        echo '<div class="error"><p>'
668
-        . sprintf(
669
-            esc_html__(
670
-                '%1$sPayPal Commerce%2$s payment method was activated but is not connected to PayPal. Please %3$sfinish setting up%4$s this payment method.',
671
-                'event_espresso'
672
-            ),
673
-            '<strong>',
674
-            '</strong>',
675
-            $open_anchor,
676
-            $close_anchor
677
-        )
678
-        . '</p></div>';
679
-    }
24
+	/**
25
+	 * @return EED_Module
26
+	 * @throws EE_Error
27
+	 * @throws ReflectionException
28
+	 */
29
+	public static function instance(): EED_Module
30
+	{
31
+		return parent::get_instance(__CLASS__);
32
+	}
33
+
34
+
35
+	/**
36
+	 * Run - initial module setup.
37
+	 *
38
+	 * @param WP $WP
39
+	 * @return void
40
+	 */
41
+	public function run($WP)
42
+	{
43
+	}
44
+
45
+
46
+	/**
47
+	 * For hooking into EE Admin Core and other modules.
48
+	 *
49
+	 * @return void
50
+	 */
51
+	public static function set_hooks_admin(): void
52
+	{
53
+		if (DbStatus::isOnline()) {
54
+			// Get onboarding URL.
55
+			add_action('wp_ajax_eeaPpGetOnboardingUrl', [__CLASS__, 'getOnboardingUrl']);
56
+			// Catch the return/redirect from PayPal onboarding page.
57
+			add_action('init', [__CLASS__, 'updateOnboardingStatus'], 10);
58
+			// Return the connection/onboard status.
59
+			add_action('wp_ajax_eeaPpGetOnboardStatus', [__CLASS__, 'getOnboardStatus']);
60
+			// Revoke access.
61
+			add_action('wp_ajax_eeaPpOffboard', [__CLASS__, 'offboard']);
62
+			// Admin notice.
63
+			add_action('admin_init', [__CLASS__, 'adminNotice']);
64
+		}
65
+	}
66
+
67
+
68
+	/**
69
+	 * Get the onboarding URL.
70
+	 * (AJAX)
71
+	 *
72
+	 * @return void
73
+	 */
74
+	public static function getOnboardingUrl(): void
75
+	{
76
+		$signup_link = '';
77
+		try {
78
+			$paypal_pm = EED_PayPalCommerce::getPaymentMethod();
79
+			if (! $paypal_pm instanceof EE_Payment_Method) {
80
+				PayPalLogger::errorLogAndExit(
81
+					esc_html__('No payment method.', 'event_espresso'),
82
+					EED_Module::getRequest()->postParams(),
83
+					$paypal_pm
84
+				);
85
+			}
86
+			PayPalExtraMetaManager::updateDebugMode($paypal_pm, EED_Module::getRequest()->postParams());
87
+			// $signup_link   = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_ONBOARDING_URL);
88
+			// $token_expired = EED_PayPalOnboard::partnerAccessTokenExpired($paypal_pm);
89
+			// if (! $signup_link || $token_expired) {
90
+			$signup_link = EED_PayPalOnboard::requestOnboardingUrl($paypal_pm);
91
+			// }
92
+			if (! $signup_link) {
93
+				$err_msg = esc_html__('Error! Could not generate a sign-up link.', 'event_espresso');
94
+				PayPalLogger::errorLogAndExit($err_msg, ['signup_link' => $signup_link], $paypal_pm);
95
+			}
96
+			PayPalExtraMetaManager::savePmOption($paypal_pm, Domain::META_KEY_ONBOARDING_URL, $signup_link);
97
+		} catch (Exception $exception) {
98
+			PayPalLogger::errorLogAndExit($exception->getMessage());
99
+		}
100
+		// Is it empty (can happen if we didn't get the URL through the API).
101
+		$signup_link = $signup_link ? $signup_link . '?&displayMode=minibrowser' : '#';
102
+		wp_send_json(
103
+			[
104
+				'signup_link' => $signup_link,
105
+			]
106
+		);
107
+	}
108
+
109
+
110
+	/**
111
+	 * Request the sign-up link from PayPal.
112
+	 *
113
+	 * @param EE_Payment_Method $paypal_pm
114
+	 * @param bool              $one_time_request
115
+	 * @return string
116
+	 * @throws EE_Error
117
+	 * @throws Exception
118
+	 */
119
+	public static function requestOnboardingUrl(EE_Payment_Method $paypal_pm, bool $one_time_request = false): string
120
+	{
121
+		$signup_link = '';
122
+		// Get the access token.
123
+		$access_token = EED_PayPalOnboard::getPartnerAccessToken($paypal_pm);
124
+		if (! $access_token) {
125
+			$err_msg = esc_html__('Error! No access token.', 'event_espresso');
126
+			PayPalLogger::errorLog($err_msg, ['access_token' => $access_token], $paypal_pm);
127
+			return '';
128
+		}
129
+		// Request the access token.
130
+		$body_params = EED_PayPalOnboard::signupLinkRequestBody($paypal_pm);
131
+		$bn_code     = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_BN_CODE);
132
+		$post_params = [
133
+			'method'  => 'POST',
134
+			'headers' => [
135
+				'User-Agent'                    => sanitize_text_field($_SERVER['HTTP_USER_AGENT']),
136
+				'Content-Type'                  => 'application/json',
137
+				'Authorization'                 => 'Bearer ' . $access_token,
138
+				'PayPal-Partner-Attribution-Id' => $bn_code,
139
+			],
140
+			'body'    => $body_params,
141
+		];
142
+		$request_url = Domain::getPayPalApiUrl($paypal_pm) . '/v2/customer/partner-referrals';
143
+		$response    = EED_PayPalOnboard::sendRequest($paypal_pm, $request_url, $post_params);
144
+		// Check the data we received.
145
+		if (isset($response['error']) || empty($response['links'])) {
146
+			// Did the original access token get replaced by any chance ?
147
+			if (! $one_time_request
148
+				&& ! empty($response['message'])
149
+				&& $response['message'] === 'Access Token not found in cache'
150
+			) {
151
+				// Clear all PM metadata and try getting the access token One more time.
152
+				PayPalExtraMetaManager::deleteAllData($paypal_pm);
153
+				return EED_PayPalOnboard::requestOnboardingUrl($paypal_pm, true);
154
+			}
155
+			$err_msg = esc_html__('Incoming sign-up link parameter validation failed.', 'event_espresso');
156
+			PayPalLogger::errorLog($err_msg, $response, $paypal_pm);
157
+			return '';
158
+		}
159
+		// Now retrieve that sign-up link.
160
+		foreach ($response['links'] as $link) {
161
+			if ($link['rel'] === 'action_url') {
162
+				$signup_link = $link['href'] ?? '';
163
+			}
164
+		}
165
+		return $signup_link;
166
+	}
167
+
168
+
169
+	/**
170
+	 * Get the return URL.
171
+	 *
172
+	 * @param EE_Payment_Method $paypal_pm
173
+	 * @return string
174
+	 * @throws Exception
175
+	 */
176
+	public static function signupLinkRequestBody(EE_Payment_Method $paypal_pm): string
177
+	{
178
+		$identifier_string = new OneTimeString($paypal_pm->debug_mode());
179
+		$tracking_id       = $identifier_string->value();
180
+		$request           = LoaderFactory::getLoader()->getShared(RequestInterface::class);
181
+		$checkout_type     = $request->getRequestParam('checkout_type', 'EXPRESS_CHECKOUT');
182
+		// Save the identifier for future use.
183
+		PayPalExtraMetaManager::savePmOption($paypal_pm, Domain::META_KEY_TRACKING_ID, $tracking_id);
184
+		// Assemble the return URL.
185
+		$return_url = EED_PayPalOnboard::getReturnUrl($paypal_pm);
186
+		return json_encode([
187
+			'tracking_id'             => $tracking_id,
188
+			'operations'              => [
189
+				[
190
+					'operation'                  => 'API_INTEGRATION',
191
+					'api_integration_preference' => [
192
+						'rest_api_integration' => [
193
+							'integration_method'  => 'PAYPAL',
194
+							'integration_type'    => 'THIRD_PARTY',
195
+							'third_party_details' => [
196
+								'features' => ['PAYMENT', 'REFUND', 'PARTNER_FEE'],
197
+							],
198
+						],
199
+					],
200
+				],
201
+			],
202
+			'products'                => [$checkout_type],
203
+			'legal_consents'          => [
204
+				[
205
+					'type'    => 'SHARE_DATA_CONSENT',
206
+					'granted' => true,
207
+				],
208
+			],
209
+			'partner_config_override' => [
210
+				'return_url' => $return_url,
211
+			],
212
+		]);
213
+	}
214
+
215
+
216
+	/**
217
+	 * Get the return URL.
218
+	 *
219
+	 * @param EE_Payment_Method $paypal_pm
220
+	 * @return string
221
+	 * @throws EE_Error
222
+	 * @throws ReflectionException
223
+	 */
224
+	public static function getReturnUrl(EE_Payment_Method $paypal_pm): string
225
+	{
226
+		$wp_nonce = EED_Module::getRequest()->getRequestParam('wp_nonce');
227
+		$nonce    = wp_create_nonce(Domain::NONCE_NAME_ONBOARDING_RETURN);
228
+		return add_query_arg(
229
+			[
230
+				'page'                        => 'espresso_payment_settings',
231
+				'webhook_action'              => 'eepPpcMerchantOnboard',
232
+				'payment_method'              => $paypal_pm->slug(),
233
+				'_wpnonce'                    => $wp_nonce,
234
+				'nonce'                       => $nonce,
235
+				Domain::META_KEY_SANDBOX_MODE => $paypal_pm->debug_mode() ? '1' : '0',
236
+			],
237
+			admin_url('admin.php')
238
+		);
239
+	}
240
+
241
+
242
+	/**
243
+	 * Redirect to the payment method (PP) settings home page.
244
+	 *
245
+	 * @return void
246
+	 */
247
+	public static function redirectToPmSettingsHome(): void
248
+	{
249
+		$get_params = EED_Module::getRequest()->getParams();
250
+		if (empty($get_params['payment_method'])) {
251
+			// Simply do not redirect.
252
+			return;
253
+		}
254
+		$args_to_add = [
255
+			'page'           => 'espresso_payment_settings',
256
+			'payment_method' => $get_params['payment_method'],
257
+		];
258
+		if (isset($get_params['sandbox_mode'])) {
259
+			$args_to_add[ Domain::META_KEY_SANDBOX_MODE ] = $get_params['sandbox_mode'];
260
+		}
261
+		$home_url = add_query_arg($args_to_add, admin_url('admin.php'));
262
+		wp_redirect($home_url);
263
+		exit;
264
+	}
265
+
266
+
267
+	/**
268
+	 * Check user’s onboarding status.
269
+	 * This will handle the user return from the auth page and also check the status via the API.
270
+	 *
271
+	 * @return void
272
+	 * @throws EE_Error
273
+	 * @throws ReflectionException
274
+	 */
275
+	public static function updateOnboardingStatus(): void
276
+	{
277
+		// Check if this is the webhook from PayPal.
278
+		if (! isset($_GET['webhook_action'], $_GET['nonce'])
279
+			|| $_GET['webhook_action'] !== 'eepPpcMerchantOnboard'
280
+		) {
281
+			return;  // Ignore.
282
+		}
283
+		$get_params = EED_Module::getRequest()->getParams();
284
+		// Get the payment method.
285
+		$paypal_pm = EED_PayPalCommerce::getPaymentMethod();
286
+		// Check the response (GET) parameters.
287
+		if (! EED_PayPalOnboard::onboardingStatusResponseValid($get_params, $paypal_pm)) {
288
+			// Missing parameters. Can't proceed.
289
+			PayPalLogger::errorLog(
290
+				esc_html__('Missing required onboarding parameters.', 'event_espresso'),
291
+				$get_params,
292
+				$paypal_pm
293
+			);
294
+			EED_PayPalOnboard::redirectToPmSettingsHome();
295
+			return;
296
+		}
297
+		// Check on the onboarding status (recommended by PP).
298
+		$onboarding_status = EED_PayPalOnboard::trackSellerOnboarding(
299
+			$paypal_pm,
300
+			$get_params[ Domain::META_KEY_SELLER_MERCHANT_ID ]
301
+		);
302
+		if (! isset($onboarding_status['valid']) || ! $onboarding_status['valid']) {
303
+			PayPalLogger::errorLog(
304
+				$onboarding_status['message'],
305
+				array_merge($get_params, $onboarding_status),
306
+				$paypal_pm
307
+			);
308
+			EED_PayPalOnboard::redirectToPmSettingsHome();
309
+			return;
310
+		}
311
+		// Start saving the setup and info.
312
+		PayPalExtraMetaManager::parseAndSaveOptions($paypal_pm, $onboarding_status);
313
+		// Save the credentials.
314
+		PayPalExtraMetaManager::saveSellerApiCredentials($paypal_pm, $get_params);
315
+		// If onboarded successfully, remove the onboarding URL.
316
+		PayPalExtraMetaManager::deletePmOption($paypal_pm, Domain::META_KEY_ONBOARDING_URL);
317
+		// Also clen GET params by redirecting, because PP auto redirects to the return_url on closing the onboarding window.
318
+		EED_PayPalOnboard::redirectToPmSettingsHome();
319
+	}
320
+
321
+
322
+	/**
323
+	 * Check if all required parameters for the onboarding status check are present.
324
+	 *
325
+	 * @param array $data
326
+	 * @param mixed $paypal_pm
327
+	 * @return bool
328
+	 */
329
+	public static function onboardingStatusResponseValid(array $data, $paypal_pm): bool
330
+	{
331
+		// Check that we have all the required parameters and the nonce is ok.
332
+		if ($paypal_pm instanceof EE_Payment_Method
333
+			&& wp_verify_nonce($data['nonce'], Domain::NONCE_NAME_ONBOARDING_RETURN)
334
+			&& ! empty($data[ Domain::API_PARAM_PARTNER_ID ])
335
+			&& ! empty($data[ Domain::META_KEY_SELLER_MERCHANT_ID ])
336
+			&& isset($data[ Domain::API_PARAM_EMAIL_CONFIRMED ])
337
+		) {
338
+			return true;
339
+		}
340
+		return false;
341
+	}
342
+
343
+
344
+	/**
345
+	 * Get partner access token.
346
+	 *
347
+	 * @param EE_Payment_Method $paypal_pm
348
+	 * @return string
349
+	 * @throws EE_Error
350
+	 * @throws ReflectionException
351
+	 */
352
+	public static function getPartnerAccessToken(EE_Payment_Method $paypal_pm): string
353
+	{
354
+		// Do we have it saved ?
355
+		$access_token = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_ACCESS_TOKEN);
356
+		$expired      = EED_PayPalOnboard::partnerAccessTokenExpired($paypal_pm);
357
+		// If we don't have it, request/update it.
358
+		if (! $access_token || $expired) {
359
+			return EED_PayPalOnboard::requestPartnerAccessToken($paypal_pm);
360
+		}
361
+		// Access token is saved as encrypted, so return decrypted.
362
+		return $access_token;
363
+	}
364
+
365
+
366
+	/**
367
+	 * Get partner access token.
368
+	 *
369
+	 * @param EE_Payment_Method $paypal_pm
370
+	 * @return bool
371
+	 */
372
+	public static function partnerAccessTokenExpired(EE_Payment_Method $paypal_pm): bool
373
+	{
374
+		$expires_at = (int) PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_TOKEN_EXPIRES_IN);
375
+		if (! $expires_at) {
376
+			return true;
377
+		}
378
+		// Validate the token expiration date.
379
+		$now          = time();
380
+		$minutes_left = round(($expires_at - $now) / 60);
381
+		// Count as expired if less than 60 minutes till expiration left.
382
+		if ($minutes_left <= 60) {
383
+			return true;
384
+		}
385
+		return false;
386
+	}
387
+
388
+
389
+	/**
390
+	 * Request the partner access token from PayPal and save/update it.
391
+	 *
392
+	 * @param EE_Payment_Method $paypal_pm
393
+	 * @return string
394
+	 * @throws EE_Error
395
+	 * @throws ReflectionException
396
+	 */
397
+	public static function requestPartnerAccessToken(EE_Payment_Method $paypal_pm): string
398
+	{
399
+		$nonce = wp_create_nonce('eea_pp_commerce_get_access_token');
400
+		// Request the access token.
401
+		$post_args = [
402
+			'method' => 'POST',
403
+			'body'   => [
404
+				'nonce'                       => $nonce,
405
+				'api_version'                 => 'v1',
406
+				Domain::META_KEY_SANDBOX_MODE => $paypal_pm->debug_mode() ? '1' : '0',
407
+			],
408
+		];
409
+		if (defined('LOCAL_MIDDLEMAN_SERVER')) {
410
+			$post_args['sslverify'] = Manager::verifySSL();
411
+		}
412
+		$post_url = EED_PayPalOnboard::getMiddlemanBaseUrl($paypal_pm) . 'get_token';
413
+		$response = EED_PayPalOnboard::sendRequest($paypal_pm, $post_url, $post_args);
414
+		if (isset($response['error'])) {
415
+			return '';
416
+		}
417
+		// Check the data we received.
418
+		if (! EED_PayPalOnboard::partnerTokenResponseValid($response, $paypal_pm)) {
419
+			return '';
420
+		}
421
+		// If we are here all seems to be ok. Save the token and it's data.
422
+		$saved = PayPalExtraMetaManager::savePartnerAccessToken($paypal_pm, $response);
423
+		if (! $saved) {
424
+			return '';
425
+		}
426
+		return $response['access_token'];
427
+	}
428
+
429
+
430
+	/**
431
+	 * Request seller onboarding status from PayPal.
432
+	 *
433
+	 * @param EE_Payment_Method $paypal_pm
434
+	 * @param string            $merchant_id
435
+	 * @return array
436
+	 */
437
+	public static function trackSellerOnboarding(EE_Payment_Method $paypal_pm, string $merchant_id): array
438
+	{
439
+		$track_onboarding = EED_PayPalOnboard::getTrackOnboardingApi($paypal_pm, $merchant_id);
440
+		if (! $track_onboarding instanceof TrackSellerOnboarding) {
441
+			$err_msg = esc_html__('Failed to track seller onboarding.', 'event_espresso');
442
+			return ['error' => 'TRACK_ONBOARDING_FAILED', 'message' => $err_msg];
443
+		}
444
+		return $track_onboarding->isValid();
445
+	}
446
+
447
+
448
+	/**
449
+	 * Returns the Track Seller Onboarding API.
450
+	 *
451
+	 * @param EE_Payment_Method $paypal_pm
452
+	 * @param string            $merchant_id
453
+	 * @return TrackSellerOnboarding|null
454
+	 * @throws EE_Error
455
+	 * @throws ReflectionException
456
+	 */
457
+	public static function getTrackOnboardingApi(
458
+		EE_Payment_Method $paypal_pm,
459
+		string            $merchant_id
460
+	): ?TrackSellerOnboarding {
461
+		$partner_id = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_PARTNER_MERCHANT_ID);
462
+		$paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm);
463
+		if (! $paypal_api instanceof PayPalApi || ! $partner_id) {
464
+			return null;
465
+		}
466
+		return new TrackSellerOnboarding($paypal_api, $partner_id, $merchant_id, $paypal_pm->debug_mode());
467
+	}
468
+
469
+
470
+	/**
471
+	 * Check the onboard status and return the result.
472
+	 * (AJAX)
473
+	 *
474
+	 * @return void
475
+	 */
476
+	public static function getOnboardStatus(): void
477
+	{
478
+		$paypal_pm = EED_PayPalCommerce::getPaymentMethod();
479
+		if (! $paypal_pm instanceof EE_Payment_Method) {
480
+			$err_msg = esc_html__('Could not specify the payment method.', 'event_espresso');
481
+			PayPalLogger::errorLog($err_msg, EED_Module::getRequest()->postParams(), $paypal_pm);
482
+			wp_send_json(['on_board' => false]);
483
+		}
484
+		try {
485
+			$seller_id = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_SELLER_MERCHANT_ID) ?? '--';
486
+		} catch (Exception $e) {
487
+			$seller_id = '--';
488
+		}
489
+		wp_send_json(
490
+			[
491
+				'on_board'  => EED_PayPalOnboard::isOnboard($paypal_pm),
492
+				'seller_id' => $seller_id,
493
+			]
494
+		);
495
+	}
496
+
497
+
498
+	/**
499
+	 * De-authorize the seller. Remove all API credentials.
500
+	 * (AJAX)
501
+	 *
502
+	 * @return void
503
+	 */
504
+	public static function offboard(): void
505
+	{
506
+		$paypal_pm = EED_PayPalCommerce::getPaymentMethod();
507
+		if (! $paypal_pm instanceof EE_Payment_Method) {
508
+			wp_send_json([
509
+				'error'   => 'INVALID_PM',
510
+				'message' => esc_html__(
511
+					'Invalid payment method. Please refresh the page and try again.',
512
+					'event_espresso'
513
+				),
514
+			]);
515
+		}
516
+		PayPalExtraMetaManager::deleteAllData($paypal_pm);
517
+		wp_send_json(['success' => true]);
518
+	}
519
+
520
+
521
+	/**
522
+	 * Checks if already onboard.
523
+	 *
524
+	 * @param EE_Payment_Method $payment_method
525
+	 * @return boolean
526
+	 */
527
+	public static function isOnboard(EE_Payment_Method $payment_method): bool
528
+	{
529
+		$pp_meta_data = PayPalExtraMetaManager::getAllData($payment_method);
530
+		return
531
+			// onborded with a third party integration ?
532
+			(! empty($pp_meta_data[ Domain::META_KEY_SELLER_MERCHANT_ID ])
533
+				&& ! empty($pp_meta_data[ Domain::META_KEY_ACCESS_TOKEN ])
534
+			)
535
+			// or with the first party integration ?
536
+			|| (! empty($pp_meta_data[ Domain::META_KEY_CLIENT_ID ])
537
+				&& ! empty($pp_meta_data[ Domain::META_KEY_CLIENT_SECRET ])
538
+				&& ! empty($pp_meta_data[ Domain::META_KEY_PAYER_ID ])
539
+			);
540
+	}
541
+
542
+
543
+	/**
544
+	 * Send a request and return a decoded response body.
545
+	 *
546
+	 * @param EE_Payment_Method $paypal_pm
547
+	 * @param string            $request_url
548
+	 * @param array             $request_args
549
+	 * @return array
550
+	 */
551
+	public static function sendRequest(EE_Payment_Method $paypal_pm, string $request_url, array $request_args): array
552
+	{
553
+		$error_return = ['error' => true];
554
+		$response     = wp_remote_request($request_url, $request_args);
555
+		if (is_wp_error($response)) {
556
+			$message = $response->get_error_message();
557
+			PayPalLogger::errorLog($message, [$request_url, $request_args, $response], $paypal_pm);
558
+			$error_return['message'] = $message;
559
+			return $error_return;
560
+		}
561
+		$response_body = (isset($response['body']) && $response['body']) ? json_decode($response['body'], true) : [];
562
+		if (empty($response_body) || isset($response_body['error'])) {
563
+			$message = $response_body['error_description']
564
+					   ?? sprintf(
565
+						   esc_html__('Unknown response received while sending a request to: %1$s', 'event_espresso'),
566
+						   $request_url
567
+					   );
568
+			PayPalLogger::errorLog($message, [$request_url, $request_args, $response], $paypal_pm);
569
+			$error_return['message'] = $message;
570
+			return $error_return;
571
+		}
572
+		return $response_body;
573
+	}
574
+
575
+
576
+	/**
577
+	 * Check the response for a partner token request.
578
+	 *
579
+	 * @param                   $response
580
+	 * @param EE_Payment_Method $paypal_pm
581
+	 * @return bool
582
+	 */
583
+	public static function partnerTokenResponseValid($response, EE_Payment_Method $paypal_pm): bool
584
+	{
585
+		// Check the data we received.
586
+		if (
587
+			empty($response['nonce'])
588
+			|| ! wp_verify_nonce($response['nonce'], 'eea_pp_commerce_get_access_token')
589
+			|| empty($response['access_token'])
590
+			|| empty($response['app_id'])
591
+			|| empty($response['expires_in'])
592
+			|| empty($response['partner_client_id'])
593
+			|| empty($response['partner_merchant_id'])
594
+		) {
595
+			// This is an error.
596
+			$err_msg = esc_html__('Incoming parameter validation failed.', 'event_espresso');
597
+			PayPalLogger::errorLog($err_msg, (array) $response, $paypal_pm);
598
+			return false;
599
+		}
600
+		return true;
601
+	}
602
+
603
+
604
+	/**
605
+	 * Returns the base URL to the middleman server.
606
+	 * If LOCAL_MIDDLEMAN_SERVER is defined, requests will be sent to connect.eventespresso.test
607
+	 *
608
+	 * @param EE_Payment_Method $payment_method
609
+	 * @return string
610
+	 * @throws EE_Error
611
+	 * @throws ReflectionException
612
+	 */
613
+	public static function getMiddlemanBaseUrl(EE_Payment_Method $payment_method): string
614
+	{
615
+		$target = defined('LOCAL_MIDDLEMAN_SERVER') ? 'test' : 'com';
616
+		// If this PM is used under different provider accounts, you might need an account indicator.
617
+		$account = defined('EE_PAYPAL_COMMERCE_ACCOUNT_INDICATOR') ? EE_PAYPAL_COMMERCE_ACCOUNT_INDICATOR : '';
618
+		$postfix = $payment_method->debug_mode() ? '_sandbox' : '';
619
+		$path    = 'paypal_commerce' . $account . $postfix;
620
+		return 'https://connect.eventespresso.' . $target . '/' . $path . '/';
621
+	}
622
+
623
+
624
+	/**
625
+	 * This Payment Method admin notices.
626
+	 *
627
+	 * @return void
628
+	 * @throws EE_Error
629
+	 * @throws ReflectionException
630
+	 */
631
+	public static function adminNotice()
632
+	{
633
+		// Show the notice if PayPal Commerce PM is active but merchant is not onboard.
634
+		$pp_commerce = EEM_Payment_Method::instance()->get_one_by_slug('paypalcheckout');
635
+		if ($pp_commerce instanceof EE_Payment_Method
636
+			&& $pp_commerce->active()
637
+			&& ! EED_PayPalOnboard::isOnboard($pp_commerce)
638
+		) {
639
+			add_action('admin_notices', [__CLASS__, 'notOnboardNotice']);
640
+		}
641
+	}
642
+
643
+
644
+	/**
645
+	 * Contents of the not onboard admin notice.
646
+	 *
647
+	 * @return void
648
+	 * @throws EE_Error
649
+	 * @throws ReflectionException
650
+	 */
651
+	public static function notOnboardNotice()
652
+	{
653
+		$open_anchor = $close_anchor = '';
654
+		$pp_commerce = EEM_Payment_Method::instance()->get_one_by_slug('paypalcheckout');
655
+		if ($pp_commerce instanceof EE_Payment_Method) {
656
+			$pm_page = add_query_arg(
657
+				[
658
+					'page'           => 'espresso_payment_settings',
659
+					'webhook_action' => 'eepPpcMerchantOnboard',
660
+					'payment_method' => $pp_commerce->slug(),
661
+				],
662
+				admin_url('admin.php')
663
+			);
664
+			$open_anchor  = "<a href='$pm_page'>";
665
+			$close_anchor = "</a>";
666
+		}
667
+		echo '<div class="error"><p>'
668
+		. sprintf(
669
+			esc_html__(
670
+				'%1$sPayPal Commerce%2$s payment method was activated but is not connected to PayPal. Please %3$sfinish setting up%4$s this payment method.',
671
+				'event_espresso'
672
+			),
673
+			'<strong>',
674
+			'</strong>',
675
+			$open_anchor,
676
+			$close_anchor
677
+		)
678
+		. '</p></div>';
679
+	}
680 680
 }
Please login to merge, or discard this patch.
PaymentMethods/PayPalCommerce/tools/fees/PartnerPaymentFees.php 1 patch
Indentation   +35 added lines, -35 removed lines patch added patch discarded remove patch
@@ -17,39 +17,39 @@
 block discarded – undo
17 17
  */
18 18
 class PartnerPaymentFees
19 19
 {
20
-    private PaymentProcessorFees $payment_processor_fees;
21
-
22
-
23
-    /**
24
-     * PartnerPaymentFees constructor.
25
-     *
26
-     * @param PaymentProcessorFees $payment_processor_fees
27
-     */
28
-    public function __construct(PaymentProcessorFees $payment_processor_fees)
29
-    {
30
-        $this->payment_processor_fees = $payment_processor_fees;
31
-    }
32
-
33
-
34
-    /**
35
-     * @param EE_Transaction $transaction
36
-     * @return float
37
-     * @throws Exception
38
-     */
39
-    public function getPartnerFee(EE_Transaction $transaction): float
40
-    {
41
-        $fee_rate = $this->payment_processor_fees->forPaymentMethod(PaymentProcessorFees::GATEWAY_PAYPAL);
42
-        if ($fee_rate <= 0) {
43
-            return 0;
44
-        }
45
-        // Don't count tax.
46
-        $total_remaining = $transaction->total() - $transaction->tax_total();
47
-        // If this is a partial payment, try to get a tax-free amount.
48
-        if ($transaction->paid() > 0) {
49
-            $paid_percent    = $transaction->paid() * 100 / $transaction->total();
50
-            $paid_tax        = ($transaction->tax_total() / 100) * $paid_percent;
51
-            $total_remaining = $transaction->remaining() - $paid_tax;
52
-        }
53
-        return CurrencyManager::normalizeValue(($total_remaining / 100) * $fee_rate);
54
-    }
20
+	private PaymentProcessorFees $payment_processor_fees;
21
+
22
+
23
+	/**
24
+	 * PartnerPaymentFees constructor.
25
+	 *
26
+	 * @param PaymentProcessorFees $payment_processor_fees
27
+	 */
28
+	public function __construct(PaymentProcessorFees $payment_processor_fees)
29
+	{
30
+		$this->payment_processor_fees = $payment_processor_fees;
31
+	}
32
+
33
+
34
+	/**
35
+	 * @param EE_Transaction $transaction
36
+	 * @return float
37
+	 * @throws Exception
38
+	 */
39
+	public function getPartnerFee(EE_Transaction $transaction): float
40
+	{
41
+		$fee_rate = $this->payment_processor_fees->forPaymentMethod(PaymentProcessorFees::GATEWAY_PAYPAL);
42
+		if ($fee_rate <= 0) {
43
+			return 0;
44
+		}
45
+		// Don't count tax.
46
+		$total_remaining = $transaction->total() - $transaction->tax_total();
47
+		// If this is a partial payment, try to get a tax-free amount.
48
+		if ($transaction->paid() > 0) {
49
+			$paid_percent    = $transaction->paid() * 100 / $transaction->total();
50
+			$paid_tax        = ($transaction->tax_total() / 100) * $paid_percent;
51
+			$total_remaining = $transaction->remaining() - $paid_tax;
52
+		}
53
+		return CurrencyManager::normalizeValue(($total_remaining / 100) * $fee_rate);
54
+	}
55 55
 }
Please login to merge, or discard this patch.
PaymentMethods/PayPalCommerce/tools/extra_meta/PayPalExtraMetaManager.php 2 patches
Indentation   +282 added lines, -282 removed lines patch added patch discarded remove patch
@@ -22,310 +22,310 @@
 block discarded – undo
22 22
  */
23 23
 class PayPalExtraMetaManager
24 24
 {
25
-    /**
26
-     * Get payment method option/extra meta
27
-     *
28
-     * @param EE_Payment_Method $paypal_pm
29
-     * @param string            $option_name
30
-     * @return mixed
31
-     */
32
-    public static function getPmOption(EE_Payment_Method $paypal_pm, string $option_name)
33
-    {
34
-        $pp_meta_data = self::extraMeta($paypal_pm);
35
-        $option_value = $pp_meta_data->getOption($option_name);
36
-        // Decrypt the encrypted options.
37
-        if (
38
-            $option_name === Domain::META_KEY_ACCESS_TOKEN
39
-            || $option_name === Domain::META_KEY_PARTNER_MERCHANT_ID
40
-            || $option_name === Domain::META_KEY_CLIENT_SECRET
41
-        ) {
42
-            $option_value = self::decryptString($option_value, $paypal_pm);
43
-        }
44
-        return $option_value;
45
-    }
25
+	/**
26
+	 * Get payment method option/extra meta
27
+	 *
28
+	 * @param EE_Payment_Method $paypal_pm
29
+	 * @param string            $option_name
30
+	 * @return mixed
31
+	 */
32
+	public static function getPmOption(EE_Payment_Method $paypal_pm, string $option_name)
33
+	{
34
+		$pp_meta_data = self::extraMeta($paypal_pm);
35
+		$option_value = $pp_meta_data->getOption($option_name);
36
+		// Decrypt the encrypted options.
37
+		if (
38
+			$option_name === Domain::META_KEY_ACCESS_TOKEN
39
+			|| $option_name === Domain::META_KEY_PARTNER_MERCHANT_ID
40
+			|| $option_name === Domain::META_KEY_CLIENT_SECRET
41
+		) {
42
+			$option_value = self::decryptString($option_value, $paypal_pm);
43
+		}
44
+		return $option_value;
45
+	}
46 46
 
47 47
 
48
-    /**
49
-     * Save payment method option/extra meta
50
-     *
51
-     * @param EE_Payment_Method $paypal_pm
52
-     * @param string            $option_name
53
-     * @param                   $option_value
54
-     * @return bool
55
-     */
56
-    public static function savePmOption(EE_Payment_Method $paypal_pm, string $option_name, $option_value): bool
57
-    {
58
-        $pp_meta_data = self::extraMeta($paypal_pm);
59
-        return $pp_meta_data->saveOption($option_name, $option_value);
60
-    }
48
+	/**
49
+	 * Save payment method option/extra meta
50
+	 *
51
+	 * @param EE_Payment_Method $paypal_pm
52
+	 * @param string            $option_name
53
+	 * @param                   $option_value
54
+	 * @return bool
55
+	 */
56
+	public static function savePmOption(EE_Payment_Method $paypal_pm, string $option_name, $option_value): bool
57
+	{
58
+		$pp_meta_data = self::extraMeta($paypal_pm);
59
+		return $pp_meta_data->saveOption($option_name, $option_value);
60
+	}
61 61
 
62 62
 
63
-    /**
64
-     * Save a list of payment method options/extra meta.
65
-     *
66
-     * @param EE_Payment_Method $paypal_pm
67
-     * @param array             $options_list
68
-     * @return bool
69
-     */
70
-    public static function savePmOptions(EE_Payment_Method $paypal_pm, array $options_list): bool
71
-    {
72
-        $pp_meta_data = self::extraMeta($paypal_pm);
73
-        return $pp_meta_data->saveBatch($options_list);
74
-    }
63
+	/**
64
+	 * Save a list of payment method options/extra meta.
65
+	 *
66
+	 * @param EE_Payment_Method $paypal_pm
67
+	 * @param array             $options_list
68
+	 * @return bool
69
+	 */
70
+	public static function savePmOptions(EE_Payment_Method $paypal_pm, array $options_list): bool
71
+	{
72
+		$pp_meta_data = self::extraMeta($paypal_pm);
73
+		return $pp_meta_data->saveBatch($options_list);
74
+	}
75 75
 
76 76
 
77
-    /**
78
-     * Delete payment method option/extra meta
79
-     *
80
-     * @param EE_Payment_Method $paypal_pm
81
-     * @param string            $option_name
82
-     * @return bool
83
-     */
84
-    public static function deletePmOption(EE_Payment_Method $paypal_pm, string $option_name): bool
85
-        {
86
-        $pp_meta_data = self::extraMeta($paypal_pm);
87
-        return $pp_meta_data->deleteOption($option_name);
88
-    }
77
+	/**
78
+	 * Delete payment method option/extra meta
79
+	 *
80
+	 * @param EE_Payment_Method $paypal_pm
81
+	 * @param string            $option_name
82
+	 * @return bool
83
+	 */
84
+	public static function deletePmOption(EE_Payment_Method $paypal_pm, string $option_name): bool
85
+		{
86
+		$pp_meta_data = self::extraMeta($paypal_pm);
87
+		return $pp_meta_data->deleteOption($option_name);
88
+	}
89 89
 
90 90
 
91
-    /**
92
-     * Get all options for payment method.
93
-     *
94
-     * @param EE_Payment_Method $paypal_pm
95
-     * @return array|bool
96
-     */
97
-    public static function getAllData(EE_Payment_Method $paypal_pm)
98
-    {
99
-        $pp_meta_data = self::extraMeta($paypal_pm);
100
-        return $pp_meta_data->getMetaData();
101
-    }
91
+	/**
92
+	 * Get all options for payment method.
93
+	 *
94
+	 * @param EE_Payment_Method $paypal_pm
95
+	 * @return array|bool
96
+	 */
97
+	public static function getAllData(EE_Payment_Method $paypal_pm)
98
+	{
99
+		$pp_meta_data = self::extraMeta($paypal_pm);
100
+		return $pp_meta_data->getMetaData();
101
+	}
102 102
 
103 103
 
104
-    /**
105
-     * Delete all options for this payment method.
106
-     *
107
-     * @param EE_Payment_Method $paypal_pm
108
-     * @return bool
109
-     */
110
-    public static function deleteAllData(EE_Payment_Method $paypal_pm): bool
111
-    {
112
-        $pp_meta_data = self::extraMeta($paypal_pm);
113
-        return $pp_meta_data->deleteMetaData();
114
-    }
104
+	/**
105
+	 * Delete all options for this payment method.
106
+	 *
107
+	 * @param EE_Payment_Method $paypal_pm
108
+	 * @return bool
109
+	 */
110
+	public static function deleteAllData(EE_Payment_Method $paypal_pm): bool
111
+	{
112
+		$pp_meta_data = self::extraMeta($paypal_pm);
113
+		return $pp_meta_data->deleteMetaData();
114
+	}
115 115
 
116 116
 
117
-    /**
118
-     * Save the debug mode option if it changed.
119
-     *
120
-     * @param EE_Payment_Method $paypal_pm
121
-     * @param array             $request_data
122
-     * @return bool             Updated or not.
123
-     */
124
-    public static function updateDebugMode(EE_Payment_Method $paypal_pm, array $request_data): bool
125
-    {
126
-        if (
127
-            isset($request_data['sandbox_mode'])
128
-            && in_array($request_data['sandbox_mode'], ['0', '1'], true)
129
-            && $paypal_pm->debug_mode() !== (bool) $request_data['sandbox_mode']
130
-        ) {
131
-            try {
132
-                $paypal_pm->save(['PMD_debug_mode' => (bool) $request_data['sandbox_mode']]);
133
-            } catch (EE_Error $e) {
134
-                $err_msg = sprintf(
135
-                    esc_html__('Note, debug mode not saved ! %1$s', 'event_espresso'),
136
-                    $e->getMessage()
137
-                );
138
-                PayPalLogger::errorLog($err_msg, $request_data, $paypal_pm);
139
-                return false;
140
-            }
141
-             return true;
142
-        }
143
-        return false;
144
-    }
117
+	/**
118
+	 * Save the debug mode option if it changed.
119
+	 *
120
+	 * @param EE_Payment_Method $paypal_pm
121
+	 * @param array             $request_data
122
+	 * @return bool             Updated or not.
123
+	 */
124
+	public static function updateDebugMode(EE_Payment_Method $paypal_pm, array $request_data): bool
125
+	{
126
+		if (
127
+			isset($request_data['sandbox_mode'])
128
+			&& in_array($request_data['sandbox_mode'], ['0', '1'], true)
129
+			&& $paypal_pm->debug_mode() !== (bool) $request_data['sandbox_mode']
130
+		) {
131
+			try {
132
+				$paypal_pm->save(['PMD_debug_mode' => (bool) $request_data['sandbox_mode']]);
133
+			} catch (EE_Error $e) {
134
+				$err_msg = sprintf(
135
+					esc_html__('Note, debug mode not saved ! %1$s', 'event_espresso'),
136
+					$e->getMessage()
137
+				);
138
+				PayPalLogger::errorLog($err_msg, $request_data, $paypal_pm);
139
+				return false;
140
+			}
141
+			 return true;
142
+		}
143
+		return false;
144
+	}
145 145
 
146 146
 
147
-    /**
148
-     * Save partner access token and parameters.
149
-     *
150
-     * @param EE_Payment_Method $paypal_pm
151
-     * @param array             $response
152
-     * @return bool
153
-     */
154
-    public static function savePartnerAccessToken(EE_Payment_Method $paypal_pm, array $response): bool
155
-    {
156
-        $paypal_data         = [];
157
-        $expected_parameters = [
158
-            Domain::META_KEY_ACCESS_TOKEN,
159
-            Domain::META_KEY_TOKEN_EXPIRES_IN,
160
-            Domain::META_KEY_APP_ID,
161
-            Domain::META_KEY_PARTNER_CLIENT_ID,
162
-            Domain::META_KEY_PARTNER_MERCHANT_ID,
163
-            Domain::META_KEY_BN_CODE,
164
-        ];
165
-        foreach ($expected_parameters as $api_key) {
166
-            if (! isset($response[ $api_key ])) {
167
-                // Don't want to try saving data that doesn't exist.
168
-                continue;
169
-            }
170
-            try {
171
-                switch ($api_key) {
172
-                    case Domain::META_KEY_ACCESS_TOKEN:
173
-                    case Domain::META_KEY_PARTNER_MERCHANT_ID:
174
-                        $paypal_data[ $api_key ] = self::encryptString($response[ $api_key ], $paypal_pm);
175
-                        break;
176
-                    case Domain::META_KEY_TOKEN_EXPIRES_IN:
177
-                        $paypal_data[ $api_key ] = time() + (int) sanitize_key($response[ $api_key ]);
178
-                        break;
179
-                    default:
180
-                        $paypal_data[ $api_key ] = sanitize_text_field($response[ $api_key ]);
181
-                }
182
-            } catch (Exception $exception) {
183
-                PayPalLogger::errorLog($exception->getMessage(), $response, $paypal_pm);
184
-                return false;
185
-            }
186
-        }
187
-        return self::savePmOptions($paypal_pm, $paypal_data);
188
-    }
147
+	/**
148
+	 * Save partner access token and parameters.
149
+	 *
150
+	 * @param EE_Payment_Method $paypal_pm
151
+	 * @param array             $response
152
+	 * @return bool
153
+	 */
154
+	public static function savePartnerAccessToken(EE_Payment_Method $paypal_pm, array $response): bool
155
+	{
156
+		$paypal_data         = [];
157
+		$expected_parameters = [
158
+			Domain::META_KEY_ACCESS_TOKEN,
159
+			Domain::META_KEY_TOKEN_EXPIRES_IN,
160
+			Domain::META_KEY_APP_ID,
161
+			Domain::META_KEY_PARTNER_CLIENT_ID,
162
+			Domain::META_KEY_PARTNER_MERCHANT_ID,
163
+			Domain::META_KEY_BN_CODE,
164
+		];
165
+		foreach ($expected_parameters as $api_key) {
166
+			if (! isset($response[ $api_key ])) {
167
+				// Don't want to try saving data that doesn't exist.
168
+				continue;
169
+			}
170
+			try {
171
+				switch ($api_key) {
172
+					case Domain::META_KEY_ACCESS_TOKEN:
173
+					case Domain::META_KEY_PARTNER_MERCHANT_ID:
174
+						$paypal_data[ $api_key ] = self::encryptString($response[ $api_key ], $paypal_pm);
175
+						break;
176
+					case Domain::META_KEY_TOKEN_EXPIRES_IN:
177
+						$paypal_data[ $api_key ] = time() + (int) sanitize_key($response[ $api_key ]);
178
+						break;
179
+					default:
180
+						$paypal_data[ $api_key ] = sanitize_text_field($response[ $api_key ]);
181
+				}
182
+			} catch (Exception $exception) {
183
+				PayPalLogger::errorLog($exception->getMessage(), $response, $paypal_pm);
184
+				return false;
185
+			}
186
+		}
187
+		return self::savePmOptions($paypal_pm, $paypal_data);
188
+	}
189 189
 
190 190
 
191
-    /**
192
-     * Save merchant/seller API credentials.
193
-     *
194
-     * @param EE_Payment_Method $paypal_pm
195
-     * @param array             $response
196
-     * @return bool
197
-     */
198
-    public static function saveSellerApiCredentials(EE_Payment_Method $paypal_pm, array $response): bool
199
-    {
200
-        $api_credentials     = [];
201
-        $expected_parameters = [
202
-            Domain::META_KEY_SELLER_MERCHANT_ID,
203
-        ];
204
-        foreach ($expected_parameters as $api_key) {
205
-            if (! isset($response[ $api_key ])) {
206
-                // Don't want to try saving data that doesn't exist.
207
-                continue;
208
-            }
209
-            $api_credentials[ $api_key ] = $response[ $api_key ];
210
-        }
211
-        return self::savePmOptions($paypal_pm, $api_credentials);
212
-    }
191
+	/**
192
+	 * Save merchant/seller API credentials.
193
+	 *
194
+	 * @param EE_Payment_Method $paypal_pm
195
+	 * @param array             $response
196
+	 * @return bool
197
+	 */
198
+	public static function saveSellerApiCredentials(EE_Payment_Method $paypal_pm, array $response): bool
199
+	{
200
+		$api_credentials     = [];
201
+		$expected_parameters = [
202
+			Domain::META_KEY_SELLER_MERCHANT_ID,
203
+		];
204
+		foreach ($expected_parameters as $api_key) {
205
+			if (! isset($response[ $api_key ])) {
206
+				// Don't want to try saving data that doesn't exist.
207
+				continue;
208
+			}
209
+			$api_credentials[ $api_key ] = $response[ $api_key ];
210
+		}
211
+		return self::savePmOptions($paypal_pm, $api_credentials);
212
+	}
213 213
 
214 214
 
215
-    /**
216
-     * Save other payment method related settings from a data array.
217
-     *
218
-     * @param EE_Payment_Method $paypal_pm
219
-     * @param array             $data
220
-     * @return bool
221
-     * @throws EE_Error
222
-     * @throws ReflectionException
223
-     */
224
-    public static function parseAndSaveOptions(EE_Payment_Method $paypal_pm, array $data): bool
225
-    {
226
-        $allowed_checkout_type = 'express_checkout';
227
-        // Note, although PayPal shows that this should include PPCP_CUSTOM or EXPRESS_CHECKOUT only,
228
-        // in reality, it will also include other products like MOBILE_PAYMENT_ACCEPTANCE etc.
229
-        if (! empty($data['response']['products'][0]['name']) && is_array($data['response']['products'])) {
230
-            foreach ($data['response']['products'] as $product) {
231
-                if (str_contains($product['name'], 'PPCP')) {
232
-                    // This merchant has PPCP in the products list, so we can enable both (all) checkout types.
233
-                    $allowed_checkout_type = 'all';
234
-                    break;
235
-                }
236
-            }
237
-        }
238
-        // Set the Checkout type (a PM option), just in case merchant doesn't save PM options manually.
239
-        $checkout_type = $paypal_pm->get_extra_meta(Domain::META_KEY_CHECKOUT_TYPE, true, false);
240
-        if (! $checkout_type) {
241
-            $paypal_pm->update_extra_meta(Domain::META_KEY_CHECKOUT_TYPE, $allowed_checkout_type);
242
-        }
243
-        // Save the scopes that were authorized.
244
-        if (! empty($data['response']['oauth_integrations'][0]['oauth_third_party'][0]['scopes'])) {
245
-            $scopes = [];
246
-            foreach ($data['response']['oauth_integrations'][0]['oauth_third_party'][0]['scopes'] as $scope) {
247
-                // Scope will look like: 'https://uri.paypal.com/services/payments/partnerfee'
248
-                $split       = explode('/', $scope);
249
-                $split_count = count($split);
250
-                // Get the scope itself.
251
-                $scopes    []= $split[ $split_count - 1 ];
252
-            }
253
-            if (empty($scopes)) {
254
-                // In case the there's a change in how scopes come in just save the list.
255
-                $scopes = $data['response']['oauth_integrations'][0]['oauth_third_party'][0]['scopes'];
256
-            }
257
-            PayPalExtraMetaManager::savePmOption($paypal_pm, Domain::META_KEY_AUTHORIZED_SCOPES, $scopes);
258
-        }
259
-        return PayPalExtraMetaManager::savePmOption(
260
-            $paypal_pm,
261
-            Domain::META_KEY_ALLOWED_CHECKOUT_TYPE,
262
-            $allowed_checkout_type
263
-        );
264
-    }
215
+	/**
216
+	 * Save other payment method related settings from a data array.
217
+	 *
218
+	 * @param EE_Payment_Method $paypal_pm
219
+	 * @param array             $data
220
+	 * @return bool
221
+	 * @throws EE_Error
222
+	 * @throws ReflectionException
223
+	 */
224
+	public static function parseAndSaveOptions(EE_Payment_Method $paypal_pm, array $data): bool
225
+	{
226
+		$allowed_checkout_type = 'express_checkout';
227
+		// Note, although PayPal shows that this should include PPCP_CUSTOM or EXPRESS_CHECKOUT only,
228
+		// in reality, it will also include other products like MOBILE_PAYMENT_ACCEPTANCE etc.
229
+		if (! empty($data['response']['products'][0]['name']) && is_array($data['response']['products'])) {
230
+			foreach ($data['response']['products'] as $product) {
231
+				if (str_contains($product['name'], 'PPCP')) {
232
+					// This merchant has PPCP in the products list, so we can enable both (all) checkout types.
233
+					$allowed_checkout_type = 'all';
234
+					break;
235
+				}
236
+			}
237
+		}
238
+		// Set the Checkout type (a PM option), just in case merchant doesn't save PM options manually.
239
+		$checkout_type = $paypal_pm->get_extra_meta(Domain::META_KEY_CHECKOUT_TYPE, true, false);
240
+		if (! $checkout_type) {
241
+			$paypal_pm->update_extra_meta(Domain::META_KEY_CHECKOUT_TYPE, $allowed_checkout_type);
242
+		}
243
+		// Save the scopes that were authorized.
244
+		if (! empty($data['response']['oauth_integrations'][0]['oauth_third_party'][0]['scopes'])) {
245
+			$scopes = [];
246
+			foreach ($data['response']['oauth_integrations'][0]['oauth_third_party'][0]['scopes'] as $scope) {
247
+				// Scope will look like: 'https://uri.paypal.com/services/payments/partnerfee'
248
+				$split       = explode('/', $scope);
249
+				$split_count = count($split);
250
+				// Get the scope itself.
251
+				$scopes    []= $split[ $split_count - 1 ];
252
+			}
253
+			if (empty($scopes)) {
254
+				// In case the there's a change in how scopes come in just save the list.
255
+				$scopes = $data['response']['oauth_integrations'][0]['oauth_third_party'][0]['scopes'];
256
+			}
257
+			PayPalExtraMetaManager::savePmOption($paypal_pm, Domain::META_KEY_AUTHORIZED_SCOPES, $scopes);
258
+		}
259
+		return PayPalExtraMetaManager::savePmOption(
260
+			$paypal_pm,
261
+			Domain::META_KEY_ALLOWED_CHECKOUT_TYPE,
262
+			$allowed_checkout_type
263
+		);
264
+	}
265 265
 
266 266
 
267
-    /**
268
-     * Get PayPal extra meta helper.
269
-     *
270
-     * @param EE_Payment_Method $paypal_pm
271
-     * @return PayPalExtraMeta
272
-     * @throws EE_Error
273
-     * @throws ReflectionException
274
-     */
275
-    public static function extraMeta(EE_Payment_Method $paypal_pm): PayPalExtraMeta
276
-    {
277
-        return new PayPalExtraMeta($paypal_pm);
278
-    }
267
+	/**
268
+	 * Get PayPal extra meta helper.
269
+	 *
270
+	 * @param EE_Payment_Method $paypal_pm
271
+	 * @return PayPalExtraMeta
272
+	 * @throws EE_Error
273
+	 * @throws ReflectionException
274
+	 */
275
+	public static function extraMeta(EE_Payment_Method $paypal_pm): PayPalExtraMeta
276
+	{
277
+		return new PayPalExtraMeta($paypal_pm);
278
+	}
279 279
 
280 280
 
281
-    /**
282
-     * Encrypt a text field.
283
-     *
284
-     * @param string            $text
285
-     * @param EE_Payment_Method $paypal_pm
286
-     * @return string|null
287
-     * @throws EE_Error
288
-     * @throws ReflectionException
289
-     */
290
-    public static function encryptString(string $text, EE_Payment_Method $paypal_pm): ?string
291
-    {
292
-        // We sure we are getting something ?
293
-        if (! $text) {
294
-            return $text;
295
-        }
296
-        // Do encrypt.
297
-        $encryptor      = LoaderFactory::getLoader()->getShared(OpenSSLEncryption::class, [new Base64Encoder()]);
298
-        $sanitized_text = sanitize_text_field($text);
299
-        $key_identifier = $paypal_pm->debug_mode()
300
-            ? PPCommerceEncryptionKeyManager::SANDBOX_ENCRYPTION_KEY_ID
301
-            : PPCommerceEncryptionKeyManager::PRODUCTION_ENCRYPTION_KEY_ID;
302
-        return $encryptor->encrypt($sanitized_text, $key_identifier);
303
-    }
281
+	/**
282
+	 * Encrypt a text field.
283
+	 *
284
+	 * @param string            $text
285
+	 * @param EE_Payment_Method $paypal_pm
286
+	 * @return string|null
287
+	 * @throws EE_Error
288
+	 * @throws ReflectionException
289
+	 */
290
+	public static function encryptString(string $text, EE_Payment_Method $paypal_pm): ?string
291
+	{
292
+		// We sure we are getting something ?
293
+		if (! $text) {
294
+			return $text;
295
+		}
296
+		// Do encrypt.
297
+		$encryptor      = LoaderFactory::getLoader()->getShared(OpenSSLEncryption::class, [new Base64Encoder()]);
298
+		$sanitized_text = sanitize_text_field($text);
299
+		$key_identifier = $paypal_pm->debug_mode()
300
+			? PPCommerceEncryptionKeyManager::SANDBOX_ENCRYPTION_KEY_ID
301
+			: PPCommerceEncryptionKeyManager::PRODUCTION_ENCRYPTION_KEY_ID;
302
+		return $encryptor->encrypt($sanitized_text, $key_identifier);
303
+	}
304 304
 
305 305
 
306
-    /**
307
-     * Decrypt a string.
308
-     *
309
-     * @param string            $text
310
-     * @param EE_Payment_Method $paypal_pm
311
-     * @return string
312
-     */
313
-    public static function decryptString(string $text, EE_Payment_Method $paypal_pm): string
314
-    {
315
-        // Are we even getting something ?
316
-        if (! $text) {
317
-            return $text;
318
-        }
319
-        // Try decrypting.
320
-        try {
321
-            $encryptor      = LoaderFactory::getLoader()->getShared(OpenSSLEncryption::class, [new Base64Encoder()]);
322
-            $key_identifier = $paypal_pm->debug_mode()
323
-                ? PPCommerceEncryptionKeyManager::SANDBOX_ENCRYPTION_KEY_ID
324
-                : PPCommerceEncryptionKeyManager::PRODUCTION_ENCRYPTION_KEY_ID;
325
-            $decrypted      = $encryptor->decrypt($text, $key_identifier);
326
-        } catch (Exception $e) {
327
-            return $text;
328
-        }
329
-        return $decrypted ?? $text;
330
-    }
306
+	/**
307
+	 * Decrypt a string.
308
+	 *
309
+	 * @param string            $text
310
+	 * @param EE_Payment_Method $paypal_pm
311
+	 * @return string
312
+	 */
313
+	public static function decryptString(string $text, EE_Payment_Method $paypal_pm): string
314
+	{
315
+		// Are we even getting something ?
316
+		if (! $text) {
317
+			return $text;
318
+		}
319
+		// Try decrypting.
320
+		try {
321
+			$encryptor      = LoaderFactory::getLoader()->getShared(OpenSSLEncryption::class, [new Base64Encoder()]);
322
+			$key_identifier = $paypal_pm->debug_mode()
323
+				? PPCommerceEncryptionKeyManager::SANDBOX_ENCRYPTION_KEY_ID
324
+				: PPCommerceEncryptionKeyManager::PRODUCTION_ENCRYPTION_KEY_ID;
325
+			$decrypted      = $encryptor->decrypt($text, $key_identifier);
326
+		} catch (Exception $e) {
327
+			return $text;
328
+		}
329
+		return $decrypted ?? $text;
330
+	}
331 331
 }
Please login to merge, or discard this patch.
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -163,7 +163,7 @@  discard block
 block discarded – undo
163 163
             Domain::META_KEY_BN_CODE,
164 164
         ];
165 165
         foreach ($expected_parameters as $api_key) {
166
-            if (! isset($response[ $api_key ])) {
166
+            if ( ! isset($response[$api_key])) {
167 167
                 // Don't want to try saving data that doesn't exist.
168 168
                 continue;
169 169
             }
@@ -171,13 +171,13 @@  discard block
 block discarded – undo
171 171
                 switch ($api_key) {
172 172
                     case Domain::META_KEY_ACCESS_TOKEN:
173 173
                     case Domain::META_KEY_PARTNER_MERCHANT_ID:
174
-                        $paypal_data[ $api_key ] = self::encryptString($response[ $api_key ], $paypal_pm);
174
+                        $paypal_data[$api_key] = self::encryptString($response[$api_key], $paypal_pm);
175 175
                         break;
176 176
                     case Domain::META_KEY_TOKEN_EXPIRES_IN:
177
-                        $paypal_data[ $api_key ] = time() + (int) sanitize_key($response[ $api_key ]);
177
+                        $paypal_data[$api_key] = time() + (int) sanitize_key($response[$api_key]);
178 178
                         break;
179 179
                     default:
180
-                        $paypal_data[ $api_key ] = sanitize_text_field($response[ $api_key ]);
180
+                        $paypal_data[$api_key] = sanitize_text_field($response[$api_key]);
181 181
                 }
182 182
             } catch (Exception $exception) {
183 183
                 PayPalLogger::errorLog($exception->getMessage(), $response, $paypal_pm);
@@ -202,11 +202,11 @@  discard block
 block discarded – undo
202 202
             Domain::META_KEY_SELLER_MERCHANT_ID,
203 203
         ];
204 204
         foreach ($expected_parameters as $api_key) {
205
-            if (! isset($response[ $api_key ])) {
205
+            if ( ! isset($response[$api_key])) {
206 206
                 // Don't want to try saving data that doesn't exist.
207 207
                 continue;
208 208
             }
209
-            $api_credentials[ $api_key ] = $response[ $api_key ];
209
+            $api_credentials[$api_key] = $response[$api_key];
210 210
         }
211 211
         return self::savePmOptions($paypal_pm, $api_credentials);
212 212
     }
@@ -226,7 +226,7 @@  discard block
 block discarded – undo
226 226
         $allowed_checkout_type = 'express_checkout';
227 227
         // Note, although PayPal shows that this should include PPCP_CUSTOM or EXPRESS_CHECKOUT only,
228 228
         // in reality, it will also include other products like MOBILE_PAYMENT_ACCEPTANCE etc.
229
-        if (! empty($data['response']['products'][0]['name']) && is_array($data['response']['products'])) {
229
+        if ( ! empty($data['response']['products'][0]['name']) && is_array($data['response']['products'])) {
230 230
             foreach ($data['response']['products'] as $product) {
231 231
                 if (str_contains($product['name'], 'PPCP')) {
232 232
                     // This merchant has PPCP in the products list, so we can enable both (all) checkout types.
@@ -237,18 +237,18 @@  discard block
 block discarded – undo
237 237
         }
238 238
         // Set the Checkout type (a PM option), just in case merchant doesn't save PM options manually.
239 239
         $checkout_type = $paypal_pm->get_extra_meta(Domain::META_KEY_CHECKOUT_TYPE, true, false);
240
-        if (! $checkout_type) {
240
+        if ( ! $checkout_type) {
241 241
             $paypal_pm->update_extra_meta(Domain::META_KEY_CHECKOUT_TYPE, $allowed_checkout_type);
242 242
         }
243 243
         // Save the scopes that were authorized.
244
-        if (! empty($data['response']['oauth_integrations'][0]['oauth_third_party'][0]['scopes'])) {
244
+        if ( ! empty($data['response']['oauth_integrations'][0]['oauth_third_party'][0]['scopes'])) {
245 245
             $scopes = [];
246 246
             foreach ($data['response']['oauth_integrations'][0]['oauth_third_party'][0]['scopes'] as $scope) {
247 247
                 // Scope will look like: 'https://uri.paypal.com/services/payments/partnerfee'
248 248
                 $split       = explode('/', $scope);
249 249
                 $split_count = count($split);
250 250
                 // Get the scope itself.
251
-                $scopes    []= $split[ $split_count - 1 ];
251
+                $scopes    [] = $split[$split_count - 1];
252 252
             }
253 253
             if (empty($scopes)) {
254 254
                 // In case the there's a change in how scopes come in just save the list.
@@ -290,7 +290,7 @@  discard block
 block discarded – undo
290 290
     public static function encryptString(string $text, EE_Payment_Method $paypal_pm): ?string
291 291
     {
292 292
         // We sure we are getting something ?
293
-        if (! $text) {
293
+        if ( ! $text) {
294 294
             return $text;
295 295
         }
296 296
         // Do encrypt.
@@ -313,7 +313,7 @@  discard block
 block discarded – undo
313 313
     public static function decryptString(string $text, EE_Payment_Method $paypal_pm): string
314 314
     {
315 315
         // Are we even getting something ?
316
-        if (! $text) {
316
+        if ( ! $text) {
317 317
             return $text;
318 318
         }
319 319
         // Try decrypting.
Please login to merge, or discard this patch.
PaymentMethods/PayPalCommerce/tools/extra_meta/PayPalExtraMeta.php 1 patch
Indentation   +158 added lines, -158 removed lines patch added patch discarded remove patch
@@ -18,162 +18,162 @@
 block discarded – undo
18 18
  */
19 19
 class PayPalExtraMeta
20 20
 {
21
-    /**
22
-     * Payment method instance.
23
-     *
24
-     * @var EE_Payment_Method
25
-     */
26
-    public $pm;
27
-
28
-    /**
29
-     * Metadata key.
30
-     *
31
-     * @var EE_Payment_Method
32
-     */
33
-    public $metadata_key;
34
-
35
-
36
-    /**
37
-     * Class constructor.
38
-     *
39
-     * @param EE_Payment_Method $pm_instance
40
-     * @throws EE_Error
41
-     * @throws ReflectionException
42
-     */
43
-    public function __construct(EE_Payment_Method $pm_instance)
44
-    {
45
-        $this->pm           = $pm_instance;
46
-        $this->metadata_key = $pm_instance->debug_mode()
47
-            ? Domain::META_KEY_PAYPAL_DATA_SANDBOX
48
-            : Domain::META_KEY_PAYPAL_DATA;
49
-    }
50
-
51
-
52
-    /**
53
-     * Save/update the provided data to the PM extra meta.
54
-     *
55
-     * @param array $data
56
-     * @return bool
57
-     */
58
-    public function saveBatch(array $data): bool
59
-    {
60
-        // Update the PM data.
61
-        try {
62
-            $paypal_data  = $this->pm->get_extra_meta($this->metadata_key, true, []);
63
-            $data_to_save = array_replace_recursive($paypal_data, $data);
64
-            $this->saveMetaData($data_to_save);
65
-        } catch (Exception $e) {
66
-            $err_msg = sprintf(
67
-                esc_html__('Could not save merchant data. %1$s', 'event_espresso'),
68
-                $e->getMessage()
69
-            );
70
-            PayPalLogger::errorLog($err_msg, $data, $this->pm);
71
-            return false;
72
-        }
73
-        return true;
74
-    }
75
-
76
-
77
-    /**
78
-     * Get PM extra meta by meta name/option.
79
-     *
80
-     * @param string $option_name
81
-     * @return mixed
82
-     */
83
-    public function getOption(string $option_name)
84
-    {
85
-        $meta_data = $this->getMetaData();
86
-        return $meta_data[ $option_name ] ?? false;
87
-    }
88
-
89
-
90
-    /**
91
-     * Get PM metadata.
92
-     * Return the metadata array if all good. False otherwise.
93
-     *
94
-     * @return array
95
-     */
96
-    public function getMetaData(): array
97
-    {
98
-        try {
99
-            return (array) $this->pm->get_extra_meta($this->metadata_key, true, []);
100
-        } catch (EE_Error | ReflectionException $e) {
101
-            $err_msg = sprintf(
102
-                esc_html__('Error getting the PM meta data: %1$s', 'event_espresso'),
103
-                $e->getMessage()
104
-            );
105
-            PayPalLogger::errorLog($err_msg, [], $this->pm);
106
-            return [];
107
-        }
108
-    }
109
-
110
-
111
-    /**
112
-     * Save/update the provided option to the PM extra meta.
113
-     *
114
-     * @param string $name
115
-     * @param        $value
116
-     * @return bool
117
-     */
118
-    public function saveOption(string $name, $value): bool
119
-    {
120
-        $meta_data = $this->getMetaData();
121
-        if (! $meta_data) {
122
-            $meta_data = [];
123
-        }
124
-        $meta_data[ $name ] = $value;
125
-        return $this->saveMetaData($meta_data);
126
-    }
127
-
128
-
129
-    /**
130
-     * Save/update the PM extra meta.
131
-     *
132
-     * @param array $data
133
-     * @return bool
134
-     */
135
-    public function saveMetaData(array $data): bool
136
-    {
137
-        try {
138
-            $this->pm->update_extra_meta($this->metadata_key, $data);
139
-        } catch (Exception $e) {
140
-            return false;
141
-        }
142
-        return true;
143
-    }
144
-
145
-
146
-    /**
147
-     * Delete PM option.
148
-     *
149
-     * @param string $name
150
-     * @return bool
151
-     */
152
-    public function deleteOption(string $name): bool
153
-    {
154
-        $meta_data = $this->getMetaData();
155
-        if (! $meta_data) {
156
-            return false;
157
-        }
158
-        unset($meta_data[ $name ]);
159
-        return $this->saveMetaData($meta_data);
160
-    }
161
-
162
-
163
-    /**
164
-     * Delete the PM extra meta.
165
-     *
166
-     * @return bool
167
-     */
168
-    public function deleteMetaData(): bool
169
-    {
170
-        try {
171
-            // Live and sandbox data.
172
-            $this->pm->delete_extra_meta(Domain::META_KEY_PAYPAL_DATA);
173
-            $this->pm->delete_extra_meta(Domain::META_KEY_PAYPAL_DATA_SANDBOX);
174
-        } catch (Exception $e) {
175
-            return false;
176
-        }
177
-        return true;
178
-    }
21
+	/**
22
+	 * Payment method instance.
23
+	 *
24
+	 * @var EE_Payment_Method
25
+	 */
26
+	public $pm;
27
+
28
+	/**
29
+	 * Metadata key.
30
+	 *
31
+	 * @var EE_Payment_Method
32
+	 */
33
+	public $metadata_key;
34
+
35
+
36
+	/**
37
+	 * Class constructor.
38
+	 *
39
+	 * @param EE_Payment_Method $pm_instance
40
+	 * @throws EE_Error
41
+	 * @throws ReflectionException
42
+	 */
43
+	public function __construct(EE_Payment_Method $pm_instance)
44
+	{
45
+		$this->pm           = $pm_instance;
46
+		$this->metadata_key = $pm_instance->debug_mode()
47
+			? Domain::META_KEY_PAYPAL_DATA_SANDBOX
48
+			: Domain::META_KEY_PAYPAL_DATA;
49
+	}
50
+
51
+
52
+	/**
53
+	 * Save/update the provided data to the PM extra meta.
54
+	 *
55
+	 * @param array $data
56
+	 * @return bool
57
+	 */
58
+	public function saveBatch(array $data): bool
59
+	{
60
+		// Update the PM data.
61
+		try {
62
+			$paypal_data  = $this->pm->get_extra_meta($this->metadata_key, true, []);
63
+			$data_to_save = array_replace_recursive($paypal_data, $data);
64
+			$this->saveMetaData($data_to_save);
65
+		} catch (Exception $e) {
66
+			$err_msg = sprintf(
67
+				esc_html__('Could not save merchant data. %1$s', 'event_espresso'),
68
+				$e->getMessage()
69
+			);
70
+			PayPalLogger::errorLog($err_msg, $data, $this->pm);
71
+			return false;
72
+		}
73
+		return true;
74
+	}
75
+
76
+
77
+	/**
78
+	 * Get PM extra meta by meta name/option.
79
+	 *
80
+	 * @param string $option_name
81
+	 * @return mixed
82
+	 */
83
+	public function getOption(string $option_name)
84
+	{
85
+		$meta_data = $this->getMetaData();
86
+		return $meta_data[ $option_name ] ?? false;
87
+	}
88
+
89
+
90
+	/**
91
+	 * Get PM metadata.
92
+	 * Return the metadata array if all good. False otherwise.
93
+	 *
94
+	 * @return array
95
+	 */
96
+	public function getMetaData(): array
97
+	{
98
+		try {
99
+			return (array) $this->pm->get_extra_meta($this->metadata_key, true, []);
100
+		} catch (EE_Error | ReflectionException $e) {
101
+			$err_msg = sprintf(
102
+				esc_html__('Error getting the PM meta data: %1$s', 'event_espresso'),
103
+				$e->getMessage()
104
+			);
105
+			PayPalLogger::errorLog($err_msg, [], $this->pm);
106
+			return [];
107
+		}
108
+	}
109
+
110
+
111
+	/**
112
+	 * Save/update the provided option to the PM extra meta.
113
+	 *
114
+	 * @param string $name
115
+	 * @param        $value
116
+	 * @return bool
117
+	 */
118
+	public function saveOption(string $name, $value): bool
119
+	{
120
+		$meta_data = $this->getMetaData();
121
+		if (! $meta_data) {
122
+			$meta_data = [];
123
+		}
124
+		$meta_data[ $name ] = $value;
125
+		return $this->saveMetaData($meta_data);
126
+	}
127
+
128
+
129
+	/**
130
+	 * Save/update the PM extra meta.
131
+	 *
132
+	 * @param array $data
133
+	 * @return bool
134
+	 */
135
+	public function saveMetaData(array $data): bool
136
+	{
137
+		try {
138
+			$this->pm->update_extra_meta($this->metadata_key, $data);
139
+		} catch (Exception $e) {
140
+			return false;
141
+		}
142
+		return true;
143
+	}
144
+
145
+
146
+	/**
147
+	 * Delete PM option.
148
+	 *
149
+	 * @param string $name
150
+	 * @return bool
151
+	 */
152
+	public function deleteOption(string $name): bool
153
+	{
154
+		$meta_data = $this->getMetaData();
155
+		if (! $meta_data) {
156
+			return false;
157
+		}
158
+		unset($meta_data[ $name ]);
159
+		return $this->saveMetaData($meta_data);
160
+	}
161
+
162
+
163
+	/**
164
+	 * Delete the PM extra meta.
165
+	 *
166
+	 * @return bool
167
+	 */
168
+	public function deleteMetaData(): bool
169
+	{
170
+		try {
171
+			// Live and sandbox data.
172
+			$this->pm->delete_extra_meta(Domain::META_KEY_PAYPAL_DATA);
173
+			$this->pm->delete_extra_meta(Domain::META_KEY_PAYPAL_DATA_SANDBOX);
174
+		} catch (Exception $e) {
175
+			return false;
176
+		}
177
+		return true;
178
+	}
179 179
 }
Please login to merge, or discard this patch.
PaymentMethods/PayPalCommerce/PayPalCommerce.php 1 patch
Indentation   +65 added lines, -65 removed lines patch added patch discarded remove patch
@@ -22,76 +22,76 @@
 block discarded – undo
22 22
  */
23 23
 class PayPalCommerce
24 24
 {
25
-    public function __construct()
26
-    {
27
-    }
25
+	public function __construct()
26
+	{
27
+	}
28 28
 
29 29
 
30
-    /**
31
-     * Register with EE and load this payment method dependencies.
32
-     *
33
-     * @return void
34
-     * @throws EE_Error
35
-     */
36
-    public function initialize()
37
-    {
38
-        $this->registerDependencies();
39
-        // Register payment method through a legacy manager.
40
-        add_filter(
41
-            'FHEE__EE_Payment_Method_Manager__register_payment_methods__payment_methods_to_register',
42
-            [__CLASS__, 'injectPaymentMethod'],
43
-            10
44
-        );
45
-        // Load modules.
46
-        /** @var LegacyModulesManager $legacy_modules_manager */
47
-        $legacy_modules_manager = LoaderFactory::getShared(LegacyModulesManager::class);
48
-        $legacy_modules_manager->registerModule(__DIR__ . '/modules/EED_PayPalCommerce.module.php');
49
-        $legacy_modules_manager->registerModule(__DIR__ . '/modules/EED_PayPalOnboard.module.php');
30
+	/**
31
+	 * Register with EE and load this payment method dependencies.
32
+	 *
33
+	 * @return void
34
+	 * @throws EE_Error
35
+	 */
36
+	public function initialize()
37
+	{
38
+		$this->registerDependencies();
39
+		// Register payment method through a legacy manager.
40
+		add_filter(
41
+			'FHEE__EE_Payment_Method_Manager__register_payment_methods__payment_methods_to_register',
42
+			[__CLASS__, 'injectPaymentMethod'],
43
+			10
44
+		);
45
+		// Load modules.
46
+		/** @var LegacyModulesManager $legacy_modules_manager */
47
+		$legacy_modules_manager = LoaderFactory::getShared(LegacyModulesManager::class);
48
+		$legacy_modules_manager->registerModule(__DIR__ . '/modules/EED_PayPalCommerce.module.php');
49
+		$legacy_modules_manager->registerModule(__DIR__ . '/modules/EED_PayPalOnboard.module.php');
50 50
 
51
-        // Setup auto loaders.
52
-        EEH_Autoloader::instance()->register_autoloader([
53
-            'SettingsForm'   => EEP_PAYPAL_COMMERCE_PATH . 'forms' . DS . 'SettingsForm.php',
54
-            'OnboardingForm' => EEP_PAYPAL_COMMERCE_PATH . 'forms' . DS . 'OnboardingForm.php',
55
-            'BillingForm'    => EEP_PAYPAL_COMMERCE_PATH . 'forms' . DS . 'BillingForm.php',
56
-        ]);
57
-    }
51
+		// Setup auto loaders.
52
+		EEH_Autoloader::instance()->register_autoloader([
53
+			'SettingsForm'   => EEP_PAYPAL_COMMERCE_PATH . 'forms' . DS . 'SettingsForm.php',
54
+			'OnboardingForm' => EEP_PAYPAL_COMMERCE_PATH . 'forms' . DS . 'OnboardingForm.php',
55
+			'BillingForm'    => EEP_PAYPAL_COMMERCE_PATH . 'forms' . DS . 'BillingForm.php',
56
+		]);
57
+	}
58 58
 
59 59
 
60
-    /**
61
-     * Add this payment to the list of PMs to be registered.
62
-     *
63
-     * @param array $pms_to_register
64
-     * @return array
65
-     */
66
-    public static function injectPaymentMethod(array $pms_to_register): array
67
-    {
68
-        $pms_to_register[] = EEP_PAYPAL_COMMERCE_PATH;
69
-        return $pms_to_register;
70
-    }
60
+	/**
61
+	 * Add this payment to the list of PMs to be registered.
62
+	 *
63
+	 * @param array $pms_to_register
64
+	 * @return array
65
+	 */
66
+	public static function injectPaymentMethod(array $pms_to_register): array
67
+	{
68
+		$pms_to_register[] = EEP_PAYPAL_COMMERCE_PATH;
69
+		return $pms_to_register;
70
+	}
71 71
 
72 72
 
73
-    /**
74
-     * Register class dependencies.
75
-     *
76
-     * @return void
77
-     * @since 5.0.22.p
78
-     */
79
-    protected function registerDependencies(): void
80
-    {
81
-        EE_Dependency_Map::instance()->registerDependencies(
82
-            'EventEspresso\PaymentMethods\PayPalCommerce\api\orders\CreateOrder',
83
-            [
84
-                null,
85
-                null,
86
-                null,
87
-                'EventEspresso\core\domain\services\capabilities\FeatureFlags' => EE_Dependency_Map::load_from_cache,
88
-            ]
89
-        );
90
-        EE_Dependency_Map::instance()->registerDependencies(
91
-            'EventEspresso\PaymentMethods\PayPalCommerce\tools\fees\PartnerPaymentFees',
92
-            [
93
-                'EventEspresso\core\services\payments\PaymentProcessorFees' => EE_Dependency_Map::load_from_cache,
94
-            ]
95
-        );
96
-    }
73
+	/**
74
+	 * Register class dependencies.
75
+	 *
76
+	 * @return void
77
+	 * @since 5.0.22.p
78
+	 */
79
+	protected function registerDependencies(): void
80
+	{
81
+		EE_Dependency_Map::instance()->registerDependencies(
82
+			'EventEspresso\PaymentMethods\PayPalCommerce\api\orders\CreateOrder',
83
+			[
84
+				null,
85
+				null,
86
+				null,
87
+				'EventEspresso\core\domain\services\capabilities\FeatureFlags' => EE_Dependency_Map::load_from_cache,
88
+			]
89
+		);
90
+		EE_Dependency_Map::instance()->registerDependencies(
91
+			'EventEspresso\PaymentMethods\PayPalCommerce\tools\fees\PartnerPaymentFees',
92
+			[
93
+				'EventEspresso\core\services\payments\PaymentProcessorFees' => EE_Dependency_Map::load_from_cache,
94
+			]
95
+		);
96
+	}
97 97
 }
Please login to merge, or discard this patch.
languages/event_espresso-translations-js.php 1 patch
Spacing   +713 added lines, -713 removed lines patch added patch discarded remove patch
@@ -2,140 +2,140 @@  discard block
 block discarded – undo
2 2
 /* THIS IS A GENERATED FILE. DO NOT EDIT DIRECTLY. */
3 3
 $generated_i18n_strings = array(
4 4
 	// Reference: packages/ui-components/src/Pagination/constants.ts:6
5
-	__( '2', 'event_espresso' ),
5
+	__('2', 'event_espresso'),
6 6
 
7 7
 	// Reference: packages/ui-components/src/Pagination/constants.ts:7
8
-	__( '6', 'event_espresso' ),
8
+	__('6', 'event_espresso'),
9 9
 
10 10
 	// Reference: packages/ui-components/src/Pagination/constants.ts:8
11
-	__( '12', 'event_espresso' ),
11
+	__('12', 'event_espresso'),
12 12
 
13 13
 	// Reference: packages/ui-components/src/Pagination/constants.ts:9
14
-	__( '24', 'event_espresso' ),
14
+	__('24', 'event_espresso'),
15 15
 
16 16
 	// Reference: packages/ui-components/src/Pagination/constants.ts:10
17
-	__( '48', 'event_espresso' ),
17
+	__('48', 'event_espresso'),
18 18
 
19 19
 	// Reference: packages/ui-components/src/Pagination/constants.ts:11
20
-	__( '96', 'event_espresso' ),
20
+	__('96', 'event_espresso'),
21 21
 
22 22
 	// Reference: domains/core/admin/blocks/src/components/AvatarImage.tsx:27
23
-	__( 'contact avatar', 'event_espresso' ),
23
+	__('contact avatar', 'event_espresso'),
24 24
 
25 25
 	// Reference: domains/core/admin/blocks/src/components/OrderByControl.tsx:12
26
-	__( 'Order by', 'event_espresso' ),
26
+	__('Order by', 'event_espresso'),
27 27
 
28 28
 	// Reference: domains/core/admin/blocks/src/components/RegStatusControl.tsx:17
29 29
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectStatus.tsx:13
30
-	__( 'Select Registration Status', 'event_espresso' ),
30
+	__('Select Registration Status', 'event_espresso'),
31 31
 
32 32
 	// Reference: domains/core/admin/blocks/src/components/SortOrderControl.tsx:14
33
-	__( 'Ascending', 'event_espresso' ),
33
+	__('Ascending', 'event_espresso'),
34 34
 
35 35
 	// Reference: domains/core/admin/blocks/src/components/SortOrderControl.tsx:18
36
-	__( 'Descending', 'event_espresso' ),
36
+	__('Descending', 'event_espresso'),
37 37
 
38 38
 	// Reference: domains/core/admin/blocks/src/components/SortOrderControl.tsx:24
39
-	__( 'Sort order:', 'event_espresso' ),
39
+	__('Sort order:', 'event_espresso'),
40 40
 
41 41
 	// Reference: domains/core/admin/blocks/src/event-attendees/AttendeesDisplay.tsx:41
42
-	__( 'There was some error fetching attendees list', 'event_espresso' ),
42
+	__('There was some error fetching attendees list', 'event_espresso'),
43 43
 
44 44
 	// Reference: domains/core/admin/blocks/src/event-attendees/AttendeesDisplay.tsx:47
45
-	__( 'To get started, select what event you want to show attendees from in the block settings.', 'event_espresso' ),
45
+	__('To get started, select what event you want to show attendees from in the block settings.', 'event_espresso'),
46 46
 
47 47
 	// Reference: domains/core/admin/blocks/src/event-attendees/AttendeesDisplay.tsx:53
48
-	__( 'There are no attendees for selected options.', 'event_espresso' ),
48
+	__('There are no attendees for selected options.', 'event_espresso'),
49 49
 
50 50
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/ArchiveSettings.tsx:12
51
-	__( 'Display on Archives', 'event_espresso' ),
51
+	__('Display on Archives', 'event_espresso'),
52 52
 
53 53
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/ArchiveSettings.tsx:17
54
-	__( 'Attendees are shown whenever this post is listed in an archive view.', 'event_espresso' ),
54
+	__('Attendees are shown whenever this post is listed in an archive view.', 'event_espresso'),
55 55
 
56 56
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/ArchiveSettings.tsx:18
57
-	__( 'Attendees are hidden whenever this post is listed in an archive view.', 'event_espresso' ),
57
+	__('Attendees are hidden whenever this post is listed in an archive view.', 'event_espresso'),
58 58
 
59 59
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/AttendeeLimit.tsx:29
60
-	__( 'Number of Attendees to Display:', 'event_espresso' ),
60
+	__('Number of Attendees to Display:', 'event_espresso'),
61 61
 
62 62
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/AttendeeLimit.tsx:34
63 63
 	/* translators: %d attendees count */
64
-	_n_noop( 'Used to adjust the number of attendees displayed (There is %d total attendee for the current filter settings).', 'Used to adjust the number of attendees displayed (There are %d total attendees for the current filter settings).', 'event_espresso' ),
64
+	_n_noop('Used to adjust the number of attendees displayed (There is %d total attendee for the current filter settings).', 'Used to adjust the number of attendees displayed (There are %d total attendees for the current filter settings).', 'event_espresso'),
65 65
 
66 66
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/GravatarSettings.tsx:27
67
-	__( 'Display Gravatar', 'event_espresso' ),
67
+	__('Display Gravatar', 'event_espresso'),
68 68
 
69 69
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/GravatarSettings.tsx:32
70
-	__( 'Gravatar images are shown for each attendee.', 'event_espresso' ),
70
+	__('Gravatar images are shown for each attendee.', 'event_espresso'),
71 71
 
72 72
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/GravatarSettings.tsx:33
73
-	__( 'No gravatar images are shown for each attendee.', 'event_espresso' ),
73
+	__('No gravatar images are shown for each attendee.', 'event_espresso'),
74 74
 
75 75
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/GravatarSettings.tsx:38
76
-	__( 'Size of Gravatar', 'event_espresso' ),
76
+	__('Size of Gravatar', 'event_espresso'),
77 77
 
78 78
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectDatetime.tsx:22
79
-	__( 'Select Datetime', 'event_espresso' ),
79
+	__('Select Datetime', 'event_espresso'),
80 80
 
81 81
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectEvent.tsx:22
82 82
 	// Reference: domains/core/admin/blocks/src/event/controls/SelectEvent.tsx:22
83
-	__( 'Select Event', 'event_espresso' ),
83
+	__('Select Event', 'event_espresso'),
84 84
 
85 85
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectOrderBy.tsx:11
86
-	__( 'Attendee id', 'event_espresso' ),
86
+	__('Attendee id', 'event_espresso'),
87 87
 
88 88
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectOrderBy.tsx:15
89
-	__( 'Last name only', 'event_espresso' ),
89
+	__('Last name only', 'event_espresso'),
90 90
 
91 91
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectOrderBy.tsx:19
92
-	__( 'First name only', 'event_espresso' ),
92
+	__('First name only', 'event_espresso'),
93 93
 
94 94
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectOrderBy.tsx:23
95
-	__( 'First, then Last name', 'event_espresso' ),
95
+	__('First, then Last name', 'event_espresso'),
96 96
 
97 97
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectOrderBy.tsx:27
98
-	__( 'Last, then First name', 'event_espresso' ),
98
+	__('Last, then First name', 'event_espresso'),
99 99
 
100 100
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectOrderBy.tsx:41
101
-	__( 'Order Attendees by:', 'event_espresso' ),
101
+	__('Order Attendees by:', 'event_espresso'),
102 102
 
103 103
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/SelectTicket.tsx:22
104
-	__( 'Select Ticket', 'event_espresso' ),
104
+	__('Select Ticket', 'event_espresso'),
105 105
 
106 106
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/index.tsx:21
107
-	__( 'Filter By Settings', 'event_espresso' ),
107
+	__('Filter By Settings', 'event_espresso'),
108 108
 
109 109
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/index.tsx:36
110
-	__( 'Gravatar Setttings', 'event_espresso' ),
110
+	__('Gravatar Setttings', 'event_espresso'),
111 111
 
112 112
 	// Reference: domains/core/admin/blocks/src/event-attendees/controls/index.tsx:39
113
-	__( 'Archive Settings', 'event_espresso' ),
113
+	__('Archive Settings', 'event_espresso'),
114 114
 
115 115
 	// Reference: domains/core/admin/blocks/src/event-attendees/index.tsx:10
116
-	__( 'Event Attendees', 'event_espresso' ),
116
+	__('Event Attendees', 'event_espresso'),
117 117
 
118 118
 	// Reference: domains/core/admin/blocks/src/event-attendees/index.tsx:11
119
-	__( 'Displays a list of people that have registered for the specified event', 'event_espresso' ),
119
+	__('Displays a list of people that have registered for the specified event', 'event_espresso'),
120 120
 
121 121
 	// Reference: domains/core/admin/blocks/src/event-attendees/index.tsx:14
122 122
 	// Reference: domains/core/admin/blocks/src/event/index.tsx:12
123 123
 	// Reference: packages/edtr-services/src/constants.ts:25
124
-	__( 'event', 'event_espresso' ),
124
+	__('event', 'event_espresso'),
125 125
 
126 126
 	// Reference: domains/core/admin/blocks/src/event-attendees/index.tsx:14
127
-	__( 'attendees', 'event_espresso' ),
127
+	__('attendees', 'event_espresso'),
128 128
 
129 129
 	// Reference: domains/core/admin/blocks/src/event-attendees/index.tsx:14
130
-	__( 'list', 'event_espresso' ),
130
+	__('list', 'event_espresso'),
131 131
 
132 132
 	// Reference: domains/core/admin/blocks/src/event/DisplayField.tsx:41
133
-	__( 'An unknown error occurred while fetching event details.', 'event_espresso' ),
133
+	__('An unknown error occurred while fetching event details.', 'event_espresso'),
134 134
 
135 135
 	// Reference: domains/core/admin/blocks/src/event/controls/SelectField.tsx:10
136 136
 	// Reference: domains/core/admin/blocks/src/services/utils.ts:24
137 137
 	// Reference: packages/utils/src/list/index.ts:13
138
-	__( 'Select…', 'event_espresso' ),
138
+	__('Select…', 'event_espresso'),
139 139
 
140 140
 	// Reference: domains/core/admin/blocks/src/event/controls/SelectField.tsx:15
141 141
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:75
@@ -144,7 +144,7 @@  discard block
 block discarded – undo
144 144
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:198
145 145
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:48
146 146
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:42
147
-	__( 'Name', 'event_espresso' ),
147
+	__('Name', 'event_espresso'),
148 148
 
149 149
 	// Reference: domains/core/admin/blocks/src/event/controls/SelectField.tsx:19
150 150
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:80
@@ -152,411 +152,411 @@  discard block
 block discarded – undo
152 152
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:203
153 153
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:54
154 154
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:47
155
-	__( 'Description', 'event_espresso' ),
155
+	__('Description', 'event_espresso'),
156 156
 
157 157
 	// Reference: domains/core/admin/blocks/src/event/controls/SelectField.tsx:23
158
-	__( 'Short description', 'event_espresso' ),
158
+	__('Short description', 'event_espresso'),
159 159
 
160 160
 	// Reference: domains/core/admin/blocks/src/event/controls/SelectField.tsx:35
161
-	__( 'Select Field', 'event_espresso' ),
161
+	__('Select Field', 'event_espresso'),
162 162
 
163 163
 	// Reference: domains/core/admin/blocks/src/event/controls/index.tsx:27
164
-	__( 'Text Color', 'event_espresso' ),
164
+	__('Text Color', 'event_espresso'),
165 165
 
166 166
 	// Reference: domains/core/admin/blocks/src/event/controls/index.tsx:32
167
-	__( 'Background Color', 'event_espresso' ),
167
+	__('Background Color', 'event_espresso'),
168 168
 
169 169
 	// Reference: domains/core/admin/blocks/src/event/controls/index.tsx:41
170 170
 	// Reference: packages/form-builder/src/FormElement/Tabs/FormElementTabs.tsx:22
171 171
 	// Reference: packages/form-builder/src/FormSection/Tabs/FormSectionTabs.tsx:21
172
-	__( 'Settings', 'event_espresso' ),
172
+	__('Settings', 'event_espresso'),
173 173
 
174 174
 	// Reference: domains/core/admin/blocks/src/event/controls/index.tsx:45
175
-	__( 'Typography', 'event_espresso' ),
175
+	__('Typography', 'event_espresso'),
176 176
 
177 177
 	// Reference: domains/core/admin/blocks/src/event/controls/index.tsx:48
178
-	__( 'Color', 'event_espresso' ),
178
+	__('Color', 'event_espresso'),
179 179
 
180 180
 	// Reference: domains/core/admin/blocks/src/event/index.tsx:12
181
-	__( 'field', 'event_espresso' ),
181
+	__('field', 'event_espresso'),
182 182
 
183 183
 	// Reference: domains/core/admin/blocks/src/event/index.tsx:8
184
-	__( 'Event Field', 'event_espresso' ),
184
+	__('Event Field', 'event_espresso'),
185 185
 
186 186
 	// Reference: domains/core/admin/blocks/src/event/index.tsx:9
187
-	__( 'Displays the selected field of an event', 'event_espresso' ),
187
+	__('Displays the selected field of an event', 'event_espresso'),
188 188
 
189 189
 	// Reference: domains/core/admin/blocks/src/services/utils.ts:17
190
-	__( 'Error', 'event_espresso' ),
190
+	__('Error', 'event_espresso'),
191 191
 
192 192
 	// Reference: domains/core/admin/blocks/src/services/utils.ts:9
193
-	__( 'Loading…', 'event_espresso' ),
193
+	__('Loading…', 'event_espresso'),
194 194
 
195 195
 	// Reference: domains/core/admin/eventEditor/src/ui/EventDescription.tsx:33
196
-	__( 'Event Description', 'event_espresso' ),
196
+	__('Event Description', 'event_espresso'),
197 197
 
198 198
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/ActiveStatus.tsx:28
199
-	__( 'Active status', 'event_espresso' ),
199
+	__('Active status', 'event_espresso'),
200 200
 
201 201
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/AltRegPage.tsx:12
202
-	__( 'Alternative Registration Page', 'event_espresso' ),
202
+	__('Alternative Registration Page', 'event_espresso'),
203 203
 
204 204
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/DefaultRegistrationStatus.tsx:25
205
-	__( 'Default Registration Status', 'event_espresso' ),
205
+	__('Default Registration Status', 'event_espresso'),
206 206
 
207 207
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/Donations.tsx:8
208
-	__( 'Donations Enabled', 'event_espresso' ),
208
+	__('Donations Enabled', 'event_espresso'),
209 209
 
210 210
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/Donations.tsx:8
211
-	__( 'Donations Disabled', 'event_espresso' ),
211
+	__('Donations Disabled', 'event_espresso'),
212 212
 
213 213
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/EventManager.tsx:16
214
-	__( 'Event Manager', 'event_espresso' ),
214
+	__('Event Manager', 'event_espresso'),
215 215
 
216 216
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/EventPhoneNumber.tsx:15
217
-	__( 'Event Phone Number', 'event_espresso' ),
217
+	__('Event Phone Number', 'event_espresso'),
218 218
 
219 219
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/MaxRegistrations.tsx:13
220
-	__( 'Max Registrations per Transaction', 'event_espresso' ),
220
+	__('Max Registrations per Transaction', 'event_espresso'),
221 221
 
222 222
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/TicketSelector.tsx:8
223
-	__( 'Ticket Selector Enabled', 'event_espresso' ),
223
+	__('Ticket Selector Enabled', 'event_espresso'),
224 224
 
225 225
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/TicketSelector.tsx:8
226
-	__( 'Ticket Selector Disabled', 'event_espresso' ),
226
+	__('Ticket Selector Disabled', 'event_espresso'),
227 227
 
228 228
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/index.tsx:41
229
-	__( 'Event Details', 'event_espresso' ),
229
+	__('Event Details', 'event_espresso'),
230 230
 
231 231
 	// Reference: domains/core/admin/eventEditor/src/ui/EventRegistrationOptions/index.tsx:47
232
-	__( 'Registration Options', 'event_espresso' ),
232
+	__('Registration Options', 'event_espresso'),
233 233
 
234 234
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/multiStep/DateFormSteps.tsx:10
235
-	__( 'primary information about the date', 'event_espresso' ),
235
+	__('primary information about the date', 'event_espresso'),
236 236
 
237 237
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/multiStep/DateFormSteps.tsx:10
238
-	__( 'Date Details', 'event_espresso' ),
238
+	__('Date Details', 'event_espresso'),
239 239
 
240 240
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/multiStep/DateFormSteps.tsx:11
241 241
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/TicketFormSteps.tsx:16
242 242
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:16
243
-	__( 'relations between tickets and dates', 'event_espresso' ),
243
+	__('relations between tickets and dates', 'event_espresso'),
244 244
 
245 245
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/multiStep/DateFormSteps.tsx:11
246
-	__( 'Assign Tickets', 'event_espresso' ),
246
+	__('Assign Tickets', 'event_espresso'),
247 247
 
248 248
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/multiStep/FooterButtons.tsx:22
249
-	__( 'Save and assign tickets', 'event_espresso' ),
249
+	__('Save and assign tickets', 'event_espresso'),
250 250
 
251 251
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/multiStep/Modal.tsx:30
252 252
 	/* translators: %d database id */
253
-	__( 'Edit datetime %s', 'event_espresso' ),
253
+	__('Edit datetime %s', 'event_espresso'),
254 254
 
255 255
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/multiStep/Modal.tsx:33
256
-	__( 'New Datetime', 'event_espresso' ),
256
+	__('New Datetime', 'event_espresso'),
257 257
 
258 258
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/multiStep/Modal.tsx:43
259
-	__( 'modal for datetime', 'event_espresso' ),
259
+	__('modal for datetime', 'event_espresso'),
260 260
 
261 261
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:110
262 262
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:107
263 263
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:233
264 264
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:106
265
-	__( 'Details', 'event_espresso' ),
265
+	__('Details', 'event_espresso'),
266 266
 
267 267
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:114
268 268
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:111
269 269
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:83
270
-	__( 'Capacity', 'event_espresso' ),
270
+	__('Capacity', 'event_espresso'),
271 271
 
272 272
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:119
273
-	__( 'The maximum number of registrants that can attend the event at this particular date.', 'event_espresso' ),
273
+	__('The maximum number of registrants that can attend the event at this particular date.', 'event_espresso'),
274 274
 
275 275
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:123
276
-	__( 'Set to 0 to close registration or leave blank for no limit.', 'event_espresso' ),
276
+	__('Set to 0 to close registration or leave blank for no limit.', 'event_espresso'),
277 277
 
278 278
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:129
279 279
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:171
280
-	__( 'Trash', 'event_espresso' ),
280
+	__('Trash', 'event_espresso'),
281 281
 
282 282
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:71
283 283
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:44
284 284
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:194
285 285
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:44
286
-	__( 'Basics', 'event_espresso' ),
286
+	__('Basics', 'event_espresso'),
287 287
 
288 288
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:88
289 289
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:62
290 290
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:62
291
-	__( 'Dates', 'event_espresso' ),
291
+	__('Dates', 'event_espresso'),
292 292
 
293 293
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:92
294 294
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:53
295 295
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:215
296
-	__( 'Start Date', 'event_espresso' ),
296
+	__('Start Date', 'event_espresso'),
297 297
 
298 298
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/dateForm/useDateFormConfig.ts:99
299 299
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:67
300 300
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:222
301
-	__( 'End Date', 'event_espresso' ),
301
+	__('End Date', 'event_espresso'),
302 302
 
303 303
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/DateRegistrationsLink.tsx:25
304 304
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/TicketRegistrationsLink.tsx:13
305
-	__( 'total registrations.', 'event_espresso' ),
305
+	__('total registrations.', 'event_espresso'),
306 306
 
307 307
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/DateRegistrationsLink.tsx:26
308
-	__( 'view ALL registrations for this date.', 'event_espresso' ),
308
+	__('view ALL registrations for this date.', 'event_espresso'),
309 309
 
310 310
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/DateSoldLink.tsx:13
311
-	__( 'view approved registrations for this date.', 'event_espresso' ),
311
+	__('view approved registrations for this date.', 'event_espresso'),
312 312
 
313 313
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/DatesList.tsx:35
314 314
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/TableView.tsx:33
315
-	__( 'Event Dates', 'event_espresso' ),
315
+	__('Event Dates', 'event_espresso'),
316 316
 
317 317
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/DatesList.tsx:38
318
-	__( 'loading event dates…', 'event_espresso' ),
318
+	__('loading event dates…', 'event_espresso'),
319 319
 
320 320
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/DatesListButtons.tsx:22
321
-	__( 'Add a date or a ticket in order to use Ticket Assignment Manager', 'event_espresso' ),
321
+	__('Add a date or a ticket in order to use Ticket Assignment Manager', 'event_espresso'),
322 322
 
323 323
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/DatesListButtons.tsx:32
324
-	__( 'Ticket Assignments', 'event_espresso' ),
324
+	__('Ticket Assignments', 'event_espresso'),
325 325
 
326 326
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/AssignTicketsButton.tsx:25
327
-	__( 'Number of related tickets', 'event_espresso' ),
327
+	__('Number of related tickets', 'event_espresso'),
328 328
 
329 329
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/AssignTicketsButton.tsx:26
330
-	__( 'There are no tickets assigned to this datetime. Please click the ticket icon to update the assignments.', 'event_espresso' ),
330
+	__('There are no tickets assigned to this datetime. Please click the ticket icon to update the assignments.', 'event_espresso'),
331 331
 
332 332
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/AssignTicketsButton.tsx:34
333
-	__( 'assign tickets', 'event_espresso' ),
333
+	__('assign tickets', 'event_espresso'),
334 334
 
335 335
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:21
336
-	__( 'event datetime main menu', 'event_espresso' ),
336
+	__('event datetime main menu', 'event_espresso'),
337 337
 
338 338
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:33
339
-	__( 'edit datetime', 'event_espresso' ),
339
+	__('edit datetime', 'event_espresso'),
340 340
 
341 341
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DateMainMenu.tsx:34
342
-	__( 'copy datetime', 'event_espresso' ),
342
+	__('copy datetime', 'event_espresso'),
343 343
 
344 344
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DeleteDatetime.tsx:15
345 345
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/DeleteTicket.tsx:48
346
-	__( 'delete permanently', 'event_espresso' ),
346
+	__('delete permanently', 'event_espresso'),
347 347
 
348 348
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DeleteDatetime.tsx:15
349
-	__( 'trash datetime', 'event_espresso' ),
349
+	__('trash datetime', 'event_espresso'),
350 350
 
351 351
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DeleteDatetime.tsx:18
352
-	__( 'Permanently Delete Datetime?', 'event_espresso' ),
352
+	__('Permanently Delete Datetime?', 'event_espresso'),
353 353
 
354 354
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DeleteDatetime.tsx:18
355
-	__( 'Move Datetime to Trash?', 'event_espresso' ),
355
+	__('Move Datetime to Trash?', 'event_espresso'),
356 356
 
357 357
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DeleteDatetime.tsx:20
358
-	__( 'Are you sure you want to permanently delete this datetime? This action is permanent and can not be undone.', 'event_espresso' ),
358
+	__('Are you sure you want to permanently delete this datetime? This action is permanent and can not be undone.', 'event_espresso'),
359 359
 
360 360
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DeleteDatetime.tsx:23
361
-	__( 'Are you sure you want to move this datetime to the trash? You can "untrash" this datetime later if you need to.', 'event_espresso' ),
361
+	__('Are you sure you want to move this datetime to the trash? You can "untrash" this datetime later if you need to.', 'event_espresso'),
362 362
 
363 363
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/actionsMenu/dropdown/DeleteDatetime.tsx:33
364
-	__( 'delete', 'event_espresso' ),
364
+	__('delete', 'event_espresso'),
365 365
 
366 366
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/actions/Actions.tsx:36
367 367
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/actions/Actions.tsx:42
368 368
 	// Reference: packages/ui-components/src/bulkEdit/BulkActions.tsx:43
369
-	__( 'bulk actions', 'event_espresso' ),
369
+	__('bulk actions', 'event_espresso'),
370 370
 
371 371
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/actions/Actions.tsx:40
372
-	__( 'edit datetime details', 'event_espresso' ),
372
+	__('edit datetime details', 'event_espresso'),
373 373
 
374 374
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/actions/Actions.tsx:44
375
-	__( 'delete datetimes', 'event_espresso' ),
375
+	__('delete datetimes', 'event_espresso'),
376 376
 
377 377
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/actions/Actions.tsx:44
378
-	__( 'trash datetimes', 'event_espresso' ),
378
+	__('trash datetimes', 'event_espresso'),
379 379
 
380 380
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/delete/Delete.tsx:14
381
-	__( 'Are you sure you want to permanently delete these datetimes? This action can NOT be undone!', 'event_espresso' ),
381
+	__('Are you sure you want to permanently delete these datetimes? This action can NOT be undone!', 'event_espresso'),
382 382
 
383 383
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/delete/Delete.tsx:15
384
-	__( 'Are you sure you want to trash these datetimes?', 'event_espresso' ),
384
+	__('Are you sure you want to trash these datetimes?', 'event_espresso'),
385 385
 
386 386
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/delete/Delete.tsx:16
387
-	__( 'Delete datetimes permanently', 'event_espresso' ),
387
+	__('Delete datetimes permanently', 'event_espresso'),
388 388
 
389 389
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/delete/Delete.tsx:16
390
-	__( 'Trash datetimes', 'event_espresso' ),
390
+	__('Trash datetimes', 'event_espresso'),
391 391
 
392 392
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/EditDetails.tsx:21
393
-	__( 'Bulk edit date details', 'event_espresso' ),
393
+	__('Bulk edit date details', 'event_espresso'),
394 394
 
395 395
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/EditDetails.tsx:22
396
-	__( 'any changes will be applied to ALL of the selected dates.', 'event_espresso' ),
396
+	__('any changes will be applied to ALL of the selected dates.', 'event_espresso'),
397 397
 
398 398
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/formValidation.ts:12
399 399
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/formValidation.ts:12
400
-	__( 'Name must be at least three characters', 'event_espresso' ),
400
+	__('Name must be at least three characters', 'event_espresso'),
401 401
 
402 402
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:66
403 403
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:66
404
-	__( 'Shift dates', 'event_espresso' ),
404
+	__('Shift dates', 'event_espresso'),
405 405
 
406 406
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:91
407 407
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:90
408
-	__( 'earlier', 'event_espresso' ),
408
+	__('earlier', 'event_espresso'),
409 409
 
410 410
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/bulkEdit/details/useBulkEditFormConfig.ts:95
411 411
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:94
412
-	__( 'later', 'event_espresso' ),
412
+	__('later', 'event_espresso'),
413 413
 
414 414
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateCapacity.tsx:31
415 415
 	/* translators: click to edit capacity<linebreak>(registration limit)… */
416
-	__( 'click to edit capacity%s(registration limit)…', 'event_espresso' ),
416
+	__('click to edit capacity%s(registration limit)…', 'event_espresso'),
417 417
 
418 418
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateCardSidebar.tsx:31
419 419
 	// Reference: packages/ee-components/src/SimpleTicketCard/SimpleTicketCard.tsx:27
420 420
 	// Reference: packages/ui-components/src/CalendarDateSwitcher/CalendarDateSwitcher.tsx:34
421
-	__( 'starts', 'event_espresso' ),
421
+	__('starts', 'event_espresso'),
422 422
 
423 423
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateCardSidebar.tsx:32
424 424
 	// Reference: packages/ee-components/src/SimpleTicketCard/SimpleTicketCard.tsx:34
425 425
 	// Reference: packages/ui-components/src/CalendarDateSwitcher/CalendarDateSwitcher.tsx:47
426
-	__( 'ends', 'event_espresso' ),
426
+	__('ends', 'event_espresso'),
427 427
 
428 428
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateCardSidebar.tsx:32
429
-	__( 'started', 'event_espresso' ),
429
+	__('started', 'event_espresso'),
430 430
 
431 431
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateCardSidebar.tsx:32
432
-	__( 'ended', 'event_espresso' ),
432
+	__('ended', 'event_espresso'),
433 433
 
434 434
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateCardSidebar.tsx:46
435
-	__( 'Edit Event Date', 'event_espresso' ),
435
+	__('Edit Event Date', 'event_espresso'),
436 436
 
437 437
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateCardSidebar.tsx:50
438
-	__( 'edit start and end dates', 'event_espresso' ),
438
+	__('edit start and end dates', 'event_espresso'),
439 439
 
440 440
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateDetailsPanel.tsx:16
441 441
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketDetailsPanel.tsx:16
442
-	__( 'sold', 'event_espresso' ),
442
+	__('sold', 'event_espresso'),
443 443
 
444 444
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateDetailsPanel.tsx:21
445
-	__( 'capacity', 'event_espresso' ),
445
+	__('capacity', 'event_espresso'),
446 446
 
447 447
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/DateDetailsPanel.tsx:27
448 448
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketDetailsPanel.tsx:26
449
-	__( 'reg list', 'event_espresso' ),
449
+	__('reg list', 'event_espresso'),
450 450
 
451 451
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/Details.tsx:43
452 452
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/Details.tsx:35
453
-	__( 'add description…', 'event_espresso' ),
453
+	__('add description…', 'event_espresso'),
454 454
 
455 455
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/Details.tsx:44
456 456
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/Details.tsx:36
457
-	__( 'Edit description', 'event_espresso' ),
457
+	__('Edit description', 'event_espresso'),
458 458
 
459 459
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/cardView/Details.tsx:45
460 460
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/Details.tsx:37
461
-	__( 'click to edit description…', 'event_espresso' ),
461
+	__('click to edit description…', 'event_espresso'),
462 462
 
463 463
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:14
464
-	__( 'View Registrations for this Date', 'event_espresso' ),
464
+	__('View Registrations for this Date', 'event_espresso'),
465 465
 
466 466
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:19
467
-	__( 'Manage Ticket Assignments', 'event_espresso' ),
467
+	__('Manage Ticket Assignments', 'event_espresso'),
468 468
 
469 469
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:24
470
-	__( 'Move Date to Trash', 'event_espresso' ),
470
+	__('Move Date to Trash', 'event_espresso'),
471 471
 
472 472
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:29
473 473
 	// Reference: packages/constants/src/datetime.ts:6
474
-	__( 'Active', 'event_espresso' ),
474
+	__('Active', 'event_espresso'),
475 475
 
476 476
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:30
477 477
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:29
478
-	__( 'Trashed', 'event_espresso' ),
478
+	__('Trashed', 'event_espresso'),
479 479
 
480 480
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:31
481 481
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:30
482 482
 	// Reference: packages/constants/src/datetime.ts:8
483
-	__( 'Expired', 'event_espresso' ),
483
+	__('Expired', 'event_espresso'),
484 484
 
485 485
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:32
486 486
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:32
487
-	__( 'Sold Out', 'event_espresso' ),
487
+	__('Sold Out', 'event_espresso'),
488 488
 
489 489
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:33
490 490
 	// Reference: packages/constants/src/datetime.ts:12
491
-	__( 'Upcoming', 'event_espresso' ),
491
+	__('Upcoming', 'event_espresso'),
492 492
 
493 493
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/config.ts:9
494
-	__( 'Edit Event Date Details', 'event_espresso' ),
494
+	__('Edit Event Date Details', 'event_espresso'),
495 495
 
496 496
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/editable/EditableName.tsx:41
497 497
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/editable/EditableName.tsx:41
498
-	__( 'click to edit title…', 'event_espresso' ),
498
+	__('click to edit title…', 'event_espresso'),
499 499
 
500 500
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/editable/EditableName.tsx:42
501 501
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/editable/EditableName.tsx:42
502
-	__( 'add title…', 'event_espresso' ),
502
+	__('add title…', 'event_espresso'),
503 503
 
504 504
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/ActiveDatesFilters.tsx:17
505 505
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/ActiveTicketsFilters.tsx:17
506
-	__( 'ON', 'event_espresso' ),
506
+	__('ON', 'event_espresso'),
507 507
 
508 508
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:10
509
-	__( 'end dates only', 'event_espresso' ),
509
+	__('end dates only', 'event_espresso'),
510 510
 
511 511
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:11
512
-	__( 'start and end dates', 'event_espresso' ),
512
+	__('start and end dates', 'event_espresso'),
513 513
 
514 514
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:16
515
-	__( 'dates above 90% capacity', 'event_espresso' ),
515
+	__('dates above 90% capacity', 'event_espresso'),
516 516
 
517 517
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:17
518
-	__( 'dates above 75% capacity', 'event_espresso' ),
518
+	__('dates above 75% capacity', 'event_espresso'),
519 519
 
520 520
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:18
521
-	__( 'dates above 50% capacity', 'event_espresso' ),
521
+	__('dates above 50% capacity', 'event_espresso'),
522 522
 
523 523
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:19
524
-	__( 'dates below 50% capacity', 'event_espresso' ),
524
+	__('dates below 50% capacity', 'event_espresso'),
525 525
 
526 526
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:23
527
-	__( 'all dates', 'event_espresso' ),
527
+	__('all dates', 'event_espresso'),
528 528
 
529 529
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:24
530
-	__( 'all active and upcoming', 'event_espresso' ),
530
+	__('all active and upcoming', 'event_espresso'),
531 531
 
532 532
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:25
533
-	__( 'active dates only', 'event_espresso' ),
533
+	__('active dates only', 'event_espresso'),
534 534
 
535 535
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:26
536
-	__( 'upcoming dates only', 'event_espresso' ),
536
+	__('upcoming dates only', 'event_espresso'),
537 537
 
538 538
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:27
539
-	__( 'next active or upcoming only', 'event_espresso' ),
539
+	__('next active or upcoming only', 'event_espresso'),
540 540
 
541 541
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:28
542
-	__( 'sold out dates only', 'event_espresso' ),
542
+	__('sold out dates only', 'event_espresso'),
543 543
 
544 544
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:29
545
-	__( 'recently expired dates', 'event_espresso' ),
545
+	__('recently expired dates', 'event_espresso'),
546 546
 
547 547
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:30
548
-	__( 'all expired dates', 'event_espresso' ),
548
+	__('all expired dates', 'event_espresso'),
549 549
 
550 550
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:31
551
-	__( 'trashed dates only', 'event_espresso' ),
551
+	__('trashed dates only', 'event_espresso'),
552 552
 
553 553
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:35
554 554
 	// Reference: packages/dates/src/components/DateRangePicker/DateRangePickerLegend.tsx:9
555 555
 	// Reference: packages/dates/src/components/DateRangePicker/index.tsx:61
556
-	__( 'start date', 'event_espresso' ),
556
+	__('start date', 'event_espresso'),
557 557
 
558 558
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:36
559
-	__( 'name', 'event_espresso' ),
559
+	__('name', 'event_espresso'),
560 560
 
561 561
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:37
562 562
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:33
@@ -564,176 +564,176 @@  discard block
 block discarded – undo
564 564
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/table/HeaderCell.tsx:27
565 565
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:33
566 566
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:23
567
-	__( 'ID', 'event_espresso' ),
567
+	__('ID', 'event_espresso'),
568 568
 
569 569
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:38
570 570
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:47
571
-	__( 'custom order', 'event_espresso' ),
571
+	__('custom order', 'event_espresso'),
572 572
 
573 573
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:42
574 574
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:51
575
-	__( 'display', 'event_espresso' ),
575
+	__('display', 'event_espresso'),
576 576
 
577 577
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:43
578
-	__( 'recurrence', 'event_espresso' ),
578
+	__('recurrence', 'event_espresso'),
579 579
 
580 580
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:44
581 581
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:53
582
-	__( 'sales', 'event_espresso' ),
582
+	__('sales', 'event_espresso'),
583 583
 
584 584
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:45
585 585
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:55
586
-	__( 'sort by', 'event_espresso' ),
586
+	__('sort by', 'event_espresso'),
587 587
 
588 588
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:46
589 589
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:54
590 590
 	// Reference: packages/ee-components/src/EntityList/EntityListFilterBar.tsx:38
591
-	__( 'search', 'event_espresso' ),
591
+	__('search', 'event_espresso'),
592 592
 
593 593
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:47
594 594
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:56
595
-	__( 'status', 'event_espresso' ),
595
+	__('status', 'event_espresso'),
596 596
 
597 597
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/filterBar/controls/options.ts:9
598
-	__( 'start dates only', 'event_espresso' ),
598
+	__('start dates only', 'event_espresso'),
599 599
 
600 600
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/newDateOptions/AddSingleDate.tsx:26
601 601
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/newDateOptions/NewDateModal.tsx:12
602 602
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/newDateOptions/OptionsModalButton.tsx:18
603
-	__( 'Add New Date', 'event_espresso' ),
603
+	__('Add New Date', 'event_espresso'),
604 604
 
605 605
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/newDateOptions/AddSingleDate.tsx:26
606
-	__( 'Add Single Date', 'event_espresso' ),
606
+	__('Add Single Date', 'event_espresso'),
607 607
 
608 608
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/newDateOptions/AddSingleDate.tsx:44
609
-	__( 'Add a single date that only occurs once', 'event_espresso' ),
609
+	__('Add a single date that only occurs once', 'event_espresso'),
610 610
 
611 611
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/newDateOptions/AddSingleDate.tsx:46
612
-	__( 'Single Date', 'event_espresso' ),
612
+	__('Single Date', 'event_espresso'),
613 613
 
614 614
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:108
615
-	__( 'Reg list', 'event_espresso' ),
615
+	__('Reg list', 'event_espresso'),
616 616
 
617 617
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:109
618
-	__( 'Regs', 'event_espresso' ),
618
+	__('Regs', 'event_espresso'),
619 619
 
620 620
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:124
621 621
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:123
622 622
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:59
623
-	__( 'Actions', 'event_espresso' ),
623
+	__('Actions', 'event_espresso'),
624 624
 
625 625
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:54
626
-	__( 'Start', 'event_espresso' ),
626
+	__('Start', 'event_espresso'),
627 627
 
628 628
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:68
629
-	__( 'End', 'event_espresso' ),
629
+	__('End', 'event_espresso'),
630 630
 
631 631
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:84
632
-	__( 'Cap', 'event_espresso' ),
632
+	__('Cap', 'event_espresso'),
633 633
 
634 634
 	// Reference: domains/core/admin/eventEditor/src/ui/datetimes/datesList/tableView/useHeaderRowGenerator.tsx:96
635 635
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:100
636
-	__( 'Sold', 'event_espresso' ),
636
+	__('Sold', 'event_espresso'),
637 637
 
638 638
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/ErrorMessage.tsx:33
639 639
 	// Reference: packages/form-builder/src/constants.ts:67
640
-	__( 'Text Input', 'event_espresso' ),
640
+	__('Text Input', 'event_espresso'),
641 641
 
642 642
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/ErrorMessage.tsx:34
643 643
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/constants.ts:32
644
-	__( 'Attendee First Name', 'event_espresso' ),
644
+	__('Attendee First Name', 'event_espresso'),
645 645
 
646 646
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/ErrorMessage.tsx:39
647 647
 	/* translators: field name */
648
-	__( 'Registration form must have a field of type "%1$s" which maps to "%2$s"', 'event_espresso' ),
648
+	__('Registration form must have a field of type "%1$s" which maps to "%2$s"', 'event_espresso'),
649 649
 
650 650
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/ErrorMessage.tsx:40
651 651
 	// Reference: packages/form-builder/src/constants.ts:82
652
-	__( 'Email Address', 'event_espresso' ),
652
+	__('Email Address', 'event_espresso'),
653 653
 
654 654
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/ErrorMessage.tsx:41
655 655
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/constants.ts:40
656
-	__( 'Attendee Email Address', 'event_espresso' ),
656
+	__('Attendee Email Address', 'event_espresso'),
657 657
 
658 658
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/ErrorMessage.tsx:49
659
-	__( 'Please add the required fields', 'event_espresso' ),
659
+	__('Please add the required fields', 'event_espresso'),
660 660
 
661 661
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/RegistrationForm.tsx:12
662
-	__( 'Registration Form', 'event_espresso' ),
662
+	__('Registration Form', 'event_espresso'),
663 663
 
664 664
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/constants.ts:13
665
-	__( 'primary registrant', 'event_espresso' ),
665
+	__('primary registrant', 'event_espresso'),
666 666
 
667 667
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/constants.ts:17
668
-	__( 'purchaser', 'event_espresso' ),
668
+	__('purchaser', 'event_espresso'),
669 669
 
670 670
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/constants.ts:21
671
-	__( 'registrants', 'event_espresso' ),
671
+	__('registrants', 'event_espresso'),
672 672
 
673 673
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/constants.ts:36
674
-	__( 'Attendee Last Name', 'event_espresso' ),
674
+	__('Attendee Last Name', 'event_espresso'),
675 675
 
676 676
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/constants.ts:44
677
-	__( 'Attendee Address', 'event_espresso' ),
677
+	__('Attendee Address', 'event_espresso'),
678 678
 
679 679
 	// Reference: domains/core/admin/eventEditor/src/ui/registrationForm/constants.ts:9
680
-	__( 'all', 'event_espresso' ),
680
+	__('all', 'event_espresso'),
681 681
 
682 682
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/ErrorMessage.tsx:18
683
-	__( 'Tickets must always have at least one date assigned to them but one or more of the tickets below does not have any. 
684
-Please correct the assignments for the highlighted cells.', 'event_espresso' ),
683
+	__('Tickets must always have at least one date assigned to them but one or more of the tickets below does not have any. 
684
+Please correct the assignments for the highlighted cells.', 'event_espresso'),
685 685
 
686 686
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/ErrorMessage.tsx:22
687
-	__( 'Event Dates must always have at least one Ticket assigned to them but one or more of the Event Dates below does not have any. 
688
-Please correct the assignments for the highlighted cells.', 'event_espresso' ),
687
+	__('Event Dates must always have at least one Ticket assigned to them but one or more of the Event Dates below does not have any. 
688
+Please correct the assignments for the highlighted cells.', 'event_espresso'),
689 689
 
690 690
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/ErrorMessage.tsx:32
691
-	__( 'Please Update Assignments', 'event_espresso' ),
691
+	__('Please Update Assignments', 'event_espresso'),
692 692
 
693 693
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/ModalContainer.tsx:26
694
-	__( 'There seem to be some dates/tickets which have no tickets/dates assigned. Do you want to fix them now?', 'event_espresso' ),
694
+	__('There seem to be some dates/tickets which have no tickets/dates assigned. Do you want to fix them now?', 'event_espresso'),
695 695
 
696 696
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/ModalContainer.tsx:29
697
-	__( 'Alert!', 'event_espresso' ),
697
+	__('Alert!', 'event_espresso'),
698 698
 
699 699
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/ModalContainer.tsx:42
700 700
 	/* translators: 1 entity id, 2 entity name */
701
-	__( 'Ticket Assignment Manager for Datetime: %1$s - %2$s', 'event_espresso' ),
701
+	__('Ticket Assignment Manager for Datetime: %1$s - %2$s', 'event_espresso'),
702 702
 
703 703
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/ModalContainer.tsx:49
704 704
 	/* translators: 1 entity id, 2 entity name */
705
-	__( 'Ticket Assignment Manager for Ticket: %1$s - %2$s', 'event_espresso' ),
705
+	__('Ticket Assignment Manager for Ticket: %1$s - %2$s', 'event_espresso'),
706 706
 
707 707
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/TicketAssignmentsManagerModal.tsx:45
708 708
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/table/Table.tsx:13
709
-	__( 'Ticket Assignment Manager', 'event_espresso' ),
709
+	__('Ticket Assignment Manager', 'event_espresso'),
710 710
 
711 711
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/config.ts:10
712
-	__( 'existing relation', 'event_espresso' ),
712
+	__('existing relation', 'event_espresso'),
713 713
 
714 714
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/config.ts:15
715
-	__( 'remove existing relation', 'event_espresso' ),
715
+	__('remove existing relation', 'event_espresso'),
716 716
 
717 717
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/config.ts:20
718
-	__( 'add new relation', 'event_espresso' ),
718
+	__('add new relation', 'event_espresso'),
719 719
 
720 720
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/config.ts:25
721
-	__( 'invalid relation', 'event_espresso' ),
721
+	__('invalid relation', 'event_espresso'),
722 722
 
723 723
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/config.ts:29
724
-	__( 'no relation', 'event_espresso' ),
724
+	__('no relation', 'event_espresso'),
725 725
 
726 726
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/table/useGetHeaderRows.tsx:15
727
-	__( 'Assignments', 'event_espresso' ),
727
+	__('Assignments', 'event_espresso'),
728 728
 
729 729
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/table/useGetHeaderRows.tsx:16
730
-	__( 'Event Dates are listed below', 'event_espresso' ),
730
+	__('Event Dates are listed below', 'event_espresso'),
731 731
 
732 732
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/table/useGetHeaderRows.tsx:17
733
-	__( 'Tickets are listed along the top', 'event_espresso' ),
733
+	__('Tickets are listed along the top', 'event_espresso'),
734 734
 
735 735
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/table/useGetHeaderRows.tsx:18
736
-	__( 'Click the cell buttons to toggle assigments', 'event_espresso' ),
736
+	__('Click the cell buttons to toggle assigments', 'event_espresso'),
737 737
 
738 738
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/components/useSubmitButtonProps.ts:29
739 739
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/FooterButtons.tsx:16
@@ -742,1570 +742,1570 @@  discard block
 block discarded – undo
742 742
 	// Reference: packages/tpc/src/buttons/useSubmitButtonProps.tsx:29
743 743
 	// Reference: packages/ui-components/src/Modal/useSubmitButtonProps.tsx:13
744 744
 	// Reference: packages/ui-components/src/Stepper/buttons/Submit.tsx:7
745
-	__( 'Submit', 'event_espresso' ),
745
+	__('Submit', 'event_espresso'),
746 746
 
747 747
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/filters/controls/DatesByMonthControl.tsx:20
748
-	__( 'All Dates', 'event_espresso' ),
748
+	__('All Dates', 'event_espresso'),
749 749
 
750 750
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/filters/controls/DatesByMonthControl.tsx:27
751
-	__( 'dates by month', 'event_espresso' ),
751
+	__('dates by month', 'event_espresso'),
752 752
 
753 753
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/filters/controls/ShowExpiredTicketsControl.tsx:16
754
-	__( 'show expired tickets', 'event_espresso' ),
754
+	__('show expired tickets', 'event_espresso'),
755 755
 
756 756
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/filters/controls/ShowTrashedDatesControl.tsx:13
757
-	__( 'show trashed dates', 'event_espresso' ),
757
+	__('show trashed dates', 'event_espresso'),
758 758
 
759 759
 	// Reference: domains/core/admin/eventEditor/src/ui/ticketAssignmentsManager/filters/controls/ShowTrashedTicketsControl.tsx:16
760
-	__( 'show trashed tickets', 'event_espresso' ),
760
+	__('show trashed tickets', 'event_espresso'),
761 761
 
762 762
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/Container.tsx:38
763 763
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actions/Actions.tsx:25
764
-	__( 'Default tickets', 'event_espresso' ),
764
+	__('Default tickets', 'event_espresso'),
765 765
 
766 766
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/ModalBody.tsx:63
767 767
 	// Reference: packages/edtr-services/src/constants.ts:26
768
-	__( 'ticket', 'event_espresso' ),
768
+	__('ticket', 'event_espresso'),
769 769
 
770 770
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/FooterButtons.tsx:26
771 771
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/FooterButtons.tsx:33
772
-	__( 'Set ticket prices', 'event_espresso' ),
772
+	__('Set ticket prices', 'event_espresso'),
773 773
 
774 774
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/FooterButtons.tsx:31
775
-	__( 'Skip prices - Save', 'event_espresso' ),
775
+	__('Skip prices - Save', 'event_espresso'),
776 776
 
777 777
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/FooterButtons.tsx:37
778 778
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/FooterButtons.tsx:57
779
-	__( 'Ticket details', 'event_espresso' ),
779
+	__('Ticket details', 'event_espresso'),
780 780
 
781 781
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/FooterButtons.tsx:38
782
-	__( 'Save', 'event_espresso' ),
782
+	__('Save', 'event_espresso'),
783 783
 
784 784
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/Modal.tsx:22
785 785
 	/* translators: %s ticket id */
786
-	__( 'Edit ticket %s', 'event_espresso' ),
786
+	__('Edit ticket %s', 'event_espresso'),
787 787
 
788 788
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/Modal.tsx:25
789 789
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/Modal.tsx:33
790
-	__( 'New Ticket Details', 'event_espresso' ),
790
+	__('New Ticket Details', 'event_espresso'),
791 791
 
792 792
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/TicketFormSteps.tsx:10
793 793
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:10
794
-	__( 'primary information about the ticket', 'event_espresso' ),
794
+	__('primary information about the ticket', 'event_espresso'),
795 795
 
796 796
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/TicketFormSteps.tsx:10
797 797
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:10
798
-	__( 'Ticket Details', 'event_espresso' ),
798
+	__('Ticket Details', 'event_espresso'),
799 799
 
800 800
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/TicketFormSteps.tsx:12
801 801
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:12
802
-	__( 'apply ticket price modifiers and taxes', 'event_espresso' ),
802
+	__('apply ticket price modifiers and taxes', 'event_espresso'),
803 803
 
804 804
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/TicketFormSteps.tsx:14
805 805
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:14
806
-	__( 'Price Calculator', 'event_espresso' ),
806
+	__('Price Calculator', 'event_espresso'),
807 807
 
808 808
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/defaultTickets/multiStep/TicketFormSteps.tsx:16
809 809
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/TicketFormSteps.tsx:16
810
-	__( 'Assign Dates', 'event_espresso' ),
810
+	__('Assign Dates', 'event_espresso'),
811 811
 
812 812
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/FooterButtons.tsx:39
813
-	__( 'Skip prices - assign dates', 'event_espresso' ),
813
+	__('Skip prices - assign dates', 'event_espresso'),
814 814
 
815 815
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/FooterButtons.tsx:50
816
-	__( 'Save and assign dates', 'event_espresso' ),
816
+	__('Save and assign dates', 'event_espresso'),
817 817
 
818 818
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/Modal.tsx:29
819 819
 	/* translators: %1$s ticket name, %2$s ticket id */
820
-	__( 'Edit ticket "%1$s" - %2$s', 'event_espresso' ),
820
+	__('Edit ticket "%1$s" - %2$s', 'event_espresso'),
821 821
 
822 822
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/multiStep/Modal.tsx:43
823
-	__( 'modal for ticket', 'event_espresso' ),
823
+	__('modal for ticket', 'event_espresso'),
824 824
 
825 825
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:101
826
-	__( 'The maximum number of this ticket available for sale.', 'event_espresso' ),
826
+	__('The maximum number of this ticket available for sale.', 'event_espresso'),
827 827
 
828 828
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:103
829
-	__( 'Set to 0 to stop sales, or leave blank for no limit.', 'event_espresso' ),
829
+	__('Set to 0 to stop sales, or leave blank for no limit.', 'event_espresso'),
830 830
 
831 831
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:114
832 832
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:119
833
-	__( 'Number of Uses', 'event_espresso' ),
833
+	__('Number of Uses', 'event_espresso'),
834 834
 
835 835
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:120
836
-	__( 'Controls the total number of times this ticket can be used, regardless of the number of dates it is assigned to.', 'event_espresso' ),
836
+	__('Controls the total number of times this ticket can be used, regardless of the number of dates it is assigned to.', 'event_espresso'),
837 837
 
838 838
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:124
839
-	__( 'Example: A ticket might have access to 4 different dates, but setting this field to 2 would mean that the ticket could only be used twice. Leave blank for no limit.', 'event_espresso' ),
839
+	__('Example: A ticket might have access to 4 different dates, but setting this field to 2 would mean that the ticket could only be used twice. Leave blank for no limit.', 'event_espresso'),
840 840
 
841 841
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:132
842 842
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:127
843
-	__( 'Minimum Quantity', 'event_espresso' ),
843
+	__('Minimum Quantity', 'event_espresso'),
844 844
 
845 845
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:137
846
-	__( 'The minimum quantity that can be selected for this ticket. Use this to create ticket bundles or graduated pricing.', 'event_espresso' ),
846
+	__('The minimum quantity that can be selected for this ticket. Use this to create ticket bundles or graduated pricing.', 'event_espresso'),
847 847
 
848 848
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:141
849
-	__( 'Leave blank for no minimum.', 'event_espresso' ),
849
+	__('Leave blank for no minimum.', 'event_espresso'),
850 850
 
851 851
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:147
852 852
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:135
853
-	__( 'Maximum Quantity', 'event_espresso' ),
853
+	__('Maximum Quantity', 'event_espresso'),
854 854
 
855 855
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:153
856
-	__( 'The maximum quantity that can be selected for this ticket. Use this to create ticket bundles or graduated pricing.', 'event_espresso' ),
856
+	__('The maximum quantity that can be selected for this ticket. Use this to create ticket bundles or graduated pricing.', 'event_espresso'),
857 857
 
858 858
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:157
859
-	__( 'Leave blank for no maximum.', 'event_espresso' ),
859
+	__('Leave blank for no maximum.', 'event_espresso'),
860 860
 
861 861
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:163
862 862
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:144
863
-	__( 'Required Ticket', 'event_espresso' ),
863
+	__('Required Ticket', 'event_espresso'),
864 864
 
865 865
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:165
866
-	__( 'If enabled, the ticket must be selected and will appear first in ticket lists.', 'event_espresso' ),
866
+	__('If enabled, the ticket must be selected and will appear first in ticket lists.', 'event_espresso'),
867 867
 
868 868
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:177
869
-	__( 'Visibility', 'event_espresso' ),
869
+	__('Visibility', 'event_espresso'),
870 870
 
871 871
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:211
872
-	__( 'Ticket Sales', 'event_espresso' ),
872
+	__('Ticket Sales', 'event_espresso'),
873 873
 
874 874
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketForm/useTicketFormConfig.ts:95
875 875
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/useBulkEditFormConfig.ts:110
876
-	__( 'Quantity For Sale', 'event_espresso' ),
876
+	__('Quantity For Sale', 'event_espresso'),
877 877
 
878 878
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/TicketRegistrationsLink.tsx:14
879
-	__( 'view ALL registrations for this ticket.', 'event_espresso' ),
879
+	__('view ALL registrations for this ticket.', 'event_espresso'),
880 880
 
881 881
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/TicketSoldLink.tsx:13
882
-	__( 'view approved registrations for this ticket.', 'event_espresso' ),
882
+	__('view approved registrations for this ticket.', 'event_espresso'),
883 883
 
884 884
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/TicketsList.tsx:36
885
-	__( 'Available Tickets', 'event_espresso' ),
885
+	__('Available Tickets', 'event_espresso'),
886 886
 
887 887
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/TicketsList.tsx:39
888
-	__( 'loading tickets…', 'event_espresso' ),
888
+	__('loading tickets…', 'event_espresso'),
889 889
 
890 890
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/AssignDatesButton.tsx:26
891
-	__( 'Number of related dates', 'event_espresso' ),
891
+	__('Number of related dates', 'event_espresso'),
892 892
 
893 893
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/AssignDatesButton.tsx:27
894
-	__( 'There are no event dates assigned to this ticket. Please click the calendar icon to update the assignments.', 'event_espresso' ),
894
+	__('There are no event dates assigned to this ticket. Please click the calendar icon to update the assignments.', 'event_espresso'),
895 895
 
896 896
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/AssignDatesButton.tsx:37
897
-	__( 'assign dates', 'event_espresso' ),
897
+	__('assign dates', 'event_espresso'),
898 898
 
899 899
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/DeleteTicket.tsx:19
900
-	__( 'Permanently Delete Ticket?', 'event_espresso' ),
900
+	__('Permanently Delete Ticket?', 'event_espresso'),
901 901
 
902 902
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/DeleteTicket.tsx:19
903
-	__( 'Move Ticket to Trash?', 'event_espresso' ),
903
+	__('Move Ticket to Trash?', 'event_espresso'),
904 904
 
905 905
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/DeleteTicket.tsx:22
906
-	__( 'Are you sure you want to permanently delete this ticket? This action is permanent and can not be undone.', 'event_espresso' ),
906
+	__('Are you sure you want to permanently delete this ticket? This action is permanent and can not be undone.', 'event_espresso'),
907 907
 
908 908
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/DeleteTicket.tsx:48
909 909
 	// Reference: packages/ee-components/src/SimpleTicketCard/actions/Trash.tsx:6
910
-	__( 'trash ticket', 'event_espresso' ),
910
+	__('trash ticket', 'event_espresso'),
911 911
 
912 912
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/TicketMainMenu.tsx:25
913
-	__( 'ticket main menu', 'event_espresso' ),
913
+	__('ticket main menu', 'event_espresso'),
914 914
 
915 915
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/TicketMainMenu.tsx:38
916 916
 	// Reference: packages/ee-components/src/SimpleTicketCard/actions/Edit.tsx:15
917
-	__( 'edit ticket', 'event_espresso' ),
917
+	__('edit ticket', 'event_espresso'),
918 918
 
919 919
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/actionsMenu/dropdown/TicketMainMenu.tsx:39
920
-	__( 'copy ticket', 'event_espresso' ),
920
+	__('copy ticket', 'event_espresso'),
921 921
 
922 922
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/actions/Actions.tsx:46
923
-	__( 'edit ticket details', 'event_espresso' ),
923
+	__('edit ticket details', 'event_espresso'),
924 924
 
925 925
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/actions/Actions.tsx:50
926
-	__( 'delete tickets', 'event_espresso' ),
926
+	__('delete tickets', 'event_espresso'),
927 927
 
928 928
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/actions/Actions.tsx:50
929
-	__( 'trash tickets', 'event_espresso' ),
929
+	__('trash tickets', 'event_espresso'),
930 930
 
931 931
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/actions/Actions.tsx:54
932
-	__( 'edit ticket prices', 'event_espresso' ),
932
+	__('edit ticket prices', 'event_espresso'),
933 933
 
934 934
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/delete/Delete.tsx:14
935
-	__( 'Are you sure you want to permanently delete these tickets? This action can NOT be undone!', 'event_espresso' ),
935
+	__('Are you sure you want to permanently delete these tickets? This action can NOT be undone!', 'event_espresso'),
936 936
 
937 937
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/delete/Delete.tsx:15
938
-	__( 'Are you sure you want to trash these tickets?', 'event_espresso' ),
938
+	__('Are you sure you want to trash these tickets?', 'event_espresso'),
939 939
 
940 940
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/delete/Delete.tsx:16
941
-	__( 'Delete tickets permanently', 'event_espresso' ),
941
+	__('Delete tickets permanently', 'event_espresso'),
942 942
 
943 943
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/delete/Delete.tsx:16
944
-	__( 'Trash tickets', 'event_espresso' ),
944
+	__('Trash tickets', 'event_espresso'),
945 945
 
946 946
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/EditDetails.tsx:21
947
-	__( 'Bulk edit ticket details', 'event_espresso' ),
947
+	__('Bulk edit ticket details', 'event_espresso'),
948 948
 
949 949
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/details/EditDetails.tsx:22
950
-	__( 'any changes will be applied to ALL of the selected tickets.', 'event_espresso' ),
950
+	__('any changes will be applied to ALL of the selected tickets.', 'event_espresso'),
951 951
 
952 952
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/EditPrices.tsx:19
953
-	__( 'Bulk edit ticket prices', 'event_espresso' ),
953
+	__('Bulk edit ticket prices', 'event_espresso'),
954 954
 
955 955
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/EditModeButtons.tsx:20
956
-	__( 'Edit all prices together', 'event_espresso' ),
956
+	__('Edit all prices together', 'event_espresso'),
957 957
 
958 958
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/EditModeButtons.tsx:21
959
-	__( 'Edit all the selected ticket prices dynamically', 'event_espresso' ),
959
+	__('Edit all the selected ticket prices dynamically', 'event_espresso'),
960 960
 
961 961
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/EditModeButtons.tsx:25
962
-	__( 'Edit prices individually', 'event_espresso' ),
962
+	__('Edit prices individually', 'event_espresso'),
963 963
 
964 964
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/EditModeButtons.tsx:26
965
-	__( 'Edit prices for each ticket individually', 'event_espresso' ),
965
+	__('Edit prices for each ticket individually', 'event_espresso'),
966 966
 
967 967
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/FooterButtons.tsx:14
968 968
 	// Reference: packages/ee-components/src/bulkEdit/details/Submit.tsx:34
969 969
 	// Reference: packages/form/src/ResetButton.tsx:18
970 970
 	// Reference: packages/tpc/src/buttons/useResetButtonProps.tsx:12
971
-	__( 'Reset', 'event_espresso' ),
971
+	__('Reset', 'event_espresso'),
972 972
 
973 973
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/buttons/FooterButtons.tsx:15
974 974
 	// Reference: packages/tpc/src/hooks/useLockedTicketAction.ts:76
975 975
 	// Reference: packages/ui-components/src/Modal/useCancelButtonProps.tsx:10
976
-	__( 'Cancel', 'event_espresso' ),
976
+	__('Cancel', 'event_espresso'),
977 977
 
978 978
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/bulkEdit/prices/editSeparately/TPCInstance.tsx:26
979 979
 	/* translators: %s ticket name */
980
-	__( 'Edit prices for Ticket: %s', 'event_espresso' ),
980
+	__('Edit prices for Ticket: %s', 'event_espresso'),
981 981
 
982 982
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketCardSidebar.tsx:30
983
-	__( 'sales start', 'event_espresso' ),
983
+	__('sales start', 'event_espresso'),
984 984
 
985 985
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketCardSidebar.tsx:33
986
-	__( 'sales began', 'event_espresso' ),
986
+	__('sales began', 'event_espresso'),
987 987
 
988 988
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketCardSidebar.tsx:35
989
-	__( 'sales ended', 'event_espresso' ),
989
+	__('sales ended', 'event_espresso'),
990 990
 
991 991
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketCardSidebar.tsx:36
992
-	__( 'sales end', 'event_espresso' ),
992
+	__('sales end', 'event_espresso'),
993 993
 
994 994
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketCardSidebar.tsx:50
995
-	__( 'Edit Ticket Sale Dates', 'event_espresso' ),
995
+	__('Edit Ticket Sale Dates', 'event_espresso'),
996 996
 
997 997
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketCardSidebar.tsx:54
998
-	__( 'edit ticket sales start and end dates', 'event_espresso' ),
998
+	__('edit ticket sales start and end dates', 'event_espresso'),
999 999
 
1000 1000
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketDetailsPanel.tsx:21
1001
-	__( 'quantity', 'event_espresso' ),
1001
+	__('quantity', 'event_espresso'),
1002 1002
 
1003 1003
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketQuantity.tsx:28
1004 1004
 	// Reference: packages/edtr-services/src/apollo/mutations/tickets/useUpdateTicketQtyByCapacity.ts:78
1005
-	__( 'Ticket quantity has been adjusted because it cannot be more than the related event date capacity.', 'event_espresso' ),
1005
+	__('Ticket quantity has been adjusted because it cannot be more than the related event date capacity.', 'event_espresso'),
1006 1006
 
1007 1007
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/cardView/TicketQuantity.tsx:51
1008
-	__( 'edit quantity of tickets available…', 'event_espresso' ),
1008
+	__('edit quantity of tickets available…', 'event_espresso'),
1009 1009
 
1010 1010
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:14
1011
-	__( 'Manage Date Assignments', 'event_espresso' ),
1011
+	__('Manage Date Assignments', 'event_espresso'),
1012 1012
 
1013 1013
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:19
1014 1014
 	// Reference: packages/tpc/src/components/table/Table.tsx:43
1015
-	__( 'Ticket Price Calculator', 'event_espresso' ),
1015
+	__('Ticket Price Calculator', 'event_espresso'),
1016 1016
 
1017 1017
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:24
1018
-	__( 'Move Ticket to Trash', 'event_espresso' ),
1018
+	__('Move Ticket to Trash', 'event_espresso'),
1019 1019
 
1020 1020
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:31
1021 1021
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:54
1022
-	__( 'On Sale', 'event_espresso' ),
1022
+	__('On Sale', 'event_espresso'),
1023 1023
 
1024 1024
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:33
1025
-	__( 'Pending', 'event_espresso' ),
1025
+	__('Pending', 'event_espresso'),
1026 1026
 
1027 1027
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/config.ts:9
1028
-	__( 'Edit Ticket Details', 'event_espresso' ),
1028
+	__('Edit Ticket Details', 'event_espresso'),
1029 1029
 
1030 1030
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/editable/EditablePrice.tsx:39
1031
-	__( 'edit ticket total…', 'event_espresso' ),
1031
+	__('edit ticket total…', 'event_espresso'),
1032 1032
 
1033 1033
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/editable/EditablePrice.tsx:53
1034
-	__( 'set price…', 'event_espresso' ),
1034
+	__('set price…', 'event_espresso'),
1035 1035
 
1036 1036
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/IsChainedButton.tsx:23
1037
-	__( 'tickets list is linked to dates list and is showing tickets for above dates only', 'event_espresso' ),
1037
+	__('tickets list is linked to dates list and is showing tickets for above dates only', 'event_espresso'),
1038 1038
 
1039 1039
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/IsChainedButton.tsx:24
1040
-	__( 'tickets list is unlinked and is showing tickets for all event dates', 'event_espresso' ),
1040
+	__('tickets list is unlinked and is showing tickets for all event dates', 'event_espresso'),
1041 1041
 
1042 1042
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:10
1043
-	__( 'ticket sales start and end dates', 'event_espresso' ),
1043
+	__('ticket sales start and end dates', 'event_espresso'),
1044 1044
 
1045 1045
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:15
1046
-	__( 'tickets with 90% or more sold', 'event_espresso' ),
1046
+	__('tickets with 90% or more sold', 'event_espresso'),
1047 1047
 
1048 1048
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:16
1049
-	__( 'tickets with 75% or more sold', 'event_espresso' ),
1049
+	__('tickets with 75% or more sold', 'event_espresso'),
1050 1050
 
1051 1051
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:17
1052
-	__( 'tickets with 50% or more sold', 'event_espresso' ),
1052
+	__('tickets with 50% or more sold', 'event_espresso'),
1053 1053
 
1054 1054
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:19
1055
-	__( 'tickets with less than 50% sold', 'event_espresso' ),
1055
+	__('tickets with less than 50% sold', 'event_espresso'),
1056 1056
 
1057 1057
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:28
1058
-	__( 'all tickets for all dates', 'event_espresso' ),
1058
+	__('all tickets for all dates', 'event_espresso'),
1059 1059
 
1060 1060
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:29
1061
-	__( 'all on sale and sale pending', 'event_espresso' ),
1061
+	__('all on sale and sale pending', 'event_espresso'),
1062 1062
 
1063 1063
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:30
1064
-	__( 'on sale tickets only', 'event_espresso' ),
1064
+	__('on sale tickets only', 'event_espresso'),
1065 1065
 
1066 1066
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:31
1067
-	__( 'sale pending tickets only', 'event_espresso' ),
1067
+	__('sale pending tickets only', 'event_espresso'),
1068 1068
 
1069 1069
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:32
1070
-	__( 'next on sale or sale pending only', 'event_espresso' ),
1070
+	__('next on sale or sale pending only', 'event_espresso'),
1071 1071
 
1072 1072
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:33
1073
-	__( 'sold out tickets only', 'event_espresso' ),
1073
+	__('sold out tickets only', 'event_espresso'),
1074 1074
 
1075 1075
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:34
1076
-	__( 'expired tickets only', 'event_espresso' ),
1076
+	__('expired tickets only', 'event_espresso'),
1077 1077
 
1078 1078
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:35
1079
-	__( 'trashed tickets only', 'event_espresso' ),
1079
+	__('trashed tickets only', 'event_espresso'),
1080 1080
 
1081 1081
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:40
1082
-	__( 'all tickets for above dates', 'event_espresso' ),
1082
+	__('all tickets for above dates', 'event_espresso'),
1083 1083
 
1084 1084
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:44
1085
-	__( 'ticket sale date', 'event_espresso' ),
1085
+	__('ticket sale date', 'event_espresso'),
1086 1086
 
1087 1087
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:45
1088
-	__( 'ticket name', 'event_espresso' ),
1088
+	__('ticket name', 'event_espresso'),
1089 1089
 
1090 1090
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:46
1091
-	__( 'ticket ID', 'event_espresso' ),
1091
+	__('ticket ID', 'event_espresso'),
1092 1092
 
1093 1093
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:52
1094
-	__( 'linked', 'event_espresso' ),
1094
+	__('linked', 'event_espresso'),
1095 1095
 
1096 1096
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:8
1097
-	__( 'ticket sales start date only', 'event_espresso' ),
1097
+	__('ticket sales start date only', 'event_espresso'),
1098 1098
 
1099 1099
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/filterBar/controls/options.ts:9
1100
-	__( 'ticket sales end date only', 'event_espresso' ),
1100
+	__('ticket sales end date only', 'event_espresso'),
1101 1101
 
1102 1102
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/newTicketOptions/AddSingleTicket.tsx:18
1103
-	__( 'Add New Ticket', 'event_espresso' ),
1103
+	__('Add New Ticket', 'event_espresso'),
1104 1104
 
1105 1105
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/newTicketOptions/AddSingleTicket.tsx:32
1106
-	__( 'Add a single ticket and assign the dates to it', 'event_espresso' ),
1106
+	__('Add a single ticket and assign the dates to it', 'event_espresso'),
1107 1107
 
1108 1108
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/newTicketOptions/AddSingleTicket.tsx:34
1109
-	__( 'Single Ticket', 'event_espresso' ),
1109
+	__('Single Ticket', 'event_espresso'),
1110 1110
 
1111 1111
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/TableView.tsx:39
1112
-	__( 'Tickets', 'event_espresso' ),
1112
+	__('Tickets', 'event_espresso'),
1113 1113
 
1114 1114
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:110
1115
-	__( 'Reg List', 'event_espresso' ),
1115
+	__('Reg List', 'event_espresso'),
1116 1116
 
1117 1117
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:53
1118
-	__( 'Goes on Sale', 'event_espresso' ),
1118
+	__('Goes on Sale', 'event_espresso'),
1119 1119
 
1120 1120
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:67
1121
-	__( 'Sale Ends', 'event_espresso' ),
1121
+	__('Sale Ends', 'event_espresso'),
1122 1122
 
1123 1123
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:68
1124
-	__( 'Ends', 'event_espresso' ),
1124
+	__('Ends', 'event_espresso'),
1125 1125
 
1126 1126
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:80
1127
-	__( 'Price', 'event_espresso' ),
1127
+	__('Price', 'event_espresso'),
1128 1128
 
1129 1129
 	// Reference: domains/core/admin/eventEditor/src/ui/tickets/ticketsList/tableView/useHeaderRowGenerator.tsx:90
1130
-	__( 'Qty', 'event_espresso' ),
1130
+	__('Qty', 'event_espresso'),
1131 1131
 
1132 1132
 	// Reference: domains/core/admin/eventEditor/src/ui/venue/VenueDetails.tsx:104
1133
-	__( 'Venue telephone', 'event_espresso' ),
1133
+	__('Venue telephone', 'event_espresso'),
1134 1134
 
1135 1135
 	// Reference: domains/core/admin/eventEditor/src/ui/venue/VenueDetails.tsx:111
1136
-	__( 'Edit this Venue', 'event_espresso' ),
1136
+	__('Edit this Venue', 'event_espresso'),
1137 1137
 
1138 1138
 	// Reference: domains/core/admin/eventEditor/src/ui/venue/VenueDetails.tsx:120
1139
-	__( 'Select a Venue for the Event', 'event_espresso' ),
1139
+	__('Select a Venue for the Event', 'event_espresso'),
1140 1140
 
1141 1141
 	// Reference: domains/core/admin/eventEditor/src/ui/venue/VenueDetails.tsx:21
1142
-	__( 'Venue Details', 'event_espresso' ),
1142
+	__('Venue Details', 'event_espresso'),
1143 1143
 
1144 1144
 	// Reference: domains/core/admin/eventEditor/src/ui/venue/VenueDetails.tsx:39
1145
-	__( 'unlimited space', 'event_espresso' ),
1145
+	__('unlimited space', 'event_espresso'),
1146 1146
 
1147 1147
 	// Reference: domains/core/admin/eventEditor/src/ui/venue/VenueDetails.tsx:42
1148 1148
 	/* translators: %d venue capacity */
1149
-	__( 'Space for up to %d people', 'event_espresso' ),
1149
+	__('Space for up to %d people', 'event_espresso'),
1150 1150
 
1151 1151
 	// Reference: domains/core/admin/eventEditor/src/ui/venue/VenueDetails.tsx:53
1152
-	__( 'Venue address', 'event_espresso' ),
1152
+	__('Venue address', 'event_espresso'),
1153 1153
 
1154 1154
 	// Reference: domains/core/admin/eventEditor/src/ui/venue/VenueDetails.tsx:59
1155
-	__( 'Venue Details card', 'event_espresso' ),
1155
+	__('Venue Details card', 'event_espresso'),
1156 1156
 
1157 1157
 	// Reference: domains/core/admin/eventEditor/src/ui/venue/VenueDetails.tsx:68
1158
-	__( 'no image', 'event_espresso' ),
1158
+	__('no image', 'event_espresso'),
1159 1159
 
1160 1160
 	// Reference: domains/core/admin/eventEditor/src/ui/venue/VenueDetails.tsx:72
1161
-	__( 'Venue name', 'event_espresso' ),
1161
+	__('Venue name', 'event_espresso'),
1162 1162
 
1163 1163
 	// Reference: domains/core/admin/eventEditor/src/ui/venue/VenueDetails.tsx:96
1164
-	__( 'Venue capacity', 'event_espresso' ),
1164
+	__('Venue capacity', 'event_espresso'),
1165 1165
 
1166 1166
 	// Reference: domains/core/admin/wpPluginsPage/src/exitSurvey/Popup.tsx:29
1167
-	__( 'Do you have a moment to share why you are deactivating Event Espresso?', 'event_espresso' ),
1167
+	__('Do you have a moment to share why you are deactivating Event Espresso?', 'event_espresso'),
1168 1168
 
1169 1169
 	// Reference: domains/core/admin/wpPluginsPage/src/exitSurvey/Popup.tsx:40
1170
-	__( 'Skip', 'event_espresso' ),
1170
+	__('Skip', 'event_espresso'),
1171 1171
 
1172 1172
 	// Reference: domains/core/admin/wpPluginsPage/src/exitSurvey/Popup.tsx:42
1173
-	__( 'Sure I\'ll help', 'event_espresso' ),
1173
+	__('Sure I\'ll help', 'event_espresso'),
1174 1174
 
1175 1175
 	// Reference: packages/adapters/src/Pagination/Pagination.tsx:23
1176
-	__( 'pagination', 'event_espresso' ),
1176
+	__('pagination', 'event_espresso'),
1177 1177
 
1178 1178
 	// Reference: packages/adapters/src/TagSelector/TagSelector.tsx:113
1179
-	__( 'toggle menu', 'event_espresso' ),
1179
+	__('toggle menu', 'event_espresso'),
1180 1180
 
1181 1181
 	// Reference: packages/constants/src/datetime.ts:10
1182
-	__( 'Postponed', 'event_espresso' ),
1182
+	__('Postponed', 'event_espresso'),
1183 1183
 
1184 1184
 	// Reference: packages/constants/src/datetime.ts:11
1185
-	__( 'SoldOut', 'event_espresso' ),
1185
+	__('SoldOut', 'event_espresso'),
1186 1186
 
1187 1187
 	// Reference: packages/constants/src/datetime.ts:7
1188 1188
 	// Reference: packages/predicates/src/registration/statusOptions.ts:11
1189
-	__( 'Cancelled', 'event_espresso' ),
1189
+	__('Cancelled', 'event_espresso'),
1190 1190
 
1191 1191
 	// Reference: packages/constants/src/datetime.ts:9
1192
-	__( 'Inactive', 'event_espresso' ),
1192
+	__('Inactive', 'event_espresso'),
1193 1193
 
1194 1194
 	// Reference: packages/data/src/mutations/useMutationWithFeedback.ts:25
1195
-	__( 'error creating %s', 'event_espresso' ),
1195
+	__('error creating %s', 'event_espresso'),
1196 1196
 
1197 1197
 	// Reference: packages/data/src/mutations/useMutationWithFeedback.ts:26
1198
-	__( 'error deleting %s', 'event_espresso' ),
1198
+	__('error deleting %s', 'event_espresso'),
1199 1199
 
1200 1200
 	// Reference: packages/data/src/mutations/useMutationWithFeedback.ts:27
1201
-	__( 'error updating %s', 'event_espresso' ),
1201
+	__('error updating %s', 'event_espresso'),
1202 1202
 
1203 1203
 	// Reference: packages/data/src/mutations/useMutationWithFeedback.ts:28
1204
-	__( 'creating %s', 'event_espresso' ),
1204
+	__('creating %s', 'event_espresso'),
1205 1205
 
1206 1206
 	// Reference: packages/data/src/mutations/useMutationWithFeedback.ts:29
1207
-	__( 'deleting %s', 'event_espresso' ),
1207
+	__('deleting %s', 'event_espresso'),
1208 1208
 
1209 1209
 	// Reference: packages/data/src/mutations/useMutationWithFeedback.ts:30
1210
-	__( 'updating %s', 'event_espresso' ),
1210
+	__('updating %s', 'event_espresso'),
1211 1211
 
1212 1212
 	// Reference: packages/data/src/mutations/useMutationWithFeedback.ts:31
1213
-	__( 'successfully created %s', 'event_espresso' ),
1213
+	__('successfully created %s', 'event_espresso'),
1214 1214
 
1215 1215
 	// Reference: packages/data/src/mutations/useMutationWithFeedback.ts:32
1216
-	__( 'successfully deleted %s', 'event_espresso' ),
1216
+	__('successfully deleted %s', 'event_espresso'),
1217 1217
 
1218 1218
 	// Reference: packages/data/src/mutations/useMutationWithFeedback.ts:33
1219
-	__( 'successfully updated %s', 'event_espresso' ),
1219
+	__('successfully updated %s', 'event_espresso'),
1220 1220
 
1221 1221
 	// Reference: packages/dates/src/components/DateRangePicker/DateRangePickerLegend.tsx:13
1222
-	__( 'day in range', 'event_espresso' ),
1222
+	__('day in range', 'event_espresso'),
1223 1223
 
1224 1224
 	// Reference: packages/dates/src/components/DateRangePicker/DateRangePickerLegend.tsx:17
1225 1225
 	// Reference: packages/dates/src/components/DateRangePicker/index.tsx:79
1226
-	__( 'end date', 'event_espresso' ),
1226
+	__('end date', 'event_espresso'),
1227 1227
 
1228 1228
 	// Reference: packages/dates/src/components/DateTimePicker.tsx:17
1229 1229
 	// Reference: packages/dates/src/components/TimePicker.tsx:17
1230 1230
 	// Reference: packages/form-builder/src/state/utils.ts:433
1231
-	__( 'time', 'event_espresso' ),
1231
+	__('time', 'event_espresso'),
1232 1232
 
1233 1233
 	// Reference: packages/dates/src/constants.ts:7
1234
-	__( 'End Date & Time must be set later than the Start Date & Time', 'event_espresso' ),
1234
+	__('End Date & Time must be set later than the Start Date & Time', 'event_espresso'),
1235 1235
 
1236 1236
 	// Reference: packages/dates/src/constants.ts:9
1237
-	__( 'Start Date & Time must be set before the End Date & Time', 'event_espresso' ),
1237
+	__('Start Date & Time must be set before the End Date & Time', 'event_espresso'),
1238 1238
 
1239 1239
 	// Reference: packages/dates/src/utils/misc.ts:16
1240
-	__( 'month(s)', 'event_espresso' ),
1240
+	__('month(s)', 'event_espresso'),
1241 1241
 
1242 1242
 	// Reference: packages/dates/src/utils/misc.ts:17
1243
-	__( 'week(s)', 'event_espresso' ),
1243
+	__('week(s)', 'event_espresso'),
1244 1244
 
1245 1245
 	// Reference: packages/dates/src/utils/misc.ts:18
1246
-	__( 'day(s)', 'event_espresso' ),
1246
+	__('day(s)', 'event_espresso'),
1247 1247
 
1248 1248
 	// Reference: packages/dates/src/utils/misc.ts:19
1249
-	__( 'hour(s)', 'event_espresso' ),
1249
+	__('hour(s)', 'event_espresso'),
1250 1250
 
1251 1251
 	// Reference: packages/dates/src/utils/misc.ts:20
1252
-	__( 'minute(s)', 'event_espresso' ),
1252
+	__('minute(s)', 'event_espresso'),
1253 1253
 
1254 1254
 	// Reference: packages/edtr-services/src/apollo/mutations/useReorderEntities.ts:63
1255
-	__( 'order updated', 'event_espresso' ),
1255
+	__('order updated', 'event_espresso'),
1256 1256
 
1257 1257
 	// Reference: packages/edtr-services/src/constants.ts:24
1258
-	__( 'datetime', 'event_espresso' ),
1258
+	__('datetime', 'event_espresso'),
1259 1259
 
1260 1260
 	// Reference: packages/edtr-services/src/constants.ts:27
1261
-	__( 'price', 'event_espresso' ),
1261
+	__('price', 'event_espresso'),
1262 1262
 
1263 1263
 	// Reference: packages/edtr-services/src/constants.ts:28
1264 1264
 	// Reference: packages/tpc/src/components/price/input/Type.tsx:30
1265
-	__( 'price type', 'event_espresso' ),
1265
+	__('price type', 'event_espresso'),
1266 1266
 
1267 1267
 	// Reference: packages/edtr-services/src/utils/dateAndTime.ts:38
1268 1268
 	// Reference: packages/ui-components/src/EditDateRangeButton/EditDateRangeButton.tsx:39
1269
-	__( 'End date has been adjusted', 'event_espresso' ),
1269
+	__('End date has been adjusted', 'event_espresso'),
1270 1270
 
1271 1271
 	// Reference: packages/edtr-services/src/utils/dateAndTime.ts:59
1272
-	__( 'Required', 'event_espresso' ),
1272
+	__('Required', 'event_espresso'),
1273 1273
 
1274 1274
 	// Reference: packages/edtr-services/src/utils/dateAndTime.ts:64
1275
-	__( 'Start Date is required', 'event_espresso' ),
1275
+	__('Start Date is required', 'event_espresso'),
1276 1276
 
1277 1277
 	// Reference: packages/edtr-services/src/utils/dateAndTime.ts:68
1278
-	__( 'End Date is required', 'event_espresso' ),
1278
+	__('End Date is required', 'event_espresso'),
1279 1279
 
1280 1280
 	// Reference: packages/ee-components/src/EntityList/EntityList.tsx:30
1281
-	__( 'no results found', 'event_espresso' ),
1281
+	__('no results found', 'event_espresso'),
1282 1282
 
1283 1283
 	// Reference: packages/ee-components/src/EntityList/EntityList.tsx:31
1284
-	__( 'try changing filter settings', 'event_espresso' ),
1284
+	__('try changing filter settings', 'event_espresso'),
1285 1285
 
1286 1286
 	// Reference: packages/ee-components/src/bulkEdit/ActionCheckbox.tsx:38
1287 1287
 	/* translators: %d entity id */
1288
-	__( 'select entity with id %d', 'event_espresso' ),
1288
+	__('select entity with id %d', 'event_espresso'),
1289 1289
 
1290 1290
 	// Reference: packages/ee-components/src/bulkEdit/ActionCheckbox.tsx:41
1291
-	__( 'select all entities', 'event_espresso' ),
1291
+	__('select all entities', 'event_espresso'),
1292 1292
 
1293 1293
 	// Reference: packages/ee-components/src/bulkEdit/details/BulkEditDetails.tsx:20
1294
-	__( 'Note: ', 'event_espresso' ),
1294
+	__('Note: ', 'event_espresso'),
1295 1295
 
1296 1296
 	// Reference: packages/ee-components/src/bulkEdit/details/BulkEditDetails.tsx:20
1297
-	__( 'any changes will be applied to ALL of the selected entities.', 'event_espresso' ),
1297
+	__('any changes will be applied to ALL of the selected entities.', 'event_espresso'),
1298 1298
 
1299 1299
 	// Reference: packages/ee-components/src/bulkEdit/details/BulkEditDetails.tsx:27
1300
-	__( 'Bulk edit details', 'event_espresso' ),
1300
+	__('Bulk edit details', 'event_espresso'),
1301 1301
 
1302 1302
 	// Reference: packages/ee-components/src/bulkEdit/details/Submit.tsx:17
1303
-	__( 'Are you sure you want to bulk update the details?', 'event_espresso' ),
1303
+	__('Are you sure you want to bulk update the details?', 'event_espresso'),
1304 1304
 
1305 1305
 	// Reference: packages/ee-components/src/bulkEdit/details/Submit.tsx:18
1306
-	__( 'Bulk update details', 'event_espresso' ),
1306
+	__('Bulk update details', 'event_espresso'),
1307 1307
 
1308 1308
 	// Reference: packages/ee-components/src/filterBar/SortByControl/index.tsx:26
1309
-	__( 'set order', 'event_espresso' ),
1309
+	__('set order', 'event_espresso'),
1310 1310
 
1311 1311
 	// Reference: packages/ee-components/src/filterBar/SortByControl/index.tsx:28
1312
-	__( 'Set Custom Dates Order - this is how dates are ordered on the frontend', 'event_espresso' ),
1312
+	__('Set Custom Dates Order - this is how dates are ordered on the frontend', 'event_espresso'),
1313 1313
 
1314 1314
 	// Reference: packages/ee-components/src/filterBar/SortByControl/index.tsx:29
1315
-	__( 'Set Custom Tickets Order - this is how tickets are ordered on the frontend', 'event_espresso' ),
1315
+	__('Set Custom Tickets Order - this is how tickets are ordered on the frontend', 'event_espresso'),
1316 1316
 
1317 1317
 	// Reference: packages/form-builder/src/FormElement/FormElementToolbar.tsx:32
1318
-	__( 'delete form element', 'event_espresso' ),
1318
+	__('delete form element', 'event_espresso'),
1319 1319
 
1320 1320
 	// Reference: packages/form-builder/src/FormElement/FormElementToolbar.tsx:49
1321
-	__( 'form element settings', 'event_espresso' ),
1321
+	__('form element settings', 'event_espresso'),
1322 1322
 
1323 1323
 	// Reference: packages/form-builder/src/FormElement/FormElementToolbar.tsx:59
1324
-	__( 'copy form element', 'event_espresso' ),
1324
+	__('copy form element', 'event_espresso'),
1325 1325
 
1326 1326
 	// Reference: packages/form-builder/src/FormElement/FormElementToolbar.tsx:69
1327
-	__( 'click, hold, and drag to reorder form element', 'event_espresso' ),
1327
+	__('click, hold, and drag to reorder form element', 'event_espresso'),
1328 1328
 
1329 1329
 	// Reference: packages/form-builder/src/FormElement/Tabs/FieldOption.tsx:20
1330
-	__( 'remove option', 'event_espresso' ),
1330
+	__('remove option', 'event_espresso'),
1331 1331
 
1332 1332
 	// Reference: packages/form-builder/src/FormElement/Tabs/FieldOption.tsx:42
1333
-	__( 'value', 'event_espresso' ),
1333
+	__('value', 'event_espresso'),
1334 1334
 
1335 1335
 	// Reference: packages/form-builder/src/FormElement/Tabs/FieldOption.tsx:52
1336
-	__( 'label', 'event_espresso' ),
1336
+	__('label', 'event_espresso'),
1337 1337
 
1338 1338
 	// Reference: packages/form-builder/src/FormElement/Tabs/FieldOption.tsx:63
1339
-	__( 'click, hold, and drag to reorder field option', 'event_espresso' ),
1339
+	__('click, hold, and drag to reorder field option', 'event_espresso'),
1340 1340
 
1341 1341
 	// Reference: packages/form-builder/src/FormElement/Tabs/FieldOptions.tsx:61
1342
-	__( 'Options are the choices you give people to select from.', 'event_espresso' ),
1342
+	__('Options are the choices you give people to select from.', 'event_espresso'),
1343 1343
 
1344 1344
 	// Reference: packages/form-builder/src/FormElement/Tabs/FieldOptions.tsx:63
1345
-	__( 'The value is a simple key that will be saved to the database and the label is what is shown to the user.', 'event_espresso' ),
1345
+	__('The value is a simple key that will be saved to the database and the label is what is shown to the user.', 'event_espresso'),
1346 1346
 
1347 1347
 	// Reference: packages/form-builder/src/FormElement/Tabs/FieldOptions.tsx:96
1348
-	__( 'add new option', 'event_espresso' ),
1348
+	__('add new option', 'event_espresso'),
1349 1349
 
1350 1350
 	// Reference: packages/form-builder/src/FormElement/Tabs/FormElementTabs.tsx:26
1351 1351
 	// Reference: packages/form-builder/src/FormSection/Tabs/FormSectionTabs.tsx:25
1352
-	__( 'Styles', 'event_espresso' ),
1352
+	__('Styles', 'event_espresso'),
1353 1353
 
1354 1354
 	// Reference: packages/form-builder/src/FormElement/Tabs/FormElementTabs.tsx:30
1355
-	__( 'Validation', 'event_espresso' ),
1355
+	__('Validation', 'event_espresso'),
1356 1356
 
1357 1357
 	// Reference: packages/form-builder/src/FormElement/Tabs/InputType.tsx:18
1358
-	__( 'Change input type', 'event_espresso' ),
1358
+	__('Change input type', 'event_espresso'),
1359 1359
 
1360 1360
 	// Reference: packages/form-builder/src/FormElement/Tabs/InputType.tsx:19
1361
-	__( 'Some configurations might be lost. Are you sure you want to change the input type?', 'event_espresso' ),
1361
+	__('Some configurations might be lost. Are you sure you want to change the input type?', 'event_espresso'),
1362 1362
 
1363 1363
 	// Reference: packages/form-builder/src/FormElement/Tabs/InputType.tsx:40
1364
-	__( 'type', 'event_espresso' ),
1364
+	__('type', 'event_espresso'),
1365 1365
 
1366 1366
 	// Reference: packages/form-builder/src/FormElement/Tabs/Settings.tsx:26
1367 1367
 	// Reference: packages/form-builder/src/FormSection/Tabs/Settings.tsx:17
1368
-	__( 'public label', 'event_espresso' ),
1368
+	__('public label', 'event_espresso'),
1369 1369
 
1370 1370
 	// Reference: packages/form-builder/src/FormElement/Tabs/Settings.tsx:33
1371 1371
 	// Reference: packages/form-builder/src/FormSection/Tabs/Settings.tsx:22
1372
-	__( 'admin label', 'event_espresso' ),
1372
+	__('admin label', 'event_espresso'),
1373 1373
 
1374 1374
 	// Reference: packages/form-builder/src/FormElement/Tabs/Settings.tsx:40
1375
-	__( 'content', 'event_espresso' ),
1375
+	__('content', 'event_espresso'),
1376 1376
 
1377 1377
 	// Reference: packages/form-builder/src/FormElement/Tabs/Settings.tsx:48
1378
-	__( 'options', 'event_espresso' ),
1378
+	__('options', 'event_espresso'),
1379 1379
 
1380 1380
 	// Reference: packages/form-builder/src/FormElement/Tabs/Settings.tsx:51
1381
-	__( 'placeholder', 'event_espresso' ),
1381
+	__('placeholder', 'event_espresso'),
1382 1382
 
1383 1383
 	// Reference: packages/form-builder/src/FormElement/Tabs/Settings.tsx:57
1384
-	__( 'admin only', 'event_espresso' ),
1384
+	__('admin only', 'event_espresso'),
1385 1385
 
1386 1386
 	// Reference: packages/form-builder/src/FormElement/Tabs/Settings.tsx:62
1387
-	__( 'help text', 'event_espresso' ),
1387
+	__('help text', 'event_espresso'),
1388 1388
 
1389 1389
 	// Reference: packages/form-builder/src/FormElement/Tabs/Settings.tsx:71
1390
-	__( 'maps to', 'event_espresso' ),
1390
+	__('maps to', 'event_espresso'),
1391 1391
 
1392 1392
 	// Reference: packages/form-builder/src/FormElement/Tabs/Styles.tsx:15
1393 1393
 	// Reference: packages/form-builder/src/FormSection/Tabs/Styles.tsx:13
1394
-	__( 'css class', 'event_espresso' ),
1394
+	__('css class', 'event_espresso'),
1395 1395
 
1396 1396
 	// Reference: packages/form-builder/src/FormElement/Tabs/Styles.tsx:20
1397
-	__( 'help text css class', 'event_espresso' ),
1397
+	__('help text css class', 'event_espresso'),
1398 1398
 
1399 1399
 	// Reference: packages/form-builder/src/FormElement/Tabs/Styles.tsx:27
1400
-	__( 'size', 'event_espresso' ),
1400
+	__('size', 'event_espresso'),
1401 1401
 
1402 1402
 	// Reference: packages/form-builder/src/FormElement/Tabs/Styles.tsx:35
1403
-	__( 'step', 'event_espresso' ),
1403
+	__('step', 'event_espresso'),
1404 1404
 
1405 1405
 	// Reference: packages/form-builder/src/FormElement/Tabs/Styles.tsx:41
1406
-	__( 'maxlength', 'event_espresso' ),
1406
+	__('maxlength', 'event_espresso'),
1407 1407
 
1408 1408
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:123
1409
-	__( 'min', 'event_espresso' ),
1409
+	__('min', 'event_espresso'),
1410 1410
 
1411 1411
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:128
1412
-	__( 'max', 'event_espresso' ),
1412
+	__('max', 'event_espresso'),
1413 1413
 
1414 1414
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:28
1415
-	__( 'Germany', 'event_espresso' ),
1415
+	__('Germany', 'event_espresso'),
1416 1416
 
1417 1417
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:32
1418
-	__( 'France', 'event_espresso' ),
1418
+	__('France', 'event_espresso'),
1419 1419
 
1420 1420
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:36
1421
-	__( 'United Kingdom', 'event_espresso' ),
1421
+	__('United Kingdom', 'event_espresso'),
1422 1422
 
1423 1423
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:40
1424
-	__( 'United States', 'event_espresso' ),
1424
+	__('United States', 'event_espresso'),
1425 1425
 
1426 1426
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:44
1427
-	__( 'Custom', 'event_espresso' ),
1427
+	__('Custom', 'event_espresso'),
1428 1428
 
1429 1429
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:54
1430
-	__( 'required', 'event_espresso' ),
1430
+	__('required', 'event_espresso'),
1431 1431
 
1432 1432
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:59
1433
-	__( 'required text', 'event_espresso' ),
1433
+	__('required text', 'event_espresso'),
1434 1434
 
1435 1435
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:66
1436
-	__( 'autocomplete', 'event_espresso' ),
1436
+	__('autocomplete', 'event_espresso'),
1437 1437
 
1438 1438
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:74
1439
-	__( 'custom format', 'event_espresso' ),
1439
+	__('custom format', 'event_espresso'),
1440 1440
 
1441 1441
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:75
1442
-	__( 'format', 'event_espresso' ),
1442
+	__('format', 'event_espresso'),
1443 1443
 
1444 1444
 	// Reference: packages/form-builder/src/FormElement/Tabs/Validation.tsx:83
1445
-	__( 'pattern', 'event_espresso' ),
1445
+	__('pattern', 'event_espresso'),
1446 1446
 
1447 1447
 	// Reference: packages/form-builder/src/FormSection/AddFormElementPopover.tsx:110
1448
-	__( 'add new form element', 'event_espresso' ),
1448
+	__('add new form element', 'event_espresso'),
1449 1449
 
1450 1450
 	// Reference: packages/form-builder/src/FormSection/AddFormElementPopover.tsx:117
1451 1451
 	// Reference: packages/form/src/renderers/RepeatableRenderer.tsx:52
1452
-	__( 'Add', 'event_espresso' ),
1452
+	__('Add', 'event_espresso'),
1453 1453
 
1454 1454
 	// Reference: packages/form-builder/src/FormSection/AddFormElementPopover.tsx:76
1455
-	__( 'Add Form Element', 'event_espresso' ),
1455
+	__('Add Form Element', 'event_espresso'),
1456 1456
 
1457 1457
 	// Reference: packages/form-builder/src/FormSection/AddFormElementPopover.tsx:85
1458
-	__( 'form element order can be changed after adding by using the drag handles in the form element toolbar', 'event_espresso' ),
1458
+	__('form element order can be changed after adding by using the drag handles in the form element toolbar', 'event_espresso'),
1459 1459
 
1460 1460
 	// Reference: packages/form-builder/src/FormSection/AddFormElementPopover.tsx:92
1461
-	__( 'load existing form section', 'event_espresso' ),
1461
+	__('load existing form section', 'event_espresso'),
1462 1462
 
1463 1463
 	// Reference: packages/form-builder/src/FormSection/FormSectionToolbar.tsx:32
1464
-	__( 'delete form section', 'event_espresso' ),
1464
+	__('delete form section', 'event_espresso'),
1465 1465
 
1466 1466
 	// Reference: packages/form-builder/src/FormSection/FormSectionToolbar.tsx:47
1467
-	__( 'form section settings', 'event_espresso' ),
1467
+	__('form section settings', 'event_espresso'),
1468 1468
 
1469 1469
 	// Reference: packages/form-builder/src/FormSection/FormSectionToolbar.tsx:57
1470
-	__( 'copy form section', 'event_espresso' ),
1470
+	__('copy form section', 'event_espresso'),
1471 1471
 
1472 1472
 	// Reference: packages/form-builder/src/FormSection/FormSectionToolbar.tsx:74
1473
-	__( 'click, hold, and drag to reorder form section', 'event_espresso' ),
1473
+	__('click, hold, and drag to reorder form section', 'event_espresso'),
1474 1474
 
1475 1475
 	// Reference: packages/form-builder/src/FormSection/FormSections.tsx:26
1476
-	__( 'Add Form Section', 'event_espresso' ),
1476
+	__('Add Form Section', 'event_espresso'),
1477 1477
 
1478 1478
 	// Reference: packages/form-builder/src/FormSection/SaveSection.tsx:47
1479
-	__( 'save form section for use in other forms', 'event_espresso' ),
1479
+	__('save form section for use in other forms', 'event_espresso'),
1480 1480
 
1481 1481
 	// Reference: packages/form-builder/src/FormSection/SaveSection.tsx:51
1482
-	__( 'save as', 'event_espresso' ),
1482
+	__('save as', 'event_espresso'),
1483 1483
 
1484 1484
 	// Reference: packages/form-builder/src/FormSection/SaveSection.tsx:55
1485
-	__( 'default', 'event_espresso' ),
1485
+	__('default', 'event_espresso'),
1486 1486
 
1487 1487
 	// Reference: packages/form-builder/src/FormSection/SaveSection.tsx:58
1488
-	__( ' a copy of this form section will be automatically added to ALL new events', 'event_espresso' ),
1488
+	__(' a copy of this form section will be automatically added to ALL new events', 'event_espresso'),
1489 1489
 
1490 1490
 	// Reference: packages/form-builder/src/FormSection/SaveSection.tsx:61
1491
-	__( 'shared', 'event_espresso' ),
1491
+	__('shared', 'event_espresso'),
1492 1492
 
1493 1493
 	// Reference: packages/form-builder/src/FormSection/SaveSection.tsx:64
1494
-	__( 'a copy of this form section will be saved for use in other events but not loaded by default', 'event_espresso' ),
1494
+	__('a copy of this form section will be saved for use in other events but not loaded by default', 'event_espresso'),
1495 1495
 
1496 1496
 	// Reference: packages/form-builder/src/FormSection/Tabs/Settings.tsx:27
1497
-	__( 'show label', 'event_espresso' ),
1497
+	__('show label', 'event_espresso'),
1498 1498
 
1499 1499
 	// Reference: packages/form-builder/src/FormSection/Tabs/Settings.tsx:33
1500
-	__( 'applies to', 'event_espresso' ),
1500
+	__('applies to', 'event_espresso'),
1501 1501
 
1502 1502
 	// Reference: packages/form-builder/src/constants.ts:102
1503 1503
 	// Reference: packages/form-builder/src/state/utils.ts:436
1504
-	__( 'URL', 'event_espresso' ),
1504
+	__('URL', 'event_espresso'),
1505 1505
 
1506 1506
 	// Reference: packages/form-builder/src/constants.ts:104
1507
-	__( 'adds a text input for entering a URL address', 'event_espresso' ),
1507
+	__('adds a text input for entering a URL address', 'event_espresso'),
1508 1508
 
1509 1509
 	// Reference: packages/form-builder/src/constants.ts:107
1510
-	__( 'Date', 'event_espresso' ),
1510
+	__('Date', 'event_espresso'),
1511 1511
 
1512 1512
 	// Reference: packages/form-builder/src/constants.ts:109
1513
-	__( 'adds a text input that allows users to enter a date directly via keyboard or a datepicker', 'event_espresso' ),
1513
+	__('adds a text input that allows users to enter a date directly via keyboard or a datepicker', 'event_espresso'),
1514 1514
 
1515 1515
 	// Reference: packages/form-builder/src/constants.ts:112
1516 1516
 	// Reference: packages/form-builder/src/state/utils.ts:369
1517
-	__( 'Local Date', 'event_espresso' ),
1517
+	__('Local Date', 'event_espresso'),
1518 1518
 
1519 1519
 	// Reference: packages/form-builder/src/constants.ts:117
1520
-	__( 'Month', 'event_espresso' ),
1520
+	__('Month', 'event_espresso'),
1521 1521
 
1522 1522
 	// Reference: packages/form-builder/src/constants.ts:119
1523
-	__( 'adds a text input that allows users to enter a month and year directly via keyboard or a datepicker', 'event_espresso' ),
1523
+	__('adds a text input that allows users to enter a month and year directly via keyboard or a datepicker', 'event_espresso'),
1524 1524
 
1525 1525
 	// Reference: packages/form-builder/src/constants.ts:122
1526
-	__( 'Time', 'event_espresso' ),
1526
+	__('Time', 'event_espresso'),
1527 1527
 
1528 1528
 	// Reference: packages/form-builder/src/constants.ts:124
1529
-	__( 'adds a text input that allows users to enter a time directly via keyboard or a timepicker', 'event_espresso' ),
1529
+	__('adds a text input that allows users to enter a time directly via keyboard or a timepicker', 'event_espresso'),
1530 1530
 
1531 1531
 	// Reference: packages/form-builder/src/constants.ts:127
1532
-	__( 'Week', 'event_espresso' ),
1532
+	__('Week', 'event_espresso'),
1533 1533
 
1534 1534
 	// Reference: packages/form-builder/src/constants.ts:129
1535
-	__( 'adds a text input that allows users to enter a week and year directly via keyboard or a datepicker', 'event_espresso' ),
1535
+	__('adds a text input that allows users to enter a week and year directly via keyboard or a datepicker', 'event_espresso'),
1536 1536
 
1537 1537
 	// Reference: packages/form-builder/src/constants.ts:132
1538
-	__( 'Day Selector', 'event_espresso' ),
1538
+	__('Day Selector', 'event_espresso'),
1539 1539
 
1540 1540
 	// Reference: packages/form-builder/src/constants.ts:134
1541
-	__( 'adds a dropdown selector that allows users to select the day of the month (01 to 31)', 'event_espresso' ),
1541
+	__('adds a dropdown selector that allows users to select the day of the month (01 to 31)', 'event_espresso'),
1542 1542
 
1543 1543
 	// Reference: packages/form-builder/src/constants.ts:137
1544
-	__( 'Month Selector', 'event_espresso' ),
1544
+	__('Month Selector', 'event_espresso'),
1545 1545
 
1546 1546
 	// Reference: packages/form-builder/src/constants.ts:139
1547
-	__( 'adds a dropdown selector that allows users to select the month of the year (01 to 12)', 'event_espresso' ),
1547
+	__('adds a dropdown selector that allows users to select the month of the year (01 to 12)', 'event_espresso'),
1548 1548
 
1549 1549
 	// Reference: packages/form-builder/src/constants.ts:142
1550
-	__( 'Year Selector', 'event_espresso' ),
1550
+	__('Year Selector', 'event_espresso'),
1551 1551
 
1552 1552
 	// Reference: packages/form-builder/src/constants.ts:144
1553
-	__( 'adds a dropdown selector that allows users to select the year from a configurable range', 'event_espresso' ),
1553
+	__('adds a dropdown selector that allows users to select the year from a configurable range', 'event_espresso'),
1554 1554
 
1555 1555
 	// Reference: packages/form-builder/src/constants.ts:147
1556
-	__( 'Radio Buttons', 'event_espresso' ),
1556
+	__('Radio Buttons', 'event_espresso'),
1557 1557
 
1558 1558
 	// Reference: packages/form-builder/src/constants.ts:149
1559
-	__( 'adds one or more radio buttons that allow users to only select one option from those provided', 'event_espresso' ),
1559
+	__('adds one or more radio buttons that allow users to only select one option from those provided', 'event_espresso'),
1560 1560
 
1561 1561
 	// Reference: packages/form-builder/src/constants.ts:152
1562 1562
 	// Reference: packages/form-builder/src/state/utils.ts:375
1563
-	__( 'Decimal Number', 'event_espresso' ),
1563
+	__('Decimal Number', 'event_espresso'),
1564 1564
 
1565 1565
 	// Reference: packages/form-builder/src/constants.ts:154
1566
-	__( 'adds a text input that only accepts numbers whose value is a decimal (float)', 'event_espresso' ),
1566
+	__('adds a text input that only accepts numbers whose value is a decimal (float)', 'event_espresso'),
1567 1567
 
1568 1568
 	// Reference: packages/form-builder/src/constants.ts:157
1569 1569
 	// Reference: packages/form-builder/src/state/utils.ts:378
1570
-	__( 'Whole Number', 'event_espresso' ),
1570
+	__('Whole Number', 'event_espresso'),
1571 1571
 
1572 1572
 	// Reference: packages/form-builder/src/constants.ts:159
1573
-	__( 'adds a text input that only accepts numbers whose value is an integer (whole number)', 'event_espresso' ),
1573
+	__('adds a text input that only accepts numbers whose value is an integer (whole number)', 'event_espresso'),
1574 1574
 
1575 1575
 	// Reference: packages/form-builder/src/constants.ts:162
1576
-	__( 'Number Range', 'event_espresso' ),
1576
+	__('Number Range', 'event_espresso'),
1577 1577
 
1578 1578
 	// Reference: packages/form-builder/src/constants.ts:167
1579
-	__( 'Phone Number', 'event_espresso' ),
1579
+	__('Phone Number', 'event_espresso'),
1580 1580
 
1581 1581
 	// Reference: packages/form-builder/src/constants.ts:172
1582
-	__( 'Dropdown', 'event_espresso' ),
1582
+	__('Dropdown', 'event_espresso'),
1583 1583
 
1584 1584
 	// Reference: packages/form-builder/src/constants.ts:174
1585
-	__( 'adds a dropdown selector that accepts a single value', 'event_espresso' ),
1585
+	__('adds a dropdown selector that accepts a single value', 'event_espresso'),
1586 1586
 
1587 1587
 	// Reference: packages/form-builder/src/constants.ts:177
1588
-	__( 'Multi Select', 'event_espresso' ),
1588
+	__('Multi Select', 'event_espresso'),
1589 1589
 
1590 1590
 	// Reference: packages/form-builder/src/constants.ts:179
1591
-	__( 'adds a dropdown selector that accepts multiple values', 'event_espresso' ),
1591
+	__('adds a dropdown selector that accepts multiple values', 'event_espresso'),
1592 1592
 
1593 1593
 	// Reference: packages/form-builder/src/constants.ts:182
1594
-	__( 'Toggle/Switch', 'event_espresso' ),
1594
+	__('Toggle/Switch', 'event_espresso'),
1595 1595
 
1596 1596
 	// Reference: packages/form-builder/src/constants.ts:184
1597
-	__( 'adds a toggle or a switch to accept true or false value', 'event_espresso' ),
1597
+	__('adds a toggle or a switch to accept true or false value', 'event_espresso'),
1598 1598
 
1599 1599
 	// Reference: packages/form-builder/src/constants.ts:187
1600
-	__( 'Multi Checkbox', 'event_espresso' ),
1600
+	__('Multi Checkbox', 'event_espresso'),
1601 1601
 
1602 1602
 	// Reference: packages/form-builder/src/constants.ts:189
1603
-	__( 'adds checkboxes that allow users to select zero or more options from those provided', 'event_espresso' ),
1603
+	__('adds checkboxes that allow users to select zero or more options from those provided', 'event_espresso'),
1604 1604
 
1605 1605
 	// Reference: packages/form-builder/src/constants.ts:192
1606
-	__( 'Country Selector', 'event_espresso' ),
1606
+	__('Country Selector', 'event_espresso'),
1607 1607
 
1608 1608
 	// Reference: packages/form-builder/src/constants.ts:194
1609
-	__( 'adds a dropdown selector populated with names of countries that are enabled for the site', 'event_espresso' ),
1609
+	__('adds a dropdown selector populated with names of countries that are enabled for the site', 'event_espresso'),
1610 1610
 
1611 1611
 	// Reference: packages/form-builder/src/constants.ts:197
1612
-	__( 'State Selector', 'event_espresso' ),
1612
+	__('State Selector', 'event_espresso'),
1613 1613
 
1614 1614
 	// Reference: packages/form-builder/src/constants.ts:202
1615
-	__( 'Button', 'event_espresso' ),
1615
+	__('Button', 'event_espresso'),
1616 1616
 
1617 1617
 	// Reference: packages/form-builder/src/constants.ts:204
1618
-	__( 'adds a button to the form that can be used for triggering fucntionality (requires custom coding)', 'event_espresso' ),
1618
+	__('adds a button to the form that can be used for triggering fucntionality (requires custom coding)', 'event_espresso'),
1619 1619
 
1620 1620
 	// Reference: packages/form-builder/src/constants.ts:207
1621
-	__( 'Reset Button', 'event_espresso' ),
1621
+	__('Reset Button', 'event_espresso'),
1622 1622
 
1623 1623
 	// Reference: packages/form-builder/src/constants.ts:209
1624
-	__( 'adds a button that will reset the form back to its original state.', 'event_espresso' ),
1624
+	__('adds a button that will reset the form back to its original state.', 'event_espresso'),
1625 1625
 
1626 1626
 	// Reference: packages/form-builder/src/constants.ts:55
1627
-	__( 'Form Section', 'event_espresso' ),
1627
+	__('Form Section', 'event_espresso'),
1628 1628
 
1629 1629
 	// Reference: packages/form-builder/src/constants.ts:57
1630
-	__( 'Used for creating logical groupings for questions and form elements. Need to add a heading or description? Use the HTML form element.', 'event_espresso' ),
1630
+	__('Used for creating logical groupings for questions and form elements. Need to add a heading or description? Use the HTML form element.', 'event_espresso'),
1631 1631
 
1632 1632
 	// Reference: packages/form-builder/src/constants.ts:62
1633
-	__( 'HTML Block', 'event_espresso' ),
1633
+	__('HTML Block', 'event_espresso'),
1634 1634
 
1635 1635
 	// Reference: packages/form-builder/src/constants.ts:64
1636
-	__( 'allows you to add HTML like headings or text paragraphs to your form', 'event_espresso' ),
1636
+	__('allows you to add HTML like headings or text paragraphs to your form', 'event_espresso'),
1637 1637
 
1638 1638
 	// Reference: packages/form-builder/src/constants.ts:69
1639
-	__( 'adds a text input that only accepts plain text', 'event_espresso' ),
1639
+	__('adds a text input that only accepts plain text', 'event_espresso'),
1640 1640
 
1641 1641
 	// Reference: packages/form-builder/src/constants.ts:72
1642
-	__( 'Plain Text Area', 'event_espresso' ),
1642
+	__('Plain Text Area', 'event_espresso'),
1643 1643
 
1644 1644
 	// Reference: packages/form-builder/src/constants.ts:74
1645
-	__( 'adds a textarea block that only accepts plain text', 'event_espresso' ),
1645
+	__('adds a textarea block that only accepts plain text', 'event_espresso'),
1646 1646
 
1647 1647
 	// Reference: packages/form-builder/src/constants.ts:77
1648
-	__( 'HTML Text Area', 'event_espresso' ),
1648
+	__('HTML Text Area', 'event_espresso'),
1649 1649
 
1650 1650
 	// Reference: packages/form-builder/src/constants.ts:79
1651
-	__( 'adds a textarea block that accepts text including simple HTML markup', 'event_espresso' ),
1651
+	__('adds a textarea block that accepts text including simple HTML markup', 'event_espresso'),
1652 1652
 
1653 1653
 	// Reference: packages/form-builder/src/constants.ts:84
1654
-	__( 'adds a text input that only accepts a valid email address', 'event_espresso' ),
1654
+	__('adds a text input that only accepts a valid email address', 'event_espresso'),
1655 1655
 
1656 1656
 	// Reference: packages/form-builder/src/constants.ts:87
1657
-	__( 'Email Confirmation', 'event_espresso' ),
1657
+	__('Email Confirmation', 'event_espresso'),
1658 1658
 
1659 1659
 	// Reference: packages/form-builder/src/constants.ts:92
1660
-	__( 'Password', 'event_espresso' ),
1660
+	__('Password', 'event_espresso'),
1661 1661
 
1662 1662
 	// Reference: packages/form-builder/src/constants.ts:94
1663
-	__( 'adds a text input that accepts text but masks what the user enters', 'event_espresso' ),
1663
+	__('adds a text input that accepts text but masks what the user enters', 'event_espresso'),
1664 1664
 
1665 1665
 	// Reference: packages/form-builder/src/constants.ts:97
1666
-	__( 'Password Confirmation', 'event_espresso' ),
1666
+	__('Password Confirmation', 'event_espresso'),
1667 1667
 
1668 1668
 	// Reference: packages/form-builder/src/data/useElementMutator.ts:54
1669
-	__( 'element', 'event_espresso' ),
1669
+	__('element', 'event_espresso'),
1670 1670
 
1671 1671
 	// Reference: packages/form-builder/src/data/useSectionMutator.ts:54
1672
-	__( 'section', 'event_espresso' ),
1672
+	__('section', 'event_espresso'),
1673 1673
 
1674 1674
 	// Reference: packages/form-builder/src/state/utils.ts:360
1675
-	__( 'click', 'event_espresso' ),
1675
+	__('click', 'event_espresso'),
1676 1676
 
1677 1677
 	// Reference: packages/form-builder/src/state/utils.ts:363
1678
-	__( 'checkboxes', 'event_espresso' ),
1678
+	__('checkboxes', 'event_espresso'),
1679 1679
 
1680 1680
 	// Reference: packages/form-builder/src/state/utils.ts:366
1681
-	__( 'date', 'event_espresso' ),
1681
+	__('date', 'event_espresso'),
1682 1682
 
1683 1683
 	// Reference: packages/form-builder/src/state/utils.ts:372
1684
-	__( 'day', 'event_espresso' ),
1684
+	__('day', 'event_espresso'),
1685 1685
 
1686 1686
 	// Reference: packages/form-builder/src/state/utils.ts:381
1687
-	__( 'email address', 'event_espresso' ),
1687
+	__('email address', 'event_espresso'),
1688 1688
 
1689 1689
 	// Reference: packages/form-builder/src/state/utils.ts:384
1690
-	__( 'confirm email address', 'event_espresso' ),
1690
+	__('confirm email address', 'event_espresso'),
1691 1691
 
1692 1692
 	// Reference: packages/form-builder/src/state/utils.ts:388
1693
-	__( 'month', 'event_espresso' ),
1693
+	__('month', 'event_espresso'),
1694 1694
 
1695 1695
 	// Reference: packages/form-builder/src/state/utils.ts:391
1696
-	__( 'password', 'event_espresso' ),
1696
+	__('password', 'event_espresso'),
1697 1697
 
1698 1698
 	// Reference: packages/form-builder/src/state/utils.ts:394
1699
-	__( 'confirm password', 'event_espresso' ),
1699
+	__('confirm password', 'event_espresso'),
1700 1700
 
1701 1701
 	// Reference: packages/form-builder/src/state/utils.ts:397
1702
-	__( 'radio buttons', 'event_espresso' ),
1702
+	__('radio buttons', 'event_espresso'),
1703 1703
 
1704 1704
 	// Reference: packages/form-builder/src/state/utils.ts:400
1705
-	__( 'number range', 'event_espresso' ),
1705
+	__('number range', 'event_espresso'),
1706 1706
 
1707 1707
 	// Reference: packages/form-builder/src/state/utils.ts:403
1708
-	__( 'selection dropdown', 'event_espresso' ),
1708
+	__('selection dropdown', 'event_espresso'),
1709 1709
 
1710 1710
 	// Reference: packages/form-builder/src/state/utils.ts:406
1711
-	__( 'country', 'event_espresso' ),
1711
+	__('country', 'event_espresso'),
1712 1712
 
1713 1713
 	// Reference: packages/form-builder/src/state/utils.ts:409
1714
-	__( 'multi-select dropdown', 'event_espresso' ),
1714
+	__('multi-select dropdown', 'event_espresso'),
1715 1715
 
1716 1716
 	// Reference: packages/form-builder/src/state/utils.ts:412
1717
-	__( 'state/province', 'event_espresso' ),
1717
+	__('state/province', 'event_espresso'),
1718 1718
 
1719 1719
 	// Reference: packages/form-builder/src/state/utils.ts:415
1720
-	__( 'on/off switch', 'event_espresso' ),
1720
+	__('on/off switch', 'event_espresso'),
1721 1721
 
1722 1722
 	// Reference: packages/form-builder/src/state/utils.ts:418
1723
-	__( 'reset', 'event_espresso' ),
1723
+	__('reset', 'event_espresso'),
1724 1724
 
1725 1725
 	// Reference: packages/form-builder/src/state/utils.ts:421
1726
-	__( 'phone number', 'event_espresso' ),
1726
+	__('phone number', 'event_espresso'),
1727 1727
 
1728 1728
 	// Reference: packages/form-builder/src/state/utils.ts:424
1729
-	__( 'text', 'event_espresso' ),
1729
+	__('text', 'event_espresso'),
1730 1730
 
1731 1731
 	// Reference: packages/form-builder/src/state/utils.ts:427
1732
-	__( 'simple textarea', 'event_espresso' ),
1732
+	__('simple textarea', 'event_espresso'),
1733 1733
 
1734 1734
 	// Reference: packages/form-builder/src/state/utils.ts:430
1735
-	__( 'html textarea', 'event_espresso' ),
1735
+	__('html textarea', 'event_espresso'),
1736 1736
 
1737 1737
 	// Reference: packages/form-builder/src/state/utils.ts:439
1738
-	__( 'week', 'event_espresso' ),
1738
+	__('week', 'event_espresso'),
1739 1739
 
1740 1740
 	// Reference: packages/form-builder/src/state/utils.ts:442
1741
-	__( 'year', 'event_espresso' ),
1741
+	__('year', 'event_espresso'),
1742 1742
 
1743 1743
 	// Reference: packages/form/src/adapters/WPMediaImage.tsx:13
1744
-	__( 'Select Image', 'event_espresso' ),
1744
+	__('Select Image', 'event_espresso'),
1745 1745
 
1746 1746
 	// Reference: packages/form/src/adapters/WPMediaImage.tsx:45
1747 1747
 	// Reference: packages/rich-text-editor/src/components/AdvancedTextEditor/toolbarButtons/WPMedia.tsx:11
1748 1748
 	// Reference: packages/rich-text-editor/src/rte-old/components/toolbarButtons/WPMedia.tsx:12
1749 1749
 	// Reference: packages/ui-components/src/SimpleEntityList/EntityTemplate.tsx:32
1750
-	__( 'Select', 'event_espresso' ),
1750
+	__('Select', 'event_espresso'),
1751 1751
 
1752 1752
 	// Reference: packages/form/src/renderers/FormRenderer.tsx:51
1753
-	__( 'Form Errors', 'event_espresso' ),
1753
+	__('Form Errors', 'event_espresso'),
1754 1754
 
1755 1755
 	// Reference: packages/form/src/renderers/RepeatableRenderer.tsx:36
1756 1756
 	/* translators: %d the entry number */
1757
-	__( 'Entry %d', 'event_espresso' ),
1757
+	__('Entry %d', 'event_espresso'),
1758 1758
 
1759 1759
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:11
1760 1760
 	// Reference: packages/helpers/src/tickets/getStatusTextLabel.ts:17
1761
-	__( 'sold out', 'event_espresso' ),
1761
+	__('sold out', 'event_espresso'),
1762 1762
 
1763 1763
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:14
1764 1764
 	// Reference: packages/helpers/src/tickets/getStatusTextLabel.ts:14
1765
-	__( 'expired', 'event_espresso' ),
1765
+	__('expired', 'event_espresso'),
1766 1766
 
1767 1767
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:17
1768
-	__( 'upcoming', 'event_espresso' ),
1768
+	__('upcoming', 'event_espresso'),
1769 1769
 
1770 1770
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:20
1771
-	__( 'active', 'event_espresso' ),
1771
+	__('active', 'event_espresso'),
1772 1772
 
1773 1773
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:23
1774 1774
 	// Reference: packages/helpers/src/tickets/getStatusTextLabel.ts:11
1775
-	__( 'trashed', 'event_espresso' ),
1775
+	__('trashed', 'event_espresso'),
1776 1776
 
1777 1777
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:26
1778
-	__( 'cancelled', 'event_espresso' ),
1778
+	__('cancelled', 'event_espresso'),
1779 1779
 
1780 1780
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:29
1781
-	__( 'postponed', 'event_espresso' ),
1781
+	__('postponed', 'event_espresso'),
1782 1782
 
1783 1783
 	// Reference: packages/helpers/src/datetimes/getStatusTextLabel.ts:33
1784
-	__( 'inactive', 'event_espresso' ),
1784
+	__('inactive', 'event_espresso'),
1785 1785
 
1786 1786
 	// Reference: packages/helpers/src/tickets/getStatusTextLabel.ts:20
1787
-	__( 'pending', 'event_espresso' ),
1787
+	__('pending', 'event_espresso'),
1788 1788
 
1789 1789
 	// Reference: packages/helpers/src/tickets/getStatusTextLabel.ts:23
1790
-	__( 'on sale', 'event_espresso' ),
1790
+	__('on sale', 'event_espresso'),
1791 1791
 
1792 1792
 	// Reference: packages/helpers/src/tickets/ticketVisibilityOptions.ts:6
1793
-	__( 'Where the ticket can be viewed throughout the UI. ', 'event_espresso' ),
1793
+	__('Where the ticket can be viewed throughout the UI. ', 'event_espresso'),
1794 1794
 
1795 1795
 	// Reference: packages/predicates/src/registration/statusOptions.ts:16
1796
-	__( 'Declined', 'event_espresso' ),
1796
+	__('Declined', 'event_espresso'),
1797 1797
 
1798 1798
 	// Reference: packages/predicates/src/registration/statusOptions.ts:21
1799
-	__( 'Incomplete', 'event_espresso' ),
1799
+	__('Incomplete', 'event_espresso'),
1800 1800
 
1801 1801
 	// Reference: packages/predicates/src/registration/statusOptions.ts:26
1802
-	__( 'Not Approved', 'event_espresso' ),
1802
+	__('Not Approved', 'event_espresso'),
1803 1803
 
1804 1804
 	// Reference: packages/predicates/src/registration/statusOptions.ts:31
1805
-	__( 'Pending Payment', 'event_espresso' ),
1805
+	__('Pending Payment', 'event_espresso'),
1806 1806
 
1807 1807
 	// Reference: packages/predicates/src/registration/statusOptions.ts:36
1808
-	__( 'Wait List', 'event_espresso' ),
1808
+	__('Wait List', 'event_espresso'),
1809 1809
 
1810 1810
 	// Reference: packages/predicates/src/registration/statusOptions.ts:6
1811
-	__( 'Approved', 'event_espresso' ),
1811
+	__('Approved', 'event_espresso'),
1812 1812
 
1813 1813
 	// Reference: packages/rich-text-editor/src/components/AdvancedTextEditor/toolbarButtons/WPMedia.tsx:9
1814 1814
 	// Reference: packages/rich-text-editor/src/rte-old/components/toolbarButtons/WPMedia.tsx:10
1815
-	__( 'Select media', 'event_espresso' ),
1815
+	__('Select media', 'event_espresso'),
1816 1816
 
1817 1817
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/RichTextEditor.tsx:84
1818
-	__( 'Write something…', 'event_espresso' ),
1818
+	__('Write something…', 'event_espresso'),
1819 1819
 
1820 1820
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/Toolbar.tsx:20
1821
-	__( 'RTE Toolbar', 'event_espresso' ),
1821
+	__('RTE Toolbar', 'event_espresso'),
1822 1822
 
1823 1823
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:11
1824
-	__( 'Normal', 'event_espresso' ),
1824
+	__('Normal', 'event_espresso'),
1825 1825
 
1826 1826
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:12
1827
-	__( 'H1', 'event_espresso' ),
1827
+	__('H1', 'event_espresso'),
1828 1828
 
1829 1829
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:13
1830
-	__( 'H2', 'event_espresso' ),
1830
+	__('H2', 'event_espresso'),
1831 1831
 
1832 1832
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:14
1833
-	__( 'H3', 'event_espresso' ),
1833
+	__('H3', 'event_espresso'),
1834 1834
 
1835 1835
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:15
1836
-	__( 'H4', 'event_espresso' ),
1836
+	__('H4', 'event_espresso'),
1837 1837
 
1838 1838
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:16
1839
-	__( 'H5', 'event_espresso' ),
1839
+	__('H5', 'event_espresso'),
1840 1840
 
1841 1841
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:17
1842
-	__( 'H6', 'event_espresso' ),
1842
+	__('H6', 'event_espresso'),
1843 1843
 
1844 1844
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:18
1845
-	__( 'Block quote', 'event_espresso' ),
1845
+	__('Block quote', 'event_espresso'),
1846 1846
 
1847 1847
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/blockType/Component.tsx:19
1848
-	__( 'Code', 'event_espresso' ),
1848
+	__('Code', 'event_espresso'),
1849 1849
 
1850 1850
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/colorPicker/Component.tsx:36
1851
-	__( 'Set color', 'event_espresso' ),
1851
+	__('Set color', 'event_espresso'),
1852 1852
 
1853 1853
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/colorPicker/Component.tsx:45
1854
-	__( 'Text color', 'event_espresso' ),
1854
+	__('Text color', 'event_espresso'),
1855 1855
 
1856 1856
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/colorPicker/Component.tsx:47
1857
-	__( 'Background color', 'event_espresso' ),
1857
+	__('Background color', 'event_espresso'),
1858 1858
 
1859 1859
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/image/Component.tsx:39
1860
-	__( 'Add image', 'event_espresso' ),
1860
+	__('Add image', 'event_espresso'),
1861 1861
 
1862 1862
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/image/Component.tsx:51
1863
-	__( 'Image URL', 'event_espresso' ),
1863
+	__('Image URL', 'event_espresso'),
1864 1864
 
1865 1865
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/image/Component.tsx:55
1866
-	__( 'Alt text', 'event_espresso' ),
1866
+	__('Alt text', 'event_espresso'),
1867 1867
 
1868 1868
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/image/Component.tsx:56
1869
-	__( 'Width', 'event_espresso' ),
1869
+	__('Width', 'event_espresso'),
1870 1870
 
1871 1871
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/image/Component.tsx:60
1872
-	__( 'Height', 'event_espresso' ),
1872
+	__('Height', 'event_espresso'),
1873 1873
 
1874 1874
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/link/Component.tsx:54
1875
-	__( 'Edit link', 'event_espresso' ),
1875
+	__('Edit link', 'event_espresso'),
1876 1876
 
1877 1877
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/link/Component.tsx:64
1878
-	__( 'URL title', 'event_espresso' ),
1878
+	__('URL title', 'event_espresso'),
1879 1879
 
1880 1880
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/list/Component.tsx:11
1881
-	__( 'Unordered list', 'event_espresso' ),
1881
+	__('Unordered list', 'event_espresso'),
1882 1882
 
1883 1883
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/list/Component.tsx:12
1884
-	__( 'Ordered list', 'event_espresso' ),
1884
+	__('Ordered list', 'event_espresso'),
1885 1885
 
1886 1886
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/list/Component.tsx:13
1887 1887
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/textAlign/Component.tsx:13
1888
-	__( 'Indent', 'event_espresso' ),
1888
+	__('Indent', 'event_espresso'),
1889 1889
 
1890 1890
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/list/Component.tsx:14
1891 1891
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/textAlign/Component.tsx:14
1892
-	__( 'Outdent', 'event_espresso' ),
1892
+	__('Outdent', 'event_espresso'),
1893 1893
 
1894 1894
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/textAlign/Component.tsx:11
1895
-	__( 'Unordered textalign', 'event_espresso' ),
1895
+	__('Unordered textalign', 'event_espresso'),
1896 1896
 
1897 1897
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/Toolbar/controls/textAlign/Component.tsx:12
1898
-	__( 'Ordered textalign', 'event_espresso' ),
1898
+	__('Ordered textalign', 'event_espresso'),
1899 1899
 
1900 1900
 	// Reference: packages/rich-text-editor/src/components/RichTextEditor/render/Image/Toolbar.tsx:32
1901
-	__( 'Image toolbar', 'event_espresso' ),
1901
+	__('Image toolbar', 'event_espresso'),
1902 1902
 
1903 1903
 	// Reference: packages/rich-text-editor/src/components/WithEditMode/WithEditMode.tsx:62
1904 1904
 	// Reference: packages/rich-text-editor/src/rte-old/components/RTEWithEditMode/RTEWithEditMode.tsx:35
1905
-	__( 'Visual editor', 'event_espresso' ),
1905
+	__('Visual editor', 'event_espresso'),
1906 1906
 
1907 1907
 	// Reference: packages/rich-text-editor/src/components/WithEditMode/WithEditMode.tsx:66
1908 1908
 	// Reference: packages/rich-text-editor/src/rte-old/components/RTEWithEditMode/RTEWithEditMode.tsx:39
1909
-	__( 'HTML editor', 'event_espresso' ),
1909
+	__('HTML editor', 'event_espresso'),
1910 1910
 
1911 1911
 	// Reference: packages/rich-text-editor/src/rte-old/components/toolbarButtons/WPMedia.tsx:68
1912
-	__( 'Add Media', 'event_espresso' ),
1912
+	__('Add Media', 'event_espresso'),
1913 1913
 
1914 1914
 	// Reference: packages/tpc/src/buttons/AddPriceModifierButton.tsx:16
1915
-	__( 'add new price modifier after this row', 'event_espresso' ),
1915
+	__('add new price modifier after this row', 'event_espresso'),
1916 1916
 
1917 1917
 	// Reference: packages/tpc/src/buttons/DeleteAllPricesButton.tsx:14
1918
-	__( 'Delete all prices', 'event_espresso' ),
1918
+	__('Delete all prices', 'event_espresso'),
1919 1919
 
1920 1920
 	// Reference: packages/tpc/src/buttons/DeleteAllPricesButton.tsx:27
1921
-	__( 'Are you sure you want to delete all of this ticket\'s prices and make it free? This action is permanent and can not be undone.', 'event_espresso' ),
1921
+	__('Are you sure you want to delete all of this ticket\'s prices and make it free? This action is permanent and can not be undone.', 'event_espresso'),
1922 1922
 
1923 1923
 	// Reference: packages/tpc/src/buttons/DeleteAllPricesButton.tsx:31
1924
-	__( 'Delete all prices?', 'event_espresso' ),
1924
+	__('Delete all prices?', 'event_espresso'),
1925 1925
 
1926 1926
 	// Reference: packages/tpc/src/buttons/DeletePriceModifierButton.tsx:12
1927
-	__( 'delete price modifier', 'event_espresso' ),
1927
+	__('delete price modifier', 'event_espresso'),
1928 1928
 
1929 1929
 	// Reference: packages/tpc/src/buttons/ReverseCalculateButton.tsx:14
1930
-	__( 'Ticket base price is being reverse calculated from bottom to top starting with the ticket total. Entering a new ticket total will reverse calculate the ticket base price after applying all price modifiers in reverse. Click to turn off reverse calculations', 'event_espresso' ),
1930
+	__('Ticket base price is being reverse calculated from bottom to top starting with the ticket total. Entering a new ticket total will reverse calculate the ticket base price after applying all price modifiers in reverse. Click to turn off reverse calculations', 'event_espresso'),
1931 1931
 
1932 1932
 	// Reference: packages/tpc/src/buttons/ReverseCalculateButton.tsx:17
1933
-	__( 'Ticket total is being calculated normally from top to bottom starting from the base price. Entering a new ticket base price will recalculate the ticket total after applying all price modifiers. Click to turn on reverse calculations', 'event_espresso' ),
1933
+	__('Ticket total is being calculated normally from top to bottom starting from the base price. Entering a new ticket base price will recalculate the ticket total after applying all price modifiers. Click to turn on reverse calculations', 'event_espresso'),
1934 1934
 
1935 1935
 	// Reference: packages/tpc/src/buttons/ReverseCalculateButton.tsx:21
1936
-	__( 'Disable reverse calculate', 'event_espresso' ),
1936
+	__('Disable reverse calculate', 'event_espresso'),
1937 1937
 
1938 1938
 	// Reference: packages/tpc/src/buttons/ReverseCalculateButton.tsx:21
1939
-	__( 'Enable reverse calculate', 'event_espresso' ),
1939
+	__('Enable reverse calculate', 'event_espresso'),
1940 1940
 
1941 1941
 	// Reference: packages/tpc/src/buttons/TicketPriceCalculatorButton.tsx:28
1942
-	__( 'ticket price calculator', 'event_espresso' ),
1942
+	__('ticket price calculator', 'event_espresso'),
1943 1943
 
1944 1944
 	// Reference: packages/tpc/src/buttons/taxes/AddDefaultTaxesButton.tsx:9
1945
-	__( 'Add default taxes', 'event_espresso' ),
1945
+	__('Add default taxes', 'event_espresso'),
1946 1946
 
1947 1947
 	// Reference: packages/tpc/src/buttons/taxes/RemoveTaxesButton.tsx:10
1948
-	__( 'Are you sure you want to remove all of this ticket\'s taxes?', 'event_espresso' ),
1948
+	__('Are you sure you want to remove all of this ticket\'s taxes?', 'event_espresso'),
1949 1949
 
1950 1950
 	// Reference: packages/tpc/src/buttons/taxes/RemoveTaxesButton.tsx:14
1951
-	__( 'Remove all taxes?', 'event_espresso' ),
1951
+	__('Remove all taxes?', 'event_espresso'),
1952 1952
 
1953 1953
 	// Reference: packages/tpc/src/buttons/taxes/RemoveTaxesButton.tsx:7
1954
-	__( 'Remove taxes', 'event_espresso' ),
1954
+	__('Remove taxes', 'event_espresso'),
1955 1955
 
1956 1956
 	// Reference: packages/tpc/src/components/AddDefaultPricesButton.tsx:9
1957
-	__( 'Add default prices', 'event_espresso' ),
1957
+	__('Add default prices', 'event_espresso'),
1958 1958
 
1959 1959
 	// Reference: packages/tpc/src/components/DefaultPricesInfo.tsx:29
1960
-	__( 'Modify default prices.', 'event_espresso' ),
1960
+	__('Modify default prices.', 'event_espresso'),
1961 1961
 
1962 1962
 	// Reference: packages/tpc/src/components/DefaultTaxesInfo.tsx:29
1963
-	__( 'New default taxes are available. Click the - Add default taxes - button to add them now.', 'event_espresso' ),
1963
+	__('New default taxes are available. Click the - Add default taxes - button to add them now.', 'event_espresso'),
1964 1964
 
1965 1965
 	// Reference: packages/tpc/src/components/LockedTicketsBanner.tsx:12
1966 1966
 	// Reference: packages/tpc/src/hooks/useLockedTicketAction.ts:74
1967
-	__( 'Price editing is disabled!', 'event_espresso' ),
1967
+	__('Price editing is disabled!', 'event_espresso'),
1968 1968
 
1969 1969
 	// Reference: packages/tpc/src/components/NoPriceTypesBanner.tsx:12
1970
-	__( 'One or more price types are missing. Maybe they were placed in the trash?', 'event_espresso' ),
1970
+	__('One or more price types are missing. Maybe they were placed in the trash?', 'event_espresso'),
1971 1971
 
1972 1972
 	// Reference: packages/tpc/src/components/NoPriceTypesBanner.tsx:17
1973 1973
 	/* translators: %s link to price types admin */
1974
-	__( 'Go to the%sto restore (untrash) your price types and/or create some new ones.', 'event_espresso' ),
1974
+	__('Go to the%sto restore (untrash) your price types and/or create some new ones.', 'event_espresso'),
1975 1975
 
1976 1976
 	// Reference: packages/tpc/src/components/NoPriceTypesBanner.tsx:18
1977
-	__( 'price types admin page', 'event_espresso' ),
1977
+	__('price types admin page', 'event_espresso'),
1978 1978
 
1979 1979
 	// Reference: packages/tpc/src/components/NoPriceTypesBanner.tsx:26
1980
-	__( 'Missing Price Types!', 'event_espresso' ),
1980
+	__('Missing Price Types!', 'event_espresso'),
1981 1981
 
1982 1982
 	// Reference: packages/tpc/src/components/NoPricesBanner.tsx:14
1983
-	__( 'This Ticket is Currently Free', 'event_espresso' ),
1983
+	__('This Ticket is Currently Free', 'event_espresso'),
1984 1984
 
1985 1985
 	// Reference: packages/tpc/src/components/NoPricesBanner.tsx:21
1986 1986
 	/* translators: %s default prices */
1987
-	__( 'Click the button below to load your %s into the calculator.', 'event_espresso' ),
1987
+	__('Click the button below to load your %s into the calculator.', 'event_espresso'),
1988 1988
 
1989 1989
 	// Reference: packages/tpc/src/components/NoPricesBanner.tsx:22
1990
-	__( 'default prices', 'event_espresso' ),
1990
+	__('default prices', 'event_espresso'),
1991 1991
 
1992 1992
 	// Reference: packages/tpc/src/components/NoPricesBanner.tsx:29
1993
-	__( 'Additional ticket price modifiers can be added or removed.', 'event_espresso' ),
1993
+	__('Additional ticket price modifiers can be added or removed.', 'event_espresso'),
1994 1994
 
1995 1995
 	// Reference: packages/tpc/src/components/NoPricesBanner.tsx:31
1996
-	__( 'Click the save button below to assign which dates this ticket will be available for purchase on.', 'event_espresso' ),
1996
+	__('Click the save button below to assign which dates this ticket will be available for purchase on.', 'event_espresso'),
1997 1997
 
1998 1998
 	// Reference: packages/tpc/src/components/TicketPriceCalculatorModal.tsx:22
1999 1999
 	// Reference: packages/ui-components/src/Confirm/ConfirmClose.tsx:7
2000 2000
 	// Reference: packages/ui-components/src/Confirm/useConfirmWithButton.tsx:10
2001 2001
 	// Reference: packages/ui-components/src/Confirm/useConfirmationDialog.tsx:52
2002
-	__( 'Changes will be lost if you proceed.', 'event_espresso' ),
2002
+	__('Changes will be lost if you proceed.', 'event_espresso'),
2003 2003
 
2004 2004
 	// Reference: packages/tpc/src/components/TicketPriceCalculatorModal.tsx:33
2005 2005
 	/* translators: %s ticket name */
2006
-	__( 'Price Calculator for Ticket: %s', 'event_espresso' ),
2006
+	__('Price Calculator for Ticket: %s', 'event_espresso'),
2007 2007
 
2008 2008
 	// Reference: packages/tpc/src/components/price/input/Description.tsx:15
2009
-	__( 'price description', 'event_espresso' ),
2009
+	__('price description', 'event_espresso'),
2010 2010
 
2011 2011
 	// Reference: packages/tpc/src/components/price/input/Description.tsx:18
2012
-	__( 'description…', 'event_espresso' ),
2012
+	__('description…', 'event_espresso'),
2013 2013
 
2014 2014
 	// Reference: packages/tpc/src/components/price/input/ID.tsx:7
2015
-	__( 'price id', 'event_espresso' ),
2015
+	__('price id', 'event_espresso'),
2016 2016
 
2017 2017
 	// Reference: packages/tpc/src/components/price/input/Name.tsx:15
2018
-	__( 'price name', 'event_espresso' ),
2018
+	__('price name', 'event_espresso'),
2019 2019
 
2020 2020
 	// Reference: packages/tpc/src/components/price/input/Name.tsx:18
2021
-	__( 'label…', 'event_espresso' ),
2021
+	__('label…', 'event_espresso'),
2022 2022
 
2023 2023
 	// Reference: packages/tpc/src/components/price/input/Order.tsx:21
2024
-	__( 'price order', 'event_espresso' ),
2024
+	__('price order', 'event_espresso'),
2025 2025
 
2026 2026
 	// Reference: packages/tpc/src/components/price/input/amount/Amount.tsx:85
2027
-	__( 'amount', 'event_espresso' ),
2027
+	__('amount', 'event_espresso'),
2028 2028
 
2029 2029
 	// Reference: packages/tpc/src/components/price/input/amount/Amount.tsx:89
2030
-	__( 'amount…', 'event_espresso' ),
2030
+	__('amount…', 'event_espresso'),
2031 2031
 
2032 2032
 	// Reference: packages/tpc/src/components/table/useFooterRowGenerator.tsx:50
2033
-	__( 'Total', 'event_espresso' ),
2033
+	__('Total', 'event_espresso'),
2034 2034
 
2035 2035
 	// Reference: packages/tpc/src/components/table/useFooterRowGenerator.tsx:59
2036
-	__( 'ticket total', 'event_espresso' ),
2036
+	__('ticket total', 'event_espresso'),
2037 2037
 
2038 2038
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:29
2039
-	__( 'Order', 'event_espresso' ),
2039
+	__('Order', 'event_espresso'),
2040 2040
 
2041 2041
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:35
2042
-	__( 'Price Type', 'event_espresso' ),
2042
+	__('Price Type', 'event_espresso'),
2043 2043
 
2044 2044
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:41
2045
-	__( 'Label', 'event_espresso' ),
2045
+	__('Label', 'event_espresso'),
2046 2046
 
2047 2047
 	// Reference: packages/tpc/src/components/table/useHeaderRowGenerator.ts:53
2048
-	__( 'Amount', 'event_espresso' ),
2048
+	__('Amount', 'event_espresso'),
2049 2049
 
2050 2050
 	// Reference: packages/tpc/src/hooks/useLockedTicketAction.ts:22
2051
-	__( 'Copy ticket', 'event_espresso' ),
2051
+	__('Copy ticket', 'event_espresso'),
2052 2052
 
2053 2053
 	// Reference: packages/tpc/src/hooks/useLockedTicketAction.ts:26
2054
-	__( 'Copy and archive this ticket', 'event_espresso' ),
2054
+	__('Copy and archive this ticket', 'event_espresso'),
2055 2055
 
2056 2056
 	// Reference: packages/tpc/src/hooks/useLockedTicketAction.ts:29
2057
-	__( 'OK', 'event_espresso' ),
2057
+	__('OK', 'event_espresso'),
2058 2058
 
2059 2059
 	// Reference: packages/tpc/src/utils/constants.ts:8
2060
-	__( 'Ticket price modifications are blocked for Tickets that have already been sold to registrants, because doing so would negatively affect internal accounting for the event. If you still need to modify ticket prices, then create a copy of those tickets, edit the prices for the new tickets, and then trash the old tickets.', 'event_espresso' ),
2060
+	__('Ticket price modifications are blocked for Tickets that have already been sold to registrants, because doing so would negatively affect internal accounting for the event. If you still need to modify ticket prices, then create a copy of those tickets, edit the prices for the new tickets, and then trash the old tickets.', 'event_espresso'),
2061 2061
 
2062 2062
 	// Reference: packages/ui-components/src/ActiveFilters/ActiveFilters.tsx:8
2063
-	__( 'active filters:', 'event_espresso' ),
2063
+	__('active filters:', 'event_espresso'),
2064 2064
 
2065 2065
 	// Reference: packages/ui-components/src/ActiveFilters/FilterTag/index.tsx:15
2066 2066
 	/* translators: %s filter name */
2067
-	__( 'remove filter - %s', 'event_espresso' ),
2067
+	__('remove filter - %s', 'event_espresso'),
2068 2068
 
2069 2069
 	// Reference: packages/ui-components/src/Address/Address.tsx:105
2070
-	__( 'Country:', 'event_espresso' ),
2070
+	__('Country:', 'event_espresso'),
2071 2071
 
2072 2072
 	// Reference: packages/ui-components/src/Address/Address.tsx:113
2073
-	__( 'Zip:', 'event_espresso' ),
2073
+	__('Zip:', 'event_espresso'),
2074 2074
 
2075 2075
 	// Reference: packages/ui-components/src/Address/Address.tsx:81
2076
-	__( 'Address:', 'event_espresso' ),
2076
+	__('Address:', 'event_espresso'),
2077 2077
 
2078 2078
 	// Reference: packages/ui-components/src/Address/Address.tsx:89
2079
-	__( 'City:', 'event_espresso' ),
2079
+	__('City:', 'event_espresso'),
2080 2080
 
2081 2081
 	// Reference: packages/ui-components/src/Address/Address.tsx:97
2082
-	__( 'State:', 'event_espresso' ),
2082
+	__('State:', 'event_espresso'),
2083 2083
 
2084 2084
 	// Reference: packages/ui-components/src/CalendarDateRange/CalendarDateRange.tsx:37
2085
-	__( 'to', 'event_espresso' ),
2085
+	__('to', 'event_espresso'),
2086 2086
 
2087 2087
 	// Reference: packages/ui-components/src/CalendarPageDate/CalendarPageDate.tsx:54
2088
-	__( 'TO', 'event_espresso' ),
2088
+	__('TO', 'event_espresso'),
2089 2089
 
2090 2090
 	// Reference: packages/ui-components/src/ColorPicker/ColorPicker.tsx:60
2091
-	__( 'Custom color', 'event_espresso' ),
2091
+	__('Custom color', 'event_espresso'),
2092 2092
 
2093 2093
 	// Reference: packages/ui-components/src/ColorPicker/Swatch.tsx:23
2094 2094
 	/* translators: color name */
2095
-	__( 'Color: %s', 'event_espresso' ),
2095
+	__('Color: %s', 'event_espresso'),
2096 2096
 
2097 2097
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:13
2098
-	__( 'Cyan bluish gray', 'event_espresso' ),
2098
+	__('Cyan bluish gray', 'event_espresso'),
2099 2099
 
2100 2100
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:17
2101
-	__( 'White', 'event_espresso' ),
2101
+	__('White', 'event_espresso'),
2102 2102
 
2103 2103
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:21
2104
-	__( 'Pale pink', 'event_espresso' ),
2104
+	__('Pale pink', 'event_espresso'),
2105 2105
 
2106 2106
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:25
2107
-	__( 'Vivid red', 'event_espresso' ),
2107
+	__('Vivid red', 'event_espresso'),
2108 2108
 
2109 2109
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:29
2110
-	__( 'Luminous vivid orange', 'event_espresso' ),
2110
+	__('Luminous vivid orange', 'event_espresso'),
2111 2111
 
2112 2112
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:33
2113
-	__( 'Luminous vivid amber', 'event_espresso' ),
2113
+	__('Luminous vivid amber', 'event_espresso'),
2114 2114
 
2115 2115
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:37
2116
-	__( 'Light green cyan', 'event_espresso' ),
2116
+	__('Light green cyan', 'event_espresso'),
2117 2117
 
2118 2118
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:41
2119
-	__( 'Vivid green cyan', 'event_espresso' ),
2119
+	__('Vivid green cyan', 'event_espresso'),
2120 2120
 
2121 2121
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:45
2122
-	__( 'Pale cyan blue', 'event_espresso' ),
2122
+	__('Pale cyan blue', 'event_espresso'),
2123 2123
 
2124 2124
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:49
2125
-	__( 'Vivid cyan blue', 'event_espresso' ),
2125
+	__('Vivid cyan blue', 'event_espresso'),
2126 2126
 
2127 2127
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:53
2128
-	__( 'Vivid purple', 'event_espresso' ),
2128
+	__('Vivid purple', 'event_espresso'),
2129 2129
 
2130 2130
 	// Reference: packages/ui-components/src/ColorPicker/constants.ts:9
2131
-	__( 'Black', 'event_espresso' ),
2131
+	__('Black', 'event_espresso'),
2132 2132
 
2133 2133
 	// Reference: packages/ui-components/src/Confirm/ConfirmClose.tsx:8
2134 2134
 	// Reference: packages/ui-components/src/Modal/ModalWithAlert.tsx:24
2135
-	__( 'Are you sure you want to close this?', 'event_espresso' ),
2135
+	__('Are you sure you want to close this?', 'event_espresso'),
2136 2136
 
2137 2137
 	// Reference: packages/ui-components/src/Confirm/ConfirmClose.tsx:9
2138 2138
 	// Reference: packages/ui-components/src/Modal/ModalWithAlert.tsx:25
2139
-	__( 'Yes, discard changes', 'event_espresso' ),
2139
+	__('Yes, discard changes', 'event_espresso'),
2140 2140
 
2141 2141
 	// Reference: packages/ui-components/src/Confirm/ConfirmDelete.tsx:7
2142
-	__( 'Are you sure you want to delete this?', 'event_espresso' ),
2142
+	__('Are you sure you want to delete this?', 'event_espresso'),
2143 2143
 
2144 2144
 	// Reference: packages/ui-components/src/Confirm/useConfirmWithButton.tsx:11
2145
-	__( 'Please confirm this action.', 'event_espresso' ),
2145
+	__('Please confirm this action.', 'event_espresso'),
2146 2146
 
2147 2147
 	// Reference: packages/ui-components/src/Confirm/useConfirmationDialog.tsx:39
2148
-	__( 'cancel', 'event_espresso' ),
2148
+	__('cancel', 'event_espresso'),
2149 2149
 
2150 2150
 	// Reference: packages/ui-components/src/Confirm/useConfirmationDialog.tsx:40
2151
-	__( 'confirm', 'event_espresso' ),
2151
+	__('confirm', 'event_espresso'),
2152 2152
 
2153 2153
 	// Reference: packages/ui-components/src/CurrencyDisplay/CurrencyDisplay.tsx:34
2154
-	__( 'free', 'event_espresso' ),
2154
+	__('free', 'event_espresso'),
2155 2155
 
2156 2156
 	// Reference: packages/ui-components/src/DateTimeRangePicker/DateTimeRangePicker.tsx:117
2157 2157
 	// Reference: packages/ui-components/src/Popover/PopoverForm/PopoverForm.tsx:44
2158
-	__( 'save', 'event_espresso' ),
2158
+	__('save', 'event_espresso'),
2159 2159
 
2160 2160
 	// Reference: packages/ui-components/src/DebugInfo/DebugInfo.tsx:36
2161
-	__( 'Hide Debug Info', 'event_espresso' ),
2161
+	__('Hide Debug Info', 'event_espresso'),
2162 2162
 
2163 2163
 	// Reference: packages/ui-components/src/DebugInfo/DebugInfo.tsx:36
2164
-	__( 'Show Debug Info', 'event_espresso' ),
2164
+	__('Show Debug Info', 'event_espresso'),
2165 2165
 
2166 2166
 	// Reference: packages/ui-components/src/EditDateRangeButton/EditDateRangeButton.tsx:49
2167
-	__( 'Edit Start and End Dates and Times', 'event_espresso' ),
2167
+	__('Edit Start and End Dates and Times', 'event_espresso'),
2168 2168
 
2169 2169
 	// Reference: packages/ui-components/src/EntityActionsMenu/entityMenuItems/CopyEntity.tsx:8
2170
-	__( 'copy', 'event_espresso' ),
2170
+	__('copy', 'event_espresso'),
2171 2171
 
2172 2172
 	// Reference: packages/ui-components/src/EntityActionsMenu/entityMenuItems/EditEntity.tsx:8
2173
-	__( 'edit', 'event_espresso' ),
2173
+	__('edit', 'event_espresso'),
2174 2174
 
2175 2175
 	// Reference: packages/ui-components/src/EntityActionsMenu/entityMenuItems/TrashEntity.tsx:8
2176
-	__( 'trash', 'event_espresso' ),
2176
+	__('trash', 'event_espresso'),
2177 2177
 
2178 2178
 	// Reference: packages/ui-components/src/EntityActionsMenu/entityMenuItems/Untrash.tsx:8
2179
-	__( 'untrash', 'event_espresso' ),
2179
+	__('untrash', 'event_espresso'),
2180 2180
 
2181 2181
 	// Reference: packages/ui-components/src/EntityList/EntityList.tsx:23
2182
-	__( 'OOPS!', 'event_espresso' ),
2182
+	__('OOPS!', 'event_espresso'),
2183 2183
 
2184 2184
 	// Reference: packages/ui-components/src/EntityList/EntityList.tsx:23
2185
-	__( 'Error Loading Entites List', 'event_espresso' ),
2185
+	__('Error Loading Entites List', 'event_espresso'),
2186 2186
 
2187 2187
 	// Reference: packages/ui-components/src/EntityList/RegistrationsLink/index.tsx:12
2188
-	__( 'click to open the registrations admin page in a new tab or window', 'event_espresso' ),
2188
+	__('click to open the registrations admin page in a new tab or window', 'event_espresso'),
2189 2189
 
2190 2190
 	// Reference: packages/ui-components/src/EntityList/filterBar/buttons/CardViewFilterButton.tsx:22
2191
-	__( 'card view', 'event_espresso' ),
2191
+	__('card view', 'event_espresso'),
2192 2192
 
2193 2193
 	// Reference: packages/ui-components/src/EntityList/filterBar/buttons/TableViewFilterButton.tsx:21
2194
-	__( 'table view', 'event_espresso' ),
2194
+	__('table view', 'event_espresso'),
2195 2195
 
2196 2196
 	// Reference: packages/ui-components/src/EntityList/filterBar/buttons/ToggleBulkActionsButton.tsx:8
2197
-	__( 'hide bulk actions', 'event_espresso' ),
2197
+	__('hide bulk actions', 'event_espresso'),
2198 2198
 
2199 2199
 	// Reference: packages/ui-components/src/EntityList/filterBar/buttons/ToggleBulkActionsButton.tsx:8
2200
-	__( 'show bulk actions', 'event_espresso' ),
2200
+	__('show bulk actions', 'event_espresso'),
2201 2201
 
2202 2202
 	// Reference: packages/ui-components/src/EntityList/filterBar/buttons/ToggleFiltersButton.tsx:23
2203
-	__( 'filters', 'event_espresso' ),
2203
+	__('filters', 'event_espresso'),
2204 2204
 
2205 2205
 	// Reference: packages/ui-components/src/Legend/ToggleLegendButton.tsx:38
2206
-	__( 'legend', 'event_espresso' ),
2206
+	__('legend', 'event_espresso'),
2207 2207
 
2208 2208
 	// Reference: packages/ui-components/src/LoadingNotice/LoadingNotice.tsx:11
2209
-	__( 'loading…', 'event_espresso' ),
2209
+	__('loading…', 'event_espresso'),
2210 2210
 
2211 2211
 	// Reference: packages/ui-components/src/Modal/Modal.tsx:59
2212
-	__( 'close modal', 'event_espresso' ),
2212
+	__('close modal', 'event_espresso'),
2213 2213
 
2214 2214
 	// Reference: packages/ui-components/src/Pagination/ItemRender.tsx:10
2215
-	__( 'jump to previous', 'event_espresso' ),
2215
+	__('jump to previous', 'event_espresso'),
2216 2216
 
2217 2217
 	// Reference: packages/ui-components/src/Pagination/ItemRender.tsx:11
2218
-	__( 'jump to next', 'event_espresso' ),
2218
+	__('jump to next', 'event_espresso'),
2219 2219
 
2220 2220
 	// Reference: packages/ui-components/src/Pagination/ItemRender.tsx:12
2221
-	__( 'page', 'event_espresso' ),
2221
+	__('page', 'event_espresso'),
2222 2222
 
2223 2223
 	// Reference: packages/ui-components/src/Pagination/ItemRender.tsx:8
2224
-	__( 'previous', 'event_espresso' ),
2224
+	__('previous', 'event_espresso'),
2225 2225
 
2226 2226
 	// Reference: packages/ui-components/src/Pagination/ItemRender.tsx:9
2227
-	__( 'next', 'event_espresso' ),
2227
+	__('next', 'event_espresso'),
2228 2228
 
2229 2229
 	// Reference: packages/ui-components/src/Pagination/PerPage.tsx:45
2230 2230
 	/* translators: %1$d is first item #, %2$d is last item #, %3$d is total items, ex: 20-30 of 100 items */
2231
-	__( '%1$d-%2$d of %3$d items', 'event_espresso' ),
2231
+	__('%1$d-%2$d of %3$d items', 'event_espresso'),
2232 2232
 
2233 2233
 	// Reference: packages/ui-components/src/Pagination/PerPage.tsx:54
2234
-	__( 'items per page', 'event_espresso' ),
2234
+	__('items per page', 'event_espresso'),
2235 2235
 
2236 2236
 	// Reference: packages/ui-components/src/Pagination/constants.ts:11
2237 2237
 	/* translators: %s is per page value */
2238
-	__( '%s / page', 'event_espresso' ),
2238
+	__('%s / page', 'event_espresso'),
2239 2239
 
2240 2240
 	// Reference: packages/ui-components/src/Pagination/constants.ts:12
2241
-	__( 'show all', 'event_espresso' ),
2241
+	__('show all', 'event_espresso'),
2242 2242
 
2243 2243
 	// Reference: packages/ui-components/src/Pagination/constants.ts:15
2244
-	__( 'Next Page', 'event_espresso' ),
2244
+	__('Next Page', 'event_espresso'),
2245 2245
 
2246 2246
 	// Reference: packages/ui-components/src/Pagination/constants.ts:16
2247
-	__( 'Previous Page', 'event_espresso' ),
2247
+	__('Previous Page', 'event_espresso'),
2248 2248
 
2249 2249
 	// Reference: packages/ui-components/src/PercentSign/index.tsx:10
2250
-	__( '%', 'event_espresso' ),
2250
+	__('%', 'event_espresso'),
2251 2251
 
2252 2252
 	// Reference: packages/ui-components/src/SimpleEntityList/EntityOptionsRow/index.tsx:31
2253 2253
 	/* translators: entity type to select */
2254
-	__( 'Select an existing %s to use as a template.', 'event_espresso' ),
2254
+	__('Select an existing %s to use as a template.', 'event_espresso'),
2255 2255
 
2256 2256
 	// Reference: packages/ui-components/src/SimpleEntityList/EntityOptionsRow/index.tsx:38
2257
-	__( 'or', 'event_espresso' ),
2257
+	__('or', 'event_espresso'),
2258 2258
 
2259 2259
 	// Reference: packages/ui-components/src/SimpleEntityList/EntityOptionsRow/index.tsx:43
2260 2260
 	/* translators: entity type to add */
2261
-	__( 'Add a new %s and insert details manually', 'event_espresso' ),
2261
+	__('Add a new %s and insert details manually', 'event_espresso'),
2262 2262
 
2263 2263
 	// Reference: packages/ui-components/src/SimpleEntityList/EntityOptionsRow/index.tsx:48
2264
-	__( 'Add New', 'event_espresso' ),
2264
+	__('Add New', 'event_espresso'),
2265 2265
 
2266 2266
 	// Reference: packages/ui-components/src/Stepper/buttons/Next.tsx:8
2267
-	__( 'Next', 'event_espresso' ),
2267
+	__('Next', 'event_espresso'),
2268 2268
 
2269 2269
 	// Reference: packages/ui-components/src/Stepper/buttons/Previous.tsx:8
2270
-	__( 'Previous', 'event_espresso' ),
2270
+	__('Previous', 'event_espresso'),
2271 2271
 
2272 2272
 	// Reference: packages/ui-components/src/Steps/Steps.tsx:31
2273
-	__( 'Steps', 'event_espresso' ),
2273
+	__('Steps', 'event_espresso'),
2274 2274
 
2275 2275
 	// Reference: packages/ui-components/src/TabbableText/index.tsx:21
2276
-	__( 'click to edit…', 'event_espresso' ),
2276
+	__('click to edit…', 'event_espresso'),
2277 2277
 
2278 2278
 	// Reference: packages/ui-components/src/TimezoneTimeInfo/Content.tsx:14
2279
-	__( 'The Website\'s Time Zone', 'event_espresso' ),
2279
+	__('The Website\'s Time Zone', 'event_espresso'),
2280 2280
 
2281 2281
 	// Reference: packages/ui-components/src/TimezoneTimeInfo/Content.tsx:19
2282
-	__( 'UTC (Greenwich Mean Time)', 'event_espresso' ),
2282
+	__('UTC (Greenwich Mean Time)', 'event_espresso'),
2283 2283
 
2284 2284
 	// Reference: packages/ui-components/src/TimezoneTimeInfo/Content.tsx:9
2285
-	__( 'Your Local Time Zone', 'event_espresso' ),
2285
+	__('Your Local Time Zone', 'event_espresso'),
2286 2286
 
2287 2287
 	// Reference: packages/ui-components/src/TimezoneTimeInfo/TimezoneTimeInfo.tsx:25
2288
-	__( 'click for timezone information', 'event_espresso' ),
2288
+	__('click for timezone information', 'event_espresso'),
2289 2289
 
2290 2290
 	// Reference: packages/ui-components/src/TimezoneTimeInfo/TimezoneTimeInfo.tsx:30
2291
-	__( 'This Date Converted To:', 'event_espresso' ),
2291
+	__('This Date Converted To:', 'event_espresso'),
2292 2292
 
2293 2293
 	// Reference: packages/ui-components/src/VenueSelector/VenueSelector.tsx:120
2294
-	__( 'Add New Venue', 'event_espresso' ),
2294
+	__('Add New Venue', 'event_espresso'),
2295 2295
 
2296 2296
 	// Reference: packages/ui-components/src/VenueSelector/VenueSelector.tsx:36
2297
-	__( '~ no venue ~', 'event_espresso' ),
2297
+	__('~ no venue ~', 'event_espresso'),
2298 2298
 
2299 2299
 	// Reference: packages/ui-components/src/VenueSelector/VenueSelector.tsx:43
2300
-	__( 'assign venue…', 'event_espresso' ),
2300
+	__('assign venue…', 'event_espresso'),
2301 2301
 
2302 2302
 	// Reference: packages/ui-components/src/VenueSelector/VenueSelector.tsx:44
2303
-	__( 'click to select a venue…', 'event_espresso' ),
2303
+	__('click to select a venue…', 'event_espresso'),
2304 2304
 
2305 2305
 	// Reference: packages/ui-components/src/bulkEdit/BulkActions.tsx:51
2306
-	__( 'select all', 'event_espresso' ),
2306
+	__('select all', 'event_espresso'),
2307 2307
 
2308 2308
 	// Reference: packages/ui-components/src/bulkEdit/BulkActions.tsx:54
2309
-	__( 'apply', 'event_espresso' )
2309
+	__('apply', 'event_espresso')
2310 2310
 );
2311 2311
 /* THIS IS THE END OF THE GENERATED FILE */
Please login to merge, or discard this patch.
modules/single_page_checkout/EED_Single_Page_Checkout.module.php 1 patch
Indentation   +1692 added lines, -1692 removed lines patch added patch discarded remove patch
@@ -20,1696 +20,1696 @@
 block discarded – undo
20 20
  */
21 21
 class EED_Single_Page_Checkout extends EED_Module
22 22
 {
23
-    /**
24
-     * $_initialized - has the SPCO controller already been initialized ?
25
-     */
26
-    private static bool $_initialized = false;
27
-
28
-
29
-    /**
30
-     * $_checkout_verified - is the EE_Checkout verified as correct for this request ?
31
-     */
32
-    private static bool $_checkout_verified = true;
33
-
34
-    /**
35
-     * $_reg_steps_array - holds initial array of reg steps
36
-     *
37
-     * @var array $_reg_steps_array
38
-     */
39
-    private static array $_reg_steps_array = [];
40
-
41
-    /**
42
-     * $checkout - EE_Checkout object for handling the properties of the current checkout process
43
-     */
44
-    public ?EE_Checkout $checkout = null;
45
-
46
-    protected ?RequestInterface $request = null;
47
-
48
-    private bool $debug = false;    //  true    false
49
-
50
-
51
-    /**
52
-     * @return EED_Single_Page_Checkout|EED_Module
53
-     * @throws EE_Error
54
-     * @throws ReflectionException
55
-     */
56
-    public static function instance()
57
-    {
58
-        add_filter('EED_Single_Page_Checkout__SPCO_active', '__return_true');
59
-        return parent::get_instance(__CLASS__);
60
-    }
61
-
62
-
63
-    /**
64
-     * @return EE_CART
65
-     */
66
-    public function cart(): EE_CART
67
-    {
68
-        return $this->checkout->cart;
69
-    }
70
-
71
-
72
-    /**
73
-     * @return RequestInterface
74
-     * @since   4.10.14.p
75
-     */
76
-    public static function getRequest(): RequestInterface
77
-    {
78
-        return LoaderFactory::getLoader()->getShared(RequestInterface::class);
79
-    }
80
-
81
-
82
-    /**
83
-     * @return EE_Transaction
84
-     */
85
-    public function transaction(): EE_Transaction
86
-    {
87
-        return $this->checkout->transaction;
88
-    }
89
-
90
-
91
-    /**
92
-     *    set_hooks - for hooking into EE Core, other modules, etc
93
-     *
94
-     * @return    void
95
-     * @throws EE_Error
96
-     */
97
-    public static function set_hooks()
98
-    {
99
-        EED_Single_Page_Checkout::set_definitions();
100
-    }
101
-
102
-
103
-    /**
104
-     *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
105
-     *
106
-     * @return    void
107
-     * @throws EE_Error
108
-     */
109
-    public static function set_hooks_admin()
110
-    {
111
-        EED_Single_Page_Checkout::set_definitions();
112
-        if (! (defined('DOING_AJAX') && DOING_AJAX)) {
113
-            return;
114
-        }
115
-        // going to start an output buffer in case anything gets accidentally output
116
-        // that might disrupt our JSON response
117
-        ob_start();
118
-        EED_Single_Page_Checkout::load_reg_steps();
119
-        // set ajax hooks
120
-        add_action('wp_ajax_process_reg_step', ['EED_Single_Page_Checkout', 'process_reg_step']);
121
-        add_action('wp_ajax_nopriv_process_reg_step', ['EED_Single_Page_Checkout', 'process_reg_step']);
122
-        add_action('wp_ajax_display_spco_reg_step', ['EED_Single_Page_Checkout', 'display_reg_step']);
123
-        add_action('wp_ajax_nopriv_display_spco_reg_step', ['EED_Single_Page_Checkout', 'display_reg_step']);
124
-        add_action('wp_ajax_update_reg_step', ['EED_Single_Page_Checkout', 'update_reg_step']);
125
-        add_action('wp_ajax_nopriv_update_reg_step', ['EED_Single_Page_Checkout', 'update_reg_step']);
126
-    }
127
-
128
-
129
-    /**
130
-     *    process ajax request
131
-     *
132
-     * @param string $ajax_action
133
-     * @throws EE_Error
134
-     * @throws ReflectionException
135
-     */
136
-    public static function process_ajax_request(string $ajax_action)
137
-    {
138
-        $request = EED_Single_Page_Checkout::getRequest();
139
-        $request->setRequestParam('action', $ajax_action);
140
-        EED_Single_Page_Checkout::instance()->_initialize();
141
-    }
142
-
143
-
144
-    /**
145
-     * ajax display registration step
146
-     *
147
-     * @throws EE_Error
148
-     * @throws ReflectionException
149
-     */
150
-    public static function display_reg_step()
151
-    {
152
-        EED_Single_Page_Checkout::process_ajax_request('display_spco_reg_step');
153
-    }
154
-
155
-
156
-    /**
157
-     * ajax process registration step
158
-     *
159
-     * @throws EE_Error
160
-     * @throws ReflectionException
161
-     */
162
-    public static function process_reg_step()
163
-    {
164
-        EED_Single_Page_Checkout::process_ajax_request('process_reg_step');
165
-    }
166
-
167
-
168
-    /**
169
-     * ajax process registration step
170
-     *
171
-     * @throws EE_Error
172
-     * @throws ReflectionException
173
-     */
174
-    public static function update_reg_step()
175
-    {
176
-        EED_Single_Page_Checkout::process_ajax_request('update_reg_step');
177
-    }
178
-
179
-
180
-    /**
181
-     * update_checkout
182
-     *
183
-     * @return void
184
-     * @throws ReflectionException
185
-     * @throws EE_Error
186
-     */
187
-    public static function update_checkout()
188
-    {
189
-        EED_Single_Page_Checkout::process_ajax_request('update_checkout');
190
-    }
191
-
192
-
193
-    /**
194
-     *    set_definitions
195
-     *
196
-     * @return    void
197
-     * @throws EE_Error
198
-     */
199
-    public static function set_definitions()
200
-    {
201
-        if (defined('SPCO_BASE_PATH')) {
202
-            return;
203
-        }
204
-        define(
205
-            'SPCO_BASE_PATH',
206
-            rtrim(str_replace(['\\', '/'], '/', plugin_dir_path(__FILE__)), '/') . '/'
207
-        );
208
-        define('SPCO_CSS_URL', plugin_dir_url(__FILE__) . 'css/');
209
-        define('SPCO_IMG_URL', plugin_dir_url(__FILE__) . 'img/');
210
-        define('SPCO_JS_URL', plugin_dir_url(__FILE__) . 'js/');
211
-        define('SPCO_INC_PATH', SPCO_BASE_PATH . 'inc/');
212
-        define('SPCO_REG_STEPS_PATH', SPCO_BASE_PATH . 'reg_steps/');
213
-        define('SPCO_TEMPLATES_PATH', SPCO_BASE_PATH . 'templates/');
214
-        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(SPCO_BASE_PATH, true);
215
-        EE_Registry::$i18n_js_strings['registration_expiration_notice'] =
216
-            EED_Single_Page_Checkout::getRegistrationExpirationNotice();
217
-    }
218
-
219
-
220
-    /**
221
-     * load_reg_steps
222
-     * loads and instantiates each reg step based on the EE_Registry::instance()->CFG->registration->reg_steps array
223
-     *
224
-     * @throws EE_Error
225
-     */
226
-    public static function load_reg_steps()
227
-    {
228
-        static $reg_steps_loaded = false;
229
-        if ($reg_steps_loaded) {
230
-            return;
231
-        }
232
-        // filter list of reg_steps
233
-        $reg_steps_to_load = (array) apply_filters(
234
-            'AHEE__SPCO__load_reg_steps__reg_steps_to_load',
235
-            EED_Single_Page_Checkout::get_reg_steps()
236
-        );
237
-        // sort by key (order)
238
-        ksort($reg_steps_to_load);
239
-        // loop through folders
240
-        foreach ($reg_steps_to_load as $order => $reg_step) {
241
-            // we need a
242
-            if (isset($reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'])) {
243
-                // copy over to the reg_steps_array
244
-                EED_Single_Page_Checkout::$_reg_steps_array[ $order ] = $reg_step;
245
-                // register custom key route for each reg step
246
-                // ie: step=>"slug" - this is the entire reason we load the reg steps array now
247
-                EED_Module::registerRoute(
248
-                    $reg_step['slug'],
249
-                    'EED_Single_Page_Checkout',
250
-                    'run',
251
-                    'step'
252
-                );
253
-                // add AJAX or other hooks
254
-                if (isset($reg_step['has_hooks']) && $reg_step['has_hooks']) {
255
-                    // setup autoloaders if necessary
256
-                    if (! class_exists($reg_step['class_name'])) {
257
-                        EEH_Autoloader::register_autoloaders_for_each_file_in_folder(
258
-                            $reg_step['file_path'],
259
-                            true
260
-                        );
261
-                    }
262
-                    if (is_callable($reg_step['class_name'], 'set_hooks')) {
263
-                        call_user_func([$reg_step['class_name'], 'set_hooks']);
264
-                    }
265
-                }
266
-            }
267
-        }
268
-        $reg_steps_loaded = true;
269
-    }
270
-
271
-
272
-    /**
273
-     *    get_reg_steps
274
-     *
275
-     * @return    array
276
-     */
277
-    public static function get_reg_steps(): array
278
-    {
279
-        $reg_steps = EE_Registry::instance()->CFG->registration->reg_steps;
280
-        if (empty($reg_steps)) {
281
-            $reg_steps = [
282
-                10  => [
283
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'attendee_information',
284
-                    'class_name' => 'EE_SPCO_Reg_Step_Attendee_Information',
285
-                    'slug'       => 'attendee_information',
286
-                    'has_hooks'  => false,
287
-                ],
288
-                30  => [
289
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'payment_options',
290
-                    'class_name' => 'EE_SPCO_Reg_Step_Payment_Options',
291
-                    'slug'       => 'payment_options',
292
-                    'has_hooks'  => true,
293
-                ],
294
-                999 => [
295
-                    'file_path'  => SPCO_REG_STEPS_PATH . 'finalize_registration',
296
-                    'class_name' => 'EE_SPCO_Reg_Step_Finalize_Registration',
297
-                    'slug'       => 'finalize_registration',
298
-                    'has_hooks'  => false,
299
-                ],
300
-            ];
301
-        }
302
-        return $reg_steps;
303
-    }
304
-
305
-
306
-    /**
307
-     * @return array|string
308
-     * @throws EE_Error
309
-     * @throws ReflectionException
310
-     */
311
-    public static function registration_checkout_for_admin()
312
-    {
313
-        $request = EED_Single_Page_Checkout::getRequest();
314
-        $request->setRequestParam('step', 'attendee_information');
315
-        $request->setRequestParam('action', 'display_spco_reg_step');
316
-        $request->setRequestParam('process_form_submission', false);
317
-        EED_Single_Page_Checkout::instance()->_initialize();
318
-        EED_Single_Page_Checkout::instance()->_display_spco_reg_form();
319
-        return EED_Single_Page_Checkout::getResponse()->getOutput();
320
-    }
321
-
322
-
323
-    /**
324
-     * @return EE_Transaction|null
325
-     * @throws EE_Error
326
-     * @throws ReflectionException
327
-     */
328
-    public static function process_registration_from_admin(): ?EE_Transaction
329
-    {
330
-        $request = EED_Single_Page_Checkout::getRequest();
331
-        $request->setRequestParam('step', 'attendee_information');
332
-        $request->setRequestParam('action', 'process_reg_step');
333
-        $request->setRequestParam('process_form_submission', true);
334
-        EED_Single_Page_Checkout::instance()->_initialize();
335
-        if (EED_Single_Page_Checkout::instance()->checkout->current_step->completed()) {
336
-            $final_reg_step = end(EED_Single_Page_Checkout::instance()->checkout->reg_steps);
337
-            if ($final_reg_step instanceof EE_SPCO_Reg_Step_Finalize_Registration) {
338
-                EED_Single_Page_Checkout::instance()->checkout->set_reg_step_initiated($final_reg_step);
339
-                if ($final_reg_step->process_reg_step()) {
340
-                    $final_reg_step->set_completed();
341
-                    EED_Single_Page_Checkout::instance()->checkout->update_txn_reg_steps_array();
342
-                    return EED_Single_Page_Checkout::instance()->checkout->transaction;
343
-                }
344
-            }
345
-        }
346
-        return null;
347
-    }
348
-
349
-
350
-    /**
351
-     *    run
352
-     *
353
-     * @param WP_Query|null $WP_Query
354
-     * @return    void
355
-     */
356
-    public function run($WP_Query)
357
-    {
358
-        if (
359
-            $WP_Query instanceof WP_Query
360
-            && $WP_Query->is_main_query()
361
-            && apply_filters('FHEE__EED_Single_Page_Checkout__run', true)
362
-            && $this->_is_reg_checkout()
363
-        ) {
364
-            $this->_initialize();
365
-        }
366
-    }
367
-
368
-
369
-    /**
370
-     * determines whether current url matches reg page url
371
-     *
372
-     * @return bool
373
-     */
374
-    protected function _is_reg_checkout(): bool
375
-    {
376
-        // get current permalink for reg page without any extra query args
377
-        $reg_page_url = get_permalink(EE_Config::instance()->core->reg_page_id);
378
-        // get request URI for current request, but without the scheme or host
379
-        $current_request_uri = EEH_URL::filter_input_server_url();
380
-        $current_request_uri = html_entity_decode($current_request_uri);
381
-        // get array of query args from the current request URI
382
-        $query_args = EEH_URL::get_query_string($current_request_uri);
383
-        // grab page id if it is set
384
-        $page_id = isset($query_args['page_id']) ? absint($query_args['page_id']) : 0;
385
-        // and remove the page id from the query args (we will re-add it later)
386
-        unset($query_args['page_id']);
387
-        // now strip all query args from current request URI
388
-        $current_request_uri = remove_query_arg(array_keys($query_args), $current_request_uri);
389
-        // and re-add the page id if it was set
390
-        if ($page_id) {
391
-            $current_request_uri = add_query_arg('page_id', $page_id, $current_request_uri);
392
-        }
393
-        // remove slashes and ?
394
-        $current_request_uri = trim($current_request_uri, '?/');
395
-        // is current request URI part of the known full reg page URL ?
396
-        return ! empty($current_request_uri) && strpos($reg_page_url, $current_request_uri) !== false;
397
-    }
398
-
399
-
400
-    /**
401
-     * @param WP_Query $wp_query
402
-     * @return    void
403
-     * @throws EE_Error
404
-     * @throws ReflectionException
405
-     */
406
-    public static function init(WP_Query $wp_query)
407
-    {
408
-        EED_Single_Page_Checkout::instance()->run($wp_query);
409
-    }
410
-
411
-
412
-    /**
413
-     * @return void
414
-     */
415
-    private function _initialize()
416
-    {
417
-        // ensure SPCO doesn't run twice
418
-        if (EED_Single_Page_Checkout::$_initialized) {
419
-            return;
420
-        }
421
-        try {
422
-            $this->request = EED_Single_Page_Checkout::getRequest();
423
-            EED_Single_Page_Checkout::load_reg_steps();
424
-            $this->_verify_session();
425
-            // set up the EE_Checkout object
426
-            $this->checkout = $this->_initialize_checkout();
427
-            // filter checkout
428
-            $this->checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize__checkout', $this->checkout);
429
-            // get the $_GET
430
-            $this->_get_request_vars();
431
-            if ($this->_block_bots()) {
432
-                return;
433
-            }
434
-            // filter continue_reg
435
-            $this->checkout->continue_reg = apply_filters(
436
-                'FHEE__EED_Single_Page_Checkout__init___continue_reg',
437
-                true,
438
-                $this->checkout
439
-            );
440
-            // load the reg steps array
441
-            if (! $this->_load_and_instantiate_reg_steps()) {
442
-                EED_Single_Page_Checkout::$_initialized = true;
443
-                return;
444
-            }
445
-            // set the current step
446
-            $this->checkout->set_current_step($this->checkout->step);
447
-            // and the next step
448
-            $this->checkout->set_next_step();
449
-            // verify that everything has been set up correctly
450
-            if (! ($this->_verify_transaction_and_get_registrations() && $this->_final_verifications())) {
451
-                EED_Single_Page_Checkout::$_initialized = true;
452
-                return;
453
-            }
454
-            do_action('AHEE__Single_Page_Checkout___initialize__after_final_verifications', $this->checkout);
455
-            // lock the transaction
456
-            $this->checkout->transaction->lock();
457
-            // make sure all of our cached objects are added to their respective model entity mappers
458
-            $this->checkout->refresh_all_entities();
459
-            // set amount owing
460
-            $this->checkout->amount_owing = $this->checkout->transaction->remaining();
461
-            // initialize each reg step, which gives them the chance to potentially alter the process
462
-            $this->_initialize_reg_steps();
463
-            // DEBUG LOG
464
-            // $this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ );
465
-            // get reg form
466
-            if (! $this->_check_form_submission()) {
467
-                EED_Single_Page_Checkout::$_initialized = true;
468
-                return;
469
-            }
470
-            // checkout the action!!!
471
-            $this->_process_form_action();
472
-            // add some style and make it dance
473
-            $this->add_styles_and_scripts($this);
474
-            // kk... SPCO has successfully run
475
-            EED_Single_Page_Checkout::$_initialized = true;
476
-            // set no cache headers and constants
477
-            EE_System::do_not_cache();
478
-            // add anchor
479
-            add_action('loop_start', [$this, 'set_checkout_anchor'], 1);
480
-            // remove transaction lock
481
-            add_action('shutdown', [$this, 'unlock_transaction'], 1);
482
-        } catch (Exception $e) {
483
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
484
-        }
485
-    }
486
-
487
-
488
-    /**
489
-     * checks that the session is valid and not expired
490
-     *
491
-     * @throws EE_Error
492
-     * @throws ReflectionException
493
-     */
494
-    private function _verify_session()
495
-    {
496
-        if (! EE_Registry::instance()->SSN instanceof EE_Session) {
497
-            throw new EE_Error(esc_html__('The EE_Session class could not be loaded.', 'event_espresso'));
498
-        }
499
-        $clear_session_requested = $this->request->getRequestParam('clear_session', false, 'bool');
500
-        // is session still valid ?
501
-        if (
502
-            $clear_session_requested
503
-            || (
504
-                EE_Registry::instance()->SSN->expired()
505
-                && $this->request->getRequestParam('e_reg_url_link') === ''
506
-            )
507
-        ) {
508
-            $this->checkout = new EE_Checkout();
509
-            EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
510
-            // EE_Registry::instance()->SSN->reset_cart();
511
-            // EE_Registry::instance()->SSN->reset_checkout();
512
-            // EE_Registry::instance()->SSN->reset_transaction();
513
-            if (! $clear_session_requested) {
514
-                EE_Error::add_attention(
515
-                    EE_Registry::$i18n_js_strings['registration_expiration_notice'],
516
-                    __FILE__,
517
-                    __FUNCTION__,
518
-                    __LINE__
519
-                );
520
-            }
521
-            // EE_Registry::instance()->SSN->reset_expired();
522
-        }
523
-    }
524
-
525
-
526
-    /**
527
-     * loads and instantiates EE_Checkout
528
-     *
529
-     * @return EE_Checkout
530
-     * @throws EE_Error
531
-     * @throws ReflectionException
532
-     */
533
-    private function _initialize_checkout(): EE_Checkout
534
-    {
535
-        // look in session for existing checkout
536
-        /** @type EE_Checkout $checkout */
537
-        $checkout = EE_Registry::instance()->SSN->checkout();
538
-        // verify
539
-        if (! $checkout instanceof EE_Checkout) {
540
-            // instantiate EE_Checkout object for handling the properties of the current checkout process
541
-            $checkout = EE_Registry::instance()->load_file(
542
-                SPCO_INC_PATH,
543
-                'EE_Checkout',
544
-                'class',
545
-                [],
546
-                false
547
-            );
548
-        } else {
549
-            if ($checkout->current_step->is_final_step() && $checkout->exit_spco() === true) {
550
-                $this->unlock_transaction();
551
-                wp_safe_redirect($checkout->redirect_url);
552
-                exit();
553
-            }
554
-        }
555
-        $checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize_checkout__checkout', $checkout);
556
-        // verify again
557
-        if (! $checkout instanceof EE_Checkout) {
558
-            throw new EE_Error(esc_html__('The EE_Checkout class could not be loaded.', 'event_espresso'));
559
-        }
560
-        // reset anything that needs a clean slate for each request
561
-        $checkout->reset_for_current_request();
562
-        return $checkout;
563
-    }
564
-
565
-
566
-    /**
567
-     * @return void
568
-     */
569
-    private function _get_request_vars()
570
-    {
571
-        // make sure this request is marked as belonging to EE
572
-        /** @var CurrentPage $current_page */
573
-        $current_page = LoaderFactory::getLoader()->getShared(CurrentPage::class);
574
-        $current_page->setEspressoPage(true);
575
-        // which step is being requested ?
576
-        $this->checkout->step = $this->request->getRequestParam('step', $this->_get_first_step());
577
-        // which step is being edited ?
578
-        $this->checkout->edit_step = $this->request->getRequestParam('edit_step');
579
-        // and what we're doing on the current step
580
-        $this->checkout->action = $this->request->getRequestParam('action', 'display_spco_reg_step');
581
-        // timestamp
582
-        $this->checkout->uts = $this->request->getRequestParam('uts', 0, 'int');
583
-        // returning to edit ?
584
-        $this->checkout->reg_url_link = $this->request->getRequestParam('e_reg_url_link');
585
-        // add reg url link to registration query params
586
-        if ($this->checkout->reg_url_link && strpos($this->checkout->reg_url_link, '1-') !== 0) {
587
-            $this->checkout->reg_cache_where_params[0]['REG_url_link'] = $this->checkout->reg_url_link;
588
-        }
589
-        // or some other kind of revisit ?
590
-        $this->checkout->revisit = $this->request->getRequestParam('revisit', false, 'bool');
591
-        // and whether to generate a reg form for this request
592
-        $this->checkout->generate_reg_form = $this->request->getRequestParam('generate_reg_form', true, 'bool');
593
-        // and whether to process a reg form submission for this request
594
-        $this->checkout->process_form_submission = $this->request->getRequestParam(
595
-            'process_form_submission',
596
-            $this->checkout->action === 'process_reg_step',
597
-            'bool'
598
-        );
599
-        $this->checkout->process_form_submission = filter_var(
600
-            $this->checkout->action !== 'display_spco_reg_step'
601
-                ? $this->checkout->process_form_submission
602
-                : false,
603
-            FILTER_VALIDATE_BOOLEAN
604
-        );
605
-        $this->_display_request_vars();
606
-    }
607
-
608
-
609
-    /**
610
-     * @return void
611
-     */
612
-    protected function _display_request_vars()
613
-    {
614
-        if (! ($this->debug && defined('WP_DEBUG') && WP_DEBUG)) {
615
-            return;
616
-        }
617
-        EEH_Debug_Tools::printr($this->request->requestParams(), 'requestParams', __FILE__, __LINE__);
618
-        EEH_Debug_Tools::printr($this->checkout->step, '$this->checkout->step', __FILE__, __LINE__);
619
-        EEH_Debug_Tools::printr($this->checkout->edit_step, '$this->checkout->edit_step', __FILE__, __LINE__);
620
-        EEH_Debug_Tools::printr($this->checkout->action, '$this->checkout->action', __FILE__, __LINE__);
621
-        EEH_Debug_Tools::printr($this->checkout->reg_url_link, '$this->checkout->reg_url_link', __FILE__, __LINE__);
622
-        EEH_Debug_Tools::printr($this->checkout->revisit, '$this->checkout->revisit', __FILE__, __LINE__);
623
-        EEH_Debug_Tools::printr(
624
-            $this->checkout->generate_reg_form,
625
-            '$this->checkout->generate_reg_form',
626
-            __FILE__,
627
-            __LINE__
628
-        );
629
-        EEH_Debug_Tools::printr(
630
-            $this->checkout->process_form_submission,
631
-            '$this->checkout->process_form_submission',
632
-            __FILE__,
633
-            __LINE__
634
-        );
635
-    }
636
-
637
-
638
-    /**
639
-     * _block_bots
640
-     * checks that the incoming request has either of the following set:
641
-     *  a UTS (unix timestamp) which indicates that the request was redirected from the Ticket Selector
642
-     *  a REG URL Link, which indicates that the request is a return visit to SPCO for a valid TXN
643
-     * so if you're not coming from the Ticket Selector nor returning for a valid IP...
644
-     * then where you coming from man?
645
-     *
646
-     * @return boolean
647
-     */
648
-    private function _block_bots(): bool
649
-    {
650
-        return EED_Invalid_Checkout_Access::getInvalidCheckoutAccess()->checkoutAccessIsInvalid($this->checkout);
651
-    }
652
-
653
-
654
-    /**
655
-     *  gets slug for first step in $_reg_steps_array
656
-     *
657
-     * @return string
658
-     */
659
-    private function _get_first_step(): string
660
-    {
661
-        $first_step = reset(EED_Single_Page_Checkout::$_reg_steps_array);
662
-        return $first_step['slug'] ?? 'attendee_information';
663
-    }
664
-
665
-
666
-    /**
667
-     * instantiates each reg step based on the loaded reg_steps array
668
-     *
669
-     * @return bool
670
-     * @throws EE_Error
671
-     * @throws InvalidArgumentException
672
-     * @throws InvalidDataTypeException
673
-     * @throws InvalidInterfaceException
674
-     * @throws ReflectionException
675
-     */
676
-    private function _load_and_instantiate_reg_steps(): bool
677
-    {
678
-        do_action('AHEE__Single_Page_Checkout___load_and_instantiate_reg_steps__start', $this->checkout);
679
-        // have reg_steps already been instantiated ?
680
-        if (
681
-            empty($this->checkout->reg_steps)
682
-            || apply_filters('FHEE__Single_Page_Checkout__load_reg_steps__reload_reg_steps', false, $this->checkout)
683
-        ) {
684
-            // if not, then loop through raw reg steps array
685
-            foreach (EED_Single_Page_Checkout::$_reg_steps_array as $order => $reg_step) {
686
-                if (! $this->_load_and_instantiate_reg_step($reg_step, $order)) {
687
-                    return false;
688
-                }
689
-            }
690
-            if (isset($this->checkout->reg_steps['registration_confirmation'])) {
691
-                // skip the registration_confirmation page ?
692
-                // just remove it from the reg steps array
693
-                $this->checkout->remove_reg_step('registration_confirmation', false);
694
-            }
695
-            // filter the array for good luck
696
-            $this->checkout->reg_steps = apply_filters(
697
-                'FHEE__Single_Page_Checkout__load_reg_steps__reg_steps',
698
-                $this->checkout->reg_steps
699
-            );
700
-            // finally re-sort based on the reg step class order properties
701
-            $this->checkout->sort_reg_steps();
702
-        } else {
703
-            foreach ($this->checkout->reg_steps as $reg_step) {
704
-                // set all current step stati to FALSE
705
-                $reg_step->set_is_current_step(false);
706
-            }
707
-        }
708
-        if (empty($this->checkout->reg_steps)) {
709
-            EE_Error::add_error(
710
-                esc_html__('No Reg Steps were loaded..', 'event_espresso'),
711
-                __FILE__,
712
-                __FUNCTION__,
713
-                __LINE__
714
-            );
715
-            return false;
716
-        }
717
-        // make reg step details available to JS
718
-        $this->checkout->set_reg_step_JSON_info();
719
-        return true;
720
-    }
721
-
722
-
723
-    /**
724
-     * @param array $reg_step
725
-     * @param int   $order
726
-     * @return bool
727
-     * @throws EE_Error
728
-     * @throws ReflectionException
729
-     */
730
-    private function _load_and_instantiate_reg_step(array $reg_step = [], int $order = 0): bool
731
-    {
732
-        // we need a file_path, class_name, and slug to add a reg step
733
-        if (isset($reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'])) {
734
-            // if editing a specific step, but this is NOT that step... (and it's not the 'finalize_registration' step)
735
-            if (
736
-                $this->checkout->reg_url_link
737
-                && $this->checkout->step !== $reg_step['slug']
738
-                && $reg_step['slug'] !== 'finalize_registration'
739
-                // normally at this point we would NOT load the reg step, but this filter can change that
740
-                && apply_filters(
741
-                    'FHEE__Single_Page_Checkout___load_and_instantiate_reg_step__bypass_reg_step',
742
-                    true,
743
-                    $reg_step,
744
-                    $this->checkout
745
-                )
746
-            ) {
747
-                return true;
748
-            }
749
-
750
-            // instantiate step class using file path and class name
751
-            $reg_step_obj = EE_Registry::instance()->load_file(
752
-                $reg_step['file_path'],
753
-                $reg_step['class_name'],
754
-                'class',
755
-                [$this->checkout],
756
-                false
757
-            );
758
-            // did we get the goods ?
759
-            if ($reg_step_obj instanceof EE_SPCO_Reg_Step) {
760
-                // set reg step order based on config
761
-                $reg_step_obj->set_order($order);
762
-                // add instantiated reg step object to the master reg steps array
763
-                $this->checkout->add_reg_step($reg_step_obj);
764
-            } else {
765
-                EE_Error::add_error(
766
-                    esc_html__('The current step could not be set.', 'event_espresso'),
767
-                    __FILE__,
768
-                    __FUNCTION__,
769
-                    __LINE__
770
-                );
771
-                return false;
772
-            }
773
-        } else {
774
-            if (WP_DEBUG) {
775
-                EE_Error::add_error(
776
-                    sprintf(
777
-                        esc_html__(
778
-                            'A registration step could not be loaded. One or more of the following data points is invalid:%4$s%5$sFile Path: %1$s%6$s%5$sClass Name: %2$s%6$s%5$sSlug: %3$s%6$s%7$s',
779
-                            'event_espresso'
780
-                        ),
781
-                        $reg_step['file_path'] ?? '',
782
-                        $reg_step['class_name'] ?? '',
783
-                        $reg_step['slug'] ?? '',
784
-                        '<ul>',
785
-                        '<li>',
786
-                        '</li>',
787
-                        '</ul>'
788
-                    ),
789
-                    __FILE__,
790
-                    __FUNCTION__,
791
-                    __LINE__
792
-                );
793
-            }
794
-            return false;
795
-        }
796
-        return true;
797
-    }
798
-
799
-
800
-    /**
801
-     * @return bool
802
-     * @throws EE_Error
803
-     * @throws ReflectionException
804
-     */
805
-    private function _verify_transaction_and_get_registrations(): bool
806
-    {
807
-        // was there already a valid transaction in the checkout from the session ?
808
-        if (! $this->checkout->transaction instanceof EE_Transaction) {
809
-            // get transaction from db or session
810
-            $this->checkout->transaction = $this->checkout->reg_url_link && ! is_admin()
811
-                ? $this->_get_transaction_and_cart_for_previous_visit()
812
-                : $this->_get_cart_for_current_session_and_setup_new_transaction();
813
-            if (! $this->checkout->transaction instanceof EE_Transaction) {
814
-                EE_Error::add_error(
815
-                    esc_html__(
816
-                        'Your Registration and Transaction information could not be retrieved from the db.',
817
-                        'event_espresso'
818
-                    ),
819
-                    __FILE__,
820
-                    __FUNCTION__,
821
-                    __LINE__
822
-                );
823
-                $this->checkout->transaction = EE_Transaction::new_instance();
824
-                // add some style and make it dance
825
-                $this->add_styles_and_scripts($this);
826
-                EED_Single_Page_Checkout::$_initialized = true;
827
-                return false;
828
-            }
829
-            // and the registrations for the transaction
830
-            $this->_get_registrations($this->checkout->transaction);
831
-        }
832
-        return true;
833
-    }
834
-
835
-
836
-    /**
837
-     * @return EE_Transaction|null
838
-     * @throws EE_Error
839
-     * @throws ReflectionException
840
-     */
841
-    private function _get_transaction_and_cart_for_previous_visit(): ?EE_Transaction
842
-    {
843
-        /** @var $TXN_model EEM_Transaction */
844
-        $TXN_model = EE_Registry::instance()->load_model('Transaction');
845
-        // because the reg_url_link is present in the request,
846
-        // this is a return visit to SPCO, so we'll get the transaction data from the db
847
-        $transaction = $TXN_model->get_transaction_from_reg_url_link($this->checkout->reg_url_link);
848
-        // verify transaction
849
-        if ($transaction instanceof EE_Transaction) {
850
-            // and get the cart that was used for that transaction
851
-            $this->checkout->cart = $this->_get_cart_for_transaction($transaction);
852
-            return $transaction;
853
-        }
854
-        EE_Error::add_error(
855
-            esc_html__(
856
-                'Your Registration and Transaction information could not be retrieved from the db.',
857
-                'event_espresso'
858
-            ),
859
-            __FILE__,
860
-            __FUNCTION__,
861
-            __LINE__
862
-        );
863
-        return null;
864
-    }
865
-
866
-
867
-    /**
868
-     * @param EE_Transaction|null $transaction
869
-     * @return EE_Cart
870
-     */
871
-    private function _get_cart_for_transaction(?EE_Transaction $transaction): EE_Cart
872
-    {
873
-        return $this->checkout->get_cart_for_transaction($transaction);
874
-    }
875
-
876
-
877
-    /**
878
-     * @param EE_Transaction|null $transaction
879
-     * @return EE_Cart
880
-     */
881
-    public function get_cart_for_transaction(?EE_Transaction $transaction): EE_Cart
882
-    {
883
-        return $this->checkout->get_cart_for_transaction($transaction);
884
-    }
885
-
886
-
887
-    /**
888
-     * generates a new EE_Transaction object and adds it to the $_transaction property.
889
-     *
890
-     * @return EE_Transaction|null
891
-     * @throws EE_Error
892
-     * @throws ReflectionException
893
-     */
894
-    private function _get_cart_for_current_session_and_setup_new_transaction(): ?EE_Transaction
895
-    {
896
-        //  if there's no transaction, then this is the FIRST visit to SPCO
897
-        // so load up the cart ( passing nothing for the TXN because it doesn't exist yet )
898
-        $this->checkout->cart = $this->_get_cart_for_transaction(null);
899
-        // and then create a new transaction
900
-        $transaction = $this->_initialize_transaction();
901
-        // verify transaction
902
-        if ($transaction instanceof EE_Transaction) {
903
-            // and save TXN data to the cart
904
-            $this->checkout->cart->get_grand_total()->save_this_and_descendants_to_txn($transaction->ID());
905
-        } else {
906
-            EE_Error::add_error(
907
-                esc_html__('A Valid Transaction could not be initialized.', 'event_espresso'),
908
-                __FILE__,
909
-                __FUNCTION__,
910
-                __LINE__
911
-            );
912
-        }
913
-        return $transaction;
914
-    }
915
-
916
-
917
-    /**
918
-     * generates a new EE_Transaction object and adds it to the $_transaction property.
919
-     *
920
-     * @return EE_Transaction|null
921
-     */
922
-    private function _initialize_transaction(): ?EE_Transaction
923
-    {
924
-        try {
925
-            // ensure cart totals have been calculated
926
-            $this->checkout->cart->get_grand_total()->recalculate_total_including_taxes();
927
-            // grab the cart grand total
928
-            $cart_total = $this->checkout->cart->get_cart_grand_total();
929
-            // create new TXN
930
-            $transaction = EE_Transaction::new_instance(
931
-                [
932
-                    'TXN_reg_steps' => $this->checkout->initialize_txn_reg_steps_array(),
933
-                    'TXN_total'     => max($cart_total, 0),
934
-                    'TXN_paid'      => 0,
935
-                    'STS_ID'        => EEM_Transaction::failed_status_code,
936
-                ]
937
-            );
938
-            // save it so that we have an ID for other objects to use
939
-            $transaction->save();
940
-            // set cron job for following up on TXNs after their session has expired
941
-            EE_Cron_Tasks::schedule_expired_transaction_check(
942
-                EE_Registry::instance()->SSN->expiration() + 1,
943
-                $transaction->ID()
944
-            );
945
-            return $transaction;
946
-        } catch (Exception $e) {
947
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
948
-        }
949
-        return null;
950
-    }
951
-
952
-
953
-    /**
954
-     * _get_registrations
955
-     *
956
-     * @param EE_Transaction $transaction
957
-     * @return void
958
-     * @throws EE_Error
959
-     * @throws ReflectionException
960
-     */
961
-    private function _get_registrations(EE_Transaction $transaction)
962
-    {
963
-        // first step: grab the registrants  { : o
964
-        $registrations                      = $transaction->registrations($this->checkout->reg_cache_where_params);
965
-        $this->checkout->total_ticket_count = count($registrations);
966
-        // verify registrations have been set
967
-        if (empty($registrations)) {
968
-            // if no cached registrations, then check the db
969
-            $registrations = $transaction->registrations($this->checkout->reg_cache_where_params);
970
-            // still nothing ? well as long as this isn't a revisit
971
-            if (empty($registrations) && ! $this->checkout->revisit) {
972
-                // generate new registrations from scratch
973
-                $registrations = $this->_initialize_registrations($transaction);
974
-            }
975
-        }
976
-        // sort by their original registration order
977
-        usort($registrations, ['EED_Single_Page_Checkout', 'sort_registrations_by_REG_count']);
978
-        // then loop thru the array
979
-        foreach ($registrations as $registration) {
980
-            // verify each registration
981
-            if ($registration instanceof EE_Registration) {
982
-                // we display all attendee info for the primary registrant
983
-                if (
984
-                    $this->checkout->reg_url_link === $registration->reg_url_link()
985
-                    && $registration->is_primary_registrant()
986
-                ) {
987
-                    $this->checkout->primary_revisit = true;
988
-                    break;
989
-                }
990
-                if ($this->checkout->revisit && $this->checkout->reg_url_link !== $registration->reg_url_link()) {
991
-                    // but hide info if it doesn't belong to you
992
-                    $transaction->clear_cache('Registration', $registration->ID());
993
-                    $this->checkout->total_ticket_count--;
994
-                }
995
-                $this->checkout->set_reg_status_updated($registration->ID(), false);
996
-            }
997
-        }
998
-    }
999
-
1000
-
1001
-    /**
1002
-     * adds related EE_Registration objects for each ticket in the cart to the current EE_Transaction object
1003
-     *
1004
-     * @param EE_Transaction $transaction
1005
-     * @return array
1006
-     * @throws EE_Error
1007
-     * @throws ReflectionException
1008
-     */
1009
-    private function _initialize_registrations(EE_Transaction $transaction): array
1010
-    {
1011
-        $att_nmbr      = 0;
1012
-        $registrations = [];
1013
-        /** @type EE_Registration_Processor $registration_processor */
1014
-        $registration_processor             = EE_Registry::instance()->load_class('Registration_Processor');
1015
-        $this->checkout->total_ticket_count = $this->checkout->cart->all_ticket_quantity_count();
1016
-        // now let's add the cart items to the $transaction
1017
-        foreach ($this->checkout->cart->get_tickets() as $line_item) {
1018
-            // do the following for each ticket of this type they selected
1019
-            for ($x = 1; $x <= $line_item->quantity(); $x++) {
1020
-                $att_nmbr++;
1021
-                /** @var CreateRegistrationCommand $CreateRegistrationCommand */
1022
-                $CreateRegistrationCommand = EE_Registry::instance()->create(
1023
-                    CreateRegistrationCommand::class,
1024
-                    [
1025
-                        $transaction,
1026
-                        $line_item,
1027
-                        $att_nmbr,
1028
-                        $this->checkout->total_ticket_count,
1029
-                    ]
1030
-                );
1031
-                // override capabilities for frontend registrations
1032
-                if ($this->request->isFrontend()) {
1033
-                    $CreateRegistrationCommand->setCapCheck(
1034
-                        new PublicCapabilities('', 'create_new_registration')
1035
-                    );
1036
-                }
1037
-                $registration = EE_Registry::instance()->BUS->execute($CreateRegistrationCommand);
1038
-                if (! $registration instanceof EE_Registration) {
1039
-                    throw new InvalidEntityException($registration, 'EE_Registration');
1040
-                }
1041
-                $registrations[ $registration->ID() ] = $registration;
1042
-            }
1043
-        }
1044
-        $registration_processor->fix_reg_final_price_rounding_issue($transaction);
1045
-        return $registrations;
1046
-    }
1047
-
1048
-
1049
-    /**
1050
-     * @param EE_Registration $reg_A
1051
-     * @param EE_Registration $reg_B
1052
-     * @return int
1053
-     * @throws EE_Error
1054
-     * @throws ReflectionException
1055
-     */
1056
-    public static function sort_registrations_by_REG_count(EE_Registration $reg_A, EE_Registration $reg_B): int
1057
-    {
1058
-        // this shouldn't ever happen within the same TXN, but oh well
1059
-        if ($reg_A->count() === $reg_B->count()) {
1060
-            return 0;
1061
-        }
1062
-        return ($reg_A->count() > $reg_B->count()) ? 1 : -1;
1063
-    }
1064
-
1065
-
1066
-    /**
1067
-     * just makes sure that everything is set up correctly before proceeding
1068
-     *
1069
-     * @return bool
1070
-     * @throws EE_Error
1071
-     * @throws ReflectionException
1072
-     */
1073
-    private function _final_verifications(): bool
1074
-    {
1075
-        // filter checkout
1076
-        $this->checkout = apply_filters(
1077
-            'FHEE__EED_Single_Page_Checkout___final_verifications__checkout',
1078
-            $this->checkout
1079
-        );
1080
-        // verify that current step is still set correctly
1081
-        if (! $this->checkout->current_step instanceof EE_SPCO_Reg_Step) {
1082
-            EE_Error::add_error(
1083
-                esc_html__(
1084
-                    'We\'re sorry but the registration process can not proceed because one or more registration steps were not setup correctly. Please refresh the page and try again or contact support.',
1085
-                    'event_espresso'
1086
-                ),
1087
-                __FILE__,
1088
-                __FUNCTION__,
1089
-                __LINE__
1090
-            );
1091
-            return false;
1092
-        }
1093
-        // if returning to SPCO, then verify that primary registrant is set
1094
-        if (! empty($this->checkout->reg_url_link)) {
1095
-            $valid_registrant = $this->checkout->transaction->primary_registration();
1096
-            if (! $valid_registrant instanceof EE_Registration) {
1097
-                EE_Error::add_error(
1098
-                    esc_html__(
1099
-                        'We\'re sorry but there appears to be an error with the "reg_url_link" or the primary registrant for this transaction. Please refresh the page and try again or contact support.',
1100
-                        'event_espresso'
1101
-                    ),
1102
-                    __FILE__,
1103
-                    __FUNCTION__,
1104
-                    __LINE__
1105
-                );
1106
-                return false;
1107
-            }
1108
-            $valid_registrant = null;
1109
-            foreach (
1110
-                $this->checkout->transaction->registrations(
1111
-                    $this->checkout->reg_cache_where_params
1112
-                ) as $registration
1113
-            ) {
1114
-                if (
1115
-                    $registration instanceof EE_Registration
1116
-                    && $registration->reg_url_link() === $this->checkout->reg_url_link
1117
-                ) {
1118
-                    $valid_registrant = $registration;
1119
-                }
1120
-            }
1121
-            if (! $valid_registrant instanceof EE_Registration) {
1122
-                // hmmm... maybe we have the wrong session because the user is opening multiple tabs ?
1123
-                if (EED_Single_Page_Checkout::$_checkout_verified) {
1124
-                    // clear the session, mark the checkout as unverified, and try again
1125
-                    EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
1126
-                    EED_Single_Page_Checkout::$_initialized       = false;
1127
-                    EED_Single_Page_Checkout::$_checkout_verified = false;
1128
-                    $this->_initialize();
1129
-                    EE_Error::reset_notices();
1130
-                    return false;
1131
-                }
1132
-                EE_Error::add_error(
1133
-                    esc_html__(
1134
-                        'We\'re sorry but there appears to be an error with the "reg_url_link" or the transaction itself. Please refresh the page and try again or contact support.',
1135
-                        'event_espresso'
1136
-                    ),
1137
-                    __FILE__,
1138
-                    __FUNCTION__,
1139
-                    __LINE__
1140
-                );
1141
-                return false;
1142
-            }
1143
-        }
1144
-        // now that things have been kinda sufficiently verified,
1145
-        // let's add the checkout to the session so that it's available to other systems
1146
-        EE_Registry::instance()->SSN->set_checkout($this->checkout);
1147
-        return true;
1148
-    }
1149
-
1150
-
1151
-    /**
1152
-     * first makes sure that EE_Transaction_Processor::set_reg_step_initiated() is called as required
1153
-     * then loops thru all the active reg steps and calls the initialize_reg_step() method
1154
-     *
1155
-     * @param bool $reinitializing
1156
-     * @throws EE_Error
1157
-     */
1158
-    private function _initialize_reg_steps(bool $reinitializing = false)
1159
-    {
1160
-        $this->checkout->set_reg_step_initiated($this->checkout->current_step);
1161
-        // loop thru all steps to call their individual "initialize" methods and set i18n strings for JS
1162
-        foreach ($this->checkout->reg_steps as $reg_step) {
1163
-            if (! $reg_step->initialize_reg_step()) {
1164
-                // if not initialized then maybe this step is being removed...
1165
-                if (! $reinitializing && $reg_step->is_current_step()) {
1166
-                    // if it was the current step, then we need to start over here
1167
-                    $this->_initialize_reg_steps(true);
1168
-                    return;
1169
-                }
1170
-                continue;
1171
-            }
1172
-            // add css and JS for current step
1173
-            $this->add_styles_and_scripts($reg_step);
1174
-            if ($reg_step->is_current_step()) {
1175
-                // the text that appears on the reg step form submit button
1176
-                $reg_step->set_submit_button_text();
1177
-            }
1178
-        }
1179
-        // dynamically creates hook point like: AHEE__Single_Page_Checkout___initialize_reg_step__attendee_information
1180
-        do_action(
1181
-            "AHEE__Single_Page_Checkout___initialize_reg_step__{$this->checkout->current_step->slug()}",
1182
-            $this->checkout->current_step
1183
-        );
1184
-    }
1185
-
1186
-
1187
-    /**
1188
-     * @return boolean
1189
-     * @throws EE_Error
1190
-     * @throws ReflectionException
1191
-     */
1192
-    private function _check_form_submission(): bool
1193
-    {
1194
-        // does this request require the reg form to be generated ?
1195
-        if ($this->checkout->generate_reg_form) {
1196
-            // ever heard that song by Blue Rodeo ?
1197
-            try {
1198
-                $this->checkout->current_step->reg_form = $this->checkout->current_step->generate_reg_form();
1199
-                // if not displaying a form, then check for form submission
1200
-                if (
1201
-                    $this->checkout->process_form_submission
1202
-                    && $this->checkout->current_step->reg_form->was_submitted()
1203
-                ) {
1204
-                    // clear out any old data in case this step is being run again
1205
-                    $this->checkout->current_step->set_valid_data([]);
1206
-                    // capture submitted form data
1207
-                    $request_data = $this->request->requestParams();
1208
-                    $this->checkout->current_step->reg_form->receive_form_submission(
1209
-                        (array) apply_filters(
1210
-                            'FHEE__Single_Page_Checkout___check_form_submission__request_params',
1211
-                            $request_data,
1212
-                            $this->checkout
1213
-                        )
1214
-                    );
1215
-                    // validate submitted form data
1216
-                    if (! $this->checkout->continue_reg || ! $this->checkout->current_step->reg_form->is_valid()) {
1217
-                        // thou shall not pass !!!
1218
-                        $this->checkout->continue_reg = false;
1219
-                        // any form validation errors?
1220
-                        if ($this->checkout->current_step->reg_form->submission_error_message() !== '') {
1221
-                            EE_Error::add_error(
1222
-                                $this->checkout->current_step->reg_form->submission_error_message(),
1223
-                                __FILE__,
1224
-                                __FUNCTION__,
1225
-                                __LINE__
1226
-                            );
1227
-                        }
1228
-                        // well not really... what will happen is
1229
-                        // we'll just get redirected back to redo the current step
1230
-                        $this->go_to_next_step();
1231
-                        return false;
1232
-                    }
1233
-                }
1234
-            } catch (EE_Error $e) {
1235
-                $e->get_error();
1236
-            }
1237
-        }
1238
-        return true;
1239
-    }
1240
-
1241
-
1242
-    /**
1243
-     * @return void
1244
-     * @throws EE_Error
1245
-     * @throws ReflectionException
1246
-     */
1247
-    private function _process_form_action()
1248
-    {
1249
-        // what cha wanna do?
1250
-        switch ($this->checkout->action) {
1251
-            // AJAX next step reg form
1252
-            case 'display_spco_reg_step':
1253
-                $this->checkout->redirect = false;
1254
-                if ($this->request->isAjax()) {
1255
-                    $this->checkout->json_response->set_reg_step_html(
1256
-                        $this->checkout->current_step->display_reg_form()
1257
-                    );
1258
-                }
1259
-                break;
1260
-            default:
1261
-                // meh... do one of those other steps first
1262
-                if (
1263
-                    ! empty($this->checkout->action)
1264
-                    && is_callable([$this->checkout->current_step, $this->checkout->action])
1265
-                ) {
1266
-                    // dynamically creates hook point like:
1267
-                    //   AHEE__Single_Page_Checkout__before_attendee_information__process_reg_step
1268
-                    do_action(
1269
-                        "AHEE__Single_Page_Checkout__before_{$this->checkout->current_step->slug()}__{$this->checkout->action}",
1270
-                        $this->checkout->current_step
1271
-                    );
1272
-                    $process_reg_step = apply_filters(
1273
-                        "AHEE__Single_Page_Checkout__process_reg_step__{$this->checkout->current_step->slug()}__{$this->checkout->action}",
1274
-                        true,
1275
-                        $this->checkout->current_step,
1276
-                        $this
1277
-                    );
1278
-                    // call action on current step
1279
-                    if ($process_reg_step && call_user_func([$this->checkout->current_step, $this->checkout->action])) {
1280
-                        // good registrant, you get to proceed
1281
-                        if (
1282
-                            $this->checkout->current_step->success_message() !== ''
1283
-                            && apply_filters(
1284
-                                'FHEE__Single_Page_Checkout___process_form_action__display_success',
1285
-                                false
1286
-                            )
1287
-                        ) {
1288
-                            EE_Error::add_success(
1289
-                                $this->checkout->current_step->success_message()
1290
-                                . '<br />' . $this->checkout->next_step->_instructions()
1291
-                            );
1292
-                        }
1293
-                        // pack it up, pack it in...
1294
-                        $this->_setup_redirect();
1295
-                    }
1296
-                    // dynamically creates hook point like:
1297
-                    //  AHEE__Single_Page_Checkout__after_payment_options__process_reg_step
1298
-                    do_action(
1299
-                        "AHEE__Single_Page_Checkout__after_{$this->checkout->current_step->slug()}__{$this->checkout->action}",
1300
-                        $this->checkout->current_step
1301
-                    );
1302
-                } else {
1303
-                    EE_Error::add_error(
1304
-                        sprintf(
1305
-                            esc_html__(
1306
-                                'The requested form action "%s" does not exist for the current "%s" registration step.',
1307
-                                'event_espresso'
1308
-                            ),
1309
-                            $this->checkout->action,
1310
-                            $this->checkout->current_step->name()
1311
-                        ),
1312
-                        __FILE__,
1313
-                        __FUNCTION__,
1314
-                        __LINE__
1315
-                    );
1316
-                }
1317
-            // end default
1318
-        }
1319
-        // store our progress so far
1320
-        $this->checkout->stash_transaction_and_checkout();
1321
-        // advance to the next step! If you pass GO, collect $200
1322
-        $this->go_to_next_step();
1323
-    }
1324
-
1325
-
1326
-    /**
1327
-     * @param EED_Single_Page_Checkout|EE_SPCO_Reg_Step $target an object with the method `translate_js_strings` and
1328
-     *                                                          `enqueue_styles_and_scripts`.
1329
-     * @return void
1330
-     */
1331
-    public function add_styles_and_scripts($target)
1332
-    {
1333
-        // i18n
1334
-        $target->translate_js_strings();
1335
-        if ($this->checkout->admin_request) {
1336
-            add_action('admin_enqueue_scripts', [$target, 'enqueue_styles_and_scripts']);
1337
-        } else {
1338
-            add_action('wp_enqueue_scripts', [$target, 'enqueue_styles_and_scripts']);
1339
-        }
1340
-    }
1341
-
1342
-
1343
-    /**
1344
-     * @return void
1345
-     */
1346
-    public function translate_js_strings()
1347
-    {
1348
-        EE_Registry::$i18n_js_strings['revisit']                        = $this->checkout->revisit;
1349
-        EE_Registry::$i18n_js_strings['e_reg_url_link']                 = $this->checkout->reg_url_link;
1350
-        EE_Registry::$i18n_js_strings['server_error']                   = esc_html__(
1351
-            'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.',
1352
-            'event_espresso'
1353
-        );
1354
-        EE_Registry::$i18n_js_strings['invalid_json_response']          = esc_html__(
1355
-            'An invalid response was returned from the server while attempting to process your request. Please refresh the page and try again or contact support.',
1356
-            'event_espresso'
1357
-        );
1358
-        EE_Registry::$i18n_js_strings['validation_error']               = esc_html__(
1359
-            'There appears to be a problem with the form validation configuration! Please check the admin settings or contact support.',
1360
-            'event_espresso'
1361
-        );
1362
-        EE_Registry::$i18n_js_strings['invalid_payment_method']         = esc_html__(
1363
-            'There appears to be a problem with the payment method configuration! Please refresh the page and try again or contact support.',
1364
-            'event_espresso'
1365
-        );
1366
-        EE_Registry::$i18n_js_strings['reg_step_error']                 = esc_html__(
1367
-            'This registration step could not be completed. Please refresh the page and try again.',
1368
-            'event_espresso'
1369
-        );
1370
-        EE_Registry::$i18n_js_strings['invalid_coupon']                 = esc_html__(
1371
-            'We\'re sorry but that coupon code does not appear to be valid. If this is incorrect, please contact the site administrator.',
1372
-            'event_espresso'
1373
-        );
1374
-        EE_Registry::$i18n_js_strings['process_registration']           = sprintf(
1375
-            esc_html__(
1376
-                'Please wait while we process your registration.%sDo not refresh the page or navigate away while this is happening.%sThank you for your patience.',
1377
-                'event_espresso'
1378
-            ),
1379
-            '<br/>',
1380
-            '<br/>'
1381
-        );
1382
-        EE_Registry::$i18n_js_strings['language']                       = get_bloginfo('language');
1383
-        EE_Registry::$i18n_js_strings['EESID']                          = EE_Registry::instance()->SSN->id();
1384
-        EE_Registry::$i18n_js_strings['currency']                       = EE_Registry::instance()->CFG->currency;
1385
-        EE_Registry::$i18n_js_strings['datepicker_yearRange']           = '-150:+20';
1386
-        EE_Registry::$i18n_js_strings['timer_years']                    = esc_html__('years', 'event_espresso');
1387
-        EE_Registry::$i18n_js_strings['timer_months']                   = esc_html__('months', 'event_espresso');
1388
-        EE_Registry::$i18n_js_strings['timer_weeks']                    = esc_html__('weeks', 'event_espresso');
1389
-        EE_Registry::$i18n_js_strings['timer_days']                     = esc_html__('days', 'event_espresso');
1390
-        EE_Registry::$i18n_js_strings['timer_hours']                    = esc_html__('hours', 'event_espresso');
1391
-        EE_Registry::$i18n_js_strings['timer_minutes']                  = esc_html__('minutes', 'event_espresso');
1392
-        EE_Registry::$i18n_js_strings['timer_seconds']                  = esc_html__('seconds', 'event_espresso');
1393
-        EE_Registry::$i18n_js_strings['timer_year']                     = esc_html__('year', 'event_espresso');
1394
-        EE_Registry::$i18n_js_strings['timer_month']                    = esc_html__('month', 'event_espresso');
1395
-        EE_Registry::$i18n_js_strings['timer_week']                     = esc_html__('week', 'event_espresso');
1396
-        EE_Registry::$i18n_js_strings['timer_day']                      = esc_html__('day', 'event_espresso');
1397
-        EE_Registry::$i18n_js_strings['timer_hour']                     = esc_html__('hour', 'event_espresso');
1398
-        EE_Registry::$i18n_js_strings['timer_minute']                   = esc_html__('minute', 'event_espresso');
1399
-        EE_Registry::$i18n_js_strings['timer_second']                   = esc_html__('second', 'event_espresso');
1400
-        EE_Registry::$i18n_js_strings['registration_expiration_notice'] =
1401
-            EED_Single_Page_Checkout::getRegistrationExpirationNotice();
1402
-        EE_Registry::$i18n_js_strings['ajax_submit']                    = apply_filters(
1403
-            'FHEE__Single_Page_Checkout__translate_js_strings__ajax_submit',
1404
-            true
1405
-        );
1406
-        EE_Registry::$i18n_js_strings['session_extension']              = absint(
1407
-            apply_filters('FHEE__EE_Session__extend_expiration__seconds_added', 10 * MINUTE_IN_SECONDS)
1408
-        );
1409
-        EE_Registry::$i18n_js_strings['session_expiration']    = EE_Registry::instance()->SSN->expiration();
1410
-        EE_Registry::$i18n_js_strings['use_session_countdown'] = EE_Registry::instance()->CFG->registration->useSessionCountdown();
1411
-        EE_Registry::$i18n_js_strings['no_copy_paste_email_confirm'] = esc_html__("We're sorry but copy and paste is disabled for email confirmation inputs. Please enter the email address manually.", 'event_espresso');
1412
-    }
1413
-
1414
-
1415
-    /**
1416
-     * @return void
1417
-     * @throws EE_Error
1418
-     */
1419
-    public function enqueue_styles_and_scripts()
1420
-    {
1421
-        // load css
1422
-        wp_register_style(
1423
-            'single_page_checkout',
1424
-            SPCO_CSS_URL . 'single_page_checkout.css',
1425
-            ['espresso_default'],
1426
-            EVENT_ESPRESSO_VERSION
1427
-        );
1428
-        wp_enqueue_style('single_page_checkout');
1429
-        // load JS
1430
-        wp_register_script(
1431
-            'single_page_checkout',
1432
-            SPCO_JS_URL . 'single_page_checkout.js',
1433
-            ['espresso_core', 'underscore', 'ee_form_section_validation'],
1434
-            EVENT_ESPRESSO_VERSION,
1435
-            true
1436
-        );
1437
-        if ($this->checkout->registration_form instanceof EE_Form_Section_Proper) {
1438
-            $this->checkout->registration_form->enqueue_js();
1439
-        }
1440
-        if ($this->checkout->current_step->reg_form instanceof EE_Form_Section_Proper) {
1441
-            $this->checkout->current_step->reg_form->enqueue_js();
1442
-        }
1443
-        wp_enqueue_script('single_page_checkout');
1444
-        /**
1445
-         * global action hook for enqueueing styles and scripts with
1446
-         * spco calls.
1447
-         */
1448
-        do_action('AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts', $this);
1449
-        /**
1450
-         * dynamic action hook for enqueueing styles and scripts with spco calls.
1451
-         * The hook will end up being something like:
1452
-         *      AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__attendee_information
1453
-         */
1454
-        do_action(
1455
-            'AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__' . $this->checkout->current_step->slug(),
1456
-            $this
1457
-        );
1458
-    }
1459
-
1460
-
1461
-    /**
1462
-     * display the Registration Single Page Checkout Form
1463
-     *
1464
-     * @return void
1465
-     * @throws EE_Error
1466
-     * @throws ReflectionException
1467
-     */
1468
-    private function _display_spco_reg_form()
1469
-    {
1470
-        // if registering via the admin, just display the reg form for the current step
1471
-        if ($this->checkout->admin_request) {
1472
-            EED_Single_Page_Checkout::getResponse()->addOutput($this->checkout->current_step->display_reg_form());
1473
-        } else {
1474
-            // add powered by EE msg
1475
-            add_action('AHEE__SPCO__reg_form_footer', ['EED_Single_Page_Checkout', 'display_registration_footer']);
1476
-            $empty_cart                                 = count(
1477
-                    $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params)
1478
-                ) < 1;
1479
-            EE_Registry::$i18n_js_strings['empty_cart'] = $empty_cart;
1480
-            $cookies_not_set_msg                        = '';
1481
-            if ($empty_cart) {
1482
-                $cookies_not_set_msg = apply_filters(
1483
-                    'FHEE__Single_Page_Checkout__display_spco_reg_form__cookies_not_set_msg',
1484
-                    sprintf(
1485
-                        esc_html__(
1486
-                            '%1$s%3$sIt appears your browser is not currently set to accept Cookies%4$s%5$sIn order to register for events, you need to enable cookies.%7$sIf you require assistance, then click the following link to learn how to %8$senable cookies%9$s%6$s%2$s',
1487
-                            'event_espresso'
1488
-                        ),
1489
-                        '<div class="ee-attention hidden" id="ee-cookies-not-set-msg">',
1490
-                        '</div>',
1491
-                        '<h6 class="important-notice">',
1492
-                        '</h6>',
1493
-                        '<p>',
1494
-                        '</p>',
1495
-                        '<br />',
1496
-                        '<a href="https://www.whatismybrowser.com/guides/how-to-enable-cookies/" target="_blank" rel="noopener noreferrer">',
1497
-                        '</a>'
1498
-                    )
1499
-                );
1500
-            }
1501
-            $this->checkout->registration_form = new EE_Form_Section_Proper(
1502
-                [
1503
-                    'name'            => 'single-page-checkout',
1504
-                    'html_id'         => 'ee-single-page-checkout-dv',
1505
-                    'layout_strategy' =>
1506
-                        new EE_Template_Layout(
1507
-                            [
1508
-                                'layout_template_file' => SPCO_TEMPLATES_PATH . 'registration_page_wrapper.template.php',
1509
-                                'template_args'        => [
1510
-                                    'empty_cart'              => $empty_cart,
1511
-                                    'revisit'                 => $this->checkout->revisit,
1512
-                                    'reg_steps'               => $this->checkout->reg_steps,
1513
-                                    'next_step'               => $this->checkout->next_step instanceof EE_SPCO_Reg_Step
1514
-                                        ? $this->checkout->next_step->slug()
1515
-                                        : '',
1516
-                                    'empty_msg'               => apply_filters(
1517
-                                        'FHEE__Single_Page_Checkout__display_spco_reg_form__empty_msg',
1518
-                                        sprintf(
1519
-                                            esc_html__(
1520
-                                                'You need to %1$sReturn to Events list%2$sselect at least one event%3$s before you can proceed with the registration process.',
1521
-                                                'event_espresso'
1522
-                                            ),
1523
-                                            '<a href="'
1524
-                                            . get_post_type_archive_link(EspressoPostType::EVENTS)
1525
-                                            . '" title="',
1526
-                                            '">',
1527
-                                            '</a>'
1528
-                                        )
1529
-                                    ),
1530
-                                    'cookies_not_set_msg'     => $cookies_not_set_msg,
1531
-                                    'registration_time_limit' => $this->checkout->get_registration_time_limit(),
1532
-                                    'use_session_countdown'   => EE_Registry::instance()->CFG->registration->useSessionCountdown(),
1533
-                                ],
1534
-                            ]
1535
-                        ),
1536
-                ]
1537
-            );
1538
-            // load template and add to output sent that gets filtered into the_content()
1539
-            EED_Single_Page_Checkout::getResponse()->addOutput($this->checkout->registration_form->get_html());
1540
-        }
1541
-    }
1542
-
1543
-
1544
-    /**
1545
-     * @param $next_step
1546
-     * @return void
1547
-     */
1548
-    public function add_extra_finalize_registration_inputs($next_step)
1549
-    {
1550
-        if ($next_step === 'finalize_registration') {
1551
-            echo '<div id="spco-extra-finalize_registration-inputs-dv"></div>';
1552
-        }
1553
-    }
1554
-
1555
-
1556
-    /**
1557
-     * @return void
1558
-     */
1559
-    public static function display_registration_footer()
1560
-    {
1561
-        if (
1562
-            apply_filters(
1563
-                'FHEE__EE_Front__Controller__show_reg_footer',
1564
-                EE_Registry::instance()->CFG->admin->show_reg_footer
1565
-            )
1566
-        ) {
1567
-            add_filter(
1568
-                'FHEE__EEH_Template__powered_by_event_espresso__url',
1569
-                function ($url) {
1570
-                    return apply_filters('FHEE__EE_Front_Controller__registration_footer__url', $url);
1571
-                }
1572
-            );
1573
-            echo apply_filters(
1574
-                'FHEE__EE_Front_Controller__display_registration_footer',
1575
-                EEH_Template::powered_by_event_espresso(
1576
-                    '',
1577
-                    'espresso-registration-footer-dv',
1578
-                    ['utm_content' => 'registration_checkout']
1579
-                )
1580
-            );
1581
-        }
1582
-    }
1583
-
1584
-
1585
-    /**
1586
-     * @return void
1587
-     * @throws EE_Error
1588
-     * @throws ReflectionException
1589
-     */
1590
-    public function unlock_transaction()
1591
-    {
1592
-        if ($this->checkout instanceof EE_Checkout && $this->checkout->transaction instanceof EE_Transaction) {
1593
-            $this->checkout->transaction->unlock();
1594
-        }
1595
-    }
1596
-
1597
-
1598
-    /**
1599
-     * @return void
1600
-     */
1601
-    private function _setup_redirect()
1602
-    {
1603
-        if ($this->checkout->continue_reg && $this->checkout->next_step instanceof EE_SPCO_Reg_Step) {
1604
-            $this->checkout->redirect = true;
1605
-            if (empty($this->checkout->redirect_url)) {
1606
-                $this->checkout->redirect_url = $this->checkout->next_step->reg_step_url();
1607
-            }
1608
-            $this->checkout->redirect_url = apply_filters(
1609
-                'FHEE__EED_Single_Page_Checkout___setup_redirect__checkout_redirect_url',
1610
-                $this->checkout->redirect_url,
1611
-                $this->checkout
1612
-            );
1613
-        }
1614
-    }
1615
-
1616
-
1617
-    /**
1618
-     * handle ajax message responses and redirects
1619
-     *
1620
-     * @return void
1621
-     * @throws EE_Error
1622
-     * @throws ReflectionException
1623
-     */
1624
-    public function go_to_next_step()
1625
-    {
1626
-        if ($this->request->isAjax()) {
1627
-            // capture contents of output buffer we started earlier in the request, and insert into JSON response
1628
-            $this->checkout->json_response->set_unexpected_errors(ob_get_clean());
1629
-        }
1630
-        $this->unlock_transaction();
1631
-        // just return for these conditions
1632
-        if (
1633
-            $this->checkout->admin_request
1634
-            || $this->checkout->action === 'redirect_form'
1635
-            || $this->checkout->action === 'update_checkout'
1636
-        ) {
1637
-            return;
1638
-        }
1639
-        // AJAX response
1640
-        $this->_handle_json_response();
1641
-        // redirect to next step or the Thank-You page
1642
-        $this->_handle_html_redirects();
1643
-        // hmmm... must be something wrong, so let's just display the form again !
1644
-        $this->_display_spco_reg_form();
1645
-    }
1646
-
1647
-
1648
-    /**
1649
-     * @return void
1650
-     * @throws EE_Error
1651
-     */
1652
-    protected function _handle_json_response()
1653
-    {
1654
-        // if this is an ajax request
1655
-        if ($this->request->isAjax()) {
1656
-            $this->checkout->json_response->set_registration_time_limit(
1657
-                $this->checkout->get_registration_time_limit()
1658
-            );
1659
-            $this->checkout->json_response->set_payment_amount($this->checkout->amount_owing);
1660
-            // just send the ajax (
1661
-            $json_response = apply_filters(
1662
-                'FHEE__EE_Single_Page_Checkout__JSON_response',
1663
-                $this->checkout->json_response
1664
-            );
1665
-            exit($json_response);
1666
-        }
1667
-    }
1668
-
1669
-
1670
-    /**
1671
-     * @return void
1672
-     */
1673
-    protected function _handle_html_redirects()
1674
-    {
1675
-        // going somewhere ?
1676
-        if ($this->checkout->redirect && ! empty($this->checkout->redirect_url)) {
1677
-            // store notices in a transient
1678
-            EE_Error::get_notices(false, true);
1679
-            wp_safe_redirect($this->checkout->redirect_url);
1680
-            exit();
1681
-        }
1682
-    }
1683
-
1684
-
1685
-    /**
1686
-     * @return void
1687
-     */
1688
-    public function set_checkout_anchor()
1689
-    {
1690
-        echo '<a id="checkout" style="float: left; margin-left: -999em;"></a>';
1691
-    }
1692
-
1693
-
1694
-    /**
1695
-     * @return string
1696
-     * @since 4.9.59.p
1697
-     */
1698
-    public static function getRegistrationExpirationNotice(): string
1699
-    {
1700
-        return sprintf(
1701
-            esc_html__(
1702
-                '%1$sWe\'re sorry, but your registration time has expired.%2$s%3$s%4$sIf you still wish to complete your registration, please return to the %5$sEvent List%6$sEvent List%7$s and reselect your tickets if available. Please accept our apologies for any inconvenience this may have caused.%8$s',
1703
-                'event_espresso'
1704
-            ),
1705
-            '<h4 class="important-notice">',
1706
-            '</h4>',
1707
-            '<br />',
1708
-            '<p>',
1709
-            '<a href="' . get_post_type_archive_link(EspressoPostType::EVENTS) . '" title="',
1710
-            '">',
1711
-            '</a>',
1712
-            '</p>'
1713
-        );
1714
-    }
23
+	/**
24
+	 * $_initialized - has the SPCO controller already been initialized ?
25
+	 */
26
+	private static bool $_initialized = false;
27
+
28
+
29
+	/**
30
+	 * $_checkout_verified - is the EE_Checkout verified as correct for this request ?
31
+	 */
32
+	private static bool $_checkout_verified = true;
33
+
34
+	/**
35
+	 * $_reg_steps_array - holds initial array of reg steps
36
+	 *
37
+	 * @var array $_reg_steps_array
38
+	 */
39
+	private static array $_reg_steps_array = [];
40
+
41
+	/**
42
+	 * $checkout - EE_Checkout object for handling the properties of the current checkout process
43
+	 */
44
+	public ?EE_Checkout $checkout = null;
45
+
46
+	protected ?RequestInterface $request = null;
47
+
48
+	private bool $debug = false;    //  true    false
49
+
50
+
51
+	/**
52
+	 * @return EED_Single_Page_Checkout|EED_Module
53
+	 * @throws EE_Error
54
+	 * @throws ReflectionException
55
+	 */
56
+	public static function instance()
57
+	{
58
+		add_filter('EED_Single_Page_Checkout__SPCO_active', '__return_true');
59
+		return parent::get_instance(__CLASS__);
60
+	}
61
+
62
+
63
+	/**
64
+	 * @return EE_CART
65
+	 */
66
+	public function cart(): EE_CART
67
+	{
68
+		return $this->checkout->cart;
69
+	}
70
+
71
+
72
+	/**
73
+	 * @return RequestInterface
74
+	 * @since   4.10.14.p
75
+	 */
76
+	public static function getRequest(): RequestInterface
77
+	{
78
+		return LoaderFactory::getLoader()->getShared(RequestInterface::class);
79
+	}
80
+
81
+
82
+	/**
83
+	 * @return EE_Transaction
84
+	 */
85
+	public function transaction(): EE_Transaction
86
+	{
87
+		return $this->checkout->transaction;
88
+	}
89
+
90
+
91
+	/**
92
+	 *    set_hooks - for hooking into EE Core, other modules, etc
93
+	 *
94
+	 * @return    void
95
+	 * @throws EE_Error
96
+	 */
97
+	public static function set_hooks()
98
+	{
99
+		EED_Single_Page_Checkout::set_definitions();
100
+	}
101
+
102
+
103
+	/**
104
+	 *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
105
+	 *
106
+	 * @return    void
107
+	 * @throws EE_Error
108
+	 */
109
+	public static function set_hooks_admin()
110
+	{
111
+		EED_Single_Page_Checkout::set_definitions();
112
+		if (! (defined('DOING_AJAX') && DOING_AJAX)) {
113
+			return;
114
+		}
115
+		// going to start an output buffer in case anything gets accidentally output
116
+		// that might disrupt our JSON response
117
+		ob_start();
118
+		EED_Single_Page_Checkout::load_reg_steps();
119
+		// set ajax hooks
120
+		add_action('wp_ajax_process_reg_step', ['EED_Single_Page_Checkout', 'process_reg_step']);
121
+		add_action('wp_ajax_nopriv_process_reg_step', ['EED_Single_Page_Checkout', 'process_reg_step']);
122
+		add_action('wp_ajax_display_spco_reg_step', ['EED_Single_Page_Checkout', 'display_reg_step']);
123
+		add_action('wp_ajax_nopriv_display_spco_reg_step', ['EED_Single_Page_Checkout', 'display_reg_step']);
124
+		add_action('wp_ajax_update_reg_step', ['EED_Single_Page_Checkout', 'update_reg_step']);
125
+		add_action('wp_ajax_nopriv_update_reg_step', ['EED_Single_Page_Checkout', 'update_reg_step']);
126
+	}
127
+
128
+
129
+	/**
130
+	 *    process ajax request
131
+	 *
132
+	 * @param string $ajax_action
133
+	 * @throws EE_Error
134
+	 * @throws ReflectionException
135
+	 */
136
+	public static function process_ajax_request(string $ajax_action)
137
+	{
138
+		$request = EED_Single_Page_Checkout::getRequest();
139
+		$request->setRequestParam('action', $ajax_action);
140
+		EED_Single_Page_Checkout::instance()->_initialize();
141
+	}
142
+
143
+
144
+	/**
145
+	 * ajax display registration step
146
+	 *
147
+	 * @throws EE_Error
148
+	 * @throws ReflectionException
149
+	 */
150
+	public static function display_reg_step()
151
+	{
152
+		EED_Single_Page_Checkout::process_ajax_request('display_spco_reg_step');
153
+	}
154
+
155
+
156
+	/**
157
+	 * ajax process registration step
158
+	 *
159
+	 * @throws EE_Error
160
+	 * @throws ReflectionException
161
+	 */
162
+	public static function process_reg_step()
163
+	{
164
+		EED_Single_Page_Checkout::process_ajax_request('process_reg_step');
165
+	}
166
+
167
+
168
+	/**
169
+	 * ajax process registration step
170
+	 *
171
+	 * @throws EE_Error
172
+	 * @throws ReflectionException
173
+	 */
174
+	public static function update_reg_step()
175
+	{
176
+		EED_Single_Page_Checkout::process_ajax_request('update_reg_step');
177
+	}
178
+
179
+
180
+	/**
181
+	 * update_checkout
182
+	 *
183
+	 * @return void
184
+	 * @throws ReflectionException
185
+	 * @throws EE_Error
186
+	 */
187
+	public static function update_checkout()
188
+	{
189
+		EED_Single_Page_Checkout::process_ajax_request('update_checkout');
190
+	}
191
+
192
+
193
+	/**
194
+	 *    set_definitions
195
+	 *
196
+	 * @return    void
197
+	 * @throws EE_Error
198
+	 */
199
+	public static function set_definitions()
200
+	{
201
+		if (defined('SPCO_BASE_PATH')) {
202
+			return;
203
+		}
204
+		define(
205
+			'SPCO_BASE_PATH',
206
+			rtrim(str_replace(['\\', '/'], '/', plugin_dir_path(__FILE__)), '/') . '/'
207
+		);
208
+		define('SPCO_CSS_URL', plugin_dir_url(__FILE__) . 'css/');
209
+		define('SPCO_IMG_URL', plugin_dir_url(__FILE__) . 'img/');
210
+		define('SPCO_JS_URL', plugin_dir_url(__FILE__) . 'js/');
211
+		define('SPCO_INC_PATH', SPCO_BASE_PATH . 'inc/');
212
+		define('SPCO_REG_STEPS_PATH', SPCO_BASE_PATH . 'reg_steps/');
213
+		define('SPCO_TEMPLATES_PATH', SPCO_BASE_PATH . 'templates/');
214
+		EEH_Autoloader::register_autoloaders_for_each_file_in_folder(SPCO_BASE_PATH, true);
215
+		EE_Registry::$i18n_js_strings['registration_expiration_notice'] =
216
+			EED_Single_Page_Checkout::getRegistrationExpirationNotice();
217
+	}
218
+
219
+
220
+	/**
221
+	 * load_reg_steps
222
+	 * loads and instantiates each reg step based on the EE_Registry::instance()->CFG->registration->reg_steps array
223
+	 *
224
+	 * @throws EE_Error
225
+	 */
226
+	public static function load_reg_steps()
227
+	{
228
+		static $reg_steps_loaded = false;
229
+		if ($reg_steps_loaded) {
230
+			return;
231
+		}
232
+		// filter list of reg_steps
233
+		$reg_steps_to_load = (array) apply_filters(
234
+			'AHEE__SPCO__load_reg_steps__reg_steps_to_load',
235
+			EED_Single_Page_Checkout::get_reg_steps()
236
+		);
237
+		// sort by key (order)
238
+		ksort($reg_steps_to_load);
239
+		// loop through folders
240
+		foreach ($reg_steps_to_load as $order => $reg_step) {
241
+			// we need a
242
+			if (isset($reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'])) {
243
+				// copy over to the reg_steps_array
244
+				EED_Single_Page_Checkout::$_reg_steps_array[ $order ] = $reg_step;
245
+				// register custom key route for each reg step
246
+				// ie: step=>"slug" - this is the entire reason we load the reg steps array now
247
+				EED_Module::registerRoute(
248
+					$reg_step['slug'],
249
+					'EED_Single_Page_Checkout',
250
+					'run',
251
+					'step'
252
+				);
253
+				// add AJAX or other hooks
254
+				if (isset($reg_step['has_hooks']) && $reg_step['has_hooks']) {
255
+					// setup autoloaders if necessary
256
+					if (! class_exists($reg_step['class_name'])) {
257
+						EEH_Autoloader::register_autoloaders_for_each_file_in_folder(
258
+							$reg_step['file_path'],
259
+							true
260
+						);
261
+					}
262
+					if (is_callable($reg_step['class_name'], 'set_hooks')) {
263
+						call_user_func([$reg_step['class_name'], 'set_hooks']);
264
+					}
265
+				}
266
+			}
267
+		}
268
+		$reg_steps_loaded = true;
269
+	}
270
+
271
+
272
+	/**
273
+	 *    get_reg_steps
274
+	 *
275
+	 * @return    array
276
+	 */
277
+	public static function get_reg_steps(): array
278
+	{
279
+		$reg_steps = EE_Registry::instance()->CFG->registration->reg_steps;
280
+		if (empty($reg_steps)) {
281
+			$reg_steps = [
282
+				10  => [
283
+					'file_path'  => SPCO_REG_STEPS_PATH . 'attendee_information',
284
+					'class_name' => 'EE_SPCO_Reg_Step_Attendee_Information',
285
+					'slug'       => 'attendee_information',
286
+					'has_hooks'  => false,
287
+				],
288
+				30  => [
289
+					'file_path'  => SPCO_REG_STEPS_PATH . 'payment_options',
290
+					'class_name' => 'EE_SPCO_Reg_Step_Payment_Options',
291
+					'slug'       => 'payment_options',
292
+					'has_hooks'  => true,
293
+				],
294
+				999 => [
295
+					'file_path'  => SPCO_REG_STEPS_PATH . 'finalize_registration',
296
+					'class_name' => 'EE_SPCO_Reg_Step_Finalize_Registration',
297
+					'slug'       => 'finalize_registration',
298
+					'has_hooks'  => false,
299
+				],
300
+			];
301
+		}
302
+		return $reg_steps;
303
+	}
304
+
305
+
306
+	/**
307
+	 * @return array|string
308
+	 * @throws EE_Error
309
+	 * @throws ReflectionException
310
+	 */
311
+	public static function registration_checkout_for_admin()
312
+	{
313
+		$request = EED_Single_Page_Checkout::getRequest();
314
+		$request->setRequestParam('step', 'attendee_information');
315
+		$request->setRequestParam('action', 'display_spco_reg_step');
316
+		$request->setRequestParam('process_form_submission', false);
317
+		EED_Single_Page_Checkout::instance()->_initialize();
318
+		EED_Single_Page_Checkout::instance()->_display_spco_reg_form();
319
+		return EED_Single_Page_Checkout::getResponse()->getOutput();
320
+	}
321
+
322
+
323
+	/**
324
+	 * @return EE_Transaction|null
325
+	 * @throws EE_Error
326
+	 * @throws ReflectionException
327
+	 */
328
+	public static function process_registration_from_admin(): ?EE_Transaction
329
+	{
330
+		$request = EED_Single_Page_Checkout::getRequest();
331
+		$request->setRequestParam('step', 'attendee_information');
332
+		$request->setRequestParam('action', 'process_reg_step');
333
+		$request->setRequestParam('process_form_submission', true);
334
+		EED_Single_Page_Checkout::instance()->_initialize();
335
+		if (EED_Single_Page_Checkout::instance()->checkout->current_step->completed()) {
336
+			$final_reg_step = end(EED_Single_Page_Checkout::instance()->checkout->reg_steps);
337
+			if ($final_reg_step instanceof EE_SPCO_Reg_Step_Finalize_Registration) {
338
+				EED_Single_Page_Checkout::instance()->checkout->set_reg_step_initiated($final_reg_step);
339
+				if ($final_reg_step->process_reg_step()) {
340
+					$final_reg_step->set_completed();
341
+					EED_Single_Page_Checkout::instance()->checkout->update_txn_reg_steps_array();
342
+					return EED_Single_Page_Checkout::instance()->checkout->transaction;
343
+				}
344
+			}
345
+		}
346
+		return null;
347
+	}
348
+
349
+
350
+	/**
351
+	 *    run
352
+	 *
353
+	 * @param WP_Query|null $WP_Query
354
+	 * @return    void
355
+	 */
356
+	public function run($WP_Query)
357
+	{
358
+		if (
359
+			$WP_Query instanceof WP_Query
360
+			&& $WP_Query->is_main_query()
361
+			&& apply_filters('FHEE__EED_Single_Page_Checkout__run', true)
362
+			&& $this->_is_reg_checkout()
363
+		) {
364
+			$this->_initialize();
365
+		}
366
+	}
367
+
368
+
369
+	/**
370
+	 * determines whether current url matches reg page url
371
+	 *
372
+	 * @return bool
373
+	 */
374
+	protected function _is_reg_checkout(): bool
375
+	{
376
+		// get current permalink for reg page without any extra query args
377
+		$reg_page_url = get_permalink(EE_Config::instance()->core->reg_page_id);
378
+		// get request URI for current request, but without the scheme or host
379
+		$current_request_uri = EEH_URL::filter_input_server_url();
380
+		$current_request_uri = html_entity_decode($current_request_uri);
381
+		// get array of query args from the current request URI
382
+		$query_args = EEH_URL::get_query_string($current_request_uri);
383
+		// grab page id if it is set
384
+		$page_id = isset($query_args['page_id']) ? absint($query_args['page_id']) : 0;
385
+		// and remove the page id from the query args (we will re-add it later)
386
+		unset($query_args['page_id']);
387
+		// now strip all query args from current request URI
388
+		$current_request_uri = remove_query_arg(array_keys($query_args), $current_request_uri);
389
+		// and re-add the page id if it was set
390
+		if ($page_id) {
391
+			$current_request_uri = add_query_arg('page_id', $page_id, $current_request_uri);
392
+		}
393
+		// remove slashes and ?
394
+		$current_request_uri = trim($current_request_uri, '?/');
395
+		// is current request URI part of the known full reg page URL ?
396
+		return ! empty($current_request_uri) && strpos($reg_page_url, $current_request_uri) !== false;
397
+	}
398
+
399
+
400
+	/**
401
+	 * @param WP_Query $wp_query
402
+	 * @return    void
403
+	 * @throws EE_Error
404
+	 * @throws ReflectionException
405
+	 */
406
+	public static function init(WP_Query $wp_query)
407
+	{
408
+		EED_Single_Page_Checkout::instance()->run($wp_query);
409
+	}
410
+
411
+
412
+	/**
413
+	 * @return void
414
+	 */
415
+	private function _initialize()
416
+	{
417
+		// ensure SPCO doesn't run twice
418
+		if (EED_Single_Page_Checkout::$_initialized) {
419
+			return;
420
+		}
421
+		try {
422
+			$this->request = EED_Single_Page_Checkout::getRequest();
423
+			EED_Single_Page_Checkout::load_reg_steps();
424
+			$this->_verify_session();
425
+			// set up the EE_Checkout object
426
+			$this->checkout = $this->_initialize_checkout();
427
+			// filter checkout
428
+			$this->checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize__checkout', $this->checkout);
429
+			// get the $_GET
430
+			$this->_get_request_vars();
431
+			if ($this->_block_bots()) {
432
+				return;
433
+			}
434
+			// filter continue_reg
435
+			$this->checkout->continue_reg = apply_filters(
436
+				'FHEE__EED_Single_Page_Checkout__init___continue_reg',
437
+				true,
438
+				$this->checkout
439
+			);
440
+			// load the reg steps array
441
+			if (! $this->_load_and_instantiate_reg_steps()) {
442
+				EED_Single_Page_Checkout::$_initialized = true;
443
+				return;
444
+			}
445
+			// set the current step
446
+			$this->checkout->set_current_step($this->checkout->step);
447
+			// and the next step
448
+			$this->checkout->set_next_step();
449
+			// verify that everything has been set up correctly
450
+			if (! ($this->_verify_transaction_and_get_registrations() && $this->_final_verifications())) {
451
+				EED_Single_Page_Checkout::$_initialized = true;
452
+				return;
453
+			}
454
+			do_action('AHEE__Single_Page_Checkout___initialize__after_final_verifications', $this->checkout);
455
+			// lock the transaction
456
+			$this->checkout->transaction->lock();
457
+			// make sure all of our cached objects are added to their respective model entity mappers
458
+			$this->checkout->refresh_all_entities();
459
+			// set amount owing
460
+			$this->checkout->amount_owing = $this->checkout->transaction->remaining();
461
+			// initialize each reg step, which gives them the chance to potentially alter the process
462
+			$this->_initialize_reg_steps();
463
+			// DEBUG LOG
464
+			// $this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ );
465
+			// get reg form
466
+			if (! $this->_check_form_submission()) {
467
+				EED_Single_Page_Checkout::$_initialized = true;
468
+				return;
469
+			}
470
+			// checkout the action!!!
471
+			$this->_process_form_action();
472
+			// add some style and make it dance
473
+			$this->add_styles_and_scripts($this);
474
+			// kk... SPCO has successfully run
475
+			EED_Single_Page_Checkout::$_initialized = true;
476
+			// set no cache headers and constants
477
+			EE_System::do_not_cache();
478
+			// add anchor
479
+			add_action('loop_start', [$this, 'set_checkout_anchor'], 1);
480
+			// remove transaction lock
481
+			add_action('shutdown', [$this, 'unlock_transaction'], 1);
482
+		} catch (Exception $e) {
483
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
484
+		}
485
+	}
486
+
487
+
488
+	/**
489
+	 * checks that the session is valid and not expired
490
+	 *
491
+	 * @throws EE_Error
492
+	 * @throws ReflectionException
493
+	 */
494
+	private function _verify_session()
495
+	{
496
+		if (! EE_Registry::instance()->SSN instanceof EE_Session) {
497
+			throw new EE_Error(esc_html__('The EE_Session class could not be loaded.', 'event_espresso'));
498
+		}
499
+		$clear_session_requested = $this->request->getRequestParam('clear_session', false, 'bool');
500
+		// is session still valid ?
501
+		if (
502
+			$clear_session_requested
503
+			|| (
504
+				EE_Registry::instance()->SSN->expired()
505
+				&& $this->request->getRequestParam('e_reg_url_link') === ''
506
+			)
507
+		) {
508
+			$this->checkout = new EE_Checkout();
509
+			EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
510
+			// EE_Registry::instance()->SSN->reset_cart();
511
+			// EE_Registry::instance()->SSN->reset_checkout();
512
+			// EE_Registry::instance()->SSN->reset_transaction();
513
+			if (! $clear_session_requested) {
514
+				EE_Error::add_attention(
515
+					EE_Registry::$i18n_js_strings['registration_expiration_notice'],
516
+					__FILE__,
517
+					__FUNCTION__,
518
+					__LINE__
519
+				);
520
+			}
521
+			// EE_Registry::instance()->SSN->reset_expired();
522
+		}
523
+	}
524
+
525
+
526
+	/**
527
+	 * loads and instantiates EE_Checkout
528
+	 *
529
+	 * @return EE_Checkout
530
+	 * @throws EE_Error
531
+	 * @throws ReflectionException
532
+	 */
533
+	private function _initialize_checkout(): EE_Checkout
534
+	{
535
+		// look in session for existing checkout
536
+		/** @type EE_Checkout $checkout */
537
+		$checkout = EE_Registry::instance()->SSN->checkout();
538
+		// verify
539
+		if (! $checkout instanceof EE_Checkout) {
540
+			// instantiate EE_Checkout object for handling the properties of the current checkout process
541
+			$checkout = EE_Registry::instance()->load_file(
542
+				SPCO_INC_PATH,
543
+				'EE_Checkout',
544
+				'class',
545
+				[],
546
+				false
547
+			);
548
+		} else {
549
+			if ($checkout->current_step->is_final_step() && $checkout->exit_spco() === true) {
550
+				$this->unlock_transaction();
551
+				wp_safe_redirect($checkout->redirect_url);
552
+				exit();
553
+			}
554
+		}
555
+		$checkout = apply_filters('FHEE__EED_Single_Page_Checkout___initialize_checkout__checkout', $checkout);
556
+		// verify again
557
+		if (! $checkout instanceof EE_Checkout) {
558
+			throw new EE_Error(esc_html__('The EE_Checkout class could not be loaded.', 'event_espresso'));
559
+		}
560
+		// reset anything that needs a clean slate for each request
561
+		$checkout->reset_for_current_request();
562
+		return $checkout;
563
+	}
564
+
565
+
566
+	/**
567
+	 * @return void
568
+	 */
569
+	private function _get_request_vars()
570
+	{
571
+		// make sure this request is marked as belonging to EE
572
+		/** @var CurrentPage $current_page */
573
+		$current_page = LoaderFactory::getLoader()->getShared(CurrentPage::class);
574
+		$current_page->setEspressoPage(true);
575
+		// which step is being requested ?
576
+		$this->checkout->step = $this->request->getRequestParam('step', $this->_get_first_step());
577
+		// which step is being edited ?
578
+		$this->checkout->edit_step = $this->request->getRequestParam('edit_step');
579
+		// and what we're doing on the current step
580
+		$this->checkout->action = $this->request->getRequestParam('action', 'display_spco_reg_step');
581
+		// timestamp
582
+		$this->checkout->uts = $this->request->getRequestParam('uts', 0, 'int');
583
+		// returning to edit ?
584
+		$this->checkout->reg_url_link = $this->request->getRequestParam('e_reg_url_link');
585
+		// add reg url link to registration query params
586
+		if ($this->checkout->reg_url_link && strpos($this->checkout->reg_url_link, '1-') !== 0) {
587
+			$this->checkout->reg_cache_where_params[0]['REG_url_link'] = $this->checkout->reg_url_link;
588
+		}
589
+		// or some other kind of revisit ?
590
+		$this->checkout->revisit = $this->request->getRequestParam('revisit', false, 'bool');
591
+		// and whether to generate a reg form for this request
592
+		$this->checkout->generate_reg_form = $this->request->getRequestParam('generate_reg_form', true, 'bool');
593
+		// and whether to process a reg form submission for this request
594
+		$this->checkout->process_form_submission = $this->request->getRequestParam(
595
+			'process_form_submission',
596
+			$this->checkout->action === 'process_reg_step',
597
+			'bool'
598
+		);
599
+		$this->checkout->process_form_submission = filter_var(
600
+			$this->checkout->action !== 'display_spco_reg_step'
601
+				? $this->checkout->process_form_submission
602
+				: false,
603
+			FILTER_VALIDATE_BOOLEAN
604
+		);
605
+		$this->_display_request_vars();
606
+	}
607
+
608
+
609
+	/**
610
+	 * @return void
611
+	 */
612
+	protected function _display_request_vars()
613
+	{
614
+		if (! ($this->debug && defined('WP_DEBUG') && WP_DEBUG)) {
615
+			return;
616
+		}
617
+		EEH_Debug_Tools::printr($this->request->requestParams(), 'requestParams', __FILE__, __LINE__);
618
+		EEH_Debug_Tools::printr($this->checkout->step, '$this->checkout->step', __FILE__, __LINE__);
619
+		EEH_Debug_Tools::printr($this->checkout->edit_step, '$this->checkout->edit_step', __FILE__, __LINE__);
620
+		EEH_Debug_Tools::printr($this->checkout->action, '$this->checkout->action', __FILE__, __LINE__);
621
+		EEH_Debug_Tools::printr($this->checkout->reg_url_link, '$this->checkout->reg_url_link', __FILE__, __LINE__);
622
+		EEH_Debug_Tools::printr($this->checkout->revisit, '$this->checkout->revisit', __FILE__, __LINE__);
623
+		EEH_Debug_Tools::printr(
624
+			$this->checkout->generate_reg_form,
625
+			'$this->checkout->generate_reg_form',
626
+			__FILE__,
627
+			__LINE__
628
+		);
629
+		EEH_Debug_Tools::printr(
630
+			$this->checkout->process_form_submission,
631
+			'$this->checkout->process_form_submission',
632
+			__FILE__,
633
+			__LINE__
634
+		);
635
+	}
636
+
637
+
638
+	/**
639
+	 * _block_bots
640
+	 * checks that the incoming request has either of the following set:
641
+	 *  a UTS (unix timestamp) which indicates that the request was redirected from the Ticket Selector
642
+	 *  a REG URL Link, which indicates that the request is a return visit to SPCO for a valid TXN
643
+	 * so if you're not coming from the Ticket Selector nor returning for a valid IP...
644
+	 * then where you coming from man?
645
+	 *
646
+	 * @return boolean
647
+	 */
648
+	private function _block_bots(): bool
649
+	{
650
+		return EED_Invalid_Checkout_Access::getInvalidCheckoutAccess()->checkoutAccessIsInvalid($this->checkout);
651
+	}
652
+
653
+
654
+	/**
655
+	 *  gets slug for first step in $_reg_steps_array
656
+	 *
657
+	 * @return string
658
+	 */
659
+	private function _get_first_step(): string
660
+	{
661
+		$first_step = reset(EED_Single_Page_Checkout::$_reg_steps_array);
662
+		return $first_step['slug'] ?? 'attendee_information';
663
+	}
664
+
665
+
666
+	/**
667
+	 * instantiates each reg step based on the loaded reg_steps array
668
+	 *
669
+	 * @return bool
670
+	 * @throws EE_Error
671
+	 * @throws InvalidArgumentException
672
+	 * @throws InvalidDataTypeException
673
+	 * @throws InvalidInterfaceException
674
+	 * @throws ReflectionException
675
+	 */
676
+	private function _load_and_instantiate_reg_steps(): bool
677
+	{
678
+		do_action('AHEE__Single_Page_Checkout___load_and_instantiate_reg_steps__start', $this->checkout);
679
+		// have reg_steps already been instantiated ?
680
+		if (
681
+			empty($this->checkout->reg_steps)
682
+			|| apply_filters('FHEE__Single_Page_Checkout__load_reg_steps__reload_reg_steps', false, $this->checkout)
683
+		) {
684
+			// if not, then loop through raw reg steps array
685
+			foreach (EED_Single_Page_Checkout::$_reg_steps_array as $order => $reg_step) {
686
+				if (! $this->_load_and_instantiate_reg_step($reg_step, $order)) {
687
+					return false;
688
+				}
689
+			}
690
+			if (isset($this->checkout->reg_steps['registration_confirmation'])) {
691
+				// skip the registration_confirmation page ?
692
+				// just remove it from the reg steps array
693
+				$this->checkout->remove_reg_step('registration_confirmation', false);
694
+			}
695
+			// filter the array for good luck
696
+			$this->checkout->reg_steps = apply_filters(
697
+				'FHEE__Single_Page_Checkout__load_reg_steps__reg_steps',
698
+				$this->checkout->reg_steps
699
+			);
700
+			// finally re-sort based on the reg step class order properties
701
+			$this->checkout->sort_reg_steps();
702
+		} else {
703
+			foreach ($this->checkout->reg_steps as $reg_step) {
704
+				// set all current step stati to FALSE
705
+				$reg_step->set_is_current_step(false);
706
+			}
707
+		}
708
+		if (empty($this->checkout->reg_steps)) {
709
+			EE_Error::add_error(
710
+				esc_html__('No Reg Steps were loaded..', 'event_espresso'),
711
+				__FILE__,
712
+				__FUNCTION__,
713
+				__LINE__
714
+			);
715
+			return false;
716
+		}
717
+		// make reg step details available to JS
718
+		$this->checkout->set_reg_step_JSON_info();
719
+		return true;
720
+	}
721
+
722
+
723
+	/**
724
+	 * @param array $reg_step
725
+	 * @param int   $order
726
+	 * @return bool
727
+	 * @throws EE_Error
728
+	 * @throws ReflectionException
729
+	 */
730
+	private function _load_and_instantiate_reg_step(array $reg_step = [], int $order = 0): bool
731
+	{
732
+		// we need a file_path, class_name, and slug to add a reg step
733
+		if (isset($reg_step['file_path'], $reg_step['class_name'], $reg_step['slug'])) {
734
+			// if editing a specific step, but this is NOT that step... (and it's not the 'finalize_registration' step)
735
+			if (
736
+				$this->checkout->reg_url_link
737
+				&& $this->checkout->step !== $reg_step['slug']
738
+				&& $reg_step['slug'] !== 'finalize_registration'
739
+				// normally at this point we would NOT load the reg step, but this filter can change that
740
+				&& apply_filters(
741
+					'FHEE__Single_Page_Checkout___load_and_instantiate_reg_step__bypass_reg_step',
742
+					true,
743
+					$reg_step,
744
+					$this->checkout
745
+				)
746
+			) {
747
+				return true;
748
+			}
749
+
750
+			// instantiate step class using file path and class name
751
+			$reg_step_obj = EE_Registry::instance()->load_file(
752
+				$reg_step['file_path'],
753
+				$reg_step['class_name'],
754
+				'class',
755
+				[$this->checkout],
756
+				false
757
+			);
758
+			// did we get the goods ?
759
+			if ($reg_step_obj instanceof EE_SPCO_Reg_Step) {
760
+				// set reg step order based on config
761
+				$reg_step_obj->set_order($order);
762
+				// add instantiated reg step object to the master reg steps array
763
+				$this->checkout->add_reg_step($reg_step_obj);
764
+			} else {
765
+				EE_Error::add_error(
766
+					esc_html__('The current step could not be set.', 'event_espresso'),
767
+					__FILE__,
768
+					__FUNCTION__,
769
+					__LINE__
770
+				);
771
+				return false;
772
+			}
773
+		} else {
774
+			if (WP_DEBUG) {
775
+				EE_Error::add_error(
776
+					sprintf(
777
+						esc_html__(
778
+							'A registration step could not be loaded. One or more of the following data points is invalid:%4$s%5$sFile Path: %1$s%6$s%5$sClass Name: %2$s%6$s%5$sSlug: %3$s%6$s%7$s',
779
+							'event_espresso'
780
+						),
781
+						$reg_step['file_path'] ?? '',
782
+						$reg_step['class_name'] ?? '',
783
+						$reg_step['slug'] ?? '',
784
+						'<ul>',
785
+						'<li>',
786
+						'</li>',
787
+						'</ul>'
788
+					),
789
+					__FILE__,
790
+					__FUNCTION__,
791
+					__LINE__
792
+				);
793
+			}
794
+			return false;
795
+		}
796
+		return true;
797
+	}
798
+
799
+
800
+	/**
801
+	 * @return bool
802
+	 * @throws EE_Error
803
+	 * @throws ReflectionException
804
+	 */
805
+	private function _verify_transaction_and_get_registrations(): bool
806
+	{
807
+		// was there already a valid transaction in the checkout from the session ?
808
+		if (! $this->checkout->transaction instanceof EE_Transaction) {
809
+			// get transaction from db or session
810
+			$this->checkout->transaction = $this->checkout->reg_url_link && ! is_admin()
811
+				? $this->_get_transaction_and_cart_for_previous_visit()
812
+				: $this->_get_cart_for_current_session_and_setup_new_transaction();
813
+			if (! $this->checkout->transaction instanceof EE_Transaction) {
814
+				EE_Error::add_error(
815
+					esc_html__(
816
+						'Your Registration and Transaction information could not be retrieved from the db.',
817
+						'event_espresso'
818
+					),
819
+					__FILE__,
820
+					__FUNCTION__,
821
+					__LINE__
822
+				);
823
+				$this->checkout->transaction = EE_Transaction::new_instance();
824
+				// add some style and make it dance
825
+				$this->add_styles_and_scripts($this);
826
+				EED_Single_Page_Checkout::$_initialized = true;
827
+				return false;
828
+			}
829
+			// and the registrations for the transaction
830
+			$this->_get_registrations($this->checkout->transaction);
831
+		}
832
+		return true;
833
+	}
834
+
835
+
836
+	/**
837
+	 * @return EE_Transaction|null
838
+	 * @throws EE_Error
839
+	 * @throws ReflectionException
840
+	 */
841
+	private function _get_transaction_and_cart_for_previous_visit(): ?EE_Transaction
842
+	{
843
+		/** @var $TXN_model EEM_Transaction */
844
+		$TXN_model = EE_Registry::instance()->load_model('Transaction');
845
+		// because the reg_url_link is present in the request,
846
+		// this is a return visit to SPCO, so we'll get the transaction data from the db
847
+		$transaction = $TXN_model->get_transaction_from_reg_url_link($this->checkout->reg_url_link);
848
+		// verify transaction
849
+		if ($transaction instanceof EE_Transaction) {
850
+			// and get the cart that was used for that transaction
851
+			$this->checkout->cart = $this->_get_cart_for_transaction($transaction);
852
+			return $transaction;
853
+		}
854
+		EE_Error::add_error(
855
+			esc_html__(
856
+				'Your Registration and Transaction information could not be retrieved from the db.',
857
+				'event_espresso'
858
+			),
859
+			__FILE__,
860
+			__FUNCTION__,
861
+			__LINE__
862
+		);
863
+		return null;
864
+	}
865
+
866
+
867
+	/**
868
+	 * @param EE_Transaction|null $transaction
869
+	 * @return EE_Cart
870
+	 */
871
+	private function _get_cart_for_transaction(?EE_Transaction $transaction): EE_Cart
872
+	{
873
+		return $this->checkout->get_cart_for_transaction($transaction);
874
+	}
875
+
876
+
877
+	/**
878
+	 * @param EE_Transaction|null $transaction
879
+	 * @return EE_Cart
880
+	 */
881
+	public function get_cart_for_transaction(?EE_Transaction $transaction): EE_Cart
882
+	{
883
+		return $this->checkout->get_cart_for_transaction($transaction);
884
+	}
885
+
886
+
887
+	/**
888
+	 * generates a new EE_Transaction object and adds it to the $_transaction property.
889
+	 *
890
+	 * @return EE_Transaction|null
891
+	 * @throws EE_Error
892
+	 * @throws ReflectionException
893
+	 */
894
+	private function _get_cart_for_current_session_and_setup_new_transaction(): ?EE_Transaction
895
+	{
896
+		//  if there's no transaction, then this is the FIRST visit to SPCO
897
+		// so load up the cart ( passing nothing for the TXN because it doesn't exist yet )
898
+		$this->checkout->cart = $this->_get_cart_for_transaction(null);
899
+		// and then create a new transaction
900
+		$transaction = $this->_initialize_transaction();
901
+		// verify transaction
902
+		if ($transaction instanceof EE_Transaction) {
903
+			// and save TXN data to the cart
904
+			$this->checkout->cart->get_grand_total()->save_this_and_descendants_to_txn($transaction->ID());
905
+		} else {
906
+			EE_Error::add_error(
907
+				esc_html__('A Valid Transaction could not be initialized.', 'event_espresso'),
908
+				__FILE__,
909
+				__FUNCTION__,
910
+				__LINE__
911
+			);
912
+		}
913
+		return $transaction;
914
+	}
915
+
916
+
917
+	/**
918
+	 * generates a new EE_Transaction object and adds it to the $_transaction property.
919
+	 *
920
+	 * @return EE_Transaction|null
921
+	 */
922
+	private function _initialize_transaction(): ?EE_Transaction
923
+	{
924
+		try {
925
+			// ensure cart totals have been calculated
926
+			$this->checkout->cart->get_grand_total()->recalculate_total_including_taxes();
927
+			// grab the cart grand total
928
+			$cart_total = $this->checkout->cart->get_cart_grand_total();
929
+			// create new TXN
930
+			$transaction = EE_Transaction::new_instance(
931
+				[
932
+					'TXN_reg_steps' => $this->checkout->initialize_txn_reg_steps_array(),
933
+					'TXN_total'     => max($cart_total, 0),
934
+					'TXN_paid'      => 0,
935
+					'STS_ID'        => EEM_Transaction::failed_status_code,
936
+				]
937
+			);
938
+			// save it so that we have an ID for other objects to use
939
+			$transaction->save();
940
+			// set cron job for following up on TXNs after their session has expired
941
+			EE_Cron_Tasks::schedule_expired_transaction_check(
942
+				EE_Registry::instance()->SSN->expiration() + 1,
943
+				$transaction->ID()
944
+			);
945
+			return $transaction;
946
+		} catch (Exception $e) {
947
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
948
+		}
949
+		return null;
950
+	}
951
+
952
+
953
+	/**
954
+	 * _get_registrations
955
+	 *
956
+	 * @param EE_Transaction $transaction
957
+	 * @return void
958
+	 * @throws EE_Error
959
+	 * @throws ReflectionException
960
+	 */
961
+	private function _get_registrations(EE_Transaction $transaction)
962
+	{
963
+		// first step: grab the registrants  { : o
964
+		$registrations                      = $transaction->registrations($this->checkout->reg_cache_where_params);
965
+		$this->checkout->total_ticket_count = count($registrations);
966
+		// verify registrations have been set
967
+		if (empty($registrations)) {
968
+			// if no cached registrations, then check the db
969
+			$registrations = $transaction->registrations($this->checkout->reg_cache_where_params);
970
+			// still nothing ? well as long as this isn't a revisit
971
+			if (empty($registrations) && ! $this->checkout->revisit) {
972
+				// generate new registrations from scratch
973
+				$registrations = $this->_initialize_registrations($transaction);
974
+			}
975
+		}
976
+		// sort by their original registration order
977
+		usort($registrations, ['EED_Single_Page_Checkout', 'sort_registrations_by_REG_count']);
978
+		// then loop thru the array
979
+		foreach ($registrations as $registration) {
980
+			// verify each registration
981
+			if ($registration instanceof EE_Registration) {
982
+				// we display all attendee info for the primary registrant
983
+				if (
984
+					$this->checkout->reg_url_link === $registration->reg_url_link()
985
+					&& $registration->is_primary_registrant()
986
+				) {
987
+					$this->checkout->primary_revisit = true;
988
+					break;
989
+				}
990
+				if ($this->checkout->revisit && $this->checkout->reg_url_link !== $registration->reg_url_link()) {
991
+					// but hide info if it doesn't belong to you
992
+					$transaction->clear_cache('Registration', $registration->ID());
993
+					$this->checkout->total_ticket_count--;
994
+				}
995
+				$this->checkout->set_reg_status_updated($registration->ID(), false);
996
+			}
997
+		}
998
+	}
999
+
1000
+
1001
+	/**
1002
+	 * adds related EE_Registration objects for each ticket in the cart to the current EE_Transaction object
1003
+	 *
1004
+	 * @param EE_Transaction $transaction
1005
+	 * @return array
1006
+	 * @throws EE_Error
1007
+	 * @throws ReflectionException
1008
+	 */
1009
+	private function _initialize_registrations(EE_Transaction $transaction): array
1010
+	{
1011
+		$att_nmbr      = 0;
1012
+		$registrations = [];
1013
+		/** @type EE_Registration_Processor $registration_processor */
1014
+		$registration_processor             = EE_Registry::instance()->load_class('Registration_Processor');
1015
+		$this->checkout->total_ticket_count = $this->checkout->cart->all_ticket_quantity_count();
1016
+		// now let's add the cart items to the $transaction
1017
+		foreach ($this->checkout->cart->get_tickets() as $line_item) {
1018
+			// do the following for each ticket of this type they selected
1019
+			for ($x = 1; $x <= $line_item->quantity(); $x++) {
1020
+				$att_nmbr++;
1021
+				/** @var CreateRegistrationCommand $CreateRegistrationCommand */
1022
+				$CreateRegistrationCommand = EE_Registry::instance()->create(
1023
+					CreateRegistrationCommand::class,
1024
+					[
1025
+						$transaction,
1026
+						$line_item,
1027
+						$att_nmbr,
1028
+						$this->checkout->total_ticket_count,
1029
+					]
1030
+				);
1031
+				// override capabilities for frontend registrations
1032
+				if ($this->request->isFrontend()) {
1033
+					$CreateRegistrationCommand->setCapCheck(
1034
+						new PublicCapabilities('', 'create_new_registration')
1035
+					);
1036
+				}
1037
+				$registration = EE_Registry::instance()->BUS->execute($CreateRegistrationCommand);
1038
+				if (! $registration instanceof EE_Registration) {
1039
+					throw new InvalidEntityException($registration, 'EE_Registration');
1040
+				}
1041
+				$registrations[ $registration->ID() ] = $registration;
1042
+			}
1043
+		}
1044
+		$registration_processor->fix_reg_final_price_rounding_issue($transaction);
1045
+		return $registrations;
1046
+	}
1047
+
1048
+
1049
+	/**
1050
+	 * @param EE_Registration $reg_A
1051
+	 * @param EE_Registration $reg_B
1052
+	 * @return int
1053
+	 * @throws EE_Error
1054
+	 * @throws ReflectionException
1055
+	 */
1056
+	public static function sort_registrations_by_REG_count(EE_Registration $reg_A, EE_Registration $reg_B): int
1057
+	{
1058
+		// this shouldn't ever happen within the same TXN, but oh well
1059
+		if ($reg_A->count() === $reg_B->count()) {
1060
+			return 0;
1061
+		}
1062
+		return ($reg_A->count() > $reg_B->count()) ? 1 : -1;
1063
+	}
1064
+
1065
+
1066
+	/**
1067
+	 * just makes sure that everything is set up correctly before proceeding
1068
+	 *
1069
+	 * @return bool
1070
+	 * @throws EE_Error
1071
+	 * @throws ReflectionException
1072
+	 */
1073
+	private function _final_verifications(): bool
1074
+	{
1075
+		// filter checkout
1076
+		$this->checkout = apply_filters(
1077
+			'FHEE__EED_Single_Page_Checkout___final_verifications__checkout',
1078
+			$this->checkout
1079
+		);
1080
+		// verify that current step is still set correctly
1081
+		if (! $this->checkout->current_step instanceof EE_SPCO_Reg_Step) {
1082
+			EE_Error::add_error(
1083
+				esc_html__(
1084
+					'We\'re sorry but the registration process can not proceed because one or more registration steps were not setup correctly. Please refresh the page and try again or contact support.',
1085
+					'event_espresso'
1086
+				),
1087
+				__FILE__,
1088
+				__FUNCTION__,
1089
+				__LINE__
1090
+			);
1091
+			return false;
1092
+		}
1093
+		// if returning to SPCO, then verify that primary registrant is set
1094
+		if (! empty($this->checkout->reg_url_link)) {
1095
+			$valid_registrant = $this->checkout->transaction->primary_registration();
1096
+			if (! $valid_registrant instanceof EE_Registration) {
1097
+				EE_Error::add_error(
1098
+					esc_html__(
1099
+						'We\'re sorry but there appears to be an error with the "reg_url_link" or the primary registrant for this transaction. Please refresh the page and try again or contact support.',
1100
+						'event_espresso'
1101
+					),
1102
+					__FILE__,
1103
+					__FUNCTION__,
1104
+					__LINE__
1105
+				);
1106
+				return false;
1107
+			}
1108
+			$valid_registrant = null;
1109
+			foreach (
1110
+				$this->checkout->transaction->registrations(
1111
+					$this->checkout->reg_cache_where_params
1112
+				) as $registration
1113
+			) {
1114
+				if (
1115
+					$registration instanceof EE_Registration
1116
+					&& $registration->reg_url_link() === $this->checkout->reg_url_link
1117
+				) {
1118
+					$valid_registrant = $registration;
1119
+				}
1120
+			}
1121
+			if (! $valid_registrant instanceof EE_Registration) {
1122
+				// hmmm... maybe we have the wrong session because the user is opening multiple tabs ?
1123
+				if (EED_Single_Page_Checkout::$_checkout_verified) {
1124
+					// clear the session, mark the checkout as unverified, and try again
1125
+					EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
1126
+					EED_Single_Page_Checkout::$_initialized       = false;
1127
+					EED_Single_Page_Checkout::$_checkout_verified = false;
1128
+					$this->_initialize();
1129
+					EE_Error::reset_notices();
1130
+					return false;
1131
+				}
1132
+				EE_Error::add_error(
1133
+					esc_html__(
1134
+						'We\'re sorry but there appears to be an error with the "reg_url_link" or the transaction itself. Please refresh the page and try again or contact support.',
1135
+						'event_espresso'
1136
+					),
1137
+					__FILE__,
1138
+					__FUNCTION__,
1139
+					__LINE__
1140
+				);
1141
+				return false;
1142
+			}
1143
+		}
1144
+		// now that things have been kinda sufficiently verified,
1145
+		// let's add the checkout to the session so that it's available to other systems
1146
+		EE_Registry::instance()->SSN->set_checkout($this->checkout);
1147
+		return true;
1148
+	}
1149
+
1150
+
1151
+	/**
1152
+	 * first makes sure that EE_Transaction_Processor::set_reg_step_initiated() is called as required
1153
+	 * then loops thru all the active reg steps and calls the initialize_reg_step() method
1154
+	 *
1155
+	 * @param bool $reinitializing
1156
+	 * @throws EE_Error
1157
+	 */
1158
+	private function _initialize_reg_steps(bool $reinitializing = false)
1159
+	{
1160
+		$this->checkout->set_reg_step_initiated($this->checkout->current_step);
1161
+		// loop thru all steps to call their individual "initialize" methods and set i18n strings for JS
1162
+		foreach ($this->checkout->reg_steps as $reg_step) {
1163
+			if (! $reg_step->initialize_reg_step()) {
1164
+				// if not initialized then maybe this step is being removed...
1165
+				if (! $reinitializing && $reg_step->is_current_step()) {
1166
+					// if it was the current step, then we need to start over here
1167
+					$this->_initialize_reg_steps(true);
1168
+					return;
1169
+				}
1170
+				continue;
1171
+			}
1172
+			// add css and JS for current step
1173
+			$this->add_styles_and_scripts($reg_step);
1174
+			if ($reg_step->is_current_step()) {
1175
+				// the text that appears on the reg step form submit button
1176
+				$reg_step->set_submit_button_text();
1177
+			}
1178
+		}
1179
+		// dynamically creates hook point like: AHEE__Single_Page_Checkout___initialize_reg_step__attendee_information
1180
+		do_action(
1181
+			"AHEE__Single_Page_Checkout___initialize_reg_step__{$this->checkout->current_step->slug()}",
1182
+			$this->checkout->current_step
1183
+		);
1184
+	}
1185
+
1186
+
1187
+	/**
1188
+	 * @return boolean
1189
+	 * @throws EE_Error
1190
+	 * @throws ReflectionException
1191
+	 */
1192
+	private function _check_form_submission(): bool
1193
+	{
1194
+		// does this request require the reg form to be generated ?
1195
+		if ($this->checkout->generate_reg_form) {
1196
+			// ever heard that song by Blue Rodeo ?
1197
+			try {
1198
+				$this->checkout->current_step->reg_form = $this->checkout->current_step->generate_reg_form();
1199
+				// if not displaying a form, then check for form submission
1200
+				if (
1201
+					$this->checkout->process_form_submission
1202
+					&& $this->checkout->current_step->reg_form->was_submitted()
1203
+				) {
1204
+					// clear out any old data in case this step is being run again
1205
+					$this->checkout->current_step->set_valid_data([]);
1206
+					// capture submitted form data
1207
+					$request_data = $this->request->requestParams();
1208
+					$this->checkout->current_step->reg_form->receive_form_submission(
1209
+						(array) apply_filters(
1210
+							'FHEE__Single_Page_Checkout___check_form_submission__request_params',
1211
+							$request_data,
1212
+							$this->checkout
1213
+						)
1214
+					);
1215
+					// validate submitted form data
1216
+					if (! $this->checkout->continue_reg || ! $this->checkout->current_step->reg_form->is_valid()) {
1217
+						// thou shall not pass !!!
1218
+						$this->checkout->continue_reg = false;
1219
+						// any form validation errors?
1220
+						if ($this->checkout->current_step->reg_form->submission_error_message() !== '') {
1221
+							EE_Error::add_error(
1222
+								$this->checkout->current_step->reg_form->submission_error_message(),
1223
+								__FILE__,
1224
+								__FUNCTION__,
1225
+								__LINE__
1226
+							);
1227
+						}
1228
+						// well not really... what will happen is
1229
+						// we'll just get redirected back to redo the current step
1230
+						$this->go_to_next_step();
1231
+						return false;
1232
+					}
1233
+				}
1234
+			} catch (EE_Error $e) {
1235
+				$e->get_error();
1236
+			}
1237
+		}
1238
+		return true;
1239
+	}
1240
+
1241
+
1242
+	/**
1243
+	 * @return void
1244
+	 * @throws EE_Error
1245
+	 * @throws ReflectionException
1246
+	 */
1247
+	private function _process_form_action()
1248
+	{
1249
+		// what cha wanna do?
1250
+		switch ($this->checkout->action) {
1251
+			// AJAX next step reg form
1252
+			case 'display_spco_reg_step':
1253
+				$this->checkout->redirect = false;
1254
+				if ($this->request->isAjax()) {
1255
+					$this->checkout->json_response->set_reg_step_html(
1256
+						$this->checkout->current_step->display_reg_form()
1257
+					);
1258
+				}
1259
+				break;
1260
+			default:
1261
+				// meh... do one of those other steps first
1262
+				if (
1263
+					! empty($this->checkout->action)
1264
+					&& is_callable([$this->checkout->current_step, $this->checkout->action])
1265
+				) {
1266
+					// dynamically creates hook point like:
1267
+					//   AHEE__Single_Page_Checkout__before_attendee_information__process_reg_step
1268
+					do_action(
1269
+						"AHEE__Single_Page_Checkout__before_{$this->checkout->current_step->slug()}__{$this->checkout->action}",
1270
+						$this->checkout->current_step
1271
+					);
1272
+					$process_reg_step = apply_filters(
1273
+						"AHEE__Single_Page_Checkout__process_reg_step__{$this->checkout->current_step->slug()}__{$this->checkout->action}",
1274
+						true,
1275
+						$this->checkout->current_step,
1276
+						$this
1277
+					);
1278
+					// call action on current step
1279
+					if ($process_reg_step && call_user_func([$this->checkout->current_step, $this->checkout->action])) {
1280
+						// good registrant, you get to proceed
1281
+						if (
1282
+							$this->checkout->current_step->success_message() !== ''
1283
+							&& apply_filters(
1284
+								'FHEE__Single_Page_Checkout___process_form_action__display_success',
1285
+								false
1286
+							)
1287
+						) {
1288
+							EE_Error::add_success(
1289
+								$this->checkout->current_step->success_message()
1290
+								. '<br />' . $this->checkout->next_step->_instructions()
1291
+							);
1292
+						}
1293
+						// pack it up, pack it in...
1294
+						$this->_setup_redirect();
1295
+					}
1296
+					// dynamically creates hook point like:
1297
+					//  AHEE__Single_Page_Checkout__after_payment_options__process_reg_step
1298
+					do_action(
1299
+						"AHEE__Single_Page_Checkout__after_{$this->checkout->current_step->slug()}__{$this->checkout->action}",
1300
+						$this->checkout->current_step
1301
+					);
1302
+				} else {
1303
+					EE_Error::add_error(
1304
+						sprintf(
1305
+							esc_html__(
1306
+								'The requested form action "%s" does not exist for the current "%s" registration step.',
1307
+								'event_espresso'
1308
+							),
1309
+							$this->checkout->action,
1310
+							$this->checkout->current_step->name()
1311
+						),
1312
+						__FILE__,
1313
+						__FUNCTION__,
1314
+						__LINE__
1315
+					);
1316
+				}
1317
+			// end default
1318
+		}
1319
+		// store our progress so far
1320
+		$this->checkout->stash_transaction_and_checkout();
1321
+		// advance to the next step! If you pass GO, collect $200
1322
+		$this->go_to_next_step();
1323
+	}
1324
+
1325
+
1326
+	/**
1327
+	 * @param EED_Single_Page_Checkout|EE_SPCO_Reg_Step $target an object with the method `translate_js_strings` and
1328
+	 *                                                          `enqueue_styles_and_scripts`.
1329
+	 * @return void
1330
+	 */
1331
+	public function add_styles_and_scripts($target)
1332
+	{
1333
+		// i18n
1334
+		$target->translate_js_strings();
1335
+		if ($this->checkout->admin_request) {
1336
+			add_action('admin_enqueue_scripts', [$target, 'enqueue_styles_and_scripts']);
1337
+		} else {
1338
+			add_action('wp_enqueue_scripts', [$target, 'enqueue_styles_and_scripts']);
1339
+		}
1340
+	}
1341
+
1342
+
1343
+	/**
1344
+	 * @return void
1345
+	 */
1346
+	public function translate_js_strings()
1347
+	{
1348
+		EE_Registry::$i18n_js_strings['revisit']                        = $this->checkout->revisit;
1349
+		EE_Registry::$i18n_js_strings['e_reg_url_link']                 = $this->checkout->reg_url_link;
1350
+		EE_Registry::$i18n_js_strings['server_error']                   = esc_html__(
1351
+			'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again or contact support.',
1352
+			'event_espresso'
1353
+		);
1354
+		EE_Registry::$i18n_js_strings['invalid_json_response']          = esc_html__(
1355
+			'An invalid response was returned from the server while attempting to process your request. Please refresh the page and try again or contact support.',
1356
+			'event_espresso'
1357
+		);
1358
+		EE_Registry::$i18n_js_strings['validation_error']               = esc_html__(
1359
+			'There appears to be a problem with the form validation configuration! Please check the admin settings or contact support.',
1360
+			'event_espresso'
1361
+		);
1362
+		EE_Registry::$i18n_js_strings['invalid_payment_method']         = esc_html__(
1363
+			'There appears to be a problem with the payment method configuration! Please refresh the page and try again or contact support.',
1364
+			'event_espresso'
1365
+		);
1366
+		EE_Registry::$i18n_js_strings['reg_step_error']                 = esc_html__(
1367
+			'This registration step could not be completed. Please refresh the page and try again.',
1368
+			'event_espresso'
1369
+		);
1370
+		EE_Registry::$i18n_js_strings['invalid_coupon']                 = esc_html__(
1371
+			'We\'re sorry but that coupon code does not appear to be valid. If this is incorrect, please contact the site administrator.',
1372
+			'event_espresso'
1373
+		);
1374
+		EE_Registry::$i18n_js_strings['process_registration']           = sprintf(
1375
+			esc_html__(
1376
+				'Please wait while we process your registration.%sDo not refresh the page or navigate away while this is happening.%sThank you for your patience.',
1377
+				'event_espresso'
1378
+			),
1379
+			'<br/>',
1380
+			'<br/>'
1381
+		);
1382
+		EE_Registry::$i18n_js_strings['language']                       = get_bloginfo('language');
1383
+		EE_Registry::$i18n_js_strings['EESID']                          = EE_Registry::instance()->SSN->id();
1384
+		EE_Registry::$i18n_js_strings['currency']                       = EE_Registry::instance()->CFG->currency;
1385
+		EE_Registry::$i18n_js_strings['datepicker_yearRange']           = '-150:+20';
1386
+		EE_Registry::$i18n_js_strings['timer_years']                    = esc_html__('years', 'event_espresso');
1387
+		EE_Registry::$i18n_js_strings['timer_months']                   = esc_html__('months', 'event_espresso');
1388
+		EE_Registry::$i18n_js_strings['timer_weeks']                    = esc_html__('weeks', 'event_espresso');
1389
+		EE_Registry::$i18n_js_strings['timer_days']                     = esc_html__('days', 'event_espresso');
1390
+		EE_Registry::$i18n_js_strings['timer_hours']                    = esc_html__('hours', 'event_espresso');
1391
+		EE_Registry::$i18n_js_strings['timer_minutes']                  = esc_html__('minutes', 'event_espresso');
1392
+		EE_Registry::$i18n_js_strings['timer_seconds']                  = esc_html__('seconds', 'event_espresso');
1393
+		EE_Registry::$i18n_js_strings['timer_year']                     = esc_html__('year', 'event_espresso');
1394
+		EE_Registry::$i18n_js_strings['timer_month']                    = esc_html__('month', 'event_espresso');
1395
+		EE_Registry::$i18n_js_strings['timer_week']                     = esc_html__('week', 'event_espresso');
1396
+		EE_Registry::$i18n_js_strings['timer_day']                      = esc_html__('day', 'event_espresso');
1397
+		EE_Registry::$i18n_js_strings['timer_hour']                     = esc_html__('hour', 'event_espresso');
1398
+		EE_Registry::$i18n_js_strings['timer_minute']                   = esc_html__('minute', 'event_espresso');
1399
+		EE_Registry::$i18n_js_strings['timer_second']                   = esc_html__('second', 'event_espresso');
1400
+		EE_Registry::$i18n_js_strings['registration_expiration_notice'] =
1401
+			EED_Single_Page_Checkout::getRegistrationExpirationNotice();
1402
+		EE_Registry::$i18n_js_strings['ajax_submit']                    = apply_filters(
1403
+			'FHEE__Single_Page_Checkout__translate_js_strings__ajax_submit',
1404
+			true
1405
+		);
1406
+		EE_Registry::$i18n_js_strings['session_extension']              = absint(
1407
+			apply_filters('FHEE__EE_Session__extend_expiration__seconds_added', 10 * MINUTE_IN_SECONDS)
1408
+		);
1409
+		EE_Registry::$i18n_js_strings['session_expiration']    = EE_Registry::instance()->SSN->expiration();
1410
+		EE_Registry::$i18n_js_strings['use_session_countdown'] = EE_Registry::instance()->CFG->registration->useSessionCountdown();
1411
+		EE_Registry::$i18n_js_strings['no_copy_paste_email_confirm'] = esc_html__("We're sorry but copy and paste is disabled for email confirmation inputs. Please enter the email address manually.", 'event_espresso');
1412
+	}
1413
+
1414
+
1415
+	/**
1416
+	 * @return void
1417
+	 * @throws EE_Error
1418
+	 */
1419
+	public function enqueue_styles_and_scripts()
1420
+	{
1421
+		// load css
1422
+		wp_register_style(
1423
+			'single_page_checkout',
1424
+			SPCO_CSS_URL . 'single_page_checkout.css',
1425
+			['espresso_default'],
1426
+			EVENT_ESPRESSO_VERSION
1427
+		);
1428
+		wp_enqueue_style('single_page_checkout');
1429
+		// load JS
1430
+		wp_register_script(
1431
+			'single_page_checkout',
1432
+			SPCO_JS_URL . 'single_page_checkout.js',
1433
+			['espresso_core', 'underscore', 'ee_form_section_validation'],
1434
+			EVENT_ESPRESSO_VERSION,
1435
+			true
1436
+		);
1437
+		if ($this->checkout->registration_form instanceof EE_Form_Section_Proper) {
1438
+			$this->checkout->registration_form->enqueue_js();
1439
+		}
1440
+		if ($this->checkout->current_step->reg_form instanceof EE_Form_Section_Proper) {
1441
+			$this->checkout->current_step->reg_form->enqueue_js();
1442
+		}
1443
+		wp_enqueue_script('single_page_checkout');
1444
+		/**
1445
+		 * global action hook for enqueueing styles and scripts with
1446
+		 * spco calls.
1447
+		 */
1448
+		do_action('AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts', $this);
1449
+		/**
1450
+		 * dynamic action hook for enqueueing styles and scripts with spco calls.
1451
+		 * The hook will end up being something like:
1452
+		 *      AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__attendee_information
1453
+		 */
1454
+		do_action(
1455
+			'AHEE__EED_Single_Page_Checkout__enqueue_styles_and_scripts__' . $this->checkout->current_step->slug(),
1456
+			$this
1457
+		);
1458
+	}
1459
+
1460
+
1461
+	/**
1462
+	 * display the Registration Single Page Checkout Form
1463
+	 *
1464
+	 * @return void
1465
+	 * @throws EE_Error
1466
+	 * @throws ReflectionException
1467
+	 */
1468
+	private function _display_spco_reg_form()
1469
+	{
1470
+		// if registering via the admin, just display the reg form for the current step
1471
+		if ($this->checkout->admin_request) {
1472
+			EED_Single_Page_Checkout::getResponse()->addOutput($this->checkout->current_step->display_reg_form());
1473
+		} else {
1474
+			// add powered by EE msg
1475
+			add_action('AHEE__SPCO__reg_form_footer', ['EED_Single_Page_Checkout', 'display_registration_footer']);
1476
+			$empty_cart                                 = count(
1477
+					$this->checkout->transaction->registrations($this->checkout->reg_cache_where_params)
1478
+				) < 1;
1479
+			EE_Registry::$i18n_js_strings['empty_cart'] = $empty_cart;
1480
+			$cookies_not_set_msg                        = '';
1481
+			if ($empty_cart) {
1482
+				$cookies_not_set_msg = apply_filters(
1483
+					'FHEE__Single_Page_Checkout__display_spco_reg_form__cookies_not_set_msg',
1484
+					sprintf(
1485
+						esc_html__(
1486
+							'%1$s%3$sIt appears your browser is not currently set to accept Cookies%4$s%5$sIn order to register for events, you need to enable cookies.%7$sIf you require assistance, then click the following link to learn how to %8$senable cookies%9$s%6$s%2$s',
1487
+							'event_espresso'
1488
+						),
1489
+						'<div class="ee-attention hidden" id="ee-cookies-not-set-msg">',
1490
+						'</div>',
1491
+						'<h6 class="important-notice">',
1492
+						'</h6>',
1493
+						'<p>',
1494
+						'</p>',
1495
+						'<br />',
1496
+						'<a href="https://www.whatismybrowser.com/guides/how-to-enable-cookies/" target="_blank" rel="noopener noreferrer">',
1497
+						'</a>'
1498
+					)
1499
+				);
1500
+			}
1501
+			$this->checkout->registration_form = new EE_Form_Section_Proper(
1502
+				[
1503
+					'name'            => 'single-page-checkout',
1504
+					'html_id'         => 'ee-single-page-checkout-dv',
1505
+					'layout_strategy' =>
1506
+						new EE_Template_Layout(
1507
+							[
1508
+								'layout_template_file' => SPCO_TEMPLATES_PATH . 'registration_page_wrapper.template.php',
1509
+								'template_args'        => [
1510
+									'empty_cart'              => $empty_cart,
1511
+									'revisit'                 => $this->checkout->revisit,
1512
+									'reg_steps'               => $this->checkout->reg_steps,
1513
+									'next_step'               => $this->checkout->next_step instanceof EE_SPCO_Reg_Step
1514
+										? $this->checkout->next_step->slug()
1515
+										: '',
1516
+									'empty_msg'               => apply_filters(
1517
+										'FHEE__Single_Page_Checkout__display_spco_reg_form__empty_msg',
1518
+										sprintf(
1519
+											esc_html__(
1520
+												'You need to %1$sReturn to Events list%2$sselect at least one event%3$s before you can proceed with the registration process.',
1521
+												'event_espresso'
1522
+											),
1523
+											'<a href="'
1524
+											. get_post_type_archive_link(EspressoPostType::EVENTS)
1525
+											. '" title="',
1526
+											'">',
1527
+											'</a>'
1528
+										)
1529
+									),
1530
+									'cookies_not_set_msg'     => $cookies_not_set_msg,
1531
+									'registration_time_limit' => $this->checkout->get_registration_time_limit(),
1532
+									'use_session_countdown'   => EE_Registry::instance()->CFG->registration->useSessionCountdown(),
1533
+								],
1534
+							]
1535
+						),
1536
+				]
1537
+			);
1538
+			// load template and add to output sent that gets filtered into the_content()
1539
+			EED_Single_Page_Checkout::getResponse()->addOutput($this->checkout->registration_form->get_html());
1540
+		}
1541
+	}
1542
+
1543
+
1544
+	/**
1545
+	 * @param $next_step
1546
+	 * @return void
1547
+	 */
1548
+	public function add_extra_finalize_registration_inputs($next_step)
1549
+	{
1550
+		if ($next_step === 'finalize_registration') {
1551
+			echo '<div id="spco-extra-finalize_registration-inputs-dv"></div>';
1552
+		}
1553
+	}
1554
+
1555
+
1556
+	/**
1557
+	 * @return void
1558
+	 */
1559
+	public static function display_registration_footer()
1560
+	{
1561
+		if (
1562
+			apply_filters(
1563
+				'FHEE__EE_Front__Controller__show_reg_footer',
1564
+				EE_Registry::instance()->CFG->admin->show_reg_footer
1565
+			)
1566
+		) {
1567
+			add_filter(
1568
+				'FHEE__EEH_Template__powered_by_event_espresso__url',
1569
+				function ($url) {
1570
+					return apply_filters('FHEE__EE_Front_Controller__registration_footer__url', $url);
1571
+				}
1572
+			);
1573
+			echo apply_filters(
1574
+				'FHEE__EE_Front_Controller__display_registration_footer',
1575
+				EEH_Template::powered_by_event_espresso(
1576
+					'',
1577
+					'espresso-registration-footer-dv',
1578
+					['utm_content' => 'registration_checkout']
1579
+				)
1580
+			);
1581
+		}
1582
+	}
1583
+
1584
+
1585
+	/**
1586
+	 * @return void
1587
+	 * @throws EE_Error
1588
+	 * @throws ReflectionException
1589
+	 */
1590
+	public function unlock_transaction()
1591
+	{
1592
+		if ($this->checkout instanceof EE_Checkout && $this->checkout->transaction instanceof EE_Transaction) {
1593
+			$this->checkout->transaction->unlock();
1594
+		}
1595
+	}
1596
+
1597
+
1598
+	/**
1599
+	 * @return void
1600
+	 */
1601
+	private function _setup_redirect()
1602
+	{
1603
+		if ($this->checkout->continue_reg && $this->checkout->next_step instanceof EE_SPCO_Reg_Step) {
1604
+			$this->checkout->redirect = true;
1605
+			if (empty($this->checkout->redirect_url)) {
1606
+				$this->checkout->redirect_url = $this->checkout->next_step->reg_step_url();
1607
+			}
1608
+			$this->checkout->redirect_url = apply_filters(
1609
+				'FHEE__EED_Single_Page_Checkout___setup_redirect__checkout_redirect_url',
1610
+				$this->checkout->redirect_url,
1611
+				$this->checkout
1612
+			);
1613
+		}
1614
+	}
1615
+
1616
+
1617
+	/**
1618
+	 * handle ajax message responses and redirects
1619
+	 *
1620
+	 * @return void
1621
+	 * @throws EE_Error
1622
+	 * @throws ReflectionException
1623
+	 */
1624
+	public function go_to_next_step()
1625
+	{
1626
+		if ($this->request->isAjax()) {
1627
+			// capture contents of output buffer we started earlier in the request, and insert into JSON response
1628
+			$this->checkout->json_response->set_unexpected_errors(ob_get_clean());
1629
+		}
1630
+		$this->unlock_transaction();
1631
+		// just return for these conditions
1632
+		if (
1633
+			$this->checkout->admin_request
1634
+			|| $this->checkout->action === 'redirect_form'
1635
+			|| $this->checkout->action === 'update_checkout'
1636
+		) {
1637
+			return;
1638
+		}
1639
+		// AJAX response
1640
+		$this->_handle_json_response();
1641
+		// redirect to next step or the Thank-You page
1642
+		$this->_handle_html_redirects();
1643
+		// hmmm... must be something wrong, so let's just display the form again !
1644
+		$this->_display_spco_reg_form();
1645
+	}
1646
+
1647
+
1648
+	/**
1649
+	 * @return void
1650
+	 * @throws EE_Error
1651
+	 */
1652
+	protected function _handle_json_response()
1653
+	{
1654
+		// if this is an ajax request
1655
+		if ($this->request->isAjax()) {
1656
+			$this->checkout->json_response->set_registration_time_limit(
1657
+				$this->checkout->get_registration_time_limit()
1658
+			);
1659
+			$this->checkout->json_response->set_payment_amount($this->checkout->amount_owing);
1660
+			// just send the ajax (
1661
+			$json_response = apply_filters(
1662
+				'FHEE__EE_Single_Page_Checkout__JSON_response',
1663
+				$this->checkout->json_response
1664
+			);
1665
+			exit($json_response);
1666
+		}
1667
+	}
1668
+
1669
+
1670
+	/**
1671
+	 * @return void
1672
+	 */
1673
+	protected function _handle_html_redirects()
1674
+	{
1675
+		// going somewhere ?
1676
+		if ($this->checkout->redirect && ! empty($this->checkout->redirect_url)) {
1677
+			// store notices in a transient
1678
+			EE_Error::get_notices(false, true);
1679
+			wp_safe_redirect($this->checkout->redirect_url);
1680
+			exit();
1681
+		}
1682
+	}
1683
+
1684
+
1685
+	/**
1686
+	 * @return void
1687
+	 */
1688
+	public function set_checkout_anchor()
1689
+	{
1690
+		echo '<a id="checkout" style="float: left; margin-left: -999em;"></a>';
1691
+	}
1692
+
1693
+
1694
+	/**
1695
+	 * @return string
1696
+	 * @since 4.9.59.p
1697
+	 */
1698
+	public static function getRegistrationExpirationNotice(): string
1699
+	{
1700
+		return sprintf(
1701
+			esc_html__(
1702
+				'%1$sWe\'re sorry, but your registration time has expired.%2$s%3$s%4$sIf you still wish to complete your registration, please return to the %5$sEvent List%6$sEvent List%7$s and reselect your tickets if available. Please accept our apologies for any inconvenience this may have caused.%8$s',
1703
+				'event_espresso'
1704
+			),
1705
+			'<h4 class="important-notice">',
1706
+			'</h4>',
1707
+			'<br />',
1708
+			'<p>',
1709
+			'<a href="' . get_post_type_archive_link(EspressoPostType::EVENTS) . '" title="',
1710
+			'">',
1711
+			'</a>',
1712
+			'</p>'
1713
+		);
1714
+	}
1715 1715
 }
Please login to merge, or discard this patch.
reg_steps/payment_options/EE_SPCO_Reg_Step_Payment_Options.class.php 2 patches
Indentation   +2933 added lines, -2933 removed lines patch added patch discarded remove patch
@@ -23,2937 +23,2937 @@
 block discarded – undo
23 23
  */
24 24
 class EE_SPCO_Reg_Step_Payment_Options extends EE_SPCO_Reg_Step
25 25
 {
26
-    /**
27
-     * @var EE_Line_Item_Display $Line_Item_Display
28
-     */
29
-    protected $line_item_display;
30
-
31
-    /**
32
-     * @var boolean $handle_IPN_in_this_request
33
-     */
34
-    protected $handle_IPN_in_this_request = false;
35
-
36
-
37
-    /**
38
-     *    set_hooks - for hooking into EE Core, other modules, etc
39
-     *
40
-     * @access    public
41
-     * @return    void
42
-     */
43
-    public static function set_hooks()
44
-    {
45
-        add_filter(
46
-            'FHEE__SPCO__EE_Line_Item_Filter_Collection',
47
-            ['EE_SPCO_Reg_Step_Payment_Options', 'add_spco_line_item_filters']
48
-        );
49
-        add_action(
50
-            'wp_ajax_switch_spco_billing_form',
51
-            ['EE_SPCO_Reg_Step_Payment_Options', 'switch_spco_billing_form']
52
-        );
53
-        add_action(
54
-            'wp_ajax_nopriv_switch_spco_billing_form',
55
-            ['EE_SPCO_Reg_Step_Payment_Options', 'switch_spco_billing_form']
56
-        );
57
-        add_action('wp_ajax_save_payer_details', ['EE_SPCO_Reg_Step_Payment_Options', 'save_payer_details']);
58
-        add_action(
59
-            'wp_ajax_nopriv_save_payer_details',
60
-            ['EE_SPCO_Reg_Step_Payment_Options', 'save_payer_details']
61
-        );
62
-        add_action(
63
-            'wp_ajax_get_transaction_details_for_gateways',
64
-            ['EE_SPCO_Reg_Step_Payment_Options', 'get_transaction_details']
65
-        );
66
-        add_action(
67
-            'wp_ajax_nopriv_get_transaction_details_for_gateways',
68
-            ['EE_SPCO_Reg_Step_Payment_Options', 'get_transaction_details']
69
-        );
70
-        add_filter(
71
-            'FHEE__EED_Recaptcha___bypass_recaptcha__bypass_request_params_array',
72
-            ['EE_SPCO_Reg_Step_Payment_Options', 'bypass_recaptcha_for_load_payment_method'],
73
-            10,
74
-            1
75
-        );
76
-    }
77
-
78
-
79
-    /**
80
-     *    ajax switch_spco_billing_form
81
-     *
82
-     */
83
-    public static function switch_spco_billing_form()
84
-    {
85
-        EED_Single_Page_Checkout::process_ajax_request('switch_payment_method');
86
-    }
87
-
88
-
89
-    /**
90
-     *    ajax save_payer_details
91
-     *
92
-     */
93
-    public static function save_payer_details()
94
-    {
95
-        EED_Single_Page_Checkout::process_ajax_request('save_payer_details_via_ajax');
96
-    }
97
-
98
-
99
-    /**
100
-     *    ajax get_transaction_details
101
-     *
102
-     */
103
-    public static function get_transaction_details()
104
-    {
105
-        EED_Single_Page_Checkout::process_ajax_request('get_transaction_details_for_gateways');
106
-    }
107
-
108
-
109
-    /**
110
-     * bypass_recaptcha_for_load_payment_method
111
-     *
112
-     * @access public
113
-     * @return array
114
-     * @throws InvalidArgumentException
115
-     * @throws InvalidDataTypeException
116
-     * @throws InvalidInterfaceException
117
-     */
118
-    public static function bypass_recaptcha_for_load_payment_method()
119
-    {
120
-        return [
121
-            'EESID'  => EE_Registry::instance()->SSN->id(),
122
-            'step'   => 'payment_options',
123
-            'action' => 'spco_billing_form',
124
-        ];
125
-    }
126
-
127
-
128
-    /**
129
-     *    class constructor
130
-     *
131
-     * @access    public
132
-     * @param EE_Checkout $checkout
133
-     */
134
-    public function __construct(EE_Checkout $checkout)
135
-    {
136
-        $this->request   = EED_Single_Page_Checkout::getRequest();
137
-        $this->_slug     = 'payment_options';
138
-        $this->_name     = esc_html__('Payment Options', 'event_espresso');
139
-        $this->_template = SPCO_REG_STEPS_PATH . $this->_slug . '/payment_options_main.template.php';
140
-        $this->checkout  = $checkout;
141
-        $this->_reset_success_message();
142
-        $this->set_instructions(
143
-            esc_html__(
144
-                'Please select a method of payment and provide any necessary billing information before proceeding.',
145
-                'event_espresso'
146
-            )
147
-        );
148
-    }
149
-
150
-
151
-    /**
152
-     * @return null
153
-     */
154
-    public function line_item_display()
155
-    {
156
-        return $this->line_item_display;
157
-    }
158
-
159
-
160
-    /**
161
-     * @param null $line_item_display
162
-     */
163
-    public function set_line_item_display($line_item_display)
164
-    {
165
-        $this->line_item_display = $line_item_display;
166
-    }
167
-
168
-
169
-    /**
170
-     * @return boolean
171
-     */
172
-    public function handle_IPN_in_this_request()
173
-    {
174
-        return $this->handle_IPN_in_this_request;
175
-    }
176
-
177
-
178
-    /**
179
-     * @param boolean $handle_IPN_in_this_request
180
-     */
181
-    public function set_handle_IPN_in_this_request($handle_IPN_in_this_request)
182
-    {
183
-        $this->handle_IPN_in_this_request = filter_var($handle_IPN_in_this_request, FILTER_VALIDATE_BOOLEAN);
184
-    }
185
-
186
-
187
-    /**
188
-     * translate_js_strings
189
-     *
190
-     * @return void
191
-     */
192
-    public function translate_js_strings()
193
-    {
194
-        EE_Registry::$i18n_js_strings['no_payment_method']      = esc_html__(
195
-            'Please select a method of payment in order to continue.',
196
-            'event_espresso'
197
-        );
198
-        EE_Registry::$i18n_js_strings['invalid_payment_method'] = esc_html__(
199
-            'A valid method of payment could not be determined. Please refresh the page and try again.',
200
-            'event_espresso'
201
-        );
202
-        EE_Registry::$i18n_js_strings['forwarding_to_offsite']  = esc_html__(
203
-            'Forwarding to Secure Payment Provider.',
204
-            'event_espresso'
205
-        );
206
-    }
207
-
208
-
209
-    /**
210
-     * enqueue_styles_and_scripts
211
-     *
212
-     * @return void
213
-     * @throws EE_Error
214
-     * @throws InvalidArgumentException
215
-     * @throws InvalidDataTypeException
216
-     * @throws InvalidInterfaceException
217
-     * @throws ReflectionException
218
-     */
219
-    public function enqueue_styles_and_scripts()
220
-    {
221
-        $transaction = $this->checkout->transaction;
222
-        // if the transaction isn't set or nothing is owed on it, don't enqueue any JS
223
-        if (! $transaction instanceof EE_Transaction || EEH_Money::compare_floats($transaction->remaining(), 0)) {
224
-            return;
225
-        }
226
-        foreach (
227
-            EEM_Payment_Method::instance()->get_all_for_transaction(
228
-                $transaction,
229
-                EEM_Payment_Method::scope_cart
230
-            ) as $payment_method
231
-        ) {
232
-            $type_obj = $payment_method->type_obj();
233
-            if ($type_obj instanceof EE_PMT_Base) {
234
-                $billing_form = $type_obj->generate_new_billing_form($transaction);
235
-                if ($billing_form instanceof EE_Form_Section_Proper) {
236
-                    $billing_form->enqueue_js();
237
-                }
238
-            }
239
-        }
240
-    }
241
-
242
-
243
-    /**
244
-     * initialize_reg_step
245
-     *
246
-     * @return bool
247
-     * @throws EE_Error
248
-     * @throws InvalidArgumentException
249
-     * @throws ReflectionException
250
-     * @throws InvalidDataTypeException
251
-     * @throws InvalidInterfaceException
252
-     */
253
-    public function initialize_reg_step()
254
-    {
255
-        // TODO: if /when we implement donations, then this will need overriding
256
-        if (
257
-            // don't need payment options for:
258
-            // registrations made via the admin
259
-            // completed transactions
260
-            // overpaid transactions
261
-            // $ 0.00 transactions(no payment required)
262
-            ! $this->checkout->payment_required()
263
-            // but do NOT remove if current action being called belongs to this reg step
264
-            && ! is_callable([$this, $this->checkout->action])
265
-            && ! $this->completed()
266
-        ) {
267
-            // and if so, then we no longer need the Payment Options step
268
-            if ($this->is_current_step()) {
269
-                $this->checkout->generate_reg_form = false;
270
-            }
271
-            $this->checkout->remove_reg_step($this->_slug);
272
-            // DEBUG LOG
273
-            // $this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ );
274
-            return false;
275
-        }
276
-        // load EEM_Payment_Method
277
-        EE_Registry::instance()->load_model('Payment_Method');
278
-        // get all active payment methods
279
-        $this->checkout->available_payment_methods = EEM_Payment_Method::instance()->get_all_for_transaction(
280
-            $this->checkout->transaction,
281
-            EEM_Payment_Method::scope_cart
282
-        );
283
-        return true;
284
-    }
285
-
286
-
287
-    /**
288
-     * @return EE_Form_Section_Proper
289
-     * @throws EE_Error
290
-     * @throws InvalidArgumentException
291
-     * @throws ReflectionException
292
-     * @throws EntityNotFoundException
293
-     * @throws InvalidDataTypeException
294
-     * @throws InvalidInterfaceException
295
-     * @throws InvalidStatusException
296
-     */
297
-    public function generate_reg_form()
298
-    {
299
-        // reset in case someone changes their mind
300
-        $this->_reset_selected_method_of_payment();
301
-        // set some defaults
302
-        $this->checkout->selected_method_of_payment = 'payments_closed';
303
-        $registrations_requiring_payment            = [];
304
-        $registrations_for_free_events              = [];
305
-        $registrations_requiring_pre_approval       = [];
306
-        $sold_out_events                            = [];
307
-        $insufficient_spaces_available              = [];
308
-        $no_payment_required                        = true;
309
-        // loop thru registrations to gather info
310
-        $registrations         = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params);
311
-        $ejected_registrations = EE_SPCO_Reg_Step_Payment_Options::find_registrations_that_lost_their_space(
312
-            $registrations,
313
-            $this->checkout->revisit
314
-        );
315
-        foreach ($registrations as $REG_ID => $registration) {
316
-            /** @var $registration EE_Registration */
317
-            // Skip if the registration has been moved
318
-            if ($registration->wasMoved()) {
319
-                continue;
320
-            }
321
-            // has this registration lost it's space ?
322
-            if (isset($ejected_registrations[ $REG_ID ])) {
323
-                if ($registration->event()->is_sold_out() || $registration->event()->is_sold_out(true)) {
324
-                    $sold_out_events[ $registration->event()->ID() ] = $registration->event();
325
-                } else {
326
-                    $insufficient_spaces_available[ $registration->event()->ID() ] = $registration->event();
327
-                }
328
-                continue;
329
-            }
330
-            // event requires admin approval
331
-            if ($registration->status_ID() === RegStatus::AWAITING_REVIEW) {
332
-                // add event to list of events with pre-approval reg status
333
-                $registrations_requiring_pre_approval[ $REG_ID ] = $registration;
334
-                do_action(
335
-                    'AHEE__EE_SPCO_Reg_Step_Payment_Options__generate_reg_form__event_requires_pre_approval',
336
-                    $registration->event(),
337
-                    $this
338
-                );
339
-                continue;
340
-            }
341
-            if (
342
-                $this->checkout->revisit
343
-                && $registration->status_ID() !== RegStatus::APPROVED
344
-                && (
345
-                    $registration->event()->is_sold_out()
346
-                    || $registration->event()->is_sold_out(true)
347
-                )
348
-            ) {
349
-                // add event to list of events that are sold out
350
-                $sold_out_events[ $registration->event()->ID() ] = $registration->event();
351
-                do_action(
352
-                    'AHEE__EE_SPCO_Reg_Step_Payment_Options__generate_reg_form__sold_out_event',
353
-                    $registration->event(),
354
-                    $this
355
-                );
356
-                continue;
357
-            }
358
-            // are they allowed to pay now and is there monies owing?
359
-            if ($registration->owes_monies_and_can_pay()) {
360
-                $registrations_requiring_payment[ $REG_ID ] = $registration;
361
-                do_action(
362
-                    'AHEE__EE_SPCO_Reg_Step_Payment_Options__generate_reg_form__event_requires_payment',
363
-                    $registration->event(),
364
-                    $this
365
-                );
366
-            } elseif (
367
-                ! $this->checkout->revisit
368
-                      && $registration->status_ID() !== RegStatus::AWAITING_REVIEW
369
-                      && $registration->ticket()->is_free()
370
-            ) {
371
-                $registrations_for_free_events[ $registration->ticket()->ID() ] = $registration;
372
-            }
373
-        }
374
-        $subsections = [];
375
-        // now decide which template to load
376
-        if (! empty($sold_out_events)) {
377
-            $subsections['sold_out_events'] = $this->_sold_out_events($sold_out_events);
378
-        }
379
-        if (! empty($insufficient_spaces_available)) {
380
-            $subsections['insufficient_space'] = $this->_insufficient_spaces_available(
381
-                $insufficient_spaces_available
382
-            );
383
-        }
384
-        if (! empty($registrations_requiring_pre_approval)) {
385
-            $subsections['registrations_requiring_pre_approval'] = $this->_registrations_requiring_pre_approval(
386
-                $registrations_requiring_pre_approval
387
-            );
388
-        }
389
-        if (! empty($registrations_for_free_events)) {
390
-            $subsections['no_payment_required'] = $this->_no_payment_required($registrations_for_free_events);
391
-        }
392
-        if (! empty($registrations_requiring_payment)) {
393
-            if ($this->checkout->amount_owing > 0) {
394
-                // autoload Line_Item_Display classes
395
-                EEH_Autoloader::register_line_item_filter_autoloaders();
396
-                $line_item_filter_processor = new EE_Line_Item_Filter_Processor(
397
-                    apply_filters(
398
-                        'FHEE__SPCO__EE_Line_Item_Filter_Collection',
399
-                        new EE_Line_Item_Filter_Collection()
400
-                    ),
401
-                    $this->checkout->cart->get_grand_total()
402
-                );
403
-                /** @var EE_Line_Item $filtered_line_item_tree */
404
-                $filtered_line_item_tree = $line_item_filter_processor->process();
405
-                EEH_Autoloader::register_line_item_display_autoloaders();
406
-                $this->set_line_item_display(new EE_Line_Item_Display('spco'));
407
-                $subsections['payment_options'] = $this->_display_payment_options(
408
-                    $this->line_item_display->display_line_item(
409
-                        $filtered_line_item_tree,
410
-                        ['registrations' => $registrations]
411
-                    )
412
-                );
413
-                $this->checkout->amount_owing   = $filtered_line_item_tree->total();
414
-                $this->_apply_registration_payments_to_amount_owing($registrations);
415
-            }
416
-            $no_payment_required = false;
417
-        } else {
418
-            $this->_hide_reg_step_submit_button_if_revisit();
419
-        }
420
-        $this->_save_selected_method_of_payment();
421
-
422
-        $subsections['default_hidden_inputs'] = $this->reg_step_hidden_inputs();
423
-        $subsections['extra_hidden_inputs']   = $this->_extra_hidden_inputs($no_payment_required);
424
-
425
-        return new EE_Form_Section_Proper(
426
-            [
427
-                'name'            => $this->reg_form_name(),
428
-                'html_id'         => $this->reg_form_name(),
429
-                'subsections'     => $subsections,
430
-                'layout_strategy' => new EE_No_Layout(),
431
-            ]
432
-        );
433
-    }
434
-
435
-
436
-    /**
437
-     * add line item filters required for this reg step
438
-     * these filters are applied via this line in EE_SPCO_Reg_Step_Payment_Options::set_hooks():
439
-     *        add_filter( 'FHEE__SPCO__EE_Line_Item_Filter_Collection', array( 'EE_SPCO_Reg_Step_Payment_Options',
440
-     *        'add_spco_line_item_filters' ) ); so any code that wants to use the same set of filters during the
441
-     *        payment options reg step, can apply these filters via the following: apply_filters(
442
-     *        'FHEE__SPCO__EE_Line_Item_Filter_Collection', new EE_Line_Item_Filter_Collection() ) or to an existing
443
-     *        filter collection by passing that instead of instantiating a new collection
444
-     *
445
-     * @param EE_Line_Item_Filter_Collection $line_item_filter_collection
446
-     * @return EE_Line_Item_Filter_Collection
447
-     * @throws EE_Error
448
-     * @throws InvalidArgumentException
449
-     * @throws ReflectionException
450
-     * @throws EntityNotFoundException
451
-     * @throws InvalidDataTypeException
452
-     * @throws InvalidInterfaceException
453
-     * @throws InvalidStatusException
454
-     */
455
-    public static function add_spco_line_item_filters(EE_Line_Item_Filter_Collection $line_item_filter_collection)
456
-    {
457
-        if (! EE_Registry::instance()->SSN instanceof EE_Session) {
458
-            return $line_item_filter_collection;
459
-        }
460
-        if (! EE_Registry::instance()->SSN->checkout() instanceof EE_Checkout) {
461
-            return $line_item_filter_collection;
462
-        }
463
-        if (! EE_Registry::instance()->SSN->checkout()->transaction instanceof EE_Transaction) {
464
-            return $line_item_filter_collection;
465
-        }
466
-        $line_item_filter_collection->add(
467
-            new EE_Billable_Line_Item_Filter(
468
-                EE_SPCO_Reg_Step_Payment_Options::remove_ejected_registrations(
469
-                    EE_Registry::instance()->SSN->checkout()->transaction->registrations(
470
-                        EE_Registry::instance()->SSN->checkout()->reg_cache_where_params
471
-                    )
472
-                )
473
-            )
474
-        );
475
-        $line_item_filter_collection->add(new EE_Non_Zero_Line_Item_Filter());
476
-        return $line_item_filter_collection;
477
-    }
478
-
479
-
480
-    /**
481
-     * remove_ejected_registrations
482
-     * if a registrant has lost their potential space at an event due to lack of payment,
483
-     * then this method removes them from the list of registrations being paid for during this request
484
-     *
485
-     * @param EE_Registration[] $registrations
486
-     * @return EE_Registration[]
487
-     * @throws EE_Error
488
-     * @throws InvalidArgumentException
489
-     * @throws ReflectionException
490
-     * @throws EntityNotFoundException
491
-     * @throws InvalidDataTypeException
492
-     * @throws InvalidInterfaceException
493
-     * @throws InvalidStatusException
494
-     */
495
-    public static function remove_ejected_registrations(array $registrations)
496
-    {
497
-        $ejected_registrations = EE_SPCO_Reg_Step_Payment_Options::find_registrations_that_lost_their_space(
498
-            $registrations,
499
-            EE_Registry::instance()->SSN->checkout()->revisit
500
-        );
501
-        foreach ($registrations as $REG_ID => $registration) {
502
-            // has this registration lost it's space ?
503
-            if (isset($ejected_registrations[ $REG_ID ])) {
504
-                unset($registrations[ $REG_ID ]);
505
-            }
506
-        }
507
-        return $registrations;
508
-    }
509
-
510
-
511
-    /**
512
-     * find_registrations_that_lost_their_space
513
-     * If a registrant chooses an offline payment method like Invoice,
514
-     * then no space is reserved for them at the event until they fully pay fo that site
515
-     * (unless the event's default reg status is set to APPROVED)
516
-     * if a registrant then later returns to pay, but the number of spaces available has been reduced due to sales,
517
-     * then this method will determine which registrations have lost the ability to complete the reg process.
518
-     *
519
-     * @param EE_Registration[] $registrations
520
-     * @param bool              $revisit
521
-     * @return array
522
-     * @throws EE_Error
523
-     * @throws InvalidArgumentException
524
-     * @throws ReflectionException
525
-     * @throws EntityNotFoundException
526
-     * @throws InvalidDataTypeException
527
-     * @throws InvalidInterfaceException
528
-     * @throws InvalidStatusException
529
-     */
530
-    public static function find_registrations_that_lost_their_space(array $registrations, $revisit = false)
531
-    {
532
-        // registrations per event
533
-        $event_reg_count = [];
534
-        // spaces left per event
535
-        $event_spaces_remaining = [];
536
-        // tickets left sorted by ID
537
-        $tickets_remaining = [];
538
-        // registrations that have lost their space
539
-        $ejected_registrations = [];
540
-        foreach ($registrations as $REG_ID => $registration) {
541
-            if (
542
-                $registration->status_ID() === RegStatus::APPROVED
543
-                || apply_filters(
544
-                    'FHEE__EE_SPCO_Reg_Step_Payment_Options__find_registrations_that_lost_their_space__allow_reg_payment',
545
-                    false,
546
-                    $registration,
547
-                    $revisit
548
-                )
549
-            ) {
550
-                continue;
551
-            }
552
-            $EVT_ID = $registration->event_ID();
553
-            $ticket = $registration->ticket();
554
-            if (! isset($tickets_remaining[ $ticket->ID() ])) {
555
-                $tickets_remaining[ $ticket->ID() ] = $ticket->remaining();
556
-            }
557
-            if ($tickets_remaining[ $ticket->ID() ] > 0) {
558
-                if (! isset($event_reg_count[ $EVT_ID ])) {
559
-                    $event_reg_count[ $EVT_ID ] = 0;
560
-                }
561
-                $event_reg_count[ $EVT_ID ]++;
562
-                if (! isset($event_spaces_remaining[ $EVT_ID ])) {
563
-                    $event_spaces_remaining[ $EVT_ID ] = $registration->event()->spaces_remaining_for_sale();
564
-                }
565
-            }
566
-            if (
567
-                $revisit
568
-                && ($tickets_remaining[ $ticket->ID() ] === 0
569
-                    || $event_reg_count[ $EVT_ID ] > $event_spaces_remaining[ $EVT_ID ]
570
-                )
571
-            ) {
572
-                $ejected_registrations[ $REG_ID ] = $registration->event();
573
-                if ($registration->status_ID() !== RegStatus::WAIT_LIST) {
574
-                    /** @type EE_Registration_Processor $registration_processor */
575
-                    $registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
576
-                    // at this point, we should have enough details about the registrant to consider the registration
577
-                    // NOT incomplete
578
-                    $registration_processor->manually_update_registration_status(
579
-                        $registration,
580
-                        RegStatus::WAIT_LIST
581
-                    );
582
-                }
583
-            }
584
-        }
585
-        return $ejected_registrations;
586
-    }
587
-
588
-
589
-    /**
590
-     * _hide_reg_step_submit_button
591
-     * removes the html for the reg step submit button
592
-     * by replacing it with an empty string via filter callback
593
-     *
594
-     * @return void
595
-     */
596
-    protected function _adjust_registration_status_if_event_old_sold()
597
-    {
598
-    }
599
-
600
-
601
-    /**
602
-     * _hide_reg_step_submit_button
603
-     * removes the html for the reg step submit button
604
-     * by replacing it with an empty string via filter callback
605
-     *
606
-     * @return void
607
-     */
608
-    protected function _hide_reg_step_submit_button_if_revisit()
609
-    {
610
-        if ($this->checkout->revisit) {
611
-            add_filter('FHEE__EE_SPCO_Reg_Step__reg_step_submit_button__sbmt_btn_html', '__return_empty_string');
612
-        }
613
-    }
614
-
615
-
616
-    /**
617
-     * sold_out_events
618
-     * displays notices regarding events that have sold out since hte registrant first signed up
619
-     *
620
-     * @param EE_Event[] $sold_out_events_array
621
-     * @return EE_Form_Section_Proper
622
-     * @throws EE_Error
623
-     */
624
-    private function _sold_out_events($sold_out_events_array = [])
625
-    {
626
-        // set some defaults
627
-        $this->checkout->selected_method_of_payment = 'events_sold_out';
628
-        $sold_out_events                            = '';
629
-        foreach ($sold_out_events_array as $sold_out_event) {
630
-            $sold_out_events .= EEH_HTML::li(
631
-                EEH_HTML::span(
632
-                    '  ' . $sold_out_event->name(),
633
-                    '',
634
-                    'dashicons dashicons-marker ee-icon-size-16 pink-text'
635
-                )
636
-            );
637
-        }
638
-        return new EE_Form_Section_Proper(
639
-            [
640
-                'layout_strategy' => new EE_Template_Layout(
641
-                    [
642
-                        'layout_template_file' => SPCO_REG_STEPS_PATH
643
-                                                  . $this->_slug
644
-                                                  . '/sold_out_events.template.php',
645
-                        'template_args'        => apply_filters(
646
-                            'FHEE__EE_SPCO_Reg_Step_Payment_Options___sold_out_events__template_args',
647
-                            [
648
-                                'sold_out_events'     => $sold_out_events,
649
-                                'sold_out_events_msg' => apply_filters(
650
-                                    'FHEE__EE_SPCO_Reg_Step_Payment_Options___sold_out_events__sold_out_events_msg',
651
-                                    sprintf(
652
-                                        esc_html__(
653
-                                            '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',
654
-                                            'event_espresso'
655
-                                        ),
656
-                                        '<strong>',
657
-                                        '</strong>',
658
-                                        '<br />'
659
-                                    )
660
-                                ),
661
-                            ]
662
-                        ),
663
-                    ]
664
-                ),
665
-            ]
666
-        );
667
-    }
668
-
669
-
670
-    /**
671
-     * _insufficient_spaces_available
672
-     * displays notices regarding events that do not have enough remaining spaces
673
-     * to satisfy the current number of registrations looking to pay
674
-     *
675
-     * @param EE_Event[] $insufficient_spaces_events_array
676
-     * @return EE_Form_Section_Proper
677
-     * @throws EE_Error
678
-     * @throws ReflectionException
679
-     */
680
-    private function _insufficient_spaces_available($insufficient_spaces_events_array = [])
681
-    {
682
-        // set some defaults
683
-        $this->checkout->selected_method_of_payment = 'invoice';
684
-        $insufficient_space_events                  = '';
685
-        foreach ($insufficient_spaces_events_array as $event) {
686
-            if ($event instanceof EE_Event) {
687
-                $insufficient_space_events .= EEH_HTML::li(
688
-                    EEH_HTML::span(' ' . $event->name(), '', 'dashicons dashicons-marker ee-icon-size-16 pink-text')
689
-                );
690
-            }
691
-        }
692
-        return new EE_Form_Section_Proper(
693
-            [
694
-                'subsections'     => [
695
-                    'default_hidden_inputs' => $this->reg_step_hidden_inputs(),
696
-                    'extra_hidden_inputs'   => $this->_extra_hidden_inputs(),
697
-                ],
698
-                'layout_strategy' => new EE_Template_Layout(
699
-                    [
700
-                        'layout_template_file' => SPCO_REG_STEPS_PATH
701
-                                                  . $this->_slug
702
-                                                  . '/sold_out_events.template.php',
703
-                        'template_args'        => apply_filters(
704
-                            'FHEE__EE_SPCO_Reg_Step_Payment_Options___insufficient_spaces_available__template_args',
705
-                            [
706
-                                'sold_out_events'     => $insufficient_space_events,
707
-                                'sold_out_events_msg' => apply_filters(
708
-                                    'FHEE__EE_SPCO_Reg_Step_Payment_Options___insufficient_spaces_available__insufficient_space_msg',
709
-                                    esc_html__(
710
-                                        '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.',
711
-                                        'event_espresso'
712
-                                    )
713
-                                ),
714
-                            ]
715
-                        ),
716
-                    ]
717
-                ),
718
-            ]
719
-        );
720
-    }
721
-
722
-
723
-    /**
724
-     * registrations_requiring_pre_approval
725
-     *
726
-     * @param array $registrations_requiring_pre_approval
727
-     * @return EE_Form_Section_Proper
728
-     * @throws EE_Error
729
-     * @throws EntityNotFoundException
730
-     * @throws ReflectionException
731
-     */
732
-    private function _registrations_requiring_pre_approval($registrations_requiring_pre_approval = [])
733
-    {
734
-        $events_requiring_pre_approval = [];
735
-        foreach ($registrations_requiring_pre_approval as $registration) {
736
-            if ($registration instanceof EE_Registration && $registration->event() instanceof EE_Event) {
737
-                $events_requiring_pre_approval[ $registration->event()->ID() ] = EEH_HTML::li(
738
-                    EEH_HTML::span(
739
-                        '',
740
-                        '',
741
-                        'dashicons dashicons-marker ee-icon-size-16 orange-text'
742
-                    )
743
-                    . EEH_HTML::span($registration->event()->name(), '', 'orange-text')
744
-                );
745
-            }
746
-        }
747
-        return new EE_Form_Section_Proper(
748
-            [
749
-                'layout_strategy' => new EE_Template_Layout(
750
-                    [
751
-                        'layout_template_file' => SPCO_REG_STEPS_PATH
752
-                                                  . $this->_slug
753
-                                                  . '/events_requiring_pre_approval.template.php', // layout_template
754
-                        'template_args'        => apply_filters(
755
-                            'FHEE__EE_SPCO_Reg_Step_Payment_Options___sold_out_events__template_args',
756
-                            [
757
-                                'events_requiring_pre_approval'     => implode('', $events_requiring_pre_approval),
758
-                                'events_requiring_pre_approval_msg' => apply_filters(
759
-                                    'FHEE__EE_SPCO_Reg_Step_Payment_Options___events_requiring_pre_approval__events_requiring_pre_approval_msg',
760
-                                    esc_html__(
761
-                                        '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.',
762
-                                        'event_espresso'
763
-                                    )
764
-                                ),
765
-                            ]
766
-                        ),
767
-                    ]
768
-                ),
769
-            ]
770
-        );
771
-    }
772
-
773
-
774
-    /**
775
-     * _no_payment_required
776
-     *
777
-     * @param EE_Event[] $registrations_for_free_events
778
-     * @return EE_Form_Section_Proper
779
-     * @throws EE_Error
780
-     */
781
-    private function _no_payment_required($registrations_for_free_events = [])
782
-    {
783
-        // set some defaults
784
-        $this->checkout->selected_method_of_payment = 'no_payment_required';
785
-        // generate no_payment_required form
786
-        return new EE_Form_Section_Proper(
787
-            [
788
-                'layout_strategy' => new EE_Template_Layout(
789
-                    [
790
-                        'layout_template_file' => SPCO_REG_STEPS_PATH
791
-                                                  . $this->_slug
792
-                                                  . '/no_payment_required.template.php', // layout_template
793
-                        'template_args'        => apply_filters(
794
-                            'FHEE__EE_SPCO_Reg_Step_Payment_Options___no_payment_required__template_args',
795
-                            [
796
-                                'revisit'                       => $this->checkout->revisit,
797
-                                'registrations'                 => [],
798
-                                'ticket_count'                  => [],
799
-                                'registrations_for_free_events' => $registrations_for_free_events,
800
-                                'no_payment_required_msg'       => EEH_HTML::p(
801
-                                    esc_html__('This is a free event, so no billing will occur.', 'event_espresso')
802
-                                ),
803
-                            ]
804
-                        ),
805
-                    ]
806
-                ),
807
-            ]
808
-        );
809
-    }
810
-
811
-
812
-    /**
813
-     * _display_payment_options
814
-     *
815
-     * @param string $transaction_details
816
-     * @return EE_Form_Section_Proper
817
-     * @throws EE_Error
818
-     * @throws InvalidArgumentException
819
-     * @throws InvalidDataTypeException
820
-     * @throws InvalidInterfaceException
821
-     */
822
-    private function _display_payment_options($transaction_details = '')
823
-    {
824
-        // has method_of_payment been set by no-js user?
825
-        $this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment();
826
-        // build payment options form
827
-        return apply_filters(
828
-            'FHEE__EE_SPCO_Reg_Step_Payment_Options___display_payment_options__payment_options_form',
829
-            new EE_Form_Section_Proper(
830
-                [
831
-                    'subsections'     => [
832
-                        'before_payment_options' => apply_filters(
833
-                            'FHEE__EE_SPCO_Reg_Step_Payment_Options___display_payment_options__before_payment_options',
834
-                            new EE_Form_Section_Proper(
835
-                                ['layout_strategy' => new EE_Div_Per_Section_Layout()]
836
-                            )
837
-                        ),
838
-                        'payment_options'        => $this->_setup_payment_options(),
839
-                        'after_payment_options'  => apply_filters(
840
-                            'FHEE__EE_SPCO_Reg_Step_Payment_Options___display_payment_options__after_payment_options',
841
-                            new EE_Form_Section_Proper(
842
-                                ['layout_strategy' => new EE_Div_Per_Section_Layout()]
843
-                            )
844
-                        ),
845
-                    ],
846
-                    'layout_strategy' => new EE_Template_Layout(
847
-                        [
848
-                            'layout_template_file' => $this->_template,
849
-                            'template_args'        => apply_filters(
850
-                                'FHEE__EE_SPCO_Reg_Step_Payment_Options___display_payment_options__template_args',
851
-                                [
852
-                                    'reg_count'                 => $this->line_item_display->total_items(),
853
-                                    'transaction_details'       => $transaction_details,
854
-                                    'available_payment_methods' => [],
855
-                                ]
856
-                            ),
857
-                        ]
858
-                    ),
859
-                ]
860
-            )
861
-        );
862
-    }
863
-
864
-
865
-    /**
866
-     * _extra_hidden_inputs
867
-     *
868
-     * @param bool $no_payment_required
869
-     * @return EE_Form_Section_Proper
870
-     * @throws EE_Error
871
-     * @throws ReflectionException
872
-     */
873
-    private function _extra_hidden_inputs($no_payment_required = true)
874
-    {
875
-        return new EE_Form_Section_Proper(
876
-            [
877
-                'html_id'         => 'ee-' . $this->slug() . '-extra-hidden-inputs',
878
-                'layout_strategy' => new EE_Div_Per_Section_Layout(),
879
-                'subsections'     => [
880
-                    'spco_no_payment_required' => new EE_Hidden_Input(
881
-                        [
882
-                            'normalization_strategy' => new EE_Boolean_Normalization(),
883
-                            'html_name'              => 'spco_no_payment_required',
884
-                            'html_id'                => 'spco-no-payment-required-payment_options',
885
-                            'default'                => $no_payment_required,
886
-                        ]
887
-                    ),
888
-                    'spco_transaction_id'      => new EE_Fixed_Hidden_Input(
889
-                        [
890
-                            'normalization_strategy' => new EE_Int_Normalization(),
891
-                            'html_name'              => 'spco_transaction_id',
892
-                            'html_id'                => 'spco-transaction-id',
893
-                            'default'                => $this->checkout->transaction->ID(),
894
-                        ]
895
-                    ),
896
-                ],
897
-            ]
898
-        );
899
-    }
900
-
901
-
902
-    /**
903
-     *    _apply_registration_payments_to_amount_owing
904
-     *
905
-     * @param array $registrations
906
-     * @throws EE_Error
907
-     */
908
-    protected function _apply_registration_payments_to_amount_owing(array $registrations)
909
-    {
910
-        $payments = [];
911
-        foreach ($registrations as $registration) {
912
-            if ($registration instanceof EE_Registration && $registration->owes_monies_and_can_pay()) {
913
-                $payments += $registration->registration_payments();
914
-            }
915
-        }
916
-        if (! empty($payments)) {
917
-            foreach ($payments as $payment) {
918
-                if ($payment instanceof EE_Registration_Payment) {
919
-                    $this->checkout->amount_owing -= $payment->amount();
920
-                }
921
-            }
922
-        }
923
-    }
924
-
925
-
926
-    /**
927
-     *    _reset_selected_method_of_payment
928
-     *
929
-     * @access    private
930
-     * @param bool $force_reset
931
-     * @return void
932
-     * @throws InvalidArgumentException
933
-     * @throws InvalidDataTypeException
934
-     * @throws InvalidInterfaceException
935
-     */
936
-    private function _reset_selected_method_of_payment($force_reset = false)
937
-    {
938
-        /** @var RequestInterface $request */
939
-        $request              = LoaderFactory::getLoader()->getShared(RequestInterface::class);
940
-        $reset_payment_method = $request->getRequestParam('reset_payment_method', $force_reset, 'bool');
941
-        if ($reset_payment_method) {
942
-            $this->checkout->selected_method_of_payment = null;
943
-            $this->checkout->payment_method             = null;
944
-            $this->checkout->billing_form               = null;
945
-            $this->_save_selected_method_of_payment();
946
-        }
947
-    }
948
-
949
-
950
-    /**
951
-     * _save_selected_method_of_payment
952
-     * stores the selected_method_of_payment in the session
953
-     * so that it's available for all subsequent requests including AJAX
954
-     *
955
-     * @access        private
956
-     * @param string $selected_method_of_payment
957
-     * @return void
958
-     * @throws InvalidArgumentException
959
-     * @throws InvalidDataTypeException
960
-     * @throws InvalidInterfaceException
961
-     */
962
-    private function _save_selected_method_of_payment($selected_method_of_payment = '')
963
-    {
964
-        $selected_method_of_payment = ! empty($selected_method_of_payment)
965
-            ? $selected_method_of_payment
966
-            : $this->checkout->selected_method_of_payment;
967
-        EE_Registry::instance()->SSN->set_session_data(
968
-            ['selected_method_of_payment' => $selected_method_of_payment]
969
-        );
970
-    }
971
-
972
-
973
-    /**
974
-     * _setup_payment_options
975
-     *
976
-     * @return EE_Form_Section_Proper
977
-     * @throws EE_Error
978
-     * @throws InvalidArgumentException
979
-     * @throws InvalidDataTypeException
980
-     * @throws InvalidInterfaceException
981
-     */
982
-    public function _setup_payment_options()
983
-    {
984
-        // load payment method classes
985
-        $this->checkout->available_payment_methods = $this->_get_available_payment_methods();
986
-        if (empty($this->checkout->available_payment_methods)) {
987
-            EE_Error::add_error(
988
-                apply_filters(
989
-                    'FHEE__EE_SPCO_Reg_Step_Payment_Options___setup_payment_options__error_message_no_payment_methods',
990
-                    sprintf(
991
-                        esc_html__(
992
-                            '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.',
993
-                            'event_espresso'
994
-                        ),
995
-                        '<br>',
996
-                        EE_Registry::instance()->CFG->organization->get_pretty('email')
997
-                    )
998
-                ),
999
-                __FILE__,
1000
-                __FUNCTION__,
1001
-                __LINE__
1002
-            );
1003
-        }
1004
-        // switch up header depending on number of available payment methods
1005
-        $payment_method_header     = count($this->checkout->available_payment_methods) > 1
1006
-            ? apply_filters(
1007
-                'FHEE__registration_page_payment_options__method_of_payment_hdr',
1008
-                esc_html__('Please Select Your Method of Payment', 'event_espresso')
1009
-            )
1010
-            : apply_filters(
1011
-                'FHEE__registration_page_payment_options__method_of_payment_hdr',
1012
-                esc_html__('Method of Payment', 'event_espresso')
1013
-            );
1014
-        $available_payment_methods = [
1015
-            // display the "Payment Method" header
1016
-            'payment_method_header' => new EE_Form_Section_HTML(
1017
-                apply_filters(
1018
-                    'FHEE__EE_SPCO_Reg_Step_Payment_Options___setup_payment_options__payment_method_header',
1019
-                    EEH_HTML::h4($payment_method_header, 'method-of-payment-hdr'),
1020
-                    $payment_method_header
1021
-                )
1022
-            ),
1023
-        ];
1024
-        // the list of actual payment methods ( invoice, PayPal, etc ) in a  ( slug => HTML )  format
1025
-        $available_payment_method_options = [];
1026
-        $default_payment_method_option    = [];
1027
-        // additional instructions to be displayed and hidden below payment methods (adding a clearing div to start)
1028
-        $payment_methods_billing_info = [
1029
-            new EE_Form_Section_HTML(
1030
-                EEH_HTML::div('<br />', '', '', 'clear:both;')
1031
-            ),
1032
-        ];
1033
-        // loop through payment methods
1034
-        foreach ($this->checkout->available_payment_methods as $payment_method) {
1035
-            if ($payment_method instanceof EE_Payment_Method) {
1036
-                $payment_method_button = EEH_HTML::img(
1037
-                    $payment_method->button_url(),
1038
-                    $payment_method->name(),
1039
-                    'spco-payment-method-' . $payment_method->slug() . '-btn-img',
1040
-                    'spco-payment-method-btn-img'
1041
-                );
1042
-                // check if any payment methods are set as default
1043
-                // if payment method is already selected OR nothing is selected and this payment method should be
1044
-                // open_by_default
1045
-                if (
1046
-                    ($this->checkout->selected_method_of_payment === $payment_method->slug())
1047
-                    || (! $this->checkout->selected_method_of_payment && $payment_method->open_by_default())
1048
-                ) {
1049
-                    $this->checkout->selected_method_of_payment = $payment_method->slug();
1050
-                    $this->_save_selected_method_of_payment();
1051
-                    $default_payment_method_option[ $payment_method->slug() ] = $payment_method_button;
1052
-                } else {
1053
-                    $available_payment_method_options[ $payment_method->slug() ] = $payment_method_button;
1054
-                }
1055
-                $payment_methods_billing_info[ $payment_method->slug() . '-info' ] =
1056
-                    $this->_payment_method_billing_info(
1057
-                        $payment_method
1058
-                    );
1059
-            }
1060
-        }
1061
-        // prepend available_payment_method_options with default_payment_method_option so that it appears first in list
1062
-        // of PMs
1063
-        $available_payment_method_options = $default_payment_method_option + $available_payment_method_options;
1064
-        // now generate the actual form  inputs
1065
-        $available_payment_methods['available_payment_methods'] = $this->_available_payment_method_inputs(
1066
-            $available_payment_method_options
1067
-        );
1068
-        $available_payment_methods                              += $payment_methods_billing_info;
1069
-        // build the available payment methods form
1070
-        return new EE_Form_Section_Proper(
1071
-            [
1072
-                'html_id'         => 'spco-available-methods-of-payment-dv',
1073
-                'subsections'     => $available_payment_methods,
1074
-                'layout_strategy' => new EE_Div_Per_Section_Layout(),
1075
-            ]
1076
-        );
1077
-    }
1078
-
1079
-
1080
-    /**
1081
-     * _get_available_payment_methods
1082
-     *
1083
-     * @return EE_Payment_Method[]
1084
-     * @throws EE_Error
1085
-     * @throws InvalidArgumentException
1086
-     * @throws InvalidDataTypeException
1087
-     * @throws InvalidInterfaceException
1088
-     */
1089
-    protected function _get_available_payment_methods()
1090
-    {
1091
-        if (! empty($this->checkout->available_payment_methods)) {
1092
-            return $this->checkout->available_payment_methods;
1093
-        }
1094
-        $available_payment_methods = [];
1095
-        $EEM_Payment_Method        = EEM_Payment_Method::instance();
1096
-        // get all active payment methods
1097
-        $payment_methods = $EEM_Payment_Method->get_all_for_transaction(
1098
-            $this->checkout->transaction,
1099
-            EEM_Payment_Method::scope_cart
1100
-        );
1101
-        foreach ($payment_methods as $payment_method) {
1102
-            if ($payment_method instanceof EE_Payment_Method) {
1103
-                $available_payment_methods[ $payment_method->slug() ] = $payment_method;
1104
-            }
1105
-        }
1106
-        return $available_payment_methods;
1107
-    }
1108
-
1109
-
1110
-    /**
1111
-     *    _available_payment_method_inputs
1112
-     *
1113
-     * @access    private
1114
-     * @param array $available_payment_method_options
1115
-     * @return    EE_Form_Section_Proper
1116
-     * @throws EE_Error
1117
-     * @throws EE_Error
1118
-     */
1119
-    private function _available_payment_method_inputs($available_payment_method_options = [])
1120
-    {
1121
-        // generate inputs
1122
-        return new EE_Form_Section_Proper(
1123
-            [
1124
-                'html_id'         => 'ee-available-payment-method-inputs',
1125
-                'layout_strategy' => new EE_Div_Per_Section_Layout(),
1126
-                'subsections'     => [
1127
-                    '' => new EE_Radio_Button_Input(
1128
-                        $available_payment_method_options,
1129
-                        [
1130
-                            'html_name'          => 'selected_method_of_payment',
1131
-                            'html_class'         => 'spco-payment-method',
1132
-                            'default'            => $this->checkout->selected_method_of_payment,
1133
-                            'label_size'         => 11,
1134
-                            'enforce_label_size' => true,
1135
-                        ]
1136
-                    ),
1137
-                ],
1138
-            ]
1139
-        );
1140
-    }
1141
-
1142
-
1143
-    /**
1144
-     *    _payment_method_billing_info
1145
-     *
1146
-     * @access    private
1147
-     * @param EE_Payment_Method $payment_method
1148
-     * @return EE_Form_Section_Proper
1149
-     * @throws EE_Error
1150
-     * @throws InvalidArgumentException
1151
-     * @throws InvalidDataTypeException
1152
-     * @throws InvalidInterfaceException
1153
-     */
1154
-    private function _payment_method_billing_info(EE_Payment_Method $payment_method)
1155
-    {
1156
-        $currently_selected = $this->checkout->selected_method_of_payment === $payment_method->slug();
1157
-        // generate the billing form for payment method
1158
-        $billing_form                 = $currently_selected
1159
-            ? $this->_get_billing_form_for_payment_method($payment_method)
1160
-            : new EE_Form_Section_HTML();
1161
-        $this->checkout->billing_form = $currently_selected
1162
-            ? $billing_form
1163
-            : $this->checkout->billing_form;
1164
-        // it's all in the details
1165
-        $info_html = EEH_HTML::h3(
1166
-            esc_html__('Important information regarding your payment', 'event_espresso'),
1167
-            '',
1168
-            'spco-payment-method-hdr'
1169
-        );
1170
-        // add some info regarding the step, either from what's saved in the admin,
1171
-        // or a default string depending on whether the PM has a billing form or not
1172
-        if ($payment_method->description()) {
1173
-            $payment_method_info = $payment_method->description();
1174
-        } elseif ($billing_form instanceof EE_Billing_Info_Form) {
1175
-            $payment_method_info = sprintf(
1176
-                esc_html__(
1177
-                    'Please provide the following billing information, then click the "%1$s" button below in order to proceed.',
1178
-                    'event_espresso'
1179
-                ),
1180
-                $this->submit_button_text()
1181
-            );
1182
-        } else {
1183
-            $payment_method_info = sprintf(
1184
-                esc_html__('Please click the "%1$s" button below in order to proceed.', 'event_espresso'),
1185
-                $this->submit_button_text()
1186
-            );
1187
-        }
1188
-        $info_html .= EEH_HTML::div(
1189
-            apply_filters(
1190
-                'FHEE__EE_SPCO_Reg_Step_Payment_Options___payment_method_billing_info__payment_method_info',
1191
-                $payment_method_info
1192
-            ),
1193
-            '',
1194
-            'spco-payment-method-desc ee-attention'
1195
-        );
1196
-        return new EE_Form_Section_Proper(
1197
-            [
1198
-                'html_id'         => 'spco-payment-method-info-' . $payment_method->slug(),
1199
-                'html_class'      => 'spco-payment-method-info-dv',
1200
-                // only display the selected or default PM
1201
-                'html_style'      => $currently_selected ? '' : 'display:none;',
1202
-                'layout_strategy' => new EE_Div_Per_Section_Layout(),
1203
-                'subsections'     => [
1204
-                    'info'         => new EE_Form_Section_HTML($info_html),
1205
-                    'billing_form' => $currently_selected ? $billing_form : new EE_Form_Section_HTML(),
1206
-                ],
1207
-            ]
1208
-        );
1209
-    }
1210
-
1211
-
1212
-    /**
1213
-     * get_billing_form_html_for_payment_method
1214
-     *
1215
-     * @return bool
1216
-     * @throws EE_Error
1217
-     * @throws InvalidArgumentException
1218
-     * @throws ReflectionException
1219
-     * @throws InvalidDataTypeException
1220
-     * @throws InvalidInterfaceException
1221
-     */
1222
-    public function get_billing_form_html_for_payment_method()
1223
-    {
1224
-        // how have they chosen to pay?
1225
-        $this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment(true);
1226
-        $this->checkout->payment_method             = $this->_get_payment_method_for_selected_method_of_payment();
1227
-        if (! $this->checkout->payment_method instanceof EE_Payment_Method) {
1228
-            return false;
1229
-        }
1230
-        if (
1231
-            apply_filters(
1232
-                'FHEE__EE_SPCO_Reg_Step_Payment_Options__registration_checkout__selected_payment_method__display_success',
1233
-                false
1234
-            )
1235
-        ) {
1236
-            EE_Error::add_success(
1237
-                apply_filters(
1238
-                    'FHEE__Single_Page_Checkout__registration_checkout__selected_payment_method',
1239
-                    sprintf(
1240
-                        esc_html__(
1241
-                            'You have selected "%s" as your method of payment. Please note the important payment information below.',
1242
-                            'event_espresso'
1243
-                        ),
1244
-                        $this->checkout->payment_method->name()
1245
-                    )
1246
-                )
1247
-            );
1248
-        }
1249
-        // now generate billing form for selected method of payment
1250
-        $payment_method_billing_form = $this->_get_billing_form_for_payment_method($this->checkout->payment_method);
1251
-        // fill form with attendee info if applicable
1252
-        if (
1253
-            $payment_method_billing_form instanceof EE_Billing_Attendee_Info_Form
1254
-            && $this->checkout->transaction_has_primary_registrant()
1255
-        ) {
1256
-            $payment_method_billing_form->populate_from_attendee(
1257
-                $this->checkout->transaction->primary_registration()->attendee()
1258
-            );
1259
-        }
1260
-        // and debug content
1261
-        if (
1262
-            $payment_method_billing_form instanceof EE_Billing_Info_Form
1263
-            && $this->checkout->payment_method->type_obj() instanceof EE_PMT_Base
1264
-        ) {
1265
-            $payment_method_billing_form =
1266
-                $this->checkout->payment_method->type_obj()->apply_billing_form_debug_settings(
1267
-                    $payment_method_billing_form
1268
-                );
1269
-        }
1270
-        $billing_info = $payment_method_billing_form instanceof EE_Form_Section_Proper
1271
-            ? $payment_method_billing_form->get_html()
1272
-            : '';
1273
-        $this->checkout->json_response->set_return_data(['payment_method_info' => $billing_info]);
1274
-        // localize validation rules for main form
1275
-        $this->checkout->current_step->reg_form->localize_validation_rules();
1276
-        $this->checkout->json_response->add_validation_rules(EE_Form_Section_Proper::js_localization());
1277
-        return true;
1278
-    }
1279
-
1280
-
1281
-    /**
1282
-     * _get_billing_form_for_payment_method
1283
-     *
1284
-     * @param EE_Payment_Method $payment_method
1285
-     * @return EE_Billing_Info_Form|EE_Billing_Attendee_Info_Form|EE_Form_Section_HTML
1286
-     * @throws EE_Error
1287
-     * @throws InvalidArgumentException
1288
-     * @throws InvalidDataTypeException
1289
-     * @throws InvalidInterfaceException
1290
-     */
1291
-    private function _get_billing_form_for_payment_method(EE_Payment_Method $payment_method)
1292
-    {
1293
-        $billing_form = $payment_method->type_obj()->billing_form(
1294
-            $this->checkout->transaction,
1295
-            ['amount_owing' => $this->checkout->amount_owing]
1296
-        );
1297
-        if ($billing_form instanceof EE_Billing_Info_Form) {
1298
-            if (
1299
-                apply_filters(
1300
-                    'FHEE__EE_SPCO_Reg_Step_Payment_Options__registration_checkout__selected_payment_method__display_success',
1301
-                    false
1302
-                )
1303
-                && $this->request->requestParamIsSet('payment_method')
1304
-            ) {
1305
-                EE_Error::add_success(
1306
-                    apply_filters(
1307
-                        'FHEE__Single_Page_Checkout__registration_checkout__selected_payment_method',
1308
-                        sprintf(
1309
-                            esc_html__(
1310
-                                'You have selected "%s" as your method of payment. Please note the important payment information below.',
1311
-                                'event_espresso'
1312
-                            ),
1313
-                            $payment_method->name()
1314
-                        )
1315
-                    )
1316
-                );
1317
-            }
1318
-            return apply_filters(
1319
-                'FHEE__EE_SPCO_Reg_Step_Payment_Options___get_billing_form_for_payment_method__billing_form',
1320
-                $billing_form,
1321
-                $payment_method
1322
-            );
1323
-        }
1324
-        // no actual billing form, so return empty HTML form section
1325
-        return new EE_Form_Section_HTML();
1326
-    }
1327
-
1328
-
1329
-    /**
1330
-     * _get_selected_method_of_payment
1331
-     *
1332
-     * @param boolean $required whether to throw an error if the "selected_method_of_payment"
1333
-     *                          is not found in the incoming request
1334
-     * @param string  $request_param
1335
-     * @return NULL|string
1336
-     * @throws EE_Error
1337
-     * @throws InvalidArgumentException
1338
-     * @throws InvalidDataTypeException
1339
-     * @throws InvalidInterfaceException
1340
-     */
1341
-    private function _get_selected_method_of_payment(
1342
-        $required = false,
1343
-        $request_param = 'selected_method_of_payment'
1344
-    ) {
1345
-        // is selected_method_of_payment set in the request ?
1346
-        $selected_method_of_payment = $this->request->getRequestParam($request_param);
1347
-        if ($selected_method_of_payment) {
1348
-            // sanitize it
1349
-            $selected_method_of_payment = is_array($selected_method_of_payment)
1350
-                ? array_shift($selected_method_of_payment)
1351
-                : $selected_method_of_payment;
1352
-            $selected_method_of_payment = sanitize_text_field($selected_method_of_payment);
1353
-            // store it in the session so that it's available for all subsequent requests including AJAX
1354
-            $this->_save_selected_method_of_payment($selected_method_of_payment);
1355
-        } else {
1356
-            // or is it set in the session ?
1357
-            $selected_method_of_payment = EE_Registry::instance()->SSN->get_session_data(
1358
-                'selected_method_of_payment'
1359
-            );
1360
-        }
1361
-        if (empty($selected_method_of_payment) && $required) {
1362
-            EE_Error::add_error(
1363
-                sprintf(
1364
-                    esc_html__(
1365
-                        '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.',
1366
-                        'event_espresso'
1367
-                    ),
1368
-                    '<br/>',
1369
-                    '<br/>',
1370
-                    EE_Registry::instance()->CFG->organization->get_pretty('email')
1371
-                ),
1372
-                __FILE__,
1373
-                __FUNCTION__,
1374
-                __LINE__
1375
-            );
1376
-            return null;
1377
-        }
1378
-        return $selected_method_of_payment;
1379
-    }
1380
-
1381
-
1382
-
1383
-
1384
-
1385
-
1386
-    /********************************************************************************************************/
1387
-    /***********************************  SWITCH PAYMENT METHOD  ************************************/
1388
-    /********************************************************************************************************/
1389
-    /**
1390
-     * switch_payment_method
1391
-     *
1392
-     * @return bool
1393
-     * @throws EE_Error
1394
-     * @throws InvalidArgumentException
1395
-     * @throws InvalidDataTypeException
1396
-     * @throws InvalidInterfaceException
1397
-     * @throws ReflectionException
1398
-     */
1399
-    public function switch_payment_method()
1400
-    {
1401
-        if (! $this->_verify_payment_method_is_set()) {
1402
-            return false;
1403
-        }
1404
-        if (
1405
-            apply_filters(
1406
-                'FHEE__EE_SPCO_Reg_Step_Payment_Options__registration_checkout__selected_payment_method__display_success',
1407
-                false
1408
-            )
1409
-        ) {
1410
-            EE_Error::add_success(
1411
-                apply_filters(
1412
-                    'FHEE__Single_Page_Checkout__registration_checkout__selected_payment_method',
1413
-                    sprintf(
1414
-                        esc_html__(
1415
-                            'You have selected "%s" as your method of payment. Please note the important payment information below.',
1416
-                            'event_espresso'
1417
-                        ),
1418
-                        $this->checkout->payment_method->name()
1419
-                    )
1420
-                )
1421
-            );
1422
-        }
1423
-        // generate billing form for selected method of payment if it hasn't been done already
1424
-        if ($this->checkout->payment_method->type_obj()->has_billing_form()) {
1425
-            $this->checkout->billing_form = $this->_get_billing_form_for_payment_method(
1426
-                $this->checkout->payment_method
1427
-            );
1428
-        }
1429
-        // fill form with attendee info if applicable
1430
-        if (
1431
-            apply_filters(
1432
-                'FHEE__populate_billing_form_fields_from_attendee',
1433
-                (
1434
-                    $this->checkout->billing_form instanceof EE_Billing_Attendee_Info_Form
1435
-                    && $this->checkout->transaction_has_primary_registrant()
1436
-                ),
1437
-                $this->checkout->billing_form,
1438
-                $this->checkout->transaction
1439
-            )
1440
-        ) {
1441
-            $this->checkout->billing_form->populate_from_attendee(
1442
-                $this->checkout->transaction->primary_registration()->attendee()
1443
-            );
1444
-        }
1445
-        // and debug content
1446
-        if (
1447
-            $this->checkout->billing_form instanceof EE_Billing_Info_Form
1448
-            && $this->checkout->payment_method->type_obj() instanceof EE_PMT_Base
1449
-        ) {
1450
-            $this->checkout->billing_form =
1451
-                $this->checkout->payment_method->type_obj()->apply_billing_form_debug_settings(
1452
-                    $this->checkout->billing_form
1453
-                );
1454
-        }
1455
-        // get html and validation rules for form
1456
-        if ($this->checkout->billing_form instanceof EE_Form_Section_Proper) {
1457
-            $this->checkout->json_response->set_return_data(
1458
-                ['payment_method_info' => $this->checkout->billing_form->get_html()]
1459
-            );
1460
-            // localize validation rules for main form
1461
-            $this->checkout->billing_form->localize_validation_rules(true);
1462
-            $this->checkout->json_response->add_validation_rules(EE_Form_Section_Proper::js_localization());
1463
-        } else {
1464
-            $this->checkout->json_response->set_return_data(['payment_method_info' => '']);
1465
-        }
1466
-        // prevents advancement to next step
1467
-        $this->checkout->continue_reg = false;
1468
-        return true;
1469
-    }
1470
-
1471
-
1472
-    /**
1473
-     * _verify_payment_method_is_set
1474
-     *
1475
-     * @return bool
1476
-     * @throws EE_Error
1477
-     * @throws InvalidArgumentException
1478
-     * @throws ReflectionException
1479
-     * @throws InvalidDataTypeException
1480
-     * @throws InvalidInterfaceException
1481
-     */
1482
-    protected function _verify_payment_method_is_set()
1483
-    {
1484
-        // generate billing form for selected method of payment if it hasn't been done already
1485
-        if (empty($this->checkout->selected_method_of_payment)) {
1486
-            // how have they chosen to pay?
1487
-            $this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment(true);
1488
-        } else {
1489
-            // choose your own adventure based on method_of_payment
1490
-            switch ($this->checkout->selected_method_of_payment) {
1491
-                case 'events_sold_out':
1492
-                    EE_Error::add_attention(
1493
-                        apply_filters(
1494
-                            'FHEE__EE_SPCO_Reg_Step_Payment_Options___verify_payment_method_is_set__sold_out_events_msg',
1495
-                            esc_html__(
1496
-                                '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.',
1497
-                                'event_espresso'
1498
-                            )
1499
-                        ),
1500
-                        __FILE__,
1501
-                        __FUNCTION__,
1502
-                        __LINE__
1503
-                    );
1504
-                    return false;
1505
-                case 'payments_closed':
1506
-                    EE_Error::add_attention(
1507
-                        apply_filters(
1508
-                            'FHEE__EE_SPCO_Reg_Step_Payment_Options___verify_payment_method_is_set__payments_closed_msg',
1509
-                            esc_html__(
1510
-                                '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.',
1511
-                                'event_espresso'
1512
-                            )
1513
-                        ),
1514
-                        __FILE__,
1515
-                        __FUNCTION__,
1516
-                        __LINE__
1517
-                    );
1518
-                    return false;
1519
-                case 'no_payment_required':
1520
-                    EE_Error::add_attention(
1521
-                        apply_filters(
1522
-                            'FHEE__EE_SPCO_Reg_Step_Payment_Options___verify_payment_method_is_set__no_payment_required_msg',
1523
-                            esc_html__(
1524
-                                '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.',
1525
-                                'event_espresso'
1526
-                            )
1527
-                        ),
1528
-                        __FILE__,
1529
-                        __FUNCTION__,
1530
-                        __LINE__
1531
-                    );
1532
-                    return false;
1533
-                default:
1534
-            }
1535
-        }
1536
-        // verify payment method
1537
-        if (! $this->checkout->payment_method instanceof EE_Payment_Method) {
1538
-            // get payment method for selected method of payment
1539
-            $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment();
1540
-        }
1541
-        return $this->checkout->payment_method instanceof EE_Payment_Method;
1542
-    }
1543
-
1544
-
1545
-
1546
-    /********************************************************************************************************/
1547
-    /***************************************  SAVE PAYER DETAILS  ****************************************/
1548
-    /********************************************************************************************************/
1549
-    /**
1550
-     * save_payer_details_via_ajax
1551
-     *
1552
-     * @return void
1553
-     * @throws EE_Error
1554
-     * @throws InvalidArgumentException
1555
-     * @throws ReflectionException
1556
-     * @throws RuntimeException
1557
-     * @throws InvalidDataTypeException
1558
-     * @throws InvalidInterfaceException
1559
-     */
1560
-    public function save_payer_details_via_ajax()
1561
-    {
1562
-        if (! $this->_verify_payment_method_is_set()) {
1563
-            return;
1564
-        }
1565
-        // generate billing form for selected method of payment if it hasn't been done already
1566
-        if ($this->checkout->payment_method->type_obj()->has_billing_form()) {
1567
-            $this->checkout->billing_form = $this->_get_billing_form_for_payment_method(
1568
-                $this->checkout->payment_method
1569
-            );
1570
-        }
1571
-        // generate primary attendee from payer info if applicable
1572
-        if (! $this->checkout->transaction_has_primary_registrant()) {
1573
-            $attendee = $this->_create_attendee_from_request_data();
1574
-            if ($attendee instanceof EE_Attendee) {
1575
-                foreach ($this->checkout->transaction->registrations() as $registration) {
1576
-                    if ($registration->is_primary_registrant()) {
1577
-                        $this->checkout->primary_attendee_obj = $attendee;
1578
-                        $registration->_add_relation_to($attendee, 'Attendee');
1579
-                        $registration->set_attendee_id($attendee->ID());
1580
-                        $registration->update_cache_after_object_save('Attendee', $attendee);
1581
-                    }
1582
-                }
1583
-            }
1584
-        }
1585
-    }
1586
-
1587
-
1588
-    /**
1589
-     * create_attendee_from_request_data
1590
-     * uses info from alternate GET or POST data (such as AJAX) to create a new attendee
1591
-     *
1592
-     * @return EE_Attendee
1593
-     * @throws EE_Error
1594
-     * @throws InvalidArgumentException
1595
-     * @throws ReflectionException
1596
-     * @throws InvalidDataTypeException
1597
-     * @throws InvalidInterfaceException
1598
-     */
1599
-    protected function _create_attendee_from_request_data()
1600
-    {
1601
-        // get State ID
1602
-        $STA_ID = $this->request->getRequestParam('state');
1603
-        if (! empty($STA_ID)) {
1604
-            // can we get state object from name ?
1605
-            EE_Registry::instance()->load_model('State');
1606
-            $state  = EEM_State::instance()->get_col([['STA_name' => $STA_ID], 'limit' => 1], 'STA_ID');
1607
-            $STA_ID = is_array($state) && ! empty($state) ? reset($state) : $STA_ID;
1608
-        }
1609
-        // get Country ISO
1610
-        $CNT_ISO = $this->request->getRequestParam('country');
1611
-        if (! empty($CNT_ISO)) {
1612
-            // can we get country object from name ?
1613
-            EE_Registry::instance()->load_model('Country');
1614
-            $country = EEM_Country::instance()->get_col(
1615
-                [['CNT_name' => $CNT_ISO], 'limit' => 1],
1616
-                'CNT_ISO'
1617
-            );
1618
-            $CNT_ISO = is_array($country) && ! empty($country) ? reset($country) : $CNT_ISO;
1619
-        }
1620
-        // grab attendee data
1621
-        $attendee_data = [
1622
-            'ATT_fname'    => $this->request->getRequestParam('first_name'),
1623
-            'ATT_lname'    => $this->request->getRequestParam('last_name'),
1624
-            'ATT_email'    => $this->request->getRequestParam('email'),
1625
-            'ATT_address'  => $this->request->getRequestParam('address'),
1626
-            'ATT_address2' => $this->request->getRequestParam('address2'),
1627
-            'ATT_city'     => $this->request->getRequestParam('city'),
1628
-            'STA_ID'       => $STA_ID,
1629
-            'CNT_ISO'      => $CNT_ISO,
1630
-            'ATT_zip'      => $this->request->getRequestParam('zip'),
1631
-            'ATT_phone'    => $this->request->getRequestParam('phone'),
1632
-        ];
1633
-        // validate the email address since it is the most important piece of info
1634
-        if (empty($attendee_data['ATT_email'])) {
1635
-            EE_Error::add_error(
1636
-                esc_html__('An invalid email address was submitted.', 'event_espresso'),
1637
-                __FILE__,
1638
-                __FUNCTION__,
1639
-                __LINE__
1640
-            );
1641
-        }
1642
-        // does this attendee already exist in the db ? we're searching using a combination of first name, last name,
1643
-        // AND email address
1644
-        if (
1645
-            ! empty($attendee_data['ATT_fname'])
1646
-            && ! empty($attendee_data['ATT_lname'])
1647
-            && ! empty($attendee_data['ATT_email'])
1648
-        ) {
1649
-            $existing_attendee = EEM_Attendee::instance()->find_existing_attendee(
1650
-                [
1651
-                    'ATT_fname' => $attendee_data['ATT_fname'],
1652
-                    'ATT_lname' => $attendee_data['ATT_lname'],
1653
-                    'ATT_email' => $attendee_data['ATT_email'],
1654
-                ]
1655
-            );
1656
-            if ($existing_attendee instanceof EE_Attendee) {
1657
-                return $existing_attendee;
1658
-            }
1659
-        }
1660
-        // no existing attendee? kk let's create a new one
1661
-        // kinda lame, but we need a first and last name to create an attendee, so use the email address if those
1662
-        // don't exist
1663
-        $attendee_data['ATT_fname'] = ! empty($attendee_data['ATT_fname'])
1664
-            ? $attendee_data['ATT_fname']
1665
-            : $attendee_data['ATT_email'];
1666
-        $attendee_data['ATT_lname'] = ! empty($attendee_data['ATT_lname'])
1667
-            ? $attendee_data['ATT_lname']
1668
-            : $attendee_data['ATT_email'];
1669
-        return EE_Attendee::new_instance($attendee_data);
1670
-    }
1671
-
1672
-
1673
-
1674
-    /********************************************************************************************************/
1675
-    /****************************************  PROCESS REG STEP  *****************************************/
1676
-    /********************************************************************************************************/
1677
-    /**
1678
-     * process_reg_step
1679
-     *
1680
-     * @return bool
1681
-     * @throws EE_Error
1682
-     * @throws InvalidArgumentException
1683
-     * @throws ReflectionException
1684
-     * @throws EntityNotFoundException
1685
-     * @throws InvalidDataTypeException
1686
-     * @throws InvalidInterfaceException
1687
-     * @throws InvalidStatusException
1688
-     */
1689
-    public function process_reg_step()
1690
-    {
1691
-        // how have they chosen to pay?
1692
-        $this->checkout->selected_method_of_payment = $this->checkout->transaction->is_free()
1693
-            ? 'no_payment_required'
1694
-            : $this->_get_selected_method_of_payment(true);
1695
-        // choose your own adventure based on method_of_payment
1696
-        switch ($this->checkout->selected_method_of_payment) {
1697
-            case 'events_sold_out':
1698
-                $this->checkout->redirect     = true;
1699
-                $this->checkout->redirect_url = $this->checkout->cancel_page_url;
1700
-                $this->checkout->json_response->set_redirect_url($this->checkout->redirect_url);
1701
-                // mark this reg step as completed
1702
-                $this->set_completed();
1703
-                return false;
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
-
1723
-            case 'no_payment_required':
1724
-                if (
1725
-                    apply_filters(
1726
-                        'FHEE__EE_SPCO_Reg_Step_Payment_Options__process_reg_step__no_payment_required__display_success',
1727
-                        false
1728
-                    )
1729
-                ) {
1730
-                    EE_Error::add_success(
1731
-                        esc_html__('no payment required.', 'event_espresso'),
1732
-                        __FILE__,
1733
-                        __FUNCTION__,
1734
-                        __LINE__
1735
-                    );
1736
-                }
1737
-                // mark this reg step as completed
1738
-                $this->set_completed();
1739
-                return true;
1740
-
1741
-            default:
1742
-                $registrations         = EE_Registry::instance()->SSN->checkout()->transaction->registrations(
1743
-                    EE_Registry::instance()->SSN->checkout()->reg_cache_where_params
1744
-                );
1745
-                $ejected_registrations = EE_SPCO_Reg_Step_Payment_Options::find_registrations_that_lost_their_space(
1746
-                    $registrations,
1747
-                    EE_Registry::instance()->SSN->checkout()->revisit
1748
-                );
1749
-                // calculate difference between the two arrays
1750
-                $registrations = array_diff($registrations, $ejected_registrations);
1751
-                if (empty($registrations)) {
1752
-                    $this->_redirect_because_event_sold_out();
1753
-                    return false;
1754
-                }
1755
-                $payment = $this->_process_payment();
1756
-                if ($payment instanceof EE_Payment) {
1757
-                    $this->checkout->continue_reg = true;
1758
-                    $this->_maybe_set_completed($payment);
1759
-                } else {
1760
-                    $this->checkout->continue_reg = false;
1761
-                }
1762
-                return $payment instanceof EE_Payment;
1763
-        }
1764
-    }
1765
-
1766
-
1767
-    /**
1768
-     * _redirect_because_event_sold_out
1769
-     *
1770
-     * @return void
1771
-     */
1772
-    protected function _redirect_because_event_sold_out()
1773
-    {
1774
-        $this->checkout->continue_reg = false;
1775
-        // set redirect URL
1776
-        $this->checkout->redirect_url = add_query_arg(
1777
-            ['e_reg_url_link' => $this->checkout->reg_url_link],
1778
-            $this->checkout->current_step->reg_step_url()
1779
-        );
1780
-        $this->checkout->json_response->set_redirect_url($this->checkout->redirect_url);
1781
-    }
1782
-
1783
-
1784
-    /**
1785
-     * @param EE_Payment $payment
1786
-     * @return void
1787
-     * @throws EE_Error
1788
-     */
1789
-    protected function _maybe_set_completed(EE_Payment $payment)
1790
-    {
1791
-        // Do we need to redirect them? If so, there's more work to be done.
1792
-        if (! $payment->redirect_url()) {
1793
-            $this->set_completed();
1794
-        }
1795
-    }
1796
-
1797
-
1798
-    /**
1799
-     *    update_reg_step
1800
-     *    this is the final step after a user  revisits the site to retry a payment
1801
-     *
1802
-     * @return bool
1803
-     * @throws EE_Error
1804
-     * @throws InvalidArgumentException
1805
-     * @throws ReflectionException
1806
-     * @throws EntityNotFoundException
1807
-     * @throws InvalidDataTypeException
1808
-     * @throws InvalidInterfaceException
1809
-     * @throws InvalidStatusException
1810
-     */
1811
-    public function update_reg_step()
1812
-    {
1813
-        $success = true;
1814
-        // if payment required
1815
-        if ($this->checkout->transaction->total() > 0) {
1816
-            do_action(
1817
-                'AHEE__EE_Single_Page_Checkout__process_finalize_registration__before_gateway',
1818
-                $this->checkout->transaction
1819
-            );
1820
-            // attempt payment via payment method
1821
-            $success = $this->process_reg_step();
1822
-        }
1823
-        if ($success && ! $this->checkout->redirect) {
1824
-            $this->checkout->cart->get_grand_total()->save_this_and_descendants_to_txn(
1825
-                $this->checkout->transaction->ID()
1826
-            );
1827
-            // set return URL
1828
-            $this->checkout->redirect_url = add_query_arg(
1829
-                ['e_reg_url_link' => $this->checkout->reg_url_link],
1830
-                $this->checkout->thank_you_page_url
1831
-            );
1832
-        }
1833
-        return $success;
1834
-    }
1835
-
1836
-
1837
-    /**
1838
-     * @return EE_Payment|null
1839
-     * @throws EE_Error
1840
-     * @throws InvalidArgumentException
1841
-     * @throws ReflectionException
1842
-     * @throws RuntimeException
1843
-     * @throws InvalidDataTypeException
1844
-     * @throws InvalidInterfaceException
1845
-     */
1846
-    private function _process_payment()
1847
-    {
1848
-        // basically confirm that the event hasn't sold out since they hit the page
1849
-        if (! $this->_last_second_ticket_verifications()) {
1850
-            return null;
1851
-        }
1852
-        // ya gotta make a choice man
1853
-        if (empty($this->checkout->selected_method_of_payment)) {
1854
-            $this->checkout->json_response->set_plz_select_method_of_payment(
1855
-                esc_html__('Please select a method of payment before proceeding.', 'event_espresso')
1856
-            );
1857
-            return null;
1858
-        }
1859
-        // get EE_Payment_Method object
1860
-        if (! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()) {
1861
-            return null;
1862
-        }
1863
-        // setup billing form
1864
-        if ($this->checkout->payment_method->type_obj()->has_billing_form()) {
1865
-            $this->checkout->billing_form = $this->_get_billing_form_for_payment_method(
1866
-                $this->checkout->payment_method
1867
-            );
1868
-            // bad billing form ?
1869
-            if (! $this->_billing_form_is_valid()) {
1870
-                return null;
1871
-            }
1872
-        }
1873
-        // ensure primary registrant has been fully processed
1874
-        if (! $this->_setup_primary_registrant_prior_to_payment()) {
1875
-            return null;
1876
-        }
1877
-        // if session is close to expiring (under 10 minutes by default)
1878
-        if ((time() - EE_Registry::instance()->SSN->expiration()) < EE_Registry::instance()->SSN->extension()) {
1879
-            // add some time to session expiration so that payment can be completed
1880
-            EE_Registry::instance()->SSN->extend_expiration();
1881
-        }
1882
-        /** @type EE_Transaction_Processor $transaction_processor */
1883
-        // $transaction_processor = EE_Registry::instance()->load_class( 'Transaction_Processor' );
1884
-        // in case a registrant leaves to an Off-Site Gateway and never returns, we want to approve any registrations
1885
-        // for events with a default reg status of Approved
1886
-        // $transaction_processor->toggle_registration_statuses_for_default_approved_events(
1887
-        //      $this->checkout->transaction, $this->checkout->reg_cache_where_params
1888
-        // );
1889
-        // attempt payment
1890
-        $payment = $this->_attempt_payment($this->checkout->payment_method);
1891
-        // process results
1892
-        $payment = $this->_validate_payment($payment);
1893
-        $payment = $this->_post_payment_processing($payment);
1894
-        // verify payment
1895
-        if ($payment instanceof EE_Payment) {
1896
-            // store that for later
1897
-            $this->checkout->payment = $payment;
1898
-            // we can also consider the TXN to not have been failed, so temporarily upgrade its status to abandoned
1899
-            $this->checkout->transaction->toggle_failed_transaction_status();
1900
-            $payment_status = $payment->status();
1901
-            if (
1902
-                $payment_status === EEM_Payment::status_id_approved
1903
-                || $payment_status === EEM_Payment::status_id_pending
1904
-            ) {
1905
-                return $payment;
1906
-            }
1907
-            return null;
1908
-        }
1909
-        if ($payment === true) {
1910
-            // please note that offline payment methods will NOT make a payment,
1911
-            // but instead just mark themselves as the PMD_ID on the transaction, and return true
1912
-            $this->checkout->payment = $payment;
1913
-            return $payment;
1914
-        }
1915
-        // where's my money?
1916
-        return null;
1917
-    }
1918
-
1919
-
1920
-    /**
1921
-     * _last_second_ticket_verifications
1922
-     *
1923
-     * @return bool
1924
-     * @throws EE_Error
1925
-     * @throws ReflectionException
1926
-     */
1927
-    protected function _last_second_ticket_verifications()
1928
-    {
1929
-        // don't bother re-validating if not a return visit
1930
-        if (! $this->checkout->revisit) {
1931
-            return true;
1932
-        }
1933
-        $registrations = $this->checkout->transaction->registrations();
1934
-        if (empty($registrations)) {
1935
-            return false;
1936
-        }
1937
-        foreach ($registrations as $registration) {
1938
-            if ($registration instanceof EE_Registration && ! $registration->is_approved()) {
1939
-                $event = $registration->event_obj();
1940
-                if ($event instanceof EE_Event && $event->is_sold_out(true)) {
1941
-                    EE_Error::add_error(
1942
-                        apply_filters(
1943
-                            'FHEE__EE_SPCO_Reg_Step_Payment_Options___last_second_ticket_verifications__sold_out_events_msg',
1944
-                            sprintf(
1945
-                                esc_html__(
1946
-                                    '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.',
1947
-                                    'event_espresso'
1948
-                                ),
1949
-                                $event->name()
1950
-                            )
1951
-                        ),
1952
-                        __FILE__,
1953
-                        __FUNCTION__,
1954
-                        __LINE__
1955
-                    );
1956
-                    return false;
1957
-                }
1958
-            }
1959
-        }
1960
-        return true;
1961
-    }
1962
-
1963
-
1964
-    /**
1965
-     * redirect_form
1966
-     *
1967
-     * @return bool
1968
-     * @throws EE_Error
1969
-     * @throws InvalidArgumentException
1970
-     * @throws ReflectionException
1971
-     * @throws InvalidDataTypeException
1972
-     * @throws InvalidInterfaceException
1973
-     */
1974
-    public function redirect_form()
1975
-    {
1976
-        $payment_method_billing_info = $this->_payment_method_billing_info(
1977
-            $this->_get_payment_method_for_selected_method_of_payment()
1978
-        );
1979
-        $html                        = $payment_method_billing_info->get_html();
1980
-        $html                        .= $this->checkout->redirect_form;
1981
-        /** @var ResponseInterface $response */
1982
-        $response = LoaderFactory::getLoader()->getShared(ResponseInterface::class);
1983
-        $response->addOutput($html);
1984
-        return true;
1985
-    }
1986
-
1987
-
1988
-    /**
1989
-     * _billing_form_is_valid
1990
-     *
1991
-     * @return bool
1992
-     * @throws EE_Error
1993
-     */
1994
-    private function _billing_form_is_valid()
1995
-    {
1996
-        if (! $this->checkout->payment_method->type_obj()->has_billing_form()) {
1997
-            return true;
1998
-        }
1999
-        if ($this->checkout->billing_form instanceof EE_Billing_Info_Form) {
2000
-            if ($this->checkout->billing_form->was_submitted()) {
2001
-                $this->checkout->billing_form->receive_form_submission();
2002
-                if ($this->checkout->billing_form->is_valid()) {
2003
-                    return true;
2004
-                }
2005
-                $validation_errors = $this->checkout->billing_form->get_validation_errors_accumulated();
2006
-                $error_strings     = [];
2007
-                foreach ($validation_errors as $validation_error) {
2008
-                    if ($validation_error instanceof EE_Validation_Error) {
2009
-                        $form_section = $validation_error->get_form_section();
2010
-                        if ($form_section instanceof EE_Form_Input_Base) {
2011
-                            $label = $form_section->html_label_text();
2012
-                        } elseif ($form_section instanceof EE_Form_Section_Base) {
2013
-                            $label = $form_section->name();
2014
-                        } else {
2015
-                            $label = esc_html__('Validation Error', 'event_espresso');
2016
-                        }
2017
-                        $error_strings[] = sprintf('%1$s: %2$s', $label, $validation_error->getMessage());
2018
-                    }
2019
-                }
2020
-                EE_Error::add_error(
2021
-                    sprintf(
2022
-                        esc_html__(
2023
-                            'One or more billing form inputs are invalid and require correction before proceeding. %1$s %2$s',
2024
-                            'event_espresso'
2025
-                        ),
2026
-                        '<br/>',
2027
-                        implode('<br/>', $error_strings)
2028
-                    ),
2029
-                    __FILE__,
2030
-                    __FUNCTION__,
2031
-                    __LINE__
2032
-                );
2033
-            } else {
2034
-                EE_Error::add_error(
2035
-                    esc_html__(
2036
-                        'The billing form was not submitted or something prevented it\'s submission.',
2037
-                        'event_espresso'
2038
-                    ),
2039
-                    __FILE__,
2040
-                    __FUNCTION__,
2041
-                    __LINE__
2042
-                );
2043
-            }
2044
-        } else {
2045
-            EE_Error::add_error(
2046
-                esc_html__(
2047
-                    'The submitted billing form is invalid possibly due to a technical reason.',
2048
-                    'event_espresso'
2049
-                ),
2050
-                __FILE__,
2051
-                __FUNCTION__,
2052
-                __LINE__
2053
-            );
2054
-        }
2055
-        return false;
2056
-    }
2057
-
2058
-
2059
-    /**
2060
-     * _setup_primary_registrant_prior_to_payment
2061
-     * ensures that the primary registrant has a valid attendee object created with the critical details populated
2062
-     * (first & last name & email) and that both the transaction object and primary registration object have been saved
2063
-     * plz note that any other registrations will NOT be saved at this point (because they may not have any details
2064
-     * yet)
2065
-     *
2066
-     * @return bool
2067
-     * @throws EE_Error
2068
-     * @throws InvalidArgumentException
2069
-     * @throws ReflectionException
2070
-     * @throws RuntimeException
2071
-     * @throws InvalidDataTypeException
2072
-     * @throws InvalidInterfaceException
2073
-     */
2074
-    private function _setup_primary_registrant_prior_to_payment()
2075
-    {
2076
-        // check if transaction has a primary registrant and that it has a related Attendee object
2077
-        // if not, then we need to at least gather some primary registrant data before attempting payment
2078
-        if (
2079
-            $this->checkout->billing_form instanceof EE_Billing_Attendee_Info_Form
2080
-            && ! $this->checkout->transaction_has_primary_registrant()
2081
-            && ! $this->_capture_primary_registration_data_from_billing_form()
2082
-        ) {
2083
-            return false;
2084
-        }
2085
-        // because saving an object clears its cache, we need to do the Chevy Shuffle
2086
-        // grab the primary_registration object
2087
-        $primary_registration = $this->checkout->transaction->primary_registration();
2088
-        // at this point we'll consider a TXN to not have been failed
2089
-        $this->checkout->transaction->toggle_failed_transaction_status();
2090
-        // save the TXN ( which clears cached copy of primary_registration)
2091
-        $this->checkout->transaction->save();
2092
-        // grab TXN ID and save it to the primary_registration
2093
-        $primary_registration->set_transaction_id($this->checkout->transaction->ID());
2094
-        // save what we have so far
2095
-        $primary_registration->save();
2096
-        return true;
2097
-    }
2098
-
2099
-
2100
-    /**
2101
-     * Captures primary registration data from the billing form.
2102
-     *
2103
-     * This method is used to gather the primary registrant data before attempting payment.
2104
-     * It checks if the billing form is an instance of EE_Billing_Attendee_Info_Form and if the transaction
2105
-     * has a primary registrant. If not, it captures the primary registrant data from the billing form.
2106
-     *
2107
-     * @return bool
2108
-     * @throws EE_Error
2109
-     * @throws InvalidArgumentException
2110
-     * @throws ReflectionException
2111
-     * @throws InvalidDataTypeException
2112
-     * @throws InvalidInterfaceException
2113
-     */
2114
-    private function _capture_primary_registration_data_from_billing_form(): bool
2115
-    {
2116
-        $primary_registration = $this->checkout->transaction->primary_registration();
2117
-        if (! $this->validatePrimaryRegistration($primary_registration)) {
2118
-            return false;
2119
-        }
2120
-
2121
-        $primary_attendee = $this->getPrimaryAttendee($primary_registration);
2122
-        if (! $this->validatePrimaryAttendee($primary_attendee)) {
2123
-            return false;
2124
-        }
2125
-
2126
-        if (! $this->addAttendeeToPrimaryRegistration($primary_attendee, $primary_registration)) {
2127
-            return false;
2128
-        }
2129
-        // both the primary registration and primary attendee objects should be valid entities at this point
2130
-        $this->checkout->primary_attendee_obj = $primary_attendee;
2131
-
2132
-        /** @type EE_Registration_Processor $registration_processor */
2133
-        $registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
2134
-        // at this point, we should have enough details about the registrant to consider the registration NOT incomplete
2135
-        $registration_processor->toggle_incomplete_registration_status_to_default(
2136
-            $primary_registration,
2137
-            false,
2138
-            new Context(
2139
-                __METHOD__,
2140
-                esc_html__(
2141
-                    'Executed when the primary registrant\'s status is updated during the registration process when processing a billing form.',
2142
-                    'event_espresso'
2143
-                )
2144
-            )
2145
-        );
2146
-        return true;
2147
-    }
2148
-
2149
-
2150
-    /**
2151
-     * returns true if the primary registration is a valid entity
2152
-     *
2153
-     * @param $primary_registration
2154
-     * @return bool
2155
-     * @throws EE_Error
2156
-     * @since 5.0.21.p
2157
-     */
2158
-    private function validatePrimaryRegistration($primary_registration): bool
2159
-    {
2160
-        if ($primary_registration instanceof EE_Registration) {
2161
-            return true;
2162
-        }
2163
-        EE_Error::add_error(
2164
-            sprintf(
2165
-                esc_html__(
2166
-                    'The primary registrant for this transaction could not be determined due to a technical issue.%sPlease try again or contact %s for assistance.',
2167
-                    'event_espresso'
2168
-                ),
2169
-                '<br/>',
2170
-                EE_Registry::instance()->CFG->organization->get_pretty('email')
2171
-            ),
2172
-            __FILE__,
2173
-            __FUNCTION__,
2174
-            __LINE__
2175
-        );
2176
-        return false;
2177
-    }
2178
-
2179
-
2180
-    /**
2181
-     * retrieves the primary attendee object for the primary registration and copies the billing form data to it.
2182
-     * if the primary registration does not have an attendee object, then one is created from the billing form info
2183
-     *
2184
-     * @param EE_Registration $primary_registration
2185
-     * @return EE_Attendee|null
2186
-     * @throws EE_Error
2187
-     * @throws ReflectionException
2188
-     * @since 5.0.21.p
2189
-     */
2190
-    private function getPrimaryAttendee(EE_Registration $primary_registration): ?EE_Attendee
2191
-    {
2192
-        // if we have a primary registration, then we should have a primary attendee
2193
-        $attendee = $primary_registration->attendee();
2194
-        if ($attendee instanceof EE_Attendee) {
2195
-            return $this->checkout->billing_form->copy_billing_form_data_to_attendee($attendee);
2196
-        }
2197
-        // if not, then we need to create one from the billing form
2198
-        return $this->checkout->billing_form->create_attendee_from_billing_form_data();
2199
-    }
2200
-
2201
-
2202
-    /**
2203
-     * returns true if the primary attendee is a valid entity
2204
-     *
2205
-     * @param $primary_attendee
2206
-     * @return bool
2207
-     * @throws EE_Error
2208
-     * @since 5.0.21.p
2209
-     */
2210
-    private function validatePrimaryAttendee($primary_attendee): bool
2211
-    {
2212
-        if ($primary_attendee instanceof EE_Attendee) {
2213
-            return true;
2214
-        }
2215
-        EE_Error::add_error(
2216
-            sprintf(
2217
-                esc_html__(
2218
-                    'The billing form details could not be used for attendee details due to a technical issue.%sPlease try again or contact %s for assistance.',
2219
-                    'event_espresso'
2220
-                ),
2221
-                '<br/>',
2222
-                EE_Registry::instance()->CFG->organization->get_pretty('email')
2223
-            ),
2224
-            __FILE__,
2225
-            __FUNCTION__,
2226
-            __LINE__
2227
-        );
2228
-        return false;
2229
-    }
2230
-
2231
-
2232
-    /**
2233
-     * returns true if the attendee was successfully added to the primary registration
2234
-     *
2235
-     * @param EE_Attendee     $primary_attendee
2236
-     * @param EE_Registration $primary_registration
2237
-     * @return bool
2238
-     * @throws EE_Error
2239
-     * @throws ReflectionException
2240
-     * @since 5.0.21.p
2241
-     */
2242
-    private function addAttendeeToPrimaryRegistration(
2243
-        EE_Attendee $primary_attendee,
2244
-        EE_Registration $primary_registration
2245
-    ): bool {
2246
-        // ensure attendee has an ID by saving
2247
-        $primary_attendee->save();
2248
-
2249
-        // compare attendee IDs
2250
-        if ($primary_registration->attendee_id() === $primary_attendee->ID()) {
2251
-            return true;
2252
-        }
2253
-
2254
-        $primary_attendee = $primary_registration->_add_relation_to($primary_attendee, 'Attendee');
2255
-        if ($primary_attendee instanceof EE_Attendee) {
2256
-            return true;
2257
-        }
2258
-
2259
-        EE_Error::add_error(
2260
-            sprintf(
2261
-                esc_html__(
2262
-                    'The primary registrant could not be associated with this transaction due to a technical issue.%sPlease try again or contact %s for assistance.',
2263
-                    'event_espresso'
2264
-                ),
2265
-                '<br/>',
2266
-                EE_Registry::instance()->CFG->organization->get_pretty('email')
2267
-            ),
2268
-            __FILE__,
2269
-            __FUNCTION__,
2270
-            __LINE__
2271
-        );
2272
-        return false;
2273
-    }
2274
-
2275
-
2276
-    /**
2277
-     * _get_payment_method_for_selected_method_of_payment
2278
-     * retrieves a valid payment method
2279
-     *
2280
-     * @return EE_Payment_Method
2281
-     * @throws EE_Error
2282
-     * @throws InvalidArgumentException
2283
-     * @throws ReflectionException
2284
-     * @throws InvalidDataTypeException
2285
-     * @throws InvalidInterfaceException
2286
-     */
2287
-    private function _get_payment_method_for_selected_method_of_payment()
2288
-    {
2289
-        if ($this->checkout->selected_method_of_payment === 'events_sold_out') {
2290
-            $this->_redirect_because_event_sold_out();
2291
-            return null;
2292
-        }
2293
-        // get EE_Payment_Method object
2294
-        if (isset($this->checkout->available_payment_methods[ $this->checkout->selected_method_of_payment ])) {
2295
-            $payment_method = $this->checkout->available_payment_methods[ $this->checkout->selected_method_of_payment ];
2296
-        } else {
2297
-            // load EEM_Payment_Method
2298
-            EE_Registry::instance()->load_model('Payment_Method');
2299
-            $EEM_Payment_Method = EEM_Payment_Method::instance();
2300
-            $payment_method     = $EEM_Payment_Method->get_one_by_slug($this->checkout->selected_method_of_payment);
2301
-        }
2302
-        // verify $payment_method
2303
-        if (! $payment_method instanceof EE_Payment_Method) {
2304
-            // not a payment
2305
-            EE_Error::add_error(
2306
-                sprintf(
2307
-                    esc_html__(
2308
-                        'The selected method of payment could not be determined due to a technical issue.%sPlease try again or contact %s for assistance.',
2309
-                        'event_espresso'
2310
-                    ),
2311
-                    '<br/>',
2312
-                    EE_Registry::instance()->CFG->organization->get_pretty('email')
2313
-                ),
2314
-                __FILE__,
2315
-                __FUNCTION__,
2316
-                __LINE__
2317
-            );
2318
-            return null;
2319
-        }
2320
-        // and verify it has a valid Payment_Method Type object
2321
-        if (! $payment_method->type_obj() instanceof EE_PMT_Base) {
2322
-            // not a payment
2323
-            EE_Error::add_error(
2324
-                sprintf(
2325
-                    esc_html__(
2326
-                        'A valid payment method could not be determined due to a technical issue.%sPlease try again or contact %s for assistance.',
2327
-                        'event_espresso'
2328
-                    ),
2329
-                    '<br/>',
2330
-                    EE_Registry::instance()->CFG->organization->get_pretty('email')
2331
-                ),
2332
-                __FILE__,
2333
-                __FUNCTION__,
2334
-                __LINE__
2335
-            );
2336
-            return null;
2337
-        }
2338
-        return $payment_method;
2339
-    }
2340
-
2341
-
2342
-    /**
2343
-     *    _attempt_payment
2344
-     *
2345
-     * @access    private
2346
-     * @type    EE_Payment_Method $payment_method
2347
-     * @return EE_Payment|null
2348
-     * @throws EE_Error
2349
-     * @throws InvalidArgumentException
2350
-     * @throws ReflectionException
2351
-     * @throws InvalidDataTypeException
2352
-     * @throws InvalidInterfaceException
2353
-     */
2354
-    private function _attempt_payment(EE_Payment_Method $payment_method): ?EE_Payment
2355
-    {
2356
-        $this->checkout->transaction->save();
2357
-        /** @var PaymentProcessor $payment_processor */
2358
-        $payment_processor = LoaderFactory::getShared(PaymentProcessor::class);
2359
-        if (! $payment_processor instanceof PaymentProcessor) {
2360
-            return null;
2361
-        }
2362
-        /** @var EE_Transaction_Processor $transaction_processor */
2363
-        $transaction_processor = LoaderFactory::getShared(EE_Transaction_Processor::class);
2364
-        if ($transaction_processor instanceof EE_Transaction_Processor) {
2365
-            $transaction_processor->set_revisit($this->checkout->revisit);
2366
-        }
2367
-        try {
2368
-            // generate payment object
2369
-            return $payment_processor->processPayment(
2370
-                $payment_method,
2371
-                $this->checkout->transaction,
2372
-                $this->checkout->billing_form instanceof EE_Billing_Info_Form
2373
-                    ? $this->checkout->billing_form
2374
-                    : null,
2375
-                $this->checkout->amount_owing,
2376
-                $this->checkout->admin_request,
2377
-                true,
2378
-                $this->_get_return_url($payment_method),
2379
-                $this->reg_step_url()
2380
-            );
2381
-        } catch (Exception $e) {
2382
-            $this->_handle_payment_processor_exception($e);
2383
-        }
2384
-        return null;
2385
-    }
2386
-
2387
-
2388
-    /**
2389
-     * _handle_payment_processor_exception
2390
-     *
2391
-     * @param Exception $e
2392
-     * @return void
2393
-     * @throws EE_Error
2394
-     * @throws InvalidArgumentException
2395
-     * @throws InvalidDataTypeException
2396
-     * @throws InvalidInterfaceException
2397
-     */
2398
-    protected function _handle_payment_processor_exception(Exception $e)
2399
-    {
2400
-        EE_Error::add_error(
2401
-            sprintf(
2402
-                esc_html__(
2403
-                    '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',
2404
-                    'event_espresso'
2405
-                ),
2406
-                '<br/>',
2407
-                EE_Registry::instance()->CFG->organization->get_pretty('email'),
2408
-                $e->getMessage(),
2409
-                $e->getFile(),
2410
-                $e->getLine()
2411
-            ),
2412
-            __FILE__,
2413
-            __FUNCTION__,
2414
-            __LINE__
2415
-        );
2416
-    }
2417
-
2418
-
2419
-    /**
2420
-     * @param EE_Payment_Method $payment_method
2421
-     * @return string
2422
-     * @throws EE_Error
2423
-     * @throws ReflectionException
2424
-     */
2425
-    protected function _get_return_url(EE_Payment_Method $payment_method)
2426
-    {
2427
-        switch ($payment_method->type_obj()->payment_occurs()) {
2428
-            case EE_PMT_Base::offsite:
2429
-                return add_query_arg(
2430
-                    [
2431
-                        'action'                     => 'process_gateway_response',
2432
-                        'selected_method_of_payment' => $this->checkout->selected_method_of_payment,
2433
-                        'spco_txn'                   => $this->checkout->transaction->ID(),
2434
-                    ],
2435
-                    $this->reg_step_url()
2436
-                );
2437
-
2438
-            case EE_PMT_Base::onsite:
2439
-            case EE_PMT_Base::offline:
2440
-                return $this->checkout->next_step->reg_step_url();
2441
-        }
2442
-        return '';
2443
-    }
2444
-
2445
-
2446
-    /**
2447
-     * _validate_payment
2448
-     *
2449
-     * @param EE_Payment $payment
2450
-     * @return EE_Payment|bool
2451
-     * @throws EE_Error
2452
-     * @throws InvalidArgumentException
2453
-     * @throws InvalidDataTypeException
2454
-     * @throws InvalidInterfaceException
2455
-     */
2456
-    private function _validate_payment($payment = null)
2457
-    {
2458
-        if ($this->checkout->payment_method->is_off_line()) {
2459
-            return true;
2460
-        }
2461
-        // verify payment object
2462
-        if (! $payment instanceof EE_Payment) {
2463
-            // not a payment
2464
-            EE_Error::add_error(
2465
-                sprintf(
2466
-                    esc_html__(
2467
-                        'A valid payment was not generated due to a technical issue.%1$sPlease try again or contact %2$s for assistance.',
2468
-                        'event_espresso'
2469
-                    ),
2470
-                    '<br/>',
2471
-                    EE_Registry::instance()->CFG->organization->get_pretty('email')
2472
-                ),
2473
-                __FILE__,
2474
-                __FUNCTION__,
2475
-                __LINE__
2476
-            );
2477
-            return false;
2478
-        }
2479
-        return $payment;
2480
-    }
2481
-
2482
-
2483
-    /**
2484
-     * _post_payment_processing
2485
-     *
2486
-     * @param EE_Payment|bool $payment
2487
-     * @return bool|EE_Payment
2488
-     * @throws EE_Error
2489
-     * @throws InvalidArgumentException
2490
-     * @throws InvalidDataTypeException
2491
-     * @throws InvalidInterfaceException
2492
-     * @throws ReflectionException
2493
-     */
2494
-    private function _post_payment_processing($payment = null)
2495
-    {
2496
-        // Off-Line payment?
2497
-        if ($payment === true) {
2498
-            return true;
2499
-        }
2500
-        if ($payment instanceof EE_Payment) {
2501
-            // Should the user be redirected?
2502
-            if ($payment->redirect_url()) {
2503
-                do_action('AHEE_log', __CLASS__, __FUNCTION__, $payment->redirect_url(), '$payment->redirect_url()');
2504
-                $this->checkout->redirect      = true;
2505
-                $this->checkout->redirect_form = $payment->redirect_form();
2506
-                $this->checkout->redirect_url  = $this->reg_step_url('redirect_form');
2507
-                // set JSON response
2508
-                $this->checkout->json_response->set_redirect_form($this->checkout->redirect_form);
2509
-                // and lastly, let's bump the payment status to pending
2510
-                $payment->set_status(EEM_Payment::status_id_pending);
2511
-                $payment->save();
2512
-            } elseif (! $this->_process_payment_status($payment, EE_PMT_Base::onsite)) {
2513
-                // User shouldn't be redirected. So let's process it here.
2514
-                // $this->_setup_redirect_for_next_step();
2515
-                $this->checkout->continue_reg = false;
2516
-            }
2517
-            return $payment;
2518
-        }
2519
-        // ummm ya... not Off-Line, not On-Site, not off-Site ????
2520
-        $this->checkout->continue_reg = false;
2521
-        return false;
2522
-    }
2523
-
2524
-
2525
-    /**
2526
-     *    _process_payment_status
2527
-     *
2528
-     * @type    EE_Payment $payment
2529
-     * @param string       $payment_occurs
2530
-     * @return bool
2531
-     * @throws EE_Error
2532
-     * @throws InvalidArgumentException
2533
-     * @throws InvalidDataTypeException
2534
-     * @throws InvalidInterfaceException
2535
-     */
2536
-    private function _process_payment_status($payment, $payment_occurs = EE_PMT_Base::offline)
2537
-    {
2538
-        // off-line payment? carry on
2539
-        if ($payment_occurs === EE_PMT_Base::offline) {
2540
-            return true;
2541
-        }
2542
-        // verify payment validity
2543
-        if ($payment instanceof EE_Payment) {
2544
-            do_action('AHEE_log', __CLASS__, __FUNCTION__, $payment->status(), '$payment->status()');
2545
-            $msg = $payment->gateway_response();
2546
-            // check results
2547
-            switch ($payment->status()) {
2548
-                // good payment
2549
-                case EEM_Payment::status_id_approved:
2550
-                    EE_Error::add_success(
2551
-                        esc_html__('Your payment was processed successfully.', 'event_espresso'),
2552
-                        __FILE__,
2553
-                        __FUNCTION__,
2554
-                        __LINE__
2555
-                    );
2556
-                    return true;
2557
-                // slow payment
2558
-                case EEM_Payment::status_id_pending:
2559
-                    if (empty($msg)) {
2560
-                        $msg = esc_html__(
2561
-                            'Your payment appears to have been processed successfully, but the Instant Payment Notification has not yet been received. It should arrive shortly.',
2562
-                            'event_espresso'
2563
-                        );
2564
-                    }
2565
-                    EE_Error::add_success($msg, __FILE__, __FUNCTION__, __LINE__);
2566
-                    return true;
2567
-                // don't wanna payment
2568
-                case EEM_Payment::status_id_cancelled:
2569
-                    if (empty($msg)) {
2570
-                        $msg = _n(
2571
-                            'Payment cancelled. Please try again.',
2572
-                            'Payment cancelled. Please try again or select another method of payment.',
2573
-                            count($this->checkout->available_payment_methods),
2574
-                            'event_espresso'
2575
-                        );
2576
-                    }
2577
-                    EE_Error::add_attention($msg, __FILE__, __FUNCTION__, __LINE__);
2578
-                    return false;
2579
-                // not enough payment
2580
-                case EEM_Payment::status_id_declined:
2581
-                    if (empty($msg)) {
2582
-                        $msg = _n(
2583
-                            'We\'re sorry but your payment was declined. Please try again.',
2584
-                            'We\'re sorry but your payment was declined. Please try again or select another method of payment.',
2585
-                            count($this->checkout->available_payment_methods),
2586
-                            'event_espresso'
2587
-                        );
2588
-                    }
2589
-                    EE_Error::add_attention($msg, __FILE__, __FUNCTION__, __LINE__);
2590
-                    return false;
2591
-                // bad payment
2592
-                case EEM_Payment::status_id_failed:
2593
-                    if (! empty($msg)) {
2594
-                        EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2595
-                        return false;
2596
-                    }
2597
-                    // default to error below
2598
-                    break;
2599
-            }
2600
-        }
2601
-        // off-site payment gateway responses are too unreliable, so let's just assume that
2602
-        // the payment processing is just running slower than the registrant's request
2603
-        if ($payment_occurs === EE_PMT_Base::offsite) {
2604
-            return true;
2605
-        }
2606
-        EE_Error::add_error(
2607
-            sprintf(
2608
-                esc_html__(
2609
-                    'Your payment could not be processed successfully due to a technical issue.%sPlease try again or contact %s for assistance.',
2610
-                    'event_espresso'
2611
-                ),
2612
-                '<br/>',
2613
-                EE_Registry::instance()->CFG->organization->get_pretty('email')
2614
-            ),
2615
-            __FILE__,
2616
-            __FUNCTION__,
2617
-            __LINE__
2618
-        );
2619
-        return false;
2620
-    }
2621
-
2622
-
2623
-
2624
-
2625
-
2626
-
2627
-    /********************************************************************************************************/
2628
-    /**********************************  PROCESS GATEWAY RESPONSE  **********************************/
2629
-    /********************************************************************************************************/
2630
-    /**
2631
-     * process_gateway_response
2632
-     * this is the return point for Off-Site Payment Methods
2633
-     * It will attempt to "handle the IPN" if it appears that this has not already occurred,
2634
-     * otherwise, it will load up the last payment made for the TXN.
2635
-     * If the payment retrieved looks good, it will then either:
2636
-     *    complete the current step and allow advancement to the next reg step
2637
-     *        or present the payment options again
2638
-     *
2639
-     * @return bool
2640
-     * @throws EE_Error
2641
-     * @throws InvalidArgumentException
2642
-     * @throws ReflectionException
2643
-     * @throws InvalidDataTypeException
2644
-     * @throws InvalidInterfaceException
2645
-     */
2646
-    public function process_gateway_response()
2647
-    {
2648
-        // how have they chosen to pay?
2649
-        $this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment(true);
2650
-        // get EE_Payment_Method object
2651
-        if (! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()) {
2652
-            $this->checkout->continue_reg = false;
2653
-            return false;
2654
-        }
2655
-        if (! $this->checkout->payment_method->is_off_site()) {
2656
-            return false;
2657
-        }
2658
-        $this->_validate_offsite_return();
2659
-        // verify TXN
2660
-        if ($this->checkout->transaction instanceof EE_Transaction) {
2661
-            $gateway = $this->checkout->payment_method->type_obj()->get_gateway();
2662
-            if (! $gateway instanceof EE_Offsite_Gateway) {
2663
-                $this->checkout->continue_reg = false;
2664
-                return false;
2665
-            }
2666
-            $payment = $this->_process_off_site_payment($gateway);
2667
-            $payment = $this->_process_cancelled_payments($payment);
2668
-            $payment = $this->_validate_payment($payment);
2669
-            // if payment was not declined by the payment gateway or cancelled by the registrant
2670
-            if ($this->_process_payment_status($payment, EE_PMT_Base::offsite)) {
2671
-                // $this->_setup_redirect_for_next_step();
2672
-                // store that for later
2673
-                $this->checkout->payment = $payment;
2674
-                // mark this reg step as completed, as long as gateway doesn't use a separate IPN request,
2675
-                // because we will complete this step during the IPN processing then
2676
-                if (! $this->handle_IPN_in_this_request()) {
2677
-                    $this->set_completed();
2678
-                }
2679
-                return true;
2680
-            }
2681
-        }
2682
-        // DEBUG LOG
2683
-        // $this->checkout->log(
2684
-        //     __CLASS__,
2685
-        //     __FUNCTION__,
2686
-        //     __LINE__,
2687
-        //     array('payment' => $payment)
2688
-        // );
2689
-        $this->checkout->continue_reg = false;
2690
-        return false;
2691
-    }
2692
-
2693
-
2694
-    /**
2695
-     * _validate_return
2696
-     *
2697
-     * @return void
2698
-     * @throws EE_Error
2699
-     * @throws InvalidArgumentException
2700
-     * @throws InvalidDataTypeException
2701
-     * @throws InvalidInterfaceException
2702
-     * @throws ReflectionException
2703
-     */
2704
-    private function _validate_offsite_return()
2705
-    {
2706
-        $TXN_ID = $this->request->getRequestParam('spco_txn', 0, 'int');
2707
-        if ($TXN_ID !== $this->checkout->transaction->ID()) {
2708
-            // Houston... we might have a problem
2709
-            $invalid_TXN = false;
2710
-            // first gather some info
2711
-            $valid_TXN          = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2712
-            $primary_registrant = $valid_TXN instanceof EE_Transaction
2713
-                ? $valid_TXN->primary_registration()
2714
-                : null;
2715
-            // let's start by retrieving the cart for this TXN
2716
-            $cart = $this->checkout->get_cart_for_transaction($this->checkout->transaction);
2717
-            if ($cart instanceof EE_Cart) {
2718
-                // verify that the current cart has tickets
2719
-                $tickets = $cart->get_tickets();
2720
-                if (empty($tickets)) {
2721
-                    $invalid_TXN = true;
2722
-                }
2723
-            } else {
2724
-                $invalid_TXN = true;
2725
-            }
2726
-            $valid_TXN_SID = $primary_registrant instanceof EE_Registration
2727
-                ? $primary_registrant->session_ID()
2728
-                : null;
2729
-            // validate current Session ID and compare against valid TXN session ID
2730
-            if (
2731
-                $invalid_TXN // if this is already true, then skip other checks
2732
-                || EE_Session::instance()->id() === null
2733
-                || (
2734
-                    // WARNING !!!
2735
-                    // this could be PayPal sending back duplicate requests (ya they do that)
2736
-                    // or it **could** mean someone is simply registering AGAIN after having just done so,
2737
-                    // so now we need to determine if this current TXN looks valid or not
2738
-                    // and whether this reg step has even been started ?
2739
-                    EE_Session::instance()->id() === $valid_TXN_SID
2740
-                    // really? you're halfway through this reg step, but you never started it ?
2741
-                    && $this->checkout->transaction->reg_step_completed($this->slug()) === false
2742
-                )
2743
-            ) {
2744
-                $invalid_TXN = true;
2745
-            }
2746
-            if ($invalid_TXN) {
2747
-                // is the valid TXN completed ?
2748
-                if ($valid_TXN instanceof EE_Transaction) {
2749
-                    // has this step even been started ?
2750
-                    $reg_step_completed = $valid_TXN->reg_step_completed($this->slug());
2751
-                    if ($reg_step_completed !== false && $reg_step_completed !== true) {
2752
-                        // so it **looks** like this is a double request from PayPal
2753
-                        // so let's try to pick up where we left off
2754
-                        $this->checkout->transaction = $valid_TXN;
2755
-                        $this->checkout->refresh_all_entities(true);
2756
-                        return;
2757
-                    }
2758
-                }
2759
-                // you appear to be lost?
2760
-                $this->_redirect_wayward_request($primary_registrant);
2761
-            }
2762
-        }
2763
-    }
2764
-
2765
-
2766
-    /**
2767
-     * _redirect_wayward_request
2768
-     *
2769
-     * @param EE_Registration|null $primary_registrant
2770
-     * @return void
2771
-     * @throws EE_Error
2772
-     * @throws InvalidArgumentException
2773
-     * @throws InvalidDataTypeException
2774
-     * @throws InvalidInterfaceException
2775
-     * @throws ReflectionException
2776
-     */
2777
-    private function _redirect_wayward_request(EE_Registration $primary_registrant)
2778
-    {
2779
-        if (! $primary_registrant instanceof EE_Registration) {
2780
-            // try redirecting based on the current TXN
2781
-            $primary_registrant = $this->checkout->transaction instanceof EE_Transaction
2782
-                ? $this->checkout->transaction->primary_registration()
2783
-                : null;
2784
-        }
2785
-        if (! $primary_registrant instanceof EE_Registration) {
2786
-            EE_Error::add_error(
2787
-                sprintf(
2788
-                    esc_html__(
2789
-                        '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.',
2790
-                        'event_espresso'
2791
-                    ),
2792
-                    '<br/>',
2793
-                    EE_Registry::instance()->CFG->organization->get_pretty('email')
2794
-                ),
2795
-                __FILE__,
2796
-                __FUNCTION__,
2797
-                __LINE__
2798
-            );
2799
-            return;
2800
-        }
2801
-        // make sure transaction is not locked
2802
-        $this->checkout->transaction->unlock();
2803
-        wp_safe_redirect(
2804
-            add_query_arg(
2805
-                [
2806
-                    'e_reg_url_link' => $primary_registrant->reg_url_link(),
2807
-                ],
2808
-                $this->checkout->thank_you_page_url
2809
-            )
2810
-        );
2811
-        exit();
2812
-    }
2813
-
2814
-
2815
-    /**
2816
-     * _process_off_site_payment
2817
-     *
2818
-     * @param EE_Offsite_Gateway $gateway
2819
-     * @return EE_Payment
2820
-     * @throws EE_Error
2821
-     * @throws InvalidArgumentException
2822
-     * @throws InvalidDataTypeException
2823
-     * @throws InvalidInterfaceException
2824
-     * @throws ReflectionException
2825
-     */
2826
-    private function _process_off_site_payment(EE_Offsite_Gateway $gateway)
2827
-    {
2828
-        try {
2829
-            $request      = LoaderFactory::getLoader()->getShared(RequestInterface::class);
2830
-            $request_data = $request->requestParams();
2831
-            // if gateway uses_separate_IPN_request, then we don't have to process the IPN manually
2832
-            $this->set_handle_IPN_in_this_request(
2833
-                $gateway->handle_IPN_in_this_request($request_data, false)
2834
-            );
2835
-            if ($this->handle_IPN_in_this_request()) {
2836
-                // get payment details and process results
2837
-                /** @var IpnHandler $payment_processor */
2838
-                $payment_processor = LoaderFactory::getShared(IpnHandler::class);
2839
-                $payment           = $payment_processor->processIPN(
2840
-                    $request_data,
2841
-                    $this->checkout->transaction,
2842
-                    $this->checkout->payment_method,
2843
-                    true,
2844
-                    false
2845
-                );
2846
-                // $payment_source = 'process_ipn';
2847
-            } else {
2848
-                $payment = $this->checkout->transaction->last_payment();
2849
-                // $payment_source = 'last_payment';
2850
-            }
2851
-        } catch (Exception $e) {
2852
-            // let's just eat the exception and try to move on using any previously set payment info
2853
-            $payment = $this->checkout->transaction->last_payment();
2854
-            // $payment_source = 'last_payment after Exception';
2855
-            // but if we STILL don't have a payment object
2856
-            if (! $payment instanceof EE_Payment) {
2857
-                // then we'll object ! ( not object like a thing... but object like what a lawyer says ! )
2858
-                $this->_handle_payment_processor_exception($e);
2859
-            }
2860
-        }
2861
-        return $payment;
2862
-    }
2863
-
2864
-
2865
-    /**
2866
-     * _process_cancelled_payments
2867
-     * just makes sure that the payment status gets updated correctly
2868
-     * so tha tan error isn't generated during payment validation
2869
-     *
2870
-     * @param EE_Payment $payment
2871
-     * @return EE_Payment|null
2872
-     * @throws EE_Error
2873
-     */
2874
-    private function _process_cancelled_payments($payment = null)
2875
-    {
2876
-        if (
2877
-            $payment instanceof EE_Payment
2878
-            && $this->request->requestParamIsSet('ee_cancel_payment')
2879
-            && $payment->status() === EEM_Payment::status_id_failed
2880
-        ) {
2881
-            $payment->set_status(EEM_Payment::status_id_cancelled);
2882
-        }
2883
-        return $payment;
2884
-    }
2885
-
2886
-
2887
-    /**
2888
-     *    get_transaction_details_for_gateways
2889
-     *
2890
-     * @access    public
2891
-     * @return void
2892
-     * @throws EE_Error
2893
-     * @throws InvalidArgumentException
2894
-     * @throws ReflectionException
2895
-     * @throws InvalidDataTypeException
2896
-     * @throws InvalidInterfaceException
2897
-     */
2898
-    public function get_transaction_details_for_gateways()
2899
-    {
2900
-        $txn_details = [];
2901
-        // ya gotta make a choice man
2902
-        if (empty($this->checkout->selected_method_of_payment)) {
2903
-            $txn_details = [
2904
-                'error' => esc_html__('Please select a method of payment before proceeding.', 'event_espresso'),
2905
-            ];
2906
-        }
2907
-        // get EE_Payment_Method object
2908
-        if (
2909
-            empty($txn_details)
2910
-            && ! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()
2911
-        ) {
2912
-            $txn_details = [
2913
-                'selected_method_of_payment' => $this->checkout->selected_method_of_payment,
2914
-                'error'                      => esc_html__(
2915
-                    'A valid Payment Method could not be determined.',
2916
-                    'event_espresso'
2917
-                ),
2918
-            ];
2919
-        }
2920
-        if (empty($txn_details) && $this->checkout->transaction instanceof EE_Transaction) {
2921
-            $return_url  = $this->_get_return_url($this->checkout->payment_method);
2922
-            $txn_details = [
2923
-                'TXN_ID'         => $this->checkout->transaction->ID(),
2924
-                'TXN_timestamp'  => $this->checkout->transaction->datetime(),
2925
-                'TXN_total'      => $this->checkout->transaction->total(),
2926
-                'TXN_paid'       => $this->checkout->transaction->paid(),
2927
-                'TXN_reg_steps'  => $this->checkout->transaction->reg_steps(),
2928
-                'STS_ID'         => $this->checkout->transaction->status_ID(),
2929
-                'PMD_ID'         => $this->checkout->transaction->payment_method_ID(),
2930
-                'payment_amount' => $this->checkout->amount_owing,
2931
-                'return_url'     => $return_url,
2932
-                'cancel_url'     => add_query_arg(['ee_cancel_payment' => true], $return_url),
2933
-                'notify_url'     => EE_Config::instance()->core->txn_page_url(
2934
-                    [
2935
-                        'e_reg_url_link'    => $this->checkout->transaction->primary_registration()->reg_url_link(),
2936
-                        'ee_payment_method' => $this->checkout->payment_method->slug(),
2937
-                    ]
2938
-                ),
2939
-            ];
2940
-        }
2941
-        echo wp_json_encode($txn_details);
2942
-        exit();
2943
-    }
2944
-
2945
-
2946
-    /**
2947
-     *    __sleep
2948
-     * to conserve db space, let's remove the reg_form and the EE_Checkout object from EE_SPCO_Reg_Step objects upon
2949
-     * serialization EE_Checkout will handle the reimplementation of itself upon waking, but we won't bother with the
2950
-     * reg form, because if needed, it will be regenerated anyways
2951
-     *
2952
-     * @return array
2953
-     */
2954
-    public function __sleep()
2955
-    {
2956
-        // remove the reg form and the checkout
2957
-        return array_diff(array_keys(get_object_vars($this)), ['reg_form', 'checkout', 'line_item_display']);
2958
-    }
26
+	/**
27
+	 * @var EE_Line_Item_Display $Line_Item_Display
28
+	 */
29
+	protected $line_item_display;
30
+
31
+	/**
32
+	 * @var boolean $handle_IPN_in_this_request
33
+	 */
34
+	protected $handle_IPN_in_this_request = false;
35
+
36
+
37
+	/**
38
+	 *    set_hooks - for hooking into EE Core, other modules, etc
39
+	 *
40
+	 * @access    public
41
+	 * @return    void
42
+	 */
43
+	public static function set_hooks()
44
+	{
45
+		add_filter(
46
+			'FHEE__SPCO__EE_Line_Item_Filter_Collection',
47
+			['EE_SPCO_Reg_Step_Payment_Options', 'add_spco_line_item_filters']
48
+		);
49
+		add_action(
50
+			'wp_ajax_switch_spco_billing_form',
51
+			['EE_SPCO_Reg_Step_Payment_Options', 'switch_spco_billing_form']
52
+		);
53
+		add_action(
54
+			'wp_ajax_nopriv_switch_spco_billing_form',
55
+			['EE_SPCO_Reg_Step_Payment_Options', 'switch_spco_billing_form']
56
+		);
57
+		add_action('wp_ajax_save_payer_details', ['EE_SPCO_Reg_Step_Payment_Options', 'save_payer_details']);
58
+		add_action(
59
+			'wp_ajax_nopriv_save_payer_details',
60
+			['EE_SPCO_Reg_Step_Payment_Options', 'save_payer_details']
61
+		);
62
+		add_action(
63
+			'wp_ajax_get_transaction_details_for_gateways',
64
+			['EE_SPCO_Reg_Step_Payment_Options', 'get_transaction_details']
65
+		);
66
+		add_action(
67
+			'wp_ajax_nopriv_get_transaction_details_for_gateways',
68
+			['EE_SPCO_Reg_Step_Payment_Options', 'get_transaction_details']
69
+		);
70
+		add_filter(
71
+			'FHEE__EED_Recaptcha___bypass_recaptcha__bypass_request_params_array',
72
+			['EE_SPCO_Reg_Step_Payment_Options', 'bypass_recaptcha_for_load_payment_method'],
73
+			10,
74
+			1
75
+		);
76
+	}
77
+
78
+
79
+	/**
80
+	 *    ajax switch_spco_billing_form
81
+	 *
82
+	 */
83
+	public static function switch_spco_billing_form()
84
+	{
85
+		EED_Single_Page_Checkout::process_ajax_request('switch_payment_method');
86
+	}
87
+
88
+
89
+	/**
90
+	 *    ajax save_payer_details
91
+	 *
92
+	 */
93
+	public static function save_payer_details()
94
+	{
95
+		EED_Single_Page_Checkout::process_ajax_request('save_payer_details_via_ajax');
96
+	}
97
+
98
+
99
+	/**
100
+	 *    ajax get_transaction_details
101
+	 *
102
+	 */
103
+	public static function get_transaction_details()
104
+	{
105
+		EED_Single_Page_Checkout::process_ajax_request('get_transaction_details_for_gateways');
106
+	}
107
+
108
+
109
+	/**
110
+	 * bypass_recaptcha_for_load_payment_method
111
+	 *
112
+	 * @access public
113
+	 * @return array
114
+	 * @throws InvalidArgumentException
115
+	 * @throws InvalidDataTypeException
116
+	 * @throws InvalidInterfaceException
117
+	 */
118
+	public static function bypass_recaptcha_for_load_payment_method()
119
+	{
120
+		return [
121
+			'EESID'  => EE_Registry::instance()->SSN->id(),
122
+			'step'   => 'payment_options',
123
+			'action' => 'spco_billing_form',
124
+		];
125
+	}
126
+
127
+
128
+	/**
129
+	 *    class constructor
130
+	 *
131
+	 * @access    public
132
+	 * @param EE_Checkout $checkout
133
+	 */
134
+	public function __construct(EE_Checkout $checkout)
135
+	{
136
+		$this->request   = EED_Single_Page_Checkout::getRequest();
137
+		$this->_slug     = 'payment_options';
138
+		$this->_name     = esc_html__('Payment Options', 'event_espresso');
139
+		$this->_template = SPCO_REG_STEPS_PATH . $this->_slug . '/payment_options_main.template.php';
140
+		$this->checkout  = $checkout;
141
+		$this->_reset_success_message();
142
+		$this->set_instructions(
143
+			esc_html__(
144
+				'Please select a method of payment and provide any necessary billing information before proceeding.',
145
+				'event_espresso'
146
+			)
147
+		);
148
+	}
149
+
150
+
151
+	/**
152
+	 * @return null
153
+	 */
154
+	public function line_item_display()
155
+	{
156
+		return $this->line_item_display;
157
+	}
158
+
159
+
160
+	/**
161
+	 * @param null $line_item_display
162
+	 */
163
+	public function set_line_item_display($line_item_display)
164
+	{
165
+		$this->line_item_display = $line_item_display;
166
+	}
167
+
168
+
169
+	/**
170
+	 * @return boolean
171
+	 */
172
+	public function handle_IPN_in_this_request()
173
+	{
174
+		return $this->handle_IPN_in_this_request;
175
+	}
176
+
177
+
178
+	/**
179
+	 * @param boolean $handle_IPN_in_this_request
180
+	 */
181
+	public function set_handle_IPN_in_this_request($handle_IPN_in_this_request)
182
+	{
183
+		$this->handle_IPN_in_this_request = filter_var($handle_IPN_in_this_request, FILTER_VALIDATE_BOOLEAN);
184
+	}
185
+
186
+
187
+	/**
188
+	 * translate_js_strings
189
+	 *
190
+	 * @return void
191
+	 */
192
+	public function translate_js_strings()
193
+	{
194
+		EE_Registry::$i18n_js_strings['no_payment_method']      = esc_html__(
195
+			'Please select a method of payment in order to continue.',
196
+			'event_espresso'
197
+		);
198
+		EE_Registry::$i18n_js_strings['invalid_payment_method'] = esc_html__(
199
+			'A valid method of payment could not be determined. Please refresh the page and try again.',
200
+			'event_espresso'
201
+		);
202
+		EE_Registry::$i18n_js_strings['forwarding_to_offsite']  = esc_html__(
203
+			'Forwarding to Secure Payment Provider.',
204
+			'event_espresso'
205
+		);
206
+	}
207
+
208
+
209
+	/**
210
+	 * enqueue_styles_and_scripts
211
+	 *
212
+	 * @return void
213
+	 * @throws EE_Error
214
+	 * @throws InvalidArgumentException
215
+	 * @throws InvalidDataTypeException
216
+	 * @throws InvalidInterfaceException
217
+	 * @throws ReflectionException
218
+	 */
219
+	public function enqueue_styles_and_scripts()
220
+	{
221
+		$transaction = $this->checkout->transaction;
222
+		// if the transaction isn't set or nothing is owed on it, don't enqueue any JS
223
+		if (! $transaction instanceof EE_Transaction || EEH_Money::compare_floats($transaction->remaining(), 0)) {
224
+			return;
225
+		}
226
+		foreach (
227
+			EEM_Payment_Method::instance()->get_all_for_transaction(
228
+				$transaction,
229
+				EEM_Payment_Method::scope_cart
230
+			) as $payment_method
231
+		) {
232
+			$type_obj = $payment_method->type_obj();
233
+			if ($type_obj instanceof EE_PMT_Base) {
234
+				$billing_form = $type_obj->generate_new_billing_form($transaction);
235
+				if ($billing_form instanceof EE_Form_Section_Proper) {
236
+					$billing_form->enqueue_js();
237
+				}
238
+			}
239
+		}
240
+	}
241
+
242
+
243
+	/**
244
+	 * initialize_reg_step
245
+	 *
246
+	 * @return bool
247
+	 * @throws EE_Error
248
+	 * @throws InvalidArgumentException
249
+	 * @throws ReflectionException
250
+	 * @throws InvalidDataTypeException
251
+	 * @throws InvalidInterfaceException
252
+	 */
253
+	public function initialize_reg_step()
254
+	{
255
+		// TODO: if /when we implement donations, then this will need overriding
256
+		if (
257
+			// don't need payment options for:
258
+			// registrations made via the admin
259
+			// completed transactions
260
+			// overpaid transactions
261
+			// $ 0.00 transactions(no payment required)
262
+			! $this->checkout->payment_required()
263
+			// but do NOT remove if current action being called belongs to this reg step
264
+			&& ! is_callable([$this, $this->checkout->action])
265
+			&& ! $this->completed()
266
+		) {
267
+			// and if so, then we no longer need the Payment Options step
268
+			if ($this->is_current_step()) {
269
+				$this->checkout->generate_reg_form = false;
270
+			}
271
+			$this->checkout->remove_reg_step($this->_slug);
272
+			// DEBUG LOG
273
+			// $this->checkout->log( __CLASS__, __FUNCTION__, __LINE__ );
274
+			return false;
275
+		}
276
+		// load EEM_Payment_Method
277
+		EE_Registry::instance()->load_model('Payment_Method');
278
+		// get all active payment methods
279
+		$this->checkout->available_payment_methods = EEM_Payment_Method::instance()->get_all_for_transaction(
280
+			$this->checkout->transaction,
281
+			EEM_Payment_Method::scope_cart
282
+		);
283
+		return true;
284
+	}
285
+
286
+
287
+	/**
288
+	 * @return EE_Form_Section_Proper
289
+	 * @throws EE_Error
290
+	 * @throws InvalidArgumentException
291
+	 * @throws ReflectionException
292
+	 * @throws EntityNotFoundException
293
+	 * @throws InvalidDataTypeException
294
+	 * @throws InvalidInterfaceException
295
+	 * @throws InvalidStatusException
296
+	 */
297
+	public function generate_reg_form()
298
+	{
299
+		// reset in case someone changes their mind
300
+		$this->_reset_selected_method_of_payment();
301
+		// set some defaults
302
+		$this->checkout->selected_method_of_payment = 'payments_closed';
303
+		$registrations_requiring_payment            = [];
304
+		$registrations_for_free_events              = [];
305
+		$registrations_requiring_pre_approval       = [];
306
+		$sold_out_events                            = [];
307
+		$insufficient_spaces_available              = [];
308
+		$no_payment_required                        = true;
309
+		// loop thru registrations to gather info
310
+		$registrations         = $this->checkout->transaction->registrations($this->checkout->reg_cache_where_params);
311
+		$ejected_registrations = EE_SPCO_Reg_Step_Payment_Options::find_registrations_that_lost_their_space(
312
+			$registrations,
313
+			$this->checkout->revisit
314
+		);
315
+		foreach ($registrations as $REG_ID => $registration) {
316
+			/** @var $registration EE_Registration */
317
+			// Skip if the registration has been moved
318
+			if ($registration->wasMoved()) {
319
+				continue;
320
+			}
321
+			// has this registration lost it's space ?
322
+			if (isset($ejected_registrations[ $REG_ID ])) {
323
+				if ($registration->event()->is_sold_out() || $registration->event()->is_sold_out(true)) {
324
+					$sold_out_events[ $registration->event()->ID() ] = $registration->event();
325
+				} else {
326
+					$insufficient_spaces_available[ $registration->event()->ID() ] = $registration->event();
327
+				}
328
+				continue;
329
+			}
330
+			// event requires admin approval
331
+			if ($registration->status_ID() === RegStatus::AWAITING_REVIEW) {
332
+				// add event to list of events with pre-approval reg status
333
+				$registrations_requiring_pre_approval[ $REG_ID ] = $registration;
334
+				do_action(
335
+					'AHEE__EE_SPCO_Reg_Step_Payment_Options__generate_reg_form__event_requires_pre_approval',
336
+					$registration->event(),
337
+					$this
338
+				);
339
+				continue;
340
+			}
341
+			if (
342
+				$this->checkout->revisit
343
+				&& $registration->status_ID() !== RegStatus::APPROVED
344
+				&& (
345
+					$registration->event()->is_sold_out()
346
+					|| $registration->event()->is_sold_out(true)
347
+				)
348
+			) {
349
+				// add event to list of events that are sold out
350
+				$sold_out_events[ $registration->event()->ID() ] = $registration->event();
351
+				do_action(
352
+					'AHEE__EE_SPCO_Reg_Step_Payment_Options__generate_reg_form__sold_out_event',
353
+					$registration->event(),
354
+					$this
355
+				);
356
+				continue;
357
+			}
358
+			// are they allowed to pay now and is there monies owing?
359
+			if ($registration->owes_monies_and_can_pay()) {
360
+				$registrations_requiring_payment[ $REG_ID ] = $registration;
361
+				do_action(
362
+					'AHEE__EE_SPCO_Reg_Step_Payment_Options__generate_reg_form__event_requires_payment',
363
+					$registration->event(),
364
+					$this
365
+				);
366
+			} elseif (
367
+				! $this->checkout->revisit
368
+					  && $registration->status_ID() !== RegStatus::AWAITING_REVIEW
369
+					  && $registration->ticket()->is_free()
370
+			) {
371
+				$registrations_for_free_events[ $registration->ticket()->ID() ] = $registration;
372
+			}
373
+		}
374
+		$subsections = [];
375
+		// now decide which template to load
376
+		if (! empty($sold_out_events)) {
377
+			$subsections['sold_out_events'] = $this->_sold_out_events($sold_out_events);
378
+		}
379
+		if (! empty($insufficient_spaces_available)) {
380
+			$subsections['insufficient_space'] = $this->_insufficient_spaces_available(
381
+				$insufficient_spaces_available
382
+			);
383
+		}
384
+		if (! empty($registrations_requiring_pre_approval)) {
385
+			$subsections['registrations_requiring_pre_approval'] = $this->_registrations_requiring_pre_approval(
386
+				$registrations_requiring_pre_approval
387
+			);
388
+		}
389
+		if (! empty($registrations_for_free_events)) {
390
+			$subsections['no_payment_required'] = $this->_no_payment_required($registrations_for_free_events);
391
+		}
392
+		if (! empty($registrations_requiring_payment)) {
393
+			if ($this->checkout->amount_owing > 0) {
394
+				// autoload Line_Item_Display classes
395
+				EEH_Autoloader::register_line_item_filter_autoloaders();
396
+				$line_item_filter_processor = new EE_Line_Item_Filter_Processor(
397
+					apply_filters(
398
+						'FHEE__SPCO__EE_Line_Item_Filter_Collection',
399
+						new EE_Line_Item_Filter_Collection()
400
+					),
401
+					$this->checkout->cart->get_grand_total()
402
+				);
403
+				/** @var EE_Line_Item $filtered_line_item_tree */
404
+				$filtered_line_item_tree = $line_item_filter_processor->process();
405
+				EEH_Autoloader::register_line_item_display_autoloaders();
406
+				$this->set_line_item_display(new EE_Line_Item_Display('spco'));
407
+				$subsections['payment_options'] = $this->_display_payment_options(
408
+					$this->line_item_display->display_line_item(
409
+						$filtered_line_item_tree,
410
+						['registrations' => $registrations]
411
+					)
412
+				);
413
+				$this->checkout->amount_owing   = $filtered_line_item_tree->total();
414
+				$this->_apply_registration_payments_to_amount_owing($registrations);
415
+			}
416
+			$no_payment_required = false;
417
+		} else {
418
+			$this->_hide_reg_step_submit_button_if_revisit();
419
+		}
420
+		$this->_save_selected_method_of_payment();
421
+
422
+		$subsections['default_hidden_inputs'] = $this->reg_step_hidden_inputs();
423
+		$subsections['extra_hidden_inputs']   = $this->_extra_hidden_inputs($no_payment_required);
424
+
425
+		return new EE_Form_Section_Proper(
426
+			[
427
+				'name'            => $this->reg_form_name(),
428
+				'html_id'         => $this->reg_form_name(),
429
+				'subsections'     => $subsections,
430
+				'layout_strategy' => new EE_No_Layout(),
431
+			]
432
+		);
433
+	}
434
+
435
+
436
+	/**
437
+	 * add line item filters required for this reg step
438
+	 * these filters are applied via this line in EE_SPCO_Reg_Step_Payment_Options::set_hooks():
439
+	 *        add_filter( 'FHEE__SPCO__EE_Line_Item_Filter_Collection', array( 'EE_SPCO_Reg_Step_Payment_Options',
440
+	 *        'add_spco_line_item_filters' ) ); so any code that wants to use the same set of filters during the
441
+	 *        payment options reg step, can apply these filters via the following: apply_filters(
442
+	 *        'FHEE__SPCO__EE_Line_Item_Filter_Collection', new EE_Line_Item_Filter_Collection() ) or to an existing
443
+	 *        filter collection by passing that instead of instantiating a new collection
444
+	 *
445
+	 * @param EE_Line_Item_Filter_Collection $line_item_filter_collection
446
+	 * @return EE_Line_Item_Filter_Collection
447
+	 * @throws EE_Error
448
+	 * @throws InvalidArgumentException
449
+	 * @throws ReflectionException
450
+	 * @throws EntityNotFoundException
451
+	 * @throws InvalidDataTypeException
452
+	 * @throws InvalidInterfaceException
453
+	 * @throws InvalidStatusException
454
+	 */
455
+	public static function add_spco_line_item_filters(EE_Line_Item_Filter_Collection $line_item_filter_collection)
456
+	{
457
+		if (! EE_Registry::instance()->SSN instanceof EE_Session) {
458
+			return $line_item_filter_collection;
459
+		}
460
+		if (! EE_Registry::instance()->SSN->checkout() instanceof EE_Checkout) {
461
+			return $line_item_filter_collection;
462
+		}
463
+		if (! EE_Registry::instance()->SSN->checkout()->transaction instanceof EE_Transaction) {
464
+			return $line_item_filter_collection;
465
+		}
466
+		$line_item_filter_collection->add(
467
+			new EE_Billable_Line_Item_Filter(
468
+				EE_SPCO_Reg_Step_Payment_Options::remove_ejected_registrations(
469
+					EE_Registry::instance()->SSN->checkout()->transaction->registrations(
470
+						EE_Registry::instance()->SSN->checkout()->reg_cache_where_params
471
+					)
472
+				)
473
+			)
474
+		);
475
+		$line_item_filter_collection->add(new EE_Non_Zero_Line_Item_Filter());
476
+		return $line_item_filter_collection;
477
+	}
478
+
479
+
480
+	/**
481
+	 * remove_ejected_registrations
482
+	 * if a registrant has lost their potential space at an event due to lack of payment,
483
+	 * then this method removes them from the list of registrations being paid for during this request
484
+	 *
485
+	 * @param EE_Registration[] $registrations
486
+	 * @return EE_Registration[]
487
+	 * @throws EE_Error
488
+	 * @throws InvalidArgumentException
489
+	 * @throws ReflectionException
490
+	 * @throws EntityNotFoundException
491
+	 * @throws InvalidDataTypeException
492
+	 * @throws InvalidInterfaceException
493
+	 * @throws InvalidStatusException
494
+	 */
495
+	public static function remove_ejected_registrations(array $registrations)
496
+	{
497
+		$ejected_registrations = EE_SPCO_Reg_Step_Payment_Options::find_registrations_that_lost_their_space(
498
+			$registrations,
499
+			EE_Registry::instance()->SSN->checkout()->revisit
500
+		);
501
+		foreach ($registrations as $REG_ID => $registration) {
502
+			// has this registration lost it's space ?
503
+			if (isset($ejected_registrations[ $REG_ID ])) {
504
+				unset($registrations[ $REG_ID ]);
505
+			}
506
+		}
507
+		return $registrations;
508
+	}
509
+
510
+
511
+	/**
512
+	 * find_registrations_that_lost_their_space
513
+	 * If a registrant chooses an offline payment method like Invoice,
514
+	 * then no space is reserved for them at the event until they fully pay fo that site
515
+	 * (unless the event's default reg status is set to APPROVED)
516
+	 * if a registrant then later returns to pay, but the number of spaces available has been reduced due to sales,
517
+	 * then this method will determine which registrations have lost the ability to complete the reg process.
518
+	 *
519
+	 * @param EE_Registration[] $registrations
520
+	 * @param bool              $revisit
521
+	 * @return array
522
+	 * @throws EE_Error
523
+	 * @throws InvalidArgumentException
524
+	 * @throws ReflectionException
525
+	 * @throws EntityNotFoundException
526
+	 * @throws InvalidDataTypeException
527
+	 * @throws InvalidInterfaceException
528
+	 * @throws InvalidStatusException
529
+	 */
530
+	public static function find_registrations_that_lost_their_space(array $registrations, $revisit = false)
531
+	{
532
+		// registrations per event
533
+		$event_reg_count = [];
534
+		// spaces left per event
535
+		$event_spaces_remaining = [];
536
+		// tickets left sorted by ID
537
+		$tickets_remaining = [];
538
+		// registrations that have lost their space
539
+		$ejected_registrations = [];
540
+		foreach ($registrations as $REG_ID => $registration) {
541
+			if (
542
+				$registration->status_ID() === RegStatus::APPROVED
543
+				|| apply_filters(
544
+					'FHEE__EE_SPCO_Reg_Step_Payment_Options__find_registrations_that_lost_their_space__allow_reg_payment',
545
+					false,
546
+					$registration,
547
+					$revisit
548
+				)
549
+			) {
550
+				continue;
551
+			}
552
+			$EVT_ID = $registration->event_ID();
553
+			$ticket = $registration->ticket();
554
+			if (! isset($tickets_remaining[ $ticket->ID() ])) {
555
+				$tickets_remaining[ $ticket->ID() ] = $ticket->remaining();
556
+			}
557
+			if ($tickets_remaining[ $ticket->ID() ] > 0) {
558
+				if (! isset($event_reg_count[ $EVT_ID ])) {
559
+					$event_reg_count[ $EVT_ID ] = 0;
560
+				}
561
+				$event_reg_count[ $EVT_ID ]++;
562
+				if (! isset($event_spaces_remaining[ $EVT_ID ])) {
563
+					$event_spaces_remaining[ $EVT_ID ] = $registration->event()->spaces_remaining_for_sale();
564
+				}
565
+			}
566
+			if (
567
+				$revisit
568
+				&& ($tickets_remaining[ $ticket->ID() ] === 0
569
+					|| $event_reg_count[ $EVT_ID ] > $event_spaces_remaining[ $EVT_ID ]
570
+				)
571
+			) {
572
+				$ejected_registrations[ $REG_ID ] = $registration->event();
573
+				if ($registration->status_ID() !== RegStatus::WAIT_LIST) {
574
+					/** @type EE_Registration_Processor $registration_processor */
575
+					$registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
576
+					// at this point, we should have enough details about the registrant to consider the registration
577
+					// NOT incomplete
578
+					$registration_processor->manually_update_registration_status(
579
+						$registration,
580
+						RegStatus::WAIT_LIST
581
+					);
582
+				}
583
+			}
584
+		}
585
+		return $ejected_registrations;
586
+	}
587
+
588
+
589
+	/**
590
+	 * _hide_reg_step_submit_button
591
+	 * removes the html for the reg step submit button
592
+	 * by replacing it with an empty string via filter callback
593
+	 *
594
+	 * @return void
595
+	 */
596
+	protected function _adjust_registration_status_if_event_old_sold()
597
+	{
598
+	}
599
+
600
+
601
+	/**
602
+	 * _hide_reg_step_submit_button
603
+	 * removes the html for the reg step submit button
604
+	 * by replacing it with an empty string via filter callback
605
+	 *
606
+	 * @return void
607
+	 */
608
+	protected function _hide_reg_step_submit_button_if_revisit()
609
+	{
610
+		if ($this->checkout->revisit) {
611
+			add_filter('FHEE__EE_SPCO_Reg_Step__reg_step_submit_button__sbmt_btn_html', '__return_empty_string');
612
+		}
613
+	}
614
+
615
+
616
+	/**
617
+	 * sold_out_events
618
+	 * displays notices regarding events that have sold out since hte registrant first signed up
619
+	 *
620
+	 * @param EE_Event[] $sold_out_events_array
621
+	 * @return EE_Form_Section_Proper
622
+	 * @throws EE_Error
623
+	 */
624
+	private function _sold_out_events($sold_out_events_array = [])
625
+	{
626
+		// set some defaults
627
+		$this->checkout->selected_method_of_payment = 'events_sold_out';
628
+		$sold_out_events                            = '';
629
+		foreach ($sold_out_events_array as $sold_out_event) {
630
+			$sold_out_events .= EEH_HTML::li(
631
+				EEH_HTML::span(
632
+					'  ' . $sold_out_event->name(),
633
+					'',
634
+					'dashicons dashicons-marker ee-icon-size-16 pink-text'
635
+				)
636
+			);
637
+		}
638
+		return new EE_Form_Section_Proper(
639
+			[
640
+				'layout_strategy' => new EE_Template_Layout(
641
+					[
642
+						'layout_template_file' => SPCO_REG_STEPS_PATH
643
+												  . $this->_slug
644
+												  . '/sold_out_events.template.php',
645
+						'template_args'        => apply_filters(
646
+							'FHEE__EE_SPCO_Reg_Step_Payment_Options___sold_out_events__template_args',
647
+							[
648
+								'sold_out_events'     => $sold_out_events,
649
+								'sold_out_events_msg' => apply_filters(
650
+									'FHEE__EE_SPCO_Reg_Step_Payment_Options___sold_out_events__sold_out_events_msg',
651
+									sprintf(
652
+										esc_html__(
653
+											'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',
654
+											'event_espresso'
655
+										),
656
+										'<strong>',
657
+										'</strong>',
658
+										'<br />'
659
+									)
660
+								),
661
+							]
662
+						),
663
+					]
664
+				),
665
+			]
666
+		);
667
+	}
668
+
669
+
670
+	/**
671
+	 * _insufficient_spaces_available
672
+	 * displays notices regarding events that do not have enough remaining spaces
673
+	 * to satisfy the current number of registrations looking to pay
674
+	 *
675
+	 * @param EE_Event[] $insufficient_spaces_events_array
676
+	 * @return EE_Form_Section_Proper
677
+	 * @throws EE_Error
678
+	 * @throws ReflectionException
679
+	 */
680
+	private function _insufficient_spaces_available($insufficient_spaces_events_array = [])
681
+	{
682
+		// set some defaults
683
+		$this->checkout->selected_method_of_payment = 'invoice';
684
+		$insufficient_space_events                  = '';
685
+		foreach ($insufficient_spaces_events_array as $event) {
686
+			if ($event instanceof EE_Event) {
687
+				$insufficient_space_events .= EEH_HTML::li(
688
+					EEH_HTML::span(' ' . $event->name(), '', 'dashicons dashicons-marker ee-icon-size-16 pink-text')
689
+				);
690
+			}
691
+		}
692
+		return new EE_Form_Section_Proper(
693
+			[
694
+				'subsections'     => [
695
+					'default_hidden_inputs' => $this->reg_step_hidden_inputs(),
696
+					'extra_hidden_inputs'   => $this->_extra_hidden_inputs(),
697
+				],
698
+				'layout_strategy' => new EE_Template_Layout(
699
+					[
700
+						'layout_template_file' => SPCO_REG_STEPS_PATH
701
+												  . $this->_slug
702
+												  . '/sold_out_events.template.php',
703
+						'template_args'        => apply_filters(
704
+							'FHEE__EE_SPCO_Reg_Step_Payment_Options___insufficient_spaces_available__template_args',
705
+							[
706
+								'sold_out_events'     => $insufficient_space_events,
707
+								'sold_out_events_msg' => apply_filters(
708
+									'FHEE__EE_SPCO_Reg_Step_Payment_Options___insufficient_spaces_available__insufficient_space_msg',
709
+									esc_html__(
710
+										'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.',
711
+										'event_espresso'
712
+									)
713
+								),
714
+							]
715
+						),
716
+					]
717
+				),
718
+			]
719
+		);
720
+	}
721
+
722
+
723
+	/**
724
+	 * registrations_requiring_pre_approval
725
+	 *
726
+	 * @param array $registrations_requiring_pre_approval
727
+	 * @return EE_Form_Section_Proper
728
+	 * @throws EE_Error
729
+	 * @throws EntityNotFoundException
730
+	 * @throws ReflectionException
731
+	 */
732
+	private function _registrations_requiring_pre_approval($registrations_requiring_pre_approval = [])
733
+	{
734
+		$events_requiring_pre_approval = [];
735
+		foreach ($registrations_requiring_pre_approval as $registration) {
736
+			if ($registration instanceof EE_Registration && $registration->event() instanceof EE_Event) {
737
+				$events_requiring_pre_approval[ $registration->event()->ID() ] = EEH_HTML::li(
738
+					EEH_HTML::span(
739
+						'',
740
+						'',
741
+						'dashicons dashicons-marker ee-icon-size-16 orange-text'
742
+					)
743
+					. EEH_HTML::span($registration->event()->name(), '', 'orange-text')
744
+				);
745
+			}
746
+		}
747
+		return new EE_Form_Section_Proper(
748
+			[
749
+				'layout_strategy' => new EE_Template_Layout(
750
+					[
751
+						'layout_template_file' => SPCO_REG_STEPS_PATH
752
+												  . $this->_slug
753
+												  . '/events_requiring_pre_approval.template.php', // layout_template
754
+						'template_args'        => apply_filters(
755
+							'FHEE__EE_SPCO_Reg_Step_Payment_Options___sold_out_events__template_args',
756
+							[
757
+								'events_requiring_pre_approval'     => implode('', $events_requiring_pre_approval),
758
+								'events_requiring_pre_approval_msg' => apply_filters(
759
+									'FHEE__EE_SPCO_Reg_Step_Payment_Options___events_requiring_pre_approval__events_requiring_pre_approval_msg',
760
+									esc_html__(
761
+										'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.',
762
+										'event_espresso'
763
+									)
764
+								),
765
+							]
766
+						),
767
+					]
768
+				),
769
+			]
770
+		);
771
+	}
772
+
773
+
774
+	/**
775
+	 * _no_payment_required
776
+	 *
777
+	 * @param EE_Event[] $registrations_for_free_events
778
+	 * @return EE_Form_Section_Proper
779
+	 * @throws EE_Error
780
+	 */
781
+	private function _no_payment_required($registrations_for_free_events = [])
782
+	{
783
+		// set some defaults
784
+		$this->checkout->selected_method_of_payment = 'no_payment_required';
785
+		// generate no_payment_required form
786
+		return new EE_Form_Section_Proper(
787
+			[
788
+				'layout_strategy' => new EE_Template_Layout(
789
+					[
790
+						'layout_template_file' => SPCO_REG_STEPS_PATH
791
+												  . $this->_slug
792
+												  . '/no_payment_required.template.php', // layout_template
793
+						'template_args'        => apply_filters(
794
+							'FHEE__EE_SPCO_Reg_Step_Payment_Options___no_payment_required__template_args',
795
+							[
796
+								'revisit'                       => $this->checkout->revisit,
797
+								'registrations'                 => [],
798
+								'ticket_count'                  => [],
799
+								'registrations_for_free_events' => $registrations_for_free_events,
800
+								'no_payment_required_msg'       => EEH_HTML::p(
801
+									esc_html__('This is a free event, so no billing will occur.', 'event_espresso')
802
+								),
803
+							]
804
+						),
805
+					]
806
+				),
807
+			]
808
+		);
809
+	}
810
+
811
+
812
+	/**
813
+	 * _display_payment_options
814
+	 *
815
+	 * @param string $transaction_details
816
+	 * @return EE_Form_Section_Proper
817
+	 * @throws EE_Error
818
+	 * @throws InvalidArgumentException
819
+	 * @throws InvalidDataTypeException
820
+	 * @throws InvalidInterfaceException
821
+	 */
822
+	private function _display_payment_options($transaction_details = '')
823
+	{
824
+		// has method_of_payment been set by no-js user?
825
+		$this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment();
826
+		// build payment options form
827
+		return apply_filters(
828
+			'FHEE__EE_SPCO_Reg_Step_Payment_Options___display_payment_options__payment_options_form',
829
+			new EE_Form_Section_Proper(
830
+				[
831
+					'subsections'     => [
832
+						'before_payment_options' => apply_filters(
833
+							'FHEE__EE_SPCO_Reg_Step_Payment_Options___display_payment_options__before_payment_options',
834
+							new EE_Form_Section_Proper(
835
+								['layout_strategy' => new EE_Div_Per_Section_Layout()]
836
+							)
837
+						),
838
+						'payment_options'        => $this->_setup_payment_options(),
839
+						'after_payment_options'  => apply_filters(
840
+							'FHEE__EE_SPCO_Reg_Step_Payment_Options___display_payment_options__after_payment_options',
841
+							new EE_Form_Section_Proper(
842
+								['layout_strategy' => new EE_Div_Per_Section_Layout()]
843
+							)
844
+						),
845
+					],
846
+					'layout_strategy' => new EE_Template_Layout(
847
+						[
848
+							'layout_template_file' => $this->_template,
849
+							'template_args'        => apply_filters(
850
+								'FHEE__EE_SPCO_Reg_Step_Payment_Options___display_payment_options__template_args',
851
+								[
852
+									'reg_count'                 => $this->line_item_display->total_items(),
853
+									'transaction_details'       => $transaction_details,
854
+									'available_payment_methods' => [],
855
+								]
856
+							),
857
+						]
858
+					),
859
+				]
860
+			)
861
+		);
862
+	}
863
+
864
+
865
+	/**
866
+	 * _extra_hidden_inputs
867
+	 *
868
+	 * @param bool $no_payment_required
869
+	 * @return EE_Form_Section_Proper
870
+	 * @throws EE_Error
871
+	 * @throws ReflectionException
872
+	 */
873
+	private function _extra_hidden_inputs($no_payment_required = true)
874
+	{
875
+		return new EE_Form_Section_Proper(
876
+			[
877
+				'html_id'         => 'ee-' . $this->slug() . '-extra-hidden-inputs',
878
+				'layout_strategy' => new EE_Div_Per_Section_Layout(),
879
+				'subsections'     => [
880
+					'spco_no_payment_required' => new EE_Hidden_Input(
881
+						[
882
+							'normalization_strategy' => new EE_Boolean_Normalization(),
883
+							'html_name'              => 'spco_no_payment_required',
884
+							'html_id'                => 'spco-no-payment-required-payment_options',
885
+							'default'                => $no_payment_required,
886
+						]
887
+					),
888
+					'spco_transaction_id'      => new EE_Fixed_Hidden_Input(
889
+						[
890
+							'normalization_strategy' => new EE_Int_Normalization(),
891
+							'html_name'              => 'spco_transaction_id',
892
+							'html_id'                => 'spco-transaction-id',
893
+							'default'                => $this->checkout->transaction->ID(),
894
+						]
895
+					),
896
+				],
897
+			]
898
+		);
899
+	}
900
+
901
+
902
+	/**
903
+	 *    _apply_registration_payments_to_amount_owing
904
+	 *
905
+	 * @param array $registrations
906
+	 * @throws EE_Error
907
+	 */
908
+	protected function _apply_registration_payments_to_amount_owing(array $registrations)
909
+	{
910
+		$payments = [];
911
+		foreach ($registrations as $registration) {
912
+			if ($registration instanceof EE_Registration && $registration->owes_monies_and_can_pay()) {
913
+				$payments += $registration->registration_payments();
914
+			}
915
+		}
916
+		if (! empty($payments)) {
917
+			foreach ($payments as $payment) {
918
+				if ($payment instanceof EE_Registration_Payment) {
919
+					$this->checkout->amount_owing -= $payment->amount();
920
+				}
921
+			}
922
+		}
923
+	}
924
+
925
+
926
+	/**
927
+	 *    _reset_selected_method_of_payment
928
+	 *
929
+	 * @access    private
930
+	 * @param bool $force_reset
931
+	 * @return void
932
+	 * @throws InvalidArgumentException
933
+	 * @throws InvalidDataTypeException
934
+	 * @throws InvalidInterfaceException
935
+	 */
936
+	private function _reset_selected_method_of_payment($force_reset = false)
937
+	{
938
+		/** @var RequestInterface $request */
939
+		$request              = LoaderFactory::getLoader()->getShared(RequestInterface::class);
940
+		$reset_payment_method = $request->getRequestParam('reset_payment_method', $force_reset, 'bool');
941
+		if ($reset_payment_method) {
942
+			$this->checkout->selected_method_of_payment = null;
943
+			$this->checkout->payment_method             = null;
944
+			$this->checkout->billing_form               = null;
945
+			$this->_save_selected_method_of_payment();
946
+		}
947
+	}
948
+
949
+
950
+	/**
951
+	 * _save_selected_method_of_payment
952
+	 * stores the selected_method_of_payment in the session
953
+	 * so that it's available for all subsequent requests including AJAX
954
+	 *
955
+	 * @access        private
956
+	 * @param string $selected_method_of_payment
957
+	 * @return void
958
+	 * @throws InvalidArgumentException
959
+	 * @throws InvalidDataTypeException
960
+	 * @throws InvalidInterfaceException
961
+	 */
962
+	private function _save_selected_method_of_payment($selected_method_of_payment = '')
963
+	{
964
+		$selected_method_of_payment = ! empty($selected_method_of_payment)
965
+			? $selected_method_of_payment
966
+			: $this->checkout->selected_method_of_payment;
967
+		EE_Registry::instance()->SSN->set_session_data(
968
+			['selected_method_of_payment' => $selected_method_of_payment]
969
+		);
970
+	}
971
+
972
+
973
+	/**
974
+	 * _setup_payment_options
975
+	 *
976
+	 * @return EE_Form_Section_Proper
977
+	 * @throws EE_Error
978
+	 * @throws InvalidArgumentException
979
+	 * @throws InvalidDataTypeException
980
+	 * @throws InvalidInterfaceException
981
+	 */
982
+	public function _setup_payment_options()
983
+	{
984
+		// load payment method classes
985
+		$this->checkout->available_payment_methods = $this->_get_available_payment_methods();
986
+		if (empty($this->checkout->available_payment_methods)) {
987
+			EE_Error::add_error(
988
+				apply_filters(
989
+					'FHEE__EE_SPCO_Reg_Step_Payment_Options___setup_payment_options__error_message_no_payment_methods',
990
+					sprintf(
991
+						esc_html__(
992
+							'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.',
993
+							'event_espresso'
994
+						),
995
+						'<br>',
996
+						EE_Registry::instance()->CFG->organization->get_pretty('email')
997
+					)
998
+				),
999
+				__FILE__,
1000
+				__FUNCTION__,
1001
+				__LINE__
1002
+			);
1003
+		}
1004
+		// switch up header depending on number of available payment methods
1005
+		$payment_method_header     = count($this->checkout->available_payment_methods) > 1
1006
+			? apply_filters(
1007
+				'FHEE__registration_page_payment_options__method_of_payment_hdr',
1008
+				esc_html__('Please Select Your Method of Payment', 'event_espresso')
1009
+			)
1010
+			: apply_filters(
1011
+				'FHEE__registration_page_payment_options__method_of_payment_hdr',
1012
+				esc_html__('Method of Payment', 'event_espresso')
1013
+			);
1014
+		$available_payment_methods = [
1015
+			// display the "Payment Method" header
1016
+			'payment_method_header' => new EE_Form_Section_HTML(
1017
+				apply_filters(
1018
+					'FHEE__EE_SPCO_Reg_Step_Payment_Options___setup_payment_options__payment_method_header',
1019
+					EEH_HTML::h4($payment_method_header, 'method-of-payment-hdr'),
1020
+					$payment_method_header
1021
+				)
1022
+			),
1023
+		];
1024
+		// the list of actual payment methods ( invoice, PayPal, etc ) in a  ( slug => HTML )  format
1025
+		$available_payment_method_options = [];
1026
+		$default_payment_method_option    = [];
1027
+		// additional instructions to be displayed and hidden below payment methods (adding a clearing div to start)
1028
+		$payment_methods_billing_info = [
1029
+			new EE_Form_Section_HTML(
1030
+				EEH_HTML::div('<br />', '', '', 'clear:both;')
1031
+			),
1032
+		];
1033
+		// loop through payment methods
1034
+		foreach ($this->checkout->available_payment_methods as $payment_method) {
1035
+			if ($payment_method instanceof EE_Payment_Method) {
1036
+				$payment_method_button = EEH_HTML::img(
1037
+					$payment_method->button_url(),
1038
+					$payment_method->name(),
1039
+					'spco-payment-method-' . $payment_method->slug() . '-btn-img',
1040
+					'spco-payment-method-btn-img'
1041
+				);
1042
+				// check if any payment methods are set as default
1043
+				// if payment method is already selected OR nothing is selected and this payment method should be
1044
+				// open_by_default
1045
+				if (
1046
+					($this->checkout->selected_method_of_payment === $payment_method->slug())
1047
+					|| (! $this->checkout->selected_method_of_payment && $payment_method->open_by_default())
1048
+				) {
1049
+					$this->checkout->selected_method_of_payment = $payment_method->slug();
1050
+					$this->_save_selected_method_of_payment();
1051
+					$default_payment_method_option[ $payment_method->slug() ] = $payment_method_button;
1052
+				} else {
1053
+					$available_payment_method_options[ $payment_method->slug() ] = $payment_method_button;
1054
+				}
1055
+				$payment_methods_billing_info[ $payment_method->slug() . '-info' ] =
1056
+					$this->_payment_method_billing_info(
1057
+						$payment_method
1058
+					);
1059
+			}
1060
+		}
1061
+		// prepend available_payment_method_options with default_payment_method_option so that it appears first in list
1062
+		// of PMs
1063
+		$available_payment_method_options = $default_payment_method_option + $available_payment_method_options;
1064
+		// now generate the actual form  inputs
1065
+		$available_payment_methods['available_payment_methods'] = $this->_available_payment_method_inputs(
1066
+			$available_payment_method_options
1067
+		);
1068
+		$available_payment_methods                              += $payment_methods_billing_info;
1069
+		// build the available payment methods form
1070
+		return new EE_Form_Section_Proper(
1071
+			[
1072
+				'html_id'         => 'spco-available-methods-of-payment-dv',
1073
+				'subsections'     => $available_payment_methods,
1074
+				'layout_strategy' => new EE_Div_Per_Section_Layout(),
1075
+			]
1076
+		);
1077
+	}
1078
+
1079
+
1080
+	/**
1081
+	 * _get_available_payment_methods
1082
+	 *
1083
+	 * @return EE_Payment_Method[]
1084
+	 * @throws EE_Error
1085
+	 * @throws InvalidArgumentException
1086
+	 * @throws InvalidDataTypeException
1087
+	 * @throws InvalidInterfaceException
1088
+	 */
1089
+	protected function _get_available_payment_methods()
1090
+	{
1091
+		if (! empty($this->checkout->available_payment_methods)) {
1092
+			return $this->checkout->available_payment_methods;
1093
+		}
1094
+		$available_payment_methods = [];
1095
+		$EEM_Payment_Method        = EEM_Payment_Method::instance();
1096
+		// get all active payment methods
1097
+		$payment_methods = $EEM_Payment_Method->get_all_for_transaction(
1098
+			$this->checkout->transaction,
1099
+			EEM_Payment_Method::scope_cart
1100
+		);
1101
+		foreach ($payment_methods as $payment_method) {
1102
+			if ($payment_method instanceof EE_Payment_Method) {
1103
+				$available_payment_methods[ $payment_method->slug() ] = $payment_method;
1104
+			}
1105
+		}
1106
+		return $available_payment_methods;
1107
+	}
1108
+
1109
+
1110
+	/**
1111
+	 *    _available_payment_method_inputs
1112
+	 *
1113
+	 * @access    private
1114
+	 * @param array $available_payment_method_options
1115
+	 * @return    EE_Form_Section_Proper
1116
+	 * @throws EE_Error
1117
+	 * @throws EE_Error
1118
+	 */
1119
+	private function _available_payment_method_inputs($available_payment_method_options = [])
1120
+	{
1121
+		// generate inputs
1122
+		return new EE_Form_Section_Proper(
1123
+			[
1124
+				'html_id'         => 'ee-available-payment-method-inputs',
1125
+				'layout_strategy' => new EE_Div_Per_Section_Layout(),
1126
+				'subsections'     => [
1127
+					'' => new EE_Radio_Button_Input(
1128
+						$available_payment_method_options,
1129
+						[
1130
+							'html_name'          => 'selected_method_of_payment',
1131
+							'html_class'         => 'spco-payment-method',
1132
+							'default'            => $this->checkout->selected_method_of_payment,
1133
+							'label_size'         => 11,
1134
+							'enforce_label_size' => true,
1135
+						]
1136
+					),
1137
+				],
1138
+			]
1139
+		);
1140
+	}
1141
+
1142
+
1143
+	/**
1144
+	 *    _payment_method_billing_info
1145
+	 *
1146
+	 * @access    private
1147
+	 * @param EE_Payment_Method $payment_method
1148
+	 * @return EE_Form_Section_Proper
1149
+	 * @throws EE_Error
1150
+	 * @throws InvalidArgumentException
1151
+	 * @throws InvalidDataTypeException
1152
+	 * @throws InvalidInterfaceException
1153
+	 */
1154
+	private function _payment_method_billing_info(EE_Payment_Method $payment_method)
1155
+	{
1156
+		$currently_selected = $this->checkout->selected_method_of_payment === $payment_method->slug();
1157
+		// generate the billing form for payment method
1158
+		$billing_form                 = $currently_selected
1159
+			? $this->_get_billing_form_for_payment_method($payment_method)
1160
+			: new EE_Form_Section_HTML();
1161
+		$this->checkout->billing_form = $currently_selected
1162
+			? $billing_form
1163
+			: $this->checkout->billing_form;
1164
+		// it's all in the details
1165
+		$info_html = EEH_HTML::h3(
1166
+			esc_html__('Important information regarding your payment', 'event_espresso'),
1167
+			'',
1168
+			'spco-payment-method-hdr'
1169
+		);
1170
+		// add some info regarding the step, either from what's saved in the admin,
1171
+		// or a default string depending on whether the PM has a billing form or not
1172
+		if ($payment_method->description()) {
1173
+			$payment_method_info = $payment_method->description();
1174
+		} elseif ($billing_form instanceof EE_Billing_Info_Form) {
1175
+			$payment_method_info = sprintf(
1176
+				esc_html__(
1177
+					'Please provide the following billing information, then click the "%1$s" button below in order to proceed.',
1178
+					'event_espresso'
1179
+				),
1180
+				$this->submit_button_text()
1181
+			);
1182
+		} else {
1183
+			$payment_method_info = sprintf(
1184
+				esc_html__('Please click the "%1$s" button below in order to proceed.', 'event_espresso'),
1185
+				$this->submit_button_text()
1186
+			);
1187
+		}
1188
+		$info_html .= EEH_HTML::div(
1189
+			apply_filters(
1190
+				'FHEE__EE_SPCO_Reg_Step_Payment_Options___payment_method_billing_info__payment_method_info',
1191
+				$payment_method_info
1192
+			),
1193
+			'',
1194
+			'spco-payment-method-desc ee-attention'
1195
+		);
1196
+		return new EE_Form_Section_Proper(
1197
+			[
1198
+				'html_id'         => 'spco-payment-method-info-' . $payment_method->slug(),
1199
+				'html_class'      => 'spco-payment-method-info-dv',
1200
+				// only display the selected or default PM
1201
+				'html_style'      => $currently_selected ? '' : 'display:none;',
1202
+				'layout_strategy' => new EE_Div_Per_Section_Layout(),
1203
+				'subsections'     => [
1204
+					'info'         => new EE_Form_Section_HTML($info_html),
1205
+					'billing_form' => $currently_selected ? $billing_form : new EE_Form_Section_HTML(),
1206
+				],
1207
+			]
1208
+		);
1209
+	}
1210
+
1211
+
1212
+	/**
1213
+	 * get_billing_form_html_for_payment_method
1214
+	 *
1215
+	 * @return bool
1216
+	 * @throws EE_Error
1217
+	 * @throws InvalidArgumentException
1218
+	 * @throws ReflectionException
1219
+	 * @throws InvalidDataTypeException
1220
+	 * @throws InvalidInterfaceException
1221
+	 */
1222
+	public function get_billing_form_html_for_payment_method()
1223
+	{
1224
+		// how have they chosen to pay?
1225
+		$this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment(true);
1226
+		$this->checkout->payment_method             = $this->_get_payment_method_for_selected_method_of_payment();
1227
+		if (! $this->checkout->payment_method instanceof EE_Payment_Method) {
1228
+			return false;
1229
+		}
1230
+		if (
1231
+			apply_filters(
1232
+				'FHEE__EE_SPCO_Reg_Step_Payment_Options__registration_checkout__selected_payment_method__display_success',
1233
+				false
1234
+			)
1235
+		) {
1236
+			EE_Error::add_success(
1237
+				apply_filters(
1238
+					'FHEE__Single_Page_Checkout__registration_checkout__selected_payment_method',
1239
+					sprintf(
1240
+						esc_html__(
1241
+							'You have selected "%s" as your method of payment. Please note the important payment information below.',
1242
+							'event_espresso'
1243
+						),
1244
+						$this->checkout->payment_method->name()
1245
+					)
1246
+				)
1247
+			);
1248
+		}
1249
+		// now generate billing form for selected method of payment
1250
+		$payment_method_billing_form = $this->_get_billing_form_for_payment_method($this->checkout->payment_method);
1251
+		// fill form with attendee info if applicable
1252
+		if (
1253
+			$payment_method_billing_form instanceof EE_Billing_Attendee_Info_Form
1254
+			&& $this->checkout->transaction_has_primary_registrant()
1255
+		) {
1256
+			$payment_method_billing_form->populate_from_attendee(
1257
+				$this->checkout->transaction->primary_registration()->attendee()
1258
+			);
1259
+		}
1260
+		// and debug content
1261
+		if (
1262
+			$payment_method_billing_form instanceof EE_Billing_Info_Form
1263
+			&& $this->checkout->payment_method->type_obj() instanceof EE_PMT_Base
1264
+		) {
1265
+			$payment_method_billing_form =
1266
+				$this->checkout->payment_method->type_obj()->apply_billing_form_debug_settings(
1267
+					$payment_method_billing_form
1268
+				);
1269
+		}
1270
+		$billing_info = $payment_method_billing_form instanceof EE_Form_Section_Proper
1271
+			? $payment_method_billing_form->get_html()
1272
+			: '';
1273
+		$this->checkout->json_response->set_return_data(['payment_method_info' => $billing_info]);
1274
+		// localize validation rules for main form
1275
+		$this->checkout->current_step->reg_form->localize_validation_rules();
1276
+		$this->checkout->json_response->add_validation_rules(EE_Form_Section_Proper::js_localization());
1277
+		return true;
1278
+	}
1279
+
1280
+
1281
+	/**
1282
+	 * _get_billing_form_for_payment_method
1283
+	 *
1284
+	 * @param EE_Payment_Method $payment_method
1285
+	 * @return EE_Billing_Info_Form|EE_Billing_Attendee_Info_Form|EE_Form_Section_HTML
1286
+	 * @throws EE_Error
1287
+	 * @throws InvalidArgumentException
1288
+	 * @throws InvalidDataTypeException
1289
+	 * @throws InvalidInterfaceException
1290
+	 */
1291
+	private function _get_billing_form_for_payment_method(EE_Payment_Method $payment_method)
1292
+	{
1293
+		$billing_form = $payment_method->type_obj()->billing_form(
1294
+			$this->checkout->transaction,
1295
+			['amount_owing' => $this->checkout->amount_owing]
1296
+		);
1297
+		if ($billing_form instanceof EE_Billing_Info_Form) {
1298
+			if (
1299
+				apply_filters(
1300
+					'FHEE__EE_SPCO_Reg_Step_Payment_Options__registration_checkout__selected_payment_method__display_success',
1301
+					false
1302
+				)
1303
+				&& $this->request->requestParamIsSet('payment_method')
1304
+			) {
1305
+				EE_Error::add_success(
1306
+					apply_filters(
1307
+						'FHEE__Single_Page_Checkout__registration_checkout__selected_payment_method',
1308
+						sprintf(
1309
+							esc_html__(
1310
+								'You have selected "%s" as your method of payment. Please note the important payment information below.',
1311
+								'event_espresso'
1312
+							),
1313
+							$payment_method->name()
1314
+						)
1315
+					)
1316
+				);
1317
+			}
1318
+			return apply_filters(
1319
+				'FHEE__EE_SPCO_Reg_Step_Payment_Options___get_billing_form_for_payment_method__billing_form',
1320
+				$billing_form,
1321
+				$payment_method
1322
+			);
1323
+		}
1324
+		// no actual billing form, so return empty HTML form section
1325
+		return new EE_Form_Section_HTML();
1326
+	}
1327
+
1328
+
1329
+	/**
1330
+	 * _get_selected_method_of_payment
1331
+	 *
1332
+	 * @param boolean $required whether to throw an error if the "selected_method_of_payment"
1333
+	 *                          is not found in the incoming request
1334
+	 * @param string  $request_param
1335
+	 * @return NULL|string
1336
+	 * @throws EE_Error
1337
+	 * @throws InvalidArgumentException
1338
+	 * @throws InvalidDataTypeException
1339
+	 * @throws InvalidInterfaceException
1340
+	 */
1341
+	private function _get_selected_method_of_payment(
1342
+		$required = false,
1343
+		$request_param = 'selected_method_of_payment'
1344
+	) {
1345
+		// is selected_method_of_payment set in the request ?
1346
+		$selected_method_of_payment = $this->request->getRequestParam($request_param);
1347
+		if ($selected_method_of_payment) {
1348
+			// sanitize it
1349
+			$selected_method_of_payment = is_array($selected_method_of_payment)
1350
+				? array_shift($selected_method_of_payment)
1351
+				: $selected_method_of_payment;
1352
+			$selected_method_of_payment = sanitize_text_field($selected_method_of_payment);
1353
+			// store it in the session so that it's available for all subsequent requests including AJAX
1354
+			$this->_save_selected_method_of_payment($selected_method_of_payment);
1355
+		} else {
1356
+			// or is it set in the session ?
1357
+			$selected_method_of_payment = EE_Registry::instance()->SSN->get_session_data(
1358
+				'selected_method_of_payment'
1359
+			);
1360
+		}
1361
+		if (empty($selected_method_of_payment) && $required) {
1362
+			EE_Error::add_error(
1363
+				sprintf(
1364
+					esc_html__(
1365
+						'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.',
1366
+						'event_espresso'
1367
+					),
1368
+					'<br/>',
1369
+					'<br/>',
1370
+					EE_Registry::instance()->CFG->organization->get_pretty('email')
1371
+				),
1372
+				__FILE__,
1373
+				__FUNCTION__,
1374
+				__LINE__
1375
+			);
1376
+			return null;
1377
+		}
1378
+		return $selected_method_of_payment;
1379
+	}
1380
+
1381
+
1382
+
1383
+
1384
+
1385
+
1386
+	/********************************************************************************************************/
1387
+	/***********************************  SWITCH PAYMENT METHOD  ************************************/
1388
+	/********************************************************************************************************/
1389
+	/**
1390
+	 * switch_payment_method
1391
+	 *
1392
+	 * @return bool
1393
+	 * @throws EE_Error
1394
+	 * @throws InvalidArgumentException
1395
+	 * @throws InvalidDataTypeException
1396
+	 * @throws InvalidInterfaceException
1397
+	 * @throws ReflectionException
1398
+	 */
1399
+	public function switch_payment_method()
1400
+	{
1401
+		if (! $this->_verify_payment_method_is_set()) {
1402
+			return false;
1403
+		}
1404
+		if (
1405
+			apply_filters(
1406
+				'FHEE__EE_SPCO_Reg_Step_Payment_Options__registration_checkout__selected_payment_method__display_success',
1407
+				false
1408
+			)
1409
+		) {
1410
+			EE_Error::add_success(
1411
+				apply_filters(
1412
+					'FHEE__Single_Page_Checkout__registration_checkout__selected_payment_method',
1413
+					sprintf(
1414
+						esc_html__(
1415
+							'You have selected "%s" as your method of payment. Please note the important payment information below.',
1416
+							'event_espresso'
1417
+						),
1418
+						$this->checkout->payment_method->name()
1419
+					)
1420
+				)
1421
+			);
1422
+		}
1423
+		// generate billing form for selected method of payment if it hasn't been done already
1424
+		if ($this->checkout->payment_method->type_obj()->has_billing_form()) {
1425
+			$this->checkout->billing_form = $this->_get_billing_form_for_payment_method(
1426
+				$this->checkout->payment_method
1427
+			);
1428
+		}
1429
+		// fill form with attendee info if applicable
1430
+		if (
1431
+			apply_filters(
1432
+				'FHEE__populate_billing_form_fields_from_attendee',
1433
+				(
1434
+					$this->checkout->billing_form instanceof EE_Billing_Attendee_Info_Form
1435
+					&& $this->checkout->transaction_has_primary_registrant()
1436
+				),
1437
+				$this->checkout->billing_form,
1438
+				$this->checkout->transaction
1439
+			)
1440
+		) {
1441
+			$this->checkout->billing_form->populate_from_attendee(
1442
+				$this->checkout->transaction->primary_registration()->attendee()
1443
+			);
1444
+		}
1445
+		// and debug content
1446
+		if (
1447
+			$this->checkout->billing_form instanceof EE_Billing_Info_Form
1448
+			&& $this->checkout->payment_method->type_obj() instanceof EE_PMT_Base
1449
+		) {
1450
+			$this->checkout->billing_form =
1451
+				$this->checkout->payment_method->type_obj()->apply_billing_form_debug_settings(
1452
+					$this->checkout->billing_form
1453
+				);
1454
+		}
1455
+		// get html and validation rules for form
1456
+		if ($this->checkout->billing_form instanceof EE_Form_Section_Proper) {
1457
+			$this->checkout->json_response->set_return_data(
1458
+				['payment_method_info' => $this->checkout->billing_form->get_html()]
1459
+			);
1460
+			// localize validation rules for main form
1461
+			$this->checkout->billing_form->localize_validation_rules(true);
1462
+			$this->checkout->json_response->add_validation_rules(EE_Form_Section_Proper::js_localization());
1463
+		} else {
1464
+			$this->checkout->json_response->set_return_data(['payment_method_info' => '']);
1465
+		}
1466
+		// prevents advancement to next step
1467
+		$this->checkout->continue_reg = false;
1468
+		return true;
1469
+	}
1470
+
1471
+
1472
+	/**
1473
+	 * _verify_payment_method_is_set
1474
+	 *
1475
+	 * @return bool
1476
+	 * @throws EE_Error
1477
+	 * @throws InvalidArgumentException
1478
+	 * @throws ReflectionException
1479
+	 * @throws InvalidDataTypeException
1480
+	 * @throws InvalidInterfaceException
1481
+	 */
1482
+	protected function _verify_payment_method_is_set()
1483
+	{
1484
+		// generate billing form for selected method of payment if it hasn't been done already
1485
+		if (empty($this->checkout->selected_method_of_payment)) {
1486
+			// how have they chosen to pay?
1487
+			$this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment(true);
1488
+		} else {
1489
+			// choose your own adventure based on method_of_payment
1490
+			switch ($this->checkout->selected_method_of_payment) {
1491
+				case 'events_sold_out':
1492
+					EE_Error::add_attention(
1493
+						apply_filters(
1494
+							'FHEE__EE_SPCO_Reg_Step_Payment_Options___verify_payment_method_is_set__sold_out_events_msg',
1495
+							esc_html__(
1496
+								'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.',
1497
+								'event_espresso'
1498
+							)
1499
+						),
1500
+						__FILE__,
1501
+						__FUNCTION__,
1502
+						__LINE__
1503
+					);
1504
+					return false;
1505
+				case 'payments_closed':
1506
+					EE_Error::add_attention(
1507
+						apply_filters(
1508
+							'FHEE__EE_SPCO_Reg_Step_Payment_Options___verify_payment_method_is_set__payments_closed_msg',
1509
+							esc_html__(
1510
+								'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.',
1511
+								'event_espresso'
1512
+							)
1513
+						),
1514
+						__FILE__,
1515
+						__FUNCTION__,
1516
+						__LINE__
1517
+					);
1518
+					return false;
1519
+				case 'no_payment_required':
1520
+					EE_Error::add_attention(
1521
+						apply_filters(
1522
+							'FHEE__EE_SPCO_Reg_Step_Payment_Options___verify_payment_method_is_set__no_payment_required_msg',
1523
+							esc_html__(
1524
+								'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.',
1525
+								'event_espresso'
1526
+							)
1527
+						),
1528
+						__FILE__,
1529
+						__FUNCTION__,
1530
+						__LINE__
1531
+					);
1532
+					return false;
1533
+				default:
1534
+			}
1535
+		}
1536
+		// verify payment method
1537
+		if (! $this->checkout->payment_method instanceof EE_Payment_Method) {
1538
+			// get payment method for selected method of payment
1539
+			$this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment();
1540
+		}
1541
+		return $this->checkout->payment_method instanceof EE_Payment_Method;
1542
+	}
1543
+
1544
+
1545
+
1546
+	/********************************************************************************************************/
1547
+	/***************************************  SAVE PAYER DETAILS  ****************************************/
1548
+	/********************************************************************************************************/
1549
+	/**
1550
+	 * save_payer_details_via_ajax
1551
+	 *
1552
+	 * @return void
1553
+	 * @throws EE_Error
1554
+	 * @throws InvalidArgumentException
1555
+	 * @throws ReflectionException
1556
+	 * @throws RuntimeException
1557
+	 * @throws InvalidDataTypeException
1558
+	 * @throws InvalidInterfaceException
1559
+	 */
1560
+	public function save_payer_details_via_ajax()
1561
+	{
1562
+		if (! $this->_verify_payment_method_is_set()) {
1563
+			return;
1564
+		}
1565
+		// generate billing form for selected method of payment if it hasn't been done already
1566
+		if ($this->checkout->payment_method->type_obj()->has_billing_form()) {
1567
+			$this->checkout->billing_form = $this->_get_billing_form_for_payment_method(
1568
+				$this->checkout->payment_method
1569
+			);
1570
+		}
1571
+		// generate primary attendee from payer info if applicable
1572
+		if (! $this->checkout->transaction_has_primary_registrant()) {
1573
+			$attendee = $this->_create_attendee_from_request_data();
1574
+			if ($attendee instanceof EE_Attendee) {
1575
+				foreach ($this->checkout->transaction->registrations() as $registration) {
1576
+					if ($registration->is_primary_registrant()) {
1577
+						$this->checkout->primary_attendee_obj = $attendee;
1578
+						$registration->_add_relation_to($attendee, 'Attendee');
1579
+						$registration->set_attendee_id($attendee->ID());
1580
+						$registration->update_cache_after_object_save('Attendee', $attendee);
1581
+					}
1582
+				}
1583
+			}
1584
+		}
1585
+	}
1586
+
1587
+
1588
+	/**
1589
+	 * create_attendee_from_request_data
1590
+	 * uses info from alternate GET or POST data (such as AJAX) to create a new attendee
1591
+	 *
1592
+	 * @return EE_Attendee
1593
+	 * @throws EE_Error
1594
+	 * @throws InvalidArgumentException
1595
+	 * @throws ReflectionException
1596
+	 * @throws InvalidDataTypeException
1597
+	 * @throws InvalidInterfaceException
1598
+	 */
1599
+	protected function _create_attendee_from_request_data()
1600
+	{
1601
+		// get State ID
1602
+		$STA_ID = $this->request->getRequestParam('state');
1603
+		if (! empty($STA_ID)) {
1604
+			// can we get state object from name ?
1605
+			EE_Registry::instance()->load_model('State');
1606
+			$state  = EEM_State::instance()->get_col([['STA_name' => $STA_ID], 'limit' => 1], 'STA_ID');
1607
+			$STA_ID = is_array($state) && ! empty($state) ? reset($state) : $STA_ID;
1608
+		}
1609
+		// get Country ISO
1610
+		$CNT_ISO = $this->request->getRequestParam('country');
1611
+		if (! empty($CNT_ISO)) {
1612
+			// can we get country object from name ?
1613
+			EE_Registry::instance()->load_model('Country');
1614
+			$country = EEM_Country::instance()->get_col(
1615
+				[['CNT_name' => $CNT_ISO], 'limit' => 1],
1616
+				'CNT_ISO'
1617
+			);
1618
+			$CNT_ISO = is_array($country) && ! empty($country) ? reset($country) : $CNT_ISO;
1619
+		}
1620
+		// grab attendee data
1621
+		$attendee_data = [
1622
+			'ATT_fname'    => $this->request->getRequestParam('first_name'),
1623
+			'ATT_lname'    => $this->request->getRequestParam('last_name'),
1624
+			'ATT_email'    => $this->request->getRequestParam('email'),
1625
+			'ATT_address'  => $this->request->getRequestParam('address'),
1626
+			'ATT_address2' => $this->request->getRequestParam('address2'),
1627
+			'ATT_city'     => $this->request->getRequestParam('city'),
1628
+			'STA_ID'       => $STA_ID,
1629
+			'CNT_ISO'      => $CNT_ISO,
1630
+			'ATT_zip'      => $this->request->getRequestParam('zip'),
1631
+			'ATT_phone'    => $this->request->getRequestParam('phone'),
1632
+		];
1633
+		// validate the email address since it is the most important piece of info
1634
+		if (empty($attendee_data['ATT_email'])) {
1635
+			EE_Error::add_error(
1636
+				esc_html__('An invalid email address was submitted.', 'event_espresso'),
1637
+				__FILE__,
1638
+				__FUNCTION__,
1639
+				__LINE__
1640
+			);
1641
+		}
1642
+		// does this attendee already exist in the db ? we're searching using a combination of first name, last name,
1643
+		// AND email address
1644
+		if (
1645
+			! empty($attendee_data['ATT_fname'])
1646
+			&& ! empty($attendee_data['ATT_lname'])
1647
+			&& ! empty($attendee_data['ATT_email'])
1648
+		) {
1649
+			$existing_attendee = EEM_Attendee::instance()->find_existing_attendee(
1650
+				[
1651
+					'ATT_fname' => $attendee_data['ATT_fname'],
1652
+					'ATT_lname' => $attendee_data['ATT_lname'],
1653
+					'ATT_email' => $attendee_data['ATT_email'],
1654
+				]
1655
+			);
1656
+			if ($existing_attendee instanceof EE_Attendee) {
1657
+				return $existing_attendee;
1658
+			}
1659
+		}
1660
+		// no existing attendee? kk let's create a new one
1661
+		// kinda lame, but we need a first and last name to create an attendee, so use the email address if those
1662
+		// don't exist
1663
+		$attendee_data['ATT_fname'] = ! empty($attendee_data['ATT_fname'])
1664
+			? $attendee_data['ATT_fname']
1665
+			: $attendee_data['ATT_email'];
1666
+		$attendee_data['ATT_lname'] = ! empty($attendee_data['ATT_lname'])
1667
+			? $attendee_data['ATT_lname']
1668
+			: $attendee_data['ATT_email'];
1669
+		return EE_Attendee::new_instance($attendee_data);
1670
+	}
1671
+
1672
+
1673
+
1674
+	/********************************************************************************************************/
1675
+	/****************************************  PROCESS REG STEP  *****************************************/
1676
+	/********************************************************************************************************/
1677
+	/**
1678
+	 * process_reg_step
1679
+	 *
1680
+	 * @return bool
1681
+	 * @throws EE_Error
1682
+	 * @throws InvalidArgumentException
1683
+	 * @throws ReflectionException
1684
+	 * @throws EntityNotFoundException
1685
+	 * @throws InvalidDataTypeException
1686
+	 * @throws InvalidInterfaceException
1687
+	 * @throws InvalidStatusException
1688
+	 */
1689
+	public function process_reg_step()
1690
+	{
1691
+		// how have they chosen to pay?
1692
+		$this->checkout->selected_method_of_payment = $this->checkout->transaction->is_free()
1693
+			? 'no_payment_required'
1694
+			: $this->_get_selected_method_of_payment(true);
1695
+		// choose your own adventure based on method_of_payment
1696
+		switch ($this->checkout->selected_method_of_payment) {
1697
+			case 'events_sold_out':
1698
+				$this->checkout->redirect     = true;
1699
+				$this->checkout->redirect_url = $this->checkout->cancel_page_url;
1700
+				$this->checkout->json_response->set_redirect_url($this->checkout->redirect_url);
1701
+				// mark this reg step as completed
1702
+				$this->set_completed();
1703
+				return false;
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
+
1723
+			case 'no_payment_required':
1724
+				if (
1725
+					apply_filters(
1726
+						'FHEE__EE_SPCO_Reg_Step_Payment_Options__process_reg_step__no_payment_required__display_success',
1727
+						false
1728
+					)
1729
+				) {
1730
+					EE_Error::add_success(
1731
+						esc_html__('no payment required.', 'event_espresso'),
1732
+						__FILE__,
1733
+						__FUNCTION__,
1734
+						__LINE__
1735
+					);
1736
+				}
1737
+				// mark this reg step as completed
1738
+				$this->set_completed();
1739
+				return true;
1740
+
1741
+			default:
1742
+				$registrations         = EE_Registry::instance()->SSN->checkout()->transaction->registrations(
1743
+					EE_Registry::instance()->SSN->checkout()->reg_cache_where_params
1744
+				);
1745
+				$ejected_registrations = EE_SPCO_Reg_Step_Payment_Options::find_registrations_that_lost_their_space(
1746
+					$registrations,
1747
+					EE_Registry::instance()->SSN->checkout()->revisit
1748
+				);
1749
+				// calculate difference between the two arrays
1750
+				$registrations = array_diff($registrations, $ejected_registrations);
1751
+				if (empty($registrations)) {
1752
+					$this->_redirect_because_event_sold_out();
1753
+					return false;
1754
+				}
1755
+				$payment = $this->_process_payment();
1756
+				if ($payment instanceof EE_Payment) {
1757
+					$this->checkout->continue_reg = true;
1758
+					$this->_maybe_set_completed($payment);
1759
+				} else {
1760
+					$this->checkout->continue_reg = false;
1761
+				}
1762
+				return $payment instanceof EE_Payment;
1763
+		}
1764
+	}
1765
+
1766
+
1767
+	/**
1768
+	 * _redirect_because_event_sold_out
1769
+	 *
1770
+	 * @return void
1771
+	 */
1772
+	protected function _redirect_because_event_sold_out()
1773
+	{
1774
+		$this->checkout->continue_reg = false;
1775
+		// set redirect URL
1776
+		$this->checkout->redirect_url = add_query_arg(
1777
+			['e_reg_url_link' => $this->checkout->reg_url_link],
1778
+			$this->checkout->current_step->reg_step_url()
1779
+		);
1780
+		$this->checkout->json_response->set_redirect_url($this->checkout->redirect_url);
1781
+	}
1782
+
1783
+
1784
+	/**
1785
+	 * @param EE_Payment $payment
1786
+	 * @return void
1787
+	 * @throws EE_Error
1788
+	 */
1789
+	protected function _maybe_set_completed(EE_Payment $payment)
1790
+	{
1791
+		// Do we need to redirect them? If so, there's more work to be done.
1792
+		if (! $payment->redirect_url()) {
1793
+			$this->set_completed();
1794
+		}
1795
+	}
1796
+
1797
+
1798
+	/**
1799
+	 *    update_reg_step
1800
+	 *    this is the final step after a user  revisits the site to retry a payment
1801
+	 *
1802
+	 * @return bool
1803
+	 * @throws EE_Error
1804
+	 * @throws InvalidArgumentException
1805
+	 * @throws ReflectionException
1806
+	 * @throws EntityNotFoundException
1807
+	 * @throws InvalidDataTypeException
1808
+	 * @throws InvalidInterfaceException
1809
+	 * @throws InvalidStatusException
1810
+	 */
1811
+	public function update_reg_step()
1812
+	{
1813
+		$success = true;
1814
+		// if payment required
1815
+		if ($this->checkout->transaction->total() > 0) {
1816
+			do_action(
1817
+				'AHEE__EE_Single_Page_Checkout__process_finalize_registration__before_gateway',
1818
+				$this->checkout->transaction
1819
+			);
1820
+			// attempt payment via payment method
1821
+			$success = $this->process_reg_step();
1822
+		}
1823
+		if ($success && ! $this->checkout->redirect) {
1824
+			$this->checkout->cart->get_grand_total()->save_this_and_descendants_to_txn(
1825
+				$this->checkout->transaction->ID()
1826
+			);
1827
+			// set return URL
1828
+			$this->checkout->redirect_url = add_query_arg(
1829
+				['e_reg_url_link' => $this->checkout->reg_url_link],
1830
+				$this->checkout->thank_you_page_url
1831
+			);
1832
+		}
1833
+		return $success;
1834
+	}
1835
+
1836
+
1837
+	/**
1838
+	 * @return EE_Payment|null
1839
+	 * @throws EE_Error
1840
+	 * @throws InvalidArgumentException
1841
+	 * @throws ReflectionException
1842
+	 * @throws RuntimeException
1843
+	 * @throws InvalidDataTypeException
1844
+	 * @throws InvalidInterfaceException
1845
+	 */
1846
+	private function _process_payment()
1847
+	{
1848
+		// basically confirm that the event hasn't sold out since they hit the page
1849
+		if (! $this->_last_second_ticket_verifications()) {
1850
+			return null;
1851
+		}
1852
+		// ya gotta make a choice man
1853
+		if (empty($this->checkout->selected_method_of_payment)) {
1854
+			$this->checkout->json_response->set_plz_select_method_of_payment(
1855
+				esc_html__('Please select a method of payment before proceeding.', 'event_espresso')
1856
+			);
1857
+			return null;
1858
+		}
1859
+		// get EE_Payment_Method object
1860
+		if (! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()) {
1861
+			return null;
1862
+		}
1863
+		// setup billing form
1864
+		if ($this->checkout->payment_method->type_obj()->has_billing_form()) {
1865
+			$this->checkout->billing_form = $this->_get_billing_form_for_payment_method(
1866
+				$this->checkout->payment_method
1867
+			);
1868
+			// bad billing form ?
1869
+			if (! $this->_billing_form_is_valid()) {
1870
+				return null;
1871
+			}
1872
+		}
1873
+		// ensure primary registrant has been fully processed
1874
+		if (! $this->_setup_primary_registrant_prior_to_payment()) {
1875
+			return null;
1876
+		}
1877
+		// if session is close to expiring (under 10 minutes by default)
1878
+		if ((time() - EE_Registry::instance()->SSN->expiration()) < EE_Registry::instance()->SSN->extension()) {
1879
+			// add some time to session expiration so that payment can be completed
1880
+			EE_Registry::instance()->SSN->extend_expiration();
1881
+		}
1882
+		/** @type EE_Transaction_Processor $transaction_processor */
1883
+		// $transaction_processor = EE_Registry::instance()->load_class( 'Transaction_Processor' );
1884
+		// in case a registrant leaves to an Off-Site Gateway and never returns, we want to approve any registrations
1885
+		// for events with a default reg status of Approved
1886
+		// $transaction_processor->toggle_registration_statuses_for_default_approved_events(
1887
+		//      $this->checkout->transaction, $this->checkout->reg_cache_where_params
1888
+		// );
1889
+		// attempt payment
1890
+		$payment = $this->_attempt_payment($this->checkout->payment_method);
1891
+		// process results
1892
+		$payment = $this->_validate_payment($payment);
1893
+		$payment = $this->_post_payment_processing($payment);
1894
+		// verify payment
1895
+		if ($payment instanceof EE_Payment) {
1896
+			// store that for later
1897
+			$this->checkout->payment = $payment;
1898
+			// we can also consider the TXN to not have been failed, so temporarily upgrade its status to abandoned
1899
+			$this->checkout->transaction->toggle_failed_transaction_status();
1900
+			$payment_status = $payment->status();
1901
+			if (
1902
+				$payment_status === EEM_Payment::status_id_approved
1903
+				|| $payment_status === EEM_Payment::status_id_pending
1904
+			) {
1905
+				return $payment;
1906
+			}
1907
+			return null;
1908
+		}
1909
+		if ($payment === true) {
1910
+			// please note that offline payment methods will NOT make a payment,
1911
+			// but instead just mark themselves as the PMD_ID on the transaction, and return true
1912
+			$this->checkout->payment = $payment;
1913
+			return $payment;
1914
+		}
1915
+		// where's my money?
1916
+		return null;
1917
+	}
1918
+
1919
+
1920
+	/**
1921
+	 * _last_second_ticket_verifications
1922
+	 *
1923
+	 * @return bool
1924
+	 * @throws EE_Error
1925
+	 * @throws ReflectionException
1926
+	 */
1927
+	protected function _last_second_ticket_verifications()
1928
+	{
1929
+		// don't bother re-validating if not a return visit
1930
+		if (! $this->checkout->revisit) {
1931
+			return true;
1932
+		}
1933
+		$registrations = $this->checkout->transaction->registrations();
1934
+		if (empty($registrations)) {
1935
+			return false;
1936
+		}
1937
+		foreach ($registrations as $registration) {
1938
+			if ($registration instanceof EE_Registration && ! $registration->is_approved()) {
1939
+				$event = $registration->event_obj();
1940
+				if ($event instanceof EE_Event && $event->is_sold_out(true)) {
1941
+					EE_Error::add_error(
1942
+						apply_filters(
1943
+							'FHEE__EE_SPCO_Reg_Step_Payment_Options___last_second_ticket_verifications__sold_out_events_msg',
1944
+							sprintf(
1945
+								esc_html__(
1946
+									'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.',
1947
+									'event_espresso'
1948
+								),
1949
+								$event->name()
1950
+							)
1951
+						),
1952
+						__FILE__,
1953
+						__FUNCTION__,
1954
+						__LINE__
1955
+					);
1956
+					return false;
1957
+				}
1958
+			}
1959
+		}
1960
+		return true;
1961
+	}
1962
+
1963
+
1964
+	/**
1965
+	 * redirect_form
1966
+	 *
1967
+	 * @return bool
1968
+	 * @throws EE_Error
1969
+	 * @throws InvalidArgumentException
1970
+	 * @throws ReflectionException
1971
+	 * @throws InvalidDataTypeException
1972
+	 * @throws InvalidInterfaceException
1973
+	 */
1974
+	public function redirect_form()
1975
+	{
1976
+		$payment_method_billing_info = $this->_payment_method_billing_info(
1977
+			$this->_get_payment_method_for_selected_method_of_payment()
1978
+		);
1979
+		$html                        = $payment_method_billing_info->get_html();
1980
+		$html                        .= $this->checkout->redirect_form;
1981
+		/** @var ResponseInterface $response */
1982
+		$response = LoaderFactory::getLoader()->getShared(ResponseInterface::class);
1983
+		$response->addOutput($html);
1984
+		return true;
1985
+	}
1986
+
1987
+
1988
+	/**
1989
+	 * _billing_form_is_valid
1990
+	 *
1991
+	 * @return bool
1992
+	 * @throws EE_Error
1993
+	 */
1994
+	private function _billing_form_is_valid()
1995
+	{
1996
+		if (! $this->checkout->payment_method->type_obj()->has_billing_form()) {
1997
+			return true;
1998
+		}
1999
+		if ($this->checkout->billing_form instanceof EE_Billing_Info_Form) {
2000
+			if ($this->checkout->billing_form->was_submitted()) {
2001
+				$this->checkout->billing_form->receive_form_submission();
2002
+				if ($this->checkout->billing_form->is_valid()) {
2003
+					return true;
2004
+				}
2005
+				$validation_errors = $this->checkout->billing_form->get_validation_errors_accumulated();
2006
+				$error_strings     = [];
2007
+				foreach ($validation_errors as $validation_error) {
2008
+					if ($validation_error instanceof EE_Validation_Error) {
2009
+						$form_section = $validation_error->get_form_section();
2010
+						if ($form_section instanceof EE_Form_Input_Base) {
2011
+							$label = $form_section->html_label_text();
2012
+						} elseif ($form_section instanceof EE_Form_Section_Base) {
2013
+							$label = $form_section->name();
2014
+						} else {
2015
+							$label = esc_html__('Validation Error', 'event_espresso');
2016
+						}
2017
+						$error_strings[] = sprintf('%1$s: %2$s', $label, $validation_error->getMessage());
2018
+					}
2019
+				}
2020
+				EE_Error::add_error(
2021
+					sprintf(
2022
+						esc_html__(
2023
+							'One or more billing form inputs are invalid and require correction before proceeding. %1$s %2$s',
2024
+							'event_espresso'
2025
+						),
2026
+						'<br/>',
2027
+						implode('<br/>', $error_strings)
2028
+					),
2029
+					__FILE__,
2030
+					__FUNCTION__,
2031
+					__LINE__
2032
+				);
2033
+			} else {
2034
+				EE_Error::add_error(
2035
+					esc_html__(
2036
+						'The billing form was not submitted or something prevented it\'s submission.',
2037
+						'event_espresso'
2038
+					),
2039
+					__FILE__,
2040
+					__FUNCTION__,
2041
+					__LINE__
2042
+				);
2043
+			}
2044
+		} else {
2045
+			EE_Error::add_error(
2046
+				esc_html__(
2047
+					'The submitted billing form is invalid possibly due to a technical reason.',
2048
+					'event_espresso'
2049
+				),
2050
+				__FILE__,
2051
+				__FUNCTION__,
2052
+				__LINE__
2053
+			);
2054
+		}
2055
+		return false;
2056
+	}
2057
+
2058
+
2059
+	/**
2060
+	 * _setup_primary_registrant_prior_to_payment
2061
+	 * ensures that the primary registrant has a valid attendee object created with the critical details populated
2062
+	 * (first & last name & email) and that both the transaction object and primary registration object have been saved
2063
+	 * plz note that any other registrations will NOT be saved at this point (because they may not have any details
2064
+	 * yet)
2065
+	 *
2066
+	 * @return bool
2067
+	 * @throws EE_Error
2068
+	 * @throws InvalidArgumentException
2069
+	 * @throws ReflectionException
2070
+	 * @throws RuntimeException
2071
+	 * @throws InvalidDataTypeException
2072
+	 * @throws InvalidInterfaceException
2073
+	 */
2074
+	private function _setup_primary_registrant_prior_to_payment()
2075
+	{
2076
+		// check if transaction has a primary registrant and that it has a related Attendee object
2077
+		// if not, then we need to at least gather some primary registrant data before attempting payment
2078
+		if (
2079
+			$this->checkout->billing_form instanceof EE_Billing_Attendee_Info_Form
2080
+			&& ! $this->checkout->transaction_has_primary_registrant()
2081
+			&& ! $this->_capture_primary_registration_data_from_billing_form()
2082
+		) {
2083
+			return false;
2084
+		}
2085
+		// because saving an object clears its cache, we need to do the Chevy Shuffle
2086
+		// grab the primary_registration object
2087
+		$primary_registration = $this->checkout->transaction->primary_registration();
2088
+		// at this point we'll consider a TXN to not have been failed
2089
+		$this->checkout->transaction->toggle_failed_transaction_status();
2090
+		// save the TXN ( which clears cached copy of primary_registration)
2091
+		$this->checkout->transaction->save();
2092
+		// grab TXN ID and save it to the primary_registration
2093
+		$primary_registration->set_transaction_id($this->checkout->transaction->ID());
2094
+		// save what we have so far
2095
+		$primary_registration->save();
2096
+		return true;
2097
+	}
2098
+
2099
+
2100
+	/**
2101
+	 * Captures primary registration data from the billing form.
2102
+	 *
2103
+	 * This method is used to gather the primary registrant data before attempting payment.
2104
+	 * It checks if the billing form is an instance of EE_Billing_Attendee_Info_Form and if the transaction
2105
+	 * has a primary registrant. If not, it captures the primary registrant data from the billing form.
2106
+	 *
2107
+	 * @return bool
2108
+	 * @throws EE_Error
2109
+	 * @throws InvalidArgumentException
2110
+	 * @throws ReflectionException
2111
+	 * @throws InvalidDataTypeException
2112
+	 * @throws InvalidInterfaceException
2113
+	 */
2114
+	private function _capture_primary_registration_data_from_billing_form(): bool
2115
+	{
2116
+		$primary_registration = $this->checkout->transaction->primary_registration();
2117
+		if (! $this->validatePrimaryRegistration($primary_registration)) {
2118
+			return false;
2119
+		}
2120
+
2121
+		$primary_attendee = $this->getPrimaryAttendee($primary_registration);
2122
+		if (! $this->validatePrimaryAttendee($primary_attendee)) {
2123
+			return false;
2124
+		}
2125
+
2126
+		if (! $this->addAttendeeToPrimaryRegistration($primary_attendee, $primary_registration)) {
2127
+			return false;
2128
+		}
2129
+		// both the primary registration and primary attendee objects should be valid entities at this point
2130
+		$this->checkout->primary_attendee_obj = $primary_attendee;
2131
+
2132
+		/** @type EE_Registration_Processor $registration_processor */
2133
+		$registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
2134
+		// at this point, we should have enough details about the registrant to consider the registration NOT incomplete
2135
+		$registration_processor->toggle_incomplete_registration_status_to_default(
2136
+			$primary_registration,
2137
+			false,
2138
+			new Context(
2139
+				__METHOD__,
2140
+				esc_html__(
2141
+					'Executed when the primary registrant\'s status is updated during the registration process when processing a billing form.',
2142
+					'event_espresso'
2143
+				)
2144
+			)
2145
+		);
2146
+		return true;
2147
+	}
2148
+
2149
+
2150
+	/**
2151
+	 * returns true if the primary registration is a valid entity
2152
+	 *
2153
+	 * @param $primary_registration
2154
+	 * @return bool
2155
+	 * @throws EE_Error
2156
+	 * @since 5.0.21.p
2157
+	 */
2158
+	private function validatePrimaryRegistration($primary_registration): bool
2159
+	{
2160
+		if ($primary_registration instanceof EE_Registration) {
2161
+			return true;
2162
+		}
2163
+		EE_Error::add_error(
2164
+			sprintf(
2165
+				esc_html__(
2166
+					'The primary registrant for this transaction could not be determined due to a technical issue.%sPlease try again or contact %s for assistance.',
2167
+					'event_espresso'
2168
+				),
2169
+				'<br/>',
2170
+				EE_Registry::instance()->CFG->organization->get_pretty('email')
2171
+			),
2172
+			__FILE__,
2173
+			__FUNCTION__,
2174
+			__LINE__
2175
+		);
2176
+		return false;
2177
+	}
2178
+
2179
+
2180
+	/**
2181
+	 * retrieves the primary attendee object for the primary registration and copies the billing form data to it.
2182
+	 * if the primary registration does not have an attendee object, then one is created from the billing form info
2183
+	 *
2184
+	 * @param EE_Registration $primary_registration
2185
+	 * @return EE_Attendee|null
2186
+	 * @throws EE_Error
2187
+	 * @throws ReflectionException
2188
+	 * @since 5.0.21.p
2189
+	 */
2190
+	private function getPrimaryAttendee(EE_Registration $primary_registration): ?EE_Attendee
2191
+	{
2192
+		// if we have a primary registration, then we should have a primary attendee
2193
+		$attendee = $primary_registration->attendee();
2194
+		if ($attendee instanceof EE_Attendee) {
2195
+			return $this->checkout->billing_form->copy_billing_form_data_to_attendee($attendee);
2196
+		}
2197
+		// if not, then we need to create one from the billing form
2198
+		return $this->checkout->billing_form->create_attendee_from_billing_form_data();
2199
+	}
2200
+
2201
+
2202
+	/**
2203
+	 * returns true if the primary attendee is a valid entity
2204
+	 *
2205
+	 * @param $primary_attendee
2206
+	 * @return bool
2207
+	 * @throws EE_Error
2208
+	 * @since 5.0.21.p
2209
+	 */
2210
+	private function validatePrimaryAttendee($primary_attendee): bool
2211
+	{
2212
+		if ($primary_attendee instanceof EE_Attendee) {
2213
+			return true;
2214
+		}
2215
+		EE_Error::add_error(
2216
+			sprintf(
2217
+				esc_html__(
2218
+					'The billing form details could not be used for attendee details due to a technical issue.%sPlease try again or contact %s for assistance.',
2219
+					'event_espresso'
2220
+				),
2221
+				'<br/>',
2222
+				EE_Registry::instance()->CFG->organization->get_pretty('email')
2223
+			),
2224
+			__FILE__,
2225
+			__FUNCTION__,
2226
+			__LINE__
2227
+		);
2228
+		return false;
2229
+	}
2230
+
2231
+
2232
+	/**
2233
+	 * returns true if the attendee was successfully added to the primary registration
2234
+	 *
2235
+	 * @param EE_Attendee     $primary_attendee
2236
+	 * @param EE_Registration $primary_registration
2237
+	 * @return bool
2238
+	 * @throws EE_Error
2239
+	 * @throws ReflectionException
2240
+	 * @since 5.0.21.p
2241
+	 */
2242
+	private function addAttendeeToPrimaryRegistration(
2243
+		EE_Attendee $primary_attendee,
2244
+		EE_Registration $primary_registration
2245
+	): bool {
2246
+		// ensure attendee has an ID by saving
2247
+		$primary_attendee->save();
2248
+
2249
+		// compare attendee IDs
2250
+		if ($primary_registration->attendee_id() === $primary_attendee->ID()) {
2251
+			return true;
2252
+		}
2253
+
2254
+		$primary_attendee = $primary_registration->_add_relation_to($primary_attendee, 'Attendee');
2255
+		if ($primary_attendee instanceof EE_Attendee) {
2256
+			return true;
2257
+		}
2258
+
2259
+		EE_Error::add_error(
2260
+			sprintf(
2261
+				esc_html__(
2262
+					'The primary registrant could not be associated with this transaction due to a technical issue.%sPlease try again or contact %s for assistance.',
2263
+					'event_espresso'
2264
+				),
2265
+				'<br/>',
2266
+				EE_Registry::instance()->CFG->organization->get_pretty('email')
2267
+			),
2268
+			__FILE__,
2269
+			__FUNCTION__,
2270
+			__LINE__
2271
+		);
2272
+		return false;
2273
+	}
2274
+
2275
+
2276
+	/**
2277
+	 * _get_payment_method_for_selected_method_of_payment
2278
+	 * retrieves a valid payment method
2279
+	 *
2280
+	 * @return EE_Payment_Method
2281
+	 * @throws EE_Error
2282
+	 * @throws InvalidArgumentException
2283
+	 * @throws ReflectionException
2284
+	 * @throws InvalidDataTypeException
2285
+	 * @throws InvalidInterfaceException
2286
+	 */
2287
+	private function _get_payment_method_for_selected_method_of_payment()
2288
+	{
2289
+		if ($this->checkout->selected_method_of_payment === 'events_sold_out') {
2290
+			$this->_redirect_because_event_sold_out();
2291
+			return null;
2292
+		}
2293
+		// get EE_Payment_Method object
2294
+		if (isset($this->checkout->available_payment_methods[ $this->checkout->selected_method_of_payment ])) {
2295
+			$payment_method = $this->checkout->available_payment_methods[ $this->checkout->selected_method_of_payment ];
2296
+		} else {
2297
+			// load EEM_Payment_Method
2298
+			EE_Registry::instance()->load_model('Payment_Method');
2299
+			$EEM_Payment_Method = EEM_Payment_Method::instance();
2300
+			$payment_method     = $EEM_Payment_Method->get_one_by_slug($this->checkout->selected_method_of_payment);
2301
+		}
2302
+		// verify $payment_method
2303
+		if (! $payment_method instanceof EE_Payment_Method) {
2304
+			// not a payment
2305
+			EE_Error::add_error(
2306
+				sprintf(
2307
+					esc_html__(
2308
+						'The selected method of payment could not be determined due to a technical issue.%sPlease try again or contact %s for assistance.',
2309
+						'event_espresso'
2310
+					),
2311
+					'<br/>',
2312
+					EE_Registry::instance()->CFG->organization->get_pretty('email')
2313
+				),
2314
+				__FILE__,
2315
+				__FUNCTION__,
2316
+				__LINE__
2317
+			);
2318
+			return null;
2319
+		}
2320
+		// and verify it has a valid Payment_Method Type object
2321
+		if (! $payment_method->type_obj() instanceof EE_PMT_Base) {
2322
+			// not a payment
2323
+			EE_Error::add_error(
2324
+				sprintf(
2325
+					esc_html__(
2326
+						'A valid payment method could not be determined due to a technical issue.%sPlease try again or contact %s for assistance.',
2327
+						'event_espresso'
2328
+					),
2329
+					'<br/>',
2330
+					EE_Registry::instance()->CFG->organization->get_pretty('email')
2331
+				),
2332
+				__FILE__,
2333
+				__FUNCTION__,
2334
+				__LINE__
2335
+			);
2336
+			return null;
2337
+		}
2338
+		return $payment_method;
2339
+	}
2340
+
2341
+
2342
+	/**
2343
+	 *    _attempt_payment
2344
+	 *
2345
+	 * @access    private
2346
+	 * @type    EE_Payment_Method $payment_method
2347
+	 * @return EE_Payment|null
2348
+	 * @throws EE_Error
2349
+	 * @throws InvalidArgumentException
2350
+	 * @throws ReflectionException
2351
+	 * @throws InvalidDataTypeException
2352
+	 * @throws InvalidInterfaceException
2353
+	 */
2354
+	private function _attempt_payment(EE_Payment_Method $payment_method): ?EE_Payment
2355
+	{
2356
+		$this->checkout->transaction->save();
2357
+		/** @var PaymentProcessor $payment_processor */
2358
+		$payment_processor = LoaderFactory::getShared(PaymentProcessor::class);
2359
+		if (! $payment_processor instanceof PaymentProcessor) {
2360
+			return null;
2361
+		}
2362
+		/** @var EE_Transaction_Processor $transaction_processor */
2363
+		$transaction_processor = LoaderFactory::getShared(EE_Transaction_Processor::class);
2364
+		if ($transaction_processor instanceof EE_Transaction_Processor) {
2365
+			$transaction_processor->set_revisit($this->checkout->revisit);
2366
+		}
2367
+		try {
2368
+			// generate payment object
2369
+			return $payment_processor->processPayment(
2370
+				$payment_method,
2371
+				$this->checkout->transaction,
2372
+				$this->checkout->billing_form instanceof EE_Billing_Info_Form
2373
+					? $this->checkout->billing_form
2374
+					: null,
2375
+				$this->checkout->amount_owing,
2376
+				$this->checkout->admin_request,
2377
+				true,
2378
+				$this->_get_return_url($payment_method),
2379
+				$this->reg_step_url()
2380
+			);
2381
+		} catch (Exception $e) {
2382
+			$this->_handle_payment_processor_exception($e);
2383
+		}
2384
+		return null;
2385
+	}
2386
+
2387
+
2388
+	/**
2389
+	 * _handle_payment_processor_exception
2390
+	 *
2391
+	 * @param Exception $e
2392
+	 * @return void
2393
+	 * @throws EE_Error
2394
+	 * @throws InvalidArgumentException
2395
+	 * @throws InvalidDataTypeException
2396
+	 * @throws InvalidInterfaceException
2397
+	 */
2398
+	protected function _handle_payment_processor_exception(Exception $e)
2399
+	{
2400
+		EE_Error::add_error(
2401
+			sprintf(
2402
+				esc_html__(
2403
+					'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',
2404
+					'event_espresso'
2405
+				),
2406
+				'<br/>',
2407
+				EE_Registry::instance()->CFG->organization->get_pretty('email'),
2408
+				$e->getMessage(),
2409
+				$e->getFile(),
2410
+				$e->getLine()
2411
+			),
2412
+			__FILE__,
2413
+			__FUNCTION__,
2414
+			__LINE__
2415
+		);
2416
+	}
2417
+
2418
+
2419
+	/**
2420
+	 * @param EE_Payment_Method $payment_method
2421
+	 * @return string
2422
+	 * @throws EE_Error
2423
+	 * @throws ReflectionException
2424
+	 */
2425
+	protected function _get_return_url(EE_Payment_Method $payment_method)
2426
+	{
2427
+		switch ($payment_method->type_obj()->payment_occurs()) {
2428
+			case EE_PMT_Base::offsite:
2429
+				return add_query_arg(
2430
+					[
2431
+						'action'                     => 'process_gateway_response',
2432
+						'selected_method_of_payment' => $this->checkout->selected_method_of_payment,
2433
+						'spco_txn'                   => $this->checkout->transaction->ID(),
2434
+					],
2435
+					$this->reg_step_url()
2436
+				);
2437
+
2438
+			case EE_PMT_Base::onsite:
2439
+			case EE_PMT_Base::offline:
2440
+				return $this->checkout->next_step->reg_step_url();
2441
+		}
2442
+		return '';
2443
+	}
2444
+
2445
+
2446
+	/**
2447
+	 * _validate_payment
2448
+	 *
2449
+	 * @param EE_Payment $payment
2450
+	 * @return EE_Payment|bool
2451
+	 * @throws EE_Error
2452
+	 * @throws InvalidArgumentException
2453
+	 * @throws InvalidDataTypeException
2454
+	 * @throws InvalidInterfaceException
2455
+	 */
2456
+	private function _validate_payment($payment = null)
2457
+	{
2458
+		if ($this->checkout->payment_method->is_off_line()) {
2459
+			return true;
2460
+		}
2461
+		// verify payment object
2462
+		if (! $payment instanceof EE_Payment) {
2463
+			// not a payment
2464
+			EE_Error::add_error(
2465
+				sprintf(
2466
+					esc_html__(
2467
+						'A valid payment was not generated due to a technical issue.%1$sPlease try again or contact %2$s for assistance.',
2468
+						'event_espresso'
2469
+					),
2470
+					'<br/>',
2471
+					EE_Registry::instance()->CFG->organization->get_pretty('email')
2472
+				),
2473
+				__FILE__,
2474
+				__FUNCTION__,
2475
+				__LINE__
2476
+			);
2477
+			return false;
2478
+		}
2479
+		return $payment;
2480
+	}
2481
+
2482
+
2483
+	/**
2484
+	 * _post_payment_processing
2485
+	 *
2486
+	 * @param EE_Payment|bool $payment
2487
+	 * @return bool|EE_Payment
2488
+	 * @throws EE_Error
2489
+	 * @throws InvalidArgumentException
2490
+	 * @throws InvalidDataTypeException
2491
+	 * @throws InvalidInterfaceException
2492
+	 * @throws ReflectionException
2493
+	 */
2494
+	private function _post_payment_processing($payment = null)
2495
+	{
2496
+		// Off-Line payment?
2497
+		if ($payment === true) {
2498
+			return true;
2499
+		}
2500
+		if ($payment instanceof EE_Payment) {
2501
+			// Should the user be redirected?
2502
+			if ($payment->redirect_url()) {
2503
+				do_action('AHEE_log', __CLASS__, __FUNCTION__, $payment->redirect_url(), '$payment->redirect_url()');
2504
+				$this->checkout->redirect      = true;
2505
+				$this->checkout->redirect_form = $payment->redirect_form();
2506
+				$this->checkout->redirect_url  = $this->reg_step_url('redirect_form');
2507
+				// set JSON response
2508
+				$this->checkout->json_response->set_redirect_form($this->checkout->redirect_form);
2509
+				// and lastly, let's bump the payment status to pending
2510
+				$payment->set_status(EEM_Payment::status_id_pending);
2511
+				$payment->save();
2512
+			} elseif (! $this->_process_payment_status($payment, EE_PMT_Base::onsite)) {
2513
+				// User shouldn't be redirected. So let's process it here.
2514
+				// $this->_setup_redirect_for_next_step();
2515
+				$this->checkout->continue_reg = false;
2516
+			}
2517
+			return $payment;
2518
+		}
2519
+		// ummm ya... not Off-Line, not On-Site, not off-Site ????
2520
+		$this->checkout->continue_reg = false;
2521
+		return false;
2522
+	}
2523
+
2524
+
2525
+	/**
2526
+	 *    _process_payment_status
2527
+	 *
2528
+	 * @type    EE_Payment $payment
2529
+	 * @param string       $payment_occurs
2530
+	 * @return bool
2531
+	 * @throws EE_Error
2532
+	 * @throws InvalidArgumentException
2533
+	 * @throws InvalidDataTypeException
2534
+	 * @throws InvalidInterfaceException
2535
+	 */
2536
+	private function _process_payment_status($payment, $payment_occurs = EE_PMT_Base::offline)
2537
+	{
2538
+		// off-line payment? carry on
2539
+		if ($payment_occurs === EE_PMT_Base::offline) {
2540
+			return true;
2541
+		}
2542
+		// verify payment validity
2543
+		if ($payment instanceof EE_Payment) {
2544
+			do_action('AHEE_log', __CLASS__, __FUNCTION__, $payment->status(), '$payment->status()');
2545
+			$msg = $payment->gateway_response();
2546
+			// check results
2547
+			switch ($payment->status()) {
2548
+				// good payment
2549
+				case EEM_Payment::status_id_approved:
2550
+					EE_Error::add_success(
2551
+						esc_html__('Your payment was processed successfully.', 'event_espresso'),
2552
+						__FILE__,
2553
+						__FUNCTION__,
2554
+						__LINE__
2555
+					);
2556
+					return true;
2557
+				// slow payment
2558
+				case EEM_Payment::status_id_pending:
2559
+					if (empty($msg)) {
2560
+						$msg = esc_html__(
2561
+							'Your payment appears to have been processed successfully, but the Instant Payment Notification has not yet been received. It should arrive shortly.',
2562
+							'event_espresso'
2563
+						);
2564
+					}
2565
+					EE_Error::add_success($msg, __FILE__, __FUNCTION__, __LINE__);
2566
+					return true;
2567
+				// don't wanna payment
2568
+				case EEM_Payment::status_id_cancelled:
2569
+					if (empty($msg)) {
2570
+						$msg = _n(
2571
+							'Payment cancelled. Please try again.',
2572
+							'Payment cancelled. Please try again or select another method of payment.',
2573
+							count($this->checkout->available_payment_methods),
2574
+							'event_espresso'
2575
+						);
2576
+					}
2577
+					EE_Error::add_attention($msg, __FILE__, __FUNCTION__, __LINE__);
2578
+					return false;
2579
+				// not enough payment
2580
+				case EEM_Payment::status_id_declined:
2581
+					if (empty($msg)) {
2582
+						$msg = _n(
2583
+							'We\'re sorry but your payment was declined. Please try again.',
2584
+							'We\'re sorry but your payment was declined. Please try again or select another method of payment.',
2585
+							count($this->checkout->available_payment_methods),
2586
+							'event_espresso'
2587
+						);
2588
+					}
2589
+					EE_Error::add_attention($msg, __FILE__, __FUNCTION__, __LINE__);
2590
+					return false;
2591
+				// bad payment
2592
+				case EEM_Payment::status_id_failed:
2593
+					if (! empty($msg)) {
2594
+						EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2595
+						return false;
2596
+					}
2597
+					// default to error below
2598
+					break;
2599
+			}
2600
+		}
2601
+		// off-site payment gateway responses are too unreliable, so let's just assume that
2602
+		// the payment processing is just running slower than the registrant's request
2603
+		if ($payment_occurs === EE_PMT_Base::offsite) {
2604
+			return true;
2605
+		}
2606
+		EE_Error::add_error(
2607
+			sprintf(
2608
+				esc_html__(
2609
+					'Your payment could not be processed successfully due to a technical issue.%sPlease try again or contact %s for assistance.',
2610
+					'event_espresso'
2611
+				),
2612
+				'<br/>',
2613
+				EE_Registry::instance()->CFG->organization->get_pretty('email')
2614
+			),
2615
+			__FILE__,
2616
+			__FUNCTION__,
2617
+			__LINE__
2618
+		);
2619
+		return false;
2620
+	}
2621
+
2622
+
2623
+
2624
+
2625
+
2626
+
2627
+	/********************************************************************************************************/
2628
+	/**********************************  PROCESS GATEWAY RESPONSE  **********************************/
2629
+	/********************************************************************************************************/
2630
+	/**
2631
+	 * process_gateway_response
2632
+	 * this is the return point for Off-Site Payment Methods
2633
+	 * It will attempt to "handle the IPN" if it appears that this has not already occurred,
2634
+	 * otherwise, it will load up the last payment made for the TXN.
2635
+	 * If the payment retrieved looks good, it will then either:
2636
+	 *    complete the current step and allow advancement to the next reg step
2637
+	 *        or present the payment options again
2638
+	 *
2639
+	 * @return bool
2640
+	 * @throws EE_Error
2641
+	 * @throws InvalidArgumentException
2642
+	 * @throws ReflectionException
2643
+	 * @throws InvalidDataTypeException
2644
+	 * @throws InvalidInterfaceException
2645
+	 */
2646
+	public function process_gateway_response()
2647
+	{
2648
+		// how have they chosen to pay?
2649
+		$this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment(true);
2650
+		// get EE_Payment_Method object
2651
+		if (! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()) {
2652
+			$this->checkout->continue_reg = false;
2653
+			return false;
2654
+		}
2655
+		if (! $this->checkout->payment_method->is_off_site()) {
2656
+			return false;
2657
+		}
2658
+		$this->_validate_offsite_return();
2659
+		// verify TXN
2660
+		if ($this->checkout->transaction instanceof EE_Transaction) {
2661
+			$gateway = $this->checkout->payment_method->type_obj()->get_gateway();
2662
+			if (! $gateway instanceof EE_Offsite_Gateway) {
2663
+				$this->checkout->continue_reg = false;
2664
+				return false;
2665
+			}
2666
+			$payment = $this->_process_off_site_payment($gateway);
2667
+			$payment = $this->_process_cancelled_payments($payment);
2668
+			$payment = $this->_validate_payment($payment);
2669
+			// if payment was not declined by the payment gateway or cancelled by the registrant
2670
+			if ($this->_process_payment_status($payment, EE_PMT_Base::offsite)) {
2671
+				// $this->_setup_redirect_for_next_step();
2672
+				// store that for later
2673
+				$this->checkout->payment = $payment;
2674
+				// mark this reg step as completed, as long as gateway doesn't use a separate IPN request,
2675
+				// because we will complete this step during the IPN processing then
2676
+				if (! $this->handle_IPN_in_this_request()) {
2677
+					$this->set_completed();
2678
+				}
2679
+				return true;
2680
+			}
2681
+		}
2682
+		// DEBUG LOG
2683
+		// $this->checkout->log(
2684
+		//     __CLASS__,
2685
+		//     __FUNCTION__,
2686
+		//     __LINE__,
2687
+		//     array('payment' => $payment)
2688
+		// );
2689
+		$this->checkout->continue_reg = false;
2690
+		return false;
2691
+	}
2692
+
2693
+
2694
+	/**
2695
+	 * _validate_return
2696
+	 *
2697
+	 * @return void
2698
+	 * @throws EE_Error
2699
+	 * @throws InvalidArgumentException
2700
+	 * @throws InvalidDataTypeException
2701
+	 * @throws InvalidInterfaceException
2702
+	 * @throws ReflectionException
2703
+	 */
2704
+	private function _validate_offsite_return()
2705
+	{
2706
+		$TXN_ID = $this->request->getRequestParam('spco_txn', 0, 'int');
2707
+		if ($TXN_ID !== $this->checkout->transaction->ID()) {
2708
+			// Houston... we might have a problem
2709
+			$invalid_TXN = false;
2710
+			// first gather some info
2711
+			$valid_TXN          = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
2712
+			$primary_registrant = $valid_TXN instanceof EE_Transaction
2713
+				? $valid_TXN->primary_registration()
2714
+				: null;
2715
+			// let's start by retrieving the cart for this TXN
2716
+			$cart = $this->checkout->get_cart_for_transaction($this->checkout->transaction);
2717
+			if ($cart instanceof EE_Cart) {
2718
+				// verify that the current cart has tickets
2719
+				$tickets = $cart->get_tickets();
2720
+				if (empty($tickets)) {
2721
+					$invalid_TXN = true;
2722
+				}
2723
+			} else {
2724
+				$invalid_TXN = true;
2725
+			}
2726
+			$valid_TXN_SID = $primary_registrant instanceof EE_Registration
2727
+				? $primary_registrant->session_ID()
2728
+				: null;
2729
+			// validate current Session ID and compare against valid TXN session ID
2730
+			if (
2731
+				$invalid_TXN // if this is already true, then skip other checks
2732
+				|| EE_Session::instance()->id() === null
2733
+				|| (
2734
+					// WARNING !!!
2735
+					// this could be PayPal sending back duplicate requests (ya they do that)
2736
+					// or it **could** mean someone is simply registering AGAIN after having just done so,
2737
+					// so now we need to determine if this current TXN looks valid or not
2738
+					// and whether this reg step has even been started ?
2739
+					EE_Session::instance()->id() === $valid_TXN_SID
2740
+					// really? you're halfway through this reg step, but you never started it ?
2741
+					&& $this->checkout->transaction->reg_step_completed($this->slug()) === false
2742
+				)
2743
+			) {
2744
+				$invalid_TXN = true;
2745
+			}
2746
+			if ($invalid_TXN) {
2747
+				// is the valid TXN completed ?
2748
+				if ($valid_TXN instanceof EE_Transaction) {
2749
+					// has this step even been started ?
2750
+					$reg_step_completed = $valid_TXN->reg_step_completed($this->slug());
2751
+					if ($reg_step_completed !== false && $reg_step_completed !== true) {
2752
+						// so it **looks** like this is a double request from PayPal
2753
+						// so let's try to pick up where we left off
2754
+						$this->checkout->transaction = $valid_TXN;
2755
+						$this->checkout->refresh_all_entities(true);
2756
+						return;
2757
+					}
2758
+				}
2759
+				// you appear to be lost?
2760
+				$this->_redirect_wayward_request($primary_registrant);
2761
+			}
2762
+		}
2763
+	}
2764
+
2765
+
2766
+	/**
2767
+	 * _redirect_wayward_request
2768
+	 *
2769
+	 * @param EE_Registration|null $primary_registrant
2770
+	 * @return void
2771
+	 * @throws EE_Error
2772
+	 * @throws InvalidArgumentException
2773
+	 * @throws InvalidDataTypeException
2774
+	 * @throws InvalidInterfaceException
2775
+	 * @throws ReflectionException
2776
+	 */
2777
+	private function _redirect_wayward_request(EE_Registration $primary_registrant)
2778
+	{
2779
+		if (! $primary_registrant instanceof EE_Registration) {
2780
+			// try redirecting based on the current TXN
2781
+			$primary_registrant = $this->checkout->transaction instanceof EE_Transaction
2782
+				? $this->checkout->transaction->primary_registration()
2783
+				: null;
2784
+		}
2785
+		if (! $primary_registrant instanceof EE_Registration) {
2786
+			EE_Error::add_error(
2787
+				sprintf(
2788
+					esc_html__(
2789
+						'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.',
2790
+						'event_espresso'
2791
+					),
2792
+					'<br/>',
2793
+					EE_Registry::instance()->CFG->organization->get_pretty('email')
2794
+				),
2795
+				__FILE__,
2796
+				__FUNCTION__,
2797
+				__LINE__
2798
+			);
2799
+			return;
2800
+		}
2801
+		// make sure transaction is not locked
2802
+		$this->checkout->transaction->unlock();
2803
+		wp_safe_redirect(
2804
+			add_query_arg(
2805
+				[
2806
+					'e_reg_url_link' => $primary_registrant->reg_url_link(),
2807
+				],
2808
+				$this->checkout->thank_you_page_url
2809
+			)
2810
+		);
2811
+		exit();
2812
+	}
2813
+
2814
+
2815
+	/**
2816
+	 * _process_off_site_payment
2817
+	 *
2818
+	 * @param EE_Offsite_Gateway $gateway
2819
+	 * @return EE_Payment
2820
+	 * @throws EE_Error
2821
+	 * @throws InvalidArgumentException
2822
+	 * @throws InvalidDataTypeException
2823
+	 * @throws InvalidInterfaceException
2824
+	 * @throws ReflectionException
2825
+	 */
2826
+	private function _process_off_site_payment(EE_Offsite_Gateway $gateway)
2827
+	{
2828
+		try {
2829
+			$request      = LoaderFactory::getLoader()->getShared(RequestInterface::class);
2830
+			$request_data = $request->requestParams();
2831
+			// if gateway uses_separate_IPN_request, then we don't have to process the IPN manually
2832
+			$this->set_handle_IPN_in_this_request(
2833
+				$gateway->handle_IPN_in_this_request($request_data, false)
2834
+			);
2835
+			if ($this->handle_IPN_in_this_request()) {
2836
+				// get payment details and process results
2837
+				/** @var IpnHandler $payment_processor */
2838
+				$payment_processor = LoaderFactory::getShared(IpnHandler::class);
2839
+				$payment           = $payment_processor->processIPN(
2840
+					$request_data,
2841
+					$this->checkout->transaction,
2842
+					$this->checkout->payment_method,
2843
+					true,
2844
+					false
2845
+				);
2846
+				// $payment_source = 'process_ipn';
2847
+			} else {
2848
+				$payment = $this->checkout->transaction->last_payment();
2849
+				// $payment_source = 'last_payment';
2850
+			}
2851
+		} catch (Exception $e) {
2852
+			// let's just eat the exception and try to move on using any previously set payment info
2853
+			$payment = $this->checkout->transaction->last_payment();
2854
+			// $payment_source = 'last_payment after Exception';
2855
+			// but if we STILL don't have a payment object
2856
+			if (! $payment instanceof EE_Payment) {
2857
+				// then we'll object ! ( not object like a thing... but object like what a lawyer says ! )
2858
+				$this->_handle_payment_processor_exception($e);
2859
+			}
2860
+		}
2861
+		return $payment;
2862
+	}
2863
+
2864
+
2865
+	/**
2866
+	 * _process_cancelled_payments
2867
+	 * just makes sure that the payment status gets updated correctly
2868
+	 * so tha tan error isn't generated during payment validation
2869
+	 *
2870
+	 * @param EE_Payment $payment
2871
+	 * @return EE_Payment|null
2872
+	 * @throws EE_Error
2873
+	 */
2874
+	private function _process_cancelled_payments($payment = null)
2875
+	{
2876
+		if (
2877
+			$payment instanceof EE_Payment
2878
+			&& $this->request->requestParamIsSet('ee_cancel_payment')
2879
+			&& $payment->status() === EEM_Payment::status_id_failed
2880
+		) {
2881
+			$payment->set_status(EEM_Payment::status_id_cancelled);
2882
+		}
2883
+		return $payment;
2884
+	}
2885
+
2886
+
2887
+	/**
2888
+	 *    get_transaction_details_for_gateways
2889
+	 *
2890
+	 * @access    public
2891
+	 * @return void
2892
+	 * @throws EE_Error
2893
+	 * @throws InvalidArgumentException
2894
+	 * @throws ReflectionException
2895
+	 * @throws InvalidDataTypeException
2896
+	 * @throws InvalidInterfaceException
2897
+	 */
2898
+	public function get_transaction_details_for_gateways()
2899
+	{
2900
+		$txn_details = [];
2901
+		// ya gotta make a choice man
2902
+		if (empty($this->checkout->selected_method_of_payment)) {
2903
+			$txn_details = [
2904
+				'error' => esc_html__('Please select a method of payment before proceeding.', 'event_espresso'),
2905
+			];
2906
+		}
2907
+		// get EE_Payment_Method object
2908
+		if (
2909
+			empty($txn_details)
2910
+			&& ! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()
2911
+		) {
2912
+			$txn_details = [
2913
+				'selected_method_of_payment' => $this->checkout->selected_method_of_payment,
2914
+				'error'                      => esc_html__(
2915
+					'A valid Payment Method could not be determined.',
2916
+					'event_espresso'
2917
+				),
2918
+			];
2919
+		}
2920
+		if (empty($txn_details) && $this->checkout->transaction instanceof EE_Transaction) {
2921
+			$return_url  = $this->_get_return_url($this->checkout->payment_method);
2922
+			$txn_details = [
2923
+				'TXN_ID'         => $this->checkout->transaction->ID(),
2924
+				'TXN_timestamp'  => $this->checkout->transaction->datetime(),
2925
+				'TXN_total'      => $this->checkout->transaction->total(),
2926
+				'TXN_paid'       => $this->checkout->transaction->paid(),
2927
+				'TXN_reg_steps'  => $this->checkout->transaction->reg_steps(),
2928
+				'STS_ID'         => $this->checkout->transaction->status_ID(),
2929
+				'PMD_ID'         => $this->checkout->transaction->payment_method_ID(),
2930
+				'payment_amount' => $this->checkout->amount_owing,
2931
+				'return_url'     => $return_url,
2932
+				'cancel_url'     => add_query_arg(['ee_cancel_payment' => true], $return_url),
2933
+				'notify_url'     => EE_Config::instance()->core->txn_page_url(
2934
+					[
2935
+						'e_reg_url_link'    => $this->checkout->transaction->primary_registration()->reg_url_link(),
2936
+						'ee_payment_method' => $this->checkout->payment_method->slug(),
2937
+					]
2938
+				),
2939
+			];
2940
+		}
2941
+		echo wp_json_encode($txn_details);
2942
+		exit();
2943
+	}
2944
+
2945
+
2946
+	/**
2947
+	 *    __sleep
2948
+	 * to conserve db space, let's remove the reg_form and the EE_Checkout object from EE_SPCO_Reg_Step objects upon
2949
+	 * serialization EE_Checkout will handle the reimplementation of itself upon waking, but we won't bother with the
2950
+	 * reg form, because if needed, it will be regenerated anyways
2951
+	 *
2952
+	 * @return array
2953
+	 */
2954
+	public function __sleep()
2955
+	{
2956
+		// remove the reg form and the checkout
2957
+		return array_diff(array_keys(get_object_vars($this)), ['reg_form', 'checkout', 'line_item_display']);
2958
+	}
2959 2959
 }
Please login to merge, or discard this patch.
Spacing   +81 added lines, -81 removed lines patch added patch discarded remove patch
@@ -136,7 +136,7 @@  discard block
 block discarded – undo
136 136
         $this->request   = EED_Single_Page_Checkout::getRequest();
137 137
         $this->_slug     = 'payment_options';
138 138
         $this->_name     = esc_html__('Payment Options', 'event_espresso');
139
-        $this->_template = SPCO_REG_STEPS_PATH . $this->_slug . '/payment_options_main.template.php';
139
+        $this->_template = SPCO_REG_STEPS_PATH.$this->_slug.'/payment_options_main.template.php';
140 140
         $this->checkout  = $checkout;
141 141
         $this->_reset_success_message();
142 142
         $this->set_instructions(
@@ -191,7 +191,7 @@  discard block
 block discarded – undo
191 191
      */
192 192
     public function translate_js_strings()
193 193
     {
194
-        EE_Registry::$i18n_js_strings['no_payment_method']      = esc_html__(
194
+        EE_Registry::$i18n_js_strings['no_payment_method'] = esc_html__(
195 195
             'Please select a method of payment in order to continue.',
196 196
             'event_espresso'
197 197
         );
@@ -199,7 +199,7 @@  discard block
 block discarded – undo
199 199
             'A valid method of payment could not be determined. Please refresh the page and try again.',
200 200
             'event_espresso'
201 201
         );
202
-        EE_Registry::$i18n_js_strings['forwarding_to_offsite']  = esc_html__(
202
+        EE_Registry::$i18n_js_strings['forwarding_to_offsite'] = esc_html__(
203 203
             'Forwarding to Secure Payment Provider.',
204 204
             'event_espresso'
205 205
         );
@@ -220,7 +220,7 @@  discard block
 block discarded – undo
220 220
     {
221 221
         $transaction = $this->checkout->transaction;
222 222
         // if the transaction isn't set or nothing is owed on it, don't enqueue any JS
223
-        if (! $transaction instanceof EE_Transaction || EEH_Money::compare_floats($transaction->remaining(), 0)) {
223
+        if ( ! $transaction instanceof EE_Transaction || EEH_Money::compare_floats($transaction->remaining(), 0)) {
224 224
             return;
225 225
         }
226 226
         foreach (
@@ -319,18 +319,18 @@  discard block
 block discarded – undo
319 319
                 continue;
320 320
             }
321 321
             // has this registration lost it's space ?
322
-            if (isset($ejected_registrations[ $REG_ID ])) {
322
+            if (isset($ejected_registrations[$REG_ID])) {
323 323
                 if ($registration->event()->is_sold_out() || $registration->event()->is_sold_out(true)) {
324
-                    $sold_out_events[ $registration->event()->ID() ] = $registration->event();
324
+                    $sold_out_events[$registration->event()->ID()] = $registration->event();
325 325
                 } else {
326
-                    $insufficient_spaces_available[ $registration->event()->ID() ] = $registration->event();
326
+                    $insufficient_spaces_available[$registration->event()->ID()] = $registration->event();
327 327
                 }
328 328
                 continue;
329 329
             }
330 330
             // event requires admin approval
331 331
             if ($registration->status_ID() === RegStatus::AWAITING_REVIEW) {
332 332
                 // add event to list of events with pre-approval reg status
333
-                $registrations_requiring_pre_approval[ $REG_ID ] = $registration;
333
+                $registrations_requiring_pre_approval[$REG_ID] = $registration;
334 334
                 do_action(
335 335
                     'AHEE__EE_SPCO_Reg_Step_Payment_Options__generate_reg_form__event_requires_pre_approval',
336 336
                     $registration->event(),
@@ -347,7 +347,7 @@  discard block
 block discarded – undo
347 347
                 )
348 348
             ) {
349 349
                 // add event to list of events that are sold out
350
-                $sold_out_events[ $registration->event()->ID() ] = $registration->event();
350
+                $sold_out_events[$registration->event()->ID()] = $registration->event();
351 351
                 do_action(
352 352
                     'AHEE__EE_SPCO_Reg_Step_Payment_Options__generate_reg_form__sold_out_event',
353 353
                     $registration->event(),
@@ -357,7 +357,7 @@  discard block
 block discarded – undo
357 357
             }
358 358
             // are they allowed to pay now and is there monies owing?
359 359
             if ($registration->owes_monies_and_can_pay()) {
360
-                $registrations_requiring_payment[ $REG_ID ] = $registration;
360
+                $registrations_requiring_payment[$REG_ID] = $registration;
361 361
                 do_action(
362 362
                     'AHEE__EE_SPCO_Reg_Step_Payment_Options__generate_reg_form__event_requires_payment',
363 363
                     $registration->event(),
@@ -368,28 +368,28 @@  discard block
 block discarded – undo
368 368
                       && $registration->status_ID() !== RegStatus::AWAITING_REVIEW
369 369
                       && $registration->ticket()->is_free()
370 370
             ) {
371
-                $registrations_for_free_events[ $registration->ticket()->ID() ] = $registration;
371
+                $registrations_for_free_events[$registration->ticket()->ID()] = $registration;
372 372
             }
373 373
         }
374 374
         $subsections = [];
375 375
         // now decide which template to load
376
-        if (! empty($sold_out_events)) {
376
+        if ( ! empty($sold_out_events)) {
377 377
             $subsections['sold_out_events'] = $this->_sold_out_events($sold_out_events);
378 378
         }
379
-        if (! empty($insufficient_spaces_available)) {
379
+        if ( ! empty($insufficient_spaces_available)) {
380 380
             $subsections['insufficient_space'] = $this->_insufficient_spaces_available(
381 381
                 $insufficient_spaces_available
382 382
             );
383 383
         }
384
-        if (! empty($registrations_requiring_pre_approval)) {
384
+        if ( ! empty($registrations_requiring_pre_approval)) {
385 385
             $subsections['registrations_requiring_pre_approval'] = $this->_registrations_requiring_pre_approval(
386 386
                 $registrations_requiring_pre_approval
387 387
             );
388 388
         }
389
-        if (! empty($registrations_for_free_events)) {
389
+        if ( ! empty($registrations_for_free_events)) {
390 390
             $subsections['no_payment_required'] = $this->_no_payment_required($registrations_for_free_events);
391 391
         }
392
-        if (! empty($registrations_requiring_payment)) {
392
+        if ( ! empty($registrations_requiring_payment)) {
393 393
             if ($this->checkout->amount_owing > 0) {
394 394
                 // autoload Line_Item_Display classes
395 395
                 EEH_Autoloader::register_line_item_filter_autoloaders();
@@ -410,7 +410,7 @@  discard block
 block discarded – undo
410 410
                         ['registrations' => $registrations]
411 411
                     )
412 412
                 );
413
-                $this->checkout->amount_owing   = $filtered_line_item_tree->total();
413
+                $this->checkout->amount_owing = $filtered_line_item_tree->total();
414 414
                 $this->_apply_registration_payments_to_amount_owing($registrations);
415 415
             }
416 416
             $no_payment_required = false;
@@ -454,13 +454,13 @@  discard block
 block discarded – undo
454 454
      */
455 455
     public static function add_spco_line_item_filters(EE_Line_Item_Filter_Collection $line_item_filter_collection)
456 456
     {
457
-        if (! EE_Registry::instance()->SSN instanceof EE_Session) {
457
+        if ( ! EE_Registry::instance()->SSN instanceof EE_Session) {
458 458
             return $line_item_filter_collection;
459 459
         }
460
-        if (! EE_Registry::instance()->SSN->checkout() instanceof EE_Checkout) {
460
+        if ( ! EE_Registry::instance()->SSN->checkout() instanceof EE_Checkout) {
461 461
             return $line_item_filter_collection;
462 462
         }
463
-        if (! EE_Registry::instance()->SSN->checkout()->transaction instanceof EE_Transaction) {
463
+        if ( ! EE_Registry::instance()->SSN->checkout()->transaction instanceof EE_Transaction) {
464 464
             return $line_item_filter_collection;
465 465
         }
466 466
         $line_item_filter_collection->add(
@@ -500,8 +500,8 @@  discard block
 block discarded – undo
500 500
         );
501 501
         foreach ($registrations as $REG_ID => $registration) {
502 502
             // has this registration lost it's space ?
503
-            if (isset($ejected_registrations[ $REG_ID ])) {
504
-                unset($registrations[ $REG_ID ]);
503
+            if (isset($ejected_registrations[$REG_ID])) {
504
+                unset($registrations[$REG_ID]);
505 505
             }
506 506
         }
507 507
         return $registrations;
@@ -551,25 +551,25 @@  discard block
 block discarded – undo
551 551
             }
552 552
             $EVT_ID = $registration->event_ID();
553 553
             $ticket = $registration->ticket();
554
-            if (! isset($tickets_remaining[ $ticket->ID() ])) {
555
-                $tickets_remaining[ $ticket->ID() ] = $ticket->remaining();
554
+            if ( ! isset($tickets_remaining[$ticket->ID()])) {
555
+                $tickets_remaining[$ticket->ID()] = $ticket->remaining();
556 556
             }
557
-            if ($tickets_remaining[ $ticket->ID() ] > 0) {
558
-                if (! isset($event_reg_count[ $EVT_ID ])) {
559
-                    $event_reg_count[ $EVT_ID ] = 0;
557
+            if ($tickets_remaining[$ticket->ID()] > 0) {
558
+                if ( ! isset($event_reg_count[$EVT_ID])) {
559
+                    $event_reg_count[$EVT_ID] = 0;
560 560
                 }
561
-                $event_reg_count[ $EVT_ID ]++;
562
-                if (! isset($event_spaces_remaining[ $EVT_ID ])) {
563
-                    $event_spaces_remaining[ $EVT_ID ] = $registration->event()->spaces_remaining_for_sale();
561
+                $event_reg_count[$EVT_ID]++;
562
+                if ( ! isset($event_spaces_remaining[$EVT_ID])) {
563
+                    $event_spaces_remaining[$EVT_ID] = $registration->event()->spaces_remaining_for_sale();
564 564
                 }
565 565
             }
566 566
             if (
567 567
                 $revisit
568
-                && ($tickets_remaining[ $ticket->ID() ] === 0
569
-                    || $event_reg_count[ $EVT_ID ] > $event_spaces_remaining[ $EVT_ID ]
568
+                && ($tickets_remaining[$ticket->ID()] === 0
569
+                    || $event_reg_count[$EVT_ID] > $event_spaces_remaining[$EVT_ID]
570 570
                 )
571 571
             ) {
572
-                $ejected_registrations[ $REG_ID ] = $registration->event();
572
+                $ejected_registrations[$REG_ID] = $registration->event();
573 573
                 if ($registration->status_ID() !== RegStatus::WAIT_LIST) {
574 574
                     /** @type EE_Registration_Processor $registration_processor */
575 575
                     $registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
@@ -629,7 +629,7 @@  discard block
 block discarded – undo
629 629
         foreach ($sold_out_events_array as $sold_out_event) {
630 630
             $sold_out_events .= EEH_HTML::li(
631 631
                 EEH_HTML::span(
632
-                    '  ' . $sold_out_event->name(),
632
+                    '  '.$sold_out_event->name(),
633 633
                     '',
634 634
                     'dashicons dashicons-marker ee-icon-size-16 pink-text'
635 635
                 )
@@ -685,7 +685,7 @@  discard block
 block discarded – undo
685 685
         foreach ($insufficient_spaces_events_array as $event) {
686 686
             if ($event instanceof EE_Event) {
687 687
                 $insufficient_space_events .= EEH_HTML::li(
688
-                    EEH_HTML::span(' ' . $event->name(), '', 'dashicons dashicons-marker ee-icon-size-16 pink-text')
688
+                    EEH_HTML::span(' '.$event->name(), '', 'dashicons dashicons-marker ee-icon-size-16 pink-text')
689 689
                 );
690 690
             }
691 691
         }
@@ -734,7 +734,7 @@  discard block
 block discarded – undo
734 734
         $events_requiring_pre_approval = [];
735 735
         foreach ($registrations_requiring_pre_approval as $registration) {
736 736
             if ($registration instanceof EE_Registration && $registration->event() instanceof EE_Event) {
737
-                $events_requiring_pre_approval[ $registration->event()->ID() ] = EEH_HTML::li(
737
+                $events_requiring_pre_approval[$registration->event()->ID()] = EEH_HTML::li(
738 738
                     EEH_HTML::span(
739 739
                         '',
740 740
                         '',
@@ -874,7 +874,7 @@  discard block
 block discarded – undo
874 874
     {
875 875
         return new EE_Form_Section_Proper(
876 876
             [
877
-                'html_id'         => 'ee-' . $this->slug() . '-extra-hidden-inputs',
877
+                'html_id'         => 'ee-'.$this->slug().'-extra-hidden-inputs',
878 878
                 'layout_strategy' => new EE_Div_Per_Section_Layout(),
879 879
                 'subsections'     => [
880 880
                     'spco_no_payment_required' => new EE_Hidden_Input(
@@ -913,7 +913,7 @@  discard block
 block discarded – undo
913 913
                 $payments += $registration->registration_payments();
914 914
             }
915 915
         }
916
-        if (! empty($payments)) {
916
+        if ( ! empty($payments)) {
917 917
             foreach ($payments as $payment) {
918 918
                 if ($payment instanceof EE_Registration_Payment) {
919 919
                     $this->checkout->amount_owing -= $payment->amount();
@@ -1002,7 +1002,7 @@  discard block
 block discarded – undo
1002 1002
             );
1003 1003
         }
1004 1004
         // switch up header depending on number of available payment methods
1005
-        $payment_method_header     = count($this->checkout->available_payment_methods) > 1
1005
+        $payment_method_header = count($this->checkout->available_payment_methods) > 1
1006 1006
             ? apply_filters(
1007 1007
                 'FHEE__registration_page_payment_options__method_of_payment_hdr',
1008 1008
                 esc_html__('Please Select Your Method of Payment', 'event_espresso')
@@ -1036,7 +1036,7 @@  discard block
 block discarded – undo
1036 1036
                 $payment_method_button = EEH_HTML::img(
1037 1037
                     $payment_method->button_url(),
1038 1038
                     $payment_method->name(),
1039
-                    'spco-payment-method-' . $payment_method->slug() . '-btn-img',
1039
+                    'spco-payment-method-'.$payment_method->slug().'-btn-img',
1040 1040
                     'spco-payment-method-btn-img'
1041 1041
                 );
1042 1042
                 // check if any payment methods are set as default
@@ -1044,15 +1044,15 @@  discard block
 block discarded – undo
1044 1044
                 // open_by_default
1045 1045
                 if (
1046 1046
                     ($this->checkout->selected_method_of_payment === $payment_method->slug())
1047
-                    || (! $this->checkout->selected_method_of_payment && $payment_method->open_by_default())
1047
+                    || ( ! $this->checkout->selected_method_of_payment && $payment_method->open_by_default())
1048 1048
                 ) {
1049 1049
                     $this->checkout->selected_method_of_payment = $payment_method->slug();
1050 1050
                     $this->_save_selected_method_of_payment();
1051
-                    $default_payment_method_option[ $payment_method->slug() ] = $payment_method_button;
1051
+                    $default_payment_method_option[$payment_method->slug()] = $payment_method_button;
1052 1052
                 } else {
1053
-                    $available_payment_method_options[ $payment_method->slug() ] = $payment_method_button;
1053
+                    $available_payment_method_options[$payment_method->slug()] = $payment_method_button;
1054 1054
                 }
1055
-                $payment_methods_billing_info[ $payment_method->slug() . '-info' ] =
1055
+                $payment_methods_billing_info[$payment_method->slug().'-info'] =
1056 1056
                     $this->_payment_method_billing_info(
1057 1057
                         $payment_method
1058 1058
                     );
@@ -1065,7 +1065,7 @@  discard block
 block discarded – undo
1065 1065
         $available_payment_methods['available_payment_methods'] = $this->_available_payment_method_inputs(
1066 1066
             $available_payment_method_options
1067 1067
         );
1068
-        $available_payment_methods                              += $payment_methods_billing_info;
1068
+        $available_payment_methods += $payment_methods_billing_info;
1069 1069
         // build the available payment methods form
1070 1070
         return new EE_Form_Section_Proper(
1071 1071
             [
@@ -1088,7 +1088,7 @@  discard block
 block discarded – undo
1088 1088
      */
1089 1089
     protected function _get_available_payment_methods()
1090 1090
     {
1091
-        if (! empty($this->checkout->available_payment_methods)) {
1091
+        if ( ! empty($this->checkout->available_payment_methods)) {
1092 1092
             return $this->checkout->available_payment_methods;
1093 1093
         }
1094 1094
         $available_payment_methods = [];
@@ -1100,7 +1100,7 @@  discard block
 block discarded – undo
1100 1100
         );
1101 1101
         foreach ($payment_methods as $payment_method) {
1102 1102
             if ($payment_method instanceof EE_Payment_Method) {
1103
-                $available_payment_methods[ $payment_method->slug() ] = $payment_method;
1103
+                $available_payment_methods[$payment_method->slug()] = $payment_method;
1104 1104
             }
1105 1105
         }
1106 1106
         return $available_payment_methods;
@@ -1195,7 +1195,7 @@  discard block
 block discarded – undo
1195 1195
         );
1196 1196
         return new EE_Form_Section_Proper(
1197 1197
             [
1198
-                'html_id'         => 'spco-payment-method-info-' . $payment_method->slug(),
1198
+                'html_id'         => 'spco-payment-method-info-'.$payment_method->slug(),
1199 1199
                 'html_class'      => 'spco-payment-method-info-dv',
1200 1200
                 // only display the selected or default PM
1201 1201
                 'html_style'      => $currently_selected ? '' : 'display:none;',
@@ -1224,7 +1224,7 @@  discard block
 block discarded – undo
1224 1224
         // how have they chosen to pay?
1225 1225
         $this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment(true);
1226 1226
         $this->checkout->payment_method             = $this->_get_payment_method_for_selected_method_of_payment();
1227
-        if (! $this->checkout->payment_method instanceof EE_Payment_Method) {
1227
+        if ( ! $this->checkout->payment_method instanceof EE_Payment_Method) {
1228 1228
             return false;
1229 1229
         }
1230 1230
         if (
@@ -1398,7 +1398,7 @@  discard block
 block discarded – undo
1398 1398
      */
1399 1399
     public function switch_payment_method()
1400 1400
     {
1401
-        if (! $this->_verify_payment_method_is_set()) {
1401
+        if ( ! $this->_verify_payment_method_is_set()) {
1402 1402
             return false;
1403 1403
         }
1404 1404
         if (
@@ -1534,7 +1534,7 @@  discard block
 block discarded – undo
1534 1534
             }
1535 1535
         }
1536 1536
         // verify payment method
1537
-        if (! $this->checkout->payment_method instanceof EE_Payment_Method) {
1537
+        if ( ! $this->checkout->payment_method instanceof EE_Payment_Method) {
1538 1538
             // get payment method for selected method of payment
1539 1539
             $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment();
1540 1540
         }
@@ -1559,7 +1559,7 @@  discard block
 block discarded – undo
1559 1559
      */
1560 1560
     public function save_payer_details_via_ajax()
1561 1561
     {
1562
-        if (! $this->_verify_payment_method_is_set()) {
1562
+        if ( ! $this->_verify_payment_method_is_set()) {
1563 1563
             return;
1564 1564
         }
1565 1565
         // generate billing form for selected method of payment if it hasn't been done already
@@ -1569,7 +1569,7 @@  discard block
 block discarded – undo
1569 1569
             );
1570 1570
         }
1571 1571
         // generate primary attendee from payer info if applicable
1572
-        if (! $this->checkout->transaction_has_primary_registrant()) {
1572
+        if ( ! $this->checkout->transaction_has_primary_registrant()) {
1573 1573
             $attendee = $this->_create_attendee_from_request_data();
1574 1574
             if ($attendee instanceof EE_Attendee) {
1575 1575
                 foreach ($this->checkout->transaction->registrations() as $registration) {
@@ -1600,7 +1600,7 @@  discard block
 block discarded – undo
1600 1600
     {
1601 1601
         // get State ID
1602 1602
         $STA_ID = $this->request->getRequestParam('state');
1603
-        if (! empty($STA_ID)) {
1603
+        if ( ! empty($STA_ID)) {
1604 1604
             // can we get state object from name ?
1605 1605
             EE_Registry::instance()->load_model('State');
1606 1606
             $state  = EEM_State::instance()->get_col([['STA_name' => $STA_ID], 'limit' => 1], 'STA_ID');
@@ -1608,7 +1608,7 @@  discard block
 block discarded – undo
1608 1608
         }
1609 1609
         // get Country ISO
1610 1610
         $CNT_ISO = $this->request->getRequestParam('country');
1611
-        if (! empty($CNT_ISO)) {
1611
+        if ( ! empty($CNT_ISO)) {
1612 1612
             // can we get country object from name ?
1613 1613
             EE_Registry::instance()->load_model('Country');
1614 1614
             $country = EEM_Country::instance()->get_col(
@@ -1789,7 +1789,7 @@  discard block
 block discarded – undo
1789 1789
     protected function _maybe_set_completed(EE_Payment $payment)
1790 1790
     {
1791 1791
         // Do we need to redirect them? If so, there's more work to be done.
1792
-        if (! $payment->redirect_url()) {
1792
+        if ( ! $payment->redirect_url()) {
1793 1793
             $this->set_completed();
1794 1794
         }
1795 1795
     }
@@ -1846,7 +1846,7 @@  discard block
 block discarded – undo
1846 1846
     private function _process_payment()
1847 1847
     {
1848 1848
         // basically confirm that the event hasn't sold out since they hit the page
1849
-        if (! $this->_last_second_ticket_verifications()) {
1849
+        if ( ! $this->_last_second_ticket_verifications()) {
1850 1850
             return null;
1851 1851
         }
1852 1852
         // ya gotta make a choice man
@@ -1857,7 +1857,7 @@  discard block
 block discarded – undo
1857 1857
             return null;
1858 1858
         }
1859 1859
         // get EE_Payment_Method object
1860
-        if (! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()) {
1860
+        if ( ! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()) {
1861 1861
             return null;
1862 1862
         }
1863 1863
         // setup billing form
@@ -1866,12 +1866,12 @@  discard block
 block discarded – undo
1866 1866
                 $this->checkout->payment_method
1867 1867
             );
1868 1868
             // bad billing form ?
1869
-            if (! $this->_billing_form_is_valid()) {
1869
+            if ( ! $this->_billing_form_is_valid()) {
1870 1870
                 return null;
1871 1871
             }
1872 1872
         }
1873 1873
         // ensure primary registrant has been fully processed
1874
-        if (! $this->_setup_primary_registrant_prior_to_payment()) {
1874
+        if ( ! $this->_setup_primary_registrant_prior_to_payment()) {
1875 1875
             return null;
1876 1876
         }
1877 1877
         // if session is close to expiring (under 10 minutes by default)
@@ -1927,7 +1927,7 @@  discard block
 block discarded – undo
1927 1927
     protected function _last_second_ticket_verifications()
1928 1928
     {
1929 1929
         // don't bother re-validating if not a return visit
1930
-        if (! $this->checkout->revisit) {
1930
+        if ( ! $this->checkout->revisit) {
1931 1931
             return true;
1932 1932
         }
1933 1933
         $registrations = $this->checkout->transaction->registrations();
@@ -1977,7 +1977,7 @@  discard block
 block discarded – undo
1977 1977
             $this->_get_payment_method_for_selected_method_of_payment()
1978 1978
         );
1979 1979
         $html                        = $payment_method_billing_info->get_html();
1980
-        $html                        .= $this->checkout->redirect_form;
1980
+        $html .= $this->checkout->redirect_form;
1981 1981
         /** @var ResponseInterface $response */
1982 1982
         $response = LoaderFactory::getLoader()->getShared(ResponseInterface::class);
1983 1983
         $response->addOutput($html);
@@ -1993,7 +1993,7 @@  discard block
 block discarded – undo
1993 1993
      */
1994 1994
     private function _billing_form_is_valid()
1995 1995
     {
1996
-        if (! $this->checkout->payment_method->type_obj()->has_billing_form()) {
1996
+        if ( ! $this->checkout->payment_method->type_obj()->has_billing_form()) {
1997 1997
             return true;
1998 1998
         }
1999 1999
         if ($this->checkout->billing_form instanceof EE_Billing_Info_Form) {
@@ -2114,16 +2114,16 @@  discard block
 block discarded – undo
2114 2114
     private function _capture_primary_registration_data_from_billing_form(): bool
2115 2115
     {
2116 2116
         $primary_registration = $this->checkout->transaction->primary_registration();
2117
-        if (! $this->validatePrimaryRegistration($primary_registration)) {
2117
+        if ( ! $this->validatePrimaryRegistration($primary_registration)) {
2118 2118
             return false;
2119 2119
         }
2120 2120
 
2121 2121
         $primary_attendee = $this->getPrimaryAttendee($primary_registration);
2122
-        if (! $this->validatePrimaryAttendee($primary_attendee)) {
2122
+        if ( ! $this->validatePrimaryAttendee($primary_attendee)) {
2123 2123
             return false;
2124 2124
         }
2125 2125
 
2126
-        if (! $this->addAttendeeToPrimaryRegistration($primary_attendee, $primary_registration)) {
2126
+        if ( ! $this->addAttendeeToPrimaryRegistration($primary_attendee, $primary_registration)) {
2127 2127
             return false;
2128 2128
         }
2129 2129
         // both the primary registration and primary attendee objects should be valid entities at this point
@@ -2291,8 +2291,8 @@  discard block
 block discarded – undo
2291 2291
             return null;
2292 2292
         }
2293 2293
         // get EE_Payment_Method object
2294
-        if (isset($this->checkout->available_payment_methods[ $this->checkout->selected_method_of_payment ])) {
2295
-            $payment_method = $this->checkout->available_payment_methods[ $this->checkout->selected_method_of_payment ];
2294
+        if (isset($this->checkout->available_payment_methods[$this->checkout->selected_method_of_payment])) {
2295
+            $payment_method = $this->checkout->available_payment_methods[$this->checkout->selected_method_of_payment];
2296 2296
         } else {
2297 2297
             // load EEM_Payment_Method
2298 2298
             EE_Registry::instance()->load_model('Payment_Method');
@@ -2300,7 +2300,7 @@  discard block
 block discarded – undo
2300 2300
             $payment_method     = $EEM_Payment_Method->get_one_by_slug($this->checkout->selected_method_of_payment);
2301 2301
         }
2302 2302
         // verify $payment_method
2303
-        if (! $payment_method instanceof EE_Payment_Method) {
2303
+        if ( ! $payment_method instanceof EE_Payment_Method) {
2304 2304
             // not a payment
2305 2305
             EE_Error::add_error(
2306 2306
                 sprintf(
@@ -2318,7 +2318,7 @@  discard block
 block discarded – undo
2318 2318
             return null;
2319 2319
         }
2320 2320
         // and verify it has a valid Payment_Method Type object
2321
-        if (! $payment_method->type_obj() instanceof EE_PMT_Base) {
2321
+        if ( ! $payment_method->type_obj() instanceof EE_PMT_Base) {
2322 2322
             // not a payment
2323 2323
             EE_Error::add_error(
2324 2324
                 sprintf(
@@ -2356,7 +2356,7 @@  discard block
 block discarded – undo
2356 2356
         $this->checkout->transaction->save();
2357 2357
         /** @var PaymentProcessor $payment_processor */
2358 2358
         $payment_processor = LoaderFactory::getShared(PaymentProcessor::class);
2359
-        if (! $payment_processor instanceof PaymentProcessor) {
2359
+        if ( ! $payment_processor instanceof PaymentProcessor) {
2360 2360
             return null;
2361 2361
         }
2362 2362
         /** @var EE_Transaction_Processor $transaction_processor */
@@ -2459,7 +2459,7 @@  discard block
 block discarded – undo
2459 2459
             return true;
2460 2460
         }
2461 2461
         // verify payment object
2462
-        if (! $payment instanceof EE_Payment) {
2462
+        if ( ! $payment instanceof EE_Payment) {
2463 2463
             // not a payment
2464 2464
             EE_Error::add_error(
2465 2465
                 sprintf(
@@ -2509,7 +2509,7 @@  discard block
 block discarded – undo
2509 2509
                 // and lastly, let's bump the payment status to pending
2510 2510
                 $payment->set_status(EEM_Payment::status_id_pending);
2511 2511
                 $payment->save();
2512
-            } elseif (! $this->_process_payment_status($payment, EE_PMT_Base::onsite)) {
2512
+            } elseif ( ! $this->_process_payment_status($payment, EE_PMT_Base::onsite)) {
2513 2513
                 // User shouldn't be redirected. So let's process it here.
2514 2514
                 // $this->_setup_redirect_for_next_step();
2515 2515
                 $this->checkout->continue_reg = false;
@@ -2590,7 +2590,7 @@  discard block
 block discarded – undo
2590 2590
                     return false;
2591 2591
                 // bad payment
2592 2592
                 case EEM_Payment::status_id_failed:
2593
-                    if (! empty($msg)) {
2593
+                    if ( ! empty($msg)) {
2594 2594
                         EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2595 2595
                         return false;
2596 2596
                     }
@@ -2648,18 +2648,18 @@  discard block
 block discarded – undo
2648 2648
         // how have they chosen to pay?
2649 2649
         $this->checkout->selected_method_of_payment = $this->_get_selected_method_of_payment(true);
2650 2650
         // get EE_Payment_Method object
2651
-        if (! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()) {
2651
+        if ( ! $this->checkout->payment_method = $this->_get_payment_method_for_selected_method_of_payment()) {
2652 2652
             $this->checkout->continue_reg = false;
2653 2653
             return false;
2654 2654
         }
2655
-        if (! $this->checkout->payment_method->is_off_site()) {
2655
+        if ( ! $this->checkout->payment_method->is_off_site()) {
2656 2656
             return false;
2657 2657
         }
2658 2658
         $this->_validate_offsite_return();
2659 2659
         // verify TXN
2660 2660
         if ($this->checkout->transaction instanceof EE_Transaction) {
2661 2661
             $gateway = $this->checkout->payment_method->type_obj()->get_gateway();
2662
-            if (! $gateway instanceof EE_Offsite_Gateway) {
2662
+            if ( ! $gateway instanceof EE_Offsite_Gateway) {
2663 2663
                 $this->checkout->continue_reg = false;
2664 2664
                 return false;
2665 2665
             }
@@ -2673,7 +2673,7 @@  discard block
 block discarded – undo
2673 2673
                 $this->checkout->payment = $payment;
2674 2674
                 // mark this reg step as completed, as long as gateway doesn't use a separate IPN request,
2675 2675
                 // because we will complete this step during the IPN processing then
2676
-                if (! $this->handle_IPN_in_this_request()) {
2676
+                if ( ! $this->handle_IPN_in_this_request()) {
2677 2677
                     $this->set_completed();
2678 2678
                 }
2679 2679
                 return true;
@@ -2776,13 +2776,13 @@  discard block
 block discarded – undo
2776 2776
      */
2777 2777
     private function _redirect_wayward_request(EE_Registration $primary_registrant)
2778 2778
     {
2779
-        if (! $primary_registrant instanceof EE_Registration) {
2779
+        if ( ! $primary_registrant instanceof EE_Registration) {
2780 2780
             // try redirecting based on the current TXN
2781 2781
             $primary_registrant = $this->checkout->transaction instanceof EE_Transaction
2782 2782
                 ? $this->checkout->transaction->primary_registration()
2783 2783
                 : null;
2784 2784
         }
2785
-        if (! $primary_registrant instanceof EE_Registration) {
2785
+        if ( ! $primary_registrant instanceof EE_Registration) {
2786 2786
             EE_Error::add_error(
2787 2787
                 sprintf(
2788 2788
                     esc_html__(
@@ -2853,7 +2853,7 @@  discard block
 block discarded – undo
2853 2853
             $payment = $this->checkout->transaction->last_payment();
2854 2854
             // $payment_source = 'last_payment after Exception';
2855 2855
             // but if we STILL don't have a payment object
2856
-            if (! $payment instanceof EE_Payment) {
2856
+            if ( ! $payment instanceof EE_Payment) {
2857 2857
                 // then we'll object ! ( not object like a thing... but object like what a lawyer says ! )
2858 2858
                 $this->_handle_payment_processor_exception($e);
2859 2859
             }
Please login to merge, or discard this patch.
admin_pages/registrations/EE_Attendee_Contact_List_Table.class.php 2 patches
Indentation   +404 added lines, -404 removed lines patch added patch discarded remove patch
@@ -13,436 +13,436 @@
 block discarded – undo
13 13
  */
14 14
 class EE_Attendee_Contact_List_Table extends EE_Admin_List_Table
15 15
 {
16
-    /**
17
-     * Initial setup of data (called by parent).
18
-     *
19
-     * @throws EE_Error
20
-     * @throws ReflectionException
21
-     */
22
-    protected function _setup_data()
23
-    {
24
-        $this->_data = $this->_view !== 'trash'
25
-            ? $this->_admin_page->get_attendees($this->_per_page)
26
-            : $this->_admin_page->get_attendees($this->_per_page, false, true);
27
-
28
-        $this->_all_data_count = $this->_view !== 'trash'
29
-            ? $this->_admin_page->get_attendees($this->_per_page, true)
30
-            : $this->_admin_page->get_attendees($this->_per_page, true, true);
31
-    }
32
-
33
-
34
-    /**
35
-     * Initial setup of properties.
36
-     */
37
-    protected function _set_properties()
38
-    {
39
-        $this->_wp_list_args = [
40
-            'singular' => esc_html__('attendee', 'event_espresso'),
41
-            'plural'   => esc_html__('attendees', 'event_espresso'),
42
-            'ajax'     => true,
43
-            'screen'   => $this->_admin_page->get_current_screen()->id,
44
-        ];
45
-
46
-        $this->_columns = [
47
-            'cb'                 => '<input type="checkbox" />', // Render a checkbox instead of text
48
-            'id'                 => esc_html__('ID', 'event_espresso'),
49
-            'ATT_fname'          => esc_html__('First Name', 'event_espresso'),
50
-            'ATT_lname'          => esc_html__('Last Name', 'event_espresso'),
51
-            'ATT_email'          => esc_html__('Email Address', 'event_espresso'),
52
-            'Registration_Count' => esc_html__('# Reg', 'event_espresso'),
53
-            'ATT_phone'          => esc_html__('Phone', 'event_espresso'),
54
-            'ATT_address'        => esc_html__('Address', 'event_espresso'),
55
-            'ATT_city'           => esc_html__('City', 'event_espresso'),
56
-            'STA_ID'             => esc_html__('State/Province', 'event_espresso'),
57
-            'CNT_ISO'            => esc_html__('Country', 'event_espresso'),
58
-        ];
59
-
60
-        $this->_sortable_columns = [
61
-            'id'                 => ['id' => false],
62
-            'ATT_lname'          => ['ATT_lname' => true], // true means its already sorted
63
-            'ATT_fname'          => ['ATT_fname' => false],
64
-            'ATT_email'          => ['ATT_email' => false],
65
-            'Registration_Count' => ['Registration_Count' => false],
66
-            'ATT_city'           => ['ATT_city' => false],
67
-            'STA_ID'             => ['STA_ID' => false],
68
-            'CNT_ISO'            => ['CNT_ISO' => false],
69
-        ];
70
-
71
-        $this->_hidden_columns = [
72
-            'ATT_phone',
73
-            'ATT_address',
74
-            'ATT_city',
75
-            'STA_ID',
76
-            'CNT_ISO',
77
-        ];
78
-    }
79
-
80
-
81
-    /**
82
-     * Initial setup of filters
83
-     *
84
-     * @return array
85
-     */
86
-    protected function _get_table_filters()
87
-    {
88
-        return [];
89
-    }
90
-
91
-
92
-    /**
93
-     * Initial setup of counts for views
94
-     *
95
-     * @throws InvalidArgumentException
96
-     * @throws InvalidDataTypeException
97
-     * @throws InvalidInterfaceException
98
-     * @throws EE_Error
99
-     * @throws EE_Error
100
-     * @throws ReflectionException
101
-     */
102
-    protected function _add_view_counts()
103
-    {
104
-        $this->_views['in_use']['count'] = $this->_admin_page->get_attendees($this->_per_page, true);
105
-        if (
106
-            EE_Registry::instance()->CAP->current_user_can(
107
-                'ee_delete_contacts',
108
-                'espresso_registrations_delete_registration'
109
-            )
110
-        ) {
111
-            $this->_views['trash']['count'] = $this->_admin_page->get_attendees($this->_per_page, true, true);
112
-        }
113
-    }
114
-
115
-
116
-    /**
117
-     * Get count of attendees.
118
-     *
119
-     * @return int
120
-     * @throws EE_Error
121
-     * @throws InvalidArgumentException
122
-     * @throws InvalidDataTypeException
123
-     * @throws InvalidInterfaceException
124
-     * @throws ReflectionException
125
-     */
126
-    protected function _get_attendees_count(): int
127
-    {
128
-        return EEM_Attendee::instance()->count();
129
-    }
130
-
131
-
132
-    /**
133
-     * Checkbox column
134
-     *
135
-     * @param EE_Attendee $item Unable to typehint this method because overrides parent.
136
-     * @return string
137
-     * @throws EE_Error
138
-     * @throws ReflectionException
139
-     */
140
-    public function column_cb($item): string
141
-    {
142
-        if (! $item instanceof EE_Attendee) {
143
-            return '';
144
-        }
145
-        return sprintf(
146
-            '<input type="checkbox" name="ATT_IDs[%1$s]" value="%1$s" />',
147
-            $item->ID()
148
-        );
149
-    }
150
-
151
-
152
-    /**
153
-     * @param EE_Attendee|null $attendee
154
-     * @return string
155
-     * @throws EE_Error
156
-     * @throws ReflectionException
157
-     */
158
-    public function column_id(?EE_Attendee $attendee): string
159
-    {
160
-        $content = '
16
+	/**
17
+	 * Initial setup of data (called by parent).
18
+	 *
19
+	 * @throws EE_Error
20
+	 * @throws ReflectionException
21
+	 */
22
+	protected function _setup_data()
23
+	{
24
+		$this->_data = $this->_view !== 'trash'
25
+			? $this->_admin_page->get_attendees($this->_per_page)
26
+			: $this->_admin_page->get_attendees($this->_per_page, false, true);
27
+
28
+		$this->_all_data_count = $this->_view !== 'trash'
29
+			? $this->_admin_page->get_attendees($this->_per_page, true)
30
+			: $this->_admin_page->get_attendees($this->_per_page, true, true);
31
+	}
32
+
33
+
34
+	/**
35
+	 * Initial setup of properties.
36
+	 */
37
+	protected function _set_properties()
38
+	{
39
+		$this->_wp_list_args = [
40
+			'singular' => esc_html__('attendee', 'event_espresso'),
41
+			'plural'   => esc_html__('attendees', 'event_espresso'),
42
+			'ajax'     => true,
43
+			'screen'   => $this->_admin_page->get_current_screen()->id,
44
+		];
45
+
46
+		$this->_columns = [
47
+			'cb'                 => '<input type="checkbox" />', // Render a checkbox instead of text
48
+			'id'                 => esc_html__('ID', 'event_espresso'),
49
+			'ATT_fname'          => esc_html__('First Name', 'event_espresso'),
50
+			'ATT_lname'          => esc_html__('Last Name', 'event_espresso'),
51
+			'ATT_email'          => esc_html__('Email Address', 'event_espresso'),
52
+			'Registration_Count' => esc_html__('# Reg', 'event_espresso'),
53
+			'ATT_phone'          => esc_html__('Phone', 'event_espresso'),
54
+			'ATT_address'        => esc_html__('Address', 'event_espresso'),
55
+			'ATT_city'           => esc_html__('City', 'event_espresso'),
56
+			'STA_ID'             => esc_html__('State/Province', 'event_espresso'),
57
+			'CNT_ISO'            => esc_html__('Country', 'event_espresso'),
58
+		];
59
+
60
+		$this->_sortable_columns = [
61
+			'id'                 => ['id' => false],
62
+			'ATT_lname'          => ['ATT_lname' => true], // true means its already sorted
63
+			'ATT_fname'          => ['ATT_fname' => false],
64
+			'ATT_email'          => ['ATT_email' => false],
65
+			'Registration_Count' => ['Registration_Count' => false],
66
+			'ATT_city'           => ['ATT_city' => false],
67
+			'STA_ID'             => ['STA_ID' => false],
68
+			'CNT_ISO'            => ['CNT_ISO' => false],
69
+		];
70
+
71
+		$this->_hidden_columns = [
72
+			'ATT_phone',
73
+			'ATT_address',
74
+			'ATT_city',
75
+			'STA_ID',
76
+			'CNT_ISO',
77
+		];
78
+	}
79
+
80
+
81
+	/**
82
+	 * Initial setup of filters
83
+	 *
84
+	 * @return array
85
+	 */
86
+	protected function _get_table_filters()
87
+	{
88
+		return [];
89
+	}
90
+
91
+
92
+	/**
93
+	 * Initial setup of counts for views
94
+	 *
95
+	 * @throws InvalidArgumentException
96
+	 * @throws InvalidDataTypeException
97
+	 * @throws InvalidInterfaceException
98
+	 * @throws EE_Error
99
+	 * @throws EE_Error
100
+	 * @throws ReflectionException
101
+	 */
102
+	protected function _add_view_counts()
103
+	{
104
+		$this->_views['in_use']['count'] = $this->_admin_page->get_attendees($this->_per_page, true);
105
+		if (
106
+			EE_Registry::instance()->CAP->current_user_can(
107
+				'ee_delete_contacts',
108
+				'espresso_registrations_delete_registration'
109
+			)
110
+		) {
111
+			$this->_views['trash']['count'] = $this->_admin_page->get_attendees($this->_per_page, true, true);
112
+		}
113
+	}
114
+
115
+
116
+	/**
117
+	 * Get count of attendees.
118
+	 *
119
+	 * @return int
120
+	 * @throws EE_Error
121
+	 * @throws InvalidArgumentException
122
+	 * @throws InvalidDataTypeException
123
+	 * @throws InvalidInterfaceException
124
+	 * @throws ReflectionException
125
+	 */
126
+	protected function _get_attendees_count(): int
127
+	{
128
+		return EEM_Attendee::instance()->count();
129
+	}
130
+
131
+
132
+	/**
133
+	 * Checkbox column
134
+	 *
135
+	 * @param EE_Attendee $item Unable to typehint this method because overrides parent.
136
+	 * @return string
137
+	 * @throws EE_Error
138
+	 * @throws ReflectionException
139
+	 */
140
+	public function column_cb($item): string
141
+	{
142
+		if (! $item instanceof EE_Attendee) {
143
+			return '';
144
+		}
145
+		return sprintf(
146
+			'<input type="checkbox" name="ATT_IDs[%1$s]" value="%1$s" />',
147
+			$item->ID()
148
+		);
149
+	}
150
+
151
+
152
+	/**
153
+	 * @param EE_Attendee|null $attendee
154
+	 * @return string
155
+	 * @throws EE_Error
156
+	 * @throws ReflectionException
157
+	 */
158
+	public function column_id(?EE_Attendee $attendee): string
159
+	{
160
+		$content = '
161 161
             <span class="ee-entity-id">' . $attendee->ID() . '</span>
162 162
             <span class="show-on-mobile-view-only">
163 163
                 ' . $this->editAttendeeLink($attendee->ID(), $attendee->full_name()) . '
164 164
             </span>';
165
-        return $this->columnContent('id', $content, 'end');
166
-    }
167
-
168
-
169
-    /**
170
-     * ATT_lname column
171
-     *
172
-     * @param EE_Attendee $attendee
173
-     * @return string
174
-     * @throws EE_Error
175
-     * @throws ReflectionException
176
-     */
177
-    public function column_ATT_lname(EE_Attendee $attendee): string
178
-    {
179
-        // edit attendee link
180
-        $content = $this->editAttendeeLink($attendee->ID(), $attendee->lname());
181
-        return $this->columnContent('ATT_lname', $content);
182
-    }
183
-
184
-
185
-    /**
186
-     * @param int    $ID
187
-     * @param string $attendee_name
188
-     * @return string
189
-     * @since   5.0.0.p
190
-     */
191
-    private function editAttendeeLink(int $ID, string $attendee_name): string
192
-    {
193
-        $edit_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
194
-            [
195
-                'action' => 'edit_attendee',
196
-                'post'   => $ID,
197
-            ],
198
-            REG_ADMIN_URL
199
-        );
200
-        return EE_Registry::instance()->CAP->current_user_can(
201
-            'ee_edit_contacts',
202
-            'espresso_registrations_edit_attendee'
203
-        )
204
-            ? '
165
+		return $this->columnContent('id', $content, 'end');
166
+	}
167
+
168
+
169
+	/**
170
+	 * ATT_lname column
171
+	 *
172
+	 * @param EE_Attendee $attendee
173
+	 * @return string
174
+	 * @throws EE_Error
175
+	 * @throws ReflectionException
176
+	 */
177
+	public function column_ATT_lname(EE_Attendee $attendee): string
178
+	{
179
+		// edit attendee link
180
+		$content = $this->editAttendeeLink($attendee->ID(), $attendee->lname());
181
+		return $this->columnContent('ATT_lname', $content);
182
+	}
183
+
184
+
185
+	/**
186
+	 * @param int    $ID
187
+	 * @param string $attendee_name
188
+	 * @return string
189
+	 * @since   5.0.0.p
190
+	 */
191
+	private function editAttendeeLink(int $ID, string $attendee_name): string
192
+	{
193
+		$edit_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
194
+			[
195
+				'action' => 'edit_attendee',
196
+				'post'   => $ID,
197
+			],
198
+			REG_ADMIN_URL
199
+		);
200
+		return EE_Registry::instance()->CAP->current_user_can(
201
+			'ee_edit_contacts',
202
+			'espresso_registrations_edit_attendee'
203
+		)
204
+			? '
205 205
             <a  href="' . $edit_lnk_url . '"
206 206
                 class="ee-aria-tooltip"
207 207
                 aria-label="' . esc_attr__('Edit Contact', 'event_espresso') . '"
208 208
             >
209 209
                 ' . $attendee_name . '
210 210
             </a>'
211
-            : $attendee_name;
212
-    }
213
-
214
-
215
-    /**
216
-     * ATT_fname column
217
-     *
218
-     * @param EE_Attendee $attendee
219
-     * @return string
220
-     * @throws InvalidArgumentException
221
-     * @throws InvalidDataTypeException
222
-     * @throws InvalidInterfaceException
223
-     * @throws EE_Error
224
-     * @throws ReflectionException
225
-     * @throws ReflectionException
226
-     * @throws ReflectionException
227
-     * @throws ReflectionException
228
-     */
229
-    public function column_ATT_fname(EE_Attendee $attendee): string
230
-    {
231
-        // Build row actions
232
-        $actions = [];
233
-        // edit attendee link
234
-        if (
235
-            EE_Registry::instance()->CAP->current_user_can(
236
-                'ee_edit_contacts',
237
-                'espresso_registrations_edit_attendee'
238
-            )
239
-        ) {
240
-            $actions['edit'] = $this->editAttendeeLink(
241
-                $attendee->ID(),
242
-                esc_html__('Edit Contact', 'event_espresso')
243
-            );
244
-        }
245
-
246
-        if ($this->_view === 'in_use') {
247
-            // trash attendee link
248
-            if (
249
-                EE_Registry::instance()->CAP->current_user_can(
250
-                    'ee_delete_contacts',
251
-                    'espresso_registrations_trash_attendees'
252
-                )
253
-            ) {
254
-                $trash_lnk_url    = EE_Admin_Page::add_query_args_and_nonce(
255
-                    [
256
-                        'action' => 'trash_attendee',
257
-                        'ATT_ID' => $attendee->ID(),
258
-                    ],
259
-                    REG_ADMIN_URL
260
-                );
261
-                $actions['trash'] = '
211
+			: $attendee_name;
212
+	}
213
+
214
+
215
+	/**
216
+	 * ATT_fname column
217
+	 *
218
+	 * @param EE_Attendee $attendee
219
+	 * @return string
220
+	 * @throws InvalidArgumentException
221
+	 * @throws InvalidDataTypeException
222
+	 * @throws InvalidInterfaceException
223
+	 * @throws EE_Error
224
+	 * @throws ReflectionException
225
+	 * @throws ReflectionException
226
+	 * @throws ReflectionException
227
+	 * @throws ReflectionException
228
+	 */
229
+	public function column_ATT_fname(EE_Attendee $attendee): string
230
+	{
231
+		// Build row actions
232
+		$actions = [];
233
+		// edit attendee link
234
+		if (
235
+			EE_Registry::instance()->CAP->current_user_can(
236
+				'ee_edit_contacts',
237
+				'espresso_registrations_edit_attendee'
238
+			)
239
+		) {
240
+			$actions['edit'] = $this->editAttendeeLink(
241
+				$attendee->ID(),
242
+				esc_html__('Edit Contact', 'event_espresso')
243
+			);
244
+		}
245
+
246
+		if ($this->_view === 'in_use') {
247
+			// trash attendee link
248
+			if (
249
+				EE_Registry::instance()->CAP->current_user_can(
250
+					'ee_delete_contacts',
251
+					'espresso_registrations_trash_attendees'
252
+				)
253
+			) {
254
+				$trash_lnk_url    = EE_Admin_Page::add_query_args_and_nonce(
255
+					[
256
+						'action' => 'trash_attendee',
257
+						'ATT_ID' => $attendee->ID(),
258
+					],
259
+					REG_ADMIN_URL
260
+				);
261
+				$actions['trash'] = '
262 262
                     <a  href="' . $trash_lnk_url . '"
263 263
                         class="ee-aria-tooltip"
264 264
                         aria-label="' . esc_attr__('Move Contact to Trash', 'event_espresso') . '"
265 265
                     >
266 266
                         ' . esc_html__('Trash', 'event_espresso') . '
267 267
                     </a>';
268
-            }
269
-        } else {
270
-            if (
271
-                EE_Registry::instance()->CAP->current_user_can(
272
-                    'ee_delete_contacts',
273
-                    'espresso_registrations_restore_attendees'
274
-                )
275
-            ) {
276
-                // restore attendee link
277
-                $restore_lnk_url    = EE_Admin_Page::add_query_args_and_nonce(
278
-                    [
279
-                        'action' => 'restore_attendees',
280
-                        'ATT_ID' => $attendee->ID(),
281
-                    ],
282
-                    REG_ADMIN_URL
283
-                );
284
-                $actions['restore'] = '
268
+			}
269
+		} else {
270
+			if (
271
+				EE_Registry::instance()->CAP->current_user_can(
272
+					'ee_delete_contacts',
273
+					'espresso_registrations_restore_attendees'
274
+				)
275
+			) {
276
+				// restore attendee link
277
+				$restore_lnk_url    = EE_Admin_Page::add_query_args_and_nonce(
278
+					[
279
+						'action' => 'restore_attendees',
280
+						'ATT_ID' => $attendee->ID(),
281
+					],
282
+					REG_ADMIN_URL
283
+				);
284
+				$actions['restore'] = '
285 285
                     <a  href="' . $restore_lnk_url . '"
286 286
                         class="ee-aria-tooltip"
287 287
                         aria-label="' . esc_attr__('Restore Contact', 'event_espresso') . '"
288 288
                     >
289 289
                         ' . esc_html__('Restore', 'event_espresso') . '
290 290
                     </a>';
291
-            }
292
-            if (
293
-                EE_Registry::instance()->CAP->current_user_can(
294
-                    'ee_delete_contacts',
295
-                    'espresso_registrations_delete_attendees',
296
-                    $attendee->ID()
297
-                ) 
298
-                && $attendee->count_related('Registration') === 0
299
-            ) {
300
-                // perm delete attendee
301
-                $delete_attendee_link       = EE_Admin_Page::add_query_args_and_nonce(
302
-                    [
303
-                        'action' => 'delete_attendee',
304
-                        'ATT_ID' => $attendee->ID(),
305
-                    ],
306
-                    REG_ADMIN_URL
307
-                );
308
-                $actions['delete'] = '
291
+			}
292
+			if (
293
+				EE_Registry::instance()->CAP->current_user_can(
294
+					'ee_delete_contacts',
295
+					'espresso_registrations_delete_attendees',
296
+					$attendee->ID()
297
+				) 
298
+				&& $attendee->count_related('Registration') === 0
299
+			) {
300
+				// perm delete attendee
301
+				$delete_attendee_link       = EE_Admin_Page::add_query_args_and_nonce(
302
+					[
303
+						'action' => 'delete_attendee',
304
+						'ATT_ID' => $attendee->ID(),
305
+					],
306
+					REG_ADMIN_URL
307
+				);
308
+				$actions['delete'] = '
309 309
                     <a  href="' . $delete_attendee_link . '"
310 310
                         class="ee-aria-tooltip"
311 311
                         aria-label="' . esc_attr__('Delete Permanently', 'event_espresso') . '"
312 312
                     >
313 313
                         ' . esc_attr__('Delete Permanently', 'event_espresso') . '
314 314
                     </a>';
315
-            }
316
-        }
317
-
318
-        $name_link    = $this->editAttendeeLink($attendee->ID(), $attendee->fname());
319
-
320
-        // Return the name contents
321
-        $content = sprintf('%1$s %2$s', $name_link, $this->row_actions($actions));
322
-        return $this->columnContent('ATT_fname', $content);
323
-    }
324
-
325
-
326
-    /**
327
-     * Email Column
328
-     *
329
-     * @param EE_Attendee $attendee
330
-     * @return string
331
-     * @throws EE_Error
332
-     * @throws ReflectionException
333
-     */
334
-    public function column_ATT_email(EE_Attendee $attendee): string
335
-    {
336
-        $content = '<a href="mailto:' . $attendee->email() . '">' . $attendee->email() . '</a>';
337
-        return $this->columnContent('ATT_email', $content);
338
-    }
339
-
340
-
341
-    /**
342
-     * Column displaying count of registrations attached to Attendee.
343
-     *
344
-     * @param EE_Attendee $attendee
345
-     * @return string
346
-     * @throws EE_Error
347
-     * @throws ReflectionException
348
-     */
349
-    public function column_Registration_Count(EE_Attendee $attendee): string
350
-    {
351
-        $link = EEH_URL::add_query_args_and_nonce(
352
-            [
353
-                'action' => 'default',
354
-                'ATT_ID' => $attendee->ID(),
355
-            ],
356
-            REG_ADMIN_URL
357
-        );
358
-        $content = '<a href="' . $link . '">' . $attendee->getCustomSelect('Registration_Count') . '</a>';
359
-        return $this->columnContent('Registration_Count', $content, 'end');
360
-    }
361
-
362
-
363
-    /**
364
-     * ATT_address column
365
-     *
366
-     * @param EE_Attendee $attendee
367
-     * @return string
368
-     * @throws EE_Error
369
-     * @throws ReflectionException
370
-     */
371
-    public function column_ATT_address(EE_Attendee $attendee): string
372
-    {
373
-        return $this->columnContent('ATT_address', $attendee->address());
374
-    }
375
-
376
-
377
-    /**
378
-     * ATT_city column
379
-     *
380
-     * @param EE_Attendee $attendee
381
-     * @return string
382
-     * @throws EE_Error
383
-     * @throws ReflectionException
384
-     */
385
-    public function column_ATT_city(EE_Attendee $attendee): string
386
-    {
387
-        return $this->columnContent('ATT_city', $attendee->city());
388
-    }
389
-
390
-
391
-    /**
392
-     * State Column
393
-     *
394
-     * @param EE_Attendee $attendee
395
-     * @return string
396
-     * @throws EE_Error
397
-     * @throws InvalidArgumentException
398
-     * @throws InvalidDataTypeException
399
-     * @throws InvalidInterfaceException
400
-     * @throws ReflectionException
401
-     */
402
-    public function column_STA_ID(EE_Attendee $attendee): string
403
-    {
404
-        $states = EEM_State::instance()->get_all_states();
405
-        $state  = isset($states[ $attendee->state_ID() ])
406
-            ? $states[ $attendee->state_ID() ]->get('STA_name')
407
-            : $attendee->state_ID();
408
-        $content = ! is_numeric($state) ? $state : '';
409
-        return $this->columnContent('STA_ID', $content);
410
-    }
411
-
412
-
413
-    /**
414
-     * Country Column
415
-     *
416
-     * @param EE_Attendee $attendee
417
-     * @return string
418
-     * @throws EE_Error
419
-     * @throws InvalidArgumentException
420
-     * @throws InvalidDataTypeException
421
-     * @throws InvalidInterfaceException
422
-     * @throws ReflectionException
423
-     * @throws ReflectionException
424
-     */
425
-    public function column_CNT_ISO(EE_Attendee $attendee): string
426
-    {
427
-        $countries = EEM_Country::instance()->get_all_countries();
428
-        $country   = isset($countries[ $attendee->country_ID() ])
429
-            ? $countries[ $attendee->country_ID() ]->get('CNT_name')
430
-            : $attendee->country_ID();
431
-        $content = ! is_numeric($country) ? $country : '';
432
-        return $this->columnContent('CNT_ISO', $content);
433
-    }
434
-
435
-
436
-    /**
437
-     * Phone Number column
438
-     *
439
-     * @param EE_Attendee $attendee
440
-     * @return string
441
-     * @throws EE_Error
442
-     * @throws ReflectionException
443
-     */
444
-    public function column_ATT_phone(EE_Attendee $attendee): string
445
-    {
446
-        return $this->columnContent('ATT_phone', $attendee->phone());
447
-    }
315
+			}
316
+		}
317
+
318
+		$name_link    = $this->editAttendeeLink($attendee->ID(), $attendee->fname());
319
+
320
+		// Return the name contents
321
+		$content = sprintf('%1$s %2$s', $name_link, $this->row_actions($actions));
322
+		return $this->columnContent('ATT_fname', $content);
323
+	}
324
+
325
+
326
+	/**
327
+	 * Email Column
328
+	 *
329
+	 * @param EE_Attendee $attendee
330
+	 * @return string
331
+	 * @throws EE_Error
332
+	 * @throws ReflectionException
333
+	 */
334
+	public function column_ATT_email(EE_Attendee $attendee): string
335
+	{
336
+		$content = '<a href="mailto:' . $attendee->email() . '">' . $attendee->email() . '</a>';
337
+		return $this->columnContent('ATT_email', $content);
338
+	}
339
+
340
+
341
+	/**
342
+	 * Column displaying count of registrations attached to Attendee.
343
+	 *
344
+	 * @param EE_Attendee $attendee
345
+	 * @return string
346
+	 * @throws EE_Error
347
+	 * @throws ReflectionException
348
+	 */
349
+	public function column_Registration_Count(EE_Attendee $attendee): string
350
+	{
351
+		$link = EEH_URL::add_query_args_and_nonce(
352
+			[
353
+				'action' => 'default',
354
+				'ATT_ID' => $attendee->ID(),
355
+			],
356
+			REG_ADMIN_URL
357
+		);
358
+		$content = '<a href="' . $link . '">' . $attendee->getCustomSelect('Registration_Count') . '</a>';
359
+		return $this->columnContent('Registration_Count', $content, 'end');
360
+	}
361
+
362
+
363
+	/**
364
+	 * ATT_address column
365
+	 *
366
+	 * @param EE_Attendee $attendee
367
+	 * @return string
368
+	 * @throws EE_Error
369
+	 * @throws ReflectionException
370
+	 */
371
+	public function column_ATT_address(EE_Attendee $attendee): string
372
+	{
373
+		return $this->columnContent('ATT_address', $attendee->address());
374
+	}
375
+
376
+
377
+	/**
378
+	 * ATT_city column
379
+	 *
380
+	 * @param EE_Attendee $attendee
381
+	 * @return string
382
+	 * @throws EE_Error
383
+	 * @throws ReflectionException
384
+	 */
385
+	public function column_ATT_city(EE_Attendee $attendee): string
386
+	{
387
+		return $this->columnContent('ATT_city', $attendee->city());
388
+	}
389
+
390
+
391
+	/**
392
+	 * State Column
393
+	 *
394
+	 * @param EE_Attendee $attendee
395
+	 * @return string
396
+	 * @throws EE_Error
397
+	 * @throws InvalidArgumentException
398
+	 * @throws InvalidDataTypeException
399
+	 * @throws InvalidInterfaceException
400
+	 * @throws ReflectionException
401
+	 */
402
+	public function column_STA_ID(EE_Attendee $attendee): string
403
+	{
404
+		$states = EEM_State::instance()->get_all_states();
405
+		$state  = isset($states[ $attendee->state_ID() ])
406
+			? $states[ $attendee->state_ID() ]->get('STA_name')
407
+			: $attendee->state_ID();
408
+		$content = ! is_numeric($state) ? $state : '';
409
+		return $this->columnContent('STA_ID', $content);
410
+	}
411
+
412
+
413
+	/**
414
+	 * Country Column
415
+	 *
416
+	 * @param EE_Attendee $attendee
417
+	 * @return string
418
+	 * @throws EE_Error
419
+	 * @throws InvalidArgumentException
420
+	 * @throws InvalidDataTypeException
421
+	 * @throws InvalidInterfaceException
422
+	 * @throws ReflectionException
423
+	 * @throws ReflectionException
424
+	 */
425
+	public function column_CNT_ISO(EE_Attendee $attendee): string
426
+	{
427
+		$countries = EEM_Country::instance()->get_all_countries();
428
+		$country   = isset($countries[ $attendee->country_ID() ])
429
+			? $countries[ $attendee->country_ID() ]->get('CNT_name')
430
+			: $attendee->country_ID();
431
+		$content = ! is_numeric($country) ? $country : '';
432
+		return $this->columnContent('CNT_ISO', $content);
433
+	}
434
+
435
+
436
+	/**
437
+	 * Phone Number column
438
+	 *
439
+	 * @param EE_Attendee $attendee
440
+	 * @return string
441
+	 * @throws EE_Error
442
+	 * @throws ReflectionException
443
+	 */
444
+	public function column_ATT_phone(EE_Attendee $attendee): string
445
+	{
446
+		return $this->columnContent('ATT_phone', $attendee->phone());
447
+	}
448 448
 }
Please login to merge, or discard this patch.
Spacing   +25 added lines, -25 removed lines patch added patch discarded remove patch
@@ -139,7 +139,7 @@  discard block
 block discarded – undo
139 139
      */
140 140
     public function column_cb($item): string
141 141
     {
142
-        if (! $item instanceof EE_Attendee) {
142
+        if ( ! $item instanceof EE_Attendee) {
143 143
             return '';
144 144
         }
145 145
         return sprintf(
@@ -158,9 +158,9 @@  discard block
 block discarded – undo
158 158
     public function column_id(?EE_Attendee $attendee): string
159 159
     {
160 160
         $content = '
161
-            <span class="ee-entity-id">' . $attendee->ID() . '</span>
161
+            <span class="ee-entity-id">' . $attendee->ID().'</span>
162 162
             <span class="show-on-mobile-view-only">
163
-                ' . $this->editAttendeeLink($attendee->ID(), $attendee->full_name()) . '
163
+                ' . $this->editAttendeeLink($attendee->ID(), $attendee->full_name()).'
164 164
             </span>';
165 165
         return $this->columnContent('id', $content, 'end');
166 166
     }
@@ -202,11 +202,11 @@  discard block
 block discarded – undo
202 202
             'espresso_registrations_edit_attendee'
203 203
         )
204 204
             ? '
205
-            <a  href="' . $edit_lnk_url . '"
205
+            <a  href="' . $edit_lnk_url.'"
206 206
                 class="ee-aria-tooltip"
207
-                aria-label="' . esc_attr__('Edit Contact', 'event_espresso') . '"
207
+                aria-label="' . esc_attr__('Edit Contact', 'event_espresso').'"
208 208
             >
209
-                ' . $attendee_name . '
209
+                ' . $attendee_name.'
210 210
             </a>'
211 211
             : $attendee_name;
212 212
     }
@@ -251,7 +251,7 @@  discard block
 block discarded – undo
251 251
                     'espresso_registrations_trash_attendees'
252 252
                 )
253 253
             ) {
254
-                $trash_lnk_url    = EE_Admin_Page::add_query_args_and_nonce(
254
+                $trash_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
255 255
                     [
256 256
                         'action' => 'trash_attendee',
257 257
                         'ATT_ID' => $attendee->ID(),
@@ -259,11 +259,11 @@  discard block
 block discarded – undo
259 259
                     REG_ADMIN_URL
260 260
                 );
261 261
                 $actions['trash'] = '
262
-                    <a  href="' . $trash_lnk_url . '"
262
+                    <a  href="' . $trash_lnk_url.'"
263 263
                         class="ee-aria-tooltip"
264
-                        aria-label="' . esc_attr__('Move Contact to Trash', 'event_espresso') . '"
264
+                        aria-label="' . esc_attr__('Move Contact to Trash', 'event_espresso').'"
265 265
                     >
266
-                        ' . esc_html__('Trash', 'event_espresso') . '
266
+                        ' . esc_html__('Trash', 'event_espresso').'
267 267
                     </a>';
268 268
             }
269 269
         } else {
@@ -274,7 +274,7 @@  discard block
 block discarded – undo
274 274
                 )
275 275
             ) {
276 276
                 // restore attendee link
277
-                $restore_lnk_url    = EE_Admin_Page::add_query_args_and_nonce(
277
+                $restore_lnk_url = EE_Admin_Page::add_query_args_and_nonce(
278 278
                     [
279 279
                         'action' => 'restore_attendees',
280 280
                         'ATT_ID' => $attendee->ID(),
@@ -282,11 +282,11 @@  discard block
 block discarded – undo
282 282
                     REG_ADMIN_URL
283 283
                 );
284 284
                 $actions['restore'] = '
285
-                    <a  href="' . $restore_lnk_url . '"
285
+                    <a  href="' . $restore_lnk_url.'"
286 286
                         class="ee-aria-tooltip"
287
-                        aria-label="' . esc_attr__('Restore Contact', 'event_espresso') . '"
287
+                        aria-label="' . esc_attr__('Restore Contact', 'event_espresso').'"
288 288
                     >
289
-                        ' . esc_html__('Restore', 'event_espresso') . '
289
+                        ' . esc_html__('Restore', 'event_espresso').'
290 290
                     </a>';
291 291
             }
292 292
             if (
@@ -298,7 +298,7 @@  discard block
 block discarded – undo
298 298
                 && $attendee->count_related('Registration') === 0
299 299
             ) {
300 300
                 // perm delete attendee
301
-                $delete_attendee_link       = EE_Admin_Page::add_query_args_and_nonce(
301
+                $delete_attendee_link = EE_Admin_Page::add_query_args_and_nonce(
302 302
                     [
303 303
                         'action' => 'delete_attendee',
304 304
                         'ATT_ID' => $attendee->ID(),
@@ -306,16 +306,16 @@  discard block
 block discarded – undo
306 306
                     REG_ADMIN_URL
307 307
                 );
308 308
                 $actions['delete'] = '
309
-                    <a  href="' . $delete_attendee_link . '"
309
+                    <a  href="' . $delete_attendee_link.'"
310 310
                         class="ee-aria-tooltip"
311
-                        aria-label="' . esc_attr__('Delete Permanently', 'event_espresso') . '"
311
+                        aria-label="' . esc_attr__('Delete Permanently', 'event_espresso').'"
312 312
                     >
313
-                        ' . esc_attr__('Delete Permanently', 'event_espresso') . '
313
+                        ' . esc_attr__('Delete Permanently', 'event_espresso').'
314 314
                     </a>';
315 315
             }
316 316
         }
317 317
 
318
-        $name_link    = $this->editAttendeeLink($attendee->ID(), $attendee->fname());
318
+        $name_link = $this->editAttendeeLink($attendee->ID(), $attendee->fname());
319 319
 
320 320
         // Return the name contents
321 321
         $content = sprintf('%1$s %2$s', $name_link, $this->row_actions($actions));
@@ -333,7 +333,7 @@  discard block
 block discarded – undo
333 333
      */
334 334
     public function column_ATT_email(EE_Attendee $attendee): string
335 335
     {
336
-        $content = '<a href="mailto:' . $attendee->email() . '">' . $attendee->email() . '</a>';
336
+        $content = '<a href="mailto:'.$attendee->email().'">'.$attendee->email().'</a>';
337 337
         return $this->columnContent('ATT_email', $content);
338 338
     }
339 339
 
@@ -355,7 +355,7 @@  discard block
 block discarded – undo
355 355
             ],
356 356
             REG_ADMIN_URL
357 357
         );
358
-        $content = '<a href="' . $link . '">' . $attendee->getCustomSelect('Registration_Count') . '</a>';
358
+        $content = '<a href="'.$link.'">'.$attendee->getCustomSelect('Registration_Count').'</a>';
359 359
         return $this->columnContent('Registration_Count', $content, 'end');
360 360
     }
361 361
 
@@ -402,8 +402,8 @@  discard block
 block discarded – undo
402 402
     public function column_STA_ID(EE_Attendee $attendee): string
403 403
     {
404 404
         $states = EEM_State::instance()->get_all_states();
405
-        $state  = isset($states[ $attendee->state_ID() ])
406
-            ? $states[ $attendee->state_ID() ]->get('STA_name')
405
+        $state  = isset($states[$attendee->state_ID()])
406
+            ? $states[$attendee->state_ID()]->get('STA_name')
407 407
             : $attendee->state_ID();
408 408
         $content = ! is_numeric($state) ? $state : '';
409 409
         return $this->columnContent('STA_ID', $content);
@@ -425,8 +425,8 @@  discard block
 block discarded – undo
425 425
     public function column_CNT_ISO(EE_Attendee $attendee): string
426 426
     {
427 427
         $countries = EEM_Country::instance()->get_all_countries();
428
-        $country   = isset($countries[ $attendee->country_ID() ])
429
-            ? $countries[ $attendee->country_ID() ]->get('CNT_name')
428
+        $country   = isset($countries[$attendee->country_ID()])
429
+            ? $countries[$attendee->country_ID()]->get('CNT_name')
430 430
             : $attendee->country_ID();
431 431
         $content = ! is_numeric($country) ? $country : '';
432 432
         return $this->columnContent('CNT_ISO', $content);
Please login to merge, or discard this patch.