Completed
Branch master (31acb9)
by
unknown
18:09 queued 10:56
created
espresso.php 1 patch
Indentation   +107 added lines, -107 removed lines patch added patch discarded remove patch
@@ -37,138 +37,138 @@
 block discarded – undo
37 37
  * @since       4.0
38 38
  */
39 39
 if (function_exists('espresso_version')) {
40
-    if (! function_exists('espresso_duplicate_plugin_error')) {
41
-        /**
42
-         *    espresso_duplicate_plugin_error
43
-         *    displays if more than one version of EE is activated at the same time.
44
-         */
45
-        function espresso_duplicate_plugin_error()
46
-        {
47
-            ?>
40
+	if (! function_exists('espresso_duplicate_plugin_error')) {
41
+		/**
42
+		 *    espresso_duplicate_plugin_error
43
+		 *    displays if more than one version of EE is activated at the same time.
44
+		 */
45
+		function espresso_duplicate_plugin_error()
46
+		{
47
+			?>
48 48
 <div class="error">
49 49
     <p>
50 50
         <?php
51
-                    echo esc_html__(
52
-                        'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
53
-                        'event_espresso'
54
-                    ); ?>
51
+					echo esc_html__(
52
+						'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
53
+						'event_espresso'
54
+					); ?>
55 55
     </p>
56 56
 </div>
57 57
 <?php
58
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
59
-        }
60
-    }
61
-    add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
58
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
59
+		}
60
+	}
61
+	add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
62 62
 } else {
63
-    define('EE_MIN_PHP_VER_REQUIRED', '7.4.0');
64
-    if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
65
-        /**
66
-         * espresso_minimum_php_version_error
67
-         *
68
-         * @return void
69
-         */
70
-        function espresso_minimum_php_version_error()
71
-        {
72
-            ?>
63
+	define('EE_MIN_PHP_VER_REQUIRED', '7.4.0');
64
+	if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
65
+		/**
66
+		 * espresso_minimum_php_version_error
67
+		 *
68
+		 * @return void
69
+		 */
70
+		function espresso_minimum_php_version_error()
71
+		{
72
+			?>
73 73
 <div class="error">
74 74
     <p>
75 75
         <?php
76
-                    printf(
77
-                        esc_html__(
78
-                            'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
79
-                            'event_espresso'
80
-                        ),
81
-                        EE_MIN_PHP_VER_REQUIRED,
82
-                        PHP_VERSION,
83
-                        '<br/>',
84
-                        '<a href="https://www.php.net/downloads.php">https://php.net/downloads.php</a>'
85
-                    );
86
-        ?>
76
+					printf(
77
+						esc_html__(
78
+							'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
79
+							'event_espresso'
80
+						),
81
+						EE_MIN_PHP_VER_REQUIRED,
82
+						PHP_VERSION,
83
+						'<br/>',
84
+						'<a href="https://www.php.net/downloads.php">https://php.net/downloads.php</a>'
85
+					);
86
+		?>
87 87
     </p>
88 88
 </div>
89 89
 <?php
90
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
91
-        }
90
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
91
+		}
92 92
 
93
-        add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
94
-    } else {
95
-        define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
93
+		add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
94
+	} else {
95
+		define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
96 96
 
97
-        require_once __DIR__ . '/vendor/autoload.php';
97
+		require_once __DIR__ . '/vendor/autoload.php';
98 98
 
99
-        /**
100
-         * espresso_version
101
-         * Returns the plugin version
102
-         *
103
-         * @return string
104
-         */
105
-        function espresso_version(): string
106
-        {
107
-            return apply_filters('FHEE__espresso__espresso_version', '5.0.35.rc.000');
108
-        }
99
+		/**
100
+		 * espresso_version
101
+		 * Returns the plugin version
102
+		 *
103
+		 * @return string
104
+		 */
105
+		function espresso_version(): string
106
+		{
107
+			return apply_filters('FHEE__espresso__espresso_version', '5.0.35.rc.000');
108
+		}
109 109
 
110
-        /**
111
-         * espresso_plugin_activation
112
-         * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
113
-         */
114
-        function espresso_plugin_activation()
115
-        {
116
-            update_option('ee_espresso_activation', true);
117
-            update_option('event-espresso-core_allow_tracking', 'no');
118
-            update_option('event-espresso-core_tracking_notice', 'hide');
119
-            // Run WP GraphQL activation callback
120
-            espressoLoadWpGraphQL();
121
-            graphql_activation_callback();
122
-        }
110
+		/**
111
+		 * espresso_plugin_activation
112
+		 * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
113
+		 */
114
+		function espresso_plugin_activation()
115
+		{
116
+			update_option('ee_espresso_activation', true);
117
+			update_option('event-espresso-core_allow_tracking', 'no');
118
+			update_option('event-espresso-core_tracking_notice', 'hide');
119
+			// Run WP GraphQL activation callback
120
+			espressoLoadWpGraphQL();
121
+			graphql_activation_callback();
122
+		}
123 123
 
124
-        register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
124
+		register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
125 125
 
126
-        /**
127
-         * espresso_plugin_deactivation
128
-         */
129
-        function espresso_plugin_deactivation()
130
-        {
131
-            // Run WP GraphQL deactivation callback
132
-            espressoLoadWpGraphQL();
133
-            graphql_deactivation_callback();
134
-            delete_option('event-espresso-core_allow_tracking');
135
-            delete_option('event-espresso-core_tracking_notice');
136
-        }
137
-        register_deactivation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_deactivation');
126
+		/**
127
+		 * espresso_plugin_deactivation
128
+		 */
129
+		function espresso_plugin_deactivation()
130
+		{
131
+			// Run WP GraphQL deactivation callback
132
+			espressoLoadWpGraphQL();
133
+			graphql_deactivation_callback();
134
+			delete_option('event-espresso-core_allow_tracking');
135
+			delete_option('event-espresso-core_tracking_notice');
136
+		}
137
+		register_deactivation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_deactivation');
138 138
 
139
-        require_once __DIR__ . '/core/bootstrap_espresso.php';
140
-        bootstrap_espresso();
141
-    }
139
+		require_once __DIR__ . '/core/bootstrap_espresso.php';
140
+		bootstrap_espresso();
141
+	}
142 142
 }
143 143
 
144 144
 if (! function_exists('espresso_deactivate_plugin')) {
145
-    /**
146
-     *    deactivate_plugin
147
-     * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
148
-     *
149
-     * @access public
150
-     * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
151
-     * @return    void
152
-     */
153
-    function espresso_deactivate_plugin(string $plugin_basename = '')
154
-    {
155
-        if (! function_exists('deactivate_plugins')) {
156
-            require_once ABSPATH . 'wp-admin/includes/plugin.php';
157
-        }
158
-        unset($_GET['activate'], $_REQUEST['activate']);
159
-        deactivate_plugins($plugin_basename);
160
-    }
145
+	/**
146
+	 *    deactivate_plugin
147
+	 * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
148
+	 *
149
+	 * @access public
150
+	 * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
151
+	 * @return    void
152
+	 */
153
+	function espresso_deactivate_plugin(string $plugin_basename = '')
154
+	{
155
+		if (! function_exists('deactivate_plugins')) {
156
+			require_once ABSPATH . 'wp-admin/includes/plugin.php';
157
+		}
158
+		unset($_GET['activate'], $_REQUEST['activate']);
159
+		deactivate_plugins($plugin_basename);
160
+	}
161 161
 }
162 162
 
163 163
 
164 164
 if (! function_exists('espressoLoadWpGraphQL')) {
165
-    function espressoLoadWpGraphQL()
166
-    {
167
-        if (
168
-            ! class_exists('WPGraphQL')
169
-            && is_readable(__DIR__ . '/vendor/wp-graphql/wp-graphql/wp-graphql.php')
170
-        ) {
171
-            require_once __DIR__ . '/vendor/wp-graphql/wp-graphql/wp-graphql.php';
172
-        }
173
-    }
165
+	function espressoLoadWpGraphQL()
166
+	{
167
+		if (
168
+			! class_exists('WPGraphQL')
169
+			&& is_readable(__DIR__ . '/vendor/wp-graphql/wp-graphql/wp-graphql.php')
170
+		) {
171
+			require_once __DIR__ . '/vendor/wp-graphql/wp-graphql/wp-graphql.php';
172
+		}
173
+	}
174 174
 }
Please login to merge, or discard this patch.
PaymentMethods/PayPalCommerce/modules/EED_PayPalOnboard.module.php 2 patches
Indentation   +729 added lines, -729 removed lines patch added patch discarded remove patch
@@ -20,736 +20,736 @@
 block discarded – undo
20 20
  */
21 21
 class EED_PayPalOnboard extends EED_Module
22 22
 {
23
-    /**
24
-     * @return EED_Module
25
-     * @throws EE_Error
26
-     * @throws ReflectionException
27
-     */
28
-    public static function instance(): EED_Module
29
-    {
30
-        return parent::get_instance(__CLASS__);
31
-    }
32
-
33
-
34
-    /**
35
-     * Run - initial module setup.
36
-     *
37
-     * @param WP $WP
38
-     * @return void
39
-     */
40
-    public function run($WP)
41
-    {
42
-    }
43
-
44
-
45
-    /**
46
-     * For hooking into EE Admin Core and other modules.
47
-     *
48
-     * @return void
49
-     */
50
-    public static function set_hooks_admin(): void
51
-    {
52
-        // check for the most basic EE capability
53
-        /** @var EE_Capabilities $capabilities */
54
-        $capabilities = LoaderFactory::getLoader()->getShared(EE_Capabilities::class);
55
-        if (
56
-            DbStatus::isOffline()
57
-            || ! $capabilities->current_user_can('ee_manage_gateways', 'manage-paypal-onboarding')
58
-        ) {
59
-            return;
60
-        }
61
-        // Get onboarding URL.
62
-        add_action('wp_ajax_eeaPpGetOnboardingUrl', [__CLASS__, 'getOnboardingUrl']);
63
-        // Catch the return/redirect from PayPal onboarding page.
64
-        add_action('init', [__CLASS__, 'updateOnboardingStatus']);
65
-        // Return the connection/onboard status.
66
-        add_action('wp_ajax_eeaPpGetOnboardStatus', [__CLASS__, 'getOnboardStatus']);
67
-        // Revoke access.
68
-        add_action('wp_ajax_eeaPpOffboard', [__CLASS__, 'offboard']);
69
-        // Clear all metadata.
70
-        add_action('wp_ajax_eeaPpClearMetaData', [__CLASS__, 'clearMetaData']);
71
-        // Admin notice.
72
-        add_action('admin_init', [__CLASS__, 'adminNotice']);
73
-    }
74
-
75
-
76
-    /**
77
-     * Get the onboarding URL.
78
-     * (AJAX)
79
-     *
80
-     * @return void
81
-     */
82
-    public static function getOnboardingUrl(): void
83
-    {
84
-        $signup_link = '';
85
-        try {
86
-            $paypal_pm = EED_PayPalCommerce::getPaymentMethod();
87
-            if (! $paypal_pm instanceof EE_Payment_Method) {
88
-                PayPalLogger::errorLogAndExit(
89
-                    esc_html__('No payment method.', 'event_espresso'),
90
-                    EED_Module::getRequest()->postParams(),
91
-                    $paypal_pm
92
-                );
93
-            }
94
-            PayPalExtraMetaManager::updateDebugMode($paypal_pm, EED_Module::getRequest()->postParams());
95
-            // Just get a new onboarding URL every time.
96
-            $signup_link = EED_PayPalOnboard::requestOnboardingUrl($paypal_pm);
97
-            if (! $signup_link) {
98
-                $err_msg = esc_html__('Error! Could not generate a sign-up link.', 'event_espresso');
99
-                PayPalLogger::errorLogAndExit($err_msg, ['signup_link' => $signup_link], $paypal_pm);
100
-            }
101
-        } catch (Exception $e) {
102
-            PayPalLogger::errorLogAndExit($e->getMessage(), ['trace' => $e->getTrace()]);
103
-        }
104
-        // Is it empty (can happen if we didn't get the URL through the API).
105
-        $signup_link = $signup_link ? $signup_link . '?&displayMode=minibrowser' : '#';
106
-        wp_send_json(
107
-            [
108
-                'signup_link' => $signup_link,
109
-            ]
110
-        );
111
-    }
112
-
113
-
114
-    /**
115
-     * Request the sign-up link from PayPal.
116
-     *
117
-     * @param EE_Payment_Method $paypal_pm
118
-     * @param bool              $one_time_request
119
-     * @return string
120
-     * @throws EE_Error
121
-     * @throws Exception
122
-     */
123
-    public static function requestOnboardingUrl(EE_Payment_Method $paypal_pm, bool $one_time_request = false): string
124
-    {
125
-        $signup_link = '';
126
-        // Get the access token.
127
-        $access_token = EED_PayPalOnboard::getPartnerAccessToken($paypal_pm);
128
-        if (! $access_token) {
129
-            $err_msg = esc_html__('Error! No access token.', 'event_espresso');
130
-            PayPalLogger::errorLog($err_msg, ['access_token' => $access_token], $paypal_pm);
131
-            return '';
132
-        }
133
-        // Request the access token.
134
-        $body_params = EED_PayPalOnboard::signupLinkRequestBody($paypal_pm);
135
-        $bn_code     = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_BN_CODE);
136
-        $post_params = [
137
-            'method'  => 'POST',
138
-            'headers' => [
139
-                'User-Agent'                    => sanitize_text_field($_SERVER['HTTP_USER_AGENT']),
140
-                'Content-Type'                  => 'application/json',
141
-                'Authorization'                 => 'Bearer ' . $access_token,
142
-                'PayPal-Partner-Attribution-Id' => $bn_code,
143
-            ],
144
-            'body'    => $body_params,
145
-        ];
146
-        $request_url = Domain::getPayPalApiUrl($paypal_pm) . '/v2/customer/partner-referrals';
147
-        $response    = EED_PayPalOnboard::sendRequest($paypal_pm, $request_url, $post_params);
148
-        // Check the data we received.
149
-        if (isset($response['error']) || empty($response['links'])) {
150
-            // Did the original access token get replaced by any chance ?
151
-            if (
152
-                ! $one_time_request
153
-                && ! empty($response['message'])
154
-                && $response['message'] === 'Access Token not found in cache'
155
-            ) {
156
-                // Clear all PM metadata and try getting the access token One more time.
157
-                PayPalExtraMetaManager::deleteData($paypal_pm);
158
-                PayPalLogger::errorLog(
159
-                    esc_html__('Removing old metadata before new onboarding.', 'event_espresso'),
160
-                    $response,
161
-                    $paypal_pm
162
-                );
163
-                return EED_PayPalOnboard::requestOnboardingUrl($paypal_pm, true);
164
-            }
165
-            $err_msg = esc_html__('Incoming sign-up link parameter validation failed.', 'event_espresso');
166
-            PayPalLogger::errorLog($err_msg, $response, $paypal_pm);
167
-            return '';
168
-        }
169
-        // Now retrieve that sign-up link.
170
-        foreach ($response['links'] as $link) {
171
-            if ($link['rel'] === 'action_url') {
172
-                $signup_link = $link['href'] ?? '';
173
-            }
174
-        }
175
-        return $signup_link;
176
-    }
177
-
178
-
179
-    /**
180
-     * Get the return URL.
181
-     *
182
-     * @param EE_Payment_Method $paypal_pm
183
-     * @return string
184
-     * @throws Exception
185
-     */
186
-    public static function signupLinkRequestBody(EE_Payment_Method $paypal_pm): string
187
-    {
188
-        $identifier_string = new OneTimeString($paypal_pm->debug_mode());
189
-        $tracking_id       = $identifier_string->value();
190
-        $request           = LoaderFactory::getLoader()->getShared(RequestInterface::class);
191
-        $selected_payment  = $request->getRequestParam('selected_payment', 'EXPRESS_CHECKOUT');
192
-        // Save the identifier for future use.
193
-        PayPalExtraMetaManager::savePmOption($paypal_pm, Domain::META_KEY_TRACKING_ID, $tracking_id);
194
-        // Assemble the return URL.
195
-        $return_url = EED_PayPalOnboard::getReturnUrl($paypal_pm, $selected_payment);
196
-        return json_encode(
197
-            [
198
-                'tracking_id'             => $tracking_id,
199
-                'operations'              => [
200
-                    [
201
-                        'operation'                  => 'API_INTEGRATION',
202
-                        'api_integration_preference' => [
203
-                            'rest_api_integration' => [
204
-                                'integration_method'  => 'PAYPAL',
205
-                                'integration_type'    => 'THIRD_PARTY',
206
-                                'third_party_details' => [
207
-                                    'features' => ['PAYMENT', 'REFUND', 'PARTNER_FEE'],
208
-                                ],
209
-                            ],
210
-                        ],
211
-                    ],
212
-                ],
213
-                'products'                => [$selected_payment],
214
-                'legal_consents'          => [
215
-                    [
216
-                        'type'    => 'SHARE_DATA_CONSENT',
217
-                        'granted' => true,
218
-                    ],
219
-                ],
220
-                'partner_config_override' => [
221
-                    'return_url' => $return_url,
222
-                ],
223
-            ]
224
-        );
225
-    }
226
-
227
-
228
-    /**
229
-     * Get the return URL.
230
-     *
231
-     * @param EE_Payment_Method $paypal_pm
232
-     * @param string            $selected_payment
233
-     * @return string
234
-     * @throws EE_Error
235
-     * @throws ReflectionException
236
-     */
237
-    public static function getReturnUrl(EE_Payment_Method $paypal_pm, string $selected_payment = ''): string
238
-    {
239
-        $wp_nonce = EED_Module::getRequest()->getRequestParam('wp_nonce');
240
-        $nonce    = wp_create_nonce(Domain::NONCE_NAME_ONBOARDING_RETURN);
241
-        return add_query_arg(
242
-            [
243
-                'page'                        => 'espresso_payment_settings',
244
-                'webhook_action'              => 'eepPpcMerchantOnboard',
245
-                'payment_method'              => $paypal_pm->slug(),
246
-                '_wpnonce'                    => $wp_nonce,
247
-                'nonce'                       => $nonce,
248
-                'selected_payment'            => $selected_payment,
249
-                Domain::META_KEY_SANDBOX_MODE => $paypal_pm->debug_mode() ? '1' : '0',
250
-            ],
251
-            admin_url('admin.php')
252
-        );
253
-    }
254
-
255
-
256
-    /**
257
-     * Redirect to the payment method (PP) settings home page.
258
-     *
259
-     * @return void
260
-     */
261
-    public static function redirectToPmSettingsHome(): void
262
-    {
263
-        $get_params = EED_Module::getRequest()->getParams();
264
-        if (empty($get_params['payment_method'])) {
265
-            // Simply do not redirect.
266
-            return;
267
-        }
268
-        $args_to_add = [
269
-            'page'           => 'espresso_payment_settings',
270
-            'payment_method' => $get_params['payment_method'],
271
-        ];
272
-        if (isset($get_params['sandbox_mode'])) {
273
-            $args_to_add[ Domain::META_KEY_SANDBOX_MODE ] = $get_params['sandbox_mode'];
274
-        }
275
-        $home_url = add_query_arg($args_to_add, admin_url('admin.php'));
276
-        wp_redirect($home_url);
277
-        exit;
278
-    }
279
-
280
-
281
-    /**
282
-     * Check user’s onboarding status.
283
-     * This will handle the user return from the auth page and also check the status via the API.
284
-     *
285
-     * @return void
286
-     * @throws EE_Error
287
-     * @throws ReflectionException
288
-     */
289
-    public static function updateOnboardingStatus(): void
290
-    {
291
-        // Check if this is the webhook from PayPal.
292
-        if (
293
-            ! isset($_GET['webhook_action'], $_GET['nonce'])
294
-            || $_GET['webhook_action'] !== 'eepPpcMerchantOnboard'
295
-        ) {
296
-            return;  // Ignore.
297
-        }
298
-        $get_params = EED_Module::getRequest()->getParams();
299
-        // Get the payment method.
300
-        $paypal_pm = EED_PayPalCommerce::getPaymentMethod();
301
-        // Check the response (GET) parameters.
302
-        if (! EED_PayPalOnboard::onboardingStatusResponseValid($get_params, $paypal_pm)) {
303
-            // Missing parameters. Can't proceed.
304
-            PayPalLogger::errorLog(
305
-                esc_html__('Missing required onboarding parameters.', 'event_espresso'),
306
-                $get_params,
307
-                $paypal_pm
308
-            );
309
-            EED_PayPalOnboard::redirectToPmSettingsHome();
310
-            return;
311
-        }
312
-        // Check on the onboarding status (recommended by PP).
313
-        $onboarding_status = EED_PayPalOnboard::trackSellerOnboarding(
314
-            $paypal_pm,
315
-            $get_params[ Domain::META_KEY_SELLER_MERCHANT_ID ]
316
-        );
317
-        if (! isset($onboarding_status['valid']) || ! $onboarding_status['valid']) {
318
-            PayPalLogger::errorLog(
319
-                $onboarding_status['message'],
320
-                array_merge($get_params, $onboarding_status),
321
-                $paypal_pm
322
-            );
323
-            EED_PayPalOnboard::redirectToPmSettingsHome();
324
-            return;
325
-        }
326
-        // Start saving the setup and info.
327
-        PayPalExtraMetaManager::parseAndSaveOptions($paypal_pm, $onboarding_status, $get_params);
328
-        // Save the credentials.
329
-        PayPalExtraMetaManager::saveSellerApiCredentials($paypal_pm, $get_params);
330
-        // Also clen GET params by redirecting, because PP auto redirects to the return_url on closing the onboarding window.
331
-        EED_PayPalOnboard::redirectToPmSettingsHome();
332
-    }
333
-
334
-
335
-    /**
336
-     * Check if all required parameters for the onboarding status check are present.
337
-     *
338
-     * @param array $data
339
-     * @param mixed $paypal_pm
340
-     * @return bool
341
-     */
342
-    public static function onboardingStatusResponseValid(array $data, $paypal_pm): bool
343
-    {
344
-        // Check that we have all the required parameters and the nonce is ok.
345
-        if (
346
-            $paypal_pm instanceof EE_Payment_Method
347
-            && wp_verify_nonce($data['nonce'], Domain::NONCE_NAME_ONBOARDING_RETURN)
348
-            && ! empty($data[ Domain::API_PARAM_PARTNER_ID ])
349
-            && ! empty($data[ Domain::META_KEY_SELLER_MERCHANT_ID ])
350
-            && isset($data[ Domain::API_PARAM_EMAIL_CONFIRMED ])
351
-        ) {
352
-            return true;
353
-        }
354
-        return false;
355
-    }
356
-
357
-
358
-    /**
359
-     * Get partner access token.
360
-     *
361
-     * @param EE_Payment_Method $paypal_pm
362
-     * @return string
363
-     * @throws EE_Error
364
-     * @throws ReflectionException
365
-     */
366
-    public static function getPartnerAccessToken(EE_Payment_Method $paypal_pm): string
367
-    {
368
-        // Do we have it saved ?
369
-        $access_token = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_ACCESS_TOKEN);
370
-        // If we don't have it, request/update it.
371
-        if (! $access_token) {
372
-            return EED_PayPalOnboard::requestPartnerAccessToken($paypal_pm);
373
-        }
374
-        if (EED_PayPalOnboard::partnerAccessTokenExpired($paypal_pm)) {
375
-            return EED_PayPalOnboard::requestPartnerAccessToken($paypal_pm);
376
-        }
377
-        // Access token is saved as encrypted, but return decrypted.
378
-        return $access_token;
379
-    }
380
-
381
-
382
-    /**
383
-     * Get partner access token.
384
-     *
385
-     * @param EE_Payment_Method $paypal_pm
386
-     * @return bool
387
-     * @throws EE_Error
388
-     * @throws ReflectionException
389
-     */
390
-    public static function partnerAccessTokenExpired(EE_Payment_Method $paypal_pm): bool
391
-    {
392
-        $expires_at = (int) PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_TOKEN_EXPIRES_IN);
393
-        if (! $expires_at) {
394
-            return true;
395
-        }
396
-        // Validate the token expiration date.
397
-        $minutes_left = round(($expires_at - time()) / 60);
398
-        // Count as expired if less than 60 minutes till expiration left.
399
-        if ($minutes_left <= 60) {
400
-            return true;
401
-        }
402
-        return false;
403
-    }
404
-
405
-
406
-    /**
407
-     * Request the partner access token from PayPal and save/update it.
408
-     *
409
-     * @param EE_Payment_Method $paypal_pm
410
-     * @return string
411
-     * @throws EE_Error
412
-     * @throws ReflectionException
413
-     */
414
-    public static function requestPartnerAccessToken(EE_Payment_Method $paypal_pm): string
415
-    {
416
-        $nonce = wp_create_nonce('eea_pp_commerce_get_access_token');
417
-        // Request the access token.
418
-        $post_args = [
419
-            'method' => 'POST',
420
-            'body'   => [
421
-                'nonce'                       => $nonce,
422
-                'api_version'                 => 'v1',
423
-                Domain::META_KEY_SANDBOX_MODE => $paypal_pm->debug_mode() ? '1' : '0',
424
-            ],
425
-        ];
426
-        if (defined('LOCAL_MIDDLEMAN_SERVER')) {
427
-            $post_args['sslverify'] = Manager::verifySSL();
428
-        }
429
-        $post_url = EED_PayPalOnboard::getMiddlemanBaseUrl($paypal_pm) . 'get_token';
430
-        $response = EED_PayPalOnboard::sendRequest($paypal_pm, $post_url, $post_args);
431
-        if (isset($response['error'])) {
432
-            return '';
433
-        }
434
-        // Check the data we received.
435
-        if (! EED_PayPalOnboard::partnerTokenResponseValid($response, $paypal_pm)) {
436
-            return '';
437
-        }
438
-        // If we are here all seems to be ok. Save the token and it's data.
439
-        $saved = PayPalExtraMetaManager::savePartnerAccessToken($paypal_pm, $response);
440
-        if (! $saved) {
441
-            return '';
442
-        }
443
-        return $response['access_token'];
444
-    }
445
-
446
-
447
-    /**
448
-     * Request seller onboarding status from PayPal.
449
-     *
450
-     * @param EE_Payment_Method $paypal_pm
451
-     * @param string            $merchant_id
452
-     * @return array
453
-     * @throws EE_Error
454
-     * @throws ReflectionException
455
-     */
456
-    public static function trackSellerOnboarding(EE_Payment_Method $paypal_pm, string $merchant_id): array
457
-    {
458
-        $track_onboarding = EED_PayPalOnboard::getTrackOnboardingApi($paypal_pm, $merchant_id);
459
-        if (! $track_onboarding instanceof TrackSellerOnboarding) {
460
-            return [
461
-                'error'   => 'TRACK_ONBOARDING_FAILED',
462
-                'message' => esc_html__('Failed to track seller onboarding.', 'event_espresso')
463
-            ];
464
-        }
465
-        return $track_onboarding->isValid();
466
-    }
467
-
468
-
469
-    /**
470
-     * Returns the Track Seller Onboarding API.
471
-     *
472
-     * @param EE_Payment_Method $paypal_pm
473
-     * @param string            $merchant_id
474
-     * @return TrackSellerOnboarding|null
475
-     * @throws EE_Error
476
-     * @throws ReflectionException
477
-     */
478
-    public static function getTrackOnboardingApi(
479
-        EE_Payment_Method $paypal_pm,
480
-        string $merchant_id
481
-    ): ?TrackSellerOnboarding {
482
-        $partner_id = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_PARTNER_MERCHANT_ID);
483
-        $paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm);
484
-        if (! $paypal_api instanceof PayPalApi || ! $partner_id) {
485
-            return null;
486
-        }
487
-        return new TrackSellerOnboarding($paypal_api, $partner_id, $merchant_id, $paypal_pm->debug_mode());
488
-    }
489
-
490
-
491
-    /**
492
-     * Check the onboard status and return the result.
493
-     * (AJAX)
494
-     *
495
-     * @return void
496
-     * @throws EE_Error
497
-     * @throws ReflectionException
498
-     */
499
-    public static function getOnboardStatus(): void
500
-    {
501
-        $paypal_pm = EED_PayPalCommerce::getPaymentMethod();
502
-        if (! $paypal_pm instanceof EE_Payment_Method) {
503
-            $err_msg = esc_html__('Could not specify the payment method.', 'event_espresso');
504
-            PayPalLogger::errorLog($err_msg, EED_Module::getRequest()->postParams(), $paypal_pm);
505
-            wp_send_json(['on_board' => false]);
506
-        }
507
-        try {
508
-            $seller_id = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_SELLER_MERCHANT_ID) ?? '--';
509
-        } catch (Exception $e) {
510
-            $seller_id = '--';
511
-            PayPalLogger::errorLog($e->getMessage(), ['trace' => $e->getTrace()]);
512
-        }
513
-        wp_send_json(
514
-            [
515
-                'on_board'  => EED_PayPalOnboard::isOnboard($paypal_pm),
516
-                'seller_id' => $seller_id,
517
-            ]
518
-        );
519
-    }
520
-
521
-
522
-    /**
523
-     * De-authorize the seller. Remove all API credentials.
524
-     * (AJAX)
525
-     *
526
-     * @return void
527
-     * @throws EE_Error
528
-     * @throws ReflectionException
529
-     */
530
-    public static function offboard(): void
531
-    {
532
-        $paypal_pm = EED_PayPalCommerce::getPaymentMethod();
533
-        EED_PayPalOnboard::validatePmAjax($paypal_pm);
534
-        PayPalExtraMetaManager::deleteData($paypal_pm);
535
-        PayPalLogger::errorLog(
536
-            esc_html__('Offboarding. Removing metadata.', 'event_espresso'),
537
-            EED_Module::getRequest()->postParams(),
538
-            $paypal_pm
539
-        );
540
-        wp_send_json(['success' => true]);
541
-    }
542
-
543
-
544
-    /**
545
-     * Clear all credentials metadata.
546
-     * (AJAX)
547
-     *
548
-     * @return void
549
-     * @throws EE_Error
550
-     * @throws ReflectionException
551
-     */
552
-    public static function clearMetaData(): void
553
-    {
554
-        $paypal_pm = EED_PayPalCommerce::getPaymentMethod();
555
-        EED_PayPalOnboard::validatePmAjax($paypal_pm);
556
-        PayPalExtraMetaManager::deleteAllData($paypal_pm);
557
-        PayPalLogger::errorLog(
558
-            esc_html__('Doing a Reset. Removing all PM settings metadata.', 'event_espresso'),
559
-            EED_Module::getRequest()->postParams(),
560
-            $paypal_pm
561
-        );
562
-        wp_send_json(['success' => true]);
563
-    }
564
-
565
-
566
-    /**
567
-     * Validate the PM instance, returning an ajax response on invalid.
568
-     *
569
-     * @param $paypal_pm
570
-     * @return void
571
-     */
572
-    public static function validatePmAjax($paypal_pm): void
573
-    {
574
-        if (! $paypal_pm instanceof EE_Payment_Method) {
575
-            wp_send_json(
576
-                [
577
-                    'error'   => 'INVALID_PM',
578
-                    'message' => esc_html__(
579
-                        'Invalid payment method. Please refresh the page and try again.',
580
-                        'event_espresso'
581
-                    ),
582
-                ]
583
-            );
584
-        }
585
-    }
586
-
587
-
588
-    /**
589
-     * Checks if already onboard.
590
-     *
591
-     * @param EE_Payment_Method $payment_method
592
-     * @return boolean
593
-     * @throws EE_Error
594
-     * @throws ReflectionException
595
-     */
596
-    public static function isOnboard(EE_Payment_Method $payment_method): bool
597
-    {
598
-        $pp_meta_data = PayPalExtraMetaManager::getAllData($payment_method);
599
-        return
600
-            (
601
-                // onboarded with a third party integration ?
602
-                ! empty($pp_meta_data[ Domain::META_KEY_SELLER_MERCHANT_ID ])
603
-                && ! empty($pp_meta_data[ Domain::META_KEY_ACCESS_TOKEN ])
604
-            ) || (
605
-                // or with the first party integration ?
606
-                ! empty($pp_meta_data[ Domain::META_KEY_CLIENT_ID ])
607
-                && ! empty($pp_meta_data[ Domain::META_KEY_CLIENT_SECRET ])
608
-                && ! empty($pp_meta_data[ Domain::META_KEY_PAYER_ID ])
609
-            );
610
-    }
611
-
612
-
613
-    /**
614
-     * Send a request and return a decoded response body.
615
-     *
616
-     * @param EE_Payment_Method $paypal_pm
617
-     * @param string            $request_url
618
-     * @param array             $request_args
619
-     * @return array
620
-     */
621
-    public static function sendRequest(EE_Payment_Method $paypal_pm, string $request_url, array $request_args): array
622
-    {
623
-        $error_return = ['error' => true];
624
-        $response     = wp_remote_request($request_url, $request_args);
625
-        if (is_wp_error($response)) {
626
-            $message = $response->get_error_message();
627
-            PayPalLogger::errorLog($message, [$request_url, $request_args, $response], $paypal_pm);
628
-            $error_return['message'] = $message;
629
-            return $error_return;
630
-        }
631
-        $response_body = (isset($response['body']) && $response['body']) ? json_decode($response['body'], true) : [];
632
-        if (empty($response_body) || isset($response_body['error'])) {
633
-            $message = $response_body['error_description']
634
-                ?? sprintf(
635
-                    esc_html__('Unknown response received while sending a request to: %1$s', 'event_espresso'),
636
-                    $request_url
637
-                );
638
-            PayPalLogger::errorLog($message, [$request_url, $request_args, $response], $paypal_pm);
639
-            $error_return['message'] = $message;
640
-            return $error_return;
641
-        }
642
-        return $response_body;
643
-    }
644
-
645
-
646
-    /**
647
-     * Check the response for a partner token request.
648
-     *
649
-     * @param array             $response
650
-     * @param EE_Payment_Method $paypal_pm
651
-     * @return bool
652
-     */
653
-    public static function partnerTokenResponseValid(array $response, EE_Payment_Method $paypal_pm): bool
654
-    {
655
-        // Check the data we received.
656
-        if (
657
-            empty($response['nonce'])
658
-            || ! wp_verify_nonce($response['nonce'], 'eea_pp_commerce_get_access_token')
659
-            || empty($response['access_token'])
660
-            || empty($response['app_id'])
661
-            || empty($response['expires_in'])
662
-            || empty($response['partner_client_id'])
663
-            || empty($response['partner_merchant_id'])
664
-        ) {
665
-            // This is an error.
666
-            PayPalLogger::errorLog(
667
-                esc_html__('Incoming parameter validation failed.', 'event_espresso'),
668
-                $response,
669
-                $paypal_pm
670
-            );
671
-            return false;
672
-        }
673
-        return true;
674
-    }
675
-
676
-
677
-    /**
678
-     * Returns the base URL to the middleman server.
679
-     * If LOCAL_MIDDLEMAN_SERVER is defined, requests will be sent to connect.eventespresso.test
680
-     *
681
-     * @param EE_Payment_Method $payment_method
682
-     * @return string
683
-     * @throws EE_Error
684
-     * @throws ReflectionException
685
-     */
686
-    public static function getMiddlemanBaseUrl(EE_Payment_Method $payment_method): string
687
-    {
688
-        $target = defined('LOCAL_MIDDLEMAN_SERVER') ? 'test' : 'com';
689
-        // If this PM is used under different provider accounts, you might need an account indicator.
690
-        $account = defined('EE_PAYPAL_COMMERCE_ACCOUNT_INDICATOR') ? EE_PAYPAL_COMMERCE_ACCOUNT_INDICATOR : '';
691
-        $postfix = $payment_method->debug_mode() ? '_sandbox' : '';
692
-        return "https://connect.eventespresso.$target/paypal_commerce$account$postfix/";
693
-    }
694
-
695
-
696
-    /**
697
-     * This Payment Method admin notices.
698
-     *
699
-     * @return void
700
-     * @throws EE_Error
701
-     * @throws ReflectionException
702
-     */
703
-    public static function adminNotice()
704
-    {
705
-        // Show the notice if PayPal Commerce PM is active but merchant is not onboard.
706
-        $pp_commerce = EEM_Payment_Method::instance()->get_one_by_slug(Domain::PM_SLUG);
707
-        if (
708
-            $pp_commerce instanceof EE_Payment_Method
709
-            && $pp_commerce->active()
710
-            && ! EED_PayPalOnboard::isOnboard($pp_commerce)
711
-        ) {
712
-            add_action('admin_notices', [EED_PayPalOnboard::class, 'notOnboardNotice']);
713
-        }
714
-    }
715
-
716
-
717
-    /**
718
-     * Contents of the not onboard admin notice.
719
-     *
720
-     * @return void
721
-     * @throws EE_Error
722
-     * @throws ReflectionException
723
-     */
724
-    public static function notOnboardNotice()
725
-    {
726
-        $open_anchor = $close_anchor = '';
727
-        $pp_commerce = EEM_Payment_Method::instance()->get_one_by_slug(Domain::PM_SLUG);
728
-        if ($pp_commerce instanceof EE_Payment_Method) {
729
-            $pm_page      = add_query_arg(
730
-                [
731
-                    'page'           => 'espresso_payment_settings',
732
-                    'webhook_action' => 'eepPpcMerchantOnboard',
733
-                    'payment_method' => $pp_commerce->slug(),
734
-                ],
735
-                admin_url('admin.php')
736
-            );
737
-            $open_anchor  = "<a href='$pm_page'>";
738
-            $close_anchor = "</a>";
739
-        }
740
-        $notice = sprintf(
741
-            esc_html__(
742
-                '%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.',
743
-                'event_espresso'
744
-            ),
745
-            '<strong>',
746
-            '</strong>',
747
-            $open_anchor,
748
-            $close_anchor
749
-        );
750
-        echo "
23
+	/**
24
+	 * @return EED_Module
25
+	 * @throws EE_Error
26
+	 * @throws ReflectionException
27
+	 */
28
+	public static function instance(): EED_Module
29
+	{
30
+		return parent::get_instance(__CLASS__);
31
+	}
32
+
33
+
34
+	/**
35
+	 * Run - initial module setup.
36
+	 *
37
+	 * @param WP $WP
38
+	 * @return void
39
+	 */
40
+	public function run($WP)
41
+	{
42
+	}
43
+
44
+
45
+	/**
46
+	 * For hooking into EE Admin Core and other modules.
47
+	 *
48
+	 * @return void
49
+	 */
50
+	public static function set_hooks_admin(): void
51
+	{
52
+		// check for the most basic EE capability
53
+		/** @var EE_Capabilities $capabilities */
54
+		$capabilities = LoaderFactory::getLoader()->getShared(EE_Capabilities::class);
55
+		if (
56
+			DbStatus::isOffline()
57
+			|| ! $capabilities->current_user_can('ee_manage_gateways', 'manage-paypal-onboarding')
58
+		) {
59
+			return;
60
+		}
61
+		// Get onboarding URL.
62
+		add_action('wp_ajax_eeaPpGetOnboardingUrl', [__CLASS__, 'getOnboardingUrl']);
63
+		// Catch the return/redirect from PayPal onboarding page.
64
+		add_action('init', [__CLASS__, 'updateOnboardingStatus']);
65
+		// Return the connection/onboard status.
66
+		add_action('wp_ajax_eeaPpGetOnboardStatus', [__CLASS__, 'getOnboardStatus']);
67
+		// Revoke access.
68
+		add_action('wp_ajax_eeaPpOffboard', [__CLASS__, 'offboard']);
69
+		// Clear all metadata.
70
+		add_action('wp_ajax_eeaPpClearMetaData', [__CLASS__, 'clearMetaData']);
71
+		// Admin notice.
72
+		add_action('admin_init', [__CLASS__, 'adminNotice']);
73
+	}
74
+
75
+
76
+	/**
77
+	 * Get the onboarding URL.
78
+	 * (AJAX)
79
+	 *
80
+	 * @return void
81
+	 */
82
+	public static function getOnboardingUrl(): void
83
+	{
84
+		$signup_link = '';
85
+		try {
86
+			$paypal_pm = EED_PayPalCommerce::getPaymentMethod();
87
+			if (! $paypal_pm instanceof EE_Payment_Method) {
88
+				PayPalLogger::errorLogAndExit(
89
+					esc_html__('No payment method.', 'event_espresso'),
90
+					EED_Module::getRequest()->postParams(),
91
+					$paypal_pm
92
+				);
93
+			}
94
+			PayPalExtraMetaManager::updateDebugMode($paypal_pm, EED_Module::getRequest()->postParams());
95
+			// Just get a new onboarding URL every time.
96
+			$signup_link = EED_PayPalOnboard::requestOnboardingUrl($paypal_pm);
97
+			if (! $signup_link) {
98
+				$err_msg = esc_html__('Error! Could not generate a sign-up link.', 'event_espresso');
99
+				PayPalLogger::errorLogAndExit($err_msg, ['signup_link' => $signup_link], $paypal_pm);
100
+			}
101
+		} catch (Exception $e) {
102
+			PayPalLogger::errorLogAndExit($e->getMessage(), ['trace' => $e->getTrace()]);
103
+		}
104
+		// Is it empty (can happen if we didn't get the URL through the API).
105
+		$signup_link = $signup_link ? $signup_link . '?&displayMode=minibrowser' : '#';
106
+		wp_send_json(
107
+			[
108
+				'signup_link' => $signup_link,
109
+			]
110
+		);
111
+	}
112
+
113
+
114
+	/**
115
+	 * Request the sign-up link from PayPal.
116
+	 *
117
+	 * @param EE_Payment_Method $paypal_pm
118
+	 * @param bool              $one_time_request
119
+	 * @return string
120
+	 * @throws EE_Error
121
+	 * @throws Exception
122
+	 */
123
+	public static function requestOnboardingUrl(EE_Payment_Method $paypal_pm, bool $one_time_request = false): string
124
+	{
125
+		$signup_link = '';
126
+		// Get the access token.
127
+		$access_token = EED_PayPalOnboard::getPartnerAccessToken($paypal_pm);
128
+		if (! $access_token) {
129
+			$err_msg = esc_html__('Error! No access token.', 'event_espresso');
130
+			PayPalLogger::errorLog($err_msg, ['access_token' => $access_token], $paypal_pm);
131
+			return '';
132
+		}
133
+		// Request the access token.
134
+		$body_params = EED_PayPalOnboard::signupLinkRequestBody($paypal_pm);
135
+		$bn_code     = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_BN_CODE);
136
+		$post_params = [
137
+			'method'  => 'POST',
138
+			'headers' => [
139
+				'User-Agent'                    => sanitize_text_field($_SERVER['HTTP_USER_AGENT']),
140
+				'Content-Type'                  => 'application/json',
141
+				'Authorization'                 => 'Bearer ' . $access_token,
142
+				'PayPal-Partner-Attribution-Id' => $bn_code,
143
+			],
144
+			'body'    => $body_params,
145
+		];
146
+		$request_url = Domain::getPayPalApiUrl($paypal_pm) . '/v2/customer/partner-referrals';
147
+		$response    = EED_PayPalOnboard::sendRequest($paypal_pm, $request_url, $post_params);
148
+		// Check the data we received.
149
+		if (isset($response['error']) || empty($response['links'])) {
150
+			// Did the original access token get replaced by any chance ?
151
+			if (
152
+				! $one_time_request
153
+				&& ! empty($response['message'])
154
+				&& $response['message'] === 'Access Token not found in cache'
155
+			) {
156
+				// Clear all PM metadata and try getting the access token One more time.
157
+				PayPalExtraMetaManager::deleteData($paypal_pm);
158
+				PayPalLogger::errorLog(
159
+					esc_html__('Removing old metadata before new onboarding.', 'event_espresso'),
160
+					$response,
161
+					$paypal_pm
162
+				);
163
+				return EED_PayPalOnboard::requestOnboardingUrl($paypal_pm, true);
164
+			}
165
+			$err_msg = esc_html__('Incoming sign-up link parameter validation failed.', 'event_espresso');
166
+			PayPalLogger::errorLog($err_msg, $response, $paypal_pm);
167
+			return '';
168
+		}
169
+		// Now retrieve that sign-up link.
170
+		foreach ($response['links'] as $link) {
171
+			if ($link['rel'] === 'action_url') {
172
+				$signup_link = $link['href'] ?? '';
173
+			}
174
+		}
175
+		return $signup_link;
176
+	}
177
+
178
+
179
+	/**
180
+	 * Get the return URL.
181
+	 *
182
+	 * @param EE_Payment_Method $paypal_pm
183
+	 * @return string
184
+	 * @throws Exception
185
+	 */
186
+	public static function signupLinkRequestBody(EE_Payment_Method $paypal_pm): string
187
+	{
188
+		$identifier_string = new OneTimeString($paypal_pm->debug_mode());
189
+		$tracking_id       = $identifier_string->value();
190
+		$request           = LoaderFactory::getLoader()->getShared(RequestInterface::class);
191
+		$selected_payment  = $request->getRequestParam('selected_payment', 'EXPRESS_CHECKOUT');
192
+		// Save the identifier for future use.
193
+		PayPalExtraMetaManager::savePmOption($paypal_pm, Domain::META_KEY_TRACKING_ID, $tracking_id);
194
+		// Assemble the return URL.
195
+		$return_url = EED_PayPalOnboard::getReturnUrl($paypal_pm, $selected_payment);
196
+		return json_encode(
197
+			[
198
+				'tracking_id'             => $tracking_id,
199
+				'operations'              => [
200
+					[
201
+						'operation'                  => 'API_INTEGRATION',
202
+						'api_integration_preference' => [
203
+							'rest_api_integration' => [
204
+								'integration_method'  => 'PAYPAL',
205
+								'integration_type'    => 'THIRD_PARTY',
206
+								'third_party_details' => [
207
+									'features' => ['PAYMENT', 'REFUND', 'PARTNER_FEE'],
208
+								],
209
+							],
210
+						],
211
+					],
212
+				],
213
+				'products'                => [$selected_payment],
214
+				'legal_consents'          => [
215
+					[
216
+						'type'    => 'SHARE_DATA_CONSENT',
217
+						'granted' => true,
218
+					],
219
+				],
220
+				'partner_config_override' => [
221
+					'return_url' => $return_url,
222
+				],
223
+			]
224
+		);
225
+	}
226
+
227
+
228
+	/**
229
+	 * Get the return URL.
230
+	 *
231
+	 * @param EE_Payment_Method $paypal_pm
232
+	 * @param string            $selected_payment
233
+	 * @return string
234
+	 * @throws EE_Error
235
+	 * @throws ReflectionException
236
+	 */
237
+	public static function getReturnUrl(EE_Payment_Method $paypal_pm, string $selected_payment = ''): string
238
+	{
239
+		$wp_nonce = EED_Module::getRequest()->getRequestParam('wp_nonce');
240
+		$nonce    = wp_create_nonce(Domain::NONCE_NAME_ONBOARDING_RETURN);
241
+		return add_query_arg(
242
+			[
243
+				'page'                        => 'espresso_payment_settings',
244
+				'webhook_action'              => 'eepPpcMerchantOnboard',
245
+				'payment_method'              => $paypal_pm->slug(),
246
+				'_wpnonce'                    => $wp_nonce,
247
+				'nonce'                       => $nonce,
248
+				'selected_payment'            => $selected_payment,
249
+				Domain::META_KEY_SANDBOX_MODE => $paypal_pm->debug_mode() ? '1' : '0',
250
+			],
251
+			admin_url('admin.php')
252
+		);
253
+	}
254
+
255
+
256
+	/**
257
+	 * Redirect to the payment method (PP) settings home page.
258
+	 *
259
+	 * @return void
260
+	 */
261
+	public static function redirectToPmSettingsHome(): void
262
+	{
263
+		$get_params = EED_Module::getRequest()->getParams();
264
+		if (empty($get_params['payment_method'])) {
265
+			// Simply do not redirect.
266
+			return;
267
+		}
268
+		$args_to_add = [
269
+			'page'           => 'espresso_payment_settings',
270
+			'payment_method' => $get_params['payment_method'],
271
+		];
272
+		if (isset($get_params['sandbox_mode'])) {
273
+			$args_to_add[ Domain::META_KEY_SANDBOX_MODE ] = $get_params['sandbox_mode'];
274
+		}
275
+		$home_url = add_query_arg($args_to_add, admin_url('admin.php'));
276
+		wp_redirect($home_url);
277
+		exit;
278
+	}
279
+
280
+
281
+	/**
282
+	 * Check user’s onboarding status.
283
+	 * This will handle the user return from the auth page and also check the status via the API.
284
+	 *
285
+	 * @return void
286
+	 * @throws EE_Error
287
+	 * @throws ReflectionException
288
+	 */
289
+	public static function updateOnboardingStatus(): void
290
+	{
291
+		// Check if this is the webhook from PayPal.
292
+		if (
293
+			! isset($_GET['webhook_action'], $_GET['nonce'])
294
+			|| $_GET['webhook_action'] !== 'eepPpcMerchantOnboard'
295
+		) {
296
+			return;  // Ignore.
297
+		}
298
+		$get_params = EED_Module::getRequest()->getParams();
299
+		// Get the payment method.
300
+		$paypal_pm = EED_PayPalCommerce::getPaymentMethod();
301
+		// Check the response (GET) parameters.
302
+		if (! EED_PayPalOnboard::onboardingStatusResponseValid($get_params, $paypal_pm)) {
303
+			// Missing parameters. Can't proceed.
304
+			PayPalLogger::errorLog(
305
+				esc_html__('Missing required onboarding parameters.', 'event_espresso'),
306
+				$get_params,
307
+				$paypal_pm
308
+			);
309
+			EED_PayPalOnboard::redirectToPmSettingsHome();
310
+			return;
311
+		}
312
+		// Check on the onboarding status (recommended by PP).
313
+		$onboarding_status = EED_PayPalOnboard::trackSellerOnboarding(
314
+			$paypal_pm,
315
+			$get_params[ Domain::META_KEY_SELLER_MERCHANT_ID ]
316
+		);
317
+		if (! isset($onboarding_status['valid']) || ! $onboarding_status['valid']) {
318
+			PayPalLogger::errorLog(
319
+				$onboarding_status['message'],
320
+				array_merge($get_params, $onboarding_status),
321
+				$paypal_pm
322
+			);
323
+			EED_PayPalOnboard::redirectToPmSettingsHome();
324
+			return;
325
+		}
326
+		// Start saving the setup and info.
327
+		PayPalExtraMetaManager::parseAndSaveOptions($paypal_pm, $onboarding_status, $get_params);
328
+		// Save the credentials.
329
+		PayPalExtraMetaManager::saveSellerApiCredentials($paypal_pm, $get_params);
330
+		// Also clen GET params by redirecting, because PP auto redirects to the return_url on closing the onboarding window.
331
+		EED_PayPalOnboard::redirectToPmSettingsHome();
332
+	}
333
+
334
+
335
+	/**
336
+	 * Check if all required parameters for the onboarding status check are present.
337
+	 *
338
+	 * @param array $data
339
+	 * @param mixed $paypal_pm
340
+	 * @return bool
341
+	 */
342
+	public static function onboardingStatusResponseValid(array $data, $paypal_pm): bool
343
+	{
344
+		// Check that we have all the required parameters and the nonce is ok.
345
+		if (
346
+			$paypal_pm instanceof EE_Payment_Method
347
+			&& wp_verify_nonce($data['nonce'], Domain::NONCE_NAME_ONBOARDING_RETURN)
348
+			&& ! empty($data[ Domain::API_PARAM_PARTNER_ID ])
349
+			&& ! empty($data[ Domain::META_KEY_SELLER_MERCHANT_ID ])
350
+			&& isset($data[ Domain::API_PARAM_EMAIL_CONFIRMED ])
351
+		) {
352
+			return true;
353
+		}
354
+		return false;
355
+	}
356
+
357
+
358
+	/**
359
+	 * Get partner access token.
360
+	 *
361
+	 * @param EE_Payment_Method $paypal_pm
362
+	 * @return string
363
+	 * @throws EE_Error
364
+	 * @throws ReflectionException
365
+	 */
366
+	public static function getPartnerAccessToken(EE_Payment_Method $paypal_pm): string
367
+	{
368
+		// Do we have it saved ?
369
+		$access_token = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_ACCESS_TOKEN);
370
+		// If we don't have it, request/update it.
371
+		if (! $access_token) {
372
+			return EED_PayPalOnboard::requestPartnerAccessToken($paypal_pm);
373
+		}
374
+		if (EED_PayPalOnboard::partnerAccessTokenExpired($paypal_pm)) {
375
+			return EED_PayPalOnboard::requestPartnerAccessToken($paypal_pm);
376
+		}
377
+		// Access token is saved as encrypted, but return decrypted.
378
+		return $access_token;
379
+	}
380
+
381
+
382
+	/**
383
+	 * Get partner access token.
384
+	 *
385
+	 * @param EE_Payment_Method $paypal_pm
386
+	 * @return bool
387
+	 * @throws EE_Error
388
+	 * @throws ReflectionException
389
+	 */
390
+	public static function partnerAccessTokenExpired(EE_Payment_Method $paypal_pm): bool
391
+	{
392
+		$expires_at = (int) PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_TOKEN_EXPIRES_IN);
393
+		if (! $expires_at) {
394
+			return true;
395
+		}
396
+		// Validate the token expiration date.
397
+		$minutes_left = round(($expires_at - time()) / 60);
398
+		// Count as expired if less than 60 minutes till expiration left.
399
+		if ($minutes_left <= 60) {
400
+			return true;
401
+		}
402
+		return false;
403
+	}
404
+
405
+
406
+	/**
407
+	 * Request the partner access token from PayPal and save/update it.
408
+	 *
409
+	 * @param EE_Payment_Method $paypal_pm
410
+	 * @return string
411
+	 * @throws EE_Error
412
+	 * @throws ReflectionException
413
+	 */
414
+	public static function requestPartnerAccessToken(EE_Payment_Method $paypal_pm): string
415
+	{
416
+		$nonce = wp_create_nonce('eea_pp_commerce_get_access_token');
417
+		// Request the access token.
418
+		$post_args = [
419
+			'method' => 'POST',
420
+			'body'   => [
421
+				'nonce'                       => $nonce,
422
+				'api_version'                 => 'v1',
423
+				Domain::META_KEY_SANDBOX_MODE => $paypal_pm->debug_mode() ? '1' : '0',
424
+			],
425
+		];
426
+		if (defined('LOCAL_MIDDLEMAN_SERVER')) {
427
+			$post_args['sslverify'] = Manager::verifySSL();
428
+		}
429
+		$post_url = EED_PayPalOnboard::getMiddlemanBaseUrl($paypal_pm) . 'get_token';
430
+		$response = EED_PayPalOnboard::sendRequest($paypal_pm, $post_url, $post_args);
431
+		if (isset($response['error'])) {
432
+			return '';
433
+		}
434
+		// Check the data we received.
435
+		if (! EED_PayPalOnboard::partnerTokenResponseValid($response, $paypal_pm)) {
436
+			return '';
437
+		}
438
+		// If we are here all seems to be ok. Save the token and it's data.
439
+		$saved = PayPalExtraMetaManager::savePartnerAccessToken($paypal_pm, $response);
440
+		if (! $saved) {
441
+			return '';
442
+		}
443
+		return $response['access_token'];
444
+	}
445
+
446
+
447
+	/**
448
+	 * Request seller onboarding status from PayPal.
449
+	 *
450
+	 * @param EE_Payment_Method $paypal_pm
451
+	 * @param string            $merchant_id
452
+	 * @return array
453
+	 * @throws EE_Error
454
+	 * @throws ReflectionException
455
+	 */
456
+	public static function trackSellerOnboarding(EE_Payment_Method $paypal_pm, string $merchant_id): array
457
+	{
458
+		$track_onboarding = EED_PayPalOnboard::getTrackOnboardingApi($paypal_pm, $merchant_id);
459
+		if (! $track_onboarding instanceof TrackSellerOnboarding) {
460
+			return [
461
+				'error'   => 'TRACK_ONBOARDING_FAILED',
462
+				'message' => esc_html__('Failed to track seller onboarding.', 'event_espresso')
463
+			];
464
+		}
465
+		return $track_onboarding->isValid();
466
+	}
467
+
468
+
469
+	/**
470
+	 * Returns the Track Seller Onboarding API.
471
+	 *
472
+	 * @param EE_Payment_Method $paypal_pm
473
+	 * @param string            $merchant_id
474
+	 * @return TrackSellerOnboarding|null
475
+	 * @throws EE_Error
476
+	 * @throws ReflectionException
477
+	 */
478
+	public static function getTrackOnboardingApi(
479
+		EE_Payment_Method $paypal_pm,
480
+		string $merchant_id
481
+	): ?TrackSellerOnboarding {
482
+		$partner_id = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_PARTNER_MERCHANT_ID);
483
+		$paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm);
484
+		if (! $paypal_api instanceof PayPalApi || ! $partner_id) {
485
+			return null;
486
+		}
487
+		return new TrackSellerOnboarding($paypal_api, $partner_id, $merchant_id, $paypal_pm->debug_mode());
488
+	}
489
+
490
+
491
+	/**
492
+	 * Check the onboard status and return the result.
493
+	 * (AJAX)
494
+	 *
495
+	 * @return void
496
+	 * @throws EE_Error
497
+	 * @throws ReflectionException
498
+	 */
499
+	public static function getOnboardStatus(): void
500
+	{
501
+		$paypal_pm = EED_PayPalCommerce::getPaymentMethod();
502
+		if (! $paypal_pm instanceof EE_Payment_Method) {
503
+			$err_msg = esc_html__('Could not specify the payment method.', 'event_espresso');
504
+			PayPalLogger::errorLog($err_msg, EED_Module::getRequest()->postParams(), $paypal_pm);
505
+			wp_send_json(['on_board' => false]);
506
+		}
507
+		try {
508
+			$seller_id = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_SELLER_MERCHANT_ID) ?? '--';
509
+		} catch (Exception $e) {
510
+			$seller_id = '--';
511
+			PayPalLogger::errorLog($e->getMessage(), ['trace' => $e->getTrace()]);
512
+		}
513
+		wp_send_json(
514
+			[
515
+				'on_board'  => EED_PayPalOnboard::isOnboard($paypal_pm),
516
+				'seller_id' => $seller_id,
517
+			]
518
+		);
519
+	}
520
+
521
+
522
+	/**
523
+	 * De-authorize the seller. Remove all API credentials.
524
+	 * (AJAX)
525
+	 *
526
+	 * @return void
527
+	 * @throws EE_Error
528
+	 * @throws ReflectionException
529
+	 */
530
+	public static function offboard(): void
531
+	{
532
+		$paypal_pm = EED_PayPalCommerce::getPaymentMethod();
533
+		EED_PayPalOnboard::validatePmAjax($paypal_pm);
534
+		PayPalExtraMetaManager::deleteData($paypal_pm);
535
+		PayPalLogger::errorLog(
536
+			esc_html__('Offboarding. Removing metadata.', 'event_espresso'),
537
+			EED_Module::getRequest()->postParams(),
538
+			$paypal_pm
539
+		);
540
+		wp_send_json(['success' => true]);
541
+	}
542
+
543
+
544
+	/**
545
+	 * Clear all credentials metadata.
546
+	 * (AJAX)
547
+	 *
548
+	 * @return void
549
+	 * @throws EE_Error
550
+	 * @throws ReflectionException
551
+	 */
552
+	public static function clearMetaData(): void
553
+	{
554
+		$paypal_pm = EED_PayPalCommerce::getPaymentMethod();
555
+		EED_PayPalOnboard::validatePmAjax($paypal_pm);
556
+		PayPalExtraMetaManager::deleteAllData($paypal_pm);
557
+		PayPalLogger::errorLog(
558
+			esc_html__('Doing a Reset. Removing all PM settings metadata.', 'event_espresso'),
559
+			EED_Module::getRequest()->postParams(),
560
+			$paypal_pm
561
+		);
562
+		wp_send_json(['success' => true]);
563
+	}
564
+
565
+
566
+	/**
567
+	 * Validate the PM instance, returning an ajax response on invalid.
568
+	 *
569
+	 * @param $paypal_pm
570
+	 * @return void
571
+	 */
572
+	public static function validatePmAjax($paypal_pm): void
573
+	{
574
+		if (! $paypal_pm instanceof EE_Payment_Method) {
575
+			wp_send_json(
576
+				[
577
+					'error'   => 'INVALID_PM',
578
+					'message' => esc_html__(
579
+						'Invalid payment method. Please refresh the page and try again.',
580
+						'event_espresso'
581
+					),
582
+				]
583
+			);
584
+		}
585
+	}
586
+
587
+
588
+	/**
589
+	 * Checks if already onboard.
590
+	 *
591
+	 * @param EE_Payment_Method $payment_method
592
+	 * @return boolean
593
+	 * @throws EE_Error
594
+	 * @throws ReflectionException
595
+	 */
596
+	public static function isOnboard(EE_Payment_Method $payment_method): bool
597
+	{
598
+		$pp_meta_data = PayPalExtraMetaManager::getAllData($payment_method);
599
+		return
600
+			(
601
+				// onboarded with a third party integration ?
602
+				! empty($pp_meta_data[ Domain::META_KEY_SELLER_MERCHANT_ID ])
603
+				&& ! empty($pp_meta_data[ Domain::META_KEY_ACCESS_TOKEN ])
604
+			) || (
605
+				// or with the first party integration ?
606
+				! empty($pp_meta_data[ Domain::META_KEY_CLIENT_ID ])
607
+				&& ! empty($pp_meta_data[ Domain::META_KEY_CLIENT_SECRET ])
608
+				&& ! empty($pp_meta_data[ Domain::META_KEY_PAYER_ID ])
609
+			);
610
+	}
611
+
612
+
613
+	/**
614
+	 * Send a request and return a decoded response body.
615
+	 *
616
+	 * @param EE_Payment_Method $paypal_pm
617
+	 * @param string            $request_url
618
+	 * @param array             $request_args
619
+	 * @return array
620
+	 */
621
+	public static function sendRequest(EE_Payment_Method $paypal_pm, string $request_url, array $request_args): array
622
+	{
623
+		$error_return = ['error' => true];
624
+		$response     = wp_remote_request($request_url, $request_args);
625
+		if (is_wp_error($response)) {
626
+			$message = $response->get_error_message();
627
+			PayPalLogger::errorLog($message, [$request_url, $request_args, $response], $paypal_pm);
628
+			$error_return['message'] = $message;
629
+			return $error_return;
630
+		}
631
+		$response_body = (isset($response['body']) && $response['body']) ? json_decode($response['body'], true) : [];
632
+		if (empty($response_body) || isset($response_body['error'])) {
633
+			$message = $response_body['error_description']
634
+				?? sprintf(
635
+					esc_html__('Unknown response received while sending a request to: %1$s', 'event_espresso'),
636
+					$request_url
637
+				);
638
+			PayPalLogger::errorLog($message, [$request_url, $request_args, $response], $paypal_pm);
639
+			$error_return['message'] = $message;
640
+			return $error_return;
641
+		}
642
+		return $response_body;
643
+	}
644
+
645
+
646
+	/**
647
+	 * Check the response for a partner token request.
648
+	 *
649
+	 * @param array             $response
650
+	 * @param EE_Payment_Method $paypal_pm
651
+	 * @return bool
652
+	 */
653
+	public static function partnerTokenResponseValid(array $response, EE_Payment_Method $paypal_pm): bool
654
+	{
655
+		// Check the data we received.
656
+		if (
657
+			empty($response['nonce'])
658
+			|| ! wp_verify_nonce($response['nonce'], 'eea_pp_commerce_get_access_token')
659
+			|| empty($response['access_token'])
660
+			|| empty($response['app_id'])
661
+			|| empty($response['expires_in'])
662
+			|| empty($response['partner_client_id'])
663
+			|| empty($response['partner_merchant_id'])
664
+		) {
665
+			// This is an error.
666
+			PayPalLogger::errorLog(
667
+				esc_html__('Incoming parameter validation failed.', 'event_espresso'),
668
+				$response,
669
+				$paypal_pm
670
+			);
671
+			return false;
672
+		}
673
+		return true;
674
+	}
675
+
676
+
677
+	/**
678
+	 * Returns the base URL to the middleman server.
679
+	 * If LOCAL_MIDDLEMAN_SERVER is defined, requests will be sent to connect.eventespresso.test
680
+	 *
681
+	 * @param EE_Payment_Method $payment_method
682
+	 * @return string
683
+	 * @throws EE_Error
684
+	 * @throws ReflectionException
685
+	 */
686
+	public static function getMiddlemanBaseUrl(EE_Payment_Method $payment_method): string
687
+	{
688
+		$target = defined('LOCAL_MIDDLEMAN_SERVER') ? 'test' : 'com';
689
+		// If this PM is used under different provider accounts, you might need an account indicator.
690
+		$account = defined('EE_PAYPAL_COMMERCE_ACCOUNT_INDICATOR') ? EE_PAYPAL_COMMERCE_ACCOUNT_INDICATOR : '';
691
+		$postfix = $payment_method->debug_mode() ? '_sandbox' : '';
692
+		return "https://connect.eventespresso.$target/paypal_commerce$account$postfix/";
693
+	}
694
+
695
+
696
+	/**
697
+	 * This Payment Method admin notices.
698
+	 *
699
+	 * @return void
700
+	 * @throws EE_Error
701
+	 * @throws ReflectionException
702
+	 */
703
+	public static function adminNotice()
704
+	{
705
+		// Show the notice if PayPal Commerce PM is active but merchant is not onboard.
706
+		$pp_commerce = EEM_Payment_Method::instance()->get_one_by_slug(Domain::PM_SLUG);
707
+		if (
708
+			$pp_commerce instanceof EE_Payment_Method
709
+			&& $pp_commerce->active()
710
+			&& ! EED_PayPalOnboard::isOnboard($pp_commerce)
711
+		) {
712
+			add_action('admin_notices', [EED_PayPalOnboard::class, 'notOnboardNotice']);
713
+		}
714
+	}
715
+
716
+
717
+	/**
718
+	 * Contents of the not onboard admin notice.
719
+	 *
720
+	 * @return void
721
+	 * @throws EE_Error
722
+	 * @throws ReflectionException
723
+	 */
724
+	public static function notOnboardNotice()
725
+	{
726
+		$open_anchor = $close_anchor = '';
727
+		$pp_commerce = EEM_Payment_Method::instance()->get_one_by_slug(Domain::PM_SLUG);
728
+		if ($pp_commerce instanceof EE_Payment_Method) {
729
+			$pm_page      = add_query_arg(
730
+				[
731
+					'page'           => 'espresso_payment_settings',
732
+					'webhook_action' => 'eepPpcMerchantOnboard',
733
+					'payment_method' => $pp_commerce->slug(),
734
+				],
735
+				admin_url('admin.php')
736
+			);
737
+			$open_anchor  = "<a href='$pm_page'>";
738
+			$close_anchor = "</a>";
739
+		}
740
+		$notice = sprintf(
741
+			esc_html__(
742
+				'%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.',
743
+				'event_espresso'
744
+			),
745
+			'<strong>',
746
+			'</strong>',
747
+			$open_anchor,
748
+			$close_anchor
749
+		);
750
+		echo "
751 751
         <div class='error'>
752 752
             <p>$notice</p>
753 753
         </div>";
754
-    }
754
+	}
755 755
 }
Please login to merge, or discard this patch.
Spacing   +29 added lines, -29 removed lines patch added patch discarded remove patch
@@ -84,7 +84,7 @@  discard block
 block discarded – undo
84 84
         $signup_link = '';
85 85
         try {
86 86
             $paypal_pm = EED_PayPalCommerce::getPaymentMethod();
87
-            if (! $paypal_pm instanceof EE_Payment_Method) {
87
+            if ( ! $paypal_pm instanceof EE_Payment_Method) {
88 88
                 PayPalLogger::errorLogAndExit(
89 89
                     esc_html__('No payment method.', 'event_espresso'),
90 90
                     EED_Module::getRequest()->postParams(),
@@ -94,7 +94,7 @@  discard block
 block discarded – undo
94 94
             PayPalExtraMetaManager::updateDebugMode($paypal_pm, EED_Module::getRequest()->postParams());
95 95
             // Just get a new onboarding URL every time.
96 96
             $signup_link = EED_PayPalOnboard::requestOnboardingUrl($paypal_pm);
97
-            if (! $signup_link) {
97
+            if ( ! $signup_link) {
98 98
                 $err_msg = esc_html__('Error! Could not generate a sign-up link.', 'event_espresso');
99 99
                 PayPalLogger::errorLogAndExit($err_msg, ['signup_link' => $signup_link], $paypal_pm);
100 100
             }
@@ -102,7 +102,7 @@  discard block
 block discarded – undo
102 102
             PayPalLogger::errorLogAndExit($e->getMessage(), ['trace' => $e->getTrace()]);
103 103
         }
104 104
         // Is it empty (can happen if we didn't get the URL through the API).
105
-        $signup_link = $signup_link ? $signup_link . '?&displayMode=minibrowser' : '#';
105
+        $signup_link = $signup_link ? $signup_link.'?&displayMode=minibrowser' : '#';
106 106
         wp_send_json(
107 107
             [
108 108
                 'signup_link' => $signup_link,
@@ -125,7 +125,7 @@  discard block
 block discarded – undo
125 125
         $signup_link = '';
126 126
         // Get the access token.
127 127
         $access_token = EED_PayPalOnboard::getPartnerAccessToken($paypal_pm);
128
-        if (! $access_token) {
128
+        if ( ! $access_token) {
129 129
             $err_msg = esc_html__('Error! No access token.', 'event_espresso');
130 130
             PayPalLogger::errorLog($err_msg, ['access_token' => $access_token], $paypal_pm);
131 131
             return '';
@@ -138,12 +138,12 @@  discard block
 block discarded – undo
138 138
             'headers' => [
139 139
                 'User-Agent'                    => sanitize_text_field($_SERVER['HTTP_USER_AGENT']),
140 140
                 'Content-Type'                  => 'application/json',
141
-                'Authorization'                 => 'Bearer ' . $access_token,
141
+                'Authorization'                 => 'Bearer '.$access_token,
142 142
                 'PayPal-Partner-Attribution-Id' => $bn_code,
143 143
             ],
144 144
             'body'    => $body_params,
145 145
         ];
146
-        $request_url = Domain::getPayPalApiUrl($paypal_pm) . '/v2/customer/partner-referrals';
146
+        $request_url = Domain::getPayPalApiUrl($paypal_pm).'/v2/customer/partner-referrals';
147 147
         $response    = EED_PayPalOnboard::sendRequest($paypal_pm, $request_url, $post_params);
148 148
         // Check the data we received.
149 149
         if (isset($response['error']) || empty($response['links'])) {
@@ -270,7 +270,7 @@  discard block
 block discarded – undo
270 270
             'payment_method' => $get_params['payment_method'],
271 271
         ];
272 272
         if (isset($get_params['sandbox_mode'])) {
273
-            $args_to_add[ Domain::META_KEY_SANDBOX_MODE ] = $get_params['sandbox_mode'];
273
+            $args_to_add[Domain::META_KEY_SANDBOX_MODE] = $get_params['sandbox_mode'];
274 274
         }
275 275
         $home_url = add_query_arg($args_to_add, admin_url('admin.php'));
276 276
         wp_redirect($home_url);
@@ -293,13 +293,13 @@  discard block
 block discarded – undo
293 293
             ! isset($_GET['webhook_action'], $_GET['nonce'])
294 294
             || $_GET['webhook_action'] !== 'eepPpcMerchantOnboard'
295 295
         ) {
296
-            return;  // Ignore.
296
+            return; // Ignore.
297 297
         }
298 298
         $get_params = EED_Module::getRequest()->getParams();
299 299
         // Get the payment method.
300 300
         $paypal_pm = EED_PayPalCommerce::getPaymentMethod();
301 301
         // Check the response (GET) parameters.
302
-        if (! EED_PayPalOnboard::onboardingStatusResponseValid($get_params, $paypal_pm)) {
302
+        if ( ! EED_PayPalOnboard::onboardingStatusResponseValid($get_params, $paypal_pm)) {
303 303
             // Missing parameters. Can't proceed.
304 304
             PayPalLogger::errorLog(
305 305
                 esc_html__('Missing required onboarding parameters.', 'event_espresso'),
@@ -312,9 +312,9 @@  discard block
 block discarded – undo
312 312
         // Check on the onboarding status (recommended by PP).
313 313
         $onboarding_status = EED_PayPalOnboard::trackSellerOnboarding(
314 314
             $paypal_pm,
315
-            $get_params[ Domain::META_KEY_SELLER_MERCHANT_ID ]
315
+            $get_params[Domain::META_KEY_SELLER_MERCHANT_ID]
316 316
         );
317
-        if (! isset($onboarding_status['valid']) || ! $onboarding_status['valid']) {
317
+        if ( ! isset($onboarding_status['valid']) || ! $onboarding_status['valid']) {
318 318
             PayPalLogger::errorLog(
319 319
                 $onboarding_status['message'],
320 320
                 array_merge($get_params, $onboarding_status),
@@ -345,9 +345,9 @@  discard block
 block discarded – undo
345 345
         if (
346 346
             $paypal_pm instanceof EE_Payment_Method
347 347
             && wp_verify_nonce($data['nonce'], Domain::NONCE_NAME_ONBOARDING_RETURN)
348
-            && ! empty($data[ Domain::API_PARAM_PARTNER_ID ])
349
-            && ! empty($data[ Domain::META_KEY_SELLER_MERCHANT_ID ])
350
-            && isset($data[ Domain::API_PARAM_EMAIL_CONFIRMED ])
348
+            && ! empty($data[Domain::API_PARAM_PARTNER_ID])
349
+            && ! empty($data[Domain::META_KEY_SELLER_MERCHANT_ID])
350
+            && isset($data[Domain::API_PARAM_EMAIL_CONFIRMED])
351 351
         ) {
352 352
             return true;
353 353
         }
@@ -368,7 +368,7 @@  discard block
 block discarded – undo
368 368
         // Do we have it saved ?
369 369
         $access_token = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_ACCESS_TOKEN);
370 370
         // If we don't have it, request/update it.
371
-        if (! $access_token) {
371
+        if ( ! $access_token) {
372 372
             return EED_PayPalOnboard::requestPartnerAccessToken($paypal_pm);
373 373
         }
374 374
         if (EED_PayPalOnboard::partnerAccessTokenExpired($paypal_pm)) {
@@ -390,7 +390,7 @@  discard block
 block discarded – undo
390 390
     public static function partnerAccessTokenExpired(EE_Payment_Method $paypal_pm): bool
391 391
     {
392 392
         $expires_at = (int) PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_TOKEN_EXPIRES_IN);
393
-        if (! $expires_at) {
393
+        if ( ! $expires_at) {
394 394
             return true;
395 395
         }
396 396
         // Validate the token expiration date.
@@ -426,18 +426,18 @@  discard block
 block discarded – undo
426 426
         if (defined('LOCAL_MIDDLEMAN_SERVER')) {
427 427
             $post_args['sslverify'] = Manager::verifySSL();
428 428
         }
429
-        $post_url = EED_PayPalOnboard::getMiddlemanBaseUrl($paypal_pm) . 'get_token';
429
+        $post_url = EED_PayPalOnboard::getMiddlemanBaseUrl($paypal_pm).'get_token';
430 430
         $response = EED_PayPalOnboard::sendRequest($paypal_pm, $post_url, $post_args);
431 431
         if (isset($response['error'])) {
432 432
             return '';
433 433
         }
434 434
         // Check the data we received.
435
-        if (! EED_PayPalOnboard::partnerTokenResponseValid($response, $paypal_pm)) {
435
+        if ( ! EED_PayPalOnboard::partnerTokenResponseValid($response, $paypal_pm)) {
436 436
             return '';
437 437
         }
438 438
         // If we are here all seems to be ok. Save the token and it's data.
439 439
         $saved = PayPalExtraMetaManager::savePartnerAccessToken($paypal_pm, $response);
440
-        if (! $saved) {
440
+        if ( ! $saved) {
441 441
             return '';
442 442
         }
443 443
         return $response['access_token'];
@@ -456,7 +456,7 @@  discard block
 block discarded – undo
456 456
     public static function trackSellerOnboarding(EE_Payment_Method $paypal_pm, string $merchant_id): array
457 457
     {
458 458
         $track_onboarding = EED_PayPalOnboard::getTrackOnboardingApi($paypal_pm, $merchant_id);
459
-        if (! $track_onboarding instanceof TrackSellerOnboarding) {
459
+        if ( ! $track_onboarding instanceof TrackSellerOnboarding) {
460 460
             return [
461 461
                 'error'   => 'TRACK_ONBOARDING_FAILED',
462 462
                 'message' => esc_html__('Failed to track seller onboarding.', 'event_espresso')
@@ -481,7 +481,7 @@  discard block
 block discarded – undo
481 481
     ): ?TrackSellerOnboarding {
482 482
         $partner_id = PayPalExtraMetaManager::getPmOption($paypal_pm, Domain::META_KEY_PARTNER_MERCHANT_ID);
483 483
         $paypal_api = EED_PayPalCommerce::getPayPalApi($paypal_pm);
484
-        if (! $paypal_api instanceof PayPalApi || ! $partner_id) {
484
+        if ( ! $paypal_api instanceof PayPalApi || ! $partner_id) {
485 485
             return null;
486 486
         }
487 487
         return new TrackSellerOnboarding($paypal_api, $partner_id, $merchant_id, $paypal_pm->debug_mode());
@@ -499,7 +499,7 @@  discard block
 block discarded – undo
499 499
     public static function getOnboardStatus(): void
500 500
     {
501 501
         $paypal_pm = EED_PayPalCommerce::getPaymentMethod();
502
-        if (! $paypal_pm instanceof EE_Payment_Method) {
502
+        if ( ! $paypal_pm instanceof EE_Payment_Method) {
503 503
             $err_msg = esc_html__('Could not specify the payment method.', 'event_espresso');
504 504
             PayPalLogger::errorLog($err_msg, EED_Module::getRequest()->postParams(), $paypal_pm);
505 505
             wp_send_json(['on_board' => false]);
@@ -571,7 +571,7 @@  discard block
 block discarded – undo
571 571
      */
572 572
     public static function validatePmAjax($paypal_pm): void
573 573
     {
574
-        if (! $paypal_pm instanceof EE_Payment_Method) {
574
+        if ( ! $paypal_pm instanceof EE_Payment_Method) {
575 575
             wp_send_json(
576 576
                 [
577 577
                     'error'   => 'INVALID_PM',
@@ -599,13 +599,13 @@  discard block
 block discarded – undo
599 599
         return
600 600
             (
601 601
                 // onboarded with a third party integration ?
602
-                ! empty($pp_meta_data[ Domain::META_KEY_SELLER_MERCHANT_ID ])
603
-                && ! empty($pp_meta_data[ Domain::META_KEY_ACCESS_TOKEN ])
602
+                ! empty($pp_meta_data[Domain::META_KEY_SELLER_MERCHANT_ID])
603
+                && ! empty($pp_meta_data[Domain::META_KEY_ACCESS_TOKEN])
604 604
             ) || (
605 605
                 // or with the first party integration ?
606
-                ! empty($pp_meta_data[ Domain::META_KEY_CLIENT_ID ])
607
-                && ! empty($pp_meta_data[ Domain::META_KEY_CLIENT_SECRET ])
608
-                && ! empty($pp_meta_data[ Domain::META_KEY_PAYER_ID ])
606
+                ! empty($pp_meta_data[Domain::META_KEY_CLIENT_ID])
607
+                && ! empty($pp_meta_data[Domain::META_KEY_CLIENT_SECRET])
608
+                && ! empty($pp_meta_data[Domain::META_KEY_PAYER_ID])
609 609
             );
610 610
     }
611 611
 
@@ -726,7 +726,7 @@  discard block
 block discarded – undo
726 726
         $open_anchor = $close_anchor = '';
727 727
         $pp_commerce = EEM_Payment_Method::instance()->get_one_by_slug(Domain::PM_SLUG);
728 728
         if ($pp_commerce instanceof EE_Payment_Method) {
729
-            $pm_page      = add_query_arg(
729
+            $pm_page = add_query_arg(
730 730
                 [
731 731
                     'page'           => 'espresso_payment_settings',
732 732
                     'webhook_action' => 'eepPpcMerchantOnboard',
Please login to merge, or discard this patch.
PaymentMethods/PayPalCommerce/PayPalCheckout/forms/OnboardingForm.php 2 patches
Indentation   +164 added lines, -164 removed lines patch added patch discarded remove patch
@@ -22,179 +22,179 @@
 block discarded – undo
22 22
  */
23 23
 class OnboardingForm extends EE_Form_Section_Proper
24 24
 {
25
-    /**
26
-     *  Payment method.
27
-     *
28
-     * @var EE_PMT_Base|null
29
-     */
30
-    protected $payment_method = null;
25
+	/**
26
+	 *  Payment method.
27
+	 *
28
+	 * @var EE_PMT_Base|null
29
+	 */
30
+	protected $payment_method = null;
31 31
 
32
-    /**
33
-     *  Payment method instance.
34
-     *
35
-     * @var EE_PMT_Base|null
36
-     */
37
-    protected $pm_instance = null;
32
+	/**
33
+	 *  Payment method instance.
34
+	 *
35
+	 * @var EE_PMT_Base|null
36
+	 */
37
+	protected $pm_instance = null;
38 38
 
39
-    /**
40
-     *  Payment method slug.
41
-     *
42
-     * @var EE_PMT_Base|null
43
-     */
44
-    protected $pm_slug = null;
39
+	/**
40
+	 *  Payment method slug.
41
+	 *
42
+	 * @var EE_PMT_Base|null
43
+	 */
44
+	protected $pm_slug = null;
45 45
 
46
-    /**
47
-     *  Options field header.
48
-     *
49
-     * @var string
50
-     */
51
-    protected $option_heading = '';
46
+	/**
47
+	 *  Options field header.
48
+	 *
49
+	 * @var string
50
+	 */
51
+	protected $option_heading = '';
52 52
 
53
-    /**
54
-     *  Onboarding URL.
55
-     *
56
-     * @var string
57
-     */
58
-    protected $onboarding_url = '';
53
+	/**
54
+	 *  Onboarding URL.
55
+	 *
56
+	 * @var string
57
+	 */
58
+	protected $onboarding_url = '';
59 59
 
60
-    /**
61
-     *  Onboarding form html entities object.
62
-     *
63
-     * @var OnboardingFormHtml|null
64
-     */
65
-    protected $form_html = null;
60
+	/**
61
+	 *  Onboarding form html entities object.
62
+	 *
63
+	 * @var OnboardingFormHtml|null
64
+	 */
65
+	protected $form_html = null;
66 66
 
67 67
 
68
-    /**
69
-     * Class constructor.
70
-     *
71
-     * @param EE_PMT_Base       $pmt
72
-     * @param EE_Payment_Method $payment_method
73
-     * @throws EE_Error
74
-     */
75
-    public function __construct(EE_PMT_Base $pmt, EE_Payment_Method $payment_method)
76
-    {
77
-        $this->payment_method      = $pmt;
78
-        $this->pm_instance         = $payment_method;
79
-        $this->pm_slug             = $this->pm_instance->slug();
80
-        $this->form_html           = new OnboardingFormHtml($pmt, $payment_method);
81
-        // Help tab link as icon.
82
-        $this->option_heading = $this->form_html->getHeader();
83
-        $options = [
84
-            'html_id'               => $this->pm_slug . '_pp_commerce_form',
85
-            'layout_strategy'       => new EE_Admin_Two_Column_Layout(),
86
-            'validation_strategies' => [new EE_Simple_HTML_Validation_Strategy()],
87
-            'subsections'           => $this->onboardSectionContents(),
88
-        ];
89
-        parent::__construct($options);
90
-    }
68
+	/**
69
+	 * Class constructor.
70
+	 *
71
+	 * @param EE_PMT_Base       $pmt
72
+	 * @param EE_Payment_Method $payment_method
73
+	 * @throws EE_Error
74
+	 */
75
+	public function __construct(EE_PMT_Base $pmt, EE_Payment_Method $payment_method)
76
+	{
77
+		$this->payment_method      = $pmt;
78
+		$this->pm_instance         = $payment_method;
79
+		$this->pm_slug             = $this->pm_instance->slug();
80
+		$this->form_html           = new OnboardingFormHtml($pmt, $payment_method);
81
+		// Help tab link as icon.
82
+		$this->option_heading = $this->form_html->getHeader();
83
+		$options = [
84
+			'html_id'               => $this->pm_slug . '_pp_commerce_form',
85
+			'layout_strategy'       => new EE_Admin_Two_Column_Layout(),
86
+			'validation_strategies' => [new EE_Simple_HTML_Validation_Strategy()],
87
+			'subsections'           => $this->onboardSectionContents(),
88
+		];
89
+		parent::__construct($options);
90
+	}
91 91
 
92 92
 
93
-    /**
94
-     * Add the onboarding options section.
95
-     *
96
-     * @return array
97
-     */
98
-    public function onboardSectionContents(): array
99
-    {
100
-        $subsections = [];
101
-        // Get the Onboarding status.
102
-        $is_onboard  = EED_PayPalOnboard::isOnboard($this->pm_instance);
103
-        $subsections = $this->form_html->addOnboardButton($subsections, $is_onboard);
104
-        $subsections = $this->form_html->addOffboardButton($subsections, $is_onboard);
105
-        return $this->form_html->addPmSlugHolder($subsections);
106
-    }
93
+	/**
94
+	 * Add the onboarding options section.
95
+	 *
96
+	 * @return array
97
+	 */
98
+	public function onboardSectionContents(): array
99
+	{
100
+		$subsections = [];
101
+		// Get the Onboarding status.
102
+		$is_onboard  = EED_PayPalOnboard::isOnboard($this->pm_instance);
103
+		$subsections = $this->form_html->addOnboardButton($subsections, $is_onboard);
104
+		$subsections = $this->form_html->addOffboardButton($subsections, $is_onboard);
105
+		return $this->form_html->addPmSlugHolder($subsections);
106
+	}
107 107
 
108 108
 
109
-    /**
110
-     * Add JS needed for this form.
111
-     * This is called automatically when displaying the form.
112
-     *
113
-     * @return void
114
-     * @throws EE_Error
115
-     * @throws ReflectionException
116
-     */
117
-    public function enqueue_js()
118
-    {
119
-        // Also tell the script about each instance of this PM.
120
-        $pm_versions = $pm_dialogs = [];
121
-        $active_payment_methods = EEM_Payment_Method::instance()->get_all_active(
122
-            EEM_Payment_Method::scope_cart,
123
-            [['PMD_slug' => ['LIKE', '%' . Domain::PM_SLUG . '%']]]
124
-        );
125
-        foreach ($active_payment_methods as $payment_method) {
126
-            if (! $payment_method instanceof EE_Payment_Method) {
127
-                continue;
128
-            }
129
-            $pm_slug = $payment_method->slug();
130
-            $pm_versions[ $pm_slug ] = [
131
-                'pm_slug' => $pm_slug,
132
-            ];
133
-            $form_html = new OnboardingFormHtml($this->payment_method, $payment_method);
134
-            $pm_dialogs[ $pm_slug ]['connect_dialog'] = $form_html->connectDialog()->get_html();
135
-            $pm_dialogs[ $pm_slug ]['disconnect_dialog'] = $form_html->disconnectDialog()->get_html();
136
-            $pm_dialogs[ $pm_slug ]['processing_mask'] = $form_html->processingMask()->get_html();
137
-        }
138
-        $countries_iso = ["US", "AU", "AT", "BE", "BG", "HR", "CY", "CZ", "DK", "EE", "FI", "FR", "DE", "GR", "HU",
139
-                          "IE", "IT", "LV", "LT", "LU", "MT", "NL", "PL", "PT", "RO", "SK", "SI", "ES", "SE"];
140
-        $parameters = [
141
-            'onboard_btn_text'     => $this->form_html->onboard_btn_text,
142
-            'sandbox_btn_text'     => $this->form_html->sandbox_btn_text,
143
-            'sandbox_text'         => $this->form_html->authed_sandbox_text,
144
-            'pm_versions'          => $pm_versions,
145
-            'onboarding_url'       => $this->onboarding_url,
146
-            'supported_countries'  => $countries_iso,
147
-            'pm_dialogs'           => $pm_dialogs,
148
-            'ee_default_styles'    => EE_ADMIN_URL . 'assets/ee-admin-page.css',
149
-            'wp_stylesheet'        => includes_url('css/dashicons.min.css'),
150
-            'can_disable_input'    => method_exists('EE_Form_Input_Base', 'isDisabled'),
151
-            'connection_notice'    => esc_html__('Error while requesting the redirect URL.', 'event_espresso'),
152
-            'error_response'       => esc_html__('Error response received', 'event_espresso'),
153
-            'request_error'        => esc_html__(
154
-                'Onboarding request Error. Please check the logs on the Payment Methods page.',
155
-                'event_espresso'
156
-            ),
157
-            'unknown_container'    => esc_html__('Could not specify the parent form.', 'event_espresso'),
158
-            'pm_nice_name'         => esc_html__('PayPal Commerce', 'event_espresso'),
159
-            'blocked_popup_notice' => esc_html__(
160
-                'The authentication process could not be executed. Please allow window pop-ups in your browser for this website in order to process a successful authentication.',
161
-                'event_espresso'
162
-            ),
163
-            'debug_is_on_notice'   => esc_html__(
164
-                'The authentication with PayPal is in sandbox mode! If you wish to process real payments with this payment method, please Offboard and use live credentials to authenticate with PayPal.',
165
-                'event_espresso'
166
-            ),
167
-            'debug_is_off_notice'  => esc_html__(
168
-                'The authentication with PayPal is in Live mode! If you wish to test this payment method, please Offboard and use sandbox credentials to authenticate with PayPal.',
169
-                'event_espresso'
170
-            ),
171
-            'refresh_alert'        => esc_html__(
172
-                'There was an unexpected error. Please refresh the page and check the logs on the Payment Methods page.',
173
-                'event_espresso'
174
-            ),
175
-        ];
176
-        // Styles.
177
-        wp_enqueue_style(
178
-            'eea_paypal_onboard_form_styles',
179
-            EEP_PAYPAL_COMMERCE_URL . 'assets' . DS . 'css' . DS . 'eea-paypal-onboard.css',
180
-            [],
181
-            EVENT_ESPRESSO_VERSION
182
-        );
183
-        // Scripts.
184
-        wp_enqueue_script(
185
-            'eea_paypal_onboard_form_scripts',
186
-            EEP_PAYPAL_COMMERCE_URL . 'assets' . DS . 'js' . DS . 'eea-paypal-onboarding.js',
187
-            [],
188
-            EVENT_ESPRESSO_VERSION
189
-        );
190
-        wp_enqueue_script(
191
-            'eea_paypal_partner_script',
192
-            'https://www.paypal.com/webapps/merchantboarding/js/lib/lightbox/partner.js',
193
-            [],
194
-            EVENT_ESPRESSO_VERSION
195
-        );
196
-        // Localize the script with some extra data.
197
-        wp_localize_script('eea_paypal_onboard_form_scripts', 'eeaPPOnboardParameters', $parameters);
198
-        parent::enqueue_js();
199
-    }
109
+	/**
110
+	 * Add JS needed for this form.
111
+	 * This is called automatically when displaying the form.
112
+	 *
113
+	 * @return void
114
+	 * @throws EE_Error
115
+	 * @throws ReflectionException
116
+	 */
117
+	public function enqueue_js()
118
+	{
119
+		// Also tell the script about each instance of this PM.
120
+		$pm_versions = $pm_dialogs = [];
121
+		$active_payment_methods = EEM_Payment_Method::instance()->get_all_active(
122
+			EEM_Payment_Method::scope_cart,
123
+			[['PMD_slug' => ['LIKE', '%' . Domain::PM_SLUG . '%']]]
124
+		);
125
+		foreach ($active_payment_methods as $payment_method) {
126
+			if (! $payment_method instanceof EE_Payment_Method) {
127
+				continue;
128
+			}
129
+			$pm_slug = $payment_method->slug();
130
+			$pm_versions[ $pm_slug ] = [
131
+				'pm_slug' => $pm_slug,
132
+			];
133
+			$form_html = new OnboardingFormHtml($this->payment_method, $payment_method);
134
+			$pm_dialogs[ $pm_slug ]['connect_dialog'] = $form_html->connectDialog()->get_html();
135
+			$pm_dialogs[ $pm_slug ]['disconnect_dialog'] = $form_html->disconnectDialog()->get_html();
136
+			$pm_dialogs[ $pm_slug ]['processing_mask'] = $form_html->processingMask()->get_html();
137
+		}
138
+		$countries_iso = ["US", "AU", "AT", "BE", "BG", "HR", "CY", "CZ", "DK", "EE", "FI", "FR", "DE", "GR", "HU",
139
+						  "IE", "IT", "LV", "LT", "LU", "MT", "NL", "PL", "PT", "RO", "SK", "SI", "ES", "SE"];
140
+		$parameters = [
141
+			'onboard_btn_text'     => $this->form_html->onboard_btn_text,
142
+			'sandbox_btn_text'     => $this->form_html->sandbox_btn_text,
143
+			'sandbox_text'         => $this->form_html->authed_sandbox_text,
144
+			'pm_versions'          => $pm_versions,
145
+			'onboarding_url'       => $this->onboarding_url,
146
+			'supported_countries'  => $countries_iso,
147
+			'pm_dialogs'           => $pm_dialogs,
148
+			'ee_default_styles'    => EE_ADMIN_URL . 'assets/ee-admin-page.css',
149
+			'wp_stylesheet'        => includes_url('css/dashicons.min.css'),
150
+			'can_disable_input'    => method_exists('EE_Form_Input_Base', 'isDisabled'),
151
+			'connection_notice'    => esc_html__('Error while requesting the redirect URL.', 'event_espresso'),
152
+			'error_response'       => esc_html__('Error response received', 'event_espresso'),
153
+			'request_error'        => esc_html__(
154
+				'Onboarding request Error. Please check the logs on the Payment Methods page.',
155
+				'event_espresso'
156
+			),
157
+			'unknown_container'    => esc_html__('Could not specify the parent form.', 'event_espresso'),
158
+			'pm_nice_name'         => esc_html__('PayPal Commerce', 'event_espresso'),
159
+			'blocked_popup_notice' => esc_html__(
160
+				'The authentication process could not be executed. Please allow window pop-ups in your browser for this website in order to process a successful authentication.',
161
+				'event_espresso'
162
+			),
163
+			'debug_is_on_notice'   => esc_html__(
164
+				'The authentication with PayPal is in sandbox mode! If you wish to process real payments with this payment method, please Offboard and use live credentials to authenticate with PayPal.',
165
+				'event_espresso'
166
+			),
167
+			'debug_is_off_notice'  => esc_html__(
168
+				'The authentication with PayPal is in Live mode! If you wish to test this payment method, please Offboard and use sandbox credentials to authenticate with PayPal.',
169
+				'event_espresso'
170
+			),
171
+			'refresh_alert'        => esc_html__(
172
+				'There was an unexpected error. Please refresh the page and check the logs on the Payment Methods page.',
173
+				'event_espresso'
174
+			),
175
+		];
176
+		// Styles.
177
+		wp_enqueue_style(
178
+			'eea_paypal_onboard_form_styles',
179
+			EEP_PAYPAL_COMMERCE_URL . 'assets' . DS . 'css' . DS . 'eea-paypal-onboard.css',
180
+			[],
181
+			EVENT_ESPRESSO_VERSION
182
+		);
183
+		// Scripts.
184
+		wp_enqueue_script(
185
+			'eea_paypal_onboard_form_scripts',
186
+			EEP_PAYPAL_COMMERCE_URL . 'assets' . DS . 'js' . DS . 'eea-paypal-onboarding.js',
187
+			[],
188
+			EVENT_ESPRESSO_VERSION
189
+		);
190
+		wp_enqueue_script(
191
+			'eea_paypal_partner_script',
192
+			'https://www.paypal.com/webapps/merchantboarding/js/lib/lightbox/partner.js',
193
+			[],
194
+			EVENT_ESPRESSO_VERSION
195
+		);
196
+		// Localize the script with some extra data.
197
+		wp_localize_script('eea_paypal_onboard_form_scripts', 'eeaPPOnboardParameters', $parameters);
198
+		parent::enqueue_js();
199
+	}
200 200
 }
Please login to merge, or discard this patch.
Spacing   +10 added lines, -10 removed lines patch added patch discarded remove patch
@@ -81,7 +81,7 @@  discard block
 block discarded – undo
81 81
         // Help tab link as icon.
82 82
         $this->option_heading = $this->form_html->getHeader();
83 83
         $options = [
84
-            'html_id'               => $this->pm_slug . '_pp_commerce_form',
84
+            'html_id'               => $this->pm_slug.'_pp_commerce_form',
85 85
             'layout_strategy'       => new EE_Admin_Two_Column_Layout(),
86 86
             'validation_strategies' => [new EE_Simple_HTML_Validation_Strategy()],
87 87
             'subsections'           => $this->onboardSectionContents(),
@@ -120,20 +120,20 @@  discard block
 block discarded – undo
120 120
         $pm_versions = $pm_dialogs = [];
121 121
         $active_payment_methods = EEM_Payment_Method::instance()->get_all_active(
122 122
             EEM_Payment_Method::scope_cart,
123
-            [['PMD_slug' => ['LIKE', '%' . Domain::PM_SLUG . '%']]]
123
+            [['PMD_slug' => ['LIKE', '%'.Domain::PM_SLUG.'%']]]
124 124
         );
125 125
         foreach ($active_payment_methods as $payment_method) {
126
-            if (! $payment_method instanceof EE_Payment_Method) {
126
+            if ( ! $payment_method instanceof EE_Payment_Method) {
127 127
                 continue;
128 128
             }
129 129
             $pm_slug = $payment_method->slug();
130
-            $pm_versions[ $pm_slug ] = [
130
+            $pm_versions[$pm_slug] = [
131 131
                 'pm_slug' => $pm_slug,
132 132
             ];
133 133
             $form_html = new OnboardingFormHtml($this->payment_method, $payment_method);
134
-            $pm_dialogs[ $pm_slug ]['connect_dialog'] = $form_html->connectDialog()->get_html();
135
-            $pm_dialogs[ $pm_slug ]['disconnect_dialog'] = $form_html->disconnectDialog()->get_html();
136
-            $pm_dialogs[ $pm_slug ]['processing_mask'] = $form_html->processingMask()->get_html();
134
+            $pm_dialogs[$pm_slug]['connect_dialog'] = $form_html->connectDialog()->get_html();
135
+            $pm_dialogs[$pm_slug]['disconnect_dialog'] = $form_html->disconnectDialog()->get_html();
136
+            $pm_dialogs[$pm_slug]['processing_mask'] = $form_html->processingMask()->get_html();
137 137
         }
138 138
         $countries_iso = ["US", "AU", "AT", "BE", "BG", "HR", "CY", "CZ", "DK", "EE", "FI", "FR", "DE", "GR", "HU",
139 139
                           "IE", "IT", "LV", "LT", "LU", "MT", "NL", "PL", "PT", "RO", "SK", "SI", "ES", "SE"];
@@ -145,7 +145,7 @@  discard block
 block discarded – undo
145 145
             'onboarding_url'       => $this->onboarding_url,
146 146
             'supported_countries'  => $countries_iso,
147 147
             'pm_dialogs'           => $pm_dialogs,
148
-            'ee_default_styles'    => EE_ADMIN_URL . 'assets/ee-admin-page.css',
148
+            'ee_default_styles'    => EE_ADMIN_URL.'assets/ee-admin-page.css',
149 149
             'wp_stylesheet'        => includes_url('css/dashicons.min.css'),
150 150
             'can_disable_input'    => method_exists('EE_Form_Input_Base', 'isDisabled'),
151 151
             'connection_notice'    => esc_html__('Error while requesting the redirect URL.', 'event_espresso'),
@@ -176,14 +176,14 @@  discard block
 block discarded – undo
176 176
         // Styles.
177 177
         wp_enqueue_style(
178 178
             'eea_paypal_onboard_form_styles',
179
-            EEP_PAYPAL_COMMERCE_URL . 'assets' . DS . 'css' . DS . 'eea-paypal-onboard.css',
179
+            EEP_PAYPAL_COMMERCE_URL.'assets'.DS.'css'.DS.'eea-paypal-onboard.css',
180 180
             [],
181 181
             EVENT_ESPRESSO_VERSION
182 182
         );
183 183
         // Scripts.
184 184
         wp_enqueue_script(
185 185
             'eea_paypal_onboard_form_scripts',
186
-            EEP_PAYPAL_COMMERCE_URL . 'assets' . DS . 'js' . DS . 'eea-paypal-onboarding.js',
186
+            EEP_PAYPAL_COMMERCE_URL.'assets'.DS.'js'.DS.'eea-paypal-onboarding.js',
187 187
             [],
188 188
             EVENT_ESPRESSO_VERSION
189 189
         );
Please login to merge, or discard this patch.
PaymentMethods/PayPalCommerce/tools/extra_meta/PayPalExtraMetaManager.php 2 patches
Indentation   +383 added lines, -383 removed lines patch added patch discarded remove patch
@@ -22,387 +22,387 @@
 block discarded – undo
22 22
  */
23 23
 class PayPalExtraMetaManager
24 24
 {
25
-    private static ?OpenSSLEncryption $encryptor = null;
26
-
27
-    private static ?PayPalExtraMeta $pay_pal_extra_meta = null;
28
-
29
-
30
-    /**
31
-     * Get PayPal extra meta helper.
32
-     *
33
-     * @param EE_Payment_Method $paypal_pm
34
-     * @return PayPalExtraMeta
35
-     * @throws EE_Error
36
-     * @throws ReflectionException
37
-     */
38
-    public static function extraMeta(EE_Payment_Method $paypal_pm): PayPalExtraMeta
39
-    {
40
-        if (
41
-            ! PayPalExtraMetaManager::$pay_pal_extra_meta instanceof PayPalExtraMeta
42
-            || PayPalExtraMetaManager::$pay_pal_extra_meta->pm->slug() !== $paypal_pm->slug()
43
-        ) {
44
-            PayPalExtraMetaManager::$pay_pal_extra_meta = new PayPalExtraMeta($paypal_pm);
45
-        }
46
-        return PayPalExtraMetaManager::$pay_pal_extra_meta;
47
-    }
48
-
49
-
50
-    /**
51
-     * Get OpenSSLEncryption instance.
52
-     *
53
-     * @return OpenSSLEncryption
54
-     */
55
-    public static function encryptor(): OpenSSLEncryption
56
-    {
57
-        if (! PayPalExtraMetaManager::$encryptor instanceof OpenSSLEncryption) {
58
-            PayPalExtraMetaManager::$encryptor = LoaderFactory::getLoader()->getShared(
59
-                OpenSSLEncryption::class,
60
-                [new Base64Encoder()]
61
-            );
62
-        }
63
-        return PayPalExtraMetaManager::$encryptor;
64
-    }
65
-
66
-
67
-    /**
68
-     * Get payment method option/extra meta
69
-     *
70
-     * @param EE_Payment_Method $paypal_pm
71
-     * @param string            $option_name
72
-     * @return mixed
73
-     * @throws EE_Error
74
-     * @throws ReflectionException
75
-     */
76
-    public static function getPmOption(EE_Payment_Method $paypal_pm, string $option_name)
77
-    {
78
-        $option_value = PayPalExtraMetaManager::extraMeta($paypal_pm)->getOption($option_name);
79
-        // Decrypt the encrypted options.
80
-        if (
81
-            $option_name === Domain::META_KEY_ACCESS_TOKEN
82
-            || $option_name === Domain::META_KEY_PARTNER_MERCHANT_ID
83
-            || $option_name === Domain::META_KEY_CLIENT_SECRET
84
-        ) {
85
-            $option_value = PayPalExtraMetaManager::decryptString($option_value, $paypal_pm);
86
-        }
87
-        return $option_value;
88
-    }
89
-
90
-
91
-    /**
92
-     * Save payment method option/extra meta
93
-     *
94
-     * @param EE_Payment_Method $paypal_pm
95
-     * @param string            $option_name
96
-     * @param                   $option_value
97
-     * @return bool
98
-     * @throws EE_Error
99
-     * @throws ReflectionException
100
-     */
101
-    public static function savePmOption(EE_Payment_Method $paypal_pm, string $option_name, $option_value): bool
102
-    {
103
-        return PayPalExtraMetaManager::extraMeta($paypal_pm)->saveOption($option_name, $option_value);
104
-    }
105
-
106
-
107
-    /**
108
-     * Save a list of payment method options/extra meta.
109
-     *
110
-     * @param EE_Payment_Method $paypal_pm
111
-     * @param array             $options_list
112
-     * @return bool
113
-     * @throws EE_Error
114
-     * @throws ReflectionException
115
-     */
116
-    public static function savePmOptions(EE_Payment_Method $paypal_pm, array $options_list): bool
117
-    {
118
-        return PayPalExtraMetaManager::extraMeta($paypal_pm)->saveBatch($options_list);
119
-    }
120
-
121
-
122
-    /**
123
-     * Delete payment method option/extra meta
124
-     *
125
-     * @param EE_Payment_Method $paypal_pm
126
-     * @param string            $option_name
127
-     * @return bool
128
-     * @throws EE_Error
129
-     * @throws ReflectionException
130
-     */
131
-    public static function deletePmOption(EE_Payment_Method $paypal_pm, string $option_name): bool
132
-    {
133
-        return PayPalExtraMetaManager::extraMeta($paypal_pm)->deleteOption($option_name);
134
-    }
135
-
136
-
137
-    /**
138
-     * Get all options for payment method.
139
-     *
140
-     * @param EE_Payment_Method $paypal_pm
141
-     * @return array
142
-     * @throws EE_Error
143
-     * @throws ReflectionException
144
-     */
145
-    public static function getAllData(EE_Payment_Method $paypal_pm): array
146
-    {
147
-        return PayPalExtraMetaManager::extraMeta($paypal_pm)->getMetaData();
148
-    }
149
-
150
-
151
-    /**
152
-     * Delete payment method metadata.
153
-     *
154
-     * @param EE_Payment_Method $paypal_pm
155
-     * @return bool
156
-     * @throws EE_Error
157
-     * @throws ReflectionException
158
-     */
159
-    public static function deleteData(EE_Payment_Method $paypal_pm): bool
160
-    {
161
-        return PayPalExtraMetaManager::extraMeta($paypal_pm)->deleteMetaData();
162
-    }
163
-
164
-
165
-    /**
166
-     * Delete all payment method metadata.
167
-     *
168
-     * @param EE_Payment_Method $paypal_pm
169
-     * @return bool
170
-     * @throws EE_Error
171
-     * @throws ReflectionException
172
-     */
173
-    public static function deleteAllData(EE_Payment_Method $paypal_pm): bool
174
-    {
175
-        return PayPalExtraMetaManager::extraMeta($paypal_pm)->deleteAllMetaData();
176
-    }
177
-
178
-    /**
179
-     * Save the debug mode option if it changed.
180
-     *
181
-     * @param EE_Payment_Method $paypal_pm
182
-     * @param array             $request_data
183
-     * @return bool             Updated or not.
184
-     * @throws EE_Error
185
-     * @throws ReflectionException
186
-     */
187
-    public static function updateDebugMode(EE_Payment_Method $paypal_pm, array $request_data): bool
188
-    {
189
-        if (
190
-            isset($request_data['sandbox_mode'])
191
-            && in_array($request_data['sandbox_mode'], ['0', '1'], true)
192
-            && $paypal_pm->debug_mode() !== (bool) $request_data['sandbox_mode']
193
-        ) {
194
-            try {
195
-                $paypal_pm->save(['PMD_debug_mode' => (bool) $request_data['sandbox_mode']]);
196
-            } catch (EE_Error $e) {
197
-                PayPalLogger::errorLog(
198
-                    sprintf(
199
-                        esc_html__('Note, debug mode not saved ! %1$s', 'event_espresso'),
200
-                        $e->getMessage()
201
-                    ),
202
-                    ['request_data' => $request_data, 'trace' => $e->getTrace()],
203
-                    $paypal_pm
204
-                );
205
-                return false;
206
-            }
207
-            return true;
208
-        }
209
-        return false;
210
-    }
211
-
212
-
213
-    /**
214
-     * Save partner access token and parameters.
215
-     *
216
-     * @param EE_Payment_Method $paypal_pm
217
-     * @param array             $response
218
-     * @return bool
219
-     * @throws EE_Error
220
-     * @throws ReflectionException
221
-     */
222
-    public static function savePartnerAccessToken(EE_Payment_Method $paypal_pm, array $response): bool
223
-    {
224
-        $paypal_data         = [];
225
-        $expected_parameters = [
226
-            Domain::META_KEY_ACCESS_TOKEN,
227
-            Domain::META_KEY_TOKEN_EXPIRES_IN,
228
-            Domain::META_KEY_APP_ID,
229
-            Domain::META_KEY_PARTNER_CLIENT_ID,
230
-            Domain::META_KEY_PARTNER_MERCHANT_ID,
231
-            Domain::META_KEY_BN_CODE,
232
-        ];
233
-        foreach ($expected_parameters as $api_key) {
234
-            if (! isset($response[ $api_key ])) {
235
-                // Don't want to try saving data that doesn't exist.
236
-                continue;
237
-            }
238
-            try {
239
-                switch ($api_key) {
240
-                    case Domain::META_KEY_ACCESS_TOKEN:
241
-                    case Domain::META_KEY_PARTNER_MERCHANT_ID:
242
-                        $paypal_data[ $api_key ] = PayPalExtraMetaManager::encryptString(
243
-                            $response[ $api_key ],
244
-                            $paypal_pm
245
-                        );
246
-                        break;
247
-                    case Domain::META_KEY_TOKEN_EXPIRES_IN:
248
-                        $paypal_data[ $api_key ] = time() + (int) sanitize_key($response[ $api_key ]);
249
-                        break;
250
-                    default:
251
-                        $paypal_data[ $api_key ] = sanitize_text_field($response[ $api_key ]);
252
-                }
253
-            } catch (Exception $e) {
254
-                PayPalLogger::errorLog(
255
-                    $e->getMessage(),
256
-                    ['response' => $response, 'trace' => $e->getTrace()],
257
-                    $paypal_pm
258
-                );
259
-                return false;
260
-            }
261
-        }
262
-        return PayPalExtraMetaManager::savePmOptions($paypal_pm, $paypal_data);
263
-    }
264
-
265
-
266
-    /**
267
-     * Save merchant/seller API credentials.
268
-     *
269
-     * @param EE_Payment_Method $paypal_pm
270
-     * @param array             $response
271
-     * @return bool
272
-     * @throws EE_Error
273
-     * @throws ReflectionException
274
-     */
275
-    public static function saveSellerApiCredentials(EE_Payment_Method $paypal_pm, array $response): bool
276
-    {
277
-        $api_credentials     = [];
278
-        $expected_parameters = [Domain::META_KEY_SELLER_MERCHANT_ID];
279
-        foreach ($expected_parameters as $api_key) {
280
-            if (! isset($response[ $api_key ])) {
281
-                // Don't want to try saving data that doesn't exist.
282
-                continue;
283
-            }
284
-            $api_credentials[ $api_key ] = $response[ $api_key ];
285
-        }
286
-        return PayPalExtraMetaManager::savePmOptions($paypal_pm, $api_credentials);
287
-    }
288
-
289
-
290
-    /**
291
-     * Save other payment method related settings from a data array.
292
-     *
293
-     * @param EE_Payment_Method $paypal_pm
294
-     * @param array             $data
295
-     * @param array             $get_params
296
-     * @return bool
297
-     * @throws EE_Error
298
-     * @throws ReflectionException
299
-     */
300
-    public static function parseAndSaveOptions(EE_Payment_Method $paypal_pm, array $data, array $get_params): bool
301
-    {
302
-        $allowed_checkout_type = 'express_checkout';
303
-        // Did the merchant onboard with PPCP enabled or no.
304
-        if (! empty($get_params['selected_payment']) && $get_params['selected_payment'] === 'PPCP') {
305
-            // Make sure that merchant's account really supports advanced card fields (included in the PPCP scope).
306
-            // Has to include "PPCP_CUSTOM" product for ACDC support. "EXPRESS_CHECKOUT" otherwise.
307
-            if (! empty($data['response']['products'][0]['name'])) {
308
-                foreach ($data['response']['products'] as $product) {
309
-                    if ($product['name'] === 'PPCP_CUSTOM') {
310
-                        // This merchant has PPCP in the products list, so we can enable both (all supported) checkout types.
311
-                        $allowed_checkout_type = 'all';
312
-                        break;
313
-                    }
314
-                }
315
-            }
316
-        }
317
-        // Set the PM option Checkout type, just in case merchant doesn't save PM options manually.
318
-        $checkout_type_setting = $paypal_pm->get_extra_meta(Domain::META_KEY_CHECKOUT_TYPE, true, false);
319
-        if (! $checkout_type_setting || $checkout_type_setting !== $allowed_checkout_type) {
320
-            $paypal_pm->update_extra_meta(Domain::META_KEY_CHECKOUT_TYPE, $allowed_checkout_type);
321
-        }
322
-        // Save the scopes that were authorized.
323
-        if (! empty($data['response']['oauth_integrations'][0]['oauth_third_party'][0]['scopes'])) {
324
-            $scopes = [];
325
-            foreach ($data['response']['oauth_integrations'][0]['oauth_third_party'][0]['scopes'] as $scope) {
326
-                // Scope will look like: 'https://uri.paypal.com/services/payments/partnerfee'
327
-                $split       = explode('/', $scope);
328
-                $split_count = count($split);
329
-                // Get the scope itself.
330
-                $scopes[] = $split[ $split_count - 1 ];
331
-            }
332
-            if (empty($scopes)) {
333
-                // In case the there's a change in how scopes come in just save the list.
334
-                $scopes = $data['response']['oauth_integrations'][0]['oauth_third_party'][0]['scopes'];
335
-            }
336
-            PayPalExtraMetaManager::savePmOption($paypal_pm, Domain::META_KEY_AUTHORIZED_SCOPES, $scopes);
337
-        }
338
-        return PayPalExtraMetaManager::savePmOption(
339
-            $paypal_pm,
340
-            Domain::META_KEY_ALLOWED_CHECKOUT_TYPE,
341
-            $allowed_checkout_type
342
-        );
343
-    }
344
-
345
-
346
-    /**
347
-     * Encrypt a text field.
348
-     *
349
-     * @param string            $text
350
-     * @param EE_Payment_Method $paypal_pm
351
-     * @return string|null
352
-     * @throws Exception
353
-     */
354
-    public static function encryptString(string $text, EE_Payment_Method $paypal_pm): ?string
355
-    {
356
-        // We sure we are getting something ?
357
-        if (! $text) {
358
-            return $text;
359
-        }
360
-
361
-        try {
362
-            // Do encrypt.
363
-            $sanitized_text = sanitize_text_field($text);
364
-            $key_identifier = $paypal_pm->debug_mode()
365
-                ? PPCommerceEncryptionKeyManager::SANDBOX_ENCRYPTION_KEY_ID
366
-                : PPCommerceEncryptionKeyManager::PRODUCTION_ENCRYPTION_KEY_ID;
367
-            $encrypted      = PayPalExtraMetaManager::encryptor()->encrypt($sanitized_text, $key_identifier);
368
-        } catch (Exception $e) {
369
-            PayPalLogger::errorLog(
370
-                $e->getMessage(),
371
-                ['trace' => $e->getTrace()],
372
-                $paypal_pm
373
-            );
374
-        }
375
-        return $encrypted ?? null;
376
-    }
377
-
378
-
379
-    /**
380
-     * Decrypt a string.
381
-     *
382
-     * @param string            $text
383
-     * @param EE_Payment_Method $paypal_pm
384
-     * @return string
385
-     */
386
-    public static function decryptString(string $text, EE_Payment_Method $paypal_pm): string
387
-    {
388
-        // Are we even getting something ?
389
-        if (! $text) {
390
-            return $text;
391
-        }
392
-        // Try decrypting.
393
-        try {
394
-            $key_identifier = $paypal_pm->debug_mode()
395
-                ? PPCommerceEncryptionKeyManager::SANDBOX_ENCRYPTION_KEY_ID
396
-                : PPCommerceEncryptionKeyManager::PRODUCTION_ENCRYPTION_KEY_ID;
397
-            $decrypted      = PayPalExtraMetaManager::encryptor()->decrypt($text, $key_identifier);
398
-        } catch (Exception $e) {
399
-            PayPalLogger::errorLog(
400
-                $e->getMessage(),
401
-                ['trace' => $e->getTrace()],
402
-                $paypal_pm
403
-            );
404
-            return $text;
405
-        }
406
-        return $decrypted ?? $text;
407
-    }
25
+	private static ?OpenSSLEncryption $encryptor = null;
26
+
27
+	private static ?PayPalExtraMeta $pay_pal_extra_meta = null;
28
+
29
+
30
+	/**
31
+	 * Get PayPal extra meta helper.
32
+	 *
33
+	 * @param EE_Payment_Method $paypal_pm
34
+	 * @return PayPalExtraMeta
35
+	 * @throws EE_Error
36
+	 * @throws ReflectionException
37
+	 */
38
+	public static function extraMeta(EE_Payment_Method $paypal_pm): PayPalExtraMeta
39
+	{
40
+		if (
41
+			! PayPalExtraMetaManager::$pay_pal_extra_meta instanceof PayPalExtraMeta
42
+			|| PayPalExtraMetaManager::$pay_pal_extra_meta->pm->slug() !== $paypal_pm->slug()
43
+		) {
44
+			PayPalExtraMetaManager::$pay_pal_extra_meta = new PayPalExtraMeta($paypal_pm);
45
+		}
46
+		return PayPalExtraMetaManager::$pay_pal_extra_meta;
47
+	}
48
+
49
+
50
+	/**
51
+	 * Get OpenSSLEncryption instance.
52
+	 *
53
+	 * @return OpenSSLEncryption
54
+	 */
55
+	public static function encryptor(): OpenSSLEncryption
56
+	{
57
+		if (! PayPalExtraMetaManager::$encryptor instanceof OpenSSLEncryption) {
58
+			PayPalExtraMetaManager::$encryptor = LoaderFactory::getLoader()->getShared(
59
+				OpenSSLEncryption::class,
60
+				[new Base64Encoder()]
61
+			);
62
+		}
63
+		return PayPalExtraMetaManager::$encryptor;
64
+	}
65
+
66
+
67
+	/**
68
+	 * Get payment method option/extra meta
69
+	 *
70
+	 * @param EE_Payment_Method $paypal_pm
71
+	 * @param string            $option_name
72
+	 * @return mixed
73
+	 * @throws EE_Error
74
+	 * @throws ReflectionException
75
+	 */
76
+	public static function getPmOption(EE_Payment_Method $paypal_pm, string $option_name)
77
+	{
78
+		$option_value = PayPalExtraMetaManager::extraMeta($paypal_pm)->getOption($option_name);
79
+		// Decrypt the encrypted options.
80
+		if (
81
+			$option_name === Domain::META_KEY_ACCESS_TOKEN
82
+			|| $option_name === Domain::META_KEY_PARTNER_MERCHANT_ID
83
+			|| $option_name === Domain::META_KEY_CLIENT_SECRET
84
+		) {
85
+			$option_value = PayPalExtraMetaManager::decryptString($option_value, $paypal_pm);
86
+		}
87
+		return $option_value;
88
+	}
89
+
90
+
91
+	/**
92
+	 * Save payment method option/extra meta
93
+	 *
94
+	 * @param EE_Payment_Method $paypal_pm
95
+	 * @param string            $option_name
96
+	 * @param                   $option_value
97
+	 * @return bool
98
+	 * @throws EE_Error
99
+	 * @throws ReflectionException
100
+	 */
101
+	public static function savePmOption(EE_Payment_Method $paypal_pm, string $option_name, $option_value): bool
102
+	{
103
+		return PayPalExtraMetaManager::extraMeta($paypal_pm)->saveOption($option_name, $option_value);
104
+	}
105
+
106
+
107
+	/**
108
+	 * Save a list of payment method options/extra meta.
109
+	 *
110
+	 * @param EE_Payment_Method $paypal_pm
111
+	 * @param array             $options_list
112
+	 * @return bool
113
+	 * @throws EE_Error
114
+	 * @throws ReflectionException
115
+	 */
116
+	public static function savePmOptions(EE_Payment_Method $paypal_pm, array $options_list): bool
117
+	{
118
+		return PayPalExtraMetaManager::extraMeta($paypal_pm)->saveBatch($options_list);
119
+	}
120
+
121
+
122
+	/**
123
+	 * Delete payment method option/extra meta
124
+	 *
125
+	 * @param EE_Payment_Method $paypal_pm
126
+	 * @param string            $option_name
127
+	 * @return bool
128
+	 * @throws EE_Error
129
+	 * @throws ReflectionException
130
+	 */
131
+	public static function deletePmOption(EE_Payment_Method $paypal_pm, string $option_name): bool
132
+	{
133
+		return PayPalExtraMetaManager::extraMeta($paypal_pm)->deleteOption($option_name);
134
+	}
135
+
136
+
137
+	/**
138
+	 * Get all options for payment method.
139
+	 *
140
+	 * @param EE_Payment_Method $paypal_pm
141
+	 * @return array
142
+	 * @throws EE_Error
143
+	 * @throws ReflectionException
144
+	 */
145
+	public static function getAllData(EE_Payment_Method $paypal_pm): array
146
+	{
147
+		return PayPalExtraMetaManager::extraMeta($paypal_pm)->getMetaData();
148
+	}
149
+
150
+
151
+	/**
152
+	 * Delete payment method metadata.
153
+	 *
154
+	 * @param EE_Payment_Method $paypal_pm
155
+	 * @return bool
156
+	 * @throws EE_Error
157
+	 * @throws ReflectionException
158
+	 */
159
+	public static function deleteData(EE_Payment_Method $paypal_pm): bool
160
+	{
161
+		return PayPalExtraMetaManager::extraMeta($paypal_pm)->deleteMetaData();
162
+	}
163
+
164
+
165
+	/**
166
+	 * Delete all payment method metadata.
167
+	 *
168
+	 * @param EE_Payment_Method $paypal_pm
169
+	 * @return bool
170
+	 * @throws EE_Error
171
+	 * @throws ReflectionException
172
+	 */
173
+	public static function deleteAllData(EE_Payment_Method $paypal_pm): bool
174
+	{
175
+		return PayPalExtraMetaManager::extraMeta($paypal_pm)->deleteAllMetaData();
176
+	}
177
+
178
+	/**
179
+	 * Save the debug mode option if it changed.
180
+	 *
181
+	 * @param EE_Payment_Method $paypal_pm
182
+	 * @param array             $request_data
183
+	 * @return bool             Updated or not.
184
+	 * @throws EE_Error
185
+	 * @throws ReflectionException
186
+	 */
187
+	public static function updateDebugMode(EE_Payment_Method $paypal_pm, array $request_data): bool
188
+	{
189
+		if (
190
+			isset($request_data['sandbox_mode'])
191
+			&& in_array($request_data['sandbox_mode'], ['0', '1'], true)
192
+			&& $paypal_pm->debug_mode() !== (bool) $request_data['sandbox_mode']
193
+		) {
194
+			try {
195
+				$paypal_pm->save(['PMD_debug_mode' => (bool) $request_data['sandbox_mode']]);
196
+			} catch (EE_Error $e) {
197
+				PayPalLogger::errorLog(
198
+					sprintf(
199
+						esc_html__('Note, debug mode not saved ! %1$s', 'event_espresso'),
200
+						$e->getMessage()
201
+					),
202
+					['request_data' => $request_data, 'trace' => $e->getTrace()],
203
+					$paypal_pm
204
+				);
205
+				return false;
206
+			}
207
+			return true;
208
+		}
209
+		return false;
210
+	}
211
+
212
+
213
+	/**
214
+	 * Save partner access token and parameters.
215
+	 *
216
+	 * @param EE_Payment_Method $paypal_pm
217
+	 * @param array             $response
218
+	 * @return bool
219
+	 * @throws EE_Error
220
+	 * @throws ReflectionException
221
+	 */
222
+	public static function savePartnerAccessToken(EE_Payment_Method $paypal_pm, array $response): bool
223
+	{
224
+		$paypal_data         = [];
225
+		$expected_parameters = [
226
+			Domain::META_KEY_ACCESS_TOKEN,
227
+			Domain::META_KEY_TOKEN_EXPIRES_IN,
228
+			Domain::META_KEY_APP_ID,
229
+			Domain::META_KEY_PARTNER_CLIENT_ID,
230
+			Domain::META_KEY_PARTNER_MERCHANT_ID,
231
+			Domain::META_KEY_BN_CODE,
232
+		];
233
+		foreach ($expected_parameters as $api_key) {
234
+			if (! isset($response[ $api_key ])) {
235
+				// Don't want to try saving data that doesn't exist.
236
+				continue;
237
+			}
238
+			try {
239
+				switch ($api_key) {
240
+					case Domain::META_KEY_ACCESS_TOKEN:
241
+					case Domain::META_KEY_PARTNER_MERCHANT_ID:
242
+						$paypal_data[ $api_key ] = PayPalExtraMetaManager::encryptString(
243
+							$response[ $api_key ],
244
+							$paypal_pm
245
+						);
246
+						break;
247
+					case Domain::META_KEY_TOKEN_EXPIRES_IN:
248
+						$paypal_data[ $api_key ] = time() + (int) sanitize_key($response[ $api_key ]);
249
+						break;
250
+					default:
251
+						$paypal_data[ $api_key ] = sanitize_text_field($response[ $api_key ]);
252
+				}
253
+			} catch (Exception $e) {
254
+				PayPalLogger::errorLog(
255
+					$e->getMessage(),
256
+					['response' => $response, 'trace' => $e->getTrace()],
257
+					$paypal_pm
258
+				);
259
+				return false;
260
+			}
261
+		}
262
+		return PayPalExtraMetaManager::savePmOptions($paypal_pm, $paypal_data);
263
+	}
264
+
265
+
266
+	/**
267
+	 * Save merchant/seller API credentials.
268
+	 *
269
+	 * @param EE_Payment_Method $paypal_pm
270
+	 * @param array             $response
271
+	 * @return bool
272
+	 * @throws EE_Error
273
+	 * @throws ReflectionException
274
+	 */
275
+	public static function saveSellerApiCredentials(EE_Payment_Method $paypal_pm, array $response): bool
276
+	{
277
+		$api_credentials     = [];
278
+		$expected_parameters = [Domain::META_KEY_SELLER_MERCHANT_ID];
279
+		foreach ($expected_parameters as $api_key) {
280
+			if (! isset($response[ $api_key ])) {
281
+				// Don't want to try saving data that doesn't exist.
282
+				continue;
283
+			}
284
+			$api_credentials[ $api_key ] = $response[ $api_key ];
285
+		}
286
+		return PayPalExtraMetaManager::savePmOptions($paypal_pm, $api_credentials);
287
+	}
288
+
289
+
290
+	/**
291
+	 * Save other payment method related settings from a data array.
292
+	 *
293
+	 * @param EE_Payment_Method $paypal_pm
294
+	 * @param array             $data
295
+	 * @param array             $get_params
296
+	 * @return bool
297
+	 * @throws EE_Error
298
+	 * @throws ReflectionException
299
+	 */
300
+	public static function parseAndSaveOptions(EE_Payment_Method $paypal_pm, array $data, array $get_params): bool
301
+	{
302
+		$allowed_checkout_type = 'express_checkout';
303
+		// Did the merchant onboard with PPCP enabled or no.
304
+		if (! empty($get_params['selected_payment']) && $get_params['selected_payment'] === 'PPCP') {
305
+			// Make sure that merchant's account really supports advanced card fields (included in the PPCP scope).
306
+			// Has to include "PPCP_CUSTOM" product for ACDC support. "EXPRESS_CHECKOUT" otherwise.
307
+			if (! empty($data['response']['products'][0]['name'])) {
308
+				foreach ($data['response']['products'] as $product) {
309
+					if ($product['name'] === 'PPCP_CUSTOM') {
310
+						// This merchant has PPCP in the products list, so we can enable both (all supported) checkout types.
311
+						$allowed_checkout_type = 'all';
312
+						break;
313
+					}
314
+				}
315
+			}
316
+		}
317
+		// Set the PM option Checkout type, just in case merchant doesn't save PM options manually.
318
+		$checkout_type_setting = $paypal_pm->get_extra_meta(Domain::META_KEY_CHECKOUT_TYPE, true, false);
319
+		if (! $checkout_type_setting || $checkout_type_setting !== $allowed_checkout_type) {
320
+			$paypal_pm->update_extra_meta(Domain::META_KEY_CHECKOUT_TYPE, $allowed_checkout_type);
321
+		}
322
+		// Save the scopes that were authorized.
323
+		if (! empty($data['response']['oauth_integrations'][0]['oauth_third_party'][0]['scopes'])) {
324
+			$scopes = [];
325
+			foreach ($data['response']['oauth_integrations'][0]['oauth_third_party'][0]['scopes'] as $scope) {
326
+				// Scope will look like: 'https://uri.paypal.com/services/payments/partnerfee'
327
+				$split       = explode('/', $scope);
328
+				$split_count = count($split);
329
+				// Get the scope itself.
330
+				$scopes[] = $split[ $split_count - 1 ];
331
+			}
332
+			if (empty($scopes)) {
333
+				// In case the there's a change in how scopes come in just save the list.
334
+				$scopes = $data['response']['oauth_integrations'][0]['oauth_third_party'][0]['scopes'];
335
+			}
336
+			PayPalExtraMetaManager::savePmOption($paypal_pm, Domain::META_KEY_AUTHORIZED_SCOPES, $scopes);
337
+		}
338
+		return PayPalExtraMetaManager::savePmOption(
339
+			$paypal_pm,
340
+			Domain::META_KEY_ALLOWED_CHECKOUT_TYPE,
341
+			$allowed_checkout_type
342
+		);
343
+	}
344
+
345
+
346
+	/**
347
+	 * Encrypt a text field.
348
+	 *
349
+	 * @param string            $text
350
+	 * @param EE_Payment_Method $paypal_pm
351
+	 * @return string|null
352
+	 * @throws Exception
353
+	 */
354
+	public static function encryptString(string $text, EE_Payment_Method $paypal_pm): ?string
355
+	{
356
+		// We sure we are getting something ?
357
+		if (! $text) {
358
+			return $text;
359
+		}
360
+
361
+		try {
362
+			// Do encrypt.
363
+			$sanitized_text = sanitize_text_field($text);
364
+			$key_identifier = $paypal_pm->debug_mode()
365
+				? PPCommerceEncryptionKeyManager::SANDBOX_ENCRYPTION_KEY_ID
366
+				: PPCommerceEncryptionKeyManager::PRODUCTION_ENCRYPTION_KEY_ID;
367
+			$encrypted      = PayPalExtraMetaManager::encryptor()->encrypt($sanitized_text, $key_identifier);
368
+		} catch (Exception $e) {
369
+			PayPalLogger::errorLog(
370
+				$e->getMessage(),
371
+				['trace' => $e->getTrace()],
372
+				$paypal_pm
373
+			);
374
+		}
375
+		return $encrypted ?? null;
376
+	}
377
+
378
+
379
+	/**
380
+	 * Decrypt a string.
381
+	 *
382
+	 * @param string            $text
383
+	 * @param EE_Payment_Method $paypal_pm
384
+	 * @return string
385
+	 */
386
+	public static function decryptString(string $text, EE_Payment_Method $paypal_pm): string
387
+	{
388
+		// Are we even getting something ?
389
+		if (! $text) {
390
+			return $text;
391
+		}
392
+		// Try decrypting.
393
+		try {
394
+			$key_identifier = $paypal_pm->debug_mode()
395
+				? PPCommerceEncryptionKeyManager::SANDBOX_ENCRYPTION_KEY_ID
396
+				: PPCommerceEncryptionKeyManager::PRODUCTION_ENCRYPTION_KEY_ID;
397
+			$decrypted      = PayPalExtraMetaManager::encryptor()->decrypt($text, $key_identifier);
398
+		} catch (Exception $e) {
399
+			PayPalLogger::errorLog(
400
+				$e->getMessage(),
401
+				['trace' => $e->getTrace()],
402
+				$paypal_pm
403
+			);
404
+			return $text;
405
+		}
406
+		return $decrypted ?? $text;
407
+	}
408 408
 }
Please login to merge, or discard this patch.
Spacing   +15 added lines, -15 removed lines patch added patch discarded remove patch
@@ -54,7 +54,7 @@  discard block
 block discarded – undo
54 54
      */
55 55
     public static function encryptor(): OpenSSLEncryption
56 56
     {
57
-        if (! PayPalExtraMetaManager::$encryptor instanceof OpenSSLEncryption) {
57
+        if ( ! PayPalExtraMetaManager::$encryptor instanceof OpenSSLEncryption) {
58 58
             PayPalExtraMetaManager::$encryptor = LoaderFactory::getLoader()->getShared(
59 59
                 OpenSSLEncryption::class,
60 60
                 [new Base64Encoder()]
@@ -231,7 +231,7 @@  discard block
 block discarded – undo
231 231
             Domain::META_KEY_BN_CODE,
232 232
         ];
233 233
         foreach ($expected_parameters as $api_key) {
234
-            if (! isset($response[ $api_key ])) {
234
+            if ( ! isset($response[$api_key])) {
235 235
                 // Don't want to try saving data that doesn't exist.
236 236
                 continue;
237 237
             }
@@ -239,16 +239,16 @@  discard block
 block discarded – undo
239 239
                 switch ($api_key) {
240 240
                     case Domain::META_KEY_ACCESS_TOKEN:
241 241
                     case Domain::META_KEY_PARTNER_MERCHANT_ID:
242
-                        $paypal_data[ $api_key ] = PayPalExtraMetaManager::encryptString(
243
-                            $response[ $api_key ],
242
+                        $paypal_data[$api_key] = PayPalExtraMetaManager::encryptString(
243
+                            $response[$api_key],
244 244
                             $paypal_pm
245 245
                         );
246 246
                         break;
247 247
                     case Domain::META_KEY_TOKEN_EXPIRES_IN:
248
-                        $paypal_data[ $api_key ] = time() + (int) sanitize_key($response[ $api_key ]);
248
+                        $paypal_data[$api_key] = time() + (int) sanitize_key($response[$api_key]);
249 249
                         break;
250 250
                     default:
251
-                        $paypal_data[ $api_key ] = sanitize_text_field($response[ $api_key ]);
251
+                        $paypal_data[$api_key] = sanitize_text_field($response[$api_key]);
252 252
                 }
253 253
             } catch (Exception $e) {
254 254
                 PayPalLogger::errorLog(
@@ -277,11 +277,11 @@  discard block
 block discarded – undo
277 277
         $api_credentials     = [];
278 278
         $expected_parameters = [Domain::META_KEY_SELLER_MERCHANT_ID];
279 279
         foreach ($expected_parameters as $api_key) {
280
-            if (! isset($response[ $api_key ])) {
280
+            if ( ! isset($response[$api_key])) {
281 281
                 // Don't want to try saving data that doesn't exist.
282 282
                 continue;
283 283
             }
284
-            $api_credentials[ $api_key ] = $response[ $api_key ];
284
+            $api_credentials[$api_key] = $response[$api_key];
285 285
         }
286 286
         return PayPalExtraMetaManager::savePmOptions($paypal_pm, $api_credentials);
287 287
     }
@@ -301,10 +301,10 @@  discard block
 block discarded – undo
301 301
     {
302 302
         $allowed_checkout_type = 'express_checkout';
303 303
         // Did the merchant onboard with PPCP enabled or no.
304
-        if (! empty($get_params['selected_payment']) && $get_params['selected_payment'] === 'PPCP') {
304
+        if ( ! empty($get_params['selected_payment']) && $get_params['selected_payment'] === 'PPCP') {
305 305
             // Make sure that merchant's account really supports advanced card fields (included in the PPCP scope).
306 306
             // Has to include "PPCP_CUSTOM" product for ACDC support. "EXPRESS_CHECKOUT" otherwise.
307
-            if (! empty($data['response']['products'][0]['name'])) {
307
+            if ( ! empty($data['response']['products'][0]['name'])) {
308 308
                 foreach ($data['response']['products'] as $product) {
309 309
                     if ($product['name'] === 'PPCP_CUSTOM') {
310 310
                         // This merchant has PPCP in the products list, so we can enable both (all supported) checkout types.
@@ -316,18 +316,18 @@  discard block
 block discarded – undo
316 316
         }
317 317
         // Set the PM option Checkout type, just in case merchant doesn't save PM options manually.
318 318
         $checkout_type_setting = $paypal_pm->get_extra_meta(Domain::META_KEY_CHECKOUT_TYPE, true, false);
319
-        if (! $checkout_type_setting || $checkout_type_setting !== $allowed_checkout_type) {
319
+        if ( ! $checkout_type_setting || $checkout_type_setting !== $allowed_checkout_type) {
320 320
             $paypal_pm->update_extra_meta(Domain::META_KEY_CHECKOUT_TYPE, $allowed_checkout_type);
321 321
         }
322 322
         // Save the scopes that were authorized.
323
-        if (! empty($data['response']['oauth_integrations'][0]['oauth_third_party'][0]['scopes'])) {
323
+        if ( ! empty($data['response']['oauth_integrations'][0]['oauth_third_party'][0]['scopes'])) {
324 324
             $scopes = [];
325 325
             foreach ($data['response']['oauth_integrations'][0]['oauth_third_party'][0]['scopes'] as $scope) {
326 326
                 // Scope will look like: 'https://uri.paypal.com/services/payments/partnerfee'
327 327
                 $split       = explode('/', $scope);
328 328
                 $split_count = count($split);
329 329
                 // Get the scope itself.
330
-                $scopes[] = $split[ $split_count - 1 ];
330
+                $scopes[] = $split[$split_count - 1];
331 331
             }
332 332
             if (empty($scopes)) {
333 333
                 // In case the there's a change in how scopes come in just save the list.
@@ -354,7 +354,7 @@  discard block
 block discarded – undo
354 354
     public static function encryptString(string $text, EE_Payment_Method $paypal_pm): ?string
355 355
     {
356 356
         // We sure we are getting something ?
357
-        if (! $text) {
357
+        if ( ! $text) {
358 358
             return $text;
359 359
         }
360 360
 
@@ -386,7 +386,7 @@  discard block
 block discarded – undo
386 386
     public static function decryptString(string $text, EE_Payment_Method $paypal_pm): string
387 387
     {
388 388
         // Are we even getting something ?
389
-        if (! $text) {
389
+        if ( ! $text) {
390 390
             return $text;
391 391
         }
392 392
         // Try decrypting.
Please login to merge, or discard this patch.
admin_pages/registration_form/Registration_Form_Admin_Page.core.php 2 patches
Indentation   +744 added lines, -744 removed lines patch added patch discarded remove patch
@@ -17,695 +17,695 @@  discard block
 block discarded – undo
17 17
  */
18 18
 class Registration_Form_Admin_Page extends EE_Admin_Page
19 19
 {
20
-    /**
21
-     * holds the specific question object for the question details screen
22
-     */
23
-    protected ?EE_Question $_question = null;
24
-
25
-    /**
26
-     * holds the specific question group object for the question group details screen
27
-     */
28
-    protected ?EE_Question_Group $_question_group = null;
29
-
30
-    protected EEM_Question $_question_model;
31
-
32
-    protected EEM_Question_Group $_question_group_model;
33
-
34
-
35
-    /**
36
-     * @Constructor
37
-     * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
38
-     * @throws EE_Error
39
-     * @throws ReflectionException
40
-     */
41
-    public function __construct($routing = true)
42
-    {
43
-        require_once(EE_MODELS . 'EEM_Question.model.php');
44
-        require_once(EE_MODELS . 'EEM_Question_Group.model.php');
45
-        $this->_question_model       = EEM_Question::instance();
46
-        $this->_question_group_model = EEM_Question_Group::instance();
47
-        parent::__construct($routing);
48
-    }
49
-
50
-
51
-    protected function _init_page_props()
52
-    {
53
-        $this->page_slug        = REGISTRATION_FORM_PG_SLUG;
54
-        $this->page_label       = esc_html__('Registration Form', 'event_espresso');
55
-        $this->_admin_base_url  = REGISTRATION_FORM_ADMIN_URL;
56
-        $this->_admin_base_path = REGISTRATION_FORM_ADMIN;
57
-    }
58
-
59
-
60
-    protected function _ajax_hooks()
61
-    {
62
-    }
63
-
64
-
65
-    protected function _define_page_props()
66
-    {
67
-        $this->_admin_page_title = esc_html__('Registration Form', 'event_espresso');
68
-        $this->_labels           = [
69
-            'buttons'    => [
70
-                'edit_question' => esc_html__('Edit Question', 'event_espresso'),
71
-            ],
72
-            'publishbox' => [
73
-                'edit_question' => esc_html__('Edit Question', 'event_espresso'),
74
-            ],
75
-        ];
76
-    }
77
-
78
-
79
-    /**
80
-     *_set_page_routes
81
-     */
82
-    protected function _set_page_routes()
83
-    {
84
-        $qst_id             =
85
-            ! empty($this->_req_data['QST_ID'])
86
-                ? $this->_req_data['QST_ID']
87
-                : 0;
88
-        $this->_page_routes = [
89
-            'default' => [
90
-                'func'       => [$this, '_questions_overview_list_table'],
91
-                'capability' => 'ee_read_questions',
92
-            ],
93
-
94
-            'edit_question' => [
95
-                'func'       => [$this, '_edit_question'],
96
-                'capability' => 'ee_edit_question',
97
-                'obj_id'     => $qst_id,
98
-                'args'       => ['edit'],
99
-            ],
100
-
101
-            'question_groups' => [
102
-                'func'       => [$this, '_questions_groups_preview'],
103
-                'capability' => 'ee_read_question_groups',
104
-            ],
105
-
106
-            'update_question' => [
107
-                'func'       => [$this, '_insert_or_update_question'],
108
-                'args'       => ['new_question' => false],
109
-                'capability' => 'ee_edit_question',
110
-                'obj_id'     => $qst_id,
111
-                'noheader'   => true,
112
-            ],
113
-        ];
114
-    }
115
-
116
-
117
-    protected function _set_page_config()
118
-    {
119
-        $this->_page_config = [
120
-            'default' => [
121
-                'nav'           => [
122
-                    'label' => esc_html__('Questions', 'event_espresso'),
123
-                    'icon'  => 'dashicons-editor-help',
124
-                    'order' => 10,
125
-                ],
126
-                'list_table'    => 'Registration_Form_Questions_Admin_List_Table',
127
-                'metaboxes'     => $this->_default_espresso_metaboxes,
128
-                'help_tabs'     => [
129
-                    'registration_form_questions_overview_help_tab'                           => [
130
-                        'title'    => esc_html__('Questions Overview', 'event_espresso'),
131
-                        'filename' => 'registration_form_questions_overview',
132
-                    ],
133
-                    'registration_form_questions_overview_table_column_headings_help_tab'     => [
134
-                        'title'    => esc_html__('Questions Overview Table Column Headings', 'event_espresso'),
135
-                        'filename' => 'registration_form_questions_overview_table_column_headings',
136
-                    ],
137
-                    'registration_form_questions_overview_views_bulk_actions_search_help_tab' => [
138
-                        'title'    => esc_html__('Question Overview Views & Bulk Actions & Search', 'event_espresso'),
139
-                        'filename' => 'registration_form_questions_overview_views_bulk_actions_search',
140
-                    ],
141
-                ],
142
-                'require_nonce' => false,
143
-            ],
144
-
145
-            'question_groups' => [
146
-                'nav'           => [
147
-                    'label' => esc_html__('Question Groups', 'event_espresso'),
148
-                    'icon'  => 'dashicons-forms',
149
-                    'order' => 20,
150
-                ],
151
-                'metaboxes'     => $this->_default_espresso_metaboxes,
152
-                'help_tabs'     => [
153
-                    'registration_form_question_groups_help_tab' => [
154
-                        'title'    => esc_html__('Question Groups', 'event_espresso'),
155
-                        'filename' => 'registration_form_question_groups',
156
-                    ],
157
-                ],
158
-                'require_nonce' => false,
159
-            ],
160
-
161
-            'edit_question' => [
162
-                'nav'           => [
163
-                    'label'      => esc_html__('Edit Question', 'event_espresso'),
164
-                    'icon'       => 'dashicons-edit-large',
165
-                    'order'      => 15,
166
-                    'persistent' => false,
167
-                    'url'        => isset($this->_req_data['question_id'])
168
-                        ? add_query_arg(
169
-                            ['question_id' => $this->_req_data['question_id']],
170
-                            $this->_current_page_view_url
171
-                        )
172
-                        : $this->_admin_base_url,
173
-                ],
174
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
175
-                'help_tabs'     => [
176
-                    'registration_form_edit_question_group_help_tab' => [
177
-                        'title'    => esc_html__('Edit Question', 'event_espresso'),
178
-                        'filename' => 'registration_form_edit_question',
179
-                    ],
180
-                ],
181
-                'require_nonce' => false,
182
-            ],
183
-        ];
184
-    }
185
-
186
-
187
-    protected function _add_screen_options()
188
-    {
189
-        // todo
190
-    }
191
-
192
-
193
-    protected function _add_screen_options_default()
194
-    {
195
-        $page_title              = $this->_admin_page_title;
196
-        $this->_admin_page_title = esc_html__('Questions', 'event_espresso');
197
-        $this->_per_page_screen_option();
198
-        $this->_admin_page_title = $page_title;
199
-    }
200
-
201
-
202
-    protected function _add_screen_options_question_groups()
203
-    {
204
-        $page_title              = $this->_admin_page_title;
205
-        $this->_admin_page_title = esc_html__('Question Groups', 'event_espresso');
206
-        $this->_per_page_screen_option();
207
-        $this->_admin_page_title = $page_title;
208
-    }
209
-
210
-
211
-    // none of the below group are currently used for Event Categories
212
-    protected function _add_feature_pointers()
213
-    {
214
-    }
215
-
216
-
217
-    public function load_scripts_styles()
218
-    {
219
-        wp_register_style(
220
-            'espresso_registration',
221
-            REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.css',
222
-            [EspressoLegacyAdminAssetManager::CSS_HANDLE_EE_ADMIN],
223
-            EVENT_ESPRESSO_VERSION
224
-        );
225
-        wp_enqueue_style('espresso_registration');
226
-    }
227
-
228
-
229
-    public function admin_init()
230
-    {
231
-    }
232
-
233
-
234
-    public function admin_notices()
235
-    {
236
-    }
237
-
238
-
239
-    public function admin_footer_scripts()
240
-    {
241
-    }
242
-
243
-
244
-    public function load_scripts_styles_default()
245
-    {
246
-    }
247
-
248
-
249
-    public function load_scripts_styles_add_question()
250
-    {
251
-        $this->load_scripts_styles_question_details();
252
-    }
253
-
254
-
255
-    public function load_scripts_styles_edit_question()
256
-    {
257
-        $this->load_scripts_styles_question_details();
258
-    }
259
-
260
-
261
-    /**
262
-     * Loads the JS required for adding or editing a question
263
-     */
264
-    protected function load_scripts_styles_question_details()
265
-    {
266
-        $this->load_scripts_styles_forms();
267
-        wp_register_script(
268
-            'espresso_registration_form_single',
269
-            REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js',
270
-            ['jquery-ui-sortable'],
271
-            EVENT_ESPRESSO_VERSION,
272
-            true
273
-        );
274
-        wp_enqueue_script('espresso_registration_form_single');
275
-        wp_localize_script(
276
-            'espresso_registration_form_single',
277
-            'ee_question_data',
278
-            [
279
-                'question_types_with_max'    => $this->_question_model->questionTypesWithMaxLength(),
280
-                'question_type_with_options' => $this->_question_model->question_types_with_options(),
281
-            ]
282
-        );
283
-    }
284
-
285
-
286
-    public function recaptcha_info_help_tab()
287
-    {
288
-        EEH_Template::display_template(REGISTRATION_FORM_TEMPLATE_PATH . 'recaptcha_info_help_tab.template.php');
289
-    }
290
-
291
-
292
-    public function load_scripts_styles_forms()
293
-    {
294
-        // styles
295
-        wp_enqueue_style('espresso-ui-theme');
296
-        // scripts
297
-        wp_enqueue_script('ee_admin_js');
298
-    }
299
-
300
-
301
-    protected function _set_list_table_views_default()
302
-    {
303
-        $this->_views = [
304
-            'all' => [
305
-                'slug'  => 'all',
306
-                'label' => esc_html__('View All Questions', 'event_espresso'),
307
-                'count' => 0,
308
-            ],
309
-        ];
310
-
311
-        if (
312
-            $this->capabilities->current_user_can(
313
-                'ee_delete_questions',
314
-                'espresso_registration_form_trash_questions'
315
-            )
316
-        ) {
317
-            $this->_views['trash'] = [
318
-                'slug'  => 'trash',
319
-                'label' => esc_html__('Trash', 'event_espresso'),
320
-                'count' => 0,
321
-            ];
322
-        }
323
-    }
324
-
325
-
326
-    /**
327
-     * This just previews the question groups tab that comes in caffeinated.
328
-     *
329
-     * @return void html
330
-     * @throws EE_Error
331
-     */
332
-    protected function _questions_groups_preview()
333
-    {
334
-        $this->_admin_page_title              = esc_html__('Question Groups (Preview)', 'event_espresso');
335
-        $this->_template_args['preview_img']  =
336
-            '<img src="' . REGISTRATION_FORM_ASSETS_URL . 'caf_reg_form_preview.jpg" alt="'
337
-            . esc_attr__(
338
-                'Preview Question Groups Overview List Table screenshot',
339
-                'event_espresso'
340
-            ) . '" />';
341
-        $this->_template_args['preview_text'] = '<strong>'
342
-            . esc_html__(
343
-                'Question Groups is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. With the Question Groups feature you are able to create new question groups, edit existing question groups, and create and edit new questions and add them to question groups.',
344
-                'event_espresso'
345
-            ) . '</strong>';
346
-        $this->display_admin_caf_preview_page('question_groups_tab');
347
-    }
348
-
349
-
350
-    /**
351
-     * Extracts the question field's values from the POST request to update or insert them
352
-     *
353
-     * @param EEM_Base $model
354
-     * @return array where each key is the name of a model's field/db column, and each value is its value.
355
-     * @throws EE_Error
356
-     * @throws ReflectionException
357
-     */
358
-    protected function _set_column_values_for(EEM_Base $model): array
359
-    {
360
-        $column_values = [];
361
-        // some initial checks for proper values.
362
-        $QST_ID = $this->request->getRequestParam('QST_ID', 0, DataType::INT);
363
-        // if QST_admin_only, then no matter what QST_required is we disable.
364
-        $QST_admin_only = $this->request->getRequestParam('QST_admin_only', false, DataType::BOOL);
365
-        if ($QST_admin_only) {
366
-            $this->request->setRequestParam('QST_required', false);
367
-        }
368
-        // if the question shouldn't have a max length, don't let them set one
369
-        if (
370
-            ! (
371
-                $this->request->requestParamIsSet('QST_type')
372
-                && $this->request->requestParamIsSet('QST_max')
373
-            ) || ! in_array(
374
-                $this->request->getRequestParam('QST_type', '', DataType::STRING),
375
-                $this->_question_model->questionTypesWithMaxLength(),
376
-                true
377
-            )
378
-        ) {
379
-            // they're not allowed to set the max
380
-            $this->request->unSetRequestParam('QST_max', true);
381
-        }
382
-        foreach ($model->field_settings() as $fieldName => $settings) {
383
-            switch($fieldName) {
384
-                case 'QSG_identifier':
385
-                    // basically if QSG_identifier is empty or not set
386
-                    if (! $this->request->getRequestParam('QSG_identifier', '', DataType::STRING)) {
387
-                        $QSG_name                    = $this->request->getRequestParam('QSG_name', '', DataType::STRING);
388
-                        $column_values[ $fieldName ] = sanitize_title($QSG_name) . '-' . uniqid('', true);
389
-                    }
390
-                    break;
391
-
392
-                case 'QST_admin_label':
393
-                    if (! $this->request->getRequestParam('QST_admin_label', '', DataType::STRING)) {
394
-                        // the admin label is blank, use a slug version of the question text
395
-                        $QST_text                    = $this->request->getRequestParam('QST_display_text', '', DataType::STRING);
396
-                        $column_values[ $fieldName ] = sanitize_title(wp_trim_words($QST_text, 10));
397
-                    } else {
398
-                        // admin label set, use it
399
-                        $column_values[ $fieldName ] = $this->request->getRequestParam('QST_admin_label', '', DataType::STRING);
400
-                    }
401
-                    break;
402
-
403
-                case 'QST_admin_only':
404
-                    if (! $QST_admin_only) {
405
-                        $column_values[ $fieldName ] = false;
406
-                    }
407
-                    break;
408
-
409
-                case 'QST_max':
410
-                    $qst_system = $this->_question_model->get_var(
411
-                        [ [ 'QST_ID' => $QST_ID ] ],
412
-                        'QST_system'
413
-                    );
414
-
415
-                    $max_max = $this->_question_model->absolute_max_for_system_question((string) $qst_system);
416
-                    $QST_max = $this->request->getRequestParam('QST_max', 0, DataType::INT);
417
-                    if ($QST_max === 0 || $QST_max > $max_max) {
418
-                        $column_values[ $fieldName ] = $max_max;
419
-                    }
420
-                    break;
421
-
422
-                default:
423
-                    // only add a property to the array if it's not null (otherwise the model should just use the default value)
424
-                    if ($this->request->requestParamIsSet($fieldName)) {
425
-                        // convert the schema type to the appropriate data type
426
-                        $schema_type = DataType::convertModelFieldSchemaType($settings->getSchemaType());
427
-                        $column_values[ $fieldName ] = $this->request->getRequestParam($fieldName, null, $schema_type);
428
-                    }
429
-            }
430
-        }
431
-        // validation for this data to be performed by the model before insertion.
432
-        return $column_values;
433
-    }
434
-
435
-
436
-    /**
437
-     *_questions_overview_list_table
438
-     *
439
-     * @throws EE_Error
440
-     */
441
-    protected function _questions_overview_list_table()
442
-    {
443
-        $this->_search_btn_label = esc_html__('Questions', 'event_espresso');
444
-        $this->display_admin_list_table_page_with_sidebar();
445
-    }
446
-
447
-
448
-    /**
449
-     * _edit_question
450
-     *
451
-     * @throws EE_Error
452
-     * @throws ReflectionException
453
-     */
454
-    protected function _edit_question()
455
-    {
456
-        $ID = isset($this->_req_data['QST_ID']) && ! empty($this->_req_data['QST_ID'])
457
-            ? absint($this->_req_data['QST_ID'])
458
-            : false;
459
-
460
-        switch ($this->_req_action) {
461
-            case 'add_question':
462
-                $this->_admin_page_title = esc_html__('Add Question', 'event_espresso');
463
-                break;
464
-            case 'edit_question':
465
-                $this->_admin_page_title = esc_html__('Edit Question', 'event_espresso');
466
-                break;
467
-            default:
468
-                $this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
469
-        }
470
-
471
-        // add PRC_ID to title if editing
472
-        $this->_admin_page_title =
473
-            $ID
474
-                ? $this->_admin_page_title . ' # ' . $ID
475
-                : $this->_admin_page_title;
476
-        if ($ID) {
477
-            $question                 = $this->_question_model->get_one_by_ID($ID);
478
-            $additional_hidden_fields = ['QST_ID' => ['type' => 'hidden', 'value' => $ID]];
479
-            $this->_set_add_edit_form_tags('update_question', $additional_hidden_fields);
480
-        } else {
481
-            $question = EE_Question::new_instance();
482
-            $question->set_order_to_latest();
483
-            $this->_set_add_edit_form_tags('insert_question');
484
-        }
485
-        if ($question->system_ID() === EEM_Attendee::system_question_phone) {
486
-            $question_types = array_intersect_key(
487
-                $this->_question_model->allowed_question_types(),
488
-                array_flip(
489
-                    [
490
-                        EEM_Question::QST_type_text,
491
-                        EEM_Question::QST_type_us_phone,
492
-                    ]
493
-                )
494
-            );
495
-        } else {
496
-            $question_types = $question->has_answers()
497
-                ? $this->_question_model->question_types_in_same_category($question->type())
498
-                : $this->_question_model->allowed_question_types();
499
-        }
500
-        $this->_template_args['QST_ID']                     = $ID;
501
-        $this->_template_args['question']                   = $question;
502
-        $this->_template_args['question_types']             = $question_types;
503
-        $this->_template_args['max_max']                    =
504
-            $this->_question_model->absolute_max_for_system_question(
505
-                $question->system_ID()
506
-            );
507
-        $this->_template_args['question_type_descriptions'] = $this->_get_question_type_descriptions();
508
-        $this->_set_publish_post_box_vars('id', $ID);
509
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
510
-            REGISTRATION_FORM_TEMPLATE_PATH . 'questions_main_meta_box.template.php',
511
-            $this->_template_args,
512
-            true
513
-        );
514
-
515
-        // the details template wrapper
516
-        $this->display_admin_page_with_sidebar();
517
-    }
518
-
519
-
520
-    /**
521
-     * @return string
522
-     * @throws EE_Error
523
-     * @throws ReflectionException
524
-     */
525
-    protected function _get_question_type_descriptions(): string
526
-    {
527
-        EE_Registry::instance()->load_helper('HTML');
528
-        $descriptions               = '';
529
-        $question_type_descriptions = $this->_question_model->question_descriptions();
530
-        foreach ($question_type_descriptions as $type => $question_type_description) {
531
-            if ($type == 'HTML_TEXTAREA') {
532
-                $html                      = new EE_Simple_HTML_Validation_Strategy();
533
-                $question_type_description .= sprintf(
534
-                    esc_html__('%1$s(allowed tags: %2$s)', 'event_espresso'),
535
-                    '<br/>',
536
-                    $html->get_list_of_allowed_tags()
537
-                );
538
-            }
539
-            $descriptions .= EEH_HTML::p(
540
-                $question_type_description,
541
-                'question_type_description-' . $type,
542
-                'question_type_description description',
543
-                'display:none;'
544
-            );
545
-        }
546
-        return $descriptions;
547
-    }
548
-
549
-
550
-    /**
551
-     * @param bool $new_question
552
-     * @throws EE_Error
553
-     * @throws ReflectionException
554
-     */
555
-    protected function _insert_or_update_question(bool $new_question = true)
556
-    {
557
-        $set_column_values = $this->_set_column_values_for($this->_question_model);
558
-        if ($new_question) {
559
-            $question    = EE_Question::new_instance($set_column_values);
560
-            $action_desc = 'added';
561
-        } else {
562
-            $question = $this->_question_model->get_one_by_ID(
563
-                $this->request->getRequestParam('QST_ID', 0, DataType::INT)
564
-            );
565
-            foreach ($set_column_values as $field => $new_value) {
566
-                $question->set($field, $new_value);
567
-            }
568
-            $action_desc = 'updated';
569
-        }
570
-        $success = $question->save();
571
-        $ID      = $question->ID();
572
-        if ($ID && $question->should_have_question_options()) {
573
-            // save the related options
574
-            // trash removed options, save old ones
575
-            // get list of all options
576
-            $options          = $question->options();
577
-            $question_options = $this->request->getRequestParam('question_options', [], DataType::ARRAY);
578
-            $QSO_default      = $this->request->getRequestParam('QSO_default', null, DataType::INT);
579
-            if (! empty($options)) {
580
-                foreach ($options as $option_ID => $option) {
581
-                    $option_req_index = $this->_get_option_req_data_index($option_ID);
582
-                    if ($option_req_index !== false) {
583
-                        $question_options[ $option_req_index ]['QSO_default'] = $option_req_index === $QSO_default;
584
-                        $option->save($question_options[ $option_req_index ]);
585
-                    } else {
586
-                        // not found, remove it
587
-                        $option->delete();
588
-                    }
589
-                }
590
-            }
591
-            // save new related options
592
-            foreach ($question_options as $index => $option_req_data) {
593
-                // skip $index that is from our sample
594
-                if ($index === 'xxcountxx') {
595
-                    continue;
596
-                }
597
-                // note we allow saving blank options.
598
-                if (empty($option_req_data['QSO_ID'])) {
599
-                    // no ID! save it!
600
-                    $new_option = EE_Question_Option::new_instance(
601
-                        [
602
-                            'QSO_value'   => $option_req_data['QSO_value'],
603
-                            'QSO_desc'    => $option_req_data['QSO_desc'],
604
-                            'QSO_default' => $index === $QSO_default,
605
-                            'QSO_order'   => $option_req_data['QSO_order'],
606
-                            'QST_ID'      => $question->ID(),
607
-                        ]
608
-                    );
609
-                    $new_option->save();
610
-                }
611
-            }
612
-        }
613
-
614
-        $success = apply_filters(
615
-            'FHEE__Registration_Form_Admin_Page___insert_or_update_question__success',
616
-            (int) $success,
617
-            $question,
618
-            $this
619
-        );
620
-
621
-        $query_args = ['action' => 'edit_question', 'QST_ID' => $ID];
622
-        if ($success !== 0) {
623
-            $msg = $new_question
624
-                ? sprintf(
625
-                    esc_html__('The %s has been created', 'event_espresso'),
626
-                    $this->_question_model->item_name()
627
-                )
628
-                : sprintf(
629
-                    esc_html__('The %s has been updated', 'event_espresso'),
630
-                    $this->_question_model->item_name()
631
-                );
632
-            EE_Error::add_success($msg);
633
-        }
634
-
635
-        $this->_redirect_after_action(false, '', $action_desc, $query_args, true);
636
-    }
637
-
638
-
639
-    /**
640
-     * Upon saving a question, there should be an array of 'question_options'. This array is index numerically, but not
641
-     * by ID
642
-     * (this is done because new question options don't have an ID, but we may want to add multiple simultaneously).
643
-     * So, this function gets the index in that request data array called question_options. Returns FALSE if not found.
644
-     *
645
-     * @param int $ID of the question option to find
646
-     * @return int index in question_options array if successful, FALSE if unsuccessful
647
-     */
648
-    protected function _get_option_req_data_index(int $ID)
649
-    {
650
-        $req_data_for_question_options = $this->_req_data['question_options'];
651
-        foreach ($req_data_for_question_options as $num => $option_data) {
652
-            if (array_key_exists('QSO_ID', $option_data) && (int) $option_data['QSO_ID'] === $ID) {
653
-                return $num;
654
-            }
655
-        }
656
-        return false;
657
-    }
658
-
659
-
660
-
661
-
662
-    /* QUERIES */
663
-    /**
664
-     * For internal use in getting all the query parameters
665
-     * (because it's pretty well the same between question, question groups,
666
-     * and for both when searching for trashed and untrashed ones)
667
-     *
668
-     * @param EEM_Base $model either EEM_Question or EEM_Question_Group
669
-     * @param int      $per_page
670
-     * @param int      $current_page
671
-     * @return array model query params,
672
-     * @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
673
-     */
674
-    protected function get_query_params(EEM_Base $model, int $per_page = 10, int $current_page = 10): array
675
-    {
676
-        $query_params             = [];
677
-        $offset                   = ($current_page - 1) * $per_page;
678
-        $query_params['limit']    = [$offset, $per_page];
679
-
680
-        $order  = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
681
-            ? $this->_req_data['order']
682
-            : 'ASC';
683
-
684
-        $orderby_field = $model instanceof EEM_Question ? 'QST_ID' : 'QSG_order';
685
-
686
-        $field_to_order_by = empty($this->_req_data['orderby']) ? $orderby_field : $this->_req_data['orderby'];
687
-
688
-        $query_params['order_by'] = [$field_to_order_by => $order];
689
-
690
-        $search_string = array_key_exists('s', $this->_req_data) ? $this->_req_data['s'] : null;
691
-        if (! empty($search_string)) {
692
-            if ($model instanceof EEM_Question_Group) {
693
-                $query_params[0] = [
694
-                    'OR' => [
695
-                        'QSG_name' => ['LIKE', "%$search_string%"],
696
-                        'QSG_desc' => ['LIKE', "%$search_string%"],
697
-                    ],
698
-                ];
699
-            } else {
700
-                $query_params[0] = [
701
-                    'QST_display_text' => ['LIKE', "%$search_string%"],
702
-                ];
703
-            }
704
-        }
705
-
706
-        // capability checks (just leaving this commented out for reference because
707
-        // it illustrates some complicated query params that could be useful when fully implemented)
708
-        /*if ( $model instanceof EEM_Question_Group ) {
20
+	/**
21
+	 * holds the specific question object for the question details screen
22
+	 */
23
+	protected ?EE_Question $_question = null;
24
+
25
+	/**
26
+	 * holds the specific question group object for the question group details screen
27
+	 */
28
+	protected ?EE_Question_Group $_question_group = null;
29
+
30
+	protected EEM_Question $_question_model;
31
+
32
+	protected EEM_Question_Group $_question_group_model;
33
+
34
+
35
+	/**
36
+	 * @Constructor
37
+	 * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
38
+	 * @throws EE_Error
39
+	 * @throws ReflectionException
40
+	 */
41
+	public function __construct($routing = true)
42
+	{
43
+		require_once(EE_MODELS . 'EEM_Question.model.php');
44
+		require_once(EE_MODELS . 'EEM_Question_Group.model.php');
45
+		$this->_question_model       = EEM_Question::instance();
46
+		$this->_question_group_model = EEM_Question_Group::instance();
47
+		parent::__construct($routing);
48
+	}
49
+
50
+
51
+	protected function _init_page_props()
52
+	{
53
+		$this->page_slug        = REGISTRATION_FORM_PG_SLUG;
54
+		$this->page_label       = esc_html__('Registration Form', 'event_espresso');
55
+		$this->_admin_base_url  = REGISTRATION_FORM_ADMIN_URL;
56
+		$this->_admin_base_path = REGISTRATION_FORM_ADMIN;
57
+	}
58
+
59
+
60
+	protected function _ajax_hooks()
61
+	{
62
+	}
63
+
64
+
65
+	protected function _define_page_props()
66
+	{
67
+		$this->_admin_page_title = esc_html__('Registration Form', 'event_espresso');
68
+		$this->_labels           = [
69
+			'buttons'    => [
70
+				'edit_question' => esc_html__('Edit Question', 'event_espresso'),
71
+			],
72
+			'publishbox' => [
73
+				'edit_question' => esc_html__('Edit Question', 'event_espresso'),
74
+			],
75
+		];
76
+	}
77
+
78
+
79
+	/**
80
+	 *_set_page_routes
81
+	 */
82
+	protected function _set_page_routes()
83
+	{
84
+		$qst_id             =
85
+			! empty($this->_req_data['QST_ID'])
86
+				? $this->_req_data['QST_ID']
87
+				: 0;
88
+		$this->_page_routes = [
89
+			'default' => [
90
+				'func'       => [$this, '_questions_overview_list_table'],
91
+				'capability' => 'ee_read_questions',
92
+			],
93
+
94
+			'edit_question' => [
95
+				'func'       => [$this, '_edit_question'],
96
+				'capability' => 'ee_edit_question',
97
+				'obj_id'     => $qst_id,
98
+				'args'       => ['edit'],
99
+			],
100
+
101
+			'question_groups' => [
102
+				'func'       => [$this, '_questions_groups_preview'],
103
+				'capability' => 'ee_read_question_groups',
104
+			],
105
+
106
+			'update_question' => [
107
+				'func'       => [$this, '_insert_or_update_question'],
108
+				'args'       => ['new_question' => false],
109
+				'capability' => 'ee_edit_question',
110
+				'obj_id'     => $qst_id,
111
+				'noheader'   => true,
112
+			],
113
+		];
114
+	}
115
+
116
+
117
+	protected function _set_page_config()
118
+	{
119
+		$this->_page_config = [
120
+			'default' => [
121
+				'nav'           => [
122
+					'label' => esc_html__('Questions', 'event_espresso'),
123
+					'icon'  => 'dashicons-editor-help',
124
+					'order' => 10,
125
+				],
126
+				'list_table'    => 'Registration_Form_Questions_Admin_List_Table',
127
+				'metaboxes'     => $this->_default_espresso_metaboxes,
128
+				'help_tabs'     => [
129
+					'registration_form_questions_overview_help_tab'                           => [
130
+						'title'    => esc_html__('Questions Overview', 'event_espresso'),
131
+						'filename' => 'registration_form_questions_overview',
132
+					],
133
+					'registration_form_questions_overview_table_column_headings_help_tab'     => [
134
+						'title'    => esc_html__('Questions Overview Table Column Headings', 'event_espresso'),
135
+						'filename' => 'registration_form_questions_overview_table_column_headings',
136
+					],
137
+					'registration_form_questions_overview_views_bulk_actions_search_help_tab' => [
138
+						'title'    => esc_html__('Question Overview Views & Bulk Actions & Search', 'event_espresso'),
139
+						'filename' => 'registration_form_questions_overview_views_bulk_actions_search',
140
+					],
141
+				],
142
+				'require_nonce' => false,
143
+			],
144
+
145
+			'question_groups' => [
146
+				'nav'           => [
147
+					'label' => esc_html__('Question Groups', 'event_espresso'),
148
+					'icon'  => 'dashicons-forms',
149
+					'order' => 20,
150
+				],
151
+				'metaboxes'     => $this->_default_espresso_metaboxes,
152
+				'help_tabs'     => [
153
+					'registration_form_question_groups_help_tab' => [
154
+						'title'    => esc_html__('Question Groups', 'event_espresso'),
155
+						'filename' => 'registration_form_question_groups',
156
+					],
157
+				],
158
+				'require_nonce' => false,
159
+			],
160
+
161
+			'edit_question' => [
162
+				'nav'           => [
163
+					'label'      => esc_html__('Edit Question', 'event_espresso'),
164
+					'icon'       => 'dashicons-edit-large',
165
+					'order'      => 15,
166
+					'persistent' => false,
167
+					'url'        => isset($this->_req_data['question_id'])
168
+						? add_query_arg(
169
+							['question_id' => $this->_req_data['question_id']],
170
+							$this->_current_page_view_url
171
+						)
172
+						: $this->_admin_base_url,
173
+				],
174
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
175
+				'help_tabs'     => [
176
+					'registration_form_edit_question_group_help_tab' => [
177
+						'title'    => esc_html__('Edit Question', 'event_espresso'),
178
+						'filename' => 'registration_form_edit_question',
179
+					],
180
+				],
181
+				'require_nonce' => false,
182
+			],
183
+		];
184
+	}
185
+
186
+
187
+	protected function _add_screen_options()
188
+	{
189
+		// todo
190
+	}
191
+
192
+
193
+	protected function _add_screen_options_default()
194
+	{
195
+		$page_title              = $this->_admin_page_title;
196
+		$this->_admin_page_title = esc_html__('Questions', 'event_espresso');
197
+		$this->_per_page_screen_option();
198
+		$this->_admin_page_title = $page_title;
199
+	}
200
+
201
+
202
+	protected function _add_screen_options_question_groups()
203
+	{
204
+		$page_title              = $this->_admin_page_title;
205
+		$this->_admin_page_title = esc_html__('Question Groups', 'event_espresso');
206
+		$this->_per_page_screen_option();
207
+		$this->_admin_page_title = $page_title;
208
+	}
209
+
210
+
211
+	// none of the below group are currently used for Event Categories
212
+	protected function _add_feature_pointers()
213
+	{
214
+	}
215
+
216
+
217
+	public function load_scripts_styles()
218
+	{
219
+		wp_register_style(
220
+			'espresso_registration',
221
+			REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.css',
222
+			[EspressoLegacyAdminAssetManager::CSS_HANDLE_EE_ADMIN],
223
+			EVENT_ESPRESSO_VERSION
224
+		);
225
+		wp_enqueue_style('espresso_registration');
226
+	}
227
+
228
+
229
+	public function admin_init()
230
+	{
231
+	}
232
+
233
+
234
+	public function admin_notices()
235
+	{
236
+	}
237
+
238
+
239
+	public function admin_footer_scripts()
240
+	{
241
+	}
242
+
243
+
244
+	public function load_scripts_styles_default()
245
+	{
246
+	}
247
+
248
+
249
+	public function load_scripts_styles_add_question()
250
+	{
251
+		$this->load_scripts_styles_question_details();
252
+	}
253
+
254
+
255
+	public function load_scripts_styles_edit_question()
256
+	{
257
+		$this->load_scripts_styles_question_details();
258
+	}
259
+
260
+
261
+	/**
262
+	 * Loads the JS required for adding or editing a question
263
+	 */
264
+	protected function load_scripts_styles_question_details()
265
+	{
266
+		$this->load_scripts_styles_forms();
267
+		wp_register_script(
268
+			'espresso_registration_form_single',
269
+			REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js',
270
+			['jquery-ui-sortable'],
271
+			EVENT_ESPRESSO_VERSION,
272
+			true
273
+		);
274
+		wp_enqueue_script('espresso_registration_form_single');
275
+		wp_localize_script(
276
+			'espresso_registration_form_single',
277
+			'ee_question_data',
278
+			[
279
+				'question_types_with_max'    => $this->_question_model->questionTypesWithMaxLength(),
280
+				'question_type_with_options' => $this->_question_model->question_types_with_options(),
281
+			]
282
+		);
283
+	}
284
+
285
+
286
+	public function recaptcha_info_help_tab()
287
+	{
288
+		EEH_Template::display_template(REGISTRATION_FORM_TEMPLATE_PATH . 'recaptcha_info_help_tab.template.php');
289
+	}
290
+
291
+
292
+	public function load_scripts_styles_forms()
293
+	{
294
+		// styles
295
+		wp_enqueue_style('espresso-ui-theme');
296
+		// scripts
297
+		wp_enqueue_script('ee_admin_js');
298
+	}
299
+
300
+
301
+	protected function _set_list_table_views_default()
302
+	{
303
+		$this->_views = [
304
+			'all' => [
305
+				'slug'  => 'all',
306
+				'label' => esc_html__('View All Questions', 'event_espresso'),
307
+				'count' => 0,
308
+			],
309
+		];
310
+
311
+		if (
312
+			$this->capabilities->current_user_can(
313
+				'ee_delete_questions',
314
+				'espresso_registration_form_trash_questions'
315
+			)
316
+		) {
317
+			$this->_views['trash'] = [
318
+				'slug'  => 'trash',
319
+				'label' => esc_html__('Trash', 'event_espresso'),
320
+				'count' => 0,
321
+			];
322
+		}
323
+	}
324
+
325
+
326
+	/**
327
+	 * This just previews the question groups tab that comes in caffeinated.
328
+	 *
329
+	 * @return void html
330
+	 * @throws EE_Error
331
+	 */
332
+	protected function _questions_groups_preview()
333
+	{
334
+		$this->_admin_page_title              = esc_html__('Question Groups (Preview)', 'event_espresso');
335
+		$this->_template_args['preview_img']  =
336
+			'<img src="' . REGISTRATION_FORM_ASSETS_URL . 'caf_reg_form_preview.jpg" alt="'
337
+			. esc_attr__(
338
+				'Preview Question Groups Overview List Table screenshot',
339
+				'event_espresso'
340
+			) . '" />';
341
+		$this->_template_args['preview_text'] = '<strong>'
342
+			. esc_html__(
343
+				'Question Groups is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. With the Question Groups feature you are able to create new question groups, edit existing question groups, and create and edit new questions and add them to question groups.',
344
+				'event_espresso'
345
+			) . '</strong>';
346
+		$this->display_admin_caf_preview_page('question_groups_tab');
347
+	}
348
+
349
+
350
+	/**
351
+	 * Extracts the question field's values from the POST request to update or insert them
352
+	 *
353
+	 * @param EEM_Base $model
354
+	 * @return array where each key is the name of a model's field/db column, and each value is its value.
355
+	 * @throws EE_Error
356
+	 * @throws ReflectionException
357
+	 */
358
+	protected function _set_column_values_for(EEM_Base $model): array
359
+	{
360
+		$column_values = [];
361
+		// some initial checks for proper values.
362
+		$QST_ID = $this->request->getRequestParam('QST_ID', 0, DataType::INT);
363
+		// if QST_admin_only, then no matter what QST_required is we disable.
364
+		$QST_admin_only = $this->request->getRequestParam('QST_admin_only', false, DataType::BOOL);
365
+		if ($QST_admin_only) {
366
+			$this->request->setRequestParam('QST_required', false);
367
+		}
368
+		// if the question shouldn't have a max length, don't let them set one
369
+		if (
370
+			! (
371
+				$this->request->requestParamIsSet('QST_type')
372
+				&& $this->request->requestParamIsSet('QST_max')
373
+			) || ! in_array(
374
+				$this->request->getRequestParam('QST_type', '', DataType::STRING),
375
+				$this->_question_model->questionTypesWithMaxLength(),
376
+				true
377
+			)
378
+		) {
379
+			// they're not allowed to set the max
380
+			$this->request->unSetRequestParam('QST_max', true);
381
+		}
382
+		foreach ($model->field_settings() as $fieldName => $settings) {
383
+			switch($fieldName) {
384
+				case 'QSG_identifier':
385
+					// basically if QSG_identifier is empty or not set
386
+					if (! $this->request->getRequestParam('QSG_identifier', '', DataType::STRING)) {
387
+						$QSG_name                    = $this->request->getRequestParam('QSG_name', '', DataType::STRING);
388
+						$column_values[ $fieldName ] = sanitize_title($QSG_name) . '-' . uniqid('', true);
389
+					}
390
+					break;
391
+
392
+				case 'QST_admin_label':
393
+					if (! $this->request->getRequestParam('QST_admin_label', '', DataType::STRING)) {
394
+						// the admin label is blank, use a slug version of the question text
395
+						$QST_text                    = $this->request->getRequestParam('QST_display_text', '', DataType::STRING);
396
+						$column_values[ $fieldName ] = sanitize_title(wp_trim_words($QST_text, 10));
397
+					} else {
398
+						// admin label set, use it
399
+						$column_values[ $fieldName ] = $this->request->getRequestParam('QST_admin_label', '', DataType::STRING);
400
+					}
401
+					break;
402
+
403
+				case 'QST_admin_only':
404
+					if (! $QST_admin_only) {
405
+						$column_values[ $fieldName ] = false;
406
+					}
407
+					break;
408
+
409
+				case 'QST_max':
410
+					$qst_system = $this->_question_model->get_var(
411
+						[ [ 'QST_ID' => $QST_ID ] ],
412
+						'QST_system'
413
+					);
414
+
415
+					$max_max = $this->_question_model->absolute_max_for_system_question((string) $qst_system);
416
+					$QST_max = $this->request->getRequestParam('QST_max', 0, DataType::INT);
417
+					if ($QST_max === 0 || $QST_max > $max_max) {
418
+						$column_values[ $fieldName ] = $max_max;
419
+					}
420
+					break;
421
+
422
+				default:
423
+					// only add a property to the array if it's not null (otherwise the model should just use the default value)
424
+					if ($this->request->requestParamIsSet($fieldName)) {
425
+						// convert the schema type to the appropriate data type
426
+						$schema_type = DataType::convertModelFieldSchemaType($settings->getSchemaType());
427
+						$column_values[ $fieldName ] = $this->request->getRequestParam($fieldName, null, $schema_type);
428
+					}
429
+			}
430
+		}
431
+		// validation for this data to be performed by the model before insertion.
432
+		return $column_values;
433
+	}
434
+
435
+
436
+	/**
437
+	 *_questions_overview_list_table
438
+	 *
439
+	 * @throws EE_Error
440
+	 */
441
+	protected function _questions_overview_list_table()
442
+	{
443
+		$this->_search_btn_label = esc_html__('Questions', 'event_espresso');
444
+		$this->display_admin_list_table_page_with_sidebar();
445
+	}
446
+
447
+
448
+	/**
449
+	 * _edit_question
450
+	 *
451
+	 * @throws EE_Error
452
+	 * @throws ReflectionException
453
+	 */
454
+	protected function _edit_question()
455
+	{
456
+		$ID = isset($this->_req_data['QST_ID']) && ! empty($this->_req_data['QST_ID'])
457
+			? absint($this->_req_data['QST_ID'])
458
+			: false;
459
+
460
+		switch ($this->_req_action) {
461
+			case 'add_question':
462
+				$this->_admin_page_title = esc_html__('Add Question', 'event_espresso');
463
+				break;
464
+			case 'edit_question':
465
+				$this->_admin_page_title = esc_html__('Edit Question', 'event_espresso');
466
+				break;
467
+			default:
468
+				$this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
469
+		}
470
+
471
+		// add PRC_ID to title if editing
472
+		$this->_admin_page_title =
473
+			$ID
474
+				? $this->_admin_page_title . ' # ' . $ID
475
+				: $this->_admin_page_title;
476
+		if ($ID) {
477
+			$question                 = $this->_question_model->get_one_by_ID($ID);
478
+			$additional_hidden_fields = ['QST_ID' => ['type' => 'hidden', 'value' => $ID]];
479
+			$this->_set_add_edit_form_tags('update_question', $additional_hidden_fields);
480
+		} else {
481
+			$question = EE_Question::new_instance();
482
+			$question->set_order_to_latest();
483
+			$this->_set_add_edit_form_tags('insert_question');
484
+		}
485
+		if ($question->system_ID() === EEM_Attendee::system_question_phone) {
486
+			$question_types = array_intersect_key(
487
+				$this->_question_model->allowed_question_types(),
488
+				array_flip(
489
+					[
490
+						EEM_Question::QST_type_text,
491
+						EEM_Question::QST_type_us_phone,
492
+					]
493
+				)
494
+			);
495
+		} else {
496
+			$question_types = $question->has_answers()
497
+				? $this->_question_model->question_types_in_same_category($question->type())
498
+				: $this->_question_model->allowed_question_types();
499
+		}
500
+		$this->_template_args['QST_ID']                     = $ID;
501
+		$this->_template_args['question']                   = $question;
502
+		$this->_template_args['question_types']             = $question_types;
503
+		$this->_template_args['max_max']                    =
504
+			$this->_question_model->absolute_max_for_system_question(
505
+				$question->system_ID()
506
+			);
507
+		$this->_template_args['question_type_descriptions'] = $this->_get_question_type_descriptions();
508
+		$this->_set_publish_post_box_vars('id', $ID);
509
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
510
+			REGISTRATION_FORM_TEMPLATE_PATH . 'questions_main_meta_box.template.php',
511
+			$this->_template_args,
512
+			true
513
+		);
514
+
515
+		// the details template wrapper
516
+		$this->display_admin_page_with_sidebar();
517
+	}
518
+
519
+
520
+	/**
521
+	 * @return string
522
+	 * @throws EE_Error
523
+	 * @throws ReflectionException
524
+	 */
525
+	protected function _get_question_type_descriptions(): string
526
+	{
527
+		EE_Registry::instance()->load_helper('HTML');
528
+		$descriptions               = '';
529
+		$question_type_descriptions = $this->_question_model->question_descriptions();
530
+		foreach ($question_type_descriptions as $type => $question_type_description) {
531
+			if ($type == 'HTML_TEXTAREA') {
532
+				$html                      = new EE_Simple_HTML_Validation_Strategy();
533
+				$question_type_description .= sprintf(
534
+					esc_html__('%1$s(allowed tags: %2$s)', 'event_espresso'),
535
+					'<br/>',
536
+					$html->get_list_of_allowed_tags()
537
+				);
538
+			}
539
+			$descriptions .= EEH_HTML::p(
540
+				$question_type_description,
541
+				'question_type_description-' . $type,
542
+				'question_type_description description',
543
+				'display:none;'
544
+			);
545
+		}
546
+		return $descriptions;
547
+	}
548
+
549
+
550
+	/**
551
+	 * @param bool $new_question
552
+	 * @throws EE_Error
553
+	 * @throws ReflectionException
554
+	 */
555
+	protected function _insert_or_update_question(bool $new_question = true)
556
+	{
557
+		$set_column_values = $this->_set_column_values_for($this->_question_model);
558
+		if ($new_question) {
559
+			$question    = EE_Question::new_instance($set_column_values);
560
+			$action_desc = 'added';
561
+		} else {
562
+			$question = $this->_question_model->get_one_by_ID(
563
+				$this->request->getRequestParam('QST_ID', 0, DataType::INT)
564
+			);
565
+			foreach ($set_column_values as $field => $new_value) {
566
+				$question->set($field, $new_value);
567
+			}
568
+			$action_desc = 'updated';
569
+		}
570
+		$success = $question->save();
571
+		$ID      = $question->ID();
572
+		if ($ID && $question->should_have_question_options()) {
573
+			// save the related options
574
+			// trash removed options, save old ones
575
+			// get list of all options
576
+			$options          = $question->options();
577
+			$question_options = $this->request->getRequestParam('question_options', [], DataType::ARRAY);
578
+			$QSO_default      = $this->request->getRequestParam('QSO_default', null, DataType::INT);
579
+			if (! empty($options)) {
580
+				foreach ($options as $option_ID => $option) {
581
+					$option_req_index = $this->_get_option_req_data_index($option_ID);
582
+					if ($option_req_index !== false) {
583
+						$question_options[ $option_req_index ]['QSO_default'] = $option_req_index === $QSO_default;
584
+						$option->save($question_options[ $option_req_index ]);
585
+					} else {
586
+						// not found, remove it
587
+						$option->delete();
588
+					}
589
+				}
590
+			}
591
+			// save new related options
592
+			foreach ($question_options as $index => $option_req_data) {
593
+				// skip $index that is from our sample
594
+				if ($index === 'xxcountxx') {
595
+					continue;
596
+				}
597
+				// note we allow saving blank options.
598
+				if (empty($option_req_data['QSO_ID'])) {
599
+					// no ID! save it!
600
+					$new_option = EE_Question_Option::new_instance(
601
+						[
602
+							'QSO_value'   => $option_req_data['QSO_value'],
603
+							'QSO_desc'    => $option_req_data['QSO_desc'],
604
+							'QSO_default' => $index === $QSO_default,
605
+							'QSO_order'   => $option_req_data['QSO_order'],
606
+							'QST_ID'      => $question->ID(),
607
+						]
608
+					);
609
+					$new_option->save();
610
+				}
611
+			}
612
+		}
613
+
614
+		$success = apply_filters(
615
+			'FHEE__Registration_Form_Admin_Page___insert_or_update_question__success',
616
+			(int) $success,
617
+			$question,
618
+			$this
619
+		);
620
+
621
+		$query_args = ['action' => 'edit_question', 'QST_ID' => $ID];
622
+		if ($success !== 0) {
623
+			$msg = $new_question
624
+				? sprintf(
625
+					esc_html__('The %s has been created', 'event_espresso'),
626
+					$this->_question_model->item_name()
627
+				)
628
+				: sprintf(
629
+					esc_html__('The %s has been updated', 'event_espresso'),
630
+					$this->_question_model->item_name()
631
+				);
632
+			EE_Error::add_success($msg);
633
+		}
634
+
635
+		$this->_redirect_after_action(false, '', $action_desc, $query_args, true);
636
+	}
637
+
638
+
639
+	/**
640
+	 * Upon saving a question, there should be an array of 'question_options'. This array is index numerically, but not
641
+	 * by ID
642
+	 * (this is done because new question options don't have an ID, but we may want to add multiple simultaneously).
643
+	 * So, this function gets the index in that request data array called question_options. Returns FALSE if not found.
644
+	 *
645
+	 * @param int $ID of the question option to find
646
+	 * @return int index in question_options array if successful, FALSE if unsuccessful
647
+	 */
648
+	protected function _get_option_req_data_index(int $ID)
649
+	{
650
+		$req_data_for_question_options = $this->_req_data['question_options'];
651
+		foreach ($req_data_for_question_options as $num => $option_data) {
652
+			if (array_key_exists('QSO_ID', $option_data) && (int) $option_data['QSO_ID'] === $ID) {
653
+				return $num;
654
+			}
655
+		}
656
+		return false;
657
+	}
658
+
659
+
660
+
661
+
662
+	/* QUERIES */
663
+	/**
664
+	 * For internal use in getting all the query parameters
665
+	 * (because it's pretty well the same between question, question groups,
666
+	 * and for both when searching for trashed and untrashed ones)
667
+	 *
668
+	 * @param EEM_Base $model either EEM_Question or EEM_Question_Group
669
+	 * @param int      $per_page
670
+	 * @param int      $current_page
671
+	 * @return array model query params,
672
+	 * @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md
673
+	 */
674
+	protected function get_query_params(EEM_Base $model, int $per_page = 10, int $current_page = 10): array
675
+	{
676
+		$query_params             = [];
677
+		$offset                   = ($current_page - 1) * $per_page;
678
+		$query_params['limit']    = [$offset, $per_page];
679
+
680
+		$order  = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
681
+			? $this->_req_data['order']
682
+			: 'ASC';
683
+
684
+		$orderby_field = $model instanceof EEM_Question ? 'QST_ID' : 'QSG_order';
685
+
686
+		$field_to_order_by = empty($this->_req_data['orderby']) ? $orderby_field : $this->_req_data['orderby'];
687
+
688
+		$query_params['order_by'] = [$field_to_order_by => $order];
689
+
690
+		$search_string = array_key_exists('s', $this->_req_data) ? $this->_req_data['s'] : null;
691
+		if (! empty($search_string)) {
692
+			if ($model instanceof EEM_Question_Group) {
693
+				$query_params[0] = [
694
+					'OR' => [
695
+						'QSG_name' => ['LIKE', "%$search_string%"],
696
+						'QSG_desc' => ['LIKE', "%$search_string%"],
697
+					],
698
+				];
699
+			} else {
700
+				$query_params[0] = [
701
+					'QST_display_text' => ['LIKE', "%$search_string%"],
702
+				];
703
+			}
704
+		}
705
+
706
+		// capability checks (just leaving this commented out for reference because
707
+		// it illustrates some complicated query params that could be useful when fully implemented)
708
+		/*if ( $model instanceof EEM_Question_Group ) {
709 709
             if (
710 710
                 ! $this->capabilities->current_user_can(
711 711
                     'edit_others_question_groups',
@@ -745,59 +745,59 @@  discard block
 block discarded – undo
745 745
             }
746 746
         }/**/
747 747
 
748
-        return $query_params;
749
-    }
750
-
751
-
752
-    /**
753
-     * @param int  $per_page
754
-     * @param int  $current_page
755
-     * @param bool $count
756
-     * @return EE_Question[]|int
757
-     * @throws EE_Error
758
-     * @throws ReflectionException
759
-     */
760
-    public function get_questions(int $per_page = 10, int $current_page = 1, bool $count = false)
761
-    {
762
-        $query_params = $this->get_query_params($this->_question_model, $per_page, $current_page);
763
-        if ($count) {
764
-            $where = isset($query_params[0]) ? [$query_params[0]] : [];
765
-            return $this->_question_model->count($where);
766
-        }
767
-        return $this->_question_model->get_all($query_params);
768
-    }
769
-
770
-
771
-    /**
772
-     * @param int  $per_page
773
-     * @param int  $current_page
774
-     * @param bool $count
775
-     * @return EE_Soft_Delete_Base_Class[]|int
776
-     * @throws EE_Error
777
-     */
778
-    public function get_trashed_questions(int $per_page, int $current_page = 1, bool $count = false)
779
-    {
780
-        $query_params = $this->get_query_params($this->_question_model, $per_page, $current_page);
781
-        $where        = isset($query_params[0]) ? [$query_params[0]] : [];
782
-        return $count
783
-            ? $this->_question_model->count_deleted($where)
784
-            : $this->_question_model->get_all_deleted($query_params);
785
-    }
786
-
787
-
788
-    /**
789
-     * @param int  $per_page
790
-     * @param int  $current_page
791
-     * @param bool $count
792
-     * @return EE_Question_Group[]|int
793
-     * @throws EE_Error
794
-     * @throws ReflectionException
795
-     */
796
-    public function get_question_groups(int $per_page, int $current_page = 1, bool $count = false)
797
-    {
798
-        // note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
799
-        return $this->_question_group_model->get_all(
800
-            $this->get_query_params($this->_question_group_model, $per_page, $current_page)
801
-        );
802
-    }
748
+		return $query_params;
749
+	}
750
+
751
+
752
+	/**
753
+	 * @param int  $per_page
754
+	 * @param int  $current_page
755
+	 * @param bool $count
756
+	 * @return EE_Question[]|int
757
+	 * @throws EE_Error
758
+	 * @throws ReflectionException
759
+	 */
760
+	public function get_questions(int $per_page = 10, int $current_page = 1, bool $count = false)
761
+	{
762
+		$query_params = $this->get_query_params($this->_question_model, $per_page, $current_page);
763
+		if ($count) {
764
+			$where = isset($query_params[0]) ? [$query_params[0]] : [];
765
+			return $this->_question_model->count($where);
766
+		}
767
+		return $this->_question_model->get_all($query_params);
768
+	}
769
+
770
+
771
+	/**
772
+	 * @param int  $per_page
773
+	 * @param int  $current_page
774
+	 * @param bool $count
775
+	 * @return EE_Soft_Delete_Base_Class[]|int
776
+	 * @throws EE_Error
777
+	 */
778
+	public function get_trashed_questions(int $per_page, int $current_page = 1, bool $count = false)
779
+	{
780
+		$query_params = $this->get_query_params($this->_question_model, $per_page, $current_page);
781
+		$where        = isset($query_params[0]) ? [$query_params[0]] : [];
782
+		return $count
783
+			? $this->_question_model->count_deleted($where)
784
+			: $this->_question_model->get_all_deleted($query_params);
785
+	}
786
+
787
+
788
+	/**
789
+	 * @param int  $per_page
790
+	 * @param int  $current_page
791
+	 * @param bool $count
792
+	 * @return EE_Question_Group[]|int
793
+	 * @throws EE_Error
794
+	 * @throws ReflectionException
795
+	 */
796
+	public function get_question_groups(int $per_page, int $current_page = 1, bool $count = false)
797
+	{
798
+		// note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
799
+		return $this->_question_group_model->get_all(
800
+			$this->get_query_params($this->_question_group_model, $per_page, $current_page)
801
+		);
802
+	}
803 803
 }
Please login to merge, or discard this patch.
Spacing   +29 added lines, -29 removed lines patch added patch discarded remove patch
@@ -40,8 +40,8 @@  discard block
 block discarded – undo
40 40
      */
41 41
     public function __construct($routing = true)
42 42
     {
43
-        require_once(EE_MODELS . 'EEM_Question.model.php');
44
-        require_once(EE_MODELS . 'EEM_Question_Group.model.php');
43
+        require_once(EE_MODELS.'EEM_Question.model.php');
44
+        require_once(EE_MODELS.'EEM_Question_Group.model.php');
45 45
         $this->_question_model       = EEM_Question::instance();
46 46
         $this->_question_group_model = EEM_Question_Group::instance();
47 47
         parent::__construct($routing);
@@ -81,7 +81,7 @@  discard block
 block discarded – undo
81 81
      */
82 82
     protected function _set_page_routes()
83 83
     {
84
-        $qst_id             =
84
+        $qst_id =
85 85
             ! empty($this->_req_data['QST_ID'])
86 86
                 ? $this->_req_data['QST_ID']
87 87
                 : 0;
@@ -218,7 +218,7 @@  discard block
 block discarded – undo
218 218
     {
219 219
         wp_register_style(
220 220
             'espresso_registration',
221
-            REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.css',
221
+            REGISTRATION_FORM_ASSETS_URL.'espresso_registration_form_admin.css',
222 222
             [EspressoLegacyAdminAssetManager::CSS_HANDLE_EE_ADMIN],
223 223
             EVENT_ESPRESSO_VERSION
224 224
         );
@@ -266,7 +266,7 @@  discard block
 block discarded – undo
266 266
         $this->load_scripts_styles_forms();
267 267
         wp_register_script(
268 268
             'espresso_registration_form_single',
269
-            REGISTRATION_FORM_ASSETS_URL . 'espresso_registration_form_admin.js',
269
+            REGISTRATION_FORM_ASSETS_URL.'espresso_registration_form_admin.js',
270 270
             ['jquery-ui-sortable'],
271 271
             EVENT_ESPRESSO_VERSION,
272 272
             true
@@ -285,7 +285,7 @@  discard block
 block discarded – undo
285 285
 
286 286
     public function recaptcha_info_help_tab()
287 287
     {
288
-        EEH_Template::display_template(REGISTRATION_FORM_TEMPLATE_PATH . 'recaptcha_info_help_tab.template.php');
288
+        EEH_Template::display_template(REGISTRATION_FORM_TEMPLATE_PATH.'recaptcha_info_help_tab.template.php');
289 289
     }
290 290
 
291 291
 
@@ -333,16 +333,16 @@  discard block
 block discarded – undo
333 333
     {
334 334
         $this->_admin_page_title              = esc_html__('Question Groups (Preview)', 'event_espresso');
335 335
         $this->_template_args['preview_img']  =
336
-            '<img src="' . REGISTRATION_FORM_ASSETS_URL . 'caf_reg_form_preview.jpg" alt="'
336
+            '<img src="'.REGISTRATION_FORM_ASSETS_URL.'caf_reg_form_preview.jpg" alt="'
337 337
             . esc_attr__(
338 338
                 'Preview Question Groups Overview List Table screenshot',
339 339
                 'event_espresso'
340
-            ) . '" />';
340
+            ).'" />';
341 341
         $this->_template_args['preview_text'] = '<strong>'
342 342
             . esc_html__(
343 343
                 'Question Groups is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. With the Question Groups feature you are able to create new question groups, edit existing question groups, and create and edit new questions and add them to question groups.',
344 344
                 'event_espresso'
345
-            ) . '</strong>';
345
+            ).'</strong>';
346 346
         $this->display_admin_caf_preview_page('question_groups_tab');
347 347
     }
348 348
 
@@ -380,42 +380,42 @@  discard block
 block discarded – undo
380 380
             $this->request->unSetRequestParam('QST_max', true);
381 381
         }
382 382
         foreach ($model->field_settings() as $fieldName => $settings) {
383
-            switch($fieldName) {
383
+            switch ($fieldName) {
384 384
                 case 'QSG_identifier':
385 385
                     // basically if QSG_identifier is empty or not set
386
-                    if (! $this->request->getRequestParam('QSG_identifier', '', DataType::STRING)) {
386
+                    if ( ! $this->request->getRequestParam('QSG_identifier', '', DataType::STRING)) {
387 387
                         $QSG_name                    = $this->request->getRequestParam('QSG_name', '', DataType::STRING);
388
-                        $column_values[ $fieldName ] = sanitize_title($QSG_name) . '-' . uniqid('', true);
388
+                        $column_values[$fieldName] = sanitize_title($QSG_name).'-'.uniqid('', true);
389 389
                     }
390 390
                     break;
391 391
 
392 392
                 case 'QST_admin_label':
393
-                    if (! $this->request->getRequestParam('QST_admin_label', '', DataType::STRING)) {
393
+                    if ( ! $this->request->getRequestParam('QST_admin_label', '', DataType::STRING)) {
394 394
                         // the admin label is blank, use a slug version of the question text
395 395
                         $QST_text                    = $this->request->getRequestParam('QST_display_text', '', DataType::STRING);
396
-                        $column_values[ $fieldName ] = sanitize_title(wp_trim_words($QST_text, 10));
396
+                        $column_values[$fieldName] = sanitize_title(wp_trim_words($QST_text, 10));
397 397
                     } else {
398 398
                         // admin label set, use it
399
-                        $column_values[ $fieldName ] = $this->request->getRequestParam('QST_admin_label', '', DataType::STRING);
399
+                        $column_values[$fieldName] = $this->request->getRequestParam('QST_admin_label', '', DataType::STRING);
400 400
                     }
401 401
                     break;
402 402
 
403 403
                 case 'QST_admin_only':
404
-                    if (! $QST_admin_only) {
405
-                        $column_values[ $fieldName ] = false;
404
+                    if ( ! $QST_admin_only) {
405
+                        $column_values[$fieldName] = false;
406 406
                     }
407 407
                     break;
408 408
 
409 409
                 case 'QST_max':
410 410
                     $qst_system = $this->_question_model->get_var(
411
-                        [ [ 'QST_ID' => $QST_ID ] ],
411
+                        [['QST_ID' => $QST_ID]],
412 412
                         'QST_system'
413 413
                     );
414 414
 
415 415
                     $max_max = $this->_question_model->absolute_max_for_system_question((string) $qst_system);
416 416
                     $QST_max = $this->request->getRequestParam('QST_max', 0, DataType::INT);
417 417
                     if ($QST_max === 0 || $QST_max > $max_max) {
418
-                        $column_values[ $fieldName ] = $max_max;
418
+                        $column_values[$fieldName] = $max_max;
419 419
                     }
420 420
                     break;
421 421
 
@@ -424,7 +424,7 @@  discard block
 block discarded – undo
424 424
                     if ($this->request->requestParamIsSet($fieldName)) {
425 425
                         // convert the schema type to the appropriate data type
426 426
                         $schema_type = DataType::convertModelFieldSchemaType($settings->getSchemaType());
427
-                        $column_values[ $fieldName ] = $this->request->getRequestParam($fieldName, null, $schema_type);
427
+                        $column_values[$fieldName] = $this->request->getRequestParam($fieldName, null, $schema_type);
428 428
                     }
429 429
             }
430 430
         }
@@ -471,7 +471,7 @@  discard block
 block discarded – undo
471 471
         // add PRC_ID to title if editing
472 472
         $this->_admin_page_title =
473 473
             $ID
474
-                ? $this->_admin_page_title . ' # ' . $ID
474
+                ? $this->_admin_page_title.' # '.$ID
475 475
                 : $this->_admin_page_title;
476 476
         if ($ID) {
477 477
             $question                 = $this->_question_model->get_one_by_ID($ID);
@@ -507,7 +507,7 @@  discard block
 block discarded – undo
507 507
         $this->_template_args['question_type_descriptions'] = $this->_get_question_type_descriptions();
508 508
         $this->_set_publish_post_box_vars('id', $ID);
509 509
         $this->_template_args['admin_page_content'] = EEH_Template::display_template(
510
-            REGISTRATION_FORM_TEMPLATE_PATH . 'questions_main_meta_box.template.php',
510
+            REGISTRATION_FORM_TEMPLATE_PATH.'questions_main_meta_box.template.php',
511 511
             $this->_template_args,
512 512
             true
513 513
         );
@@ -529,7 +529,7 @@  discard block
 block discarded – undo
529 529
         $question_type_descriptions = $this->_question_model->question_descriptions();
530 530
         foreach ($question_type_descriptions as $type => $question_type_description) {
531 531
             if ($type == 'HTML_TEXTAREA') {
532
-                $html                      = new EE_Simple_HTML_Validation_Strategy();
532
+                $html = new EE_Simple_HTML_Validation_Strategy();
533 533
                 $question_type_description .= sprintf(
534 534
                     esc_html__('%1$s(allowed tags: %2$s)', 'event_espresso'),
535 535
                     '<br/>',
@@ -538,7 +538,7 @@  discard block
 block discarded – undo
538 538
             }
539 539
             $descriptions .= EEH_HTML::p(
540 540
                 $question_type_description,
541
-                'question_type_description-' . $type,
541
+                'question_type_description-'.$type,
542 542
                 'question_type_description description',
543 543
                 'display:none;'
544 544
             );
@@ -576,12 +576,12 @@  discard block
 block discarded – undo
576 576
             $options          = $question->options();
577 577
             $question_options = $this->request->getRequestParam('question_options', [], DataType::ARRAY);
578 578
             $QSO_default      = $this->request->getRequestParam('QSO_default', null, DataType::INT);
579
-            if (! empty($options)) {
579
+            if ( ! empty($options)) {
580 580
                 foreach ($options as $option_ID => $option) {
581 581
                     $option_req_index = $this->_get_option_req_data_index($option_ID);
582 582
                     if ($option_req_index !== false) {
583
-                        $question_options[ $option_req_index ]['QSO_default'] = $option_req_index === $QSO_default;
584
-                        $option->save($question_options[ $option_req_index ]);
583
+                        $question_options[$option_req_index]['QSO_default'] = $option_req_index === $QSO_default;
584
+                        $option->save($question_options[$option_req_index]);
585 585
                     } else {
586 586
                         // not found, remove it
587 587
                         $option->delete();
@@ -677,7 +677,7 @@  discard block
 block discarded – undo
677 677
         $offset                   = ($current_page - 1) * $per_page;
678 678
         $query_params['limit']    = [$offset, $per_page];
679 679
 
680
-        $order  = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
680
+        $order = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
681 681
             ? $this->_req_data['order']
682 682
             : 'ASC';
683 683
 
@@ -688,7 +688,7 @@  discard block
 block discarded – undo
688 688
         $query_params['order_by'] = [$field_to_order_by => $order];
689 689
 
690 690
         $search_string = array_key_exists('s', $this->_req_data) ? $this->_req_data['s'] : null;
691
-        if (! empty($search_string)) {
691
+        if ( ! empty($search_string)) {
692 692
             if ($model instanceof EEM_Question_Group) {
693 693
                 $query_params[0] = [
694 694
                     'OR' => [
Please login to merge, or discard this patch.
core/EE_Error.core.php 2 patches
Indentation   +1138 added lines, -1138 removed lines patch added patch discarded remove patch
@@ -18,245 +18,245 @@  discard block
 block discarded – undo
18 18
  */
19 19
 class EE_Error extends Exception
20 20
 {
21
-    const OPTIONS_KEY_NOTICES = 'ee_notices';
22
-
23
-    /**
24
-     *    stores details for all exception
25
-     *
26
-     * @var array
27
-     */
28
-    private static $_all_exceptions = [];
29
-
30
-    /**
31
-     *    tracks number of errors
32
-     *
33
-     * @var int
34
-     */
35
-    private static $_error_count = 0;
36
-
37
-    /**
38
-     * @var array $_espresso_notices
39
-     */
40
-    private static $_espresso_notices = ['success' => false, 'errors' => false, 'attention' => false];
41
-
42
-
43
-    /**
44
-     * @override default exception handling
45
-     * @param string         $message
46
-     * @param int            $code
47
-     * @param Exception|null $previous
48
-     */
49
-    public function __construct($message, $code = 0, Exception $previous = null)
50
-    {
51
-        if (version_compare(PHP_VERSION, '5.3.0', '<')) {
52
-            parent::__construct($message, $code);
53
-        } else {
54
-            parent::__construct($message, $code, $previous);
55
-        }
56
-    }
57
-
58
-
59
-    /**
60
-     *    error_handler
61
-     *
62
-     * @param int  $code
63
-     * @param string $message
64
-     * @param string $file
65
-     * @param int|string $line
66
-     * @return void
67
-     */
68
-    public static function error_handler(int $code, string $message, string $file, $line)
69
-    {
70
-        $type    = EE_Error::error_type($code);
71
-        $site    = site_url();
72
-        $to      = strpos($site, 'eventespresso.com')
73
-            ? '[email protected]'
74
-            : get_option('admin_email');
75
-        $subject = "$type $message in " . EVENT_ESPRESSO_VERSION . ' on ' . site_url();
76
-        $msg     = EE_Error::_format_error($type, $message, $file, $line);
77
-        if (function_exists('wp_mail')) {
78
-            add_filter('wp_mail_content_type', ['EE_Error', 'set_content_type']);
79
-            wp_mail($to, $subject, $msg);
80
-        }
81
-        echo '<div id="message" class="espresso-notices error"><p>';
82
-        echo wp_kses($type . ': ' . $message . '<br />' . $file . ' line ' . $line, AllowedTags::getWithFormTags());
83
-        echo '<br /></p></div>';
84
-    }
85
-
86
-
87
-    /**
88
-     * error_type
89
-     * http://www.php.net/manual/en/errorfunc.constants.php#109430
90
-     *
91
-     * @param int $code
92
-     * @return string
93
-     */
94
-    public static function error_type(int $code): string
95
-    {
96
-        switch ($code) {
97
-            case E_ERROR: // 1 //
98
-                return 'E_ERROR';
99
-            case E_WARNING: // 2 //
100
-                return 'E_WARNING';
101
-            case E_PARSE: // 4 //
102
-                return 'E_PARSE';
103
-            case E_NOTICE: // 8 //
104
-                return 'E_NOTICE';
105
-            case E_CORE_ERROR: // 16 //
106
-                return 'E_CORE_ERROR';
107
-            case E_CORE_WARNING: // 32 //
108
-                return 'E_CORE_WARNING';
109
-            case E_COMPILE_ERROR: // 64 //
110
-                return 'E_COMPILE_ERROR';
111
-            case E_COMPILE_WARNING: // 128 //
112
-                return 'E_COMPILE_WARNING';
113
-            case E_USER_ERROR: // 256 //
114
-                return 'E_USER_ERROR';
115
-            case E_USER_WARNING: // 512 //
116
-                return 'E_USER_WARNING';
117
-            case E_USER_NOTICE: // 1024 //
118
-                return 'E_USER_NOTICE';
119
-            case E_STRICT: // 2048 //
120
-                return 'E_STRICT';
121
-            case E_RECOVERABLE_ERROR: // 4096 //
122
-                return 'E_RECOVERABLE_ERROR';
123
-            case E_DEPRECATED: // 8192 //
124
-                return 'E_DEPRECATED';
125
-            case E_USER_DEPRECATED: // 16384 //
126
-                return 'E_USER_DEPRECATED';
127
-            case E_ALL: // 16384 //
128
-                return 'E_ALL';
129
-        }
130
-        return '';
131
-    }
132
-
133
-
134
-    /**
135
-     *    fatal_error_handler
136
-     *
137
-     * @return void
138
-     */
139
-    public static function fatal_error_handler()
140
-    {
141
-        $last_error = error_get_last();
142
-        if ($last_error['type'] === E_ERROR) {
143
-            EE_Error::error_handler(E_ERROR, $last_error['message'], $last_error['file'], $last_error['line']);
144
-        }
145
-    }
146
-
147
-
148
-    /**
149
-     * _format_error
150
-     *
151
-     * @param $code
152
-     * @param $message
153
-     * @param $file
154
-     * @param $line
155
-     * @return string
156
-     */
157
-    private static function _format_error($code, $message, $file, $line): string
158
-    {
159
-        $html =
160
-            "<table><thead><th>Item</th><th>Details</th></thead><tbody>";
161
-        $html .= "<tr><td><b>Code</b></td><td>$code</td></tr>";
162
-        $html .= "<tr><td><b>Error</b></td><td>$message</td></tr>";
163
-        $html .= "<tr><td><b>File</b></td><td>$file</td></tr>";
164
-        $html .= "<tr><td><b>Line</b></td><td>$line</td></tr>";
165
-        $html .= '</tbody></table>';
166
-        return $html;
167
-    }
168
-
169
-
170
-    /**
171
-     * set_content_type
172
-     *
173
-     * @param $content_type
174
-     * @return string
175
-     */
176
-    public static function set_content_type($content_type): string
177
-    {
178
-        return 'text/html';
179
-    }
180
-
181
-
182
-    /**
183
-     * @return void
184
-     * @throws EE_Error
185
-     * @throws ReflectionException
186
-     */
187
-    public function get_error()
188
-    {
189
-        if (apply_filters('FHEE__EE_Error__get_error__show_normal_exceptions', false)) {
190
-            throw $this;
191
-        }
192
-        // get separate user and developer messages if they exist
193
-        $msg      = explode('||', $this->getMessage());
194
-        $user_msg = $msg[0];
195
-        $dev_msg  = $msg[1] ?? $msg[0];
196
-        $msg      = WP_DEBUG ? $dev_msg : $user_msg;
197
-        // add details to _all_exceptions array
198
-        $x_time                                     = time();
199
-        self::$_all_exceptions[ $x_time ]['name']   = get_class($this);
200
-        self::$_all_exceptions[ $x_time ]['file']   = $this->getFile();
201
-        self::$_all_exceptions[ $x_time ]['line']   = $this->getLine();
202
-        self::$_all_exceptions[ $x_time ]['msg']    = $msg;
203
-        self::$_all_exceptions[ $x_time ]['code']   = $this->getCode();
204
-        self::$_all_exceptions[ $x_time ]['trace']  = $this->getTrace();
205
-        self::$_all_exceptions[ $x_time ]['string'] = $this->getTraceAsString();
206
-        self::$_error_count++;
207
-        // add_action( 'shutdown', array( $this, 'display_errors' ));
208
-        $this->display_errors();
209
-    }
210
-
211
-
212
-    /**
213
-     * @param bool   $check_stored
214
-     * @param string $type_to_check
215
-     * @return bool
216
-     * @throws InvalidInterfaceException
217
-     * @throws InvalidArgumentException
218
-     * @throws InvalidDataTypeException
219
-     */
220
-    public static function has_error(bool $check_stored = false, string $type_to_check = 'errors'): bool
221
-    {
222
-        $has_error = isset(self::$_espresso_notices[ $type_to_check ])
223
-                     && ! empty(self::$_espresso_notices[ $type_to_check ]);
224
-        if ($check_stored && ! $has_error) {
225
-            $notices = EE_Error::getStoredNotices();
226
-            foreach ($notices as $type => $notice) {
227
-                if ($type === $type_to_check && $notice) {
228
-                    return true;
229
-                }
230
-            }
231
-        }
232
-        return $has_error;
233
-    }
234
-
235
-
236
-    /**
237
-     * @echo string
238
-     * @throws ReflectionException
239
-     */
240
-    public function display_errors()
241
-    {
242
-        $trace_details = '';
243
-        $output = '
21
+	const OPTIONS_KEY_NOTICES = 'ee_notices';
22
+
23
+	/**
24
+	 *    stores details for all exception
25
+	 *
26
+	 * @var array
27
+	 */
28
+	private static $_all_exceptions = [];
29
+
30
+	/**
31
+	 *    tracks number of errors
32
+	 *
33
+	 * @var int
34
+	 */
35
+	private static $_error_count = 0;
36
+
37
+	/**
38
+	 * @var array $_espresso_notices
39
+	 */
40
+	private static $_espresso_notices = ['success' => false, 'errors' => false, 'attention' => false];
41
+
42
+
43
+	/**
44
+	 * @override default exception handling
45
+	 * @param string         $message
46
+	 * @param int            $code
47
+	 * @param Exception|null $previous
48
+	 */
49
+	public function __construct($message, $code = 0, Exception $previous = null)
50
+	{
51
+		if (version_compare(PHP_VERSION, '5.3.0', '<')) {
52
+			parent::__construct($message, $code);
53
+		} else {
54
+			parent::__construct($message, $code, $previous);
55
+		}
56
+	}
57
+
58
+
59
+	/**
60
+	 *    error_handler
61
+	 *
62
+	 * @param int  $code
63
+	 * @param string $message
64
+	 * @param string $file
65
+	 * @param int|string $line
66
+	 * @return void
67
+	 */
68
+	public static function error_handler(int $code, string $message, string $file, $line)
69
+	{
70
+		$type    = EE_Error::error_type($code);
71
+		$site    = site_url();
72
+		$to      = strpos($site, 'eventespresso.com')
73
+			? '[email protected]'
74
+			: get_option('admin_email');
75
+		$subject = "$type $message in " . EVENT_ESPRESSO_VERSION . ' on ' . site_url();
76
+		$msg     = EE_Error::_format_error($type, $message, $file, $line);
77
+		if (function_exists('wp_mail')) {
78
+			add_filter('wp_mail_content_type', ['EE_Error', 'set_content_type']);
79
+			wp_mail($to, $subject, $msg);
80
+		}
81
+		echo '<div id="message" class="espresso-notices error"><p>';
82
+		echo wp_kses($type . ': ' . $message . '<br />' . $file . ' line ' . $line, AllowedTags::getWithFormTags());
83
+		echo '<br /></p></div>';
84
+	}
85
+
86
+
87
+	/**
88
+	 * error_type
89
+	 * http://www.php.net/manual/en/errorfunc.constants.php#109430
90
+	 *
91
+	 * @param int $code
92
+	 * @return string
93
+	 */
94
+	public static function error_type(int $code): string
95
+	{
96
+		switch ($code) {
97
+			case E_ERROR: // 1 //
98
+				return 'E_ERROR';
99
+			case E_WARNING: // 2 //
100
+				return 'E_WARNING';
101
+			case E_PARSE: // 4 //
102
+				return 'E_PARSE';
103
+			case E_NOTICE: // 8 //
104
+				return 'E_NOTICE';
105
+			case E_CORE_ERROR: // 16 //
106
+				return 'E_CORE_ERROR';
107
+			case E_CORE_WARNING: // 32 //
108
+				return 'E_CORE_WARNING';
109
+			case E_COMPILE_ERROR: // 64 //
110
+				return 'E_COMPILE_ERROR';
111
+			case E_COMPILE_WARNING: // 128 //
112
+				return 'E_COMPILE_WARNING';
113
+			case E_USER_ERROR: // 256 //
114
+				return 'E_USER_ERROR';
115
+			case E_USER_WARNING: // 512 //
116
+				return 'E_USER_WARNING';
117
+			case E_USER_NOTICE: // 1024 //
118
+				return 'E_USER_NOTICE';
119
+			case E_STRICT: // 2048 //
120
+				return 'E_STRICT';
121
+			case E_RECOVERABLE_ERROR: // 4096 //
122
+				return 'E_RECOVERABLE_ERROR';
123
+			case E_DEPRECATED: // 8192 //
124
+				return 'E_DEPRECATED';
125
+			case E_USER_DEPRECATED: // 16384 //
126
+				return 'E_USER_DEPRECATED';
127
+			case E_ALL: // 16384 //
128
+				return 'E_ALL';
129
+		}
130
+		return '';
131
+	}
132
+
133
+
134
+	/**
135
+	 *    fatal_error_handler
136
+	 *
137
+	 * @return void
138
+	 */
139
+	public static function fatal_error_handler()
140
+	{
141
+		$last_error = error_get_last();
142
+		if ($last_error['type'] === E_ERROR) {
143
+			EE_Error::error_handler(E_ERROR, $last_error['message'], $last_error['file'], $last_error['line']);
144
+		}
145
+	}
146
+
147
+
148
+	/**
149
+	 * _format_error
150
+	 *
151
+	 * @param $code
152
+	 * @param $message
153
+	 * @param $file
154
+	 * @param $line
155
+	 * @return string
156
+	 */
157
+	private static function _format_error($code, $message, $file, $line): string
158
+	{
159
+		$html =
160
+			"<table><thead><th>Item</th><th>Details</th></thead><tbody>";
161
+		$html .= "<tr><td><b>Code</b></td><td>$code</td></tr>";
162
+		$html .= "<tr><td><b>Error</b></td><td>$message</td></tr>";
163
+		$html .= "<tr><td><b>File</b></td><td>$file</td></tr>";
164
+		$html .= "<tr><td><b>Line</b></td><td>$line</td></tr>";
165
+		$html .= '</tbody></table>';
166
+		return $html;
167
+	}
168
+
169
+
170
+	/**
171
+	 * set_content_type
172
+	 *
173
+	 * @param $content_type
174
+	 * @return string
175
+	 */
176
+	public static function set_content_type($content_type): string
177
+	{
178
+		return 'text/html';
179
+	}
180
+
181
+
182
+	/**
183
+	 * @return void
184
+	 * @throws EE_Error
185
+	 * @throws ReflectionException
186
+	 */
187
+	public function get_error()
188
+	{
189
+		if (apply_filters('FHEE__EE_Error__get_error__show_normal_exceptions', false)) {
190
+			throw $this;
191
+		}
192
+		// get separate user and developer messages if they exist
193
+		$msg      = explode('||', $this->getMessage());
194
+		$user_msg = $msg[0];
195
+		$dev_msg  = $msg[1] ?? $msg[0];
196
+		$msg      = WP_DEBUG ? $dev_msg : $user_msg;
197
+		// add details to _all_exceptions array
198
+		$x_time                                     = time();
199
+		self::$_all_exceptions[ $x_time ]['name']   = get_class($this);
200
+		self::$_all_exceptions[ $x_time ]['file']   = $this->getFile();
201
+		self::$_all_exceptions[ $x_time ]['line']   = $this->getLine();
202
+		self::$_all_exceptions[ $x_time ]['msg']    = $msg;
203
+		self::$_all_exceptions[ $x_time ]['code']   = $this->getCode();
204
+		self::$_all_exceptions[ $x_time ]['trace']  = $this->getTrace();
205
+		self::$_all_exceptions[ $x_time ]['string'] = $this->getTraceAsString();
206
+		self::$_error_count++;
207
+		// add_action( 'shutdown', array( $this, 'display_errors' ));
208
+		$this->display_errors();
209
+	}
210
+
211
+
212
+	/**
213
+	 * @param bool   $check_stored
214
+	 * @param string $type_to_check
215
+	 * @return bool
216
+	 * @throws InvalidInterfaceException
217
+	 * @throws InvalidArgumentException
218
+	 * @throws InvalidDataTypeException
219
+	 */
220
+	public static function has_error(bool $check_stored = false, string $type_to_check = 'errors'): bool
221
+	{
222
+		$has_error = isset(self::$_espresso_notices[ $type_to_check ])
223
+					 && ! empty(self::$_espresso_notices[ $type_to_check ]);
224
+		if ($check_stored && ! $has_error) {
225
+			$notices = EE_Error::getStoredNotices();
226
+			foreach ($notices as $type => $notice) {
227
+				if ($type === $type_to_check && $notice) {
228
+					return true;
229
+				}
230
+			}
231
+		}
232
+		return $has_error;
233
+	}
234
+
235
+
236
+	/**
237
+	 * @echo string
238
+	 * @throws ReflectionException
239
+	 */
240
+	public function display_errors()
241
+	{
242
+		$trace_details = '';
243
+		$output = '
244 244
         <div id="ee-error-message" class="error">';
245
-        if (! WP_DEBUG) {
246
-            $output .= '
245
+		if (! WP_DEBUG) {
246
+			$output .= '
247 247
 	        <p>';
248
-        }
249
-        // cycle thru errors
250
-        foreach (self::$_all_exceptions as $time => $ex) {
251
-            $error_code = '';
252
-            // process trace info
253
-            if (empty($ex['trace'])) {
254
-                $trace_details .= esc_html__(
255
-                    'Sorry, but no trace information was available for this exception.',
256
-                    'event_espresso'
257
-                );
258
-            } else {
259
-                $trace_details .= '
248
+		}
249
+		// cycle thru errors
250
+		foreach (self::$_all_exceptions as $time => $ex) {
251
+			$error_code = '';
252
+			// process trace info
253
+			if (empty($ex['trace'])) {
254
+				$trace_details .= esc_html__(
255
+					'Sorry, but no trace information was available for this exception.',
256
+					'event_espresso'
257
+				);
258
+			} else {
259
+				$trace_details .= '
260 260
 			<div id="ee-trace-details">
261 261
 			<table>
262 262
 				<tr>
@@ -266,43 +266,43 @@  discard block
 block discarded – undo
266 266
 					<th scope="col">Class</th>
267 267
 					<th scope="col">Method( arguments )</th>
268 268
 				</tr>';
269
-                $last_on_stack = count($ex['trace']) - 1;
270
-                // reverse array so that stack is in proper chronological order
271
-                $sorted_trace = array_reverse($ex['trace']);
272
-                foreach ($sorted_trace as $number => $trace) {
273
-                    $file     = $trace['file'] ?? '';
274
-                    $class    = $trace['class'] ?? '';
275
-                    $type     = $trace['type'] ?? '';
276
-                    $function = $trace['function'] ?? '';
277
-                    $args     = isset($trace['args']) ? $this->_convert_args_to_string($trace['args']) : '';
278
-                    $line     = $trace['line'] ?? '';
279
-                    $zebra    = ($number % 2) ? ' odd' : '';
280
-                    if (empty($file) && ! empty($class)) {
281
-                        $a    = new ReflectionClass($class);
282
-                        $file = $a->getFileName();
283
-                        if (empty($line) && ! empty($function)) {
284
-                            try {
285
-                                // if $function is a closure, this throws an exception
286
-                                $b    = new ReflectionMethod($class, $function);
287
-                                $line = $b->getStartLine();
288
-                            } catch (Exception $closure_exception) {
289
-                                $line = 'unknown';
290
-                            }
291
-                        }
292
-                    }
293
-                    if ($number === $last_on_stack) {
294
-                        $file       = $ex['file'] !== '' ? $ex['file'] : $file;
295
-                        $line       = $ex['line'] !== '' ? $ex['line'] : $line;
296
-                        $error_code = self::generate_error_code($file, $trace['function'], $line);
297
-                    }
298
-                    $number_display   = ! empty($number) ? $number : '&nbsp;';
299
-                    $line_display     = ! empty($line) ? $line : '&nbsp;';
300
-                    $file_display     = ! empty($file) ? $file : '&nbsp;';
301
-                    $class_display    = ! empty($class) ? $class : '&nbsp;';
302
-                    $type_display     = ! empty($type) ? $type : '&nbsp;';
303
-                    $function_display = ! empty($function) ? $function : '&nbsp;';
304
-                    $args_display     = ! empty($args) ? '( ' . $args . ' )' : '';
305
-                    $trace_details    .= '
269
+				$last_on_stack = count($ex['trace']) - 1;
270
+				// reverse array so that stack is in proper chronological order
271
+				$sorted_trace = array_reverse($ex['trace']);
272
+				foreach ($sorted_trace as $number => $trace) {
273
+					$file     = $trace['file'] ?? '';
274
+					$class    = $trace['class'] ?? '';
275
+					$type     = $trace['type'] ?? '';
276
+					$function = $trace['function'] ?? '';
277
+					$args     = isset($trace['args']) ? $this->_convert_args_to_string($trace['args']) : '';
278
+					$line     = $trace['line'] ?? '';
279
+					$zebra    = ($number % 2) ? ' odd' : '';
280
+					if (empty($file) && ! empty($class)) {
281
+						$a    = new ReflectionClass($class);
282
+						$file = $a->getFileName();
283
+						if (empty($line) && ! empty($function)) {
284
+							try {
285
+								// if $function is a closure, this throws an exception
286
+								$b    = new ReflectionMethod($class, $function);
287
+								$line = $b->getStartLine();
288
+							} catch (Exception $closure_exception) {
289
+								$line = 'unknown';
290
+							}
291
+						}
292
+					}
293
+					if ($number === $last_on_stack) {
294
+						$file       = $ex['file'] !== '' ? $ex['file'] : $file;
295
+						$line       = $ex['line'] !== '' ? $ex['line'] : $line;
296
+						$error_code = self::generate_error_code($file, $trace['function'], $line);
297
+					}
298
+					$number_display   = ! empty($number) ? $number : '&nbsp;';
299
+					$line_display     = ! empty($line) ? $line : '&nbsp;';
300
+					$file_display     = ! empty($file) ? $file : '&nbsp;';
301
+					$class_display    = ! empty($class) ? $class : '&nbsp;';
302
+					$type_display     = ! empty($type) ? $type : '&nbsp;';
303
+					$function_display = ! empty($function) ? $function : '&nbsp;';
304
+					$args_display     = ! empty($args) ? '( ' . $args . ' )' : '';
305
+					$trace_details    .= '
306 306
 					<tr>
307 307
 						<td class="' . $zebra . '">' . $number_display . '</td>
308 308
 						<td class="' . $zebra . '">' . $line_display . '</td>
@@ -310,649 +310,649 @@  discard block
 block discarded – undo
310 310
 						<td class="' . $zebra . '">' . $class_display . '</td>
311 311
 						<td class="' . $zebra . '">' . $type_display . $function_display . $args_display . '</td>
312 312
 					</tr>';
313
-                }
314
-                $trace_details .= '
313
+				}
314
+				$trace_details .= '
315 315
 			 </table>
316 316
 			</div>';
317
-            }
318
-            $ex['code'] = $ex['code'] ?: $error_code;
319
-            // add generic non-identifying messages for non-privileged users
320
-            if (! WP_DEBUG) {
321
-                $output .= '<span class="ee-error-user-msg-spn">'
322
-                           . trim($ex['msg'])
323
-                           . '</span> &nbsp; <sup>'
324
-                           . $ex['code']
325
-                           . '</sup><br />';
326
-            } else {
327
-                // or helpful developer messages if debugging is on
328
-                $output .= '
317
+			}
318
+			$ex['code'] = $ex['code'] ?: $error_code;
319
+			// add generic non-identifying messages for non-privileged users
320
+			if (! WP_DEBUG) {
321
+				$output .= '<span class="ee-error-user-msg-spn">'
322
+						   . trim($ex['msg'])
323
+						   . '</span> &nbsp; <sup>'
324
+						   . $ex['code']
325
+						   . '</sup><br />';
326
+			} else {
327
+				// or helpful developer messages if debugging is on
328
+				$output .= '
329 329
 		<div class="ee-error-dev-msg-dv">
330 330
 			<p class="ee-error-dev-msg-pg">
331 331
 				<strong class="ee-error-dev-msg-str">An '
332
-                           . $ex['name']
333
-                           . ' exception was thrown!</strong>  &nbsp; <span>code: '
334
-                           . $ex['code']
335
-                           . '</span><br />
332
+						   . $ex['name']
333
+						   . ' exception was thrown!</strong>  &nbsp; <span>code: '
334
+						   . $ex['code']
335
+						   . '</span><br />
336 336
 				<span class="big-text">"'
337
-                           . trim($ex['msg'])
338
-                           . '"</span><br/>
337
+						   . trim($ex['msg'])
338
+						   . '"</span><br/>
339 339
 				<a id="display-ee-error-trace-'
340
-                           . self::$_error_count
341
-                           . $time
342
-                           . '" class="display-ee-error-trace-lnk small-text" rel="ee-error-trace-'
343
-                           . self::$_error_count
344
-                           . $time
345
-                           . '">
340
+						   . self::$_error_count
341
+						   . $time
342
+						   . '" class="display-ee-error-trace-lnk small-text" rel="ee-error-trace-'
343
+						   . self::$_error_count
344
+						   . $time
345
+						   . '">
346 346
 					'
347
-                           . esc_html__('click to view backtrace and class/method details', 'event_espresso')
348
-                           . '
347
+						   . esc_html__('click to view backtrace and class/method details', 'event_espresso')
348
+						   . '
349 349
 				</a><br />
350 350
 				<span class="small-text lt-grey-text">'
351
-                           . $ex['file']
352
-                           . ' &nbsp; ( line no: '
353
-                           . $ex['line']
354
-                           . ' )</span>
351
+						   . $ex['file']
352
+						   . ' &nbsp; ( line no: '
353
+						   . $ex['line']
354
+						   . ' )</span>
355 355
 			</p>
356 356
 			<div id="ee-error-trace-'
357
-                           . self::$_error_count
358
-                           . $time
359
-                           . '-dv" class="ee-error-trace-dv" style="display: none;">
357
+						   . self::$_error_count
358
+						   . $time
359
+						   . '-dv" class="ee-error-trace-dv" style="display: none;">
360 360
 				'
361
-                           . $trace_details;
362
-                if (! empty($class)) {
363
-                    $output .= '
361
+						   . $trace_details;
362
+				if (! empty($class)) {
363
+					$output .= '
364 364
 				<div style="padding:3px; margin:0 0 1em; border:1px solid #666; background:#fff; border-radius:3px;">
365 365
 					<div style="padding:1em 2em; border:1px solid #666; background:#f9f9f9;">
366 366
 						<h3>Class Details</h3>';
367
-                    $a      = new ReflectionClass($class);
368
-                    $output .= '
367
+					$a      = new ReflectionClass($class);
368
+					$output .= '
369 369
 						<pre>' . $a . '</pre>
370 370
 					</div>
371 371
 				</div>';
372
-                }
373
-                $output .= '
372
+				}
373
+				$output .= '
374 374
 			</div>
375 375
 		</div>
376 376
 		<br />';
377
-            }
378
-            $this->write_to_error_log($time, $ex);
379
-        }
380
-        // remove last linebreak
381
-        $output = substr($output, 0, -6);
382
-        if (! WP_DEBUG) {
383
-            $output .= '
377
+			}
378
+			$this->write_to_error_log($time, $ex);
379
+		}
380
+		// remove last linebreak
381
+		$output = substr($output, 0, -6);
382
+		if (! WP_DEBUG) {
383
+			$output .= '
384 384
 	        </p>';
385
-        }
386
-        $output .= '
385
+		}
386
+		$output .= '
387 387
         </div>';
388
-        $output .= self::_print_scripts(true);
389
-        if (defined('DOING_AJAX')) {
390
-            echo wp_json_encode(['error' => $output]);
391
-            exit();
392
-        }
393
-        echo wp_kses($output, AllowedTags::getWithFormTags());
394
-        die();
395
-    }
396
-
397
-
398
-    /**
399
-     *    generate string from exception trace args
400
-     *
401
-     * @param array $arguments
402
-     * @param bool  $array
403
-     * @return string
404
-     */
405
-    private function _convert_args_to_string(array $arguments = [], bool $array = false): string
406
-    {
407
-        $arg_string = '';
408
-        if (! empty($arguments)) {
409
-            $args = [];
410
-            foreach ($arguments as $arg) {
411
-                if (! empty($arg)) {
412
-                    if (is_string($arg)) {
413
-                        $args[] = " '" . $arg . "'";
414
-                    } elseif (is_array($arg)) {
415
-                        $args[] = 'ARRAY(' . $this->_convert_args_to_string($arg, true);
416
-                    } elseif (is_bool($arg)) {
417
-                        $args[] = $arg ? ' TRUE' : ' FALSE';
418
-                    } elseif (is_object($arg)) {
419
-                        $args[] = ' OBJECT ' . get_class($arg);
420
-                    } elseif (is_resource($arg)) {
421
-                        $args[] = get_resource_type($arg);
422
-                    } else {
423
-                        $args[] = $arg;
424
-                    }
425
-                } else {
426
-                    $args[] = ' NULL';
427
-                }
428
-            }
429
-            $arg_string = implode(', ', $args);
430
-        }
431
-        if ($array) {
432
-            $arg_string .= ' )';
433
-        }
434
-        return $arg_string;
435
-    }
436
-
437
-
438
-    /**
439
-     *    add error message
440
-     *
441
-     * @param string $msg         the message to display to users or developers - adding a double pipe || (OR) creates
442
-     *                            separate messages for user || dev
443
-     * @param string $file        the file that the error occurred in - just use __FILE__
444
-     * @param string $func        the function/method that the error occurred in - just use __FUNCTION__
445
-     * @param int|string $line        the line number where the error occurred - just use __LINE__
446
-     * @return        void
447
-     */
448
-    public static function add_error(string $msg, string $file, string $func, $line)
449
-    {
450
-        self::_add_notice('errors', $msg, $file, $func, $line);
451
-        self::$_error_count++;
452
-    }
453
-
454
-
455
-    /**
456
-     * If WP_DEBUG is active, throws an exception. If WP_DEBUG is off, just
457
-     * adds an error
458
-     *
459
-     * @param string $msg
460
-     * @param string $file
461
-     * @param string $func
462
-     * @param int|string $line
463
-     * @throws EE_Error
464
-     */
465
-    public static function throw_exception_if_debugging(
466
-        string $msg = '',
467
-        string $file = '',
468
-        string $func = '',
469
-        $line = ''
470
-    ) {
471
-        if (WP_DEBUG) {
472
-            throw new EE_Error($msg);
473
-        }
474
-        EE_Error::add_error($msg, $file, $func, $line);
475
-    }
476
-
477
-
478
-    /**
479
-     *    add success message
480
-     *
481
-     * @param string $msg         the message to display to users or developers - adding a double pipe || (OR) creates
482
-     *                            separate messages for user || dev
483
-     * @param string $file        the file that the error occurred in - just use __FILE__
484
-     * @param string $func        the function/method that the error occurred in - just use __FUNCTION__
485
-     * @param int|string $line        the line number where the error occurred - just use __LINE__
486
-     * @return void
487
-     */
488
-    public static function add_success(string $msg = '', string $file = '', string $func = '', $line = '')
489
-    {
490
-        self::_add_notice('success', $msg, $file, $func, $line);
491
-    }
492
-
493
-
494
-    /**
495
-     *    add attention message
496
-     *
497
-     * @param string $msg         the message to display to users or developers - adding a double pipe || (OR) creates
498
-     *                            separate messages for user || dev
499
-     * @param string $file        the file that the error occurred in - just use __FILE__
500
-     * @param string $func        the function/method that the error occurred in - just use __FUNCTION__
501
-     * @param int|string $line        the line number where the error occurred - just use __LINE__
502
-     * @return        void
503
-     */
504
-    public static function add_attention(string $msg = '', string $file = '', string $func = '', $line = '')
505
-    {
506
-        self::_add_notice('attention', $msg, $file, $func, $line);
507
-    }
508
-
509
-
510
-    /**
511
-     * @param string $type whether the message is for a success or error notification
512
-     * @param string $msg  the message to display to users or developers
513
-     *                     - adding a double pipe || (OR) creates separate messages for user || dev
514
-     * @param string $file the file that the error occurred in - just use __FILE__
515
-     * @param string $func the function/method that the error occurred in - just use __FUNCTION__
516
-     * @param int|string $line the line number where the error occurred - just use __LINE__
517
-     * @return void
518
-     */
519
-    private static function _add_notice(
520
-        string $type = 'success',
521
-        string $msg = '',
522
-        string $file = '',
523
-        string $func = '',
524
-        $line = ''
525
-    ) {
526
-        if (empty($msg)) {
527
-            EE_Error::doing_it_wrong(
528
-                'EE_Error::add_' . $type . '()',
529
-                sprintf(
530
-                    esc_html__(
531
-                        'Notifications are not much use without a message! Please add a message to the EE_Error::add_%s() call made in %s on line %d',
532
-                        'event_espresso'
533
-                    ),
534
-                    $type,
535
-                    $file,
536
-                    $line
537
-                ),
538
-                EVENT_ESPRESSO_VERSION
539
-            );
540
-        }
541
-        if ($type === 'errors' && (empty($file) || empty($func) || empty($line))) {
542
-            EE_Error::doing_it_wrong(
543
-                'EE_Error::add_error()',
544
-                esc_html__(
545
-                    'You need to provide the file name, function name, and line number that the error occurred on in order to better assist with debugging.',
546
-                    'event_espresso'
547
-                ),
548
-                EVENT_ESPRESSO_VERSION
549
-            );
550
-        }
551
-        // get separate user and developer messages if they exist
552
-        $msg      = explode('||', $msg);
553
-        $user_msg = $msg[0];
554
-        $dev_msg  = $msg[1] ?? $msg[0];
555
-        /**
556
-         * Do an action so other code can be triggered when a notice is created
557
-         *
558
-         * @param string $type     can be 'errors', 'attention', or 'success'
559
-         * @param string $user_msg message displayed to user when WP_DEBUG is off
560
-         * @param string $user_msg message displayed to user when WP_DEBUG is on
561
-         * @param string $file     file where error was generated
562
-         * @param string $func     function where error was generated
563
-         * @param int|string $line     line where error was generated
564
-         */
565
-        do_action('AHEE__EE_Error___add_notice', $type, $user_msg, $dev_msg, $file, $func, $line);
566
-        $msg = WP_DEBUG ? $dev_msg : $user_msg;
567
-        // add notice if message exists
568
-        if (! empty($msg)) {
569
-            // get error code
570
-            $notice_code = EE_Error::generate_error_code($file, $func, $line);
571
-            if (WP_DEBUG && $type === 'errors') {
572
-                $msg .= '<br/><span class="tiny-text">' . $notice_code . '</span>';
573
-            }
574
-
575
-            if (! is_array(self::$_espresso_notices[ $type ]) || ! array_key_exists($type, self::$_espresso_notices)) {
576
-                self::$_espresso_notices[ $type ] = [];
577
-            }
578
-
579
-            // add notice. Index by code if it's not blank
580
-            if ($notice_code) {
581
-                self::$_espresso_notices[ $type ][ $notice_code ] = $msg;
582
-            } else {
583
-                self::$_espresso_notices[ $type ][] = $msg;
584
-            }
585
-            add_action('wp_footer', ['EE_Error', 'enqueue_error_scripts'], 1);
586
-        }
587
-    }
588
-
589
-
590
-    /**
591
-     * in some case it may be necessary to overwrite the existing success messages
592
-     *
593
-     * @return        void
594
-     */
595
-    public static function overwrite_success()
596
-    {
597
-        self::$_espresso_notices['success'] = [];
598
-    }
599
-
600
-
601
-    /**
602
-     * in some case it may be necessary to overwrite the existing attention messages
603
-     *
604
-     * @return void
605
-     */
606
-    public static function overwrite_attention()
607
-    {
608
-        self::$_espresso_notices['attention'] = [];
609
-    }
610
-
611
-
612
-    /**
613
-     * in some case it may be necessary to overwrite the existing error messages
614
-     *
615
-     * @return void
616
-     */
617
-    public static function overwrite_errors()
618
-    {
619
-        self::$_espresso_notices['errors'] = [];
620
-    }
621
-
622
-
623
-    /**
624
-     * @return void
625
-     */
626
-    public static function reset_notices()
627
-    {
628
-        self::$_espresso_notices['success']   = [];
629
-        self::$_espresso_notices['attention'] = [];
630
-        self::$_espresso_notices['errors']    = [];
631
-    }
632
-
633
-
634
-    /**
635
-     * @return int
636
-     */
637
-    public static function has_notices(): int
638
-    {
639
-        $has_notices = 0;
640
-        // check for success messages
641
-        $has_notices = self::$_espresso_notices['success'] && ! empty(self::$_espresso_notices['success'])
642
-            ? 3
643
-            : $has_notices;
644
-        // check for attention messages
645
-        $has_notices = self::$_espresso_notices['attention'] && ! empty(self::$_espresso_notices['attention'])
646
-            ? 2
647
-            : $has_notices;
648
-        // check for error messages
649
-        return self::$_espresso_notices['errors'] && ! empty(self::$_espresso_notices['errors'])
650
-            ? 1
651
-            : $has_notices;
652
-    }
653
-
654
-
655
-    /**
656
-     * This simply returns non formatted error notices as they were sent into the EE_Error object.
657
-     *
658
-     * @return array
659
-     * @since 4.9.0
660
-     */
661
-    public static function get_vanilla_notices(): array
662
-    {
663
-        return [
664
-            'success'   => self::$_espresso_notices['success'] ?? [],
665
-            'attention' => self::$_espresso_notices['attention'] ?? [],
666
-            'errors'    => self::$_espresso_notices['errors'] ?? [],
667
-        ];
668
-    }
669
-
670
-
671
-    /**
672
-     * @return array
673
-     * @throws InvalidArgumentException
674
-     * @throws InvalidDataTypeException
675
-     * @throws InvalidInterfaceException
676
-     */
677
-    public static function getStoredNotices(): array
678
-    {
679
-        if ($user_id = get_current_user_id()) {
680
-            // get notices for logged in user
681
-            $notices = get_user_option(EE_Error::OPTIONS_KEY_NOTICES, $user_id);
682
-            return is_array($notices) ? $notices : [];
683
-        }
684
-        if (EE_Session::isLoadedAndActive()) {
685
-            // get notices for user currently engaged in a session
686
-            $session_data = EE_Session::instance()->get_session_data(EE_Error::OPTIONS_KEY_NOTICES);
687
-            return is_array($session_data) ? $session_data : [];
688
-        }
689
-        // get global notices and hope they apply to the current site visitor
690
-        $notices = get_option(EE_Error::OPTIONS_KEY_NOTICES, []);
691
-        return is_array($notices) ? $notices : [];
692
-    }
693
-
694
-
695
-    /**
696
-     * @param array $notices
697
-     * @return bool
698
-     * @throws InvalidArgumentException
699
-     * @throws InvalidDataTypeException
700
-     * @throws InvalidInterfaceException
701
-     */
702
-    public static function storeNotices(array $notices): bool
703
-    {
704
-        if ($user_id = get_current_user_id()) {
705
-            // store notices for logged in user
706
-            return (bool) update_user_option(
707
-                $user_id,
708
-                EE_Error::OPTIONS_KEY_NOTICES,
709
-                $notices
710
-            );
711
-        }
712
-        if (EE_Session::isLoadedAndActive()) {
713
-            // store notices for user currently engaged in a session
714
-            return EE_Session::instance()->set_session_data(
715
-                [EE_Error::OPTIONS_KEY_NOTICES => $notices]
716
-            );
717
-        }
718
-        // store global notices and hope they apply to the same site visitor on the next request
719
-        return update_option(EE_Error::OPTIONS_KEY_NOTICES, $notices);
720
-    }
721
-
722
-
723
-    /**
724
-     * @return bool
725
-     * @throws InvalidArgumentException
726
-     * @throws InvalidDataTypeException
727
-     * @throws InvalidInterfaceException
728
-     */
729
-    public static function clearNotices(): bool
730
-    {
731
-        if ($user_id = get_current_user_id()) {
732
-            // clear notices for logged in user
733
-            return (bool) update_user_option(
734
-                $user_id,
735
-                EE_Error::OPTIONS_KEY_NOTICES,
736
-                []
737
-            );
738
-        }
739
-        if (EE_Session::isLoadedAndActive()) {
740
-            // clear notices for user currently engaged in a session
741
-            return EE_Session::instance()->reset_data([EE_Error::OPTIONS_KEY_NOTICES]);
742
-        }
743
-        // clear global notices and hope none belonged to some for some other site visitor
744
-        return update_option(EE_Error::OPTIONS_KEY_NOTICES, []);
745
-    }
746
-
747
-
748
-    /**
749
-     * saves notices to the db for retrieval on next request
750
-     *
751
-     * @return void
752
-     * @throws InvalidArgumentException
753
-     * @throws InvalidDataTypeException
754
-     * @throws InvalidInterfaceException
755
-     */
756
-    public static function stashNoticesBeforeRedirect()
757
-    {
758
-        EE_Error::get_notices(false, true);
759
-    }
760
-
761
-
762
-    /**
763
-     * compile all error or success messages into one string
764
-     *
765
-     * @param boolean $format_output        whether to format the messages for display in the WP admin
766
-     * @param boolean $save_to_transient    whether to save notices to the db for retrieval on next request
767
-     *                                          - ONLY do this just before redirecting
768
-     * @param bool $remove_empty             whether to unset empty messages
769
-     * @param bool $add_preface              whether to add notice before messages like "An error has occurred:"
770
-     * @return array|string
771
-     * @throws InvalidArgumentException
772
-     * @throws InvalidDataTypeException
773
-     * @throws InvalidInterfaceException
774
-     * @see EE_Error::get_raw_notices if you want the raw notices without any preparations made to them
775
-     */
776
-    public static function get_notices(
777
-        bool $format_output = true,
778
-        bool $save_to_transient = false,
779
-        bool $remove_empty = true,
780
-        bool $add_preface = true
781
-    ) {
782
-        $success_messages   = '';
783
-        $attention_messages = '';
784
-        $error_messages     = '';
785
-        /** @var RequestInterface $request */
786
-        $request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
787
-        // either save notices to the db
788
-        if ($save_to_transient || $request->requestParamIsSet('activate-selected')) {
789
-            self::$_espresso_notices = array_merge(
790
-                EE_Error::getStoredNotices(),
791
-                self::$_espresso_notices
792
-            );
793
-            EE_Error::storeNotices(self::$_espresso_notices);
794
-            return [];
795
-        }
796
-        $print_scripts = EE_Error::combineExistingAndNewNotices();
797
-        // check for success messages
798
-        if (! empty(self::$_espresso_notices['success'])) {
799
-            // combine messages
800
-            $success_messages .= implode('<br />', self::$_espresso_notices['success']);
801
-            $print_scripts    = true;
802
-        }
803
-        // check for attention messages
804
-        if (! empty(self::$_espresso_notices['attention'])) {
805
-            // combine messages
806
-            $attention_messages .= implode('<br />', self::$_espresso_notices['attention']);
807
-            $print_scripts      = true;
808
-        }
809
-        // check for error messages
810
-        if (! empty(self::$_espresso_notices['errors'])) {
811
-            if ($add_preface) {
812
-                $error_messages .= count(self::$_espresso_notices['errors']) > 1
813
-                    ? esc_html__('The following errors have occurred:', 'event_espresso')
814
-                    : esc_html__('An error has occurred:', 'event_espresso');
815
-            }
816
-            // combine messages
817
-            $error_messages .= '<br />' . implode('<br />', self::$_espresso_notices['errors']);
818
-            $print_scripts  = true;
819
-        }
820
-        if ($format_output) {
821
-            $notices = EE_Error::formatNoticesOutput(
822
-                $success_messages,
823
-                $attention_messages,
824
-                $error_messages
825
-            );
826
-        } else {
827
-            $notices = [
828
-                'success'   => $success_messages,
829
-                'attention' => $attention_messages,
830
-                'errors'    => $error_messages,
831
-            ];
832
-            if ($remove_empty) {
833
-                // remove empty notices
834
-                foreach ($notices as $type => $notice) {
835
-                    if (empty($notice)) {
836
-                        unset($notices[ $type ]);
837
-                    }
838
-                }
839
-            }
840
-        }
841
-        if ($print_scripts) {
842
-            self::_print_scripts();
843
-        }
844
-        return $notices;
845
-    }
846
-
847
-
848
-    /**
849
-     * @return bool
850
-     * @throws InvalidArgumentException
851
-     * @throws InvalidDataTypeException
852
-     * @throws InvalidInterfaceException
853
-     */
854
-    private static function combineExistingAndNewNotices(): bool
855
-    {
856
-        $print_scripts = false;
857
-        // grab any notices that have been previously saved
858
-        $notices = EE_Error::getStoredNotices();
859
-        if (! empty($notices)) {
860
-            foreach ($notices as $type => $notice) {
861
-                if (is_array($notice) && ! empty($notice)) {
862
-                    // make sure that existing notice type is an array
863
-                    self::$_espresso_notices[ $type ] = is_array(self::$_espresso_notices[ $type ])
864
-                                                        && ! empty(self::$_espresso_notices[ $type ])
865
-                        ? self::$_espresso_notices[ $type ]
866
-                        : [];
867
-                    // add newly created notices to existing ones
868
-                    self::$_espresso_notices[ $type ] += $notice;
869
-                    $print_scripts                    = true;
870
-                }
871
-            }
872
-            // now clear any stored notices
873
-            EE_Error::clearNotices();
874
-        }
875
-        return $print_scripts;
876
-    }
877
-
878
-
879
-    /**
880
-     * @param string $success_messages
881
-     * @param string $attention_messages
882
-     * @param string $error_messages
883
-     * @return string
884
-     */
885
-    private static function formatNoticesOutput(
886
-        string $success_messages,
887
-        string $attention_messages,
888
-        string $error_messages
889
-    ): string {
890
-        $notices = '<div id="espresso-notices">';
891
-        $close   = is_admin()
892
-            ? ''
893
-            : '<a class="close-espresso-notice hide-if-no-js"><span class="dashicons dashicons-no"/></a>';
894
-        if ($success_messages !== '') {
895
-            $css_id    = is_admin() ? 'ee-success-message' : 'espresso-notices-success';
896
-            $css_class = is_admin() ? 'updated fade ee-status-outline ee-status-bg--success' : 'success fade-away';
897
-            // showMessage( $success_messages );
898
-            $notices .= '<div id="' . $css_id . '" '
899
-                        . 'class="espresso-notices ' . $css_class . '" '
900
-                        . 'style="display:none;">'
901
-                        . '<p>' . $success_messages . '</p>'
902
-                        . $close
903
-                        . '</div>';
904
-        }
905
-        if ($attention_messages !== '') {
906
-            $css_id    = is_admin()  ? 'ee-attention-message' : 'espresso-notices-attention';
907
-            $css_class = is_admin()
908
-                ? 'notice notice-info ee-notices-attention ee-status-outline ee-status-bg--attention'
909
-                : 'attention fade-away';
910
-            // showMessage( $error_messages, TRUE );
911
-            $notices .= '<div id="' . $css_id . '" '
912
-                        . 'class="espresso-notices ' . $css_class . '" '
913
-                        . 'style="display:none;">'
914
-                        . '<p>' . $attention_messages . '</p>'
915
-                        . $close
916
-                        . '</div>';
917
-        }
918
-        if ($error_messages !== '') {
919
-            $css_id    = is_admin() ? 'ee-error-message' : 'espresso-notices-error';
920
-            $css_class = is_admin()
921
-                ? 'error ee-status-outline ee-status-bg--error'
922
-                : 'error fade-away';
923
-            // showMessage( $error_messages, TRUE );
924
-            $notices .= '<div id="' . $css_id . '" '
925
-                        . 'class="espresso-notices ' . $css_class . '" '
926
-                        . 'style="display:none;">'
927
-                        . '<p>' . $error_messages . '</p>'
928
-                        . $close
929
-                        . '</div>';
930
-        }
931
-        $notices .= '</div>';
932
-        return $notices;
933
-    }
934
-
935
-
936
-    /**
937
-     * _print_scripts
938
-     *
939
-     * @param bool $force_print
940
-     * @return    string
941
-     */
942
-    private static function _print_scripts(bool $force_print = false): string
943
-    {
944
-        if (! $force_print && (did_action('admin_enqueue_scripts') || did_action('wp_enqueue_scripts'))) {
945
-            if (wp_script_is('ee_error_js', 'registered')) {
946
-                wp_enqueue_style('espresso_default');
947
-                wp_enqueue_style('espresso_custom_css');
948
-                wp_enqueue_script('ee_error_js');
949
-            }
950
-            if (wp_script_is('ee_error_js')) {
951
-                wp_localize_script('ee_error_js', 'ee_settings', ['wp_debug' => WP_DEBUG]);
952
-                return '';
953
-            }
954
-        } else {
955
-            return '
388
+		$output .= self::_print_scripts(true);
389
+		if (defined('DOING_AJAX')) {
390
+			echo wp_json_encode(['error' => $output]);
391
+			exit();
392
+		}
393
+		echo wp_kses($output, AllowedTags::getWithFormTags());
394
+		die();
395
+	}
396
+
397
+
398
+	/**
399
+	 *    generate string from exception trace args
400
+	 *
401
+	 * @param array $arguments
402
+	 * @param bool  $array
403
+	 * @return string
404
+	 */
405
+	private function _convert_args_to_string(array $arguments = [], bool $array = false): string
406
+	{
407
+		$arg_string = '';
408
+		if (! empty($arguments)) {
409
+			$args = [];
410
+			foreach ($arguments as $arg) {
411
+				if (! empty($arg)) {
412
+					if (is_string($arg)) {
413
+						$args[] = " '" . $arg . "'";
414
+					} elseif (is_array($arg)) {
415
+						$args[] = 'ARRAY(' . $this->_convert_args_to_string($arg, true);
416
+					} elseif (is_bool($arg)) {
417
+						$args[] = $arg ? ' TRUE' : ' FALSE';
418
+					} elseif (is_object($arg)) {
419
+						$args[] = ' OBJECT ' . get_class($arg);
420
+					} elseif (is_resource($arg)) {
421
+						$args[] = get_resource_type($arg);
422
+					} else {
423
+						$args[] = $arg;
424
+					}
425
+				} else {
426
+					$args[] = ' NULL';
427
+				}
428
+			}
429
+			$arg_string = implode(', ', $args);
430
+		}
431
+		if ($array) {
432
+			$arg_string .= ' )';
433
+		}
434
+		return $arg_string;
435
+	}
436
+
437
+
438
+	/**
439
+	 *    add error message
440
+	 *
441
+	 * @param string $msg         the message to display to users or developers - adding a double pipe || (OR) creates
442
+	 *                            separate messages for user || dev
443
+	 * @param string $file        the file that the error occurred in - just use __FILE__
444
+	 * @param string $func        the function/method that the error occurred in - just use __FUNCTION__
445
+	 * @param int|string $line        the line number where the error occurred - just use __LINE__
446
+	 * @return        void
447
+	 */
448
+	public static function add_error(string $msg, string $file, string $func, $line)
449
+	{
450
+		self::_add_notice('errors', $msg, $file, $func, $line);
451
+		self::$_error_count++;
452
+	}
453
+
454
+
455
+	/**
456
+	 * If WP_DEBUG is active, throws an exception. If WP_DEBUG is off, just
457
+	 * adds an error
458
+	 *
459
+	 * @param string $msg
460
+	 * @param string $file
461
+	 * @param string $func
462
+	 * @param int|string $line
463
+	 * @throws EE_Error
464
+	 */
465
+	public static function throw_exception_if_debugging(
466
+		string $msg = '',
467
+		string $file = '',
468
+		string $func = '',
469
+		$line = ''
470
+	) {
471
+		if (WP_DEBUG) {
472
+			throw new EE_Error($msg);
473
+		}
474
+		EE_Error::add_error($msg, $file, $func, $line);
475
+	}
476
+
477
+
478
+	/**
479
+	 *    add success message
480
+	 *
481
+	 * @param string $msg         the message to display to users or developers - adding a double pipe || (OR) creates
482
+	 *                            separate messages for user || dev
483
+	 * @param string $file        the file that the error occurred in - just use __FILE__
484
+	 * @param string $func        the function/method that the error occurred in - just use __FUNCTION__
485
+	 * @param int|string $line        the line number where the error occurred - just use __LINE__
486
+	 * @return void
487
+	 */
488
+	public static function add_success(string $msg = '', string $file = '', string $func = '', $line = '')
489
+	{
490
+		self::_add_notice('success', $msg, $file, $func, $line);
491
+	}
492
+
493
+
494
+	/**
495
+	 *    add attention message
496
+	 *
497
+	 * @param string $msg         the message to display to users or developers - adding a double pipe || (OR) creates
498
+	 *                            separate messages for user || dev
499
+	 * @param string $file        the file that the error occurred in - just use __FILE__
500
+	 * @param string $func        the function/method that the error occurred in - just use __FUNCTION__
501
+	 * @param int|string $line        the line number where the error occurred - just use __LINE__
502
+	 * @return        void
503
+	 */
504
+	public static function add_attention(string $msg = '', string $file = '', string $func = '', $line = '')
505
+	{
506
+		self::_add_notice('attention', $msg, $file, $func, $line);
507
+	}
508
+
509
+
510
+	/**
511
+	 * @param string $type whether the message is for a success or error notification
512
+	 * @param string $msg  the message to display to users or developers
513
+	 *                     - adding a double pipe || (OR) creates separate messages for user || dev
514
+	 * @param string $file the file that the error occurred in - just use __FILE__
515
+	 * @param string $func the function/method that the error occurred in - just use __FUNCTION__
516
+	 * @param int|string $line the line number where the error occurred - just use __LINE__
517
+	 * @return void
518
+	 */
519
+	private static function _add_notice(
520
+		string $type = 'success',
521
+		string $msg = '',
522
+		string $file = '',
523
+		string $func = '',
524
+		$line = ''
525
+	) {
526
+		if (empty($msg)) {
527
+			EE_Error::doing_it_wrong(
528
+				'EE_Error::add_' . $type . '()',
529
+				sprintf(
530
+					esc_html__(
531
+						'Notifications are not much use without a message! Please add a message to the EE_Error::add_%s() call made in %s on line %d',
532
+						'event_espresso'
533
+					),
534
+					$type,
535
+					$file,
536
+					$line
537
+				),
538
+				EVENT_ESPRESSO_VERSION
539
+			);
540
+		}
541
+		if ($type === 'errors' && (empty($file) || empty($func) || empty($line))) {
542
+			EE_Error::doing_it_wrong(
543
+				'EE_Error::add_error()',
544
+				esc_html__(
545
+					'You need to provide the file name, function name, and line number that the error occurred on in order to better assist with debugging.',
546
+					'event_espresso'
547
+				),
548
+				EVENT_ESPRESSO_VERSION
549
+			);
550
+		}
551
+		// get separate user and developer messages if they exist
552
+		$msg      = explode('||', $msg);
553
+		$user_msg = $msg[0];
554
+		$dev_msg  = $msg[1] ?? $msg[0];
555
+		/**
556
+		 * Do an action so other code can be triggered when a notice is created
557
+		 *
558
+		 * @param string $type     can be 'errors', 'attention', or 'success'
559
+		 * @param string $user_msg message displayed to user when WP_DEBUG is off
560
+		 * @param string $user_msg message displayed to user when WP_DEBUG is on
561
+		 * @param string $file     file where error was generated
562
+		 * @param string $func     function where error was generated
563
+		 * @param int|string $line     line where error was generated
564
+		 */
565
+		do_action('AHEE__EE_Error___add_notice', $type, $user_msg, $dev_msg, $file, $func, $line);
566
+		$msg = WP_DEBUG ? $dev_msg : $user_msg;
567
+		// add notice if message exists
568
+		if (! empty($msg)) {
569
+			// get error code
570
+			$notice_code = EE_Error::generate_error_code($file, $func, $line);
571
+			if (WP_DEBUG && $type === 'errors') {
572
+				$msg .= '<br/><span class="tiny-text">' . $notice_code . '</span>';
573
+			}
574
+
575
+			if (! is_array(self::$_espresso_notices[ $type ]) || ! array_key_exists($type, self::$_espresso_notices)) {
576
+				self::$_espresso_notices[ $type ] = [];
577
+			}
578
+
579
+			// add notice. Index by code if it's not blank
580
+			if ($notice_code) {
581
+				self::$_espresso_notices[ $type ][ $notice_code ] = $msg;
582
+			} else {
583
+				self::$_espresso_notices[ $type ][] = $msg;
584
+			}
585
+			add_action('wp_footer', ['EE_Error', 'enqueue_error_scripts'], 1);
586
+		}
587
+	}
588
+
589
+
590
+	/**
591
+	 * in some case it may be necessary to overwrite the existing success messages
592
+	 *
593
+	 * @return        void
594
+	 */
595
+	public static function overwrite_success()
596
+	{
597
+		self::$_espresso_notices['success'] = [];
598
+	}
599
+
600
+
601
+	/**
602
+	 * in some case it may be necessary to overwrite the existing attention messages
603
+	 *
604
+	 * @return void
605
+	 */
606
+	public static function overwrite_attention()
607
+	{
608
+		self::$_espresso_notices['attention'] = [];
609
+	}
610
+
611
+
612
+	/**
613
+	 * in some case it may be necessary to overwrite the existing error messages
614
+	 *
615
+	 * @return void
616
+	 */
617
+	public static function overwrite_errors()
618
+	{
619
+		self::$_espresso_notices['errors'] = [];
620
+	}
621
+
622
+
623
+	/**
624
+	 * @return void
625
+	 */
626
+	public static function reset_notices()
627
+	{
628
+		self::$_espresso_notices['success']   = [];
629
+		self::$_espresso_notices['attention'] = [];
630
+		self::$_espresso_notices['errors']    = [];
631
+	}
632
+
633
+
634
+	/**
635
+	 * @return int
636
+	 */
637
+	public static function has_notices(): int
638
+	{
639
+		$has_notices = 0;
640
+		// check for success messages
641
+		$has_notices = self::$_espresso_notices['success'] && ! empty(self::$_espresso_notices['success'])
642
+			? 3
643
+			: $has_notices;
644
+		// check for attention messages
645
+		$has_notices = self::$_espresso_notices['attention'] && ! empty(self::$_espresso_notices['attention'])
646
+			? 2
647
+			: $has_notices;
648
+		// check for error messages
649
+		return self::$_espresso_notices['errors'] && ! empty(self::$_espresso_notices['errors'])
650
+			? 1
651
+			: $has_notices;
652
+	}
653
+
654
+
655
+	/**
656
+	 * This simply returns non formatted error notices as they were sent into the EE_Error object.
657
+	 *
658
+	 * @return array
659
+	 * @since 4.9.0
660
+	 */
661
+	public static function get_vanilla_notices(): array
662
+	{
663
+		return [
664
+			'success'   => self::$_espresso_notices['success'] ?? [],
665
+			'attention' => self::$_espresso_notices['attention'] ?? [],
666
+			'errors'    => self::$_espresso_notices['errors'] ?? [],
667
+		];
668
+	}
669
+
670
+
671
+	/**
672
+	 * @return array
673
+	 * @throws InvalidArgumentException
674
+	 * @throws InvalidDataTypeException
675
+	 * @throws InvalidInterfaceException
676
+	 */
677
+	public static function getStoredNotices(): array
678
+	{
679
+		if ($user_id = get_current_user_id()) {
680
+			// get notices for logged in user
681
+			$notices = get_user_option(EE_Error::OPTIONS_KEY_NOTICES, $user_id);
682
+			return is_array($notices) ? $notices : [];
683
+		}
684
+		if (EE_Session::isLoadedAndActive()) {
685
+			// get notices for user currently engaged in a session
686
+			$session_data = EE_Session::instance()->get_session_data(EE_Error::OPTIONS_KEY_NOTICES);
687
+			return is_array($session_data) ? $session_data : [];
688
+		}
689
+		// get global notices and hope they apply to the current site visitor
690
+		$notices = get_option(EE_Error::OPTIONS_KEY_NOTICES, []);
691
+		return is_array($notices) ? $notices : [];
692
+	}
693
+
694
+
695
+	/**
696
+	 * @param array $notices
697
+	 * @return bool
698
+	 * @throws InvalidArgumentException
699
+	 * @throws InvalidDataTypeException
700
+	 * @throws InvalidInterfaceException
701
+	 */
702
+	public static function storeNotices(array $notices): bool
703
+	{
704
+		if ($user_id = get_current_user_id()) {
705
+			// store notices for logged in user
706
+			return (bool) update_user_option(
707
+				$user_id,
708
+				EE_Error::OPTIONS_KEY_NOTICES,
709
+				$notices
710
+			);
711
+		}
712
+		if (EE_Session::isLoadedAndActive()) {
713
+			// store notices for user currently engaged in a session
714
+			return EE_Session::instance()->set_session_data(
715
+				[EE_Error::OPTIONS_KEY_NOTICES => $notices]
716
+			);
717
+		}
718
+		// store global notices and hope they apply to the same site visitor on the next request
719
+		return update_option(EE_Error::OPTIONS_KEY_NOTICES, $notices);
720
+	}
721
+
722
+
723
+	/**
724
+	 * @return bool
725
+	 * @throws InvalidArgumentException
726
+	 * @throws InvalidDataTypeException
727
+	 * @throws InvalidInterfaceException
728
+	 */
729
+	public static function clearNotices(): bool
730
+	{
731
+		if ($user_id = get_current_user_id()) {
732
+			// clear notices for logged in user
733
+			return (bool) update_user_option(
734
+				$user_id,
735
+				EE_Error::OPTIONS_KEY_NOTICES,
736
+				[]
737
+			);
738
+		}
739
+		if (EE_Session::isLoadedAndActive()) {
740
+			// clear notices for user currently engaged in a session
741
+			return EE_Session::instance()->reset_data([EE_Error::OPTIONS_KEY_NOTICES]);
742
+		}
743
+		// clear global notices and hope none belonged to some for some other site visitor
744
+		return update_option(EE_Error::OPTIONS_KEY_NOTICES, []);
745
+	}
746
+
747
+
748
+	/**
749
+	 * saves notices to the db for retrieval on next request
750
+	 *
751
+	 * @return void
752
+	 * @throws InvalidArgumentException
753
+	 * @throws InvalidDataTypeException
754
+	 * @throws InvalidInterfaceException
755
+	 */
756
+	public static function stashNoticesBeforeRedirect()
757
+	{
758
+		EE_Error::get_notices(false, true);
759
+	}
760
+
761
+
762
+	/**
763
+	 * compile all error or success messages into one string
764
+	 *
765
+	 * @param boolean $format_output        whether to format the messages for display in the WP admin
766
+	 * @param boolean $save_to_transient    whether to save notices to the db for retrieval on next request
767
+	 *                                          - ONLY do this just before redirecting
768
+	 * @param bool $remove_empty             whether to unset empty messages
769
+	 * @param bool $add_preface              whether to add notice before messages like "An error has occurred:"
770
+	 * @return array|string
771
+	 * @throws InvalidArgumentException
772
+	 * @throws InvalidDataTypeException
773
+	 * @throws InvalidInterfaceException
774
+	 * @see EE_Error::get_raw_notices if you want the raw notices without any preparations made to them
775
+	 */
776
+	public static function get_notices(
777
+		bool $format_output = true,
778
+		bool $save_to_transient = false,
779
+		bool $remove_empty = true,
780
+		bool $add_preface = true
781
+	) {
782
+		$success_messages   = '';
783
+		$attention_messages = '';
784
+		$error_messages     = '';
785
+		/** @var RequestInterface $request */
786
+		$request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
787
+		// either save notices to the db
788
+		if ($save_to_transient || $request->requestParamIsSet('activate-selected')) {
789
+			self::$_espresso_notices = array_merge(
790
+				EE_Error::getStoredNotices(),
791
+				self::$_espresso_notices
792
+			);
793
+			EE_Error::storeNotices(self::$_espresso_notices);
794
+			return [];
795
+		}
796
+		$print_scripts = EE_Error::combineExistingAndNewNotices();
797
+		// check for success messages
798
+		if (! empty(self::$_espresso_notices['success'])) {
799
+			// combine messages
800
+			$success_messages .= implode('<br />', self::$_espresso_notices['success']);
801
+			$print_scripts    = true;
802
+		}
803
+		// check for attention messages
804
+		if (! empty(self::$_espresso_notices['attention'])) {
805
+			// combine messages
806
+			$attention_messages .= implode('<br />', self::$_espresso_notices['attention']);
807
+			$print_scripts      = true;
808
+		}
809
+		// check for error messages
810
+		if (! empty(self::$_espresso_notices['errors'])) {
811
+			if ($add_preface) {
812
+				$error_messages .= count(self::$_espresso_notices['errors']) > 1
813
+					? esc_html__('The following errors have occurred:', 'event_espresso')
814
+					: esc_html__('An error has occurred:', 'event_espresso');
815
+			}
816
+			// combine messages
817
+			$error_messages .= '<br />' . implode('<br />', self::$_espresso_notices['errors']);
818
+			$print_scripts  = true;
819
+		}
820
+		if ($format_output) {
821
+			$notices = EE_Error::formatNoticesOutput(
822
+				$success_messages,
823
+				$attention_messages,
824
+				$error_messages
825
+			);
826
+		} else {
827
+			$notices = [
828
+				'success'   => $success_messages,
829
+				'attention' => $attention_messages,
830
+				'errors'    => $error_messages,
831
+			];
832
+			if ($remove_empty) {
833
+				// remove empty notices
834
+				foreach ($notices as $type => $notice) {
835
+					if (empty($notice)) {
836
+						unset($notices[ $type ]);
837
+					}
838
+				}
839
+			}
840
+		}
841
+		if ($print_scripts) {
842
+			self::_print_scripts();
843
+		}
844
+		return $notices;
845
+	}
846
+
847
+
848
+	/**
849
+	 * @return bool
850
+	 * @throws InvalidArgumentException
851
+	 * @throws InvalidDataTypeException
852
+	 * @throws InvalidInterfaceException
853
+	 */
854
+	private static function combineExistingAndNewNotices(): bool
855
+	{
856
+		$print_scripts = false;
857
+		// grab any notices that have been previously saved
858
+		$notices = EE_Error::getStoredNotices();
859
+		if (! empty($notices)) {
860
+			foreach ($notices as $type => $notice) {
861
+				if (is_array($notice) && ! empty($notice)) {
862
+					// make sure that existing notice type is an array
863
+					self::$_espresso_notices[ $type ] = is_array(self::$_espresso_notices[ $type ])
864
+														&& ! empty(self::$_espresso_notices[ $type ])
865
+						? self::$_espresso_notices[ $type ]
866
+						: [];
867
+					// add newly created notices to existing ones
868
+					self::$_espresso_notices[ $type ] += $notice;
869
+					$print_scripts                    = true;
870
+				}
871
+			}
872
+			// now clear any stored notices
873
+			EE_Error::clearNotices();
874
+		}
875
+		return $print_scripts;
876
+	}
877
+
878
+
879
+	/**
880
+	 * @param string $success_messages
881
+	 * @param string $attention_messages
882
+	 * @param string $error_messages
883
+	 * @return string
884
+	 */
885
+	private static function formatNoticesOutput(
886
+		string $success_messages,
887
+		string $attention_messages,
888
+		string $error_messages
889
+	): string {
890
+		$notices = '<div id="espresso-notices">';
891
+		$close   = is_admin()
892
+			? ''
893
+			: '<a class="close-espresso-notice hide-if-no-js"><span class="dashicons dashicons-no"/></a>';
894
+		if ($success_messages !== '') {
895
+			$css_id    = is_admin() ? 'ee-success-message' : 'espresso-notices-success';
896
+			$css_class = is_admin() ? 'updated fade ee-status-outline ee-status-bg--success' : 'success fade-away';
897
+			// showMessage( $success_messages );
898
+			$notices .= '<div id="' . $css_id . '" '
899
+						. 'class="espresso-notices ' . $css_class . '" '
900
+						. 'style="display:none;">'
901
+						. '<p>' . $success_messages . '</p>'
902
+						. $close
903
+						. '</div>';
904
+		}
905
+		if ($attention_messages !== '') {
906
+			$css_id    = is_admin()  ? 'ee-attention-message' : 'espresso-notices-attention';
907
+			$css_class = is_admin()
908
+				? 'notice notice-info ee-notices-attention ee-status-outline ee-status-bg--attention'
909
+				: 'attention fade-away';
910
+			// showMessage( $error_messages, TRUE );
911
+			$notices .= '<div id="' . $css_id . '" '
912
+						. 'class="espresso-notices ' . $css_class . '" '
913
+						. 'style="display:none;">'
914
+						. '<p>' . $attention_messages . '</p>'
915
+						. $close
916
+						. '</div>';
917
+		}
918
+		if ($error_messages !== '') {
919
+			$css_id    = is_admin() ? 'ee-error-message' : 'espresso-notices-error';
920
+			$css_class = is_admin()
921
+				? 'error ee-status-outline ee-status-bg--error'
922
+				: 'error fade-away';
923
+			// showMessage( $error_messages, TRUE );
924
+			$notices .= '<div id="' . $css_id . '" '
925
+						. 'class="espresso-notices ' . $css_class . '" '
926
+						. 'style="display:none;">'
927
+						. '<p>' . $error_messages . '</p>'
928
+						. $close
929
+						. '</div>';
930
+		}
931
+		$notices .= '</div>';
932
+		return $notices;
933
+	}
934
+
935
+
936
+	/**
937
+	 * _print_scripts
938
+	 *
939
+	 * @param bool $force_print
940
+	 * @return    string
941
+	 */
942
+	private static function _print_scripts(bool $force_print = false): string
943
+	{
944
+		if (! $force_print && (did_action('admin_enqueue_scripts') || did_action('wp_enqueue_scripts'))) {
945
+			if (wp_script_is('ee_error_js', 'registered')) {
946
+				wp_enqueue_style('espresso_default');
947
+				wp_enqueue_style('espresso_custom_css');
948
+				wp_enqueue_script('ee_error_js');
949
+			}
950
+			if (wp_script_is('ee_error_js')) {
951
+				wp_localize_script('ee_error_js', 'ee_settings', ['wp_debug' => WP_DEBUG]);
952
+				return '';
953
+			}
954
+		} else {
955
+			return '
956 956
 <script>
957 957
 /* <![CDATA[ */
958 958
 const ee_settings = {"wp_debug":"' . WP_DEBUG . '"};
@@ -962,233 +962,233 @@  discard block
 block discarded – undo
962 962
 <script src="' . EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js' . '?ver=' . espresso_version() . '" type="text/javascript"></script>
963 963
 <script src="' . EE_GLOBAL_ASSETS_URL . 'scripts/EE_Error.js' . '?ver=' . espresso_version() . '" type="text/javascript"></script>
964 964
 ';
965
-        }
966
-        return '';
967
-    }
968
-
969
-
970
-    /**
971
-     * @return void
972
-     */
973
-    public static function enqueue_error_scripts()
974
-    {
975
-        self::_print_scripts();
976
-    }
977
-
978
-
979
-    /**
980
-     * create error code from filepath, function name,
981
-     * and line number where exception or error was thrown
982
-     *
983
-     * @param string $file
984
-     * @param string $func
985
-     * @param int|string $line
986
-     * @return string
987
-     */
988
-    public static function generate_error_code(string $file = '', string $func = '', $line = ''): string
989
-    {
990
-        $file       = explode('.', basename($file));
991
-        $error_code = ! empty($file[0]) ? $file[0] : '';
992
-        $error_code .= ! empty($func) ? ' - ' . $func : '';
993
-        $error_code .= ! empty($line) ? ' - ' . $line : '';
994
-        return $error_code;
995
-    }
996
-
997
-
998
-    /**
999
-     * write exception details to log file
1000
-     * Since 4.9.53.rc.006 this writes to the standard PHP log file, not EE's custom log file
1001
-     *
1002
-     * @param int   $time
1003
-     * @param array $ex
1004
-     * @param bool  $clear
1005
-     * @return void
1006
-     */
1007
-    public function write_to_error_log(int $time = 0, array $ex = [], bool $clear = false)
1008
-    {
1009
-        if (empty($ex)) {
1010
-            return;
1011
-        }
1012
-        if (! $time) {
1013
-            $time = time();
1014
-        }
1015
-        $exception_log = '----------------------------------------------------------------------------------------'
1016
-                         . PHP_EOL;
1017
-        $exception_log .= '[' . date('Y-m-d H:i:s', $time) . ']  Exception Details' . PHP_EOL;
1018
-        $exception_log .= 'Message: ' . $ex['msg'] . PHP_EOL;
1019
-        $exception_log .= 'Code: ' . $ex['code'] . PHP_EOL;
1020
-        $exception_log .= 'File: ' . $ex['file'] . PHP_EOL;
1021
-        $exception_log .= 'Line No: ' . $ex['line'] . PHP_EOL;
1022
-        $exception_log .= 'Stack trace: ' . PHP_EOL;
1023
-        $exception_log .= $ex['string'] . PHP_EOL;
1024
-        $exception_log .= '----------------------------------------------------------------------------------------'
1025
-                          . PHP_EOL;
1026
-        try {
1027
-            error_log($exception_log);
1028
-        } catch (Exception $e) {
1029
-            EE_Error::add_error(
1030
-                sprintf(
1031
-                    esc_html__(
1032
-                        'Event Espresso error logging could not be setup because: %s',
1033
-                        'event_espresso'
1034
-                    ),
1035
-                    $e->getMessage()
1036
-                ),
1037
-                __FILE__,
1038
-                __FUNCTION__,
1039
-                __LINE__
1040
-            );
1041
-        }
1042
-    }
1043
-
1044
-
1045
-    /**
1046
-     * This is just a wrapper for the EEH_Debug_Tools::instance()->doing_it_wrong() method.
1047
-     * doing_it_wrong() is used in those cases where a normal PHP error won't get thrown,
1048
-     * but the code execution is done in a manner that could lead to unexpected results
1049
-     * (i.e. running to early, or too late in WP or EE loading process).
1050
-     * A good test for knowing whether to use this method is:
1051
-     * 1. Is there going to be a PHP error if something isn't setup/used correctly?
1052
-     * Yes -> use EE_Error::add_error() or throw new EE_Error()
1053
-     * 2. If this is loaded before something else, it won't break anything,
1054
-     * but just wont' do what its supposed to do? Yes -> use EE_Error::doing_it_wrong()
1055
-     *
1056
-     * @param string   $function     The function that was called
1057
-     * @param string   $message      A message explaining what has been done incorrectly
1058
-     * @param string   $version      The version of Event Espresso where the error was added
1059
-     * @param string   $applies_when a version string for when you want the doing_it_wrong notice to begin appearing
1060
-     *                               for a deprecated function. This allows deprecation to occur during one version,
1061
-     *                               but not have any notices appear until a later version. This allows developers
1062
-     *                               extra time to update their code before notices appear.
1063
-     * @param int|null $error_type
1064
-     * @uses   constant WP_DEBUG test if wp_debug is on or not
1065
-     */
1066
-    public static function doing_it_wrong(
1067
-        string $function,
1068
-        string $message,
1069
-        string $version,
1070
-        string $applies_when = '',
1071
-        int $error_type = null
1072
-    ) {
1073
-        if (defined('WP_DEBUG') && WP_DEBUG) {
1074
-            EEH_Debug_Tools::instance()->doing_it_wrong($function, $message, $version, $applies_when, $error_type);
1075
-        }
1076
-    }
1077
-
1078
-
1079
-    /**
1080
-     * Like get_notices, but returns an array of all the notices of the given type.
1081
-     *
1082
-     * @return array {
1083
-     * @type array $success   all the success messages
1084
-     * @type array $errors    all the error messages
1085
-     * @type array $attention all the attention messages
1086
-     * }
1087
-     */
1088
-    public static function get_raw_notices(): array
1089
-    {
1090
-        return self::$_espresso_notices;
1091
-    }
1092
-
1093
-
1094
-    /**
1095
-     * @param string $pan_name     the name, or key of the Persistent Admin Notice to be stored
1096
-     * @param string $pan_message  the message to be stored persistently until dismissed
1097
-     * @param bool   $force_update allows one to enforce the reappearance of a persistent message.
1098
-     * @return void
1099
-     * @throws InvalidDataTypeException
1100
-     * @deprecated 4.9.27
1101
-     */
1102
-    public static function add_persistent_admin_notice(
1103
-        string $pan_name = '',
1104
-        string $pan_message = '',
1105
-        bool $force_update = false
1106
-    ) {
1107
-        new PersistentAdminNotice(
1108
-            $pan_name,
1109
-            $pan_message,
1110
-            $force_update
1111
-        );
1112
-        EE_Error::doing_it_wrong(
1113
-            __METHOD__,
1114
-            sprintf(
1115
-                esc_html__('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'),
1116
-                '\EventEspresso\core\domain\entities\notifications\PersistentAdminNotice'
1117
-            ),
1118
-            '4.9.27'
1119
-        );
1120
-    }
1121
-
1122
-
1123
-    /**
1124
-     * @param string $pan_name the name, or key of the Persistent Admin Notice to be dismissed
1125
-     * @param bool   $purge
1126
-     * @param bool   $return
1127
-     * @throws DomainException
1128
-     * @throws InvalidInterfaceException
1129
-     * @throws InvalidDataTypeException
1130
-     * @throws ServiceNotFoundException
1131
-     * @throws InvalidArgumentException
1132
-     * @deprecated 4.9.27
1133
-     */
1134
-    public static function dismiss_persistent_admin_notice(
1135
-        string $pan_name = '',
1136
-        bool $purge = false,
1137
-        bool $return = false
1138
-    ) {
1139
-        /** @var PersistentAdminNoticeManager $persistent_admin_notice_manager */
1140
-        $persistent_admin_notice_manager = LoaderFactory::getLoader()->getShared(
1141
-            'EventEspresso\core\services\notifications\PersistentAdminNoticeManager'
1142
-        );
1143
-        $persistent_admin_notice_manager->dismissNotice($pan_name, $purge, $return);
1144
-        EE_Error::doing_it_wrong(
1145
-            __METHOD__,
1146
-            sprintf(
1147
-                esc_html__('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'),
1148
-                '\EventEspresso\core\services\notifications\PersistentAdminNoticeManager'
1149
-            ),
1150
-            '4.9.27'
1151
-        );
1152
-    }
1153
-
1154
-
1155
-    /**
1156
-     * @param string $pan_name    the name, or key of the Persistent Admin Notice to be stored
1157
-     * @param string $pan_message the message to be stored persistently until dismissed
1158
-     * @param string $return_url  URL to go back to after nag notice is dismissed
1159
-     * @deprecated 4.9.27
1160
-     */
1161
-    public static function display_persistent_admin_notices(
1162
-        string $pan_name = '',
1163
-        string $pan_message = '',
1164
-        string $return_url = ''
1165
-    ) {
1166
-        EE_Error::doing_it_wrong(
1167
-            __METHOD__,
1168
-            sprintf(
1169
-                esc_html__('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'),
1170
-                '\EventEspresso\core\services\notifications\PersistentAdminNoticeManager'
1171
-            ),
1172
-            '4.9.27'
1173
-        );
1174
-    }
1175
-
1176
-
1177
-    /**
1178
-     * @param string $return_url
1179
-     * @deprecated 4.9.27
1180
-     */
1181
-    public static function get_persistent_admin_notices(string $return_url = '')
1182
-    {
1183
-        EE_Error::doing_it_wrong(
1184
-            __METHOD__,
1185
-            sprintf(
1186
-                esc_html__('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'),
1187
-                '\EventEspresso\core\services\notifications\PersistentAdminNoticeManager'
1188
-            ),
1189
-            '4.9.27'
1190
-        );
1191
-    }
965
+		}
966
+		return '';
967
+	}
968
+
969
+
970
+	/**
971
+	 * @return void
972
+	 */
973
+	public static function enqueue_error_scripts()
974
+	{
975
+		self::_print_scripts();
976
+	}
977
+
978
+
979
+	/**
980
+	 * create error code from filepath, function name,
981
+	 * and line number where exception or error was thrown
982
+	 *
983
+	 * @param string $file
984
+	 * @param string $func
985
+	 * @param int|string $line
986
+	 * @return string
987
+	 */
988
+	public static function generate_error_code(string $file = '', string $func = '', $line = ''): string
989
+	{
990
+		$file       = explode('.', basename($file));
991
+		$error_code = ! empty($file[0]) ? $file[0] : '';
992
+		$error_code .= ! empty($func) ? ' - ' . $func : '';
993
+		$error_code .= ! empty($line) ? ' - ' . $line : '';
994
+		return $error_code;
995
+	}
996
+
997
+
998
+	/**
999
+	 * write exception details to log file
1000
+	 * Since 4.9.53.rc.006 this writes to the standard PHP log file, not EE's custom log file
1001
+	 *
1002
+	 * @param int   $time
1003
+	 * @param array $ex
1004
+	 * @param bool  $clear
1005
+	 * @return void
1006
+	 */
1007
+	public function write_to_error_log(int $time = 0, array $ex = [], bool $clear = false)
1008
+	{
1009
+		if (empty($ex)) {
1010
+			return;
1011
+		}
1012
+		if (! $time) {
1013
+			$time = time();
1014
+		}
1015
+		$exception_log = '----------------------------------------------------------------------------------------'
1016
+						 . PHP_EOL;
1017
+		$exception_log .= '[' . date('Y-m-d H:i:s', $time) . ']  Exception Details' . PHP_EOL;
1018
+		$exception_log .= 'Message: ' . $ex['msg'] . PHP_EOL;
1019
+		$exception_log .= 'Code: ' . $ex['code'] . PHP_EOL;
1020
+		$exception_log .= 'File: ' . $ex['file'] . PHP_EOL;
1021
+		$exception_log .= 'Line No: ' . $ex['line'] . PHP_EOL;
1022
+		$exception_log .= 'Stack trace: ' . PHP_EOL;
1023
+		$exception_log .= $ex['string'] . PHP_EOL;
1024
+		$exception_log .= '----------------------------------------------------------------------------------------'
1025
+						  . PHP_EOL;
1026
+		try {
1027
+			error_log($exception_log);
1028
+		} catch (Exception $e) {
1029
+			EE_Error::add_error(
1030
+				sprintf(
1031
+					esc_html__(
1032
+						'Event Espresso error logging could not be setup because: %s',
1033
+						'event_espresso'
1034
+					),
1035
+					$e->getMessage()
1036
+				),
1037
+				__FILE__,
1038
+				__FUNCTION__,
1039
+				__LINE__
1040
+			);
1041
+		}
1042
+	}
1043
+
1044
+
1045
+	/**
1046
+	 * This is just a wrapper for the EEH_Debug_Tools::instance()->doing_it_wrong() method.
1047
+	 * doing_it_wrong() is used in those cases where a normal PHP error won't get thrown,
1048
+	 * but the code execution is done in a manner that could lead to unexpected results
1049
+	 * (i.e. running to early, or too late in WP or EE loading process).
1050
+	 * A good test for knowing whether to use this method is:
1051
+	 * 1. Is there going to be a PHP error if something isn't setup/used correctly?
1052
+	 * Yes -> use EE_Error::add_error() or throw new EE_Error()
1053
+	 * 2. If this is loaded before something else, it won't break anything,
1054
+	 * but just wont' do what its supposed to do? Yes -> use EE_Error::doing_it_wrong()
1055
+	 *
1056
+	 * @param string   $function     The function that was called
1057
+	 * @param string   $message      A message explaining what has been done incorrectly
1058
+	 * @param string   $version      The version of Event Espresso where the error was added
1059
+	 * @param string   $applies_when a version string for when you want the doing_it_wrong notice to begin appearing
1060
+	 *                               for a deprecated function. This allows deprecation to occur during one version,
1061
+	 *                               but not have any notices appear until a later version. This allows developers
1062
+	 *                               extra time to update their code before notices appear.
1063
+	 * @param int|null $error_type
1064
+	 * @uses   constant WP_DEBUG test if wp_debug is on or not
1065
+	 */
1066
+	public static function doing_it_wrong(
1067
+		string $function,
1068
+		string $message,
1069
+		string $version,
1070
+		string $applies_when = '',
1071
+		int $error_type = null
1072
+	) {
1073
+		if (defined('WP_DEBUG') && WP_DEBUG) {
1074
+			EEH_Debug_Tools::instance()->doing_it_wrong($function, $message, $version, $applies_when, $error_type);
1075
+		}
1076
+	}
1077
+
1078
+
1079
+	/**
1080
+	 * Like get_notices, but returns an array of all the notices of the given type.
1081
+	 *
1082
+	 * @return array {
1083
+	 * @type array $success   all the success messages
1084
+	 * @type array $errors    all the error messages
1085
+	 * @type array $attention all the attention messages
1086
+	 * }
1087
+	 */
1088
+	public static function get_raw_notices(): array
1089
+	{
1090
+		return self::$_espresso_notices;
1091
+	}
1092
+
1093
+
1094
+	/**
1095
+	 * @param string $pan_name     the name, or key of the Persistent Admin Notice to be stored
1096
+	 * @param string $pan_message  the message to be stored persistently until dismissed
1097
+	 * @param bool   $force_update allows one to enforce the reappearance of a persistent message.
1098
+	 * @return void
1099
+	 * @throws InvalidDataTypeException
1100
+	 * @deprecated 4.9.27
1101
+	 */
1102
+	public static function add_persistent_admin_notice(
1103
+		string $pan_name = '',
1104
+		string $pan_message = '',
1105
+		bool $force_update = false
1106
+	) {
1107
+		new PersistentAdminNotice(
1108
+			$pan_name,
1109
+			$pan_message,
1110
+			$force_update
1111
+		);
1112
+		EE_Error::doing_it_wrong(
1113
+			__METHOD__,
1114
+			sprintf(
1115
+				esc_html__('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'),
1116
+				'\EventEspresso\core\domain\entities\notifications\PersistentAdminNotice'
1117
+			),
1118
+			'4.9.27'
1119
+		);
1120
+	}
1121
+
1122
+
1123
+	/**
1124
+	 * @param string $pan_name the name, or key of the Persistent Admin Notice to be dismissed
1125
+	 * @param bool   $purge
1126
+	 * @param bool   $return
1127
+	 * @throws DomainException
1128
+	 * @throws InvalidInterfaceException
1129
+	 * @throws InvalidDataTypeException
1130
+	 * @throws ServiceNotFoundException
1131
+	 * @throws InvalidArgumentException
1132
+	 * @deprecated 4.9.27
1133
+	 */
1134
+	public static function dismiss_persistent_admin_notice(
1135
+		string $pan_name = '',
1136
+		bool $purge = false,
1137
+		bool $return = false
1138
+	) {
1139
+		/** @var PersistentAdminNoticeManager $persistent_admin_notice_manager */
1140
+		$persistent_admin_notice_manager = LoaderFactory::getLoader()->getShared(
1141
+			'EventEspresso\core\services\notifications\PersistentAdminNoticeManager'
1142
+		);
1143
+		$persistent_admin_notice_manager->dismissNotice($pan_name, $purge, $return);
1144
+		EE_Error::doing_it_wrong(
1145
+			__METHOD__,
1146
+			sprintf(
1147
+				esc_html__('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'),
1148
+				'\EventEspresso\core\services\notifications\PersistentAdminNoticeManager'
1149
+			),
1150
+			'4.9.27'
1151
+		);
1152
+	}
1153
+
1154
+
1155
+	/**
1156
+	 * @param string $pan_name    the name, or key of the Persistent Admin Notice to be stored
1157
+	 * @param string $pan_message the message to be stored persistently until dismissed
1158
+	 * @param string $return_url  URL to go back to after nag notice is dismissed
1159
+	 * @deprecated 4.9.27
1160
+	 */
1161
+	public static function display_persistent_admin_notices(
1162
+		string $pan_name = '',
1163
+		string $pan_message = '',
1164
+		string $return_url = ''
1165
+	) {
1166
+		EE_Error::doing_it_wrong(
1167
+			__METHOD__,
1168
+			sprintf(
1169
+				esc_html__('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'),
1170
+				'\EventEspresso\core\services\notifications\PersistentAdminNoticeManager'
1171
+			),
1172
+			'4.9.27'
1173
+		);
1174
+	}
1175
+
1176
+
1177
+	/**
1178
+	 * @param string $return_url
1179
+	 * @deprecated 4.9.27
1180
+	 */
1181
+	public static function get_persistent_admin_notices(string $return_url = '')
1182
+	{
1183
+		EE_Error::doing_it_wrong(
1184
+			__METHOD__,
1185
+			sprintf(
1186
+				esc_html__('Usage is deprecated. Use "%1$s" instead.', 'event_espresso'),
1187
+				'\EventEspresso\core\services\notifications\PersistentAdminNoticeManager'
1188
+			),
1189
+			'4.9.27'
1190
+		);
1191
+	}
1192 1192
 }
1193 1193
 
1194 1194
 // end of Class EE_Exceptions
@@ -1201,29 +1201,29 @@  discard block
 block discarded – undo
1201 1201
  */
1202 1202
 function espresso_error_enqueue_scripts()
1203 1203
 {
1204
-    // js for error handling
1205
-    if (! wp_script_is('espresso_core', 'registered')) {
1206
-        wp_register_script(
1207
-            'espresso_core',
1208
-            EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js',
1209
-            ['jquery'],
1210
-            EVENT_ESPRESSO_VERSION
1211
-        );
1212
-    }
1213
-    wp_register_script(
1214
-        'ee_error_js',
1215
-        EE_GLOBAL_ASSETS_URL . 'scripts/EE_Error.js',
1216
-        ['espresso_core'],
1217
-        EVENT_ESPRESSO_VERSION
1218
-    );
1219
-    wp_localize_script('ee_error_js', 'ee_settings', ['wp_debug' => WP_DEBUG]);
1204
+	// js for error handling
1205
+	if (! wp_script_is('espresso_core', 'registered')) {
1206
+		wp_register_script(
1207
+			'espresso_core',
1208
+			EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js',
1209
+			['jquery'],
1210
+			EVENT_ESPRESSO_VERSION
1211
+		);
1212
+	}
1213
+	wp_register_script(
1214
+		'ee_error_js',
1215
+		EE_GLOBAL_ASSETS_URL . 'scripts/EE_Error.js',
1216
+		['espresso_core'],
1217
+		EVENT_ESPRESSO_VERSION
1218
+	);
1219
+	wp_localize_script('ee_error_js', 'ee_settings', ['wp_debug' => WP_DEBUG]);
1220 1220
 }
1221 1221
 
1222 1222
 
1223 1223
 if (is_admin()) {
1224
-    add_action('admin_enqueue_scripts', 'espresso_error_enqueue_scripts', 5);
1224
+	add_action('admin_enqueue_scripts', 'espresso_error_enqueue_scripts', 5);
1225 1225
 } else {
1226
-    add_action('wp_enqueue_scripts', 'espresso_error_enqueue_scripts', 5);
1226
+	add_action('wp_enqueue_scripts', 'espresso_error_enqueue_scripts', 5);
1227 1227
 }
1228 1228
 
1229 1229
 
Please login to merge, or discard this patch.
Spacing   +78 added lines, -78 removed lines patch added patch discarded remove patch
@@ -72,14 +72,14 @@  discard block
 block discarded – undo
72 72
         $to      = strpos($site, 'eventespresso.com')
73 73
             ? '[email protected]'
74 74
             : get_option('admin_email');
75
-        $subject = "$type $message in " . EVENT_ESPRESSO_VERSION . ' on ' . site_url();
75
+        $subject = "$type $message in ".EVENT_ESPRESSO_VERSION.' on '.site_url();
76 76
         $msg     = EE_Error::_format_error($type, $message, $file, $line);
77 77
         if (function_exists('wp_mail')) {
78 78
             add_filter('wp_mail_content_type', ['EE_Error', 'set_content_type']);
79 79
             wp_mail($to, $subject, $msg);
80 80
         }
81 81
         echo '<div id="message" class="espresso-notices error"><p>';
82
-        echo wp_kses($type . ': ' . $message . '<br />' . $file . ' line ' . $line, AllowedTags::getWithFormTags());
82
+        echo wp_kses($type.': '.$message.'<br />'.$file.' line '.$line, AllowedTags::getWithFormTags());
83 83
         echo '<br /></p></div>';
84 84
     }
85 85
 
@@ -196,13 +196,13 @@  discard block
 block discarded – undo
196 196
         $msg      = WP_DEBUG ? $dev_msg : $user_msg;
197 197
         // add details to _all_exceptions array
198 198
         $x_time                                     = time();
199
-        self::$_all_exceptions[ $x_time ]['name']   = get_class($this);
200
-        self::$_all_exceptions[ $x_time ]['file']   = $this->getFile();
201
-        self::$_all_exceptions[ $x_time ]['line']   = $this->getLine();
202
-        self::$_all_exceptions[ $x_time ]['msg']    = $msg;
203
-        self::$_all_exceptions[ $x_time ]['code']   = $this->getCode();
204
-        self::$_all_exceptions[ $x_time ]['trace']  = $this->getTrace();
205
-        self::$_all_exceptions[ $x_time ]['string'] = $this->getTraceAsString();
199
+        self::$_all_exceptions[$x_time]['name']   = get_class($this);
200
+        self::$_all_exceptions[$x_time]['file']   = $this->getFile();
201
+        self::$_all_exceptions[$x_time]['line']   = $this->getLine();
202
+        self::$_all_exceptions[$x_time]['msg']    = $msg;
203
+        self::$_all_exceptions[$x_time]['code']   = $this->getCode();
204
+        self::$_all_exceptions[$x_time]['trace']  = $this->getTrace();
205
+        self::$_all_exceptions[$x_time]['string'] = $this->getTraceAsString();
206 206
         self::$_error_count++;
207 207
         // add_action( 'shutdown', array( $this, 'display_errors' ));
208 208
         $this->display_errors();
@@ -219,8 +219,8 @@  discard block
 block discarded – undo
219 219
      */
220 220
     public static function has_error(bool $check_stored = false, string $type_to_check = 'errors'): bool
221 221
     {
222
-        $has_error = isset(self::$_espresso_notices[ $type_to_check ])
223
-                     && ! empty(self::$_espresso_notices[ $type_to_check ]);
222
+        $has_error = isset(self::$_espresso_notices[$type_to_check])
223
+                     && ! empty(self::$_espresso_notices[$type_to_check]);
224 224
         if ($check_stored && ! $has_error) {
225 225
             $notices = EE_Error::getStoredNotices();
226 226
             foreach ($notices as $type => $notice) {
@@ -242,7 +242,7 @@  discard block
 block discarded – undo
242 242
         $trace_details = '';
243 243
         $output = '
244 244
         <div id="ee-error-message" class="error">';
245
-        if (! WP_DEBUG) {
245
+        if ( ! WP_DEBUG) {
246 246
             $output .= '
247 247
 	        <p>';
248 248
         }
@@ -301,14 +301,14 @@  discard block
 block discarded – undo
301 301
                     $class_display    = ! empty($class) ? $class : '&nbsp;';
302 302
                     $type_display     = ! empty($type) ? $type : '&nbsp;';
303 303
                     $function_display = ! empty($function) ? $function : '&nbsp;';
304
-                    $args_display     = ! empty($args) ? '( ' . $args . ' )' : '';
305
-                    $trace_details    .= '
304
+                    $args_display     = ! empty($args) ? '( '.$args.' )' : '';
305
+                    $trace_details .= '
306 306
 					<tr>
307
-						<td class="' . $zebra . '">' . $number_display . '</td>
308
-						<td class="' . $zebra . '">' . $line_display . '</td>
309
-						<td class="' . $zebra . '">' . $file_display . '</td>
310
-						<td class="' . $zebra . '">' . $class_display . '</td>
311
-						<td class="' . $zebra . '">' . $type_display . $function_display . $args_display . '</td>
307
+						<td class="' . $zebra.'">'.$number_display.'</td>
308
+						<td class="' . $zebra.'">'.$line_display.'</td>
309
+						<td class="' . $zebra.'">'.$file_display.'</td>
310
+						<td class="' . $zebra.'">'.$class_display.'</td>
311
+						<td class="' . $zebra.'">'.$type_display.$function_display.$args_display.'</td>
312 312
 					</tr>';
313 313
                 }
314 314
                 $trace_details .= '
@@ -317,7 +317,7 @@  discard block
 block discarded – undo
317 317
             }
318 318
             $ex['code'] = $ex['code'] ?: $error_code;
319 319
             // add generic non-identifying messages for non-privileged users
320
-            if (! WP_DEBUG) {
320
+            if ( ! WP_DEBUG) {
321 321
                 $output .= '<span class="ee-error-user-msg-spn">'
322 322
                            . trim($ex['msg'])
323 323
                            . '</span> &nbsp; <sup>'
@@ -359,14 +359,14 @@  discard block
 block discarded – undo
359 359
                            . '-dv" class="ee-error-trace-dv" style="display: none;">
360 360
 				'
361 361
                            . $trace_details;
362
-                if (! empty($class)) {
362
+                if ( ! empty($class)) {
363 363
                     $output .= '
364 364
 				<div style="padding:3px; margin:0 0 1em; border:1px solid #666; background:#fff; border-radius:3px;">
365 365
 					<div style="padding:1em 2em; border:1px solid #666; background:#f9f9f9;">
366 366
 						<h3>Class Details</h3>';
367
-                    $a      = new ReflectionClass($class);
367
+                    $a = new ReflectionClass($class);
368 368
                     $output .= '
369
-						<pre>' . $a . '</pre>
369
+						<pre>' . $a.'</pre>
370 370
 					</div>
371 371
 				</div>';
372 372
                 }
@@ -379,7 +379,7 @@  discard block
 block discarded – undo
379 379
         }
380 380
         // remove last linebreak
381 381
         $output = substr($output, 0, -6);
382
-        if (! WP_DEBUG) {
382
+        if ( ! WP_DEBUG) {
383 383
             $output .= '
384 384
 	        </p>';
385 385
         }
@@ -405,18 +405,18 @@  discard block
 block discarded – undo
405 405
     private function _convert_args_to_string(array $arguments = [], bool $array = false): string
406 406
     {
407 407
         $arg_string = '';
408
-        if (! empty($arguments)) {
408
+        if ( ! empty($arguments)) {
409 409
             $args = [];
410 410
             foreach ($arguments as $arg) {
411
-                if (! empty($arg)) {
411
+                if ( ! empty($arg)) {
412 412
                     if (is_string($arg)) {
413
-                        $args[] = " '" . $arg . "'";
413
+                        $args[] = " '".$arg."'";
414 414
                     } elseif (is_array($arg)) {
415
-                        $args[] = 'ARRAY(' . $this->_convert_args_to_string($arg, true);
415
+                        $args[] = 'ARRAY('.$this->_convert_args_to_string($arg, true);
416 416
                     } elseif (is_bool($arg)) {
417 417
                         $args[] = $arg ? ' TRUE' : ' FALSE';
418 418
                     } elseif (is_object($arg)) {
419
-                        $args[] = ' OBJECT ' . get_class($arg);
419
+                        $args[] = ' OBJECT '.get_class($arg);
420 420
                     } elseif (is_resource($arg)) {
421 421
                         $args[] = get_resource_type($arg);
422 422
                     } else {
@@ -525,7 +525,7 @@  discard block
 block discarded – undo
525 525
     ) {
526 526
         if (empty($msg)) {
527 527
             EE_Error::doing_it_wrong(
528
-                'EE_Error::add_' . $type . '()',
528
+                'EE_Error::add_'.$type.'()',
529 529
                 sprintf(
530 530
                     esc_html__(
531 531
                         'Notifications are not much use without a message! Please add a message to the EE_Error::add_%s() call made in %s on line %d',
@@ -565,22 +565,22 @@  discard block
 block discarded – undo
565 565
         do_action('AHEE__EE_Error___add_notice', $type, $user_msg, $dev_msg, $file, $func, $line);
566 566
         $msg = WP_DEBUG ? $dev_msg : $user_msg;
567 567
         // add notice if message exists
568
-        if (! empty($msg)) {
568
+        if ( ! empty($msg)) {
569 569
             // get error code
570 570
             $notice_code = EE_Error::generate_error_code($file, $func, $line);
571 571
             if (WP_DEBUG && $type === 'errors') {
572
-                $msg .= '<br/><span class="tiny-text">' . $notice_code . '</span>';
572
+                $msg .= '<br/><span class="tiny-text">'.$notice_code.'</span>';
573 573
             }
574 574
 
575
-            if (! is_array(self::$_espresso_notices[ $type ]) || ! array_key_exists($type, self::$_espresso_notices)) {
576
-                self::$_espresso_notices[ $type ] = [];
575
+            if ( ! is_array(self::$_espresso_notices[$type]) || ! array_key_exists($type, self::$_espresso_notices)) {
576
+                self::$_espresso_notices[$type] = [];
577 577
             }
578 578
 
579 579
             // add notice. Index by code if it's not blank
580 580
             if ($notice_code) {
581
-                self::$_espresso_notices[ $type ][ $notice_code ] = $msg;
581
+                self::$_espresso_notices[$type][$notice_code] = $msg;
582 582
             } else {
583
-                self::$_espresso_notices[ $type ][] = $msg;
583
+                self::$_espresso_notices[$type][] = $msg;
584 584
             }
585 585
             add_action('wp_footer', ['EE_Error', 'enqueue_error_scripts'], 1);
586 586
         }
@@ -795,27 +795,27 @@  discard block
 block discarded – undo
795 795
         }
796 796
         $print_scripts = EE_Error::combineExistingAndNewNotices();
797 797
         // check for success messages
798
-        if (! empty(self::$_espresso_notices['success'])) {
798
+        if ( ! empty(self::$_espresso_notices['success'])) {
799 799
             // combine messages
800 800
             $success_messages .= implode('<br />', self::$_espresso_notices['success']);
801
-            $print_scripts    = true;
801
+            $print_scripts = true;
802 802
         }
803 803
         // check for attention messages
804
-        if (! empty(self::$_espresso_notices['attention'])) {
804
+        if ( ! empty(self::$_espresso_notices['attention'])) {
805 805
             // combine messages
806 806
             $attention_messages .= implode('<br />', self::$_espresso_notices['attention']);
807
-            $print_scripts      = true;
807
+            $print_scripts = true;
808 808
         }
809 809
         // check for error messages
810
-        if (! empty(self::$_espresso_notices['errors'])) {
810
+        if ( ! empty(self::$_espresso_notices['errors'])) {
811 811
             if ($add_preface) {
812 812
                 $error_messages .= count(self::$_espresso_notices['errors']) > 1
813 813
                     ? esc_html__('The following errors have occurred:', 'event_espresso')
814 814
                     : esc_html__('An error has occurred:', 'event_espresso');
815 815
             }
816 816
             // combine messages
817
-            $error_messages .= '<br />' . implode('<br />', self::$_espresso_notices['errors']);
818
-            $print_scripts  = true;
817
+            $error_messages .= '<br />'.implode('<br />', self::$_espresso_notices['errors']);
818
+            $print_scripts = true;
819 819
         }
820 820
         if ($format_output) {
821 821
             $notices = EE_Error::formatNoticesOutput(
@@ -833,7 +833,7 @@  discard block
 block discarded – undo
833 833
                 // remove empty notices
834 834
                 foreach ($notices as $type => $notice) {
835 835
                     if (empty($notice)) {
836
-                        unset($notices[ $type ]);
836
+                        unset($notices[$type]);
837 837
                     }
838 838
                 }
839 839
             }
@@ -856,17 +856,17 @@  discard block
 block discarded – undo
856 856
         $print_scripts = false;
857 857
         // grab any notices that have been previously saved
858 858
         $notices = EE_Error::getStoredNotices();
859
-        if (! empty($notices)) {
859
+        if ( ! empty($notices)) {
860 860
             foreach ($notices as $type => $notice) {
861 861
                 if (is_array($notice) && ! empty($notice)) {
862 862
                     // make sure that existing notice type is an array
863
-                    self::$_espresso_notices[ $type ] = is_array(self::$_espresso_notices[ $type ])
864
-                                                        && ! empty(self::$_espresso_notices[ $type ])
865
-                        ? self::$_espresso_notices[ $type ]
863
+                    self::$_espresso_notices[$type] = is_array(self::$_espresso_notices[$type])
864
+                                                        && ! empty(self::$_espresso_notices[$type])
865
+                        ? self::$_espresso_notices[$type]
866 866
                         : [];
867 867
                     // add newly created notices to existing ones
868
-                    self::$_espresso_notices[ $type ] += $notice;
869
-                    $print_scripts                    = true;
868
+                    self::$_espresso_notices[$type] += $notice;
869
+                    $print_scripts = true;
870 870
                 }
871 871
             }
872 872
             // now clear any stored notices
@@ -895,23 +895,23 @@  discard block
 block discarded – undo
895 895
             $css_id    = is_admin() ? 'ee-success-message' : 'espresso-notices-success';
896 896
             $css_class = is_admin() ? 'updated fade ee-status-outline ee-status-bg--success' : 'success fade-away';
897 897
             // showMessage( $success_messages );
898
-            $notices .= '<div id="' . $css_id . '" '
899
-                        . 'class="espresso-notices ' . $css_class . '" '
898
+            $notices .= '<div id="'.$css_id.'" '
899
+                        . 'class="espresso-notices '.$css_class.'" '
900 900
                         . 'style="display:none;">'
901
-                        . '<p>' . $success_messages . '</p>'
901
+                        . '<p>'.$success_messages.'</p>'
902 902
                         . $close
903 903
                         . '</div>';
904 904
         }
905 905
         if ($attention_messages !== '') {
906
-            $css_id    = is_admin()  ? 'ee-attention-message' : 'espresso-notices-attention';
906
+            $css_id    = is_admin() ? 'ee-attention-message' : 'espresso-notices-attention';
907 907
             $css_class = is_admin()
908 908
                 ? 'notice notice-info ee-notices-attention ee-status-outline ee-status-bg--attention'
909 909
                 : 'attention fade-away';
910 910
             // showMessage( $error_messages, TRUE );
911
-            $notices .= '<div id="' . $css_id . '" '
912
-                        . 'class="espresso-notices ' . $css_class . '" '
911
+            $notices .= '<div id="'.$css_id.'" '
912
+                        . 'class="espresso-notices '.$css_class.'" '
913 913
                         . 'style="display:none;">'
914
-                        . '<p>' . $attention_messages . '</p>'
914
+                        . '<p>'.$attention_messages.'</p>'
915 915
                         . $close
916 916
                         . '</div>';
917 917
         }
@@ -921,10 +921,10 @@  discard block
 block discarded – undo
921 921
                 ? 'error ee-status-outline ee-status-bg--error'
922 922
                 : 'error fade-away';
923 923
             // showMessage( $error_messages, TRUE );
924
-            $notices .= '<div id="' . $css_id . '" '
925
-                        . 'class="espresso-notices ' . $css_class . '" '
924
+            $notices .= '<div id="'.$css_id.'" '
925
+                        . 'class="espresso-notices '.$css_class.'" '
926 926
                         . 'style="display:none;">'
927
-                        . '<p>' . $error_messages . '</p>'
927
+                        . '<p>'.$error_messages.'</p>'
928 928
                         . $close
929 929
                         . '</div>';
930 930
         }
@@ -941,7 +941,7 @@  discard block
 block discarded – undo
941 941
      */
942 942
     private static function _print_scripts(bool $force_print = false): string
943 943
     {
944
-        if (! $force_print && (did_action('admin_enqueue_scripts') || did_action('wp_enqueue_scripts'))) {
944
+        if ( ! $force_print && (did_action('admin_enqueue_scripts') || did_action('wp_enqueue_scripts'))) {
945 945
             if (wp_script_is('ee_error_js', 'registered')) {
946 946
                 wp_enqueue_style('espresso_default');
947 947
                 wp_enqueue_style('espresso_custom_css');
@@ -955,12 +955,12 @@  discard block
 block discarded – undo
955 955
             return '
956 956
 <script>
957 957
 /* <![CDATA[ */
958
-const ee_settings = {"wp_debug":"' . WP_DEBUG . '"};
958
+const ee_settings = {"wp_debug":"' . WP_DEBUG.'"};
959 959
 /* ]]> */
960 960
 </script>
961
-<script src="' . includes_url() . 'js/jquery/jquery.js" type="text/javascript"></script>
962
-<script src="' . EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js' . '?ver=' . espresso_version() . '" type="text/javascript"></script>
963
-<script src="' . EE_GLOBAL_ASSETS_URL . 'scripts/EE_Error.js' . '?ver=' . espresso_version() . '" type="text/javascript"></script>
961
+<script src="' . includes_url().'js/jquery/jquery.js" type="text/javascript"></script>
962
+<script src="' . EE_GLOBAL_ASSETS_URL.'scripts/espresso_core.js'.'?ver='.espresso_version().'" type="text/javascript"></script>
963
+<script src="' . EE_GLOBAL_ASSETS_URL.'scripts/EE_Error.js'.'?ver='.espresso_version().'" type="text/javascript"></script>
964 964
 ';
965 965
         }
966 966
         return '';
@@ -989,8 +989,8 @@  discard block
 block discarded – undo
989 989
     {
990 990
         $file       = explode('.', basename($file));
991 991
         $error_code = ! empty($file[0]) ? $file[0] : '';
992
-        $error_code .= ! empty($func) ? ' - ' . $func : '';
993
-        $error_code .= ! empty($line) ? ' - ' . $line : '';
992
+        $error_code .= ! empty($func) ? ' - '.$func : '';
993
+        $error_code .= ! empty($line) ? ' - '.$line : '';
994 994
         return $error_code;
995 995
     }
996 996
 
@@ -1009,18 +1009,18 @@  discard block
 block discarded – undo
1009 1009
         if (empty($ex)) {
1010 1010
             return;
1011 1011
         }
1012
-        if (! $time) {
1012
+        if ( ! $time) {
1013 1013
             $time = time();
1014 1014
         }
1015 1015
         $exception_log = '----------------------------------------------------------------------------------------'
1016 1016
                          . PHP_EOL;
1017
-        $exception_log .= '[' . date('Y-m-d H:i:s', $time) . ']  Exception Details' . PHP_EOL;
1018
-        $exception_log .= 'Message: ' . $ex['msg'] . PHP_EOL;
1019
-        $exception_log .= 'Code: ' . $ex['code'] . PHP_EOL;
1020
-        $exception_log .= 'File: ' . $ex['file'] . PHP_EOL;
1021
-        $exception_log .= 'Line No: ' . $ex['line'] . PHP_EOL;
1022
-        $exception_log .= 'Stack trace: ' . PHP_EOL;
1023
-        $exception_log .= $ex['string'] . PHP_EOL;
1017
+        $exception_log .= '['.date('Y-m-d H:i:s', $time).']  Exception Details'.PHP_EOL;
1018
+        $exception_log .= 'Message: '.$ex['msg'].PHP_EOL;
1019
+        $exception_log .= 'Code: '.$ex['code'].PHP_EOL;
1020
+        $exception_log .= 'File: '.$ex['file'].PHP_EOL;
1021
+        $exception_log .= 'Line No: '.$ex['line'].PHP_EOL;
1022
+        $exception_log .= 'Stack trace: '.PHP_EOL;
1023
+        $exception_log .= $ex['string'].PHP_EOL;
1024 1024
         $exception_log .= '----------------------------------------------------------------------------------------'
1025 1025
                           . PHP_EOL;
1026 1026
         try {
@@ -1202,17 +1202,17 @@  discard block
 block discarded – undo
1202 1202
 function espresso_error_enqueue_scripts()
1203 1203
 {
1204 1204
     // js for error handling
1205
-    if (! wp_script_is('espresso_core', 'registered')) {
1205
+    if ( ! wp_script_is('espresso_core', 'registered')) {
1206 1206
         wp_register_script(
1207 1207
             'espresso_core',
1208
-            EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js',
1208
+            EE_GLOBAL_ASSETS_URL.'scripts/espresso_core.js',
1209 1209
             ['jquery'],
1210 1210
             EVENT_ESPRESSO_VERSION
1211 1211
         );
1212 1212
     }
1213 1213
     wp_register_script(
1214 1214
         'ee_error_js',
1215
-        EE_GLOBAL_ASSETS_URL . 'scripts/EE_Error.js',
1215
+        EE_GLOBAL_ASSETS_URL.'scripts/EE_Error.js',
1216 1216
         ['espresso_core'],
1217 1217
         EVENT_ESPRESSO_VERSION
1218 1218
     );
Please login to merge, or discard this patch.
core/domain/services/registration/form/v1/RegForm.php 2 patches
Indentation   +272 added lines, -272 removed lines patch added patch discarded remove patch
@@ -38,276 +38,276 @@
 block discarded – undo
38 38
  */
39 39
 class RegForm extends EE_Form_Section_Proper
40 40
 {
41
-    private EE_Line_Item_Display $line_item_display;
42
-
43
-    private string $primary_registrant = '';
44
-
45
-    private array $required_questions = [];
46
-
47
-    private array $subsections = [];
48
-
49
-
50
-    private bool $print_copy_info = false;
51
-
52
-    protected int $reg_form_count = 0;
53
-
54
-    public EE_Registration_Config $reg_config;
55
-
56
-    public EE_SPCO_Reg_Step_Attendee_Information $reg_step;
57
-
58
-
59
-    /**
60
-     * RegForm constructor.
61
-     *
62
-     * @param EE_SPCO_Reg_Step_Attendee_Information $reg_step
63
-     * @param EE_Registration_Config                $reg_config
64
-     * @throws ReflectionException
65
-     * @throws EE_Error
66
-     */
67
-    public function __construct(
68
-        EE_SPCO_Reg_Step_Attendee_Information $reg_step,
69
-        EE_Registration_Config $reg_config
70
-    ) {
71
-        $this->reg_step   = $reg_step;
72
-        $this->reg_config = $reg_config;
73
-        // setup some classes so that they are ready for loading during construction of other classes
74
-        LoaderFactory::getShared(CountryOptions::class, [$this->reg_step->checkout->action]);
75
-        LoaderFactory::getShared(StateOptions::class, [$this->reg_step->checkout->action]);
76
-        LoaderFactory::getShared(RegFormQuestionFactory::class, [[$this, 'addRequiredQuestion']]);
77
-        parent::__construct(
78
-            [
79
-                'name'            => $this->reg_step->reg_form_name(),
80
-                'html_id'         => $this->reg_step->reg_form_name(),
81
-                'layout_strategy' => new EE_No_Layout(),
82
-                'subsections'     => $this->generateSubsections(),
83
-            ]
84
-        );
85
-    }
86
-
87
-
88
-    /**
89
-     * @return void
90
-     */
91
-    public function enablePrintCopyInfo(): void
92
-    {
93
-        $this->print_copy_info = true;
94
-    }
95
-
96
-
97
-    /**
98
-     * @return bool
99
-     */
100
-    public function printCopyInfo(): bool
101
-    {
102
-        return $this->print_copy_info;
103
-    }
104
-
105
-
106
-    /**
107
-     * @return int
108
-     */
109
-    public function regFormCount(): int
110
-    {
111
-        return $this->reg_form_count;
112
-    }
113
-
114
-
115
-    /**
116
-     * @return array
117
-     */
118
-    public function requiredQuestions(): array
119
-    {
120
-        return $this->required_questions;
121
-    }
122
-
123
-
124
-    /**
125
-     * @param string $identifier
126
-     * @param string $required_question
127
-     */
128
-    public function addRequiredQuestion(string $identifier, string $required_question): void
129
-    {
130
-        $this->required_questions[ $identifier ] = $required_question;
131
-    }
132
-
133
-
134
-    /**
135
-     * @return EE_Form_Section_Proper[]
136
-     * @throws DomainException
137
-     * @throws EE_Error
138
-     * @throws InvalidArgumentException
139
-     * @throws ReflectionException
140
-     * @throws EntityNotFoundException
141
-     * @throws InvalidDataTypeException
142
-     * @throws InvalidInterfaceException
143
-     */
144
-    private function generateSubsections(): array
145
-    {
146
-        $this->configureLineItemDisplay();
147
-        $this->addAttendeeInformationNotice();
148
-
149
-        $this->subsections["ticket-details"] = new TicketDetailsTable(
150
-            $this->reg_step->checkout->cart->get_grand_total(),
151
-            $this->line_item_display,
152
-            $this->reg_step->checkout->revisit
153
-        );
154
-
155
-        // grab the saved registrations from the transaction
156
-        $registrations = $this->reg_step->checkout->transaction->registrations(
157
-            $this->reg_step->checkout->reg_cache_where_params
158
-        );
159
-        if ($registrations) {
160
-            foreach ($registrations as $registration) {
161
-                if (! $registration instanceof EE_Registration) {
162
-                    continue;
163
-                }
164
-                $this->subsections["ticket-details"]->addTicket($registration->ticket());
165
-                $this->addAttendeeRegForm($registration);
166
-            }
167
-            $this->addCopyAttendeeInfoForm($registrations);
168
-        }
169
-        $this->addPrivacyConsentCheckbox();
170
-        $this->displayEventQuestionsLink();
171
-        $this->subsections['default_hidden_inputs']  =  $this->reg_step->reg_step_hidden_inputs();
172
-
173
-        return (array) apply_filters(
174
-            'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegForm__generateSubsections__subsections',
175
-            $this->subsections,
176
-            $this
177
-        );
178
-    }
179
-
180
-
181
-    /**
182
-     * @throws EE_Error
183
-     * @throws ReflectionException
184
-     */
185
-    private function configureLineItemDisplay()
186
-    {
187
-        // autoload Line_Item_Display classes
188
-        EEH_Autoloader::register_line_item_display_autoloaders();
189
-        $this->line_item_display = new EE_Line_Item_Display();
190
-        // calculate taxes
191
-        $this->line_item_display->display_line_item(
192
-            $this->reg_step->checkout->cart->get_grand_total(),
193
-            ['set_tax_rate' => true]
194
-        );
195
-    }
196
-
197
-
198
-    private function addAttendeeInformationNotice(): void
199
-    {
200
-        if (is_admin()) {
201
-            return;
202
-        }
203
-        $this->subsections['attendee_information_notice'] = new AttendeeInformationNotice();
204
-    }
205
-
206
-
207
-    /**
208
-     * @param EE_Registration $registration
209
-     * @throws EE_Error
210
-     * @throws ReflectionException
211
-     */
212
-    private function addAttendeeRegForm(EE_Registration $registration): void
213
-    {
214
-        // can this registration be processed during this visit ?
215
-        if (! $this->reg_step->checkout->visit_allows_processing_of_this_registration($registration)) {
216
-            return;
217
-        }
218
-        $reg_url_link = $registration->reg_url_link();
219
-        if ($registration->is_primary_registrant()) {
220
-            $this->primary_registrant = $reg_url_link;
221
-        }
222
-
223
-        /** @var AttendeeRegForm $registrant_form */
224
-        $registrant_form = LoaderFactory::getNew(
225
-            AttendeeRegForm::class,
226
-            [
227
-                $registration,
228
-                $this->reg_config->copyAttendeeInfo(),
229
-                [$this, 'enablePrintCopyInfo'],
230
-                $this->reg_step,
231
-            ]
232
-        );
233
-
234
-        // skip section if there are no questions
235
-        if (! $registrant_form->hasQuestions()) {
236
-            return;
237
-        }
238
-
239
-        // but increment the reg form count if form is valid.
240
-        $this->reg_form_count++;
241
-        $this->subsections["panel-div-open-$reg_url_link"]  = new EE_Form_Section_HTML(
242
-            EEH_HTML::div(
243
-                '',
244
-                "spco-attendee-panel-dv-$reg_url_link",
245
-                "spco-attendee-panel-dv spco-attendee-ticket-$reg_url_link"
246
-            )
247
-        );
248
-        $this->subsections["event-header-$reg_url_link"]    = new EventHeader($registration->event());
249
-        $this->subsections[ $reg_url_link ]                 = $registrant_form;
250
-        $this->subsections["panel-div-close-$reg_url_link"] = new EE_Form_Section_HTML(
251
-            EEH_HTML::divx("spco-attendee-panel-dv-$reg_url_link")
252
-        );
253
-    }
254
-
255
-
256
-    /**
257
-     * @throws ReflectionException
258
-     * @throws EE_Error
259
-     */
260
-    private function addCopyAttendeeInfoForm(array $registrations)
261
-    {
262
-        if (
263
-            $this->primary_registrant
264
-            && count($registrations) > 1
265
-            && isset($this->subsections[ $this->primary_registrant ])
266
-            && $this->subsections[ $this->primary_registrant ] instanceof EE_Form_Section_Proper
267
-        ) {
268
-            $this->subsections[ $this->primary_registrant ]->add_subsections(
269
-                [
270
-                    'spco_copy_attendee_chk' => $this->print_copy_info
271
-                        ? new CopyAttendeeInfoForm($registrations, $this->reg_step->slug())
272
-                        : new AutoCopyAttendeeInfoForm($this->reg_step->slug()),
273
-                ],
274
-                'primary_registrant',
275
-                false
276
-            );
277
-        }
278
-    }
279
-
280
-
281
-    /**
282
-     * @return void
283
-     * @throws EE_Error
284
-     */
285
-    private function addPrivacyConsentCheckbox(): void
286
-    {
287
-        // if this isn't a revisit, and they have the privacy consent box enabled, add it
288
-        if (! $this->reg_step->checkout->revisit && $this->reg_config->isConsentCheckboxEnabled()) {
289
-            $this->subsections['consent_box'] = new PrivacyConsentCheckboxForm(
290
-                $this->reg_step->slug(),
291
-                $this->reg_config->getConsentCheckboxLabelText()
292
-            );
293
-        }
294
-    }
295
-
296
-
297
-    private function displayEventQuestionsLink()
298
-    {
299
-        $this->subsections['event_questions_link'] = new EE_Form_Section_HTML(
300
-            EEH_HTML::div(
301
-                EEH_HTML::link(
302
-                    '',
303
-                    esc_html__('show&nbsp;event&nbsp;questions', 'event_espresso'),
304
-                    esc_html__('show&nbsp;event&nbsp;questions', 'event_espresso'),
305
-                    'spco-display-event-questions-lnk',
306
-                    'act-like-link smaller-text hidden hide-if-no-js float-right'
307
-                ),
308
-                '',
309
-                'clearfix'
310
-            )
311
-        );
312
-    }
41
+	private EE_Line_Item_Display $line_item_display;
42
+
43
+	private string $primary_registrant = '';
44
+
45
+	private array $required_questions = [];
46
+
47
+	private array $subsections = [];
48
+
49
+
50
+	private bool $print_copy_info = false;
51
+
52
+	protected int $reg_form_count = 0;
53
+
54
+	public EE_Registration_Config $reg_config;
55
+
56
+	public EE_SPCO_Reg_Step_Attendee_Information $reg_step;
57
+
58
+
59
+	/**
60
+	 * RegForm constructor.
61
+	 *
62
+	 * @param EE_SPCO_Reg_Step_Attendee_Information $reg_step
63
+	 * @param EE_Registration_Config                $reg_config
64
+	 * @throws ReflectionException
65
+	 * @throws EE_Error
66
+	 */
67
+	public function __construct(
68
+		EE_SPCO_Reg_Step_Attendee_Information $reg_step,
69
+		EE_Registration_Config $reg_config
70
+	) {
71
+		$this->reg_step   = $reg_step;
72
+		$this->reg_config = $reg_config;
73
+		// setup some classes so that they are ready for loading during construction of other classes
74
+		LoaderFactory::getShared(CountryOptions::class, [$this->reg_step->checkout->action]);
75
+		LoaderFactory::getShared(StateOptions::class, [$this->reg_step->checkout->action]);
76
+		LoaderFactory::getShared(RegFormQuestionFactory::class, [[$this, 'addRequiredQuestion']]);
77
+		parent::__construct(
78
+			[
79
+				'name'            => $this->reg_step->reg_form_name(),
80
+				'html_id'         => $this->reg_step->reg_form_name(),
81
+				'layout_strategy' => new EE_No_Layout(),
82
+				'subsections'     => $this->generateSubsections(),
83
+			]
84
+		);
85
+	}
86
+
87
+
88
+	/**
89
+	 * @return void
90
+	 */
91
+	public function enablePrintCopyInfo(): void
92
+	{
93
+		$this->print_copy_info = true;
94
+	}
95
+
96
+
97
+	/**
98
+	 * @return bool
99
+	 */
100
+	public function printCopyInfo(): bool
101
+	{
102
+		return $this->print_copy_info;
103
+	}
104
+
105
+
106
+	/**
107
+	 * @return int
108
+	 */
109
+	public function regFormCount(): int
110
+	{
111
+		return $this->reg_form_count;
112
+	}
113
+
114
+
115
+	/**
116
+	 * @return array
117
+	 */
118
+	public function requiredQuestions(): array
119
+	{
120
+		return $this->required_questions;
121
+	}
122
+
123
+
124
+	/**
125
+	 * @param string $identifier
126
+	 * @param string $required_question
127
+	 */
128
+	public function addRequiredQuestion(string $identifier, string $required_question): void
129
+	{
130
+		$this->required_questions[ $identifier ] = $required_question;
131
+	}
132
+
133
+
134
+	/**
135
+	 * @return EE_Form_Section_Proper[]
136
+	 * @throws DomainException
137
+	 * @throws EE_Error
138
+	 * @throws InvalidArgumentException
139
+	 * @throws ReflectionException
140
+	 * @throws EntityNotFoundException
141
+	 * @throws InvalidDataTypeException
142
+	 * @throws InvalidInterfaceException
143
+	 */
144
+	private function generateSubsections(): array
145
+	{
146
+		$this->configureLineItemDisplay();
147
+		$this->addAttendeeInformationNotice();
148
+
149
+		$this->subsections["ticket-details"] = new TicketDetailsTable(
150
+			$this->reg_step->checkout->cart->get_grand_total(),
151
+			$this->line_item_display,
152
+			$this->reg_step->checkout->revisit
153
+		);
154
+
155
+		// grab the saved registrations from the transaction
156
+		$registrations = $this->reg_step->checkout->transaction->registrations(
157
+			$this->reg_step->checkout->reg_cache_where_params
158
+		);
159
+		if ($registrations) {
160
+			foreach ($registrations as $registration) {
161
+				if (! $registration instanceof EE_Registration) {
162
+					continue;
163
+				}
164
+				$this->subsections["ticket-details"]->addTicket($registration->ticket());
165
+				$this->addAttendeeRegForm($registration);
166
+			}
167
+			$this->addCopyAttendeeInfoForm($registrations);
168
+		}
169
+		$this->addPrivacyConsentCheckbox();
170
+		$this->displayEventQuestionsLink();
171
+		$this->subsections['default_hidden_inputs']  =  $this->reg_step->reg_step_hidden_inputs();
172
+
173
+		return (array) apply_filters(
174
+			'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegForm__generateSubsections__subsections',
175
+			$this->subsections,
176
+			$this
177
+		);
178
+	}
179
+
180
+
181
+	/**
182
+	 * @throws EE_Error
183
+	 * @throws ReflectionException
184
+	 */
185
+	private function configureLineItemDisplay()
186
+	{
187
+		// autoload Line_Item_Display classes
188
+		EEH_Autoloader::register_line_item_display_autoloaders();
189
+		$this->line_item_display = new EE_Line_Item_Display();
190
+		// calculate taxes
191
+		$this->line_item_display->display_line_item(
192
+			$this->reg_step->checkout->cart->get_grand_total(),
193
+			['set_tax_rate' => true]
194
+		);
195
+	}
196
+
197
+
198
+	private function addAttendeeInformationNotice(): void
199
+	{
200
+		if (is_admin()) {
201
+			return;
202
+		}
203
+		$this->subsections['attendee_information_notice'] = new AttendeeInformationNotice();
204
+	}
205
+
206
+
207
+	/**
208
+	 * @param EE_Registration $registration
209
+	 * @throws EE_Error
210
+	 * @throws ReflectionException
211
+	 */
212
+	private function addAttendeeRegForm(EE_Registration $registration): void
213
+	{
214
+		// can this registration be processed during this visit ?
215
+		if (! $this->reg_step->checkout->visit_allows_processing_of_this_registration($registration)) {
216
+			return;
217
+		}
218
+		$reg_url_link = $registration->reg_url_link();
219
+		if ($registration->is_primary_registrant()) {
220
+			$this->primary_registrant = $reg_url_link;
221
+		}
222
+
223
+		/** @var AttendeeRegForm $registrant_form */
224
+		$registrant_form = LoaderFactory::getNew(
225
+			AttendeeRegForm::class,
226
+			[
227
+				$registration,
228
+				$this->reg_config->copyAttendeeInfo(),
229
+				[$this, 'enablePrintCopyInfo'],
230
+				$this->reg_step,
231
+			]
232
+		);
233
+
234
+		// skip section if there are no questions
235
+		if (! $registrant_form->hasQuestions()) {
236
+			return;
237
+		}
238
+
239
+		// but increment the reg form count if form is valid.
240
+		$this->reg_form_count++;
241
+		$this->subsections["panel-div-open-$reg_url_link"]  = new EE_Form_Section_HTML(
242
+			EEH_HTML::div(
243
+				'',
244
+				"spco-attendee-panel-dv-$reg_url_link",
245
+				"spco-attendee-panel-dv spco-attendee-ticket-$reg_url_link"
246
+			)
247
+		);
248
+		$this->subsections["event-header-$reg_url_link"]    = new EventHeader($registration->event());
249
+		$this->subsections[ $reg_url_link ]                 = $registrant_form;
250
+		$this->subsections["panel-div-close-$reg_url_link"] = new EE_Form_Section_HTML(
251
+			EEH_HTML::divx("spco-attendee-panel-dv-$reg_url_link")
252
+		);
253
+	}
254
+
255
+
256
+	/**
257
+	 * @throws ReflectionException
258
+	 * @throws EE_Error
259
+	 */
260
+	private function addCopyAttendeeInfoForm(array $registrations)
261
+	{
262
+		if (
263
+			$this->primary_registrant
264
+			&& count($registrations) > 1
265
+			&& isset($this->subsections[ $this->primary_registrant ])
266
+			&& $this->subsections[ $this->primary_registrant ] instanceof EE_Form_Section_Proper
267
+		) {
268
+			$this->subsections[ $this->primary_registrant ]->add_subsections(
269
+				[
270
+					'spco_copy_attendee_chk' => $this->print_copy_info
271
+						? new CopyAttendeeInfoForm($registrations, $this->reg_step->slug())
272
+						: new AutoCopyAttendeeInfoForm($this->reg_step->slug()),
273
+				],
274
+				'primary_registrant',
275
+				false
276
+			);
277
+		}
278
+	}
279
+
280
+
281
+	/**
282
+	 * @return void
283
+	 * @throws EE_Error
284
+	 */
285
+	private function addPrivacyConsentCheckbox(): void
286
+	{
287
+		// if this isn't a revisit, and they have the privacy consent box enabled, add it
288
+		if (! $this->reg_step->checkout->revisit && $this->reg_config->isConsentCheckboxEnabled()) {
289
+			$this->subsections['consent_box'] = new PrivacyConsentCheckboxForm(
290
+				$this->reg_step->slug(),
291
+				$this->reg_config->getConsentCheckboxLabelText()
292
+			);
293
+		}
294
+	}
295
+
296
+
297
+	private function displayEventQuestionsLink()
298
+	{
299
+		$this->subsections['event_questions_link'] = new EE_Form_Section_HTML(
300
+			EEH_HTML::div(
301
+				EEH_HTML::link(
302
+					'',
303
+					esc_html__('show&nbsp;event&nbsp;questions', 'event_espresso'),
304
+					esc_html__('show&nbsp;event&nbsp;questions', 'event_espresso'),
305
+					'spco-display-event-questions-lnk',
306
+					'act-like-link smaller-text hidden hide-if-no-js float-right'
307
+				),
308
+				'',
309
+				'clearfix'
310
+			)
311
+		);
312
+	}
313 313
 }
Please login to merge, or discard this patch.
Spacing   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -127,7 +127,7 @@  discard block
 block discarded – undo
127 127
      */
128 128
     public function addRequiredQuestion(string $identifier, string $required_question): void
129 129
     {
130
-        $this->required_questions[ $identifier ] = $required_question;
130
+        $this->required_questions[$identifier] = $required_question;
131 131
     }
132 132
 
133 133
 
@@ -158,7 +158,7 @@  discard block
 block discarded – undo
158 158
         );
159 159
         if ($registrations) {
160 160
             foreach ($registrations as $registration) {
161
-                if (! $registration instanceof EE_Registration) {
161
+                if ( ! $registration instanceof EE_Registration) {
162 162
                     continue;
163 163
                 }
164 164
                 $this->subsections["ticket-details"]->addTicket($registration->ticket());
@@ -168,7 +168,7 @@  discard block
 block discarded – undo
168 168
         }
169 169
         $this->addPrivacyConsentCheckbox();
170 170
         $this->displayEventQuestionsLink();
171
-        $this->subsections['default_hidden_inputs']  =  $this->reg_step->reg_step_hidden_inputs();
171
+        $this->subsections['default_hidden_inputs'] = $this->reg_step->reg_step_hidden_inputs();
172 172
 
173 173
         return (array) apply_filters(
174 174
             'FHEE__EventEspresso_core_domain_services_registration_form_v1_RegForm__generateSubsections__subsections',
@@ -212,7 +212,7 @@  discard block
 block discarded – undo
212 212
     private function addAttendeeRegForm(EE_Registration $registration): void
213 213
     {
214 214
         // can this registration be processed during this visit ?
215
-        if (! $this->reg_step->checkout->visit_allows_processing_of_this_registration($registration)) {
215
+        if ( ! $this->reg_step->checkout->visit_allows_processing_of_this_registration($registration)) {
216 216
             return;
217 217
         }
218 218
         $reg_url_link = $registration->reg_url_link();
@@ -232,13 +232,13 @@  discard block
 block discarded – undo
232 232
         );
233 233
 
234 234
         // skip section if there are no questions
235
-        if (! $registrant_form->hasQuestions()) {
235
+        if ( ! $registrant_form->hasQuestions()) {
236 236
             return;
237 237
         }
238 238
 
239 239
         // but increment the reg form count if form is valid.
240 240
         $this->reg_form_count++;
241
-        $this->subsections["panel-div-open-$reg_url_link"]  = new EE_Form_Section_HTML(
241
+        $this->subsections["panel-div-open-$reg_url_link"] = new EE_Form_Section_HTML(
242 242
             EEH_HTML::div(
243 243
                 '',
244 244
                 "spco-attendee-panel-dv-$reg_url_link",
@@ -246,7 +246,7 @@  discard block
 block discarded – undo
246 246
             )
247 247
         );
248 248
         $this->subsections["event-header-$reg_url_link"]    = new EventHeader($registration->event());
249
-        $this->subsections[ $reg_url_link ]                 = $registrant_form;
249
+        $this->subsections[$reg_url_link]                 = $registrant_form;
250 250
         $this->subsections["panel-div-close-$reg_url_link"] = new EE_Form_Section_HTML(
251 251
             EEH_HTML::divx("spco-attendee-panel-dv-$reg_url_link")
252 252
         );
@@ -262,10 +262,10 @@  discard block
 block discarded – undo
262 262
         if (
263 263
             $this->primary_registrant
264 264
             && count($registrations) > 1
265
-            && isset($this->subsections[ $this->primary_registrant ])
266
-            && $this->subsections[ $this->primary_registrant ] instanceof EE_Form_Section_Proper
265
+            && isset($this->subsections[$this->primary_registrant])
266
+            && $this->subsections[$this->primary_registrant] instanceof EE_Form_Section_Proper
267 267
         ) {
268
-            $this->subsections[ $this->primary_registrant ]->add_subsections(
268
+            $this->subsections[$this->primary_registrant]->add_subsections(
269 269
                 [
270 270
                     'spco_copy_attendee_chk' => $this->print_copy_info
271 271
                         ? new CopyAttendeeInfoForm($registrations, $this->reg_step->slug())
@@ -285,7 +285,7 @@  discard block
 block discarded – undo
285 285
     private function addPrivacyConsentCheckbox(): void
286 286
     {
287 287
         // if this isn't a revisit, and they have the privacy consent box enabled, add it
288
-        if (! $this->reg_step->checkout->revisit && $this->reg_config->isConsentCheckboxEnabled()) {
288
+        if ( ! $this->reg_step->checkout->revisit && $this->reg_config->isConsentCheckboxEnabled()) {
289 289
             $this->subsections['consent_box'] = new PrivacyConsentCheckboxForm(
290 290
                 $this->reg_step->slug(),
291 291
                 $this->reg_config->getConsentCheckboxLabelText()
Please login to merge, or discard this patch.
domain/services/registration/form/v1/subsections/TicketDetailsTable.php 2 patches
Indentation   +111 added lines, -111 removed lines patch added patch discarded remove patch
@@ -13,115 +13,115 @@
 block discarded – undo
13 13
 
14 14
 class TicketDetailsTable extends EE_Form_Section_HTML
15 15
 {
16
-    private EE_Line_Item $cart_grand_total;
17
-    private EE_Line_Item_Display $line_item_display;
18
-
19
-    private bool $revisit;
20
-
21
-    private array $tickets = [];
22
-
23
-    private static array $ticket_line_item_options = [
24
-        'extra_css' => [
25
-            'row' => 'ee-ticket-details-row',
26
-            'name' => 'ee-ticket-details-name',
27
-            'qty' => 'ee-ticket-details-qty',
28
-            'price' => 'ee-ticket-details-price',
29
-            'total' => 'ee-ticket-details-total',
30
-        ]
31
-    ];
32
-
33
-
34
-    /**
35
-     * @param EE_Line_Item $cart_grand_total
36
-     * @param EE_Line_Item_Display $line_item_display
37
-     * @param bool      $revisit
38
-     */
39
-    public function __construct(EE_Line_Item $cart_grand_total, EE_Line_Item_Display $line_item_display, bool $revisit)
40
-    {
41
-        $this->cart_grand_total = $cart_grand_total;
42
-        $this->line_item_display = $line_item_display;
43
-        $this->revisit = $revisit;
44
-        parent::__construct();
45
-    }
46
-
47
-
48
-    /**
49
-     * @throws EE_Error
50
-     * @throws ReflectionException
51
-     */
52
-    public function addTicket(EE_Ticket $ticket): void
53
-    {
54
-        if (! isset($this->tickets[ $ticket->ID() ])) {
55
-            $this->tickets[ $ticket->ID() ] = $ticket;
56
-        }
57
-    }
58
-
59
-
60
-    /**
61
-     * @throws ReflectionException
62
-     * @throws EE_Error
63
-     */
64
-    public function get_html(): string
65
-    {
66
-        if ($this->revisit) {
67
-            return '';
68
-        }
69
-        $table_rows = '';
70
-        foreach ($this->tickets as $ticket) {
71
-            $table_rows .= $this->generateTicketDetailsTableRow($ticket);
72
-        }
73
-        return $this->generateTicketDetailsTable($table_rows);
74
-    }
75
-
76
-
77
-    /**
78
-     * @param string $table_rows
79
-     * @return string
80
-     */
81
-    private function generateTicketDetailsTable(string $table_rows): string
82
-    {
83
-
84
-        return EEH_HTML::div(
85
-            EEH_HTML::table(
86
-                EEH_HTML::thead(
87
-                    EEH_HTML::tr(
88
-                        EEH_HTML::th('', '', 'ee-ticket-details-name jst-left')
89
-                        . EEH_HTML::th(esc_html__('Qty', 'event_espresso'), '', 'ee-ticket-details-qty jst-rght')
90
-                        . EEH_HTML::th(esc_html__('Price', 'event_espresso'), '', 'ee-ticket-details-price jst-rght')
91
-                        . EEH_HTML::th(esc_html__('Total', 'event_espresso'), '', 'ee-ticket-details-total jst-rght'),
92
-                    )
93
-                )
94
-                . EEH_HTML::tbody($table_rows),
95
-                '',
96
-                'spco-ticket-details'
97
-            ),
98
-            '',
99
-            'spco-ticket-info-dv'
100
-        );
101
-    }
102
-
103
-
104
-    /**
105
-     * @param EE_Ticket $ticket
106
-     * @return string
107
-     * @throws EE_Error
108
-     * @throws ReflectionException
109
-     */
110
-    private function generateTicketDetailsTableRow(EE_Ticket $ticket): string
111
-    {
112
-        $ticket_line_item = EEH_Line_Item::get_line_items_by_object_type_and_IDs(
113
-            $this->cart_grand_total,
114
-            'Ticket',
115
-            [$ticket->ID()]
116
-        );
117
-        $ticket_line_item = ! empty($ticket_line_item) ? reset($ticket_line_item) : $ticket_line_item;
118
-
119
-        $ticket_line_item_options = self::$ticket_line_item_options;
120
-        $ticket_line_item_options['extra_css']['row'] = "ticket-details-{$ticket->ID()}";
121
-
122
-
123
-        return $ticket_line_item instanceof EE_Line_Item
124
-            ? $this->line_item_display->display_line_item($ticket_line_item, $ticket_line_item_options)
125
-            : '';
126
-    }
16
+	private EE_Line_Item $cart_grand_total;
17
+	private EE_Line_Item_Display $line_item_display;
18
+
19
+	private bool $revisit;
20
+
21
+	private array $tickets = [];
22
+
23
+	private static array $ticket_line_item_options = [
24
+		'extra_css' => [
25
+			'row' => 'ee-ticket-details-row',
26
+			'name' => 'ee-ticket-details-name',
27
+			'qty' => 'ee-ticket-details-qty',
28
+			'price' => 'ee-ticket-details-price',
29
+			'total' => 'ee-ticket-details-total',
30
+		]
31
+	];
32
+
33
+
34
+	/**
35
+	 * @param EE_Line_Item $cart_grand_total
36
+	 * @param EE_Line_Item_Display $line_item_display
37
+	 * @param bool      $revisit
38
+	 */
39
+	public function __construct(EE_Line_Item $cart_grand_total, EE_Line_Item_Display $line_item_display, bool $revisit)
40
+	{
41
+		$this->cart_grand_total = $cart_grand_total;
42
+		$this->line_item_display = $line_item_display;
43
+		$this->revisit = $revisit;
44
+		parent::__construct();
45
+	}
46
+
47
+
48
+	/**
49
+	 * @throws EE_Error
50
+	 * @throws ReflectionException
51
+	 */
52
+	public function addTicket(EE_Ticket $ticket): void
53
+	{
54
+		if (! isset($this->tickets[ $ticket->ID() ])) {
55
+			$this->tickets[ $ticket->ID() ] = $ticket;
56
+		}
57
+	}
58
+
59
+
60
+	/**
61
+	 * @throws ReflectionException
62
+	 * @throws EE_Error
63
+	 */
64
+	public function get_html(): string
65
+	{
66
+		if ($this->revisit) {
67
+			return '';
68
+		}
69
+		$table_rows = '';
70
+		foreach ($this->tickets as $ticket) {
71
+			$table_rows .= $this->generateTicketDetailsTableRow($ticket);
72
+		}
73
+		return $this->generateTicketDetailsTable($table_rows);
74
+	}
75
+
76
+
77
+	/**
78
+	 * @param string $table_rows
79
+	 * @return string
80
+	 */
81
+	private function generateTicketDetailsTable(string $table_rows): string
82
+	{
83
+
84
+		return EEH_HTML::div(
85
+			EEH_HTML::table(
86
+				EEH_HTML::thead(
87
+					EEH_HTML::tr(
88
+						EEH_HTML::th('', '', 'ee-ticket-details-name jst-left')
89
+						. EEH_HTML::th(esc_html__('Qty', 'event_espresso'), '', 'ee-ticket-details-qty jst-rght')
90
+						. EEH_HTML::th(esc_html__('Price', 'event_espresso'), '', 'ee-ticket-details-price jst-rght')
91
+						. EEH_HTML::th(esc_html__('Total', 'event_espresso'), '', 'ee-ticket-details-total jst-rght'),
92
+					)
93
+				)
94
+				. EEH_HTML::tbody($table_rows),
95
+				'',
96
+				'spco-ticket-details'
97
+			),
98
+			'',
99
+			'spco-ticket-info-dv'
100
+		);
101
+	}
102
+
103
+
104
+	/**
105
+	 * @param EE_Ticket $ticket
106
+	 * @return string
107
+	 * @throws EE_Error
108
+	 * @throws ReflectionException
109
+	 */
110
+	private function generateTicketDetailsTableRow(EE_Ticket $ticket): string
111
+	{
112
+		$ticket_line_item = EEH_Line_Item::get_line_items_by_object_type_and_IDs(
113
+			$this->cart_grand_total,
114
+			'Ticket',
115
+			[$ticket->ID()]
116
+		);
117
+		$ticket_line_item = ! empty($ticket_line_item) ? reset($ticket_line_item) : $ticket_line_item;
118
+
119
+		$ticket_line_item_options = self::$ticket_line_item_options;
120
+		$ticket_line_item_options['extra_css']['row'] = "ticket-details-{$ticket->ID()}";
121
+
122
+
123
+		return $ticket_line_item instanceof EE_Line_Item
124
+			? $this->line_item_display->display_line_item($ticket_line_item, $ticket_line_item_options)
125
+			: '';
126
+	}
127 127
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -51,8 +51,8 @@
 block discarded – undo
51 51
      */
52 52
     public function addTicket(EE_Ticket $ticket): void
53 53
     {
54
-        if (! isset($this->tickets[ $ticket->ID() ])) {
55
-            $this->tickets[ $ticket->ID() ] = $ticket;
54
+        if ( ! isset($this->tickets[$ticket->ID()])) {
55
+            $this->tickets[$ticket->ID()] = $ticket;
56 56
         }
57 57
     }
58 58
 
Please login to merge, or discard this patch.
core/helpers/EEH_HTML.helper.php 2 patches
Indentation   +940 added lines, -940 removed lines patch added patch discarded remove patch
@@ -15,944 +15,944 @@
 block discarded – undo
15 15
  */
16 16
 class EEH_HTML
17 17
 {
18
-    private static ?EEH_HTML $_instance = null;
19
-
20
-    /**
21
-     * some initial formatting for table indentation
22
-     *
23
-     * @var int[]
24
-     */
25
-    private static array $_indent = [
26
-        'table' => 0,
27
-        'thead' => 1,
28
-        'tbody' => 1,
29
-        'tr'    => 2,
30
-        'th'    => 3,
31
-        'td'    => 3,
32
-        'div'   => 0,
33
-        'h1'    => 0,
34
-        'h2'    => 0,
35
-        'h3'    => 0,
36
-        'h4'    => 0,
37
-        'h5'    => 0,
38
-        'h6'    => 0,
39
-        'p'     => 0,
40
-        'ul'    => 0,
41
-        'li'    => 1,
42
-    ];
43
-
44
-
45
-    /**
46
-     * @singleton method used to instantiate class object
47
-     * @return EEH_HTML
48
-     */
49
-    public static function instance(): EEH_HTML
50
-    {
51
-        // check if class object is instantiated, and instantiated properly
52
-        if (! self::$_instance instanceof EEH_HTML) {
53
-            self::$_instance = new EEH_HTML();
54
-        }
55
-        return self::$_instance;
56
-    }
57
-
58
-
59
-    /**
60
-     * Generates an opening HTML <XX> tag and adds any passed attributes
61
-     * if passed content, it will also add that, as well as the closing </XX> tag
62
-     *
63
-     * @param string $tag
64
-     * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
65
-     * @param string $id               - html id attribute
66
-     * @param string $class            - html class attribute
67
-     * @param string $style            - html style attribute for applying inline styles
68
-     * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
69
-     * @param bool   $force_close
70
-     * @return string
71
-     */
72
-    protected static function _open_tag(
73
-        string $tag = 'div',
74
-        string $content = '',
75
-        string $id = '',
76
-        string $class = '',
77
-        string $style = '',
78
-        string $other_attributes = '',
79
-        bool $force_close = false
80
-    ): string {
81
-        $attributes = ! empty($id) ? ' id="' . trim(EEH_HTML::sanitize_id($id)) . '"' : '';
82
-        $attributes .= ! empty($class) ? ' class="' . trim($class) . '"' : '';
83
-        $attributes .= ! empty($style) ? ' style="' . trim($style) . '"' : '';
84
-        $attributes .= ! empty($other_attributes) ? ' ' . trim($other_attributes) : '';
85
-        $html       = EEH_HTML::nl(0, $tag) . '<' . $tag . $attributes . '>';
86
-        $html       .= trim($content) !== '' ? EEH_HTML::nl(1, $tag) . $content : '';
87
-        $indent     = ! empty($content) || $force_close;
88
-        $html       .= ! empty($content) || $force_close
89
-            ? EEH_HTML::_close_tag($tag, $id, $class, $indent, $content)
90
-            : '';
91
-        return $html;
92
-    }
93
-
94
-
95
-    /**
96
-     * Generates HTML closing </XX> tag - if passed the id or class attribute
97
-     * used for the opening tag, will append a comment
98
-     *
99
-     * @access protected
100
-     * @param string $tag
101
-     * @param string $id    - html id attribute
102
-     * @param string $class - html class attribute
103
-     * @param bool   $indent
104
-     * @param string $content
105
-     * @return string
106
-     */
107
-    protected static function _close_tag(
108
-        string $tag = 'div',
109
-        string $id = '',
110
-        string $class = '',
111
-        bool $indent = true,
112
-        string $content = ''
113
-    ): string {
114
-        $alotta_content = strlen($content) > 500;
115
-        $comment         = '';
116
-        if ($id && $alotta_content) {
117
-            $comment = EEH_HTML::comment('close ' . $id) . EEH_HTML::nl(0, $tag);
118
-        } elseif ($class && $alotta_content) {
119
-            $comment = EEH_HTML::comment('close ' . $class) . EEH_HTML::nl(0, $tag);
120
-        }
121
-        $html = $indent ? EEH_HTML::nl(-1, $tag) : '';
122
-        $html .= '</' . $tag . '>' . $comment;
123
-        return $html;
124
-    }
125
-
126
-
127
-    /**
128
-     *  div - generates HTML opening <div> tag and adds any passed attributes
129
-     *  to add an id use:       echo EEH_HTML::div( 'this is some content', 'footer' );
130
-     *  to add a class use:     echo EEH_HTML::div( 'this is some content', '', 'float_left' );
131
-     *  to add a both an id and a class use:    echo EEH_HTML::div( 'this is some content', 'footer', 'float_left' );
132
-     *
133
-     * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
134
-     * @param string $id               - html id attribute
135
-     * @param string $class            - html class attribute
136
-     * @param string $style            - html style attribute for applying inline styles
137
-     * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
138
-     * @return string
139
-     */
140
-    public static function div(
141
-        string $content = '',
142
-        string $id = '',
143
-        string $class = '',
144
-        string $style = '',
145
-        string $other_attributes = ''
146
-    ): string {
147
-        return EEH_HTML::_open_tag('div', $content, $id, $class, $style, $other_attributes);
148
-    }
149
-
150
-
151
-    /**
152
-     * Generates HTML closing </div> tag - if passed the id or class attribute used for the opening div tag, will
153
-     * append a comment usage: echo EEH_HTML::divx();
154
-     *
155
-     * @param string $id    - html id attribute
156
-     * @param string $class - html class attribute
157
-     * @return string
158
-     */
159
-    public static function divx(string $id = '', string $class = ''): string
160
-    {
161
-        return EEH_HTML::_close_tag('div', $id, $class);
162
-    }
163
-
164
-
165
-    /**
166
-     * Generates HTML <h1></h1> tags, inserts content, and adds any passed attributes
167
-     * usage: echo EEH_HTML::h1( 'This is a Heading' );
168
-     *
169
-     * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
170
-     * @param string $id               - html id attribute
171
-     * @param string $class            - html class attribute
172
-     * @param string $style            - html style attribute for applying inline styles
173
-     * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
174
-     * @return string
175
-     */
176
-    public static function h1(
177
-        string $content = '',
178
-        string $id = '',
179
-        string $class = '',
180
-        string $style = '',
181
-        string $other_attributes = ''
182
-    ): string {
183
-        return EEH_HTML::_open_tag('h1', $content, $id, $class, $style, $other_attributes, true);
184
-    }
185
-
186
-
187
-    /**
188
-     * Generates HTML <h2></h2> tags, inserts content, and adds any passed attributes
189
-     * usage: echo EEH_HTML::h2( 'This is a Heading' );
190
-     *
191
-     * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
192
-     * @param string $id               - html id attribute
193
-     * @param string $class            - html class attribute
194
-     * @param string $style            - html style attribute for applying inline styles
195
-     * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
196
-     * @return string
197
-     */
198
-    public static function h2(
199
-        string $content = '',
200
-        string $id = '',
201
-        string $class = '',
202
-        string $style = '',
203
-        string $other_attributes = ''
204
-    ): string {
205
-        return EEH_HTML::_open_tag('h2', $content, $id, $class, $style, $other_attributes, true);
206
-    }
207
-
208
-
209
-    /**
210
-     * Generates HTML <h3></h3> tags, inserts content, and adds any passed attributes
211
-     * usage: echo EEH_HTML::h3( 'This is a Heading' );
212
-     *
213
-     * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
214
-     * @param string $id               - html id attribute
215
-     * @param string $class            - html class attribute
216
-     * @param string $style            - html style attribute for applying inline styles
217
-     * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
218
-     * @return string
219
-     */
220
-    public static function h3(
221
-        string $content = '',
222
-        string $id = '',
223
-        string $class = '',
224
-        string $style = '',
225
-        string $other_attributes = ''
226
-    ): string {
227
-        return EEH_HTML::_open_tag('h3', $content, $id, $class, $style, $other_attributes, true);
228
-    }
229
-
230
-
231
-    /**
232
-     * Generates HTML <h4></h4> tags, inserts content, and adds any passed attributes
233
-     * usage: echo EEH_HTML::h4( 'This is a Heading' );
234
-     *
235
-     * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
236
-     * @param string $id               - html id attribute
237
-     * @param string $class            - html class attribute
238
-     * @param string $style            - html style attribute for applying inline styles
239
-     * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
240
-     * @return string
241
-     */
242
-    public static function h4(
243
-        string $content = '',
244
-        string $id = '',
245
-        string $class = '',
246
-        string $style = '',
247
-        string $other_attributes = ''
248
-    ): string {
249
-        return EEH_HTML::_open_tag('h4', $content, $id, $class, $style, $other_attributes, true);
250
-    }
251
-
252
-
253
-    /**
254
-     * Generates HTML <h5></h5> tags, inserts content, and adds any passed attributes
255
-     * usage: echo EEH_HTML::h5( 'This is a Heading' );
256
-     *
257
-     * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
258
-     * @param string $id               - html id attribute
259
-     * @param string $class            - html class attribute
260
-     * @param string $style            - html style attribute for applying inline styles
261
-     * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
262
-     * @return string
263
-     */
264
-    public static function h5(
265
-        string $content = '',
266
-        string $id = '',
267
-        string $class = '',
268
-        string $style = '',
269
-        string $other_attributes = ''
270
-    ): string {
271
-        return EEH_HTML::_open_tag('h5', $content, $id, $class, $style, $other_attributes, true);
272
-    }
273
-
274
-
275
-    /**
276
-     * Generates HTML <h6></h6> tags, inserts content, and adds any passed attributes
277
-     * usage: echo EEH_HTML::h6( 'This is a Heading' );
278
-     *
279
-     * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
280
-     * @param string $id               - html id attribute
281
-     * @param string $class            - html class attribute
282
-     * @param string $style            - html style attribute for applying inline styles
283
-     * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
284
-     * @return string
285
-     */
286
-    public static function h6(
287
-        string $content = '',
288
-        string $id = '',
289
-        string $class = '',
290
-        string $style = '',
291
-        string $other_attributes = ''
292
-    ): string {
293
-        return EEH_HTML::_open_tag('h6', $content, $id, $class, $style, $other_attributes, true);
294
-    }
295
-
296
-
297
-    /**
298
-     * Generates HTML <p></p> tags, inserts content, and adds any passed attributes
299
-     * usage: echo EEH_HTML::p( 'this is a paragraph' );
300
-     *
301
-     * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
302
-     * @param string $id               - html id attribute
303
-     * @param string $class            - html class attribute
304
-     * @param string $style            - html style attribute for applying inline styles
305
-     * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
306
-     * @return string
307
-     */
308
-    public static function p(
309
-        string $content = '',
310
-        string $id = '',
311
-        string $class = '',
312
-        string $style = '',
313
-        string $other_attributes = ''
314
-    ): string {
315
-        return EEH_HTML::_open_tag('p', $content, $id, $class, $style, $other_attributes, true);
316
-    }
317
-
318
-
319
-    /**
320
-     *  ul - generates HTML opening <ul> tag and adds any passed attributes
321
-     *  usage:      echo EEH_HTML::ul( 'my-list-id', 'my-list-class' );
322
-     *
323
-     * @param string $id               - html id attribute
324
-     * @param string $class            - html class attribute
325
-     * @param string $style            - html style attribute for applying inline styles
326
-     * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
327
-     * @return string
328
-     */
329
-    public static function ul(
330
-        string $id = '',
331
-        string $class = '',
332
-        string $style = '',
333
-        string $other_attributes = ''
334
-    ): string {
335
-        return EEH_HTML::_open_tag('ul', '', $id, $class, $style, $other_attributes);
336
-    }
337
-
338
-
339
-    /**
340
-     * Generates HTML closing </ul> tag - if passed the id or class attribute used for the opening ul tag, will append
341
-     * a comment usage: echo EEH_HTML::ulx();
342
-     *
343
-     * @param string $id    - html id attribute
344
-     * @param string $class - html class attribute
345
-     * @return string
346
-     */
347
-    public static function ulx(string $id = '', string $class = ''): string
348
-    {
349
-        return EEH_HTML::_close_tag('ul', $id, $class);
350
-    }
351
-
352
-
353
-    /**
354
-     * Generates HTML <li> tag, inserts content, and adds any passed attributes
355
-     * if passed content, it will also add that, as well as the closing </li> tag
356
-     * usage: echo EEH_HTML::li( 'this is a line item' );
357
-     *
358
-     * @param string $id               - html id attribute
359
-     * @param string $class            - html class attribute
360
-     * @param string $style            - html style attribute for applying inline styles
361
-     * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
362
-     * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
363
-     * @return string
364
-     */
365
-    public static function li(
366
-        string $content = '',
367
-        string $id = '',
368
-        string $class = '',
369
-        string $style = '',
370
-        string $other_attributes = ''
371
-    ): string {
372
-        return EEH_HTML::_open_tag('li', $content, $id, $class, $style, $other_attributes);
373
-    }
374
-
375
-
376
-    /**
377
-     * Generates HTML closing </li> tag - if passed the id or class attribute used for the opening ul tag, will append
378
-     * a comment usage: echo EEH_HTML::lix();
379
-     *
380
-     * @param string $id    - html id attribute
381
-     * @param string $class - html class attribute
382
-     * @return string
383
-     */
384
-    public static function lix(string $id = '', string $class = ''): string
385
-    {
386
-        return EEH_HTML::_close_tag('li', $id, $class);
387
-    }
388
-
389
-
390
-    /**
391
-     *    table - generates an HTML <table> tag and adds any passed attributes
392
-     *    usage: echo EEH_HTML::table();
393
-     *
394
-     * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
395
-     * @param string $id               - html id attribute
396
-     * @param string $class            - html class attribute
397
-     * @param string $style            - html style attribute for applying inline styles
398
-     * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
399
-     * @return string
400
-     */
401
-    public static function table(
402
-        string $content = '',
403
-        string $id = '',
404
-        string $class = '',
405
-        string $style = '',
406
-        string $other_attributes = ''
407
-    ): string {
408
-        return EEH_HTML::_open_tag('table', $content, $id, $class, $style, $other_attributes);
409
-    }
410
-
411
-
412
-    /**
413
-     * tablex - generates an HTML </table> tag - if passed the id or class attribute used for the opening ul tag, will
414
-     * append a comment
415
-     *
416
-     * @param string $id    - html id attribute
417
-     * @param string $class - html class attribute
418
-     * @return string
419
-     */
420
-    public static function tablex(string $id = '', string $class = ''): string
421
-    {
422
-        return EEH_HTML::_close_tag('table', $id, $class);
423
-    }
424
-
425
-
426
-    /**
427
-     *    thead - generates an HTML <thead> tag and adds any passed attributes
428
-     *    usage: echo EEH_HTML::thead();
429
-     *
430
-     * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
431
-     * @param string $id               - html id attribute
432
-     * @param string $class            - html class attribute
433
-     * @param string $style            - html style attribute for applying inline styles
434
-     * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
435
-     * @return string
436
-     */
437
-    public static function thead(
438
-        string $content = '',
439
-        string $id = '',
440
-        string $class = '',
441
-        string $style = '',
442
-        string $other_attributes = ''
443
-    ): string {
444
-        return EEH_HTML::_open_tag('thead', $content, $id, $class, $style, $other_attributes);
445
-    }
446
-
447
-
448
-    /**
449
-     * theadx - generates an HTML </thead> tag - if passed the id or class attribute used for the opening ul tag, will
450
-     * append a comment
451
-     *
452
-     * @param string $id    - html id attribute
453
-     * @param string $class - html class attribute
454
-     * @return string
455
-     */
456
-    public static function theadx(string $id = '', string $class = ''): string
457
-    {
458
-        return EEH_HTML::_close_tag('thead', $id, $class);
459
-    }
460
-
461
-
462
-    /**
463
-     *    tbody - generates an HTML <tbody> tag and adds any passed attributes
464
-     *    usage: echo EEH_HTML::tbody();
465
-     *
466
-     * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
467
-     * @param string $id               - html id attribute
468
-     * @param string $class            - html class attribute
469
-     * @param string $style            - html style attribute for applying inline styles
470
-     * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
471
-     * @return string
472
-     */
473
-    public static function tbody(
474
-        string $content = '',
475
-        string $id = '',
476
-        string $class = '',
477
-        string $style = '',
478
-        string $other_attributes = ''
479
-    ): string {
480
-        return EEH_HTML::_open_tag('tbody', $content, $id, $class, $style, $other_attributes);
481
-    }
482
-
483
-
484
-    /**
485
-     * tbodyx - generates an HTML </tbody> tag - if passed the id or class attribute used for the opening ul tag, will
486
-     * append a comment
487
-     *
488
-     * @param string $id    - html id attribute
489
-     * @param string $class - html class attribute
490
-     * @return string
491
-     */
492
-    public static function tbodyx(string $id = '', string $class = ''): string
493
-    {
494
-        return EEH_HTML::_close_tag('tbody', $id, $class);
495
-    }
496
-
497
-
498
-    /**
499
-     *    tr - generates an HTML <tr> tag and adds any passed attributes
500
-     *    usage: echo EEH_HTML::tr();
501
-     *
502
-     * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
503
-     * @param string $id               - html id attribute
504
-     * @param string $class            - html class attribute
505
-     * @param string $style            - html style attribute for applying inline styles
506
-     * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
507
-     * @return string
508
-     */
509
-    public static function tr(
510
-        string $content = '',
511
-        string $id = '',
512
-        string $class = '',
513
-        string $style = '',
514
-        string $other_attributes = ''
515
-    ): string {
516
-        return EEH_HTML::_open_tag('tr', $content, $id, $class, $style, $other_attributes);
517
-    }
518
-
519
-
520
-    /**
521
-     * trx - generates an HTML </tr> tag - if passed the id or class attribute used for the opening ul tag, will append
522
-     * a comment
523
-     *
524
-     * @param string $id    - html id attribute
525
-     * @param string $class - html class attribute
526
-     * @return string
527
-     */
528
-    public static function trx(string $id = '', string $class = ''): string
529
-    {
530
-        return EEH_HTML::_close_tag('tr', $id, $class);
531
-    }
532
-
533
-
534
-    /**
535
-     *    th - generates an HTML <th> tag and adds any passed attributes
536
-     *    usage: echo EEH_HTML::th();
537
-     *
538
-     * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
539
-     * @param string $id               - html id attribute
540
-     * @param string $class            - html class attribute
541
-     * @param string $style            - html style attribute for applying inline styles
542
-     * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
543
-     * @return string
544
-     */
545
-    public static function th(
546
-        string $content = '',
547
-        string $id = '',
548
-        string $class = '',
549
-        string $style = '',
550
-        string $other_attributes = 'scope="col"'
551
-    ): string {
552
-        return EEH_HTML::_open_tag('th', $content, $id, $class, $style, $other_attributes);
553
-    }
554
-
555
-
556
-    /**
557
-     * thx - generates an HTML </th> tag - if passed the id or class attribute used for the opening ul tag, will append
558
-     * a comment
559
-     *
560
-     * @param string $id    - html id attribute
561
-     * @param string $class - html class attribute
562
-     * @return string
563
-     */
564
-    public static function thx(string $id = '', string $class = ''): string
565
-    {
566
-        return EEH_HTML::_close_tag('th', $id, $class);
567
-    }
568
-
569
-
570
-    /**
571
-     *    td - generates an HTML <td> tag and adds any passed attributes
572
-     *    usage: echo EEH_HTML::td();
573
-     *
574
-     * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
575
-     * @param string $id               - html id attribute
576
-     * @param string $class            - html class attribute
577
-     * @param string $style            - html style attribute for applying inline styles
578
-     * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
579
-     * @return string
580
-     */
581
-    public static function td(
582
-        string $content = '',
583
-        string $id = '',
584
-        string $class = '',
585
-        string $style = '',
586
-        string $other_attributes = ''
587
-    ): string {
588
-        return EEH_HTML::_open_tag('td', $content, $id, $class, $style, $other_attributes);
589
-    }
590
-
591
-
592
-    /**
593
-     * tdx - generates an HTML </td> tag - if passed the id or class attribute used for the opening ul tag, will append
594
-     * a comment
595
-     *
596
-     * @param string $id    - html id attribute
597
-     * @param string $class - html class attribute
598
-     * @return string
599
-     */
600
-    public static function tdx(string $id = '', string $class = ''): string
601
-    {
602
-        return EEH_HTML::_close_tag('td', $id, $class);
603
-    }
604
-
605
-
606
-    /**
607
-     * no_row - for generating a "hidden" table row, good for embedding tables within tables
608
-     * generates a new table row with one td cell that spans however many columns you set
609
-     * removes all styles from the tr and td
610
-     *
611
-     * @param string $content
612
-     * @param int    $colspan
613
-     * @return string
614
-     */
615
-    public static function no_row(string $content = '', int $colspan = 2): string
616
-    {
617
-        return EEH_HTML::tr(
618
-            EEH_HTML::td($content, '', '', '', 'colspan="' . $colspan . '"'),
619
-            '',
620
-            'ee-no-row'
621
-        );
622
-    }
623
-
624
-
625
-    /**
626
-     * Generates HTML <a href="url">text</a> tags, inserts content, and adds any passed attributes
627
-     * usage: echo EEH_HTML::link( 'domain.com', 'this is a link' );
628
-     *
629
-     * @param string $href             URL to link to
630
-     * @param string $link_text        - the text that will become "hyperlinked"
631
-     * @param string $title            - html title attribute
632
-     * @param string $id               - html id attribute
633
-     * @param string $class            - html class attribute
634
-     * @param string $style            - html style attribute for applying inline styles
635
-     * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
636
-     * @return string
637
-     */
638
-    public static function link(
639
-        string $href = '',
640
-        string $link_text = '',
641
-        string $title = '',
642
-        string $id = '',
643
-        string $class = '',
644
-        string $style = '',
645
-        string $other_attributes = ''
646
-    ): string {
647
-        $link_text  = ! empty($link_text) ? $link_text : $href;
648
-        $attributes = ! empty($href) ? ' href="' . $href . '"' : '';
649
-        $attributes .= ! empty($id) ? ' id="' . EEH_HTML::sanitize_id($id) . '"' : '';
650
-        $attributes .= ! empty($class) ? ' class="' . $class . '"' : '';
651
-        $attributes .= ! empty($style) ? ' style="' . $style . '"' : '';
652
-        $attributes .= ! empty($title) ? ' title="' . esc_attr($title) . '"' : '';
653
-        $attributes .= ! empty($other_attributes) ? ' ' . $other_attributes : '';
654
-        return "<a$attributes>$link_text</a>";
655
-    }
656
-
657
-
658
-    /**
659
-     * Generates HTML <button>text</button> tags, inserts content, and adds any passed attributes
660
-     * usage: echo EEH_HTML::button( 'this is a button' );
661
-     *
662
-     * @param string $btn_text         - the text that will become "hyperlinked"
663
-     * @param string $class            - html class attribute
664
-     * @param string $aria_label       - aria-label attribute
665
-     * @param string $id               - html id attribute
666
-     * @param string $style            - html style attribute for applying inline styles
667
-     * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
668
-     * @return string
669
-     */
670
-    public static function button(
671
-        string $btn_text = '',
672
-        string $class = '',
673
-        string $aria_label = '',
674
-        string $id = '',
675
-        string $style = '',
676
-        string $other_attributes = ''
677
-    ): string {
678
-        $attributes = ! empty($aria_label) ? ' aria-label="' . $aria_label . '"' : '';
679
-        $attributes .= ! empty($id) ? ' id="' . EEH_HTML::sanitize_id($id) . '"' : '';
680
-        $attributes .= ! empty($class) ? ' class="' . $class . '"' : '';
681
-        $attributes .= ! empty($style) ? ' style="' . $style . '"' : '';
682
-        $attributes .= ! empty($other_attributes) ? ' ' . $other_attributes : '';
683
-        return "<button type='button' $attributes>$btn_text</button>";
684
-    }
685
-
686
-
687
-    /**
688
-     *    img - generates an HTML <img> tag and adds any passed attributes
689
-     *    usage: echo EEH_HTML::img();
690
-     *
691
-     * @param string $src              - html src attribute ie: the path or URL to the image
692
-     * @param string $alt              - html alt attribute
693
-     * @param string $id               - html id attribute
694
-     * @param string $class            - html class attribute
695
-     * @param string $style            - html style attribute for applying inline styles
696
-     * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
697
-     * @return string
698
-     */
699
-    public static function img(
700
-        string $src = '',
701
-        string $alt = '',
702
-        string $id = '',
703
-        string $class = '',
704
-        string $style = '',
705
-        string $other_attributes = ''
706
-    ): string {
707
-        $attributes = ! empty($src) ? ' src="' . esc_url_raw($src) . '"' : '';
708
-        $attributes .= ! empty($alt) ? ' alt="' . esc_attr($alt) . '"' : '';
709
-        $attributes .= ! empty($id) ? ' id="' . EEH_HTML::sanitize_id($id) . '"' : '';
710
-        $attributes .= ! empty($class) ? ' class="' . $class . '"' : '';
711
-        $attributes .= ! empty($style) ? ' style="' . $style . '"' : '';
712
-        $attributes .= ! empty($other_attributes) ? ' ' . $other_attributes : '';
713
-        return '<img' . $attributes . '/>';
714
-    }
715
-
716
-
717
-    /**
718
-     * Generates HTML <tag></tag> tags, inserts content, and adds any passed attributes
719
-     * usage: echo EEH_HTML::span( 'this is some inline text' );
720
-     *
721
-     * @param string $tag
722
-     * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
723
-     * @param string $id               - html id attribute
724
-     * @param string $class            - html class attribute
725
-     * @param string $style            - html style attribute for applying inline styles
726
-     * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
727
-     * @return string
728
-     */
729
-    protected static function _inline_tag(
730
-        string $tag = 'span',
731
-        string $content = '',
732
-        string $id = '',
733
-        string $class = '',
734
-        string $style = '',
735
-        string $other_attributes = ''
736
-    ): string {
737
-        $attributes = ! empty($id) ? ' id="' . EEH_HTML::sanitize_id($id) . '"' : '';
738
-        $attributes .= ! empty($class) ? ' class="' . $class . '"' : '';
739
-        $attributes .= ! empty($style) ? ' style="' . $style . '"' : '';
740
-        $attributes .= ! empty($other_attributes) ? ' ' . $other_attributes : '';
741
-        return '<' . $tag . ' ' . $attributes . '>' . $content . '</' . $tag . '>';
742
-    }
743
-
744
-
745
-    /**
746
-     * Generates HTML <label></label> tags, inserts content, and adds any passed attributes
747
-     * usage: echo EEH_HTML::span( 'this is some inline text' );
748
-     *
749
-     * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
750
-     * @param string $id               - html id attribute
751
-     * @param string $class            - html class attribute
752
-     * @param string $style            - html style attribute for applying inline styles
753
-     * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
754
-     * @return string
755
-     */
756
-    public static function label(
757
-        string $content = '',
758
-        string $id = '',
759
-        string $class = '',
760
-        string $style = '',
761
-        string $other_attributes = ''
762
-    ): string {
763
-        return EEH_HTML::_inline_tag('label', $content, $id, $class, $style, $other_attributes);
764
-    }
765
-
766
-
767
-    /**
768
-     * Generates HTML <span></span> tags, inserts content, and adds any passed attributes
769
-     * usage: echo EEH_HTML::span( 'this is some inline text' );
770
-     *
771
-     * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
772
-     * @param string $id               - html id attribute
773
-     * @param string $class            - html class attribute
774
-     * @param string $style            - html style attribute for applying inline styles
775
-     * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
776
-     * @return string
777
-     */
778
-    public static function span(
779
-        string $content = '',
780
-        string $id = '',
781
-        string $class = '',
782
-        string $style = '',
783
-        string $other_attributes = ''
784
-    ): string {
785
-        return EEH_HTML::_inline_tag('span', $content, $id, $class, $style, $other_attributes);
786
-    }
787
-
788
-
789
-    /**
790
-     * Generates HTML <span></span> tags, inserts content, and adds any passed attributes
791
-     * usage: echo EEH_HTML::span( 'this is some inline text' );
792
-     *
793
-     * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
794
-     * @param string $id               - html id attribute
795
-     * @param string $class            - html class attribute
796
-     * @param string $style            - html style attribute for applying inline styles
797
-     * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
798
-     * @return string
799
-     */
800
-    public static function strong(
801
-        string $content = '',
802
-        string $id = '',
803
-        string $class = '',
804
-        string $style = '',
805
-        string $other_attributes = ''
806
-    ): string {
807
-        return EEH_HTML::_inline_tag('strong', $content, $id, $class, $style, $other_attributes);
808
-    }
809
-
810
-
811
-    /**
812
-     * Generates an html <--  comment --> tag
813
-     *  usage: echo comment( 'this is a comment' );
814
-     *
815
-     * @param string $comment
816
-     * @return string
817
-     */
818
-    public static function comment(string $comment = ''): string
819
-    {
820
-        return ! empty($comment) ? EEH_HTML::nl() . '<!-- ' . $comment . ' -->' : '';
821
-    }
822
-
823
-
824
-    /**
825
-     * br - generates a line break
826
-     *
827
-     * @param int $number - the number of line breaks to return
828
-     * @return string
829
-     */
830
-    public static function br(int $number = 1): string
831
-    {
832
-        return str_repeat('<br />', $number);
833
-    }
834
-
835
-
836
-    /**
837
-     * nbsp - generates non-breaking space entities based on number supplied
838
-     *
839
-     * @param int $number - the number of non-breaking spaces to return
840
-     * @return string
841
-     */
842
-    public static function nbsp(int $number = 1): string
843
-    {
844
-        return str_repeat('&nbsp;', $number);
845
-    }
846
-
847
-
848
-    /**
849
-     * sanitize_id
850
-     * functionally does the same as the wp_core function sanitize_key except it does NOT use
851
-     * strtolower and allows capitals.
852
-     *
853
-     * @param string $id
854
-     * @return string
855
-     */
856
-    public static function sanitize_id(string $id = ''): string
857
-    {
858
-        $key = str_replace(' ', '-', trim($id));
859
-        return preg_replace('/[^a-zA-Z0-9_\-]/', '', $key);
860
-    }
861
-
862
-
863
-    /**
864
-     * return a newline and tabs ("nl" stands for "new line")
865
-     *
866
-     * @param int    $indent the number of tabs to ADD to the current indent (can be negative or zero)
867
-     * @param string $tag
868
-     * @return string - newline character plus # of indents passed (can be + or -)
869
-     */
870
-    public static function nl(int $indent = 0, string $tag = 'none'): string
871
-    {
872
-        $html = "\n";
873
-        EEH_HTML::indent($indent, $tag);
874
-        $html .= str_repeat("\t", EEH_HTML::$_indent[ $tag ]);
875
-        return $html;
876
-    }
877
-
878
-
879
-    /**
880
-     * Changes the indents used in EEH_HTML::nl. Often it's convenient to change
881
-     * the indentation level without actually creating a new line
882
-     *
883
-     * @param int    $indent can be negative to decrease the indentation level
884
-     * @param string $tag
885
-     */
886
-    public static function indent(int $indent, string $tag = 'none')
887
-    {
888
-        static $default_indentation = false;
889
-        if (! $default_indentation) {
890
-            EEH_HTML::_set_default_indentation();
891
-            $default_indentation = true;
892
-        }
893
-        if (! isset(EEH_HTML::$_indent[ $tag ])) {
894
-            EEH_HTML::$_indent[ $tag ] = 0;
895
-        }
896
-        EEH_HTML::$_indent[ $tag ] += $indent;
897
-        EEH_HTML::$_indent[ $tag ] = max(EEH_HTML::$_indent[ $tag ], 0);
898
-    }
899
-
900
-
901
-    /**
902
-     *  class _set_default_indentation
903
-     */
904
-    private static function _set_default_indentation()
905
-    {
906
-        // set some initial formatting for table indentation
907
-        EEH_HTML::$_indent = [
908
-            'none'     => 0,
909
-            'form'     => 0,
910
-            'radio'    => 0,
911
-            'checkbox' => 0,
912
-            'select'   => 0,
913
-            'option'   => 0,
914
-            'optgroup' => 0,
915
-            'table'    => 1,
916
-            'thead'    => 2,
917
-            'tbody'    => 2,
918
-            'tr'       => 3,
919
-            'th'       => 4,
920
-            'td'       => 4,
921
-            'div'      => 0,
922
-            'h1'       => 0,
923
-            'h2'       => 0,
924
-            'h3'       => 0,
925
-            'h4'       => 0,
926
-            'h5'       => 0,
927
-            'h6'       => 0,
928
-            'p'        => 0,
929
-            'ul'       => 0,
930
-            'li'       => 1,
931
-        ];
932
-    }
933
-
934
-
935
-    /**
936
-     * Retrieves the list of tags considered "simple", that are probably safe for
937
-     * use in inputs
938
-     *
939
-     * @return array
940
-     * @global array $allowedtags
941
-     */
942
-    public static function get_simple_tags(): array
943
-    {
944
-        global $allowedtags;
945
-        $tags_we_allow = array_merge_recursive(
946
-            $allowedtags,
947
-            [
948
-                'ol' => [],
949
-                'ul' => [],
950
-                'li' => [],
951
-                'br' => [],
952
-                'p'  => [],
953
-                'a'  => ['target'],
954
-            ]
955
-        );
956
-        return apply_filters('FHEE__EEH_HTML__get_simple_tags', $tags_we_allow);
957
-    }
18
+	private static ?EEH_HTML $_instance = null;
19
+
20
+	/**
21
+	 * some initial formatting for table indentation
22
+	 *
23
+	 * @var int[]
24
+	 */
25
+	private static array $_indent = [
26
+		'table' => 0,
27
+		'thead' => 1,
28
+		'tbody' => 1,
29
+		'tr'    => 2,
30
+		'th'    => 3,
31
+		'td'    => 3,
32
+		'div'   => 0,
33
+		'h1'    => 0,
34
+		'h2'    => 0,
35
+		'h3'    => 0,
36
+		'h4'    => 0,
37
+		'h5'    => 0,
38
+		'h6'    => 0,
39
+		'p'     => 0,
40
+		'ul'    => 0,
41
+		'li'    => 1,
42
+	];
43
+
44
+
45
+	/**
46
+	 * @singleton method used to instantiate class object
47
+	 * @return EEH_HTML
48
+	 */
49
+	public static function instance(): EEH_HTML
50
+	{
51
+		// check if class object is instantiated, and instantiated properly
52
+		if (! self::$_instance instanceof EEH_HTML) {
53
+			self::$_instance = new EEH_HTML();
54
+		}
55
+		return self::$_instance;
56
+	}
57
+
58
+
59
+	/**
60
+	 * Generates an opening HTML <XX> tag and adds any passed attributes
61
+	 * if passed content, it will also add that, as well as the closing </XX> tag
62
+	 *
63
+	 * @param string $tag
64
+	 * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
65
+	 * @param string $id               - html id attribute
66
+	 * @param string $class            - html class attribute
67
+	 * @param string $style            - html style attribute for applying inline styles
68
+	 * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
69
+	 * @param bool   $force_close
70
+	 * @return string
71
+	 */
72
+	protected static function _open_tag(
73
+		string $tag = 'div',
74
+		string $content = '',
75
+		string $id = '',
76
+		string $class = '',
77
+		string $style = '',
78
+		string $other_attributes = '',
79
+		bool $force_close = false
80
+	): string {
81
+		$attributes = ! empty($id) ? ' id="' . trim(EEH_HTML::sanitize_id($id)) . '"' : '';
82
+		$attributes .= ! empty($class) ? ' class="' . trim($class) . '"' : '';
83
+		$attributes .= ! empty($style) ? ' style="' . trim($style) . '"' : '';
84
+		$attributes .= ! empty($other_attributes) ? ' ' . trim($other_attributes) : '';
85
+		$html       = EEH_HTML::nl(0, $tag) . '<' . $tag . $attributes . '>';
86
+		$html       .= trim($content) !== '' ? EEH_HTML::nl(1, $tag) . $content : '';
87
+		$indent     = ! empty($content) || $force_close;
88
+		$html       .= ! empty($content) || $force_close
89
+			? EEH_HTML::_close_tag($tag, $id, $class, $indent, $content)
90
+			: '';
91
+		return $html;
92
+	}
93
+
94
+
95
+	/**
96
+	 * Generates HTML closing </XX> tag - if passed the id or class attribute
97
+	 * used for the opening tag, will append a comment
98
+	 *
99
+	 * @access protected
100
+	 * @param string $tag
101
+	 * @param string $id    - html id attribute
102
+	 * @param string $class - html class attribute
103
+	 * @param bool   $indent
104
+	 * @param string $content
105
+	 * @return string
106
+	 */
107
+	protected static function _close_tag(
108
+		string $tag = 'div',
109
+		string $id = '',
110
+		string $class = '',
111
+		bool $indent = true,
112
+		string $content = ''
113
+	): string {
114
+		$alotta_content = strlen($content) > 500;
115
+		$comment         = '';
116
+		if ($id && $alotta_content) {
117
+			$comment = EEH_HTML::comment('close ' . $id) . EEH_HTML::nl(0, $tag);
118
+		} elseif ($class && $alotta_content) {
119
+			$comment = EEH_HTML::comment('close ' . $class) . EEH_HTML::nl(0, $tag);
120
+		}
121
+		$html = $indent ? EEH_HTML::nl(-1, $tag) : '';
122
+		$html .= '</' . $tag . '>' . $comment;
123
+		return $html;
124
+	}
125
+
126
+
127
+	/**
128
+	 *  div - generates HTML opening <div> tag and adds any passed attributes
129
+	 *  to add an id use:       echo EEH_HTML::div( 'this is some content', 'footer' );
130
+	 *  to add a class use:     echo EEH_HTML::div( 'this is some content', '', 'float_left' );
131
+	 *  to add a both an id and a class use:    echo EEH_HTML::div( 'this is some content', 'footer', 'float_left' );
132
+	 *
133
+	 * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
134
+	 * @param string $id               - html id attribute
135
+	 * @param string $class            - html class attribute
136
+	 * @param string $style            - html style attribute for applying inline styles
137
+	 * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
138
+	 * @return string
139
+	 */
140
+	public static function div(
141
+		string $content = '',
142
+		string $id = '',
143
+		string $class = '',
144
+		string $style = '',
145
+		string $other_attributes = ''
146
+	): string {
147
+		return EEH_HTML::_open_tag('div', $content, $id, $class, $style, $other_attributes);
148
+	}
149
+
150
+
151
+	/**
152
+	 * Generates HTML closing </div> tag - if passed the id or class attribute used for the opening div tag, will
153
+	 * append a comment usage: echo EEH_HTML::divx();
154
+	 *
155
+	 * @param string $id    - html id attribute
156
+	 * @param string $class - html class attribute
157
+	 * @return string
158
+	 */
159
+	public static function divx(string $id = '', string $class = ''): string
160
+	{
161
+		return EEH_HTML::_close_tag('div', $id, $class);
162
+	}
163
+
164
+
165
+	/**
166
+	 * Generates HTML <h1></h1> tags, inserts content, and adds any passed attributes
167
+	 * usage: echo EEH_HTML::h1( 'This is a Heading' );
168
+	 *
169
+	 * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
170
+	 * @param string $id               - html id attribute
171
+	 * @param string $class            - html class attribute
172
+	 * @param string $style            - html style attribute for applying inline styles
173
+	 * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
174
+	 * @return string
175
+	 */
176
+	public static function h1(
177
+		string $content = '',
178
+		string $id = '',
179
+		string $class = '',
180
+		string $style = '',
181
+		string $other_attributes = ''
182
+	): string {
183
+		return EEH_HTML::_open_tag('h1', $content, $id, $class, $style, $other_attributes, true);
184
+	}
185
+
186
+
187
+	/**
188
+	 * Generates HTML <h2></h2> tags, inserts content, and adds any passed attributes
189
+	 * usage: echo EEH_HTML::h2( 'This is a Heading' );
190
+	 *
191
+	 * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
192
+	 * @param string $id               - html id attribute
193
+	 * @param string $class            - html class attribute
194
+	 * @param string $style            - html style attribute for applying inline styles
195
+	 * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
196
+	 * @return string
197
+	 */
198
+	public static function h2(
199
+		string $content = '',
200
+		string $id = '',
201
+		string $class = '',
202
+		string $style = '',
203
+		string $other_attributes = ''
204
+	): string {
205
+		return EEH_HTML::_open_tag('h2', $content, $id, $class, $style, $other_attributes, true);
206
+	}
207
+
208
+
209
+	/**
210
+	 * Generates HTML <h3></h3> tags, inserts content, and adds any passed attributes
211
+	 * usage: echo EEH_HTML::h3( 'This is a Heading' );
212
+	 *
213
+	 * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
214
+	 * @param string $id               - html id attribute
215
+	 * @param string $class            - html class attribute
216
+	 * @param string $style            - html style attribute for applying inline styles
217
+	 * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
218
+	 * @return string
219
+	 */
220
+	public static function h3(
221
+		string $content = '',
222
+		string $id = '',
223
+		string $class = '',
224
+		string $style = '',
225
+		string $other_attributes = ''
226
+	): string {
227
+		return EEH_HTML::_open_tag('h3', $content, $id, $class, $style, $other_attributes, true);
228
+	}
229
+
230
+
231
+	/**
232
+	 * Generates HTML <h4></h4> tags, inserts content, and adds any passed attributes
233
+	 * usage: echo EEH_HTML::h4( 'This is a Heading' );
234
+	 *
235
+	 * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
236
+	 * @param string $id               - html id attribute
237
+	 * @param string $class            - html class attribute
238
+	 * @param string $style            - html style attribute for applying inline styles
239
+	 * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
240
+	 * @return string
241
+	 */
242
+	public static function h4(
243
+		string $content = '',
244
+		string $id = '',
245
+		string $class = '',
246
+		string $style = '',
247
+		string $other_attributes = ''
248
+	): string {
249
+		return EEH_HTML::_open_tag('h4', $content, $id, $class, $style, $other_attributes, true);
250
+	}
251
+
252
+
253
+	/**
254
+	 * Generates HTML <h5></h5> tags, inserts content, and adds any passed attributes
255
+	 * usage: echo EEH_HTML::h5( 'This is a Heading' );
256
+	 *
257
+	 * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
258
+	 * @param string $id               - html id attribute
259
+	 * @param string $class            - html class attribute
260
+	 * @param string $style            - html style attribute for applying inline styles
261
+	 * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
262
+	 * @return string
263
+	 */
264
+	public static function h5(
265
+		string $content = '',
266
+		string $id = '',
267
+		string $class = '',
268
+		string $style = '',
269
+		string $other_attributes = ''
270
+	): string {
271
+		return EEH_HTML::_open_tag('h5', $content, $id, $class, $style, $other_attributes, true);
272
+	}
273
+
274
+
275
+	/**
276
+	 * Generates HTML <h6></h6> tags, inserts content, and adds any passed attributes
277
+	 * usage: echo EEH_HTML::h6( 'This is a Heading' );
278
+	 *
279
+	 * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
280
+	 * @param string $id               - html id attribute
281
+	 * @param string $class            - html class attribute
282
+	 * @param string $style            - html style attribute for applying inline styles
283
+	 * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
284
+	 * @return string
285
+	 */
286
+	public static function h6(
287
+		string $content = '',
288
+		string $id = '',
289
+		string $class = '',
290
+		string $style = '',
291
+		string $other_attributes = ''
292
+	): string {
293
+		return EEH_HTML::_open_tag('h6', $content, $id, $class, $style, $other_attributes, true);
294
+	}
295
+
296
+
297
+	/**
298
+	 * Generates HTML <p></p> tags, inserts content, and adds any passed attributes
299
+	 * usage: echo EEH_HTML::p( 'this is a paragraph' );
300
+	 *
301
+	 * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
302
+	 * @param string $id               - html id attribute
303
+	 * @param string $class            - html class attribute
304
+	 * @param string $style            - html style attribute for applying inline styles
305
+	 * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
306
+	 * @return string
307
+	 */
308
+	public static function p(
309
+		string $content = '',
310
+		string $id = '',
311
+		string $class = '',
312
+		string $style = '',
313
+		string $other_attributes = ''
314
+	): string {
315
+		return EEH_HTML::_open_tag('p', $content, $id, $class, $style, $other_attributes, true);
316
+	}
317
+
318
+
319
+	/**
320
+	 *  ul - generates HTML opening <ul> tag and adds any passed attributes
321
+	 *  usage:      echo EEH_HTML::ul( 'my-list-id', 'my-list-class' );
322
+	 *
323
+	 * @param string $id               - html id attribute
324
+	 * @param string $class            - html class attribute
325
+	 * @param string $style            - html style attribute for applying inline styles
326
+	 * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
327
+	 * @return string
328
+	 */
329
+	public static function ul(
330
+		string $id = '',
331
+		string $class = '',
332
+		string $style = '',
333
+		string $other_attributes = ''
334
+	): string {
335
+		return EEH_HTML::_open_tag('ul', '', $id, $class, $style, $other_attributes);
336
+	}
337
+
338
+
339
+	/**
340
+	 * Generates HTML closing </ul> tag - if passed the id or class attribute used for the opening ul tag, will append
341
+	 * a comment usage: echo EEH_HTML::ulx();
342
+	 *
343
+	 * @param string $id    - html id attribute
344
+	 * @param string $class - html class attribute
345
+	 * @return string
346
+	 */
347
+	public static function ulx(string $id = '', string $class = ''): string
348
+	{
349
+		return EEH_HTML::_close_tag('ul', $id, $class);
350
+	}
351
+
352
+
353
+	/**
354
+	 * Generates HTML <li> tag, inserts content, and adds any passed attributes
355
+	 * if passed content, it will also add that, as well as the closing </li> tag
356
+	 * usage: echo EEH_HTML::li( 'this is a line item' );
357
+	 *
358
+	 * @param string $id               - html id attribute
359
+	 * @param string $class            - html class attribute
360
+	 * @param string $style            - html style attribute for applying inline styles
361
+	 * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
362
+	 * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
363
+	 * @return string
364
+	 */
365
+	public static function li(
366
+		string $content = '',
367
+		string $id = '',
368
+		string $class = '',
369
+		string $style = '',
370
+		string $other_attributes = ''
371
+	): string {
372
+		return EEH_HTML::_open_tag('li', $content, $id, $class, $style, $other_attributes);
373
+	}
374
+
375
+
376
+	/**
377
+	 * Generates HTML closing </li> tag - if passed the id or class attribute used for the opening ul tag, will append
378
+	 * a comment usage: echo EEH_HTML::lix();
379
+	 *
380
+	 * @param string $id    - html id attribute
381
+	 * @param string $class - html class attribute
382
+	 * @return string
383
+	 */
384
+	public static function lix(string $id = '', string $class = ''): string
385
+	{
386
+		return EEH_HTML::_close_tag('li', $id, $class);
387
+	}
388
+
389
+
390
+	/**
391
+	 *    table - generates an HTML <table> tag and adds any passed attributes
392
+	 *    usage: echo EEH_HTML::table();
393
+	 *
394
+	 * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
395
+	 * @param string $id               - html id attribute
396
+	 * @param string $class            - html class attribute
397
+	 * @param string $style            - html style attribute for applying inline styles
398
+	 * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
399
+	 * @return string
400
+	 */
401
+	public static function table(
402
+		string $content = '',
403
+		string $id = '',
404
+		string $class = '',
405
+		string $style = '',
406
+		string $other_attributes = ''
407
+	): string {
408
+		return EEH_HTML::_open_tag('table', $content, $id, $class, $style, $other_attributes);
409
+	}
410
+
411
+
412
+	/**
413
+	 * tablex - generates an HTML </table> tag - if passed the id or class attribute used for the opening ul tag, will
414
+	 * append a comment
415
+	 *
416
+	 * @param string $id    - html id attribute
417
+	 * @param string $class - html class attribute
418
+	 * @return string
419
+	 */
420
+	public static function tablex(string $id = '', string $class = ''): string
421
+	{
422
+		return EEH_HTML::_close_tag('table', $id, $class);
423
+	}
424
+
425
+
426
+	/**
427
+	 *    thead - generates an HTML <thead> tag and adds any passed attributes
428
+	 *    usage: echo EEH_HTML::thead();
429
+	 *
430
+	 * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
431
+	 * @param string $id               - html id attribute
432
+	 * @param string $class            - html class attribute
433
+	 * @param string $style            - html style attribute for applying inline styles
434
+	 * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
435
+	 * @return string
436
+	 */
437
+	public static function thead(
438
+		string $content = '',
439
+		string $id = '',
440
+		string $class = '',
441
+		string $style = '',
442
+		string $other_attributes = ''
443
+	): string {
444
+		return EEH_HTML::_open_tag('thead', $content, $id, $class, $style, $other_attributes);
445
+	}
446
+
447
+
448
+	/**
449
+	 * theadx - generates an HTML </thead> tag - if passed the id or class attribute used for the opening ul tag, will
450
+	 * append a comment
451
+	 *
452
+	 * @param string $id    - html id attribute
453
+	 * @param string $class - html class attribute
454
+	 * @return string
455
+	 */
456
+	public static function theadx(string $id = '', string $class = ''): string
457
+	{
458
+		return EEH_HTML::_close_tag('thead', $id, $class);
459
+	}
460
+
461
+
462
+	/**
463
+	 *    tbody - generates an HTML <tbody> tag and adds any passed attributes
464
+	 *    usage: echo EEH_HTML::tbody();
465
+	 *
466
+	 * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
467
+	 * @param string $id               - html id attribute
468
+	 * @param string $class            - html class attribute
469
+	 * @param string $style            - html style attribute for applying inline styles
470
+	 * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
471
+	 * @return string
472
+	 */
473
+	public static function tbody(
474
+		string $content = '',
475
+		string $id = '',
476
+		string $class = '',
477
+		string $style = '',
478
+		string $other_attributes = ''
479
+	): string {
480
+		return EEH_HTML::_open_tag('tbody', $content, $id, $class, $style, $other_attributes);
481
+	}
482
+
483
+
484
+	/**
485
+	 * tbodyx - generates an HTML </tbody> tag - if passed the id or class attribute used for the opening ul tag, will
486
+	 * append a comment
487
+	 *
488
+	 * @param string $id    - html id attribute
489
+	 * @param string $class - html class attribute
490
+	 * @return string
491
+	 */
492
+	public static function tbodyx(string $id = '', string $class = ''): string
493
+	{
494
+		return EEH_HTML::_close_tag('tbody', $id, $class);
495
+	}
496
+
497
+
498
+	/**
499
+	 *    tr - generates an HTML <tr> tag and adds any passed attributes
500
+	 *    usage: echo EEH_HTML::tr();
501
+	 *
502
+	 * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
503
+	 * @param string $id               - html id attribute
504
+	 * @param string $class            - html class attribute
505
+	 * @param string $style            - html style attribute for applying inline styles
506
+	 * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
507
+	 * @return string
508
+	 */
509
+	public static function tr(
510
+		string $content = '',
511
+		string $id = '',
512
+		string $class = '',
513
+		string $style = '',
514
+		string $other_attributes = ''
515
+	): string {
516
+		return EEH_HTML::_open_tag('tr', $content, $id, $class, $style, $other_attributes);
517
+	}
518
+
519
+
520
+	/**
521
+	 * trx - generates an HTML </tr> tag - if passed the id or class attribute used for the opening ul tag, will append
522
+	 * a comment
523
+	 *
524
+	 * @param string $id    - html id attribute
525
+	 * @param string $class - html class attribute
526
+	 * @return string
527
+	 */
528
+	public static function trx(string $id = '', string $class = ''): string
529
+	{
530
+		return EEH_HTML::_close_tag('tr', $id, $class);
531
+	}
532
+
533
+
534
+	/**
535
+	 *    th - generates an HTML <th> tag and adds any passed attributes
536
+	 *    usage: echo EEH_HTML::th();
537
+	 *
538
+	 * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
539
+	 * @param string $id               - html id attribute
540
+	 * @param string $class            - html class attribute
541
+	 * @param string $style            - html style attribute for applying inline styles
542
+	 * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
543
+	 * @return string
544
+	 */
545
+	public static function th(
546
+		string $content = '',
547
+		string $id = '',
548
+		string $class = '',
549
+		string $style = '',
550
+		string $other_attributes = 'scope="col"'
551
+	): string {
552
+		return EEH_HTML::_open_tag('th', $content, $id, $class, $style, $other_attributes);
553
+	}
554
+
555
+
556
+	/**
557
+	 * thx - generates an HTML </th> tag - if passed the id or class attribute used for the opening ul tag, will append
558
+	 * a comment
559
+	 *
560
+	 * @param string $id    - html id attribute
561
+	 * @param string $class - html class attribute
562
+	 * @return string
563
+	 */
564
+	public static function thx(string $id = '', string $class = ''): string
565
+	{
566
+		return EEH_HTML::_close_tag('th', $id, $class);
567
+	}
568
+
569
+
570
+	/**
571
+	 *    td - generates an HTML <td> tag and adds any passed attributes
572
+	 *    usage: echo EEH_HTML::td();
573
+	 *
574
+	 * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
575
+	 * @param string $id               - html id attribute
576
+	 * @param string $class            - html class attribute
577
+	 * @param string $style            - html style attribute for applying inline styles
578
+	 * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
579
+	 * @return string
580
+	 */
581
+	public static function td(
582
+		string $content = '',
583
+		string $id = '',
584
+		string $class = '',
585
+		string $style = '',
586
+		string $other_attributes = ''
587
+	): string {
588
+		return EEH_HTML::_open_tag('td', $content, $id, $class, $style, $other_attributes);
589
+	}
590
+
591
+
592
+	/**
593
+	 * tdx - generates an HTML </td> tag - if passed the id or class attribute used for the opening ul tag, will append
594
+	 * a comment
595
+	 *
596
+	 * @param string $id    - html id attribute
597
+	 * @param string $class - html class attribute
598
+	 * @return string
599
+	 */
600
+	public static function tdx(string $id = '', string $class = ''): string
601
+	{
602
+		return EEH_HTML::_close_tag('td', $id, $class);
603
+	}
604
+
605
+
606
+	/**
607
+	 * no_row - for generating a "hidden" table row, good for embedding tables within tables
608
+	 * generates a new table row with one td cell that spans however many columns you set
609
+	 * removes all styles from the tr and td
610
+	 *
611
+	 * @param string $content
612
+	 * @param int    $colspan
613
+	 * @return string
614
+	 */
615
+	public static function no_row(string $content = '', int $colspan = 2): string
616
+	{
617
+		return EEH_HTML::tr(
618
+			EEH_HTML::td($content, '', '', '', 'colspan="' . $colspan . '"'),
619
+			'',
620
+			'ee-no-row'
621
+		);
622
+	}
623
+
624
+
625
+	/**
626
+	 * Generates HTML <a href="url">text</a> tags, inserts content, and adds any passed attributes
627
+	 * usage: echo EEH_HTML::link( 'domain.com', 'this is a link' );
628
+	 *
629
+	 * @param string $href             URL to link to
630
+	 * @param string $link_text        - the text that will become "hyperlinked"
631
+	 * @param string $title            - html title attribute
632
+	 * @param string $id               - html id attribute
633
+	 * @param string $class            - html class attribute
634
+	 * @param string $style            - html style attribute for applying inline styles
635
+	 * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
636
+	 * @return string
637
+	 */
638
+	public static function link(
639
+		string $href = '',
640
+		string $link_text = '',
641
+		string $title = '',
642
+		string $id = '',
643
+		string $class = '',
644
+		string $style = '',
645
+		string $other_attributes = ''
646
+	): string {
647
+		$link_text  = ! empty($link_text) ? $link_text : $href;
648
+		$attributes = ! empty($href) ? ' href="' . $href . '"' : '';
649
+		$attributes .= ! empty($id) ? ' id="' . EEH_HTML::sanitize_id($id) . '"' : '';
650
+		$attributes .= ! empty($class) ? ' class="' . $class . '"' : '';
651
+		$attributes .= ! empty($style) ? ' style="' . $style . '"' : '';
652
+		$attributes .= ! empty($title) ? ' title="' . esc_attr($title) . '"' : '';
653
+		$attributes .= ! empty($other_attributes) ? ' ' . $other_attributes : '';
654
+		return "<a$attributes>$link_text</a>";
655
+	}
656
+
657
+
658
+	/**
659
+	 * Generates HTML <button>text</button> tags, inserts content, and adds any passed attributes
660
+	 * usage: echo EEH_HTML::button( 'this is a button' );
661
+	 *
662
+	 * @param string $btn_text         - the text that will become "hyperlinked"
663
+	 * @param string $class            - html class attribute
664
+	 * @param string $aria_label       - aria-label attribute
665
+	 * @param string $id               - html id attribute
666
+	 * @param string $style            - html style attribute for applying inline styles
667
+	 * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
668
+	 * @return string
669
+	 */
670
+	public static function button(
671
+		string $btn_text = '',
672
+		string $class = '',
673
+		string $aria_label = '',
674
+		string $id = '',
675
+		string $style = '',
676
+		string $other_attributes = ''
677
+	): string {
678
+		$attributes = ! empty($aria_label) ? ' aria-label="' . $aria_label . '"' : '';
679
+		$attributes .= ! empty($id) ? ' id="' . EEH_HTML::sanitize_id($id) . '"' : '';
680
+		$attributes .= ! empty($class) ? ' class="' . $class . '"' : '';
681
+		$attributes .= ! empty($style) ? ' style="' . $style . '"' : '';
682
+		$attributes .= ! empty($other_attributes) ? ' ' . $other_attributes : '';
683
+		return "<button type='button' $attributes>$btn_text</button>";
684
+	}
685
+
686
+
687
+	/**
688
+	 *    img - generates an HTML <img> tag and adds any passed attributes
689
+	 *    usage: echo EEH_HTML::img();
690
+	 *
691
+	 * @param string $src              - html src attribute ie: the path or URL to the image
692
+	 * @param string $alt              - html alt attribute
693
+	 * @param string $id               - html id attribute
694
+	 * @param string $class            - html class attribute
695
+	 * @param string $style            - html style attribute for applying inline styles
696
+	 * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
697
+	 * @return string
698
+	 */
699
+	public static function img(
700
+		string $src = '',
701
+		string $alt = '',
702
+		string $id = '',
703
+		string $class = '',
704
+		string $style = '',
705
+		string $other_attributes = ''
706
+	): string {
707
+		$attributes = ! empty($src) ? ' src="' . esc_url_raw($src) . '"' : '';
708
+		$attributes .= ! empty($alt) ? ' alt="' . esc_attr($alt) . '"' : '';
709
+		$attributes .= ! empty($id) ? ' id="' . EEH_HTML::sanitize_id($id) . '"' : '';
710
+		$attributes .= ! empty($class) ? ' class="' . $class . '"' : '';
711
+		$attributes .= ! empty($style) ? ' style="' . $style . '"' : '';
712
+		$attributes .= ! empty($other_attributes) ? ' ' . $other_attributes : '';
713
+		return '<img' . $attributes . '/>';
714
+	}
715
+
716
+
717
+	/**
718
+	 * Generates HTML <tag></tag> tags, inserts content, and adds any passed attributes
719
+	 * usage: echo EEH_HTML::span( 'this is some inline text' );
720
+	 *
721
+	 * @param string $tag
722
+	 * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
723
+	 * @param string $id               - html id attribute
724
+	 * @param string $class            - html class attribute
725
+	 * @param string $style            - html style attribute for applying inline styles
726
+	 * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
727
+	 * @return string
728
+	 */
729
+	protected static function _inline_tag(
730
+		string $tag = 'span',
731
+		string $content = '',
732
+		string $id = '',
733
+		string $class = '',
734
+		string $style = '',
735
+		string $other_attributes = ''
736
+	): string {
737
+		$attributes = ! empty($id) ? ' id="' . EEH_HTML::sanitize_id($id) . '"' : '';
738
+		$attributes .= ! empty($class) ? ' class="' . $class . '"' : '';
739
+		$attributes .= ! empty($style) ? ' style="' . $style . '"' : '';
740
+		$attributes .= ! empty($other_attributes) ? ' ' . $other_attributes : '';
741
+		return '<' . $tag . ' ' . $attributes . '>' . $content . '</' . $tag . '>';
742
+	}
743
+
744
+
745
+	/**
746
+	 * Generates HTML <label></label> tags, inserts content, and adds any passed attributes
747
+	 * usage: echo EEH_HTML::span( 'this is some inline text' );
748
+	 *
749
+	 * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
750
+	 * @param string $id               - html id attribute
751
+	 * @param string $class            - html class attribute
752
+	 * @param string $style            - html style attribute for applying inline styles
753
+	 * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
754
+	 * @return string
755
+	 */
756
+	public static function label(
757
+		string $content = '',
758
+		string $id = '',
759
+		string $class = '',
760
+		string $style = '',
761
+		string $other_attributes = ''
762
+	): string {
763
+		return EEH_HTML::_inline_tag('label', $content, $id, $class, $style, $other_attributes);
764
+	}
765
+
766
+
767
+	/**
768
+	 * Generates HTML <span></span> tags, inserts content, and adds any passed attributes
769
+	 * usage: echo EEH_HTML::span( 'this is some inline text' );
770
+	 *
771
+	 * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
772
+	 * @param string $id               - html id attribute
773
+	 * @param string $class            - html class attribute
774
+	 * @param string $style            - html style attribute for applying inline styles
775
+	 * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
776
+	 * @return string
777
+	 */
778
+	public static function span(
779
+		string $content = '',
780
+		string $id = '',
781
+		string $class = '',
782
+		string $style = '',
783
+		string $other_attributes = ''
784
+	): string {
785
+		return EEH_HTML::_inline_tag('span', $content, $id, $class, $style, $other_attributes);
786
+	}
787
+
788
+
789
+	/**
790
+	 * Generates HTML <span></span> tags, inserts content, and adds any passed attributes
791
+	 * usage: echo EEH_HTML::span( 'this is some inline text' );
792
+	 *
793
+	 * @param string $content          - inserted after opening tag, and appends closing tag, otherwise tag is left open
794
+	 * @param string $id               - html id attribute
795
+	 * @param string $class            - html class attribute
796
+	 * @param string $style            - html style attribute for applying inline styles
797
+	 * @param string $other_attributes - additional attributes like "colspan", inline JS, "rel" tags, etc
798
+	 * @return string
799
+	 */
800
+	public static function strong(
801
+		string $content = '',
802
+		string $id = '',
803
+		string $class = '',
804
+		string $style = '',
805
+		string $other_attributes = ''
806
+	): string {
807
+		return EEH_HTML::_inline_tag('strong', $content, $id, $class, $style, $other_attributes);
808
+	}
809
+
810
+
811
+	/**
812
+	 * Generates an html <--  comment --> tag
813
+	 *  usage: echo comment( 'this is a comment' );
814
+	 *
815
+	 * @param string $comment
816
+	 * @return string
817
+	 */
818
+	public static function comment(string $comment = ''): string
819
+	{
820
+		return ! empty($comment) ? EEH_HTML::nl() . '<!-- ' . $comment . ' -->' : '';
821
+	}
822
+
823
+
824
+	/**
825
+	 * br - generates a line break
826
+	 *
827
+	 * @param int $number - the number of line breaks to return
828
+	 * @return string
829
+	 */
830
+	public static function br(int $number = 1): string
831
+	{
832
+		return str_repeat('<br />', $number);
833
+	}
834
+
835
+
836
+	/**
837
+	 * nbsp - generates non-breaking space entities based on number supplied
838
+	 *
839
+	 * @param int $number - the number of non-breaking spaces to return
840
+	 * @return string
841
+	 */
842
+	public static function nbsp(int $number = 1): string
843
+	{
844
+		return str_repeat('&nbsp;', $number);
845
+	}
846
+
847
+
848
+	/**
849
+	 * sanitize_id
850
+	 * functionally does the same as the wp_core function sanitize_key except it does NOT use
851
+	 * strtolower and allows capitals.
852
+	 *
853
+	 * @param string $id
854
+	 * @return string
855
+	 */
856
+	public static function sanitize_id(string $id = ''): string
857
+	{
858
+		$key = str_replace(' ', '-', trim($id));
859
+		return preg_replace('/[^a-zA-Z0-9_\-]/', '', $key);
860
+	}
861
+
862
+
863
+	/**
864
+	 * return a newline and tabs ("nl" stands for "new line")
865
+	 *
866
+	 * @param int    $indent the number of tabs to ADD to the current indent (can be negative or zero)
867
+	 * @param string $tag
868
+	 * @return string - newline character plus # of indents passed (can be + or -)
869
+	 */
870
+	public static function nl(int $indent = 0, string $tag = 'none'): string
871
+	{
872
+		$html = "\n";
873
+		EEH_HTML::indent($indent, $tag);
874
+		$html .= str_repeat("\t", EEH_HTML::$_indent[ $tag ]);
875
+		return $html;
876
+	}
877
+
878
+
879
+	/**
880
+	 * Changes the indents used in EEH_HTML::nl. Often it's convenient to change
881
+	 * the indentation level without actually creating a new line
882
+	 *
883
+	 * @param int    $indent can be negative to decrease the indentation level
884
+	 * @param string $tag
885
+	 */
886
+	public static function indent(int $indent, string $tag = 'none')
887
+	{
888
+		static $default_indentation = false;
889
+		if (! $default_indentation) {
890
+			EEH_HTML::_set_default_indentation();
891
+			$default_indentation = true;
892
+		}
893
+		if (! isset(EEH_HTML::$_indent[ $tag ])) {
894
+			EEH_HTML::$_indent[ $tag ] = 0;
895
+		}
896
+		EEH_HTML::$_indent[ $tag ] += $indent;
897
+		EEH_HTML::$_indent[ $tag ] = max(EEH_HTML::$_indent[ $tag ], 0);
898
+	}
899
+
900
+
901
+	/**
902
+	 *  class _set_default_indentation
903
+	 */
904
+	private static function _set_default_indentation()
905
+	{
906
+		// set some initial formatting for table indentation
907
+		EEH_HTML::$_indent = [
908
+			'none'     => 0,
909
+			'form'     => 0,
910
+			'radio'    => 0,
911
+			'checkbox' => 0,
912
+			'select'   => 0,
913
+			'option'   => 0,
914
+			'optgroup' => 0,
915
+			'table'    => 1,
916
+			'thead'    => 2,
917
+			'tbody'    => 2,
918
+			'tr'       => 3,
919
+			'th'       => 4,
920
+			'td'       => 4,
921
+			'div'      => 0,
922
+			'h1'       => 0,
923
+			'h2'       => 0,
924
+			'h3'       => 0,
925
+			'h4'       => 0,
926
+			'h5'       => 0,
927
+			'h6'       => 0,
928
+			'p'        => 0,
929
+			'ul'       => 0,
930
+			'li'       => 1,
931
+		];
932
+	}
933
+
934
+
935
+	/**
936
+	 * Retrieves the list of tags considered "simple", that are probably safe for
937
+	 * use in inputs
938
+	 *
939
+	 * @return array
940
+	 * @global array $allowedtags
941
+	 */
942
+	public static function get_simple_tags(): array
943
+	{
944
+		global $allowedtags;
945
+		$tags_we_allow = array_merge_recursive(
946
+			$allowedtags,
947
+			[
948
+				'ol' => [],
949
+				'ul' => [],
950
+				'li' => [],
951
+				'br' => [],
952
+				'p'  => [],
953
+				'a'  => ['target'],
954
+			]
955
+		);
956
+		return apply_filters('FHEE__EEH_HTML__get_simple_tags', $tags_we_allow);
957
+	}
958 958
 }
Please login to merge, or discard this patch.
Spacing   +42 added lines, -42 removed lines patch added patch discarded remove patch
@@ -49,7 +49,7 @@  discard block
 block discarded – undo
49 49
     public static function instance(): EEH_HTML
50 50
     {
51 51
         // check if class object is instantiated, and instantiated properly
52
-        if (! self::$_instance instanceof EEH_HTML) {
52
+        if ( ! self::$_instance instanceof EEH_HTML) {
53 53
             self::$_instance = new EEH_HTML();
54 54
         }
55 55
         return self::$_instance;
@@ -78,12 +78,12 @@  discard block
 block discarded – undo
78 78
         string $other_attributes = '',
79 79
         bool $force_close = false
80 80
     ): string {
81
-        $attributes = ! empty($id) ? ' id="' . trim(EEH_HTML::sanitize_id($id)) . '"' : '';
82
-        $attributes .= ! empty($class) ? ' class="' . trim($class) . '"' : '';
83
-        $attributes .= ! empty($style) ? ' style="' . trim($style) . '"' : '';
84
-        $attributes .= ! empty($other_attributes) ? ' ' . trim($other_attributes) : '';
85
-        $html       = EEH_HTML::nl(0, $tag) . '<' . $tag . $attributes . '>';
86
-        $html       .= trim($content) !== '' ? EEH_HTML::nl(1, $tag) . $content : '';
81
+        $attributes = ! empty($id) ? ' id="'.trim(EEH_HTML::sanitize_id($id)).'"' : '';
82
+        $attributes .= ! empty($class) ? ' class="'.trim($class).'"' : '';
83
+        $attributes .= ! empty($style) ? ' style="'.trim($style).'"' : '';
84
+        $attributes .= ! empty($other_attributes) ? ' '.trim($other_attributes) : '';
85
+        $html       = EEH_HTML::nl(0, $tag).'<'.$tag.$attributes.'>';
86
+        $html       .= trim($content) !== '' ? EEH_HTML::nl(1, $tag).$content : '';
87 87
         $indent     = ! empty($content) || $force_close;
88 88
         $html       .= ! empty($content) || $force_close
89 89
             ? EEH_HTML::_close_tag($tag, $id, $class, $indent, $content)
@@ -112,14 +112,14 @@  discard block
 block discarded – undo
112 112
         string $content = ''
113 113
     ): string {
114 114
         $alotta_content = strlen($content) > 500;
115
-        $comment         = '';
115
+        $comment = '';
116 116
         if ($id && $alotta_content) {
117
-            $comment = EEH_HTML::comment('close ' . $id) . EEH_HTML::nl(0, $tag);
117
+            $comment = EEH_HTML::comment('close '.$id).EEH_HTML::nl(0, $tag);
118 118
         } elseif ($class && $alotta_content) {
119
-            $comment = EEH_HTML::comment('close ' . $class) . EEH_HTML::nl(0, $tag);
119
+            $comment = EEH_HTML::comment('close '.$class).EEH_HTML::nl(0, $tag);
120 120
         }
121 121
         $html = $indent ? EEH_HTML::nl(-1, $tag) : '';
122
-        $html .= '</' . $tag . '>' . $comment;
122
+        $html .= '</'.$tag.'>'.$comment;
123 123
         return $html;
124 124
     }
125 125
 
@@ -615,7 +615,7 @@  discard block
 block discarded – undo
615 615
     public static function no_row(string $content = '', int $colspan = 2): string
616 616
     {
617 617
         return EEH_HTML::tr(
618
-            EEH_HTML::td($content, '', '', '', 'colspan="' . $colspan . '"'),
618
+            EEH_HTML::td($content, '', '', '', 'colspan="'.$colspan.'"'),
619 619
             '',
620 620
             'ee-no-row'
621 621
         );
@@ -645,12 +645,12 @@  discard block
 block discarded – undo
645 645
         string $other_attributes = ''
646 646
     ): string {
647 647
         $link_text  = ! empty($link_text) ? $link_text : $href;
648
-        $attributes = ! empty($href) ? ' href="' . $href . '"' : '';
649
-        $attributes .= ! empty($id) ? ' id="' . EEH_HTML::sanitize_id($id) . '"' : '';
650
-        $attributes .= ! empty($class) ? ' class="' . $class . '"' : '';
651
-        $attributes .= ! empty($style) ? ' style="' . $style . '"' : '';
652
-        $attributes .= ! empty($title) ? ' title="' . esc_attr($title) . '"' : '';
653
-        $attributes .= ! empty($other_attributes) ? ' ' . $other_attributes : '';
648
+        $attributes = ! empty($href) ? ' href="'.$href.'"' : '';
649
+        $attributes .= ! empty($id) ? ' id="'.EEH_HTML::sanitize_id($id).'"' : '';
650
+        $attributes .= ! empty($class) ? ' class="'.$class.'"' : '';
651
+        $attributes .= ! empty($style) ? ' style="'.$style.'"' : '';
652
+        $attributes .= ! empty($title) ? ' title="'.esc_attr($title).'"' : '';
653
+        $attributes .= ! empty($other_attributes) ? ' '.$other_attributes : '';
654 654
         return "<a$attributes>$link_text</a>";
655 655
     }
656 656
 
@@ -675,11 +675,11 @@  discard block
 block discarded – undo
675 675
         string $style = '',
676 676
         string $other_attributes = ''
677 677
     ): string {
678
-        $attributes = ! empty($aria_label) ? ' aria-label="' . $aria_label . '"' : '';
679
-        $attributes .= ! empty($id) ? ' id="' . EEH_HTML::sanitize_id($id) . '"' : '';
680
-        $attributes .= ! empty($class) ? ' class="' . $class . '"' : '';
681
-        $attributes .= ! empty($style) ? ' style="' . $style . '"' : '';
682
-        $attributes .= ! empty($other_attributes) ? ' ' . $other_attributes : '';
678
+        $attributes = ! empty($aria_label) ? ' aria-label="'.$aria_label.'"' : '';
679
+        $attributes .= ! empty($id) ? ' id="'.EEH_HTML::sanitize_id($id).'"' : '';
680
+        $attributes .= ! empty($class) ? ' class="'.$class.'"' : '';
681
+        $attributes .= ! empty($style) ? ' style="'.$style.'"' : '';
682
+        $attributes .= ! empty($other_attributes) ? ' '.$other_attributes : '';
683 683
         return "<button type='button' $attributes>$btn_text</button>";
684 684
     }
685 685
 
@@ -704,13 +704,13 @@  discard block
 block discarded – undo
704 704
         string $style = '',
705 705
         string $other_attributes = ''
706 706
     ): string {
707
-        $attributes = ! empty($src) ? ' src="' . esc_url_raw($src) . '"' : '';
708
-        $attributes .= ! empty($alt) ? ' alt="' . esc_attr($alt) . '"' : '';
709
-        $attributes .= ! empty($id) ? ' id="' . EEH_HTML::sanitize_id($id) . '"' : '';
710
-        $attributes .= ! empty($class) ? ' class="' . $class . '"' : '';
711
-        $attributes .= ! empty($style) ? ' style="' . $style . '"' : '';
712
-        $attributes .= ! empty($other_attributes) ? ' ' . $other_attributes : '';
713
-        return '<img' . $attributes . '/>';
707
+        $attributes = ! empty($src) ? ' src="'.esc_url_raw($src).'"' : '';
708
+        $attributes .= ! empty($alt) ? ' alt="'.esc_attr($alt).'"' : '';
709
+        $attributes .= ! empty($id) ? ' id="'.EEH_HTML::sanitize_id($id).'"' : '';
710
+        $attributes .= ! empty($class) ? ' class="'.$class.'"' : '';
711
+        $attributes .= ! empty($style) ? ' style="'.$style.'"' : '';
712
+        $attributes .= ! empty($other_attributes) ? ' '.$other_attributes : '';
713
+        return '<img'.$attributes.'/>';
714 714
     }
715 715
 
716 716
 
@@ -734,11 +734,11 @@  discard block
 block discarded – undo
734 734
         string $style = '',
735 735
         string $other_attributes = ''
736 736
     ): string {
737
-        $attributes = ! empty($id) ? ' id="' . EEH_HTML::sanitize_id($id) . '"' : '';
738
-        $attributes .= ! empty($class) ? ' class="' . $class . '"' : '';
739
-        $attributes .= ! empty($style) ? ' style="' . $style . '"' : '';
740
-        $attributes .= ! empty($other_attributes) ? ' ' . $other_attributes : '';
741
-        return '<' . $tag . ' ' . $attributes . '>' . $content . '</' . $tag . '>';
737
+        $attributes = ! empty($id) ? ' id="'.EEH_HTML::sanitize_id($id).'"' : '';
738
+        $attributes .= ! empty($class) ? ' class="'.$class.'"' : '';
739
+        $attributes .= ! empty($style) ? ' style="'.$style.'"' : '';
740
+        $attributes .= ! empty($other_attributes) ? ' '.$other_attributes : '';
741
+        return '<'.$tag.' '.$attributes.'>'.$content.'</'.$tag.'>';
742 742
     }
743 743
 
744 744
 
@@ -817,7 +817,7 @@  discard block
 block discarded – undo
817 817
      */
818 818
     public static function comment(string $comment = ''): string
819 819
     {
820
-        return ! empty($comment) ? EEH_HTML::nl() . '<!-- ' . $comment . ' -->' : '';
820
+        return ! empty($comment) ? EEH_HTML::nl().'<!-- '.$comment.' -->' : '';
821 821
     }
822 822
 
823 823
 
@@ -871,7 +871,7 @@  discard block
 block discarded – undo
871 871
     {
872 872
         $html = "\n";
873 873
         EEH_HTML::indent($indent, $tag);
874
-        $html .= str_repeat("\t", EEH_HTML::$_indent[ $tag ]);
874
+        $html .= str_repeat("\t", EEH_HTML::$_indent[$tag]);
875 875
         return $html;
876 876
     }
877 877
 
@@ -886,15 +886,15 @@  discard block
 block discarded – undo
886 886
     public static function indent(int $indent, string $tag = 'none')
887 887
     {
888 888
         static $default_indentation = false;
889
-        if (! $default_indentation) {
889
+        if ( ! $default_indentation) {
890 890
             EEH_HTML::_set_default_indentation();
891 891
             $default_indentation = true;
892 892
         }
893
-        if (! isset(EEH_HTML::$_indent[ $tag ])) {
894
-            EEH_HTML::$_indent[ $tag ] = 0;
893
+        if ( ! isset(EEH_HTML::$_indent[$tag])) {
894
+            EEH_HTML::$_indent[$tag] = 0;
895 895
         }
896
-        EEH_HTML::$_indent[ $tag ] += $indent;
897
-        EEH_HTML::$_indent[ $tag ] = max(EEH_HTML::$_indent[ $tag ], 0);
896
+        EEH_HTML::$_indent[$tag] += $indent;
897
+        EEH_HTML::$_indent[$tag] = max(EEH_HTML::$_indent[$tag], 0);
898 898
     }
899 899
 
900 900
 
Please login to merge, or discard this patch.