Completed
Branch fix/kses-6 (dd7b82)
by
unknown
09:41 queued 07:30
created
admin_pages/payments/Payments_Admin_Page.core.php 2 patches
Indentation   +1191 added lines, -1191 removed lines patch added patch discarded remove patch
@@ -16,1195 +16,1195 @@
 block discarded – undo
16 16
 class Payments_Admin_Page extends EE_Admin_Page
17 17
 {
18 18
 
19
-    /**
20
-     * Variables used for when we're re-sorting the logs results,
21
-     * in case we needed to do two queries, and we need to resort
22
-     *
23
-     * @var string
24
-     */
25
-    private $_sort_logs_again_direction;
26
-
27
-
28
-    /**
29
-     * @Constructor
30
-     * @access public
31
-     * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
32
-     * @throws EE_Error
33
-     * @throws InvalidArgumentException
34
-     * @throws InvalidDataTypeException
35
-     * @throws InvalidInterfaceException
36
-     * @throws ReflectionException
37
-     */
38
-    public function __construct($routing = true)
39
-    {
40
-        parent::__construct($routing);
41
-    }
42
-
43
-
44
-    protected function _init_page_props()
45
-    {
46
-        $this->page_slug = EE_PAYMENTS_PG_SLUG;
47
-        $this->page_label = esc_html__('Payment Methods', 'event_espresso');
48
-        $this->_admin_base_url = EE_PAYMENTS_ADMIN_URL;
49
-        $this->_admin_base_path = EE_PAYMENTS_ADMIN;
50
-    }
51
-
52
-
53
-    protected function _ajax_hooks()
54
-    {
55
-        // todo: all hooks for ajax goes here.
56
-    }
57
-
58
-
59
-    protected function _define_page_props()
60
-    {
61
-        $this->_admin_page_title = $this->page_label;
62
-        $this->_labels = array(
63
-            'publishbox' => esc_html__('Update Settings', 'event_espresso'),
64
-        );
65
-    }
66
-
67
-
68
-    protected function _set_page_routes()
69
-    {
70
-        /**
71
-         * note that with payment method capabilities, although we've implemented
72
-         * capability mapping which will be used for accessing payment methods owned by
73
-         * other users.  This is not fully implemented yet in the payment method ui.
74
-         * Currently, only the "plural" caps are in active use.
75
-         * When cap mapping is implemented, some routes will need to use the singular form of
76
-         * capability method and also include the $id of the payment method for the route.
77
-         **/
78
-        $this->_page_routes = array(
79
-            'default'                   => array(
80
-                'func'       => '_payment_methods_list',
81
-                'capability' => 'ee_edit_payment_methods',
82
-            ),
83
-            'payment_settings'          => array(
84
-                'func'       => '_payment_settings',
85
-                'capability' => 'ee_manage_gateways',
86
-            ),
87
-            'activate_payment_method'   => array(
88
-                'func'       => '_activate_payment_method',
89
-                'noheader'   => true,
90
-                'capability' => 'ee_edit_payment_methods',
91
-            ),
92
-            'deactivate_payment_method' => array(
93
-                'func'       => '_deactivate_payment_method',
94
-                'noheader'   => true,
95
-                'capability' => 'ee_delete_payment_methods',
96
-            ),
97
-            'update_payment_method'     => array(
98
-                'func'               => '_update_payment_method',
99
-                'noheader'           => true,
100
-                'headers_sent_route' => 'default',
101
-                'capability'         => 'ee_edit_payment_methods',
102
-            ),
103
-            'update_payment_settings'   => array(
104
-                'func'       => '_update_payment_settings',
105
-                'noheader'   => true,
106
-                'capability' => 'ee_manage_gateways',
107
-            ),
108
-            'payment_log'               => array(
109
-                'func'       => '_payment_log_overview_list_table',
110
-                'capability' => 'ee_read_payment_methods',
111
-            ),
112
-            'payment_log_details'       => array(
113
-                'func'       => '_payment_log_details',
114
-                'capability' => 'ee_read_payment_methods',
115
-            ),
116
-        );
117
-    }
118
-
119
-
120
-    /**
121
-     * @throws EE_Error
122
-     * @throws ReflectionException
123
-     */
124
-    protected function _set_page_config()
125
-    {
126
-        $payment_method_list_config = array(
127
-            'nav'           => array(
128
-                'label' => esc_html__('Payment Methods', 'event_espresso'),
129
-                'order' => 10,
130
-            ),
131
-            'metaboxes'     => $this->_default_espresso_metaboxes,
132
-            'help_tabs'     => array_merge(
133
-                array(
134
-                    'payment_methods_overview_help_tab' => array(
135
-                        'title'    => esc_html__('Payment Methods Overview', 'event_espresso'),
136
-                        'filename' => 'payment_methods_overview',
137
-                    ),
138
-                ),
139
-                $this->_add_payment_method_help_tabs()
140
-            ),
141
-            'require_nonce' => false,
142
-        );
143
-        $this->_page_config = array(
144
-            'default'          => $payment_method_list_config,
145
-            'payment_settings' => array(
146
-                'nav'           => array(
147
-                    'label' => esc_html__('Settings', 'event_espresso'),
148
-                    'order' => 20,
149
-                ),
150
-                'help_tabs'     => array(
151
-                    'payment_methods_settings_help_tab' => array(
152
-                        'title'    => esc_html__('Payment Method Settings', 'event_espresso'),
153
-                        'filename' => 'payment_methods_settings',
154
-                    ),
155
-                ),
156
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
157
-                'require_nonce' => false,
158
-            ),
159
-            'payment_log'      => array(
160
-                'nav'           => array(
161
-                    'label' => esc_html__("Logs", 'event_espresso'),
162
-                    'order' => 30,
163
-                ),
164
-                'list_table'    => 'Payment_Log_Admin_List_Table',
165
-                'metaboxes'     => $this->_default_espresso_metaboxes,
166
-                'require_nonce' => false,
167
-            ),
168
-        );
169
-    }
170
-
171
-
172
-    /**
173
-     * @return array
174
-     * @throws DomainException
175
-     * @throws EE_Error
176
-     * @throws InvalidArgumentException
177
-     * @throws InvalidDataTypeException
178
-     * @throws InvalidInterfaceException
179
-     * @throws ReflectionException
180
-     */
181
-    protected function _add_payment_method_help_tabs()
182
-    {
183
-        EE_Registry::instance()->load_lib('Payment_Method_Manager');
184
-        $payment_method_types = EE_Payment_Method_Manager::instance()->payment_method_types();
185
-        $all_pmt_help_tabs_config = array();
186
-        foreach ($payment_method_types as $payment_method_type) {
187
-            if (
188
-                ! EE_Registry::instance()->CAP->current_user_can(
189
-                    $payment_method_type->cap_name(),
190
-                    'specific_payment_method_type_access'
191
-                )
192
-            ) {
193
-                continue;
194
-            }
195
-            foreach ($payment_method_type->help_tabs_config() as $help_tab_name => $config) {
196
-                $template_args = isset($config['template_args']) ? $config['template_args'] : array();
197
-                $template_args['admin_page_obj'] = $this;
198
-                $all_pmt_help_tabs_config[ $help_tab_name ] = array(
199
-                    'title'   => $config['title'],
200
-                    'content' => EEH_Template::display_template(
201
-                        $payment_method_type->file_folder() . 'help_tabs/' . $config['filename'] . '.help_tab.php',
202
-                        $template_args,
203
-                        true
204
-                    ),
205
-                );
206
-            }
207
-        }
208
-        return $all_pmt_help_tabs_config;
209
-    }
210
-
211
-
212
-    // none of the below group are currently used for Gateway Settings
213
-    protected function _add_screen_options()
214
-    {
215
-    }
216
-
217
-
218
-    protected function _add_feature_pointers()
219
-    {
220
-    }
221
-
222
-
223
-    public function admin_init()
224
-    {
225
-    }
226
-
227
-
228
-    public function admin_notices()
229
-    {
230
-    }
231
-
232
-
233
-    public function admin_footer_scripts()
234
-    {
235
-    }
236
-
237
-
238
-    public function load_scripts_styles()
239
-    {
240
-        // styles
241
-        wp_enqueue_style('espresso-ui-theme');
242
-        // scripts
243
-        wp_enqueue_script('ee_admin_js');
244
-        wp_enqueue_script('ee-text-links');
245
-        wp_enqueue_script(
246
-            'espresso_payments',
247
-            EE_PAYMENTS_ASSETS_URL . 'espresso_payments_admin.js',
248
-            array('ee-datepicker'),
249
-            EVENT_ESPRESSO_VERSION,
250
-            true
251
-        );
252
-    }
253
-
254
-
255
-    public function load_scripts_styles_default()
256
-    {
257
-        // styles
258
-        wp_register_style(
259
-            'espresso_payments',
260
-            EE_PAYMENTS_ASSETS_URL . 'ee-payments.css',
261
-            array(),
262
-            EVENT_ESPRESSO_VERSION
263
-        );
264
-        wp_enqueue_style('espresso_payments');
265
-        wp_enqueue_style('ee-text-links');
266
-        // scripts
267
-    }
268
-
269
-
270
-    /**
271
-     * @throws EE_Error
272
-     * @throws ReflectionException
273
-     */
274
-    protected function _payment_methods_list()
275
-    {
276
-        /**
277
-         * first let's ensure payment methods have been set up.
278
-         * We do this here because when people activate a payment method for the first time (as an addon),
279
-         * it may not set up its capabilities or get registered correctly due to the loading process.
280
-         * However, people MUST set up the details for the payment method,
281
-         * so it's safe to do a recheck here.
282
-         */
283
-        EE_Registry::instance()->load_lib('Payment_Method_Manager');
284
-        EEM_Payment_Method::instance()->verify_button_urls();
285
-        // set up tabs, one for each payment method type
286
-        $tabs = array();
287
-        $payment_methods = array();
288
-        foreach (EE_Payment_Method_Manager::instance()->payment_method_types() as $pmt_obj) {
289
-            // we don't want to show admin-only PMTs for now
290
-            if ($pmt_obj instanceof EE_PMT_Admin_Only) {
291
-                continue;
292
-            }
293
-            // check access
294
-            if (
295
-                ! EE_Registry::instance()->CAP->current_user_can(
296
-                    $pmt_obj->cap_name(),
297
-                    'specific_payment_method_type_access'
298
-                )
299
-            ) {
300
-                continue;
301
-            }
302
-            // check for any active pms of that type
303
-            $payment_method = EEM_Payment_Method::instance()->get_one_of_type($pmt_obj->system_name());
304
-            if (! $payment_method instanceof EE_Payment_Method) {
305
-                $payment_method = EE_Payment_Method::new_instance(
306
-                    array(
307
-                        'PMD_slug'       => sanitize_key($pmt_obj->system_name()),
308
-                        'PMD_type'       => $pmt_obj->system_name(),
309
-                        'PMD_name'       => $pmt_obj->pretty_name(),
310
-                        'PMD_admin_name' => $pmt_obj->pretty_name(),
311
-                    )
312
-                );
313
-            }
314
-            $payment_methods[ $payment_method->slug() ] = $payment_method;
315
-        }
316
-        $payment_methods = apply_filters(
317
-            'FHEE__Payments_Admin_Page___payment_methods_list__payment_methods',
318
-            $payment_methods
319
-        );
320
-        foreach ($payment_methods as $payment_method) {
321
-            if ($payment_method instanceof EE_Payment_Method) {
322
-                add_meta_box(
323
-                    // html id
324
-                    'espresso_' . $payment_method->slug() . '_payment_settings',
325
-                    // title
326
-                    sprintf(esc_html__('%s Settings', 'event_espresso'), $payment_method->admin_name()),
327
-                    // callback
328
-                    array($this, 'payment_method_settings_meta_box'),
329
-                    // post type
330
-                    null,
331
-                    // context
332
-                    'normal',
333
-                    // priority
334
-                    'default',
335
-                    // callback args
336
-                    array('payment_method' => $payment_method)
337
-                );
338
-                // setup for tabbed content
339
-                $tabs[ $payment_method->slug() ] = array(
340
-                    'label' => $payment_method->admin_name(),
341
-                    'class' => $payment_method->active() ? 'gateway-active' : '',
342
-                    'href'  => 'espresso_' . $payment_method->slug() . '_payment_settings',
343
-                    'title' => esc_html__('Modify this Payment Method', 'event_espresso'),
344
-                    'slug'  => $payment_method->slug(),
345
-                );
346
-            }
347
-        }
348
-        $this->_template_args['admin_page_header'] = EEH_Tabbed_Content::tab_text_links(
349
-            $tabs,
350
-            'payment_method_links',
351
-            '|',
352
-            $this->_get_active_payment_method_slug()
353
-        );
354
-        $this->display_admin_page_with_sidebar();
355
-    }
356
-
357
-
358
-    /**
359
-     *   _get_active_payment_method_slug
360
-     *
361
-     * @return string
362
-     * @throws EE_Error
363
-     */
364
-    protected function _get_active_payment_method_slug()
365
-    {
366
-        $payment_method_slug = false;
367
-        // decide which payment method tab to open first, as dictated by the request's 'payment_method'
368
-        if (isset($this->_req_data['payment_method'])) {
369
-            // if they provided the current payment method, use it
370
-            $payment_method_slug = sanitize_key($this->_req_data['payment_method']);
371
-        }
372
-        /** @var EE_Payment_Method $payment_method */
373
-        $payment_method = EEM_Payment_Method::instance()->get_one(array(array('PMD_slug' => $payment_method_slug)));
374
-        // if that didn't work or wasn't provided, find another way to select the current pm
375
-        if (! $this->_verify_payment_method($payment_method)) {
376
-            // like, looking for an active one
377
-            $payment_method = EEM_Payment_Method::instance()->get_one_active('CART');
378
-            // test that one as well
379
-            if ($this->_verify_payment_method($payment_method)) {
380
-                $payment_method_slug = $payment_method->slug();
381
-            } else {
382
-                $payment_method_slug = 'paypal_standard';
383
-            }
384
-        }
385
-        return $payment_method_slug;
386
-    }
387
-
388
-
389
-    /**
390
-     *    payment_method_settings_meta_box
391
-     *    returns TRUE if the passed payment method is properly constructed and the logged-in user has the correct
392
-     *    capabilities to access it
393
-     *
394
-     * @param EE_Payment_Method $payment_method
395
-     * @return boolean
396
-     * @throws EE_Error
397
-     */
398
-    protected function _verify_payment_method($payment_method)
399
-    {
400
-        if (
401
-            $payment_method instanceof EE_Payment_Method && $payment_method->type_obj() instanceof EE_PMT_Base
402
-            && EE_Registry::instance()->CAP->current_user_can(
403
-                $payment_method->type_obj()->cap_name(),
404
-                'specific_payment_method_type_access'
405
-            )
406
-        ) {
407
-            return true;
408
-        }
409
-        return false;
410
-    }
411
-
412
-
413
-    /**
414
-     *    payment_method_settings_meta_box
415
-     *
416
-     * @param NULL  $post_obj_which_is_null is an object containing the current post (as a $post object)
417
-     * @param array $metabox                is an array with metabox id, title, callback, and args elements. the value
418
-     *                                      at 'args' has key 'payment_method', as set within _payment_methods_list
419
-     * @return void
420
-     * @throws EE_Error
421
-     * @throws ReflectionException
422
-     */
423
-    public function payment_method_settings_meta_box($post_obj_which_is_null, $metabox)
424
-    {
425
-        $payment_method = isset($metabox['args'], $metabox['args']['payment_method'])
426
-            ? $metabox['args']['payment_method'] : null;
427
-        if (! $payment_method instanceof EE_Payment_Method) {
428
-            throw new EE_Error(
429
-                esc_html__(
430
-                    'Payment method metabox setup incorrectly. No Payment method object was supplied',
431
-                    'event_espresso'
432
-                )
433
-            );
434
-        }
435
-        $payment_method_scopes = $payment_method->active();
436
-        // if the payment method really exists show its form, otherwise the activation template
437
-        if ($payment_method->ID() && ! empty($payment_method_scopes)) {
438
-            $form = $this->_generate_payment_method_settings_form($payment_method);
439
-            if ($form->form_data_present_in($this->_req_data)) {
440
-                $form->receive_form_submission($this->_req_data);
441
-            }
442
-            echo wp_kses($form->form_open() . $form->get_html_and_js() . $form->form_close(), AllowedTags::getWithFormTags());
443
-        } else {
444
-            echo wp_kses($this->_activate_payment_method_button($payment_method)->get_html_and_js(), AllowedTags::getWithFormTags());
445
-        }
446
-    }
447
-
448
-
449
-    /**
450
-     * Gets the form for all the settings related to this payment method type
451
-     *
452
-     * @access protected
453
-     * @param EE_Payment_Method $payment_method
454
-     * @return EE_Form_Section_Proper
455
-     * @throws EE_Error
456
-     */
457
-    protected function _generate_payment_method_settings_form(EE_Payment_Method $payment_method = null)
458
-    {
459
-        if (! $payment_method instanceof EE_Payment_Method) {
460
-            return new EE_Form_Section_Proper();
461
-        }
462
-        return new EE_Form_Section_Proper(
463
-            array(
464
-                'name'            => $payment_method->slug() . '_settings_form',
465
-                'html_id'         => $payment_method->slug() . '_settings_form',
466
-                'action'          => EE_Admin_Page::add_query_args_and_nonce(
467
-                    array(
468
-                        'action'         => 'update_payment_method',
469
-                        'payment_method' => $payment_method->slug(),
470
-                    ),
471
-                    EE_PAYMENTS_ADMIN_URL
472
-                ),
473
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
474
-                'subsections'     => apply_filters(
475
-                    'FHEE__Payments_Admin_Page___generate_payment_method_settings_form__form_subsections',
476
-                    array(
477
-                        'pci_dss_compliance'      => $this->_pci_dss_compliance($payment_method),
478
-                        'currency_support'        => $this->_currency_support($payment_method),
479
-                        'payment_method_settings' => $this->_payment_method_settings($payment_method),
480
-                        'update'                  => $this->_update_payment_method_button($payment_method),
481
-                        'deactivate'              => $this->_deactivate_payment_method_button($payment_method),
482
-                        'fine_print'              => $this->_fine_print(),
483
-                    ),
484
-                    $payment_method
485
-                ),
486
-            )
487
-        );
488
-    }
489
-
490
-
491
-    /**
492
-     * _pci_dss_compliance
493
-     *
494
-     * @access protected
495
-     * @param EE_Payment_Method $payment_method
496
-     * @return EE_Form_Section_HTML
497
-     * @throws EE_Error
498
-     */
499
-    protected function _pci_dss_compliance(EE_Payment_Method $payment_method)
500
-    {
501
-        if ($payment_method->type_obj()->requires_https()) {
502
-            return new EE_Form_Section_HTML(
503
-                EEH_HTML::table(
504
-                    EEH_HTML::tr(
505
-                        EEH_HTML::th(
506
-                            EEH_HTML::label(
507
-                                EEH_HTML::strong(
508
-                                    esc_html__('IMPORTANT', 'event_espresso'),
509
-                                    '',
510
-                                    'important-notice'
511
-                                )
512
-                            )
513
-                        ) .
514
-                        EEH_HTML::td(
515
-                            EEH_HTML::strong(
516
-                                esc_html__(
517
-                                    'You are responsible for your own website security and Payment Card Industry Data Security Standards (PCI DSS) compliance.',
518
-                                    'event_espresso'
519
-                                )
520
-                            )
521
-                            .
522
-                            EEH_HTML::br()
523
-                            .
524
-                            esc_html__('Learn more about ', 'event_espresso')
525
-                            . EEH_HTML::link(
526
-                                'https://www.pcisecuritystandards.org/merchants/index.php',
527
-                                esc_html__('PCI DSS compliance', 'event_espresso')
528
-                            )
529
-                        )
530
-                    )
531
-                )
532
-            );
533
-        }
534
-        return new EE_Form_Section_HTML('');
535
-    }
536
-
537
-
538
-    /**
539
-     * _currency_support
540
-     *
541
-     * @access protected
542
-     * @param EE_Payment_Method $payment_method
543
-     * @return EE_Form_Section_HTML
544
-     * @throws EE_Error
545
-     */
546
-    protected function _currency_support(EE_Payment_Method $payment_method)
547
-    {
548
-        if (! $payment_method->usable_for_currency(EE_Config::instance()->currency->code)) {
549
-            return new EE_Form_Section_HTML(
550
-                EEH_HTML::table(
551
-                    EEH_HTML::tr(
552
-                        EEH_HTML::th(
553
-                            EEH_HTML::label(
554
-                                EEH_HTML::strong(
555
-                                    esc_html__('IMPORTANT', 'event_espresso'),
556
-                                    '',
557
-                                    'important-notice'
558
-                                )
559
-                            )
560
-                        ) .
561
-                        EEH_HTML::td(
562
-                            EEH_HTML::strong(
563
-                                sprintf(
564
-                                    esc_html__(
565
-                                        'This payment method does not support the currency set on your site (%1$s). Please activate a different payment method or change your site\'s country and associated currency.',
566
-                                        'event_espresso'
567
-                                    ),
568
-                                    EE_Config::instance()->currency->code
569
-                                )
570
-                            )
571
-                        )
572
-                    )
573
-                )
574
-            );
575
-        }
576
-        return new EE_Form_Section_HTML('');
577
-    }
578
-
579
-
580
-    /**
581
-     * _update_payment_method_button
582
-     *
583
-     * @access protected
584
-     * @param EE_Payment_Method $payment_method
585
-     * @return EE_Payment_Method_Form
586
-     * @throws EE_Error
587
-     */
588
-    protected function _payment_method_settings(EE_Payment_Method $payment_method)
589
-    {
590
-        // modify the form, so we only have/show fields that will be implemented for this version
591
-        return $this->_simplify_form($payment_method->type_obj()->settings_form(), $payment_method->name());
592
-    }
593
-
594
-
595
-    /**
596
-     * Simplifies the form to merely reproduce 4.1's gateway settings functionality
597
-     *
598
-     * @param EE_Form_Section_Proper $form_section
599
-     * @param string                 $payment_method_name
600
-     * @return EE_Payment_Method_Form
601
-     * @throws EE_Error
602
-     */
603
-    protected function _simplify_form($form_section, $payment_method_name = '')
604
-    {
605
-        if ($form_section instanceof EE_Payment_Method_Form) {
606
-            $form_section->exclude(
607
-                array(
608
-                    'PMD_type', // don't want them changing the type
609
-                    'PMD_slug', // or the slug (probably never)
610
-                    'PMD_wp_user', // or the user's ID
611
-                    'Currency' // or the currency, until the rest of EE supports simultaneous currencies
612
-                )
613
-            );
614
-            return $form_section;
615
-        } else {
616
-            throw new EE_Error(
617
-                sprintf(
618
-                    esc_html__(
619
-                        'The EE_Payment_Method_Form for the "%1$s" payment method is missing or invalid.',
620
-                        'event_espresso'
621
-                    ),
622
-                    $payment_method_name
623
-                )
624
-            );
625
-        }
626
-    }
627
-
628
-
629
-    /**
630
-     * _update_payment_method_button
631
-     *
632
-     * @access protected
633
-     * @param EE_Payment_Method $payment_method
634
-     * @return EE_Form_Section_HTML
635
-     * @throws EE_Error
636
-     */
637
-    protected function _update_payment_method_button(EE_Payment_Method $payment_method)
638
-    {
639
-        $update_button = new EE_Submit_Input(
640
-            array(
641
-                'name'       => 'submit',
642
-                'html_id'    => 'save_' . $payment_method->slug() . '_settings',
643
-                'default'    => sprintf(
644
-                    esc_html__('Update %s Payment Settings', 'event_espresso'),
645
-                    $payment_method->admin_name()
646
-                ),
647
-                'html_label' => EEH_HTML::nbsp(),
648
-            )
649
-        );
650
-        return new EE_Form_Section_HTML(
651
-            EEH_HTML::table(
652
-                EEH_HTML::no_row(EEH_HTML::br(2)) .
653
-                EEH_HTML::tr(
654
-                    EEH_HTML::th(esc_html__('Update Settings', 'event_espresso')) .
655
-                    EEH_HTML::td(
656
-                        $update_button->get_html_for_input()
657
-                    )
658
-                )
659
-            )
660
-        );
661
-    }
662
-
663
-
664
-    /**
665
-     * _deactivate_payment_method_button
666
-     *
667
-     * @access protected
668
-     * @param EE_Payment_Method $payment_method
669
-     * @return EE_Form_Section_HTML
670
-     */
671
-    protected function _deactivate_payment_method_button(EE_Payment_Method $payment_method)
672
-    {
673
-        $link_text_and_title = sprintf(
674
-            esc_html__('Deactivate %1$s Payments?', 'event_espresso'),
675
-            $payment_method->admin_name()
676
-        );
677
-        return new EE_Form_Section_HTML(
678
-            EEH_HTML::table(
679
-                EEH_HTML::tr(
680
-                    EEH_HTML::th(esc_html__('Deactivate Payment Method', 'event_espresso')) .
681
-                    EEH_HTML::td(
682
-                        EEH_HTML::link(
683
-                            EE_Admin_Page::add_query_args_and_nonce(
684
-                                array(
685
-                                    'action'         => 'deactivate_payment_method',
686
-                                    'payment_method' => $payment_method->slug(),
687
-                                ),
688
-                                EE_PAYMENTS_ADMIN_URL
689
-                            ),
690
-                            $link_text_and_title,
691
-                            $link_text_and_title,
692
-                            'deactivate_' . $payment_method->slug(),
693
-                            'espresso-button button-secondary'
694
-                        )
695
-                    )
696
-                )
697
-            )
698
-        );
699
-    }
700
-
701
-
702
-    /**
703
-     * _activate_payment_method_button
704
-     *
705
-     * @access protected
706
-     * @param EE_Payment_Method $payment_method
707
-     * @return EE_Form_Section_Proper
708
-     * @throws EE_Error
709
-     */
710
-    protected function _activate_payment_method_button(EE_Payment_Method $payment_method)
711
-    {
712
-        $link_text_and_title = sprintf(
713
-            esc_html__('Activate %1$s Payment Method?', 'event_espresso'),
714
-            $payment_method->admin_name()
715
-        );
716
-        return new EE_Form_Section_Proper(
717
-            array(
718
-                'name'            => 'activate_' . $payment_method->slug() . '_settings_form',
719
-                'html_id'         => 'activate_' . $payment_method->slug() . '_settings_form',
720
-                'action'          => '#',
721
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
722
-                'subsections'     => apply_filters(
723
-                    'FHEE__Payments_Admin_Page___activate_payment_method_button__form_subsections',
724
-                    array(
725
-                        new EE_Form_Section_HTML(
726
-                            EEH_HTML::table(
727
-                                EEH_HTML::tr(
728
-                                    EEH_HTML::td(
729
-                                        $payment_method->type_obj()->introductory_html(),
730
-                                        '',
731
-                                        '',
732
-                                        '',
733
-                                        'colspan="2"'
734
-                                    )
735
-                                ) .
736
-                                EEH_HTML::tr(
737
-                                    EEH_HTML::th(
738
-                                        EEH_HTML::label(esc_html__('Click to Activate ', 'event_espresso'))
739
-                                    ) .
740
-                                    EEH_HTML::td(
741
-                                        EEH_HTML::link(
742
-                                            EE_Admin_Page::add_query_args_and_nonce(
743
-                                                array(
744
-                                                    'action'              => 'activate_payment_method',
745
-                                                    'payment_method_type' => $payment_method->type(),
746
-                                                ),
747
-                                                EE_PAYMENTS_ADMIN_URL
748
-                                            ),
749
-                                            $link_text_and_title,
750
-                                            $link_text_and_title,
751
-                                            'activate_' . $payment_method->slug(),
752
-                                            'espresso-button-green button-primary'
753
-                                        )
754
-                                    )
755
-                                )
756
-                            )
757
-                        ),
758
-                    ),
759
-                    $payment_method
760
-                ),
761
-            )
762
-        );
763
-    }
764
-
765
-
766
-    /**
767
-     * _fine_print
768
-     *
769
-     * @access protected
770
-     * @return EE_Form_Section_HTML
771
-     */
772
-    protected function _fine_print()
773
-    {
774
-        return new EE_Form_Section_HTML(
775
-            EEH_HTML::table(
776
-                EEH_HTML::tr(
777
-                    EEH_HTML::th() .
778
-                    EEH_HTML::td(
779
-                        EEH_HTML::p(esc_html__('All fields marked with a * are required fields', 'event_espresso'), '', 'grey-text')
780
-                    )
781
-                )
782
-            )
783
-        );
784
-    }
785
-
786
-
787
-    /**
788
-     * Activates a payment method of that type. Mostly assuming there is only 1 of that type (or none so far)
789
-     *
790
-     * @throws EE_Error
791
-     * @throws ReflectionException
792
-     * @global WP_User $current_user
793
-     */
794
-    protected function _activate_payment_method()
795
-    {
796
-        if (isset($this->_req_data['payment_method_type'])) {
797
-            $payment_method_type = sanitize_text_field($this->_req_data['payment_method_type']);
798
-            // see if one exists
799
-            EE_Registry::instance()->load_lib('Payment_Method_Manager');
800
-            $payment_method = EE_Payment_Method_Manager::instance()
801
-                                                       ->activate_a_payment_method_of_type($payment_method_type);
802
-            $this->_redirect_after_action(
803
-                1,
804
-                'Payment Method',
805
-                'activated',
806
-                array('action' => 'default', 'payment_method' => $payment_method->slug())
807
-            );
808
-        } else {
809
-            $this->_redirect_after_action(false, 'Payment Method', 'activated', array('action' => 'default'));
810
-        }
811
-    }
812
-
813
-
814
-    /**
815
-     * @throws EE_Error
816
-     * @throws ReflectionException
817
-     */
818
-    protected function _deactivate_payment_method()
819
-    {
820
-        if (isset($this->_req_data['payment_method'])) {
821
-            $payment_method_slug = sanitize_key($this->_req_data['payment_method']);
822
-            // deactivate it
823
-            EE_Registry::instance()->load_lib('Payment_Method_Manager');
824
-            $count_updated = EE_Payment_Method_Manager::instance()->deactivate_payment_method($payment_method_slug);
825
-            $this->_redirect_after_action(
826
-                $count_updated,
827
-                'Payment Method',
828
-                'deactivated',
829
-                array('action' => 'default', 'payment_method' => $payment_method_slug)
830
-            );
831
-        } else {
832
-            $this->_redirect_after_action(false, 'Payment Method', 'deactivated', array('action' => 'default'));
833
-        }
834
-    }
835
-
836
-
837
-    /**
838
-     * Processes the payment method form that was submitted. This is slightly trickier than usual form
839
-     * processing because we first need to identify WHICH form was processed and which payment method
840
-     * it corresponds to. Once we have done that, we see if the form is valid. If it is, the
841
-     * form's data is saved, and we redirect to the default payment methods page, setting the updated payment method
842
-     * as the currently-selected one. If it DOESN'T validate, we render the page with the form's errors (in the
843
-     * subsequently called 'headers_sent_func' which is _payment_methods_list)
844
-     *
845
-     * @return void
846
-     * @throws EE_Error
847
-     * @throws ReflectionException
848
-     */
849
-    protected function _update_payment_method()
850
-    {
851
-        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
852
-            // ok let's find which gateway form to use based on the form input
853
-            EE_Registry::instance()->load_lib('Payment_Method_Manager');
854
-            /** @var $correct_pmt_form_to_use EE_Payment_Method_Form */
855
-            $correct_pmt_form_to_use = null;
856
-            $payment_method = null;
857
-            foreach (EEM_Payment_Method::instance()->get_all() as $payment_method) {
858
-                if ($payment_method instanceof EE_Payment_Method) {
859
-                    // get the form and simplify it, like what we do when we display it
860
-                    $pmt_form = $this->_generate_payment_method_settings_form($payment_method);
861
-                    if ($pmt_form->form_data_present_in($this->_req_data)) {
862
-                        $correct_pmt_form_to_use = $pmt_form;
863
-                        break;
864
-                    }
865
-                }
866
-            }
867
-            // if we couldn't find the correct payment method type...
868
-            if (! $correct_pmt_form_to_use) {
869
-                EE_Error::add_error(
870
-                    esc_html__(
871
-                        "We could not find which payment method type your form submission related to. Please contact support",
872
-                        'event_espresso'
873
-                    ),
874
-                    __FILE__,
875
-                    __FUNCTION__,
876
-                    __LINE__
877
-                );
878
-                $this->_redirect_after_action(false, 'Payment Method', 'activated', array('action' => 'default'));
879
-            }
880
-            $correct_pmt_form_to_use->receive_form_submission($this->_req_data);
881
-            if ($correct_pmt_form_to_use->is_valid()) {
882
-                $payment_settings_subform = $correct_pmt_form_to_use->get_subsection('payment_method_settings');
883
-                if (! $payment_settings_subform instanceof EE_Payment_Method_Form) {
884
-                    throw new EE_Error(
885
-                        sprintf(
886
-                            esc_html__(
887
-                                'The payment method could not be saved because the form sections were misnamed. We expected to find %1$s, but did not.',
888
-                                'event_espresso'
889
-                            ),
890
-                            'payment_method_settings'
891
-                        )
892
-                    );
893
-                }
894
-                $payment_settings_subform->save();
895
-                /** @var $pm EE_Payment_Method */
896
-                $this->_redirect_after_action(
897
-                    true,
898
-                    'Payment Method',
899
-                    'updated',
900
-                    array('action' => 'default', 'payment_method' => $payment_method->slug())
901
-                );
902
-            } else {
903
-                EE_Error::add_error(
904
-                    sprintf(
905
-                        esc_html__(
906
-                            'Payment method of type %s was not saved because there were validation errors. They have been marked in the form',
907
-                            'event_espresso'
908
-                        ),
909
-                        $payment_method instanceof EE_Payment_Method ? $payment_method->type_obj()->pretty_name()
910
-                            : esc_html__('"(unknown)"', 'event_espresso')
911
-                    ),
912
-                    __FILE__,
913
-                    __FUNCTION__,
914
-                    __LINE__
915
-                );
916
-            }
917
-        }
918
-    }
919
-
920
-
921
-    /**
922
-     * Displays payment settings (not payment METHOD settings, that's _payment_method_settings)
923
-     * @throws DomainException
924
-     * @throws EE_Error
925
-     * @throws InvalidArgumentException
926
-     * @throws InvalidDataTypeException
927
-     * @throws InvalidInterfaceException
928
-     */
929
-    protected function _payment_settings()
930
-    {
931
-        $form = $this->getPaymentSettingsForm();
932
-        $this->_set_add_edit_form_tags('update_payment_settings');
933
-        $this->_set_publish_post_box_vars(null, false, false, null, false);
934
-        $this->_template_args['admin_page_content'] =  $form->get_html_and_js();
935
-        $this->display_admin_page_with_sidebar();
936
-    }
937
-
938
-
939
-    /**
940
-     *        _update_payment_settings
941
-     *
942
-     * @access protected
943
-     * @return void
944
-     * @throws EE_Error
945
-     * @throws InvalidArgumentException
946
-     * @throws InvalidDataTypeException
947
-     * @throws InvalidInterfaceException
948
-     */
949
-    protected function _update_payment_settings()
950
-    {
951
-        $form = $this->getPaymentSettingsForm();
952
-        if ($form->was_submitted($this->_req_data)) {
953
-            $form->receive_form_submission($this->_req_data);
954
-            if ($form->is_valid()) {
955
-                /**
956
-                 * @var $reg_config EE_Registration_Config
957
-                 */
958
-                $loader = LoaderFactory::getLoader();
959
-                $reg_config = $loader->getShared('EE_Registration_Config');
960
-                $valid_data = $form->valid_data();
961
-                $reg_config->show_pending_payment_options = $valid_data['show_pending_payment_options'];
962
-                $reg_config->gateway_log_lifespan = $valid_data['gateway_log_lifespan'];
963
-            }
964
-        }
965
-        EE_Registry::instance()->CFG = apply_filters(
966
-            'FHEE__Payments_Admin_Page___update_payment_settings__CFG',
967
-            EE_Registry::instance()->CFG
968
-        );
969
-
970
-        $what = esc_html__('Payment Settings', 'event_espresso');
971
-        $success = $this->_update_espresso_configuration(
972
-            $what,
973
-            EE_Registry::instance()->CFG,
974
-            __FILE__,
975
-            __FUNCTION__,
976
-            __LINE__
977
-        );
978
-        $this->_redirect_after_action(
979
-            $success,
980
-            $what,
981
-            esc_html__('updated', 'event_espresso'),
982
-            array('action' => 'payment_settings')
983
-        );
984
-    }
985
-
986
-
987
-    /**
988
-     * Gets the form used for updating payment settings
989
-     *
990
-     * @return EE_Form_Section_Proper
991
-     * @throws EE_Error
992
-     * @throws InvalidArgumentException
993
-     * @throws InvalidDataTypeException
994
-     * @throws InvalidInterfaceException
995
-     */
996
-    protected function getPaymentSettingsForm()
997
-    {
998
-        /**
999
-         * @var $reg_config EE_Registration_Config
1000
-         */
1001
-        $reg_config = LoaderFactory::getLoader()->getShared('EE_Registration_Config');
1002
-        return new EE_Form_Section_Proper(
1003
-            array(
1004
-                'name' => 'payment-settings',
1005
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1006
-                'subsections' => array(
1007
-                    'show_pending_payment_options' => new EE_Yes_No_Input(
1008
-                        array(
1009
-                            'html_name' => 'show_pending_payment_options',
1010
-                            'default' => $reg_config->show_pending_payment_options,
1011
-                            'html_help_text' => esc_html__(
1012
-                                "If a payment is marked as 'Pending Payment', or if payment is deferred (ie, an offline gateway like Check, Bank, or Invoice is used), then give registrants the option to retry payment. ",
1013
-                                'event_espresso'
1014
-                            )
1015
-                        )
1016
-                    ),
1017
-                    'gateway_log_lifespan' => new EE_Select_Input(
1018
-                        $reg_config->gatewayLogLifespanOptions(),
1019
-                        array(
1020
-                            'html_label_text' => esc_html__('Gateway Logs Lifespan', 'event_espresso'),
1021
-                            'html_help_text' => esc_html__('If issues arise with payments being made through a payment gateway, it\'s helpful to log non-sensitive communications with the payment gateway. But it\'s a security responsibility, so it\'s a good idea to not keep them for any longer than necessary.', 'event_espresso'),
1022
-                            'default' => $reg_config->gateway_log_lifespan,
1023
-                        )
1024
-                    )
1025
-                )
1026
-            )
1027
-        );
1028
-    }
1029
-
1030
-
1031
-    /**
1032
-     * @throws EE_Error
1033
-     */
1034
-    protected function _payment_log_overview_list_table()
1035
-    {
1036
-        $this->display_admin_list_table_page_with_sidebar();
1037
-    }
1038
-
1039
-
1040
-    protected function _set_list_table_views_payment_log()
1041
-    {
1042
-        $this->_views = array(
1043
-            'all' => array(
1044
-                'slug'  => 'all',
1045
-                'label' => esc_html__('View All Logs', 'event_espresso'),
1046
-                'count' => 0,
1047
-            ),
1048
-        );
1049
-    }
1050
-
1051
-
1052
-    /**
1053
-     * @param int  $per_page
1054
-     * @param int  $current_page
1055
-     * @param bool $count
1056
-     * @return array|int
1057
-     * @throws EE_Error
1058
-     * @throws ReflectionException
1059
-     */
1060
-    public function get_payment_logs($per_page = 50, $current_page = 0, $count = false)
1061
-    {
1062
-        EE_Registry::instance()->load_model('Change_Log');
1063
-        // we may need to do multiple queries (joining differently), so we actually want an array of query params
1064
-        $query_params = array(array('LOG_type' => EEM_Change_Log::type_gateway));
1065
-        // check if they've selected a specific payment method
1066
-        if (isset($this->_req_data['_payment_method']) && $this->_req_data['_payment_method'] !== 'all') {
1067
-            $query_params[0]['OR*pm_or_pay_pm'] = array(
1068
-                'Payment.Payment_Method.PMD_ID' => $this->_req_data['_payment_method'],
1069
-                'Payment_Method.PMD_ID'         => $this->_req_data['_payment_method'],
1070
-            );
1071
-        }
1072
-        // take into account search
1073
-        if (isset($this->_req_data['s']) && $this->_req_data['s']) {
1074
-            $similarity_string = array('LIKE', '%' . str_replace("", "%", $this->_req_data['s']) . '%');
1075
-            $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_fname'] = $similarity_string;
1076
-            $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_lname'] = $similarity_string;
1077
-            $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_email'] = $similarity_string;
1078
-            $query_params[0]['OR*s']['Payment.Payment_Method.PMD_name'] = $similarity_string;
1079
-            $query_params[0]['OR*s']['Payment.Payment_Method.PMD_admin_name'] = $similarity_string;
1080
-            $query_params[0]['OR*s']['Payment.Payment_Method.PMD_type'] = $similarity_string;
1081
-            $query_params[0]['OR*s']['LOG_message'] = $similarity_string;
1082
-            $query_params[0]['OR*s']['Payment_Method.PMD_name'] = $similarity_string;
1083
-            $query_params[0]['OR*s']['Payment_Method.PMD_admin_name'] = $similarity_string;
1084
-            $query_params[0]['OR*s']['Payment_Method.PMD_type'] = $similarity_string;
1085
-            $query_params[0]['OR*s']['LOG_message'] = $similarity_string;
1086
-        }
1087
-        if (
1088
-            isset($this->_req_data['payment-filter-start-date'])
1089
-            && isset($this->_req_data['payment-filter-end-date'])
1090
-        ) {
1091
-            // add date
1092
-            $start_date = wp_strip_all_tags($this->_req_data['payment-filter-start-date']);
1093
-            $end_date = wp_strip_all_tags($this->_req_data['payment-filter-end-date']);
1094
-            // make sure our timestamps start and end right at the boundaries for each day
1095
-            $start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
1096
-            $end_date = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
1097
-            // convert to timestamps
1098
-            $start_date = strtotime($start_date);
1099
-            $end_date = strtotime($end_date);
1100
-            // makes sure start date is the lowest value and vice versa
1101
-            $start_date = min($start_date, $end_date);
1102
-            $end_date = max($start_date, $end_date);
1103
-            // convert for query
1104
-            $start_date = EEM_Change_Log::instance()->convert_datetime_for_query(
1105
-                'LOG_time',
1106
-                date('Y-m-d H:i:s', $start_date),
1107
-                'Y-m-d H:i:s'
1108
-            );
1109
-            $end_date   = EEM_Change_Log::instance()->convert_datetime_for_query(
1110
-                'LOG_time',
1111
-                date('Y-m-d H:i:s', $end_date),
1112
-                'Y-m-d H:i:s'
1113
-            );
1114
-            $query_params[0]['LOG_time'] = array('BETWEEN', array($start_date, $end_date));
1115
-        }
1116
-        if ($count) {
1117
-            return EEM_Change_Log::instance()->count($query_params);
1118
-        }
1119
-        if (isset($this->_req_data['order'])) {
1120
-            $sort = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
1121
-                ? $this->_req_data['order']
1122
-                : 'DESC';
1123
-            $query_params['order_by'] = array('LOG_time' => $sort);
1124
-        } else {
1125
-            $query_params['order_by'] = array('LOG_time' => 'DESC');
1126
-        }
1127
-        $offset = ($current_page - 1) * $per_page;
1128
-        if (! isset($this->_req_data['download_results'])) {
1129
-            $query_params['limit'] = array($offset, $per_page);
1130
-        }
1131
-        // now they've requested to instead just download the file instead of viewing it.
1132
-        if (isset($this->_req_data['download_results'])) {
1133
-            $wpdb_results = EEM_Change_Log::instance()->get_all_efficiently($query_params);
1134
-            header('Content-Disposition: attachment');
1135
-            header("Content-Disposition: attachment; filename=ee_payment_logs_for_" . sanitize_key(site_url()));
1136
-            echo '<h1> '
1137
-                . sprintf(
1138
-                    esc_html__('Payment Logs for %1$s', 'event_espresso'),
1139
-                    esc_url_raw(site_url())
1140
-                )
1141
-                . '</h1 >';
1142
-            echo '<h3>' . esc_html__('Query:', 'event_espresso') . '</h3>';
1143
-            echo esc_html(var_export($query_params, true));
1144
-            echo '<h3>' . esc_html__('Results:', 'event_espresso') . '</h3>';
1145
-            echo esc_html(var_export($wpdb_results, true));
1146
-            die;
1147
-        }
1148
-        return EEM_Change_Log::instance()->get_all($query_params);
1149
-    }
1150
-
1151
-
1152
-    /**
1153
-     * Used by usort to RE-sort log query results, because we lose the ordering
1154
-     * because we're possibly combining the results from two queries
1155
-     *
1156
-     * @param EE_Change_Log $logA
1157
-     * @param EE_Change_Log $logB
1158
-     * @return int
1159
-     * @throws EE_Error
1160
-     * @throws ReflectionException
1161
-     */
1162
-    protected function _sort_logs_again($logA, $logB)
1163
-    {
1164
-        $timeA = $logA->get_raw('LOG_time');
1165
-        $timeB = $logB->get_raw('LOG_time');
1166
-        if ($timeA == $timeB) {
1167
-            return 0;
1168
-        }
1169
-        $comparison = $timeA < $timeB ? -1 : 1;
1170
-        if (strtoupper($this->_sort_logs_again_direction) == 'DESC') {
1171
-            return $comparison * -1;
1172
-        }
1173
-        return $comparison;
1174
-    }
1175
-
1176
-
1177
-    /**
1178
-     * @throws EE_Error
1179
-     * @throws ReflectionException
1180
-     */
1181
-    protected function _payment_log_details()
1182
-    {
1183
-        EE_Registry::instance()->load_model('Change_Log');
1184
-        /** @var $payment_log EE_Change_Log */
1185
-        $payment_log = EEM_Change_Log::instance()->get_one_by_ID($this->_req_data['ID']);
1186
-        $payment_method = null;
1187
-        $transaction = null;
1188
-        if ($payment_log instanceof EE_Change_Log) {
1189
-            if ($payment_log->object() instanceof EE_Payment) {
1190
-                $payment_method = $payment_log->object()->payment_method();
1191
-                $transaction = $payment_log->object()->transaction();
1192
-            } elseif ($payment_log->object() instanceof EE_Payment_Method) {
1193
-                $payment_method = $payment_log->object();
1194
-            } elseif ($payment_log->object() instanceof EE_Transaction) {
1195
-                $transaction = $payment_log->object();
1196
-                $payment_method = $transaction->payment_method();
1197
-            }
1198
-        }
1199
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
1200
-            EE_PAYMENTS_TEMPLATE_PATH . 'payment_log_details.template.php',
1201
-            array(
1202
-                'payment_log'    => $payment_log,
1203
-                'payment_method' => $payment_method,
1204
-                'transaction'    => $transaction,
1205
-            ),
1206
-            true
1207
-        );
1208
-        $this->display_admin_page_with_sidebar();
1209
-    }
19
+	/**
20
+	 * Variables used for when we're re-sorting the logs results,
21
+	 * in case we needed to do two queries, and we need to resort
22
+	 *
23
+	 * @var string
24
+	 */
25
+	private $_sort_logs_again_direction;
26
+
27
+
28
+	/**
29
+	 * @Constructor
30
+	 * @access public
31
+	 * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
32
+	 * @throws EE_Error
33
+	 * @throws InvalidArgumentException
34
+	 * @throws InvalidDataTypeException
35
+	 * @throws InvalidInterfaceException
36
+	 * @throws ReflectionException
37
+	 */
38
+	public function __construct($routing = true)
39
+	{
40
+		parent::__construct($routing);
41
+	}
42
+
43
+
44
+	protected function _init_page_props()
45
+	{
46
+		$this->page_slug = EE_PAYMENTS_PG_SLUG;
47
+		$this->page_label = esc_html__('Payment Methods', 'event_espresso');
48
+		$this->_admin_base_url = EE_PAYMENTS_ADMIN_URL;
49
+		$this->_admin_base_path = EE_PAYMENTS_ADMIN;
50
+	}
51
+
52
+
53
+	protected function _ajax_hooks()
54
+	{
55
+		// todo: all hooks for ajax goes here.
56
+	}
57
+
58
+
59
+	protected function _define_page_props()
60
+	{
61
+		$this->_admin_page_title = $this->page_label;
62
+		$this->_labels = array(
63
+			'publishbox' => esc_html__('Update Settings', 'event_espresso'),
64
+		);
65
+	}
66
+
67
+
68
+	protected function _set_page_routes()
69
+	{
70
+		/**
71
+		 * note that with payment method capabilities, although we've implemented
72
+		 * capability mapping which will be used for accessing payment methods owned by
73
+		 * other users.  This is not fully implemented yet in the payment method ui.
74
+		 * Currently, only the "plural" caps are in active use.
75
+		 * When cap mapping is implemented, some routes will need to use the singular form of
76
+		 * capability method and also include the $id of the payment method for the route.
77
+		 **/
78
+		$this->_page_routes = array(
79
+			'default'                   => array(
80
+				'func'       => '_payment_methods_list',
81
+				'capability' => 'ee_edit_payment_methods',
82
+			),
83
+			'payment_settings'          => array(
84
+				'func'       => '_payment_settings',
85
+				'capability' => 'ee_manage_gateways',
86
+			),
87
+			'activate_payment_method'   => array(
88
+				'func'       => '_activate_payment_method',
89
+				'noheader'   => true,
90
+				'capability' => 'ee_edit_payment_methods',
91
+			),
92
+			'deactivate_payment_method' => array(
93
+				'func'       => '_deactivate_payment_method',
94
+				'noheader'   => true,
95
+				'capability' => 'ee_delete_payment_methods',
96
+			),
97
+			'update_payment_method'     => array(
98
+				'func'               => '_update_payment_method',
99
+				'noheader'           => true,
100
+				'headers_sent_route' => 'default',
101
+				'capability'         => 'ee_edit_payment_methods',
102
+			),
103
+			'update_payment_settings'   => array(
104
+				'func'       => '_update_payment_settings',
105
+				'noheader'   => true,
106
+				'capability' => 'ee_manage_gateways',
107
+			),
108
+			'payment_log'               => array(
109
+				'func'       => '_payment_log_overview_list_table',
110
+				'capability' => 'ee_read_payment_methods',
111
+			),
112
+			'payment_log_details'       => array(
113
+				'func'       => '_payment_log_details',
114
+				'capability' => 'ee_read_payment_methods',
115
+			),
116
+		);
117
+	}
118
+
119
+
120
+	/**
121
+	 * @throws EE_Error
122
+	 * @throws ReflectionException
123
+	 */
124
+	protected function _set_page_config()
125
+	{
126
+		$payment_method_list_config = array(
127
+			'nav'           => array(
128
+				'label' => esc_html__('Payment Methods', 'event_espresso'),
129
+				'order' => 10,
130
+			),
131
+			'metaboxes'     => $this->_default_espresso_metaboxes,
132
+			'help_tabs'     => array_merge(
133
+				array(
134
+					'payment_methods_overview_help_tab' => array(
135
+						'title'    => esc_html__('Payment Methods Overview', 'event_espresso'),
136
+						'filename' => 'payment_methods_overview',
137
+					),
138
+				),
139
+				$this->_add_payment_method_help_tabs()
140
+			),
141
+			'require_nonce' => false,
142
+		);
143
+		$this->_page_config = array(
144
+			'default'          => $payment_method_list_config,
145
+			'payment_settings' => array(
146
+				'nav'           => array(
147
+					'label' => esc_html__('Settings', 'event_espresso'),
148
+					'order' => 20,
149
+				),
150
+				'help_tabs'     => array(
151
+					'payment_methods_settings_help_tab' => array(
152
+						'title'    => esc_html__('Payment Method Settings', 'event_espresso'),
153
+						'filename' => 'payment_methods_settings',
154
+					),
155
+				),
156
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
157
+				'require_nonce' => false,
158
+			),
159
+			'payment_log'      => array(
160
+				'nav'           => array(
161
+					'label' => esc_html__("Logs", 'event_espresso'),
162
+					'order' => 30,
163
+				),
164
+				'list_table'    => 'Payment_Log_Admin_List_Table',
165
+				'metaboxes'     => $this->_default_espresso_metaboxes,
166
+				'require_nonce' => false,
167
+			),
168
+		);
169
+	}
170
+
171
+
172
+	/**
173
+	 * @return array
174
+	 * @throws DomainException
175
+	 * @throws EE_Error
176
+	 * @throws InvalidArgumentException
177
+	 * @throws InvalidDataTypeException
178
+	 * @throws InvalidInterfaceException
179
+	 * @throws ReflectionException
180
+	 */
181
+	protected function _add_payment_method_help_tabs()
182
+	{
183
+		EE_Registry::instance()->load_lib('Payment_Method_Manager');
184
+		$payment_method_types = EE_Payment_Method_Manager::instance()->payment_method_types();
185
+		$all_pmt_help_tabs_config = array();
186
+		foreach ($payment_method_types as $payment_method_type) {
187
+			if (
188
+				! EE_Registry::instance()->CAP->current_user_can(
189
+					$payment_method_type->cap_name(),
190
+					'specific_payment_method_type_access'
191
+				)
192
+			) {
193
+				continue;
194
+			}
195
+			foreach ($payment_method_type->help_tabs_config() as $help_tab_name => $config) {
196
+				$template_args = isset($config['template_args']) ? $config['template_args'] : array();
197
+				$template_args['admin_page_obj'] = $this;
198
+				$all_pmt_help_tabs_config[ $help_tab_name ] = array(
199
+					'title'   => $config['title'],
200
+					'content' => EEH_Template::display_template(
201
+						$payment_method_type->file_folder() . 'help_tabs/' . $config['filename'] . '.help_tab.php',
202
+						$template_args,
203
+						true
204
+					),
205
+				);
206
+			}
207
+		}
208
+		return $all_pmt_help_tabs_config;
209
+	}
210
+
211
+
212
+	// none of the below group are currently used for Gateway Settings
213
+	protected function _add_screen_options()
214
+	{
215
+	}
216
+
217
+
218
+	protected function _add_feature_pointers()
219
+	{
220
+	}
221
+
222
+
223
+	public function admin_init()
224
+	{
225
+	}
226
+
227
+
228
+	public function admin_notices()
229
+	{
230
+	}
231
+
232
+
233
+	public function admin_footer_scripts()
234
+	{
235
+	}
236
+
237
+
238
+	public function load_scripts_styles()
239
+	{
240
+		// styles
241
+		wp_enqueue_style('espresso-ui-theme');
242
+		// scripts
243
+		wp_enqueue_script('ee_admin_js');
244
+		wp_enqueue_script('ee-text-links');
245
+		wp_enqueue_script(
246
+			'espresso_payments',
247
+			EE_PAYMENTS_ASSETS_URL . 'espresso_payments_admin.js',
248
+			array('ee-datepicker'),
249
+			EVENT_ESPRESSO_VERSION,
250
+			true
251
+		);
252
+	}
253
+
254
+
255
+	public function load_scripts_styles_default()
256
+	{
257
+		// styles
258
+		wp_register_style(
259
+			'espresso_payments',
260
+			EE_PAYMENTS_ASSETS_URL . 'ee-payments.css',
261
+			array(),
262
+			EVENT_ESPRESSO_VERSION
263
+		);
264
+		wp_enqueue_style('espresso_payments');
265
+		wp_enqueue_style('ee-text-links');
266
+		// scripts
267
+	}
268
+
269
+
270
+	/**
271
+	 * @throws EE_Error
272
+	 * @throws ReflectionException
273
+	 */
274
+	protected function _payment_methods_list()
275
+	{
276
+		/**
277
+		 * first let's ensure payment methods have been set up.
278
+		 * We do this here because when people activate a payment method for the first time (as an addon),
279
+		 * it may not set up its capabilities or get registered correctly due to the loading process.
280
+		 * However, people MUST set up the details for the payment method,
281
+		 * so it's safe to do a recheck here.
282
+		 */
283
+		EE_Registry::instance()->load_lib('Payment_Method_Manager');
284
+		EEM_Payment_Method::instance()->verify_button_urls();
285
+		// set up tabs, one for each payment method type
286
+		$tabs = array();
287
+		$payment_methods = array();
288
+		foreach (EE_Payment_Method_Manager::instance()->payment_method_types() as $pmt_obj) {
289
+			// we don't want to show admin-only PMTs for now
290
+			if ($pmt_obj instanceof EE_PMT_Admin_Only) {
291
+				continue;
292
+			}
293
+			// check access
294
+			if (
295
+				! EE_Registry::instance()->CAP->current_user_can(
296
+					$pmt_obj->cap_name(),
297
+					'specific_payment_method_type_access'
298
+				)
299
+			) {
300
+				continue;
301
+			}
302
+			// check for any active pms of that type
303
+			$payment_method = EEM_Payment_Method::instance()->get_one_of_type($pmt_obj->system_name());
304
+			if (! $payment_method instanceof EE_Payment_Method) {
305
+				$payment_method = EE_Payment_Method::new_instance(
306
+					array(
307
+						'PMD_slug'       => sanitize_key($pmt_obj->system_name()),
308
+						'PMD_type'       => $pmt_obj->system_name(),
309
+						'PMD_name'       => $pmt_obj->pretty_name(),
310
+						'PMD_admin_name' => $pmt_obj->pretty_name(),
311
+					)
312
+				);
313
+			}
314
+			$payment_methods[ $payment_method->slug() ] = $payment_method;
315
+		}
316
+		$payment_methods = apply_filters(
317
+			'FHEE__Payments_Admin_Page___payment_methods_list__payment_methods',
318
+			$payment_methods
319
+		);
320
+		foreach ($payment_methods as $payment_method) {
321
+			if ($payment_method instanceof EE_Payment_Method) {
322
+				add_meta_box(
323
+					// html id
324
+					'espresso_' . $payment_method->slug() . '_payment_settings',
325
+					// title
326
+					sprintf(esc_html__('%s Settings', 'event_espresso'), $payment_method->admin_name()),
327
+					// callback
328
+					array($this, 'payment_method_settings_meta_box'),
329
+					// post type
330
+					null,
331
+					// context
332
+					'normal',
333
+					// priority
334
+					'default',
335
+					// callback args
336
+					array('payment_method' => $payment_method)
337
+				);
338
+				// setup for tabbed content
339
+				$tabs[ $payment_method->slug() ] = array(
340
+					'label' => $payment_method->admin_name(),
341
+					'class' => $payment_method->active() ? 'gateway-active' : '',
342
+					'href'  => 'espresso_' . $payment_method->slug() . '_payment_settings',
343
+					'title' => esc_html__('Modify this Payment Method', 'event_espresso'),
344
+					'slug'  => $payment_method->slug(),
345
+				);
346
+			}
347
+		}
348
+		$this->_template_args['admin_page_header'] = EEH_Tabbed_Content::tab_text_links(
349
+			$tabs,
350
+			'payment_method_links',
351
+			'|',
352
+			$this->_get_active_payment_method_slug()
353
+		);
354
+		$this->display_admin_page_with_sidebar();
355
+	}
356
+
357
+
358
+	/**
359
+	 *   _get_active_payment_method_slug
360
+	 *
361
+	 * @return string
362
+	 * @throws EE_Error
363
+	 */
364
+	protected function _get_active_payment_method_slug()
365
+	{
366
+		$payment_method_slug = false;
367
+		// decide which payment method tab to open first, as dictated by the request's 'payment_method'
368
+		if (isset($this->_req_data['payment_method'])) {
369
+			// if they provided the current payment method, use it
370
+			$payment_method_slug = sanitize_key($this->_req_data['payment_method']);
371
+		}
372
+		/** @var EE_Payment_Method $payment_method */
373
+		$payment_method = EEM_Payment_Method::instance()->get_one(array(array('PMD_slug' => $payment_method_slug)));
374
+		// if that didn't work or wasn't provided, find another way to select the current pm
375
+		if (! $this->_verify_payment_method($payment_method)) {
376
+			// like, looking for an active one
377
+			$payment_method = EEM_Payment_Method::instance()->get_one_active('CART');
378
+			// test that one as well
379
+			if ($this->_verify_payment_method($payment_method)) {
380
+				$payment_method_slug = $payment_method->slug();
381
+			} else {
382
+				$payment_method_slug = 'paypal_standard';
383
+			}
384
+		}
385
+		return $payment_method_slug;
386
+	}
387
+
388
+
389
+	/**
390
+	 *    payment_method_settings_meta_box
391
+	 *    returns TRUE if the passed payment method is properly constructed and the logged-in user has the correct
392
+	 *    capabilities to access it
393
+	 *
394
+	 * @param EE_Payment_Method $payment_method
395
+	 * @return boolean
396
+	 * @throws EE_Error
397
+	 */
398
+	protected function _verify_payment_method($payment_method)
399
+	{
400
+		if (
401
+			$payment_method instanceof EE_Payment_Method && $payment_method->type_obj() instanceof EE_PMT_Base
402
+			&& EE_Registry::instance()->CAP->current_user_can(
403
+				$payment_method->type_obj()->cap_name(),
404
+				'specific_payment_method_type_access'
405
+			)
406
+		) {
407
+			return true;
408
+		}
409
+		return false;
410
+	}
411
+
412
+
413
+	/**
414
+	 *    payment_method_settings_meta_box
415
+	 *
416
+	 * @param NULL  $post_obj_which_is_null is an object containing the current post (as a $post object)
417
+	 * @param array $metabox                is an array with metabox id, title, callback, and args elements. the value
418
+	 *                                      at 'args' has key 'payment_method', as set within _payment_methods_list
419
+	 * @return void
420
+	 * @throws EE_Error
421
+	 * @throws ReflectionException
422
+	 */
423
+	public function payment_method_settings_meta_box($post_obj_which_is_null, $metabox)
424
+	{
425
+		$payment_method = isset($metabox['args'], $metabox['args']['payment_method'])
426
+			? $metabox['args']['payment_method'] : null;
427
+		if (! $payment_method instanceof EE_Payment_Method) {
428
+			throw new EE_Error(
429
+				esc_html__(
430
+					'Payment method metabox setup incorrectly. No Payment method object was supplied',
431
+					'event_espresso'
432
+				)
433
+			);
434
+		}
435
+		$payment_method_scopes = $payment_method->active();
436
+		// if the payment method really exists show its form, otherwise the activation template
437
+		if ($payment_method->ID() && ! empty($payment_method_scopes)) {
438
+			$form = $this->_generate_payment_method_settings_form($payment_method);
439
+			if ($form->form_data_present_in($this->_req_data)) {
440
+				$form->receive_form_submission($this->_req_data);
441
+			}
442
+			echo wp_kses($form->form_open() . $form->get_html_and_js() . $form->form_close(), AllowedTags::getWithFormTags());
443
+		} else {
444
+			echo wp_kses($this->_activate_payment_method_button($payment_method)->get_html_and_js(), AllowedTags::getWithFormTags());
445
+		}
446
+	}
447
+
448
+
449
+	/**
450
+	 * Gets the form for all the settings related to this payment method type
451
+	 *
452
+	 * @access protected
453
+	 * @param EE_Payment_Method $payment_method
454
+	 * @return EE_Form_Section_Proper
455
+	 * @throws EE_Error
456
+	 */
457
+	protected function _generate_payment_method_settings_form(EE_Payment_Method $payment_method = null)
458
+	{
459
+		if (! $payment_method instanceof EE_Payment_Method) {
460
+			return new EE_Form_Section_Proper();
461
+		}
462
+		return new EE_Form_Section_Proper(
463
+			array(
464
+				'name'            => $payment_method->slug() . '_settings_form',
465
+				'html_id'         => $payment_method->slug() . '_settings_form',
466
+				'action'          => EE_Admin_Page::add_query_args_and_nonce(
467
+					array(
468
+						'action'         => 'update_payment_method',
469
+						'payment_method' => $payment_method->slug(),
470
+					),
471
+					EE_PAYMENTS_ADMIN_URL
472
+				),
473
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
474
+				'subsections'     => apply_filters(
475
+					'FHEE__Payments_Admin_Page___generate_payment_method_settings_form__form_subsections',
476
+					array(
477
+						'pci_dss_compliance'      => $this->_pci_dss_compliance($payment_method),
478
+						'currency_support'        => $this->_currency_support($payment_method),
479
+						'payment_method_settings' => $this->_payment_method_settings($payment_method),
480
+						'update'                  => $this->_update_payment_method_button($payment_method),
481
+						'deactivate'              => $this->_deactivate_payment_method_button($payment_method),
482
+						'fine_print'              => $this->_fine_print(),
483
+					),
484
+					$payment_method
485
+				),
486
+			)
487
+		);
488
+	}
489
+
490
+
491
+	/**
492
+	 * _pci_dss_compliance
493
+	 *
494
+	 * @access protected
495
+	 * @param EE_Payment_Method $payment_method
496
+	 * @return EE_Form_Section_HTML
497
+	 * @throws EE_Error
498
+	 */
499
+	protected function _pci_dss_compliance(EE_Payment_Method $payment_method)
500
+	{
501
+		if ($payment_method->type_obj()->requires_https()) {
502
+			return new EE_Form_Section_HTML(
503
+				EEH_HTML::table(
504
+					EEH_HTML::tr(
505
+						EEH_HTML::th(
506
+							EEH_HTML::label(
507
+								EEH_HTML::strong(
508
+									esc_html__('IMPORTANT', 'event_espresso'),
509
+									'',
510
+									'important-notice'
511
+								)
512
+							)
513
+						) .
514
+						EEH_HTML::td(
515
+							EEH_HTML::strong(
516
+								esc_html__(
517
+									'You are responsible for your own website security and Payment Card Industry Data Security Standards (PCI DSS) compliance.',
518
+									'event_espresso'
519
+								)
520
+							)
521
+							.
522
+							EEH_HTML::br()
523
+							.
524
+							esc_html__('Learn more about ', 'event_espresso')
525
+							. EEH_HTML::link(
526
+								'https://www.pcisecuritystandards.org/merchants/index.php',
527
+								esc_html__('PCI DSS compliance', 'event_espresso')
528
+							)
529
+						)
530
+					)
531
+				)
532
+			);
533
+		}
534
+		return new EE_Form_Section_HTML('');
535
+	}
536
+
537
+
538
+	/**
539
+	 * _currency_support
540
+	 *
541
+	 * @access protected
542
+	 * @param EE_Payment_Method $payment_method
543
+	 * @return EE_Form_Section_HTML
544
+	 * @throws EE_Error
545
+	 */
546
+	protected function _currency_support(EE_Payment_Method $payment_method)
547
+	{
548
+		if (! $payment_method->usable_for_currency(EE_Config::instance()->currency->code)) {
549
+			return new EE_Form_Section_HTML(
550
+				EEH_HTML::table(
551
+					EEH_HTML::tr(
552
+						EEH_HTML::th(
553
+							EEH_HTML::label(
554
+								EEH_HTML::strong(
555
+									esc_html__('IMPORTANT', 'event_espresso'),
556
+									'',
557
+									'important-notice'
558
+								)
559
+							)
560
+						) .
561
+						EEH_HTML::td(
562
+							EEH_HTML::strong(
563
+								sprintf(
564
+									esc_html__(
565
+										'This payment method does not support the currency set on your site (%1$s). Please activate a different payment method or change your site\'s country and associated currency.',
566
+										'event_espresso'
567
+									),
568
+									EE_Config::instance()->currency->code
569
+								)
570
+							)
571
+						)
572
+					)
573
+				)
574
+			);
575
+		}
576
+		return new EE_Form_Section_HTML('');
577
+	}
578
+
579
+
580
+	/**
581
+	 * _update_payment_method_button
582
+	 *
583
+	 * @access protected
584
+	 * @param EE_Payment_Method $payment_method
585
+	 * @return EE_Payment_Method_Form
586
+	 * @throws EE_Error
587
+	 */
588
+	protected function _payment_method_settings(EE_Payment_Method $payment_method)
589
+	{
590
+		// modify the form, so we only have/show fields that will be implemented for this version
591
+		return $this->_simplify_form($payment_method->type_obj()->settings_form(), $payment_method->name());
592
+	}
593
+
594
+
595
+	/**
596
+	 * Simplifies the form to merely reproduce 4.1's gateway settings functionality
597
+	 *
598
+	 * @param EE_Form_Section_Proper $form_section
599
+	 * @param string                 $payment_method_name
600
+	 * @return EE_Payment_Method_Form
601
+	 * @throws EE_Error
602
+	 */
603
+	protected function _simplify_form($form_section, $payment_method_name = '')
604
+	{
605
+		if ($form_section instanceof EE_Payment_Method_Form) {
606
+			$form_section->exclude(
607
+				array(
608
+					'PMD_type', // don't want them changing the type
609
+					'PMD_slug', // or the slug (probably never)
610
+					'PMD_wp_user', // or the user's ID
611
+					'Currency' // or the currency, until the rest of EE supports simultaneous currencies
612
+				)
613
+			);
614
+			return $form_section;
615
+		} else {
616
+			throw new EE_Error(
617
+				sprintf(
618
+					esc_html__(
619
+						'The EE_Payment_Method_Form for the "%1$s" payment method is missing or invalid.',
620
+						'event_espresso'
621
+					),
622
+					$payment_method_name
623
+				)
624
+			);
625
+		}
626
+	}
627
+
628
+
629
+	/**
630
+	 * _update_payment_method_button
631
+	 *
632
+	 * @access protected
633
+	 * @param EE_Payment_Method $payment_method
634
+	 * @return EE_Form_Section_HTML
635
+	 * @throws EE_Error
636
+	 */
637
+	protected function _update_payment_method_button(EE_Payment_Method $payment_method)
638
+	{
639
+		$update_button = new EE_Submit_Input(
640
+			array(
641
+				'name'       => 'submit',
642
+				'html_id'    => 'save_' . $payment_method->slug() . '_settings',
643
+				'default'    => sprintf(
644
+					esc_html__('Update %s Payment Settings', 'event_espresso'),
645
+					$payment_method->admin_name()
646
+				),
647
+				'html_label' => EEH_HTML::nbsp(),
648
+			)
649
+		);
650
+		return new EE_Form_Section_HTML(
651
+			EEH_HTML::table(
652
+				EEH_HTML::no_row(EEH_HTML::br(2)) .
653
+				EEH_HTML::tr(
654
+					EEH_HTML::th(esc_html__('Update Settings', 'event_espresso')) .
655
+					EEH_HTML::td(
656
+						$update_button->get_html_for_input()
657
+					)
658
+				)
659
+			)
660
+		);
661
+	}
662
+
663
+
664
+	/**
665
+	 * _deactivate_payment_method_button
666
+	 *
667
+	 * @access protected
668
+	 * @param EE_Payment_Method $payment_method
669
+	 * @return EE_Form_Section_HTML
670
+	 */
671
+	protected function _deactivate_payment_method_button(EE_Payment_Method $payment_method)
672
+	{
673
+		$link_text_and_title = sprintf(
674
+			esc_html__('Deactivate %1$s Payments?', 'event_espresso'),
675
+			$payment_method->admin_name()
676
+		);
677
+		return new EE_Form_Section_HTML(
678
+			EEH_HTML::table(
679
+				EEH_HTML::tr(
680
+					EEH_HTML::th(esc_html__('Deactivate Payment Method', 'event_espresso')) .
681
+					EEH_HTML::td(
682
+						EEH_HTML::link(
683
+							EE_Admin_Page::add_query_args_and_nonce(
684
+								array(
685
+									'action'         => 'deactivate_payment_method',
686
+									'payment_method' => $payment_method->slug(),
687
+								),
688
+								EE_PAYMENTS_ADMIN_URL
689
+							),
690
+							$link_text_and_title,
691
+							$link_text_and_title,
692
+							'deactivate_' . $payment_method->slug(),
693
+							'espresso-button button-secondary'
694
+						)
695
+					)
696
+				)
697
+			)
698
+		);
699
+	}
700
+
701
+
702
+	/**
703
+	 * _activate_payment_method_button
704
+	 *
705
+	 * @access protected
706
+	 * @param EE_Payment_Method $payment_method
707
+	 * @return EE_Form_Section_Proper
708
+	 * @throws EE_Error
709
+	 */
710
+	protected function _activate_payment_method_button(EE_Payment_Method $payment_method)
711
+	{
712
+		$link_text_and_title = sprintf(
713
+			esc_html__('Activate %1$s Payment Method?', 'event_espresso'),
714
+			$payment_method->admin_name()
715
+		);
716
+		return new EE_Form_Section_Proper(
717
+			array(
718
+				'name'            => 'activate_' . $payment_method->slug() . '_settings_form',
719
+				'html_id'         => 'activate_' . $payment_method->slug() . '_settings_form',
720
+				'action'          => '#',
721
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
722
+				'subsections'     => apply_filters(
723
+					'FHEE__Payments_Admin_Page___activate_payment_method_button__form_subsections',
724
+					array(
725
+						new EE_Form_Section_HTML(
726
+							EEH_HTML::table(
727
+								EEH_HTML::tr(
728
+									EEH_HTML::td(
729
+										$payment_method->type_obj()->introductory_html(),
730
+										'',
731
+										'',
732
+										'',
733
+										'colspan="2"'
734
+									)
735
+								) .
736
+								EEH_HTML::tr(
737
+									EEH_HTML::th(
738
+										EEH_HTML::label(esc_html__('Click to Activate ', 'event_espresso'))
739
+									) .
740
+									EEH_HTML::td(
741
+										EEH_HTML::link(
742
+											EE_Admin_Page::add_query_args_and_nonce(
743
+												array(
744
+													'action'              => 'activate_payment_method',
745
+													'payment_method_type' => $payment_method->type(),
746
+												),
747
+												EE_PAYMENTS_ADMIN_URL
748
+											),
749
+											$link_text_and_title,
750
+											$link_text_and_title,
751
+											'activate_' . $payment_method->slug(),
752
+											'espresso-button-green button-primary'
753
+										)
754
+									)
755
+								)
756
+							)
757
+						),
758
+					),
759
+					$payment_method
760
+				),
761
+			)
762
+		);
763
+	}
764
+
765
+
766
+	/**
767
+	 * _fine_print
768
+	 *
769
+	 * @access protected
770
+	 * @return EE_Form_Section_HTML
771
+	 */
772
+	protected function _fine_print()
773
+	{
774
+		return new EE_Form_Section_HTML(
775
+			EEH_HTML::table(
776
+				EEH_HTML::tr(
777
+					EEH_HTML::th() .
778
+					EEH_HTML::td(
779
+						EEH_HTML::p(esc_html__('All fields marked with a * are required fields', 'event_espresso'), '', 'grey-text')
780
+					)
781
+				)
782
+			)
783
+		);
784
+	}
785
+
786
+
787
+	/**
788
+	 * Activates a payment method of that type. Mostly assuming there is only 1 of that type (or none so far)
789
+	 *
790
+	 * @throws EE_Error
791
+	 * @throws ReflectionException
792
+	 * @global WP_User $current_user
793
+	 */
794
+	protected function _activate_payment_method()
795
+	{
796
+		if (isset($this->_req_data['payment_method_type'])) {
797
+			$payment_method_type = sanitize_text_field($this->_req_data['payment_method_type']);
798
+			// see if one exists
799
+			EE_Registry::instance()->load_lib('Payment_Method_Manager');
800
+			$payment_method = EE_Payment_Method_Manager::instance()
801
+													   ->activate_a_payment_method_of_type($payment_method_type);
802
+			$this->_redirect_after_action(
803
+				1,
804
+				'Payment Method',
805
+				'activated',
806
+				array('action' => 'default', 'payment_method' => $payment_method->slug())
807
+			);
808
+		} else {
809
+			$this->_redirect_after_action(false, 'Payment Method', 'activated', array('action' => 'default'));
810
+		}
811
+	}
812
+
813
+
814
+	/**
815
+	 * @throws EE_Error
816
+	 * @throws ReflectionException
817
+	 */
818
+	protected function _deactivate_payment_method()
819
+	{
820
+		if (isset($this->_req_data['payment_method'])) {
821
+			$payment_method_slug = sanitize_key($this->_req_data['payment_method']);
822
+			// deactivate it
823
+			EE_Registry::instance()->load_lib('Payment_Method_Manager');
824
+			$count_updated = EE_Payment_Method_Manager::instance()->deactivate_payment_method($payment_method_slug);
825
+			$this->_redirect_after_action(
826
+				$count_updated,
827
+				'Payment Method',
828
+				'deactivated',
829
+				array('action' => 'default', 'payment_method' => $payment_method_slug)
830
+			);
831
+		} else {
832
+			$this->_redirect_after_action(false, 'Payment Method', 'deactivated', array('action' => 'default'));
833
+		}
834
+	}
835
+
836
+
837
+	/**
838
+	 * Processes the payment method form that was submitted. This is slightly trickier than usual form
839
+	 * processing because we first need to identify WHICH form was processed and which payment method
840
+	 * it corresponds to. Once we have done that, we see if the form is valid. If it is, the
841
+	 * form's data is saved, and we redirect to the default payment methods page, setting the updated payment method
842
+	 * as the currently-selected one. If it DOESN'T validate, we render the page with the form's errors (in the
843
+	 * subsequently called 'headers_sent_func' which is _payment_methods_list)
844
+	 *
845
+	 * @return void
846
+	 * @throws EE_Error
847
+	 * @throws ReflectionException
848
+	 */
849
+	protected function _update_payment_method()
850
+	{
851
+		if ($_SERVER['REQUEST_METHOD'] == 'POST') {
852
+			// ok let's find which gateway form to use based on the form input
853
+			EE_Registry::instance()->load_lib('Payment_Method_Manager');
854
+			/** @var $correct_pmt_form_to_use EE_Payment_Method_Form */
855
+			$correct_pmt_form_to_use = null;
856
+			$payment_method = null;
857
+			foreach (EEM_Payment_Method::instance()->get_all() as $payment_method) {
858
+				if ($payment_method instanceof EE_Payment_Method) {
859
+					// get the form and simplify it, like what we do when we display it
860
+					$pmt_form = $this->_generate_payment_method_settings_form($payment_method);
861
+					if ($pmt_form->form_data_present_in($this->_req_data)) {
862
+						$correct_pmt_form_to_use = $pmt_form;
863
+						break;
864
+					}
865
+				}
866
+			}
867
+			// if we couldn't find the correct payment method type...
868
+			if (! $correct_pmt_form_to_use) {
869
+				EE_Error::add_error(
870
+					esc_html__(
871
+						"We could not find which payment method type your form submission related to. Please contact support",
872
+						'event_espresso'
873
+					),
874
+					__FILE__,
875
+					__FUNCTION__,
876
+					__LINE__
877
+				);
878
+				$this->_redirect_after_action(false, 'Payment Method', 'activated', array('action' => 'default'));
879
+			}
880
+			$correct_pmt_form_to_use->receive_form_submission($this->_req_data);
881
+			if ($correct_pmt_form_to_use->is_valid()) {
882
+				$payment_settings_subform = $correct_pmt_form_to_use->get_subsection('payment_method_settings');
883
+				if (! $payment_settings_subform instanceof EE_Payment_Method_Form) {
884
+					throw new EE_Error(
885
+						sprintf(
886
+							esc_html__(
887
+								'The payment method could not be saved because the form sections were misnamed. We expected to find %1$s, but did not.',
888
+								'event_espresso'
889
+							),
890
+							'payment_method_settings'
891
+						)
892
+					);
893
+				}
894
+				$payment_settings_subform->save();
895
+				/** @var $pm EE_Payment_Method */
896
+				$this->_redirect_after_action(
897
+					true,
898
+					'Payment Method',
899
+					'updated',
900
+					array('action' => 'default', 'payment_method' => $payment_method->slug())
901
+				);
902
+			} else {
903
+				EE_Error::add_error(
904
+					sprintf(
905
+						esc_html__(
906
+							'Payment method of type %s was not saved because there were validation errors. They have been marked in the form',
907
+							'event_espresso'
908
+						),
909
+						$payment_method instanceof EE_Payment_Method ? $payment_method->type_obj()->pretty_name()
910
+							: esc_html__('"(unknown)"', 'event_espresso')
911
+					),
912
+					__FILE__,
913
+					__FUNCTION__,
914
+					__LINE__
915
+				);
916
+			}
917
+		}
918
+	}
919
+
920
+
921
+	/**
922
+	 * Displays payment settings (not payment METHOD settings, that's _payment_method_settings)
923
+	 * @throws DomainException
924
+	 * @throws EE_Error
925
+	 * @throws InvalidArgumentException
926
+	 * @throws InvalidDataTypeException
927
+	 * @throws InvalidInterfaceException
928
+	 */
929
+	protected function _payment_settings()
930
+	{
931
+		$form = $this->getPaymentSettingsForm();
932
+		$this->_set_add_edit_form_tags('update_payment_settings');
933
+		$this->_set_publish_post_box_vars(null, false, false, null, false);
934
+		$this->_template_args['admin_page_content'] =  $form->get_html_and_js();
935
+		$this->display_admin_page_with_sidebar();
936
+	}
937
+
938
+
939
+	/**
940
+	 *        _update_payment_settings
941
+	 *
942
+	 * @access protected
943
+	 * @return void
944
+	 * @throws EE_Error
945
+	 * @throws InvalidArgumentException
946
+	 * @throws InvalidDataTypeException
947
+	 * @throws InvalidInterfaceException
948
+	 */
949
+	protected function _update_payment_settings()
950
+	{
951
+		$form = $this->getPaymentSettingsForm();
952
+		if ($form->was_submitted($this->_req_data)) {
953
+			$form->receive_form_submission($this->_req_data);
954
+			if ($form->is_valid()) {
955
+				/**
956
+				 * @var $reg_config EE_Registration_Config
957
+				 */
958
+				$loader = LoaderFactory::getLoader();
959
+				$reg_config = $loader->getShared('EE_Registration_Config');
960
+				$valid_data = $form->valid_data();
961
+				$reg_config->show_pending_payment_options = $valid_data['show_pending_payment_options'];
962
+				$reg_config->gateway_log_lifespan = $valid_data['gateway_log_lifespan'];
963
+			}
964
+		}
965
+		EE_Registry::instance()->CFG = apply_filters(
966
+			'FHEE__Payments_Admin_Page___update_payment_settings__CFG',
967
+			EE_Registry::instance()->CFG
968
+		);
969
+
970
+		$what = esc_html__('Payment Settings', 'event_espresso');
971
+		$success = $this->_update_espresso_configuration(
972
+			$what,
973
+			EE_Registry::instance()->CFG,
974
+			__FILE__,
975
+			__FUNCTION__,
976
+			__LINE__
977
+		);
978
+		$this->_redirect_after_action(
979
+			$success,
980
+			$what,
981
+			esc_html__('updated', 'event_espresso'),
982
+			array('action' => 'payment_settings')
983
+		);
984
+	}
985
+
986
+
987
+	/**
988
+	 * Gets the form used for updating payment settings
989
+	 *
990
+	 * @return EE_Form_Section_Proper
991
+	 * @throws EE_Error
992
+	 * @throws InvalidArgumentException
993
+	 * @throws InvalidDataTypeException
994
+	 * @throws InvalidInterfaceException
995
+	 */
996
+	protected function getPaymentSettingsForm()
997
+	{
998
+		/**
999
+		 * @var $reg_config EE_Registration_Config
1000
+		 */
1001
+		$reg_config = LoaderFactory::getLoader()->getShared('EE_Registration_Config');
1002
+		return new EE_Form_Section_Proper(
1003
+			array(
1004
+				'name' => 'payment-settings',
1005
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1006
+				'subsections' => array(
1007
+					'show_pending_payment_options' => new EE_Yes_No_Input(
1008
+						array(
1009
+							'html_name' => 'show_pending_payment_options',
1010
+							'default' => $reg_config->show_pending_payment_options,
1011
+							'html_help_text' => esc_html__(
1012
+								"If a payment is marked as 'Pending Payment', or if payment is deferred (ie, an offline gateway like Check, Bank, or Invoice is used), then give registrants the option to retry payment. ",
1013
+								'event_espresso'
1014
+							)
1015
+						)
1016
+					),
1017
+					'gateway_log_lifespan' => new EE_Select_Input(
1018
+						$reg_config->gatewayLogLifespanOptions(),
1019
+						array(
1020
+							'html_label_text' => esc_html__('Gateway Logs Lifespan', 'event_espresso'),
1021
+							'html_help_text' => esc_html__('If issues arise with payments being made through a payment gateway, it\'s helpful to log non-sensitive communications with the payment gateway. But it\'s a security responsibility, so it\'s a good idea to not keep them for any longer than necessary.', 'event_espresso'),
1022
+							'default' => $reg_config->gateway_log_lifespan,
1023
+						)
1024
+					)
1025
+				)
1026
+			)
1027
+		);
1028
+	}
1029
+
1030
+
1031
+	/**
1032
+	 * @throws EE_Error
1033
+	 */
1034
+	protected function _payment_log_overview_list_table()
1035
+	{
1036
+		$this->display_admin_list_table_page_with_sidebar();
1037
+	}
1038
+
1039
+
1040
+	protected function _set_list_table_views_payment_log()
1041
+	{
1042
+		$this->_views = array(
1043
+			'all' => array(
1044
+				'slug'  => 'all',
1045
+				'label' => esc_html__('View All Logs', 'event_espresso'),
1046
+				'count' => 0,
1047
+			),
1048
+		);
1049
+	}
1050
+
1051
+
1052
+	/**
1053
+	 * @param int  $per_page
1054
+	 * @param int  $current_page
1055
+	 * @param bool $count
1056
+	 * @return array|int
1057
+	 * @throws EE_Error
1058
+	 * @throws ReflectionException
1059
+	 */
1060
+	public function get_payment_logs($per_page = 50, $current_page = 0, $count = false)
1061
+	{
1062
+		EE_Registry::instance()->load_model('Change_Log');
1063
+		// we may need to do multiple queries (joining differently), so we actually want an array of query params
1064
+		$query_params = array(array('LOG_type' => EEM_Change_Log::type_gateway));
1065
+		// check if they've selected a specific payment method
1066
+		if (isset($this->_req_data['_payment_method']) && $this->_req_data['_payment_method'] !== 'all') {
1067
+			$query_params[0]['OR*pm_or_pay_pm'] = array(
1068
+				'Payment.Payment_Method.PMD_ID' => $this->_req_data['_payment_method'],
1069
+				'Payment_Method.PMD_ID'         => $this->_req_data['_payment_method'],
1070
+			);
1071
+		}
1072
+		// take into account search
1073
+		if (isset($this->_req_data['s']) && $this->_req_data['s']) {
1074
+			$similarity_string = array('LIKE', '%' . str_replace("", "%", $this->_req_data['s']) . '%');
1075
+			$query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_fname'] = $similarity_string;
1076
+			$query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_lname'] = $similarity_string;
1077
+			$query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_email'] = $similarity_string;
1078
+			$query_params[0]['OR*s']['Payment.Payment_Method.PMD_name'] = $similarity_string;
1079
+			$query_params[0]['OR*s']['Payment.Payment_Method.PMD_admin_name'] = $similarity_string;
1080
+			$query_params[0]['OR*s']['Payment.Payment_Method.PMD_type'] = $similarity_string;
1081
+			$query_params[0]['OR*s']['LOG_message'] = $similarity_string;
1082
+			$query_params[0]['OR*s']['Payment_Method.PMD_name'] = $similarity_string;
1083
+			$query_params[0]['OR*s']['Payment_Method.PMD_admin_name'] = $similarity_string;
1084
+			$query_params[0]['OR*s']['Payment_Method.PMD_type'] = $similarity_string;
1085
+			$query_params[0]['OR*s']['LOG_message'] = $similarity_string;
1086
+		}
1087
+		if (
1088
+			isset($this->_req_data['payment-filter-start-date'])
1089
+			&& isset($this->_req_data['payment-filter-end-date'])
1090
+		) {
1091
+			// add date
1092
+			$start_date = wp_strip_all_tags($this->_req_data['payment-filter-start-date']);
1093
+			$end_date = wp_strip_all_tags($this->_req_data['payment-filter-end-date']);
1094
+			// make sure our timestamps start and end right at the boundaries for each day
1095
+			$start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
1096
+			$end_date = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
1097
+			// convert to timestamps
1098
+			$start_date = strtotime($start_date);
1099
+			$end_date = strtotime($end_date);
1100
+			// makes sure start date is the lowest value and vice versa
1101
+			$start_date = min($start_date, $end_date);
1102
+			$end_date = max($start_date, $end_date);
1103
+			// convert for query
1104
+			$start_date = EEM_Change_Log::instance()->convert_datetime_for_query(
1105
+				'LOG_time',
1106
+				date('Y-m-d H:i:s', $start_date),
1107
+				'Y-m-d H:i:s'
1108
+			);
1109
+			$end_date   = EEM_Change_Log::instance()->convert_datetime_for_query(
1110
+				'LOG_time',
1111
+				date('Y-m-d H:i:s', $end_date),
1112
+				'Y-m-d H:i:s'
1113
+			);
1114
+			$query_params[0]['LOG_time'] = array('BETWEEN', array($start_date, $end_date));
1115
+		}
1116
+		if ($count) {
1117
+			return EEM_Change_Log::instance()->count($query_params);
1118
+		}
1119
+		if (isset($this->_req_data['order'])) {
1120
+			$sort = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
1121
+				? $this->_req_data['order']
1122
+				: 'DESC';
1123
+			$query_params['order_by'] = array('LOG_time' => $sort);
1124
+		} else {
1125
+			$query_params['order_by'] = array('LOG_time' => 'DESC');
1126
+		}
1127
+		$offset = ($current_page - 1) * $per_page;
1128
+		if (! isset($this->_req_data['download_results'])) {
1129
+			$query_params['limit'] = array($offset, $per_page);
1130
+		}
1131
+		// now they've requested to instead just download the file instead of viewing it.
1132
+		if (isset($this->_req_data['download_results'])) {
1133
+			$wpdb_results = EEM_Change_Log::instance()->get_all_efficiently($query_params);
1134
+			header('Content-Disposition: attachment');
1135
+			header("Content-Disposition: attachment; filename=ee_payment_logs_for_" . sanitize_key(site_url()));
1136
+			echo '<h1> '
1137
+				. sprintf(
1138
+					esc_html__('Payment Logs for %1$s', 'event_espresso'),
1139
+					esc_url_raw(site_url())
1140
+				)
1141
+				. '</h1 >';
1142
+			echo '<h3>' . esc_html__('Query:', 'event_espresso') . '</h3>';
1143
+			echo esc_html(var_export($query_params, true));
1144
+			echo '<h3>' . esc_html__('Results:', 'event_espresso') . '</h3>';
1145
+			echo esc_html(var_export($wpdb_results, true));
1146
+			die;
1147
+		}
1148
+		return EEM_Change_Log::instance()->get_all($query_params);
1149
+	}
1150
+
1151
+
1152
+	/**
1153
+	 * Used by usort to RE-sort log query results, because we lose the ordering
1154
+	 * because we're possibly combining the results from two queries
1155
+	 *
1156
+	 * @param EE_Change_Log $logA
1157
+	 * @param EE_Change_Log $logB
1158
+	 * @return int
1159
+	 * @throws EE_Error
1160
+	 * @throws ReflectionException
1161
+	 */
1162
+	protected function _sort_logs_again($logA, $logB)
1163
+	{
1164
+		$timeA = $logA->get_raw('LOG_time');
1165
+		$timeB = $logB->get_raw('LOG_time');
1166
+		if ($timeA == $timeB) {
1167
+			return 0;
1168
+		}
1169
+		$comparison = $timeA < $timeB ? -1 : 1;
1170
+		if (strtoupper($this->_sort_logs_again_direction) == 'DESC') {
1171
+			return $comparison * -1;
1172
+		}
1173
+		return $comparison;
1174
+	}
1175
+
1176
+
1177
+	/**
1178
+	 * @throws EE_Error
1179
+	 * @throws ReflectionException
1180
+	 */
1181
+	protected function _payment_log_details()
1182
+	{
1183
+		EE_Registry::instance()->load_model('Change_Log');
1184
+		/** @var $payment_log EE_Change_Log */
1185
+		$payment_log = EEM_Change_Log::instance()->get_one_by_ID($this->_req_data['ID']);
1186
+		$payment_method = null;
1187
+		$transaction = null;
1188
+		if ($payment_log instanceof EE_Change_Log) {
1189
+			if ($payment_log->object() instanceof EE_Payment) {
1190
+				$payment_method = $payment_log->object()->payment_method();
1191
+				$transaction = $payment_log->object()->transaction();
1192
+			} elseif ($payment_log->object() instanceof EE_Payment_Method) {
1193
+				$payment_method = $payment_log->object();
1194
+			} elseif ($payment_log->object() instanceof EE_Transaction) {
1195
+				$transaction = $payment_log->object();
1196
+				$payment_method = $transaction->payment_method();
1197
+			}
1198
+		}
1199
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
1200
+			EE_PAYMENTS_TEMPLATE_PATH . 'payment_log_details.template.php',
1201
+			array(
1202
+				'payment_log'    => $payment_log,
1203
+				'payment_method' => $payment_method,
1204
+				'transaction'    => $transaction,
1205
+			),
1206
+			true
1207
+		);
1208
+		$this->display_admin_page_with_sidebar();
1209
+	}
1210 1210
 }
Please login to merge, or discard this patch.
Spacing   +41 added lines, -41 removed lines patch added patch discarded remove patch
@@ -195,10 +195,10 @@  discard block
 block discarded – undo
195 195
             foreach ($payment_method_type->help_tabs_config() as $help_tab_name => $config) {
196 196
                 $template_args = isset($config['template_args']) ? $config['template_args'] : array();
197 197
                 $template_args['admin_page_obj'] = $this;
198
-                $all_pmt_help_tabs_config[ $help_tab_name ] = array(
198
+                $all_pmt_help_tabs_config[$help_tab_name] = array(
199 199
                     'title'   => $config['title'],
200 200
                     'content' => EEH_Template::display_template(
201
-                        $payment_method_type->file_folder() . 'help_tabs/' . $config['filename'] . '.help_tab.php',
201
+                        $payment_method_type->file_folder().'help_tabs/'.$config['filename'].'.help_tab.php',
202 202
                         $template_args,
203 203
                         true
204 204
                     ),
@@ -244,7 +244,7 @@  discard block
 block discarded – undo
244 244
         wp_enqueue_script('ee-text-links');
245 245
         wp_enqueue_script(
246 246
             'espresso_payments',
247
-            EE_PAYMENTS_ASSETS_URL . 'espresso_payments_admin.js',
247
+            EE_PAYMENTS_ASSETS_URL.'espresso_payments_admin.js',
248 248
             array('ee-datepicker'),
249 249
             EVENT_ESPRESSO_VERSION,
250 250
             true
@@ -257,7 +257,7 @@  discard block
 block discarded – undo
257 257
         // styles
258 258
         wp_register_style(
259 259
             'espresso_payments',
260
-            EE_PAYMENTS_ASSETS_URL . 'ee-payments.css',
260
+            EE_PAYMENTS_ASSETS_URL.'ee-payments.css',
261 261
             array(),
262 262
             EVENT_ESPRESSO_VERSION
263 263
         );
@@ -301,7 +301,7 @@  discard block
 block discarded – undo
301 301
             }
302 302
             // check for any active pms of that type
303 303
             $payment_method = EEM_Payment_Method::instance()->get_one_of_type($pmt_obj->system_name());
304
-            if (! $payment_method instanceof EE_Payment_Method) {
304
+            if ( ! $payment_method instanceof EE_Payment_Method) {
305 305
                 $payment_method = EE_Payment_Method::new_instance(
306 306
                     array(
307 307
                         'PMD_slug'       => sanitize_key($pmt_obj->system_name()),
@@ -311,7 +311,7 @@  discard block
 block discarded – undo
311 311
                     )
312 312
                 );
313 313
             }
314
-            $payment_methods[ $payment_method->slug() ] = $payment_method;
314
+            $payment_methods[$payment_method->slug()] = $payment_method;
315 315
         }
316 316
         $payment_methods = apply_filters(
317 317
             'FHEE__Payments_Admin_Page___payment_methods_list__payment_methods',
@@ -321,7 +321,7 @@  discard block
 block discarded – undo
321 321
             if ($payment_method instanceof EE_Payment_Method) {
322 322
                 add_meta_box(
323 323
                     // html id
324
-                    'espresso_' . $payment_method->slug() . '_payment_settings',
324
+                    'espresso_'.$payment_method->slug().'_payment_settings',
325 325
                     // title
326 326
                     sprintf(esc_html__('%s Settings', 'event_espresso'), $payment_method->admin_name()),
327 327
                     // callback
@@ -336,10 +336,10 @@  discard block
 block discarded – undo
336 336
                     array('payment_method' => $payment_method)
337 337
                 );
338 338
                 // setup for tabbed content
339
-                $tabs[ $payment_method->slug() ] = array(
339
+                $tabs[$payment_method->slug()] = array(
340 340
                     'label' => $payment_method->admin_name(),
341 341
                     'class' => $payment_method->active() ? 'gateway-active' : '',
342
-                    'href'  => 'espresso_' . $payment_method->slug() . '_payment_settings',
342
+                    'href'  => 'espresso_'.$payment_method->slug().'_payment_settings',
343 343
                     'title' => esc_html__('Modify this Payment Method', 'event_espresso'),
344 344
                     'slug'  => $payment_method->slug(),
345 345
                 );
@@ -372,7 +372,7 @@  discard block
 block discarded – undo
372 372
         /** @var EE_Payment_Method $payment_method */
373 373
         $payment_method = EEM_Payment_Method::instance()->get_one(array(array('PMD_slug' => $payment_method_slug)));
374 374
         // if that didn't work or wasn't provided, find another way to select the current pm
375
-        if (! $this->_verify_payment_method($payment_method)) {
375
+        if ( ! $this->_verify_payment_method($payment_method)) {
376 376
             // like, looking for an active one
377 377
             $payment_method = EEM_Payment_Method::instance()->get_one_active('CART');
378 378
             // test that one as well
@@ -424,7 +424,7 @@  discard block
 block discarded – undo
424 424
     {
425 425
         $payment_method = isset($metabox['args'], $metabox['args']['payment_method'])
426 426
             ? $metabox['args']['payment_method'] : null;
427
-        if (! $payment_method instanceof EE_Payment_Method) {
427
+        if ( ! $payment_method instanceof EE_Payment_Method) {
428 428
             throw new EE_Error(
429 429
                 esc_html__(
430 430
                     'Payment method metabox setup incorrectly. No Payment method object was supplied',
@@ -439,7 +439,7 @@  discard block
 block discarded – undo
439 439
             if ($form->form_data_present_in($this->_req_data)) {
440 440
                 $form->receive_form_submission($this->_req_data);
441 441
             }
442
-            echo wp_kses($form->form_open() . $form->get_html_and_js() . $form->form_close(), AllowedTags::getWithFormTags());
442
+            echo wp_kses($form->form_open().$form->get_html_and_js().$form->form_close(), AllowedTags::getWithFormTags());
443 443
         } else {
444 444
             echo wp_kses($this->_activate_payment_method_button($payment_method)->get_html_and_js(), AllowedTags::getWithFormTags());
445 445
         }
@@ -456,13 +456,13 @@  discard block
 block discarded – undo
456 456
      */
457 457
     protected function _generate_payment_method_settings_form(EE_Payment_Method $payment_method = null)
458 458
     {
459
-        if (! $payment_method instanceof EE_Payment_Method) {
459
+        if ( ! $payment_method instanceof EE_Payment_Method) {
460 460
             return new EE_Form_Section_Proper();
461 461
         }
462 462
         return new EE_Form_Section_Proper(
463 463
             array(
464
-                'name'            => $payment_method->slug() . '_settings_form',
465
-                'html_id'         => $payment_method->slug() . '_settings_form',
464
+                'name'            => $payment_method->slug().'_settings_form',
465
+                'html_id'         => $payment_method->slug().'_settings_form',
466 466
                 'action'          => EE_Admin_Page::add_query_args_and_nonce(
467 467
                     array(
468 468
                         'action'         => 'update_payment_method',
@@ -510,7 +510,7 @@  discard block
 block discarded – undo
510 510
                                     'important-notice'
511 511
                                 )
512 512
                             )
513
-                        ) .
513
+                        ).
514 514
                         EEH_HTML::td(
515 515
                             EEH_HTML::strong(
516 516
                                 esc_html__(
@@ -545,7 +545,7 @@  discard block
 block discarded – undo
545 545
      */
546 546
     protected function _currency_support(EE_Payment_Method $payment_method)
547 547
     {
548
-        if (! $payment_method->usable_for_currency(EE_Config::instance()->currency->code)) {
548
+        if ( ! $payment_method->usable_for_currency(EE_Config::instance()->currency->code)) {
549 549
             return new EE_Form_Section_HTML(
550 550
                 EEH_HTML::table(
551 551
                     EEH_HTML::tr(
@@ -557,7 +557,7 @@  discard block
 block discarded – undo
557 557
                                     'important-notice'
558 558
                                 )
559 559
                             )
560
-                        ) .
560
+                        ).
561 561
                         EEH_HTML::td(
562 562
                             EEH_HTML::strong(
563 563
                                 sprintf(
@@ -639,7 +639,7 @@  discard block
 block discarded – undo
639 639
         $update_button = new EE_Submit_Input(
640 640
             array(
641 641
                 'name'       => 'submit',
642
-                'html_id'    => 'save_' . $payment_method->slug() . '_settings',
642
+                'html_id'    => 'save_'.$payment_method->slug().'_settings',
643 643
                 'default'    => sprintf(
644 644
                     esc_html__('Update %s Payment Settings', 'event_espresso'),
645 645
                     $payment_method->admin_name()
@@ -649,9 +649,9 @@  discard block
 block discarded – undo
649 649
         );
650 650
         return new EE_Form_Section_HTML(
651 651
             EEH_HTML::table(
652
-                EEH_HTML::no_row(EEH_HTML::br(2)) .
652
+                EEH_HTML::no_row(EEH_HTML::br(2)).
653 653
                 EEH_HTML::tr(
654
-                    EEH_HTML::th(esc_html__('Update Settings', 'event_espresso')) .
654
+                    EEH_HTML::th(esc_html__('Update Settings', 'event_espresso')).
655 655
                     EEH_HTML::td(
656 656
                         $update_button->get_html_for_input()
657 657
                     )
@@ -677,7 +677,7 @@  discard block
 block discarded – undo
677 677
         return new EE_Form_Section_HTML(
678 678
             EEH_HTML::table(
679 679
                 EEH_HTML::tr(
680
-                    EEH_HTML::th(esc_html__('Deactivate Payment Method', 'event_espresso')) .
680
+                    EEH_HTML::th(esc_html__('Deactivate Payment Method', 'event_espresso')).
681 681
                     EEH_HTML::td(
682 682
                         EEH_HTML::link(
683 683
                             EE_Admin_Page::add_query_args_and_nonce(
@@ -689,7 +689,7 @@  discard block
 block discarded – undo
689 689
                             ),
690 690
                             $link_text_and_title,
691 691
                             $link_text_and_title,
692
-                            'deactivate_' . $payment_method->slug(),
692
+                            'deactivate_'.$payment_method->slug(),
693 693
                             'espresso-button button-secondary'
694 694
                         )
695 695
                     )
@@ -715,8 +715,8 @@  discard block
 block discarded – undo
715 715
         );
716 716
         return new EE_Form_Section_Proper(
717 717
             array(
718
-                'name'            => 'activate_' . $payment_method->slug() . '_settings_form',
719
-                'html_id'         => 'activate_' . $payment_method->slug() . '_settings_form',
718
+                'name'            => 'activate_'.$payment_method->slug().'_settings_form',
719
+                'html_id'         => 'activate_'.$payment_method->slug().'_settings_form',
720 720
                 'action'          => '#',
721 721
                 'layout_strategy' => new EE_Admin_Two_Column_Layout(),
722 722
                 'subsections'     => apply_filters(
@@ -732,11 +732,11 @@  discard block
 block discarded – undo
732 732
                                         '',
733 733
                                         'colspan="2"'
734 734
                                     )
735
-                                ) .
735
+                                ).
736 736
                                 EEH_HTML::tr(
737 737
                                     EEH_HTML::th(
738 738
                                         EEH_HTML::label(esc_html__('Click to Activate ', 'event_espresso'))
739
-                                    ) .
739
+                                    ).
740 740
                                     EEH_HTML::td(
741 741
                                         EEH_HTML::link(
742 742
                                             EE_Admin_Page::add_query_args_and_nonce(
@@ -748,7 +748,7 @@  discard block
 block discarded – undo
748 748
                                             ),
749 749
                                             $link_text_and_title,
750 750
                                             $link_text_and_title,
751
-                                            'activate_' . $payment_method->slug(),
751
+                                            'activate_'.$payment_method->slug(),
752 752
                                             'espresso-button-green button-primary'
753 753
                                         )
754 754
                                     )
@@ -774,7 +774,7 @@  discard block
 block discarded – undo
774 774
         return new EE_Form_Section_HTML(
775 775
             EEH_HTML::table(
776 776
                 EEH_HTML::tr(
777
-                    EEH_HTML::th() .
777
+                    EEH_HTML::th().
778 778
                     EEH_HTML::td(
779 779
                         EEH_HTML::p(esc_html__('All fields marked with a * are required fields', 'event_espresso'), '', 'grey-text')
780 780
                     )
@@ -865,7 +865,7 @@  discard block
 block discarded – undo
865 865
                 }
866 866
             }
867 867
             // if we couldn't find the correct payment method type...
868
-            if (! $correct_pmt_form_to_use) {
868
+            if ( ! $correct_pmt_form_to_use) {
869 869
                 EE_Error::add_error(
870 870
                     esc_html__(
871 871
                         "We could not find which payment method type your form submission related to. Please contact support",
@@ -880,7 +880,7 @@  discard block
 block discarded – undo
880 880
             $correct_pmt_form_to_use->receive_form_submission($this->_req_data);
881 881
             if ($correct_pmt_form_to_use->is_valid()) {
882 882
                 $payment_settings_subform = $correct_pmt_form_to_use->get_subsection('payment_method_settings');
883
-                if (! $payment_settings_subform instanceof EE_Payment_Method_Form) {
883
+                if ( ! $payment_settings_subform instanceof EE_Payment_Method_Form) {
884 884
                     throw new EE_Error(
885 885
                         sprintf(
886 886
                             esc_html__(
@@ -931,7 +931,7 @@  discard block
 block discarded – undo
931 931
         $form = $this->getPaymentSettingsForm();
932 932
         $this->_set_add_edit_form_tags('update_payment_settings');
933 933
         $this->_set_publish_post_box_vars(null, false, false, null, false);
934
-        $this->_template_args['admin_page_content'] =  $form->get_html_and_js();
934
+        $this->_template_args['admin_page_content'] = $form->get_html_and_js();
935 935
         $this->display_admin_page_with_sidebar();
936 936
     }
937 937
 
@@ -1071,7 +1071,7 @@  discard block
 block discarded – undo
1071 1071
         }
1072 1072
         // take into account search
1073 1073
         if (isset($this->_req_data['s']) && $this->_req_data['s']) {
1074
-            $similarity_string = array('LIKE', '%' . str_replace("", "%", $this->_req_data['s']) . '%');
1074
+            $similarity_string = array('LIKE', '%'.str_replace("", "%", $this->_req_data['s']).'%');
1075 1075
             $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_fname'] = $similarity_string;
1076 1076
             $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_lname'] = $similarity_string;
1077 1077
             $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_email'] = $similarity_string;
@@ -1092,8 +1092,8 @@  discard block
 block discarded – undo
1092 1092
             $start_date = wp_strip_all_tags($this->_req_data['payment-filter-start-date']);
1093 1093
             $end_date = wp_strip_all_tags($this->_req_data['payment-filter-end-date']);
1094 1094
             // make sure our timestamps start and end right at the boundaries for each day
1095
-            $start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
1096
-            $end_date = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
1095
+            $start_date = date('Y-m-d', strtotime($start_date)).' 00:00:00';
1096
+            $end_date = date('Y-m-d', strtotime($end_date)).' 23:59:59';
1097 1097
             // convert to timestamps
1098 1098
             $start_date = strtotime($start_date);
1099 1099
             $end_date = strtotime($end_date);
@@ -1106,7 +1106,7 @@  discard block
 block discarded – undo
1106 1106
                 date('Y-m-d H:i:s', $start_date),
1107 1107
                 'Y-m-d H:i:s'
1108 1108
             );
1109
-            $end_date   = EEM_Change_Log::instance()->convert_datetime_for_query(
1109
+            $end_date = EEM_Change_Log::instance()->convert_datetime_for_query(
1110 1110
                 'LOG_time',
1111 1111
                 date('Y-m-d H:i:s', $end_date),
1112 1112
                 'Y-m-d H:i:s'
@@ -1125,23 +1125,23 @@  discard block
 block discarded – undo
1125 1125
             $query_params['order_by'] = array('LOG_time' => 'DESC');
1126 1126
         }
1127 1127
         $offset = ($current_page - 1) * $per_page;
1128
-        if (! isset($this->_req_data['download_results'])) {
1128
+        if ( ! isset($this->_req_data['download_results'])) {
1129 1129
             $query_params['limit'] = array($offset, $per_page);
1130 1130
         }
1131 1131
         // now they've requested to instead just download the file instead of viewing it.
1132 1132
         if (isset($this->_req_data['download_results'])) {
1133 1133
             $wpdb_results = EEM_Change_Log::instance()->get_all_efficiently($query_params);
1134 1134
             header('Content-Disposition: attachment');
1135
-            header("Content-Disposition: attachment; filename=ee_payment_logs_for_" . sanitize_key(site_url()));
1135
+            header("Content-Disposition: attachment; filename=ee_payment_logs_for_".sanitize_key(site_url()));
1136 1136
             echo '<h1> '
1137 1137
                 . sprintf(
1138 1138
                     esc_html__('Payment Logs for %1$s', 'event_espresso'),
1139 1139
                     esc_url_raw(site_url())
1140 1140
                 )
1141 1141
                 . '</h1 >';
1142
-            echo '<h3>' . esc_html__('Query:', 'event_espresso') . '</h3>';
1142
+            echo '<h3>'.esc_html__('Query:', 'event_espresso').'</h3>';
1143 1143
             echo esc_html(var_export($query_params, true));
1144
-            echo '<h3>' . esc_html__('Results:', 'event_espresso') . '</h3>';
1144
+            echo '<h3>'.esc_html__('Results:', 'event_espresso').'</h3>';
1145 1145
             echo esc_html(var_export($wpdb_results, true));
1146 1146
             die;
1147 1147
         }
@@ -1197,7 +1197,7 @@  discard block
 block discarded – undo
1197 1197
             }
1198 1198
         }
1199 1199
         $this->_template_args['admin_page_content'] = EEH_Template::display_template(
1200
-            EE_PAYMENTS_TEMPLATE_PATH . 'payment_log_details.template.php',
1200
+            EE_PAYMENTS_TEMPLATE_PATH.'payment_log_details.template.php',
1201 1201
             array(
1202 1202
                 'payment_log'    => $payment_log,
1203 1203
                 'payment_method' => $payment_method,
Please login to merge, or discard this patch.
admin/extend/registration_form/Extend_Registration_Form_Admin_Page.core.php 1 patch
Indentation   +1432 added lines, -1432 removed lines patch added patch discarded remove patch
@@ -15,1436 +15,1436 @@
 block discarded – undo
15 15
 class Extend_Registration_Form_Admin_Page extends Registration_Form_Admin_Page
16 16
 {
17 17
 
18
-    /**
19
-     * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
20
-     */
21
-    public function __construct($routing = true)
22
-    {
23
-        define('REGISTRATION_FORM_CAF_ADMIN', EE_CORE_CAF_ADMIN_EXTEND . 'registration_form/');
24
-        define('REGISTRATION_FORM_CAF_ASSETS_PATH', REGISTRATION_FORM_CAF_ADMIN . 'assets/');
25
-        define('REGISTRATION_FORM_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registration_form/assets/');
26
-        define('REGISTRATION_FORM_CAF_TEMPLATE_PATH', REGISTRATION_FORM_CAF_ADMIN . 'templates/');
27
-        define('REGISTRATION_FORM_CAF_TEMPLATE_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registration_form/templates/');
28
-        parent::__construct($routing);
29
-    }
30
-
31
-
32
-    /**
33
-     * @return void
34
-     */
35
-    protected function _extend_page_config()
36
-    {
37
-        $this->_admin_base_path = REGISTRATION_FORM_CAF_ADMIN;
38
-        $qst_id = ! empty($this->_req_data['QST_ID']) && ! is_array($this->_req_data['QST_ID'])
39
-            ? $this->_req_data['QST_ID'] : 0;
40
-        $qsg_id = ! empty($this->_req_data['QSG_ID']) && ! is_array($this->_req_data['QSG_ID'])
41
-            ? $this->_req_data['QSG_ID'] : 0;
42
-
43
-        $new_page_routes = array(
44
-            'question_groups'    => array(
45
-                'func'       => '_question_groups_overview_list_table',
46
-                'capability' => 'ee_read_question_groups',
47
-            ),
48
-            'add_question'       => array(
49
-                'func'       => '_edit_question',
50
-                'capability' => 'ee_edit_questions',
51
-            ),
52
-            'insert_question'    => array(
53
-                'func'       => '_insert_or_update_question',
54
-                'args'       => array('new_question' => true),
55
-                'capability' => 'ee_edit_questions',
56
-                'noheader'   => true,
57
-            ),
58
-            'duplicate_question' => array(
59
-                'func'       => '_duplicate_question',
60
-                'capability' => 'ee_edit_questions',
61
-                'noheader'   => true,
62
-            ),
63
-            'trash_question'     => array(
64
-                'func'       => '_trash_question',
65
-                'capability' => 'ee_delete_question',
66
-                'obj_id'     => $qst_id,
67
-                'noheader'   => true,
68
-            ),
69
-
70
-            'restore_question' => array(
71
-                'func'       => '_trash_or_restore_questions',
72
-                'capability' => 'ee_delete_question',
73
-                'obj_id'     => $qst_id,
74
-                'args'       => array('trash' => false),
75
-                'noheader'   => true,
76
-            ),
77
-
78
-            'delete_question' => array(
79
-                'func'       => '_delete_question',
80
-                'capability' => 'ee_delete_question',
81
-                'obj_id'     => $qst_id,
82
-                'noheader'   => true,
83
-            ),
84
-
85
-            'trash_questions' => array(
86
-                'func'       => '_trash_or_restore_questions',
87
-                'capability' => 'ee_delete_questions',
88
-                'args'       => array('trash' => true),
89
-                'noheader'   => true,
90
-            ),
91
-
92
-            'restore_questions' => array(
93
-                'func'       => '_trash_or_restore_questions',
94
-                'capability' => 'ee_delete_questions',
95
-                'args'       => array('trash' => false),
96
-                'noheader'   => true,
97
-            ),
98
-
99
-            'delete_questions' => array(
100
-                'func'       => '_delete_questions',
101
-                'args'       => array(),
102
-                'capability' => 'ee_delete_questions',
103
-                'noheader'   => true,
104
-            ),
105
-
106
-            'add_question_group' => array(
107
-                'func'       => '_edit_question_group',
108
-                'capability' => 'ee_edit_question_groups',
109
-            ),
110
-
111
-            'edit_question_group' => array(
112
-                'func'       => '_edit_question_group',
113
-                'capability' => 'ee_edit_question_group',
114
-                'obj_id'     => $qsg_id,
115
-                'args'       => array('edit'),
116
-            ),
117
-
118
-            'delete_question_groups' => array(
119
-                'func'       => '_delete_question_groups',
120
-                'capability' => 'ee_delete_question_groups',
121
-                'noheader'   => true,
122
-            ),
123
-
124
-            'delete_question_group' => array(
125
-                'func'       => '_delete_question_groups',
126
-                'capability' => 'ee_delete_question_group',
127
-                'obj_id'     => $qsg_id,
128
-                'noheader'   => true,
129
-            ),
130
-
131
-            'trash_question_group' => array(
132
-                'func'       => '_trash_or_restore_question_groups',
133
-                'args'       => array('trash' => true),
134
-                'capability' => 'ee_delete_question_group',
135
-                'obj_id'     => $qsg_id,
136
-                'noheader'   => true,
137
-            ),
138
-
139
-            'restore_question_group' => array(
140
-                'func'       => '_trash_or_restore_question_groups',
141
-                'args'       => array('trash' => false),
142
-                'capability' => 'ee_delete_question_group',
143
-                'obj_id'     => $qsg_id,
144
-                'noheader'   => true,
145
-            ),
146
-
147
-            'insert_question_group' => array(
148
-                'func'       => '_insert_or_update_question_group',
149
-                'args'       => array('new_question_group' => true),
150
-                'capability' => 'ee_edit_question_groups',
151
-                'noheader'   => true,
152
-            ),
153
-
154
-            'update_question_group' => array(
155
-                'func'       => '_insert_or_update_question_group',
156
-                'args'       => array('new_question_group' => false),
157
-                'capability' => 'ee_edit_question_group',
158
-                'obj_id'     => $qsg_id,
159
-                'noheader'   => true,
160
-            ),
161
-
162
-            'trash_question_groups' => array(
163
-                'func'       => '_trash_or_restore_question_groups',
164
-                'args'       => array('trash' => true),
165
-                'capability' => 'ee_delete_question_groups',
166
-                'noheader'   => array('trash' => false),
167
-            ),
168
-
169
-            'restore_question_groups' => array(
170
-                'func'       => '_trash_or_restore_question_groups',
171
-                'args'       => array('trash' => false),
172
-                'capability' => 'ee_delete_question_groups',
173
-                'noheader'   => true,
174
-            ),
175
-
176
-
177
-            'espresso_update_question_group_order' => array(
178
-                'func'       => 'update_question_group_order',
179
-                'capability' => 'ee_edit_question_groups',
180
-                'noheader'   => true,
181
-            ),
182
-
183
-            'view_reg_form_settings' => array(
184
-                'func'       => '_reg_form_settings',
185
-                'capability' => 'manage_options',
186
-            ),
187
-
188
-            'update_reg_form_settings' => array(
189
-                'func'       => '_update_reg_form_settings',
190
-                'capability' => 'manage_options',
191
-                'noheader'   => true,
192
-            ),
193
-        );
194
-        $this->_page_routes = array_merge($this->_page_routes, $new_page_routes);
195
-
196
-        $new_page_config = array(
197
-
198
-            'question_groups' => array(
199
-                'nav'           => array(
200
-                    'label' => esc_html__('Question Groups', 'event_espresso'),
201
-                    'order' => 20,
202
-                ),
203
-                'list_table'    => 'Registration_Form_Question_Groups_Admin_List_Table',
204
-                'help_tabs'     => array(
205
-                    'registration_form_question_groups_help_tab'                           => array(
206
-                        'title'    => esc_html__('Question Groups', 'event_espresso'),
207
-                        'filename' => 'registration_form_question_groups',
208
-                    ),
209
-                    'registration_form_question_groups_table_column_headings_help_tab'     => array(
210
-                        'title'    => esc_html__('Question Groups Table Column Headings', 'event_espresso'),
211
-                        'filename' => 'registration_form_question_groups_table_column_headings',
212
-                    ),
213
-                    'registration_form_question_groups_views_bulk_actions_search_help_tab' => array(
214
-                        'title'    => esc_html__('Question Groups Views & Bulk Actions & Search', 'event_espresso'),
215
-                        'filename' => 'registration_form_question_groups_views_bulk_actions_search',
216
-                    ),
217
-                ),
218
-                'metaboxes'     => $this->_default_espresso_metaboxes,
219
-                'require_nonce' => false,
220
-                'qtips'         => array(
221
-                    'EE_Registration_Form_Tips',
222
-                ),
223
-            ),
224
-
225
-            'add_question' => array(
226
-                'nav'           => array(
227
-                    'label'      => esc_html__('Add Question', 'event_espresso'),
228
-                    'order'      => 5,
229
-                    'persistent' => false,
230
-                ),
231
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
232
-                'help_tabs'     => array(
233
-                    'registration_form_add_question_help_tab' => array(
234
-                        'title'    => esc_html__('Add Question', 'event_espresso'),
235
-                        'filename' => 'registration_form_add_question',
236
-                    ),
237
-                ),
238
-                'require_nonce' => false,
239
-            ),
240
-
241
-            'add_question_group' => array(
242
-                'nav'           => array(
243
-                    'label'      => esc_html__('Add Question Group', 'event_espresso'),
244
-                    'order'      => 5,
245
-                    'persistent' => false,
246
-                ),
247
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
248
-                'help_tabs'     => array(
249
-                    'registration_form_add_question_group_help_tab' => array(
250
-                        'title'    => esc_html__('Add Question Group', 'event_espresso'),
251
-                        'filename' => 'registration_form_add_question_group',
252
-                    ),
253
-                ),
254
-                'require_nonce' => false,
255
-            ),
256
-
257
-            'edit_question_group' => array(
258
-                'nav'           => array(
259
-                    'label'      => esc_html__('Edit Question Group', 'event_espresso'),
260
-                    'order'      => 5,
261
-                    'persistent' => false,
262
-                    'url'        => isset($this->_req_data['question_group_id']) ? add_query_arg(
263
-                        array('question_group_id' => $this->_req_data['question_group_id']),
264
-                        $this->_current_page_view_url
265
-                    ) : $this->_admin_base_url,
266
-                ),
267
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
268
-                'help_tabs'     => array(
269
-                    'registration_form_edit_question_group_help_tab' => array(
270
-                        'title'    => esc_html__('Edit Question Group', 'event_espresso'),
271
-                        'filename' => 'registration_form_edit_question_group',
272
-                    ),
273
-                ),
274
-                'require_nonce' => false,
275
-            ),
276
-
277
-            'view_reg_form_settings' => array(
278
-                'nav'           => array(
279
-                    'label' => esc_html__('Reg Form Settings', 'event_espresso'),
280
-                    'order' => 40,
281
-                ),
282
-                'labels'        => array(
283
-                    'publishbox' => esc_html__('Update Settings', 'event_espresso'),
284
-                ),
285
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
286
-                'help_tabs'     => array(
287
-                    'registration_form_reg_form_settings_help_tab' => array(
288
-                        'title'    => esc_html__('Registration Form Settings', 'event_espresso'),
289
-                        'filename' => 'registration_form_reg_form_settings',
290
-                    ),
291
-                ),
292
-                'require_nonce' => false,
293
-            ),
294
-
295
-        );
296
-        $this->_page_config = array_merge($this->_page_config, $new_page_config);
297
-
298
-        // change the list table we're going to use so it's the NEW list table!
299
-        $this->_page_config['default']['list_table'] = 'Extend_Registration_Form_Questions_Admin_List_Table';
300
-
301
-
302
-        // additional labels
303
-        $new_labels = array(
304
-            'add_question'          => esc_html__('Add New Question', 'event_espresso'),
305
-            'delete_question'       => esc_html__('Delete Question', 'event_espresso'),
306
-            'add_question_group'    => esc_html__('Add New Question Group', 'event_espresso'),
307
-            'edit_question_group'   => esc_html__('Edit Question Group', 'event_espresso'),
308
-            'delete_question_group' => esc_html__('Delete Question Group', 'event_espresso'),
309
-        );
310
-        $this->_labels['buttons'] = array_merge($this->_labels['buttons'], $new_labels);
311
-    }
312
-
313
-
314
-    /**
315
-     * @return void
316
-     */
317
-    protected function _ajax_hooks()
318
-    {
319
-        add_action('wp_ajax_espresso_update_question_group_order', array($this, 'update_question_group_order'));
320
-    }
321
-
322
-
323
-    /**
324
-     * @return void
325
-     */
326
-    public function load_scripts_styles_question_groups()
327
-    {
328
-        wp_enqueue_script('espresso_ajax_table_sorting');
329
-    }
330
-
331
-
332
-    /**
333
-     * @return void
334
-     */
335
-    public function load_scripts_styles_add_question_group()
336
-    {
337
-        $this->load_scripts_styles_forms();
338
-        $this->load_sortable_question_script();
339
-    }
340
-
341
-
342
-    /**
343
-     * @return void
344
-     */
345
-    public function load_scripts_styles_edit_question_group()
346
-    {
347
-        $this->load_scripts_styles_forms();
348
-        $this->load_sortable_question_script();
349
-    }
350
-
351
-
352
-    /**
353
-     * registers and enqueues script for questions
354
-     *
355
-     * @return void
356
-     */
357
-    public function load_sortable_question_script()
358
-    {
359
-        wp_register_script(
360
-            'ee-question-sortable',
361
-            REGISTRATION_FORM_CAF_ASSETS_URL . 'ee_question_order.js',
362
-            array('jquery-ui-sortable'),
363
-            EVENT_ESPRESSO_VERSION,
364
-            true
365
-        );
366
-        wp_enqueue_script('ee-question-sortable');
367
-    }
368
-
369
-
370
-    /**
371
-     * @return void
372
-     */
373
-    protected function _set_list_table_views_default()
374
-    {
375
-        $this->_views = array(
376
-            'all' => array(
377
-                'slug'        => 'all',
378
-                'label'       => esc_html__('View All Questions', 'event_espresso'),
379
-                'count'       => 0,
380
-                'bulk_action' => array(
381
-                    'trash_questions' => esc_html__('Trash', 'event_espresso'),
382
-                ),
383
-            ),
384
-        );
385
-
386
-        if (
387
-            EE_Registry::instance()->CAP->current_user_can(
388
-                'ee_delete_questions',
389
-                'espresso_registration_form_trash_questions'
390
-            )
391
-        ) {
392
-            $this->_views['trash'] = array(
393
-                'slug'        => 'trash',
394
-                'label'       => esc_html__('Trash', 'event_espresso'),
395
-                'count'       => 0,
396
-                'bulk_action' => array(
397
-                    'delete_questions'  => esc_html__('Delete Permanently', 'event_espresso'),
398
-                    'restore_questions' => esc_html__('Restore', 'event_espresso'),
399
-                ),
400
-            );
401
-        }
402
-    }
403
-
404
-
405
-    /**
406
-     * @return void
407
-     */
408
-    protected function _set_list_table_views_question_groups()
409
-    {
410
-        $this->_views = array(
411
-            'all' => array(
412
-                'slug'        => 'all',
413
-                'label'       => esc_html__('All', 'event_espresso'),
414
-                'count'       => 0,
415
-                'bulk_action' => array(
416
-                    'trash_question_groups' => esc_html__('Trash', 'event_espresso'),
417
-                ),
418
-            ),
419
-        );
420
-
421
-        if (
422
-            EE_Registry::instance()->CAP->current_user_can(
423
-                'ee_delete_question_groups',
424
-                'espresso_registration_form_trash_question_groups'
425
-            )
426
-        ) {
427
-            $this->_views['trash'] = array(
428
-                'slug'        => 'trash',
429
-                'label'       => esc_html__('Trash', 'event_espresso'),
430
-                'count'       => 0,
431
-                'bulk_action' => array(
432
-                    'delete_question_groups'  => esc_html__('Delete Permanently', 'event_espresso'),
433
-                    'restore_question_groups' => esc_html__('Restore', 'event_espresso'),
434
-                ),
435
-            );
436
-        }
437
-    }
438
-
439
-
440
-    /**
441
-     * @return void
442
-     * @throws EE_Error
443
-     * @throws InvalidArgumentException
444
-     * @throws InvalidDataTypeException
445
-     * @throws InvalidInterfaceException
446
-     */
447
-    protected function _questions_overview_list_table()
448
-    {
449
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
450
-            'add_question',
451
-            'add_question',
452
-            array(),
453
-            'add-new-h2'
454
-        );
455
-        parent::_questions_overview_list_table();
456
-    }
457
-
458
-
459
-    /**
460
-     * @return void
461
-     * @throws DomainException
462
-     * @throws EE_Error
463
-     * @throws InvalidArgumentException
464
-     * @throws InvalidDataTypeException
465
-     * @throws InvalidInterfaceException
466
-     */
467
-    protected function _question_groups_overview_list_table()
468
-    {
469
-        $this->_search_btn_label = esc_html__('Question Groups', 'event_espresso');
470
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
471
-            'add_question_group',
472
-            'add_question_group',
473
-            array(),
474
-            'add-new-h2'
475
-        );
476
-        $this->display_admin_list_table_page_with_sidebar();
477
-    }
478
-
479
-
480
-    /**
481
-     * @return void
482
-     * @throws EE_Error
483
-     * @throws InvalidArgumentException
484
-     * @throws InvalidDataTypeException
485
-     * @throws InvalidInterfaceException
486
-     */
487
-    protected function _delete_question()
488
-    {
489
-        $success = $this->_delete_items($this->_question_model);
490
-        $this->_redirect_after_action(
491
-            $success,
492
-            $this->_question_model->item_name($success),
493
-            'deleted',
494
-            array('action' => 'default', 'status' => 'all')
495
-        );
496
-    }
497
-
498
-
499
-    /**
500
-     * @return void
501
-     * @throws EE_Error
502
-     * @throws InvalidArgumentException
503
-     * @throws InvalidDataTypeException
504
-     * @throws InvalidInterfaceException
505
-     */
506
-    protected function _delete_questions()
507
-    {
508
-        $success = $this->_delete_items($this->_question_model);
509
-        $this->_redirect_after_action(
510
-            $success,
511
-            $this->_question_model->item_name($success),
512
-            'deleted permanently',
513
-            array('action' => 'default', 'status' => 'trash')
514
-        );
515
-    }
516
-
517
-
518
-    /**
519
-     * Performs the deletion of a single or multiple questions or question groups.
520
-     *
521
-     * @param EEM_Soft_Delete_Base $model
522
-     * @return int number of items deleted permanently
523
-     * @throws EE_Error
524
-     * @throws InvalidArgumentException
525
-     * @throws InvalidDataTypeException
526
-     * @throws InvalidInterfaceException
527
-     */
528
-    private function _delete_items(EEM_Soft_Delete_Base $model)
529
-    {
530
-        $success = 0;
531
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
532
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
533
-            // if array has more than one element than success message should be plural
534
-            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
535
-            // cycle thru bulk action checkboxes
536
-            while (list($ID, $value) = each($this->_req_data['checkbox'])) {
537
-                if (! $this->_delete_item($ID, $model)) {
538
-                    $success = 0;
539
-                }
540
-            }
541
-        } elseif (! empty($this->_req_data['QSG_ID'])) {
542
-            $success = $this->_delete_item($this->_req_data['QSG_ID'], $model);
543
-        } elseif (! empty($this->_req_data['QST_ID'])) {
544
-            $success = $this->_delete_item($this->_req_data['QST_ID'], $model);
545
-        } else {
546
-            EE_Error::add_error(
547
-                sprintf(
548
-                    esc_html__(
549
-                        "No Questions or Question Groups were selected for deleting. This error usually shows when you've attempted to delete via bulk action but there were no selections.",
550
-                        "event_espresso"
551
-                    )
552
-                ),
553
-                __FILE__,
554
-                __FUNCTION__,
555
-                __LINE__
556
-            );
557
-        }
558
-        return $success;
559
-    }
560
-
561
-
562
-    /**
563
-     * Deletes the specified question (and its associated question options) or question group
564
-     *
565
-     * @param int                  $id
566
-     * @param EEM_Soft_Delete_Base $model
567
-     * @return boolean
568
-     * @throws EE_Error
569
-     * @throws InvalidArgumentException
570
-     * @throws InvalidDataTypeException
571
-     * @throws InvalidInterfaceException
572
-     */
573
-    protected function _delete_item($id, $model)
574
-    {
575
-        if ($model instanceof EEM_Question) {
576
-            EEM_Question_Option::instance()->delete_permanently(array(array('QST_ID' => absint($id))));
577
-        }
578
-        return $model->delete_permanently_by_ID(absint($id));
579
-    }
580
-
581
-
582
-    /******************************    QUESTION GROUPS    ******************************/
583
-
584
-
585
-    /**
586
-     * @param string $type
587
-     * @return void
588
-     * @throws DomainException
589
-     * @throws EE_Error
590
-     * @throws InvalidArgumentException
591
-     * @throws InvalidDataTypeException
592
-     * @throws InvalidInterfaceException
593
-     */
594
-    protected function _edit_question_group($type = 'add')
595
-    {
596
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
597
-        $ID = isset($this->_req_data['QSG_ID']) && ! empty($this->_req_data['QSG_ID'])
598
-            ? absint($this->_req_data['QSG_ID'])
599
-            : false;
600
-
601
-        switch ($this->_req_action) {
602
-            case 'add_question_group':
603
-                $this->_admin_page_title = esc_html__('Add Question Group', 'event_espresso');
604
-                break;
605
-            case 'edit_question_group':
606
-                $this->_admin_page_title = esc_html__('Edit Question Group', 'event_espresso');
607
-                break;
608
-            default:
609
-                $this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
610
-        }
611
-        // add ID to title if editing
612
-        $this->_admin_page_title = $ID ? $this->_admin_page_title . ' # ' . $ID : $this->_admin_page_title;
613
-        if ($ID) {
614
-            /** @var EE_Question_Group $questionGroup */
615
-            $questionGroup = $this->_question_group_model->get_one_by_ID($ID);
616
-            $additional_hidden_fields = array('QSG_ID' => array('type' => 'hidden', 'value' => $ID));
617
-            $this->_set_add_edit_form_tags('update_question_group', $additional_hidden_fields);
618
-        } else {
619
-            /** @var EE_Question_Group $questionGroup */
620
-            $questionGroup = EEM_Question_Group::instance()->create_default_object();
621
-            $questionGroup->set_order_to_latest();
622
-            $this->_set_add_edit_form_tags('insert_question_group');
623
-        }
624
-        $this->_template_args['values'] = $this->_yes_no_values;
625
-        $this->_template_args['all_questions'] = $questionGroup->questions_in_and_not_in_group();
626
-        $this->_template_args['QSG_ID'] = $ID ? $ID : true;
627
-        $this->_template_args['question_group'] = $questionGroup;
628
-
629
-        $redirect_URL = add_query_arg(array('action' => 'question_groups'), $this->_admin_base_url);
630
-        $this->_set_publish_post_box_vars('id', $ID, false, $redirect_URL);
631
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
632
-            REGISTRATION_FORM_CAF_TEMPLATE_PATH . 'question_groups_main_meta_box.template.php',
633
-            $this->_template_args,
634
-            true
635
-        );
636
-
637
-        // the details template wrapper
638
-        $this->display_admin_page_with_sidebar();
639
-    }
640
-
641
-
642
-    /**
643
-     * @return void
644
-     * @throws EE_Error
645
-     * @throws InvalidArgumentException
646
-     * @throws InvalidDataTypeException
647
-     * @throws InvalidInterfaceException
648
-     */
649
-    protected function _delete_question_groups()
650
-    {
651
-        $success = $this->_delete_items($this->_question_group_model);
652
-        $this->_redirect_after_action(
653
-            $success,
654
-            $this->_question_group_model->item_name($success),
655
-            'deleted permanently',
656
-            array('action' => 'question_groups', 'status' => 'trash')
657
-        );
658
-    }
659
-
660
-
661
-    /**
662
-     * @param bool $new_question_group
663
-     * @throws EE_Error
664
-     * @throws InvalidArgumentException
665
-     * @throws InvalidDataTypeException
666
-     * @throws InvalidInterfaceException
667
-     */
668
-    protected function _insert_or_update_question_group($new_question_group = true)
669
-    {
670
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
671
-        $set_column_values = $this->_set_column_values_for($this->_question_group_model);
672
-        if ($new_question_group) {
673
-            // make sure identifier is unique
674
-            $identifier_value = isset($set_column_values['QSG_identifier']) ? $set_column_values['QSG_identifier'] : '';
675
-            $identifier_exists = ! empty($identifier_value)
676
-                ? $this->_question_group_model->count([['QSG_identifier' => $set_column_values['QSG_identifier']]]) > 0
677
-                : false;
678
-            if ($identifier_exists) {
679
-                $set_column_values['QSG_identifier'] .= uniqid('id', true);
680
-            }
681
-            $QSG_ID = $this->_question_group_model->insert($set_column_values);
682
-            $success = $QSG_ID ? 1 : 0;
683
-            if ($success === 0) {
684
-                EE_Error::add_error(
685
-                    esc_html__('Something went wrong saving the question group.', 'event_espresso'),
686
-                    __FILE__,
687
-                    __FUNCTION__,
688
-                    __LINE__
689
-                );
690
-                $this->_redirect_after_action(
691
-                    false,
692
-                    '',
693
-                    '',
694
-                    array('action' => 'edit_question_group', 'QSG_ID' => $QSG_ID),
695
-                    true
696
-                );
697
-            }
698
-        } else {
699
-            $QSG_ID = absint($this->_req_data['QSG_ID']);
700
-            unset($set_column_values['QSG_ID']);
701
-            $success = $this->_question_group_model->update($set_column_values, array(array('QSG_ID' => $QSG_ID)));
702
-        }
703
-
704
-        $phone_question_id = EEM_Question::instance()->get_Question_ID_from_system_string(
705
-            EEM_Attendee::system_question_phone
706
-        );
707
-        // update the existing related questions
708
-        // BUT FIRST...  delete the phone question from the Question_Group_Question
709
-        // if it is being added to this question group (therefore removed from the existing group)
710
-        if (isset($this->_req_data['questions'], $this->_req_data['questions'][ $phone_question_id ])) {
711
-            // delete where QST ID = system phone question ID and Question Group ID is NOT this group
712
-            EEM_Question_Group_Question::instance()->delete(
713
-                array(
714
-                    array(
715
-                        'QST_ID' => $phone_question_id,
716
-                        'QSG_ID' => array('!=', $QSG_ID),
717
-                    ),
718
-                )
719
-            );
720
-        }
721
-        /** @type EE_Question_Group $question_group */
722
-        $question_group = $this->_question_group_model->get_one_by_ID($QSG_ID);
723
-        $questions = $question_group->questions();
724
-        // make sure system phone question is added to list of questions for this group
725
-        if (! isset($questions[ $phone_question_id ])) {
726
-            $questions[ $phone_question_id ] = EEM_Question::instance()->get_one_by_ID($phone_question_id);
727
-        }
728
-
729
-        foreach ($questions as $question_ID => $question) {
730
-            // first we always check for order.
731
-            if (! empty($this->_req_data['question_orders'][ $question_ID ])) {
732
-                // update question order
733
-                $question_group->update_question_order(
734
-                    $question_ID,
735
-                    $this->_req_data['question_orders'][ $question_ID ]
736
-                );
737
-            }
738
-
739
-            // then we always check if adding or removing.
740
-            if (isset($this->_req_data['questions'], $this->_req_data['questions'][ $question_ID ])) {
741
-                $question_group->add_question($question_ID);
742
-            } else {
743
-                // not found, remove it (but only if not a system question for the personal group
744
-                // with the exception of lname system question - we allow removal of it)
745
-                if (
746
-                    in_array(
747
-                        $question->system_ID(),
748
-                        EEM_Question::instance()->required_system_questions_in_system_question_group(
749
-                            $question_group->system_group()
750
-                        )
751
-                    )
752
-                ) {
753
-                    continue;
754
-                } else {
755
-                    $question_group->remove_question($question_ID);
756
-                }
757
-            }
758
-        }
759
-        // save new related questions
760
-        if (isset($this->_req_data['questions'])) {
761
-            foreach ($this->_req_data['questions'] as $QST_ID) {
762
-                $question_group->add_question($QST_ID);
763
-                if (isset($this->_req_data['question_orders'][ $QST_ID ])) {
764
-                    $question_group->update_question_order($QST_ID, $this->_req_data['question_orders'][ $QST_ID ]);
765
-                }
766
-            }
767
-        }
768
-
769
-        if ($success !== false) {
770
-            $msg = $new_question_group
771
-                ? sprintf(
772
-                    esc_html__('The %s has been created', 'event_espresso'),
773
-                    $this->_question_group_model->item_name()
774
-                )
775
-                : sprintf(
776
-                    esc_html__(
777
-                        'The %s has been updated',
778
-                        'event_espresso'
779
-                    ),
780
-                    $this->_question_group_model->item_name()
781
-                );
782
-            EE_Error::add_success($msg);
783
-        }
784
-        $this->_redirect_after_action(
785
-            false,
786
-            '',
787
-            '',
788
-            array('action' => 'edit_question_group', 'QSG_ID' => $QSG_ID),
789
-            true
790
-        );
791
-    }
792
-
793
-
794
-    /**
795
-     * duplicates a question and all its question options and redirects to the new question.
796
-     *
797
-     * @return void
798
-     * @throws EE_Error
799
-     * @throws InvalidArgumentException
800
-     * @throws ReflectionException
801
-     * @throws InvalidDataTypeException
802
-     * @throws InvalidInterfaceException
803
-     */
804
-    public function _duplicate_question()
805
-    {
806
-        $question_ID = (int) $this->_req_data['QST_ID'];
807
-        $question = EEM_Question::instance()->get_one_by_ID($question_ID);
808
-        if ($question instanceof EE_Question) {
809
-            $new_question = $question->duplicate();
810
-            if ($new_question instanceof EE_Question) {
811
-                $this->_redirect_after_action(
812
-                    true,
813
-                    esc_html__('Question', 'event_espresso'),
814
-                    esc_html__('Duplicated', 'event_espresso'),
815
-                    array('action' => 'edit_question', 'QST_ID' => $new_question->ID()),
816
-                    true
817
-                );
818
-            } else {
819
-                global $wpdb;
820
-                EE_Error::add_error(
821
-                    sprintf(
822
-                        esc_html__(
823
-                            'Could not duplicate question with ID %1$d because: %2$s',
824
-                            'event_espresso'
825
-                        ),
826
-                        $question_ID,
827
-                        $wpdb->last_error
828
-                    ),
829
-                    __FILE__,
830
-                    __FUNCTION__,
831
-                    __LINE__
832
-                );
833
-                $this->_redirect_after_action(false, '', '', array('action' => 'default'), false);
834
-            }
835
-        } else {
836
-            EE_Error::add_error(
837
-                sprintf(
838
-                    esc_html__(
839
-                        'Could not duplicate question with ID %d because it didn\'t exist!',
840
-                        'event_espresso'
841
-                    ),
842
-                    $question_ID
843
-                ),
844
-                __FILE__,
845
-                __FUNCTION__,
846
-                __LINE__
847
-            );
848
-            $this->_redirect_after_action(false, '', '', array('action' => 'default'), false);
849
-        }
850
-    }
851
-
852
-
853
-    /**
854
-     * @param bool $trash
855
-     * @throws EE_Error
856
-     */
857
-    protected function _trash_or_restore_question_groups($trash = true)
858
-    {
859
-        $this->_trash_or_restore_items($this->_question_group_model, $trash);
860
-    }
861
-
862
-
863
-    /**
864
-     *_trash_question
865
-     *
866
-     * @return void
867
-     * @throws EE_Error
868
-     */
869
-    protected function _trash_question()
870
-    {
871
-        $success = $this->_question_model->delete_by_ID((int) $this->_req_data['QST_ID']);
872
-        $query_args = array('action' => 'default', 'status' => 'all');
873
-        $this->_redirect_after_action($success, $this->_question_model->item_name($success), 'trashed', $query_args);
874
-    }
875
-
876
-
877
-    /**
878
-     * @param bool $trash
879
-     * @throws EE_Error
880
-     */
881
-    protected function _trash_or_restore_questions($trash = true)
882
-    {
883
-        $this->_trash_or_restore_items($this->_question_model, $trash);
884
-    }
885
-
886
-
887
-    /**
888
-     * Internally used to delete or restore items, using the request data. Meant to be
889
-     * flexible between question or question groups
890
-     *
891
-     * @param EEM_Soft_Delete_Base $model
892
-     * @param boolean              $trash whether to trash or restore
893
-     * @throws EE_Error
894
-     */
895
-    private function _trash_or_restore_items(EEM_Soft_Delete_Base $model, $trash = true)
896
-    {
897
-
898
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
899
-
900
-        $success = 1;
901
-        // Checkboxes
902
-        // echo "trash $trash";
903
-        // var_dump($this->_req_data['checkbox']);die;
904
-        if (isset($this->_req_data['checkbox'])) {
905
-            if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
906
-                // if array has more than one element than success message should be plural
907
-                $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
908
-                // cycle thru bulk action checkboxes
909
-                while (list($ID, $value) = each($this->_req_data['checkbox'])) {
910
-                    if (! $model->delete_or_restore_by_ID($trash, absint($ID))) {
911
-                        $success = 0;
912
-                    }
913
-                }
914
-            } else {
915
-                // grab single id and delete
916
-                $ID = absint($this->_req_data['checkbox']);
917
-                if (! $model->delete_or_restore_by_ID($trash, $ID)) {
918
-                    $success = 0;
919
-                }
920
-            }
921
-        } else {
922
-            // delete via trash link
923
-            // grab single id and delete
924
-            $ID = absint($this->_req_data[ $model->primary_key_name() ]);
925
-            if (! $model->delete_or_restore_by_ID($trash, $ID)) {
926
-                $success = 0;
927
-            }
928
-        }
929
-
930
-
931
-        $action = $model instanceof EEM_Question ? 'default' : 'question_groups';// strtolower( $model->item_name(2) );
932
-        // echo "action :$action";
933
-        // $action = 'questions' ? 'default' : $action;
934
-        if ($trash) {
935
-            $action_desc = 'trashed';
936
-            $status = 'trash';
937
-        } else {
938
-            $action_desc = 'restored';
939
-            $status = 'all';
940
-        }
941
-        $this->_redirect_after_action(
942
-            $success,
943
-            $model->item_name($success),
944
-            $action_desc,
945
-            array('action' => $action, 'status' => $status)
946
-        );
947
-    }
948
-
949
-
950
-    /**
951
-     * @param            $per_page
952
-     * @param int        $current_page
953
-     * @param bool|false $count
954
-     * @return EE_Soft_Delete_Base_Class[]|int
955
-     * @throws EE_Error
956
-     * @throws InvalidArgumentException
957
-     * @throws InvalidDataTypeException
958
-     * @throws InvalidInterfaceException
959
-     */
960
-    public function get_trashed_questions($per_page, $current_page = 1, $count = false)
961
-    {
962
-        $query_params = $this->get_query_params(EEM_Question::instance(), $per_page, $current_page);
963
-
964
-        if ($count) {
965
-            // note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
966
-            $where = isset($query_params[0]) ? array($query_params[0]) : array();
967
-            $results = $this->_question_model->count_deleted($where);
968
-        } else {
969
-            // note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
970
-            $results = $this->_question_model->get_all_deleted($query_params);
971
-        }
972
-        return $results;
973
-    }
974
-
975
-
976
-    /**
977
-     * @param            $per_page
978
-     * @param int        $current_page
979
-     * @param bool|false $count
980
-     * @return EE_Soft_Delete_Base_Class[]|int
981
-     * @throws EE_Error
982
-     * @throws InvalidArgumentException
983
-     * @throws InvalidDataTypeException
984
-     * @throws InvalidInterfaceException
985
-     */
986
-    public function get_question_groups($per_page, $current_page = 1, $count = false)
987
-    {
988
-        $questionGroupModel = EEM_Question_Group::instance();
989
-        $query_params = $this->get_query_params($questionGroupModel, $per_page, $current_page);
990
-        if ($count) {
991
-            $where = isset($query_params[0]) ? array($query_params[0]) : array();
992
-            $results = $questionGroupModel->count($where);
993
-        } else {
994
-            $results = $questionGroupModel->get_all($query_params);
995
-        }
996
-        return $results;
997
-    }
998
-
999
-
1000
-    /**
1001
-     * @param      $per_page
1002
-     * @param int  $current_page
1003
-     * @param bool $count
1004
-     * @return EE_Soft_Delete_Base_Class[]|int
1005
-     * @throws EE_Error
1006
-     * @throws InvalidArgumentException
1007
-     * @throws InvalidDataTypeException
1008
-     * @throws InvalidInterfaceException
1009
-     */
1010
-    public function get_trashed_question_groups($per_page, $current_page = 1, $count = false)
1011
-    {
1012
-        $questionGroupModel = EEM_Question_Group::instance();
1013
-        $query_params = $this->get_query_params($questionGroupModel, $per_page, $current_page);
1014
-        if ($count) {
1015
-            $where = isset($query_params[0]) ? array($query_params[0]) : array();
1016
-            $query_params['limit'] = null;
1017
-            $results = $questionGroupModel->count_deleted($where);
1018
-        } else {
1019
-            $results = $questionGroupModel->get_all_deleted($query_params);
1020
-        }
1021
-        return $results;
1022
-    }
1023
-
1024
-
1025
-    /**
1026
-     * method for performing updates to question order
1027
-     *
1028
-     * @return void results array
1029
-     * @throws EE_Error
1030
-     * @throws InvalidArgumentException
1031
-     * @throws InvalidDataTypeException
1032
-     * @throws InvalidInterfaceException
1033
-     */
1034
-    public function update_question_group_order()
1035
-    {
1036
-
1037
-        $success = esc_html__('Question group order was updated successfully.', 'event_espresso');
1038
-
1039
-        // grab our row IDs
1040
-        $row_ids = isset($this->_req_data['row_ids']) && ! empty($this->_req_data['row_ids'])
1041
-            ? explode(',', rtrim($this->_req_data['row_ids'], ','))
1042
-            : array();
1043
-
1044
-        $perpage = ! empty($this->_req_data['perpage'])
1045
-            ? (int) $this->_req_data['perpage']
1046
-            : null;
1047
-        $curpage = ! empty($this->_req_data['curpage'])
1048
-            ? (int) $this->_req_data['curpage']
1049
-            : null;
1050
-
1051
-        if (! empty($row_ids)) {
1052
-            // figure out where we start the row_id count at for the current page.
1053
-            $qsgcount = empty($curpage) ? 0 : ($curpage - 1) * $perpage;
1054
-
1055
-            $row_count = count($row_ids);
1056
-            for ($i = 0; $i < $row_count; $i++) {
1057
-                // Update the questions when re-ordering
1058
-                $updated = EEM_Question_Group::instance()->update(
1059
-                    array('QSG_order' => $qsgcount),
1060
-                    array(array('QSG_ID' => $row_ids[ $i ]))
1061
-                );
1062
-                if ($updated === false) {
1063
-                    $success = false;
1064
-                }
1065
-                $qsgcount++;
1066
-            }
1067
-        } else {
1068
-            $success = false;
1069
-        }
1070
-
1071
-        $errors = ! $success
1072
-            ? esc_html__('An error occurred. The question group order was not updated.', 'event_espresso')
1073
-            : false;
1074
-
1075
-        echo wp_json_encode(array('return_data' => false, 'success' => $success, 'errors' => $errors));
1076
-        die();
1077
-    }
1078
-
1079
-
1080
-
1081
-    /***************************************       REGISTRATION SETTINGS       ***************************************/
1082
-
1083
-
1084
-    /**
1085
-     * @throws DomainException
1086
-     * @throws EE_Error
1087
-     * @throws InvalidArgumentException
1088
-     * @throws InvalidDataTypeException
1089
-     * @throws InvalidInterfaceException
1090
-     */
1091
-    protected function _reg_form_settings()
1092
-    {
1093
-        $this->_template_args['values'] = $this->_yes_no_values;
1094
-        add_action(
1095
-            'AHEE__Extend_Registration_Form_Admin_Page___reg_form_settings_template',
1096
-            array($this, 'email_validation_settings_form'),
1097
-            2
1098
-        );
1099
-        add_action(
1100
-            'AHEE__Extend_Registration_Form_Admin_Page___reg_form_settings_template',
1101
-            array($this, 'copy_attendee_info_settings_form'),
1102
-            4
1103
-        );
1104
-        $this->_template_args = (array) apply_filters(
1105
-            'FHEE__Extend_Registration_Form_Admin_Page___reg_form_settings___template_args',
1106
-            $this->_template_args
1107
-        );
1108
-        $this->_set_add_edit_form_tags('update_reg_form_settings');
1109
-        $this->_set_publish_post_box_vars(null, false, false, null, false);
1110
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
1111
-            REGISTRATION_FORM_CAF_TEMPLATE_PATH . 'reg_form_settings.template.php',
1112
-            $this->_template_args,
1113
-            true
1114
-        );
1115
-        $this->display_admin_page_with_sidebar();
1116
-    }
1117
-
1118
-
1119
-    /**
1120
-     * @return void
1121
-     * @throws EE_Error
1122
-     * @throws InvalidArgumentException
1123
-     * @throws ReflectionException
1124
-     * @throws InvalidDataTypeException
1125
-     * @throws InvalidInterfaceException
1126
-     */
1127
-    protected function _update_reg_form_settings()
1128
-    {
1129
-        EE_Registry::instance()->CFG->registration = $this->update_email_validation_settings_form(
1130
-            EE_Registry::instance()->CFG->registration
1131
-        );
1132
-        EE_Registry::instance()->CFG->registration = $this->update_copy_attendee_info_settings_form(
1133
-            EE_Registry::instance()->CFG->registration
1134
-        );
1135
-        EE_Registry::instance()->CFG->registration = apply_filters(
1136
-            'FHEE__Extend_Registration_Form_Admin_Page___update_reg_form_settings__CFG_registration',
1137
-            EE_Registry::instance()->CFG->registration
1138
-        );
1139
-        $success = $this->_update_espresso_configuration(
1140
-            esc_html__('Registration Form Options', 'event_espresso'),
1141
-            EE_Registry::instance()->CFG,
1142
-            __FILE__,
1143
-            __FUNCTION__,
1144
-            __LINE__
1145
-        );
1146
-        $this->_redirect_after_action(
1147
-            $success,
1148
-            esc_html__('Registration Form Options', 'event_espresso'),
1149
-            'updated',
1150
-            array('action' => 'view_reg_form_settings')
1151
-        );
1152
-    }
1153
-
1154
-
1155
-    /**
1156
-     * @return void
1157
-     * @throws EE_Error
1158
-     * @throws InvalidArgumentException
1159
-     * @throws InvalidDataTypeException
1160
-     * @throws InvalidInterfaceException
1161
-     */
1162
-    public function copy_attendee_info_settings_form()
1163
-    {
1164
-        echo wp_kses($this->_copy_attendee_info_settings_form()->get_html(), AllowedTags::getWithFormTags());
1165
-    }
1166
-
1167
-    /**
1168
-     * _copy_attendee_info_settings_form
1169
-     *
1170
-     * @access protected
1171
-     * @return EE_Form_Section_Proper
1172
-     * @throws \EE_Error
1173
-     */
1174
-    protected function _copy_attendee_info_settings_form()
1175
-    {
1176
-        return new EE_Form_Section_Proper(
1177
-            array(
1178
-                'name'            => 'copy_attendee_info_settings',
1179
-                'html_id'         => 'copy_attendee_info_settings',
1180
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1181
-                'subsections'     => apply_filters(
1182
-                    'FHEE__Extend_Registration_Form_Admin_Page___copy_attendee_info_settings_form__form_subsections',
1183
-                    array(
1184
-                        'copy_attendee_info_hdr'   => new EE_Form_Section_HTML(
1185
-                            EEH_HTML::h2(esc_html__('Copy Attendee Info Settings', 'event_espresso'))
1186
-                        ),
1187
-                        'copy_attendee_info' => new EE_Yes_No_Input(
1188
-                            array(
1189
-                                'html_label_text' => esc_html__(
1190
-                                    'Allow copy #1 attendee info to extra attendees?',
1191
-                                    'event_espresso'
1192
-                                ),
1193
-                                'html_help_text'  => esc_html__(
1194
-                                    'Set to yes if you want to enable the copy of #1 attendee info to extra attendees at Registration Form.',
1195
-                                    'event_espresso'
1196
-                                ),
1197
-                                'default'         => EE_Registry::instance()->CFG->registration->copyAttendeeInfo(),
1198
-                                'required'        => false,
1199
-                                'display_html_label_text' => false,
1200
-                            )
1201
-                        ),
1202
-                    )
1203
-                ),
1204
-            )
1205
-        );
1206
-    }
1207
-
1208
-    /**
1209
-     * @param EE_Registration_Config $EE_Registration_Config
1210
-     * @return EE_Registration_Config
1211
-     * @throws EE_Error
1212
-     * @throws InvalidArgumentException
1213
-     * @throws ReflectionException
1214
-     * @throws InvalidDataTypeException
1215
-     * @throws InvalidInterfaceException
1216
-     */
1217
-    public function update_copy_attendee_info_settings_form(EE_Registration_Config $EE_Registration_Config)
1218
-    {
1219
-        $prev_copy_attendee_info = $EE_Registration_Config->copyAttendeeInfo();
1220
-        try {
1221
-            $copy_attendee_info_settings_form = $this->_copy_attendee_info_settings_form();
1222
-            // if not displaying a form, then check for form submission
1223
-            if ($copy_attendee_info_settings_form->was_submitted()) {
1224
-                // capture form data
1225
-                $copy_attendee_info_settings_form->receive_form_submission();
1226
-                // validate form data
1227
-                if ($copy_attendee_info_settings_form->is_valid()) {
1228
-                    // grab validated data from form
1229
-                    $valid_data = $copy_attendee_info_settings_form->valid_data();
1230
-                    if (isset($valid_data['copy_attendee_info'])) {
1231
-                        $EE_Registration_Config->setCopyAttendeeInfo($valid_data['copy_attendee_info']);
1232
-                    } else {
1233
-                        EE_Error::add_error(
1234
-                            esc_html__(
1235
-                                'Invalid or missing Copy Attendee Info settings. Please refresh the form and try again.',
1236
-                                'event_espresso'
1237
-                            ),
1238
-                            __FILE__,
1239
-                            __FUNCTION__,
1240
-                            __LINE__
1241
-                        );
1242
-                    }
1243
-                } else {
1244
-                    if ($copy_attendee_info_settings_form->submission_error_message() !== '') {
1245
-                        EE_Error::add_error(
1246
-                            $copy_attendee_info_settings_form->submission_error_message(),
1247
-                            __FILE__,
1248
-                            __FUNCTION__,
1249
-                            __LINE__
1250
-                        );
1251
-                    }
1252
-                }
1253
-            }
1254
-        } catch (EE_Error $e) {
1255
-            $e->get_error();
1256
-        }
1257
-        return $EE_Registration_Config;
1258
-    }
1259
-
1260
-
1261
-    /**
1262
-     * @return void
1263
-     * @throws EE_Error
1264
-     * @throws InvalidArgumentException
1265
-     * @throws InvalidDataTypeException
1266
-     * @throws InvalidInterfaceException
1267
-     */
1268
-    public function email_validation_settings_form()
1269
-    {
1270
-        echo wp_kses($this->_email_validation_settings_form()->get_html(), AllowedTags::getWithFormTags());
1271
-    }
1272
-
1273
-
1274
-    /**
1275
-     * _email_validation_settings_form
1276
-     *
1277
-     * @access protected
1278
-     * @return EE_Form_Section_Proper
1279
-     * @throws \EE_Error
1280
-     */
1281
-    protected function _email_validation_settings_form()
1282
-    {
1283
-        return new EE_Form_Section_Proper(
1284
-            array(
1285
-                'name'            => 'email_validation_settings',
1286
-                'html_id'         => 'email_validation_settings',
1287
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1288
-                'subsections'     => apply_filters(
1289
-                    'FHEE__Extend_Registration_Form_Admin_Page___email_validation_settings_form__form_subsections',
1290
-                    array(
1291
-                        'email_validation_hdr'   => new EE_Form_Section_HTML(
1292
-                            EEH_HTML::h2(esc_html__('Email Validation Settings', 'event_espresso'))
1293
-                        ),
1294
-                        'email_validation_level' => new EE_Select_Input(
1295
-                            array(
1296
-                                'basic'      => esc_html__('Basic', 'event_espresso'),
1297
-                                'wp_default' => esc_html__('WordPress Default', 'event_espresso'),
1298
-                                'i18n'       => esc_html__('International', 'event_espresso'),
1299
-                                'i18n_dns'   => esc_html__('International + DNS Check', 'event_espresso'),
1300
-                            ),
1301
-                            array(
1302
-                                'html_label_text' => esc_html__('Email Validation Level', 'event_espresso')
1303
-                                                     . EEH_Template::get_help_tab_link('email_validation_info'),
1304
-                                'html_help_text'  => esc_html__(
1305
-                                    'These levels range from basic validation ( ie: [email protected] ) to more advanced checks against international email addresses (ie: üñîçøðé@example.com ) with additional MX and A record checks to confirm the domain actually exists. More information on on each level can be found within the help section.',
1306
-                                    'event_espresso'
1307
-                                ),
1308
-                                'default'         => isset(
1309
-                                    EE_Registry::instance()->CFG->registration->email_validation_level
1310
-                                )
1311
-                                    ? EE_Registry::instance()->CFG->registration->email_validation_level
1312
-                                    : 'wp_default',
1313
-                                'required'        => false,
1314
-                            )
1315
-                        ),
1316
-                    )
1317
-                ),
1318
-            )
1319
-        );
1320
-    }
1321
-
1322
-
1323
-    /**
1324
-     * @param EE_Registration_Config $EE_Registration_Config
1325
-     * @return EE_Registration_Config
1326
-     * @throws EE_Error
1327
-     * @throws InvalidArgumentException
1328
-     * @throws ReflectionException
1329
-     * @throws InvalidDataTypeException
1330
-     * @throws InvalidInterfaceException
1331
-     */
1332
-    public function update_email_validation_settings_form(EE_Registration_Config $EE_Registration_Config)
1333
-    {
1334
-        $prev_email_validation_level = $EE_Registration_Config->email_validation_level;
1335
-        try {
1336
-            $email_validation_settings_form = $this->_email_validation_settings_form();
1337
-            // if not displaying a form, then check for form submission
1338
-            if ($email_validation_settings_form->was_submitted()) {
1339
-                // capture form data
1340
-                $email_validation_settings_form->receive_form_submission();
1341
-                // validate form data
1342
-                if ($email_validation_settings_form->is_valid()) {
1343
-                    // grab validated data from form
1344
-                    $valid_data = $email_validation_settings_form->valid_data();
1345
-                    if (isset($valid_data['email_validation_level'])) {
1346
-                        $email_validation_level = $valid_data['email_validation_level'];
1347
-                        // now if they want to use international email addresses
1348
-                        if ($email_validation_level === 'i18n' || $email_validation_level === 'i18n_dns') {
1349
-                            // in case we need to reset their email validation level,
1350
-                            // make sure that the previous value wasn't already set to one of the i18n options.
1351
-                            if ($prev_email_validation_level === 'i18n' || $prev_email_validation_level === 'i18n_dns') {
1352
-                                // if so, then reset it back to "basic" since that is the only other option that,
1353
-                                // despite offering poor validation, supports i18n email addresses
1354
-                                $prev_email_validation_level = 'basic';
1355
-                            }
1356
-                            // confirm our i18n email validation will work on the server
1357
-                            if (! $this->_verify_pcre_support($EE_Registration_Config, $email_validation_level)) {
1358
-                                // or reset email validation level to previous value
1359
-                                $email_validation_level = $prev_email_validation_level;
1360
-                            }
1361
-                        }
1362
-                        $EE_Registration_Config->email_validation_level = $email_validation_level;
1363
-                    } else {
1364
-                        EE_Error::add_error(
1365
-                            esc_html__(
1366
-                                'Invalid or missing Email Validation settings. Please refresh the form and try again.',
1367
-                                'event_espresso'
1368
-                            ),
1369
-                            __FILE__,
1370
-                            __FUNCTION__,
1371
-                            __LINE__
1372
-                        );
1373
-                    }
1374
-                } else {
1375
-                    if ($email_validation_settings_form->submission_error_message() !== '') {
1376
-                        EE_Error::add_error(
1377
-                            $email_validation_settings_form->submission_error_message(),
1378
-                            __FILE__,
1379
-                            __FUNCTION__,
1380
-                            __LINE__
1381
-                        );
1382
-                    }
1383
-                }
1384
-            }
1385
-        } catch (EE_Error $e) {
1386
-            $e->get_error();
1387
-        }
1388
-        return $EE_Registration_Config;
1389
-    }
1390
-
1391
-
1392
-    /**
1393
-     * confirms that the server's PHP version has the PCRE module enabled,
1394
-     * and that the PCRE version works with our i18n email validation
1395
-     *
1396
-     * @param EE_Registration_Config $EE_Registration_Config
1397
-     * @param string                 $email_validation_level
1398
-     * @return bool
1399
-     */
1400
-    private function _verify_pcre_support(EE_Registration_Config $EE_Registration_Config, $email_validation_level)
1401
-    {
1402
-        // first check that PCRE is enabled
1403
-        if (! defined('PREG_BAD_UTF8_ERROR')) {
1404
-            EE_Error::add_error(
1405
-                sprintf(
1406
-                    esc_html__(
1407
-                        'We\'re sorry, but it appears that your server\'s version of PHP was not compiled with PCRE unicode support.%1$sPlease contact your hosting company and ask them whether the PCRE compiled with your version of PHP on your server can be been built with the "--enable-unicode-properties" and "--enable-utf8" configuration switches to enable more complex regex expressions.%1$sIf they are unable, or unwilling to do so, then your server will not support international email addresses using UTF-8 unicode characters. This means you will either have to lower your email validation level to "Basic" or "WordPress Default", or switch to a hosting company that has/can enable PCRE unicode support on the server.',
1408
-                        'event_espresso'
1409
-                    ),
1410
-                    '<br />'
1411
-                ),
1412
-                __FILE__,
1413
-                __FUNCTION__,
1414
-                __LINE__
1415
-            );
1416
-            return false;
1417
-        } else {
1418
-            // PCRE support is enabled, but let's still
1419
-            // perform a test to see if the server will support it.
1420
-            // but first, save the updated validation level to the config,
1421
-            // so that the validation strategy picks it up.
1422
-            // this will get bumped back down if it doesn't work
1423
-            $EE_Registration_Config->email_validation_level = $email_validation_level;
1424
-            try {
1425
-                $email_validator = new EE_Email_Validation_Strategy();
1426
-                $i18n_email_address = apply_filters(
1427
-                    'FHEE__Extend_Registration_Form_Admin_Page__update_email_validation_settings_form__i18n_email_address',
1428
-                    'jägerjü[email protected]'
1429
-                );
1430
-                $email_validator->validate($i18n_email_address);
1431
-            } catch (Exception $e) {
1432
-                EE_Error::add_error(
1433
-                    sprintf(
1434
-                        esc_html__(
1435
-                            'We\'re sorry, but it appears that your server\'s configuration will not support the "International" or "International + DNS Check" email validation levels.%1$sTo correct this issue, please consult with your hosting company regarding your server\'s PCRE settings.%1$sIt is recommended that your PHP version be configured to use PCRE 8.10 or newer.%1$sMore information regarding PCRE versions and installation can be found here: %2$s',
1436
-                            'event_espresso'
1437
-                        ),
1438
-                        '<br />',
1439
-                        '<a href="http://php.net/manual/en/pcre.installation.php" target="_blank" rel="noopener noreferrer">http://php.net/manual/en/pcre.installation.php</a>'
1440
-                    ),
1441
-                    __FILE__,
1442
-                    __FUNCTION__,
1443
-                    __LINE__
1444
-                );
1445
-                return false;
1446
-            }
1447
-        }
1448
-        return true;
1449
-    }
18
+	/**
19
+	 * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
20
+	 */
21
+	public function __construct($routing = true)
22
+	{
23
+		define('REGISTRATION_FORM_CAF_ADMIN', EE_CORE_CAF_ADMIN_EXTEND . 'registration_form/');
24
+		define('REGISTRATION_FORM_CAF_ASSETS_PATH', REGISTRATION_FORM_CAF_ADMIN . 'assets/');
25
+		define('REGISTRATION_FORM_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registration_form/assets/');
26
+		define('REGISTRATION_FORM_CAF_TEMPLATE_PATH', REGISTRATION_FORM_CAF_ADMIN . 'templates/');
27
+		define('REGISTRATION_FORM_CAF_TEMPLATE_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registration_form/templates/');
28
+		parent::__construct($routing);
29
+	}
30
+
31
+
32
+	/**
33
+	 * @return void
34
+	 */
35
+	protected function _extend_page_config()
36
+	{
37
+		$this->_admin_base_path = REGISTRATION_FORM_CAF_ADMIN;
38
+		$qst_id = ! empty($this->_req_data['QST_ID']) && ! is_array($this->_req_data['QST_ID'])
39
+			? $this->_req_data['QST_ID'] : 0;
40
+		$qsg_id = ! empty($this->_req_data['QSG_ID']) && ! is_array($this->_req_data['QSG_ID'])
41
+			? $this->_req_data['QSG_ID'] : 0;
42
+
43
+		$new_page_routes = array(
44
+			'question_groups'    => array(
45
+				'func'       => '_question_groups_overview_list_table',
46
+				'capability' => 'ee_read_question_groups',
47
+			),
48
+			'add_question'       => array(
49
+				'func'       => '_edit_question',
50
+				'capability' => 'ee_edit_questions',
51
+			),
52
+			'insert_question'    => array(
53
+				'func'       => '_insert_or_update_question',
54
+				'args'       => array('new_question' => true),
55
+				'capability' => 'ee_edit_questions',
56
+				'noheader'   => true,
57
+			),
58
+			'duplicate_question' => array(
59
+				'func'       => '_duplicate_question',
60
+				'capability' => 'ee_edit_questions',
61
+				'noheader'   => true,
62
+			),
63
+			'trash_question'     => array(
64
+				'func'       => '_trash_question',
65
+				'capability' => 'ee_delete_question',
66
+				'obj_id'     => $qst_id,
67
+				'noheader'   => true,
68
+			),
69
+
70
+			'restore_question' => array(
71
+				'func'       => '_trash_or_restore_questions',
72
+				'capability' => 'ee_delete_question',
73
+				'obj_id'     => $qst_id,
74
+				'args'       => array('trash' => false),
75
+				'noheader'   => true,
76
+			),
77
+
78
+			'delete_question' => array(
79
+				'func'       => '_delete_question',
80
+				'capability' => 'ee_delete_question',
81
+				'obj_id'     => $qst_id,
82
+				'noheader'   => true,
83
+			),
84
+
85
+			'trash_questions' => array(
86
+				'func'       => '_trash_or_restore_questions',
87
+				'capability' => 'ee_delete_questions',
88
+				'args'       => array('trash' => true),
89
+				'noheader'   => true,
90
+			),
91
+
92
+			'restore_questions' => array(
93
+				'func'       => '_trash_or_restore_questions',
94
+				'capability' => 'ee_delete_questions',
95
+				'args'       => array('trash' => false),
96
+				'noheader'   => true,
97
+			),
98
+
99
+			'delete_questions' => array(
100
+				'func'       => '_delete_questions',
101
+				'args'       => array(),
102
+				'capability' => 'ee_delete_questions',
103
+				'noheader'   => true,
104
+			),
105
+
106
+			'add_question_group' => array(
107
+				'func'       => '_edit_question_group',
108
+				'capability' => 'ee_edit_question_groups',
109
+			),
110
+
111
+			'edit_question_group' => array(
112
+				'func'       => '_edit_question_group',
113
+				'capability' => 'ee_edit_question_group',
114
+				'obj_id'     => $qsg_id,
115
+				'args'       => array('edit'),
116
+			),
117
+
118
+			'delete_question_groups' => array(
119
+				'func'       => '_delete_question_groups',
120
+				'capability' => 'ee_delete_question_groups',
121
+				'noheader'   => true,
122
+			),
123
+
124
+			'delete_question_group' => array(
125
+				'func'       => '_delete_question_groups',
126
+				'capability' => 'ee_delete_question_group',
127
+				'obj_id'     => $qsg_id,
128
+				'noheader'   => true,
129
+			),
130
+
131
+			'trash_question_group' => array(
132
+				'func'       => '_trash_or_restore_question_groups',
133
+				'args'       => array('trash' => true),
134
+				'capability' => 'ee_delete_question_group',
135
+				'obj_id'     => $qsg_id,
136
+				'noheader'   => true,
137
+			),
138
+
139
+			'restore_question_group' => array(
140
+				'func'       => '_trash_or_restore_question_groups',
141
+				'args'       => array('trash' => false),
142
+				'capability' => 'ee_delete_question_group',
143
+				'obj_id'     => $qsg_id,
144
+				'noheader'   => true,
145
+			),
146
+
147
+			'insert_question_group' => array(
148
+				'func'       => '_insert_or_update_question_group',
149
+				'args'       => array('new_question_group' => true),
150
+				'capability' => 'ee_edit_question_groups',
151
+				'noheader'   => true,
152
+			),
153
+
154
+			'update_question_group' => array(
155
+				'func'       => '_insert_or_update_question_group',
156
+				'args'       => array('new_question_group' => false),
157
+				'capability' => 'ee_edit_question_group',
158
+				'obj_id'     => $qsg_id,
159
+				'noheader'   => true,
160
+			),
161
+
162
+			'trash_question_groups' => array(
163
+				'func'       => '_trash_or_restore_question_groups',
164
+				'args'       => array('trash' => true),
165
+				'capability' => 'ee_delete_question_groups',
166
+				'noheader'   => array('trash' => false),
167
+			),
168
+
169
+			'restore_question_groups' => array(
170
+				'func'       => '_trash_or_restore_question_groups',
171
+				'args'       => array('trash' => false),
172
+				'capability' => 'ee_delete_question_groups',
173
+				'noheader'   => true,
174
+			),
175
+
176
+
177
+			'espresso_update_question_group_order' => array(
178
+				'func'       => 'update_question_group_order',
179
+				'capability' => 'ee_edit_question_groups',
180
+				'noheader'   => true,
181
+			),
182
+
183
+			'view_reg_form_settings' => array(
184
+				'func'       => '_reg_form_settings',
185
+				'capability' => 'manage_options',
186
+			),
187
+
188
+			'update_reg_form_settings' => array(
189
+				'func'       => '_update_reg_form_settings',
190
+				'capability' => 'manage_options',
191
+				'noheader'   => true,
192
+			),
193
+		);
194
+		$this->_page_routes = array_merge($this->_page_routes, $new_page_routes);
195
+
196
+		$new_page_config = array(
197
+
198
+			'question_groups' => array(
199
+				'nav'           => array(
200
+					'label' => esc_html__('Question Groups', 'event_espresso'),
201
+					'order' => 20,
202
+				),
203
+				'list_table'    => 'Registration_Form_Question_Groups_Admin_List_Table',
204
+				'help_tabs'     => array(
205
+					'registration_form_question_groups_help_tab'                           => array(
206
+						'title'    => esc_html__('Question Groups', 'event_espresso'),
207
+						'filename' => 'registration_form_question_groups',
208
+					),
209
+					'registration_form_question_groups_table_column_headings_help_tab'     => array(
210
+						'title'    => esc_html__('Question Groups Table Column Headings', 'event_espresso'),
211
+						'filename' => 'registration_form_question_groups_table_column_headings',
212
+					),
213
+					'registration_form_question_groups_views_bulk_actions_search_help_tab' => array(
214
+						'title'    => esc_html__('Question Groups Views & Bulk Actions & Search', 'event_espresso'),
215
+						'filename' => 'registration_form_question_groups_views_bulk_actions_search',
216
+					),
217
+				),
218
+				'metaboxes'     => $this->_default_espresso_metaboxes,
219
+				'require_nonce' => false,
220
+				'qtips'         => array(
221
+					'EE_Registration_Form_Tips',
222
+				),
223
+			),
224
+
225
+			'add_question' => array(
226
+				'nav'           => array(
227
+					'label'      => esc_html__('Add Question', 'event_espresso'),
228
+					'order'      => 5,
229
+					'persistent' => false,
230
+				),
231
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
232
+				'help_tabs'     => array(
233
+					'registration_form_add_question_help_tab' => array(
234
+						'title'    => esc_html__('Add Question', 'event_espresso'),
235
+						'filename' => 'registration_form_add_question',
236
+					),
237
+				),
238
+				'require_nonce' => false,
239
+			),
240
+
241
+			'add_question_group' => array(
242
+				'nav'           => array(
243
+					'label'      => esc_html__('Add Question Group', 'event_espresso'),
244
+					'order'      => 5,
245
+					'persistent' => false,
246
+				),
247
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
248
+				'help_tabs'     => array(
249
+					'registration_form_add_question_group_help_tab' => array(
250
+						'title'    => esc_html__('Add Question Group', 'event_espresso'),
251
+						'filename' => 'registration_form_add_question_group',
252
+					),
253
+				),
254
+				'require_nonce' => false,
255
+			),
256
+
257
+			'edit_question_group' => array(
258
+				'nav'           => array(
259
+					'label'      => esc_html__('Edit Question Group', 'event_espresso'),
260
+					'order'      => 5,
261
+					'persistent' => false,
262
+					'url'        => isset($this->_req_data['question_group_id']) ? add_query_arg(
263
+						array('question_group_id' => $this->_req_data['question_group_id']),
264
+						$this->_current_page_view_url
265
+					) : $this->_admin_base_url,
266
+				),
267
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
268
+				'help_tabs'     => array(
269
+					'registration_form_edit_question_group_help_tab' => array(
270
+						'title'    => esc_html__('Edit Question Group', 'event_espresso'),
271
+						'filename' => 'registration_form_edit_question_group',
272
+					),
273
+				),
274
+				'require_nonce' => false,
275
+			),
276
+
277
+			'view_reg_form_settings' => array(
278
+				'nav'           => array(
279
+					'label' => esc_html__('Reg Form Settings', 'event_espresso'),
280
+					'order' => 40,
281
+				),
282
+				'labels'        => array(
283
+					'publishbox' => esc_html__('Update Settings', 'event_espresso'),
284
+				),
285
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
286
+				'help_tabs'     => array(
287
+					'registration_form_reg_form_settings_help_tab' => array(
288
+						'title'    => esc_html__('Registration Form Settings', 'event_espresso'),
289
+						'filename' => 'registration_form_reg_form_settings',
290
+					),
291
+				),
292
+				'require_nonce' => false,
293
+			),
294
+
295
+		);
296
+		$this->_page_config = array_merge($this->_page_config, $new_page_config);
297
+
298
+		// change the list table we're going to use so it's the NEW list table!
299
+		$this->_page_config['default']['list_table'] = 'Extend_Registration_Form_Questions_Admin_List_Table';
300
+
301
+
302
+		// additional labels
303
+		$new_labels = array(
304
+			'add_question'          => esc_html__('Add New Question', 'event_espresso'),
305
+			'delete_question'       => esc_html__('Delete Question', 'event_espresso'),
306
+			'add_question_group'    => esc_html__('Add New Question Group', 'event_espresso'),
307
+			'edit_question_group'   => esc_html__('Edit Question Group', 'event_espresso'),
308
+			'delete_question_group' => esc_html__('Delete Question Group', 'event_espresso'),
309
+		);
310
+		$this->_labels['buttons'] = array_merge($this->_labels['buttons'], $new_labels);
311
+	}
312
+
313
+
314
+	/**
315
+	 * @return void
316
+	 */
317
+	protected function _ajax_hooks()
318
+	{
319
+		add_action('wp_ajax_espresso_update_question_group_order', array($this, 'update_question_group_order'));
320
+	}
321
+
322
+
323
+	/**
324
+	 * @return void
325
+	 */
326
+	public function load_scripts_styles_question_groups()
327
+	{
328
+		wp_enqueue_script('espresso_ajax_table_sorting');
329
+	}
330
+
331
+
332
+	/**
333
+	 * @return void
334
+	 */
335
+	public function load_scripts_styles_add_question_group()
336
+	{
337
+		$this->load_scripts_styles_forms();
338
+		$this->load_sortable_question_script();
339
+	}
340
+
341
+
342
+	/**
343
+	 * @return void
344
+	 */
345
+	public function load_scripts_styles_edit_question_group()
346
+	{
347
+		$this->load_scripts_styles_forms();
348
+		$this->load_sortable_question_script();
349
+	}
350
+
351
+
352
+	/**
353
+	 * registers and enqueues script for questions
354
+	 *
355
+	 * @return void
356
+	 */
357
+	public function load_sortable_question_script()
358
+	{
359
+		wp_register_script(
360
+			'ee-question-sortable',
361
+			REGISTRATION_FORM_CAF_ASSETS_URL . 'ee_question_order.js',
362
+			array('jquery-ui-sortable'),
363
+			EVENT_ESPRESSO_VERSION,
364
+			true
365
+		);
366
+		wp_enqueue_script('ee-question-sortable');
367
+	}
368
+
369
+
370
+	/**
371
+	 * @return void
372
+	 */
373
+	protected function _set_list_table_views_default()
374
+	{
375
+		$this->_views = array(
376
+			'all' => array(
377
+				'slug'        => 'all',
378
+				'label'       => esc_html__('View All Questions', 'event_espresso'),
379
+				'count'       => 0,
380
+				'bulk_action' => array(
381
+					'trash_questions' => esc_html__('Trash', 'event_espresso'),
382
+				),
383
+			),
384
+		);
385
+
386
+		if (
387
+			EE_Registry::instance()->CAP->current_user_can(
388
+				'ee_delete_questions',
389
+				'espresso_registration_form_trash_questions'
390
+			)
391
+		) {
392
+			$this->_views['trash'] = array(
393
+				'slug'        => 'trash',
394
+				'label'       => esc_html__('Trash', 'event_espresso'),
395
+				'count'       => 0,
396
+				'bulk_action' => array(
397
+					'delete_questions'  => esc_html__('Delete Permanently', 'event_espresso'),
398
+					'restore_questions' => esc_html__('Restore', 'event_espresso'),
399
+				),
400
+			);
401
+		}
402
+	}
403
+
404
+
405
+	/**
406
+	 * @return void
407
+	 */
408
+	protected function _set_list_table_views_question_groups()
409
+	{
410
+		$this->_views = array(
411
+			'all' => array(
412
+				'slug'        => 'all',
413
+				'label'       => esc_html__('All', 'event_espresso'),
414
+				'count'       => 0,
415
+				'bulk_action' => array(
416
+					'trash_question_groups' => esc_html__('Trash', 'event_espresso'),
417
+				),
418
+			),
419
+		);
420
+
421
+		if (
422
+			EE_Registry::instance()->CAP->current_user_can(
423
+				'ee_delete_question_groups',
424
+				'espresso_registration_form_trash_question_groups'
425
+			)
426
+		) {
427
+			$this->_views['trash'] = array(
428
+				'slug'        => 'trash',
429
+				'label'       => esc_html__('Trash', 'event_espresso'),
430
+				'count'       => 0,
431
+				'bulk_action' => array(
432
+					'delete_question_groups'  => esc_html__('Delete Permanently', 'event_espresso'),
433
+					'restore_question_groups' => esc_html__('Restore', 'event_espresso'),
434
+				),
435
+			);
436
+		}
437
+	}
438
+
439
+
440
+	/**
441
+	 * @return void
442
+	 * @throws EE_Error
443
+	 * @throws InvalidArgumentException
444
+	 * @throws InvalidDataTypeException
445
+	 * @throws InvalidInterfaceException
446
+	 */
447
+	protected function _questions_overview_list_table()
448
+	{
449
+		$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
450
+			'add_question',
451
+			'add_question',
452
+			array(),
453
+			'add-new-h2'
454
+		);
455
+		parent::_questions_overview_list_table();
456
+	}
457
+
458
+
459
+	/**
460
+	 * @return void
461
+	 * @throws DomainException
462
+	 * @throws EE_Error
463
+	 * @throws InvalidArgumentException
464
+	 * @throws InvalidDataTypeException
465
+	 * @throws InvalidInterfaceException
466
+	 */
467
+	protected function _question_groups_overview_list_table()
468
+	{
469
+		$this->_search_btn_label = esc_html__('Question Groups', 'event_espresso');
470
+		$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
471
+			'add_question_group',
472
+			'add_question_group',
473
+			array(),
474
+			'add-new-h2'
475
+		);
476
+		$this->display_admin_list_table_page_with_sidebar();
477
+	}
478
+
479
+
480
+	/**
481
+	 * @return void
482
+	 * @throws EE_Error
483
+	 * @throws InvalidArgumentException
484
+	 * @throws InvalidDataTypeException
485
+	 * @throws InvalidInterfaceException
486
+	 */
487
+	protected function _delete_question()
488
+	{
489
+		$success = $this->_delete_items($this->_question_model);
490
+		$this->_redirect_after_action(
491
+			$success,
492
+			$this->_question_model->item_name($success),
493
+			'deleted',
494
+			array('action' => 'default', 'status' => 'all')
495
+		);
496
+	}
497
+
498
+
499
+	/**
500
+	 * @return void
501
+	 * @throws EE_Error
502
+	 * @throws InvalidArgumentException
503
+	 * @throws InvalidDataTypeException
504
+	 * @throws InvalidInterfaceException
505
+	 */
506
+	protected function _delete_questions()
507
+	{
508
+		$success = $this->_delete_items($this->_question_model);
509
+		$this->_redirect_after_action(
510
+			$success,
511
+			$this->_question_model->item_name($success),
512
+			'deleted permanently',
513
+			array('action' => 'default', 'status' => 'trash')
514
+		);
515
+	}
516
+
517
+
518
+	/**
519
+	 * Performs the deletion of a single or multiple questions or question groups.
520
+	 *
521
+	 * @param EEM_Soft_Delete_Base $model
522
+	 * @return int number of items deleted permanently
523
+	 * @throws EE_Error
524
+	 * @throws InvalidArgumentException
525
+	 * @throws InvalidDataTypeException
526
+	 * @throws InvalidInterfaceException
527
+	 */
528
+	private function _delete_items(EEM_Soft_Delete_Base $model)
529
+	{
530
+		$success = 0;
531
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
532
+		if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
533
+			// if array has more than one element than success message should be plural
534
+			$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
535
+			// cycle thru bulk action checkboxes
536
+			while (list($ID, $value) = each($this->_req_data['checkbox'])) {
537
+				if (! $this->_delete_item($ID, $model)) {
538
+					$success = 0;
539
+				}
540
+			}
541
+		} elseif (! empty($this->_req_data['QSG_ID'])) {
542
+			$success = $this->_delete_item($this->_req_data['QSG_ID'], $model);
543
+		} elseif (! empty($this->_req_data['QST_ID'])) {
544
+			$success = $this->_delete_item($this->_req_data['QST_ID'], $model);
545
+		} else {
546
+			EE_Error::add_error(
547
+				sprintf(
548
+					esc_html__(
549
+						"No Questions or Question Groups were selected for deleting. This error usually shows when you've attempted to delete via bulk action but there were no selections.",
550
+						"event_espresso"
551
+					)
552
+				),
553
+				__FILE__,
554
+				__FUNCTION__,
555
+				__LINE__
556
+			);
557
+		}
558
+		return $success;
559
+	}
560
+
561
+
562
+	/**
563
+	 * Deletes the specified question (and its associated question options) or question group
564
+	 *
565
+	 * @param int                  $id
566
+	 * @param EEM_Soft_Delete_Base $model
567
+	 * @return boolean
568
+	 * @throws EE_Error
569
+	 * @throws InvalidArgumentException
570
+	 * @throws InvalidDataTypeException
571
+	 * @throws InvalidInterfaceException
572
+	 */
573
+	protected function _delete_item($id, $model)
574
+	{
575
+		if ($model instanceof EEM_Question) {
576
+			EEM_Question_Option::instance()->delete_permanently(array(array('QST_ID' => absint($id))));
577
+		}
578
+		return $model->delete_permanently_by_ID(absint($id));
579
+	}
580
+
581
+
582
+	/******************************    QUESTION GROUPS    ******************************/
583
+
584
+
585
+	/**
586
+	 * @param string $type
587
+	 * @return void
588
+	 * @throws DomainException
589
+	 * @throws EE_Error
590
+	 * @throws InvalidArgumentException
591
+	 * @throws InvalidDataTypeException
592
+	 * @throws InvalidInterfaceException
593
+	 */
594
+	protected function _edit_question_group($type = 'add')
595
+	{
596
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
597
+		$ID = isset($this->_req_data['QSG_ID']) && ! empty($this->_req_data['QSG_ID'])
598
+			? absint($this->_req_data['QSG_ID'])
599
+			: false;
600
+
601
+		switch ($this->_req_action) {
602
+			case 'add_question_group':
603
+				$this->_admin_page_title = esc_html__('Add Question Group', 'event_espresso');
604
+				break;
605
+			case 'edit_question_group':
606
+				$this->_admin_page_title = esc_html__('Edit Question Group', 'event_espresso');
607
+				break;
608
+			default:
609
+				$this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
610
+		}
611
+		// add ID to title if editing
612
+		$this->_admin_page_title = $ID ? $this->_admin_page_title . ' # ' . $ID : $this->_admin_page_title;
613
+		if ($ID) {
614
+			/** @var EE_Question_Group $questionGroup */
615
+			$questionGroup = $this->_question_group_model->get_one_by_ID($ID);
616
+			$additional_hidden_fields = array('QSG_ID' => array('type' => 'hidden', 'value' => $ID));
617
+			$this->_set_add_edit_form_tags('update_question_group', $additional_hidden_fields);
618
+		} else {
619
+			/** @var EE_Question_Group $questionGroup */
620
+			$questionGroup = EEM_Question_Group::instance()->create_default_object();
621
+			$questionGroup->set_order_to_latest();
622
+			$this->_set_add_edit_form_tags('insert_question_group');
623
+		}
624
+		$this->_template_args['values'] = $this->_yes_no_values;
625
+		$this->_template_args['all_questions'] = $questionGroup->questions_in_and_not_in_group();
626
+		$this->_template_args['QSG_ID'] = $ID ? $ID : true;
627
+		$this->_template_args['question_group'] = $questionGroup;
628
+
629
+		$redirect_URL = add_query_arg(array('action' => 'question_groups'), $this->_admin_base_url);
630
+		$this->_set_publish_post_box_vars('id', $ID, false, $redirect_URL);
631
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
632
+			REGISTRATION_FORM_CAF_TEMPLATE_PATH . 'question_groups_main_meta_box.template.php',
633
+			$this->_template_args,
634
+			true
635
+		);
636
+
637
+		// the details template wrapper
638
+		$this->display_admin_page_with_sidebar();
639
+	}
640
+
641
+
642
+	/**
643
+	 * @return void
644
+	 * @throws EE_Error
645
+	 * @throws InvalidArgumentException
646
+	 * @throws InvalidDataTypeException
647
+	 * @throws InvalidInterfaceException
648
+	 */
649
+	protected function _delete_question_groups()
650
+	{
651
+		$success = $this->_delete_items($this->_question_group_model);
652
+		$this->_redirect_after_action(
653
+			$success,
654
+			$this->_question_group_model->item_name($success),
655
+			'deleted permanently',
656
+			array('action' => 'question_groups', 'status' => 'trash')
657
+		);
658
+	}
659
+
660
+
661
+	/**
662
+	 * @param bool $new_question_group
663
+	 * @throws EE_Error
664
+	 * @throws InvalidArgumentException
665
+	 * @throws InvalidDataTypeException
666
+	 * @throws InvalidInterfaceException
667
+	 */
668
+	protected function _insert_or_update_question_group($new_question_group = true)
669
+	{
670
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
671
+		$set_column_values = $this->_set_column_values_for($this->_question_group_model);
672
+		if ($new_question_group) {
673
+			// make sure identifier is unique
674
+			$identifier_value = isset($set_column_values['QSG_identifier']) ? $set_column_values['QSG_identifier'] : '';
675
+			$identifier_exists = ! empty($identifier_value)
676
+				? $this->_question_group_model->count([['QSG_identifier' => $set_column_values['QSG_identifier']]]) > 0
677
+				: false;
678
+			if ($identifier_exists) {
679
+				$set_column_values['QSG_identifier'] .= uniqid('id', true);
680
+			}
681
+			$QSG_ID = $this->_question_group_model->insert($set_column_values);
682
+			$success = $QSG_ID ? 1 : 0;
683
+			if ($success === 0) {
684
+				EE_Error::add_error(
685
+					esc_html__('Something went wrong saving the question group.', 'event_espresso'),
686
+					__FILE__,
687
+					__FUNCTION__,
688
+					__LINE__
689
+				);
690
+				$this->_redirect_after_action(
691
+					false,
692
+					'',
693
+					'',
694
+					array('action' => 'edit_question_group', 'QSG_ID' => $QSG_ID),
695
+					true
696
+				);
697
+			}
698
+		} else {
699
+			$QSG_ID = absint($this->_req_data['QSG_ID']);
700
+			unset($set_column_values['QSG_ID']);
701
+			$success = $this->_question_group_model->update($set_column_values, array(array('QSG_ID' => $QSG_ID)));
702
+		}
703
+
704
+		$phone_question_id = EEM_Question::instance()->get_Question_ID_from_system_string(
705
+			EEM_Attendee::system_question_phone
706
+		);
707
+		// update the existing related questions
708
+		// BUT FIRST...  delete the phone question from the Question_Group_Question
709
+		// if it is being added to this question group (therefore removed from the existing group)
710
+		if (isset($this->_req_data['questions'], $this->_req_data['questions'][ $phone_question_id ])) {
711
+			// delete where QST ID = system phone question ID and Question Group ID is NOT this group
712
+			EEM_Question_Group_Question::instance()->delete(
713
+				array(
714
+					array(
715
+						'QST_ID' => $phone_question_id,
716
+						'QSG_ID' => array('!=', $QSG_ID),
717
+					),
718
+				)
719
+			);
720
+		}
721
+		/** @type EE_Question_Group $question_group */
722
+		$question_group = $this->_question_group_model->get_one_by_ID($QSG_ID);
723
+		$questions = $question_group->questions();
724
+		// make sure system phone question is added to list of questions for this group
725
+		if (! isset($questions[ $phone_question_id ])) {
726
+			$questions[ $phone_question_id ] = EEM_Question::instance()->get_one_by_ID($phone_question_id);
727
+		}
728
+
729
+		foreach ($questions as $question_ID => $question) {
730
+			// first we always check for order.
731
+			if (! empty($this->_req_data['question_orders'][ $question_ID ])) {
732
+				// update question order
733
+				$question_group->update_question_order(
734
+					$question_ID,
735
+					$this->_req_data['question_orders'][ $question_ID ]
736
+				);
737
+			}
738
+
739
+			// then we always check if adding or removing.
740
+			if (isset($this->_req_data['questions'], $this->_req_data['questions'][ $question_ID ])) {
741
+				$question_group->add_question($question_ID);
742
+			} else {
743
+				// not found, remove it (but only if not a system question for the personal group
744
+				// with the exception of lname system question - we allow removal of it)
745
+				if (
746
+					in_array(
747
+						$question->system_ID(),
748
+						EEM_Question::instance()->required_system_questions_in_system_question_group(
749
+							$question_group->system_group()
750
+						)
751
+					)
752
+				) {
753
+					continue;
754
+				} else {
755
+					$question_group->remove_question($question_ID);
756
+				}
757
+			}
758
+		}
759
+		// save new related questions
760
+		if (isset($this->_req_data['questions'])) {
761
+			foreach ($this->_req_data['questions'] as $QST_ID) {
762
+				$question_group->add_question($QST_ID);
763
+				if (isset($this->_req_data['question_orders'][ $QST_ID ])) {
764
+					$question_group->update_question_order($QST_ID, $this->_req_data['question_orders'][ $QST_ID ]);
765
+				}
766
+			}
767
+		}
768
+
769
+		if ($success !== false) {
770
+			$msg = $new_question_group
771
+				? sprintf(
772
+					esc_html__('The %s has been created', 'event_espresso'),
773
+					$this->_question_group_model->item_name()
774
+				)
775
+				: sprintf(
776
+					esc_html__(
777
+						'The %s has been updated',
778
+						'event_espresso'
779
+					),
780
+					$this->_question_group_model->item_name()
781
+				);
782
+			EE_Error::add_success($msg);
783
+		}
784
+		$this->_redirect_after_action(
785
+			false,
786
+			'',
787
+			'',
788
+			array('action' => 'edit_question_group', 'QSG_ID' => $QSG_ID),
789
+			true
790
+		);
791
+	}
792
+
793
+
794
+	/**
795
+	 * duplicates a question and all its question options and redirects to the new question.
796
+	 *
797
+	 * @return void
798
+	 * @throws EE_Error
799
+	 * @throws InvalidArgumentException
800
+	 * @throws ReflectionException
801
+	 * @throws InvalidDataTypeException
802
+	 * @throws InvalidInterfaceException
803
+	 */
804
+	public function _duplicate_question()
805
+	{
806
+		$question_ID = (int) $this->_req_data['QST_ID'];
807
+		$question = EEM_Question::instance()->get_one_by_ID($question_ID);
808
+		if ($question instanceof EE_Question) {
809
+			$new_question = $question->duplicate();
810
+			if ($new_question instanceof EE_Question) {
811
+				$this->_redirect_after_action(
812
+					true,
813
+					esc_html__('Question', 'event_espresso'),
814
+					esc_html__('Duplicated', 'event_espresso'),
815
+					array('action' => 'edit_question', 'QST_ID' => $new_question->ID()),
816
+					true
817
+				);
818
+			} else {
819
+				global $wpdb;
820
+				EE_Error::add_error(
821
+					sprintf(
822
+						esc_html__(
823
+							'Could not duplicate question with ID %1$d because: %2$s',
824
+							'event_espresso'
825
+						),
826
+						$question_ID,
827
+						$wpdb->last_error
828
+					),
829
+					__FILE__,
830
+					__FUNCTION__,
831
+					__LINE__
832
+				);
833
+				$this->_redirect_after_action(false, '', '', array('action' => 'default'), false);
834
+			}
835
+		} else {
836
+			EE_Error::add_error(
837
+				sprintf(
838
+					esc_html__(
839
+						'Could not duplicate question with ID %d because it didn\'t exist!',
840
+						'event_espresso'
841
+					),
842
+					$question_ID
843
+				),
844
+				__FILE__,
845
+				__FUNCTION__,
846
+				__LINE__
847
+			);
848
+			$this->_redirect_after_action(false, '', '', array('action' => 'default'), false);
849
+		}
850
+	}
851
+
852
+
853
+	/**
854
+	 * @param bool $trash
855
+	 * @throws EE_Error
856
+	 */
857
+	protected function _trash_or_restore_question_groups($trash = true)
858
+	{
859
+		$this->_trash_or_restore_items($this->_question_group_model, $trash);
860
+	}
861
+
862
+
863
+	/**
864
+	 *_trash_question
865
+	 *
866
+	 * @return void
867
+	 * @throws EE_Error
868
+	 */
869
+	protected function _trash_question()
870
+	{
871
+		$success = $this->_question_model->delete_by_ID((int) $this->_req_data['QST_ID']);
872
+		$query_args = array('action' => 'default', 'status' => 'all');
873
+		$this->_redirect_after_action($success, $this->_question_model->item_name($success), 'trashed', $query_args);
874
+	}
875
+
876
+
877
+	/**
878
+	 * @param bool $trash
879
+	 * @throws EE_Error
880
+	 */
881
+	protected function _trash_or_restore_questions($trash = true)
882
+	{
883
+		$this->_trash_or_restore_items($this->_question_model, $trash);
884
+	}
885
+
886
+
887
+	/**
888
+	 * Internally used to delete or restore items, using the request data. Meant to be
889
+	 * flexible between question or question groups
890
+	 *
891
+	 * @param EEM_Soft_Delete_Base $model
892
+	 * @param boolean              $trash whether to trash or restore
893
+	 * @throws EE_Error
894
+	 */
895
+	private function _trash_or_restore_items(EEM_Soft_Delete_Base $model, $trash = true)
896
+	{
897
+
898
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
899
+
900
+		$success = 1;
901
+		// Checkboxes
902
+		// echo "trash $trash";
903
+		// var_dump($this->_req_data['checkbox']);die;
904
+		if (isset($this->_req_data['checkbox'])) {
905
+			if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
906
+				// if array has more than one element than success message should be plural
907
+				$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
908
+				// cycle thru bulk action checkboxes
909
+				while (list($ID, $value) = each($this->_req_data['checkbox'])) {
910
+					if (! $model->delete_or_restore_by_ID($trash, absint($ID))) {
911
+						$success = 0;
912
+					}
913
+				}
914
+			} else {
915
+				// grab single id and delete
916
+				$ID = absint($this->_req_data['checkbox']);
917
+				if (! $model->delete_or_restore_by_ID($trash, $ID)) {
918
+					$success = 0;
919
+				}
920
+			}
921
+		} else {
922
+			// delete via trash link
923
+			// grab single id and delete
924
+			$ID = absint($this->_req_data[ $model->primary_key_name() ]);
925
+			if (! $model->delete_or_restore_by_ID($trash, $ID)) {
926
+				$success = 0;
927
+			}
928
+		}
929
+
930
+
931
+		$action = $model instanceof EEM_Question ? 'default' : 'question_groups';// strtolower( $model->item_name(2) );
932
+		// echo "action :$action";
933
+		// $action = 'questions' ? 'default' : $action;
934
+		if ($trash) {
935
+			$action_desc = 'trashed';
936
+			$status = 'trash';
937
+		} else {
938
+			$action_desc = 'restored';
939
+			$status = 'all';
940
+		}
941
+		$this->_redirect_after_action(
942
+			$success,
943
+			$model->item_name($success),
944
+			$action_desc,
945
+			array('action' => $action, 'status' => $status)
946
+		);
947
+	}
948
+
949
+
950
+	/**
951
+	 * @param            $per_page
952
+	 * @param int        $current_page
953
+	 * @param bool|false $count
954
+	 * @return EE_Soft_Delete_Base_Class[]|int
955
+	 * @throws EE_Error
956
+	 * @throws InvalidArgumentException
957
+	 * @throws InvalidDataTypeException
958
+	 * @throws InvalidInterfaceException
959
+	 */
960
+	public function get_trashed_questions($per_page, $current_page = 1, $count = false)
961
+	{
962
+		$query_params = $this->get_query_params(EEM_Question::instance(), $per_page, $current_page);
963
+
964
+		if ($count) {
965
+			// note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
966
+			$where = isset($query_params[0]) ? array($query_params[0]) : array();
967
+			$results = $this->_question_model->count_deleted($where);
968
+		} else {
969
+			// note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
970
+			$results = $this->_question_model->get_all_deleted($query_params);
971
+		}
972
+		return $results;
973
+	}
974
+
975
+
976
+	/**
977
+	 * @param            $per_page
978
+	 * @param int        $current_page
979
+	 * @param bool|false $count
980
+	 * @return EE_Soft_Delete_Base_Class[]|int
981
+	 * @throws EE_Error
982
+	 * @throws InvalidArgumentException
983
+	 * @throws InvalidDataTypeException
984
+	 * @throws InvalidInterfaceException
985
+	 */
986
+	public function get_question_groups($per_page, $current_page = 1, $count = false)
987
+	{
988
+		$questionGroupModel = EEM_Question_Group::instance();
989
+		$query_params = $this->get_query_params($questionGroupModel, $per_page, $current_page);
990
+		if ($count) {
991
+			$where = isset($query_params[0]) ? array($query_params[0]) : array();
992
+			$results = $questionGroupModel->count($where);
993
+		} else {
994
+			$results = $questionGroupModel->get_all($query_params);
995
+		}
996
+		return $results;
997
+	}
998
+
999
+
1000
+	/**
1001
+	 * @param      $per_page
1002
+	 * @param int  $current_page
1003
+	 * @param bool $count
1004
+	 * @return EE_Soft_Delete_Base_Class[]|int
1005
+	 * @throws EE_Error
1006
+	 * @throws InvalidArgumentException
1007
+	 * @throws InvalidDataTypeException
1008
+	 * @throws InvalidInterfaceException
1009
+	 */
1010
+	public function get_trashed_question_groups($per_page, $current_page = 1, $count = false)
1011
+	{
1012
+		$questionGroupModel = EEM_Question_Group::instance();
1013
+		$query_params = $this->get_query_params($questionGroupModel, $per_page, $current_page);
1014
+		if ($count) {
1015
+			$where = isset($query_params[0]) ? array($query_params[0]) : array();
1016
+			$query_params['limit'] = null;
1017
+			$results = $questionGroupModel->count_deleted($where);
1018
+		} else {
1019
+			$results = $questionGroupModel->get_all_deleted($query_params);
1020
+		}
1021
+		return $results;
1022
+	}
1023
+
1024
+
1025
+	/**
1026
+	 * method for performing updates to question order
1027
+	 *
1028
+	 * @return void results array
1029
+	 * @throws EE_Error
1030
+	 * @throws InvalidArgumentException
1031
+	 * @throws InvalidDataTypeException
1032
+	 * @throws InvalidInterfaceException
1033
+	 */
1034
+	public function update_question_group_order()
1035
+	{
1036
+
1037
+		$success = esc_html__('Question group order was updated successfully.', 'event_espresso');
1038
+
1039
+		// grab our row IDs
1040
+		$row_ids = isset($this->_req_data['row_ids']) && ! empty($this->_req_data['row_ids'])
1041
+			? explode(',', rtrim($this->_req_data['row_ids'], ','))
1042
+			: array();
1043
+
1044
+		$perpage = ! empty($this->_req_data['perpage'])
1045
+			? (int) $this->_req_data['perpage']
1046
+			: null;
1047
+		$curpage = ! empty($this->_req_data['curpage'])
1048
+			? (int) $this->_req_data['curpage']
1049
+			: null;
1050
+
1051
+		if (! empty($row_ids)) {
1052
+			// figure out where we start the row_id count at for the current page.
1053
+			$qsgcount = empty($curpage) ? 0 : ($curpage - 1) * $perpage;
1054
+
1055
+			$row_count = count($row_ids);
1056
+			for ($i = 0; $i < $row_count; $i++) {
1057
+				// Update the questions when re-ordering
1058
+				$updated = EEM_Question_Group::instance()->update(
1059
+					array('QSG_order' => $qsgcount),
1060
+					array(array('QSG_ID' => $row_ids[ $i ]))
1061
+				);
1062
+				if ($updated === false) {
1063
+					$success = false;
1064
+				}
1065
+				$qsgcount++;
1066
+			}
1067
+		} else {
1068
+			$success = false;
1069
+		}
1070
+
1071
+		$errors = ! $success
1072
+			? esc_html__('An error occurred. The question group order was not updated.', 'event_espresso')
1073
+			: false;
1074
+
1075
+		echo wp_json_encode(array('return_data' => false, 'success' => $success, 'errors' => $errors));
1076
+		die();
1077
+	}
1078
+
1079
+
1080
+
1081
+	/***************************************       REGISTRATION SETTINGS       ***************************************/
1082
+
1083
+
1084
+	/**
1085
+	 * @throws DomainException
1086
+	 * @throws EE_Error
1087
+	 * @throws InvalidArgumentException
1088
+	 * @throws InvalidDataTypeException
1089
+	 * @throws InvalidInterfaceException
1090
+	 */
1091
+	protected function _reg_form_settings()
1092
+	{
1093
+		$this->_template_args['values'] = $this->_yes_no_values;
1094
+		add_action(
1095
+			'AHEE__Extend_Registration_Form_Admin_Page___reg_form_settings_template',
1096
+			array($this, 'email_validation_settings_form'),
1097
+			2
1098
+		);
1099
+		add_action(
1100
+			'AHEE__Extend_Registration_Form_Admin_Page___reg_form_settings_template',
1101
+			array($this, 'copy_attendee_info_settings_form'),
1102
+			4
1103
+		);
1104
+		$this->_template_args = (array) apply_filters(
1105
+			'FHEE__Extend_Registration_Form_Admin_Page___reg_form_settings___template_args',
1106
+			$this->_template_args
1107
+		);
1108
+		$this->_set_add_edit_form_tags('update_reg_form_settings');
1109
+		$this->_set_publish_post_box_vars(null, false, false, null, false);
1110
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
1111
+			REGISTRATION_FORM_CAF_TEMPLATE_PATH . 'reg_form_settings.template.php',
1112
+			$this->_template_args,
1113
+			true
1114
+		);
1115
+		$this->display_admin_page_with_sidebar();
1116
+	}
1117
+
1118
+
1119
+	/**
1120
+	 * @return void
1121
+	 * @throws EE_Error
1122
+	 * @throws InvalidArgumentException
1123
+	 * @throws ReflectionException
1124
+	 * @throws InvalidDataTypeException
1125
+	 * @throws InvalidInterfaceException
1126
+	 */
1127
+	protected function _update_reg_form_settings()
1128
+	{
1129
+		EE_Registry::instance()->CFG->registration = $this->update_email_validation_settings_form(
1130
+			EE_Registry::instance()->CFG->registration
1131
+		);
1132
+		EE_Registry::instance()->CFG->registration = $this->update_copy_attendee_info_settings_form(
1133
+			EE_Registry::instance()->CFG->registration
1134
+		);
1135
+		EE_Registry::instance()->CFG->registration = apply_filters(
1136
+			'FHEE__Extend_Registration_Form_Admin_Page___update_reg_form_settings__CFG_registration',
1137
+			EE_Registry::instance()->CFG->registration
1138
+		);
1139
+		$success = $this->_update_espresso_configuration(
1140
+			esc_html__('Registration Form Options', 'event_espresso'),
1141
+			EE_Registry::instance()->CFG,
1142
+			__FILE__,
1143
+			__FUNCTION__,
1144
+			__LINE__
1145
+		);
1146
+		$this->_redirect_after_action(
1147
+			$success,
1148
+			esc_html__('Registration Form Options', 'event_espresso'),
1149
+			'updated',
1150
+			array('action' => 'view_reg_form_settings')
1151
+		);
1152
+	}
1153
+
1154
+
1155
+	/**
1156
+	 * @return void
1157
+	 * @throws EE_Error
1158
+	 * @throws InvalidArgumentException
1159
+	 * @throws InvalidDataTypeException
1160
+	 * @throws InvalidInterfaceException
1161
+	 */
1162
+	public function copy_attendee_info_settings_form()
1163
+	{
1164
+		echo wp_kses($this->_copy_attendee_info_settings_form()->get_html(), AllowedTags::getWithFormTags());
1165
+	}
1166
+
1167
+	/**
1168
+	 * _copy_attendee_info_settings_form
1169
+	 *
1170
+	 * @access protected
1171
+	 * @return EE_Form_Section_Proper
1172
+	 * @throws \EE_Error
1173
+	 */
1174
+	protected function _copy_attendee_info_settings_form()
1175
+	{
1176
+		return new EE_Form_Section_Proper(
1177
+			array(
1178
+				'name'            => 'copy_attendee_info_settings',
1179
+				'html_id'         => 'copy_attendee_info_settings',
1180
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1181
+				'subsections'     => apply_filters(
1182
+					'FHEE__Extend_Registration_Form_Admin_Page___copy_attendee_info_settings_form__form_subsections',
1183
+					array(
1184
+						'copy_attendee_info_hdr'   => new EE_Form_Section_HTML(
1185
+							EEH_HTML::h2(esc_html__('Copy Attendee Info Settings', 'event_espresso'))
1186
+						),
1187
+						'copy_attendee_info' => new EE_Yes_No_Input(
1188
+							array(
1189
+								'html_label_text' => esc_html__(
1190
+									'Allow copy #1 attendee info to extra attendees?',
1191
+									'event_espresso'
1192
+								),
1193
+								'html_help_text'  => esc_html__(
1194
+									'Set to yes if you want to enable the copy of #1 attendee info to extra attendees at Registration Form.',
1195
+									'event_espresso'
1196
+								),
1197
+								'default'         => EE_Registry::instance()->CFG->registration->copyAttendeeInfo(),
1198
+								'required'        => false,
1199
+								'display_html_label_text' => false,
1200
+							)
1201
+						),
1202
+					)
1203
+				),
1204
+			)
1205
+		);
1206
+	}
1207
+
1208
+	/**
1209
+	 * @param EE_Registration_Config $EE_Registration_Config
1210
+	 * @return EE_Registration_Config
1211
+	 * @throws EE_Error
1212
+	 * @throws InvalidArgumentException
1213
+	 * @throws ReflectionException
1214
+	 * @throws InvalidDataTypeException
1215
+	 * @throws InvalidInterfaceException
1216
+	 */
1217
+	public function update_copy_attendee_info_settings_form(EE_Registration_Config $EE_Registration_Config)
1218
+	{
1219
+		$prev_copy_attendee_info = $EE_Registration_Config->copyAttendeeInfo();
1220
+		try {
1221
+			$copy_attendee_info_settings_form = $this->_copy_attendee_info_settings_form();
1222
+			// if not displaying a form, then check for form submission
1223
+			if ($copy_attendee_info_settings_form->was_submitted()) {
1224
+				// capture form data
1225
+				$copy_attendee_info_settings_form->receive_form_submission();
1226
+				// validate form data
1227
+				if ($copy_attendee_info_settings_form->is_valid()) {
1228
+					// grab validated data from form
1229
+					$valid_data = $copy_attendee_info_settings_form->valid_data();
1230
+					if (isset($valid_data['copy_attendee_info'])) {
1231
+						$EE_Registration_Config->setCopyAttendeeInfo($valid_data['copy_attendee_info']);
1232
+					} else {
1233
+						EE_Error::add_error(
1234
+							esc_html__(
1235
+								'Invalid or missing Copy Attendee Info settings. Please refresh the form and try again.',
1236
+								'event_espresso'
1237
+							),
1238
+							__FILE__,
1239
+							__FUNCTION__,
1240
+							__LINE__
1241
+						);
1242
+					}
1243
+				} else {
1244
+					if ($copy_attendee_info_settings_form->submission_error_message() !== '') {
1245
+						EE_Error::add_error(
1246
+							$copy_attendee_info_settings_form->submission_error_message(),
1247
+							__FILE__,
1248
+							__FUNCTION__,
1249
+							__LINE__
1250
+						);
1251
+					}
1252
+				}
1253
+			}
1254
+		} catch (EE_Error $e) {
1255
+			$e->get_error();
1256
+		}
1257
+		return $EE_Registration_Config;
1258
+	}
1259
+
1260
+
1261
+	/**
1262
+	 * @return void
1263
+	 * @throws EE_Error
1264
+	 * @throws InvalidArgumentException
1265
+	 * @throws InvalidDataTypeException
1266
+	 * @throws InvalidInterfaceException
1267
+	 */
1268
+	public function email_validation_settings_form()
1269
+	{
1270
+		echo wp_kses($this->_email_validation_settings_form()->get_html(), AllowedTags::getWithFormTags());
1271
+	}
1272
+
1273
+
1274
+	/**
1275
+	 * _email_validation_settings_form
1276
+	 *
1277
+	 * @access protected
1278
+	 * @return EE_Form_Section_Proper
1279
+	 * @throws \EE_Error
1280
+	 */
1281
+	protected function _email_validation_settings_form()
1282
+	{
1283
+		return new EE_Form_Section_Proper(
1284
+			array(
1285
+				'name'            => 'email_validation_settings',
1286
+				'html_id'         => 'email_validation_settings',
1287
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1288
+				'subsections'     => apply_filters(
1289
+					'FHEE__Extend_Registration_Form_Admin_Page___email_validation_settings_form__form_subsections',
1290
+					array(
1291
+						'email_validation_hdr'   => new EE_Form_Section_HTML(
1292
+							EEH_HTML::h2(esc_html__('Email Validation Settings', 'event_espresso'))
1293
+						),
1294
+						'email_validation_level' => new EE_Select_Input(
1295
+							array(
1296
+								'basic'      => esc_html__('Basic', 'event_espresso'),
1297
+								'wp_default' => esc_html__('WordPress Default', 'event_espresso'),
1298
+								'i18n'       => esc_html__('International', 'event_espresso'),
1299
+								'i18n_dns'   => esc_html__('International + DNS Check', 'event_espresso'),
1300
+							),
1301
+							array(
1302
+								'html_label_text' => esc_html__('Email Validation Level', 'event_espresso')
1303
+													 . EEH_Template::get_help_tab_link('email_validation_info'),
1304
+								'html_help_text'  => esc_html__(
1305
+									'These levels range from basic validation ( ie: [email protected] ) to more advanced checks against international email addresses (ie: üñîçøðé@example.com ) with additional MX and A record checks to confirm the domain actually exists. More information on on each level can be found within the help section.',
1306
+									'event_espresso'
1307
+								),
1308
+								'default'         => isset(
1309
+									EE_Registry::instance()->CFG->registration->email_validation_level
1310
+								)
1311
+									? EE_Registry::instance()->CFG->registration->email_validation_level
1312
+									: 'wp_default',
1313
+								'required'        => false,
1314
+							)
1315
+						),
1316
+					)
1317
+				),
1318
+			)
1319
+		);
1320
+	}
1321
+
1322
+
1323
+	/**
1324
+	 * @param EE_Registration_Config $EE_Registration_Config
1325
+	 * @return EE_Registration_Config
1326
+	 * @throws EE_Error
1327
+	 * @throws InvalidArgumentException
1328
+	 * @throws ReflectionException
1329
+	 * @throws InvalidDataTypeException
1330
+	 * @throws InvalidInterfaceException
1331
+	 */
1332
+	public function update_email_validation_settings_form(EE_Registration_Config $EE_Registration_Config)
1333
+	{
1334
+		$prev_email_validation_level = $EE_Registration_Config->email_validation_level;
1335
+		try {
1336
+			$email_validation_settings_form = $this->_email_validation_settings_form();
1337
+			// if not displaying a form, then check for form submission
1338
+			if ($email_validation_settings_form->was_submitted()) {
1339
+				// capture form data
1340
+				$email_validation_settings_form->receive_form_submission();
1341
+				// validate form data
1342
+				if ($email_validation_settings_form->is_valid()) {
1343
+					// grab validated data from form
1344
+					$valid_data = $email_validation_settings_form->valid_data();
1345
+					if (isset($valid_data['email_validation_level'])) {
1346
+						$email_validation_level = $valid_data['email_validation_level'];
1347
+						// now if they want to use international email addresses
1348
+						if ($email_validation_level === 'i18n' || $email_validation_level === 'i18n_dns') {
1349
+							// in case we need to reset their email validation level,
1350
+							// make sure that the previous value wasn't already set to one of the i18n options.
1351
+							if ($prev_email_validation_level === 'i18n' || $prev_email_validation_level === 'i18n_dns') {
1352
+								// if so, then reset it back to "basic" since that is the only other option that,
1353
+								// despite offering poor validation, supports i18n email addresses
1354
+								$prev_email_validation_level = 'basic';
1355
+							}
1356
+							// confirm our i18n email validation will work on the server
1357
+							if (! $this->_verify_pcre_support($EE_Registration_Config, $email_validation_level)) {
1358
+								// or reset email validation level to previous value
1359
+								$email_validation_level = $prev_email_validation_level;
1360
+							}
1361
+						}
1362
+						$EE_Registration_Config->email_validation_level = $email_validation_level;
1363
+					} else {
1364
+						EE_Error::add_error(
1365
+							esc_html__(
1366
+								'Invalid or missing Email Validation settings. Please refresh the form and try again.',
1367
+								'event_espresso'
1368
+							),
1369
+							__FILE__,
1370
+							__FUNCTION__,
1371
+							__LINE__
1372
+						);
1373
+					}
1374
+				} else {
1375
+					if ($email_validation_settings_form->submission_error_message() !== '') {
1376
+						EE_Error::add_error(
1377
+							$email_validation_settings_form->submission_error_message(),
1378
+							__FILE__,
1379
+							__FUNCTION__,
1380
+							__LINE__
1381
+						);
1382
+					}
1383
+				}
1384
+			}
1385
+		} catch (EE_Error $e) {
1386
+			$e->get_error();
1387
+		}
1388
+		return $EE_Registration_Config;
1389
+	}
1390
+
1391
+
1392
+	/**
1393
+	 * confirms that the server's PHP version has the PCRE module enabled,
1394
+	 * and that the PCRE version works with our i18n email validation
1395
+	 *
1396
+	 * @param EE_Registration_Config $EE_Registration_Config
1397
+	 * @param string                 $email_validation_level
1398
+	 * @return bool
1399
+	 */
1400
+	private function _verify_pcre_support(EE_Registration_Config $EE_Registration_Config, $email_validation_level)
1401
+	{
1402
+		// first check that PCRE is enabled
1403
+		if (! defined('PREG_BAD_UTF8_ERROR')) {
1404
+			EE_Error::add_error(
1405
+				sprintf(
1406
+					esc_html__(
1407
+						'We\'re sorry, but it appears that your server\'s version of PHP was not compiled with PCRE unicode support.%1$sPlease contact your hosting company and ask them whether the PCRE compiled with your version of PHP on your server can be been built with the "--enable-unicode-properties" and "--enable-utf8" configuration switches to enable more complex regex expressions.%1$sIf they are unable, or unwilling to do so, then your server will not support international email addresses using UTF-8 unicode characters. This means you will either have to lower your email validation level to "Basic" or "WordPress Default", or switch to a hosting company that has/can enable PCRE unicode support on the server.',
1408
+						'event_espresso'
1409
+					),
1410
+					'<br />'
1411
+				),
1412
+				__FILE__,
1413
+				__FUNCTION__,
1414
+				__LINE__
1415
+			);
1416
+			return false;
1417
+		} else {
1418
+			// PCRE support is enabled, but let's still
1419
+			// perform a test to see if the server will support it.
1420
+			// but first, save the updated validation level to the config,
1421
+			// so that the validation strategy picks it up.
1422
+			// this will get bumped back down if it doesn't work
1423
+			$EE_Registration_Config->email_validation_level = $email_validation_level;
1424
+			try {
1425
+				$email_validator = new EE_Email_Validation_Strategy();
1426
+				$i18n_email_address = apply_filters(
1427
+					'FHEE__Extend_Registration_Form_Admin_Page__update_email_validation_settings_form__i18n_email_address',
1428
+					'jägerjü[email protected]'
1429
+				);
1430
+				$email_validator->validate($i18n_email_address);
1431
+			} catch (Exception $e) {
1432
+				EE_Error::add_error(
1433
+					sprintf(
1434
+						esc_html__(
1435
+							'We\'re sorry, but it appears that your server\'s configuration will not support the "International" or "International + DNS Check" email validation levels.%1$sTo correct this issue, please consult with your hosting company regarding your server\'s PCRE settings.%1$sIt is recommended that your PHP version be configured to use PCRE 8.10 or newer.%1$sMore information regarding PCRE versions and installation can be found here: %2$s',
1436
+							'event_espresso'
1437
+						),
1438
+						'<br />',
1439
+						'<a href="http://php.net/manual/en/pcre.installation.php" target="_blank" rel="noopener noreferrer">http://php.net/manual/en/pcre.installation.php</a>'
1440
+					),
1441
+					__FILE__,
1442
+					__FUNCTION__,
1443
+					__LINE__
1444
+				);
1445
+				return false;
1446
+			}
1447
+		}
1448
+		return true;
1449
+	}
1450 1450
 }
Please login to merge, or discard this patch.
extend/registration_form/templates/questions_in_group_meta_box.template.php 1 patch
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -4,7 +4,7 @@
 block discarded – undo
4 4
 use EventEspresso\core\services\request\sanitizers\AllowedTags;
5 5
 
6 6
 assert($question_group instanceof EE_Question_Group);
7
-assert(isset($all_questions) && (empty($all_questions) || is_array($all_questions)));// list of unused questions
7
+assert(isset($all_questions) && (empty($all_questions) || is_array($all_questions))); // list of unused questions
8 8
 foreach ($all_questions as $question_option) {
9 9
     assert($question_option);
10 10
     assert($question_option instanceof EE_Question);
Please login to merge, or discard this patch.
core/EE_System.core.php 2 patches
Indentation   +1345 added lines, -1345 removed lines patch added patch discarded remove patch
@@ -27,1349 +27,1349 @@
 block discarded – undo
27 27
 final class EE_System implements ResettableInterface
28 28
 {
29 29
 
30
-    /**
31
-     * indicates this is a 'normal' request. Ie, not activation, nor upgrade, nor activation.
32
-     * So examples of this would be a normal GET request on the frontend or backend, or a POST, etc
33
-     */
34
-    const req_type_normal = 0;
35
-
36
-    /**
37
-     * Indicates this is a brand new installation of EE so we should install
38
-     * tables and default data etc
39
-     */
40
-    const req_type_new_activation = 1;
41
-
42
-    /**
43
-     * we've detected that EE has been reactivated (or EE was activated during maintenance mode,
44
-     * and we just exited maintenance mode). We MUST check the database is setup properly
45
-     * and that default data is setup too
46
-     */
47
-    const req_type_reactivation = 2;
48
-
49
-    /**
50
-     * indicates that EE has been upgraded since its previous request.
51
-     * We may have data migration scripts to call and will want to trigger maintenance mode
52
-     */
53
-    const req_type_upgrade = 3;
54
-
55
-    /**
56
-     * TODO  will detect that EE has been DOWNGRADED. We probably don't want to run in this case...
57
-     */
58
-    const req_type_downgrade = 4;
59
-
60
-    /**
61
-     * @deprecated since version 4.6.0.dev.006
62
-     * Now whenever a new_activation is detected the request type is still just
63
-     * new_activation (same for reactivation, upgrade, downgrade etc), but if we'r ein maintenance mode
64
-     * EE_System::initialize_db_if_no_migrations_required and EE_Addon::initialize_db_if_no_migrations_required
65
-     * will instead enqueue that EE plugin's db initialization for when we're taken out of maintenance mode.
66
-     * (Specifically, when the migration manager indicates migrations are finished
67
-     * EE_Data_Migration_Manager::initialize_db_for_enqueued_ee_plugins() will be called)
68
-     */
69
-    const req_type_activation_but_not_installed = 5;
70
-
71
-    /**
72
-     * option prefix for recording the activation history (like core's "espresso_db_update") of addons
73
-     */
74
-    const addon_activation_history_option_prefix = 'ee_addon_activation_history_';
75
-
76
-    /**
77
-     * @var EE_System $_instance
78
-     */
79
-    private static $_instance;
80
-
81
-    /**
82
-     * @var EE_Registry $registry
83
-     */
84
-    private $registry;
85
-
86
-    /**
87
-     * @var LoaderInterface $loader
88
-     */
89
-    private $loader;
90
-
91
-    /**
92
-     * @var EE_Capabilities $capabilities
93
-     */
94
-    private $capabilities;
95
-
96
-    /**
97
-     * @var RequestInterface $request
98
-     */
99
-    private $request;
100
-
101
-    /**
102
-     * @var EE_Maintenance_Mode $maintenance_mode
103
-     */
104
-    private $maintenance_mode;
105
-
106
-    /**
107
-     * Stores which type of request this is, options being one of the constants on EE_System starting with req_type_*.
108
-     * It can be a brand-new activation, a reactivation, an upgrade, a downgrade, or a normal request.
109
-     *
110
-     * @var int $_req_type
111
-     */
112
-    private $_req_type;
113
-
114
-    /**
115
-     * Whether or not there was a non-micro version change in EE core version during this request
116
-     *
117
-     * @var boolean $_major_version_change
118
-     */
119
-    private $_major_version_change = false;
120
-
121
-    /**
122
-     * A Context DTO dedicated solely to identifying the current request type.
123
-     *
124
-     * @var RequestTypeContextCheckerInterface $request_type
125
-     */
126
-    private $request_type;
127
-
128
-    /**
129
-     * @param EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes
130
-     */
131
-    private $register_custom_post_types;
132
-
133
-    /**
134
-     * @param EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies
135
-     */
136
-    private $register_custom_taxonomies;
137
-
138
-    /**
139
-     * @param EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms
140
-     */
141
-    private $register_custom_taxonomy_terms;
142
-
143
-    /**
144
-     * @singleton method used to instantiate class object
145
-     * @param EE_Registry|null         $registry
146
-     * @param LoaderInterface|null     $loader
147
-     * @param RequestInterface|null    $request
148
-     * @param EE_Maintenance_Mode|null $maintenance_mode
149
-     * @return EE_System
150
-     */
151
-    public static function instance(
152
-        EE_Registry $registry = null,
153
-        LoaderInterface $loader = null,
154
-        RequestInterface $request = null,
155
-        EE_Maintenance_Mode $maintenance_mode = null
156
-    ) {
157
-        // check if class object is instantiated
158
-        if (! self::$_instance instanceof EE_System) {
159
-            self::$_instance = new self($registry, $loader, $request, $maintenance_mode);
160
-        }
161
-        return self::$_instance;
162
-    }
163
-
164
-
165
-    /**
166
-     * resets the instance and returns it
167
-     *
168
-     * @return EE_System
169
-     */
170
-    public static function reset()
171
-    {
172
-        self::$_instance->_req_type = null;
173
-        // make sure none of the old hooks are left hanging around
174
-        remove_all_actions('AHEE__EE_System__perform_activations_upgrades_and_migrations');
175
-        // we need to reset the migration manager in order for it to detect DMSs properly
176
-        EE_Data_Migration_Manager::reset();
177
-        self::instance()->detect_activations_or_upgrades();
178
-        self::instance()->perform_activations_upgrades_and_migrations();
179
-        return self::instance();
180
-    }
181
-
182
-
183
-    /**
184
-     * sets hooks for running rest of system
185
-     * provides "AHEE__EE_System__construct__complete" hook for EE Addons to use as their starting point
186
-     * starting EE Addons from any other point may lead to problems
187
-     *
188
-     * @param EE_Registry         $registry
189
-     * @param LoaderInterface     $loader
190
-     * @param RequestInterface    $request
191
-     * @param EE_Maintenance_Mode $maintenance_mode
192
-     */
193
-    private function __construct(
194
-        EE_Registry $registry,
195
-        LoaderInterface $loader,
196
-        RequestInterface $request,
197
-        EE_Maintenance_Mode $maintenance_mode
198
-    ) {
199
-        $this->registry = $registry;
200
-        $this->loader = $loader;
201
-        $this->request = $request;
202
-        $this->maintenance_mode = $maintenance_mode;
203
-        do_action('AHEE__EE_System__construct__begin', $this);
204
-        add_action(
205
-            'AHEE__EE_Bootstrap__load_espresso_addons',
206
-            array($this, 'loadCapabilities'),
207
-            5
208
-        );
209
-        add_action(
210
-            'AHEE__EE_Bootstrap__load_espresso_addons',
211
-            array($this, 'loadCommandBus'),
212
-            7
213
-        );
214
-        add_action(
215
-            'AHEE__EE_Bootstrap__load_espresso_addons',
216
-            array($this, 'loadPluginApi'),
217
-            9
218
-        );
219
-        // allow addons to load first so that they can register autoloaders, set hooks for running DMS's, etc
220
-        add_action(
221
-            'AHEE__EE_Bootstrap__load_espresso_addons',
222
-            array($this, 'load_espresso_addons')
223
-        );
224
-        // when an ee addon is activated, we want to call the core hook(s) again
225
-        // because the newly-activated addon didn't get a chance to run at all
226
-        add_action('activate_plugin', array($this, 'load_espresso_addons'), 1);
227
-        // detect whether install or upgrade
228
-        add_action(
229
-            'AHEE__EE_Bootstrap__detect_activations_or_upgrades',
230
-            array($this, 'detect_activations_or_upgrades'),
231
-            3
232
-        );
233
-        // load EE_Config, EE_Textdomain, etc
234
-        add_action(
235
-            'AHEE__EE_Bootstrap__load_core_configuration',
236
-            array($this, 'load_core_configuration'),
237
-            5
238
-        );
239
-        // load specifications for matching routes to current request
240
-        add_action(
241
-            'AHEE__EE_Bootstrap__load_core_configuration',
242
-            array($this, 'loadRouteMatchSpecifications')
243
-        );
244
-        // load specifications for custom post types
245
-        add_action(
246
-            'AHEE__EE_Bootstrap__load_core_configuration',
247
-            array($this, 'loadCustomPostTypes')
248
-        );
249
-        // load EE_Config, EE_Textdomain, etc
250
-        add_action(
251
-            'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets',
252
-            array($this, 'register_shortcodes_modules_and_widgets'),
253
-            7
254
-        );
255
-        // you wanna get going? I wanna get going... let's get going!
256
-        add_action(
257
-            'AHEE__EE_Bootstrap__brew_espresso',
258
-            array($this, 'brew_espresso'),
259
-            9
260
-        );
261
-        // other housekeeping
262
-        // exclude EE critical pages from wp_list_pages
263
-        add_filter(
264
-            'wp_list_pages_excludes',
265
-            array($this, 'remove_pages_from_wp_list_pages'),
266
-            10
267
-        );
268
-        // ALL EE Addons should use the following hook point to attach their initial setup too
269
-        // it's extremely important for EE Addons to register any class autoloaders so that they can be available when the EE_Config loads
270
-        do_action('AHEE__EE_System__construct__complete', $this);
271
-    }
272
-
273
-
274
-    /**
275
-     * load and setup EE_Capabilities
276
-     *
277
-     * @return void
278
-     * @throws EE_Error
279
-     */
280
-    public function loadCapabilities()
281
-    {
282
-        $this->capabilities = $this->loader->getShared('EE_Capabilities');
283
-        add_action(
284
-            'AHEE__EE_Capabilities__init_caps__before_initialization',
285
-            function () {
286
-                LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
287
-            }
288
-        );
289
-    }
290
-
291
-
292
-    /**
293
-     * create and cache the CommandBus, and also add middleware
294
-     * The CapChecker middleware requires the use of EE_Capabilities
295
-     * which is why we need to load the CommandBus after Caps are set up
296
-     *
297
-     * @return void
298
-     * @throws EE_Error
299
-     */
300
-    public function loadCommandBus()
301
-    {
302
-        $this->loader->getShared(
303
-            'CommandBusInterface',
304
-            array(
305
-                null,
306
-                apply_filters(
307
-                    'FHEE__EE_Load_Espresso_Core__handle_request__CommandBus_middleware',
308
-                    array(
309
-                        $this->loader->getShared('EventEspresso\core\services\commands\middleware\CapChecker'),
310
-                        $this->loader->getShared('EventEspresso\core\services\commands\middleware\AddActionHook'),
311
-                    )
312
-                ),
313
-            )
314
-        );
315
-    }
316
-
317
-
318
-    /**
319
-     * @return void
320
-     * @throws EE_Error
321
-     */
322
-    public function loadPluginApi()
323
-    {
324
-        // set autoloaders for all of the classes implementing EEI_Plugin_API
325
-        // which provide helpers for EE plugin authors to more easily register certain components with EE.
326
-        EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'plugin_api');
327
-    }
328
-
329
-
330
-    /**
331
-     * @param string $addon_name
332
-     * @param string $version_constant
333
-     * @param string $min_version_required
334
-     * @param string $load_callback
335
-     * @param string $plugin_file_constant
336
-     * @return void
337
-     */
338
-    private function deactivateIncompatibleAddon(
339
-        $addon_name,
340
-        $version_constant,
341
-        $min_version_required,
342
-        $load_callback,
343
-        $plugin_file_constant
344
-    ) {
345
-        if (! defined($version_constant)) {
346
-            return;
347
-        }
348
-        $addon_version = constant($version_constant);
349
-        if ($addon_version && version_compare($addon_version, $min_version_required, '<')) {
350
-            remove_action('AHEE__EE_System__load_espresso_addons', $load_callback);
351
-            if (! function_exists('deactivate_plugins')) {
352
-                require_once ABSPATH . 'wp-admin/includes/plugin.php';
353
-            }
354
-            deactivate_plugins(plugin_basename(constant($plugin_file_constant)));
355
-            $this->request->unSetRequestParams(['activate', 'activate-multi'], true);
356
-            EE_Error::add_error(
357
-                sprintf(
358
-                    esc_html__(
359
-                        'We\'re sorry, but the Event Espresso %1$s addon was deactivated because version %2$s or higher is required with this version of Event Espresso core.',
360
-                        'event_espresso'
361
-                    ),
362
-                    $addon_name,
363
-                    $min_version_required
364
-                ),
365
-                __FILE__,
366
-                __FUNCTION__ . "({$addon_name})",
367
-                __LINE__
368
-            );
369
-            EE_Error::get_notices(false, true);
370
-        }
371
-    }
372
-
373
-
374
-    /**
375
-     * load_espresso_addons
376
-     * allow addons to load first so that they can set hooks for running DMS's, etc
377
-     * this is hooked into both:
378
-     *    'AHEE__EE_Bootstrap__load_core_configuration'
379
-     *        which runs during the WP 'plugins_loaded' action at priority 5
380
-     *    and the WP 'activate_plugin' hook point
381
-     *
382
-     * @access public
383
-     * @return void
384
-     */
385
-    public function load_espresso_addons()
386
-    {
387
-        $this->deactivateIncompatibleAddon(
388
-            'Wait Lists',
389
-            'EE_WAIT_LISTS_VERSION',
390
-            '1.0.0.beta.074',
391
-            'load_espresso_wait_lists',
392
-            'EE_WAIT_LISTS_PLUGIN_FILE'
393
-        );
394
-        $this->deactivateIncompatibleAddon(
395
-            'Automated Upcoming Event Notifications',
396
-            'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_VERSION',
397
-            '1.0.0.beta.091',
398
-            'load_espresso_automated_upcoming_event_notification',
399
-            'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_PLUGIN_FILE'
400
-        );
401
-        do_action('AHEE__EE_System__load_espresso_addons');
402
-        // if the WP API basic auth plugin isn't already loaded, load it now.
403
-        // We want it for mobile apps. Just include the entire plugin
404
-        // also, don't load the basic auth when a plugin is getting activated, because
405
-        // it could be the basic auth plugin, and it doesn't check if its methods are already defined
406
-        // and causes a fatal error
407
-        if (
408
-            ($this->request->isWordPressApi() || $this->request->isApi())
409
-            && $this->request->getRequestParam('activate') !== 'true'
410
-            && ! function_exists('json_basic_auth_handler')
411
-            && ! function_exists('json_basic_auth_error')
412
-            && ! in_array(
413
-                $this->request->getRequestParam('action'),
414
-                array('activate', 'activate-selected'),
415
-                true
416
-            )
417
-        ) {
418
-            include_once EE_THIRD_PARTY . 'wp-api-basic-auth/basic-auth.php';
419
-        }
420
-        do_action('AHEE__EE_System__load_espresso_addons__complete');
421
-    }
422
-
423
-
424
-    /**
425
-     * detect_activations_or_upgrades
426
-     * Checks for activation or upgrade of core first;
427
-     * then also checks if any registered addons have been activated or upgraded
428
-     * This is hooked into 'AHEE__EE_Bootstrap__detect_activations_or_upgrades'
429
-     * which runs during the WP 'plugins_loaded' action at priority 3
430
-     *
431
-     * @access public
432
-     * @return void
433
-     */
434
-    public function detect_activations_or_upgrades()
435
-    {
436
-        // first off: let's make sure to handle core
437
-        $this->detect_if_activation_or_upgrade();
438
-        foreach ($this->registry->addons as $addon) {
439
-            if ($addon instanceof EE_Addon) {
440
-                // detect teh request type for that addon
441
-                $addon->detect_req_type();
442
-            }
443
-        }
444
-    }
445
-
446
-
447
-    /**
448
-     * detect_if_activation_or_upgrade
449
-     * Takes care of detecting whether this is a brand new install or code upgrade,
450
-     * and either setting up the DB or setting up maintenance mode etc.
451
-     *
452
-     * @access public
453
-     * @return void
454
-     */
455
-    public function detect_if_activation_or_upgrade()
456
-    {
457
-        do_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin');
458
-        // check if db has been updated, or if its a brand-new installation
459
-        $espresso_db_update = $this->fix_espresso_db_upgrade_option();
460
-        $request_type = $this->detect_req_type($espresso_db_update);
461
-        // EEH_Debug_Tools::printr( $request_type, '$request_type', __FILE__, __LINE__ );
462
-        switch ($request_type) {
463
-            case EE_System::req_type_new_activation:
464
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__new_activation');
465
-                $this->_handle_core_version_change($espresso_db_update);
466
-                break;
467
-            case EE_System::req_type_reactivation:
468
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__reactivation');
469
-                $this->_handle_core_version_change($espresso_db_update);
470
-                break;
471
-            case EE_System::req_type_upgrade:
472
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__upgrade');
473
-                // migrations may be required now that we've upgraded
474
-                $this->maintenance_mode->set_maintenance_mode_if_db_old();
475
-                $this->_handle_core_version_change($espresso_db_update);
476
-                break;
477
-            case EE_System::req_type_downgrade:
478
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__downgrade');
479
-                // its possible migrations are no longer required
480
-                $this->maintenance_mode->set_maintenance_mode_if_db_old();
481
-                $this->_handle_core_version_change($espresso_db_update);
482
-                break;
483
-            case EE_System::req_type_normal:
484
-            default:
485
-                break;
486
-        }
487
-        do_action('AHEE__EE_System__detect_if_activation_or_upgrade__complete');
488
-    }
489
-
490
-
491
-    /**
492
-     * Updates the list of installed versions and sets hooks for
493
-     * initializing the database later during the request
494
-     *
495
-     * @param array $espresso_db_update
496
-     */
497
-    private function _handle_core_version_change($espresso_db_update)
498
-    {
499
-        $this->update_list_of_installed_versions($espresso_db_update);
500
-        // get ready to verify the DB is ok (provided we aren't in maintenance mode, of course)
501
-        add_action(
502
-            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
503
-            array($this, 'initialize_db_if_no_migrations_required')
504
-        );
505
-    }
506
-
507
-
508
-    /**
509
-     * standardizes the wp option 'espresso_db_upgrade' which actually stores
510
-     * information about what versions of EE have been installed and activated,
511
-     * NOT necessarily the state of the database
512
-     *
513
-     * @param mixed $espresso_db_update           the value of the WordPress option.
514
-     *                                            If not supplied, fetches it from the options table
515
-     * @return array the correct value of 'espresso_db_upgrade', after saving it, if it needed correction
516
-     */
517
-    private function fix_espresso_db_upgrade_option($espresso_db_update = null)
518
-    {
519
-        do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
520
-        if (! $espresso_db_update) {
521
-            $espresso_db_update = get_option('espresso_db_update');
522
-        }
523
-        // check that option is an array
524
-        if (! is_array($espresso_db_update)) {
525
-            // if option is FALSE, then it never existed
526
-            if ($espresso_db_update === false) {
527
-                // make $espresso_db_update an array and save option with autoload OFF
528
-                $espresso_db_update = array();
529
-                add_option('espresso_db_update', $espresso_db_update, '', 'no');
530
-            } else {
531
-                // option is NOT FALSE but also is NOT an array, so make it an array and save it
532
-                $espresso_db_update = array($espresso_db_update => array());
533
-                update_option('espresso_db_update', $espresso_db_update);
534
-            }
535
-        } else {
536
-            $corrected_db_update = array();
537
-            // if IS an array, but is it an array where KEYS are version numbers, and values are arrays?
538
-            foreach ($espresso_db_update as $should_be_version_string => $should_be_array) {
539
-                if (is_int($should_be_version_string) && ! is_array($should_be_array)) {
540
-                    // the key is an int, and the value IS NOT an array
541
-                    // so it must be numerically-indexed, where values are versions installed...
542
-                    // fix it!
543
-                    $version_string = $should_be_array;
544
-                    $corrected_db_update[ $version_string ] = array('unknown-date');
545
-                } else {
546
-                    // ok it checks out
547
-                    $corrected_db_update[ $should_be_version_string ] = $should_be_array;
548
-                }
549
-            }
550
-            $espresso_db_update = $corrected_db_update;
551
-            update_option('espresso_db_update', $espresso_db_update);
552
-        }
553
-        do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__complete', $espresso_db_update);
554
-        return $espresso_db_update;
555
-    }
556
-
557
-
558
-    /**
559
-     * Does the traditional work of setting up the plugin's database and adding default data.
560
-     * If migration script/process did not exist, this is what would happen on every activation/reactivation/upgrade.
561
-     * NOTE: if we're in maintenance mode (which would be the case if we detect there are data
562
-     * migration scripts that need to be run and a version change happens), enqueues core for database initialization,
563
-     * so that it will be done when migrations are finished
564
-     *
565
-     * @param boolean $initialize_addons_too if true, we double-check addons' database tables etc too;
566
-     * @param boolean $verify_schema         if true will re-check the database tables have the correct schema.
567
-     *                                       This is a resource-intensive job
568
-     *                                       so we prefer to only do it when necessary
569
-     * @return void
570
-     * @throws EE_Error
571
-     */
572
-    public function initialize_db_if_no_migrations_required($initialize_addons_too = false, $verify_schema = true)
573
-    {
574
-        $request_type = $this->detect_req_type();
575
-        // only initialize system if we're not in maintenance mode.
576
-        if ($this->maintenance_mode->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
577
-            /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
578
-            $rewrite_rules = $this->loader->getShared(
579
-                'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
580
-            );
581
-            $rewrite_rules->flush();
582
-            if ($verify_schema) {
583
-                EEH_Activation::initialize_db_and_folders();
584
-            }
585
-            EEH_Activation::initialize_db_content();
586
-            EEH_Activation::system_initialization();
587
-            if ($initialize_addons_too) {
588
-                $this->initialize_addons();
589
-            }
590
-        } else {
591
-            EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for('Core');
592
-        }
593
-        if (
594
-            $request_type === EE_System::req_type_new_activation
595
-            || $request_type === EE_System::req_type_reactivation
596
-            || (
597
-                $request_type === EE_System::req_type_upgrade
598
-                && $this->is_major_version_change()
599
-            )
600
-        ) {
601
-            add_action('AHEE__EE_System__initialize_last', array($this, 'redirect_to_about_ee'), 9);
602
-        }
603
-    }
604
-
605
-
606
-    /**
607
-     * Initializes the db for all registered addons
608
-     *
609
-     * @throws EE_Error
610
-     */
611
-    public function initialize_addons()
612
-    {
613
-        // foreach registered addon, make sure its db is up-to-date too
614
-        foreach ($this->registry->addons as $addon) {
615
-            if ($addon instanceof EE_Addon) {
616
-                $addon->initialize_db_if_no_migrations_required();
617
-            }
618
-        }
619
-    }
620
-
621
-
622
-    /**
623
-     * Adds the current code version to the saved wp option which stores a list of all ee versions ever installed.
624
-     *
625
-     * @param    array  $version_history
626
-     * @param    string $current_version_to_add version to be added to the version history
627
-     * @return    boolean success as to whether or not this option was changed
628
-     */
629
-    public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
630
-    {
631
-        if (! $version_history) {
632
-            $version_history = $this->fix_espresso_db_upgrade_option($version_history);
633
-        }
634
-        if ($current_version_to_add === null) {
635
-            $current_version_to_add = espresso_version();
636
-        }
637
-        $version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
638
-        // re-save
639
-        return update_option('espresso_db_update', $version_history);
640
-    }
641
-
642
-
643
-    /**
644
-     * Detects if the current version indicated in the has existed in the list of
645
-     * previously-installed versions of EE (espresso_db_update). Does NOT modify it (ie, no side-effect)
646
-     *
647
-     * @param array $espresso_db_update array from the wp option stored under the name 'espresso_db_update'.
648
-     *                                  If not supplied, fetches it from the options table.
649
-     *                                  Also, caches its result so later parts of the code can also know whether
650
-     *                                  there's been an update or not. This way we can add the current version to
651
-     *                                  espresso_db_update, but still know if this is a new install or not
652
-     * @return int one of the constants on EE_System::req_type_
653
-     */
654
-    public function detect_req_type($espresso_db_update = null)
655
-    {
656
-        if ($this->_req_type === null) {
657
-            $espresso_db_update = ! empty($espresso_db_update)
658
-                ? $espresso_db_update
659
-                : $this->fix_espresso_db_upgrade_option();
660
-            $this->_req_type = EE_System::detect_req_type_given_activation_history(
661
-                $espresso_db_update,
662
-                'ee_espresso_activation',
663
-                espresso_version()
664
-            );
665
-            $this->_major_version_change = $this->_detect_major_version_change($espresso_db_update);
666
-            $this->request->setIsActivation($this->_req_type !== EE_System::req_type_normal);
667
-        }
668
-        return $this->_req_type;
669
-    }
670
-
671
-
672
-    /**
673
-     * Returns whether or not there was a non-micro version change (ie, change in either
674
-     * the first or second number in the version. Eg 4.9.0.rc.001 to 4.10.0.rc.000,
675
-     * but not 4.9.0.rc.0001 to 4.9.1.rc.0001
676
-     *
677
-     * @param $activation_history
678
-     * @return bool
679
-     */
680
-    private function _detect_major_version_change($activation_history)
681
-    {
682
-        $previous_version = EE_System::_get_most_recently_active_version_from_activation_history($activation_history);
683
-        $previous_version_parts = explode('.', $previous_version);
684
-        $current_version_parts = explode('.', espresso_version());
685
-        return isset($previous_version_parts[0], $previous_version_parts[1], $current_version_parts[0], $current_version_parts[1])
686
-               && ($previous_version_parts[0] !== $current_version_parts[0]
687
-                   || $previous_version_parts[1] !== $current_version_parts[1]
688
-               );
689
-    }
690
-
691
-
692
-    /**
693
-     * Returns true if either the major or minor version of EE changed during this request.
694
-     * Eg 4.9.0.rc.001 to 4.10.0.rc.000, but not 4.9.0.rc.0001 to 4.9.1.rc.0001
695
-     *
696
-     * @return bool
697
-     */
698
-    public function is_major_version_change()
699
-    {
700
-        return $this->_major_version_change;
701
-    }
702
-
703
-
704
-    /**
705
-     * Determines the request type for any ee addon, given three piece of info: the current array of activation
706
-     * histories (for core that' 'espresso_db_update' wp option); the name of the WordPress option which is temporarily
707
-     * set upon activation of the plugin (for core it's 'ee_espresso_activation'); and the version that this plugin was
708
-     * just activated to (for core that will always be espresso_version())
709
-     *
710
-     * @param array  $activation_history_for_addon     the option's value which stores the activation history for this
711
-     *                                                 ee plugin. for core that's 'espresso_db_update'
712
-     * @param string $activation_indicator_option_name the name of the WordPress option that is temporarily set to
713
-     *                                                 indicate that this plugin was just activated
714
-     * @param string $version_to_upgrade_to            the version that was just upgraded to (for core that will be
715
-     *                                                 espresso_version())
716
-     * @return int one of the constants on EE_System::req_type_*
717
-     */
718
-    public static function detect_req_type_given_activation_history(
719
-        $activation_history_for_addon,
720
-        $activation_indicator_option_name,
721
-        $version_to_upgrade_to
722
-    ) {
723
-        $version_is_higher = self::_new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to);
724
-        if ($activation_history_for_addon) {
725
-            // it exists, so this isn't a completely new install
726
-            // check if this version already in that list of previously installed versions
727
-            if (! isset($activation_history_for_addon[ $version_to_upgrade_to ])) {
728
-                // it a version we haven't seen before
729
-                if ($version_is_higher === 1) {
730
-                    $req_type = EE_System::req_type_upgrade;
731
-                } else {
732
-                    $req_type = EE_System::req_type_downgrade;
733
-                }
734
-                delete_option($activation_indicator_option_name);
735
-            } else {
736
-                // its not an update. maybe a reactivation?
737
-                if (get_option($activation_indicator_option_name, false)) {
738
-                    if ($version_is_higher === -1) {
739
-                        $req_type = EE_System::req_type_downgrade;
740
-                    } elseif ($version_is_higher === 0) {
741
-                        // we've seen this version before, but it's an activation. must be a reactivation
742
-                        $req_type = EE_System::req_type_reactivation;
743
-                    } else {// $version_is_higher === 1
744
-                        $req_type = EE_System::req_type_upgrade;
745
-                    }
746
-                    delete_option($activation_indicator_option_name);
747
-                } else {
748
-                    // we've seen this version before and the activation indicate doesn't show it was just activated
749
-                    if ($version_is_higher === -1) {
750
-                        $req_type = EE_System::req_type_downgrade;
751
-                    } elseif ($version_is_higher === 0) {
752
-                        // we've seen this version before and it's not an activation. its normal request
753
-                        $req_type = EE_System::req_type_normal;
754
-                    } else {// $version_is_higher === 1
755
-                        $req_type = EE_System::req_type_upgrade;
756
-                    }
757
-                }
758
-            }
759
-        } else {
760
-            // brand new install
761
-            $req_type = EE_System::req_type_new_activation;
762
-            delete_option($activation_indicator_option_name);
763
-        }
764
-        return $req_type;
765
-    }
766
-
767
-
768
-    /**
769
-     * Detects if the $version_to_upgrade_to is higher than the most recent version in
770
-     * the $activation_history_for_addon
771
-     *
772
-     * @param array  $activation_history_for_addon (keys are versions, values are arrays of times activated,
773
-     *                                             sometimes containing 'unknown-date'
774
-     * @param string $version_to_upgrade_to        (current version)
775
-     * @return int results of version_compare( $version_to_upgrade_to, $most_recently_active_version ).
776
-     *                                             ie, -1 if $version_to_upgrade_to is LOWER (downgrade);
777
-     *                                             0 if $version_to_upgrade_to MATCHES (reactivation or normal request);
778
-     *                                             1 if $version_to_upgrade_to is HIGHER (upgrade) ;
779
-     */
780
-    private static function _new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to)
781
-    {
782
-        // find the most recently-activated version
783
-        $most_recently_active_version =
784
-            EE_System::_get_most_recently_active_version_from_activation_history($activation_history_for_addon);
785
-        return version_compare($version_to_upgrade_to, $most_recently_active_version);
786
-    }
787
-
788
-
789
-    /**
790
-     * Gets the most recently active version listed in the activation history,
791
-     * and if none are found (ie, it's a brand new install) returns '0.0.0.dev.000'.
792
-     *
793
-     * @param array $activation_history  (keys are versions, values are arrays of times activated,
794
-     *                                   sometimes containing 'unknown-date'
795
-     * @return string
796
-     */
797
-    private static function _get_most_recently_active_version_from_activation_history($activation_history)
798
-    {
799
-        $most_recently_active_version_activation = '1970-01-01 00:00:00';
800
-        $most_recently_active_version = '0.0.0.dev.000';
801
-        if (is_array($activation_history)) {
802
-            foreach ($activation_history as $version => $times_activated) {
803
-                // check there is a record of when this version was activated. Otherwise,
804
-                // mark it as unknown
805
-                if (! $times_activated) {
806
-                    $times_activated = array('unknown-date');
807
-                }
808
-                if (is_string($times_activated)) {
809
-                    $times_activated = array($times_activated);
810
-                }
811
-                foreach ($times_activated as $an_activation) {
812
-                    if (
813
-                        $an_activation !== 'unknown-date'
814
-                        && $an_activation
815
-                           > $most_recently_active_version_activation
816
-                    ) {
817
-                        $most_recently_active_version = $version;
818
-                        $most_recently_active_version_activation = $an_activation === 'unknown-date'
819
-                            ? '1970-01-01 00:00:00'
820
-                            : $an_activation;
821
-                    }
822
-                }
823
-            }
824
-        }
825
-        return $most_recently_active_version;
826
-    }
827
-
828
-
829
-    /**
830
-     * This redirects to the about EE page after activation
831
-     *
832
-     * @return void
833
-     */
834
-    public function redirect_to_about_ee()
835
-    {
836
-        $notices = EE_Error::get_notices(false);
837
-        // if current user is an admin and it's not an ajax or rest request
838
-        if (
839
-            ! isset($notices['errors'])
840
-            && $this->request->isAdmin()
841
-            && apply_filters(
842
-                'FHEE__EE_System__redirect_to_about_ee__do_redirect',
843
-                $this->capabilities->current_user_can('manage_options', 'espresso_about_default')
844
-            )
845
-        ) {
846
-            $query_params = array('page' => 'espresso_about');
847
-            if (EE_System::instance()->detect_req_type() === EE_System::req_type_new_activation) {
848
-                $query_params['new_activation'] = true;
849
-            }
850
-            if (EE_System::instance()->detect_req_type() === EE_System::req_type_reactivation) {
851
-                $query_params['reactivation'] = true;
852
-            }
853
-            $url = add_query_arg($query_params, admin_url('admin.php'));
854
-            wp_safe_redirect($url);
855
-            exit();
856
-        }
857
-    }
858
-
859
-
860
-    /**
861
-     * load_core_configuration
862
-     * this is hooked into 'AHEE__EE_Bootstrap__load_core_configuration'
863
-     * which runs during the WP 'plugins_loaded' action at priority 5
864
-     *
865
-     * @return void
866
-     * @throws ReflectionException
867
-     * @throws Exception
868
-     */
869
-    public function load_core_configuration()
870
-    {
871
-        do_action('AHEE__EE_System__load_core_configuration__begin', $this);
872
-        $this->loader->getShared('EE_Load_Textdomain');
873
-        // load textdomain
874
-        EE_Load_Textdomain::load_textdomain();
875
-        // load caf stuff a chance to play during the activation process too.
876
-        $this->_maybe_brew_regular();
877
-        // load and setup EE_Config and EE_Network_Config
878
-        $config = $this->loader->getShared('EE_Config');
879
-        $this->loader->getShared('EE_Network_Config');
880
-        // setup autoloaders
881
-        // enable logging?
882
-        if ($config->admin->use_remote_logging) {
883
-            $this->loader->getShared('EE_Log');
884
-        }
885
-        // check for activation errors
886
-        $activation_errors = get_option('ee_plugin_activation_errors', false);
887
-        if ($activation_errors) {
888
-            EE_Error::add_error($activation_errors, __FILE__, __FUNCTION__, __LINE__);
889
-            update_option('ee_plugin_activation_errors', false);
890
-        }
891
-        // get model names
892
-        $this->_parse_model_names();
893
-        // configure custom post type definitions
894
-        $this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions');
895
-        $this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions');
896
-        do_action('AHEE__EE_System__load_core_configuration__complete', $this);
897
-    }
898
-
899
-
900
-    /**
901
-     * cycles through all of the models/*.model.php files, and assembles an array of model names
902
-     *
903
-     * @return void
904
-     * @throws ReflectionException
905
-     */
906
-    private function _parse_model_names()
907
-    {
908
-        // get all the files in the EE_MODELS folder that end in .model.php
909
-        $models = glob(EE_MODELS . '*.model.php');
910
-        $model_names = array();
911
-        $non_abstract_db_models = array();
912
-        foreach ($models as $model) {
913
-            // get model classname
914
-            $classname = EEH_File::get_classname_from_filepath_with_standard_filename($model);
915
-            $short_name = str_replace('EEM_', '', $classname);
916
-            $reflectionClass = new ReflectionClass($classname);
917
-            if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
918
-                $non_abstract_db_models[ $short_name ] = $classname;
919
-            }
920
-            $model_names[ $short_name ] = $classname;
921
-        }
922
-        $this->registry->models = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
923
-        $this->registry->non_abstract_db_models = apply_filters(
924
-            'FHEE__EE_System__parse_implemented_model_names',
925
-            $non_abstract_db_models
926
-        );
927
-    }
928
-
929
-
930
-    /**
931
-     * The purpose of this method is to simply check for a file named "caffeinated/brewing_regular.php" for any hooks
932
-     * that need to be setup before our EE_System launches.
933
-     *
934
-     * @return void
935
-     * @throws DomainException
936
-     * @throws InvalidArgumentException
937
-     * @throws InvalidDataTypeException
938
-     * @throws InvalidInterfaceException
939
-     * @throws InvalidClassException
940
-     * @throws InvalidFilePathException
941
-     */
942
-    private function _maybe_brew_regular()
943
-    {
944
-        /** @var Domain $domain */
945
-        $domain = DomainFactory::getShared(
946
-            new FullyQualifiedName(
947
-                'EventEspresso\core\domain\Domain'
948
-            ),
949
-            array(
950
-                new FilePath(EVENT_ESPRESSO_MAIN_FILE),
951
-                Version::fromString(espresso_version()),
952
-            )
953
-        );
954
-        if ($domain->isCaffeinated()) {
955
-            require_once EE_CAFF_PATH . 'brewing_regular.php';
956
-        }
957
-    }
958
-
959
-
960
-    /**
961
-     * @since 4.9.71.p
962
-     * @throws Exception
963
-     */
964
-    public function loadRouteMatchSpecifications()
965
-    {
966
-        try {
967
-            $this->loader->getShared(
968
-                'EventEspresso\core\services\route_match\RouteMatchSpecificationManager'
969
-            );
970
-        } catch (Exception $exception) {
971
-            new ExceptionStackTraceDisplay($exception);
972
-        }
973
-        do_action('AHEE__EE_System__loadRouteMatchSpecifications');
974
-    }
975
-
976
-
977
-    /**
978
-     * loading CPT related classes earlier so that their definitions are available
979
-     * but not performing any actual registration with WP core until load_CPTs_and_session() is called
980
-     *
981
-     * @since   4.10.21.p
982
-     */
983
-    public function loadCustomPostTypes()
984
-    {
985
-        $this->register_custom_taxonomies = $this->loader->getShared(
986
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies'
987
-        );
988
-        $this->register_custom_post_types = $this->loader->getShared(
989
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes'
990
-        );
991
-        $this->register_custom_taxonomy_terms = $this->loader->getShared(
992
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms'
993
-        );
994
-        // integrate WP_Query with the EE models
995
-        $this->loader->getShared('EE_CPT_Strategy');
996
-        // load legacy EE_Request_Handler in case add-ons still need it
997
-        $this->loader->getShared('EE_Request_Handler');
998
-    }
999
-
1000
-
1001
-    /**
1002
-     * register_shortcodes_modules_and_widgets
1003
-     * generate lists of shortcodes and modules, then verify paths and classes
1004
-     * This is hooked into 'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets'
1005
-     * which runs during the WP 'plugins_loaded' action at priority 7
1006
-     *
1007
-     * @access public
1008
-     * @return void
1009
-     * @throws Exception
1010
-     */
1011
-    public function register_shortcodes_modules_and_widgets()
1012
-    {
1013
-        if ($this->request->isFrontend() || $this->request->isIframe() || $this->request->isAjax()) {
1014
-            // load, register, and add shortcodes the new way
1015
-            $this->loader->getShared('EventEspresso\core\services\shortcodes\ShortcodesManager');
1016
-        }
1017
-        do_action('AHEE__EE_System__register_shortcodes_modules_and_widgets');
1018
-        // check for addons using old hook point
1019
-        if (has_action('AHEE__EE_System__register_shortcodes_modules_and_addons')) {
1020
-            $this->_incompatible_addon_error();
1021
-        }
1022
-    }
1023
-
1024
-
1025
-    /**
1026
-     * _incompatible_addon_error
1027
-     *
1028
-     * @access public
1029
-     * @return void
1030
-     */
1031
-    private function _incompatible_addon_error()
1032
-    {
1033
-        // get array of classes hooking into here
1034
-        $class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook(
1035
-            'AHEE__EE_System__register_shortcodes_modules_and_addons'
1036
-        );
1037
-        if (! empty($class_names)) {
1038
-            $msg = esc_html__(
1039
-                'The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
1040
-                'event_espresso'
1041
-            );
1042
-            $msg .= '<ul>';
1043
-            foreach ($class_names as $class_name) {
1044
-                $msg .= '<li><b>Event Espresso - '
1045
-                        . str_replace(
1046
-                            array('EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'),
1047
-                            '',
1048
-                            $class_name
1049
-                        ) . '</b></li>';
1050
-            }
1051
-            $msg .= '</ul>';
1052
-            $msg .= esc_html__(
1053
-                'Compatibility issues can be avoided and/or resolved by keeping addons and plugins updated to the latest version.',
1054
-                'event_espresso'
1055
-            );
1056
-            // save list of incompatible addons to wp-options for later use
1057
-            add_option('ee_incompatible_addons', $class_names, '', 'no');
1058
-            if (is_admin()) {
1059
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1060
-            }
1061
-        }
1062
-    }
1063
-
1064
-
1065
-    /**
1066
-     * brew_espresso
1067
-     * begins the process of setting hooks for initializing EE in the correct order
1068
-     * This is happening on the 'AHEE__EE_Bootstrap__brew_espresso' hook point
1069
-     * which runs during the WP 'plugins_loaded' action at priority 9
1070
-     *
1071
-     * @return void
1072
-     */
1073
-    public function brew_espresso()
1074
-    {
1075
-        do_action('AHEE__EE_System__brew_espresso__begin', $this);
1076
-        // load some final core systems
1077
-        add_action('init', array($this, 'set_hooks_for_core'), 1);
1078
-        add_action('init', array($this, 'perform_activations_upgrades_and_migrations'), 3);
1079
-        add_action('init', array($this, 'load_CPTs_and_session'), 5);
1080
-        add_action('init', array($this, 'load_controllers'), 7);
1081
-        add_action('init', array($this, 'core_loaded_and_ready'), 9);
1082
-        add_action('init', array($this, 'initialize'), 10);
1083
-        add_action('init', array($this, 'initialize_last'), 100);
1084
-        if (is_admin() && apply_filters('FHEE__EE_System__brew_espresso__load_pue', true)) {
1085
-            // pew pew pew
1086
-            $this->loader->getShared('EventEspresso\core\services\licensing\LicenseService');
1087
-            do_action('AHEE__EE_System__brew_espresso__after_pue_init');
1088
-        }
1089
-        do_action('AHEE__EE_System__brew_espresso__complete', $this);
1090
-    }
1091
-
1092
-
1093
-    /**
1094
-     *    set_hooks_for_core
1095
-     *
1096
-     * @access public
1097
-     * @return    void
1098
-     * @throws EE_Error
1099
-     */
1100
-    public function set_hooks_for_core()
1101
-    {
1102
-        $this->_deactivate_incompatible_addons();
1103
-        do_action('AHEE__EE_System__set_hooks_for_core');
1104
-        $this->loader->getShared('EventEspresso\core\domain\values\session\SessionLifespan');
1105
-        // caps need to be initialized on every request so that capability maps are set.
1106
-        // @see https://events.codebasehq.com/projects/event-espresso/tickets/8674
1107
-        $this->registry->CAP->init_caps();
1108
-    }
1109
-
1110
-
1111
-    /**
1112
-     * Using the information gathered in EE_System::_incompatible_addon_error,
1113
-     * deactivates any addons considered incompatible with the current version of EE
1114
-     */
1115
-    private function _deactivate_incompatible_addons()
1116
-    {
1117
-        $incompatible_addons = get_option('ee_incompatible_addons', array());
1118
-        if (! empty($incompatible_addons)) {
1119
-            $active_plugins = get_option('active_plugins', array());
1120
-            foreach ($active_plugins as $active_plugin) {
1121
-                foreach ($incompatible_addons as $incompatible_addon) {
1122
-                    if (strpos($active_plugin, $incompatible_addon) !== false) {
1123
-                        $this->request->unSetRequestParams(['activate'], true);
1124
-                        espresso_deactivate_plugin($active_plugin);
1125
-                    }
1126
-                }
1127
-            }
1128
-        }
1129
-    }
1130
-
1131
-
1132
-    /**
1133
-     *    perform_activations_upgrades_and_migrations
1134
-     *
1135
-     * @access public
1136
-     * @return    void
1137
-     */
1138
-    public function perform_activations_upgrades_and_migrations()
1139
-    {
1140
-        do_action('AHEE__EE_System__perform_activations_upgrades_and_migrations');
1141
-    }
1142
-
1143
-
1144
-    /**
1145
-     * @return void
1146
-     * @throws DomainException
1147
-     */
1148
-    public function load_CPTs_and_session()
1149
-    {
1150
-        do_action('AHEE__EE_System__load_CPTs_and_session__start');
1151
-        $this->register_custom_taxonomies->registerCustomTaxonomies();
1152
-        $this->register_custom_post_types->registerCustomPostTypes();
1153
-        $this->register_custom_taxonomy_terms->registerCustomTaxonomyTerms();
1154
-        // load legacy Custom Post Types and Taxonomies
1155
-        $this->loader->getShared('EE_Register_CPTs');
1156
-        do_action('AHEE__EE_System__load_CPTs_and_session__complete');
1157
-    }
1158
-
1159
-
1160
-    /**
1161
-     * load_controllers
1162
-     * this is the best place to load any additional controllers that needs access to EE core.
1163
-     * it is expected that all basic core EE systems, that are not dependant on the current request are loaded at this
1164
-     * time
1165
-     *
1166
-     * @access public
1167
-     * @return void
1168
-     */
1169
-    public function load_controllers()
1170
-    {
1171
-        do_action('AHEE__EE_System__load_controllers__start');
1172
-        // let's get it started
1173
-        if (
1174
-            ! $this->maintenance_mode->level()
1175
-            && ($this->request->isFrontend() || $this->request->isFrontAjax())
1176
-        ) {
1177
-            do_action('AHEE__EE_System__load_controllers__load_front_controllers');
1178
-            $this->loader->getShared('EE_Front_Controller');
1179
-        } elseif ($this->request->isAdmin() || $this->request->isAdminAjax()) {
1180
-            do_action('AHEE__EE_System__load_controllers__load_admin_controllers');
1181
-            $this->loader->getShared('EE_Admin');
1182
-        } elseif ($this->request->isWordPressHeartbeat()) {
1183
-            $this->loader->getShared('EventEspresso\core\domain\services\admin\ajax\WordpressHeartbeat');
1184
-        }
1185
-        do_action('AHEE__EE_System__load_controllers__complete');
1186
-    }
1187
-
1188
-
1189
-    /**
1190
-     * core_loaded_and_ready
1191
-     * all of the basic EE core should be loaded at this point and available regardless of M-Mode
1192
-     *
1193
-     * @access public
1194
-     * @return void
1195
-     * @throws Exception
1196
-     */
1197
-    public function core_loaded_and_ready()
1198
-    {
1199
-        if (
1200
-            $this->request->isAdmin()
1201
-            || $this->request->isFrontend()
1202
-            || $this->request->isIframe()
1203
-            || $this->request->isWordPressApi()
1204
-        ) {
1205
-            try {
1206
-                $this->loader->getShared('EventEspresso\core\services\assets\Registry');
1207
-                $this->loader->getShared('EventEspresso\core\domain\services\assets\CoreAssetManager');
1208
-                if ($this->canLoadBlocks()) {
1209
-                    $this->loader->getShared(
1210
-                        'EventEspresso\core\services\editor\BlockRegistrationManager'
1211
-                    );
1212
-                }
1213
-            } catch (Exception $exception) {
1214
-                new ExceptionStackTraceDisplay($exception);
1215
-            }
1216
-        }
1217
-        if (
1218
-            $this->request->isAdmin()
1219
-            || $this->request->isEeAjax()
1220
-            || $this->request->isFrontend()
1221
-        ) {
1222
-            $this->loader->getShared('EE_Session');
1223
-        }
1224
-        do_action('AHEE__EE_System__core_loaded_and_ready');
1225
-        // always load template tags, because it's faster than checking if it's a front-end request, and many page
1226
-        // builders require these even on the front-end
1227
-        require_once EE_PUBLIC . 'template_tags.php';
1228
-        do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1229
-    }
1230
-
1231
-
1232
-    /**
1233
-     * initialize
1234
-     * this is the best place to begin initializing client code
1235
-     *
1236
-     * @access public
1237
-     * @return void
1238
-     */
1239
-    public function initialize()
1240
-    {
1241
-        do_action('AHEE__EE_System__initialize');
1242
-        add_filter(
1243
-            'safe_style_css',
1244
-            function ($styles) {
1245
-                $styles[] = 'display';
1246
-                $styles[] = 'visibility';
1247
-                return $styles;
1248
-            }
1249
-        );
1250
-    }
1251
-
1252
-
1253
-    /**
1254
-     * initialize_last
1255
-     * this is run really late during the WP init hook point, and ensures that mostly everything else that needs to
1256
-     * initialize has done so
1257
-     *
1258
-     * @access public
1259
-     * @return void
1260
-     */
1261
-    public function initialize_last()
1262
-    {
1263
-        do_action('AHEE__EE_System__initialize_last');
1264
-        /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
1265
-        $rewrite_rules = $this->loader->getShared(
1266
-            'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
1267
-        );
1268
-        $rewrite_rules->flushRewriteRules();
1269
-        add_action('admin_bar_init', array($this, 'addEspressoToolbar'));
1270
-        if (
1271
-            ($this->request->isAjax() || $this->request->isAdmin())
1272
-            && $this->maintenance_mode->models_can_query()
1273
-        ) {
1274
-            $this->loader->getShared('EventEspresso\core\services\privacy\export\PersonalDataExporterManager');
1275
-            $this->loader->getShared('EventEspresso\core\services\privacy\erasure\PersonalDataEraserManager');
1276
-        }
1277
-    }
1278
-
1279
-
1280
-    /**
1281
-     * @return void
1282
-     * @throws EE_Error
1283
-     */
1284
-    public function addEspressoToolbar()
1285
-    {
1286
-        $this->loader->getShared(
1287
-            'EventEspresso\core\domain\services\admin\AdminToolBar',
1288
-            array($this->registry->CAP)
1289
-        );
1290
-    }
1291
-
1292
-
1293
-    /**
1294
-     * do_not_cache
1295
-     * sets no cache headers and defines no cache constants for WP plugins
1296
-     *
1297
-     * @access public
1298
-     * @return void
1299
-     */
1300
-    public static function do_not_cache()
1301
-    {
1302
-        // set no cache constants
1303
-        if (! defined('DONOTCACHEPAGE')) {
1304
-            define('DONOTCACHEPAGE', true);
1305
-        }
1306
-        if (! defined('DONOTCACHCEOBJECT')) {
1307
-            define('DONOTCACHCEOBJECT', true);
1308
-        }
1309
-        if (! defined('DONOTCACHEDB')) {
1310
-            define('DONOTCACHEDB', true);
1311
-        }
1312
-        // add no cache headers
1313
-        add_action('send_headers', array('EE_System', 'nocache_headers'), 10);
1314
-        // plus a little extra for nginx and Google Chrome
1315
-        add_filter('nocache_headers', array('EE_System', 'extra_nocache_headers'), 10, 1);
1316
-        // prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes with the registration process
1317
-        remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
1318
-    }
1319
-
1320
-
1321
-    /**
1322
-     *    extra_nocache_headers
1323
-     *
1324
-     * @access    public
1325
-     * @param $headers
1326
-     * @return    array
1327
-     */
1328
-    public static function extra_nocache_headers($headers)
1329
-    {
1330
-        // for NGINX
1331
-        $headers['X-Accel-Expires'] = 0;
1332
-        // plus extra for Google Chrome since it doesn't seem to respect "no-cache", but WILL respect "no-store"
1333
-        $headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0';
1334
-        return $headers;
1335
-    }
1336
-
1337
-
1338
-    /**
1339
-     *    nocache_headers
1340
-     *
1341
-     * @access    public
1342
-     * @return    void
1343
-     */
1344
-    public static function nocache_headers()
1345
-    {
1346
-        nocache_headers();
1347
-    }
1348
-
1349
-
1350
-    /**
1351
-     * simply hooks into "wp_list_pages_exclude" filter (for wp_list_pages method) and makes sure EE critical pages are
1352
-     * never returned with the function.
1353
-     *
1354
-     * @param  array $exclude_array any existing pages being excluded are in this array.
1355
-     * @return array
1356
-     */
1357
-    public function remove_pages_from_wp_list_pages($exclude_array)
1358
-    {
1359
-        return array_merge($exclude_array, $this->registry->CFG->core->get_critical_pages_array());
1360
-    }
1361
-
1362
-
1363
-    /**
1364
-     * Return whether blocks can be registered/loaded or not.
1365
-     * @return bool
1366
-     */
1367
-    private function canLoadBlocks()
1368
-    {
1369
-        return apply_filters('FHEE__EE_System__canLoadBlocks', true)
1370
-               && function_exists('register_block_type')
1371
-               // don't load blocks if in the Divi page builder editor context
1372
-               // @see https://github.com/eventespresso/event-espresso-core/issues/814
1373
-               && ! $this->request->getRequestParam('et_fb', false);
1374
-    }
30
+	/**
31
+	 * indicates this is a 'normal' request. Ie, not activation, nor upgrade, nor activation.
32
+	 * So examples of this would be a normal GET request on the frontend or backend, or a POST, etc
33
+	 */
34
+	const req_type_normal = 0;
35
+
36
+	/**
37
+	 * Indicates this is a brand new installation of EE so we should install
38
+	 * tables and default data etc
39
+	 */
40
+	const req_type_new_activation = 1;
41
+
42
+	/**
43
+	 * we've detected that EE has been reactivated (or EE was activated during maintenance mode,
44
+	 * and we just exited maintenance mode). We MUST check the database is setup properly
45
+	 * and that default data is setup too
46
+	 */
47
+	const req_type_reactivation = 2;
48
+
49
+	/**
50
+	 * indicates that EE has been upgraded since its previous request.
51
+	 * We may have data migration scripts to call and will want to trigger maintenance mode
52
+	 */
53
+	const req_type_upgrade = 3;
54
+
55
+	/**
56
+	 * TODO  will detect that EE has been DOWNGRADED. We probably don't want to run in this case...
57
+	 */
58
+	const req_type_downgrade = 4;
59
+
60
+	/**
61
+	 * @deprecated since version 4.6.0.dev.006
62
+	 * Now whenever a new_activation is detected the request type is still just
63
+	 * new_activation (same for reactivation, upgrade, downgrade etc), but if we'r ein maintenance mode
64
+	 * EE_System::initialize_db_if_no_migrations_required and EE_Addon::initialize_db_if_no_migrations_required
65
+	 * will instead enqueue that EE plugin's db initialization for when we're taken out of maintenance mode.
66
+	 * (Specifically, when the migration manager indicates migrations are finished
67
+	 * EE_Data_Migration_Manager::initialize_db_for_enqueued_ee_plugins() will be called)
68
+	 */
69
+	const req_type_activation_but_not_installed = 5;
70
+
71
+	/**
72
+	 * option prefix for recording the activation history (like core's "espresso_db_update") of addons
73
+	 */
74
+	const addon_activation_history_option_prefix = 'ee_addon_activation_history_';
75
+
76
+	/**
77
+	 * @var EE_System $_instance
78
+	 */
79
+	private static $_instance;
80
+
81
+	/**
82
+	 * @var EE_Registry $registry
83
+	 */
84
+	private $registry;
85
+
86
+	/**
87
+	 * @var LoaderInterface $loader
88
+	 */
89
+	private $loader;
90
+
91
+	/**
92
+	 * @var EE_Capabilities $capabilities
93
+	 */
94
+	private $capabilities;
95
+
96
+	/**
97
+	 * @var RequestInterface $request
98
+	 */
99
+	private $request;
100
+
101
+	/**
102
+	 * @var EE_Maintenance_Mode $maintenance_mode
103
+	 */
104
+	private $maintenance_mode;
105
+
106
+	/**
107
+	 * Stores which type of request this is, options being one of the constants on EE_System starting with req_type_*.
108
+	 * It can be a brand-new activation, a reactivation, an upgrade, a downgrade, or a normal request.
109
+	 *
110
+	 * @var int $_req_type
111
+	 */
112
+	private $_req_type;
113
+
114
+	/**
115
+	 * Whether or not there was a non-micro version change in EE core version during this request
116
+	 *
117
+	 * @var boolean $_major_version_change
118
+	 */
119
+	private $_major_version_change = false;
120
+
121
+	/**
122
+	 * A Context DTO dedicated solely to identifying the current request type.
123
+	 *
124
+	 * @var RequestTypeContextCheckerInterface $request_type
125
+	 */
126
+	private $request_type;
127
+
128
+	/**
129
+	 * @param EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes
130
+	 */
131
+	private $register_custom_post_types;
132
+
133
+	/**
134
+	 * @param EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies
135
+	 */
136
+	private $register_custom_taxonomies;
137
+
138
+	/**
139
+	 * @param EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms
140
+	 */
141
+	private $register_custom_taxonomy_terms;
142
+
143
+	/**
144
+	 * @singleton method used to instantiate class object
145
+	 * @param EE_Registry|null         $registry
146
+	 * @param LoaderInterface|null     $loader
147
+	 * @param RequestInterface|null    $request
148
+	 * @param EE_Maintenance_Mode|null $maintenance_mode
149
+	 * @return EE_System
150
+	 */
151
+	public static function instance(
152
+		EE_Registry $registry = null,
153
+		LoaderInterface $loader = null,
154
+		RequestInterface $request = null,
155
+		EE_Maintenance_Mode $maintenance_mode = null
156
+	) {
157
+		// check if class object is instantiated
158
+		if (! self::$_instance instanceof EE_System) {
159
+			self::$_instance = new self($registry, $loader, $request, $maintenance_mode);
160
+		}
161
+		return self::$_instance;
162
+	}
163
+
164
+
165
+	/**
166
+	 * resets the instance and returns it
167
+	 *
168
+	 * @return EE_System
169
+	 */
170
+	public static function reset()
171
+	{
172
+		self::$_instance->_req_type = null;
173
+		// make sure none of the old hooks are left hanging around
174
+		remove_all_actions('AHEE__EE_System__perform_activations_upgrades_and_migrations');
175
+		// we need to reset the migration manager in order for it to detect DMSs properly
176
+		EE_Data_Migration_Manager::reset();
177
+		self::instance()->detect_activations_or_upgrades();
178
+		self::instance()->perform_activations_upgrades_and_migrations();
179
+		return self::instance();
180
+	}
181
+
182
+
183
+	/**
184
+	 * sets hooks for running rest of system
185
+	 * provides "AHEE__EE_System__construct__complete" hook for EE Addons to use as their starting point
186
+	 * starting EE Addons from any other point may lead to problems
187
+	 *
188
+	 * @param EE_Registry         $registry
189
+	 * @param LoaderInterface     $loader
190
+	 * @param RequestInterface    $request
191
+	 * @param EE_Maintenance_Mode $maintenance_mode
192
+	 */
193
+	private function __construct(
194
+		EE_Registry $registry,
195
+		LoaderInterface $loader,
196
+		RequestInterface $request,
197
+		EE_Maintenance_Mode $maintenance_mode
198
+	) {
199
+		$this->registry = $registry;
200
+		$this->loader = $loader;
201
+		$this->request = $request;
202
+		$this->maintenance_mode = $maintenance_mode;
203
+		do_action('AHEE__EE_System__construct__begin', $this);
204
+		add_action(
205
+			'AHEE__EE_Bootstrap__load_espresso_addons',
206
+			array($this, 'loadCapabilities'),
207
+			5
208
+		);
209
+		add_action(
210
+			'AHEE__EE_Bootstrap__load_espresso_addons',
211
+			array($this, 'loadCommandBus'),
212
+			7
213
+		);
214
+		add_action(
215
+			'AHEE__EE_Bootstrap__load_espresso_addons',
216
+			array($this, 'loadPluginApi'),
217
+			9
218
+		);
219
+		// allow addons to load first so that they can register autoloaders, set hooks for running DMS's, etc
220
+		add_action(
221
+			'AHEE__EE_Bootstrap__load_espresso_addons',
222
+			array($this, 'load_espresso_addons')
223
+		);
224
+		// when an ee addon is activated, we want to call the core hook(s) again
225
+		// because the newly-activated addon didn't get a chance to run at all
226
+		add_action('activate_plugin', array($this, 'load_espresso_addons'), 1);
227
+		// detect whether install or upgrade
228
+		add_action(
229
+			'AHEE__EE_Bootstrap__detect_activations_or_upgrades',
230
+			array($this, 'detect_activations_or_upgrades'),
231
+			3
232
+		);
233
+		// load EE_Config, EE_Textdomain, etc
234
+		add_action(
235
+			'AHEE__EE_Bootstrap__load_core_configuration',
236
+			array($this, 'load_core_configuration'),
237
+			5
238
+		);
239
+		// load specifications for matching routes to current request
240
+		add_action(
241
+			'AHEE__EE_Bootstrap__load_core_configuration',
242
+			array($this, 'loadRouteMatchSpecifications')
243
+		);
244
+		// load specifications for custom post types
245
+		add_action(
246
+			'AHEE__EE_Bootstrap__load_core_configuration',
247
+			array($this, 'loadCustomPostTypes')
248
+		);
249
+		// load EE_Config, EE_Textdomain, etc
250
+		add_action(
251
+			'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets',
252
+			array($this, 'register_shortcodes_modules_and_widgets'),
253
+			7
254
+		);
255
+		// you wanna get going? I wanna get going... let's get going!
256
+		add_action(
257
+			'AHEE__EE_Bootstrap__brew_espresso',
258
+			array($this, 'brew_espresso'),
259
+			9
260
+		);
261
+		// other housekeeping
262
+		// exclude EE critical pages from wp_list_pages
263
+		add_filter(
264
+			'wp_list_pages_excludes',
265
+			array($this, 'remove_pages_from_wp_list_pages'),
266
+			10
267
+		);
268
+		// ALL EE Addons should use the following hook point to attach their initial setup too
269
+		// it's extremely important for EE Addons to register any class autoloaders so that they can be available when the EE_Config loads
270
+		do_action('AHEE__EE_System__construct__complete', $this);
271
+	}
272
+
273
+
274
+	/**
275
+	 * load and setup EE_Capabilities
276
+	 *
277
+	 * @return void
278
+	 * @throws EE_Error
279
+	 */
280
+	public function loadCapabilities()
281
+	{
282
+		$this->capabilities = $this->loader->getShared('EE_Capabilities');
283
+		add_action(
284
+			'AHEE__EE_Capabilities__init_caps__before_initialization',
285
+			function () {
286
+				LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
287
+			}
288
+		);
289
+	}
290
+
291
+
292
+	/**
293
+	 * create and cache the CommandBus, and also add middleware
294
+	 * The CapChecker middleware requires the use of EE_Capabilities
295
+	 * which is why we need to load the CommandBus after Caps are set up
296
+	 *
297
+	 * @return void
298
+	 * @throws EE_Error
299
+	 */
300
+	public function loadCommandBus()
301
+	{
302
+		$this->loader->getShared(
303
+			'CommandBusInterface',
304
+			array(
305
+				null,
306
+				apply_filters(
307
+					'FHEE__EE_Load_Espresso_Core__handle_request__CommandBus_middleware',
308
+					array(
309
+						$this->loader->getShared('EventEspresso\core\services\commands\middleware\CapChecker'),
310
+						$this->loader->getShared('EventEspresso\core\services\commands\middleware\AddActionHook'),
311
+					)
312
+				),
313
+			)
314
+		);
315
+	}
316
+
317
+
318
+	/**
319
+	 * @return void
320
+	 * @throws EE_Error
321
+	 */
322
+	public function loadPluginApi()
323
+	{
324
+		// set autoloaders for all of the classes implementing EEI_Plugin_API
325
+		// which provide helpers for EE plugin authors to more easily register certain components with EE.
326
+		EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'plugin_api');
327
+	}
328
+
329
+
330
+	/**
331
+	 * @param string $addon_name
332
+	 * @param string $version_constant
333
+	 * @param string $min_version_required
334
+	 * @param string $load_callback
335
+	 * @param string $plugin_file_constant
336
+	 * @return void
337
+	 */
338
+	private function deactivateIncompatibleAddon(
339
+		$addon_name,
340
+		$version_constant,
341
+		$min_version_required,
342
+		$load_callback,
343
+		$plugin_file_constant
344
+	) {
345
+		if (! defined($version_constant)) {
346
+			return;
347
+		}
348
+		$addon_version = constant($version_constant);
349
+		if ($addon_version && version_compare($addon_version, $min_version_required, '<')) {
350
+			remove_action('AHEE__EE_System__load_espresso_addons', $load_callback);
351
+			if (! function_exists('deactivate_plugins')) {
352
+				require_once ABSPATH . 'wp-admin/includes/plugin.php';
353
+			}
354
+			deactivate_plugins(plugin_basename(constant($plugin_file_constant)));
355
+			$this->request->unSetRequestParams(['activate', 'activate-multi'], true);
356
+			EE_Error::add_error(
357
+				sprintf(
358
+					esc_html__(
359
+						'We\'re sorry, but the Event Espresso %1$s addon was deactivated because version %2$s or higher is required with this version of Event Espresso core.',
360
+						'event_espresso'
361
+					),
362
+					$addon_name,
363
+					$min_version_required
364
+				),
365
+				__FILE__,
366
+				__FUNCTION__ . "({$addon_name})",
367
+				__LINE__
368
+			);
369
+			EE_Error::get_notices(false, true);
370
+		}
371
+	}
372
+
373
+
374
+	/**
375
+	 * load_espresso_addons
376
+	 * allow addons to load first so that they can set hooks for running DMS's, etc
377
+	 * this is hooked into both:
378
+	 *    'AHEE__EE_Bootstrap__load_core_configuration'
379
+	 *        which runs during the WP 'plugins_loaded' action at priority 5
380
+	 *    and the WP 'activate_plugin' hook point
381
+	 *
382
+	 * @access public
383
+	 * @return void
384
+	 */
385
+	public function load_espresso_addons()
386
+	{
387
+		$this->deactivateIncompatibleAddon(
388
+			'Wait Lists',
389
+			'EE_WAIT_LISTS_VERSION',
390
+			'1.0.0.beta.074',
391
+			'load_espresso_wait_lists',
392
+			'EE_WAIT_LISTS_PLUGIN_FILE'
393
+		);
394
+		$this->deactivateIncompatibleAddon(
395
+			'Automated Upcoming Event Notifications',
396
+			'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_VERSION',
397
+			'1.0.0.beta.091',
398
+			'load_espresso_automated_upcoming_event_notification',
399
+			'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_PLUGIN_FILE'
400
+		);
401
+		do_action('AHEE__EE_System__load_espresso_addons');
402
+		// if the WP API basic auth plugin isn't already loaded, load it now.
403
+		// We want it for mobile apps. Just include the entire plugin
404
+		// also, don't load the basic auth when a plugin is getting activated, because
405
+		// it could be the basic auth plugin, and it doesn't check if its methods are already defined
406
+		// and causes a fatal error
407
+		if (
408
+			($this->request->isWordPressApi() || $this->request->isApi())
409
+			&& $this->request->getRequestParam('activate') !== 'true'
410
+			&& ! function_exists('json_basic_auth_handler')
411
+			&& ! function_exists('json_basic_auth_error')
412
+			&& ! in_array(
413
+				$this->request->getRequestParam('action'),
414
+				array('activate', 'activate-selected'),
415
+				true
416
+			)
417
+		) {
418
+			include_once EE_THIRD_PARTY . 'wp-api-basic-auth/basic-auth.php';
419
+		}
420
+		do_action('AHEE__EE_System__load_espresso_addons__complete');
421
+	}
422
+
423
+
424
+	/**
425
+	 * detect_activations_or_upgrades
426
+	 * Checks for activation or upgrade of core first;
427
+	 * then also checks if any registered addons have been activated or upgraded
428
+	 * This is hooked into 'AHEE__EE_Bootstrap__detect_activations_or_upgrades'
429
+	 * which runs during the WP 'plugins_loaded' action at priority 3
430
+	 *
431
+	 * @access public
432
+	 * @return void
433
+	 */
434
+	public function detect_activations_or_upgrades()
435
+	{
436
+		// first off: let's make sure to handle core
437
+		$this->detect_if_activation_or_upgrade();
438
+		foreach ($this->registry->addons as $addon) {
439
+			if ($addon instanceof EE_Addon) {
440
+				// detect teh request type for that addon
441
+				$addon->detect_req_type();
442
+			}
443
+		}
444
+	}
445
+
446
+
447
+	/**
448
+	 * detect_if_activation_or_upgrade
449
+	 * Takes care of detecting whether this is a brand new install or code upgrade,
450
+	 * and either setting up the DB or setting up maintenance mode etc.
451
+	 *
452
+	 * @access public
453
+	 * @return void
454
+	 */
455
+	public function detect_if_activation_or_upgrade()
456
+	{
457
+		do_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin');
458
+		// check if db has been updated, or if its a brand-new installation
459
+		$espresso_db_update = $this->fix_espresso_db_upgrade_option();
460
+		$request_type = $this->detect_req_type($espresso_db_update);
461
+		// EEH_Debug_Tools::printr( $request_type, '$request_type', __FILE__, __LINE__ );
462
+		switch ($request_type) {
463
+			case EE_System::req_type_new_activation:
464
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__new_activation');
465
+				$this->_handle_core_version_change($espresso_db_update);
466
+				break;
467
+			case EE_System::req_type_reactivation:
468
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__reactivation');
469
+				$this->_handle_core_version_change($espresso_db_update);
470
+				break;
471
+			case EE_System::req_type_upgrade:
472
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__upgrade');
473
+				// migrations may be required now that we've upgraded
474
+				$this->maintenance_mode->set_maintenance_mode_if_db_old();
475
+				$this->_handle_core_version_change($espresso_db_update);
476
+				break;
477
+			case EE_System::req_type_downgrade:
478
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__downgrade');
479
+				// its possible migrations are no longer required
480
+				$this->maintenance_mode->set_maintenance_mode_if_db_old();
481
+				$this->_handle_core_version_change($espresso_db_update);
482
+				break;
483
+			case EE_System::req_type_normal:
484
+			default:
485
+				break;
486
+		}
487
+		do_action('AHEE__EE_System__detect_if_activation_or_upgrade__complete');
488
+	}
489
+
490
+
491
+	/**
492
+	 * Updates the list of installed versions and sets hooks for
493
+	 * initializing the database later during the request
494
+	 *
495
+	 * @param array $espresso_db_update
496
+	 */
497
+	private function _handle_core_version_change($espresso_db_update)
498
+	{
499
+		$this->update_list_of_installed_versions($espresso_db_update);
500
+		// get ready to verify the DB is ok (provided we aren't in maintenance mode, of course)
501
+		add_action(
502
+			'AHEE__EE_System__perform_activations_upgrades_and_migrations',
503
+			array($this, 'initialize_db_if_no_migrations_required')
504
+		);
505
+	}
506
+
507
+
508
+	/**
509
+	 * standardizes the wp option 'espresso_db_upgrade' which actually stores
510
+	 * information about what versions of EE have been installed and activated,
511
+	 * NOT necessarily the state of the database
512
+	 *
513
+	 * @param mixed $espresso_db_update           the value of the WordPress option.
514
+	 *                                            If not supplied, fetches it from the options table
515
+	 * @return array the correct value of 'espresso_db_upgrade', after saving it, if it needed correction
516
+	 */
517
+	private function fix_espresso_db_upgrade_option($espresso_db_update = null)
518
+	{
519
+		do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
520
+		if (! $espresso_db_update) {
521
+			$espresso_db_update = get_option('espresso_db_update');
522
+		}
523
+		// check that option is an array
524
+		if (! is_array($espresso_db_update)) {
525
+			// if option is FALSE, then it never existed
526
+			if ($espresso_db_update === false) {
527
+				// make $espresso_db_update an array and save option with autoload OFF
528
+				$espresso_db_update = array();
529
+				add_option('espresso_db_update', $espresso_db_update, '', 'no');
530
+			} else {
531
+				// option is NOT FALSE but also is NOT an array, so make it an array and save it
532
+				$espresso_db_update = array($espresso_db_update => array());
533
+				update_option('espresso_db_update', $espresso_db_update);
534
+			}
535
+		} else {
536
+			$corrected_db_update = array();
537
+			// if IS an array, but is it an array where KEYS are version numbers, and values are arrays?
538
+			foreach ($espresso_db_update as $should_be_version_string => $should_be_array) {
539
+				if (is_int($should_be_version_string) && ! is_array($should_be_array)) {
540
+					// the key is an int, and the value IS NOT an array
541
+					// so it must be numerically-indexed, where values are versions installed...
542
+					// fix it!
543
+					$version_string = $should_be_array;
544
+					$corrected_db_update[ $version_string ] = array('unknown-date');
545
+				} else {
546
+					// ok it checks out
547
+					$corrected_db_update[ $should_be_version_string ] = $should_be_array;
548
+				}
549
+			}
550
+			$espresso_db_update = $corrected_db_update;
551
+			update_option('espresso_db_update', $espresso_db_update);
552
+		}
553
+		do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__complete', $espresso_db_update);
554
+		return $espresso_db_update;
555
+	}
556
+
557
+
558
+	/**
559
+	 * Does the traditional work of setting up the plugin's database and adding default data.
560
+	 * If migration script/process did not exist, this is what would happen on every activation/reactivation/upgrade.
561
+	 * NOTE: if we're in maintenance mode (which would be the case if we detect there are data
562
+	 * migration scripts that need to be run and a version change happens), enqueues core for database initialization,
563
+	 * so that it will be done when migrations are finished
564
+	 *
565
+	 * @param boolean $initialize_addons_too if true, we double-check addons' database tables etc too;
566
+	 * @param boolean $verify_schema         if true will re-check the database tables have the correct schema.
567
+	 *                                       This is a resource-intensive job
568
+	 *                                       so we prefer to only do it when necessary
569
+	 * @return void
570
+	 * @throws EE_Error
571
+	 */
572
+	public function initialize_db_if_no_migrations_required($initialize_addons_too = false, $verify_schema = true)
573
+	{
574
+		$request_type = $this->detect_req_type();
575
+		// only initialize system if we're not in maintenance mode.
576
+		if ($this->maintenance_mode->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
577
+			/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
578
+			$rewrite_rules = $this->loader->getShared(
579
+				'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
580
+			);
581
+			$rewrite_rules->flush();
582
+			if ($verify_schema) {
583
+				EEH_Activation::initialize_db_and_folders();
584
+			}
585
+			EEH_Activation::initialize_db_content();
586
+			EEH_Activation::system_initialization();
587
+			if ($initialize_addons_too) {
588
+				$this->initialize_addons();
589
+			}
590
+		} else {
591
+			EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for('Core');
592
+		}
593
+		if (
594
+			$request_type === EE_System::req_type_new_activation
595
+			|| $request_type === EE_System::req_type_reactivation
596
+			|| (
597
+				$request_type === EE_System::req_type_upgrade
598
+				&& $this->is_major_version_change()
599
+			)
600
+		) {
601
+			add_action('AHEE__EE_System__initialize_last', array($this, 'redirect_to_about_ee'), 9);
602
+		}
603
+	}
604
+
605
+
606
+	/**
607
+	 * Initializes the db for all registered addons
608
+	 *
609
+	 * @throws EE_Error
610
+	 */
611
+	public function initialize_addons()
612
+	{
613
+		// foreach registered addon, make sure its db is up-to-date too
614
+		foreach ($this->registry->addons as $addon) {
615
+			if ($addon instanceof EE_Addon) {
616
+				$addon->initialize_db_if_no_migrations_required();
617
+			}
618
+		}
619
+	}
620
+
621
+
622
+	/**
623
+	 * Adds the current code version to the saved wp option which stores a list of all ee versions ever installed.
624
+	 *
625
+	 * @param    array  $version_history
626
+	 * @param    string $current_version_to_add version to be added to the version history
627
+	 * @return    boolean success as to whether or not this option was changed
628
+	 */
629
+	public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
630
+	{
631
+		if (! $version_history) {
632
+			$version_history = $this->fix_espresso_db_upgrade_option($version_history);
633
+		}
634
+		if ($current_version_to_add === null) {
635
+			$current_version_to_add = espresso_version();
636
+		}
637
+		$version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
638
+		// re-save
639
+		return update_option('espresso_db_update', $version_history);
640
+	}
641
+
642
+
643
+	/**
644
+	 * Detects if the current version indicated in the has existed in the list of
645
+	 * previously-installed versions of EE (espresso_db_update). Does NOT modify it (ie, no side-effect)
646
+	 *
647
+	 * @param array $espresso_db_update array from the wp option stored under the name 'espresso_db_update'.
648
+	 *                                  If not supplied, fetches it from the options table.
649
+	 *                                  Also, caches its result so later parts of the code can also know whether
650
+	 *                                  there's been an update or not. This way we can add the current version to
651
+	 *                                  espresso_db_update, but still know if this is a new install or not
652
+	 * @return int one of the constants on EE_System::req_type_
653
+	 */
654
+	public function detect_req_type($espresso_db_update = null)
655
+	{
656
+		if ($this->_req_type === null) {
657
+			$espresso_db_update = ! empty($espresso_db_update)
658
+				? $espresso_db_update
659
+				: $this->fix_espresso_db_upgrade_option();
660
+			$this->_req_type = EE_System::detect_req_type_given_activation_history(
661
+				$espresso_db_update,
662
+				'ee_espresso_activation',
663
+				espresso_version()
664
+			);
665
+			$this->_major_version_change = $this->_detect_major_version_change($espresso_db_update);
666
+			$this->request->setIsActivation($this->_req_type !== EE_System::req_type_normal);
667
+		}
668
+		return $this->_req_type;
669
+	}
670
+
671
+
672
+	/**
673
+	 * Returns whether or not there was a non-micro version change (ie, change in either
674
+	 * the first or second number in the version. Eg 4.9.0.rc.001 to 4.10.0.rc.000,
675
+	 * but not 4.9.0.rc.0001 to 4.9.1.rc.0001
676
+	 *
677
+	 * @param $activation_history
678
+	 * @return bool
679
+	 */
680
+	private function _detect_major_version_change($activation_history)
681
+	{
682
+		$previous_version = EE_System::_get_most_recently_active_version_from_activation_history($activation_history);
683
+		$previous_version_parts = explode('.', $previous_version);
684
+		$current_version_parts = explode('.', espresso_version());
685
+		return isset($previous_version_parts[0], $previous_version_parts[1], $current_version_parts[0], $current_version_parts[1])
686
+			   && ($previous_version_parts[0] !== $current_version_parts[0]
687
+				   || $previous_version_parts[1] !== $current_version_parts[1]
688
+			   );
689
+	}
690
+
691
+
692
+	/**
693
+	 * Returns true if either the major or minor version of EE changed during this request.
694
+	 * Eg 4.9.0.rc.001 to 4.10.0.rc.000, but not 4.9.0.rc.0001 to 4.9.1.rc.0001
695
+	 *
696
+	 * @return bool
697
+	 */
698
+	public function is_major_version_change()
699
+	{
700
+		return $this->_major_version_change;
701
+	}
702
+
703
+
704
+	/**
705
+	 * Determines the request type for any ee addon, given three piece of info: the current array of activation
706
+	 * histories (for core that' 'espresso_db_update' wp option); the name of the WordPress option which is temporarily
707
+	 * set upon activation of the plugin (for core it's 'ee_espresso_activation'); and the version that this plugin was
708
+	 * just activated to (for core that will always be espresso_version())
709
+	 *
710
+	 * @param array  $activation_history_for_addon     the option's value which stores the activation history for this
711
+	 *                                                 ee plugin. for core that's 'espresso_db_update'
712
+	 * @param string $activation_indicator_option_name the name of the WordPress option that is temporarily set to
713
+	 *                                                 indicate that this plugin was just activated
714
+	 * @param string $version_to_upgrade_to            the version that was just upgraded to (for core that will be
715
+	 *                                                 espresso_version())
716
+	 * @return int one of the constants on EE_System::req_type_*
717
+	 */
718
+	public static function detect_req_type_given_activation_history(
719
+		$activation_history_for_addon,
720
+		$activation_indicator_option_name,
721
+		$version_to_upgrade_to
722
+	) {
723
+		$version_is_higher = self::_new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to);
724
+		if ($activation_history_for_addon) {
725
+			// it exists, so this isn't a completely new install
726
+			// check if this version already in that list of previously installed versions
727
+			if (! isset($activation_history_for_addon[ $version_to_upgrade_to ])) {
728
+				// it a version we haven't seen before
729
+				if ($version_is_higher === 1) {
730
+					$req_type = EE_System::req_type_upgrade;
731
+				} else {
732
+					$req_type = EE_System::req_type_downgrade;
733
+				}
734
+				delete_option($activation_indicator_option_name);
735
+			} else {
736
+				// its not an update. maybe a reactivation?
737
+				if (get_option($activation_indicator_option_name, false)) {
738
+					if ($version_is_higher === -1) {
739
+						$req_type = EE_System::req_type_downgrade;
740
+					} elseif ($version_is_higher === 0) {
741
+						// we've seen this version before, but it's an activation. must be a reactivation
742
+						$req_type = EE_System::req_type_reactivation;
743
+					} else {// $version_is_higher === 1
744
+						$req_type = EE_System::req_type_upgrade;
745
+					}
746
+					delete_option($activation_indicator_option_name);
747
+				} else {
748
+					// we've seen this version before and the activation indicate doesn't show it was just activated
749
+					if ($version_is_higher === -1) {
750
+						$req_type = EE_System::req_type_downgrade;
751
+					} elseif ($version_is_higher === 0) {
752
+						// we've seen this version before and it's not an activation. its normal request
753
+						$req_type = EE_System::req_type_normal;
754
+					} else {// $version_is_higher === 1
755
+						$req_type = EE_System::req_type_upgrade;
756
+					}
757
+				}
758
+			}
759
+		} else {
760
+			// brand new install
761
+			$req_type = EE_System::req_type_new_activation;
762
+			delete_option($activation_indicator_option_name);
763
+		}
764
+		return $req_type;
765
+	}
766
+
767
+
768
+	/**
769
+	 * Detects if the $version_to_upgrade_to is higher than the most recent version in
770
+	 * the $activation_history_for_addon
771
+	 *
772
+	 * @param array  $activation_history_for_addon (keys are versions, values are arrays of times activated,
773
+	 *                                             sometimes containing 'unknown-date'
774
+	 * @param string $version_to_upgrade_to        (current version)
775
+	 * @return int results of version_compare( $version_to_upgrade_to, $most_recently_active_version ).
776
+	 *                                             ie, -1 if $version_to_upgrade_to is LOWER (downgrade);
777
+	 *                                             0 if $version_to_upgrade_to MATCHES (reactivation or normal request);
778
+	 *                                             1 if $version_to_upgrade_to is HIGHER (upgrade) ;
779
+	 */
780
+	private static function _new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to)
781
+	{
782
+		// find the most recently-activated version
783
+		$most_recently_active_version =
784
+			EE_System::_get_most_recently_active_version_from_activation_history($activation_history_for_addon);
785
+		return version_compare($version_to_upgrade_to, $most_recently_active_version);
786
+	}
787
+
788
+
789
+	/**
790
+	 * Gets the most recently active version listed in the activation history,
791
+	 * and if none are found (ie, it's a brand new install) returns '0.0.0.dev.000'.
792
+	 *
793
+	 * @param array $activation_history  (keys are versions, values are arrays of times activated,
794
+	 *                                   sometimes containing 'unknown-date'
795
+	 * @return string
796
+	 */
797
+	private static function _get_most_recently_active_version_from_activation_history($activation_history)
798
+	{
799
+		$most_recently_active_version_activation = '1970-01-01 00:00:00';
800
+		$most_recently_active_version = '0.0.0.dev.000';
801
+		if (is_array($activation_history)) {
802
+			foreach ($activation_history as $version => $times_activated) {
803
+				// check there is a record of when this version was activated. Otherwise,
804
+				// mark it as unknown
805
+				if (! $times_activated) {
806
+					$times_activated = array('unknown-date');
807
+				}
808
+				if (is_string($times_activated)) {
809
+					$times_activated = array($times_activated);
810
+				}
811
+				foreach ($times_activated as $an_activation) {
812
+					if (
813
+						$an_activation !== 'unknown-date'
814
+						&& $an_activation
815
+						   > $most_recently_active_version_activation
816
+					) {
817
+						$most_recently_active_version = $version;
818
+						$most_recently_active_version_activation = $an_activation === 'unknown-date'
819
+							? '1970-01-01 00:00:00'
820
+							: $an_activation;
821
+					}
822
+				}
823
+			}
824
+		}
825
+		return $most_recently_active_version;
826
+	}
827
+
828
+
829
+	/**
830
+	 * This redirects to the about EE page after activation
831
+	 *
832
+	 * @return void
833
+	 */
834
+	public function redirect_to_about_ee()
835
+	{
836
+		$notices = EE_Error::get_notices(false);
837
+		// if current user is an admin and it's not an ajax or rest request
838
+		if (
839
+			! isset($notices['errors'])
840
+			&& $this->request->isAdmin()
841
+			&& apply_filters(
842
+				'FHEE__EE_System__redirect_to_about_ee__do_redirect',
843
+				$this->capabilities->current_user_can('manage_options', 'espresso_about_default')
844
+			)
845
+		) {
846
+			$query_params = array('page' => 'espresso_about');
847
+			if (EE_System::instance()->detect_req_type() === EE_System::req_type_new_activation) {
848
+				$query_params['new_activation'] = true;
849
+			}
850
+			if (EE_System::instance()->detect_req_type() === EE_System::req_type_reactivation) {
851
+				$query_params['reactivation'] = true;
852
+			}
853
+			$url = add_query_arg($query_params, admin_url('admin.php'));
854
+			wp_safe_redirect($url);
855
+			exit();
856
+		}
857
+	}
858
+
859
+
860
+	/**
861
+	 * load_core_configuration
862
+	 * this is hooked into 'AHEE__EE_Bootstrap__load_core_configuration'
863
+	 * which runs during the WP 'plugins_loaded' action at priority 5
864
+	 *
865
+	 * @return void
866
+	 * @throws ReflectionException
867
+	 * @throws Exception
868
+	 */
869
+	public function load_core_configuration()
870
+	{
871
+		do_action('AHEE__EE_System__load_core_configuration__begin', $this);
872
+		$this->loader->getShared('EE_Load_Textdomain');
873
+		// load textdomain
874
+		EE_Load_Textdomain::load_textdomain();
875
+		// load caf stuff a chance to play during the activation process too.
876
+		$this->_maybe_brew_regular();
877
+		// load and setup EE_Config and EE_Network_Config
878
+		$config = $this->loader->getShared('EE_Config');
879
+		$this->loader->getShared('EE_Network_Config');
880
+		// setup autoloaders
881
+		// enable logging?
882
+		if ($config->admin->use_remote_logging) {
883
+			$this->loader->getShared('EE_Log');
884
+		}
885
+		// check for activation errors
886
+		$activation_errors = get_option('ee_plugin_activation_errors', false);
887
+		if ($activation_errors) {
888
+			EE_Error::add_error($activation_errors, __FILE__, __FUNCTION__, __LINE__);
889
+			update_option('ee_plugin_activation_errors', false);
890
+		}
891
+		// get model names
892
+		$this->_parse_model_names();
893
+		// configure custom post type definitions
894
+		$this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions');
895
+		$this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions');
896
+		do_action('AHEE__EE_System__load_core_configuration__complete', $this);
897
+	}
898
+
899
+
900
+	/**
901
+	 * cycles through all of the models/*.model.php files, and assembles an array of model names
902
+	 *
903
+	 * @return void
904
+	 * @throws ReflectionException
905
+	 */
906
+	private function _parse_model_names()
907
+	{
908
+		// get all the files in the EE_MODELS folder that end in .model.php
909
+		$models = glob(EE_MODELS . '*.model.php');
910
+		$model_names = array();
911
+		$non_abstract_db_models = array();
912
+		foreach ($models as $model) {
913
+			// get model classname
914
+			$classname = EEH_File::get_classname_from_filepath_with_standard_filename($model);
915
+			$short_name = str_replace('EEM_', '', $classname);
916
+			$reflectionClass = new ReflectionClass($classname);
917
+			if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
918
+				$non_abstract_db_models[ $short_name ] = $classname;
919
+			}
920
+			$model_names[ $short_name ] = $classname;
921
+		}
922
+		$this->registry->models = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
923
+		$this->registry->non_abstract_db_models = apply_filters(
924
+			'FHEE__EE_System__parse_implemented_model_names',
925
+			$non_abstract_db_models
926
+		);
927
+	}
928
+
929
+
930
+	/**
931
+	 * The purpose of this method is to simply check for a file named "caffeinated/brewing_regular.php" for any hooks
932
+	 * that need to be setup before our EE_System launches.
933
+	 *
934
+	 * @return void
935
+	 * @throws DomainException
936
+	 * @throws InvalidArgumentException
937
+	 * @throws InvalidDataTypeException
938
+	 * @throws InvalidInterfaceException
939
+	 * @throws InvalidClassException
940
+	 * @throws InvalidFilePathException
941
+	 */
942
+	private function _maybe_brew_regular()
943
+	{
944
+		/** @var Domain $domain */
945
+		$domain = DomainFactory::getShared(
946
+			new FullyQualifiedName(
947
+				'EventEspresso\core\domain\Domain'
948
+			),
949
+			array(
950
+				new FilePath(EVENT_ESPRESSO_MAIN_FILE),
951
+				Version::fromString(espresso_version()),
952
+			)
953
+		);
954
+		if ($domain->isCaffeinated()) {
955
+			require_once EE_CAFF_PATH . 'brewing_regular.php';
956
+		}
957
+	}
958
+
959
+
960
+	/**
961
+	 * @since 4.9.71.p
962
+	 * @throws Exception
963
+	 */
964
+	public function loadRouteMatchSpecifications()
965
+	{
966
+		try {
967
+			$this->loader->getShared(
968
+				'EventEspresso\core\services\route_match\RouteMatchSpecificationManager'
969
+			);
970
+		} catch (Exception $exception) {
971
+			new ExceptionStackTraceDisplay($exception);
972
+		}
973
+		do_action('AHEE__EE_System__loadRouteMatchSpecifications');
974
+	}
975
+
976
+
977
+	/**
978
+	 * loading CPT related classes earlier so that their definitions are available
979
+	 * but not performing any actual registration with WP core until load_CPTs_and_session() is called
980
+	 *
981
+	 * @since   4.10.21.p
982
+	 */
983
+	public function loadCustomPostTypes()
984
+	{
985
+		$this->register_custom_taxonomies = $this->loader->getShared(
986
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies'
987
+		);
988
+		$this->register_custom_post_types = $this->loader->getShared(
989
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes'
990
+		);
991
+		$this->register_custom_taxonomy_terms = $this->loader->getShared(
992
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms'
993
+		);
994
+		// integrate WP_Query with the EE models
995
+		$this->loader->getShared('EE_CPT_Strategy');
996
+		// load legacy EE_Request_Handler in case add-ons still need it
997
+		$this->loader->getShared('EE_Request_Handler');
998
+	}
999
+
1000
+
1001
+	/**
1002
+	 * register_shortcodes_modules_and_widgets
1003
+	 * generate lists of shortcodes and modules, then verify paths and classes
1004
+	 * This is hooked into 'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets'
1005
+	 * which runs during the WP 'plugins_loaded' action at priority 7
1006
+	 *
1007
+	 * @access public
1008
+	 * @return void
1009
+	 * @throws Exception
1010
+	 */
1011
+	public function register_shortcodes_modules_and_widgets()
1012
+	{
1013
+		if ($this->request->isFrontend() || $this->request->isIframe() || $this->request->isAjax()) {
1014
+			// load, register, and add shortcodes the new way
1015
+			$this->loader->getShared('EventEspresso\core\services\shortcodes\ShortcodesManager');
1016
+		}
1017
+		do_action('AHEE__EE_System__register_shortcodes_modules_and_widgets');
1018
+		// check for addons using old hook point
1019
+		if (has_action('AHEE__EE_System__register_shortcodes_modules_and_addons')) {
1020
+			$this->_incompatible_addon_error();
1021
+		}
1022
+	}
1023
+
1024
+
1025
+	/**
1026
+	 * _incompatible_addon_error
1027
+	 *
1028
+	 * @access public
1029
+	 * @return void
1030
+	 */
1031
+	private function _incompatible_addon_error()
1032
+	{
1033
+		// get array of classes hooking into here
1034
+		$class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook(
1035
+			'AHEE__EE_System__register_shortcodes_modules_and_addons'
1036
+		);
1037
+		if (! empty($class_names)) {
1038
+			$msg = esc_html__(
1039
+				'The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
1040
+				'event_espresso'
1041
+			);
1042
+			$msg .= '<ul>';
1043
+			foreach ($class_names as $class_name) {
1044
+				$msg .= '<li><b>Event Espresso - '
1045
+						. str_replace(
1046
+							array('EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'),
1047
+							'',
1048
+							$class_name
1049
+						) . '</b></li>';
1050
+			}
1051
+			$msg .= '</ul>';
1052
+			$msg .= esc_html__(
1053
+				'Compatibility issues can be avoided and/or resolved by keeping addons and plugins updated to the latest version.',
1054
+				'event_espresso'
1055
+			);
1056
+			// save list of incompatible addons to wp-options for later use
1057
+			add_option('ee_incompatible_addons', $class_names, '', 'no');
1058
+			if (is_admin()) {
1059
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1060
+			}
1061
+		}
1062
+	}
1063
+
1064
+
1065
+	/**
1066
+	 * brew_espresso
1067
+	 * begins the process of setting hooks for initializing EE in the correct order
1068
+	 * This is happening on the 'AHEE__EE_Bootstrap__brew_espresso' hook point
1069
+	 * which runs during the WP 'plugins_loaded' action at priority 9
1070
+	 *
1071
+	 * @return void
1072
+	 */
1073
+	public function brew_espresso()
1074
+	{
1075
+		do_action('AHEE__EE_System__brew_espresso__begin', $this);
1076
+		// load some final core systems
1077
+		add_action('init', array($this, 'set_hooks_for_core'), 1);
1078
+		add_action('init', array($this, 'perform_activations_upgrades_and_migrations'), 3);
1079
+		add_action('init', array($this, 'load_CPTs_and_session'), 5);
1080
+		add_action('init', array($this, 'load_controllers'), 7);
1081
+		add_action('init', array($this, 'core_loaded_and_ready'), 9);
1082
+		add_action('init', array($this, 'initialize'), 10);
1083
+		add_action('init', array($this, 'initialize_last'), 100);
1084
+		if (is_admin() && apply_filters('FHEE__EE_System__brew_espresso__load_pue', true)) {
1085
+			// pew pew pew
1086
+			$this->loader->getShared('EventEspresso\core\services\licensing\LicenseService');
1087
+			do_action('AHEE__EE_System__brew_espresso__after_pue_init');
1088
+		}
1089
+		do_action('AHEE__EE_System__brew_espresso__complete', $this);
1090
+	}
1091
+
1092
+
1093
+	/**
1094
+	 *    set_hooks_for_core
1095
+	 *
1096
+	 * @access public
1097
+	 * @return    void
1098
+	 * @throws EE_Error
1099
+	 */
1100
+	public function set_hooks_for_core()
1101
+	{
1102
+		$this->_deactivate_incompatible_addons();
1103
+		do_action('AHEE__EE_System__set_hooks_for_core');
1104
+		$this->loader->getShared('EventEspresso\core\domain\values\session\SessionLifespan');
1105
+		// caps need to be initialized on every request so that capability maps are set.
1106
+		// @see https://events.codebasehq.com/projects/event-espresso/tickets/8674
1107
+		$this->registry->CAP->init_caps();
1108
+	}
1109
+
1110
+
1111
+	/**
1112
+	 * Using the information gathered in EE_System::_incompatible_addon_error,
1113
+	 * deactivates any addons considered incompatible with the current version of EE
1114
+	 */
1115
+	private function _deactivate_incompatible_addons()
1116
+	{
1117
+		$incompatible_addons = get_option('ee_incompatible_addons', array());
1118
+		if (! empty($incompatible_addons)) {
1119
+			$active_plugins = get_option('active_plugins', array());
1120
+			foreach ($active_plugins as $active_plugin) {
1121
+				foreach ($incompatible_addons as $incompatible_addon) {
1122
+					if (strpos($active_plugin, $incompatible_addon) !== false) {
1123
+						$this->request->unSetRequestParams(['activate'], true);
1124
+						espresso_deactivate_plugin($active_plugin);
1125
+					}
1126
+				}
1127
+			}
1128
+		}
1129
+	}
1130
+
1131
+
1132
+	/**
1133
+	 *    perform_activations_upgrades_and_migrations
1134
+	 *
1135
+	 * @access public
1136
+	 * @return    void
1137
+	 */
1138
+	public function perform_activations_upgrades_and_migrations()
1139
+	{
1140
+		do_action('AHEE__EE_System__perform_activations_upgrades_and_migrations');
1141
+	}
1142
+
1143
+
1144
+	/**
1145
+	 * @return void
1146
+	 * @throws DomainException
1147
+	 */
1148
+	public function load_CPTs_and_session()
1149
+	{
1150
+		do_action('AHEE__EE_System__load_CPTs_and_session__start');
1151
+		$this->register_custom_taxonomies->registerCustomTaxonomies();
1152
+		$this->register_custom_post_types->registerCustomPostTypes();
1153
+		$this->register_custom_taxonomy_terms->registerCustomTaxonomyTerms();
1154
+		// load legacy Custom Post Types and Taxonomies
1155
+		$this->loader->getShared('EE_Register_CPTs');
1156
+		do_action('AHEE__EE_System__load_CPTs_and_session__complete');
1157
+	}
1158
+
1159
+
1160
+	/**
1161
+	 * load_controllers
1162
+	 * this is the best place to load any additional controllers that needs access to EE core.
1163
+	 * it is expected that all basic core EE systems, that are not dependant on the current request are loaded at this
1164
+	 * time
1165
+	 *
1166
+	 * @access public
1167
+	 * @return void
1168
+	 */
1169
+	public function load_controllers()
1170
+	{
1171
+		do_action('AHEE__EE_System__load_controllers__start');
1172
+		// let's get it started
1173
+		if (
1174
+			! $this->maintenance_mode->level()
1175
+			&& ($this->request->isFrontend() || $this->request->isFrontAjax())
1176
+		) {
1177
+			do_action('AHEE__EE_System__load_controllers__load_front_controllers');
1178
+			$this->loader->getShared('EE_Front_Controller');
1179
+		} elseif ($this->request->isAdmin() || $this->request->isAdminAjax()) {
1180
+			do_action('AHEE__EE_System__load_controllers__load_admin_controllers');
1181
+			$this->loader->getShared('EE_Admin');
1182
+		} elseif ($this->request->isWordPressHeartbeat()) {
1183
+			$this->loader->getShared('EventEspresso\core\domain\services\admin\ajax\WordpressHeartbeat');
1184
+		}
1185
+		do_action('AHEE__EE_System__load_controllers__complete');
1186
+	}
1187
+
1188
+
1189
+	/**
1190
+	 * core_loaded_and_ready
1191
+	 * all of the basic EE core should be loaded at this point and available regardless of M-Mode
1192
+	 *
1193
+	 * @access public
1194
+	 * @return void
1195
+	 * @throws Exception
1196
+	 */
1197
+	public function core_loaded_and_ready()
1198
+	{
1199
+		if (
1200
+			$this->request->isAdmin()
1201
+			|| $this->request->isFrontend()
1202
+			|| $this->request->isIframe()
1203
+			|| $this->request->isWordPressApi()
1204
+		) {
1205
+			try {
1206
+				$this->loader->getShared('EventEspresso\core\services\assets\Registry');
1207
+				$this->loader->getShared('EventEspresso\core\domain\services\assets\CoreAssetManager');
1208
+				if ($this->canLoadBlocks()) {
1209
+					$this->loader->getShared(
1210
+						'EventEspresso\core\services\editor\BlockRegistrationManager'
1211
+					);
1212
+				}
1213
+			} catch (Exception $exception) {
1214
+				new ExceptionStackTraceDisplay($exception);
1215
+			}
1216
+		}
1217
+		if (
1218
+			$this->request->isAdmin()
1219
+			|| $this->request->isEeAjax()
1220
+			|| $this->request->isFrontend()
1221
+		) {
1222
+			$this->loader->getShared('EE_Session');
1223
+		}
1224
+		do_action('AHEE__EE_System__core_loaded_and_ready');
1225
+		// always load template tags, because it's faster than checking if it's a front-end request, and many page
1226
+		// builders require these even on the front-end
1227
+		require_once EE_PUBLIC . 'template_tags.php';
1228
+		do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1229
+	}
1230
+
1231
+
1232
+	/**
1233
+	 * initialize
1234
+	 * this is the best place to begin initializing client code
1235
+	 *
1236
+	 * @access public
1237
+	 * @return void
1238
+	 */
1239
+	public function initialize()
1240
+	{
1241
+		do_action('AHEE__EE_System__initialize');
1242
+		add_filter(
1243
+			'safe_style_css',
1244
+			function ($styles) {
1245
+				$styles[] = 'display';
1246
+				$styles[] = 'visibility';
1247
+				return $styles;
1248
+			}
1249
+		);
1250
+	}
1251
+
1252
+
1253
+	/**
1254
+	 * initialize_last
1255
+	 * this is run really late during the WP init hook point, and ensures that mostly everything else that needs to
1256
+	 * initialize has done so
1257
+	 *
1258
+	 * @access public
1259
+	 * @return void
1260
+	 */
1261
+	public function initialize_last()
1262
+	{
1263
+		do_action('AHEE__EE_System__initialize_last');
1264
+		/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
1265
+		$rewrite_rules = $this->loader->getShared(
1266
+			'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
1267
+		);
1268
+		$rewrite_rules->flushRewriteRules();
1269
+		add_action('admin_bar_init', array($this, 'addEspressoToolbar'));
1270
+		if (
1271
+			($this->request->isAjax() || $this->request->isAdmin())
1272
+			&& $this->maintenance_mode->models_can_query()
1273
+		) {
1274
+			$this->loader->getShared('EventEspresso\core\services\privacy\export\PersonalDataExporterManager');
1275
+			$this->loader->getShared('EventEspresso\core\services\privacy\erasure\PersonalDataEraserManager');
1276
+		}
1277
+	}
1278
+
1279
+
1280
+	/**
1281
+	 * @return void
1282
+	 * @throws EE_Error
1283
+	 */
1284
+	public function addEspressoToolbar()
1285
+	{
1286
+		$this->loader->getShared(
1287
+			'EventEspresso\core\domain\services\admin\AdminToolBar',
1288
+			array($this->registry->CAP)
1289
+		);
1290
+	}
1291
+
1292
+
1293
+	/**
1294
+	 * do_not_cache
1295
+	 * sets no cache headers and defines no cache constants for WP plugins
1296
+	 *
1297
+	 * @access public
1298
+	 * @return void
1299
+	 */
1300
+	public static function do_not_cache()
1301
+	{
1302
+		// set no cache constants
1303
+		if (! defined('DONOTCACHEPAGE')) {
1304
+			define('DONOTCACHEPAGE', true);
1305
+		}
1306
+		if (! defined('DONOTCACHCEOBJECT')) {
1307
+			define('DONOTCACHCEOBJECT', true);
1308
+		}
1309
+		if (! defined('DONOTCACHEDB')) {
1310
+			define('DONOTCACHEDB', true);
1311
+		}
1312
+		// add no cache headers
1313
+		add_action('send_headers', array('EE_System', 'nocache_headers'), 10);
1314
+		// plus a little extra for nginx and Google Chrome
1315
+		add_filter('nocache_headers', array('EE_System', 'extra_nocache_headers'), 10, 1);
1316
+		// prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes with the registration process
1317
+		remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
1318
+	}
1319
+
1320
+
1321
+	/**
1322
+	 *    extra_nocache_headers
1323
+	 *
1324
+	 * @access    public
1325
+	 * @param $headers
1326
+	 * @return    array
1327
+	 */
1328
+	public static function extra_nocache_headers($headers)
1329
+	{
1330
+		// for NGINX
1331
+		$headers['X-Accel-Expires'] = 0;
1332
+		// plus extra for Google Chrome since it doesn't seem to respect "no-cache", but WILL respect "no-store"
1333
+		$headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0';
1334
+		return $headers;
1335
+	}
1336
+
1337
+
1338
+	/**
1339
+	 *    nocache_headers
1340
+	 *
1341
+	 * @access    public
1342
+	 * @return    void
1343
+	 */
1344
+	public static function nocache_headers()
1345
+	{
1346
+		nocache_headers();
1347
+	}
1348
+
1349
+
1350
+	/**
1351
+	 * simply hooks into "wp_list_pages_exclude" filter (for wp_list_pages method) and makes sure EE critical pages are
1352
+	 * never returned with the function.
1353
+	 *
1354
+	 * @param  array $exclude_array any existing pages being excluded are in this array.
1355
+	 * @return array
1356
+	 */
1357
+	public function remove_pages_from_wp_list_pages($exclude_array)
1358
+	{
1359
+		return array_merge($exclude_array, $this->registry->CFG->core->get_critical_pages_array());
1360
+	}
1361
+
1362
+
1363
+	/**
1364
+	 * Return whether blocks can be registered/loaded or not.
1365
+	 * @return bool
1366
+	 */
1367
+	private function canLoadBlocks()
1368
+	{
1369
+		return apply_filters('FHEE__EE_System__canLoadBlocks', true)
1370
+			   && function_exists('register_block_type')
1371
+			   // don't load blocks if in the Divi page builder editor context
1372
+			   // @see https://github.com/eventespresso/event-espresso-core/issues/814
1373
+			   && ! $this->request->getRequestParam('et_fb', false);
1374
+	}
1375 1375
 }
Please login to merge, or discard this patch.
Spacing   +28 added lines, -28 removed lines patch added patch discarded remove patch
@@ -155,7 +155,7 @@  discard block
 block discarded – undo
155 155
         EE_Maintenance_Mode $maintenance_mode = null
156 156
     ) {
157 157
         // check if class object is instantiated
158
-        if (! self::$_instance instanceof EE_System) {
158
+        if ( ! self::$_instance instanceof EE_System) {
159 159
             self::$_instance = new self($registry, $loader, $request, $maintenance_mode);
160 160
         }
161 161
         return self::$_instance;
@@ -282,7 +282,7 @@  discard block
 block discarded – undo
282 282
         $this->capabilities = $this->loader->getShared('EE_Capabilities');
283 283
         add_action(
284 284
             'AHEE__EE_Capabilities__init_caps__before_initialization',
285
-            function () {
285
+            function() {
286 286
                 LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
287 287
             }
288 288
         );
@@ -323,7 +323,7 @@  discard block
 block discarded – undo
323 323
     {
324 324
         // set autoloaders for all of the classes implementing EEI_Plugin_API
325 325
         // which provide helpers for EE plugin authors to more easily register certain components with EE.
326
-        EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'plugin_api');
326
+        EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES.'plugin_api');
327 327
     }
328 328
 
329 329
 
@@ -342,14 +342,14 @@  discard block
 block discarded – undo
342 342
         $load_callback,
343 343
         $plugin_file_constant
344 344
     ) {
345
-        if (! defined($version_constant)) {
345
+        if ( ! defined($version_constant)) {
346 346
             return;
347 347
         }
348 348
         $addon_version = constant($version_constant);
349 349
         if ($addon_version && version_compare($addon_version, $min_version_required, '<')) {
350 350
             remove_action('AHEE__EE_System__load_espresso_addons', $load_callback);
351
-            if (! function_exists('deactivate_plugins')) {
352
-                require_once ABSPATH . 'wp-admin/includes/plugin.php';
351
+            if ( ! function_exists('deactivate_plugins')) {
352
+                require_once ABSPATH.'wp-admin/includes/plugin.php';
353 353
             }
354 354
             deactivate_plugins(plugin_basename(constant($plugin_file_constant)));
355 355
             $this->request->unSetRequestParams(['activate', 'activate-multi'], true);
@@ -363,7 +363,7 @@  discard block
 block discarded – undo
363 363
                     $min_version_required
364 364
                 ),
365 365
                 __FILE__,
366
-                __FUNCTION__ . "({$addon_name})",
366
+                __FUNCTION__."({$addon_name})",
367 367
                 __LINE__
368 368
             );
369 369
             EE_Error::get_notices(false, true);
@@ -415,7 +415,7 @@  discard block
 block discarded – undo
415 415
                 true
416 416
             )
417 417
         ) {
418
-            include_once EE_THIRD_PARTY . 'wp-api-basic-auth/basic-auth.php';
418
+            include_once EE_THIRD_PARTY.'wp-api-basic-auth/basic-auth.php';
419 419
         }
420 420
         do_action('AHEE__EE_System__load_espresso_addons__complete');
421 421
     }
@@ -517,11 +517,11 @@  discard block
 block discarded – undo
517 517
     private function fix_espresso_db_upgrade_option($espresso_db_update = null)
518 518
     {
519 519
         do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
520
-        if (! $espresso_db_update) {
520
+        if ( ! $espresso_db_update) {
521 521
             $espresso_db_update = get_option('espresso_db_update');
522 522
         }
523 523
         // check that option is an array
524
-        if (! is_array($espresso_db_update)) {
524
+        if ( ! is_array($espresso_db_update)) {
525 525
             // if option is FALSE, then it never existed
526 526
             if ($espresso_db_update === false) {
527 527
                 // make $espresso_db_update an array and save option with autoload OFF
@@ -541,10 +541,10 @@  discard block
 block discarded – undo
541 541
                     // so it must be numerically-indexed, where values are versions installed...
542 542
                     // fix it!
543 543
                     $version_string = $should_be_array;
544
-                    $corrected_db_update[ $version_string ] = array('unknown-date');
544
+                    $corrected_db_update[$version_string] = array('unknown-date');
545 545
                 } else {
546 546
                     // ok it checks out
547
-                    $corrected_db_update[ $should_be_version_string ] = $should_be_array;
547
+                    $corrected_db_update[$should_be_version_string] = $should_be_array;
548 548
                 }
549 549
             }
550 550
             $espresso_db_update = $corrected_db_update;
@@ -628,13 +628,13 @@  discard block
 block discarded – undo
628 628
      */
629 629
     public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
630 630
     {
631
-        if (! $version_history) {
631
+        if ( ! $version_history) {
632 632
             $version_history = $this->fix_espresso_db_upgrade_option($version_history);
633 633
         }
634 634
         if ($current_version_to_add === null) {
635 635
             $current_version_to_add = espresso_version();
636 636
         }
637
-        $version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
637
+        $version_history[$current_version_to_add][] = date('Y-m-d H:i:s', time());
638 638
         // re-save
639 639
         return update_option('espresso_db_update', $version_history);
640 640
     }
@@ -724,7 +724,7 @@  discard block
 block discarded – undo
724 724
         if ($activation_history_for_addon) {
725 725
             // it exists, so this isn't a completely new install
726 726
             // check if this version already in that list of previously installed versions
727
-            if (! isset($activation_history_for_addon[ $version_to_upgrade_to ])) {
727
+            if ( ! isset($activation_history_for_addon[$version_to_upgrade_to])) {
728 728
                 // it a version we haven't seen before
729 729
                 if ($version_is_higher === 1) {
730 730
                     $req_type = EE_System::req_type_upgrade;
@@ -802,7 +802,7 @@  discard block
 block discarded – undo
802 802
             foreach ($activation_history as $version => $times_activated) {
803 803
                 // check there is a record of when this version was activated. Otherwise,
804 804
                 // mark it as unknown
805
-                if (! $times_activated) {
805
+                if ( ! $times_activated) {
806 806
                     $times_activated = array('unknown-date');
807 807
                 }
808 808
                 if (is_string($times_activated)) {
@@ -906,7 +906,7 @@  discard block
 block discarded – undo
906 906
     private function _parse_model_names()
907 907
     {
908 908
         // get all the files in the EE_MODELS folder that end in .model.php
909
-        $models = glob(EE_MODELS . '*.model.php');
909
+        $models = glob(EE_MODELS.'*.model.php');
910 910
         $model_names = array();
911 911
         $non_abstract_db_models = array();
912 912
         foreach ($models as $model) {
@@ -915,9 +915,9 @@  discard block
 block discarded – undo
915 915
             $short_name = str_replace('EEM_', '', $classname);
916 916
             $reflectionClass = new ReflectionClass($classname);
917 917
             if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
918
-                $non_abstract_db_models[ $short_name ] = $classname;
918
+                $non_abstract_db_models[$short_name] = $classname;
919 919
             }
920
-            $model_names[ $short_name ] = $classname;
920
+            $model_names[$short_name] = $classname;
921 921
         }
922 922
         $this->registry->models = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
923 923
         $this->registry->non_abstract_db_models = apply_filters(
@@ -952,7 +952,7 @@  discard block
 block discarded – undo
952 952
             )
953 953
         );
954 954
         if ($domain->isCaffeinated()) {
955
-            require_once EE_CAFF_PATH . 'brewing_regular.php';
955
+            require_once EE_CAFF_PATH.'brewing_regular.php';
956 956
         }
957 957
     }
958 958
 
@@ -1034,7 +1034,7 @@  discard block
 block discarded – undo
1034 1034
         $class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook(
1035 1035
             'AHEE__EE_System__register_shortcodes_modules_and_addons'
1036 1036
         );
1037
-        if (! empty($class_names)) {
1037
+        if ( ! empty($class_names)) {
1038 1038
             $msg = esc_html__(
1039 1039
                 'The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
1040 1040
                 'event_espresso'
@@ -1046,7 +1046,7 @@  discard block
 block discarded – undo
1046 1046
                             array('EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'),
1047 1047
                             '',
1048 1048
                             $class_name
1049
-                        ) . '</b></li>';
1049
+                        ).'</b></li>';
1050 1050
             }
1051 1051
             $msg .= '</ul>';
1052 1052
             $msg .= esc_html__(
@@ -1115,7 +1115,7 @@  discard block
 block discarded – undo
1115 1115
     private function _deactivate_incompatible_addons()
1116 1116
     {
1117 1117
         $incompatible_addons = get_option('ee_incompatible_addons', array());
1118
-        if (! empty($incompatible_addons)) {
1118
+        if ( ! empty($incompatible_addons)) {
1119 1119
             $active_plugins = get_option('active_plugins', array());
1120 1120
             foreach ($active_plugins as $active_plugin) {
1121 1121
                 foreach ($incompatible_addons as $incompatible_addon) {
@@ -1224,7 +1224,7 @@  discard block
 block discarded – undo
1224 1224
         do_action('AHEE__EE_System__core_loaded_and_ready');
1225 1225
         // always load template tags, because it's faster than checking if it's a front-end request, and many page
1226 1226
         // builders require these even on the front-end
1227
-        require_once EE_PUBLIC . 'template_tags.php';
1227
+        require_once EE_PUBLIC.'template_tags.php';
1228 1228
         do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1229 1229
     }
1230 1230
 
@@ -1241,7 +1241,7 @@  discard block
 block discarded – undo
1241 1241
         do_action('AHEE__EE_System__initialize');
1242 1242
         add_filter(
1243 1243
             'safe_style_css',
1244
-            function ($styles) {
1244
+            function($styles) {
1245 1245
                 $styles[] = 'display';
1246 1246
                 $styles[] = 'visibility';
1247 1247
                 return $styles;
@@ -1300,13 +1300,13 @@  discard block
 block discarded – undo
1300 1300
     public static function do_not_cache()
1301 1301
     {
1302 1302
         // set no cache constants
1303
-        if (! defined('DONOTCACHEPAGE')) {
1303
+        if ( ! defined('DONOTCACHEPAGE')) {
1304 1304
             define('DONOTCACHEPAGE', true);
1305 1305
         }
1306
-        if (! defined('DONOTCACHCEOBJECT')) {
1306
+        if ( ! defined('DONOTCACHCEOBJECT')) {
1307 1307
             define('DONOTCACHCEOBJECT', true);
1308 1308
         }
1309
-        if (! defined('DONOTCACHEDB')) {
1309
+        if ( ! defined('DONOTCACHEDB')) {
1310 1310
             define('DONOTCACHEDB', true);
1311 1311
         }
1312 1312
         // add no cache headers
Please login to merge, or discard this patch.
espresso.php 1 patch
Indentation   +80 added lines, -80 removed lines patch added patch discarded remove patch
@@ -38,103 +38,103 @@
 block discarded – undo
38 38
  * @since           4.0
39 39
  */
40 40
 if (function_exists('espresso_version')) {
41
-    if (! function_exists('espresso_duplicate_plugin_error')) {
42
-        /**
43
-         *    espresso_duplicate_plugin_error
44
-         *    displays if more than one version of EE is activated at the same time
45
-         */
46
-        function espresso_duplicate_plugin_error()
47
-        {
48
-            ?>
41
+	if (! function_exists('espresso_duplicate_plugin_error')) {
42
+		/**
43
+		 *    espresso_duplicate_plugin_error
44
+		 *    displays if more than one version of EE is activated at the same time
45
+		 */
46
+		function espresso_duplicate_plugin_error()
47
+		{
48
+			?>
49 49
             <div class="error">
50 50
                 <p>
51 51
                     <?php
52
-                    echo esc_html__(
53
-                        '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.',
54
-                        'event_espresso'
55
-                    ); ?>
52
+					echo esc_html__(
53
+						'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.',
54
+						'event_espresso'
55
+					); ?>
56 56
                 </p>
57 57
             </div>
58 58
             <?php
59
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
60
-        }
61
-    }
62
-    add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
59
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
60
+		}
61
+	}
62
+	add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
63 63
 } else {
64
-    define('EE_MIN_PHP_VER_REQUIRED', '5.6.2');
65
-    if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
66
-        /**
67
-         * espresso_minimum_php_version_error
68
-         *
69
-         * @return void
70
-         */
71
-        function espresso_minimum_php_version_error()
72
-        {
73
-            ?>
64
+	define('EE_MIN_PHP_VER_REQUIRED', '5.6.2');
65
+	if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
66
+		/**
67
+		 * espresso_minimum_php_version_error
68
+		 *
69
+		 * @return void
70
+		 */
71
+		function espresso_minimum_php_version_error()
72
+		{
73
+			?>
74 74
             <div class="error">
75 75
                 <p>
76 76
                     <?php
77
-                    printf(
78
-                        esc_html__(
79
-                            '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.',
80
-                            'event_espresso'
81
-                        ),
82
-                        EE_MIN_PHP_VER_REQUIRED,
83
-                        PHP_VERSION,
84
-                        '<br/>',
85
-                        '<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
86
-                    );
87
-                    ?>
77
+					printf(
78
+						esc_html__(
79
+							'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.',
80
+							'event_espresso'
81
+						),
82
+						EE_MIN_PHP_VER_REQUIRED,
83
+						PHP_VERSION,
84
+						'<br/>',
85
+						'<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
86
+					);
87
+					?>
88 88
                 </p>
89 89
             </div>
90 90
             <?php
91
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
92
-        }
91
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
92
+		}
93 93
 
94
-        add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
95
-    } else {
96
-        define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
97
-        /**
98
-         * espresso_version
99
-         * Returns the plugin version
100
-         *
101
-         * @return string
102
-         */
103
-        function espresso_version()
104
-        {
105
-            return apply_filters('FHEE__espresso__espresso_version', '4.10.30.rc.011');
106
-        }
94
+		add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
95
+	} else {
96
+		define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
97
+		/**
98
+		 * espresso_version
99
+		 * Returns the plugin version
100
+		 *
101
+		 * @return string
102
+		 */
103
+		function espresso_version()
104
+		{
105
+			return apply_filters('FHEE__espresso__espresso_version', '4.10.30.rc.011');
106
+		}
107 107
 
108
-        /**
109
-         * espresso_plugin_activation
110
-         * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
111
-         */
112
-        function espresso_plugin_activation()
113
-        {
114
-            update_option('ee_espresso_activation', true);
115
-        }
108
+		/**
109
+		 * espresso_plugin_activation
110
+		 * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
111
+		 */
112
+		function espresso_plugin_activation()
113
+		{
114
+			update_option('ee_espresso_activation', true);
115
+		}
116 116
 
117
-        register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
117
+		register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
118 118
 
119
-        require_once __DIR__ . '/core/bootstrap_espresso.php';
120
-        bootstrap_espresso();
121
-    }
119
+		require_once __DIR__ . '/core/bootstrap_espresso.php';
120
+		bootstrap_espresso();
121
+	}
122 122
 }
123 123
 if (! function_exists('espresso_deactivate_plugin')) {
124
-    /**
125
-     *    deactivate_plugin
126
-     * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
127
-     *
128
-     * @access public
129
-     * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
130
-     * @return    void
131
-     */
132
-    function espresso_deactivate_plugin($plugin_basename = '')
133
-    {
134
-        if (! function_exists('deactivate_plugins')) {
135
-            require_once ABSPATH . 'wp-admin/includes/plugin.php';
136
-        }
137
-        unset($_GET['activate'], $_REQUEST['activate']);
138
-        deactivate_plugins($plugin_basename);
139
-    }
124
+	/**
125
+	 *    deactivate_plugin
126
+	 * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
127
+	 *
128
+	 * @access public
129
+	 * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
130
+	 * @return    void
131
+	 */
132
+	function espresso_deactivate_plugin($plugin_basename = '')
133
+	{
134
+		if (! function_exists('deactivate_plugins')) {
135
+			require_once ABSPATH . 'wp-admin/includes/plugin.php';
136
+		}
137
+		unset($_GET['activate'], $_REQUEST['activate']);
138
+		deactivate_plugins($plugin_basename);
139
+	}
140 140
 }
141 141
\ No newline at end of file
Please login to merge, or discard this patch.
core/helpers/EEH_Form_Fields.helper.php 2 patches
Indentation   +1971 added lines, -1971 removed lines patch added patch discarded remove patch
@@ -29,1997 +29,1997 @@
 block discarded – undo
29 29
 {
30 30
 
31 31
 
32
-    /**
33
-     *  Generates HTML for the forms used on admin pages
34
-     *
35
-     *
36
-     * @static
37
-     * @access public
38
-     * @param array $input_vars - array of input field details
39
-     *                          format:
40
-     *                          $template_form_fields['field-id'] = array(
41
-     *                          'name' => 'name_attribute',
42
-     *                          'label' => esc_html__('Field Label', 'event_espresso'), //or false
43
-     *                          'input' => 'hidden', //field input type can be 'text', 'select', 'textarea', 'hidden',
44
-     *                          'checkbox', 'wp_editor'
45
-     *                          'type' => 'int', //what "type" the value is (i.e. string, int etc)
46
-     *                          'required' => false, //boolean for whether the field is required
47
-     *                          'validation' => true, //boolean, whether to validate the field (todo)
48
-     *                          'value' => 'some_value_for_field', //what value is used for field
49
-     *                          'format' => '%d', //what format the value is (%d, %f, or %s)
50
-     *                          'db-col' => 'column_in_db' //used to indicate which column the field corresponds with
51
-     *                          in the db
52
-     *                          'options' => optiona, optionb || array('value' => 'label', '') //if the input type is
53
-     *                          "select", this allows you to set the args for the different <option> tags.
54
-     *                          'tabindex' => 1 //this allows you to set the tabindex for the field.
55
-     *                          'append_content' => '' //this allows you to send in html content to append to the
56
-     *                          field.
57
-     *                          )
58
-     * @param array $form_id    - used for defining unique identifiers for the form.
59
-     * @return string
60
-     * @todo   : at some point we can break this down into other static methods to abstract it a bit better.
61
-     */
62
-    public static function get_form_fields($input_vars = [], $form_id = false)
63
-    {
64
-
65
-        if (empty($input_vars)) {
66
-            EE_Error::add_error(
67
-                esc_html__('missing required variables for the form field generator', 'event_espresso'),
68
-                __FILE__,
69
-                __FUNCTION__,
70
-                __LINE__
71
-            );
72
-            return false;
73
-        }
74
-
75
-        $output        = "";
76
-        $inputs        = [];
77
-        $hidden_inputs = [];
78
-
79
-        // cycle thru inputs
80
-        foreach ($input_vars as $input_key => $input_value) {
81
-            $defaults = [
82
-                'append_content' => '',
83
-                'css_class'      => '',
84
-                'cols'           => 80,
85
-                'db-col'         => 'column_in_db',
86
-                'format'         => '%d',
87
-                'input'          => 'hidden',
88
-                'label'          => esc_html__('No label', 'event_espresso'),
89
-                'name'           => $input_key,
90
-                'options'        => [],
91
-                'required'       => false,
92
-                'tabindex'       => 0,
93
-                'rows'           => 10,
94
-                'type'           => 'int',
95
-                'validation'     => true,
96
-                'value'          => 'some_value_for_field',
97
-            ];
98
-
99
-            $input_value = wp_parse_args($input_value, $defaults);
100
-
101
-            $append_content = $input_value['append_content'];
102
-            $css_class      = $input_value['css_class'];
103
-            $cols           = $input_value['cols'];
104
-            $label          = $input_value['label'];
105
-            $name           = $input_value['name'];
106
-            $options        = $input_value['options'];
107
-            $required       = $input_value['required'];
108
-            $tab_index      = $input_value['tabindex'];
109
-            $rows           = $input_value['rows'];
110
-            $type           = $input_value['input'];
111
-            $value          = $input_value['value'];
112
-
113
-            $id    = $form_id ? $form_id . '-' . $input_key : $input_key;
114
-            $class = $required ? 'required ' . $css_class : $css_class;
115
-
116
-            // what type of input are we dealing with ?
117
-            switch ($type) {
118
-                case 'checkbox':
119
-                case 'radio':
120
-                    $field = self::adminMulti($value, $class, $id, $name, $required, $tab_index, $type, 1, $label);
121
-                    $field .= $append_content ?: '';
122
-                    break;
123
-
124
-                case 'hidden':
125
-                    $field           = null;
126
-                    $hidden_inputs[] = self::adminHidden($css_class, $id, $name, $value);
127
-                    break;
128
-
129
-                case 'select':
130
-                    $options = is_array($options) ? $options : explode(',', $options);
131
-                    $field   = self::adminLabel($id, $label, $required);
132
-                    $field   .= self::adminSelect($value, $class, $id, $name, $required, $tab_index, $options);
133
-                    $field   .= $append_content ?: '';
134
-                    break;
135
-
136
-                case 'textarea':
137
-                    $field = self::adminLabel($id, $label, $required);
138
-                    $field .= self::adminTextarea($class, $cols, $id, $name, $required, $rows, $tab_index, $value);
139
-                    $field .= $append_content ?: '';
140
-                    break;
141
-
142
-                case 'wp_editor':
143
-                    $label = esc_html($label);
144
-                    $field = "<h4>{$label}</h4>";
145
-                    $field .= $append_content ?: '';
146
-                    $field .= self::adminWpEditor(
147
-                        $class,
148
-                        $id,
149
-                        $name,
150
-                        $rows,
151
-                        $tab_index,
152
-                        $value
153
-                    );
154
-                    break;
155
-
156
-                default:
157
-                    $field = self::adminLabel($id, $label, $required);
158
-                    $field .= self::adminText($class, $id, $name, $required, $tab_index, $value);
159
-                    $field .= $append_content ?: '';
160
-            }
161
-            if ($field) {
162
-                $inputs[] = $field;
163
-            }
164
-        } // end foreach( $input_vars as $input_key => $input_value )
165
-
166
-        if (! empty($inputs)) {
167
-            $glue   = "
32
+	/**
33
+	 *  Generates HTML for the forms used on admin pages
34
+	 *
35
+	 *
36
+	 * @static
37
+	 * @access public
38
+	 * @param array $input_vars - array of input field details
39
+	 *                          format:
40
+	 *                          $template_form_fields['field-id'] = array(
41
+	 *                          'name' => 'name_attribute',
42
+	 *                          'label' => esc_html__('Field Label', 'event_espresso'), //or false
43
+	 *                          'input' => 'hidden', //field input type can be 'text', 'select', 'textarea', 'hidden',
44
+	 *                          'checkbox', 'wp_editor'
45
+	 *                          'type' => 'int', //what "type" the value is (i.e. string, int etc)
46
+	 *                          'required' => false, //boolean for whether the field is required
47
+	 *                          'validation' => true, //boolean, whether to validate the field (todo)
48
+	 *                          'value' => 'some_value_for_field', //what value is used for field
49
+	 *                          'format' => '%d', //what format the value is (%d, %f, or %s)
50
+	 *                          'db-col' => 'column_in_db' //used to indicate which column the field corresponds with
51
+	 *                          in the db
52
+	 *                          'options' => optiona, optionb || array('value' => 'label', '') //if the input type is
53
+	 *                          "select", this allows you to set the args for the different <option> tags.
54
+	 *                          'tabindex' => 1 //this allows you to set the tabindex for the field.
55
+	 *                          'append_content' => '' //this allows you to send in html content to append to the
56
+	 *                          field.
57
+	 *                          )
58
+	 * @param array $form_id    - used for defining unique identifiers for the form.
59
+	 * @return string
60
+	 * @todo   : at some point we can break this down into other static methods to abstract it a bit better.
61
+	 */
62
+	public static function get_form_fields($input_vars = [], $form_id = false)
63
+	{
64
+
65
+		if (empty($input_vars)) {
66
+			EE_Error::add_error(
67
+				esc_html__('missing required variables for the form field generator', 'event_espresso'),
68
+				__FILE__,
69
+				__FUNCTION__,
70
+				__LINE__
71
+			);
72
+			return false;
73
+		}
74
+
75
+		$output        = "";
76
+		$inputs        = [];
77
+		$hidden_inputs = [];
78
+
79
+		// cycle thru inputs
80
+		foreach ($input_vars as $input_key => $input_value) {
81
+			$defaults = [
82
+				'append_content' => '',
83
+				'css_class'      => '',
84
+				'cols'           => 80,
85
+				'db-col'         => 'column_in_db',
86
+				'format'         => '%d',
87
+				'input'          => 'hidden',
88
+				'label'          => esc_html__('No label', 'event_espresso'),
89
+				'name'           => $input_key,
90
+				'options'        => [],
91
+				'required'       => false,
92
+				'tabindex'       => 0,
93
+				'rows'           => 10,
94
+				'type'           => 'int',
95
+				'validation'     => true,
96
+				'value'          => 'some_value_for_field',
97
+			];
98
+
99
+			$input_value = wp_parse_args($input_value, $defaults);
100
+
101
+			$append_content = $input_value['append_content'];
102
+			$css_class      = $input_value['css_class'];
103
+			$cols           = $input_value['cols'];
104
+			$label          = $input_value['label'];
105
+			$name           = $input_value['name'];
106
+			$options        = $input_value['options'];
107
+			$required       = $input_value['required'];
108
+			$tab_index      = $input_value['tabindex'];
109
+			$rows           = $input_value['rows'];
110
+			$type           = $input_value['input'];
111
+			$value          = $input_value['value'];
112
+
113
+			$id    = $form_id ? $form_id . '-' . $input_key : $input_key;
114
+			$class = $required ? 'required ' . $css_class : $css_class;
115
+
116
+			// what type of input are we dealing with ?
117
+			switch ($type) {
118
+				case 'checkbox':
119
+				case 'radio':
120
+					$field = self::adminMulti($value, $class, $id, $name, $required, $tab_index, $type, 1, $label);
121
+					$field .= $append_content ?: '';
122
+					break;
123
+
124
+				case 'hidden':
125
+					$field           = null;
126
+					$hidden_inputs[] = self::adminHidden($css_class, $id, $name, $value);
127
+					break;
128
+
129
+				case 'select':
130
+					$options = is_array($options) ? $options : explode(',', $options);
131
+					$field   = self::adminLabel($id, $label, $required);
132
+					$field   .= self::adminSelect($value, $class, $id, $name, $required, $tab_index, $options);
133
+					$field   .= $append_content ?: '';
134
+					break;
135
+
136
+				case 'textarea':
137
+					$field = self::adminLabel($id, $label, $required);
138
+					$field .= self::adminTextarea($class, $cols, $id, $name, $required, $rows, $tab_index, $value);
139
+					$field .= $append_content ?: '';
140
+					break;
141
+
142
+				case 'wp_editor':
143
+					$label = esc_html($label);
144
+					$field = "<h4>{$label}</h4>";
145
+					$field .= $append_content ?: '';
146
+					$field .= self::adminWpEditor(
147
+						$class,
148
+						$id,
149
+						$name,
150
+						$rows,
151
+						$tab_index,
152
+						$value
153
+					);
154
+					break;
155
+
156
+				default:
157
+					$field = self::adminLabel($id, $label, $required);
158
+					$field .= self::adminText($class, $id, $name, $required, $tab_index, $value);
159
+					$field .= $append_content ?: '';
160
+			}
161
+			if ($field) {
162
+				$inputs[] = $field;
163
+			}
164
+		} // end foreach( $input_vars as $input_key => $input_value )
165
+
166
+		if (! empty($inputs)) {
167
+			$glue   = "
168 168
                 </li>
169 169
                 <li>
170 170
                     ";
171
-            $inputs = implode($glue, $inputs);
172
-            $output = "
171
+			$inputs = implode($glue, $inputs);
172
+			$output = "
173 173
             <ul>
174 174
                 <li>
175 175
                 {$inputs} 
176 176
                 </li>
177 177
             </ul>
178 178
             ";
179
-        }
180
-        return $output . implode("\n", $hidden_inputs);
181
-    }
182
-
183
-
184
-    /**
185
-     * form_fields_array
186
-     * This utility function assembles form fields from a given structured array with field information.
187
-     * //TODO: This is an alternate generator that we may want to use instead.
188
-     *
189
-     * @param array $fields structured array of fields to assemble in the following format:
190
-     *                      [field_name] => array(
191
-     *                      ['label'] => 'label for field',
192
-     *                      ['labels'] => array('label_1', 'label_2'); //optional - if the field type is a multi select
193
-     *                      type of field you can indicated the labels for each option via this index
194
-     *                      ['extra_desc'] => 'extra description for the field', //optional
195
-     *                      ['type'] => 'textarea'|'text'|'wp_editor'|'checkbox'|'radio'|'hidden'|'select', //defaults
196
-     *                      to text
197
-     *                      ['value'] => 'value that goes in the field', //(if multi then this is an array of values
198
-     *                      and the 'default' paramater will be used for what is selected)
199
-     *                      ['default'] => 'default if the field type is multi (i.e. select or radios or checkboxes)',
200
-     *                      ['class'] => 'name-of-class(es)-for-input',
201
-     *                      ['classes'] => array('class_1', 'class_2'); //optional - if the field type is a multi
202
-     *                      select type of field you can indicate the css class for each option via this index.
203
-     *                      ['id'] => 'css-id-for-input') //defaults to 'field_name'
204
-     *                      ['unique_id'] => 1 //defaults to empty string.  This is useful for when the fields
205
-     *                      generated are going to be used in a loop and you want to make sure that the field
206
-     *                      identifiers are unique from each other.
207
-     *                      ['dimensions'] => array(100,300), //defaults to empty array.  This is used by field types
208
-     *                      such as textarea to indicate cols/rows.
209
-     *                      ['tabindex'] => '' //this allows you to set the tabindex for the field.
210
-     *                      ['wpeditor_args'] => array() //if the type of field is wpeditor then this can optionally
211
-     *                      contain an array of arguments for the editor setup.
212
-     *
213
-     * @return array         an array of inputs for form indexed by field name, and in the following structure:
214
-     *     [field_name] => array( 'label' => '{label_html}', 'field' => '{input_html}'
215
-     */
216
-    public static function get_form_fields_array($fields)
217
-    {
218
-
219
-        $form_fields = [];
220
-        $fields      = (array) $fields;
221
-
222
-        foreach ($fields as $field_name => $field_atts) {
223
-            // defaults:
224
-            $defaults = [
225
-                'class'         => '',
226
-                'classes'       => '',
227
-                'default'       => '',
228
-                'dimensions'    => ['10', '5'],
229
-                'extra_desc'    => '',
230
-                'id'            => $field_name,
231
-                'label'         => '',
232
-                'labels'        => '',
233
-                'required'      => false,
234
-                'tabindex'      => 0,
235
-                'type'          => 'text',
236
-                'unique_id'     => '',
237
-                'value'         => '',
238
-                'wpeditor_args' => [],
239
-            ];
240
-            // merge defaults with passed arguments
241
-            $_fields = wp_parse_args($field_atts, $defaults);
242
-
243
-            $class          = $_fields['class'];
244
-            $classes        = $_fields['classes'];
245
-            $default        = $_fields['default'];
246
-            $dims           = $_fields['dimensions'];
247
-            $extra_desc     = $_fields['extra_desc'];
248
-            $id             = $_fields['id'];
249
-            $label          = $_fields['label'];
250
-            $labels         = $_fields['labels'];
251
-            $required       = $_fields['required'];
252
-            $tab_index      = $_fields['tabindex'];
253
-            $type           = $_fields['type'];
254
-            $unique_id      = $_fields['unique_id'];
255
-            $value          = $_fields['value'];
256
-            $wp_editor_args = $_fields['wpeditor_args'];
257
-
258
-            // generate label
259
-            $label = ! empty($label) ? self::adminLabel($id, $label, $required) : '';
260
-            // generate field name
261
-            $name = ! empty($unique_id) ? $field_name . '[' . $unique_id . ']' : $field_name;
262
-
263
-            // we determine what we're building based on the type
264
-            switch ($type) {
265
-                case 'checkbox':
266
-                case 'radio':
267
-                    if (is_array($value)) {
268
-                        $c_input = '';
269
-                        foreach ($value as $key => $val) {
270
-                            $c_input .= self::adminMulti(
271
-                                $default,
272
-                                isset($classes[ $key ]) ? $classes[ $key ] : '',
273
-                                $field_name . '_' . $value,
274
-                                $name,
275
-                                $required,
276
-                                $tab_index,
277
-                                $type,
278
-                                $val,
279
-                                isset($labels[ $key ]) ? $labels[ $key ] : ''
280
-                            );
281
-                        }
282
-                        $field = $c_input;
283
-                    } else {
284
-                        $field = self::adminMulti(
285
-                            $default,
286
-                            $class,
287
-                            $id,
288
-                            $name,
289
-                            $required,
290
-                            $tab_index,
291
-                            $type,
292
-                            $value,
293
-                            $_fields['label']
294
-                        );
295
-                    }
296
-                    break;
297
-
298
-                case 'hidden':
299
-                    $field = self::adminHidden($class, $id, $name, $value);
300
-                    break;
301
-
302
-                case 'select':
303
-                    $options = [];
304
-                    foreach ($value as $key => $val) {
305
-                        $options[ $val ] = isset($labels[ $key ]) ? $labels[ $key ] : '';
306
-                    }
307
-                    $field = self::adminSelect($default, $class, $id, $name, $required, $tab_index, $options);
308
-                    break;
309
-
310
-                case 'textarea':
311
-                    $field =
312
-                        self::adminTextarea($class, $dims[0], $id, $name, $required, $dims[1], $tab_index, $value);
313
-                    break;
314
-
315
-                case 'wp_editor':
316
-                    $field = self::adminWpEditor(
317
-                        $class,
318
-                        $_fields['id'],
319
-                        $name,
320
-                        $dims[1],
321
-                        $tab_index,
322
-                        $value,
323
-                        $wp_editor_args
324
-                    );
325
-                    break;
326
-
327
-                default:
328
-                    $field = self::adminText($class, $id, $name, $required, $tab_index, $value);
329
-            }
330
-
331
-            $form_fields[ $field_name ] = ['label' => $label, 'field' => $field . $extra_desc];
332
-        }
333
-
334
-        return $form_fields;
335
-    }
336
-
337
-
338
-    /**
339
-     * @param string $class
340
-     * @param string $id
341
-     * @param string $name
342
-     * @param string $value
343
-     * @return string
344
-     * @since   4.10.14.p
345
-     */
346
-    private static function adminHidden($class, $id, $name, $value)
347
-    {
348
-        $id    = esc_attr($id);
349
-        $name  = esc_attr($name);
350
-        $class = esc_attr($class);
351
-        return "
179
+		}
180
+		return $output . implode("\n", $hidden_inputs);
181
+	}
182
+
183
+
184
+	/**
185
+	 * form_fields_array
186
+	 * This utility function assembles form fields from a given structured array with field information.
187
+	 * //TODO: This is an alternate generator that we may want to use instead.
188
+	 *
189
+	 * @param array $fields structured array of fields to assemble in the following format:
190
+	 *                      [field_name] => array(
191
+	 *                      ['label'] => 'label for field',
192
+	 *                      ['labels'] => array('label_1', 'label_2'); //optional - if the field type is a multi select
193
+	 *                      type of field you can indicated the labels for each option via this index
194
+	 *                      ['extra_desc'] => 'extra description for the field', //optional
195
+	 *                      ['type'] => 'textarea'|'text'|'wp_editor'|'checkbox'|'radio'|'hidden'|'select', //defaults
196
+	 *                      to text
197
+	 *                      ['value'] => 'value that goes in the field', //(if multi then this is an array of values
198
+	 *                      and the 'default' paramater will be used for what is selected)
199
+	 *                      ['default'] => 'default if the field type is multi (i.e. select or radios or checkboxes)',
200
+	 *                      ['class'] => 'name-of-class(es)-for-input',
201
+	 *                      ['classes'] => array('class_1', 'class_2'); //optional - if the field type is a multi
202
+	 *                      select type of field you can indicate the css class for each option via this index.
203
+	 *                      ['id'] => 'css-id-for-input') //defaults to 'field_name'
204
+	 *                      ['unique_id'] => 1 //defaults to empty string.  This is useful for when the fields
205
+	 *                      generated are going to be used in a loop and you want to make sure that the field
206
+	 *                      identifiers are unique from each other.
207
+	 *                      ['dimensions'] => array(100,300), //defaults to empty array.  This is used by field types
208
+	 *                      such as textarea to indicate cols/rows.
209
+	 *                      ['tabindex'] => '' //this allows you to set the tabindex for the field.
210
+	 *                      ['wpeditor_args'] => array() //if the type of field is wpeditor then this can optionally
211
+	 *                      contain an array of arguments for the editor setup.
212
+	 *
213
+	 * @return array         an array of inputs for form indexed by field name, and in the following structure:
214
+	 *     [field_name] => array( 'label' => '{label_html}', 'field' => '{input_html}'
215
+	 */
216
+	public static function get_form_fields_array($fields)
217
+	{
218
+
219
+		$form_fields = [];
220
+		$fields      = (array) $fields;
221
+
222
+		foreach ($fields as $field_name => $field_atts) {
223
+			// defaults:
224
+			$defaults = [
225
+				'class'         => '',
226
+				'classes'       => '',
227
+				'default'       => '',
228
+				'dimensions'    => ['10', '5'],
229
+				'extra_desc'    => '',
230
+				'id'            => $field_name,
231
+				'label'         => '',
232
+				'labels'        => '',
233
+				'required'      => false,
234
+				'tabindex'      => 0,
235
+				'type'          => 'text',
236
+				'unique_id'     => '',
237
+				'value'         => '',
238
+				'wpeditor_args' => [],
239
+			];
240
+			// merge defaults with passed arguments
241
+			$_fields = wp_parse_args($field_atts, $defaults);
242
+
243
+			$class          = $_fields['class'];
244
+			$classes        = $_fields['classes'];
245
+			$default        = $_fields['default'];
246
+			$dims           = $_fields['dimensions'];
247
+			$extra_desc     = $_fields['extra_desc'];
248
+			$id             = $_fields['id'];
249
+			$label          = $_fields['label'];
250
+			$labels         = $_fields['labels'];
251
+			$required       = $_fields['required'];
252
+			$tab_index      = $_fields['tabindex'];
253
+			$type           = $_fields['type'];
254
+			$unique_id      = $_fields['unique_id'];
255
+			$value          = $_fields['value'];
256
+			$wp_editor_args = $_fields['wpeditor_args'];
257
+
258
+			// generate label
259
+			$label = ! empty($label) ? self::adminLabel($id, $label, $required) : '';
260
+			// generate field name
261
+			$name = ! empty($unique_id) ? $field_name . '[' . $unique_id . ']' : $field_name;
262
+
263
+			// we determine what we're building based on the type
264
+			switch ($type) {
265
+				case 'checkbox':
266
+				case 'radio':
267
+					if (is_array($value)) {
268
+						$c_input = '';
269
+						foreach ($value as $key => $val) {
270
+							$c_input .= self::adminMulti(
271
+								$default,
272
+								isset($classes[ $key ]) ? $classes[ $key ] : '',
273
+								$field_name . '_' . $value,
274
+								$name,
275
+								$required,
276
+								$tab_index,
277
+								$type,
278
+								$val,
279
+								isset($labels[ $key ]) ? $labels[ $key ] : ''
280
+							);
281
+						}
282
+						$field = $c_input;
283
+					} else {
284
+						$field = self::adminMulti(
285
+							$default,
286
+							$class,
287
+							$id,
288
+							$name,
289
+							$required,
290
+							$tab_index,
291
+							$type,
292
+							$value,
293
+							$_fields['label']
294
+						);
295
+					}
296
+					break;
297
+
298
+				case 'hidden':
299
+					$field = self::adminHidden($class, $id, $name, $value);
300
+					break;
301
+
302
+				case 'select':
303
+					$options = [];
304
+					foreach ($value as $key => $val) {
305
+						$options[ $val ] = isset($labels[ $key ]) ? $labels[ $key ] : '';
306
+					}
307
+					$field = self::adminSelect($default, $class, $id, $name, $required, $tab_index, $options);
308
+					break;
309
+
310
+				case 'textarea':
311
+					$field =
312
+						self::adminTextarea($class, $dims[0], $id, $name, $required, $dims[1], $tab_index, $value);
313
+					break;
314
+
315
+				case 'wp_editor':
316
+					$field = self::adminWpEditor(
317
+						$class,
318
+						$_fields['id'],
319
+						$name,
320
+						$dims[1],
321
+						$tab_index,
322
+						$value,
323
+						$wp_editor_args
324
+					);
325
+					break;
326
+
327
+				default:
328
+					$field = self::adminText($class, $id, $name, $required, $tab_index, $value);
329
+			}
330
+
331
+			$form_fields[ $field_name ] = ['label' => $label, 'field' => $field . $extra_desc];
332
+		}
333
+
334
+		return $form_fields;
335
+	}
336
+
337
+
338
+	/**
339
+	 * @param string $class
340
+	 * @param string $id
341
+	 * @param string $name
342
+	 * @param string $value
343
+	 * @return string
344
+	 * @since   4.10.14.p
345
+	 */
346
+	private static function adminHidden($class, $id, $name, $value)
347
+	{
348
+		$id    = esc_attr($id);
349
+		$name  = esc_attr($name);
350
+		$class = esc_attr($class);
351
+		return "
352 352
         <input name='{$name}' type='hidden' id='{$id}' class='{$class}' value='{$value}' />";
353
-    }
354
-
355
-
356
-    /**
357
-     * @param string $id
358
-     * @param string $label
359
-     * @param string $required
360
-     * @return string
361
-     * @since   4.10.14.p
362
-     */
363
-    private static function adminLabel($id, $label, $required)
364
-    {
365
-        $id       = esc_attr($id);
366
-        $label    = esc_html($label);
367
-        $required = filter_var($required, FILTER_VALIDATE_BOOLEAN) ? " <span>*</span>" : '';
368
-        return "<label for='{$id}'>{$label}{$required}</label>";
369
-    }
370
-
371
-
372
-    /**
373
-     * @param string $default
374
-     * @param string $class
375
-     * @param string $id
376
-     * @param string $name
377
-     * @param string $required
378
-     * @param int    $tab_index
379
-     * @param string $type
380
-     * @param string $value
381
-     * @param string $label
382
-     * @return string
383
-     * @since   4.10.14.p
384
-     */
385
-    private static function adminMulti($default, $class, $id, $name, $required, $tab_index, $type, $value, $label = '')
386
-    {
387
-        $id        = esc_attr($id);
388
-        $name      = esc_attr($name);
389
-        $class     = esc_attr($class);
390
-        $tab_index = absint($tab_index);
391
-        $checked   = ! empty($default) && $default == $value ? 'checked ' : '';
392
-        $required  = filter_var($required, FILTER_VALIDATE_BOOLEAN) ? 'required' : '';
393
-        $input     = "
353
+	}
354
+
355
+
356
+	/**
357
+	 * @param string $id
358
+	 * @param string $label
359
+	 * @param string $required
360
+	 * @return string
361
+	 * @since   4.10.14.p
362
+	 */
363
+	private static function adminLabel($id, $label, $required)
364
+	{
365
+		$id       = esc_attr($id);
366
+		$label    = esc_html($label);
367
+		$required = filter_var($required, FILTER_VALIDATE_BOOLEAN) ? " <span>*</span>" : '';
368
+		return "<label for='{$id}'>{$label}{$required}</label>";
369
+	}
370
+
371
+
372
+	/**
373
+	 * @param string $default
374
+	 * @param string $class
375
+	 * @param string $id
376
+	 * @param string $name
377
+	 * @param string $required
378
+	 * @param int    $tab_index
379
+	 * @param string $type
380
+	 * @param string $value
381
+	 * @param string $label
382
+	 * @return string
383
+	 * @since   4.10.14.p
384
+	 */
385
+	private static function adminMulti($default, $class, $id, $name, $required, $tab_index, $type, $value, $label = '')
386
+	{
387
+		$id        = esc_attr($id);
388
+		$name      = esc_attr($name);
389
+		$class     = esc_attr($class);
390
+		$tab_index = absint($tab_index);
391
+		$checked   = ! empty($default) && $default == $value ? 'checked ' : '';
392
+		$required  = filter_var($required, FILTER_VALIDATE_BOOLEAN) ? 'required' : '';
393
+		$input     = "
394 394
         <input name='{$name}[]' type='{$type}' id='{$id}' class='{$class}' value='{$value}' {$checked} {$required} tabindex='{$tab_index}'/>";
395
-        if ($label === '') {
396
-            return $input;
397
-        }
398
-        $label = esc_html($label);
399
-        return "
395
+		if ($label === '') {
396
+			return $input;
397
+		}
398
+		$label = esc_html($label);
399
+		return "
400 400
         <label for='$id'>
401 401
             {$input}
402 402
             {$label}
403 403
         </label>";
404
-    }
405
-
406
-
407
-    /**
408
-     * @param string $default
409
-     * @param string $class
410
-     * @param string $id
411
-     * @param string $name
412
-     * @param string $required
413
-     * @param int    $tab_index
414
-     * @param array  $options
415
-     * @return string
416
-     * @since   4.10.14.p
417
-     */
418
-    private static function adminSelect($default, $class, $id, $name, $required, $tab_index, $options = [])
419
-    {
420
-        $options_array = [];
421
-        foreach ($options as $value => $label) {
422
-            $selected        = ! empty($default) && $default == $value ? 'selected' : '';
423
-            $value           = esc_attr($value);
424
-            $label           = wp_strip_all_tags($label);
425
-            $options_array[] = "<option value='{$value}' {$selected}>{$label}</option>";
426
-        }
427
-        $options_html = implode($options_array, "\n");
428
-        $id           = esc_attr($id);
429
-        $name         = esc_attr($name);
430
-        $class        = esc_attr($class);
431
-        $tab_index    = absint($tab_index);
432
-        $required     = filter_var($required, FILTER_VALIDATE_BOOLEAN) ? 'required' : '';
433
-        return "
404
+	}
405
+
406
+
407
+	/**
408
+	 * @param string $default
409
+	 * @param string $class
410
+	 * @param string $id
411
+	 * @param string $name
412
+	 * @param string $required
413
+	 * @param int    $tab_index
414
+	 * @param array  $options
415
+	 * @return string
416
+	 * @since   4.10.14.p
417
+	 */
418
+	private static function adminSelect($default, $class, $id, $name, $required, $tab_index, $options = [])
419
+	{
420
+		$options_array = [];
421
+		foreach ($options as $value => $label) {
422
+			$selected        = ! empty($default) && $default == $value ? 'selected' : '';
423
+			$value           = esc_attr($value);
424
+			$label           = wp_strip_all_tags($label);
425
+			$options_array[] = "<option value='{$value}' {$selected}>{$label}</option>";
426
+		}
427
+		$options_html = implode($options_array, "\n");
428
+		$id           = esc_attr($id);
429
+		$name         = esc_attr($name);
430
+		$class        = esc_attr($class);
431
+		$tab_index    = absint($tab_index);
432
+		$required     = filter_var($required, FILTER_VALIDATE_BOOLEAN) ? 'required' : '';
433
+		return "
434 434
         <select name='{$name}' id='{$id}' class='{$class}' {$required} tabindex='{$tab_index}'>
435 435
             {$options_html}
436 436
         </select>";
437
-    }
438
-
439
-
440
-    /**
441
-     * @param string $class
442
-     * @param string $id
443
-     * @param string $name
444
-     * @param string $required
445
-     * @param int    $tab_index
446
-     * @param string $value
447
-     * @return string
448
-     * @since   4.10.14.p
449
-     */
450
-    private static function adminText($class, $id, $name, $required, $tab_index, $value)
451
-    {
452
-        $id        = esc_attr($id);
453
-        $name      = esc_attr($name);
454
-        $class     = esc_attr($class);
455
-        $tab_index = absint($tab_index);
456
-        $required  = filter_var($required, FILTER_VALIDATE_BOOLEAN) ? 'required' : '';
457
-        return "
437
+	}
438
+
439
+
440
+	/**
441
+	 * @param string $class
442
+	 * @param string $id
443
+	 * @param string $name
444
+	 * @param string $required
445
+	 * @param int    $tab_index
446
+	 * @param string $value
447
+	 * @return string
448
+	 * @since   4.10.14.p
449
+	 */
450
+	private static function adminText($class, $id, $name, $required, $tab_index, $value)
451
+	{
452
+		$id        = esc_attr($id);
453
+		$name      = esc_attr($name);
454
+		$class     = esc_attr($class);
455
+		$tab_index = absint($tab_index);
456
+		$required  = filter_var($required, FILTER_VALIDATE_BOOLEAN) ? 'required' : '';
457
+		return "
458 458
         <input name='{$name}' type='text' id='{$id}' class='{$class}' value='{$value}' {$required} tabindex='{$tab_index}'/>";
459
-    }
460
-
461
-
462
-    /**
463
-     * @param string $class
464
-     * @param int    $cols
465
-     * @param string $id
466
-     * @param string $name
467
-     * @param string $required
468
-     * @param int    $rows
469
-     * @param int    $tab_index
470
-     * @param string $value
471
-     * @return string
472
-     * @since   4.10.14.p
473
-     */
474
-    private static function adminTextarea($class, $cols, $id, $name, $required, $rows, $tab_index, $value)
475
-    {
476
-        $id        = esc_attr($id);
477
-        $name      = esc_attr($name);
478
-        $class     = esc_attr($class);
479
-        $cols      = absint($cols);
480
-        $rows      = absint($rows);
481
-        $value     = esc_textarea($value);
482
-        $tab_index = absint($tab_index);
483
-        $required  = filter_var($required, FILTER_VALIDATE_BOOLEAN) ? 'required' : '';
484
-        return "
459
+	}
460
+
461
+
462
+	/**
463
+	 * @param string $class
464
+	 * @param int    $cols
465
+	 * @param string $id
466
+	 * @param string $name
467
+	 * @param string $required
468
+	 * @param int    $rows
469
+	 * @param int    $tab_index
470
+	 * @param string $value
471
+	 * @return string
472
+	 * @since   4.10.14.p
473
+	 */
474
+	private static function adminTextarea($class, $cols, $id, $name, $required, $rows, $tab_index, $value)
475
+	{
476
+		$id        = esc_attr($id);
477
+		$name      = esc_attr($name);
478
+		$class     = esc_attr($class);
479
+		$cols      = absint($cols);
480
+		$rows      = absint($rows);
481
+		$value     = esc_textarea($value);
482
+		$tab_index = absint($tab_index);
483
+		$required  = filter_var($required, FILTER_VALIDATE_BOOLEAN) ? 'required' : '';
484
+		return "
485 485
         <textarea name='{$name}' id='{$id}' class='{$class}' rows='{$rows}' cols='{$cols}' {$required} tabindex='{$tab_index}'>
486 486
             {$value}
487 487
         </textarea>";
488
-    }
489
-
490
-
491
-    /**
492
-     * @param string $class
493
-     * @param string $id
494
-     * @param string $name
495
-     * @param int    $rows
496
-     * @param int    $tab_index
497
-     * @param string $value
498
-     * @param array  $wp_editor_args
499
-     * @return false|string
500
-     * @since   4.10.14.p
501
-     */
502
-    private static function adminWpEditor($class, $id, $name, $rows, $tab_index, $value, $wp_editor_args = [])
503
-    {
504
-        $editor_settings = $wp_editor_args + [
505
-                'textarea_name' => esc_attr($name),
506
-                'textarea_rows' => absint($rows),
507
-                'editor_class'  => esc_attr($class),
508
-                'tabindex'      => absint($tab_index),
509
-            ];
510
-        ob_start();
511
-        wp_editor($value, esc_attr($id), $editor_settings);
512
-        return ob_get_clean();
513
-    }
514
-
515
-
516
-    /**
517
-     * espresso admin page select_input
518
-     * Turns an array into a select fields
519
-     *
520
-     * @static
521
-     * @access public
522
-     * @param string  $name       field name
523
-     * @param array   $values     option values, numbered array starting at 0, where each value is an array with a key
524
-     *                            'text' (meaning text to display' and 'id' (meaning the internal value) eg:
525
-     *                            array(1=>array('text'=>'Monday','id'=>1),2=>array('text'=>'Tuesday','id'=>2)...). or
526
-     *                            as an array of key-value pairs, where the key is to be used for the select input's
527
-     *                            name, and the value will be the text shown to the user.  Optionally you can also
528
-     *                            include an additional key of "class" which will add a specific class to the option
529
-     *                            for that value.
530
-     * @param string  $default    default value
531
-     * @param string  $parameters extra parameters
532
-     * @param string  $class      css class
533
-     * @param boolean $autosize   whether to autosize the select or not
534
-     * @return string              html string for the select input
535
-     */
536
-    public static function select_input($name, $values, $default = '', $parameters = '', $class = '', $autosize = true)
537
-    {
538
-        // if $values was submitted in the wrong format, convert it over
539
-        if (! empty($values) && (! array_key_exists(0, $values) || ! is_array($values[0]))) {
540
-            $converted_values = [];
541
-            foreach ($values as $id => $text) {
542
-                $converted_values[] = ['id' => $id, 'text' => $text];
543
-            }
544
-            $values = $converted_values;
545
-        }
546
-
547
-        $field =
548
-            '<select id="' . EEH_Formatter::ee_tep_output_string($name)
549
-            . '" name="' . EEH_Formatter::ee_tep_output_string($name)
550
-            . '"';
551
-
552
-        if (EEH_Formatter::ee_tep_not_null($parameters)) {
553
-            $field .= ' ' . $parameters;
554
-        }
555
-        if ($autosize) {
556
-            $size = 'med';
557
-            for ($ii = 0, $ni = sizeof($values); $ii < $ni; $ii++) {
558
-                if ($values[ $ii ]['text']) {
559
-                    if (strlen($values[ $ii ]['text']) > 5) {
560
-                        $size = 'wide';
561
-                    }
562
-                }
563
-            }
564
-        } else {
565
-            $size = '';
566
-        }
567
-
568
-        $field .= ' class="' . $class . ' ' . $size . '">';
569
-
570
-        if (empty($default) && isset($GLOBALS[ $name ])) {
571
-            $default = stripslashes($GLOBALS[ $name ]);
572
-        }
573
-
574
-
575
-        for ($i = 0, $n = sizeof($values); $i < $n; $i++) {
576
-            $field .= '<option value="' . $values[ $i ]['id'] . '"';
577
-            if ($default == $values[ $i ]['id']) {
578
-                $field .= ' selected = "selected"';
579
-            }
580
-            if (isset($values[ $i ]['class'])) {
581
-                $field .= ' class="' . $values[ $i ]['class'] . '"';
582
-            }
583
-            $field .= '>' . $values[ $i ]['text'] . '</option>';
584
-        }
585
-        $field .= '</select>';
586
-
587
-        return $field;
588
-    }
589
-
590
-
591
-    /**
592
-     * generate_question_groups_html
593
-     *
594
-     * @param array  $question_groups
595
-     * @param string $group_wrapper
596
-     * @return string HTML
597
-     * @throws EE_Error
598
-     * @throws ReflectionException
599
-     */
600
-    public static function generate_question_groups_html($question_groups = [], $group_wrapper = 'fieldset')
601
-    {
602
-
603
-        $html                            = '';
604
-        $before_question_group_questions =
605
-            apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions', '');
606
-        $after_question_group_questions  =
607
-            apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', '');
608
-
609
-        if (! empty($question_groups)) {
610
-            // loop thru question groups
611
-            foreach ($question_groups as $QSG) {
612
-                // check that questions exist
613
-                if (! empty($QSG['QSG_questions'])) {
614
-                    // use fieldsets
615
-                    $html .= "\n\t"
616
-                             . '<'
617
-                             . $group_wrapper
618
-                             . ' class="espresso-question-group-wrap" id="'
619
-                             . $QSG['QSG_identifier']
620
-                             . '">';
621
-                    // group_name
622
-                    $html .= $QSG['QSG_show_group_name']
623
-                        ? "\n\t\t"
624
-                          . '<h5 class="espresso-question-group-title-h5 section-title">'
625
-                          . self::prep_answer($QSG['QSG_name'])
626
-                          . '</h5>'
627
-                        : '';
628
-                    // group_desc
629
-                    $html .= $QSG['QSG_show_group_desc'] && ! empty($QSG['QSG_desc'])
630
-                        ? '<div class="espresso-question-group-desc-pg">'
631
-                          . self::prep_answer($QSG['QSG_desc'])
632
-                          . '</div>'
633
-                        : '';
634
-
635
-                    $html .= $before_question_group_questions;
636
-                    // loop thru questions
637
-                    foreach ($QSG['QSG_questions'] as $question) {
638
-                        $QFI  = new EE_Question_Form_Input(
639
-                            $question['qst_obj'],
640
-                            $question['ans_obj'],
641
-                            $question
642
-                        );
643
-                        $html .= self::generate_form_input($QFI);
644
-                    }
645
-                    $html .= $after_question_group_questions;
646
-                    $html .= "\n\t" . '</' . $group_wrapper . '>';
647
-                }
648
-            }
649
-        }
650
-
651
-        return $html;
652
-    }
653
-
654
-
655
-    /**
656
-     * generate_question_groups_html
657
-     *
658
-     * @param array  $question_groups
659
-     * @param array  $q_meta
660
-     * @param bool   $from_admin
661
-     * @param string $group_wrapper
662
-     * @return string HTML
663
-     * @throws EE_Error
664
-     * @throws ReflectionException
665
-     */
666
-    public static function generate_question_groups_html2(
667
-        $question_groups = [],
668
-        $q_meta = [],
669
-        $from_admin = false,
670
-        $group_wrapper = 'fieldset'
671
-    ) {
672
-
673
-        $html                            = '';
674
-        $before_question_group_questions =
675
-            apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions', '');
676
-        $after_question_group_questions  =
677
-            apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', '');
678
-
679
-        $default_q_meta = [
680
-            'att_nmbr'    => 1,
681
-            'ticket_id'   => '',
682
-            'input_name'  => '',
683
-            'input_id'    => '',
684
-            'input_class' => '',
685
-        ];
686
-        $q_meta         = array_merge($default_q_meta, $q_meta);
687
-
688
-        if (! empty($question_groups)) {
689
-            // loop thru question groups
690
-            foreach ($question_groups as $QSG) {
691
-                if ($QSG instanceof EE_Question_Group) {
692
-                    // check that questions exist
693
-
694
-                    $where = ['QST_deleted' => 0];
695
-                    if (! $from_admin) {
696
-                        $where['QST_admin_only'] = 0;
697
-                    }
698
-                    $questions =
699
-                        $QSG->questions([$where, 'order_by' => ['Question_Group_Question.QGQ_order' => 'ASC']]);
700
-                    if (! empty($questions)) {
701
-                        // use fieldsets
702
-                        $html .= "\n\t"
703
-                                 . '<' . $group_wrapper . ' class="espresso-question-group-wrap" '
704
-                                 . 'id="' . $QSG->get('QSG_identifier') . '">';
705
-                        // group_name
706
-                        if ($QSG->show_group_name()) {
707
-                            $html .= "\n\t\t"
708
-                                     . '<h5 class="espresso-question-group-title-h5 section-title">'
709
-                                     . $QSG->get_pretty('QSG_name')
710
-                                     . '</h5>';
711
-                        }
712
-                        // group_desc
713
-                        if ($QSG->show_group_desc()) {
714
-                            $html .= '<div class="espresso-question-group-desc-pg">'
715
-                                     . $QSG->get_pretty('QSG_desc')
716
-                                     . '</div>';
717
-                        }
718
-
719
-                        $html .= $before_question_group_questions;
720
-                        // loop thru questions
721
-                        foreach ($questions as $QST) {
722
-                            $qstn_id = $QST->is_system_question() ? $QST->system_ID() : $QST->ID();
723
-
724
-                            $answer = null;
725
-
726
-                            /** @var RequestInterface $request */
727
-                            $request      = LoaderFactory::getLoader()->getShared(RequestInterface::class);
728
-                            $request_qstn = $request->getRequestParam('qstn', [], 'string', true);
729
-                            if (! empty($request_qstn) && isset($q_meta['input_id']) && isset($q_meta['att_nmbr'])) {
730
-                                // check for answer in $request_qstn in case we are reprocessing a form after an error
731
-                                if (isset($request_qstn[ $q_meta['input_id'] ][ $qstn_id ])) {
732
-                                    $answer = is_array($request_qstn[ $q_meta['input_id'] ][ $qstn_id ])
733
-                                        ? $request_qstn[ $q_meta['input_id'] ][ $qstn_id ]
734
-                                        : sanitize_text_field($request_qstn[ $q_meta['input_id'] ][ $qstn_id ]);
735
-                                }
736
-                            } elseif (isset($q_meta['attendee']) && $q_meta['attendee']) {
737
-                                // attendee data from the session
738
-                                $answer =
739
-                                    isset($q_meta['attendee'][ $qstn_id ]) ? $q_meta['attendee'][ $qstn_id ] : null;
740
-                            }
741
-
742
-
743
-                            $QFI  = new EE_Question_Form_Input(
744
-                                $QST,
745
-                                EE_Answer::new_instance(
746
-                                    [
747
-                                        'ANS_ID'    => 0,
748
-                                        'QST_ID'    => 0,
749
-                                        'REG_ID'    => 0,
750
-                                        'ANS_value' => $answer,
751
-                                    ]
752
-                                ),
753
-                                $q_meta
754
-                            );
755
-                            $html .= self::generate_form_input($QFI);
756
-                        }
757
-                        $html .= $after_question_group_questions;
758
-                        $html .= "\n\t" . '</' . $group_wrapper . '>';
759
-                    }
760
-                }
761
-            }
762
-        }
763
-        return $html;
764
-    }
765
-
766
-
767
-    /**
768
-     * generate_form_input
769
-     *
770
-     * @param EE_Question_Form_Input $QFI
771
-     * @return string HTML
772
-     * @throws EE_Error
773
-     * @throws ReflectionException
774
-     */
775
-    public static function generate_form_input(EE_Question_Form_Input $QFI)
776
-    {
777
-        if (isset($QFI->QST_admin_only) && $QFI->QST_admin_only && ! is_admin()) {
778
-            return '';
779
-        }
780
-        /** @var RequestInterface $request */
781
-        $request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
782
-
783
-        $QFI = self::_load_system_dropdowns($QFI);
784
-        $QFI = self::_load_specialized_dropdowns($QFI);
785
-
786
-        // we also need to verify
787
-
788
-        $display_text = $QFI->get('QST_display_text');
789
-        $input_name   = $QFI->get('QST_input_name');
790
-        $answer       = $request->getRequestParam($input_name, $QFI->get('ANS_value'));
791
-        $input_id     = $QFI->get('QST_input_id');
792
-        $input_class  = $QFI->get('QST_input_class');
793
-        //      $disabled = $QFI->get('QST_disabled') ? ' disabled="disabled"' : '';
794
-        $disabled          = $QFI->get('QST_disabled');
795
-        $required_label    = apply_filters(' FHEE__EEH_Form_Fields__generate_form_input__required_label', '<em>*</em>');
796
-        $QST_required      = $QFI->get('QST_required');
797
-        $required          =
798
-            $QST_required
799
-                ? ['label' => $required_label, 'class' => 'required needs-value', 'title' => $QST_required]
800
-                : [];
801
-        $use_html_entities = $QFI->get_meta('htmlentities');
802
-        $required_text     =
803
-            $QFI->get('QST_required_text') != ''
804
-                ? $QFI->get('QST_required_text')
805
-                : esc_html__('This field is required', 'event_espresso');
806
-        $required_text     = $QST_required
807
-            ? "\n\t\t\t"
808
-              . '<div class="required-text hidden">'
809
-              . self::prep_answer($required_text, $use_html_entities)
810
-              . '</div>'
811
-            : '';
812
-        $label_class       = 'espresso-form-input-lbl';
813
-        $QST_options       = $QFI->options(true, $answer);
814
-        $options           = is_array($QST_options) ? self::prep_answer_options($QST_options) : [];
815
-        $system_ID         = $QFI->get('QST_system');
816
-        $label_b4          = $QFI->get_meta('label_b4');
817
-        $use_desc_4_label  = $QFI->get_meta('use_desc_4_label');
818
-
819
-
820
-        switch ($QFI->get('QST_type')) {
821
-            case 'TEXTAREA':
822
-                return EEH_Form_Fields::textarea(
823
-                    $display_text,
824
-                    $answer,
825
-                    $input_name,
826
-                    $input_id,
827
-                    $input_class,
828
-                    [],
829
-                    $required,
830
-                    $required_text,
831
-                    $label_class,
832
-                    $disabled,
833
-                    $system_ID,
834
-                    $use_html_entities
835
-                );
836
-
837
-            case 'DROPDOWN':
838
-                return EEH_Form_Fields::select(
839
-                    $display_text,
840
-                    $answer,
841
-                    $options,
842
-                    $input_name,
843
-                    $input_id,
844
-                    $input_class,
845
-                    $required,
846
-                    $required_text,
847
-                    $label_class,
848
-                    $disabled,
849
-                    $system_ID,
850
-                    $use_html_entities,
851
-                    true
852
-                );
853
-
854
-
855
-            case 'RADIO_BTN':
856
-                return EEH_Form_Fields::radio(
857
-                    $display_text,
858
-                    $answer,
859
-                    $options,
860
-                    $input_name,
861
-                    $input_id,
862
-                    $input_class,
863
-                    $required,
864
-                    $required_text,
865
-                    $label_class,
866
-                    $disabled,
867
-                    $system_ID,
868
-                    $use_html_entities,
869
-                    $label_b4,
870
-                    $use_desc_4_label
871
-                );
872
-
873
-            case 'CHECKBOX':
874
-                return EEH_Form_Fields::checkbox(
875
-                    $display_text,
876
-                    $answer,
877
-                    $options,
878
-                    $input_name,
879
-                    $input_id,
880
-                    $input_class,
881
-                    $required,
882
-                    $required_text,
883
-                    $label_class,
884
-                    $disabled,
885
-                    $label_b4,
886
-                    $system_ID,
887
-                    $use_html_entities
888
-                );
889
-
890
-            case 'DATE':
891
-                return EEH_Form_Fields::datepicker(
892
-                    $display_text,
893
-                    $answer,
894
-                    $input_name,
895
-                    $input_id,
896
-                    $input_class,
897
-                    $required,
898
-                    $required_text,
899
-                    $label_class,
900
-                    $disabled,
901
-                    $system_ID,
902
-                    $use_html_entities
903
-                );
904
-
905
-            case 'TEXT':
906
-            default:
907
-                return EEH_Form_Fields::text(
908
-                    $display_text,
909
-                    $answer,
910
-                    $input_name,
911
-                    $input_id,
912
-                    $input_class,
913
-                    $required,
914
-                    $required_text,
915
-                    $label_class,
916
-                    $disabled,
917
-                    $system_ID,
918
-                    $use_html_entities
919
-                );
920
-        }
921
-    }
922
-
923
-
924
-    /**
925
-     * generates HTML for a form text input
926
-     *
927
-     * @param string $question    label content
928
-     * @param string $answer      form input value attribute
929
-     * @param string $name        form input name attribute
930
-     * @param string $id          form input css id attribute
931
-     * @param string $class       form input css class attribute
932
-     * @param array  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
933
-     *                            required 'class', and required 'msg' attribute
934
-     * @param string $label_class css class attribute for the label
935
-     * @param string $disabled    disabled="disabled" or null
936
-     * @return string HTML
937
-     */
938
-    public static function text(
939
-        $question = false,
940
-        $answer = null,
941
-        $name = false,
942
-        $id = '',
943
-        $class = '',
944
-        $required = false,
945
-        $required_text = '',
946
-        $label_class = '',
947
-        $disabled = false,
948
-        $system_ID = false,
949
-        $use_html_entities = true
950
-    ) {
951
-        // need these
952
-        if (! $question || ! $name) {
953
-            return null;
954
-        }
955
-        // prep the answer
956
-        $answer = is_array($answer) ? '' : self::prep_answer($answer, $use_html_entities);
957
-        // prep the required array
958
-        $required = self::prep_required($required);
959
-        // set disabled tag
960
-        $disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
961
-        // ya gots ta have style man!!!
962
-        $txt_class = is_admin() ? 'regular-text' : 'espresso-text-inp';
963
-        $class     = empty($class) ? $txt_class : $class;
964
-        $class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
965
-        $extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
966
-
967
-        $label_html =
968
-            $required_text
969
-            . "\n\t\t\t"
970
-            . '<label for="' . $name . '" class="' . $label_class . '">'
971
-            . self::prep_question($question)
972
-            . $required['label']
973
-            . '</label><br/>';
974
-        // filter label but ensure required text comes before it
975
-        $label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
976
-
977
-        $input_html =
978
-            "\n\t\t\t"
979
-            . '<input type="text" name="' . $name . '" id="' . $id . '" '
980
-            . 'class="' . $class . ' ' . $required['class'] . '" value="' . esc_attr($answer) . '"  '
981
-            . 'title="' . esc_attr($required['msg']) . '" ' . $disabled . ' ' . $extra . '/>';
982
-
983
-        $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
984
-        return $label_html . $input_html;
985
-    }
986
-
987
-
988
-    /**
989
-     * generates HTML for a form textarea
990
-     *
991
-     * @param string $question    label content
992
-     * @param string $answer      form input value attribute
993
-     * @param string $name        form input name attribute
994
-     * @param string $id          form input css id attribute
995
-     * @param string $class       form input css class attribute
996
-     * @param array  $dimensions  array of form input rows and cols attributes : array( 'rows' => 3, 'cols' => 40 )
997
-     * @param array  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
998
-     *                            required 'class', and required 'msg' attribute
999
-     * @param string $label_class css class attribute for the label
1000
-     * @param string $disabled    disabled="disabled" or null
1001
-     * @return string HTML
1002
-     */
1003
-    public static function textarea(
1004
-        $question = false,
1005
-        $answer = null,
1006
-        $name = false,
1007
-        $id = '',
1008
-        $class = '',
1009
-        $dimensions = false,
1010
-        $required = false,
1011
-        $required_text = '',
1012
-        $label_class = '',
1013
-        $disabled = false,
1014
-        $system_ID = false,
1015
-        $use_html_entities = true
1016
-    ) {
1017
-        // need these
1018
-        if (! $question || ! $name) {
1019
-            return null;
1020
-        }
1021
-        // prep the answer
1022
-        $answer = is_array($answer) ? '' : self::prep_answer($answer, $use_html_entities);
1023
-        // prep the required array
1024
-        $required = self::prep_required($required);
1025
-        // make sure $dimensions is an array
1026
-        $dimensions = is_array($dimensions) ? $dimensions : [];
1027
-        // and set some defaults
1028
-        $dimensions = array_merge(['rows' => 3, 'cols' => 40], $dimensions);
1029
-        // set disabled tag
1030
-        $disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1031
-        // ya gots ta have style man!!!
1032
-        $txt_class = is_admin() ? 'regular-text' : 'espresso-textarea-inp';
1033
-        $class     = empty($class) ? $txt_class : $class;
1034
-        $class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
1035
-        $extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1036
-
1037
-        $label_html =
1038
-            $required_text
1039
-            . "\n\t\t\t"
1040
-            . '<label for="' . $name . '" class="' . $label_class . '">'
1041
-            . self::prep_question($question)
1042
-            . $required['label']
1043
-            . '</label><br/>';
1044
-        // filter label but ensure required text comes before it
1045
-        $label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
1046
-
1047
-        $input_html =
1048
-            "\n\t\t\t"
1049
-            . '<textarea name="' . $name . '" id="' . $id . '" class="' . $class . ' ' . $required['class'] . '" '
1050
-            . 'rows="' . $dimensions['rows'] . '" cols="' . $dimensions['cols'] . '"  '
1051
-            . 'title="' . $required['msg'] . '" ' . $disabled . ' ' . $extra . '>'
1052
-            . esc_textarea($answer)
1053
-            . '</textarea>';
1054
-
1055
-        $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1056
-        return $label_html . $input_html;
1057
-    }
1058
-
1059
-
1060
-    /**
1061
-     * generates HTML for a form select input
1062
-     *
1063
-     * @param string $question    label content
1064
-     * @param string $answer      form input value attribute
1065
-     * @param array  $options     array of answer options where array key = option value and array value = option
1066
-     *                            display text
1067
-     * @param string $name        form input name attribute
1068
-     * @param string $id          form input css id attribute
1069
-     * @param string $class       form input css class attribute
1070
-     * @param array  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
1071
-     *                            required 'class', and required 'msg' attribute
1072
-     * @param string $label_class css class attribute for the label
1073
-     * @param string $disabled    disabled="disabled" or null
1074
-     * @return string HTML
1075
-     */
1076
-    public static function select(
1077
-        $question = false,
1078
-        $answer = null,
1079
-        $options = false,
1080
-        $name = false,
1081
-        $id = '',
1082
-        $class = '',
1083
-        $required = false,
1084
-        $required_text = '',
1085
-        $label_class = '',
1086
-        $disabled = false,
1087
-        $system_ID = false,
1088
-        $use_html_entities = true,
1089
-        $add_please_select_option = false
1090
-    ) {
1091
-
1092
-        // need these
1093
-        if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1094
-            return null;
1095
-        }
1096
-        // prep the answer
1097
-        $answer =
1098
-            is_array($answer)
1099
-                ? self::prep_answer(array_shift($answer), $use_html_entities)
1100
-                : self::prep_answer(
1101
-                    $answer,
1102
-                    $use_html_entities
1103
-                );
1104
-        // prep the required array
1105
-        $required = self::prep_required($required);
1106
-        // set disabled tag
1107
-        $disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1108
-        // ya gots ta have style man!!!
1109
-        $txt_class = is_admin() ? 'wide' : 'espresso-select-inp';
1110
-        $class     = empty($class) ? $txt_class : $class;
1111
-        $class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
1112
-        $extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1113
-
1114
-        $label_html =
1115
-            $required_text
1116
-            . "\n\t\t\t"
1117
-            . '<label for="' . $name . '" class="' . $label_class . '">'
1118
-            . self::prep_question($question)
1119
-            . $required['label']
1120
-            . '</label><br/>';
1121
-        // filter label but ensure required text comes before it
1122
-        $label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
1123
-
1124
-        $input_html =
1125
-            "\n\t\t\t"
1126
-            . '<select name="' . $name . '" id="' . $id . '" class="' . $class . ' ' . $required['class'] . '" '
1127
-            . 'title="' . esc_attr($required['msg']) . '"' . $disabled . ' ' . $extra . '>';
1128
-        // recursively count array elements, to determine total number of options
1129
-        $only_option = count($options, 1) == 1;
1130
-        if (! $only_option) {
1131
-            // if there is NO answer set and there are multiple options to choose from, then set the "please select" message as selected
1132
-            $selected   = $answer === null ? ' selected' : '';
1133
-            $input_html .= $add_please_select_option
1134
-                ? "\n\t\t\t\t"
1135
-                  . '<option value=""' . $selected . '>'
1136
-                  . esc_html__(' - please select - ', 'event_espresso')
1137
-                  . '</option>'
1138
-                : '';
1139
-        }
1140
-        foreach ($options as $key => $value) {
1141
-            // if value is an array, then create option groups, else create regular ol' options
1142
-            $input_html .= is_array($value)
1143
-                ? self::_generate_select_option_group(
1144
-                    $key,
1145
-                    $value,
1146
-                    $answer,
1147
-                    $use_html_entities
1148
-                )
1149
-                : self::_generate_select_option(
1150
-                    $value->value(),
1151
-                    $value->desc(),
1152
-                    $answer,
1153
-                    $only_option,
1154
-                    $use_html_entities
1155
-                );
1156
-        }
1157
-
1158
-        $input_html .= "\n\t\t\t" . '</select>';
1159
-
1160
-        $input_html =
1161
-            apply_filters(
1162
-                'FHEE__EEH_Form_Fields__select__before_end_wrapper',
1163
-                $input_html,
1164
-                $question,
1165
-                $answer,
1166
-                $name,
1167
-                $id,
1168
-                $class,
1169
-                $system_ID
1170
-            );
1171
-
1172
-        $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1173
-        return $label_html . $input_html;
1174
-    }
1175
-
1176
-
1177
-    /**
1178
-     *  _generate_select_option_group
1179
-     *
1180
-     *  if  $value for a select box is an array, then the key will be used as the optgroup label
1181
-     *  and the value array will be looped thru and the elements sent to _generate_select_option
1182
-     *
1183
-     * @param mixed   $opt_group
1184
-     * @param mixed   $QSOs
1185
-     * @param mixed   $answer
1186
-     * @param boolean $use_html_entities
1187
-     * @return string
1188
-     */
1189
-    private static function _generate_select_option_group($opt_group, $QSOs, $answer, $use_html_entities = true)
1190
-    {
1191
-        $html = "\n\t\t\t\t" . '<optgroup label="' . self::prep_option_value($opt_group) . '">';
1192
-        foreach ($QSOs as $QSO) {
1193
-            $html .= self::_generate_select_option($QSO->value(), $QSO->desc(), $answer, false, $use_html_entities);
1194
-        }
1195
-        $html .= "\n\t\t\t\t" . '</optgroup>';
1196
-        return $html;
1197
-    }
1198
-
1199
-
1200
-    /**
1201
-     *  _generate_select_option
1202
-     *
1203
-     * @param mixed   $key
1204
-     * @param mixed   $value
1205
-     * @param mixed   $answer
1206
-     * @param int     $only_option
1207
-     * @param boolean $use_html_entities
1208
-     * @return string
1209
-     */
1210
-    private static function _generate_select_option(
1211
-        $key,
1212
-        $value,
1213
-        $answer,
1214
-        $only_option = false,
1215
-        $use_html_entities = true
1216
-    ) {
1217
-        $key      = self::prep_answer($key, $use_html_entities);
1218
-        $value    = self::prep_answer($value, $use_html_entities);
1219
-        $value    = ! empty($value) ? $value : $key;
1220
-        $selected = ($answer == $key || $only_option) ? 'selected' : '';
1221
-        return "\n\t\t\t\t"
1222
-               . '<option value="' . self::prep_option_value($key) . '" ' . $selected . '> '
1223
-               . $value
1224
-               . '&nbsp;&nbsp;&nbsp;</option>';
1225
-    }
1226
-
1227
-
1228
-    /**
1229
-     * generates HTML for form radio button inputs
1230
-     *
1231
-     * @param bool|string $question    label content
1232
-     * @param string      $answer      form input value attribute
1233
-     * @param array|bool  $options     array of answer options where array key = option value and array value = option
1234
-     *                                 display text
1235
-     * @param bool|string $name        form input name attribute
1236
-     * @param string      $id          form input css id attribute
1237
-     * @param string      $class       form input css class attribute
1238
-     * @param array|bool  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
1239
-     *                                 required 'class', and required 'msg' attribute
1240
-     * @param string      $required_text
1241
-     * @param string      $label_class css class attribute for the label
1242
-     * @param bool|string $disabled    disabled="disabled" or null
1243
-     * @param bool        $system_ID
1244
-     * @param bool        $use_html_entities
1245
-     * @param bool        $label_b4
1246
-     * @param bool        $use_desc_4_label
1247
-     * @return string HTML
1248
-     */
1249
-    public static function radio(
1250
-        $question = false,
1251
-        $answer = null,
1252
-        $options = false,
1253
-        $name = false,
1254
-        $id = '',
1255
-        $class = '',
1256
-        $required = false,
1257
-        $required_text = '',
1258
-        $label_class = '',
1259
-        $disabled = false,
1260
-        $system_ID = false,
1261
-        $use_html_entities = true,
1262
-        $label_b4 = false,
1263
-        $use_desc_4_label = false
1264
-    ) {
1265
-        // need these
1266
-        if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1267
-            return null;
1268
-        }
1269
-        // prep the answer
1270
-        $answer = is_array($answer) ? '' : self::prep_answer($answer, $use_html_entities);
1271
-        // prep the required array
1272
-        $required = self::prep_required($required);
1273
-        // set disabled tag
1274
-        $disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1275
-        // ya gots ta have style man!!!
1276
-        $radio_class = is_admin() ? 'ee-admin-radio-lbl' : $label_class;
1277
-        $class       = ! empty($class) ? $class : 'espresso-radio-btn-inp';
1278
-        $extra       = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1279
-
1280
-        $label_html =
1281
-            $required_text
1282
-            . "\n\t\t\t"
1283
-            . '<label class="' . $label_class . '">'
1284
-            . self::prep_question($question)
1285
-            . $required['label']
1286
-            . '</label> ';
1287
-        // filter label but ensure required text comes before it
1288
-        $label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
1289
-
1290
-        $input_html =
1291
-            "\n\t\t\t"
1292
-            . '<ul id="' . $id . '-ul" class="espresso-radio-btn-options-ul ' . $label_class . ' ' . $class . '-ul">';
1293
-
1294
-        $class .= ! empty($system_ID) ? ' ' . $system_ID : '';
1295
-        $class .= ! empty($required['class']) ? ' ' . $required['class'] : '';
1296
-
1297
-        foreach ($options as $OPT) {
1298
-            if ($OPT instanceof EE_Question_Option) {
1299
-                $value   = self::prep_option_value($OPT->value());
1300
-                $label   = $use_desc_4_label ? $OPT->desc() : $OPT->value();
1301
-                $size    = $use_desc_4_label
1302
-                    ? self::get_label_size_class($OPT->value() . ' ' . $OPT->desc())
1303
-                    : self::get_label_size_class($OPT->value());
1304
-                $desc    = $OPT->desc();// no self::prep_answer
1305
-                $answer  = is_numeric($value) && empty($answer) ? 0 : $answer;
1306
-                $checked = (string) $value == (string) $answer ? ' checked' : '';
1307
-                $opt     = '-' . sanitize_key($value);
1308
-
1309
-                $input_html .= "\n\t\t\t\t" . '<li' . $size . '>';
1310
-                $input_html .= "\n\t\t\t\t\t" . '<label class="' . $radio_class . ' espresso-radio-btn-lbl">';
1311
-                $input_html .= $label_b4 ? "\n\t\t\t\t\t\t" . '<span>' . $label . '</span>' : '';
1312
-                $input_html .= "\n\t\t\t\t\t\t"
1313
-                               . '<input type="radio" name="' . $name . '" id="' . $id . $opt . '" '
1314
-                               . 'class="' . $class . '" value="' . $value . '" '
1315
-                               . 'title="' . esc_attr($required['msg']) . '" ' . $disabled
1316
-                               . $checked . ' ' . $extra . '/>';
1317
-                $input_html .= ! $label_b4
1318
-                    ? "\n\t\t\t\t\t\t"
1319
-                      . '<span class="espresso-radio-btn-desc">'
1320
-                      . $label
1321
-                      . '</span>'
1322
-                    : '';
1323
-                $input_html .= "\n\t\t\t\t\t" . '</label>';
1324
-                $input_html .= $use_desc_4_label
1325
-                    ? ''
1326
-                    : '<span class="espresso-radio-btn-option-desc small-text grey-text">' . $desc . '</span>';
1327
-                $input_html .= "\n\t\t\t\t" . '</li>';
1328
-            }
1329
-        }
1330
-
1331
-        $input_html .= "\n\t\t\t" . '</ul>';
1332
-
1333
-        $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1334
-        return $label_html . $input_html;
1335
-    }
1336
-
1337
-
1338
-    /**
1339
-     * generates HTML for form checkbox inputs
1340
-     *
1341
-     * @param string $question    label content
1342
-     * @param string $answer      form input value attribute
1343
-     * @param array  $options     array of options where array key = option value and array value = option display text
1344
-     * @param string $name        form input name attribute
1345
-     * @param string $id          form input css id attribute
1346
-     * @param string $class       form input css class attribute
1347
-     * @param array  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
1348
-     *                            required 'class', and required 'msg' attribute
1349
-     * @param string $label_class css class attribute for the label
1350
-     * @param string $disabled    disabled="disabled" or null
1351
-     * @return string HTML
1352
-     */
1353
-    public static function checkbox(
1354
-        $question = false,
1355
-        $answer = null,
1356
-        $options = false,
1357
-        $name = false,
1358
-        $id = '',
1359
-        $class = '',
1360
-        $required = false,
1361
-        $required_text = '',
1362
-        $label_class = '',
1363
-        $disabled = false,
1364
-        $label_b4 = false,
1365
-        $system_ID = false,
1366
-        $use_html_entities = true
1367
-    ) {
1368
-        // need these
1369
-        if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1370
-            return null;
1371
-        }
1372
-        $answer = maybe_unserialize($answer);
1373
-
1374
-        // prep the answer(s)
1375
-        $answer = is_array($answer) ? $answer : [sanitize_key($answer) => $answer];
1376
-
1377
-        foreach ($answer as $key => $value) {
1378
-            $key            = self::prep_option_value($key);
1379
-            $answer[ $key ] = self::prep_answer($value, $use_html_entities);
1380
-        }
1381
-
1382
-        // prep the required array
1383
-        $required = self::prep_required($required);
1384
-        // set disabled tag
1385
-        $disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1386
-        // ya gots ta have style man!!!
1387
-        $radio_class = is_admin() ? 'ee-admin-radio-lbl' : $label_class;
1388
-        $class       = empty($class) ? 'espresso-radio-btn-inp' : $class;
1389
-        $extra       = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1390
-
1391
-        $label_html =
1392
-            $required_text
1393
-            . "\n\t\t\t"
1394
-            . '<label class="' . $label_class . '">'
1395
-            . self::prep_question($question)
1396
-            . $required['label']
1397
-            . '</label> ';
1398
-        // filter label but ensure required text comes before it
1399
-        $label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
1400
-
1401
-        $input_html =
1402
-            "\n\t\t\t"
1403
-            . '<ul id="' . $id . '-ul" class="espresso-checkbox-options-ul ' . $label_class . ' ' . $class . '-ul">';
1404
-
1405
-        $class .= ! empty($system_ID) ? ' ' . $system_ID : '';
1406
-        $class .= ! empty($required['class']) ? ' ' . $required['class'] : '';
1407
-
1408
-        foreach ($options as $OPT) {
1409
-            $value = $OPT->value();// self::prep_option_value( $OPT->value() );
1410
-            $size  = self::get_label_size_class($OPT->value() . ' ' . $OPT->desc());
1411
-            $text  = self::prep_answer($OPT->value());
1412
-            $desc  = $OPT->desc();
1413
-            $opt   = '-' . sanitize_key($value);
1414
-
1415
-            $checked = is_array($answer) && in_array($text, $answer) ? ' checked' : '';
1416
-
1417
-            $input_html .= "\n\t\t\t\t" . '<li' . $size . '>';
1418
-            $input_html .= "\n\t\t\t\t\t" . '<label class="' . $radio_class . ' espresso-checkbox-lbl">';
1419
-            $input_html .= $label_b4 ? "\n\t\t\t\t\t\t" . '<span>' . $text . '</span>' : '';
1420
-            $input_html .= "\n\t\t\t\t\t\t"
1421
-                           . '<input type="checkbox" name="' . $name . '[' . $OPT->ID() . ']" '
1422
-                           . 'id="' . $id . $opt . '" class="' . $class . '" value="' . $value . '" '
1423
-                           . 'title="' . esc_attr($required['msg']) . '" ' . $disabled . $checked . ' ' . $extra . '/>';
1424
-            $input_html .= ! $label_b4 ? "\n\t\t\t\t\t\t" . '<span>' . $text . '</span>' : '';
1425
-            $input_html .= "\n\t\t\t\t\t" . '</label>';
1426
-            if (! empty($desc) && $desc != $text) {
1427
-                $input_html .= "\n\t\t\t\t\t"
1428
-                               . ' &nbsp; <br/><div class="espresso-checkbox-option-desc small-text grey-text">'
1429
-                               . $desc
1430
-                               . '</div>';
1431
-            }
1432
-            $input_html .= "\n\t\t\t\t" . '</li>';
1433
-        }
1434
-
1435
-        $input_html .= "\n\t\t\t" . '</ul>';
1436
-
1437
-        $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1438
-        return $label_html . $input_html;
1439
-    }
1440
-
1441
-
1442
-    /**
1443
-     * generates HTML for a form datepicker input
1444
-     *
1445
-     * @param string $question    label content
1446
-     * @param string $answer      form input value attribute
1447
-     * @param string $name        form input name attribute
1448
-     * @param string $id          form input css id attribute
1449
-     * @param string $class       form input css class attribute
1450
-     * @param array  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
1451
-     *                            required 'class', and required 'msg' attribute
1452
-     * @param string $label_class css class attribute for the label
1453
-     * @param string $disabled    disabled="disabled" or null
1454
-     * @return string HTML
1455
-     */
1456
-    public static function datepicker(
1457
-        $question = false,
1458
-        $answer = null,
1459
-        $name = false,
1460
-        $id = '',
1461
-        $class = '',
1462
-        $required = false,
1463
-        $required_text = '',
1464
-        $label_class = '',
1465
-        $disabled = false,
1466
-        $system_ID = false,
1467
-        $use_html_entities = true
1468
-    ) {
1469
-        // need these
1470
-        if (! $question || ! $name) {
1471
-            return null;
1472
-        }
1473
-        // prep the answer
1474
-        $answer = is_array($answer) ? '' : self::prep_answer($answer, $use_html_entities);
1475
-        // prep the required array
1476
-        $required = self::prep_required($required);
1477
-        // set disabled tag
1478
-        $disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1479
-        // ya gots ta have style man!!!
1480
-        $txt_class = is_admin() ? 'regular-text' : 'espresso-datepicker-inp';
1481
-        $class     = empty($class) ? $txt_class : $class;
1482
-        $class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
1483
-        $extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1484
-
1485
-        $label_html =
1486
-            $required_text
1487
-            . "\n\t\t\t"
1488
-            . '<label for="' . $name . '" class="' . $label_class . '">'
1489
-            . self::prep_question($question)
1490
-            . $required['label']
1491
-            . '</label><br/>';
1492
-        // filter label but ensure required text comes before it
1493
-        $label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
1494
-
1495
-        $input_html =
1496
-            "\n\t\t\t"
1497
-            . '<input type="text" name="' . $name . '" id="' . $id . '" '
1498
-            . 'class="' . $class . ' ' . $required['class'] . ' datepicker" value="' . $answer . '"  '
1499
-            . 'title="' . esc_attr($required['msg']) . '" ' . $disabled . ' ' . $extra . '/>';
1500
-
1501
-        // enqueue scripts
1502
-        wp_register_style(
1503
-            'espresso-ui-theme',
1504
-            EE_GLOBAL_ASSETS_URL . 'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
1505
-            [],
1506
-            EVENT_ESPRESSO_VERSION
1507
-        );
1508
-        wp_enqueue_style('espresso-ui-theme');
1509
-        wp_enqueue_script('jquery-ui-datepicker');
1510
-
1511
-        $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1512
-        return $label_html . $input_html;
1513
-    }
1514
-
1515
-
1516
-    /**
1517
-     *  remove_label_keep_required_msg
1518
-     *  this will strip out a form input's label HTML while keeping the required text HTML that MUST be before the label
1519
-     *
1520
-     * @access public
1521
-     * @return     string
1522
-     */
1523
-    public static function remove_label_keep_required_msg($label_html, $required_text)
1524
-    {
1525
-        return $required_text;
1526
-    }
1527
-
1528
-
1529
-    /**
1530
-     * Simply returns the HTML for a hidden input of the given name and value.
1531
-     *
1532
-     * @param string $name
1533
-     * @param string $value
1534
-     * @return string HTML
1535
-     */
1536
-    public static function hidden_input($name, $value, $id = '')
1537
-    {
1538
-        $id = ! empty($id) ? $id : $name;
1539
-        return '<input id="' . $id . '" type="hidden" name="' . $name . '" value="' . $value . '"/>';
1540
-    }
1541
-
1542
-
1543
-    /**
1544
-     * prep_question
1545
-     *
1546
-     * @param string $question
1547
-     * @return string
1548
-     */
1549
-    public static function prep_question($question)
1550
-    {
1551
-        return $question;
1552
-    }
1553
-
1554
-
1555
-    /**
1556
-     *  prep_answer
1557
-     *
1558
-     * @param mixed $answer
1559
-     * @return string
1560
-     */
1561
-    public static function prep_answer($answer, $use_html_entities = true)
1562
-    {
1563
-        // make sure we convert bools first.  Otherwise (bool) false becomes an empty string which is NOT desired,
1564
-        // we want "0".
1565
-        if (is_bool($answer)) {
1566
-            $answer = $answer ? 1 : 0;
1567
-        }
1568
-        $answer = trim(stripslashes(str_replace('&#039;', "'", $answer)));
1569
-        return $use_html_entities ? htmlentities($answer, ENT_QUOTES, 'UTF-8') : $answer;
1570
-    }
1571
-
1572
-
1573
-    /**
1574
-     *  prep_answer_options
1575
-     *
1576
-     * @param array $QSOs array of EE_Question_Option objects
1577
-     * @return array
1578
-     */
1579
-    public static function prep_answer_options($QSOs = [])
1580
-    {
1581
-        $prepped_answer_options = [];
1582
-        if (is_array($QSOs) && ! empty($QSOs)) {
1583
-            foreach ($QSOs as $key => $QSO) {
1584
-                if (! $QSO instanceof EE_Question_Option) {
1585
-                    $QSO = EE_Question_Option::new_instance(
1586
-                        [
1587
-                            'QSO_value' => is_array($QSO) && isset($QSO['id'])
1588
-                                ? (string) $QSO['id']
1589
-                                : (string) $key,
1590
-                            'QSO_desc'  => is_array($QSO) && isset($QSO['text'])
1591
-                                ? (string) $QSO['text']
1592
-                                : (string) $QSO,
1593
-                        ]
1594
-                    );
1595
-                }
1596
-                if ($QSO->opt_group()) {
1597
-                    $prepped_answer_options[ $QSO->opt_group() ][] = $QSO;
1598
-                } else {
1599
-                    $prepped_answer_options[] = $QSO;
1600
-                }
1601
-            }
1602
-        }
1603
-        //      d( $prepped_answer_options );
1604
-        return $prepped_answer_options;
1605
-    }
1606
-
1607
-
1608
-    /**
1609
-     *  prep_option_value
1610
-     *
1611
-     * @param string $option_value
1612
-     * @return string
1613
-     */
1614
-    public static function prep_option_value($option_value)
1615
-    {
1616
-        return esc_attr(trim(stripslashes($option_value)));
1617
-    }
1618
-
1619
-
1620
-    /**
1621
-     *  prep_required
1622
-     *
1623
-     * @param string|array $required
1624
-     * @return array
1625
-     */
1626
-    public static function prep_required($required = [])
1627
-    {
1628
-        // make sure required is an array
1629
-        $required = is_array($required) ? $required : [];
1630
-        // and set some defaults
1631
-        return array_merge(['label' => '', 'class' => '', 'msg' => ''], $required);
1632
-    }
1633
-
1634
-
1635
-    /**
1636
-     *  get_label_size_class
1637
-     *
1638
-     * @param string $value
1639
-     * @return string
1640
-     */
1641
-    public static function get_label_size_class($value = false)
1642
-    {
1643
-        if ($value === false || $value === '') {
1644
-            return ' class="medium-lbl"';
1645
-        }
1646
-        // determine length of option value
1647
-        $val_size = strlen($value);
1648
-        switch ($val_size) {
1649
-            case $val_size < 3:
1650
-                $size = ' class="nano-lbl"';
1651
-                break;
1652
-            case $val_size < 6:
1653
-                $size = ' class="micro-lbl"';
1654
-                break;
1655
-            case $val_size < 12:
1656
-                $size = ' class="tiny-lbl"';
1657
-                break;
1658
-            case $val_size < 25:
1659
-                $size = ' class="small-lbl"';
1660
-                break;
1661
-            case $val_size > 100:
1662
-                $size = ' class="big-lbl"';
1663
-                break;
1664
-            default:
1665
-                $size = ' class="medium-lbl"';
1666
-                break;
1667
-        }
1668
-        return $size;
1669
-    }
1670
-
1671
-
1672
-    /**
1673
-     *  _load_system_dropdowns
1674
-     *
1675
-     * @param EE_Question_Form_Input $QFI
1676
-     * @return array
1677
-     * @throws EE_Error
1678
-     * @throws ReflectionException
1679
-     */
1680
-    private static function _load_system_dropdowns($QFI)
1681
-    {
1682
-        $QST_system = $QFI->get('QST_system');
1683
-        switch ($QST_system) {
1684
-            case 'state':
1685
-                $QFI = self::generate_state_dropdown($QFI);
1686
-                break;
1687
-            case 'country':
1688
-                $QFI = self::generate_country_dropdown($QFI);
1689
-                break;
1690
-            case 'admin-state':
1691
-                $QFI = self::generate_state_dropdown($QFI, true);
1692
-                break;
1693
-            case 'admin-country':
1694
-                $QFI = self::generate_country_dropdown($QFI, true);
1695
-                break;
1696
-        }
1697
-        return $QFI;
1698
-    }
1699
-
1700
-
1701
-    /**
1702
-     * This preps dropdowns that are specialized.
1703
-     *
1704
-     * @param EE_Question_Form_Input $QFI
1705
-     *
1706
-     * @return EE_Question_Form_Input
1707
-     * @throws EE_Error
1708
-     * @throws ReflectionException
1709
-     * @since  4.6.0
1710
-     */
1711
-    protected static function _load_specialized_dropdowns($QFI)
1712
-    {
1713
-        switch ($QFI->get('QST_type')) {
1714
-            case 'STATE':
1715
-                $QFI = self::generate_state_dropdown($QFI);
1716
-                break;
1717
-            case 'COUNTRY':
1718
-                $QFI = self::generate_country_dropdown($QFI);
1719
-                break;
1720
-        }
1721
-        return $QFI;
1722
-    }
1723
-
1724
-
1725
-    /**
1726
-     *    generate_state_dropdown
1727
-     *
1728
-     * @param EE_Question_Form_Input $QST
1729
-     * @param bool                   $get_all
1730
-     * @return EE_Question_Form_Input
1731
-     * @throws EE_Error
1732
-     * @throws ReflectionException
1733
-     */
1734
-    public static function generate_state_dropdown($QST, $get_all = false)
1735
-    {
1736
-        $states = $get_all
1737
-            ? EEM_State::instance()->get_all_states()
1738
-            : EEM_State::instance()->get_all_states_of_active_countries();
1739
-        if ($states && count($states) != count($QST->options())) {
1740
-            $QST->set('QST_type', 'DROPDOWN');
1741
-            // if multiple countries, we'll create option groups within the dropdown
1742
-            foreach ($states as $state) {
1743
-                if ($state instanceof EE_State) {
1744
-                    $QSO = EE_Question_Option::new_instance(
1745
-                        [
1746
-                            'QSO_value'   => $state->ID(),
1747
-                            'QSO_desc'    => $state->name(),
1748
-                            'QST_ID'      => $QST->get('QST_ID'),
1749
-                            'QSO_deleted' => false,
1750
-                        ]
1751
-                    );
1752
-                    // set option group
1753
-                    $QSO->set_opt_group($state->country()->name());
1754
-                    // add option to question
1755
-                    $QST->add_temp_option($QSO);
1756
-                }
1757
-            }
1758
-        }
1759
-        return $QST;
1760
-    }
1761
-
1762
-
1763
-    /**
1764
-     *    generate_country_dropdown
1765
-     *
1766
-     * @param      $QST
1767
-     * @param bool $get_all
1768
-     * @return array
1769
-     * @throws EE_Error
1770
-     * @throws ReflectionException
1771
-     * @internal param array $question
1772
-     */
1773
-    public static function generate_country_dropdown($QST, $get_all = false)
1774
-    {
1775
-        $countries = $get_all
1776
-            ? EEM_Country::instance()->get_all_countries()
1777
-            : EEM_Country::instance()->get_all_active_countries();
1778
-        if ($countries && count($countries) != count($QST->options())) {
1779
-            $QST->set('QST_type', 'DROPDOWN');
1780
-            // now add countries
1781
-            foreach ($countries as $country) {
1782
-                if ($country instanceof EE_Country) {
1783
-                    $QSO = EE_Question_Option::new_instance(
1784
-                        [
1785
-                            'QSO_value'   => $country->ID(),
1786
-                            'QSO_desc'    => $country->name(),
1787
-                            'QST_ID'      => $QST->get('QST_ID'),
1788
-                            'QSO_deleted' => false,
1789
-                        ]
1790
-                    );
1791
-                    $QST->add_temp_option($QSO);
1792
-                }
1793
-            }
1794
-        }
1795
-        return $QST;
1796
-    }
1797
-
1798
-
1799
-    /**
1800
-     *  generates options for a month dropdown selector with numbers from 01 to 12
1801
-     *
1802
-     * @return array()
1803
-     */
1804
-    public static function two_digit_months_dropdown_options()
1805
-    {
1806
-        $options = [];
1807
-        for ($x = 1; $x <= 12; $x++) {
1808
-            $mm             = str_pad($x, 2, '0', STR_PAD_LEFT);
1809
-            $options[ $mm ] = $mm;
1810
-        }
1811
-        return EEH_Form_Fields::prep_answer_options($options);
1812
-    }
1813
-
1814
-
1815
-    /**
1816
-     *  generates a year dropdown selector with numbers for the next ten years
1817
-     *
1818
-     * @return array
1819
-     */
1820
-    public static function next_decade_two_digit_year_dropdown_options()
1821
-    {
1822
-        $options      = [];
1823
-        $current_year = date('y');
1824
-        $next_decade  = $current_year + 10;
1825
-        for ($x = $current_year; $x <= $next_decade; $x++) {
1826
-            $yy             = str_pad($x, 2, '0', STR_PAD_LEFT);
1827
-            $options[ $yy ] = $yy;
1828
-        }
1829
-        return EEH_Form_Fields::prep_answer_options($options);
1830
-    }
1831
-
1832
-
1833
-    /**
1834
-     * generates a month/year dropdown selector for all registrations matching the given criteria.  Typically used for
1835
-     * list table filter.
1836
-     *
1837
-     * @param string  $cur_date     any currently selected date can be entered here.
1838
-     * @param string  $status       Registration status
1839
-     * @param integer $evt_category Event Category ID if the Event Category filter is selected
1840
-     * @return string                html
1841
-     * @throws EE_Error
1842
-     */
1843
-    public static function generate_registration_months_dropdown($cur_date = '', $status = '', $evt_category = 0)
1844
-    {
1845
-        $_where = [];
1846
-        if (! empty($status)) {
1847
-            $_where['STS_ID'] = $status;
1848
-        }
1849
-
1850
-        if ($evt_category > 0) {
1851
-            $_where['Event.Term_Taxonomy.term_id'] = $evt_category;
1852
-        }
1853
-
1854
-        $regdtts = EEM_Registration::instance()->get_reg_months_and_years($_where);
1855
-
1856
-        // setup vals for select input helper
1857
-        $options = [
1858
-            0 => [
1859
-                'text' => esc_html__('Select a Month/Year', 'event_espresso'),
1860
-                'id'   => '',
1861
-            ],
1862
-        ];
1863
-
1864
-        foreach ($regdtts as $regdtt) {
1865
-            $date      = $regdtt->reg_month . ' ' . $regdtt->reg_year;
1866
-            $options[] = [
1867
-                'text' => $date,
1868
-                'id'   => $date,
1869
-            ];
1870
-        }
1871
-
1872
-        return self::select_input('month_range', $options, $cur_date, '', 'wide');
1873
-    }
1874
-
1875
-
1876
-    /**
1877
-     * generates a month/year dropdown selector for all events matching the given criteria
1878
-     * Typically used for list table filter
1879
-     *
1880
-     * @param string $cur_date          any currently selected date can be entered here.
1881
-     * @param string $status            "view" (i.e. all, today, month, draft)
1882
-     * @param int    $evt_category      category event belongs to
1883
-     * @param string $evt_active_status "upcoming", "expired", "active", or "inactive"
1884
-     * @return string                    html
1885
-     * @throws EE_Error
1886
-     */
1887
-    public static function generate_event_months_dropdown(
1888
-        $cur_date = '',
1889
-        $status = null,
1890
-        $evt_category = null,
1891
-        $evt_active_status = null
1892
-    ) {
1893
-        // determine what post_status our condition will have for the query.
1894
-        // phpcs:disable PSR2.ControlStructures.SwitchDeclaration.TerminatingComment
1895
-        switch ($status) {
1896
-            case 'month':
1897
-            case 'today':
1898
-            case null:
1899
-            case 'all':
1900
-                $where['Event.status'] = ['NOT IN', ['trash']];
1901
-                break;
1902
-            case 'draft':
1903
-                $where['Event.status'] = ['IN', ['draft', 'auto-draft']];
1904
-                break;
1905
-            default:
1906
-                $where['Event.status'] = $status;
1907
-        }
1908
-
1909
-        // phpcs:enable
1910
-
1911
-        // categories?
1912
-
1913
-
1914
-        if (! empty($evt_category)) {
1915
-            $where['Event.Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1916
-            $where['Event.Term_Taxonomy.term_id']  = $evt_category;
1917
-        }
1918
-
1919
-
1920
-        //      $where['DTT_is_primary'] = 1;
1921
-
1922
-        $DTTS = EEM_Datetime::instance()->get_dtt_months_and_years($where, $evt_active_status);
1923
-
1924
-        // let's setup vals for select input helper
1925
-        $options = [
1926
-            0 => [
1927
-                'text' => esc_html__('Select a Month/Year', 'event_espresso'),
1928
-                'id'   => "",
1929
-            ],
1930
-        ];
1931
-
1932
-
1933
-        // translate month and date
1934
-        global $wp_locale;
1935
-
1936
-        foreach ($DTTS as $DTT) {
1937
-            $localized_date = $wp_locale->get_month($DTT->dtt_month_num) . ' ' . $DTT->dtt_year;
1938
-            $id             = $DTT->dtt_month . ' ' . $DTT->dtt_year;
1939
-            $options[]      = [
1940
-                'text' => $localized_date,
1941
-                'id'   => $id,
1942
-            ];
1943
-        }
1944
-
1945
-
1946
-        return self::select_input('month_range', $options, $cur_date, '', 'wide');
1947
-    }
1948
-
1949
-
1950
-    /**
1951
-     * generates the dropdown selector for event categories
1952
-     * typically used as a filter on list tables.
1953
-     *
1954
-     * @param integer $current_cat currently selected category
1955
-     * @return string               html for dropdown
1956
-     * @throws EE_Error
1957
-     * @throws ReflectionException
1958
-     */
1959
-    public static function generate_event_category_dropdown($current_cat = -1)
1960
-    {
1961
-        $categories = EEM_Term::instance()->get_all_ee_categories(true);
1962
-        $options    = [
1963
-            '0' => [
1964
-                'text' => esc_html__('All Categories', 'event_espresso'),
1965
-                'id'   => -1,
1966
-            ],
1967
-        ];
1968
-
1969
-        // setup categories for dropdown
1970
-        foreach ($categories as $category) {
1971
-            $options[] = [
1972
-                'text' => $category->get('name'),
1973
-                'id'   => $category->ID(),
1974
-            ];
1975
-        }
1976
-
1977
-        return self::select_input('EVT_CAT', $options, $current_cat);
1978
-    }
1979
-
1980
-
1981
-    /**
1982
-     *    generate a submit button with or without it's own microform
1983
-     *    this is the only way to create buttons that are compatible across all themes
1984
-     *
1985
-     * @access    public
1986
-     * @param string      $url              - the form action
1987
-     * @param string      $ID               - some kind of unique ID, appended with "-sbmt" for the input and "-frm"
1988
-     *                                      for the form
1989
-     * @param string      $class            - css classes (separated by spaces if more than one)
1990
-     * @param string      $text             - what appears on the button
1991
-     * @param string      $nonce_action     - if using nonces
1992
-     * @param bool|string $input_only       - whether to print form header and footer. TRUE returns the input without
1993
-     *                                      the form
1994
-     * @param string      $extra_attributes - any extra attributes that need to be attached to the form input
1995
-     * @return    string
1996
-     */
1997
-    public static function submit_button(
1998
-        $url = '',
1999
-        $ID = '',
2000
-        $class = '',
2001
-        $text = '',
2002
-        $nonce_action = '',
2003
-        $input_only = false,
2004
-        $extra_attributes = ''
2005
-    ) {
2006
-        $btn = '';
2007
-        if (empty($url) || empty($ID)) {
2008
-            return $btn;
2009
-        }
2010
-        $text = ! empty($text) ? $text : esc_html__('Submit', 'event_espresso');
2011
-        $btn  .= '<input id="' . $ID . '-btn" class="' . $class . '" '
2012
-                 . 'type="submit" value="' . $text . '" ' . $extra_attributes . '/>';
2013
-        if (! $input_only) {
2014
-            $btn_frm = '<form id="' . $ID . '-frm" method="POST" action="' . $url . '">';
2015
-            $btn_frm .= ! empty($nonce_action)
2016
-                ? wp_nonce_field($nonce_action, $nonce_action . '_nonce', true, false)
2017
-                : '';
2018
-            $btn_frm .= $btn;
2019
-            $btn_frm .= '</form>';
2020
-            $btn     = $btn_frm;
2021
-            unset($btn_frm);
2022
-        }
2023
-        return $btn;
2024
-    }
488
+	}
489
+
490
+
491
+	/**
492
+	 * @param string $class
493
+	 * @param string $id
494
+	 * @param string $name
495
+	 * @param int    $rows
496
+	 * @param int    $tab_index
497
+	 * @param string $value
498
+	 * @param array  $wp_editor_args
499
+	 * @return false|string
500
+	 * @since   4.10.14.p
501
+	 */
502
+	private static function adminWpEditor($class, $id, $name, $rows, $tab_index, $value, $wp_editor_args = [])
503
+	{
504
+		$editor_settings = $wp_editor_args + [
505
+				'textarea_name' => esc_attr($name),
506
+				'textarea_rows' => absint($rows),
507
+				'editor_class'  => esc_attr($class),
508
+				'tabindex'      => absint($tab_index),
509
+			];
510
+		ob_start();
511
+		wp_editor($value, esc_attr($id), $editor_settings);
512
+		return ob_get_clean();
513
+	}
514
+
515
+
516
+	/**
517
+	 * espresso admin page select_input
518
+	 * Turns an array into a select fields
519
+	 *
520
+	 * @static
521
+	 * @access public
522
+	 * @param string  $name       field name
523
+	 * @param array   $values     option values, numbered array starting at 0, where each value is an array with a key
524
+	 *                            'text' (meaning text to display' and 'id' (meaning the internal value) eg:
525
+	 *                            array(1=>array('text'=>'Monday','id'=>1),2=>array('text'=>'Tuesday','id'=>2)...). or
526
+	 *                            as an array of key-value pairs, where the key is to be used for the select input's
527
+	 *                            name, and the value will be the text shown to the user.  Optionally you can also
528
+	 *                            include an additional key of "class" which will add a specific class to the option
529
+	 *                            for that value.
530
+	 * @param string  $default    default value
531
+	 * @param string  $parameters extra parameters
532
+	 * @param string  $class      css class
533
+	 * @param boolean $autosize   whether to autosize the select or not
534
+	 * @return string              html string for the select input
535
+	 */
536
+	public static function select_input($name, $values, $default = '', $parameters = '', $class = '', $autosize = true)
537
+	{
538
+		// if $values was submitted in the wrong format, convert it over
539
+		if (! empty($values) && (! array_key_exists(0, $values) || ! is_array($values[0]))) {
540
+			$converted_values = [];
541
+			foreach ($values as $id => $text) {
542
+				$converted_values[] = ['id' => $id, 'text' => $text];
543
+			}
544
+			$values = $converted_values;
545
+		}
546
+
547
+		$field =
548
+			'<select id="' . EEH_Formatter::ee_tep_output_string($name)
549
+			. '" name="' . EEH_Formatter::ee_tep_output_string($name)
550
+			. '"';
551
+
552
+		if (EEH_Formatter::ee_tep_not_null($parameters)) {
553
+			$field .= ' ' . $parameters;
554
+		}
555
+		if ($autosize) {
556
+			$size = 'med';
557
+			for ($ii = 0, $ni = sizeof($values); $ii < $ni; $ii++) {
558
+				if ($values[ $ii ]['text']) {
559
+					if (strlen($values[ $ii ]['text']) > 5) {
560
+						$size = 'wide';
561
+					}
562
+				}
563
+			}
564
+		} else {
565
+			$size = '';
566
+		}
567
+
568
+		$field .= ' class="' . $class . ' ' . $size . '">';
569
+
570
+		if (empty($default) && isset($GLOBALS[ $name ])) {
571
+			$default = stripslashes($GLOBALS[ $name ]);
572
+		}
573
+
574
+
575
+		for ($i = 0, $n = sizeof($values); $i < $n; $i++) {
576
+			$field .= '<option value="' . $values[ $i ]['id'] . '"';
577
+			if ($default == $values[ $i ]['id']) {
578
+				$field .= ' selected = "selected"';
579
+			}
580
+			if (isset($values[ $i ]['class'])) {
581
+				$field .= ' class="' . $values[ $i ]['class'] . '"';
582
+			}
583
+			$field .= '>' . $values[ $i ]['text'] . '</option>';
584
+		}
585
+		$field .= '</select>';
586
+
587
+		return $field;
588
+	}
589
+
590
+
591
+	/**
592
+	 * generate_question_groups_html
593
+	 *
594
+	 * @param array  $question_groups
595
+	 * @param string $group_wrapper
596
+	 * @return string HTML
597
+	 * @throws EE_Error
598
+	 * @throws ReflectionException
599
+	 */
600
+	public static function generate_question_groups_html($question_groups = [], $group_wrapper = 'fieldset')
601
+	{
602
+
603
+		$html                            = '';
604
+		$before_question_group_questions =
605
+			apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions', '');
606
+		$after_question_group_questions  =
607
+			apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', '');
608
+
609
+		if (! empty($question_groups)) {
610
+			// loop thru question groups
611
+			foreach ($question_groups as $QSG) {
612
+				// check that questions exist
613
+				if (! empty($QSG['QSG_questions'])) {
614
+					// use fieldsets
615
+					$html .= "\n\t"
616
+							 . '<'
617
+							 . $group_wrapper
618
+							 . ' class="espresso-question-group-wrap" id="'
619
+							 . $QSG['QSG_identifier']
620
+							 . '">';
621
+					// group_name
622
+					$html .= $QSG['QSG_show_group_name']
623
+						? "\n\t\t"
624
+						  . '<h5 class="espresso-question-group-title-h5 section-title">'
625
+						  . self::prep_answer($QSG['QSG_name'])
626
+						  . '</h5>'
627
+						: '';
628
+					// group_desc
629
+					$html .= $QSG['QSG_show_group_desc'] && ! empty($QSG['QSG_desc'])
630
+						? '<div class="espresso-question-group-desc-pg">'
631
+						  . self::prep_answer($QSG['QSG_desc'])
632
+						  . '</div>'
633
+						: '';
634
+
635
+					$html .= $before_question_group_questions;
636
+					// loop thru questions
637
+					foreach ($QSG['QSG_questions'] as $question) {
638
+						$QFI  = new EE_Question_Form_Input(
639
+							$question['qst_obj'],
640
+							$question['ans_obj'],
641
+							$question
642
+						);
643
+						$html .= self::generate_form_input($QFI);
644
+					}
645
+					$html .= $after_question_group_questions;
646
+					$html .= "\n\t" . '</' . $group_wrapper . '>';
647
+				}
648
+			}
649
+		}
650
+
651
+		return $html;
652
+	}
653
+
654
+
655
+	/**
656
+	 * generate_question_groups_html
657
+	 *
658
+	 * @param array  $question_groups
659
+	 * @param array  $q_meta
660
+	 * @param bool   $from_admin
661
+	 * @param string $group_wrapper
662
+	 * @return string HTML
663
+	 * @throws EE_Error
664
+	 * @throws ReflectionException
665
+	 */
666
+	public static function generate_question_groups_html2(
667
+		$question_groups = [],
668
+		$q_meta = [],
669
+		$from_admin = false,
670
+		$group_wrapper = 'fieldset'
671
+	) {
672
+
673
+		$html                            = '';
674
+		$before_question_group_questions =
675
+			apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__before_question_group_questions', '');
676
+		$after_question_group_questions  =
677
+			apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', '');
678
+
679
+		$default_q_meta = [
680
+			'att_nmbr'    => 1,
681
+			'ticket_id'   => '',
682
+			'input_name'  => '',
683
+			'input_id'    => '',
684
+			'input_class' => '',
685
+		];
686
+		$q_meta         = array_merge($default_q_meta, $q_meta);
687
+
688
+		if (! empty($question_groups)) {
689
+			// loop thru question groups
690
+			foreach ($question_groups as $QSG) {
691
+				if ($QSG instanceof EE_Question_Group) {
692
+					// check that questions exist
693
+
694
+					$where = ['QST_deleted' => 0];
695
+					if (! $from_admin) {
696
+						$where['QST_admin_only'] = 0;
697
+					}
698
+					$questions =
699
+						$QSG->questions([$where, 'order_by' => ['Question_Group_Question.QGQ_order' => 'ASC']]);
700
+					if (! empty($questions)) {
701
+						// use fieldsets
702
+						$html .= "\n\t"
703
+								 . '<' . $group_wrapper . ' class="espresso-question-group-wrap" '
704
+								 . 'id="' . $QSG->get('QSG_identifier') . '">';
705
+						// group_name
706
+						if ($QSG->show_group_name()) {
707
+							$html .= "\n\t\t"
708
+									 . '<h5 class="espresso-question-group-title-h5 section-title">'
709
+									 . $QSG->get_pretty('QSG_name')
710
+									 . '</h5>';
711
+						}
712
+						// group_desc
713
+						if ($QSG->show_group_desc()) {
714
+							$html .= '<div class="espresso-question-group-desc-pg">'
715
+									 . $QSG->get_pretty('QSG_desc')
716
+									 . '</div>';
717
+						}
718
+
719
+						$html .= $before_question_group_questions;
720
+						// loop thru questions
721
+						foreach ($questions as $QST) {
722
+							$qstn_id = $QST->is_system_question() ? $QST->system_ID() : $QST->ID();
723
+
724
+							$answer = null;
725
+
726
+							/** @var RequestInterface $request */
727
+							$request      = LoaderFactory::getLoader()->getShared(RequestInterface::class);
728
+							$request_qstn = $request->getRequestParam('qstn', [], 'string', true);
729
+							if (! empty($request_qstn) && isset($q_meta['input_id']) && isset($q_meta['att_nmbr'])) {
730
+								// check for answer in $request_qstn in case we are reprocessing a form after an error
731
+								if (isset($request_qstn[ $q_meta['input_id'] ][ $qstn_id ])) {
732
+									$answer = is_array($request_qstn[ $q_meta['input_id'] ][ $qstn_id ])
733
+										? $request_qstn[ $q_meta['input_id'] ][ $qstn_id ]
734
+										: sanitize_text_field($request_qstn[ $q_meta['input_id'] ][ $qstn_id ]);
735
+								}
736
+							} elseif (isset($q_meta['attendee']) && $q_meta['attendee']) {
737
+								// attendee data from the session
738
+								$answer =
739
+									isset($q_meta['attendee'][ $qstn_id ]) ? $q_meta['attendee'][ $qstn_id ] : null;
740
+							}
741
+
742
+
743
+							$QFI  = new EE_Question_Form_Input(
744
+								$QST,
745
+								EE_Answer::new_instance(
746
+									[
747
+										'ANS_ID'    => 0,
748
+										'QST_ID'    => 0,
749
+										'REG_ID'    => 0,
750
+										'ANS_value' => $answer,
751
+									]
752
+								),
753
+								$q_meta
754
+							);
755
+							$html .= self::generate_form_input($QFI);
756
+						}
757
+						$html .= $after_question_group_questions;
758
+						$html .= "\n\t" . '</' . $group_wrapper . '>';
759
+					}
760
+				}
761
+			}
762
+		}
763
+		return $html;
764
+	}
765
+
766
+
767
+	/**
768
+	 * generate_form_input
769
+	 *
770
+	 * @param EE_Question_Form_Input $QFI
771
+	 * @return string HTML
772
+	 * @throws EE_Error
773
+	 * @throws ReflectionException
774
+	 */
775
+	public static function generate_form_input(EE_Question_Form_Input $QFI)
776
+	{
777
+		if (isset($QFI->QST_admin_only) && $QFI->QST_admin_only && ! is_admin()) {
778
+			return '';
779
+		}
780
+		/** @var RequestInterface $request */
781
+		$request = LoaderFactory::getLoader()->getShared(RequestInterface::class);
782
+
783
+		$QFI = self::_load_system_dropdowns($QFI);
784
+		$QFI = self::_load_specialized_dropdowns($QFI);
785
+
786
+		// we also need to verify
787
+
788
+		$display_text = $QFI->get('QST_display_text');
789
+		$input_name   = $QFI->get('QST_input_name');
790
+		$answer       = $request->getRequestParam($input_name, $QFI->get('ANS_value'));
791
+		$input_id     = $QFI->get('QST_input_id');
792
+		$input_class  = $QFI->get('QST_input_class');
793
+		//      $disabled = $QFI->get('QST_disabled') ? ' disabled="disabled"' : '';
794
+		$disabled          = $QFI->get('QST_disabled');
795
+		$required_label    = apply_filters(' FHEE__EEH_Form_Fields__generate_form_input__required_label', '<em>*</em>');
796
+		$QST_required      = $QFI->get('QST_required');
797
+		$required          =
798
+			$QST_required
799
+				? ['label' => $required_label, 'class' => 'required needs-value', 'title' => $QST_required]
800
+				: [];
801
+		$use_html_entities = $QFI->get_meta('htmlentities');
802
+		$required_text     =
803
+			$QFI->get('QST_required_text') != ''
804
+				? $QFI->get('QST_required_text')
805
+				: esc_html__('This field is required', 'event_espresso');
806
+		$required_text     = $QST_required
807
+			? "\n\t\t\t"
808
+			  . '<div class="required-text hidden">'
809
+			  . self::prep_answer($required_text, $use_html_entities)
810
+			  . '</div>'
811
+			: '';
812
+		$label_class       = 'espresso-form-input-lbl';
813
+		$QST_options       = $QFI->options(true, $answer);
814
+		$options           = is_array($QST_options) ? self::prep_answer_options($QST_options) : [];
815
+		$system_ID         = $QFI->get('QST_system');
816
+		$label_b4          = $QFI->get_meta('label_b4');
817
+		$use_desc_4_label  = $QFI->get_meta('use_desc_4_label');
818
+
819
+
820
+		switch ($QFI->get('QST_type')) {
821
+			case 'TEXTAREA':
822
+				return EEH_Form_Fields::textarea(
823
+					$display_text,
824
+					$answer,
825
+					$input_name,
826
+					$input_id,
827
+					$input_class,
828
+					[],
829
+					$required,
830
+					$required_text,
831
+					$label_class,
832
+					$disabled,
833
+					$system_ID,
834
+					$use_html_entities
835
+				);
836
+
837
+			case 'DROPDOWN':
838
+				return EEH_Form_Fields::select(
839
+					$display_text,
840
+					$answer,
841
+					$options,
842
+					$input_name,
843
+					$input_id,
844
+					$input_class,
845
+					$required,
846
+					$required_text,
847
+					$label_class,
848
+					$disabled,
849
+					$system_ID,
850
+					$use_html_entities,
851
+					true
852
+				);
853
+
854
+
855
+			case 'RADIO_BTN':
856
+				return EEH_Form_Fields::radio(
857
+					$display_text,
858
+					$answer,
859
+					$options,
860
+					$input_name,
861
+					$input_id,
862
+					$input_class,
863
+					$required,
864
+					$required_text,
865
+					$label_class,
866
+					$disabled,
867
+					$system_ID,
868
+					$use_html_entities,
869
+					$label_b4,
870
+					$use_desc_4_label
871
+				);
872
+
873
+			case 'CHECKBOX':
874
+				return EEH_Form_Fields::checkbox(
875
+					$display_text,
876
+					$answer,
877
+					$options,
878
+					$input_name,
879
+					$input_id,
880
+					$input_class,
881
+					$required,
882
+					$required_text,
883
+					$label_class,
884
+					$disabled,
885
+					$label_b4,
886
+					$system_ID,
887
+					$use_html_entities
888
+				);
889
+
890
+			case 'DATE':
891
+				return EEH_Form_Fields::datepicker(
892
+					$display_text,
893
+					$answer,
894
+					$input_name,
895
+					$input_id,
896
+					$input_class,
897
+					$required,
898
+					$required_text,
899
+					$label_class,
900
+					$disabled,
901
+					$system_ID,
902
+					$use_html_entities
903
+				);
904
+
905
+			case 'TEXT':
906
+			default:
907
+				return EEH_Form_Fields::text(
908
+					$display_text,
909
+					$answer,
910
+					$input_name,
911
+					$input_id,
912
+					$input_class,
913
+					$required,
914
+					$required_text,
915
+					$label_class,
916
+					$disabled,
917
+					$system_ID,
918
+					$use_html_entities
919
+				);
920
+		}
921
+	}
922
+
923
+
924
+	/**
925
+	 * generates HTML for a form text input
926
+	 *
927
+	 * @param string $question    label content
928
+	 * @param string $answer      form input value attribute
929
+	 * @param string $name        form input name attribute
930
+	 * @param string $id          form input css id attribute
931
+	 * @param string $class       form input css class attribute
932
+	 * @param array  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
933
+	 *                            required 'class', and required 'msg' attribute
934
+	 * @param string $label_class css class attribute for the label
935
+	 * @param string $disabled    disabled="disabled" or null
936
+	 * @return string HTML
937
+	 */
938
+	public static function text(
939
+		$question = false,
940
+		$answer = null,
941
+		$name = false,
942
+		$id = '',
943
+		$class = '',
944
+		$required = false,
945
+		$required_text = '',
946
+		$label_class = '',
947
+		$disabled = false,
948
+		$system_ID = false,
949
+		$use_html_entities = true
950
+	) {
951
+		// need these
952
+		if (! $question || ! $name) {
953
+			return null;
954
+		}
955
+		// prep the answer
956
+		$answer = is_array($answer) ? '' : self::prep_answer($answer, $use_html_entities);
957
+		// prep the required array
958
+		$required = self::prep_required($required);
959
+		// set disabled tag
960
+		$disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
961
+		// ya gots ta have style man!!!
962
+		$txt_class = is_admin() ? 'regular-text' : 'espresso-text-inp';
963
+		$class     = empty($class) ? $txt_class : $class;
964
+		$class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
965
+		$extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
966
+
967
+		$label_html =
968
+			$required_text
969
+			. "\n\t\t\t"
970
+			. '<label for="' . $name . '" class="' . $label_class . '">'
971
+			. self::prep_question($question)
972
+			. $required['label']
973
+			. '</label><br/>';
974
+		// filter label but ensure required text comes before it
975
+		$label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
976
+
977
+		$input_html =
978
+			"\n\t\t\t"
979
+			. '<input type="text" name="' . $name . '" id="' . $id . '" '
980
+			. 'class="' . $class . ' ' . $required['class'] . '" value="' . esc_attr($answer) . '"  '
981
+			. 'title="' . esc_attr($required['msg']) . '" ' . $disabled . ' ' . $extra . '/>';
982
+
983
+		$input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
984
+		return $label_html . $input_html;
985
+	}
986
+
987
+
988
+	/**
989
+	 * generates HTML for a form textarea
990
+	 *
991
+	 * @param string $question    label content
992
+	 * @param string $answer      form input value attribute
993
+	 * @param string $name        form input name attribute
994
+	 * @param string $id          form input css id attribute
995
+	 * @param string $class       form input css class attribute
996
+	 * @param array  $dimensions  array of form input rows and cols attributes : array( 'rows' => 3, 'cols' => 40 )
997
+	 * @param array  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
998
+	 *                            required 'class', and required 'msg' attribute
999
+	 * @param string $label_class css class attribute for the label
1000
+	 * @param string $disabled    disabled="disabled" or null
1001
+	 * @return string HTML
1002
+	 */
1003
+	public static function textarea(
1004
+		$question = false,
1005
+		$answer = null,
1006
+		$name = false,
1007
+		$id = '',
1008
+		$class = '',
1009
+		$dimensions = false,
1010
+		$required = false,
1011
+		$required_text = '',
1012
+		$label_class = '',
1013
+		$disabled = false,
1014
+		$system_ID = false,
1015
+		$use_html_entities = true
1016
+	) {
1017
+		// need these
1018
+		if (! $question || ! $name) {
1019
+			return null;
1020
+		}
1021
+		// prep the answer
1022
+		$answer = is_array($answer) ? '' : self::prep_answer($answer, $use_html_entities);
1023
+		// prep the required array
1024
+		$required = self::prep_required($required);
1025
+		// make sure $dimensions is an array
1026
+		$dimensions = is_array($dimensions) ? $dimensions : [];
1027
+		// and set some defaults
1028
+		$dimensions = array_merge(['rows' => 3, 'cols' => 40], $dimensions);
1029
+		// set disabled tag
1030
+		$disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1031
+		// ya gots ta have style man!!!
1032
+		$txt_class = is_admin() ? 'regular-text' : 'espresso-textarea-inp';
1033
+		$class     = empty($class) ? $txt_class : $class;
1034
+		$class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
1035
+		$extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1036
+
1037
+		$label_html =
1038
+			$required_text
1039
+			. "\n\t\t\t"
1040
+			. '<label for="' . $name . '" class="' . $label_class . '">'
1041
+			. self::prep_question($question)
1042
+			. $required['label']
1043
+			. '</label><br/>';
1044
+		// filter label but ensure required text comes before it
1045
+		$label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
1046
+
1047
+		$input_html =
1048
+			"\n\t\t\t"
1049
+			. '<textarea name="' . $name . '" id="' . $id . '" class="' . $class . ' ' . $required['class'] . '" '
1050
+			. 'rows="' . $dimensions['rows'] . '" cols="' . $dimensions['cols'] . '"  '
1051
+			. 'title="' . $required['msg'] . '" ' . $disabled . ' ' . $extra . '>'
1052
+			. esc_textarea($answer)
1053
+			. '</textarea>';
1054
+
1055
+		$input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1056
+		return $label_html . $input_html;
1057
+	}
1058
+
1059
+
1060
+	/**
1061
+	 * generates HTML for a form select input
1062
+	 *
1063
+	 * @param string $question    label content
1064
+	 * @param string $answer      form input value attribute
1065
+	 * @param array  $options     array of answer options where array key = option value and array value = option
1066
+	 *                            display text
1067
+	 * @param string $name        form input name attribute
1068
+	 * @param string $id          form input css id attribute
1069
+	 * @param string $class       form input css class attribute
1070
+	 * @param array  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
1071
+	 *                            required 'class', and required 'msg' attribute
1072
+	 * @param string $label_class css class attribute for the label
1073
+	 * @param string $disabled    disabled="disabled" or null
1074
+	 * @return string HTML
1075
+	 */
1076
+	public static function select(
1077
+		$question = false,
1078
+		$answer = null,
1079
+		$options = false,
1080
+		$name = false,
1081
+		$id = '',
1082
+		$class = '',
1083
+		$required = false,
1084
+		$required_text = '',
1085
+		$label_class = '',
1086
+		$disabled = false,
1087
+		$system_ID = false,
1088
+		$use_html_entities = true,
1089
+		$add_please_select_option = false
1090
+	) {
1091
+
1092
+		// need these
1093
+		if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1094
+			return null;
1095
+		}
1096
+		// prep the answer
1097
+		$answer =
1098
+			is_array($answer)
1099
+				? self::prep_answer(array_shift($answer), $use_html_entities)
1100
+				: self::prep_answer(
1101
+					$answer,
1102
+					$use_html_entities
1103
+				);
1104
+		// prep the required array
1105
+		$required = self::prep_required($required);
1106
+		// set disabled tag
1107
+		$disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1108
+		// ya gots ta have style man!!!
1109
+		$txt_class = is_admin() ? 'wide' : 'espresso-select-inp';
1110
+		$class     = empty($class) ? $txt_class : $class;
1111
+		$class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
1112
+		$extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1113
+
1114
+		$label_html =
1115
+			$required_text
1116
+			. "\n\t\t\t"
1117
+			. '<label for="' . $name . '" class="' . $label_class . '">'
1118
+			. self::prep_question($question)
1119
+			. $required['label']
1120
+			. '</label><br/>';
1121
+		// filter label but ensure required text comes before it
1122
+		$label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
1123
+
1124
+		$input_html =
1125
+			"\n\t\t\t"
1126
+			. '<select name="' . $name . '" id="' . $id . '" class="' . $class . ' ' . $required['class'] . '" '
1127
+			. 'title="' . esc_attr($required['msg']) . '"' . $disabled . ' ' . $extra . '>';
1128
+		// recursively count array elements, to determine total number of options
1129
+		$only_option = count($options, 1) == 1;
1130
+		if (! $only_option) {
1131
+			// if there is NO answer set and there are multiple options to choose from, then set the "please select" message as selected
1132
+			$selected   = $answer === null ? ' selected' : '';
1133
+			$input_html .= $add_please_select_option
1134
+				? "\n\t\t\t\t"
1135
+				  . '<option value=""' . $selected . '>'
1136
+				  . esc_html__(' - please select - ', 'event_espresso')
1137
+				  . '</option>'
1138
+				: '';
1139
+		}
1140
+		foreach ($options as $key => $value) {
1141
+			// if value is an array, then create option groups, else create regular ol' options
1142
+			$input_html .= is_array($value)
1143
+				? self::_generate_select_option_group(
1144
+					$key,
1145
+					$value,
1146
+					$answer,
1147
+					$use_html_entities
1148
+				)
1149
+				: self::_generate_select_option(
1150
+					$value->value(),
1151
+					$value->desc(),
1152
+					$answer,
1153
+					$only_option,
1154
+					$use_html_entities
1155
+				);
1156
+		}
1157
+
1158
+		$input_html .= "\n\t\t\t" . '</select>';
1159
+
1160
+		$input_html =
1161
+			apply_filters(
1162
+				'FHEE__EEH_Form_Fields__select__before_end_wrapper',
1163
+				$input_html,
1164
+				$question,
1165
+				$answer,
1166
+				$name,
1167
+				$id,
1168
+				$class,
1169
+				$system_ID
1170
+			);
1171
+
1172
+		$input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1173
+		return $label_html . $input_html;
1174
+	}
1175
+
1176
+
1177
+	/**
1178
+	 *  _generate_select_option_group
1179
+	 *
1180
+	 *  if  $value for a select box is an array, then the key will be used as the optgroup label
1181
+	 *  and the value array will be looped thru and the elements sent to _generate_select_option
1182
+	 *
1183
+	 * @param mixed   $opt_group
1184
+	 * @param mixed   $QSOs
1185
+	 * @param mixed   $answer
1186
+	 * @param boolean $use_html_entities
1187
+	 * @return string
1188
+	 */
1189
+	private static function _generate_select_option_group($opt_group, $QSOs, $answer, $use_html_entities = true)
1190
+	{
1191
+		$html = "\n\t\t\t\t" . '<optgroup label="' . self::prep_option_value($opt_group) . '">';
1192
+		foreach ($QSOs as $QSO) {
1193
+			$html .= self::_generate_select_option($QSO->value(), $QSO->desc(), $answer, false, $use_html_entities);
1194
+		}
1195
+		$html .= "\n\t\t\t\t" . '</optgroup>';
1196
+		return $html;
1197
+	}
1198
+
1199
+
1200
+	/**
1201
+	 *  _generate_select_option
1202
+	 *
1203
+	 * @param mixed   $key
1204
+	 * @param mixed   $value
1205
+	 * @param mixed   $answer
1206
+	 * @param int     $only_option
1207
+	 * @param boolean $use_html_entities
1208
+	 * @return string
1209
+	 */
1210
+	private static function _generate_select_option(
1211
+		$key,
1212
+		$value,
1213
+		$answer,
1214
+		$only_option = false,
1215
+		$use_html_entities = true
1216
+	) {
1217
+		$key      = self::prep_answer($key, $use_html_entities);
1218
+		$value    = self::prep_answer($value, $use_html_entities);
1219
+		$value    = ! empty($value) ? $value : $key;
1220
+		$selected = ($answer == $key || $only_option) ? 'selected' : '';
1221
+		return "\n\t\t\t\t"
1222
+			   . '<option value="' . self::prep_option_value($key) . '" ' . $selected . '> '
1223
+			   . $value
1224
+			   . '&nbsp;&nbsp;&nbsp;</option>';
1225
+	}
1226
+
1227
+
1228
+	/**
1229
+	 * generates HTML for form radio button inputs
1230
+	 *
1231
+	 * @param bool|string $question    label content
1232
+	 * @param string      $answer      form input value attribute
1233
+	 * @param array|bool  $options     array of answer options where array key = option value and array value = option
1234
+	 *                                 display text
1235
+	 * @param bool|string $name        form input name attribute
1236
+	 * @param string      $id          form input css id attribute
1237
+	 * @param string      $class       form input css class attribute
1238
+	 * @param array|bool  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
1239
+	 *                                 required 'class', and required 'msg' attribute
1240
+	 * @param string      $required_text
1241
+	 * @param string      $label_class css class attribute for the label
1242
+	 * @param bool|string $disabled    disabled="disabled" or null
1243
+	 * @param bool        $system_ID
1244
+	 * @param bool        $use_html_entities
1245
+	 * @param bool        $label_b4
1246
+	 * @param bool        $use_desc_4_label
1247
+	 * @return string HTML
1248
+	 */
1249
+	public static function radio(
1250
+		$question = false,
1251
+		$answer = null,
1252
+		$options = false,
1253
+		$name = false,
1254
+		$id = '',
1255
+		$class = '',
1256
+		$required = false,
1257
+		$required_text = '',
1258
+		$label_class = '',
1259
+		$disabled = false,
1260
+		$system_ID = false,
1261
+		$use_html_entities = true,
1262
+		$label_b4 = false,
1263
+		$use_desc_4_label = false
1264
+	) {
1265
+		// need these
1266
+		if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1267
+			return null;
1268
+		}
1269
+		// prep the answer
1270
+		$answer = is_array($answer) ? '' : self::prep_answer($answer, $use_html_entities);
1271
+		// prep the required array
1272
+		$required = self::prep_required($required);
1273
+		// set disabled tag
1274
+		$disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1275
+		// ya gots ta have style man!!!
1276
+		$radio_class = is_admin() ? 'ee-admin-radio-lbl' : $label_class;
1277
+		$class       = ! empty($class) ? $class : 'espresso-radio-btn-inp';
1278
+		$extra       = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1279
+
1280
+		$label_html =
1281
+			$required_text
1282
+			. "\n\t\t\t"
1283
+			. '<label class="' . $label_class . '">'
1284
+			. self::prep_question($question)
1285
+			. $required['label']
1286
+			. '</label> ';
1287
+		// filter label but ensure required text comes before it
1288
+		$label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
1289
+
1290
+		$input_html =
1291
+			"\n\t\t\t"
1292
+			. '<ul id="' . $id . '-ul" class="espresso-radio-btn-options-ul ' . $label_class . ' ' . $class . '-ul">';
1293
+
1294
+		$class .= ! empty($system_ID) ? ' ' . $system_ID : '';
1295
+		$class .= ! empty($required['class']) ? ' ' . $required['class'] : '';
1296
+
1297
+		foreach ($options as $OPT) {
1298
+			if ($OPT instanceof EE_Question_Option) {
1299
+				$value   = self::prep_option_value($OPT->value());
1300
+				$label   = $use_desc_4_label ? $OPT->desc() : $OPT->value();
1301
+				$size    = $use_desc_4_label
1302
+					? self::get_label_size_class($OPT->value() . ' ' . $OPT->desc())
1303
+					: self::get_label_size_class($OPT->value());
1304
+				$desc    = $OPT->desc();// no self::prep_answer
1305
+				$answer  = is_numeric($value) && empty($answer) ? 0 : $answer;
1306
+				$checked = (string) $value == (string) $answer ? ' checked' : '';
1307
+				$opt     = '-' . sanitize_key($value);
1308
+
1309
+				$input_html .= "\n\t\t\t\t" . '<li' . $size . '>';
1310
+				$input_html .= "\n\t\t\t\t\t" . '<label class="' . $radio_class . ' espresso-radio-btn-lbl">';
1311
+				$input_html .= $label_b4 ? "\n\t\t\t\t\t\t" . '<span>' . $label . '</span>' : '';
1312
+				$input_html .= "\n\t\t\t\t\t\t"
1313
+							   . '<input type="radio" name="' . $name . '" id="' . $id . $opt . '" '
1314
+							   . 'class="' . $class . '" value="' . $value . '" '
1315
+							   . 'title="' . esc_attr($required['msg']) . '" ' . $disabled
1316
+							   . $checked . ' ' . $extra . '/>';
1317
+				$input_html .= ! $label_b4
1318
+					? "\n\t\t\t\t\t\t"
1319
+					  . '<span class="espresso-radio-btn-desc">'
1320
+					  . $label
1321
+					  . '</span>'
1322
+					: '';
1323
+				$input_html .= "\n\t\t\t\t\t" . '</label>';
1324
+				$input_html .= $use_desc_4_label
1325
+					? ''
1326
+					: '<span class="espresso-radio-btn-option-desc small-text grey-text">' . $desc . '</span>';
1327
+				$input_html .= "\n\t\t\t\t" . '</li>';
1328
+			}
1329
+		}
1330
+
1331
+		$input_html .= "\n\t\t\t" . '</ul>';
1332
+
1333
+		$input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1334
+		return $label_html . $input_html;
1335
+	}
1336
+
1337
+
1338
+	/**
1339
+	 * generates HTML for form checkbox inputs
1340
+	 *
1341
+	 * @param string $question    label content
1342
+	 * @param string $answer      form input value attribute
1343
+	 * @param array  $options     array of options where array key = option value and array value = option display text
1344
+	 * @param string $name        form input name attribute
1345
+	 * @param string $id          form input css id attribute
1346
+	 * @param string $class       form input css class attribute
1347
+	 * @param array  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
1348
+	 *                            required 'class', and required 'msg' attribute
1349
+	 * @param string $label_class css class attribute for the label
1350
+	 * @param string $disabled    disabled="disabled" or null
1351
+	 * @return string HTML
1352
+	 */
1353
+	public static function checkbox(
1354
+		$question = false,
1355
+		$answer = null,
1356
+		$options = false,
1357
+		$name = false,
1358
+		$id = '',
1359
+		$class = '',
1360
+		$required = false,
1361
+		$required_text = '',
1362
+		$label_class = '',
1363
+		$disabled = false,
1364
+		$label_b4 = false,
1365
+		$system_ID = false,
1366
+		$use_html_entities = true
1367
+	) {
1368
+		// need these
1369
+		if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1370
+			return null;
1371
+		}
1372
+		$answer = maybe_unserialize($answer);
1373
+
1374
+		// prep the answer(s)
1375
+		$answer = is_array($answer) ? $answer : [sanitize_key($answer) => $answer];
1376
+
1377
+		foreach ($answer as $key => $value) {
1378
+			$key            = self::prep_option_value($key);
1379
+			$answer[ $key ] = self::prep_answer($value, $use_html_entities);
1380
+		}
1381
+
1382
+		// prep the required array
1383
+		$required = self::prep_required($required);
1384
+		// set disabled tag
1385
+		$disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1386
+		// ya gots ta have style man!!!
1387
+		$radio_class = is_admin() ? 'ee-admin-radio-lbl' : $label_class;
1388
+		$class       = empty($class) ? 'espresso-radio-btn-inp' : $class;
1389
+		$extra       = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1390
+
1391
+		$label_html =
1392
+			$required_text
1393
+			. "\n\t\t\t"
1394
+			. '<label class="' . $label_class . '">'
1395
+			. self::prep_question($question)
1396
+			. $required['label']
1397
+			. '</label> ';
1398
+		// filter label but ensure required text comes before it
1399
+		$label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
1400
+
1401
+		$input_html =
1402
+			"\n\t\t\t"
1403
+			. '<ul id="' . $id . '-ul" class="espresso-checkbox-options-ul ' . $label_class . ' ' . $class . '-ul">';
1404
+
1405
+		$class .= ! empty($system_ID) ? ' ' . $system_ID : '';
1406
+		$class .= ! empty($required['class']) ? ' ' . $required['class'] : '';
1407
+
1408
+		foreach ($options as $OPT) {
1409
+			$value = $OPT->value();// self::prep_option_value( $OPT->value() );
1410
+			$size  = self::get_label_size_class($OPT->value() . ' ' . $OPT->desc());
1411
+			$text  = self::prep_answer($OPT->value());
1412
+			$desc  = $OPT->desc();
1413
+			$opt   = '-' . sanitize_key($value);
1414
+
1415
+			$checked = is_array($answer) && in_array($text, $answer) ? ' checked' : '';
1416
+
1417
+			$input_html .= "\n\t\t\t\t" . '<li' . $size . '>';
1418
+			$input_html .= "\n\t\t\t\t\t" . '<label class="' . $radio_class . ' espresso-checkbox-lbl">';
1419
+			$input_html .= $label_b4 ? "\n\t\t\t\t\t\t" . '<span>' . $text . '</span>' : '';
1420
+			$input_html .= "\n\t\t\t\t\t\t"
1421
+						   . '<input type="checkbox" name="' . $name . '[' . $OPT->ID() . ']" '
1422
+						   . 'id="' . $id . $opt . '" class="' . $class . '" value="' . $value . '" '
1423
+						   . 'title="' . esc_attr($required['msg']) . '" ' . $disabled . $checked . ' ' . $extra . '/>';
1424
+			$input_html .= ! $label_b4 ? "\n\t\t\t\t\t\t" . '<span>' . $text . '</span>' : '';
1425
+			$input_html .= "\n\t\t\t\t\t" . '</label>';
1426
+			if (! empty($desc) && $desc != $text) {
1427
+				$input_html .= "\n\t\t\t\t\t"
1428
+							   . ' &nbsp; <br/><div class="espresso-checkbox-option-desc small-text grey-text">'
1429
+							   . $desc
1430
+							   . '</div>';
1431
+			}
1432
+			$input_html .= "\n\t\t\t\t" . '</li>';
1433
+		}
1434
+
1435
+		$input_html .= "\n\t\t\t" . '</ul>';
1436
+
1437
+		$input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1438
+		return $label_html . $input_html;
1439
+	}
1440
+
1441
+
1442
+	/**
1443
+	 * generates HTML for a form datepicker input
1444
+	 *
1445
+	 * @param string $question    label content
1446
+	 * @param string $answer      form input value attribute
1447
+	 * @param string $name        form input name attribute
1448
+	 * @param string $id          form input css id attribute
1449
+	 * @param string $class       form input css class attribute
1450
+	 * @param array  $required    'label', 'class', and 'msg' - array of values for required "label" content, css
1451
+	 *                            required 'class', and required 'msg' attribute
1452
+	 * @param string $label_class css class attribute for the label
1453
+	 * @param string $disabled    disabled="disabled" or null
1454
+	 * @return string HTML
1455
+	 */
1456
+	public static function datepicker(
1457
+		$question = false,
1458
+		$answer = null,
1459
+		$name = false,
1460
+		$id = '',
1461
+		$class = '',
1462
+		$required = false,
1463
+		$required_text = '',
1464
+		$label_class = '',
1465
+		$disabled = false,
1466
+		$system_ID = false,
1467
+		$use_html_entities = true
1468
+	) {
1469
+		// need these
1470
+		if (! $question || ! $name) {
1471
+			return null;
1472
+		}
1473
+		// prep the answer
1474
+		$answer = is_array($answer) ? '' : self::prep_answer($answer, $use_html_entities);
1475
+		// prep the required array
1476
+		$required = self::prep_required($required);
1477
+		// set disabled tag
1478
+		$disabled = $answer === null || ! $disabled ? '' : ' disabled="disabled"';
1479
+		// ya gots ta have style man!!!
1480
+		$txt_class = is_admin() ? 'regular-text' : 'espresso-datepicker-inp';
1481
+		$class     = empty($class) ? $txt_class : $class;
1482
+		$class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
1483
+		$extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1484
+
1485
+		$label_html =
1486
+			$required_text
1487
+			. "\n\t\t\t"
1488
+			. '<label for="' . $name . '" class="' . $label_class . '">'
1489
+			. self::prep_question($question)
1490
+			. $required['label']
1491
+			. '</label><br/>';
1492
+		// filter label but ensure required text comes before it
1493
+		$label_html = apply_filters('FHEE__EEH_Form_Fields__label_html', $label_html, $required_text);
1494
+
1495
+		$input_html =
1496
+			"\n\t\t\t"
1497
+			. '<input type="text" name="' . $name . '" id="' . $id . '" '
1498
+			. 'class="' . $class . ' ' . $required['class'] . ' datepicker" value="' . $answer . '"  '
1499
+			. 'title="' . esc_attr($required['msg']) . '" ' . $disabled . ' ' . $extra . '/>';
1500
+
1501
+		// enqueue scripts
1502
+		wp_register_style(
1503
+			'espresso-ui-theme',
1504
+			EE_GLOBAL_ASSETS_URL . 'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
1505
+			[],
1506
+			EVENT_ESPRESSO_VERSION
1507
+		);
1508
+		wp_enqueue_style('espresso-ui-theme');
1509
+		wp_enqueue_script('jquery-ui-datepicker');
1510
+
1511
+		$input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1512
+		return $label_html . $input_html;
1513
+	}
1514
+
1515
+
1516
+	/**
1517
+	 *  remove_label_keep_required_msg
1518
+	 *  this will strip out a form input's label HTML while keeping the required text HTML that MUST be before the label
1519
+	 *
1520
+	 * @access public
1521
+	 * @return     string
1522
+	 */
1523
+	public static function remove_label_keep_required_msg($label_html, $required_text)
1524
+	{
1525
+		return $required_text;
1526
+	}
1527
+
1528
+
1529
+	/**
1530
+	 * Simply returns the HTML for a hidden input of the given name and value.
1531
+	 *
1532
+	 * @param string $name
1533
+	 * @param string $value
1534
+	 * @return string HTML
1535
+	 */
1536
+	public static function hidden_input($name, $value, $id = '')
1537
+	{
1538
+		$id = ! empty($id) ? $id : $name;
1539
+		return '<input id="' . $id . '" type="hidden" name="' . $name . '" value="' . $value . '"/>';
1540
+	}
1541
+
1542
+
1543
+	/**
1544
+	 * prep_question
1545
+	 *
1546
+	 * @param string $question
1547
+	 * @return string
1548
+	 */
1549
+	public static function prep_question($question)
1550
+	{
1551
+		return $question;
1552
+	}
1553
+
1554
+
1555
+	/**
1556
+	 *  prep_answer
1557
+	 *
1558
+	 * @param mixed $answer
1559
+	 * @return string
1560
+	 */
1561
+	public static function prep_answer($answer, $use_html_entities = true)
1562
+	{
1563
+		// make sure we convert bools first.  Otherwise (bool) false becomes an empty string which is NOT desired,
1564
+		// we want "0".
1565
+		if (is_bool($answer)) {
1566
+			$answer = $answer ? 1 : 0;
1567
+		}
1568
+		$answer = trim(stripslashes(str_replace('&#039;', "'", $answer)));
1569
+		return $use_html_entities ? htmlentities($answer, ENT_QUOTES, 'UTF-8') : $answer;
1570
+	}
1571
+
1572
+
1573
+	/**
1574
+	 *  prep_answer_options
1575
+	 *
1576
+	 * @param array $QSOs array of EE_Question_Option objects
1577
+	 * @return array
1578
+	 */
1579
+	public static function prep_answer_options($QSOs = [])
1580
+	{
1581
+		$prepped_answer_options = [];
1582
+		if (is_array($QSOs) && ! empty($QSOs)) {
1583
+			foreach ($QSOs as $key => $QSO) {
1584
+				if (! $QSO instanceof EE_Question_Option) {
1585
+					$QSO = EE_Question_Option::new_instance(
1586
+						[
1587
+							'QSO_value' => is_array($QSO) && isset($QSO['id'])
1588
+								? (string) $QSO['id']
1589
+								: (string) $key,
1590
+							'QSO_desc'  => is_array($QSO) && isset($QSO['text'])
1591
+								? (string) $QSO['text']
1592
+								: (string) $QSO,
1593
+						]
1594
+					);
1595
+				}
1596
+				if ($QSO->opt_group()) {
1597
+					$prepped_answer_options[ $QSO->opt_group() ][] = $QSO;
1598
+				} else {
1599
+					$prepped_answer_options[] = $QSO;
1600
+				}
1601
+			}
1602
+		}
1603
+		//      d( $prepped_answer_options );
1604
+		return $prepped_answer_options;
1605
+	}
1606
+
1607
+
1608
+	/**
1609
+	 *  prep_option_value
1610
+	 *
1611
+	 * @param string $option_value
1612
+	 * @return string
1613
+	 */
1614
+	public static function prep_option_value($option_value)
1615
+	{
1616
+		return esc_attr(trim(stripslashes($option_value)));
1617
+	}
1618
+
1619
+
1620
+	/**
1621
+	 *  prep_required
1622
+	 *
1623
+	 * @param string|array $required
1624
+	 * @return array
1625
+	 */
1626
+	public static function prep_required($required = [])
1627
+	{
1628
+		// make sure required is an array
1629
+		$required = is_array($required) ? $required : [];
1630
+		// and set some defaults
1631
+		return array_merge(['label' => '', 'class' => '', 'msg' => ''], $required);
1632
+	}
1633
+
1634
+
1635
+	/**
1636
+	 *  get_label_size_class
1637
+	 *
1638
+	 * @param string $value
1639
+	 * @return string
1640
+	 */
1641
+	public static function get_label_size_class($value = false)
1642
+	{
1643
+		if ($value === false || $value === '') {
1644
+			return ' class="medium-lbl"';
1645
+		}
1646
+		// determine length of option value
1647
+		$val_size = strlen($value);
1648
+		switch ($val_size) {
1649
+			case $val_size < 3:
1650
+				$size = ' class="nano-lbl"';
1651
+				break;
1652
+			case $val_size < 6:
1653
+				$size = ' class="micro-lbl"';
1654
+				break;
1655
+			case $val_size < 12:
1656
+				$size = ' class="tiny-lbl"';
1657
+				break;
1658
+			case $val_size < 25:
1659
+				$size = ' class="small-lbl"';
1660
+				break;
1661
+			case $val_size > 100:
1662
+				$size = ' class="big-lbl"';
1663
+				break;
1664
+			default:
1665
+				$size = ' class="medium-lbl"';
1666
+				break;
1667
+		}
1668
+		return $size;
1669
+	}
1670
+
1671
+
1672
+	/**
1673
+	 *  _load_system_dropdowns
1674
+	 *
1675
+	 * @param EE_Question_Form_Input $QFI
1676
+	 * @return array
1677
+	 * @throws EE_Error
1678
+	 * @throws ReflectionException
1679
+	 */
1680
+	private static function _load_system_dropdowns($QFI)
1681
+	{
1682
+		$QST_system = $QFI->get('QST_system');
1683
+		switch ($QST_system) {
1684
+			case 'state':
1685
+				$QFI = self::generate_state_dropdown($QFI);
1686
+				break;
1687
+			case 'country':
1688
+				$QFI = self::generate_country_dropdown($QFI);
1689
+				break;
1690
+			case 'admin-state':
1691
+				$QFI = self::generate_state_dropdown($QFI, true);
1692
+				break;
1693
+			case 'admin-country':
1694
+				$QFI = self::generate_country_dropdown($QFI, true);
1695
+				break;
1696
+		}
1697
+		return $QFI;
1698
+	}
1699
+
1700
+
1701
+	/**
1702
+	 * This preps dropdowns that are specialized.
1703
+	 *
1704
+	 * @param EE_Question_Form_Input $QFI
1705
+	 *
1706
+	 * @return EE_Question_Form_Input
1707
+	 * @throws EE_Error
1708
+	 * @throws ReflectionException
1709
+	 * @since  4.6.0
1710
+	 */
1711
+	protected static function _load_specialized_dropdowns($QFI)
1712
+	{
1713
+		switch ($QFI->get('QST_type')) {
1714
+			case 'STATE':
1715
+				$QFI = self::generate_state_dropdown($QFI);
1716
+				break;
1717
+			case 'COUNTRY':
1718
+				$QFI = self::generate_country_dropdown($QFI);
1719
+				break;
1720
+		}
1721
+		return $QFI;
1722
+	}
1723
+
1724
+
1725
+	/**
1726
+	 *    generate_state_dropdown
1727
+	 *
1728
+	 * @param EE_Question_Form_Input $QST
1729
+	 * @param bool                   $get_all
1730
+	 * @return EE_Question_Form_Input
1731
+	 * @throws EE_Error
1732
+	 * @throws ReflectionException
1733
+	 */
1734
+	public static function generate_state_dropdown($QST, $get_all = false)
1735
+	{
1736
+		$states = $get_all
1737
+			? EEM_State::instance()->get_all_states()
1738
+			: EEM_State::instance()->get_all_states_of_active_countries();
1739
+		if ($states && count($states) != count($QST->options())) {
1740
+			$QST->set('QST_type', 'DROPDOWN');
1741
+			// if multiple countries, we'll create option groups within the dropdown
1742
+			foreach ($states as $state) {
1743
+				if ($state instanceof EE_State) {
1744
+					$QSO = EE_Question_Option::new_instance(
1745
+						[
1746
+							'QSO_value'   => $state->ID(),
1747
+							'QSO_desc'    => $state->name(),
1748
+							'QST_ID'      => $QST->get('QST_ID'),
1749
+							'QSO_deleted' => false,
1750
+						]
1751
+					);
1752
+					// set option group
1753
+					$QSO->set_opt_group($state->country()->name());
1754
+					// add option to question
1755
+					$QST->add_temp_option($QSO);
1756
+				}
1757
+			}
1758
+		}
1759
+		return $QST;
1760
+	}
1761
+
1762
+
1763
+	/**
1764
+	 *    generate_country_dropdown
1765
+	 *
1766
+	 * @param      $QST
1767
+	 * @param bool $get_all
1768
+	 * @return array
1769
+	 * @throws EE_Error
1770
+	 * @throws ReflectionException
1771
+	 * @internal param array $question
1772
+	 */
1773
+	public static function generate_country_dropdown($QST, $get_all = false)
1774
+	{
1775
+		$countries = $get_all
1776
+			? EEM_Country::instance()->get_all_countries()
1777
+			: EEM_Country::instance()->get_all_active_countries();
1778
+		if ($countries && count($countries) != count($QST->options())) {
1779
+			$QST->set('QST_type', 'DROPDOWN');
1780
+			// now add countries
1781
+			foreach ($countries as $country) {
1782
+				if ($country instanceof EE_Country) {
1783
+					$QSO = EE_Question_Option::new_instance(
1784
+						[
1785
+							'QSO_value'   => $country->ID(),
1786
+							'QSO_desc'    => $country->name(),
1787
+							'QST_ID'      => $QST->get('QST_ID'),
1788
+							'QSO_deleted' => false,
1789
+						]
1790
+					);
1791
+					$QST->add_temp_option($QSO);
1792
+				}
1793
+			}
1794
+		}
1795
+		return $QST;
1796
+	}
1797
+
1798
+
1799
+	/**
1800
+	 *  generates options for a month dropdown selector with numbers from 01 to 12
1801
+	 *
1802
+	 * @return array()
1803
+	 */
1804
+	public static function two_digit_months_dropdown_options()
1805
+	{
1806
+		$options = [];
1807
+		for ($x = 1; $x <= 12; $x++) {
1808
+			$mm             = str_pad($x, 2, '0', STR_PAD_LEFT);
1809
+			$options[ $mm ] = $mm;
1810
+		}
1811
+		return EEH_Form_Fields::prep_answer_options($options);
1812
+	}
1813
+
1814
+
1815
+	/**
1816
+	 *  generates a year dropdown selector with numbers for the next ten years
1817
+	 *
1818
+	 * @return array
1819
+	 */
1820
+	public static function next_decade_two_digit_year_dropdown_options()
1821
+	{
1822
+		$options      = [];
1823
+		$current_year = date('y');
1824
+		$next_decade  = $current_year + 10;
1825
+		for ($x = $current_year; $x <= $next_decade; $x++) {
1826
+			$yy             = str_pad($x, 2, '0', STR_PAD_LEFT);
1827
+			$options[ $yy ] = $yy;
1828
+		}
1829
+		return EEH_Form_Fields::prep_answer_options($options);
1830
+	}
1831
+
1832
+
1833
+	/**
1834
+	 * generates a month/year dropdown selector for all registrations matching the given criteria.  Typically used for
1835
+	 * list table filter.
1836
+	 *
1837
+	 * @param string  $cur_date     any currently selected date can be entered here.
1838
+	 * @param string  $status       Registration status
1839
+	 * @param integer $evt_category Event Category ID if the Event Category filter is selected
1840
+	 * @return string                html
1841
+	 * @throws EE_Error
1842
+	 */
1843
+	public static function generate_registration_months_dropdown($cur_date = '', $status = '', $evt_category = 0)
1844
+	{
1845
+		$_where = [];
1846
+		if (! empty($status)) {
1847
+			$_where['STS_ID'] = $status;
1848
+		}
1849
+
1850
+		if ($evt_category > 0) {
1851
+			$_where['Event.Term_Taxonomy.term_id'] = $evt_category;
1852
+		}
1853
+
1854
+		$regdtts = EEM_Registration::instance()->get_reg_months_and_years($_where);
1855
+
1856
+		// setup vals for select input helper
1857
+		$options = [
1858
+			0 => [
1859
+				'text' => esc_html__('Select a Month/Year', 'event_espresso'),
1860
+				'id'   => '',
1861
+			],
1862
+		];
1863
+
1864
+		foreach ($regdtts as $regdtt) {
1865
+			$date      = $regdtt->reg_month . ' ' . $regdtt->reg_year;
1866
+			$options[] = [
1867
+				'text' => $date,
1868
+				'id'   => $date,
1869
+			];
1870
+		}
1871
+
1872
+		return self::select_input('month_range', $options, $cur_date, '', 'wide');
1873
+	}
1874
+
1875
+
1876
+	/**
1877
+	 * generates a month/year dropdown selector for all events matching the given criteria
1878
+	 * Typically used for list table filter
1879
+	 *
1880
+	 * @param string $cur_date          any currently selected date can be entered here.
1881
+	 * @param string $status            "view" (i.e. all, today, month, draft)
1882
+	 * @param int    $evt_category      category event belongs to
1883
+	 * @param string $evt_active_status "upcoming", "expired", "active", or "inactive"
1884
+	 * @return string                    html
1885
+	 * @throws EE_Error
1886
+	 */
1887
+	public static function generate_event_months_dropdown(
1888
+		$cur_date = '',
1889
+		$status = null,
1890
+		$evt_category = null,
1891
+		$evt_active_status = null
1892
+	) {
1893
+		// determine what post_status our condition will have for the query.
1894
+		// phpcs:disable PSR2.ControlStructures.SwitchDeclaration.TerminatingComment
1895
+		switch ($status) {
1896
+			case 'month':
1897
+			case 'today':
1898
+			case null:
1899
+			case 'all':
1900
+				$where['Event.status'] = ['NOT IN', ['trash']];
1901
+				break;
1902
+			case 'draft':
1903
+				$where['Event.status'] = ['IN', ['draft', 'auto-draft']];
1904
+				break;
1905
+			default:
1906
+				$where['Event.status'] = $status;
1907
+		}
1908
+
1909
+		// phpcs:enable
1910
+
1911
+		// categories?
1912
+
1913
+
1914
+		if (! empty($evt_category)) {
1915
+			$where['Event.Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1916
+			$where['Event.Term_Taxonomy.term_id']  = $evt_category;
1917
+		}
1918
+
1919
+
1920
+		//      $where['DTT_is_primary'] = 1;
1921
+
1922
+		$DTTS = EEM_Datetime::instance()->get_dtt_months_and_years($where, $evt_active_status);
1923
+
1924
+		// let's setup vals for select input helper
1925
+		$options = [
1926
+			0 => [
1927
+				'text' => esc_html__('Select a Month/Year', 'event_espresso'),
1928
+				'id'   => "",
1929
+			],
1930
+		];
1931
+
1932
+
1933
+		// translate month and date
1934
+		global $wp_locale;
1935
+
1936
+		foreach ($DTTS as $DTT) {
1937
+			$localized_date = $wp_locale->get_month($DTT->dtt_month_num) . ' ' . $DTT->dtt_year;
1938
+			$id             = $DTT->dtt_month . ' ' . $DTT->dtt_year;
1939
+			$options[]      = [
1940
+				'text' => $localized_date,
1941
+				'id'   => $id,
1942
+			];
1943
+		}
1944
+
1945
+
1946
+		return self::select_input('month_range', $options, $cur_date, '', 'wide');
1947
+	}
1948
+
1949
+
1950
+	/**
1951
+	 * generates the dropdown selector for event categories
1952
+	 * typically used as a filter on list tables.
1953
+	 *
1954
+	 * @param integer $current_cat currently selected category
1955
+	 * @return string               html for dropdown
1956
+	 * @throws EE_Error
1957
+	 * @throws ReflectionException
1958
+	 */
1959
+	public static function generate_event_category_dropdown($current_cat = -1)
1960
+	{
1961
+		$categories = EEM_Term::instance()->get_all_ee_categories(true);
1962
+		$options    = [
1963
+			'0' => [
1964
+				'text' => esc_html__('All Categories', 'event_espresso'),
1965
+				'id'   => -1,
1966
+			],
1967
+		];
1968
+
1969
+		// setup categories for dropdown
1970
+		foreach ($categories as $category) {
1971
+			$options[] = [
1972
+				'text' => $category->get('name'),
1973
+				'id'   => $category->ID(),
1974
+			];
1975
+		}
1976
+
1977
+		return self::select_input('EVT_CAT', $options, $current_cat);
1978
+	}
1979
+
1980
+
1981
+	/**
1982
+	 *    generate a submit button with or without it's own microform
1983
+	 *    this is the only way to create buttons that are compatible across all themes
1984
+	 *
1985
+	 * @access    public
1986
+	 * @param string      $url              - the form action
1987
+	 * @param string      $ID               - some kind of unique ID, appended with "-sbmt" for the input and "-frm"
1988
+	 *                                      for the form
1989
+	 * @param string      $class            - css classes (separated by spaces if more than one)
1990
+	 * @param string      $text             - what appears on the button
1991
+	 * @param string      $nonce_action     - if using nonces
1992
+	 * @param bool|string $input_only       - whether to print form header and footer. TRUE returns the input without
1993
+	 *                                      the form
1994
+	 * @param string      $extra_attributes - any extra attributes that need to be attached to the form input
1995
+	 * @return    string
1996
+	 */
1997
+	public static function submit_button(
1998
+		$url = '',
1999
+		$ID = '',
2000
+		$class = '',
2001
+		$text = '',
2002
+		$nonce_action = '',
2003
+		$input_only = false,
2004
+		$extra_attributes = ''
2005
+	) {
2006
+		$btn = '';
2007
+		if (empty($url) || empty($ID)) {
2008
+			return $btn;
2009
+		}
2010
+		$text = ! empty($text) ? $text : esc_html__('Submit', 'event_espresso');
2011
+		$btn  .= '<input id="' . $ID . '-btn" class="' . $class . '" '
2012
+				 . 'type="submit" value="' . $text . '" ' . $extra_attributes . '/>';
2013
+		if (! $input_only) {
2014
+			$btn_frm = '<form id="' . $ID . '-frm" method="POST" action="' . $url . '">';
2015
+			$btn_frm .= ! empty($nonce_action)
2016
+				? wp_nonce_field($nonce_action, $nonce_action . '_nonce', true, false)
2017
+				: '';
2018
+			$btn_frm .= $btn;
2019
+			$btn_frm .= '</form>';
2020
+			$btn     = $btn_frm;
2021
+			unset($btn_frm);
2022
+		}
2023
+		return $btn;
2024
+	}
2025 2025
 }
Please login to merge, or discard this patch.
Spacing   +136 added lines, -136 removed lines patch added patch discarded remove patch
@@ -110,8 +110,8 @@  discard block
 block discarded – undo
110 110
             $type           = $input_value['input'];
111 111
             $value          = $input_value['value'];
112 112
 
113
-            $id    = $form_id ? $form_id . '-' . $input_key : $input_key;
114
-            $class = $required ? 'required ' . $css_class : $css_class;
113
+            $id    = $form_id ? $form_id.'-'.$input_key : $input_key;
114
+            $class = $required ? 'required '.$css_class : $css_class;
115 115
 
116 116
             // what type of input are we dealing with ?
117 117
             switch ($type) {
@@ -163,8 +163,8 @@  discard block
 block discarded – undo
163 163
             }
164 164
         } // end foreach( $input_vars as $input_key => $input_value )
165 165
 
166
-        if (! empty($inputs)) {
167
-            $glue   = "
166
+        if ( ! empty($inputs)) {
167
+            $glue = "
168 168
                 </li>
169 169
                 <li>
170 170
                     ";
@@ -177,7 +177,7 @@  discard block
 block discarded – undo
177 177
             </ul>
178 178
             ";
179 179
         }
180
-        return $output . implode("\n", $hidden_inputs);
180
+        return $output.implode("\n", $hidden_inputs);
181 181
     }
182 182
 
183 183
 
@@ -258,7 +258,7 @@  discard block
 block discarded – undo
258 258
             // generate label
259 259
             $label = ! empty($label) ? self::adminLabel($id, $label, $required) : '';
260 260
             // generate field name
261
-            $name = ! empty($unique_id) ? $field_name . '[' . $unique_id . ']' : $field_name;
261
+            $name = ! empty($unique_id) ? $field_name.'['.$unique_id.']' : $field_name;
262 262
 
263 263
             // we determine what we're building based on the type
264 264
             switch ($type) {
@@ -269,14 +269,14 @@  discard block
 block discarded – undo
269 269
                         foreach ($value as $key => $val) {
270 270
                             $c_input .= self::adminMulti(
271 271
                                 $default,
272
-                                isset($classes[ $key ]) ? $classes[ $key ] : '',
273
-                                $field_name . '_' . $value,
272
+                                isset($classes[$key]) ? $classes[$key] : '',
273
+                                $field_name.'_'.$value,
274 274
                                 $name,
275 275
                                 $required,
276 276
                                 $tab_index,
277 277
                                 $type,
278 278
                                 $val,
279
-                                isset($labels[ $key ]) ? $labels[ $key ] : ''
279
+                                isset($labels[$key]) ? $labels[$key] : ''
280 280
                             );
281 281
                         }
282 282
                         $field = $c_input;
@@ -302,7 +302,7 @@  discard block
 block discarded – undo
302 302
                 case 'select':
303 303
                     $options = [];
304 304
                     foreach ($value as $key => $val) {
305
-                        $options[ $val ] = isset($labels[ $key ]) ? $labels[ $key ] : '';
305
+                        $options[$val] = isset($labels[$key]) ? $labels[$key] : '';
306 306
                     }
307 307
                     $field = self::adminSelect($default, $class, $id, $name, $required, $tab_index, $options);
308 308
                     break;
@@ -328,7 +328,7 @@  discard block
 block discarded – undo
328 328
                     $field = self::adminText($class, $id, $name, $required, $tab_index, $value);
329 329
             }
330 330
 
331
-            $form_fields[ $field_name ] = ['label' => $label, 'field' => $field . $extra_desc];
331
+            $form_fields[$field_name] = ['label' => $label, 'field' => $field.$extra_desc];
332 332
         }
333 333
 
334 334
         return $form_fields;
@@ -536,7 +536,7 @@  discard block
 block discarded – undo
536 536
     public static function select_input($name, $values, $default = '', $parameters = '', $class = '', $autosize = true)
537 537
     {
538 538
         // if $values was submitted in the wrong format, convert it over
539
-        if (! empty($values) && (! array_key_exists(0, $values) || ! is_array($values[0]))) {
539
+        if ( ! empty($values) && ( ! array_key_exists(0, $values) || ! is_array($values[0]))) {
540 540
             $converted_values = [];
541 541
             foreach ($values as $id => $text) {
542 542
                 $converted_values[] = ['id' => $id, 'text' => $text];
@@ -545,18 +545,18 @@  discard block
 block discarded – undo
545 545
         }
546 546
 
547 547
         $field =
548
-            '<select id="' . EEH_Formatter::ee_tep_output_string($name)
549
-            . '" name="' . EEH_Formatter::ee_tep_output_string($name)
548
+            '<select id="'.EEH_Formatter::ee_tep_output_string($name)
549
+            . '" name="'.EEH_Formatter::ee_tep_output_string($name)
550 550
             . '"';
551 551
 
552 552
         if (EEH_Formatter::ee_tep_not_null($parameters)) {
553
-            $field .= ' ' . $parameters;
553
+            $field .= ' '.$parameters;
554 554
         }
555 555
         if ($autosize) {
556 556
             $size = 'med';
557 557
             for ($ii = 0, $ni = sizeof($values); $ii < $ni; $ii++) {
558
-                if ($values[ $ii ]['text']) {
559
-                    if (strlen($values[ $ii ]['text']) > 5) {
558
+                if ($values[$ii]['text']) {
559
+                    if (strlen($values[$ii]['text']) > 5) {
560 560
                         $size = 'wide';
561 561
                     }
562 562
                 }
@@ -565,22 +565,22 @@  discard block
 block discarded – undo
565 565
             $size = '';
566 566
         }
567 567
 
568
-        $field .= ' class="' . $class . ' ' . $size . '">';
568
+        $field .= ' class="'.$class.' '.$size.'">';
569 569
 
570
-        if (empty($default) && isset($GLOBALS[ $name ])) {
571
-            $default = stripslashes($GLOBALS[ $name ]);
570
+        if (empty($default) && isset($GLOBALS[$name])) {
571
+            $default = stripslashes($GLOBALS[$name]);
572 572
         }
573 573
 
574 574
 
575 575
         for ($i = 0, $n = sizeof($values); $i < $n; $i++) {
576
-            $field .= '<option value="' . $values[ $i ]['id'] . '"';
577
-            if ($default == $values[ $i ]['id']) {
576
+            $field .= '<option value="'.$values[$i]['id'].'"';
577
+            if ($default == $values[$i]['id']) {
578 578
                 $field .= ' selected = "selected"';
579 579
             }
580
-            if (isset($values[ $i ]['class'])) {
581
-                $field .= ' class="' . $values[ $i ]['class'] . '"';
580
+            if (isset($values[$i]['class'])) {
581
+                $field .= ' class="'.$values[$i]['class'].'"';
582 582
             }
583
-            $field .= '>' . $values[ $i ]['text'] . '</option>';
583
+            $field .= '>'.$values[$i]['text'].'</option>';
584 584
         }
585 585
         $field .= '</select>';
586 586
 
@@ -606,11 +606,11 @@  discard block
 block discarded – undo
606 606
         $after_question_group_questions  =
607 607
             apply_filters('FHEE__EEH_Form_Fields__generate_question_groups_html__after_question_group_questions', '');
608 608
 
609
-        if (! empty($question_groups)) {
609
+        if ( ! empty($question_groups)) {
610 610
             // loop thru question groups
611 611
             foreach ($question_groups as $QSG) {
612 612
                 // check that questions exist
613
-                if (! empty($QSG['QSG_questions'])) {
613
+                if ( ! empty($QSG['QSG_questions'])) {
614 614
                     // use fieldsets
615 615
                     $html .= "\n\t"
616 616
                              . '<'
@@ -635,7 +635,7 @@  discard block
 block discarded – undo
635 635
                     $html .= $before_question_group_questions;
636 636
                     // loop thru questions
637 637
                     foreach ($QSG['QSG_questions'] as $question) {
638
-                        $QFI  = new EE_Question_Form_Input(
638
+                        $QFI = new EE_Question_Form_Input(
639 639
                             $question['qst_obj'],
640 640
                             $question['ans_obj'],
641 641
                             $question
@@ -643,7 +643,7 @@  discard block
 block discarded – undo
643 643
                         $html .= self::generate_form_input($QFI);
644 644
                     }
645 645
                     $html .= $after_question_group_questions;
646
-                    $html .= "\n\t" . '</' . $group_wrapper . '>';
646
+                    $html .= "\n\t".'</'.$group_wrapper.'>';
647 647
                 }
648 648
             }
649 649
         }
@@ -683,25 +683,25 @@  discard block
 block discarded – undo
683 683
             'input_id'    => '',
684 684
             'input_class' => '',
685 685
         ];
686
-        $q_meta         = array_merge($default_q_meta, $q_meta);
686
+        $q_meta = array_merge($default_q_meta, $q_meta);
687 687
 
688
-        if (! empty($question_groups)) {
688
+        if ( ! empty($question_groups)) {
689 689
             // loop thru question groups
690 690
             foreach ($question_groups as $QSG) {
691 691
                 if ($QSG instanceof EE_Question_Group) {
692 692
                     // check that questions exist
693 693
 
694 694
                     $where = ['QST_deleted' => 0];
695
-                    if (! $from_admin) {
695
+                    if ( ! $from_admin) {
696 696
                         $where['QST_admin_only'] = 0;
697 697
                     }
698 698
                     $questions =
699 699
                         $QSG->questions([$where, 'order_by' => ['Question_Group_Question.QGQ_order' => 'ASC']]);
700
-                    if (! empty($questions)) {
700
+                    if ( ! empty($questions)) {
701 701
                         // use fieldsets
702 702
                         $html .= "\n\t"
703
-                                 . '<' . $group_wrapper . ' class="espresso-question-group-wrap" '
704
-                                 . 'id="' . $QSG->get('QSG_identifier') . '">';
703
+                                 . '<'.$group_wrapper.' class="espresso-question-group-wrap" '
704
+                                 . 'id="'.$QSG->get('QSG_identifier').'">';
705 705
                         // group_name
706 706
                         if ($QSG->show_group_name()) {
707 707
                             $html .= "\n\t\t"
@@ -726,21 +726,21 @@  discard block
 block discarded – undo
726 726
                             /** @var RequestInterface $request */
727 727
                             $request      = LoaderFactory::getLoader()->getShared(RequestInterface::class);
728 728
                             $request_qstn = $request->getRequestParam('qstn', [], 'string', true);
729
-                            if (! empty($request_qstn) && isset($q_meta['input_id']) && isset($q_meta['att_nmbr'])) {
729
+                            if ( ! empty($request_qstn) && isset($q_meta['input_id']) && isset($q_meta['att_nmbr'])) {
730 730
                                 // check for answer in $request_qstn in case we are reprocessing a form after an error
731
-                                if (isset($request_qstn[ $q_meta['input_id'] ][ $qstn_id ])) {
732
-                                    $answer = is_array($request_qstn[ $q_meta['input_id'] ][ $qstn_id ])
733
-                                        ? $request_qstn[ $q_meta['input_id'] ][ $qstn_id ]
734
-                                        : sanitize_text_field($request_qstn[ $q_meta['input_id'] ][ $qstn_id ]);
731
+                                if (isset($request_qstn[$q_meta['input_id']][$qstn_id])) {
732
+                                    $answer = is_array($request_qstn[$q_meta['input_id']][$qstn_id])
733
+                                        ? $request_qstn[$q_meta['input_id']][$qstn_id]
734
+                                        : sanitize_text_field($request_qstn[$q_meta['input_id']][$qstn_id]);
735 735
                                 }
736 736
                             } elseif (isset($q_meta['attendee']) && $q_meta['attendee']) {
737 737
                                 // attendee data from the session
738 738
                                 $answer =
739
-                                    isset($q_meta['attendee'][ $qstn_id ]) ? $q_meta['attendee'][ $qstn_id ] : null;
739
+                                    isset($q_meta['attendee'][$qstn_id]) ? $q_meta['attendee'][$qstn_id] : null;
740 740
                             }
741 741
 
742 742
 
743
-                            $QFI  = new EE_Question_Form_Input(
743
+                            $QFI = new EE_Question_Form_Input(
744 744
                                 $QST,
745 745
                                 EE_Answer::new_instance(
746 746
                                     [
@@ -755,7 +755,7 @@  discard block
 block discarded – undo
755 755
                             $html .= self::generate_form_input($QFI);
756 756
                         }
757 757
                         $html .= $after_question_group_questions;
758
-                        $html .= "\n\t" . '</' . $group_wrapper . '>';
758
+                        $html .= "\n\t".'</'.$group_wrapper.'>';
759 759
                     }
760 760
                 }
761 761
             }
@@ -803,7 +803,7 @@  discard block
 block discarded – undo
803 803
             $QFI->get('QST_required_text') != ''
804 804
                 ? $QFI->get('QST_required_text')
805 805
                 : esc_html__('This field is required', 'event_espresso');
806
-        $required_text     = $QST_required
806
+        $required_text = $QST_required
807 807
             ? "\n\t\t\t"
808 808
               . '<div class="required-text hidden">'
809 809
               . self::prep_answer($required_text, $use_html_entities)
@@ -949,7 +949,7 @@  discard block
 block discarded – undo
949 949
         $use_html_entities = true
950 950
     ) {
951 951
         // need these
952
-        if (! $question || ! $name) {
952
+        if ( ! $question || ! $name) {
953 953
             return null;
954 954
         }
955 955
         // prep the answer
@@ -961,13 +961,13 @@  discard block
 block discarded – undo
961 961
         // ya gots ta have style man!!!
962 962
         $txt_class = is_admin() ? 'regular-text' : 'espresso-text-inp';
963 963
         $class     = empty($class) ? $txt_class : $class;
964
-        $class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
964
+        $class     .= ! empty($system_ID) ? ' '.$system_ID : '';
965 965
         $extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
966 966
 
967 967
         $label_html =
968 968
             $required_text
969 969
             . "\n\t\t\t"
970
-            . '<label for="' . $name . '" class="' . $label_class . '">'
970
+            . '<label for="'.$name.'" class="'.$label_class.'">'
971 971
             . self::prep_question($question)
972 972
             . $required['label']
973 973
             . '</label><br/>';
@@ -976,12 +976,12 @@  discard block
 block discarded – undo
976 976
 
977 977
         $input_html =
978 978
             "\n\t\t\t"
979
-            . '<input type="text" name="' . $name . '" id="' . $id . '" '
980
-            . 'class="' . $class . ' ' . $required['class'] . '" value="' . esc_attr($answer) . '"  '
981
-            . 'title="' . esc_attr($required['msg']) . '" ' . $disabled . ' ' . $extra . '/>';
979
+            . '<input type="text" name="'.$name.'" id="'.$id.'" '
980
+            . 'class="'.$class.' '.$required['class'].'" value="'.esc_attr($answer).'"  '
981
+            . 'title="'.esc_attr($required['msg']).'" '.$disabled.' '.$extra.'/>';
982 982
 
983 983
         $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
984
-        return $label_html . $input_html;
984
+        return $label_html.$input_html;
985 985
     }
986 986
 
987 987
 
@@ -1015,7 +1015,7 @@  discard block
 block discarded – undo
1015 1015
         $use_html_entities = true
1016 1016
     ) {
1017 1017
         // need these
1018
-        if (! $question || ! $name) {
1018
+        if ( ! $question || ! $name) {
1019 1019
             return null;
1020 1020
         }
1021 1021
         // prep the answer
@@ -1031,13 +1031,13 @@  discard block
 block discarded – undo
1031 1031
         // ya gots ta have style man!!!
1032 1032
         $txt_class = is_admin() ? 'regular-text' : 'espresso-textarea-inp';
1033 1033
         $class     = empty($class) ? $txt_class : $class;
1034
-        $class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
1034
+        $class     .= ! empty($system_ID) ? ' '.$system_ID : '';
1035 1035
         $extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1036 1036
 
1037 1037
         $label_html =
1038 1038
             $required_text
1039 1039
             . "\n\t\t\t"
1040
-            . '<label for="' . $name . '" class="' . $label_class . '">'
1040
+            . '<label for="'.$name.'" class="'.$label_class.'">'
1041 1041
             . self::prep_question($question)
1042 1042
             . $required['label']
1043 1043
             . '</label><br/>';
@@ -1046,14 +1046,14 @@  discard block
 block discarded – undo
1046 1046
 
1047 1047
         $input_html =
1048 1048
             "\n\t\t\t"
1049
-            . '<textarea name="' . $name . '" id="' . $id . '" class="' . $class . ' ' . $required['class'] . '" '
1050
-            . 'rows="' . $dimensions['rows'] . '" cols="' . $dimensions['cols'] . '"  '
1051
-            . 'title="' . $required['msg'] . '" ' . $disabled . ' ' . $extra . '>'
1049
+            . '<textarea name="'.$name.'" id="'.$id.'" class="'.$class.' '.$required['class'].'" '
1050
+            . 'rows="'.$dimensions['rows'].'" cols="'.$dimensions['cols'].'"  '
1051
+            . 'title="'.$required['msg'].'" '.$disabled.' '.$extra.'>'
1052 1052
             . esc_textarea($answer)
1053 1053
             . '</textarea>';
1054 1054
 
1055 1055
         $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1056
-        return $label_html . $input_html;
1056
+        return $label_html.$input_html;
1057 1057
     }
1058 1058
 
1059 1059
 
@@ -1090,7 +1090,7 @@  discard block
 block discarded – undo
1090 1090
     ) {
1091 1091
 
1092 1092
         // need these
1093
-        if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1093
+        if ( ! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1094 1094
             return null;
1095 1095
         }
1096 1096
         // prep the answer
@@ -1108,13 +1108,13 @@  discard block
 block discarded – undo
1108 1108
         // ya gots ta have style man!!!
1109 1109
         $txt_class = is_admin() ? 'wide' : 'espresso-select-inp';
1110 1110
         $class     = empty($class) ? $txt_class : $class;
1111
-        $class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
1111
+        $class     .= ! empty($system_ID) ? ' '.$system_ID : '';
1112 1112
         $extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1113 1113
 
1114 1114
         $label_html =
1115 1115
             $required_text
1116 1116
             . "\n\t\t\t"
1117
-            . '<label for="' . $name . '" class="' . $label_class . '">'
1117
+            . '<label for="'.$name.'" class="'.$label_class.'">'
1118 1118
             . self::prep_question($question)
1119 1119
             . $required['label']
1120 1120
             . '</label><br/>';
@@ -1123,16 +1123,16 @@  discard block
 block discarded – undo
1123 1123
 
1124 1124
         $input_html =
1125 1125
             "\n\t\t\t"
1126
-            . '<select name="' . $name . '" id="' . $id . '" class="' . $class . ' ' . $required['class'] . '" '
1127
-            . 'title="' . esc_attr($required['msg']) . '"' . $disabled . ' ' . $extra . '>';
1126
+            . '<select name="'.$name.'" id="'.$id.'" class="'.$class.' '.$required['class'].'" '
1127
+            . 'title="'.esc_attr($required['msg']).'"'.$disabled.' '.$extra.'>';
1128 1128
         // recursively count array elements, to determine total number of options
1129 1129
         $only_option = count($options, 1) == 1;
1130
-        if (! $only_option) {
1130
+        if ( ! $only_option) {
1131 1131
             // if there is NO answer set and there are multiple options to choose from, then set the "please select" message as selected
1132
-            $selected   = $answer === null ? ' selected' : '';
1132
+            $selected = $answer === null ? ' selected' : '';
1133 1133
             $input_html .= $add_please_select_option
1134 1134
                 ? "\n\t\t\t\t"
1135
-                  . '<option value=""' . $selected . '>'
1135
+                  . '<option value=""'.$selected.'>'
1136 1136
                   . esc_html__(' - please select - ', 'event_espresso')
1137 1137
                   . '</option>'
1138 1138
                 : '';
@@ -1155,7 +1155,7 @@  discard block
 block discarded – undo
1155 1155
                 );
1156 1156
         }
1157 1157
 
1158
-        $input_html .= "\n\t\t\t" . '</select>';
1158
+        $input_html .= "\n\t\t\t".'</select>';
1159 1159
 
1160 1160
         $input_html =
1161 1161
             apply_filters(
@@ -1170,7 +1170,7 @@  discard block
 block discarded – undo
1170 1170
             );
1171 1171
 
1172 1172
         $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1173
-        return $label_html . $input_html;
1173
+        return $label_html.$input_html;
1174 1174
     }
1175 1175
 
1176 1176
 
@@ -1188,11 +1188,11 @@  discard block
 block discarded – undo
1188 1188
      */
1189 1189
     private static function _generate_select_option_group($opt_group, $QSOs, $answer, $use_html_entities = true)
1190 1190
     {
1191
-        $html = "\n\t\t\t\t" . '<optgroup label="' . self::prep_option_value($opt_group) . '">';
1191
+        $html = "\n\t\t\t\t".'<optgroup label="'.self::prep_option_value($opt_group).'">';
1192 1192
         foreach ($QSOs as $QSO) {
1193 1193
             $html .= self::_generate_select_option($QSO->value(), $QSO->desc(), $answer, false, $use_html_entities);
1194 1194
         }
1195
-        $html .= "\n\t\t\t\t" . '</optgroup>';
1195
+        $html .= "\n\t\t\t\t".'</optgroup>';
1196 1196
         return $html;
1197 1197
     }
1198 1198
 
@@ -1219,7 +1219,7 @@  discard block
 block discarded – undo
1219 1219
         $value    = ! empty($value) ? $value : $key;
1220 1220
         $selected = ($answer == $key || $only_option) ? 'selected' : '';
1221 1221
         return "\n\t\t\t\t"
1222
-               . '<option value="' . self::prep_option_value($key) . '" ' . $selected . '> '
1222
+               . '<option value="'.self::prep_option_value($key).'" '.$selected.'> '
1223 1223
                . $value
1224 1224
                . '&nbsp;&nbsp;&nbsp;</option>';
1225 1225
     }
@@ -1263,7 +1263,7 @@  discard block
 block discarded – undo
1263 1263
         $use_desc_4_label = false
1264 1264
     ) {
1265 1265
         // need these
1266
-        if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1266
+        if ( ! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1267 1267
             return null;
1268 1268
         }
1269 1269
         // prep the answer
@@ -1280,7 +1280,7 @@  discard block
 block discarded – undo
1280 1280
         $label_html =
1281 1281
             $required_text
1282 1282
             . "\n\t\t\t"
1283
-            . '<label class="' . $label_class . '">'
1283
+            . '<label class="'.$label_class.'">'
1284 1284
             . self::prep_question($question)
1285 1285
             . $required['label']
1286 1286
             . '</label> ';
@@ -1289,49 +1289,49 @@  discard block
 block discarded – undo
1289 1289
 
1290 1290
         $input_html =
1291 1291
             "\n\t\t\t"
1292
-            . '<ul id="' . $id . '-ul" class="espresso-radio-btn-options-ul ' . $label_class . ' ' . $class . '-ul">';
1292
+            . '<ul id="'.$id.'-ul" class="espresso-radio-btn-options-ul '.$label_class.' '.$class.'-ul">';
1293 1293
 
1294
-        $class .= ! empty($system_ID) ? ' ' . $system_ID : '';
1295
-        $class .= ! empty($required['class']) ? ' ' . $required['class'] : '';
1294
+        $class .= ! empty($system_ID) ? ' '.$system_ID : '';
1295
+        $class .= ! empty($required['class']) ? ' '.$required['class'] : '';
1296 1296
 
1297 1297
         foreach ($options as $OPT) {
1298 1298
             if ($OPT instanceof EE_Question_Option) {
1299 1299
                 $value   = self::prep_option_value($OPT->value());
1300 1300
                 $label   = $use_desc_4_label ? $OPT->desc() : $OPT->value();
1301 1301
                 $size    = $use_desc_4_label
1302
-                    ? self::get_label_size_class($OPT->value() . ' ' . $OPT->desc())
1302
+                    ? self::get_label_size_class($OPT->value().' '.$OPT->desc())
1303 1303
                     : self::get_label_size_class($OPT->value());
1304
-                $desc    = $OPT->desc();// no self::prep_answer
1304
+                $desc    = $OPT->desc(); // no self::prep_answer
1305 1305
                 $answer  = is_numeric($value) && empty($answer) ? 0 : $answer;
1306 1306
                 $checked = (string) $value == (string) $answer ? ' checked' : '';
1307
-                $opt     = '-' . sanitize_key($value);
1307
+                $opt     = '-'.sanitize_key($value);
1308 1308
 
1309
-                $input_html .= "\n\t\t\t\t" . '<li' . $size . '>';
1310
-                $input_html .= "\n\t\t\t\t\t" . '<label class="' . $radio_class . ' espresso-radio-btn-lbl">';
1311
-                $input_html .= $label_b4 ? "\n\t\t\t\t\t\t" . '<span>' . $label . '</span>' : '';
1309
+                $input_html .= "\n\t\t\t\t".'<li'.$size.'>';
1310
+                $input_html .= "\n\t\t\t\t\t".'<label class="'.$radio_class.' espresso-radio-btn-lbl">';
1311
+                $input_html .= $label_b4 ? "\n\t\t\t\t\t\t".'<span>'.$label.'</span>' : '';
1312 1312
                 $input_html .= "\n\t\t\t\t\t\t"
1313
-                               . '<input type="radio" name="' . $name . '" id="' . $id . $opt . '" '
1314
-                               . 'class="' . $class . '" value="' . $value . '" '
1315
-                               . 'title="' . esc_attr($required['msg']) . '" ' . $disabled
1316
-                               . $checked . ' ' . $extra . '/>';
1313
+                               . '<input type="radio" name="'.$name.'" id="'.$id.$opt.'" '
1314
+                               . 'class="'.$class.'" value="'.$value.'" '
1315
+                               . 'title="'.esc_attr($required['msg']).'" '.$disabled
1316
+                               . $checked.' '.$extra.'/>';
1317 1317
                 $input_html .= ! $label_b4
1318 1318
                     ? "\n\t\t\t\t\t\t"
1319 1319
                       . '<span class="espresso-radio-btn-desc">'
1320 1320
                       . $label
1321 1321
                       . '</span>'
1322 1322
                     : '';
1323
-                $input_html .= "\n\t\t\t\t\t" . '</label>';
1323
+                $input_html .= "\n\t\t\t\t\t".'</label>';
1324 1324
                 $input_html .= $use_desc_4_label
1325 1325
                     ? ''
1326
-                    : '<span class="espresso-radio-btn-option-desc small-text grey-text">' . $desc . '</span>';
1327
-                $input_html .= "\n\t\t\t\t" . '</li>';
1326
+                    : '<span class="espresso-radio-btn-option-desc small-text grey-text">'.$desc.'</span>';
1327
+                $input_html .= "\n\t\t\t\t".'</li>';
1328 1328
             }
1329 1329
         }
1330 1330
 
1331
-        $input_html .= "\n\t\t\t" . '</ul>';
1331
+        $input_html .= "\n\t\t\t".'</ul>';
1332 1332
 
1333 1333
         $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1334
-        return $label_html . $input_html;
1334
+        return $label_html.$input_html;
1335 1335
     }
1336 1336
 
1337 1337
 
@@ -1366,7 +1366,7 @@  discard block
 block discarded – undo
1366 1366
         $use_html_entities = true
1367 1367
     ) {
1368 1368
         // need these
1369
-        if (! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1369
+        if ( ! $question || ! $name || ! $options || empty($options) || ! is_array($options)) {
1370 1370
             return null;
1371 1371
         }
1372 1372
         $answer = maybe_unserialize($answer);
@@ -1376,7 +1376,7 @@  discard block
 block discarded – undo
1376 1376
 
1377 1377
         foreach ($answer as $key => $value) {
1378 1378
             $key            = self::prep_option_value($key);
1379
-            $answer[ $key ] = self::prep_answer($value, $use_html_entities);
1379
+            $answer[$key] = self::prep_answer($value, $use_html_entities);
1380 1380
         }
1381 1381
 
1382 1382
         // prep the required array
@@ -1391,7 +1391,7 @@  discard block
 block discarded – undo
1391 1391
         $label_html =
1392 1392
             $required_text
1393 1393
             . "\n\t\t\t"
1394
-            . '<label class="' . $label_class . '">'
1394
+            . '<label class="'.$label_class.'">'
1395 1395
             . self::prep_question($question)
1396 1396
             . $required['label']
1397 1397
             . '</label> ';
@@ -1400,42 +1400,42 @@  discard block
 block discarded – undo
1400 1400
 
1401 1401
         $input_html =
1402 1402
             "\n\t\t\t"
1403
-            . '<ul id="' . $id . '-ul" class="espresso-checkbox-options-ul ' . $label_class . ' ' . $class . '-ul">';
1403
+            . '<ul id="'.$id.'-ul" class="espresso-checkbox-options-ul '.$label_class.' '.$class.'-ul">';
1404 1404
 
1405
-        $class .= ! empty($system_ID) ? ' ' . $system_ID : '';
1406
-        $class .= ! empty($required['class']) ? ' ' . $required['class'] : '';
1405
+        $class .= ! empty($system_ID) ? ' '.$system_ID : '';
1406
+        $class .= ! empty($required['class']) ? ' '.$required['class'] : '';
1407 1407
 
1408 1408
         foreach ($options as $OPT) {
1409
-            $value = $OPT->value();// self::prep_option_value( $OPT->value() );
1410
-            $size  = self::get_label_size_class($OPT->value() . ' ' . $OPT->desc());
1409
+            $value = $OPT->value(); // self::prep_option_value( $OPT->value() );
1410
+            $size  = self::get_label_size_class($OPT->value().' '.$OPT->desc());
1411 1411
             $text  = self::prep_answer($OPT->value());
1412 1412
             $desc  = $OPT->desc();
1413
-            $opt   = '-' . sanitize_key($value);
1413
+            $opt   = '-'.sanitize_key($value);
1414 1414
 
1415 1415
             $checked = is_array($answer) && in_array($text, $answer) ? ' checked' : '';
1416 1416
 
1417
-            $input_html .= "\n\t\t\t\t" . '<li' . $size . '>';
1418
-            $input_html .= "\n\t\t\t\t\t" . '<label class="' . $radio_class . ' espresso-checkbox-lbl">';
1419
-            $input_html .= $label_b4 ? "\n\t\t\t\t\t\t" . '<span>' . $text . '</span>' : '';
1417
+            $input_html .= "\n\t\t\t\t".'<li'.$size.'>';
1418
+            $input_html .= "\n\t\t\t\t\t".'<label class="'.$radio_class.' espresso-checkbox-lbl">';
1419
+            $input_html .= $label_b4 ? "\n\t\t\t\t\t\t".'<span>'.$text.'</span>' : '';
1420 1420
             $input_html .= "\n\t\t\t\t\t\t"
1421
-                           . '<input type="checkbox" name="' . $name . '[' . $OPT->ID() . ']" '
1422
-                           . 'id="' . $id . $opt . '" class="' . $class . '" value="' . $value . '" '
1423
-                           . 'title="' . esc_attr($required['msg']) . '" ' . $disabled . $checked . ' ' . $extra . '/>';
1424
-            $input_html .= ! $label_b4 ? "\n\t\t\t\t\t\t" . '<span>' . $text . '</span>' : '';
1425
-            $input_html .= "\n\t\t\t\t\t" . '</label>';
1426
-            if (! empty($desc) && $desc != $text) {
1421
+                           . '<input type="checkbox" name="'.$name.'['.$OPT->ID().']" '
1422
+                           . 'id="'.$id.$opt.'" class="'.$class.'" value="'.$value.'" '
1423
+                           . 'title="'.esc_attr($required['msg']).'" '.$disabled.$checked.' '.$extra.'/>';
1424
+            $input_html .= ! $label_b4 ? "\n\t\t\t\t\t\t".'<span>'.$text.'</span>' : '';
1425
+            $input_html .= "\n\t\t\t\t\t".'</label>';
1426
+            if ( ! empty($desc) && $desc != $text) {
1427 1427
                 $input_html .= "\n\t\t\t\t\t"
1428 1428
                                . ' &nbsp; <br/><div class="espresso-checkbox-option-desc small-text grey-text">'
1429 1429
                                . $desc
1430 1430
                                . '</div>';
1431 1431
             }
1432
-            $input_html .= "\n\t\t\t\t" . '</li>';
1432
+            $input_html .= "\n\t\t\t\t".'</li>';
1433 1433
         }
1434 1434
 
1435
-        $input_html .= "\n\t\t\t" . '</ul>';
1435
+        $input_html .= "\n\t\t\t".'</ul>';
1436 1436
 
1437 1437
         $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1438
-        return $label_html . $input_html;
1438
+        return $label_html.$input_html;
1439 1439
     }
1440 1440
 
1441 1441
 
@@ -1467,7 +1467,7 @@  discard block
 block discarded – undo
1467 1467
         $use_html_entities = true
1468 1468
     ) {
1469 1469
         // need these
1470
-        if (! $question || ! $name) {
1470
+        if ( ! $question || ! $name) {
1471 1471
             return null;
1472 1472
         }
1473 1473
         // prep the answer
@@ -1479,13 +1479,13 @@  discard block
 block discarded – undo
1479 1479
         // ya gots ta have style man!!!
1480 1480
         $txt_class = is_admin() ? 'regular-text' : 'espresso-datepicker-inp';
1481 1481
         $class     = empty($class) ? $txt_class : $class;
1482
-        $class     .= ! empty($system_ID) ? ' ' . $system_ID : '';
1482
+        $class     .= ! empty($system_ID) ? ' '.$system_ID : '';
1483 1483
         $extra     = apply_filters('FHEE__EEH_Form_Fields__additional_form_field_attributes', '');
1484 1484
 
1485 1485
         $label_html =
1486 1486
             $required_text
1487 1487
             . "\n\t\t\t"
1488
-            . '<label for="' . $name . '" class="' . $label_class . '">'
1488
+            . '<label for="'.$name.'" class="'.$label_class.'">'
1489 1489
             . self::prep_question($question)
1490 1490
             . $required['label']
1491 1491
             . '</label><br/>';
@@ -1494,14 +1494,14 @@  discard block
 block discarded – undo
1494 1494
 
1495 1495
         $input_html =
1496 1496
             "\n\t\t\t"
1497
-            . '<input type="text" name="' . $name . '" id="' . $id . '" '
1498
-            . 'class="' . $class . ' ' . $required['class'] . ' datepicker" value="' . $answer . '"  '
1499
-            . 'title="' . esc_attr($required['msg']) . '" ' . $disabled . ' ' . $extra . '/>';
1497
+            . '<input type="text" name="'.$name.'" id="'.$id.'" '
1498
+            . 'class="'.$class.' '.$required['class'].' datepicker" value="'.$answer.'"  '
1499
+            . 'title="'.esc_attr($required['msg']).'" '.$disabled.' '.$extra.'/>';
1500 1500
 
1501 1501
         // enqueue scripts
1502 1502
         wp_register_style(
1503 1503
             'espresso-ui-theme',
1504
-            EE_GLOBAL_ASSETS_URL . 'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
1504
+            EE_GLOBAL_ASSETS_URL.'css/espresso-ui-theme/jquery-ui-1.10.3.custom.min.css',
1505 1505
             [],
1506 1506
             EVENT_ESPRESSO_VERSION
1507 1507
         );
@@ -1509,7 +1509,7 @@  discard block
 block discarded – undo
1509 1509
         wp_enqueue_script('jquery-ui-datepicker');
1510 1510
 
1511 1511
         $input_html = apply_filters('FHEE__EEH_Form_Fields__input_html', $input_html, $label_html, $id);
1512
-        return $label_html . $input_html;
1512
+        return $label_html.$input_html;
1513 1513
     }
1514 1514
 
1515 1515
 
@@ -1536,7 +1536,7 @@  discard block
 block discarded – undo
1536 1536
     public static function hidden_input($name, $value, $id = '')
1537 1537
     {
1538 1538
         $id = ! empty($id) ? $id : $name;
1539
-        return '<input id="' . $id . '" type="hidden" name="' . $name . '" value="' . $value . '"/>';
1539
+        return '<input id="'.$id.'" type="hidden" name="'.$name.'" value="'.$value.'"/>';
1540 1540
     }
1541 1541
 
1542 1542
 
@@ -1581,7 +1581,7 @@  discard block
 block discarded – undo
1581 1581
         $prepped_answer_options = [];
1582 1582
         if (is_array($QSOs) && ! empty($QSOs)) {
1583 1583
             foreach ($QSOs as $key => $QSO) {
1584
-                if (! $QSO instanceof EE_Question_Option) {
1584
+                if ( ! $QSO instanceof EE_Question_Option) {
1585 1585
                     $QSO = EE_Question_Option::new_instance(
1586 1586
                         [
1587 1587
                             'QSO_value' => is_array($QSO) && isset($QSO['id'])
@@ -1594,7 +1594,7 @@  discard block
 block discarded – undo
1594 1594
                     );
1595 1595
                 }
1596 1596
                 if ($QSO->opt_group()) {
1597
-                    $prepped_answer_options[ $QSO->opt_group() ][] = $QSO;
1597
+                    $prepped_answer_options[$QSO->opt_group()][] = $QSO;
1598 1598
                 } else {
1599 1599
                     $prepped_answer_options[] = $QSO;
1600 1600
                 }
@@ -1806,7 +1806,7 @@  discard block
 block discarded – undo
1806 1806
         $options = [];
1807 1807
         for ($x = 1; $x <= 12; $x++) {
1808 1808
             $mm             = str_pad($x, 2, '0', STR_PAD_LEFT);
1809
-            $options[ $mm ] = $mm;
1809
+            $options[$mm] = $mm;
1810 1810
         }
1811 1811
         return EEH_Form_Fields::prep_answer_options($options);
1812 1812
     }
@@ -1824,7 +1824,7 @@  discard block
 block discarded – undo
1824 1824
         $next_decade  = $current_year + 10;
1825 1825
         for ($x = $current_year; $x <= $next_decade; $x++) {
1826 1826
             $yy             = str_pad($x, 2, '0', STR_PAD_LEFT);
1827
-            $options[ $yy ] = $yy;
1827
+            $options[$yy] = $yy;
1828 1828
         }
1829 1829
         return EEH_Form_Fields::prep_answer_options($options);
1830 1830
     }
@@ -1843,7 +1843,7 @@  discard block
 block discarded – undo
1843 1843
     public static function generate_registration_months_dropdown($cur_date = '', $status = '', $evt_category = 0)
1844 1844
     {
1845 1845
         $_where = [];
1846
-        if (! empty($status)) {
1846
+        if ( ! empty($status)) {
1847 1847
             $_where['STS_ID'] = $status;
1848 1848
         }
1849 1849
 
@@ -1862,7 +1862,7 @@  discard block
 block discarded – undo
1862 1862
         ];
1863 1863
 
1864 1864
         foreach ($regdtts as $regdtt) {
1865
-            $date      = $regdtt->reg_month . ' ' . $regdtt->reg_year;
1865
+            $date      = $regdtt->reg_month.' '.$regdtt->reg_year;
1866 1866
             $options[] = [
1867 1867
                 'text' => $date,
1868 1868
                 'id'   => $date,
@@ -1911,7 +1911,7 @@  discard block
 block discarded – undo
1911 1911
         // categories?
1912 1912
 
1913 1913
 
1914
-        if (! empty($evt_category)) {
1914
+        if ( ! empty($evt_category)) {
1915 1915
             $where['Event.Term_Taxonomy.taxonomy'] = 'espresso_event_categories';
1916 1916
             $where['Event.Term_Taxonomy.term_id']  = $evt_category;
1917 1917
         }
@@ -1934,8 +1934,8 @@  discard block
 block discarded – undo
1934 1934
         global $wp_locale;
1935 1935
 
1936 1936
         foreach ($DTTS as $DTT) {
1937
-            $localized_date = $wp_locale->get_month($DTT->dtt_month_num) . ' ' . $DTT->dtt_year;
1938
-            $id             = $DTT->dtt_month . ' ' . $DTT->dtt_year;
1937
+            $localized_date = $wp_locale->get_month($DTT->dtt_month_num).' '.$DTT->dtt_year;
1938
+            $id             = $DTT->dtt_month.' '.$DTT->dtt_year;
1939 1939
             $options[]      = [
1940 1940
                 'text' => $localized_date,
1941 1941
                 'id'   => $id,
@@ -2008,16 +2008,16 @@  discard block
 block discarded – undo
2008 2008
             return $btn;
2009 2009
         }
2010 2010
         $text = ! empty($text) ? $text : esc_html__('Submit', 'event_espresso');
2011
-        $btn  .= '<input id="' . $ID . '-btn" class="' . $class . '" '
2012
-                 . 'type="submit" value="' . $text . '" ' . $extra_attributes . '/>';
2013
-        if (! $input_only) {
2014
-            $btn_frm = '<form id="' . $ID . '-frm" method="POST" action="' . $url . '">';
2011
+        $btn .= '<input id="'.$ID.'-btn" class="'.$class.'" '
2012
+                 . 'type="submit" value="'.$text.'" '.$extra_attributes.'/>';
2013
+        if ( ! $input_only) {
2014
+            $btn_frm = '<form id="'.$ID.'-frm" method="POST" action="'.$url.'">';
2015 2015
             $btn_frm .= ! empty($nonce_action)
2016
-                ? wp_nonce_field($nonce_action, $nonce_action . '_nonce', true, false)
2016
+                ? wp_nonce_field($nonce_action, $nonce_action.'_nonce', true, false)
2017 2017
                 : '';
2018 2018
             $btn_frm .= $btn;
2019 2019
             $btn_frm .= '</form>';
2020
-            $btn     = $btn_frm;
2020
+            $btn = $btn_frm;
2021 2021
             unset($btn_frm);
2022 2022
         }
2023 2023
         return $btn;
Please login to merge, or discard this patch.
core/helpers/EEH_DTT_Helper.helper.php 2 patches
Indentation   +983 added lines, -983 removed lines patch added patch discarded remove patch
@@ -17,1045 +17,1045 @@
 block discarded – undo
17 17
 {
18 18
 
19 19
 
20
-    /**
21
-     * return the timezone set for the WP install
22
-     *
23
-     * @return string valid timezone string for PHP DateTimeZone() class
24
-     * @throws InvalidArgumentException
25
-     * @throws InvalidDataTypeException
26
-     * @throws InvalidInterfaceException
27
-     */
28
-    public static function get_timezone()
29
-    {
30
-        return EEH_DTT_Helper::get_valid_timezone_string();
31
-    }
20
+	/**
21
+	 * return the timezone set for the WP install
22
+	 *
23
+	 * @return string valid timezone string for PHP DateTimeZone() class
24
+	 * @throws InvalidArgumentException
25
+	 * @throws InvalidDataTypeException
26
+	 * @throws InvalidInterfaceException
27
+	 */
28
+	public static function get_timezone()
29
+	{
30
+		return EEH_DTT_Helper::get_valid_timezone_string();
31
+	}
32 32
 
33 33
 
34
-    /**
35
-     * get_valid_timezone_string
36
-     *    ensures that a valid timezone string is returned
37
-     *
38
-     * @param string $timezone_string
39
-     * @return string
40
-     * @throws InvalidArgumentException
41
-     * @throws InvalidDataTypeException
42
-     * @throws InvalidInterfaceException
43
-     */
44
-    public static function get_valid_timezone_string($timezone_string = '')
45
-    {
46
-        return self::getHelperAdapter()->getValidTimezoneString($timezone_string);
47
-    }
34
+	/**
35
+	 * get_valid_timezone_string
36
+	 *    ensures that a valid timezone string is returned
37
+	 *
38
+	 * @param string $timezone_string
39
+	 * @return string
40
+	 * @throws InvalidArgumentException
41
+	 * @throws InvalidDataTypeException
42
+	 * @throws InvalidInterfaceException
43
+	 */
44
+	public static function get_valid_timezone_string($timezone_string = '')
45
+	{
46
+		return self::getHelperAdapter()->getValidTimezoneString($timezone_string);
47
+	}
48 48
 
49 49
 
50
-    /**
51
-     * This only purpose for this static method is to validate that the incoming timezone is a valid php timezone.
52
-     *
53
-     * @static
54
-     * @param  string $timezone_string Timezone string to check
55
-     * @param bool    $throw_error
56
-     * @return bool
57
-     * @throws InvalidArgumentException
58
-     * @throws InvalidDataTypeException
59
-     * @throws InvalidInterfaceException
60
-     */
61
-    public static function validate_timezone($timezone_string, $throw_error = true)
62
-    {
63
-        return self::getHelperAdapter()->validateTimezone($timezone_string, $throw_error);
64
-    }
50
+	/**
51
+	 * This only purpose for this static method is to validate that the incoming timezone is a valid php timezone.
52
+	 *
53
+	 * @static
54
+	 * @param  string $timezone_string Timezone string to check
55
+	 * @param bool    $throw_error
56
+	 * @return bool
57
+	 * @throws InvalidArgumentException
58
+	 * @throws InvalidDataTypeException
59
+	 * @throws InvalidInterfaceException
60
+	 */
61
+	public static function validate_timezone($timezone_string, $throw_error = true)
62
+	{
63
+		return self::getHelperAdapter()->validateTimezone($timezone_string, $throw_error);
64
+	}
65 65
 
66 66
 
67
-    /**
68
-     * This returns a string that can represent the provided gmt offset in format that can be passed into
69
-     * DateTimeZone.  This is NOT a string that can be passed as a value on the WordPress timezone_string option.
70
-     *
71
-     * @param float|string $gmt_offset
72
-     * @return string
73
-     * @throws InvalidArgumentException
74
-     * @throws InvalidDataTypeException
75
-     * @throws InvalidInterfaceException
76
-     */
77
-    public static function get_timezone_string_from_gmt_offset($gmt_offset = '')
78
-    {
79
-        return self::getHelperAdapter()->getTimezoneStringFromGmtOffset($gmt_offset);
80
-    }
67
+	/**
68
+	 * This returns a string that can represent the provided gmt offset in format that can be passed into
69
+	 * DateTimeZone.  This is NOT a string that can be passed as a value on the WordPress timezone_string option.
70
+	 *
71
+	 * @param float|string $gmt_offset
72
+	 * @return string
73
+	 * @throws InvalidArgumentException
74
+	 * @throws InvalidDataTypeException
75
+	 * @throws InvalidInterfaceException
76
+	 */
77
+	public static function get_timezone_string_from_gmt_offset($gmt_offset = '')
78
+	{
79
+		return self::getHelperAdapter()->getTimezoneStringFromGmtOffset($gmt_offset);
80
+	}
81 81
 
82 82
 
83
-    /**
84
-     * Gets the site's GMT offset based on either the timezone string
85
-     * (in which case teh gmt offset will vary depending on the location's
86
-     * observance of daylight savings time) or the gmt_offset wp option
87
-     *
88
-     * @return int seconds offset
89
-     * @throws InvalidArgumentException
90
-     * @throws InvalidDataTypeException
91
-     * @throws InvalidInterfaceException
92
-     */
93
-    public static function get_site_timezone_gmt_offset()
94
-    {
95
-        return self::getHelperAdapter()->getSiteTimezoneGmtOffset();
96
-    }
83
+	/**
84
+	 * Gets the site's GMT offset based on either the timezone string
85
+	 * (in which case teh gmt offset will vary depending on the location's
86
+	 * observance of daylight savings time) or the gmt_offset wp option
87
+	 *
88
+	 * @return int seconds offset
89
+	 * @throws InvalidArgumentException
90
+	 * @throws InvalidDataTypeException
91
+	 * @throws InvalidInterfaceException
92
+	 */
93
+	public static function get_site_timezone_gmt_offset()
94
+	{
95
+		return self::getHelperAdapter()->getSiteTimezoneGmtOffset();
96
+	}
97 97
 
98 98
 
99
-    /**
100
-     * Depending on PHP version,
101
-     * there might not be valid current timezone strings to match these gmt_offsets in its timezone tables.
102
-     * To get around that, for these fringe timezones we bump them to a known valid offset.
103
-     * This method should ONLY be called after first verifying an timezone_string cannot be retrieved for the offset.
104
-     *
105
-     * @deprecated 4.9.54.rc    Developers this was always meant to only be an internally used method.  This will be
106
-     *                          removed in a future version of EE.
107
-     * @param int $gmt_offset
108
-     * @return int
109
-     * @throws InvalidArgumentException
110
-     * @throws InvalidDataTypeException
111
-     * @throws InvalidInterfaceException
112
-     */
113
-    public static function adjust_invalid_gmt_offsets($gmt_offset = 0)
114
-    {
115
-        return self::getHelperAdapter()->adjustInvalidGmtOffsets($gmt_offset);
116
-    }
99
+	/**
100
+	 * Depending on PHP version,
101
+	 * there might not be valid current timezone strings to match these gmt_offsets in its timezone tables.
102
+	 * To get around that, for these fringe timezones we bump them to a known valid offset.
103
+	 * This method should ONLY be called after first verifying an timezone_string cannot be retrieved for the offset.
104
+	 *
105
+	 * @deprecated 4.9.54.rc    Developers this was always meant to only be an internally used method.  This will be
106
+	 *                          removed in a future version of EE.
107
+	 * @param int $gmt_offset
108
+	 * @return int
109
+	 * @throws InvalidArgumentException
110
+	 * @throws InvalidDataTypeException
111
+	 * @throws InvalidInterfaceException
112
+	 */
113
+	public static function adjust_invalid_gmt_offsets($gmt_offset = 0)
114
+	{
115
+		return self::getHelperAdapter()->adjustInvalidGmtOffsets($gmt_offset);
116
+	}
117 117
 
118 118
 
119
-    /**
120
-     * get_timezone_string_from_abbreviations_list
121
-     *
122
-     * @deprecated 4.9.54.rc  Developers, this was never intended to be public.  This is a soft deprecation for now.
123
-     *                        If you are using this, you'll want to work out an alternate way of getting the value.
124
-     * @param int  $gmt_offset
125
-     * @param bool $coerce If true, we attempt to coerce with our adjustment table @see self::adjust_invalid_gmt_offset.
126
-     * @return string
127
-     * @throws EE_Error
128
-     * @throws InvalidArgumentException
129
-     * @throws InvalidDataTypeException
130
-     * @throws InvalidInterfaceException
131
-     */
132
-    public static function get_timezone_string_from_abbreviations_list($gmt_offset = 0, $coerce = true)
133
-    {
134
-        $gmt_offset =  (int) $gmt_offset;
135
-        /** @var array[] $abbreviations */
136
-        $abbreviations = DateTimeZone::listAbbreviations();
137
-        foreach ($abbreviations as $abbreviation) {
138
-            foreach ($abbreviation as $timezone) {
139
-                if ((int) $timezone['offset'] === $gmt_offset && (bool) $timezone['dst'] === false) {
140
-                    try {
141
-                        $offset = self::get_timezone_offset(new DateTimeZone($timezone['timezone_id']));
142
-                        if ($offset !== $gmt_offset) {
143
-                            continue;
144
-                        }
145
-                        return $timezone['timezone_id'];
146
-                    } catch (Exception $e) {
147
-                        continue;
148
-                    }
149
-                }
150
-            }
151
-        }
152
-        // if $coerce is true, let's see if we can get a timezone string after the offset is adjusted
153
-        if ($coerce === true) {
154
-            $timezone_string = self::get_timezone_string_from_abbreviations_list(
155
-                self::adjust_invalid_gmt_offsets($gmt_offset),
156
-                false
157
-            );
158
-            if ($timezone_string) {
159
-                return $timezone_string;
160
-            }
161
-        }
162
-        throw new EE_Error(
163
-            sprintf(
164
-                esc_html__(
165
-                    'The provided GMT offset (%1$s), is invalid, please check with %2$sthis list%3$s for what valid timezones can be used',
166
-                    'event_espresso'
167
-                ),
168
-                $gmt_offset / HOUR_IN_SECONDS,
169
-                '<a href="http://www.php.net/manual/en/timezones.php">',
170
-                '</a>'
171
-            )
172
-        );
173
-    }
119
+	/**
120
+	 * get_timezone_string_from_abbreviations_list
121
+	 *
122
+	 * @deprecated 4.9.54.rc  Developers, this was never intended to be public.  This is a soft deprecation for now.
123
+	 *                        If you are using this, you'll want to work out an alternate way of getting the value.
124
+	 * @param int  $gmt_offset
125
+	 * @param bool $coerce If true, we attempt to coerce with our adjustment table @see self::adjust_invalid_gmt_offset.
126
+	 * @return string
127
+	 * @throws EE_Error
128
+	 * @throws InvalidArgumentException
129
+	 * @throws InvalidDataTypeException
130
+	 * @throws InvalidInterfaceException
131
+	 */
132
+	public static function get_timezone_string_from_abbreviations_list($gmt_offset = 0, $coerce = true)
133
+	{
134
+		$gmt_offset =  (int) $gmt_offset;
135
+		/** @var array[] $abbreviations */
136
+		$abbreviations = DateTimeZone::listAbbreviations();
137
+		foreach ($abbreviations as $abbreviation) {
138
+			foreach ($abbreviation as $timezone) {
139
+				if ((int) $timezone['offset'] === $gmt_offset && (bool) $timezone['dst'] === false) {
140
+					try {
141
+						$offset = self::get_timezone_offset(new DateTimeZone($timezone['timezone_id']));
142
+						if ($offset !== $gmt_offset) {
143
+							continue;
144
+						}
145
+						return $timezone['timezone_id'];
146
+					} catch (Exception $e) {
147
+						continue;
148
+					}
149
+				}
150
+			}
151
+		}
152
+		// if $coerce is true, let's see if we can get a timezone string after the offset is adjusted
153
+		if ($coerce === true) {
154
+			$timezone_string = self::get_timezone_string_from_abbreviations_list(
155
+				self::adjust_invalid_gmt_offsets($gmt_offset),
156
+				false
157
+			);
158
+			if ($timezone_string) {
159
+				return $timezone_string;
160
+			}
161
+		}
162
+		throw new EE_Error(
163
+			sprintf(
164
+				esc_html__(
165
+					'The provided GMT offset (%1$s), is invalid, please check with %2$sthis list%3$s for what valid timezones can be used',
166
+					'event_espresso'
167
+				),
168
+				$gmt_offset / HOUR_IN_SECONDS,
169
+				'<a href="http://www.php.net/manual/en/timezones.php">',
170
+				'</a>'
171
+			)
172
+		);
173
+	}
174 174
 
175 175
 
176
-    /**
177
-     * Get Timezone Transitions
178
-     *
179
-     * @param DateTimeZone $date_time_zone
180
-     * @param int|null     $time
181
-     * @param bool         $first_only
182
-     * @return array
183
-     * @throws InvalidArgumentException
184
-     * @throws InvalidDataTypeException
185
-     * @throws InvalidInterfaceException
186
-     */
187
-    public static function get_timezone_transitions(DateTimeZone $date_time_zone, $time = null, $first_only = true)
188
-    {
189
-        return self::getHelperAdapter()->getTimezoneTransitions($date_time_zone, $time, $first_only);
190
-    }
176
+	/**
177
+	 * Get Timezone Transitions
178
+	 *
179
+	 * @param DateTimeZone $date_time_zone
180
+	 * @param int|null     $time
181
+	 * @param bool         $first_only
182
+	 * @return array
183
+	 * @throws InvalidArgumentException
184
+	 * @throws InvalidDataTypeException
185
+	 * @throws InvalidInterfaceException
186
+	 */
187
+	public static function get_timezone_transitions(DateTimeZone $date_time_zone, $time = null, $first_only = true)
188
+	{
189
+		return self::getHelperAdapter()->getTimezoneTransitions($date_time_zone, $time, $first_only);
190
+	}
191 191
 
192 192
 
193
-    /**
194
-     * Get Timezone Offset for given timezone object.
195
-     *
196
-     * @param DateTimeZone $date_time_zone
197
-     * @param null         $time
198
-     * @return mixed
199
-     * @throws InvalidArgumentException
200
-     * @throws InvalidDataTypeException
201
-     * @throws InvalidInterfaceException
202
-     */
203
-    public static function get_timezone_offset(DateTimeZone $date_time_zone, $time = null)
204
-    {
205
-        return self::getHelperAdapter()->getTimezoneOffset($date_time_zone, $time);
206
-    }
193
+	/**
194
+	 * Get Timezone Offset for given timezone object.
195
+	 *
196
+	 * @param DateTimeZone $date_time_zone
197
+	 * @param null         $time
198
+	 * @return mixed
199
+	 * @throws InvalidArgumentException
200
+	 * @throws InvalidDataTypeException
201
+	 * @throws InvalidInterfaceException
202
+	 */
203
+	public static function get_timezone_offset(DateTimeZone $date_time_zone, $time = null)
204
+	{
205
+		return self::getHelperAdapter()->getTimezoneOffset($date_time_zone, $time);
206
+	}
207 207
 
208 208
 
209
-    /**
210
-     * Prints a select input for the given timezone string.
211
-     * @param string $timezone_string
212
-     * @deprecatd 4.9.54.rc   Soft deprecation.  Consider using \EEH_DTT_Helper::wp_timezone_choice instead.
213
-     * @throws InvalidArgumentException
214
-     * @throws InvalidDataTypeException
215
-     * @throws InvalidInterfaceException
216
-     */
217
-    public static function timezone_select_input($timezone_string = '')
218
-    {
219
-        self::getHelperAdapter()->timezoneSelectInput($timezone_string);
220
-    }
209
+	/**
210
+	 * Prints a select input for the given timezone string.
211
+	 * @param string $timezone_string
212
+	 * @deprecatd 4.9.54.rc   Soft deprecation.  Consider using \EEH_DTT_Helper::wp_timezone_choice instead.
213
+	 * @throws InvalidArgumentException
214
+	 * @throws InvalidDataTypeException
215
+	 * @throws InvalidInterfaceException
216
+	 */
217
+	public static function timezone_select_input($timezone_string = '')
218
+	{
219
+		self::getHelperAdapter()->timezoneSelectInput($timezone_string);
220
+	}
221 221
 
222 222
 
223
-    /**
224
-     * This method will take an incoming unix timestamp and add the offset to it for the given timezone_string.
225
-     * If no unix timestamp is given then time() is used.  If no timezone is given then the set timezone string for
226
-     * the site is used.
227
-     * This is used typically when using a Unix timestamp any core WP functions that expect their specially
228
-     * computed timestamp (i.e. date_i18n() )
229
-     *
230
-     * @param int    $unix_timestamp                  if 0, then time() will be used.
231
-     * @param string $timezone_string                 timezone_string. If empty, then the current set timezone for the
232
-     *                                                site will be used.
233
-     * @return int $unix_timestamp with the offset applied for the given timezone.
234
-     * @throws InvalidArgumentException
235
-     * @throws InvalidDataTypeException
236
-     * @throws InvalidInterfaceException
237
-     */
238
-    public static function get_timestamp_with_offset($unix_timestamp = 0, $timezone_string = '')
239
-    {
240
-        return self::getHelperAdapter()->getTimestampWithOffset($unix_timestamp, $timezone_string);
241
-    }
223
+	/**
224
+	 * This method will take an incoming unix timestamp and add the offset to it for the given timezone_string.
225
+	 * If no unix timestamp is given then time() is used.  If no timezone is given then the set timezone string for
226
+	 * the site is used.
227
+	 * This is used typically when using a Unix timestamp any core WP functions that expect their specially
228
+	 * computed timestamp (i.e. date_i18n() )
229
+	 *
230
+	 * @param int    $unix_timestamp                  if 0, then time() will be used.
231
+	 * @param string $timezone_string                 timezone_string. If empty, then the current set timezone for the
232
+	 *                                                site will be used.
233
+	 * @return int $unix_timestamp with the offset applied for the given timezone.
234
+	 * @throws InvalidArgumentException
235
+	 * @throws InvalidDataTypeException
236
+	 * @throws InvalidInterfaceException
237
+	 */
238
+	public static function get_timestamp_with_offset($unix_timestamp = 0, $timezone_string = '')
239
+	{
240
+		return self::getHelperAdapter()->getTimestampWithOffset($unix_timestamp, $timezone_string);
241
+	}
242 242
 
243 243
 
244
-    /**
245
-     *    _set_date_time_field
246
-     *    modifies EE_Base_Class EE_Datetime_Field objects
247
-     *
248
-     * @param  EE_Base_Class $obj                 EE_Base_Class object
249
-     * @param    DateTime    $DateTime            PHP DateTime object
250
-     * @param  string        $datetime_field_name the datetime fieldname to be manipulated
251
-     * @return EE_Base_Class
252
-     * @throws EE_Error
253
-     */
254
-    protected static function _set_date_time_field(EE_Base_Class $obj, DateTime $DateTime, $datetime_field_name)
255
-    {
256
-        // grab current datetime format
257
-        $current_format = $obj->get_format();
258
-        // set new full timestamp format
259
-        $obj->set_date_format(EE_Datetime_Field::mysql_date_format);
260
-        $obj->set_time_format(EE_Datetime_Field::mysql_time_format);
261
-        // set the new date value using a full timestamp format so that no data is lost
262
-        $obj->set($datetime_field_name, $DateTime->format(EE_Datetime_Field::mysql_timestamp_format));
263
-        // reset datetime formats
264
-        $obj->set_date_format($current_format[0]);
265
-        $obj->set_time_format($current_format[1]);
266
-        return $obj;
267
-    }
244
+	/**
245
+	 *    _set_date_time_field
246
+	 *    modifies EE_Base_Class EE_Datetime_Field objects
247
+	 *
248
+	 * @param  EE_Base_Class $obj                 EE_Base_Class object
249
+	 * @param    DateTime    $DateTime            PHP DateTime object
250
+	 * @param  string        $datetime_field_name the datetime fieldname to be manipulated
251
+	 * @return EE_Base_Class
252
+	 * @throws EE_Error
253
+	 */
254
+	protected static function _set_date_time_field(EE_Base_Class $obj, DateTime $DateTime, $datetime_field_name)
255
+	{
256
+		// grab current datetime format
257
+		$current_format = $obj->get_format();
258
+		// set new full timestamp format
259
+		$obj->set_date_format(EE_Datetime_Field::mysql_date_format);
260
+		$obj->set_time_format(EE_Datetime_Field::mysql_time_format);
261
+		// set the new date value using a full timestamp format so that no data is lost
262
+		$obj->set($datetime_field_name, $DateTime->format(EE_Datetime_Field::mysql_timestamp_format));
263
+		// reset datetime formats
264
+		$obj->set_date_format($current_format[0]);
265
+		$obj->set_time_format($current_format[1]);
266
+		return $obj;
267
+	}
268 268
 
269 269
 
270
-    /**
271
-     *    date_time_add
272
-     *    helper for doing simple datetime calculations on a given datetime from EE_Base_Class
273
-     *    and modifying it IN the EE_Base_Class so you don't have to do anything else.
274
-     *
275
-     * @param  EE_Base_Class $obj                 EE_Base_Class object
276
-     * @param  string        $datetime_field_name name of the EE_Datetime_Filed datatype db column to be manipulated
277
-     * @param  string        $period              what you are adding. The options are (years, months, days, hours,
278
-     *                                            minutes, seconds) defaults to years
279
-     * @param  integer       $value               what you want to increment the time by
280
-     * @return EE_Base_Class return the EE_Base_Class object so right away you can do something with it
281
-     *                                            (chaining)
282
-     * @throws EE_Error
283
-     * @throws Exception
284
-     */
285
-    public static function date_time_add(EE_Base_Class $obj, $datetime_field_name, $period = 'years', $value = 1)
286
-    {
287
-        // get the raw UTC date.
288
-        $DateTime = $obj->get_DateTime_object($datetime_field_name);
289
-        $DateTime = EEH_DTT_Helper::calc_date($DateTime, $period, $value);
290
-        return EEH_DTT_Helper::_set_date_time_field($obj, $DateTime, $datetime_field_name);
291
-    }
270
+	/**
271
+	 *    date_time_add
272
+	 *    helper for doing simple datetime calculations on a given datetime from EE_Base_Class
273
+	 *    and modifying it IN the EE_Base_Class so you don't have to do anything else.
274
+	 *
275
+	 * @param  EE_Base_Class $obj                 EE_Base_Class object
276
+	 * @param  string        $datetime_field_name name of the EE_Datetime_Filed datatype db column to be manipulated
277
+	 * @param  string        $period              what you are adding. The options are (years, months, days, hours,
278
+	 *                                            minutes, seconds) defaults to years
279
+	 * @param  integer       $value               what you want to increment the time by
280
+	 * @return EE_Base_Class return the EE_Base_Class object so right away you can do something with it
281
+	 *                                            (chaining)
282
+	 * @throws EE_Error
283
+	 * @throws Exception
284
+	 */
285
+	public static function date_time_add(EE_Base_Class $obj, $datetime_field_name, $period = 'years', $value = 1)
286
+	{
287
+		// get the raw UTC date.
288
+		$DateTime = $obj->get_DateTime_object($datetime_field_name);
289
+		$DateTime = EEH_DTT_Helper::calc_date($DateTime, $period, $value);
290
+		return EEH_DTT_Helper::_set_date_time_field($obj, $DateTime, $datetime_field_name);
291
+	}
292 292
 
293 293
 
294
-    /**
295
-     *    date_time_subtract
296
-     *    same as date_time_add except subtracting value instead of adding.
297
-     *
298
-     * @param EE_Base_Class $obj
299
-     * @param  string       $datetime_field_name name of the EE_Datetime_Filed datatype db column to be manipulated
300
-     * @param string        $period
301
-     * @param int           $value
302
-     * @return EE_Base_Class
303
-     * @throws EE_Error
304
-     * @throws Exception
305
-     */
306
-    public static function date_time_subtract(EE_Base_Class $obj, $datetime_field_name, $period = 'years', $value = 1)
307
-    {
308
-        // get the raw UTC date
309
-        $DateTime = $obj->get_DateTime_object($datetime_field_name);
310
-        $DateTime = EEH_DTT_Helper::calc_date($DateTime, $period, $value, '-');
311
-        return EEH_DTT_Helper::_set_date_time_field($obj, $DateTime, $datetime_field_name);
312
-    }
294
+	/**
295
+	 *    date_time_subtract
296
+	 *    same as date_time_add except subtracting value instead of adding.
297
+	 *
298
+	 * @param EE_Base_Class $obj
299
+	 * @param  string       $datetime_field_name name of the EE_Datetime_Filed datatype db column to be manipulated
300
+	 * @param string        $period
301
+	 * @param int           $value
302
+	 * @return EE_Base_Class
303
+	 * @throws EE_Error
304
+	 * @throws Exception
305
+	 */
306
+	public static function date_time_subtract(EE_Base_Class $obj, $datetime_field_name, $period = 'years', $value = 1)
307
+	{
308
+		// get the raw UTC date
309
+		$DateTime = $obj->get_DateTime_object($datetime_field_name);
310
+		$DateTime = EEH_DTT_Helper::calc_date($DateTime, $period, $value, '-');
311
+		return EEH_DTT_Helper::_set_date_time_field($obj, $DateTime, $datetime_field_name);
312
+	}
313 313
 
314 314
 
315
-    /**
316
-     * Simply takes an incoming DateTime object and does calculations on it based on the incoming parameters
317
-     *
318
-     * @param  DateTime   $DateTime DateTime object
319
-     * @param  string     $period   a value to indicate what interval is being used in the calculation. The options are
320
-     *                              'years', 'months', 'days', 'hours', 'minutes', 'seconds'. Defaults to years.
321
-     * @param  int|string $value    What you want to increment the date by
322
-     * @param  string     $operand  What operand you wish to use for the calculation
323
-     * @return DateTime return whatever type came in.
324
-     * @throws Exception
325
-     * @throws EE_Error
326
-     */
327
-    protected static function _modify_datetime_object(DateTime $DateTime, $period = 'years', $value = 1, $operand = '+')
328
-    {
329
-        if (! $DateTime instanceof DateTime) {
330
-            throw new EE_Error(
331
-                sprintf(
332
-                    esc_html__('Expected a PHP DateTime object, but instead received %1$s', 'event_espresso'),
333
-                    print_r($DateTime, true)
334
-                )
335
-            );
336
-        }
337
-        switch ($period) {
338
-            case 'years':
339
-                $value = 'P' . $value . 'Y';
340
-                break;
341
-            case 'months':
342
-                $value = 'P' . $value . 'M';
343
-                break;
344
-            case 'weeks':
345
-                $value = 'P' . $value . 'W';
346
-                break;
347
-            case 'days':
348
-                $value = 'P' . $value . 'D';
349
-                break;
350
-            case 'hours':
351
-                $value = 'PT' . $value . 'H';
352
-                break;
353
-            case 'minutes':
354
-                $value = 'PT' . $value . 'M';
355
-                break;
356
-            case 'seconds':
357
-                $value = 'PT' . $value . 'S';
358
-                break;
359
-        }
360
-        switch ($operand) {
361
-            case '+':
362
-                $DateTime->add(new DateInterval($value));
363
-                break;
364
-            case '-':
365
-                $DateTime->sub(new DateInterval($value));
366
-                break;
367
-        }
368
-        return $DateTime;
369
-    }
315
+	/**
316
+	 * Simply takes an incoming DateTime object and does calculations on it based on the incoming parameters
317
+	 *
318
+	 * @param  DateTime   $DateTime DateTime object
319
+	 * @param  string     $period   a value to indicate what interval is being used in the calculation. The options are
320
+	 *                              'years', 'months', 'days', 'hours', 'minutes', 'seconds'. Defaults to years.
321
+	 * @param  int|string $value    What you want to increment the date by
322
+	 * @param  string     $operand  What operand you wish to use for the calculation
323
+	 * @return DateTime return whatever type came in.
324
+	 * @throws Exception
325
+	 * @throws EE_Error
326
+	 */
327
+	protected static function _modify_datetime_object(DateTime $DateTime, $period = 'years', $value = 1, $operand = '+')
328
+	{
329
+		if (! $DateTime instanceof DateTime) {
330
+			throw new EE_Error(
331
+				sprintf(
332
+					esc_html__('Expected a PHP DateTime object, but instead received %1$s', 'event_espresso'),
333
+					print_r($DateTime, true)
334
+				)
335
+			);
336
+		}
337
+		switch ($period) {
338
+			case 'years':
339
+				$value = 'P' . $value . 'Y';
340
+				break;
341
+			case 'months':
342
+				$value = 'P' . $value . 'M';
343
+				break;
344
+			case 'weeks':
345
+				$value = 'P' . $value . 'W';
346
+				break;
347
+			case 'days':
348
+				$value = 'P' . $value . 'D';
349
+				break;
350
+			case 'hours':
351
+				$value = 'PT' . $value . 'H';
352
+				break;
353
+			case 'minutes':
354
+				$value = 'PT' . $value . 'M';
355
+				break;
356
+			case 'seconds':
357
+				$value = 'PT' . $value . 'S';
358
+				break;
359
+		}
360
+		switch ($operand) {
361
+			case '+':
362
+				$DateTime->add(new DateInterval($value));
363
+				break;
364
+			case '-':
365
+				$DateTime->sub(new DateInterval($value));
366
+				break;
367
+		}
368
+		return $DateTime;
369
+	}
370 370
 
371 371
 
372
-    /**
373
-     * Simply takes an incoming Unix timestamp and does calculations on it based on the incoming parameters
374
-     *
375
-     * @param  int     $timestamp Unix timestamp
376
-     * @param  string  $period    a value to indicate what interval is being used in the calculation. The options are
377
-     *                            'years', 'months', 'days', 'hours', 'minutes', 'seconds'. Defaults to years.
378
-     * @param  integer $value     What you want to increment the date by
379
-     * @param  string  $operand   What operand you wish to use for the calculation
380
-     * @return int
381
-     * @throws EE_Error
382
-     */
383
-    protected static function _modify_timestamp($timestamp, $period = 'years', $value = 1, $operand = '+')
384
-    {
385
-        if (! preg_match(EE_Datetime_Field::unix_timestamp_regex, $timestamp)) {
386
-            throw new EE_Error(
387
-                sprintf(
388
-                    esc_html__('Expected a Unix timestamp, but instead received %1$s', 'event_espresso'),
389
-                    print_r($timestamp, true)
390
-                )
391
-            );
392
-        }
393
-        switch ($period) {
394
-            case 'years':
395
-                $value = YEAR_IN_SECONDS * $value;
396
-                break;
397
-            case 'months':
398
-                $value = YEAR_IN_SECONDS / 12 * $value;
399
-                break;
400
-            case 'weeks':
401
-                $value = WEEK_IN_SECONDS * $value;
402
-                break;
403
-            case 'days':
404
-                $value = DAY_IN_SECONDS * $value;
405
-                break;
406
-            case 'hours':
407
-                $value = HOUR_IN_SECONDS * $value;
408
-                break;
409
-            case 'minutes':
410
-                $value = MINUTE_IN_SECONDS * $value;
411
-                break;
412
-        }
413
-        switch ($operand) {
414
-            case '+':
415
-                $timestamp += $value;
416
-                break;
417
-            case '-':
418
-                $timestamp -= $value;
419
-                break;
420
-        }
421
-        return $timestamp;
422
-    }
372
+	/**
373
+	 * Simply takes an incoming Unix timestamp and does calculations on it based on the incoming parameters
374
+	 *
375
+	 * @param  int     $timestamp Unix timestamp
376
+	 * @param  string  $period    a value to indicate what interval is being used in the calculation. The options are
377
+	 *                            'years', 'months', 'days', 'hours', 'minutes', 'seconds'. Defaults to years.
378
+	 * @param  integer $value     What you want to increment the date by
379
+	 * @param  string  $operand   What operand you wish to use for the calculation
380
+	 * @return int
381
+	 * @throws EE_Error
382
+	 */
383
+	protected static function _modify_timestamp($timestamp, $period = 'years', $value = 1, $operand = '+')
384
+	{
385
+		if (! preg_match(EE_Datetime_Field::unix_timestamp_regex, $timestamp)) {
386
+			throw new EE_Error(
387
+				sprintf(
388
+					esc_html__('Expected a Unix timestamp, but instead received %1$s', 'event_espresso'),
389
+					print_r($timestamp, true)
390
+				)
391
+			);
392
+		}
393
+		switch ($period) {
394
+			case 'years':
395
+				$value = YEAR_IN_SECONDS * $value;
396
+				break;
397
+			case 'months':
398
+				$value = YEAR_IN_SECONDS / 12 * $value;
399
+				break;
400
+			case 'weeks':
401
+				$value = WEEK_IN_SECONDS * $value;
402
+				break;
403
+			case 'days':
404
+				$value = DAY_IN_SECONDS * $value;
405
+				break;
406
+			case 'hours':
407
+				$value = HOUR_IN_SECONDS * $value;
408
+				break;
409
+			case 'minutes':
410
+				$value = MINUTE_IN_SECONDS * $value;
411
+				break;
412
+		}
413
+		switch ($operand) {
414
+			case '+':
415
+				$timestamp += $value;
416
+				break;
417
+			case '-':
418
+				$timestamp -= $value;
419
+				break;
420
+		}
421
+		return $timestamp;
422
+	}
423 423
 
424 424
 
425
-    /**
426
-     * Simply takes an incoming UTC timestamp or DateTime object and does calculations on it based on the incoming
427
-     * parameters and returns the new timestamp or DateTime.
428
-     *
429
-     * @param  int | DateTime $DateTime_or_timestamp DateTime object or Unix timestamp
430
-     * @param  string         $period                a value to indicate what interval is being used in the
431
-     *                                               calculation. The options are 'years', 'months', 'days', 'hours',
432
-     *                                               'minutes', 'seconds'. Defaults to years.
433
-     * @param  integer        $value                 What you want to increment the date by
434
-     * @param  string         $operand               What operand you wish to use for the calculation
435
-     * @return mixed string|DateTime          return whatever type came in.
436
-     * @throws Exception
437
-     * @throws EE_Error
438
-     */
439
-    public static function calc_date($DateTime_or_timestamp, $period = 'years', $value = 1, $operand = '+')
440
-    {
441
-        if ($DateTime_or_timestamp instanceof DateTime) {
442
-            return EEH_DTT_Helper::_modify_datetime_object(
443
-                $DateTime_or_timestamp,
444
-                $period,
445
-                $value,
446
-                $operand
447
-            );
448
-        }
449
-        if (preg_match(EE_Datetime_Field::unix_timestamp_regex, $DateTime_or_timestamp)) {
450
-            return EEH_DTT_Helper::_modify_timestamp(
451
-                $DateTime_or_timestamp,
452
-                $period,
453
-                $value,
454
-                $operand
455
-            );
456
-        }
457
-        // error
458
-        return $DateTime_or_timestamp;
459
-    }
425
+	/**
426
+	 * Simply takes an incoming UTC timestamp or DateTime object and does calculations on it based on the incoming
427
+	 * parameters and returns the new timestamp or DateTime.
428
+	 *
429
+	 * @param  int | DateTime $DateTime_or_timestamp DateTime object or Unix timestamp
430
+	 * @param  string         $period                a value to indicate what interval is being used in the
431
+	 *                                               calculation. The options are 'years', 'months', 'days', 'hours',
432
+	 *                                               'minutes', 'seconds'. Defaults to years.
433
+	 * @param  integer        $value                 What you want to increment the date by
434
+	 * @param  string         $operand               What operand you wish to use for the calculation
435
+	 * @return mixed string|DateTime          return whatever type came in.
436
+	 * @throws Exception
437
+	 * @throws EE_Error
438
+	 */
439
+	public static function calc_date($DateTime_or_timestamp, $period = 'years', $value = 1, $operand = '+')
440
+	{
441
+		if ($DateTime_or_timestamp instanceof DateTime) {
442
+			return EEH_DTT_Helper::_modify_datetime_object(
443
+				$DateTime_or_timestamp,
444
+				$period,
445
+				$value,
446
+				$operand
447
+			);
448
+		}
449
+		if (preg_match(EE_Datetime_Field::unix_timestamp_regex, $DateTime_or_timestamp)) {
450
+			return EEH_DTT_Helper::_modify_timestamp(
451
+				$DateTime_or_timestamp,
452
+				$period,
453
+				$value,
454
+				$operand
455
+			);
456
+		}
457
+		// error
458
+		return $DateTime_or_timestamp;
459
+	}
460 460
 
461 461
 
462
-    /**
463
-     * The purpose of this helper method is to receive an incoming format string in php date/time format
464
-     * and spit out the js and moment.js equivalent formats.
465
-     * Note, if no format string is given, then it is assumed the user wants what is set for WP.
466
-     * Note, js date and time formats are those used by the jquery-ui datepicker and the jquery-ui date-
467
-     * time picker.
468
-     *
469
-     * @see http://stackoverflow.com/posts/16725290/ for the code inspiration.
470
-     * @param string $date_format_string
471
-     * @param string $time_format_string
472
-     * @return array
473
-     *              array(
474
-     *              'js' => array (
475
-     *              'date' => //date format
476
-     *              'time' => //time format
477
-     *              ),
478
-     *              'moment' => //date and time format.
479
-     *              )
480
-     */
481
-    public static function convert_php_to_js_and_moment_date_formats(
482
-        $date_format_string = null,
483
-        $time_format_string = null
484
-    ) {
485
-        if ($date_format_string === null) {
486
-            $date_format_string = (string) get_option('date_format');
487
-        }
488
-        if ($time_format_string === null) {
489
-            $time_format_string = (string) get_option('time_format');
490
-        }
491
-        $date_format = self::_php_to_js_moment_converter($date_format_string);
492
-        $time_format = self::_php_to_js_moment_converter($time_format_string);
493
-        return array(
494
-            'js'     => array(
495
-                'date' => $date_format['js'],
496
-                'time' => $time_format['js'],
497
-            ),
498
-            'moment' => $date_format['moment'] . ' ' . $time_format['moment'],
499
-            'moment_split' => array(
500
-                'date' => $date_format['moment'],
501
-                'time' => $time_format['moment']
502
-            )
503
-        );
504
-    }
462
+	/**
463
+	 * The purpose of this helper method is to receive an incoming format string in php date/time format
464
+	 * and spit out the js and moment.js equivalent formats.
465
+	 * Note, if no format string is given, then it is assumed the user wants what is set for WP.
466
+	 * Note, js date and time formats are those used by the jquery-ui datepicker and the jquery-ui date-
467
+	 * time picker.
468
+	 *
469
+	 * @see http://stackoverflow.com/posts/16725290/ for the code inspiration.
470
+	 * @param string $date_format_string
471
+	 * @param string $time_format_string
472
+	 * @return array
473
+	 *              array(
474
+	 *              'js' => array (
475
+	 *              'date' => //date format
476
+	 *              'time' => //time format
477
+	 *              ),
478
+	 *              'moment' => //date and time format.
479
+	 *              )
480
+	 */
481
+	public static function convert_php_to_js_and_moment_date_formats(
482
+		$date_format_string = null,
483
+		$time_format_string = null
484
+	) {
485
+		if ($date_format_string === null) {
486
+			$date_format_string = (string) get_option('date_format');
487
+		}
488
+		if ($time_format_string === null) {
489
+			$time_format_string = (string) get_option('time_format');
490
+		}
491
+		$date_format = self::_php_to_js_moment_converter($date_format_string);
492
+		$time_format = self::_php_to_js_moment_converter($time_format_string);
493
+		return array(
494
+			'js'     => array(
495
+				'date' => $date_format['js'],
496
+				'time' => $time_format['js'],
497
+			),
498
+			'moment' => $date_format['moment'] . ' ' . $time_format['moment'],
499
+			'moment_split' => array(
500
+				'date' => $date_format['moment'],
501
+				'time' => $time_format['moment']
502
+			)
503
+		);
504
+	}
505 505
 
506 506
 
507
-    /**
508
-     * This converts incoming format string into js and moment variations.
509
-     *
510
-     * @param string $format_string incoming php format string
511
-     * @return array js and moment formats.
512
-     */
513
-    protected static function _php_to_js_moment_converter($format_string)
514
-    {
515
-        /**
516
-         * This is a map of symbols for formats.
517
-         * The index is the php symbol, the equivalent values are in the array.
518
-         *
519
-         * @var array
520
-         */
521
-        $symbols_map          = array(
522
-            // Day
523
-            // 01
524
-            'd' => array(
525
-                'js'     => 'dd',
526
-                'moment' => 'DD',
527
-            ),
528
-            // Mon
529
-            'D' => array(
530
-                'js'     => 'D',
531
-                'moment' => 'ddd',
532
-            ),
533
-            // 1,2,...31
534
-            'j' => array(
535
-                'js'     => 'd',
536
-                'moment' => 'D',
537
-            ),
538
-            // Monday
539
-            'l' => array(
540
-                'js'     => 'DD',
541
-                'moment' => 'dddd',
542
-            ),
543
-            // ISO numeric representation of the day of the week (1-6)
544
-            'N' => array(
545
-                'js'     => '',
546
-                'moment' => 'E',
547
-            ),
548
-            // st,nd.rd
549
-            'S' => array(
550
-                'js'     => '',
551
-                'moment' => 'o',
552
-            ),
553
-            // numeric representation of day of week (0-6)
554
-            'w' => array(
555
-                'js'     => '',
556
-                'moment' => 'd',
557
-            ),
558
-            // day of year starting from 0 (0-365)
559
-            'z' => array(
560
-                'js'     => 'o',
561
-                'moment' => 'DDD' // note moment does not start with 0 so will need to modify by subtracting 1
562
-            ),
563
-            // Week
564
-            // ISO-8601 week number of year (weeks starting on monday)
565
-            'W' => array(
566
-                'js'     => '',
567
-                'moment' => 'w',
568
-            ),
569
-            // Month
570
-            // January...December
571
-            'F' => array(
572
-                'js'     => 'MM',
573
-                'moment' => 'MMMM',
574
-            ),
575
-            // 01...12
576
-            'm' => array(
577
-                'js'     => 'mm',
578
-                'moment' => 'MM',
579
-            ),
580
-            // Jan...Dec
581
-            'M' => array(
582
-                'js'     => 'M',
583
-                'moment' => 'MMM',
584
-            ),
585
-            // 1-12
586
-            'n' => array(
587
-                'js'     => 'm',
588
-                'moment' => 'M',
589
-            ),
590
-            // number of days in given month
591
-            't' => array(
592
-                'js'     => '',
593
-                'moment' => '',
594
-            ),
595
-            // Year
596
-            // whether leap year or not 1/0
597
-            'L' => array(
598
-                'js'     => '',
599
-                'moment' => '',
600
-            ),
601
-            // ISO-8601 year number
602
-            'o' => array(
603
-                'js'     => '',
604
-                'moment' => 'GGGG',
605
-            ),
606
-            // 1999...2003
607
-            'Y' => array(
608
-                'js'     => 'yy',
609
-                'moment' => 'YYYY',
610
-            ),
611
-            // 99...03
612
-            'y' => array(
613
-                'js'     => 'y',
614
-                'moment' => 'YY',
615
-            ),
616
-            // Time
617
-            // am/pm
618
-            'a' => array(
619
-                'js'     => 'tt',
620
-                'moment' => 'a',
621
-            ),
622
-            // AM/PM
623
-            'A' => array(
624
-                'js'     => 'TT',
625
-                'moment' => 'A',
626
-            ),
627
-            // Swatch Internet Time?!?
628
-            'B' => array(
629
-                'js'     => '',
630
-                'moment' => '',
631
-            ),
632
-            // 1...12
633
-            'g' => array(
634
-                'js'     => 'h',
635
-                'moment' => 'h',
636
-            ),
637
-            // 0...23
638
-            'G' => array(
639
-                'js'     => 'H',
640
-                'moment' => 'H',
641
-            ),
642
-            // 01...12
643
-            'h' => array(
644
-                'js'     => 'hh',
645
-                'moment' => 'hh',
646
-            ),
647
-            // 00...23
648
-            'H' => array(
649
-                'js'     => 'HH',
650
-                'moment' => 'HH',
651
-            ),
652
-            // 00..59
653
-            'i' => array(
654
-                'js'     => 'mm',
655
-                'moment' => 'mm',
656
-            ),
657
-            // seconds... 00...59
658
-            's' => array(
659
-                'js'     => 'ss',
660
-                'moment' => 'ss',
661
-            ),
662
-            // microseconds
663
-            'u' => array(
664
-                'js'     => '',
665
-                'moment' => '',
666
-            ),
667
-        );
668
-        $jquery_ui_format     = '';
669
-        $moment_format        = '';
670
-        $escaping             = false;
671
-        $format_string_length = strlen($format_string);
672
-        for ($i = 0; $i < $format_string_length; $i++) {
673
-            $char = $format_string[ $i ];
674
-            if ($char === '\\') { // PHP date format escaping character
675
-                $i++;
676
-                if ($escaping) {
677
-                    $jquery_ui_format .= $format_string[ $i ];
678
-                    $moment_format    .= $format_string[ $i ];
679
-                } else {
680
-                    $jquery_ui_format .= '\'' . $format_string[ $i ];
681
-                    $moment_format    .= $format_string[ $i ];
682
-                }
683
-                $escaping = true;
684
-            } else {
685
-                if ($escaping) {
686
-                    $jquery_ui_format .= "'";
687
-                    $moment_format    .= "'";
688
-                    $escaping         = false;
689
-                }
690
-                if (isset($symbols_map[ $char ])) {
691
-                    $jquery_ui_format .= $symbols_map[ $char ]['js'];
692
-                    $moment_format    .= $symbols_map[ $char ]['moment'];
693
-                } else {
694
-                    $jquery_ui_format .= $char;
695
-                    $moment_format    .= $char;
696
-                }
697
-            }
698
-        }
699
-        return array('js' => $jquery_ui_format, 'moment' => $moment_format);
700
-    }
507
+	/**
508
+	 * This converts incoming format string into js and moment variations.
509
+	 *
510
+	 * @param string $format_string incoming php format string
511
+	 * @return array js and moment formats.
512
+	 */
513
+	protected static function _php_to_js_moment_converter($format_string)
514
+	{
515
+		/**
516
+		 * This is a map of symbols for formats.
517
+		 * The index is the php symbol, the equivalent values are in the array.
518
+		 *
519
+		 * @var array
520
+		 */
521
+		$symbols_map          = array(
522
+			// Day
523
+			// 01
524
+			'd' => array(
525
+				'js'     => 'dd',
526
+				'moment' => 'DD',
527
+			),
528
+			// Mon
529
+			'D' => array(
530
+				'js'     => 'D',
531
+				'moment' => 'ddd',
532
+			),
533
+			// 1,2,...31
534
+			'j' => array(
535
+				'js'     => 'd',
536
+				'moment' => 'D',
537
+			),
538
+			// Monday
539
+			'l' => array(
540
+				'js'     => 'DD',
541
+				'moment' => 'dddd',
542
+			),
543
+			// ISO numeric representation of the day of the week (1-6)
544
+			'N' => array(
545
+				'js'     => '',
546
+				'moment' => 'E',
547
+			),
548
+			// st,nd.rd
549
+			'S' => array(
550
+				'js'     => '',
551
+				'moment' => 'o',
552
+			),
553
+			// numeric representation of day of week (0-6)
554
+			'w' => array(
555
+				'js'     => '',
556
+				'moment' => 'd',
557
+			),
558
+			// day of year starting from 0 (0-365)
559
+			'z' => array(
560
+				'js'     => 'o',
561
+				'moment' => 'DDD' // note moment does not start with 0 so will need to modify by subtracting 1
562
+			),
563
+			// Week
564
+			// ISO-8601 week number of year (weeks starting on monday)
565
+			'W' => array(
566
+				'js'     => '',
567
+				'moment' => 'w',
568
+			),
569
+			// Month
570
+			// January...December
571
+			'F' => array(
572
+				'js'     => 'MM',
573
+				'moment' => 'MMMM',
574
+			),
575
+			// 01...12
576
+			'm' => array(
577
+				'js'     => 'mm',
578
+				'moment' => 'MM',
579
+			),
580
+			// Jan...Dec
581
+			'M' => array(
582
+				'js'     => 'M',
583
+				'moment' => 'MMM',
584
+			),
585
+			// 1-12
586
+			'n' => array(
587
+				'js'     => 'm',
588
+				'moment' => 'M',
589
+			),
590
+			// number of days in given month
591
+			't' => array(
592
+				'js'     => '',
593
+				'moment' => '',
594
+			),
595
+			// Year
596
+			// whether leap year or not 1/0
597
+			'L' => array(
598
+				'js'     => '',
599
+				'moment' => '',
600
+			),
601
+			// ISO-8601 year number
602
+			'o' => array(
603
+				'js'     => '',
604
+				'moment' => 'GGGG',
605
+			),
606
+			// 1999...2003
607
+			'Y' => array(
608
+				'js'     => 'yy',
609
+				'moment' => 'YYYY',
610
+			),
611
+			// 99...03
612
+			'y' => array(
613
+				'js'     => 'y',
614
+				'moment' => 'YY',
615
+			),
616
+			// Time
617
+			// am/pm
618
+			'a' => array(
619
+				'js'     => 'tt',
620
+				'moment' => 'a',
621
+			),
622
+			// AM/PM
623
+			'A' => array(
624
+				'js'     => 'TT',
625
+				'moment' => 'A',
626
+			),
627
+			// Swatch Internet Time?!?
628
+			'B' => array(
629
+				'js'     => '',
630
+				'moment' => '',
631
+			),
632
+			// 1...12
633
+			'g' => array(
634
+				'js'     => 'h',
635
+				'moment' => 'h',
636
+			),
637
+			// 0...23
638
+			'G' => array(
639
+				'js'     => 'H',
640
+				'moment' => 'H',
641
+			),
642
+			// 01...12
643
+			'h' => array(
644
+				'js'     => 'hh',
645
+				'moment' => 'hh',
646
+			),
647
+			// 00...23
648
+			'H' => array(
649
+				'js'     => 'HH',
650
+				'moment' => 'HH',
651
+			),
652
+			// 00..59
653
+			'i' => array(
654
+				'js'     => 'mm',
655
+				'moment' => 'mm',
656
+			),
657
+			// seconds... 00...59
658
+			's' => array(
659
+				'js'     => 'ss',
660
+				'moment' => 'ss',
661
+			),
662
+			// microseconds
663
+			'u' => array(
664
+				'js'     => '',
665
+				'moment' => '',
666
+			),
667
+		);
668
+		$jquery_ui_format     = '';
669
+		$moment_format        = '';
670
+		$escaping             = false;
671
+		$format_string_length = strlen($format_string);
672
+		for ($i = 0; $i < $format_string_length; $i++) {
673
+			$char = $format_string[ $i ];
674
+			if ($char === '\\') { // PHP date format escaping character
675
+				$i++;
676
+				if ($escaping) {
677
+					$jquery_ui_format .= $format_string[ $i ];
678
+					$moment_format    .= $format_string[ $i ];
679
+				} else {
680
+					$jquery_ui_format .= '\'' . $format_string[ $i ];
681
+					$moment_format    .= $format_string[ $i ];
682
+				}
683
+				$escaping = true;
684
+			} else {
685
+				if ($escaping) {
686
+					$jquery_ui_format .= "'";
687
+					$moment_format    .= "'";
688
+					$escaping         = false;
689
+				}
690
+				if (isset($symbols_map[ $char ])) {
691
+					$jquery_ui_format .= $symbols_map[ $char ]['js'];
692
+					$moment_format    .= $symbols_map[ $char ]['moment'];
693
+				} else {
694
+					$jquery_ui_format .= $char;
695
+					$moment_format    .= $char;
696
+				}
697
+			}
698
+		}
699
+		return array('js' => $jquery_ui_format, 'moment' => $moment_format);
700
+	}
701 701
 
702 702
 
703
-    /**
704
-     * This takes an incoming format string and validates it to ensure it will work fine with PHP.
705
-     *
706
-     * @param string $format_string   Incoming format string for php date().
707
-     * @return mixed bool|array  If all is okay then TRUE is returned.  Otherwise an array of validation
708
-     *                                errors is returned.  So for client code calling, check for is_array() to
709
-     *                                indicate failed validations.
710
-     */
711
-    public static function validate_format_string($format_string)
712
-    {
713
-        $error_msg = array();
714
-        // time format checks
715
-        switch (true) {
716
-            case strpos($format_string, 'h') !== false:
717
-            case strpos($format_string, 'g') !== false:
718
-                /**
719
-                 * if the time string has a lowercase 'h' which == 12 hour time format and there
720
-                 * is not any ante meridiem format ('a' or 'A').  Then throw an error because its
721
-                 * too ambiguous and PHP won't be able to figure out whether 1 = 1pm or 1am.
722
-                 */
723
-                if (stripos($format_string, 'A') === false) {
724
-                    $error_msg[] = esc_html__(
725
-                        'There is a  time format for 12 hour time but no  "a" or "A" to indicate am/pm.  Without this distinction, PHP is unable to determine if a "1" for the hour value equals "1pm" or "1am".',
726
-                        'event_espresso'
727
-                    );
728
-                }
729
-                break;
730
-        }
731
-        return empty($error_msg) ? true : $error_msg;
732
-    }
703
+	/**
704
+	 * This takes an incoming format string and validates it to ensure it will work fine with PHP.
705
+	 *
706
+	 * @param string $format_string   Incoming format string for php date().
707
+	 * @return mixed bool|array  If all is okay then TRUE is returned.  Otherwise an array of validation
708
+	 *                                errors is returned.  So for client code calling, check for is_array() to
709
+	 *                                indicate failed validations.
710
+	 */
711
+	public static function validate_format_string($format_string)
712
+	{
713
+		$error_msg = array();
714
+		// time format checks
715
+		switch (true) {
716
+			case strpos($format_string, 'h') !== false:
717
+			case strpos($format_string, 'g') !== false:
718
+				/**
719
+				 * if the time string has a lowercase 'h' which == 12 hour time format and there
720
+				 * is not any ante meridiem format ('a' or 'A').  Then throw an error because its
721
+				 * too ambiguous and PHP won't be able to figure out whether 1 = 1pm or 1am.
722
+				 */
723
+				if (stripos($format_string, 'A') === false) {
724
+					$error_msg[] = esc_html__(
725
+						'There is a  time format for 12 hour time but no  "a" or "A" to indicate am/pm.  Without this distinction, PHP is unable to determine if a "1" for the hour value equals "1pm" or "1am".',
726
+						'event_espresso'
727
+					);
728
+				}
729
+				break;
730
+		}
731
+		return empty($error_msg) ? true : $error_msg;
732
+	}
733 733
 
734 734
 
735
-    /**
736
-     *     If the the first date starts at midnight on one day, and the next date ends at midnight on the
737
-     *     very next day then this method will return true.
738
-     *    If $date_1 = 2015-12-15 00:00:00 and $date_2 = 2015-12-16 00:00:00 then this function will return true.
739
-     *    If $date_1 = 2015-12-15 03:00:00 and $date_2 = 2015-12_16 03:00:00 then this function will return false.
740
-     *    If $date_1 = 2015-12-15 00:00:00 and $date_2 = 2015-12-15 00:00:00 then this function will return true.
741
-     *
742
-     * @param mixed $date_1
743
-     * @param mixed $date_2
744
-     * @return bool
745
-     */
746
-    public static function dates_represent_one_24_hour_date($date_1, $date_2)
747
-    {
735
+	/**
736
+	 *     If the the first date starts at midnight on one day, and the next date ends at midnight on the
737
+	 *     very next day then this method will return true.
738
+	 *    If $date_1 = 2015-12-15 00:00:00 and $date_2 = 2015-12-16 00:00:00 then this function will return true.
739
+	 *    If $date_1 = 2015-12-15 03:00:00 and $date_2 = 2015-12_16 03:00:00 then this function will return false.
740
+	 *    If $date_1 = 2015-12-15 00:00:00 and $date_2 = 2015-12-15 00:00:00 then this function will return true.
741
+	 *
742
+	 * @param mixed $date_1
743
+	 * @param mixed $date_2
744
+	 * @return bool
745
+	 */
746
+	public static function dates_represent_one_24_hour_date($date_1, $date_2)
747
+	{
748 748
 
749
-        if (
750
-            (! $date_1 instanceof DateTime || ! $date_2 instanceof DateTime)
751
-            || ($date_1->format(EE_Datetime_Field::mysql_time_format) !== '00:00:00'
752
-                || $date_2->format(
753
-                    EE_Datetime_Field::mysql_time_format
754
-                ) !== '00:00:00')
755
-        ) {
756
-            return false;
757
-        }
758
-        return $date_2->format('U') - $date_1->format('U') === 86400;
759
-    }
749
+		if (
750
+			(! $date_1 instanceof DateTime || ! $date_2 instanceof DateTime)
751
+			|| ($date_1->format(EE_Datetime_Field::mysql_time_format) !== '00:00:00'
752
+				|| $date_2->format(
753
+					EE_Datetime_Field::mysql_time_format
754
+				) !== '00:00:00')
755
+		) {
756
+			return false;
757
+		}
758
+		return $date_2->format('U') - $date_1->format('U') === 86400;
759
+	}
760 760
 
761 761
 
762
-    /**
763
-     * This returns the appropriate query interval string that can be used in sql queries involving mysql Date
764
-     * Functions.
765
-     *
766
-     * @param string $timezone_string    A timezone string in a valid format to instantiate a DateTimeZone object.
767
-     * @param string $field_for_interval The Database field that is the interval is applied to in the query.
768
-     * @return string
769
-     */
770
-    public static function get_sql_query_interval_for_offset($timezone_string, $field_for_interval)
771
-    {
772
-        try {
773
-            /** need to account for timezone offset on the selects */
774
-            $DateTimeZone = new DateTimeZone($timezone_string);
775
-        } catch (Exception $e) {
776
-            $DateTimeZone = null;
777
-        }
778
-        /**
779
-         * Note get_option( 'gmt_offset') returns a value in hours, whereas DateTimeZone::getOffset returns values in seconds.
780
-         * Hence we do the calc for DateTimeZone::getOffset.
781
-         */
782
-        $offset         = $DateTimeZone instanceof DateTimeZone
783
-            ? $DateTimeZone->getOffset(new DateTime('now')) / HOUR_IN_SECONDS
784
-            : (float) get_option('gmt_offset');
785
-        $query_interval = $offset < 0
786
-            ? 'DATE_SUB(' . $field_for_interval . ', INTERVAL ' . $offset * -1 . ' HOUR)'
787
-            : 'DATE_ADD(' . $field_for_interval . ', INTERVAL ' . $offset . ' HOUR)';
788
-        return $query_interval;
789
-    }
762
+	/**
763
+	 * This returns the appropriate query interval string that can be used in sql queries involving mysql Date
764
+	 * Functions.
765
+	 *
766
+	 * @param string $timezone_string    A timezone string in a valid format to instantiate a DateTimeZone object.
767
+	 * @param string $field_for_interval The Database field that is the interval is applied to in the query.
768
+	 * @return string
769
+	 */
770
+	public static function get_sql_query_interval_for_offset($timezone_string, $field_for_interval)
771
+	{
772
+		try {
773
+			/** need to account for timezone offset on the selects */
774
+			$DateTimeZone = new DateTimeZone($timezone_string);
775
+		} catch (Exception $e) {
776
+			$DateTimeZone = null;
777
+		}
778
+		/**
779
+		 * Note get_option( 'gmt_offset') returns a value in hours, whereas DateTimeZone::getOffset returns values in seconds.
780
+		 * Hence we do the calc for DateTimeZone::getOffset.
781
+		 */
782
+		$offset         = $DateTimeZone instanceof DateTimeZone
783
+			? $DateTimeZone->getOffset(new DateTime('now')) / HOUR_IN_SECONDS
784
+			: (float) get_option('gmt_offset');
785
+		$query_interval = $offset < 0
786
+			? 'DATE_SUB(' . $field_for_interval . ', INTERVAL ' . $offset * -1 . ' HOUR)'
787
+			: 'DATE_ADD(' . $field_for_interval . ', INTERVAL ' . $offset . ' HOUR)';
788
+		return $query_interval;
789
+	}
790 790
 
791 791
 
792
-    /**
793
-     * Retrieves the site's default timezone and returns it formatted so it's ready for display
794
-     * to users. If you want to customize how its displayed feel free to fetch the 'timezone_string'
795
-     * and 'gmt_offset' WordPress options directly; or use the filter
796
-     * FHEE__EEH_DTT_Helper__get_timezone_string_for_display
797
-     * (although note that we remove any HTML that may be added)
798
-     *
799
-     * @return string
800
-     */
801
-    public static function get_timezone_string_for_display()
802
-    {
803
-        $pretty_timezone = apply_filters('FHEE__EEH_DTT_Helper__get_timezone_string_for_display', '');
804
-        if (! empty($pretty_timezone)) {
805
-            return esc_html($pretty_timezone);
806
-        }
807
-        $timezone_string = get_option('timezone_string');
808
-        if ($timezone_string) {
809
-            static $mo_loaded = false;
810
-            // Load translations for continents and cities just like wp_timezone_choice does
811
-            if (! $mo_loaded) {
812
-                $locale = get_locale();
813
-                $mofile = WP_LANG_DIR . '/continents-cities-' . $locale . '.mo';
814
-                load_textdomain('continents-cities', $mofile);
815
-                $mo_loaded = true;
816
-            }
817
-            // well that was easy.
818
-            $parts = explode('/', $timezone_string);
819
-            // remove the continent
820
-            unset($parts[0]);
821
-            $t_parts = array();
822
-            // phpcs:disable WordPress.WP.I18n.NonSingularStringLiteralText
823
-            // phpcs:disable WordPress.WP.I18n.TextDomainMismatch
824
-            // disabled because this code is copied from WordPress and is a WordPress domain
825
-            foreach ($parts as $part) {
826
-                $t_parts[] = translate(str_replace('_', ' ', $part), 'continents-cities');
827
-            }
828
-            return implode(' - ', $t_parts);
829
-            // phpcs:enable
830
-        }
831
-        // they haven't set the timezone string, so let's return a string like "UTC+1"
832
-        $gmt_offset = get_option('gmt_offset');
833
-        $prefix     = (int) $gmt_offset >= 0 ? '+' : '';
834
-        $parts      = explode('.', (string) $gmt_offset);
835
-        if (count($parts) === 1) {
836
-            $parts[1] = '00';
837
-        } else {
838
-            // convert the part after the decimal, eg "5" (from x.5) or "25" (from x.25)
839
-            // to minutes, eg 30 or 15, respectively
840
-            $hour_fraction = (float) ('0.' . $parts[1]);
841
-            $parts[1]      = (string) $hour_fraction * 60;
842
-        }
843
-        return sprintf(esc_html__('UTC%1$s', 'event_espresso'), $prefix . implode(':', $parts));
844
-    }
792
+	/**
793
+	 * Retrieves the site's default timezone and returns it formatted so it's ready for display
794
+	 * to users. If you want to customize how its displayed feel free to fetch the 'timezone_string'
795
+	 * and 'gmt_offset' WordPress options directly; or use the filter
796
+	 * FHEE__EEH_DTT_Helper__get_timezone_string_for_display
797
+	 * (although note that we remove any HTML that may be added)
798
+	 *
799
+	 * @return string
800
+	 */
801
+	public static function get_timezone_string_for_display()
802
+	{
803
+		$pretty_timezone = apply_filters('FHEE__EEH_DTT_Helper__get_timezone_string_for_display', '');
804
+		if (! empty($pretty_timezone)) {
805
+			return esc_html($pretty_timezone);
806
+		}
807
+		$timezone_string = get_option('timezone_string');
808
+		if ($timezone_string) {
809
+			static $mo_loaded = false;
810
+			// Load translations for continents and cities just like wp_timezone_choice does
811
+			if (! $mo_loaded) {
812
+				$locale = get_locale();
813
+				$mofile = WP_LANG_DIR . '/continents-cities-' . $locale . '.mo';
814
+				load_textdomain('continents-cities', $mofile);
815
+				$mo_loaded = true;
816
+			}
817
+			// well that was easy.
818
+			$parts = explode('/', $timezone_string);
819
+			// remove the continent
820
+			unset($parts[0]);
821
+			$t_parts = array();
822
+			// phpcs:disable WordPress.WP.I18n.NonSingularStringLiteralText
823
+			// phpcs:disable WordPress.WP.I18n.TextDomainMismatch
824
+			// disabled because this code is copied from WordPress and is a WordPress domain
825
+			foreach ($parts as $part) {
826
+				$t_parts[] = translate(str_replace('_', ' ', $part), 'continents-cities');
827
+			}
828
+			return implode(' - ', $t_parts);
829
+			// phpcs:enable
830
+		}
831
+		// they haven't set the timezone string, so let's return a string like "UTC+1"
832
+		$gmt_offset = get_option('gmt_offset');
833
+		$prefix     = (int) $gmt_offset >= 0 ? '+' : '';
834
+		$parts      = explode('.', (string) $gmt_offset);
835
+		if (count($parts) === 1) {
836
+			$parts[1] = '00';
837
+		} else {
838
+			// convert the part after the decimal, eg "5" (from x.5) or "25" (from x.25)
839
+			// to minutes, eg 30 or 15, respectively
840
+			$hour_fraction = (float) ('0.' . $parts[1]);
841
+			$parts[1]      = (string) $hour_fraction * 60;
842
+		}
843
+		return sprintf(esc_html__('UTC%1$s', 'event_espresso'), $prefix . implode(':', $parts));
844
+	}
845 845
 
846 846
 
847 847
 
848
-    /**
849
-     * So PHP does this awesome thing where if you are trying to get a timestamp
850
-     * for a month using a string like "February" or "February 2017",
851
-     * and you don't specify a day as part of your string,
852
-     * then PHP will use whatever the current day of the month is.
853
-     * IF the current day of the month happens to be the 30th or 31st,
854
-     * then PHP gets really confused by a date like February 30,
855
-     * so instead of saying
856
-     *      "Hey February only has 28 days (this year)...
857
-     *      ...you must have meant the last day of the month!"
858
-     * PHP does the next most logical thing, and bumps the date up to March 2nd,
859
-     * because someone requesting February 30th obviously meant March 1st!
860
-     * The way around this is to always set the day to the first,
861
-     * so that the month will stay on the month you wanted.
862
-     * this method will add that "1" into your date regardless of the format.
863
-     *
864
-     * @param string $month
865
-     * @return string
866
-     */
867
-    public static function first_of_month_timestamp($month = '')
868
-    {
869
-        $month = (string) $month;
870
-        $year  = '';
871
-        // check if the incoming string has a year in it or not
872
-        if (preg_match('/\b\d{4}\b/', $month, $matches)) {
873
-            $year = $matches[0];
874
-            // ten remove that from the month string as well as any spaces
875
-            $month = trim(str_replace($year, '', $month));
876
-            // add a space before the year
877
-            $year = " {$year}";
878
-        }
879
-        // return timestamp for something like "February 1 2017"
880
-        return strtotime("{$month} 1{$year}");
881
-    }
848
+	/**
849
+	 * So PHP does this awesome thing where if you are trying to get a timestamp
850
+	 * for a month using a string like "February" or "February 2017",
851
+	 * and you don't specify a day as part of your string,
852
+	 * then PHP will use whatever the current day of the month is.
853
+	 * IF the current day of the month happens to be the 30th or 31st,
854
+	 * then PHP gets really confused by a date like February 30,
855
+	 * so instead of saying
856
+	 *      "Hey February only has 28 days (this year)...
857
+	 *      ...you must have meant the last day of the month!"
858
+	 * PHP does the next most logical thing, and bumps the date up to March 2nd,
859
+	 * because someone requesting February 30th obviously meant March 1st!
860
+	 * The way around this is to always set the day to the first,
861
+	 * so that the month will stay on the month you wanted.
862
+	 * this method will add that "1" into your date regardless of the format.
863
+	 *
864
+	 * @param string $month
865
+	 * @return string
866
+	 */
867
+	public static function first_of_month_timestamp($month = '')
868
+	{
869
+		$month = (string) $month;
870
+		$year  = '';
871
+		// check if the incoming string has a year in it or not
872
+		if (preg_match('/\b\d{4}\b/', $month, $matches)) {
873
+			$year = $matches[0];
874
+			// ten remove that from the month string as well as any spaces
875
+			$month = trim(str_replace($year, '', $month));
876
+			// add a space before the year
877
+			$year = " {$year}";
878
+		}
879
+		// return timestamp for something like "February 1 2017"
880
+		return strtotime("{$month} 1{$year}");
881
+	}
882 882
 
883 883
 
884
-    /**
885
-     * This simply returns the timestamp for tomorrow (midnight next day) in this sites timezone.  So it may be midnight
886
-     * for this sites timezone, but the timestamp could be some other time GMT.
887
-     */
888
-    public static function tomorrow()
889
-    {
890
-        // The multiplication of -1 ensures that we switch positive offsets to negative and negative offsets to positive
891
-        // before adding to the timestamp.  Why? Because we want tomorrow to be for midnight the next day in THIS timezone
892
-        // not an offset from midnight in UTC.  So if we're starting with UTC 00:00:00, then we want to make sure the
893
-        // final timestamp is equivalent to midnight in this timezone as represented in GMT.
894
-        return strtotime('tomorrow') + (self::get_site_timezone_gmt_offset() * -1);
895
-    }
884
+	/**
885
+	 * This simply returns the timestamp for tomorrow (midnight next day) in this sites timezone.  So it may be midnight
886
+	 * for this sites timezone, but the timestamp could be some other time GMT.
887
+	 */
888
+	public static function tomorrow()
889
+	{
890
+		// The multiplication of -1 ensures that we switch positive offsets to negative and negative offsets to positive
891
+		// before adding to the timestamp.  Why? Because we want tomorrow to be for midnight the next day in THIS timezone
892
+		// not an offset from midnight in UTC.  So if we're starting with UTC 00:00:00, then we want to make sure the
893
+		// final timestamp is equivalent to midnight in this timezone as represented in GMT.
894
+		return strtotime('tomorrow') + (self::get_site_timezone_gmt_offset() * -1);
895
+	}
896 896
 
897 897
 
898
-    /**
899
-     * **
900
-     * Gives a nicely-formatted list of timezone strings.
901
-     * Copied from the core wp function by the same name so we could customize to remove UTC offsets.
902
-     *
903
-     * @since     4.9.40.rc.008
904
-     * @staticvar bool $mo_loaded
905
-     * @staticvar string $locale_loaded
906
-     * @param string $selected_zone Selected timezone.
907
-     * @param string $locale        Optional. Locale to load the timezones in. Default current site locale.
908
-     * @return string
909
-     */
910
-    public static function wp_timezone_choice($selected_zone, $locale = null)
911
-    {
912
-        static $mo_loaded = false, $locale_loaded = null;
913
-        $continents = array(
914
-            'Africa',
915
-            'America',
916
-            'Antarctica',
917
-            'Arctic',
918
-            'Asia',
919
-            'Atlantic',
920
-            'Australia',
921
-            'Europe',
922
-            'Indian',
923
-            'Pacific',
924
-        );
925
-        // Load translations for continents and cities.
926
-        if (! $mo_loaded || $locale !== $locale_loaded) {
927
-            $locale_loaded = $locale ? $locale : get_locale();
928
-            $mofile        = WP_LANG_DIR . '/continents-cities-' . $locale_loaded . '.mo';
929
-            unload_textdomain('continents-cities');
930
-            load_textdomain('continents-cities', $mofile);
931
-            $mo_loaded = true;
932
-        }
933
-        $zone_data = array();
934
-        foreach (timezone_identifiers_list() as $zone) {
935
-            $zone = explode('/', $zone);
936
-            if (! in_array($zone[0], $continents, true)) {
937
-                continue;
938
-            }
939
-            // This determines what gets set and translated - we don't translate Etc/* strings here, they are done later
940
-            $exists      = array(
941
-                0 => isset($zone[0]) && $zone[0],
942
-                1 => isset($zone[1]) && $zone[1],
943
-                2 => isset($zone[2]) && $zone[2],
944
-            );
945
-            $exists[3]   = $exists[0] && $zone[0] !== 'Etc';
946
-            $exists[4]   = $exists[1] && $exists[3];
947
-            $exists[5]   = $exists[2] && $exists[3];
948
-            // phpcs:disable WordPress.WP.I18n.NonSingularStringLiteralText
949
-            // phpcs:disable WordPress.WP.I18n.TextDomainMismatch
950
-            // disabled because this code is copied from WordPress and is a WordPress domain
951
-            $zone_data[] = array(
952
-                'continent'   => $exists[0] ? $zone[0] : '',
953
-                'city'        => $exists[1] ? $zone[1] : '',
954
-                'subcity'     => $exists[2] ? $zone[2] : '',
955
-                't_continent' => $exists[3]
956
-                    ? translate(str_replace('_', ' ', $zone[0]), 'continents-cities')
957
-                    : '',
958
-                't_city'      => $exists[4]
959
-                    ? translate(str_replace('_', ' ', $zone[1]), 'continents-cities')
960
-                    : '',
961
-                't_subcity'   => $exists[5]
962
-                    ? translate(str_replace('_', ' ', $zone[2]), 'continents-cities')
963
-                    : '',
964
-            );
965
-            // phpcs:enable
966
-        }
967
-        usort($zone_data, '_wp_timezone_choice_usort_callback');
968
-        $structure = array();
969
-        if (empty($selected_zone)) {
970
-            $structure[] = '<option selected value="">' . esc_html__('Select a city', 'event_espresso') . '</option>';
971
-        }
972
-        foreach ($zone_data as $key => $zone) {
973
-            // Build value in an array to join later
974
-            $value = array($zone['continent']);
975
-            if (empty($zone['city'])) {
976
-                // It's at the continent level (generally won't happen)
977
-                $display = $zone['t_continent'];
978
-            } else {
979
-                // It's inside a continent group
980
-                // Continent optgroup
981
-                if (! isset($zone_data[ $key - 1 ]) || $zone_data[ $key - 1 ]['continent'] !== $zone['continent']) {
982
-                    $label       = $zone['t_continent'];
983
-                    $structure[] = '<optgroup label="' . esc_attr($label) . '">';
984
-                }
985
-                // Add the city to the value
986
-                $value[] = $zone['city'];
987
-                $display = $zone['t_city'];
988
-                if (! empty($zone['subcity'])) {
989
-                    // Add the subcity to the value
990
-                    $value[] = $zone['subcity'];
991
-                    $display .= ' - ' . $zone['t_subcity'];
992
-                }
993
-            }
994
-            // Build the value
995
-            $value       = implode('/', $value);
996
-            $selected    = $value === $selected_zone ? ' selected' : '';
997
-            $structure[] = '<option value="' . esc_attr($value) . '"' . $selected . '>'
998
-                           . esc_html($display)
999
-                           . '</option>';
1000
-            // Close continent optgroup
1001
-            if (
1002
-                ! empty($zone['city'])
1003
-                && (
1004
-                    ! isset($zone_data[ $key + 1 ])
1005
-                    || (isset($zone_data[ $key + 1 ]) && $zone_data[ $key + 1 ]['continent'] !== $zone['continent'])
1006
-                )
1007
-            ) {
1008
-                $structure[] = '</optgroup>';
1009
-            }
1010
-        }
1011
-        return implode("\n", $structure);
1012
-    }
898
+	/**
899
+	 * **
900
+	 * Gives a nicely-formatted list of timezone strings.
901
+	 * Copied from the core wp function by the same name so we could customize to remove UTC offsets.
902
+	 *
903
+	 * @since     4.9.40.rc.008
904
+	 * @staticvar bool $mo_loaded
905
+	 * @staticvar string $locale_loaded
906
+	 * @param string $selected_zone Selected timezone.
907
+	 * @param string $locale        Optional. Locale to load the timezones in. Default current site locale.
908
+	 * @return string
909
+	 */
910
+	public static function wp_timezone_choice($selected_zone, $locale = null)
911
+	{
912
+		static $mo_loaded = false, $locale_loaded = null;
913
+		$continents = array(
914
+			'Africa',
915
+			'America',
916
+			'Antarctica',
917
+			'Arctic',
918
+			'Asia',
919
+			'Atlantic',
920
+			'Australia',
921
+			'Europe',
922
+			'Indian',
923
+			'Pacific',
924
+		);
925
+		// Load translations for continents and cities.
926
+		if (! $mo_loaded || $locale !== $locale_loaded) {
927
+			$locale_loaded = $locale ? $locale : get_locale();
928
+			$mofile        = WP_LANG_DIR . '/continents-cities-' . $locale_loaded . '.mo';
929
+			unload_textdomain('continents-cities');
930
+			load_textdomain('continents-cities', $mofile);
931
+			$mo_loaded = true;
932
+		}
933
+		$zone_data = array();
934
+		foreach (timezone_identifiers_list() as $zone) {
935
+			$zone = explode('/', $zone);
936
+			if (! in_array($zone[0], $continents, true)) {
937
+				continue;
938
+			}
939
+			// This determines what gets set and translated - we don't translate Etc/* strings here, they are done later
940
+			$exists      = array(
941
+				0 => isset($zone[0]) && $zone[0],
942
+				1 => isset($zone[1]) && $zone[1],
943
+				2 => isset($zone[2]) && $zone[2],
944
+			);
945
+			$exists[3]   = $exists[0] && $zone[0] !== 'Etc';
946
+			$exists[4]   = $exists[1] && $exists[3];
947
+			$exists[5]   = $exists[2] && $exists[3];
948
+			// phpcs:disable WordPress.WP.I18n.NonSingularStringLiteralText
949
+			// phpcs:disable WordPress.WP.I18n.TextDomainMismatch
950
+			// disabled because this code is copied from WordPress and is a WordPress domain
951
+			$zone_data[] = array(
952
+				'continent'   => $exists[0] ? $zone[0] : '',
953
+				'city'        => $exists[1] ? $zone[1] : '',
954
+				'subcity'     => $exists[2] ? $zone[2] : '',
955
+				't_continent' => $exists[3]
956
+					? translate(str_replace('_', ' ', $zone[0]), 'continents-cities')
957
+					: '',
958
+				't_city'      => $exists[4]
959
+					? translate(str_replace('_', ' ', $zone[1]), 'continents-cities')
960
+					: '',
961
+				't_subcity'   => $exists[5]
962
+					? translate(str_replace('_', ' ', $zone[2]), 'continents-cities')
963
+					: '',
964
+			);
965
+			// phpcs:enable
966
+		}
967
+		usort($zone_data, '_wp_timezone_choice_usort_callback');
968
+		$structure = array();
969
+		if (empty($selected_zone)) {
970
+			$structure[] = '<option selected value="">' . esc_html__('Select a city', 'event_espresso') . '</option>';
971
+		}
972
+		foreach ($zone_data as $key => $zone) {
973
+			// Build value in an array to join later
974
+			$value = array($zone['continent']);
975
+			if (empty($zone['city'])) {
976
+				// It's at the continent level (generally won't happen)
977
+				$display = $zone['t_continent'];
978
+			} else {
979
+				// It's inside a continent group
980
+				// Continent optgroup
981
+				if (! isset($zone_data[ $key - 1 ]) || $zone_data[ $key - 1 ]['continent'] !== $zone['continent']) {
982
+					$label       = $zone['t_continent'];
983
+					$structure[] = '<optgroup label="' . esc_attr($label) . '">';
984
+				}
985
+				// Add the city to the value
986
+				$value[] = $zone['city'];
987
+				$display = $zone['t_city'];
988
+				if (! empty($zone['subcity'])) {
989
+					// Add the subcity to the value
990
+					$value[] = $zone['subcity'];
991
+					$display .= ' - ' . $zone['t_subcity'];
992
+				}
993
+			}
994
+			// Build the value
995
+			$value       = implode('/', $value);
996
+			$selected    = $value === $selected_zone ? ' selected' : '';
997
+			$structure[] = '<option value="' . esc_attr($value) . '"' . $selected . '>'
998
+						   . esc_html($display)
999
+						   . '</option>';
1000
+			// Close continent optgroup
1001
+			if (
1002
+				! empty($zone['city'])
1003
+				&& (
1004
+					! isset($zone_data[ $key + 1 ])
1005
+					|| (isset($zone_data[ $key + 1 ]) && $zone_data[ $key + 1 ]['continent'] !== $zone['continent'])
1006
+				)
1007
+			) {
1008
+				$structure[] = '</optgroup>';
1009
+			}
1010
+		}
1011
+		return implode("\n", $structure);
1012
+	}
1013 1013
 
1014 1014
 
1015
-    /**
1016
-     * Shim for the WP function `get_user_locale` that was added in WordPress 4.7.0
1017
-     *
1018
-     * @param int|WP_User $user_id
1019
-     * @return string
1020
-     */
1021
-    public static function get_user_locale($user_id = 0)
1022
-    {
1023
-        if (function_exists('get_user_locale')) {
1024
-            return get_user_locale($user_id);
1025
-        }
1026
-        return get_locale();
1027
-    }
1015
+	/**
1016
+	 * Shim for the WP function `get_user_locale` that was added in WordPress 4.7.0
1017
+	 *
1018
+	 * @param int|WP_User $user_id
1019
+	 * @return string
1020
+	 */
1021
+	public static function get_user_locale($user_id = 0)
1022
+	{
1023
+		if (function_exists('get_user_locale')) {
1024
+			return get_user_locale($user_id);
1025
+		}
1026
+		return get_locale();
1027
+	}
1028 1028
 
1029 1029
 
1030
-    /**
1031
-     * Return the appropriate helper adapter for DTT related things.
1032
-     *
1033
-     * @return HelperInterface
1034
-     * @throws InvalidArgumentException
1035
-     * @throws InvalidDataTypeException
1036
-     * @throws InvalidInterfaceException
1037
-     */
1038
-    private static function getHelperAdapter()
1039
-    {
1040
-        $dtt_helper_fqcn = PHP_VERSION_ID < 50600
1041
-            ? 'EventEspresso\core\services\helpers\datetime\PhpCompatLessFiveSixHelper'
1042
-            : 'EventEspresso\core\services\helpers\datetime\PhpCompatGreaterFiveSixHelper';
1043
-        return LoaderFactory::getLoader()->getShared($dtt_helper_fqcn);
1044
-    }
1030
+	/**
1031
+	 * Return the appropriate helper adapter for DTT related things.
1032
+	 *
1033
+	 * @return HelperInterface
1034
+	 * @throws InvalidArgumentException
1035
+	 * @throws InvalidDataTypeException
1036
+	 * @throws InvalidInterfaceException
1037
+	 */
1038
+	private static function getHelperAdapter()
1039
+	{
1040
+		$dtt_helper_fqcn = PHP_VERSION_ID < 50600
1041
+			? 'EventEspresso\core\services\helpers\datetime\PhpCompatLessFiveSixHelper'
1042
+			: 'EventEspresso\core\services\helpers\datetime\PhpCompatGreaterFiveSixHelper';
1043
+		return LoaderFactory::getLoader()->getShared($dtt_helper_fqcn);
1044
+	}
1045 1045
 
1046 1046
 
1047
-    /**
1048
-     * Helper function for setting the timezone on a DateTime object.
1049
-     * This is implemented to standardize a workaround for a PHP bug outlined in
1050
-     * https://events.codebasehq.com/projects/event-espresso/tickets/11407 and
1051
-     * https://events.codebasehq.com/projects/event-espresso/tickets/11233
1052
-     *
1053
-     * @param DateTime     $datetime
1054
-     * @param DateTimeZone $timezone
1055
-     */
1056
-    public static function setTimezone(DateTime $datetime, DateTimeZone $timezone)
1057
-    {
1058
-        $datetime->setTimezone($timezone);
1059
-        $datetime->getTimestamp();
1060
-    }
1047
+	/**
1048
+	 * Helper function for setting the timezone on a DateTime object.
1049
+	 * This is implemented to standardize a workaround for a PHP bug outlined in
1050
+	 * https://events.codebasehq.com/projects/event-espresso/tickets/11407 and
1051
+	 * https://events.codebasehq.com/projects/event-espresso/tickets/11233
1052
+	 *
1053
+	 * @param DateTime     $datetime
1054
+	 * @param DateTimeZone $timezone
1055
+	 */
1056
+	public static function setTimezone(DateTime $datetime, DateTimeZone $timezone)
1057
+	{
1058
+		$datetime->setTimezone($timezone);
1059
+		$datetime->getTimestamp();
1060
+	}
1061 1061
 }
Please login to merge, or discard this patch.
Spacing   +41 added lines, -41 removed lines patch added patch discarded remove patch
@@ -131,7 +131,7 @@  discard block
 block discarded – undo
131 131
      */
132 132
     public static function get_timezone_string_from_abbreviations_list($gmt_offset = 0, $coerce = true)
133 133
     {
134
-        $gmt_offset =  (int) $gmt_offset;
134
+        $gmt_offset = (int) $gmt_offset;
135 135
         /** @var array[] $abbreviations */
136 136
         $abbreviations = DateTimeZone::listAbbreviations();
137 137
         foreach ($abbreviations as $abbreviation) {
@@ -326,7 +326,7 @@  discard block
 block discarded – undo
326 326
      */
327 327
     protected static function _modify_datetime_object(DateTime $DateTime, $period = 'years', $value = 1, $operand = '+')
328 328
     {
329
-        if (! $DateTime instanceof DateTime) {
329
+        if ( ! $DateTime instanceof DateTime) {
330 330
             throw new EE_Error(
331 331
                 sprintf(
332 332
                     esc_html__('Expected a PHP DateTime object, but instead received %1$s', 'event_espresso'),
@@ -336,25 +336,25 @@  discard block
 block discarded – undo
336 336
         }
337 337
         switch ($period) {
338 338
             case 'years':
339
-                $value = 'P' . $value . 'Y';
339
+                $value = 'P'.$value.'Y';
340 340
                 break;
341 341
             case 'months':
342
-                $value = 'P' . $value . 'M';
342
+                $value = 'P'.$value.'M';
343 343
                 break;
344 344
             case 'weeks':
345
-                $value = 'P' . $value . 'W';
345
+                $value = 'P'.$value.'W';
346 346
                 break;
347 347
             case 'days':
348
-                $value = 'P' . $value . 'D';
348
+                $value = 'P'.$value.'D';
349 349
                 break;
350 350
             case 'hours':
351
-                $value = 'PT' . $value . 'H';
351
+                $value = 'PT'.$value.'H';
352 352
                 break;
353 353
             case 'minutes':
354
-                $value = 'PT' . $value . 'M';
354
+                $value = 'PT'.$value.'M';
355 355
                 break;
356 356
             case 'seconds':
357
-                $value = 'PT' . $value . 'S';
357
+                $value = 'PT'.$value.'S';
358 358
                 break;
359 359
         }
360 360
         switch ($operand) {
@@ -382,7 +382,7 @@  discard block
 block discarded – undo
382 382
      */
383 383
     protected static function _modify_timestamp($timestamp, $period = 'years', $value = 1, $operand = '+')
384 384
     {
385
-        if (! preg_match(EE_Datetime_Field::unix_timestamp_regex, $timestamp)) {
385
+        if ( ! preg_match(EE_Datetime_Field::unix_timestamp_regex, $timestamp)) {
386 386
             throw new EE_Error(
387 387
                 sprintf(
388 388
                     esc_html__('Expected a Unix timestamp, but instead received %1$s', 'event_espresso'),
@@ -495,7 +495,7 @@  discard block
 block discarded – undo
495 495
                 'date' => $date_format['js'],
496 496
                 'time' => $time_format['js'],
497 497
             ),
498
-            'moment' => $date_format['moment'] . ' ' . $time_format['moment'],
498
+            'moment' => $date_format['moment'].' '.$time_format['moment'],
499 499
             'moment_split' => array(
500 500
                 'date' => $date_format['moment'],
501 501
                 'time' => $time_format['moment']
@@ -518,7 +518,7 @@  discard block
 block discarded – undo
518 518
          *
519 519
          * @var array
520 520
          */
521
-        $symbols_map          = array(
521
+        $symbols_map = array(
522 522
             // Day
523 523
             // 01
524 524
             'd' => array(
@@ -670,26 +670,26 @@  discard block
 block discarded – undo
670 670
         $escaping             = false;
671 671
         $format_string_length = strlen($format_string);
672 672
         for ($i = 0; $i < $format_string_length; $i++) {
673
-            $char = $format_string[ $i ];
673
+            $char = $format_string[$i];
674 674
             if ($char === '\\') { // PHP date format escaping character
675 675
                 $i++;
676 676
                 if ($escaping) {
677
-                    $jquery_ui_format .= $format_string[ $i ];
678
-                    $moment_format    .= $format_string[ $i ];
677
+                    $jquery_ui_format .= $format_string[$i];
678
+                    $moment_format    .= $format_string[$i];
679 679
                 } else {
680
-                    $jquery_ui_format .= '\'' . $format_string[ $i ];
681
-                    $moment_format    .= $format_string[ $i ];
680
+                    $jquery_ui_format .= '\''.$format_string[$i];
681
+                    $moment_format    .= $format_string[$i];
682 682
                 }
683 683
                 $escaping = true;
684 684
             } else {
685 685
                 if ($escaping) {
686 686
                     $jquery_ui_format .= "'";
687 687
                     $moment_format    .= "'";
688
-                    $escaping         = false;
688
+                    $escaping = false;
689 689
                 }
690
-                if (isset($symbols_map[ $char ])) {
691
-                    $jquery_ui_format .= $symbols_map[ $char ]['js'];
692
-                    $moment_format    .= $symbols_map[ $char ]['moment'];
690
+                if (isset($symbols_map[$char])) {
691
+                    $jquery_ui_format .= $symbols_map[$char]['js'];
692
+                    $moment_format    .= $symbols_map[$char]['moment'];
693 693
                 } else {
694 694
                     $jquery_ui_format .= $char;
695 695
                     $moment_format    .= $char;
@@ -747,7 +747,7 @@  discard block
 block discarded – undo
747 747
     {
748 748
 
749 749
         if (
750
-            (! $date_1 instanceof DateTime || ! $date_2 instanceof DateTime)
750
+            ( ! $date_1 instanceof DateTime || ! $date_2 instanceof DateTime)
751 751
             || ($date_1->format(EE_Datetime_Field::mysql_time_format) !== '00:00:00'
752 752
                 || $date_2->format(
753 753
                     EE_Datetime_Field::mysql_time_format
@@ -783,8 +783,8 @@  discard block
 block discarded – undo
783 783
             ? $DateTimeZone->getOffset(new DateTime('now')) / HOUR_IN_SECONDS
784 784
             : (float) get_option('gmt_offset');
785 785
         $query_interval = $offset < 0
786
-            ? 'DATE_SUB(' . $field_for_interval . ', INTERVAL ' . $offset * -1 . ' HOUR)'
787
-            : 'DATE_ADD(' . $field_for_interval . ', INTERVAL ' . $offset . ' HOUR)';
786
+            ? 'DATE_SUB('.$field_for_interval.', INTERVAL '.$offset * -1.' HOUR)'
787
+            : 'DATE_ADD('.$field_for_interval.', INTERVAL '.$offset.' HOUR)';
788 788
         return $query_interval;
789 789
     }
790 790
 
@@ -801,16 +801,16 @@  discard block
 block discarded – undo
801 801
     public static function get_timezone_string_for_display()
802 802
     {
803 803
         $pretty_timezone = apply_filters('FHEE__EEH_DTT_Helper__get_timezone_string_for_display', '');
804
-        if (! empty($pretty_timezone)) {
804
+        if ( ! empty($pretty_timezone)) {
805 805
             return esc_html($pretty_timezone);
806 806
         }
807 807
         $timezone_string = get_option('timezone_string');
808 808
         if ($timezone_string) {
809 809
             static $mo_loaded = false;
810 810
             // Load translations for continents and cities just like wp_timezone_choice does
811
-            if (! $mo_loaded) {
811
+            if ( ! $mo_loaded) {
812 812
                 $locale = get_locale();
813
-                $mofile = WP_LANG_DIR . '/continents-cities-' . $locale . '.mo';
813
+                $mofile = WP_LANG_DIR.'/continents-cities-'.$locale.'.mo';
814 814
                 load_textdomain('continents-cities', $mofile);
815 815
                 $mo_loaded = true;
816 816
             }
@@ -837,10 +837,10 @@  discard block
 block discarded – undo
837 837
         } else {
838 838
             // convert the part after the decimal, eg "5" (from x.5) or "25" (from x.25)
839 839
             // to minutes, eg 30 or 15, respectively
840
-            $hour_fraction = (float) ('0.' . $parts[1]);
840
+            $hour_fraction = (float) ('0.'.$parts[1]);
841 841
             $parts[1]      = (string) $hour_fraction * 60;
842 842
         }
843
-        return sprintf(esc_html__('UTC%1$s', 'event_espresso'), $prefix . implode(':', $parts));
843
+        return sprintf(esc_html__('UTC%1$s', 'event_espresso'), $prefix.implode(':', $parts));
844 844
     }
845 845
 
846 846
 
@@ -923,9 +923,9 @@  discard block
 block discarded – undo
923 923
             'Pacific',
924 924
         );
925 925
         // Load translations for continents and cities.
926
-        if (! $mo_loaded || $locale !== $locale_loaded) {
926
+        if ( ! $mo_loaded || $locale !== $locale_loaded) {
927 927
             $locale_loaded = $locale ? $locale : get_locale();
928
-            $mofile        = WP_LANG_DIR . '/continents-cities-' . $locale_loaded . '.mo';
928
+            $mofile        = WP_LANG_DIR.'/continents-cities-'.$locale_loaded.'.mo';
929 929
             unload_textdomain('continents-cities');
930 930
             load_textdomain('continents-cities', $mofile);
931 931
             $mo_loaded = true;
@@ -933,11 +933,11 @@  discard block
 block discarded – undo
933 933
         $zone_data = array();
934 934
         foreach (timezone_identifiers_list() as $zone) {
935 935
             $zone = explode('/', $zone);
936
-            if (! in_array($zone[0], $continents, true)) {
936
+            if ( ! in_array($zone[0], $continents, true)) {
937 937
                 continue;
938 938
             }
939 939
             // This determines what gets set and translated - we don't translate Etc/* strings here, they are done later
940
-            $exists      = array(
940
+            $exists = array(
941 941
                 0 => isset($zone[0]) && $zone[0],
942 942
                 1 => isset($zone[1]) && $zone[1],
943 943
                 2 => isset($zone[2]) && $zone[2],
@@ -967,7 +967,7 @@  discard block
 block discarded – undo
967 967
         usort($zone_data, '_wp_timezone_choice_usort_callback');
968 968
         $structure = array();
969 969
         if (empty($selected_zone)) {
970
-            $structure[] = '<option selected value="">' . esc_html__('Select a city', 'event_espresso') . '</option>';
970
+            $structure[] = '<option selected value="">'.esc_html__('Select a city', 'event_espresso').'</option>';
971 971
         }
972 972
         foreach ($zone_data as $key => $zone) {
973 973
             // Build value in an array to join later
@@ -978,31 +978,31 @@  discard block
 block discarded – undo
978 978
             } else {
979 979
                 // It's inside a continent group
980 980
                 // Continent optgroup
981
-                if (! isset($zone_data[ $key - 1 ]) || $zone_data[ $key - 1 ]['continent'] !== $zone['continent']) {
981
+                if ( ! isset($zone_data[$key - 1]) || $zone_data[$key - 1]['continent'] !== $zone['continent']) {
982 982
                     $label       = $zone['t_continent'];
983
-                    $structure[] = '<optgroup label="' . esc_attr($label) . '">';
983
+                    $structure[] = '<optgroup label="'.esc_attr($label).'">';
984 984
                 }
985 985
                 // Add the city to the value
986 986
                 $value[] = $zone['city'];
987 987
                 $display = $zone['t_city'];
988
-                if (! empty($zone['subcity'])) {
988
+                if ( ! empty($zone['subcity'])) {
989 989
                     // Add the subcity to the value
990 990
                     $value[] = $zone['subcity'];
991
-                    $display .= ' - ' . $zone['t_subcity'];
991
+                    $display .= ' - '.$zone['t_subcity'];
992 992
                 }
993 993
             }
994 994
             // Build the value
995 995
             $value       = implode('/', $value);
996 996
             $selected    = $value === $selected_zone ? ' selected' : '';
997
-            $structure[] = '<option value="' . esc_attr($value) . '"' . $selected . '>'
997
+            $structure[] = '<option value="'.esc_attr($value).'"'.$selected.'>'
998 998
                            . esc_html($display)
999 999
                            . '</option>';
1000 1000
             // Close continent optgroup
1001 1001
             if (
1002 1002
                 ! empty($zone['city'])
1003 1003
                 && (
1004
-                    ! isset($zone_data[ $key + 1 ])
1005
-                    || (isset($zone_data[ $key + 1 ]) && $zone_data[ $key + 1 ]['continent'] !== $zone['continent'])
1004
+                    ! isset($zone_data[$key + 1])
1005
+                    || (isset($zone_data[$key + 1]) && $zone_data[$key + 1]['continent'] !== $zone['continent'])
1006 1006
                 )
1007 1007
             ) {
1008 1008
                 $structure[] = '</optgroup>';
Please login to merge, or discard this patch.
core/templates/json_linked_data_for_event.template.php 1 patch
Indentation   +15 added lines, -15 removed lines patch added patch discarded remove patch
@@ -29,8 +29,8 @@  discard block
 block discarded – undo
29 29
   "eventStatus": [ "<?php echo esc_url_raw($event_status); ?>" ],
30 30
   "offers": [
31 31
     <?php
32
-    $i = 0;
33
-    foreach ($event_tickets as $ticket) {?>
32
+	$i = 0;
33
+	foreach ($event_tickets as $ticket) {?>
34 34
     {
35 35
       "@type": "Offer",
36 36
       "url": "<?php echo esc_url_raw($event_permalink); ?>",
@@ -39,18 +39,18 @@  discard block
 block discarded – undo
39 39
       "price": "<?php echo esc_html($ticket['price']); ?>",
40 40
       "priceCurrency": "<?php echo esc_html($currency); ?>"
41 41
         <?php if (isset($ticket['availability'])) {
42
-            ?>,"availability": "<?php echo esc_url_raw('https://schema.org/' . $ticket['availability']); ?>"
42
+			?>,"availability": "<?php echo esc_url_raw('https://schema.org/' . $ticket['availability']); ?>"
43 43
         <?php } ?>
44 44
     }<?php
45
-    $i++;
46
-    if ($i < count($event_tickets)) {
47
-        echo ',';
48
-    }
49
-    }
50
-    ?>
45
+	$i++;
46
+	if ($i < count($event_tickets)) {
47
+		echo ',';
48
+	}
49
+	}
50
+	?>
51 51
     ]<?php
52
-    if ($venue_name) {
53
-        ?>,
52
+	if ($venue_name) {
53
+		?>,
54 54
   "location": {
55 55
     "@type": "Place",
56 56
     "name": <?php echo wp_json_encode($venue_name); ?>,
@@ -63,13 +63,13 @@  discard block
 block discarded – undo
63 63
     }
64 64
   }
65 65
         <?php
66
-    } ?>
66
+	} ?>
67 67
     <?php
68
-    if ($event_image) {
69
-        ?>,
68
+	if ($event_image) {
69
+		?>,
70 70
   "image": "<?php echo esc_url_raw($event_image); ?>"
71 71
         <?php
72
-    } ?>
72
+	} ?>
73 73
     <?php do_action('AHEE__json_linked_data_for_event__template'); ?>
74 74
 }
75 75
 
Please login to merge, or discard this patch.
display/EE_Checkbox_Dropdown_Selector_Display_Strategy.strategy.php 2 patches
Indentation   +176 added lines, -176 removed lines patch added patch discarded remove patch
@@ -13,180 +13,180 @@
 block discarded – undo
13 13
 {
14 14
 
15 15
 
16
-    /**
17
-     * enqueues css and js, so that this can be called statically
18
-     */
19
-    public static function enqueue_styles_and_scripts()
20
-    {
21
-        wp_register_style(
22
-            'checkbox_dropdown_selector',
23
-            EE_GLOBAL_ASSETS_URL . 'css/checkbox_dropdown_selector.css',
24
-            array('espresso_default'),
25
-            EVENT_ESPRESSO_VERSION
26
-        );
27
-        wp_register_style(
28
-            'espresso_default',
29
-            EE_GLOBAL_ASSETS_URL . 'css/espresso_default.css',
30
-            array('dashicons'),
31
-            EVENT_ESPRESSO_VERSION
32
-        );
33
-        wp_enqueue_style('checkbox_dropdown_selector');
34
-        wp_register_script(
35
-            'checkbox_dropdown_selector',
36
-            EE_GLOBAL_ASSETS_URL . 'scripts/checkbox_dropdown_selector.js',
37
-            array('jquery'),
38
-            EVENT_ESPRESSO_VERSION,
39
-            true
40
-        );
41
-        wp_localize_script(
42
-            'ticket_selector',
43
-            'eeDTS',
44
-            array(
45
-                'maxChecked' => EE_Registry::instance()
46
-                    ->CFG
47
-                    ->template_settings
48
-                    ->EED_Ticket_Selector
49
-                    ->getDatetimeSelectorMaxChecked()
50
-            )
51
-        );
52
-        wp_enqueue_script('checkbox_dropdown_selector');
53
-    }
54
-
55
-
56
-
57
-    /**
58
-     * Informs the rest of the forms system what CSS and JS is needed to display the input
59
-     */
60
-    public function enqueue_js()
61
-    {
62
-        EE_Checkbox_Dropdown_Selector_Display_Strategy::enqueue_styles_and_scripts();
63
-    }
64
-
65
-
66
-
67
-    /**
68
-     * callback for Iframe::addStylesheets() child class methods
69
-     *
70
-     * @param array $iframe_css
71
-     * @return array
72
-     */
73
-    public function iframe_css(array $iframe_css)
74
-    {
75
-        $iframe_css['checkbox_dropdown_selector'] = EE_GLOBAL_ASSETS_URL . 'css/checkbox_dropdown_selector.css';
76
-        return $iframe_css;
77
-    }
78
-
79
-
80
-
81
-    /**
82
-     * callback for Iframe::addScripts() child class methods
83
-     *
84
-     * @param array $iframe_js
85
-     * @return array
86
-     */
87
-    public function iframe_js(array $iframe_js)
88
-    {
89
-        $iframe_js['checkbox_dropdown_selector'] = EE_GLOBAL_ASSETS_URL . 'scripts/checkbox_dropdown_selector.js';
90
-        return $iframe_js;
91
-    }
92
-
93
-
94
-    /**
95
-     * @throws EE_Error
96
-     * @return string of html to display the field
97
-     */
98
-    public function display()
99
-    {
100
-        $input = $this->get_input();
101
-        $select_button_text = $input instanceof EE_Checkbox_Dropdown_Selector_Input ? $input->select_button_text() : '';
102
-        // $multi = count( $input->options() ) > 1 ? TRUE : FALSE;
103
-        $input->set_label_sizes();
104
-        $label_size_class = $input->get_label_size_class();
105
-        if (! is_array($input->raw_value()) && $input->raw_value() !== null) {
106
-            EE_Error::doing_it_wrong(
107
-                'EE_Checkbox_Display_Strategy::display()',
108
-                sprintf(
109
-                    esc_html__(
110
-                        'Input values for checkboxes should be an array of values, but the value for input "%1$s" is "%2$s". Please verify that the input name is exactly "%3$s"',
111
-                        'event_espresso'
112
-                    ),
113
-                    $input->html_id(),
114
-                    var_export($input->raw_value(), true),
115
-                    $input->html_name() . '[]'
116
-                ),
117
-                '4.8.1'
118
-            );
119
-        }
120
-
121
-
122
-        $html = \EEH_HTML::div('', '', 'checkbox-dropdown-selector-wrap-dv');
123
-        $html .= '<button id="' . $input->html_id() . '-btn"';
124
-        // $html .= ' name="' . $input->html_name() . '"';
125
-        $html .= ' class="' . $input->html_class() . ' checkbox-dropdown-selector-btn button-secondary button"';
126
-        $html .= ' style="' . $input->html_style() . '"';
127
-        $html .= ' data-target="' . $input->html_id() . '-options-dv"';
128
-        $html .= ' ' . $input->other_html_attributes() . '>';
129
-        $html .= '<span class="checkbox-dropdown-selector-selected-spn">';
130
-        $html .= $select_button_text;
131
-        $html .= '</span> <span class="dashicons dashicons-arrow-down"></span>';
132
-        $html .= '</button>';
133
-        $html .= EEH_HTML::div(
134
-            '',
135
-            $input->html_id() . '-options-dv',
136
-            'checkbox-dropdown-selector'
137
-        );
138
-        $html .= EEH_HTML::link(
139
-            '',
140
-            '<span class="dashicons dashicons-no"></span>',
141
-            esc_html__('close datetime selector', 'event_espresso'),
142
-            '',
143
-            'close-espresso-notice'
144
-        );
145
-        $html .= EEH_HTML::ul();
146
-        $input_raw_value = (array) $input->raw_value();
147
-        foreach ($input->options() as $value => $display_text) {
148
-            $html .= EEH_HTML::li();
149
-            $value = $input->get_normalization_strategy()->unnormalize_one($value);
150
-            $html_id = $this->get_sub_input_id($value);
151
-            $html .= EEH_HTML::nl(0, 'checkbox');
152
-            $html .= '<label for="'
153
-                     . $html_id
154
-                     . '" id="'
155
-                     . $html_id
156
-                     . '-lbl" class="ee-checkbox-label-after'
157
-                     . $label_size_class
158
-                     . '">';
159
-            $html .= EEH_HTML::nl(1, 'checkbox');
160
-            $html .= '<input type="checkbox"';
161
-            $html .= ' name="' . $input->html_name() . '[]"';
162
-            $html .= ' id="' . $html_id . '"';
163
-            $html .= ' class="' . $input->html_class() . '-option"';
164
-            $html .= $input->html_style() ? ' style="' . $input->html_style() . '"' : '';
165
-            $html .= ' value="' . esc_attr($value) . '"';
166
-            $html .= ! empty($input_raw_value) && in_array($value, $input_raw_value, true)
167
-                ? ' checked'
168
-                : '';
169
-            $html .= ' ' . $this->_input->other_html_attributes();
170
-            $html .= '>';
171
-            $html .= '<span class="datetime-selector-option-text-spn">' . $display_text . '</span>';
172
-            $html .= EEH_HTML::nl(-1, 'checkbox') . '</label>';
173
-            $html .= EEH_HTML::lix();
174
-        }
175
-        $html .= EEH_HTML::ulx();
176
-        $html .= EEH_HTML::divx();
177
-        $html .= EEH_HTML::divx();
178
-        $html .= EEH_HTML::p(
179
-            apply_filters(
180
-                'FHEE__EE_Checkbox_Dropdown_Selector_Display_Strategy__display__html',
181
-                esc_html__(
182
-                    'To view additional ticket options, click the "Filter by Date" button and select more dates.',
183
-                    'event_espresso'
184
-                )
185
-            ),
186
-            $input->html_id() . '-date-time-filter-notice-pg',
187
-            'date-time-filter-notice-pg small-text lt-grey-text'
188
-        );
189
-        $html .= \EEH_HTML::br();
190
-        return $html;
191
-    }
16
+	/**
17
+	 * enqueues css and js, so that this can be called statically
18
+	 */
19
+	public static function enqueue_styles_and_scripts()
20
+	{
21
+		wp_register_style(
22
+			'checkbox_dropdown_selector',
23
+			EE_GLOBAL_ASSETS_URL . 'css/checkbox_dropdown_selector.css',
24
+			array('espresso_default'),
25
+			EVENT_ESPRESSO_VERSION
26
+		);
27
+		wp_register_style(
28
+			'espresso_default',
29
+			EE_GLOBAL_ASSETS_URL . 'css/espresso_default.css',
30
+			array('dashicons'),
31
+			EVENT_ESPRESSO_VERSION
32
+		);
33
+		wp_enqueue_style('checkbox_dropdown_selector');
34
+		wp_register_script(
35
+			'checkbox_dropdown_selector',
36
+			EE_GLOBAL_ASSETS_URL . 'scripts/checkbox_dropdown_selector.js',
37
+			array('jquery'),
38
+			EVENT_ESPRESSO_VERSION,
39
+			true
40
+		);
41
+		wp_localize_script(
42
+			'ticket_selector',
43
+			'eeDTS',
44
+			array(
45
+				'maxChecked' => EE_Registry::instance()
46
+					->CFG
47
+					->template_settings
48
+					->EED_Ticket_Selector
49
+					->getDatetimeSelectorMaxChecked()
50
+			)
51
+		);
52
+		wp_enqueue_script('checkbox_dropdown_selector');
53
+	}
54
+
55
+
56
+
57
+	/**
58
+	 * Informs the rest of the forms system what CSS and JS is needed to display the input
59
+	 */
60
+	public function enqueue_js()
61
+	{
62
+		EE_Checkbox_Dropdown_Selector_Display_Strategy::enqueue_styles_and_scripts();
63
+	}
64
+
65
+
66
+
67
+	/**
68
+	 * callback for Iframe::addStylesheets() child class methods
69
+	 *
70
+	 * @param array $iframe_css
71
+	 * @return array
72
+	 */
73
+	public function iframe_css(array $iframe_css)
74
+	{
75
+		$iframe_css['checkbox_dropdown_selector'] = EE_GLOBAL_ASSETS_URL . 'css/checkbox_dropdown_selector.css';
76
+		return $iframe_css;
77
+	}
78
+
79
+
80
+
81
+	/**
82
+	 * callback for Iframe::addScripts() child class methods
83
+	 *
84
+	 * @param array $iframe_js
85
+	 * @return array
86
+	 */
87
+	public function iframe_js(array $iframe_js)
88
+	{
89
+		$iframe_js['checkbox_dropdown_selector'] = EE_GLOBAL_ASSETS_URL . 'scripts/checkbox_dropdown_selector.js';
90
+		return $iframe_js;
91
+	}
92
+
93
+
94
+	/**
95
+	 * @throws EE_Error
96
+	 * @return string of html to display the field
97
+	 */
98
+	public function display()
99
+	{
100
+		$input = $this->get_input();
101
+		$select_button_text = $input instanceof EE_Checkbox_Dropdown_Selector_Input ? $input->select_button_text() : '';
102
+		// $multi = count( $input->options() ) > 1 ? TRUE : FALSE;
103
+		$input->set_label_sizes();
104
+		$label_size_class = $input->get_label_size_class();
105
+		if (! is_array($input->raw_value()) && $input->raw_value() !== null) {
106
+			EE_Error::doing_it_wrong(
107
+				'EE_Checkbox_Display_Strategy::display()',
108
+				sprintf(
109
+					esc_html__(
110
+						'Input values for checkboxes should be an array of values, but the value for input "%1$s" is "%2$s". Please verify that the input name is exactly "%3$s"',
111
+						'event_espresso'
112
+					),
113
+					$input->html_id(),
114
+					var_export($input->raw_value(), true),
115
+					$input->html_name() . '[]'
116
+				),
117
+				'4.8.1'
118
+			);
119
+		}
120
+
121
+
122
+		$html = \EEH_HTML::div('', '', 'checkbox-dropdown-selector-wrap-dv');
123
+		$html .= '<button id="' . $input->html_id() . '-btn"';
124
+		// $html .= ' name="' . $input->html_name() . '"';
125
+		$html .= ' class="' . $input->html_class() . ' checkbox-dropdown-selector-btn button-secondary button"';
126
+		$html .= ' style="' . $input->html_style() . '"';
127
+		$html .= ' data-target="' . $input->html_id() . '-options-dv"';
128
+		$html .= ' ' . $input->other_html_attributes() . '>';
129
+		$html .= '<span class="checkbox-dropdown-selector-selected-spn">';
130
+		$html .= $select_button_text;
131
+		$html .= '</span> <span class="dashicons dashicons-arrow-down"></span>';
132
+		$html .= '</button>';
133
+		$html .= EEH_HTML::div(
134
+			'',
135
+			$input->html_id() . '-options-dv',
136
+			'checkbox-dropdown-selector'
137
+		);
138
+		$html .= EEH_HTML::link(
139
+			'',
140
+			'<span class="dashicons dashicons-no"></span>',
141
+			esc_html__('close datetime selector', 'event_espresso'),
142
+			'',
143
+			'close-espresso-notice'
144
+		);
145
+		$html .= EEH_HTML::ul();
146
+		$input_raw_value = (array) $input->raw_value();
147
+		foreach ($input->options() as $value => $display_text) {
148
+			$html .= EEH_HTML::li();
149
+			$value = $input->get_normalization_strategy()->unnormalize_one($value);
150
+			$html_id = $this->get_sub_input_id($value);
151
+			$html .= EEH_HTML::nl(0, 'checkbox');
152
+			$html .= '<label for="'
153
+					 . $html_id
154
+					 . '" id="'
155
+					 . $html_id
156
+					 . '-lbl" class="ee-checkbox-label-after'
157
+					 . $label_size_class
158
+					 . '">';
159
+			$html .= EEH_HTML::nl(1, 'checkbox');
160
+			$html .= '<input type="checkbox"';
161
+			$html .= ' name="' . $input->html_name() . '[]"';
162
+			$html .= ' id="' . $html_id . '"';
163
+			$html .= ' class="' . $input->html_class() . '-option"';
164
+			$html .= $input->html_style() ? ' style="' . $input->html_style() . '"' : '';
165
+			$html .= ' value="' . esc_attr($value) . '"';
166
+			$html .= ! empty($input_raw_value) && in_array($value, $input_raw_value, true)
167
+				? ' checked'
168
+				: '';
169
+			$html .= ' ' . $this->_input->other_html_attributes();
170
+			$html .= '>';
171
+			$html .= '<span class="datetime-selector-option-text-spn">' . $display_text . '</span>';
172
+			$html .= EEH_HTML::nl(-1, 'checkbox') . '</label>';
173
+			$html .= EEH_HTML::lix();
174
+		}
175
+		$html .= EEH_HTML::ulx();
176
+		$html .= EEH_HTML::divx();
177
+		$html .= EEH_HTML::divx();
178
+		$html .= EEH_HTML::p(
179
+			apply_filters(
180
+				'FHEE__EE_Checkbox_Dropdown_Selector_Display_Strategy__display__html',
181
+				esc_html__(
182
+					'To view additional ticket options, click the "Filter by Date" button and select more dates.',
183
+					'event_espresso'
184
+				)
185
+			),
186
+			$input->html_id() . '-date-time-filter-notice-pg',
187
+			'date-time-filter-notice-pg small-text lt-grey-text'
188
+		);
189
+		$html .= \EEH_HTML::br();
190
+		return $html;
191
+	}
192 192
 }
Please login to merge, or discard this patch.
Spacing   +22 added lines, -22 removed lines patch added patch discarded remove patch
@@ -20,20 +20,20 @@  discard block
 block discarded – undo
20 20
     {
21 21
         wp_register_style(
22 22
             'checkbox_dropdown_selector',
23
-            EE_GLOBAL_ASSETS_URL . 'css/checkbox_dropdown_selector.css',
23
+            EE_GLOBAL_ASSETS_URL.'css/checkbox_dropdown_selector.css',
24 24
             array('espresso_default'),
25 25
             EVENT_ESPRESSO_VERSION
26 26
         );
27 27
         wp_register_style(
28 28
             'espresso_default',
29
-            EE_GLOBAL_ASSETS_URL . 'css/espresso_default.css',
29
+            EE_GLOBAL_ASSETS_URL.'css/espresso_default.css',
30 30
             array('dashicons'),
31 31
             EVENT_ESPRESSO_VERSION
32 32
         );
33 33
         wp_enqueue_style('checkbox_dropdown_selector');
34 34
         wp_register_script(
35 35
             'checkbox_dropdown_selector',
36
-            EE_GLOBAL_ASSETS_URL . 'scripts/checkbox_dropdown_selector.js',
36
+            EE_GLOBAL_ASSETS_URL.'scripts/checkbox_dropdown_selector.js',
37 37
             array('jquery'),
38 38
             EVENT_ESPRESSO_VERSION,
39 39
             true
@@ -72,7 +72,7 @@  discard block
 block discarded – undo
72 72
      */
73 73
     public function iframe_css(array $iframe_css)
74 74
     {
75
-        $iframe_css['checkbox_dropdown_selector'] = EE_GLOBAL_ASSETS_URL . 'css/checkbox_dropdown_selector.css';
75
+        $iframe_css['checkbox_dropdown_selector'] = EE_GLOBAL_ASSETS_URL.'css/checkbox_dropdown_selector.css';
76 76
         return $iframe_css;
77 77
     }
78 78
 
@@ -86,7 +86,7 @@  discard block
 block discarded – undo
86 86
      */
87 87
     public function iframe_js(array $iframe_js)
88 88
     {
89
-        $iframe_js['checkbox_dropdown_selector'] = EE_GLOBAL_ASSETS_URL . 'scripts/checkbox_dropdown_selector.js';
89
+        $iframe_js['checkbox_dropdown_selector'] = EE_GLOBAL_ASSETS_URL.'scripts/checkbox_dropdown_selector.js';
90 90
         return $iframe_js;
91 91
     }
92 92
 
@@ -102,7 +102,7 @@  discard block
 block discarded – undo
102 102
         // $multi = count( $input->options() ) > 1 ? TRUE : FALSE;
103 103
         $input->set_label_sizes();
104 104
         $label_size_class = $input->get_label_size_class();
105
-        if (! is_array($input->raw_value()) && $input->raw_value() !== null) {
105
+        if ( ! is_array($input->raw_value()) && $input->raw_value() !== null) {
106 106
             EE_Error::doing_it_wrong(
107 107
                 'EE_Checkbox_Display_Strategy::display()',
108 108
                 sprintf(
@@ -112,7 +112,7 @@  discard block
 block discarded – undo
112 112
                     ),
113 113
                     $input->html_id(),
114 114
                     var_export($input->raw_value(), true),
115
-                    $input->html_name() . '[]'
115
+                    $input->html_name().'[]'
116 116
                 ),
117 117
                 '4.8.1'
118 118
             );
@@ -120,19 +120,19 @@  discard block
 block discarded – undo
120 120
 
121 121
 
122 122
         $html = \EEH_HTML::div('', '', 'checkbox-dropdown-selector-wrap-dv');
123
-        $html .= '<button id="' . $input->html_id() . '-btn"';
123
+        $html .= '<button id="'.$input->html_id().'-btn"';
124 124
         // $html .= ' name="' . $input->html_name() . '"';
125
-        $html .= ' class="' . $input->html_class() . ' checkbox-dropdown-selector-btn button-secondary button"';
126
-        $html .= ' style="' . $input->html_style() . '"';
127
-        $html .= ' data-target="' . $input->html_id() . '-options-dv"';
128
-        $html .= ' ' . $input->other_html_attributes() . '>';
125
+        $html .= ' class="'.$input->html_class().' checkbox-dropdown-selector-btn button-secondary button"';
126
+        $html .= ' style="'.$input->html_style().'"';
127
+        $html .= ' data-target="'.$input->html_id().'-options-dv"';
128
+        $html .= ' '.$input->other_html_attributes().'>';
129 129
         $html .= '<span class="checkbox-dropdown-selector-selected-spn">';
130 130
         $html .= $select_button_text;
131 131
         $html .= '</span> <span class="dashicons dashicons-arrow-down"></span>';
132 132
         $html .= '</button>';
133 133
         $html .= EEH_HTML::div(
134 134
             '',
135
-            $input->html_id() . '-options-dv',
135
+            $input->html_id().'-options-dv',
136 136
             'checkbox-dropdown-selector'
137 137
         );
138 138
         $html .= EEH_HTML::link(
@@ -158,18 +158,18 @@  discard block
 block discarded – undo
158 158
                      . '">';
159 159
             $html .= EEH_HTML::nl(1, 'checkbox');
160 160
             $html .= '<input type="checkbox"';
161
-            $html .= ' name="' . $input->html_name() . '[]"';
162
-            $html .= ' id="' . $html_id . '"';
163
-            $html .= ' class="' . $input->html_class() . '-option"';
164
-            $html .= $input->html_style() ? ' style="' . $input->html_style() . '"' : '';
165
-            $html .= ' value="' . esc_attr($value) . '"';
161
+            $html .= ' name="'.$input->html_name().'[]"';
162
+            $html .= ' id="'.$html_id.'"';
163
+            $html .= ' class="'.$input->html_class().'-option"';
164
+            $html .= $input->html_style() ? ' style="'.$input->html_style().'"' : '';
165
+            $html .= ' value="'.esc_attr($value).'"';
166 166
             $html .= ! empty($input_raw_value) && in_array($value, $input_raw_value, true)
167 167
                 ? ' checked'
168 168
                 : '';
169
-            $html .= ' ' . $this->_input->other_html_attributes();
169
+            $html .= ' '.$this->_input->other_html_attributes();
170 170
             $html .= '>';
171
-            $html .= '<span class="datetime-selector-option-text-spn">' . $display_text . '</span>';
172
-            $html .= EEH_HTML::nl(-1, 'checkbox') . '</label>';
171
+            $html .= '<span class="datetime-selector-option-text-spn">'.$display_text.'</span>';
172
+            $html .= EEH_HTML::nl(-1, 'checkbox').'</label>';
173 173
             $html .= EEH_HTML::lix();
174 174
         }
175 175
         $html .= EEH_HTML::ulx();
@@ -183,7 +183,7 @@  discard block
 block discarded – undo
183 183
                     'event_espresso'
184 184
                 )
185 185
             ),
186
-            $input->html_id() . '-date-time-filter-notice-pg',
186
+            $input->html_id().'-date-time-filter-notice-pg',
187 187
             'date-time-filter-notice-pg small-text lt-grey-text'
188 188
         );
189 189
         $html .= \EEH_HTML::br();
Please login to merge, or discard this patch.