Completed
Branch BUG/fix-wordpress-heartbeat (c66ef1)
by
unknown
09:48 queued 34s
created
modules/thank_you_page/EED_Thank_You_Page.module.php 2 patches
Indentation   +785 added lines, -785 removed lines patch added patch discarded remove patch
@@ -10,609 +10,609 @@  discard block
 block discarded – undo
10 10
 class EED_Thank_You_Page extends EED_Module
11 11
 {
12 12
 
13
-    /**
14
-     * time in seconds to wait for the IPN to arrive before telling the registrant to bugger off ( 1200s = 20 minutes )
15
-     */
16
-    const IPN_wait_time = 1200;
17
-
18
-    /**
19
-     * The transaction specified by the reg_url_link passed from the Request, or from the Session
20
-     *
21
-     * @var EE_Transaction $_current_txn
22
-     */
23
-    private $_current_txn;
24
-
25
-    /**
26
-     * @var EE_Registration $_primary_registrant
27
-     */
28
-    private $_primary_registrant;
29
-
30
-    /**
31
-     * The reg_url_link passed from the Request, or from the Session
32
-     *
33
-     * @var string $_reg_url_link
34
-     */
35
-    private $_reg_url_link;
36
-
37
-    /**
38
-     * whether the incoming reg_url_link is for the primary registrant or not
39
-     *
40
-     * @var boolean $_is_primary
41
-     */
42
-    private $_is_primary;
43
-
44
-    /**
45
-     * The URL for revisiting the SPCO attendee information step
46
-     *
47
-     * @var string $_SPCO_attendee_information_url
48
-     */
49
-    private $_SPCO_attendee_information_url;
50
-
51
-    /**
52
-     * The URL for revisiting the SPCO payment options step
53
-     *
54
-     * @var string $_SPCO_payment_options_url
55
-     */
56
-    private $_SPCO_payment_options_url;
57
-
58
-    /**
59
-     * whether to display the Payment Options link
60
-     *
61
-     * @var boolean $_show_try_pay_again_link
62
-     */
63
-    private $_show_try_pay_again_link = false;
64
-
65
-    /**
66
-     * whether payments are allowed at this time
67
-     *
68
-     * @var boolean $_payments_closed
69
-     */
70
-    private $_payments_closed = false;
71
-
72
-    /**
73
-     * whether the selected payment method is Bank, Check , Invoice, etc
74
-     *
75
-     * @var boolean $_is_offline_payment_method
76
-     */
77
-    private $_is_offline_payment_method = true;
78
-
79
-
80
-    /**
81
-     * @return EED_Module|EED_Thank_You_Page
82
-     */
83
-    public static function instance()
84
-    {
85
-        return parent::get_instance(__CLASS__);
86
-    }
87
-
88
-
89
-    /**
90
-     * set_hooks - for hooking into EE Core, modules, etc
91
-     *
92
-     * @return void
93
-     */
94
-    public static function set_hooks()
95
-    {
96
-        add_action('wp_loaded', array('EED_Thank_You_Page', 'set_definitions'), 2);
97
-    }
98
-
99
-
100
-    /**
101
-     * set_hooks_admin - for hooking into EE Admin Core, modules, etc
102
-     *
103
-     * @return void
104
-     */
105
-    public static function set_hooks_admin()
106
-    {
107
-        add_action(
108
-            'wp_ajax_espresso_resend_reg_confirmation_email',
109
-            array('EED_Thank_You_Page', 'resend_reg_confirmation_email'),
110
-            10,
111
-            2
112
-        );
113
-        add_action(
114
-            'wp_ajax_nopriv_espresso_resend_reg_confirmation_email',
115
-            array('EED_Thank_You_Page', 'resend_reg_confirmation_email'),
116
-            10,
117
-            2
118
-        );
119
-    }
120
-
121
-
122
-    /**
123
-     * set_definitions
124
-     *
125
-     * @return void
126
-     */
127
-    public static function set_definitions()
128
-    {
129
-        define('THANK_YOU_ASSETS_URL', plugin_dir_url(__FILE__) . 'assets' . DS);
130
-        define('THANK_YOU_TEMPLATES_PATH', str_replace('\\', DS, plugin_dir_path(__FILE__)) . 'templates' . DS);
131
-    }
132
-
133
-
134
-    /**
135
-     * get_txn
136
-     *
137
-     * @return EE_Transaction
138
-     */
139
-    public function get_txn()
140
-    {
141
-        if ($this->_current_txn instanceof EE_Transaction) {
142
-            return $this->_current_txn;
143
-        }
144
-        $TXN_model = EE_Registry::instance()->load_model('Transaction');
145
-        if (! $TXN_model instanceof EEM_Transaction) {
146
-            EE_Error::add_error(
147
-                __('The transaction model could not be established.', 'event_espresso'),
148
-                __FILE__,
149
-                __FUNCTION__,
150
-                __LINE__
151
-            );
152
-            return null;
153
-        }
154
-        // get the transaction. yes, we may have just loaded it, but it may have been updated, or this may be via an ajax request
155
-        $this->_current_txn = $TXN_model->get_transaction_from_reg_url_link($this->_reg_url_link);
156
-        // verify TXN
157
-        if (WP_DEBUG && ! $this->_current_txn instanceof EE_Transaction) {
158
-            EE_Error::add_error(
159
-                __(
160
-                    'No transaction information could be retrieved or the transaction data is not of the correct type.',
161
-                    'event_espresso'
162
-                ),
163
-                __FILE__,
164
-                __FUNCTION__,
165
-                __LINE__
166
-            );
167
-            return null;
168
-        }
169
-        return $this->_current_txn;
170
-    }
171
-
172
-
173
-    /**
174
-     * get_txn_payments
175
-     *
176
-     * @param int $since
177
-     * @return mixed array of EE_Payment || FALSE
178
-     * @throws \EE_Error
179
-     */
180
-    public function get_txn_payments($since = 0)
181
-    {
182
-        if (! $this->get_txn()) {
183
-            return false;
184
-        }
185
-        $args = array('order_by' => array('PAY_timestamp' => 'ASC'));
186
-        if ($since > 0) {
187
-            $args[0] = array('PAY_timestamp' => array('>', $since));
188
-        }
189
-        // get array of payments with most recent first
190
-        return $this->_current_txn->payments($args);
191
-    }
192
-
193
-
194
-    /**
195
-     * @return bool
196
-     */
197
-    public function isOfflinePaymentMethod()
198
-    {
199
-        return $this->_is_offline_payment_method;
200
-    }
201
-
202
-
203
-
204
-
205
-    /**
206
-     * get_reg_url_link
207
-     *
208
-     * @return void
209
-     */
210
-    private function _get_reg_url_link()
211
-    {
212
-        if (! empty($this->_reg_url_link)) {
213
-            return;
214
-        }
215
-        // only do thank you page stuff if we have a REG_url_link in the url
216
-        if (WP_DEBUG && ! EE_Registry::instance()->REQ->is_set('e_reg_url_link')) {
217
-            EE_Error::add_error(
218
-                __(
219
-                    'No transaction information could be retrieved because the registration URL link is missing or invalid.',
220
-                    'event_espresso'
221
-                ),
222
-                __FILE__,
223
-                __FUNCTION__,
224
-                __LINE__
225
-            );
226
-            return;
227
-        }
228
-        // check for reg_url_link
229
-        $this->_reg_url_link = EE_Registry::instance()->REQ->get('e_reg_url_link');
230
-    }
231
-
232
-
233
-    /**
234
-     * set_reg_url_link
235
-     *
236
-     * @param string $reg_url_link
237
-     */
238
-    public function set_reg_url_link($reg_url_link = null)
239
-    {
240
-        $this->_reg_url_link = ! empty($reg_url_link) ? $reg_url_link : $this->_reg_url_link;
241
-    }
242
-
243
-
244
-    /**
245
-     * run - initial module setup
246
-     * this method is primarily used for activating resources in the EE_Front_Controller thru the use of filters
247
-     *
248
-     * @param WP $WP
249
-     * @return void
250
-     * @throws \EE_Error
251
-     */
252
-    public function run($WP)
253
-    {
254
-    }
255
-
256
-
257
-    /**
258
-     * load_resources
259
-     *
260
-     * @return void
261
-     * @throws \EE_Error
262
-     */
263
-    public function load_resources()
264
-    {
265
-        $this->_get_reg_url_link();
266
-        // resend_reg_confirmation_email ?
267
-        if (EE_Registry::instance()->REQ->is_set('resend')) {
268
-            EED_Thank_You_Page::resend_reg_confirmation_email();
269
-        }
270
-        EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
271
-        $this->_translate_strings();
272
-        // load assets
273
-        add_action('wp_enqueue_scripts', array($this, 'load_js'), 10);
274
-    }
275
-
276
-
277
-    /**
278
-     * load_js
279
-     *
280
-     * @return void
281
-     */
282
-    protected function _translate_strings()
283
-    {
284
-        EE_Registry::$i18n_js_strings['e_reg_url_link'] = $this->_reg_url_link;
285
-        EE_Registry::$i18n_js_strings['initial_access'] = time();
286
-        EE_Registry::$i18n_js_strings['IPN_wait_time'] = EED_Thank_You_Page::IPN_wait_time;
287
-        EE_Registry::$i18n_js_strings['TXN_complete'] = EEM_Transaction::complete_status_code;
288
-        EE_Registry::$i18n_js_strings['TXN_incomplete'] = EEM_Transaction::incomplete_status_code;
289
-        EE_Registry::$i18n_js_strings['checking_for_new_payments'] = __(
290
-            'checking for new payments...',
291
-            'event_espresso'
292
-        );
293
-        EE_Registry::$i18n_js_strings['loading_payment_info'] = __(
294
-            'loading payment information...',
295
-            'event_espresso'
296
-        );
297
-        EE_Registry::$i18n_js_strings['server_error'] = __(
298
-            'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again.',
299
-            'event_espresso'
300
-        );
301
-        EE_Registry::$i18n_js_strings['slow_IPN'] = apply_filters(
302
-            'EED_Thank_You_Page__load_js__slow_IPN',
303
-            sprintf(
304
-                __(
305
-                    '%sThe Payment Notification appears to be taking longer than usual to arrive. Maybe check back later or just wait for your payment and registration confirmation results to be sent to you via email. We apologize for any inconvenience this may have caused.%s',
306
-                    'event_espresso'
307
-                ),
308
-                '<div id="espresso-thank-you-page-slow-IPN-dv" class="ee-attention jst-left">',
309
-                '</div>'
310
-            )
311
-        );
312
-    }
313
-
314
-
315
-    /**
316
-     * load_js
317
-     *
318
-     * @return void
319
-     */
320
-    public function load_js()
321
-    {
322
-        wp_register_script(
323
-            'thank_you_page',
324
-            THANK_YOU_ASSETS_URL . 'thank_you_page.js',
325
-            array('espresso_core', 'heartbeat'),
326
-            EVENT_ESPRESSO_VERSION,
327
-            true
328
-        );
329
-        wp_enqueue_script('thank_you_page');
330
-        wp_enqueue_style('espresso_default');
331
-    }
332
-
333
-
334
-    /**
335
-     * init
336
-     *
337
-     * @return void
338
-     * @throws \EE_Error
339
-     */
340
-    public function init()
341
-    {
342
-        $this->_get_reg_url_link();
343
-        if (! $this->get_txn()) {
344
-            echo EEH_HTML::div(
345
-                EEH_HTML::h4(__('We\'re sorry...', 'event_espresso'), '', '') .
346
-                sprintf(
347
-                    __(
348
-                        'This is a system page for displaying transaction information after a purchase.%1$sYou are most likely seeing this notice because you have navigated to this page%1$sthrough some means other than completing a transaction.%1$sSorry for the disappointment, but you will most likely find nothing of interest here.%1$s%1$s',
349
-                        'event_espresso'
350
-                    ),
351
-                    '<br/>'
352
-                ),
353
-                '',
354
-                'ee-attention'
355
-            );
356
-            return null;
357
-        }
358
-        // if we've made it to the Thank You page, then let's toggle any "Failed" transactions to "Incomplete"
359
-        if ($this->_current_txn->status_ID() === EEM_Transaction::failed_status_code) {
360
-            $this->_current_txn->set_status(EEM_Transaction::incomplete_status_code);
361
-            $this->_current_txn->save();
362
-        }
363
-        $this->_primary_registrant = $this->_current_txn->primary_registration() instanceof EE_Registration
364
-            ? $this->_current_txn->primary_registration()
365
-            : null;
366
-        $this->_is_primary = $this->_primary_registrant->reg_url_link() === $this->_reg_url_link ? true : false;
367
-        $show_try_pay_again_link_default = apply_filters(
368
-            'AFEE__EED_Thank_You_Page__init__show_try_pay_again_link_default',
369
-            true
370
-        );
371
-        $this->_show_try_pay_again_link = $show_try_pay_again_link_default;
372
-        // txn status ?
373
-        if ($this->_current_txn->is_completed()) {
374
-            $this->_show_try_pay_again_link = $show_try_pay_again_link_default;
375
-        } elseif ($this->_current_txn->is_incomplete()
376
-            && ($this->_primary_registrant->is_approved()
377
-                || $this->_primary_registrant->is_pending_payment())
378
-        ) {
379
-            $this->_show_try_pay_again_link = true;
380
-        } elseif ($this->_primary_registrant->is_approved() || $this->_primary_registrant->is_pending_payment()) {
381
-            // its pending
382
-            $this->_show_try_pay_again_link = isset(
383
-                EE_Registry::instance()->CFG->registration->show_pending_payment_options
384
-            )
385
-                                              && EE_Registry::instance()->CFG
386
-                                                  ->registration->show_pending_payment_options
387
-                ? true
388
-                : $show_try_pay_again_link_default;
389
-        }
390
-        $this->_payments_closed = ! $this->_current_txn->payment_method() instanceof EE_Payment_Method
391
-            ? true
392
-            : false;
393
-        $this->_is_offline_payment_method = false;
394
-        if (// if payment method is unknown
395
-            ! $this->_current_txn->payment_method() instanceof EE_Payment_Method
396
-            || (
397
-                // or is an offline payment method
398
-                $this->_current_txn->payment_method() instanceof EE_Payment_Method
399
-                && $this->_current_txn->payment_method()->is_off_line()
400
-            )
401
-        ) {
402
-            $this->_is_offline_payment_method = true;
403
-        }
404
-        // link to SPCO
405
-        $revisit_spco_url = add_query_arg(
406
-            array('ee' => '_register', 'revisit' => true, 'e_reg_url_link' => $this->_reg_url_link),
407
-            EE_Registry::instance()->CFG->core->reg_page_url()
408
-        );
409
-        // link to SPCO payment_options
410
-        $this->_SPCO_payment_options_url = $this->_primary_registrant instanceof EE_Registration
411
-            ? $this->_primary_registrant->payment_overview_url()
412
-            : add_query_arg(
413
-                array('step' => 'payment_options'),
414
-                $revisit_spco_url
415
-            );
416
-        // link to SPCO attendee_information
417
-        $this->_SPCO_attendee_information_url = $this->_primary_registrant instanceof EE_Registration
418
-            ? $this->_primary_registrant->edit_attendee_information_url()
419
-            : false;
420
-        do_action('AHEE__EED_Thank_You_Page__init_end', $this->_current_txn);
421
-        // set no cache headers and constants
422
-        EE_System::do_not_cache();
423
-    }
424
-
425
-
426
-    /**
427
-     * display_thank_you_page_results
428
-     *
429
-     * @return string
430
-     * @throws \EE_Error
431
-     */
432
-    public function thank_you_page_results()
433
-    {
434
-        $this->init();
435
-        if (! $this->_current_txn instanceof EE_Transaction) {
436
-            return EE_Error::get_notices();
437
-        }
438
-        // link to receipt
439
-        $template_args['TXN_receipt_url'] = $this->_current_txn->receipt_url('html');
440
-        if (! empty($template_args['TXN_receipt_url'])) {
441
-            $template_args['order_conf_desc'] = __(
442
-                '%1$sCongratulations%2$sYour registration has been successfully processed.%3$sCheck your email for your registration confirmation or click the button below to view / download / print a full description of your purchases and registration information.',
443
-                'event_espresso'
444
-            );
445
-        } else {
446
-            $template_args['order_conf_desc'] = __(
447
-                '%1$sCongratulations%2$sYour registration has been successfully processed.%3$sCheck your email for your registration confirmation.',
448
-                'event_espresso'
449
-            );
450
-        }
451
-        $template_args['transaction'] = $this->_current_txn;
452
-        $template_args['revisit'] = EE_Registry::instance()->REQ->get('revisit', false);
453
-        add_action('AHEE__thank_you_page_overview_template__content', array($this, 'get_registration_details'));
454
-        if ($this->_is_primary && ! $this->_current_txn->is_free()) {
455
-            add_action('AHEE__thank_you_page_overview_template__content', array($this, 'get_ajax_content'));
456
-        }
457
-        return EEH_Template::locate_template(
458
-            THANK_YOU_TEMPLATES_PATH . 'thank-you-page-overview.template.php',
459
-            $template_args,
460
-            true,
461
-            true
462
-        );
463
-    }
464
-
465
-
466
-
467
-    /**
468
-     * _update_server_wait_time
469
-     *
470
-     * @param array $thank_you_page_data thank you page portion of the incoming JSON array from the WP heartbeat data
471
-     * @return array
472
-     * @throws \EE_Error
473
-     */
474
-    private function _update_server_wait_time($thank_you_page_data = array())
475
-    {
476
-        $response['espresso_thank_you_page'] = array(
477
-            'still_waiting' => isset($thank_you_page_data['initial_access'])
478
-                ? time() - $thank_you_page_data['initial_access']
479
-                : 0,
480
-            'txn_status'    => $this->_current_txn->status_ID(),
481
-        );
482
-        return $response;
483
-    }
484
-
485
-
486
-    /**
487
-     * get_registration_details
488
-     *
489
-     * @throws \EE_Error
490
-     */
491
-    public function get_registration_details()
492
-    {
493
-        // prepare variables for displaying
494
-        $template_args = array();
495
-        $template_args['transaction'] = $this->_current_txn;
496
-        $template_args['reg_url_link'] = $this->_reg_url_link;
497
-        $template_args['is_primary'] = $this->_is_primary;
498
-        $template_args['SPCO_attendee_information_url'] = $this->_SPCO_attendee_information_url;
499
-        $template_args['resend_reg_confirmation_url'] = add_query_arg(
500
-            array('token' => $this->_reg_url_link, 'resend_reg_confirmation' => 'true'),
501
-            EE_Registry::instance()->CFG->core->thank_you_page_url()
502
-        );
503
-        // verify template arguments
504
-        EEH_Template_Validator::verify_instanceof($template_args['transaction'], '$transaction', 'EE_Transaction');
505
-        EEH_Template_Validator::verify_isnt_null(
506
-            $template_args['SPCO_attendee_information_url'],
507
-            '$SPCO_attendee_information_url'
508
-        );
509
-        echo EEH_Template::locate_template(
510
-            THANK_YOU_TEMPLATES_PATH . 'thank-you-page-registration-details.template.php',
511
-            $template_args,
512
-            true,
513
-            true
514
-        );
515
-    }
516
-
517
-
518
-    /**
519
-     * resend_reg_confirmation_email
520
-     *
521
-     * @throws \EE_Error
522
-     */
523
-    public static function resend_reg_confirmation_email()
524
-    {
525
-        EE_Registry::instance()->load_core('Request_Handler');
526
-        $reg_url_link = EE_Registry::instance()->REQ->get('token');
527
-        // was a REG_ID passed ?
528
-        if ($reg_url_link) {
529
-            $registration = EE_Registry::instance()->load_model('Registration')->get_one(
530
-                array(array('REG_url_link' => $reg_url_link))
531
-            );
532
-            if ($registration instanceof EE_Registration) {
533
-                // resend email
534
-                EED_Messages::process_resend(array('_REG_ID' => $registration->ID()));
535
-            } else {
536
-                EE_Error::add_error(
537
-                    __(
538
-                        'The Registration Confirmation email could not be sent because a valid Registration could not be retrieved from the database.',
539
-                        'event_espresso'
540
-                    ),
541
-                    __FILE__,
542
-                    __FUNCTION__,
543
-                    __LINE__
544
-                );
545
-            }
546
-        } else {
547
-            EE_Error::add_error(
548
-                __(
549
-                    'The Registration Confirmation email could not be sent because a registration token is missing or invalid.',
550
-                    'event_espresso'
551
-                ),
552
-                __FILE__,
553
-                __FUNCTION__,
554
-                __LINE__
555
-            );
556
-        }
557
-        // request sent via AJAX ?
558
-        if (EE_FRONT_AJAX) {
559
-            echo wp_json_encode(EE_Error::get_notices(false));
560
-            die();
561
-            // or was JS disabled ?
562
-        } else {
563
-            // save errors so that they get picked up on the next request
564
-            EE_Error::get_notices(true, true);
565
-            wp_safe_redirect(
566
-                add_query_arg(
567
-                    array('e_reg_url_link' => $reg_url_link),
568
-                    EE_Registry::instance()->CFG->core->thank_you_page_url()
569
-                )
570
-            );
571
-        }
572
-    }
573
-
574
-
575
-    /**
576
-     * get_ajax_content
577
-     *
578
-     * @return void
579
-     * @throws \EE_Error
580
-     */
581
-    public function get_ajax_content()
582
-    {
583
-        if (! $this->get_txn()) {
584
-            return;
585
-        }
586
-        // first determine which event(s) require pre-approval or not
587
-        $events = array();
588
-        $events_requiring_pre_approval = array();
589
-        foreach ($this->_current_txn->registrations() as $registration) {
590
-            if ($registration instanceof EE_Registration) {
591
-                $event = $registration->event();
592
-                if ($event instanceof EE_Event) {
593
-                    if ($registration->is_not_approved() && $registration->event() instanceof EE_Event) {
594
-                        $events_requiring_pre_approval[ $event->ID() ] = $event;
595
-                    } else {
596
-                        $events[ $event->ID() ] = $event;
597
-                    }
598
-                }
599
-            }
600
-        }
601
-        $this->display_details_for_events_requiring_pre_approval($events_requiring_pre_approval);
602
-        $this->display_details_for_events($events);
603
-    }
604
-
605
-
606
-    /**
607
-     * display_details_for_events
608
-     *
609
-     * @param EE_Event[] $events
610
-     * @return void
611
-     */
612
-    public function display_details_for_events($events = array())
613
-    {
614
-        if (! empty($events)) {
615
-            ?>
13
+	/**
14
+	 * time in seconds to wait for the IPN to arrive before telling the registrant to bugger off ( 1200s = 20 minutes )
15
+	 */
16
+	const IPN_wait_time = 1200;
17
+
18
+	/**
19
+	 * The transaction specified by the reg_url_link passed from the Request, or from the Session
20
+	 *
21
+	 * @var EE_Transaction $_current_txn
22
+	 */
23
+	private $_current_txn;
24
+
25
+	/**
26
+	 * @var EE_Registration $_primary_registrant
27
+	 */
28
+	private $_primary_registrant;
29
+
30
+	/**
31
+	 * The reg_url_link passed from the Request, or from the Session
32
+	 *
33
+	 * @var string $_reg_url_link
34
+	 */
35
+	private $_reg_url_link;
36
+
37
+	/**
38
+	 * whether the incoming reg_url_link is for the primary registrant or not
39
+	 *
40
+	 * @var boolean $_is_primary
41
+	 */
42
+	private $_is_primary;
43
+
44
+	/**
45
+	 * The URL for revisiting the SPCO attendee information step
46
+	 *
47
+	 * @var string $_SPCO_attendee_information_url
48
+	 */
49
+	private $_SPCO_attendee_information_url;
50
+
51
+	/**
52
+	 * The URL for revisiting the SPCO payment options step
53
+	 *
54
+	 * @var string $_SPCO_payment_options_url
55
+	 */
56
+	private $_SPCO_payment_options_url;
57
+
58
+	/**
59
+	 * whether to display the Payment Options link
60
+	 *
61
+	 * @var boolean $_show_try_pay_again_link
62
+	 */
63
+	private $_show_try_pay_again_link = false;
64
+
65
+	/**
66
+	 * whether payments are allowed at this time
67
+	 *
68
+	 * @var boolean $_payments_closed
69
+	 */
70
+	private $_payments_closed = false;
71
+
72
+	/**
73
+	 * whether the selected payment method is Bank, Check , Invoice, etc
74
+	 *
75
+	 * @var boolean $_is_offline_payment_method
76
+	 */
77
+	private $_is_offline_payment_method = true;
78
+
79
+
80
+	/**
81
+	 * @return EED_Module|EED_Thank_You_Page
82
+	 */
83
+	public static function instance()
84
+	{
85
+		return parent::get_instance(__CLASS__);
86
+	}
87
+
88
+
89
+	/**
90
+	 * set_hooks - for hooking into EE Core, modules, etc
91
+	 *
92
+	 * @return void
93
+	 */
94
+	public static function set_hooks()
95
+	{
96
+		add_action('wp_loaded', array('EED_Thank_You_Page', 'set_definitions'), 2);
97
+	}
98
+
99
+
100
+	/**
101
+	 * set_hooks_admin - for hooking into EE Admin Core, modules, etc
102
+	 *
103
+	 * @return void
104
+	 */
105
+	public static function set_hooks_admin()
106
+	{
107
+		add_action(
108
+			'wp_ajax_espresso_resend_reg_confirmation_email',
109
+			array('EED_Thank_You_Page', 'resend_reg_confirmation_email'),
110
+			10,
111
+			2
112
+		);
113
+		add_action(
114
+			'wp_ajax_nopriv_espresso_resend_reg_confirmation_email',
115
+			array('EED_Thank_You_Page', 'resend_reg_confirmation_email'),
116
+			10,
117
+			2
118
+		);
119
+	}
120
+
121
+
122
+	/**
123
+	 * set_definitions
124
+	 *
125
+	 * @return void
126
+	 */
127
+	public static function set_definitions()
128
+	{
129
+		define('THANK_YOU_ASSETS_URL', plugin_dir_url(__FILE__) . 'assets' . DS);
130
+		define('THANK_YOU_TEMPLATES_PATH', str_replace('\\', DS, plugin_dir_path(__FILE__)) . 'templates' . DS);
131
+	}
132
+
133
+
134
+	/**
135
+	 * get_txn
136
+	 *
137
+	 * @return EE_Transaction
138
+	 */
139
+	public function get_txn()
140
+	{
141
+		if ($this->_current_txn instanceof EE_Transaction) {
142
+			return $this->_current_txn;
143
+		}
144
+		$TXN_model = EE_Registry::instance()->load_model('Transaction');
145
+		if (! $TXN_model instanceof EEM_Transaction) {
146
+			EE_Error::add_error(
147
+				__('The transaction model could not be established.', 'event_espresso'),
148
+				__FILE__,
149
+				__FUNCTION__,
150
+				__LINE__
151
+			);
152
+			return null;
153
+		}
154
+		// get the transaction. yes, we may have just loaded it, but it may have been updated, or this may be via an ajax request
155
+		$this->_current_txn = $TXN_model->get_transaction_from_reg_url_link($this->_reg_url_link);
156
+		// verify TXN
157
+		if (WP_DEBUG && ! $this->_current_txn instanceof EE_Transaction) {
158
+			EE_Error::add_error(
159
+				__(
160
+					'No transaction information could be retrieved or the transaction data is not of the correct type.',
161
+					'event_espresso'
162
+				),
163
+				__FILE__,
164
+				__FUNCTION__,
165
+				__LINE__
166
+			);
167
+			return null;
168
+		}
169
+		return $this->_current_txn;
170
+	}
171
+
172
+
173
+	/**
174
+	 * get_txn_payments
175
+	 *
176
+	 * @param int $since
177
+	 * @return mixed array of EE_Payment || FALSE
178
+	 * @throws \EE_Error
179
+	 */
180
+	public function get_txn_payments($since = 0)
181
+	{
182
+		if (! $this->get_txn()) {
183
+			return false;
184
+		}
185
+		$args = array('order_by' => array('PAY_timestamp' => 'ASC'));
186
+		if ($since > 0) {
187
+			$args[0] = array('PAY_timestamp' => array('>', $since));
188
+		}
189
+		// get array of payments with most recent first
190
+		return $this->_current_txn->payments($args);
191
+	}
192
+
193
+
194
+	/**
195
+	 * @return bool
196
+	 */
197
+	public function isOfflinePaymentMethod()
198
+	{
199
+		return $this->_is_offline_payment_method;
200
+	}
201
+
202
+
203
+
204
+
205
+	/**
206
+	 * get_reg_url_link
207
+	 *
208
+	 * @return void
209
+	 */
210
+	private function _get_reg_url_link()
211
+	{
212
+		if (! empty($this->_reg_url_link)) {
213
+			return;
214
+		}
215
+		// only do thank you page stuff if we have a REG_url_link in the url
216
+		if (WP_DEBUG && ! EE_Registry::instance()->REQ->is_set('e_reg_url_link')) {
217
+			EE_Error::add_error(
218
+				__(
219
+					'No transaction information could be retrieved because the registration URL link is missing or invalid.',
220
+					'event_espresso'
221
+				),
222
+				__FILE__,
223
+				__FUNCTION__,
224
+				__LINE__
225
+			);
226
+			return;
227
+		}
228
+		// check for reg_url_link
229
+		$this->_reg_url_link = EE_Registry::instance()->REQ->get('e_reg_url_link');
230
+	}
231
+
232
+
233
+	/**
234
+	 * set_reg_url_link
235
+	 *
236
+	 * @param string $reg_url_link
237
+	 */
238
+	public function set_reg_url_link($reg_url_link = null)
239
+	{
240
+		$this->_reg_url_link = ! empty($reg_url_link) ? $reg_url_link : $this->_reg_url_link;
241
+	}
242
+
243
+
244
+	/**
245
+	 * run - initial module setup
246
+	 * this method is primarily used for activating resources in the EE_Front_Controller thru the use of filters
247
+	 *
248
+	 * @param WP $WP
249
+	 * @return void
250
+	 * @throws \EE_Error
251
+	 */
252
+	public function run($WP)
253
+	{
254
+	}
255
+
256
+
257
+	/**
258
+	 * load_resources
259
+	 *
260
+	 * @return void
261
+	 * @throws \EE_Error
262
+	 */
263
+	public function load_resources()
264
+	{
265
+		$this->_get_reg_url_link();
266
+		// resend_reg_confirmation_email ?
267
+		if (EE_Registry::instance()->REQ->is_set('resend')) {
268
+			EED_Thank_You_Page::resend_reg_confirmation_email();
269
+		}
270
+		EE_Registry::instance()->SSN->clear_session(__CLASS__, __FUNCTION__);
271
+		$this->_translate_strings();
272
+		// load assets
273
+		add_action('wp_enqueue_scripts', array($this, 'load_js'), 10);
274
+	}
275
+
276
+
277
+	/**
278
+	 * load_js
279
+	 *
280
+	 * @return void
281
+	 */
282
+	protected function _translate_strings()
283
+	{
284
+		EE_Registry::$i18n_js_strings['e_reg_url_link'] = $this->_reg_url_link;
285
+		EE_Registry::$i18n_js_strings['initial_access'] = time();
286
+		EE_Registry::$i18n_js_strings['IPN_wait_time'] = EED_Thank_You_Page::IPN_wait_time;
287
+		EE_Registry::$i18n_js_strings['TXN_complete'] = EEM_Transaction::complete_status_code;
288
+		EE_Registry::$i18n_js_strings['TXN_incomplete'] = EEM_Transaction::incomplete_status_code;
289
+		EE_Registry::$i18n_js_strings['checking_for_new_payments'] = __(
290
+			'checking for new payments...',
291
+			'event_espresso'
292
+		);
293
+		EE_Registry::$i18n_js_strings['loading_payment_info'] = __(
294
+			'loading payment information...',
295
+			'event_espresso'
296
+		);
297
+		EE_Registry::$i18n_js_strings['server_error'] = __(
298
+			'An unknown error occurred on the server while attempting to process your request. Please refresh the page and try again.',
299
+			'event_espresso'
300
+		);
301
+		EE_Registry::$i18n_js_strings['slow_IPN'] = apply_filters(
302
+			'EED_Thank_You_Page__load_js__slow_IPN',
303
+			sprintf(
304
+				__(
305
+					'%sThe Payment Notification appears to be taking longer than usual to arrive. Maybe check back later or just wait for your payment and registration confirmation results to be sent to you via email. We apologize for any inconvenience this may have caused.%s',
306
+					'event_espresso'
307
+				),
308
+				'<div id="espresso-thank-you-page-slow-IPN-dv" class="ee-attention jst-left">',
309
+				'</div>'
310
+			)
311
+		);
312
+	}
313
+
314
+
315
+	/**
316
+	 * load_js
317
+	 *
318
+	 * @return void
319
+	 */
320
+	public function load_js()
321
+	{
322
+		wp_register_script(
323
+			'thank_you_page',
324
+			THANK_YOU_ASSETS_URL . 'thank_you_page.js',
325
+			array('espresso_core', 'heartbeat'),
326
+			EVENT_ESPRESSO_VERSION,
327
+			true
328
+		);
329
+		wp_enqueue_script('thank_you_page');
330
+		wp_enqueue_style('espresso_default');
331
+	}
332
+
333
+
334
+	/**
335
+	 * init
336
+	 *
337
+	 * @return void
338
+	 * @throws \EE_Error
339
+	 */
340
+	public function init()
341
+	{
342
+		$this->_get_reg_url_link();
343
+		if (! $this->get_txn()) {
344
+			echo EEH_HTML::div(
345
+				EEH_HTML::h4(__('We\'re sorry...', 'event_espresso'), '', '') .
346
+				sprintf(
347
+					__(
348
+						'This is a system page for displaying transaction information after a purchase.%1$sYou are most likely seeing this notice because you have navigated to this page%1$sthrough some means other than completing a transaction.%1$sSorry for the disappointment, but you will most likely find nothing of interest here.%1$s%1$s',
349
+						'event_espresso'
350
+					),
351
+					'<br/>'
352
+				),
353
+				'',
354
+				'ee-attention'
355
+			);
356
+			return null;
357
+		}
358
+		// if we've made it to the Thank You page, then let's toggle any "Failed" transactions to "Incomplete"
359
+		if ($this->_current_txn->status_ID() === EEM_Transaction::failed_status_code) {
360
+			$this->_current_txn->set_status(EEM_Transaction::incomplete_status_code);
361
+			$this->_current_txn->save();
362
+		}
363
+		$this->_primary_registrant = $this->_current_txn->primary_registration() instanceof EE_Registration
364
+			? $this->_current_txn->primary_registration()
365
+			: null;
366
+		$this->_is_primary = $this->_primary_registrant->reg_url_link() === $this->_reg_url_link ? true : false;
367
+		$show_try_pay_again_link_default = apply_filters(
368
+			'AFEE__EED_Thank_You_Page__init__show_try_pay_again_link_default',
369
+			true
370
+		);
371
+		$this->_show_try_pay_again_link = $show_try_pay_again_link_default;
372
+		// txn status ?
373
+		if ($this->_current_txn->is_completed()) {
374
+			$this->_show_try_pay_again_link = $show_try_pay_again_link_default;
375
+		} elseif ($this->_current_txn->is_incomplete()
376
+			&& ($this->_primary_registrant->is_approved()
377
+				|| $this->_primary_registrant->is_pending_payment())
378
+		) {
379
+			$this->_show_try_pay_again_link = true;
380
+		} elseif ($this->_primary_registrant->is_approved() || $this->_primary_registrant->is_pending_payment()) {
381
+			// its pending
382
+			$this->_show_try_pay_again_link = isset(
383
+				EE_Registry::instance()->CFG->registration->show_pending_payment_options
384
+			)
385
+											  && EE_Registry::instance()->CFG
386
+												  ->registration->show_pending_payment_options
387
+				? true
388
+				: $show_try_pay_again_link_default;
389
+		}
390
+		$this->_payments_closed = ! $this->_current_txn->payment_method() instanceof EE_Payment_Method
391
+			? true
392
+			: false;
393
+		$this->_is_offline_payment_method = false;
394
+		if (// if payment method is unknown
395
+			! $this->_current_txn->payment_method() instanceof EE_Payment_Method
396
+			|| (
397
+				// or is an offline payment method
398
+				$this->_current_txn->payment_method() instanceof EE_Payment_Method
399
+				&& $this->_current_txn->payment_method()->is_off_line()
400
+			)
401
+		) {
402
+			$this->_is_offline_payment_method = true;
403
+		}
404
+		// link to SPCO
405
+		$revisit_spco_url = add_query_arg(
406
+			array('ee' => '_register', 'revisit' => true, 'e_reg_url_link' => $this->_reg_url_link),
407
+			EE_Registry::instance()->CFG->core->reg_page_url()
408
+		);
409
+		// link to SPCO payment_options
410
+		$this->_SPCO_payment_options_url = $this->_primary_registrant instanceof EE_Registration
411
+			? $this->_primary_registrant->payment_overview_url()
412
+			: add_query_arg(
413
+				array('step' => 'payment_options'),
414
+				$revisit_spco_url
415
+			);
416
+		// link to SPCO attendee_information
417
+		$this->_SPCO_attendee_information_url = $this->_primary_registrant instanceof EE_Registration
418
+			? $this->_primary_registrant->edit_attendee_information_url()
419
+			: false;
420
+		do_action('AHEE__EED_Thank_You_Page__init_end', $this->_current_txn);
421
+		// set no cache headers and constants
422
+		EE_System::do_not_cache();
423
+	}
424
+
425
+
426
+	/**
427
+	 * display_thank_you_page_results
428
+	 *
429
+	 * @return string
430
+	 * @throws \EE_Error
431
+	 */
432
+	public function thank_you_page_results()
433
+	{
434
+		$this->init();
435
+		if (! $this->_current_txn instanceof EE_Transaction) {
436
+			return EE_Error::get_notices();
437
+		}
438
+		// link to receipt
439
+		$template_args['TXN_receipt_url'] = $this->_current_txn->receipt_url('html');
440
+		if (! empty($template_args['TXN_receipt_url'])) {
441
+			$template_args['order_conf_desc'] = __(
442
+				'%1$sCongratulations%2$sYour registration has been successfully processed.%3$sCheck your email for your registration confirmation or click the button below to view / download / print a full description of your purchases and registration information.',
443
+				'event_espresso'
444
+			);
445
+		} else {
446
+			$template_args['order_conf_desc'] = __(
447
+				'%1$sCongratulations%2$sYour registration has been successfully processed.%3$sCheck your email for your registration confirmation.',
448
+				'event_espresso'
449
+			);
450
+		}
451
+		$template_args['transaction'] = $this->_current_txn;
452
+		$template_args['revisit'] = EE_Registry::instance()->REQ->get('revisit', false);
453
+		add_action('AHEE__thank_you_page_overview_template__content', array($this, 'get_registration_details'));
454
+		if ($this->_is_primary && ! $this->_current_txn->is_free()) {
455
+			add_action('AHEE__thank_you_page_overview_template__content', array($this, 'get_ajax_content'));
456
+		}
457
+		return EEH_Template::locate_template(
458
+			THANK_YOU_TEMPLATES_PATH . 'thank-you-page-overview.template.php',
459
+			$template_args,
460
+			true,
461
+			true
462
+		);
463
+	}
464
+
465
+
466
+
467
+	/**
468
+	 * _update_server_wait_time
469
+	 *
470
+	 * @param array $thank_you_page_data thank you page portion of the incoming JSON array from the WP heartbeat data
471
+	 * @return array
472
+	 * @throws \EE_Error
473
+	 */
474
+	private function _update_server_wait_time($thank_you_page_data = array())
475
+	{
476
+		$response['espresso_thank_you_page'] = array(
477
+			'still_waiting' => isset($thank_you_page_data['initial_access'])
478
+				? time() - $thank_you_page_data['initial_access']
479
+				: 0,
480
+			'txn_status'    => $this->_current_txn->status_ID(),
481
+		);
482
+		return $response;
483
+	}
484
+
485
+
486
+	/**
487
+	 * get_registration_details
488
+	 *
489
+	 * @throws \EE_Error
490
+	 */
491
+	public function get_registration_details()
492
+	{
493
+		// prepare variables for displaying
494
+		$template_args = array();
495
+		$template_args['transaction'] = $this->_current_txn;
496
+		$template_args['reg_url_link'] = $this->_reg_url_link;
497
+		$template_args['is_primary'] = $this->_is_primary;
498
+		$template_args['SPCO_attendee_information_url'] = $this->_SPCO_attendee_information_url;
499
+		$template_args['resend_reg_confirmation_url'] = add_query_arg(
500
+			array('token' => $this->_reg_url_link, 'resend_reg_confirmation' => 'true'),
501
+			EE_Registry::instance()->CFG->core->thank_you_page_url()
502
+		);
503
+		// verify template arguments
504
+		EEH_Template_Validator::verify_instanceof($template_args['transaction'], '$transaction', 'EE_Transaction');
505
+		EEH_Template_Validator::verify_isnt_null(
506
+			$template_args['SPCO_attendee_information_url'],
507
+			'$SPCO_attendee_information_url'
508
+		);
509
+		echo EEH_Template::locate_template(
510
+			THANK_YOU_TEMPLATES_PATH . 'thank-you-page-registration-details.template.php',
511
+			$template_args,
512
+			true,
513
+			true
514
+		);
515
+	}
516
+
517
+
518
+	/**
519
+	 * resend_reg_confirmation_email
520
+	 *
521
+	 * @throws \EE_Error
522
+	 */
523
+	public static function resend_reg_confirmation_email()
524
+	{
525
+		EE_Registry::instance()->load_core('Request_Handler');
526
+		$reg_url_link = EE_Registry::instance()->REQ->get('token');
527
+		// was a REG_ID passed ?
528
+		if ($reg_url_link) {
529
+			$registration = EE_Registry::instance()->load_model('Registration')->get_one(
530
+				array(array('REG_url_link' => $reg_url_link))
531
+			);
532
+			if ($registration instanceof EE_Registration) {
533
+				// resend email
534
+				EED_Messages::process_resend(array('_REG_ID' => $registration->ID()));
535
+			} else {
536
+				EE_Error::add_error(
537
+					__(
538
+						'The Registration Confirmation email could not be sent because a valid Registration could not be retrieved from the database.',
539
+						'event_espresso'
540
+					),
541
+					__FILE__,
542
+					__FUNCTION__,
543
+					__LINE__
544
+				);
545
+			}
546
+		} else {
547
+			EE_Error::add_error(
548
+				__(
549
+					'The Registration Confirmation email could not be sent because a registration token is missing or invalid.',
550
+					'event_espresso'
551
+				),
552
+				__FILE__,
553
+				__FUNCTION__,
554
+				__LINE__
555
+			);
556
+		}
557
+		// request sent via AJAX ?
558
+		if (EE_FRONT_AJAX) {
559
+			echo wp_json_encode(EE_Error::get_notices(false));
560
+			die();
561
+			// or was JS disabled ?
562
+		} else {
563
+			// save errors so that they get picked up on the next request
564
+			EE_Error::get_notices(true, true);
565
+			wp_safe_redirect(
566
+				add_query_arg(
567
+					array('e_reg_url_link' => $reg_url_link),
568
+					EE_Registry::instance()->CFG->core->thank_you_page_url()
569
+				)
570
+			);
571
+		}
572
+	}
573
+
574
+
575
+	/**
576
+	 * get_ajax_content
577
+	 *
578
+	 * @return void
579
+	 * @throws \EE_Error
580
+	 */
581
+	public function get_ajax_content()
582
+	{
583
+		if (! $this->get_txn()) {
584
+			return;
585
+		}
586
+		// first determine which event(s) require pre-approval or not
587
+		$events = array();
588
+		$events_requiring_pre_approval = array();
589
+		foreach ($this->_current_txn->registrations() as $registration) {
590
+			if ($registration instanceof EE_Registration) {
591
+				$event = $registration->event();
592
+				if ($event instanceof EE_Event) {
593
+					if ($registration->is_not_approved() && $registration->event() instanceof EE_Event) {
594
+						$events_requiring_pre_approval[ $event->ID() ] = $event;
595
+					} else {
596
+						$events[ $event->ID() ] = $event;
597
+					}
598
+				}
599
+			}
600
+		}
601
+		$this->display_details_for_events_requiring_pre_approval($events_requiring_pre_approval);
602
+		$this->display_details_for_events($events);
603
+	}
604
+
605
+
606
+	/**
607
+	 * display_details_for_events
608
+	 *
609
+	 * @param EE_Event[] $events
610
+	 * @return void
611
+	 */
612
+	public function display_details_for_events($events = array())
613
+	{
614
+		if (! empty($events)) {
615
+			?>
616 616
             <div id="espresso-thank-you-page-ajax-content-dv">
617 617
                 <div id="espresso-thank-you-page-ajax-transaction-dv"></div>
618 618
                 <div id="espresso-thank-you-page-ajax-payment-dv"></div>
@@ -620,19 +620,19 @@  discard block
 block discarded – undo
620 620
                     <div id="ee-ajax-loading-dv" class="float-left lt-blue-text">
621 621
                         <span class="dashicons dashicons-upload"></span><span id="ee-ajax-loading-msg-spn">
622 622
                             <?php _e(
623
-                                'loading transaction and payment information...',
624
-                                'event_espresso'
625
-                            ); ?></span>
623
+								'loading transaction and payment information...',
624
+								'event_espresso'
625
+							); ?></span>
626 626
                     </div>
627 627
                     <?php if (! $this->_is_offline_payment_method && ! $this->_payments_closed) : ?>
628 628
                         <p id="ee-ajax-loading-pg" class="highlight-bg small-text clear">
629 629
                             <?php echo apply_filters(
630
-                                'EED_Thank_You_Page__get_ajax_content__waiting_for_IPN_msg',
631
-                                __(
632
-                                    'Some payment gateways can take 15 minutes or more to return their payment notification, so please be patient if you require payment confirmation as soon as possible. Please note that as soon as everything is finalized, we will send your full payment and registration confirmation results to you via email.',
633
-                                    'event_espresso'
634
-                                )
635
-                            ); ?>
630
+								'EED_Thank_You_Page__get_ajax_content__waiting_for_IPN_msg',
631
+								__(
632
+									'Some payment gateways can take 15 minutes or more to return their payment notification, so please be patient if you require payment confirmation as soon as possible. Please note that as soon as everything is finalized, we will send your full payment and registration confirmation results to you via email.',
633
+									'event_espresso'
634
+								)
635
+							); ?>
636 636
                             <br/>
637 637
                             <span class="jst-rght ee-block small-text lt-grey-text">
638 638
                                 <?php _e('current wait time ', 'event_espresso'); ?>
@@ -643,117 +643,117 @@  discard block
 block discarded – undo
643 643
                 <div class="clear"></div>
644 644
             </div>
645 645
             <?php
646
-        }
647
-    }
648
-
649
-
650
-    /**
651
-     * display_details_for_events_requiring_pre_approval
652
-     *
653
-     * @param EE_Event[] $events
654
-     * @return void
655
-     */
656
-    public function display_details_for_events_requiring_pre_approval($events = array())
657
-    {
658
-        if (! empty($events)) {
659
-            ?>
646
+		}
647
+	}
648
+
649
+
650
+	/**
651
+	 * display_details_for_events_requiring_pre_approval
652
+	 *
653
+	 * @param EE_Event[] $events
654
+	 * @return void
655
+	 */
656
+	public function display_details_for_events_requiring_pre_approval($events = array())
657
+	{
658
+		if (! empty($events)) {
659
+			?>
660 660
             <div id="espresso-thank-you-page-not-approved-message-dv">
661 661
                 <h4 class="orange-text"><?php _e('Important Notice:', 'event_espresso'); ?></h4>
662 662
                 <p id="events-requiring-pre-approval-pg" class="small-text">
663 663
                     <?php echo apply_filters(
664
-                        'AHEE__EED_Thank_You_Page__get_ajax_content__not_approved_message',
665
-                        __(
666
-                            'The following Event(s) you have registered for do not require payment at this time and will not be billed for during this transaction. Billing will only occur after all attendees have been approved by the event organizer. You will be notified when your registration has been processed. If this is a free event, then no billing will occur.',
667
-                            'event_espresso'
668
-                        )
669
-                    ); ?>
664
+						'AHEE__EED_Thank_You_Page__get_ajax_content__not_approved_message',
665
+						__(
666
+							'The following Event(s) you have registered for do not require payment at this time and will not be billed for during this transaction. Billing will only occur after all attendees have been approved by the event organizer. You will be notified when your registration has been processed. If this is a free event, then no billing will occur.',
667
+							'event_espresso'
668
+						)
669
+					); ?>
670 670
                 </p>
671 671
                 <ul class="events-requiring-pre-approval-ul">
672 672
                     <?php
673
-                    foreach ($events as $event) {
674
-                        if ($event instanceof EE_Event) {
675
-                            echo '<li><span class="dashicons dashicons-marker ee-icon-size-16 orange-text"></span>',
676
-                            $event->name(),
677
-                            '</li>';
678
-                        }
679
-                    } ?>
673
+					foreach ($events as $event) {
674
+						if ($event instanceof EE_Event) {
675
+							echo '<li><span class="dashicons dashicons-marker ee-icon-size-16 orange-text"></span>',
676
+							$event->name(),
677
+							'</li>';
678
+						}
679
+					} ?>
680 680
                 </ul>
681 681
                 <div class="clear"></div>
682 682
             </div>
683 683
             <?php
684
-        }
685
-    }
686
-
687
-
688
-    /**
689
-     * get_transaction_details
690
-     *
691
-     * @return string
692
-     * @throws \EE_Error
693
-     */
694
-    public function get_transaction_details()
695
-    {
696
-        // prepare variables for displaying
697
-        $template_args = array();
698
-        $template_args['transaction'] = $this->_current_txn;
699
-        $template_args['reg_url_link'] = $this->_reg_url_link;
700
-        $template_args['primary_registrant_name'] = $this->_primary_registrant->attendee()->full_name(true);
701
-        // link to SPCO payment_options
702
-        $template_args['show_try_pay_again_link'] = $this->_show_try_pay_again_link;
703
-        $template_args['SPCO_payment_options_url'] = $this->_SPCO_payment_options_url;
704
-        // verify template arguments
705
-        EEH_Template_Validator::verify_instanceof($template_args['transaction'], '$transaction', 'EE_Transaction');
706
-        EEH_Template_Validator::verify_isnt_null(
707
-            $template_args['show_try_pay_again_link'],
708
-            '$show_try_pay_again_link'
709
-        );
710
-        EEH_Template_Validator::verify_isnt_null(
711
-            $template_args['SPCO_payment_options_url'],
712
-            '$SPCO_payment_options_url'
713
-        );
714
-        return EEH_Template::locate_template(
715
-            THANK_YOU_TEMPLATES_PATH . 'thank-you-page-transaction-details.template.php',
716
-            $template_args,
717
-            true,
718
-            true
719
-        );
720
-    }
721
-
722
-
723
-    /**
724
-     * get_payment_row_html
725
-     *
726
-     * @param EE_Payment $payment
727
-     * @return string
728
-     * @throws \EE_Error
729
-     */
730
-    public function get_payment_row_html($payment = null)
731
-    {
732
-        $html = '';
733
-        if ($payment instanceof EE_Payment) {
734
-            if ($payment->payment_method() instanceof EE_Payment_Method
735
-                && $payment->status() === EEM_Payment::status_id_failed
736
-                && $payment->payment_method()->is_off_site()
737
-            ) {
738
-                // considering the registrant has made it to the Thank You page,
739
-                // any failed payments may actually be pending and the IPN is just slow
740
-                // so let's
741
-                $payment->set_status(EEM_Payment::status_id_pending);
742
-            }
743
-            $payment_declined_msg = $payment->STS_ID() === EEM_Payment::status_id_declined
744
-                ? '<br /><span class="small-text">' . $payment->gateway_response() . '</span>'
745
-                : '';
746
-            $html .= '
684
+		}
685
+	}
686
+
687
+
688
+	/**
689
+	 * get_transaction_details
690
+	 *
691
+	 * @return string
692
+	 * @throws \EE_Error
693
+	 */
694
+	public function get_transaction_details()
695
+	{
696
+		// prepare variables for displaying
697
+		$template_args = array();
698
+		$template_args['transaction'] = $this->_current_txn;
699
+		$template_args['reg_url_link'] = $this->_reg_url_link;
700
+		$template_args['primary_registrant_name'] = $this->_primary_registrant->attendee()->full_name(true);
701
+		// link to SPCO payment_options
702
+		$template_args['show_try_pay_again_link'] = $this->_show_try_pay_again_link;
703
+		$template_args['SPCO_payment_options_url'] = $this->_SPCO_payment_options_url;
704
+		// verify template arguments
705
+		EEH_Template_Validator::verify_instanceof($template_args['transaction'], '$transaction', 'EE_Transaction');
706
+		EEH_Template_Validator::verify_isnt_null(
707
+			$template_args['show_try_pay_again_link'],
708
+			'$show_try_pay_again_link'
709
+		);
710
+		EEH_Template_Validator::verify_isnt_null(
711
+			$template_args['SPCO_payment_options_url'],
712
+			'$SPCO_payment_options_url'
713
+		);
714
+		return EEH_Template::locate_template(
715
+			THANK_YOU_TEMPLATES_PATH . 'thank-you-page-transaction-details.template.php',
716
+			$template_args,
717
+			true,
718
+			true
719
+		);
720
+	}
721
+
722
+
723
+	/**
724
+	 * get_payment_row_html
725
+	 *
726
+	 * @param EE_Payment $payment
727
+	 * @return string
728
+	 * @throws \EE_Error
729
+	 */
730
+	public function get_payment_row_html($payment = null)
731
+	{
732
+		$html = '';
733
+		if ($payment instanceof EE_Payment) {
734
+			if ($payment->payment_method() instanceof EE_Payment_Method
735
+				&& $payment->status() === EEM_Payment::status_id_failed
736
+				&& $payment->payment_method()->is_off_site()
737
+			) {
738
+				// considering the registrant has made it to the Thank You page,
739
+				// any failed payments may actually be pending and the IPN is just slow
740
+				// so let's
741
+				$payment->set_status(EEM_Payment::status_id_pending);
742
+			}
743
+			$payment_declined_msg = $payment->STS_ID() === EEM_Payment::status_id_declined
744
+				? '<br /><span class="small-text">' . $payment->gateway_response() . '</span>'
745
+				: '';
746
+			$html .= '
747 747
 				<tr>
748 748
 					<td>
749 749
 						' . $payment->timestamp() . '
750 750
 					</td>
751 751
 					<td>
752 752
 						' . (
753
-                $payment->payment_method() instanceof EE_Payment_Method
754
-                    ? $payment->payment_method()->name()
755
-                    : __('Unknown', 'event_espresso')
756
-                ) . '
753
+				$payment->payment_method() instanceof EE_Payment_Method
754
+					? $payment->payment_method()->name()
755
+					: __('Unknown', 'event_espresso')
756
+				) . '
757 757
 					</td>
758 758
 					<td class="jst-rght">
759 759
 						' . EEH_Template::format_currency($payment->amount()) . '
@@ -762,83 +762,83 @@  discard block
 block discarded – undo
762 762
 						' . $payment->pretty_status(true) . $payment_declined_msg . '
763 763
 					</td>
764 764
 				</tr>';
765
-            do_action('AHEE__thank_you_page_payment_details_template__after_each_payment', $payment);
766
-        }
767
-        return $html;
768
-    }
769
-
770
-
771
-    /**
772
-     * get_payment_details
773
-     *
774
-     * @param array $payments
775
-     * @return string
776
-     * @throws \EE_Error
777
-     */
778
-    public function get_payment_details($payments = array())
779
-    {
780
-        // prepare variables for displaying
781
-        $template_args = array();
782
-        $template_args['transaction'] = $this->_current_txn;
783
-        $template_args['reg_url_link'] = $this->_reg_url_link;
784
-        $template_args['payments'] = array();
785
-        foreach ($payments as $payment) {
786
-            $template_args['payments'][] = $this->get_payment_row_html($payment);
787
-        }
788
-        // create a hacky payment object, but dont save it
789
-        $payment = EE_Payment::new_instance(
790
-            array(
791
-                'TXN_ID'        => $this->_current_txn->ID(),
792
-                'STS_ID'        => EEM_Payment::status_id_pending,
793
-                'PAY_timestamp' => time(),
794
-                'PAY_amount'    => $this->_current_txn->total(),
795
-                'PMD_ID'        => $this->_current_txn->payment_method_ID(),
796
-            )
797
-        );
798
-        $payment_method = $this->_current_txn->payment_method();
799
-        if ($payment_method instanceof EE_Payment_Method && $payment_method->type_obj() instanceof EE_PMT_Base) {
800
-            $template_args['gateway_content'] = $payment_method->type_obj()->payment_overview_content($payment);
801
-        } else {
802
-            $template_args['gateway_content'] = '';
803
-        }
804
-        // link to SPCO payment_options
805
-        $template_args['show_try_pay_again_link'] = $this->_show_try_pay_again_link;
806
-        $template_args['SPCO_payment_options_url'] = $this->_SPCO_payment_options_url;
807
-        // verify template arguments
808
-        EEH_Template_Validator::verify_instanceof($template_args['transaction'], '$transaction', 'EE_Transaction');
809
-        EEH_Template_Validator::verify_isnt_null($template_args['payments'], '$payments');
810
-        EEH_Template_Validator::verify_isnt_null(
811
-            $template_args['show_try_pay_again_link'],
812
-            '$show_try_pay_again_link'
813
-        );
814
-        EEH_Template_Validator::verify_isnt_null($template_args['gateway_content'], '$gateway_content');
815
-        EEH_Template_Validator::verify_isnt_null(
816
-            $template_args['SPCO_payment_options_url'],
817
-            '$SPCO_payment_options_url'
818
-        );
819
-        return EEH_Template::locate_template(
820
-            THANK_YOU_TEMPLATES_PATH . 'thank-you-page-payment-details.template.php',
821
-            $template_args,
822
-            true,
823
-            true
824
-        );
825
-    }
826
-
827
-
828
-    /**
829
-     * get_payment_details
830
-     *
831
-     * @param array $payments
832
-     * @return string
833
-     * @throws \EE_Error
834
-     */
835
-    public function get_new_payments($payments = array())
836
-    {
837
-        $payments_html = '';
838
-        // prepare variables for displaying
839
-        foreach ($payments as $payment) {
840
-            $payments_html .= $this->get_payment_row_html($payment);
841
-        }
842
-        return $payments_html;
843
-    }
765
+			do_action('AHEE__thank_you_page_payment_details_template__after_each_payment', $payment);
766
+		}
767
+		return $html;
768
+	}
769
+
770
+
771
+	/**
772
+	 * get_payment_details
773
+	 *
774
+	 * @param array $payments
775
+	 * @return string
776
+	 * @throws \EE_Error
777
+	 */
778
+	public function get_payment_details($payments = array())
779
+	{
780
+		// prepare variables for displaying
781
+		$template_args = array();
782
+		$template_args['transaction'] = $this->_current_txn;
783
+		$template_args['reg_url_link'] = $this->_reg_url_link;
784
+		$template_args['payments'] = array();
785
+		foreach ($payments as $payment) {
786
+			$template_args['payments'][] = $this->get_payment_row_html($payment);
787
+		}
788
+		// create a hacky payment object, but dont save it
789
+		$payment = EE_Payment::new_instance(
790
+			array(
791
+				'TXN_ID'        => $this->_current_txn->ID(),
792
+				'STS_ID'        => EEM_Payment::status_id_pending,
793
+				'PAY_timestamp' => time(),
794
+				'PAY_amount'    => $this->_current_txn->total(),
795
+				'PMD_ID'        => $this->_current_txn->payment_method_ID(),
796
+			)
797
+		);
798
+		$payment_method = $this->_current_txn->payment_method();
799
+		if ($payment_method instanceof EE_Payment_Method && $payment_method->type_obj() instanceof EE_PMT_Base) {
800
+			$template_args['gateway_content'] = $payment_method->type_obj()->payment_overview_content($payment);
801
+		} else {
802
+			$template_args['gateway_content'] = '';
803
+		}
804
+		// link to SPCO payment_options
805
+		$template_args['show_try_pay_again_link'] = $this->_show_try_pay_again_link;
806
+		$template_args['SPCO_payment_options_url'] = $this->_SPCO_payment_options_url;
807
+		// verify template arguments
808
+		EEH_Template_Validator::verify_instanceof($template_args['transaction'], '$transaction', 'EE_Transaction');
809
+		EEH_Template_Validator::verify_isnt_null($template_args['payments'], '$payments');
810
+		EEH_Template_Validator::verify_isnt_null(
811
+			$template_args['show_try_pay_again_link'],
812
+			'$show_try_pay_again_link'
813
+		);
814
+		EEH_Template_Validator::verify_isnt_null($template_args['gateway_content'], '$gateway_content');
815
+		EEH_Template_Validator::verify_isnt_null(
816
+			$template_args['SPCO_payment_options_url'],
817
+			'$SPCO_payment_options_url'
818
+		);
819
+		return EEH_Template::locate_template(
820
+			THANK_YOU_TEMPLATES_PATH . 'thank-you-page-payment-details.template.php',
821
+			$template_args,
822
+			true,
823
+			true
824
+		);
825
+	}
826
+
827
+
828
+	/**
829
+	 * get_payment_details
830
+	 *
831
+	 * @param array $payments
832
+	 * @return string
833
+	 * @throws \EE_Error
834
+	 */
835
+	public function get_new_payments($payments = array())
836
+	{
837
+		$payments_html = '';
838
+		// prepare variables for displaying
839
+		foreach ($payments as $payment) {
840
+			$payments_html .= $this->get_payment_row_html($payment);
841
+		}
842
+		return $payments_html;
843
+	}
844 844
 }
Please login to merge, or discard this patch.
Spacing   +25 added lines, -25 removed lines patch added patch discarded remove patch
@@ -126,8 +126,8 @@  discard block
 block discarded – undo
126 126
      */
127 127
     public static function set_definitions()
128 128
     {
129
-        define('THANK_YOU_ASSETS_URL', plugin_dir_url(__FILE__) . 'assets' . DS);
130
-        define('THANK_YOU_TEMPLATES_PATH', str_replace('\\', DS, plugin_dir_path(__FILE__)) . 'templates' . DS);
129
+        define('THANK_YOU_ASSETS_URL', plugin_dir_url(__FILE__).'assets'.DS);
130
+        define('THANK_YOU_TEMPLATES_PATH', str_replace('\\', DS, plugin_dir_path(__FILE__)).'templates'.DS);
131 131
     }
132 132
 
133 133
 
@@ -142,7 +142,7 @@  discard block
 block discarded – undo
142 142
             return $this->_current_txn;
143 143
         }
144 144
         $TXN_model = EE_Registry::instance()->load_model('Transaction');
145
-        if (! $TXN_model instanceof EEM_Transaction) {
145
+        if ( ! $TXN_model instanceof EEM_Transaction) {
146 146
             EE_Error::add_error(
147 147
                 __('The transaction model could not be established.', 'event_espresso'),
148 148
                 __FILE__,
@@ -179,7 +179,7 @@  discard block
 block discarded – undo
179 179
      */
180 180
     public function get_txn_payments($since = 0)
181 181
     {
182
-        if (! $this->get_txn()) {
182
+        if ( ! $this->get_txn()) {
183 183
             return false;
184 184
         }
185 185
         $args = array('order_by' => array('PAY_timestamp' => 'ASC'));
@@ -209,7 +209,7 @@  discard block
 block discarded – undo
209 209
      */
210 210
     private function _get_reg_url_link()
211 211
     {
212
-        if (! empty($this->_reg_url_link)) {
212
+        if ( ! empty($this->_reg_url_link)) {
213 213
             return;
214 214
         }
215 215
         // only do thank you page stuff if we have a REG_url_link in the url
@@ -321,7 +321,7 @@  discard block
 block discarded – undo
321 321
     {
322 322
         wp_register_script(
323 323
             'thank_you_page',
324
-            THANK_YOU_ASSETS_URL . 'thank_you_page.js',
324
+            THANK_YOU_ASSETS_URL.'thank_you_page.js',
325 325
             array('espresso_core', 'heartbeat'),
326 326
             EVENT_ESPRESSO_VERSION,
327 327
             true
@@ -340,9 +340,9 @@  discard block
 block discarded – undo
340 340
     public function init()
341 341
     {
342 342
         $this->_get_reg_url_link();
343
-        if (! $this->get_txn()) {
343
+        if ( ! $this->get_txn()) {
344 344
             echo EEH_HTML::div(
345
-                EEH_HTML::h4(__('We\'re sorry...', 'event_espresso'), '', '') .
345
+                EEH_HTML::h4(__('We\'re sorry...', 'event_espresso'), '', '').
346 346
                 sprintf(
347 347
                     __(
348 348
                         'This is a system page for displaying transaction information after a purchase.%1$sYou are most likely seeing this notice because you have navigated to this page%1$sthrough some means other than completing a transaction.%1$sSorry for the disappointment, but you will most likely find nothing of interest here.%1$s%1$s',
@@ -432,12 +432,12 @@  discard block
 block discarded – undo
432 432
     public function thank_you_page_results()
433 433
     {
434 434
         $this->init();
435
-        if (! $this->_current_txn instanceof EE_Transaction) {
435
+        if ( ! $this->_current_txn instanceof EE_Transaction) {
436 436
             return EE_Error::get_notices();
437 437
         }
438 438
         // link to receipt
439 439
         $template_args['TXN_receipt_url'] = $this->_current_txn->receipt_url('html');
440
-        if (! empty($template_args['TXN_receipt_url'])) {
440
+        if ( ! empty($template_args['TXN_receipt_url'])) {
441 441
             $template_args['order_conf_desc'] = __(
442 442
                 '%1$sCongratulations%2$sYour registration has been successfully processed.%3$sCheck your email for your registration confirmation or click the button below to view / download / print a full description of your purchases and registration information.',
443 443
                 'event_espresso'
@@ -455,7 +455,7 @@  discard block
 block discarded – undo
455 455
             add_action('AHEE__thank_you_page_overview_template__content', array($this, 'get_ajax_content'));
456 456
         }
457 457
         return EEH_Template::locate_template(
458
-            THANK_YOU_TEMPLATES_PATH . 'thank-you-page-overview.template.php',
458
+            THANK_YOU_TEMPLATES_PATH.'thank-you-page-overview.template.php',
459 459
             $template_args,
460 460
             true,
461 461
             true
@@ -507,7 +507,7 @@  discard block
 block discarded – undo
507 507
             '$SPCO_attendee_information_url'
508 508
         );
509 509
         echo EEH_Template::locate_template(
510
-            THANK_YOU_TEMPLATES_PATH . 'thank-you-page-registration-details.template.php',
510
+            THANK_YOU_TEMPLATES_PATH.'thank-you-page-registration-details.template.php',
511 511
             $template_args,
512 512
             true,
513 513
             true
@@ -580,7 +580,7 @@  discard block
 block discarded – undo
580 580
      */
581 581
     public function get_ajax_content()
582 582
     {
583
-        if (! $this->get_txn()) {
583
+        if ( ! $this->get_txn()) {
584 584
             return;
585 585
         }
586 586
         // first determine which event(s) require pre-approval or not
@@ -591,9 +591,9 @@  discard block
 block discarded – undo
591 591
                 $event = $registration->event();
592 592
                 if ($event instanceof EE_Event) {
593 593
                     if ($registration->is_not_approved() && $registration->event() instanceof EE_Event) {
594
-                        $events_requiring_pre_approval[ $event->ID() ] = $event;
594
+                        $events_requiring_pre_approval[$event->ID()] = $event;
595 595
                     } else {
596
-                        $events[ $event->ID() ] = $event;
596
+                        $events[$event->ID()] = $event;
597 597
                     }
598 598
                 }
599 599
             }
@@ -611,7 +611,7 @@  discard block
 block discarded – undo
611 611
      */
612 612
     public function display_details_for_events($events = array())
613 613
     {
614
-        if (! empty($events)) {
614
+        if ( ! empty($events)) {
615 615
             ?>
616 616
             <div id="espresso-thank-you-page-ajax-content-dv">
617 617
                 <div id="espresso-thank-you-page-ajax-transaction-dv"></div>
@@ -624,7 +624,7 @@  discard block
 block discarded – undo
624 624
                                 'event_espresso'
625 625
                             ); ?></span>
626 626
                     </div>
627
-                    <?php if (! $this->_is_offline_payment_method && ! $this->_payments_closed) : ?>
627
+                    <?php if ( ! $this->_is_offline_payment_method && ! $this->_payments_closed) : ?>
628 628
                         <p id="ee-ajax-loading-pg" class="highlight-bg small-text clear">
629 629
                             <?php echo apply_filters(
630 630
                                 'EED_Thank_You_Page__get_ajax_content__waiting_for_IPN_msg',
@@ -655,7 +655,7 @@  discard block
 block discarded – undo
655 655
      */
656 656
     public function display_details_for_events_requiring_pre_approval($events = array())
657 657
     {
658
-        if (! empty($events)) {
658
+        if ( ! empty($events)) {
659 659
             ?>
660 660
             <div id="espresso-thank-you-page-not-approved-message-dv">
661 661
                 <h4 class="orange-text"><?php _e('Important Notice:', 'event_espresso'); ?></h4>
@@ -712,7 +712,7 @@  discard block
 block discarded – undo
712 712
             '$SPCO_payment_options_url'
713 713
         );
714 714
         return EEH_Template::locate_template(
715
-            THANK_YOU_TEMPLATES_PATH . 'thank-you-page-transaction-details.template.php',
715
+            THANK_YOU_TEMPLATES_PATH.'thank-you-page-transaction-details.template.php',
716 716
             $template_args,
717 717
             true,
718 718
             true
@@ -741,25 +741,25 @@  discard block
 block discarded – undo
741 741
                 $payment->set_status(EEM_Payment::status_id_pending);
742 742
             }
743 743
             $payment_declined_msg = $payment->STS_ID() === EEM_Payment::status_id_declined
744
-                ? '<br /><span class="small-text">' . $payment->gateway_response() . '</span>'
744
+                ? '<br /><span class="small-text">'.$payment->gateway_response().'</span>'
745 745
                 : '';
746 746
             $html .= '
747 747
 				<tr>
748 748
 					<td>
749
-						' . $payment->timestamp() . '
749
+						' . $payment->timestamp().'
750 750
 					</td>
751 751
 					<td>
752 752
 						' . (
753 753
                 $payment->payment_method() instanceof EE_Payment_Method
754 754
                     ? $payment->payment_method()->name()
755 755
                     : __('Unknown', 'event_espresso')
756
-                ) . '
756
+                ).'
757 757
 					</td>
758 758
 					<td class="jst-rght">
759
-						' . EEH_Template::format_currency($payment->amount()) . '
759
+						' . EEH_Template::format_currency($payment->amount()).'
760 760
 					</td>
761 761
 					<td class="jst-rght" style="line-height:1;">
762
-						' . $payment->pretty_status(true) . $payment_declined_msg . '
762
+						' . $payment->pretty_status(true).$payment_declined_msg.'
763 763
 					</td>
764 764
 				</tr>';
765 765
             do_action('AHEE__thank_you_page_payment_details_template__after_each_payment', $payment);
@@ -817,7 +817,7 @@  discard block
 block discarded – undo
817 817
             '$SPCO_payment_options_url'
818 818
         );
819 819
         return EEH_Template::locate_template(
820
-            THANK_YOU_TEMPLATES_PATH . 'thank-you-page-payment-details.template.php',
820
+            THANK_YOU_TEMPLATES_PATH.'thank-you-page-payment-details.template.php',
821 821
             $template_args,
822 822
             true,
823 823
             true
Please login to merge, or discard this patch.
caffeinated/admin/extend/events/Extend_Events_Admin_Page.core.php 2 patches
Indentation   +1253 added lines, -1253 removed lines patch added patch discarded remove patch
@@ -16,1257 +16,1257 @@
 block discarded – undo
16 16
 {
17 17
 
18 18
 
19
-    /**
20
-     * Extend_Events_Admin_Page constructor.
21
-     *
22
-     * @param bool $routing
23
-     */
24
-    public function __construct($routing = true)
25
-    {
26
-        parent::__construct($routing);
27
-        if (! defined('EVENTS_CAF_TEMPLATE_PATH')) {
28
-            define('EVENTS_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'events/templates/');
29
-            define('EVENTS_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'events/assets/');
30
-            define('EVENTS_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'events/assets/');
31
-        }
32
-    }
33
-
34
-
35
-    /**
36
-     * Sets routes.
37
-     */
38
-    protected function _extend_page_config()
39
-    {
40
-        $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'events';
41
-        // is there a evt_id in the request?
42
-        $evt_id = ! empty($this->_req_data['EVT_ID']) && ! is_array($this->_req_data['EVT_ID'])
43
-            ? $this->_req_data['EVT_ID']
44
-            : 0;
45
-        $evt_id = ! empty($this->_req_data['post']) ? $this->_req_data['post'] : $evt_id;
46
-        // tkt_id?
47
-        $tkt_id = ! empty($this->_req_data['TKT_ID']) && ! is_array($this->_req_data['TKT_ID'])
48
-            ? $this->_req_data['TKT_ID']
49
-            : 0;
50
-        $new_page_routes = array(
51
-            'duplicate_event'          => array(
52
-                'func'       => '_duplicate_event',
53
-                'capability' => 'ee_edit_event',
54
-                'obj_id'     => $evt_id,
55
-                'noheader'   => true,
56
-            ),
57
-            'ticket_list_table'        => array(
58
-                'func'       => '_tickets_overview_list_table',
59
-                'capability' => 'ee_read_default_tickets',
60
-            ),
61
-            'trash_ticket'             => array(
62
-                'func'       => '_trash_or_restore_ticket',
63
-                'capability' => 'ee_delete_default_ticket',
64
-                'obj_id'     => $tkt_id,
65
-                'noheader'   => true,
66
-                'args'       => array('trash' => true),
67
-            ),
68
-            'trash_tickets'            => array(
69
-                'func'       => '_trash_or_restore_ticket',
70
-                'capability' => 'ee_delete_default_tickets',
71
-                'noheader'   => true,
72
-                'args'       => array('trash' => true),
73
-            ),
74
-            'restore_ticket'           => array(
75
-                'func'       => '_trash_or_restore_ticket',
76
-                'capability' => 'ee_delete_default_ticket',
77
-                'obj_id'     => $tkt_id,
78
-                'noheader'   => true,
79
-            ),
80
-            'restore_tickets'          => array(
81
-                'func'       => '_trash_or_restore_ticket',
82
-                'capability' => 'ee_delete_default_tickets',
83
-                'noheader'   => true,
84
-            ),
85
-            'delete_ticket'            => array(
86
-                'func'       => '_delete_ticket',
87
-                'capability' => 'ee_delete_default_ticket',
88
-                'obj_id'     => $tkt_id,
89
-                'noheader'   => true,
90
-            ),
91
-            'delete_tickets'           => array(
92
-                'func'       => '_delete_ticket',
93
-                'capability' => 'ee_delete_default_tickets',
94
-                'noheader'   => true,
95
-            ),
96
-            'import_page'              => array(
97
-                'func'       => '_import_page',
98
-                'capability' => 'import',
99
-            ),
100
-            'import'                   => array(
101
-                'func'       => '_import_events',
102
-                'capability' => 'import',
103
-                'noheader'   => true,
104
-            ),
105
-            'import_events'            => array(
106
-                'func'       => '_import_events',
107
-                'capability' => 'import',
108
-                'noheader'   => true,
109
-            ),
110
-            'export_events'            => array(
111
-                'func'       => '_events_export',
112
-                'capability' => 'export',
113
-                'noheader'   => true,
114
-            ),
115
-            'export_categories'        => array(
116
-                'func'       => '_categories_export',
117
-                'capability' => 'export',
118
-                'noheader'   => true,
119
-            ),
120
-            'sample_export_file'       => array(
121
-                'func'       => '_sample_export_file',
122
-                'capability' => 'export',
123
-                'noheader'   => true,
124
-            ),
125
-            'update_template_settings' => array(
126
-                'func'       => '_update_template_settings',
127
-                'capability' => 'manage_options',
128
-                'noheader'   => true,
129
-            ),
130
-        );
131
-        $this->_page_routes = array_merge($this->_page_routes, $new_page_routes);
132
-        // partial route/config override
133
-        $this->_page_config['import_events']['metaboxes'] = $this->_default_espresso_metaboxes;
134
-        $this->_page_config['create_new']['metaboxes'][] = '_premium_event_editor_meta_boxes';
135
-        $this->_page_config['create_new']['qtips'][] = 'EE_Event_Editor_Tips';
136
-        $this->_page_config['edit']['qtips'][] = 'EE_Event_Editor_Tips';
137
-        $this->_page_config['edit']['metaboxes'][] = '_premium_event_editor_meta_boxes';
138
-        $this->_page_config['default']['list_table'] = 'Extend_Events_Admin_List_Table';
139
-        // add tickets tab but only if there are more than one default ticket!
140
-        $tkt_count = EEM_Ticket::instance()->count_deleted_and_undeleted(
141
-            array(array('TKT_is_default' => 1)),
142
-            'TKT_ID',
143
-            true
144
-        );
145
-        if ($tkt_count > 1) {
146
-            $new_page_config = array(
147
-                'ticket_list_table' => array(
148
-                    'nav'           => array(
149
-                        'label' => esc_html__('Default Tickets', 'event_espresso'),
150
-                        'order' => 60,
151
-                    ),
152
-                    'list_table'    => 'Tickets_List_Table',
153
-                    'require_nonce' => false,
154
-                ),
155
-            );
156
-        }
157
-        // template settings
158
-        $new_page_config['template_settings'] = array(
159
-            'nav'           => array(
160
-                'label' => esc_html__('Templates', 'event_espresso'),
161
-                'order' => 30,
162
-            ),
163
-            'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
164
-            'help_tabs'     => array(
165
-                'general_settings_templates_help_tab' => array(
166
-                    'title'    => esc_html__('Templates', 'event_espresso'),
167
-                    'filename' => 'general_settings_templates',
168
-                ),
169
-            ),
170
-            'help_tour'     => array('Templates_Help_Tour'),
171
-            'require_nonce' => false,
172
-        );
173
-        $this->_page_config = array_merge($this->_page_config, $new_page_config);
174
-        // add filters and actions
175
-        // modifying _views
176
-        add_filter(
177
-            'FHEE_event_datetime_metabox_add_additional_date_time_template',
178
-            array($this, 'add_additional_datetime_button'),
179
-            10,
180
-            2
181
-        );
182
-        add_filter(
183
-            'FHEE_event_datetime_metabox_clone_button_template',
184
-            array($this, 'add_datetime_clone_button'),
185
-            10,
186
-            2
187
-        );
188
-        add_filter(
189
-            'FHEE_event_datetime_metabox_timezones_template',
190
-            array($this, 'datetime_timezones_template'),
191
-            10,
192
-            2
193
-        );
194
-        // filters for event list table
195
-        add_filter('FHEE__Extend_Events_Admin_List_Table__filters', array($this, 'list_table_filters'), 10, 2);
196
-        add_filter(
197
-            'FHEE__Events_Admin_List_Table__column_actions__action_links',
198
-            array($this, 'extra_list_table_actions'),
199
-            10,
200
-            2
201
-        );
202
-        // legend item
203
-        add_filter('FHEE__Events_Admin_Page___event_legend_items__items', array($this, 'additional_legend_items'));
204
-        add_action('admin_init', array($this, 'admin_init'));
205
-    }
206
-
207
-
208
-    /**
209
-     * admin_init
210
-     */
211
-    public function admin_init()
212
-    {
213
-        EE_Registry::$i18n_js_strings = array_merge(
214
-            EE_Registry::$i18n_js_strings,
215
-            array(
216
-                'image_confirm'          => esc_html__(
217
-                    'Do you really want to delete this image? Please remember to update your event to complete the removal.',
218
-                    'event_espresso'
219
-                ),
220
-                'event_starts_on'        => esc_html__('Event Starts on', 'event_espresso'),
221
-                'event_ends_on'          => esc_html__('Event Ends on', 'event_espresso'),
222
-                'event_datetime_actions' => esc_html__('Actions', 'event_espresso'),
223
-                'event_clone_dt_msg'     => esc_html__('Clone this Event Date and Time', 'event_espresso'),
224
-                'remove_event_dt_msg'    => esc_html__('Remove this Event Time', 'event_espresso'),
225
-            )
226
-        );
227
-    }
228
-
229
-
230
-    /**
231
-     * Add per page screen options to the default ticket list table view.
232
-     */
233
-    protected function _add_screen_options_ticket_list_table()
234
-    {
235
-        $this->_per_page_screen_option();
236
-    }
237
-
238
-
239
-    /**
240
-     * @param string $return
241
-     * @param int    $id
242
-     * @param string $new_title
243
-     * @param string $new_slug
244
-     * @return string
245
-     */
246
-    public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
247
-    {
248
-        $return = parent::extra_permalink_field_buttons($return, $id, $new_title, $new_slug);
249
-        // make sure this is only when editing
250
-        if (! empty($id)) {
251
-            $href = EE_Admin_Page::add_query_args_and_nonce(
252
-                array('action' => 'duplicate_event', 'EVT_ID' => $id),
253
-                $this->_admin_base_url
254
-            );
255
-            $title = esc_attr__('Duplicate Event', 'event_espresso');
256
-            $return .= '<a href="'
257
-                       . $href
258
-                       . '" title="'
259
-                       . $title
260
-                       . '" id="ee-duplicate-event-button" class="button button-small"  value="duplicate_event">'
261
-                       . $title
262
-                       . '</a>';
263
-        }
264
-        return $return;
265
-    }
266
-
267
-
268
-    /**
269
-     * Set the list table views for the default ticket list table view.
270
-     */
271
-    public function _set_list_table_views_ticket_list_table()
272
-    {
273
-        $this->_views = array(
274
-            'all'     => array(
275
-                'slug'        => 'all',
276
-                'label'       => esc_html__('All', 'event_espresso'),
277
-                'count'       => 0,
278
-                'bulk_action' => array(
279
-                    'trash_tickets' => esc_html__('Move to Trash', 'event_espresso'),
280
-                ),
281
-            ),
282
-            'trashed' => array(
283
-                'slug'        => 'trashed',
284
-                'label'       => esc_html__('Trash', 'event_espresso'),
285
-                'count'       => 0,
286
-                'bulk_action' => array(
287
-                    'restore_tickets' => esc_html__('Restore from Trash', 'event_espresso'),
288
-                    'delete_tickets'  => esc_html__('Delete Permanently', 'event_espresso'),
289
-                ),
290
-            ),
291
-        );
292
-    }
293
-
294
-
295
-    /**
296
-     * Enqueue scripts and styles for the event editor.
297
-     */
298
-    public function load_scripts_styles_edit()
299
-    {
300
-        wp_register_script(
301
-            'ee-event-editor-heartbeat',
302
-            EVENTS_CAF_ASSETS_URL . 'event-editor-heartbeat.js',
303
-            array('ee_admin_js', 'heartbeat'),
304
-            EVENT_ESPRESSO_VERSION,
305
-            true
306
-        );
307
-        wp_enqueue_script('ee-accounting');
308
-        // styles
309
-        wp_enqueue_style('espresso-ui-theme');
310
-        wp_enqueue_script('event_editor_js');
311
-        wp_enqueue_script('ee-event-editor-heartbeat');
312
-    }
313
-
314
-
315
-    /**
316
-     * Returns template for the additional datetime.
317
-     *
318
-     * @param $template
319
-     * @param $template_args
320
-     * @return mixed
321
-     * @throws DomainException
322
-     */
323
-    public function add_additional_datetime_button($template, $template_args)
324
-    {
325
-        return EEH_Template::display_template(
326
-            EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_add_additional_time.template.php',
327
-            $template_args,
328
-            true
329
-        );
330
-    }
331
-
332
-
333
-    /**
334
-     * Returns the template for cloning a datetime.
335
-     *
336
-     * @param $template
337
-     * @param $template_args
338
-     * @return mixed
339
-     * @throws DomainException
340
-     */
341
-    public function add_datetime_clone_button($template, $template_args)
342
-    {
343
-        return EEH_Template::display_template(
344
-            EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_metabox_clone_button.template.php',
345
-            $template_args,
346
-            true
347
-        );
348
-    }
349
-
350
-
351
-    /**
352
-     * Returns the template for datetime timezones.
353
-     *
354
-     * @param $template
355
-     * @param $template_args
356
-     * @return mixed
357
-     * @throws DomainException
358
-     */
359
-    public function datetime_timezones_template($template, $template_args)
360
-    {
361
-        return EEH_Template::display_template(
362
-            EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_timezones.template.php',
363
-            $template_args,
364
-            true
365
-        );
366
-    }
367
-
368
-
369
-    /**
370
-     * Sets the views for the default list table view.
371
-     */
372
-    protected function _set_list_table_views_default()
373
-    {
374
-        parent::_set_list_table_views_default();
375
-        $new_views = array(
376
-            'today' => array(
377
-                'slug'        => 'today',
378
-                'label'       => esc_html__('Today', 'event_espresso'),
379
-                'count'       => $this->total_events_today(),
380
-                'bulk_action' => array(
381
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
382
-                ),
383
-            ),
384
-            'month' => array(
385
-                'slug'        => 'month',
386
-                'label'       => esc_html__('This Month', 'event_espresso'),
387
-                'count'       => $this->total_events_this_month(),
388
-                'bulk_action' => array(
389
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
390
-                ),
391
-            ),
392
-        );
393
-        $this->_views = array_merge($this->_views, $new_views);
394
-    }
395
-
396
-
397
-    /**
398
-     * Returns the extra action links for the default list table view.
399
-     *
400
-     * @param array     $action_links
401
-     * @param \EE_Event $event
402
-     * @return array
403
-     * @throws EE_Error
404
-     */
405
-    public function extra_list_table_actions(array $action_links, \EE_Event $event)
406
-    {
407
-        if (EE_Registry::instance()->CAP->current_user_can(
408
-            'ee_read_registrations',
409
-            'espresso_registrations_reports',
410
-            $event->ID()
411
-        )
412
-        ) {
413
-            $reports_query_args = array(
414
-                'action' => 'reports',
415
-                'EVT_ID' => $event->ID(),
416
-            );
417
-            $reports_link = EE_Admin_Page::add_query_args_and_nonce($reports_query_args, REG_ADMIN_URL);
418
-            $action_links[] = '<a href="'
419
-                              . $reports_link
420
-                              . '" title="'
421
-                              . esc_attr__('View Report', 'event_espresso')
422
-                              . '"><div class="dashicons dashicons-chart-bar"></div></a>'
423
-                              . "\n\t";
424
-        }
425
-        if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
426
-            EE_Registry::instance()->load_helper('MSG_Template');
427
-            $action_links[] = EEH_MSG_Template::get_message_action_link(
428
-                'see_notifications_for',
429
-                null,
430
-                array('EVT_ID' => $event->ID())
431
-            );
432
-        }
433
-        return $action_links;
434
-    }
435
-
436
-
437
-    /**
438
-     * @param $items
439
-     * @return mixed
440
-     */
441
-    public function additional_legend_items($items)
442
-    {
443
-        if (EE_Registry::instance()->CAP->current_user_can(
444
-            'ee_read_registrations',
445
-            'espresso_registrations_reports'
446
-        )
447
-        ) {
448
-            $items['reports'] = array(
449
-                'class' => 'dashicons dashicons-chart-bar',
450
-                'desc'  => esc_html__('Event Reports', 'event_espresso'),
451
-            );
452
-        }
453
-        if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
454
-            $related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
455
-            if (isset($related_for_icon['css_class']) && isset($related_for_icon['label'])) {
456
-                $items['view_related_messages'] = array(
457
-                    'class' => $related_for_icon['css_class'],
458
-                    'desc'  => $related_for_icon['label'],
459
-                );
460
-            }
461
-        }
462
-        return $items;
463
-    }
464
-
465
-
466
-    /**
467
-     * This is the callback method for the duplicate event route
468
-     * Method looks for 'EVT_ID' in the request and retrieves that event and its details and duplicates them
469
-     * into a new event.  We add a hook so that any plugins that add extra event details can hook into this
470
-     * action.  Note that the dupe will have **DUPLICATE** as its title and slug.
471
-     * After duplication the redirect is to the new event edit page.
472
-     *
473
-     * @return void
474
-     * @access protected
475
-     * @throws EE_Error If EE_Event is not available with given ID
476
-     */
477
-    protected function _duplicate_event()
478
-    {
479
-        // first make sure the ID for the event is in the request.
480
-        //  If it isn't then we need to bail and redirect back to overview list table (cause how did we get here?)
481
-        if (! isset($this->_req_data['EVT_ID'])) {
482
-            EE_Error::add_error(
483
-                esc_html__(
484
-                    'In order to duplicate an event an Event ID is required.  None was given.',
485
-                    'event_espresso'
486
-                ),
487
-                __FILE__,
488
-                __FUNCTION__,
489
-                __LINE__
490
-            );
491
-            $this->_redirect_after_action(false, '', '', array(), true);
492
-            return;
493
-        }
494
-        // k we've got EVT_ID so let's use that to get the event we'll duplicate
495
-        $orig_event = EEM_Event::instance()->get_one_by_ID($this->_req_data['EVT_ID']);
496
-        if (! $orig_event instanceof EE_Event) {
497
-            throw new EE_Error(
498
-                sprintf(
499
-                    esc_html__('An EE_Event object could not be retrieved for the given ID (%s)', 'event_espresso'),
500
-                    $this->_req_data['EVT_ID']
501
-                )
502
-            );
503
-        }
504
-        // k now let's clone the $orig_event before getting relations
505
-        $new_event = clone $orig_event;
506
-        // original datetimes
507
-        $orig_datetimes = $orig_event->get_many_related('Datetime');
508
-        // other original relations
509
-        $orig_ven = $orig_event->get_many_related('Venue');
510
-        // reset the ID and modify other details to make it clear this is a dupe
511
-        $new_event->set('EVT_ID', 0);
512
-        $new_name = $new_event->name() . ' ' . esc_html__('**DUPLICATE**', 'event_espresso');
513
-        $new_event->set('EVT_name', $new_name);
514
-        $new_event->set(
515
-            'EVT_slug',
516
-            wp_unique_post_slug(
517
-                sanitize_title($orig_event->name()),
518
-                0,
519
-                'publish',
520
-                'espresso_events',
521
-                0
522
-            )
523
-        );
524
-        $new_event->set('status', 'draft');
525
-        // duplicate discussion settings
526
-        $new_event->set('comment_status', $orig_event->get('comment_status'));
527
-        $new_event->set('ping_status', $orig_event->get('ping_status'));
528
-        // save the new event
529
-        $new_event->save();
530
-        // venues
531
-        foreach ($orig_ven as $ven) {
532
-            $new_event->_add_relation_to($ven, 'Venue');
533
-        }
534
-        $new_event->save();
535
-        // now we need to get the question group relations and handle that
536
-        // first primary question groups
537
-        $orig_primary_qgs = $orig_event->get_many_related(
538
-            'Question_Group',
539
-            array(array('Event_Question_Group.EQG_primary' => 1))
540
-        );
541
-        if (! empty($orig_primary_qgs)) {
542
-            foreach ($orig_primary_qgs as $id => $obj) {
543
-                if ($obj instanceof EE_Question_Group) {
544
-                    $new_event->_add_relation_to($obj, 'Question_Group', array('EQG_primary' => 1));
545
-                }
546
-            }
547
-        }
548
-        // next additional attendee question groups
549
-        $orig_additional_qgs = $orig_event->get_many_related(
550
-            'Question_Group',
551
-            array(array('Event_Question_Group.EQG_primary' => 0))
552
-        );
553
-        if (! empty($orig_additional_qgs)) {
554
-            foreach ($orig_additional_qgs as $id => $obj) {
555
-                if ($obj instanceof EE_Question_Group) {
556
-                    $new_event->_add_relation_to($obj, 'Question_Group', array('EQG_primary' => 0));
557
-                }
558
-            }
559
-        }
560
-
561
-        $new_event->save();
562
-
563
-        // k now that we have the new event saved we can loop through the datetimes and start adding relations.
564
-        $cloned_tickets = array();
565
-        foreach ($orig_datetimes as $orig_dtt) {
566
-            if (! $orig_dtt instanceof EE_Datetime) {
567
-                continue;
568
-            }
569
-            $new_dtt = clone $orig_dtt;
570
-            $orig_tkts = $orig_dtt->tickets();
571
-            // save new dtt then add to event
572
-            $new_dtt->set('DTT_ID', 0);
573
-            $new_dtt->set('DTT_sold', 0);
574
-            $new_dtt->set_reserved(0);
575
-            $new_dtt->save();
576
-            $new_event->_add_relation_to($new_dtt, 'Datetime');
577
-            $new_event->save();
578
-            // now let's get the ticket relations setup.
579
-            foreach ((array) $orig_tkts as $orig_tkt) {
580
-                // it's possible a datetime will have no tickets so let's verify we HAVE a ticket first.
581
-                if (! $orig_tkt instanceof EE_Ticket) {
582
-                    continue;
583
-                }
584
-                // is this ticket archived?  If it is then let's skip
585
-                if ($orig_tkt->get('TKT_deleted')) {
586
-                    continue;
587
-                }
588
-                // does this original ticket already exist in the clone_tickets cache?
589
-                //  If so we'll just use the new ticket from it.
590
-                if (isset($cloned_tickets[ $orig_tkt->ID() ])) {
591
-                    $new_tkt = $cloned_tickets[ $orig_tkt->ID() ];
592
-                } else {
593
-                    $new_tkt = clone $orig_tkt;
594
-                    // get relations on the $orig_tkt that we need to setup.
595
-                    $orig_prices = $orig_tkt->prices();
596
-                    $new_tkt->set('TKT_ID', 0);
597
-                    $new_tkt->set('TKT_sold', 0);
598
-                    $new_tkt->set('TKT_reserved', 0);
599
-                    $new_tkt->save(); // make sure new ticket has ID.
600
-                    // price relations on new ticket need to be setup.
601
-                    foreach ($orig_prices as $orig_price) {
602
-                        $new_price = clone $orig_price;
603
-                        $new_price->set('PRC_ID', 0);
604
-                        $new_price->save();
605
-                        $new_tkt->_add_relation_to($new_price, 'Price');
606
-                        $new_tkt->save();
607
-                    }
608
-
609
-                    do_action(
610
-                        'AHEE__Extend_Events_Admin_Page___duplicate_event__duplicate_ticket__after',
611
-                        $orig_tkt,
612
-                        $new_tkt,
613
-                        $orig_prices,
614
-                        $orig_event,
615
-                        $orig_dtt,
616
-                        $new_dtt
617
-                    );
618
-                }
619
-                // k now we can add the new ticket as a relation to the new datetime
620
-                // and make sure its added to our cached $cloned_tickets array
621
-                // for use with later datetimes that have the same ticket.
622
-                $new_dtt->_add_relation_to($new_tkt, 'Ticket');
623
-                $new_dtt->save();
624
-                $cloned_tickets[ $orig_tkt->ID() ] = $new_tkt;
625
-            }
626
-        }
627
-        // clone taxonomy information
628
-        $taxonomies_to_clone_with = apply_filters(
629
-            'FHEE__Extend_Events_Admin_Page___duplicate_event__taxonomies_to_clone',
630
-            array('espresso_event_categories', 'espresso_event_type', 'post_tag')
631
-        );
632
-        // get terms for original event (notice)
633
-        $orig_terms = wp_get_object_terms($orig_event->ID(), $taxonomies_to_clone_with);
634
-        // loop through terms and add them to new event.
635
-        foreach ($orig_terms as $term) {
636
-            wp_set_object_terms($new_event->ID(), $term->term_id, $term->taxonomy, true);
637
-        }
638
-
639
-        // duplicate other core WP_Post items for this event.
640
-        // post thumbnail (feature image).
641
-        $feature_image_id = get_post_thumbnail_id($orig_event->ID());
642
-        if ($feature_image_id) {
643
-            update_post_meta($new_event->ID(), '_thumbnail_id', $feature_image_id);
644
-        }
645
-
646
-        // duplicate page_template setting
647
-        $page_template = get_post_meta($orig_event->ID(), '_wp_page_template', true);
648
-        if ($page_template) {
649
-            update_post_meta($new_event->ID(), '_wp_page_template', $page_template);
650
-        }
651
-
652
-        do_action('AHEE__Extend_Events_Admin_Page___duplicate_event__after', $new_event, $orig_event);
653
-        // now let's redirect to the edit page for this duplicated event if we have a new event id.
654
-        if ($new_event->ID()) {
655
-            $redirect_args = array(
656
-                'post'   => $new_event->ID(),
657
-                'action' => 'edit',
658
-            );
659
-            EE_Error::add_success(
660
-                esc_html__(
661
-                    'Event successfully duplicated.  Please review the details below and make any necessary edits',
662
-                    'event_espresso'
663
-                )
664
-            );
665
-        } else {
666
-            $redirect_args = array(
667
-                'action' => 'default',
668
-            );
669
-            EE_Error::add_error(
670
-                esc_html__('Not able to duplicate event.  Something went wrong.', 'event_espresso'),
671
-                __FILE__,
672
-                __FUNCTION__,
673
-                __LINE__
674
-            );
675
-        }
676
-        $this->_redirect_after_action(false, '', '', $redirect_args, true);
677
-    }
678
-
679
-
680
-    /**
681
-     * Generates output for the import page.
682
-     *
683
-     * @throws DomainException
684
-     */
685
-    protected function _import_page()
686
-    {
687
-        $title = esc_html__('Import', 'event_espresso');
688
-        $intro = esc_html__(
689
-            'If you have a previously exported Event Espresso 4 information in a Comma Separated Value (CSV) file format, you can upload the file here: ',
690
-            'event_espresso'
691
-        );
692
-        $form_url = EVENTS_ADMIN_URL;
693
-        $action = 'import_events';
694
-        $type = 'csv';
695
-        $this->_template_args['form'] = EE_Import::instance()->upload_form(
696
-            $title,
697
-            $intro,
698
-            $form_url,
699
-            $action,
700
-            $type
701
-        );
702
-        $this->_template_args['sample_file_link'] = EE_Admin_Page::add_query_args_and_nonce(
703
-            array('action' => 'sample_export_file'),
704
-            $this->_admin_base_url
705
-        );
706
-        $content = EEH_Template::display_template(
707
-            EVENTS_CAF_TEMPLATE_PATH . 'import_page.template.php',
708
-            $this->_template_args,
709
-            true
710
-        );
711
-        $this->_template_args['admin_page_content'] = $content;
712
-        $this->display_admin_page_with_sidebar();
713
-    }
714
-
715
-
716
-    /**
717
-     * _import_events
718
-     * This handles displaying the screen and running imports for importing events.
719
-     *
720
-     * @return void
721
-     */
722
-    protected function _import_events()
723
-    {
724
-        require_once(EE_CLASSES . 'EE_Import.class.php');
725
-        $success = EE_Import::instance()->import();
726
-        $this->_redirect_after_action($success, 'Import File', 'ran', array('action' => 'import_page'), true);
727
-    }
728
-
729
-
730
-    /**
731
-     * _events_export
732
-     * Will export all (or just the given event) to a Excel compatible file.
733
-     *
734
-     * @access protected
735
-     * @return void
736
-     */
737
-    protected function _events_export()
738
-    {
739
-        if (isset($this->_req_data['EVT_ID'])) {
740
-            $event_ids = $this->_req_data['EVT_ID'];
741
-        } elseif (isset($this->_req_data['EVT_IDs'])) {
742
-            $event_ids = $this->_req_data['EVT_IDs'];
743
-        } else {
744
-            $event_ids = null;
745
-        }
746
-        // todo: I don't like doing this but it'll do until we modify EE_Export Class.
747
-        $new_request_args = array(
748
-            'export' => 'report',
749
-            'action' => 'all_event_data',
750
-            'EVT_ID' => $event_ids,
751
-        );
752
-        $this->_req_data = array_merge($this->_req_data, $new_request_args);
753
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
754
-            require_once(EE_CLASSES . 'EE_Export.class.php');
755
-            $EE_Export = EE_Export::instance($this->_req_data);
756
-            $EE_Export->export();
757
-        }
758
-    }
759
-
760
-
761
-    /**
762
-     * handle category exports()
763
-     *
764
-     * @return void
765
-     */
766
-    protected function _categories_export()
767
-    {
768
-        // todo: I don't like doing this but it'll do until we modify EE_Export Class.
769
-        $new_request_args = array(
770
-            'export'       => 'report',
771
-            'action'       => 'categories',
772
-            'category_ids' => $this->_req_data['EVT_CAT_ID'],
773
-        );
774
-        $this->_req_data = array_merge($this->_req_data, $new_request_args);
775
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
776
-            require_once(EE_CLASSES . 'EE_Export.class.php');
777
-            $EE_Export = EE_Export::instance($this->_req_data);
778
-            $EE_Export->export();
779
-        }
780
-    }
781
-
782
-
783
-    /**
784
-     * Creates a sample CSV file for importing
785
-     */
786
-    protected function _sample_export_file()
787
-    {
788
-        // require_once(EE_CLASSES . 'EE_Export.class.php');
789
-        EE_Export::instance()->export_sample();
790
-    }
791
-
792
-
793
-    /*************        Template Settings        *************/
794
-    /**
795
-     * Generates template settings page output
796
-     *
797
-     * @throws DomainException
798
-     * @throws EE_Error
799
-     */
800
-    protected function _template_settings()
801
-    {
802
-        $this->_template_args['values'] = $this->_yes_no_values;
803
-        /**
804
-         * Note leaving this filter in for backward compatibility this was moved in 4.6.x
805
-         * from General_Settings_Admin_Page to here.
806
-         */
807
-        $this->_template_args = apply_filters(
808
-            'FHEE__General_Settings_Admin_Page__template_settings__template_args',
809
-            $this->_template_args
810
-        );
811
-        $this->_set_add_edit_form_tags('update_template_settings');
812
-        $this->_set_publish_post_box_vars(null, false, false, null, false);
813
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
814
-            EVENTS_CAF_TEMPLATE_PATH . 'template_settings.template.php',
815
-            $this->_template_args,
816
-            true
817
-        );
818
-        $this->display_admin_page_with_sidebar();
819
-    }
820
-
821
-
822
-    /**
823
-     * Handler for updating template settings.
824
-     *
825
-     * @throws InvalidInterfaceException
826
-     * @throws InvalidDataTypeException
827
-     * @throws InvalidArgumentException
828
-     */
829
-    protected function _update_template_settings()
830
-    {
831
-        /**
832
-         * Note leaving this filter in for backward compatibility this was moved in 4.6.x
833
-         * from General_Settings_Admin_Page to here.
834
-         */
835
-        EE_Registry::instance()->CFG->template_settings = apply_filters(
836
-            'FHEE__General_Settings_Admin_Page__update_template_settings__data',
837
-            EE_Registry::instance()->CFG->template_settings,
838
-            $this->_req_data
839
-        );
840
-        // update custom post type slugs and detect if we need to flush rewrite rules
841
-        $old_slug = EE_Registry::instance()->CFG->core->event_cpt_slug;
842
-        EE_Registry::instance()->CFG->core->event_cpt_slug = empty($this->_req_data['event_cpt_slug'])
843
-            ? EE_Registry::instance()->CFG->core->event_cpt_slug
844
-            : EEH_URL::slugify($this->_req_data['event_cpt_slug'], 'events');
845
-        $what = 'Template Settings';
846
-        $success = $this->_update_espresso_configuration(
847
-            $what,
848
-            EE_Registry::instance()->CFG->template_settings,
849
-            __FILE__,
850
-            __FUNCTION__,
851
-            __LINE__
852
-        );
853
-        if (EE_Registry::instance()->CFG->core->event_cpt_slug != $old_slug) {
854
-            /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
855
-            $rewrite_rules = LoaderFactory::getLoader()->getShared(
856
-                'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
857
-            );
858
-            $rewrite_rules->flush();
859
-        }
860
-        $this->_redirect_after_action($success, $what, 'updated', array('action' => 'template_settings'));
861
-    }
862
-
863
-
864
-    /**
865
-     * _premium_event_editor_meta_boxes
866
-     * add all metaboxes related to the event_editor
867
-     *
868
-     * @access protected
869
-     * @return void
870
-     * @throws EE_Error
871
-     */
872
-    protected function _premium_event_editor_meta_boxes()
873
-    {
874
-        $this->verify_cpt_object();
875
-        add_meta_box(
876
-            'espresso_event_editor_event_options',
877
-            esc_html__('Event Registration Options', 'event_espresso'),
878
-            array($this, 'registration_options_meta_box'),
879
-            $this->page_slug,
880
-            'side',
881
-            'core'
882
-        );
883
-    }
884
-
885
-
886
-    /**
887
-     * override caf metabox
888
-     *
889
-     * @return void
890
-     * @throws DomainException
891
-     */
892
-    public function registration_options_meta_box()
893
-    {
894
-        $yes_no_values = array(
895
-            array('id' => true, 'text' => esc_html__('Yes', 'event_espresso')),
896
-            array('id' => false, 'text' => esc_html__('No', 'event_espresso')),
897
-        );
898
-        $default_reg_status_values = EEM_Registration::reg_status_array(
899
-            array(
900
-                EEM_Registration::status_id_cancelled,
901
-                EEM_Registration::status_id_declined,
902
-                EEM_Registration::status_id_incomplete,
903
-                EEM_Registration::status_id_wait_list,
904
-            ),
905
-            true
906
-        );
907
-        $template_args['active_status'] = $this->_cpt_model_obj->pretty_active_status(false);
908
-        $template_args['_event'] = $this->_cpt_model_obj;
909
-        $template_args['additional_limit'] = $this->_cpt_model_obj->additional_limit();
910
-        $template_args['default_registration_status'] = EEH_Form_Fields::select_input(
911
-            'default_reg_status',
912
-            $default_reg_status_values,
913
-            $this->_cpt_model_obj->default_registration_status()
914
-        );
915
-        $template_args['display_description'] = EEH_Form_Fields::select_input(
916
-            'display_desc',
917
-            $yes_no_values,
918
-            $this->_cpt_model_obj->display_description()
919
-        );
920
-        $template_args['display_ticket_selector'] = EEH_Form_Fields::select_input(
921
-            'display_ticket_selector',
922
-            $yes_no_values,
923
-            $this->_cpt_model_obj->display_ticket_selector(),
924
-            '',
925
-            '',
926
-            false
927
-        );
928
-        $template_args['EVT_default_registration_status'] = EEH_Form_Fields::select_input(
929
-            'EVT_default_registration_status',
930
-            $default_reg_status_values,
931
-            $this->_cpt_model_obj->default_registration_status()
932
-        );
933
-        $template_args['additional_registration_options'] = apply_filters(
934
-            'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
935
-            '',
936
-            $template_args,
937
-            $yes_no_values,
938
-            $default_reg_status_values
939
-        );
940
-        EEH_Template::display_template(
941
-            EVENTS_CAF_TEMPLATE_PATH . 'event_registration_options.template.php',
942
-            $template_args
943
-        );
944
-    }
945
-
946
-
947
-
948
-    /**
949
-     * wp_list_table_mods for caf
950
-     * ============================
951
-     */
952
-    /**
953
-     * hook into list table filters and provide filters for caffeinated list table
954
-     *
955
-     * @param  array $old_filters    any existing filters present
956
-     * @param  array $list_table_obj the list table object
957
-     * @return array                  new filters
958
-     */
959
-    public function list_table_filters($old_filters, $list_table_obj)
960
-    {
961
-        $filters = array();
962
-        // first month/year filters
963
-        $filters[] = $this->espresso_event_months_dropdown();
964
-        $status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
965
-        // active status dropdown
966
-        if ($status !== 'draft') {
967
-            $filters[] = $this->active_status_dropdown(
968
-                isset($this->_req_data['active_status']) ? $this->_req_data['active_status'] : ''
969
-            );
970
-        }
971
-        // category filter
972
-        $filters[] = $this->category_dropdown();
973
-        return array_merge($old_filters, $filters);
974
-    }
975
-
976
-
977
-    /**
978
-     * espresso_event_months_dropdown
979
-     *
980
-     * @access public
981
-     * @return string                dropdown listing month/year selections for events.
982
-     */
983
-    public function espresso_event_months_dropdown()
984
-    {
985
-        // what we need to do is get all PRIMARY datetimes for all events to filter on.
986
-        // Note we need to include any other filters that are set!
987
-        $status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
988
-        // categories?
989
-        $category = isset($this->_req_data['EVT_CAT']) && $this->_req_data['EVT_CAT'] > 0
990
-            ? $this->_req_data['EVT_CAT']
991
-            : null;
992
-        // active status?
993
-        $active_status = isset($this->_req_data['active_status']) ? $this->_req_data['active_status'] : null;
994
-        $cur_date = isset($this->_req_data['month_range']) ? $this->_req_data['month_range'] : '';
995
-        return EEH_Form_Fields::generate_event_months_dropdown($cur_date, $status, $category, $active_status);
996
-    }
997
-
998
-
999
-    /**
1000
-     * returns a list of "active" statuses on the event
1001
-     *
1002
-     * @param  string $current_value whatever the current active status is
1003
-     * @return string
1004
-     */
1005
-    public function active_status_dropdown($current_value = '')
1006
-    {
1007
-        $select_name = 'active_status';
1008
-        $values = array(
1009
-            'none'     => esc_html__('Show Active/Inactive', 'event_espresso'),
1010
-            'active'   => esc_html__('Active', 'event_espresso'),
1011
-            'upcoming' => esc_html__('Upcoming', 'event_espresso'),
1012
-            'expired'  => esc_html__('Expired', 'event_espresso'),
1013
-            'inactive' => esc_html__('Inactive', 'event_espresso'),
1014
-        );
1015
-        $id = 'id="espresso-active-status-dropdown-filter"';
1016
-        $class = 'wide';
1017
-        return EEH_Form_Fields::select_input($select_name, $values, $current_value, $id, $class);
1018
-    }
1019
-
1020
-
1021
-    /**
1022
-     * output a dropdown of the categories for the category filter on the event admin list table
1023
-     *
1024
-     * @access  public
1025
-     * @return string html
1026
-     */
1027
-    public function category_dropdown()
1028
-    {
1029
-        $cur_cat = isset($this->_req_data['EVT_CAT']) ? $this->_req_data['EVT_CAT'] : -1;
1030
-        return EEH_Form_Fields::generate_event_category_dropdown($cur_cat);
1031
-    }
1032
-
1033
-
1034
-    /**
1035
-     * get total number of events today
1036
-     *
1037
-     * @access public
1038
-     * @return int
1039
-     * @throws EE_Error
1040
-     */
1041
-    public function total_events_today()
1042
-    {
1043
-        $start = EEM_Datetime::instance()->convert_datetime_for_query(
1044
-            'DTT_EVT_start',
1045
-            date('Y-m-d') . ' 00:00:00',
1046
-            'Y-m-d H:i:s',
1047
-            'UTC'
1048
-        );
1049
-        $end = EEM_Datetime::instance()->convert_datetime_for_query(
1050
-            'DTT_EVT_start',
1051
-            date('Y-m-d') . ' 23:59:59',
1052
-            'Y-m-d H:i:s',
1053
-            'UTC'
1054
-        );
1055
-        $where = array(
1056
-            'Datetime.DTT_EVT_start' => array('BETWEEN', array($start, $end)),
1057
-        );
1058
-        $count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
1059
-        return $count;
1060
-    }
1061
-
1062
-
1063
-    /**
1064
-     * get total number of events this month
1065
-     *
1066
-     * @access public
1067
-     * @return int
1068
-     * @throws EE_Error
1069
-     */
1070
-    public function total_events_this_month()
1071
-    {
1072
-        // Dates
1073
-        $this_year_r = date('Y');
1074
-        $this_month_r = date('m');
1075
-        $days_this_month = date('t');
1076
-        $start = EEM_Datetime::instance()->convert_datetime_for_query(
1077
-            'DTT_EVT_start',
1078
-            $this_year_r . '-' . $this_month_r . '-01 00:00:00',
1079
-            'Y-m-d H:i:s',
1080
-            'UTC'
1081
-        );
1082
-        $end = EEM_Datetime::instance()->convert_datetime_for_query(
1083
-            'DTT_EVT_start',
1084
-            $this_year_r . '-' . $this_month_r . '-' . $days_this_month . ' 23:59:59',
1085
-            'Y-m-d H:i:s',
1086
-            'UTC'
1087
-        );
1088
-        $where = array(
1089
-            'Datetime.DTT_EVT_start' => array('BETWEEN', array($start, $end)),
1090
-        );
1091
-        $count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
1092
-        return $count;
1093
-    }
1094
-
1095
-
1096
-    /** DEFAULT TICKETS STUFF **/
1097
-
1098
-    /**
1099
-     * Output default tickets list table view.
1100
-     */
1101
-    public function _tickets_overview_list_table()
1102
-    {
1103
-        $this->_search_btn_label = esc_html__('Tickets', 'event_espresso');
1104
-        $this->display_admin_list_table_page_with_no_sidebar();
1105
-    }
1106
-
1107
-
1108
-    /**
1109
-     * @param int  $per_page
1110
-     * @param bool $count
1111
-     * @param bool $trashed
1112
-     * @return \EE_Soft_Delete_Base_Class[]|int
1113
-     */
1114
-    public function get_default_tickets($per_page = 10, $count = false, $trashed = false)
1115
-    {
1116
-        $orderby = empty($this->_req_data['orderby']) ? 'TKT_name' : $this->_req_data['orderby'];
1117
-        $order = empty($this->_req_data['order']) ? 'ASC' : $this->_req_data['order'];
1118
-        switch ($orderby) {
1119
-            case 'TKT_name':
1120
-                $orderby = array('TKT_name' => $order);
1121
-                break;
1122
-            case 'TKT_price':
1123
-                $orderby = array('TKT_price' => $order);
1124
-                break;
1125
-            case 'TKT_uses':
1126
-                $orderby = array('TKT_uses' => $order);
1127
-                break;
1128
-            case 'TKT_min':
1129
-                $orderby = array('TKT_min' => $order);
1130
-                break;
1131
-            case 'TKT_max':
1132
-                $orderby = array('TKT_max' => $order);
1133
-                break;
1134
-            case 'TKT_qty':
1135
-                $orderby = array('TKT_qty' => $order);
1136
-                break;
1137
-        }
1138
-        $current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
1139
-            ? $this->_req_data['paged']
1140
-            : 1;
1141
-        $per_page = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
1142
-            ? $this->_req_data['perpage']
1143
-            : $per_page;
1144
-        $_where = array(
1145
-            'TKT_is_default' => 1,
1146
-            'TKT_deleted'    => $trashed,
1147
-        );
1148
-        $offset = ($current_page - 1) * $per_page;
1149
-        $limit = array($offset, $per_page);
1150
-        if (isset($this->_req_data['s'])) {
1151
-            $sstr = '%' . $this->_req_data['s'] . '%';
1152
-            $_where['OR'] = array(
1153
-                'TKT_name'        => array('LIKE', $sstr),
1154
-                'TKT_description' => array('LIKE', $sstr),
1155
-            );
1156
-        }
1157
-        $query_params = array(
1158
-            $_where,
1159
-            'order_by' => $orderby,
1160
-            'limit'    => $limit,
1161
-            'group_by' => 'TKT_ID',
1162
-        );
1163
-        if ($count) {
1164
-            return EEM_Ticket::instance()->count_deleted_and_undeleted(array($_where));
1165
-        } else {
1166
-            return EEM_Ticket::instance()->get_all_deleted_and_undeleted($query_params);
1167
-        }
1168
-    }
1169
-
1170
-
1171
-    /**
1172
-     * @param bool $trash
1173
-     * @throws EE_Error
1174
-     */
1175
-    protected function _trash_or_restore_ticket($trash = false)
1176
-    {
1177
-        $success = 1;
1178
-        $TKT = EEM_Ticket::instance();
1179
-        // checkboxes?
1180
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1181
-            // if array has more than one element then success message should be plural
1182
-            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1183
-            // cycle thru the boxes
1184
-            while (list($TKT_ID, $value) = each($this->_req_data['checkbox'])) {
1185
-                if ($trash) {
1186
-                    if (! $TKT->delete_by_ID($TKT_ID)) {
1187
-                        $success = 0;
1188
-                    }
1189
-                } else {
1190
-                    if (! $TKT->restore_by_ID($TKT_ID)) {
1191
-                        $success = 0;
1192
-                    }
1193
-                }
1194
-            }
1195
-        } else {
1196
-            // grab single id and trash
1197
-            $TKT_ID = absint($this->_req_data['TKT_ID']);
1198
-            if ($trash) {
1199
-                if (! $TKT->delete_by_ID($TKT_ID)) {
1200
-                    $success = 0;
1201
-                }
1202
-            } else {
1203
-                if (! $TKT->restore_by_ID($TKT_ID)) {
1204
-                    $success = 0;
1205
-                }
1206
-            }
1207
-        }
1208
-        $action_desc = $trash ? 'moved to the trash' : 'restored';
1209
-        $query_args = array(
1210
-            'action' => 'ticket_list_table',
1211
-            'status' => $trash ? '' : 'trashed',
1212
-        );
1213
-        $this->_redirect_after_action($success, 'Tickets', $action_desc, $query_args);
1214
-    }
1215
-
1216
-
1217
-    /**
1218
-     * Handles trashing default ticket.
1219
-     */
1220
-    protected function _delete_ticket()
1221
-    {
1222
-        $success = 1;
1223
-        // checkboxes?
1224
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1225
-            // if array has more than one element then success message should be plural
1226
-            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1227
-            // cycle thru the boxes
1228
-            while (list($TKT_ID, $value) = each($this->_req_data['checkbox'])) {
1229
-                // delete
1230
-                if (! $this->_delete_the_ticket($TKT_ID)) {
1231
-                    $success = 0;
1232
-                }
1233
-            }
1234
-        } else {
1235
-            // grab single id and trash
1236
-            $TKT_ID = absint($this->_req_data['TKT_ID']);
1237
-            if (! $this->_delete_the_ticket($TKT_ID)) {
1238
-                $success = 0;
1239
-            }
1240
-        }
1241
-        $action_desc = 'deleted';
1242
-        $query_args = array(
1243
-            'action' => 'ticket_list_table',
1244
-            'status' => 'trashed',
1245
-        );
1246
-        // fail safe.  If the default ticket count === 1 then we need to redirect to event overview.
1247
-        if (EEM_Ticket::instance()->count_deleted_and_undeleted(
1248
-            array(array('TKT_is_default' => 1)),
1249
-            'TKT_ID',
1250
-            true
1251
-        )
1252
-        ) {
1253
-            $query_args = array();
1254
-        }
1255
-        $this->_redirect_after_action($success, 'Tickets', $action_desc, $query_args);
1256
-    }
1257
-
1258
-
1259
-    /**
1260
-     * @param int $TKT_ID
1261
-     * @return bool|int
1262
-     * @throws EE_Error
1263
-     */
1264
-    protected function _delete_the_ticket($TKT_ID)
1265
-    {
1266
-        $tkt = EEM_Ticket::instance()->get_one_by_ID($TKT_ID);
1267
-        $tkt->_remove_relations('Datetime');
1268
-        // delete all related prices first
1269
-        $tkt->delete_related_permanently('Price');
1270
-        return $tkt->delete_permanently();
1271
-    }
19
+	/**
20
+	 * Extend_Events_Admin_Page constructor.
21
+	 *
22
+	 * @param bool $routing
23
+	 */
24
+	public function __construct($routing = true)
25
+	{
26
+		parent::__construct($routing);
27
+		if (! defined('EVENTS_CAF_TEMPLATE_PATH')) {
28
+			define('EVENTS_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'events/templates/');
29
+			define('EVENTS_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'events/assets/');
30
+			define('EVENTS_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'events/assets/');
31
+		}
32
+	}
33
+
34
+
35
+	/**
36
+	 * Sets routes.
37
+	 */
38
+	protected function _extend_page_config()
39
+	{
40
+		$this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'events';
41
+		// is there a evt_id in the request?
42
+		$evt_id = ! empty($this->_req_data['EVT_ID']) && ! is_array($this->_req_data['EVT_ID'])
43
+			? $this->_req_data['EVT_ID']
44
+			: 0;
45
+		$evt_id = ! empty($this->_req_data['post']) ? $this->_req_data['post'] : $evt_id;
46
+		// tkt_id?
47
+		$tkt_id = ! empty($this->_req_data['TKT_ID']) && ! is_array($this->_req_data['TKT_ID'])
48
+			? $this->_req_data['TKT_ID']
49
+			: 0;
50
+		$new_page_routes = array(
51
+			'duplicate_event'          => array(
52
+				'func'       => '_duplicate_event',
53
+				'capability' => 'ee_edit_event',
54
+				'obj_id'     => $evt_id,
55
+				'noheader'   => true,
56
+			),
57
+			'ticket_list_table'        => array(
58
+				'func'       => '_tickets_overview_list_table',
59
+				'capability' => 'ee_read_default_tickets',
60
+			),
61
+			'trash_ticket'             => array(
62
+				'func'       => '_trash_or_restore_ticket',
63
+				'capability' => 'ee_delete_default_ticket',
64
+				'obj_id'     => $tkt_id,
65
+				'noheader'   => true,
66
+				'args'       => array('trash' => true),
67
+			),
68
+			'trash_tickets'            => array(
69
+				'func'       => '_trash_or_restore_ticket',
70
+				'capability' => 'ee_delete_default_tickets',
71
+				'noheader'   => true,
72
+				'args'       => array('trash' => true),
73
+			),
74
+			'restore_ticket'           => array(
75
+				'func'       => '_trash_or_restore_ticket',
76
+				'capability' => 'ee_delete_default_ticket',
77
+				'obj_id'     => $tkt_id,
78
+				'noheader'   => true,
79
+			),
80
+			'restore_tickets'          => array(
81
+				'func'       => '_trash_or_restore_ticket',
82
+				'capability' => 'ee_delete_default_tickets',
83
+				'noheader'   => true,
84
+			),
85
+			'delete_ticket'            => array(
86
+				'func'       => '_delete_ticket',
87
+				'capability' => 'ee_delete_default_ticket',
88
+				'obj_id'     => $tkt_id,
89
+				'noheader'   => true,
90
+			),
91
+			'delete_tickets'           => array(
92
+				'func'       => '_delete_ticket',
93
+				'capability' => 'ee_delete_default_tickets',
94
+				'noheader'   => true,
95
+			),
96
+			'import_page'              => array(
97
+				'func'       => '_import_page',
98
+				'capability' => 'import',
99
+			),
100
+			'import'                   => array(
101
+				'func'       => '_import_events',
102
+				'capability' => 'import',
103
+				'noheader'   => true,
104
+			),
105
+			'import_events'            => array(
106
+				'func'       => '_import_events',
107
+				'capability' => 'import',
108
+				'noheader'   => true,
109
+			),
110
+			'export_events'            => array(
111
+				'func'       => '_events_export',
112
+				'capability' => 'export',
113
+				'noheader'   => true,
114
+			),
115
+			'export_categories'        => array(
116
+				'func'       => '_categories_export',
117
+				'capability' => 'export',
118
+				'noheader'   => true,
119
+			),
120
+			'sample_export_file'       => array(
121
+				'func'       => '_sample_export_file',
122
+				'capability' => 'export',
123
+				'noheader'   => true,
124
+			),
125
+			'update_template_settings' => array(
126
+				'func'       => '_update_template_settings',
127
+				'capability' => 'manage_options',
128
+				'noheader'   => true,
129
+			),
130
+		);
131
+		$this->_page_routes = array_merge($this->_page_routes, $new_page_routes);
132
+		// partial route/config override
133
+		$this->_page_config['import_events']['metaboxes'] = $this->_default_espresso_metaboxes;
134
+		$this->_page_config['create_new']['metaboxes'][] = '_premium_event_editor_meta_boxes';
135
+		$this->_page_config['create_new']['qtips'][] = 'EE_Event_Editor_Tips';
136
+		$this->_page_config['edit']['qtips'][] = 'EE_Event_Editor_Tips';
137
+		$this->_page_config['edit']['metaboxes'][] = '_premium_event_editor_meta_boxes';
138
+		$this->_page_config['default']['list_table'] = 'Extend_Events_Admin_List_Table';
139
+		// add tickets tab but only if there are more than one default ticket!
140
+		$tkt_count = EEM_Ticket::instance()->count_deleted_and_undeleted(
141
+			array(array('TKT_is_default' => 1)),
142
+			'TKT_ID',
143
+			true
144
+		);
145
+		if ($tkt_count > 1) {
146
+			$new_page_config = array(
147
+				'ticket_list_table' => array(
148
+					'nav'           => array(
149
+						'label' => esc_html__('Default Tickets', 'event_espresso'),
150
+						'order' => 60,
151
+					),
152
+					'list_table'    => 'Tickets_List_Table',
153
+					'require_nonce' => false,
154
+				),
155
+			);
156
+		}
157
+		// template settings
158
+		$new_page_config['template_settings'] = array(
159
+			'nav'           => array(
160
+				'label' => esc_html__('Templates', 'event_espresso'),
161
+				'order' => 30,
162
+			),
163
+			'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
164
+			'help_tabs'     => array(
165
+				'general_settings_templates_help_tab' => array(
166
+					'title'    => esc_html__('Templates', 'event_espresso'),
167
+					'filename' => 'general_settings_templates',
168
+				),
169
+			),
170
+			'help_tour'     => array('Templates_Help_Tour'),
171
+			'require_nonce' => false,
172
+		);
173
+		$this->_page_config = array_merge($this->_page_config, $new_page_config);
174
+		// add filters and actions
175
+		// modifying _views
176
+		add_filter(
177
+			'FHEE_event_datetime_metabox_add_additional_date_time_template',
178
+			array($this, 'add_additional_datetime_button'),
179
+			10,
180
+			2
181
+		);
182
+		add_filter(
183
+			'FHEE_event_datetime_metabox_clone_button_template',
184
+			array($this, 'add_datetime_clone_button'),
185
+			10,
186
+			2
187
+		);
188
+		add_filter(
189
+			'FHEE_event_datetime_metabox_timezones_template',
190
+			array($this, 'datetime_timezones_template'),
191
+			10,
192
+			2
193
+		);
194
+		// filters for event list table
195
+		add_filter('FHEE__Extend_Events_Admin_List_Table__filters', array($this, 'list_table_filters'), 10, 2);
196
+		add_filter(
197
+			'FHEE__Events_Admin_List_Table__column_actions__action_links',
198
+			array($this, 'extra_list_table_actions'),
199
+			10,
200
+			2
201
+		);
202
+		// legend item
203
+		add_filter('FHEE__Events_Admin_Page___event_legend_items__items', array($this, 'additional_legend_items'));
204
+		add_action('admin_init', array($this, 'admin_init'));
205
+	}
206
+
207
+
208
+	/**
209
+	 * admin_init
210
+	 */
211
+	public function admin_init()
212
+	{
213
+		EE_Registry::$i18n_js_strings = array_merge(
214
+			EE_Registry::$i18n_js_strings,
215
+			array(
216
+				'image_confirm'          => esc_html__(
217
+					'Do you really want to delete this image? Please remember to update your event to complete the removal.',
218
+					'event_espresso'
219
+				),
220
+				'event_starts_on'        => esc_html__('Event Starts on', 'event_espresso'),
221
+				'event_ends_on'          => esc_html__('Event Ends on', 'event_espresso'),
222
+				'event_datetime_actions' => esc_html__('Actions', 'event_espresso'),
223
+				'event_clone_dt_msg'     => esc_html__('Clone this Event Date and Time', 'event_espresso'),
224
+				'remove_event_dt_msg'    => esc_html__('Remove this Event Time', 'event_espresso'),
225
+			)
226
+		);
227
+	}
228
+
229
+
230
+	/**
231
+	 * Add per page screen options to the default ticket list table view.
232
+	 */
233
+	protected function _add_screen_options_ticket_list_table()
234
+	{
235
+		$this->_per_page_screen_option();
236
+	}
237
+
238
+
239
+	/**
240
+	 * @param string $return
241
+	 * @param int    $id
242
+	 * @param string $new_title
243
+	 * @param string $new_slug
244
+	 * @return string
245
+	 */
246
+	public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
247
+	{
248
+		$return = parent::extra_permalink_field_buttons($return, $id, $new_title, $new_slug);
249
+		// make sure this is only when editing
250
+		if (! empty($id)) {
251
+			$href = EE_Admin_Page::add_query_args_and_nonce(
252
+				array('action' => 'duplicate_event', 'EVT_ID' => $id),
253
+				$this->_admin_base_url
254
+			);
255
+			$title = esc_attr__('Duplicate Event', 'event_espresso');
256
+			$return .= '<a href="'
257
+					   . $href
258
+					   . '" title="'
259
+					   . $title
260
+					   . '" id="ee-duplicate-event-button" class="button button-small"  value="duplicate_event">'
261
+					   . $title
262
+					   . '</a>';
263
+		}
264
+		return $return;
265
+	}
266
+
267
+
268
+	/**
269
+	 * Set the list table views for the default ticket list table view.
270
+	 */
271
+	public function _set_list_table_views_ticket_list_table()
272
+	{
273
+		$this->_views = array(
274
+			'all'     => array(
275
+				'slug'        => 'all',
276
+				'label'       => esc_html__('All', 'event_espresso'),
277
+				'count'       => 0,
278
+				'bulk_action' => array(
279
+					'trash_tickets' => esc_html__('Move to Trash', 'event_espresso'),
280
+				),
281
+			),
282
+			'trashed' => array(
283
+				'slug'        => 'trashed',
284
+				'label'       => esc_html__('Trash', 'event_espresso'),
285
+				'count'       => 0,
286
+				'bulk_action' => array(
287
+					'restore_tickets' => esc_html__('Restore from Trash', 'event_espresso'),
288
+					'delete_tickets'  => esc_html__('Delete Permanently', 'event_espresso'),
289
+				),
290
+			),
291
+		);
292
+	}
293
+
294
+
295
+	/**
296
+	 * Enqueue scripts and styles for the event editor.
297
+	 */
298
+	public function load_scripts_styles_edit()
299
+	{
300
+		wp_register_script(
301
+			'ee-event-editor-heartbeat',
302
+			EVENTS_CAF_ASSETS_URL . 'event-editor-heartbeat.js',
303
+			array('ee_admin_js', 'heartbeat'),
304
+			EVENT_ESPRESSO_VERSION,
305
+			true
306
+		);
307
+		wp_enqueue_script('ee-accounting');
308
+		// styles
309
+		wp_enqueue_style('espresso-ui-theme');
310
+		wp_enqueue_script('event_editor_js');
311
+		wp_enqueue_script('ee-event-editor-heartbeat');
312
+	}
313
+
314
+
315
+	/**
316
+	 * Returns template for the additional datetime.
317
+	 *
318
+	 * @param $template
319
+	 * @param $template_args
320
+	 * @return mixed
321
+	 * @throws DomainException
322
+	 */
323
+	public function add_additional_datetime_button($template, $template_args)
324
+	{
325
+		return EEH_Template::display_template(
326
+			EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_add_additional_time.template.php',
327
+			$template_args,
328
+			true
329
+		);
330
+	}
331
+
332
+
333
+	/**
334
+	 * Returns the template for cloning a datetime.
335
+	 *
336
+	 * @param $template
337
+	 * @param $template_args
338
+	 * @return mixed
339
+	 * @throws DomainException
340
+	 */
341
+	public function add_datetime_clone_button($template, $template_args)
342
+	{
343
+		return EEH_Template::display_template(
344
+			EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_metabox_clone_button.template.php',
345
+			$template_args,
346
+			true
347
+		);
348
+	}
349
+
350
+
351
+	/**
352
+	 * Returns the template for datetime timezones.
353
+	 *
354
+	 * @param $template
355
+	 * @param $template_args
356
+	 * @return mixed
357
+	 * @throws DomainException
358
+	 */
359
+	public function datetime_timezones_template($template, $template_args)
360
+	{
361
+		return EEH_Template::display_template(
362
+			EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_timezones.template.php',
363
+			$template_args,
364
+			true
365
+		);
366
+	}
367
+
368
+
369
+	/**
370
+	 * Sets the views for the default list table view.
371
+	 */
372
+	protected function _set_list_table_views_default()
373
+	{
374
+		parent::_set_list_table_views_default();
375
+		$new_views = array(
376
+			'today' => array(
377
+				'slug'        => 'today',
378
+				'label'       => esc_html__('Today', 'event_espresso'),
379
+				'count'       => $this->total_events_today(),
380
+				'bulk_action' => array(
381
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
382
+				),
383
+			),
384
+			'month' => array(
385
+				'slug'        => 'month',
386
+				'label'       => esc_html__('This Month', 'event_espresso'),
387
+				'count'       => $this->total_events_this_month(),
388
+				'bulk_action' => array(
389
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
390
+				),
391
+			),
392
+		);
393
+		$this->_views = array_merge($this->_views, $new_views);
394
+	}
395
+
396
+
397
+	/**
398
+	 * Returns the extra action links for the default list table view.
399
+	 *
400
+	 * @param array     $action_links
401
+	 * @param \EE_Event $event
402
+	 * @return array
403
+	 * @throws EE_Error
404
+	 */
405
+	public function extra_list_table_actions(array $action_links, \EE_Event $event)
406
+	{
407
+		if (EE_Registry::instance()->CAP->current_user_can(
408
+			'ee_read_registrations',
409
+			'espresso_registrations_reports',
410
+			$event->ID()
411
+		)
412
+		) {
413
+			$reports_query_args = array(
414
+				'action' => 'reports',
415
+				'EVT_ID' => $event->ID(),
416
+			);
417
+			$reports_link = EE_Admin_Page::add_query_args_and_nonce($reports_query_args, REG_ADMIN_URL);
418
+			$action_links[] = '<a href="'
419
+							  . $reports_link
420
+							  . '" title="'
421
+							  . esc_attr__('View Report', 'event_espresso')
422
+							  . '"><div class="dashicons dashicons-chart-bar"></div></a>'
423
+							  . "\n\t";
424
+		}
425
+		if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
426
+			EE_Registry::instance()->load_helper('MSG_Template');
427
+			$action_links[] = EEH_MSG_Template::get_message_action_link(
428
+				'see_notifications_for',
429
+				null,
430
+				array('EVT_ID' => $event->ID())
431
+			);
432
+		}
433
+		return $action_links;
434
+	}
435
+
436
+
437
+	/**
438
+	 * @param $items
439
+	 * @return mixed
440
+	 */
441
+	public function additional_legend_items($items)
442
+	{
443
+		if (EE_Registry::instance()->CAP->current_user_can(
444
+			'ee_read_registrations',
445
+			'espresso_registrations_reports'
446
+		)
447
+		) {
448
+			$items['reports'] = array(
449
+				'class' => 'dashicons dashicons-chart-bar',
450
+				'desc'  => esc_html__('Event Reports', 'event_espresso'),
451
+			);
452
+		}
453
+		if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
454
+			$related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
455
+			if (isset($related_for_icon['css_class']) && isset($related_for_icon['label'])) {
456
+				$items['view_related_messages'] = array(
457
+					'class' => $related_for_icon['css_class'],
458
+					'desc'  => $related_for_icon['label'],
459
+				);
460
+			}
461
+		}
462
+		return $items;
463
+	}
464
+
465
+
466
+	/**
467
+	 * This is the callback method for the duplicate event route
468
+	 * Method looks for 'EVT_ID' in the request and retrieves that event and its details and duplicates them
469
+	 * into a new event.  We add a hook so that any plugins that add extra event details can hook into this
470
+	 * action.  Note that the dupe will have **DUPLICATE** as its title and slug.
471
+	 * After duplication the redirect is to the new event edit page.
472
+	 *
473
+	 * @return void
474
+	 * @access protected
475
+	 * @throws EE_Error If EE_Event is not available with given ID
476
+	 */
477
+	protected function _duplicate_event()
478
+	{
479
+		// first make sure the ID for the event is in the request.
480
+		//  If it isn't then we need to bail and redirect back to overview list table (cause how did we get here?)
481
+		if (! isset($this->_req_data['EVT_ID'])) {
482
+			EE_Error::add_error(
483
+				esc_html__(
484
+					'In order to duplicate an event an Event ID is required.  None was given.',
485
+					'event_espresso'
486
+				),
487
+				__FILE__,
488
+				__FUNCTION__,
489
+				__LINE__
490
+			);
491
+			$this->_redirect_after_action(false, '', '', array(), true);
492
+			return;
493
+		}
494
+		// k we've got EVT_ID so let's use that to get the event we'll duplicate
495
+		$orig_event = EEM_Event::instance()->get_one_by_ID($this->_req_data['EVT_ID']);
496
+		if (! $orig_event instanceof EE_Event) {
497
+			throw new EE_Error(
498
+				sprintf(
499
+					esc_html__('An EE_Event object could not be retrieved for the given ID (%s)', 'event_espresso'),
500
+					$this->_req_data['EVT_ID']
501
+				)
502
+			);
503
+		}
504
+		// k now let's clone the $orig_event before getting relations
505
+		$new_event = clone $orig_event;
506
+		// original datetimes
507
+		$orig_datetimes = $orig_event->get_many_related('Datetime');
508
+		// other original relations
509
+		$orig_ven = $orig_event->get_many_related('Venue');
510
+		// reset the ID and modify other details to make it clear this is a dupe
511
+		$new_event->set('EVT_ID', 0);
512
+		$new_name = $new_event->name() . ' ' . esc_html__('**DUPLICATE**', 'event_espresso');
513
+		$new_event->set('EVT_name', $new_name);
514
+		$new_event->set(
515
+			'EVT_slug',
516
+			wp_unique_post_slug(
517
+				sanitize_title($orig_event->name()),
518
+				0,
519
+				'publish',
520
+				'espresso_events',
521
+				0
522
+			)
523
+		);
524
+		$new_event->set('status', 'draft');
525
+		// duplicate discussion settings
526
+		$new_event->set('comment_status', $orig_event->get('comment_status'));
527
+		$new_event->set('ping_status', $orig_event->get('ping_status'));
528
+		// save the new event
529
+		$new_event->save();
530
+		// venues
531
+		foreach ($orig_ven as $ven) {
532
+			$new_event->_add_relation_to($ven, 'Venue');
533
+		}
534
+		$new_event->save();
535
+		// now we need to get the question group relations and handle that
536
+		// first primary question groups
537
+		$orig_primary_qgs = $orig_event->get_many_related(
538
+			'Question_Group',
539
+			array(array('Event_Question_Group.EQG_primary' => 1))
540
+		);
541
+		if (! empty($orig_primary_qgs)) {
542
+			foreach ($orig_primary_qgs as $id => $obj) {
543
+				if ($obj instanceof EE_Question_Group) {
544
+					$new_event->_add_relation_to($obj, 'Question_Group', array('EQG_primary' => 1));
545
+				}
546
+			}
547
+		}
548
+		// next additional attendee question groups
549
+		$orig_additional_qgs = $orig_event->get_many_related(
550
+			'Question_Group',
551
+			array(array('Event_Question_Group.EQG_primary' => 0))
552
+		);
553
+		if (! empty($orig_additional_qgs)) {
554
+			foreach ($orig_additional_qgs as $id => $obj) {
555
+				if ($obj instanceof EE_Question_Group) {
556
+					$new_event->_add_relation_to($obj, 'Question_Group', array('EQG_primary' => 0));
557
+				}
558
+			}
559
+		}
560
+
561
+		$new_event->save();
562
+
563
+		// k now that we have the new event saved we can loop through the datetimes and start adding relations.
564
+		$cloned_tickets = array();
565
+		foreach ($orig_datetimes as $orig_dtt) {
566
+			if (! $orig_dtt instanceof EE_Datetime) {
567
+				continue;
568
+			}
569
+			$new_dtt = clone $orig_dtt;
570
+			$orig_tkts = $orig_dtt->tickets();
571
+			// save new dtt then add to event
572
+			$new_dtt->set('DTT_ID', 0);
573
+			$new_dtt->set('DTT_sold', 0);
574
+			$new_dtt->set_reserved(0);
575
+			$new_dtt->save();
576
+			$new_event->_add_relation_to($new_dtt, 'Datetime');
577
+			$new_event->save();
578
+			// now let's get the ticket relations setup.
579
+			foreach ((array) $orig_tkts as $orig_tkt) {
580
+				// it's possible a datetime will have no tickets so let's verify we HAVE a ticket first.
581
+				if (! $orig_tkt instanceof EE_Ticket) {
582
+					continue;
583
+				}
584
+				// is this ticket archived?  If it is then let's skip
585
+				if ($orig_tkt->get('TKT_deleted')) {
586
+					continue;
587
+				}
588
+				// does this original ticket already exist in the clone_tickets cache?
589
+				//  If so we'll just use the new ticket from it.
590
+				if (isset($cloned_tickets[ $orig_tkt->ID() ])) {
591
+					$new_tkt = $cloned_tickets[ $orig_tkt->ID() ];
592
+				} else {
593
+					$new_tkt = clone $orig_tkt;
594
+					// get relations on the $orig_tkt that we need to setup.
595
+					$orig_prices = $orig_tkt->prices();
596
+					$new_tkt->set('TKT_ID', 0);
597
+					$new_tkt->set('TKT_sold', 0);
598
+					$new_tkt->set('TKT_reserved', 0);
599
+					$new_tkt->save(); // make sure new ticket has ID.
600
+					// price relations on new ticket need to be setup.
601
+					foreach ($orig_prices as $orig_price) {
602
+						$new_price = clone $orig_price;
603
+						$new_price->set('PRC_ID', 0);
604
+						$new_price->save();
605
+						$new_tkt->_add_relation_to($new_price, 'Price');
606
+						$new_tkt->save();
607
+					}
608
+
609
+					do_action(
610
+						'AHEE__Extend_Events_Admin_Page___duplicate_event__duplicate_ticket__after',
611
+						$orig_tkt,
612
+						$new_tkt,
613
+						$orig_prices,
614
+						$orig_event,
615
+						$orig_dtt,
616
+						$new_dtt
617
+					);
618
+				}
619
+				// k now we can add the new ticket as a relation to the new datetime
620
+				// and make sure its added to our cached $cloned_tickets array
621
+				// for use with later datetimes that have the same ticket.
622
+				$new_dtt->_add_relation_to($new_tkt, 'Ticket');
623
+				$new_dtt->save();
624
+				$cloned_tickets[ $orig_tkt->ID() ] = $new_tkt;
625
+			}
626
+		}
627
+		// clone taxonomy information
628
+		$taxonomies_to_clone_with = apply_filters(
629
+			'FHEE__Extend_Events_Admin_Page___duplicate_event__taxonomies_to_clone',
630
+			array('espresso_event_categories', 'espresso_event_type', 'post_tag')
631
+		);
632
+		// get terms for original event (notice)
633
+		$orig_terms = wp_get_object_terms($orig_event->ID(), $taxonomies_to_clone_with);
634
+		// loop through terms and add them to new event.
635
+		foreach ($orig_terms as $term) {
636
+			wp_set_object_terms($new_event->ID(), $term->term_id, $term->taxonomy, true);
637
+		}
638
+
639
+		// duplicate other core WP_Post items for this event.
640
+		// post thumbnail (feature image).
641
+		$feature_image_id = get_post_thumbnail_id($orig_event->ID());
642
+		if ($feature_image_id) {
643
+			update_post_meta($new_event->ID(), '_thumbnail_id', $feature_image_id);
644
+		}
645
+
646
+		// duplicate page_template setting
647
+		$page_template = get_post_meta($orig_event->ID(), '_wp_page_template', true);
648
+		if ($page_template) {
649
+			update_post_meta($new_event->ID(), '_wp_page_template', $page_template);
650
+		}
651
+
652
+		do_action('AHEE__Extend_Events_Admin_Page___duplicate_event__after', $new_event, $orig_event);
653
+		// now let's redirect to the edit page for this duplicated event if we have a new event id.
654
+		if ($new_event->ID()) {
655
+			$redirect_args = array(
656
+				'post'   => $new_event->ID(),
657
+				'action' => 'edit',
658
+			);
659
+			EE_Error::add_success(
660
+				esc_html__(
661
+					'Event successfully duplicated.  Please review the details below and make any necessary edits',
662
+					'event_espresso'
663
+				)
664
+			);
665
+		} else {
666
+			$redirect_args = array(
667
+				'action' => 'default',
668
+			);
669
+			EE_Error::add_error(
670
+				esc_html__('Not able to duplicate event.  Something went wrong.', 'event_espresso'),
671
+				__FILE__,
672
+				__FUNCTION__,
673
+				__LINE__
674
+			);
675
+		}
676
+		$this->_redirect_after_action(false, '', '', $redirect_args, true);
677
+	}
678
+
679
+
680
+	/**
681
+	 * Generates output for the import page.
682
+	 *
683
+	 * @throws DomainException
684
+	 */
685
+	protected function _import_page()
686
+	{
687
+		$title = esc_html__('Import', 'event_espresso');
688
+		$intro = esc_html__(
689
+			'If you have a previously exported Event Espresso 4 information in a Comma Separated Value (CSV) file format, you can upload the file here: ',
690
+			'event_espresso'
691
+		);
692
+		$form_url = EVENTS_ADMIN_URL;
693
+		$action = 'import_events';
694
+		$type = 'csv';
695
+		$this->_template_args['form'] = EE_Import::instance()->upload_form(
696
+			$title,
697
+			$intro,
698
+			$form_url,
699
+			$action,
700
+			$type
701
+		);
702
+		$this->_template_args['sample_file_link'] = EE_Admin_Page::add_query_args_and_nonce(
703
+			array('action' => 'sample_export_file'),
704
+			$this->_admin_base_url
705
+		);
706
+		$content = EEH_Template::display_template(
707
+			EVENTS_CAF_TEMPLATE_PATH . 'import_page.template.php',
708
+			$this->_template_args,
709
+			true
710
+		);
711
+		$this->_template_args['admin_page_content'] = $content;
712
+		$this->display_admin_page_with_sidebar();
713
+	}
714
+
715
+
716
+	/**
717
+	 * _import_events
718
+	 * This handles displaying the screen and running imports for importing events.
719
+	 *
720
+	 * @return void
721
+	 */
722
+	protected function _import_events()
723
+	{
724
+		require_once(EE_CLASSES . 'EE_Import.class.php');
725
+		$success = EE_Import::instance()->import();
726
+		$this->_redirect_after_action($success, 'Import File', 'ran', array('action' => 'import_page'), true);
727
+	}
728
+
729
+
730
+	/**
731
+	 * _events_export
732
+	 * Will export all (or just the given event) to a Excel compatible file.
733
+	 *
734
+	 * @access protected
735
+	 * @return void
736
+	 */
737
+	protected function _events_export()
738
+	{
739
+		if (isset($this->_req_data['EVT_ID'])) {
740
+			$event_ids = $this->_req_data['EVT_ID'];
741
+		} elseif (isset($this->_req_data['EVT_IDs'])) {
742
+			$event_ids = $this->_req_data['EVT_IDs'];
743
+		} else {
744
+			$event_ids = null;
745
+		}
746
+		// todo: I don't like doing this but it'll do until we modify EE_Export Class.
747
+		$new_request_args = array(
748
+			'export' => 'report',
749
+			'action' => 'all_event_data',
750
+			'EVT_ID' => $event_ids,
751
+		);
752
+		$this->_req_data = array_merge($this->_req_data, $new_request_args);
753
+		if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
754
+			require_once(EE_CLASSES . 'EE_Export.class.php');
755
+			$EE_Export = EE_Export::instance($this->_req_data);
756
+			$EE_Export->export();
757
+		}
758
+	}
759
+
760
+
761
+	/**
762
+	 * handle category exports()
763
+	 *
764
+	 * @return void
765
+	 */
766
+	protected function _categories_export()
767
+	{
768
+		// todo: I don't like doing this but it'll do until we modify EE_Export Class.
769
+		$new_request_args = array(
770
+			'export'       => 'report',
771
+			'action'       => 'categories',
772
+			'category_ids' => $this->_req_data['EVT_CAT_ID'],
773
+		);
774
+		$this->_req_data = array_merge($this->_req_data, $new_request_args);
775
+		if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
776
+			require_once(EE_CLASSES . 'EE_Export.class.php');
777
+			$EE_Export = EE_Export::instance($this->_req_data);
778
+			$EE_Export->export();
779
+		}
780
+	}
781
+
782
+
783
+	/**
784
+	 * Creates a sample CSV file for importing
785
+	 */
786
+	protected function _sample_export_file()
787
+	{
788
+		// require_once(EE_CLASSES . 'EE_Export.class.php');
789
+		EE_Export::instance()->export_sample();
790
+	}
791
+
792
+
793
+	/*************        Template Settings        *************/
794
+	/**
795
+	 * Generates template settings page output
796
+	 *
797
+	 * @throws DomainException
798
+	 * @throws EE_Error
799
+	 */
800
+	protected function _template_settings()
801
+	{
802
+		$this->_template_args['values'] = $this->_yes_no_values;
803
+		/**
804
+		 * Note leaving this filter in for backward compatibility this was moved in 4.6.x
805
+		 * from General_Settings_Admin_Page to here.
806
+		 */
807
+		$this->_template_args = apply_filters(
808
+			'FHEE__General_Settings_Admin_Page__template_settings__template_args',
809
+			$this->_template_args
810
+		);
811
+		$this->_set_add_edit_form_tags('update_template_settings');
812
+		$this->_set_publish_post_box_vars(null, false, false, null, false);
813
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
814
+			EVENTS_CAF_TEMPLATE_PATH . 'template_settings.template.php',
815
+			$this->_template_args,
816
+			true
817
+		);
818
+		$this->display_admin_page_with_sidebar();
819
+	}
820
+
821
+
822
+	/**
823
+	 * Handler for updating template settings.
824
+	 *
825
+	 * @throws InvalidInterfaceException
826
+	 * @throws InvalidDataTypeException
827
+	 * @throws InvalidArgumentException
828
+	 */
829
+	protected function _update_template_settings()
830
+	{
831
+		/**
832
+		 * Note leaving this filter in for backward compatibility this was moved in 4.6.x
833
+		 * from General_Settings_Admin_Page to here.
834
+		 */
835
+		EE_Registry::instance()->CFG->template_settings = apply_filters(
836
+			'FHEE__General_Settings_Admin_Page__update_template_settings__data',
837
+			EE_Registry::instance()->CFG->template_settings,
838
+			$this->_req_data
839
+		);
840
+		// update custom post type slugs and detect if we need to flush rewrite rules
841
+		$old_slug = EE_Registry::instance()->CFG->core->event_cpt_slug;
842
+		EE_Registry::instance()->CFG->core->event_cpt_slug = empty($this->_req_data['event_cpt_slug'])
843
+			? EE_Registry::instance()->CFG->core->event_cpt_slug
844
+			: EEH_URL::slugify($this->_req_data['event_cpt_slug'], 'events');
845
+		$what = 'Template Settings';
846
+		$success = $this->_update_espresso_configuration(
847
+			$what,
848
+			EE_Registry::instance()->CFG->template_settings,
849
+			__FILE__,
850
+			__FUNCTION__,
851
+			__LINE__
852
+		);
853
+		if (EE_Registry::instance()->CFG->core->event_cpt_slug != $old_slug) {
854
+			/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
855
+			$rewrite_rules = LoaderFactory::getLoader()->getShared(
856
+				'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
857
+			);
858
+			$rewrite_rules->flush();
859
+		}
860
+		$this->_redirect_after_action($success, $what, 'updated', array('action' => 'template_settings'));
861
+	}
862
+
863
+
864
+	/**
865
+	 * _premium_event_editor_meta_boxes
866
+	 * add all metaboxes related to the event_editor
867
+	 *
868
+	 * @access protected
869
+	 * @return void
870
+	 * @throws EE_Error
871
+	 */
872
+	protected function _premium_event_editor_meta_boxes()
873
+	{
874
+		$this->verify_cpt_object();
875
+		add_meta_box(
876
+			'espresso_event_editor_event_options',
877
+			esc_html__('Event Registration Options', 'event_espresso'),
878
+			array($this, 'registration_options_meta_box'),
879
+			$this->page_slug,
880
+			'side',
881
+			'core'
882
+		);
883
+	}
884
+
885
+
886
+	/**
887
+	 * override caf metabox
888
+	 *
889
+	 * @return void
890
+	 * @throws DomainException
891
+	 */
892
+	public function registration_options_meta_box()
893
+	{
894
+		$yes_no_values = array(
895
+			array('id' => true, 'text' => esc_html__('Yes', 'event_espresso')),
896
+			array('id' => false, 'text' => esc_html__('No', 'event_espresso')),
897
+		);
898
+		$default_reg_status_values = EEM_Registration::reg_status_array(
899
+			array(
900
+				EEM_Registration::status_id_cancelled,
901
+				EEM_Registration::status_id_declined,
902
+				EEM_Registration::status_id_incomplete,
903
+				EEM_Registration::status_id_wait_list,
904
+			),
905
+			true
906
+		);
907
+		$template_args['active_status'] = $this->_cpt_model_obj->pretty_active_status(false);
908
+		$template_args['_event'] = $this->_cpt_model_obj;
909
+		$template_args['additional_limit'] = $this->_cpt_model_obj->additional_limit();
910
+		$template_args['default_registration_status'] = EEH_Form_Fields::select_input(
911
+			'default_reg_status',
912
+			$default_reg_status_values,
913
+			$this->_cpt_model_obj->default_registration_status()
914
+		);
915
+		$template_args['display_description'] = EEH_Form_Fields::select_input(
916
+			'display_desc',
917
+			$yes_no_values,
918
+			$this->_cpt_model_obj->display_description()
919
+		);
920
+		$template_args['display_ticket_selector'] = EEH_Form_Fields::select_input(
921
+			'display_ticket_selector',
922
+			$yes_no_values,
923
+			$this->_cpt_model_obj->display_ticket_selector(),
924
+			'',
925
+			'',
926
+			false
927
+		);
928
+		$template_args['EVT_default_registration_status'] = EEH_Form_Fields::select_input(
929
+			'EVT_default_registration_status',
930
+			$default_reg_status_values,
931
+			$this->_cpt_model_obj->default_registration_status()
932
+		);
933
+		$template_args['additional_registration_options'] = apply_filters(
934
+			'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
935
+			'',
936
+			$template_args,
937
+			$yes_no_values,
938
+			$default_reg_status_values
939
+		);
940
+		EEH_Template::display_template(
941
+			EVENTS_CAF_TEMPLATE_PATH . 'event_registration_options.template.php',
942
+			$template_args
943
+		);
944
+	}
945
+
946
+
947
+
948
+	/**
949
+	 * wp_list_table_mods for caf
950
+	 * ============================
951
+	 */
952
+	/**
953
+	 * hook into list table filters and provide filters for caffeinated list table
954
+	 *
955
+	 * @param  array $old_filters    any existing filters present
956
+	 * @param  array $list_table_obj the list table object
957
+	 * @return array                  new filters
958
+	 */
959
+	public function list_table_filters($old_filters, $list_table_obj)
960
+	{
961
+		$filters = array();
962
+		// first month/year filters
963
+		$filters[] = $this->espresso_event_months_dropdown();
964
+		$status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
965
+		// active status dropdown
966
+		if ($status !== 'draft') {
967
+			$filters[] = $this->active_status_dropdown(
968
+				isset($this->_req_data['active_status']) ? $this->_req_data['active_status'] : ''
969
+			);
970
+		}
971
+		// category filter
972
+		$filters[] = $this->category_dropdown();
973
+		return array_merge($old_filters, $filters);
974
+	}
975
+
976
+
977
+	/**
978
+	 * espresso_event_months_dropdown
979
+	 *
980
+	 * @access public
981
+	 * @return string                dropdown listing month/year selections for events.
982
+	 */
983
+	public function espresso_event_months_dropdown()
984
+	{
985
+		// what we need to do is get all PRIMARY datetimes for all events to filter on.
986
+		// Note we need to include any other filters that are set!
987
+		$status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
988
+		// categories?
989
+		$category = isset($this->_req_data['EVT_CAT']) && $this->_req_data['EVT_CAT'] > 0
990
+			? $this->_req_data['EVT_CAT']
991
+			: null;
992
+		// active status?
993
+		$active_status = isset($this->_req_data['active_status']) ? $this->_req_data['active_status'] : null;
994
+		$cur_date = isset($this->_req_data['month_range']) ? $this->_req_data['month_range'] : '';
995
+		return EEH_Form_Fields::generate_event_months_dropdown($cur_date, $status, $category, $active_status);
996
+	}
997
+
998
+
999
+	/**
1000
+	 * returns a list of "active" statuses on the event
1001
+	 *
1002
+	 * @param  string $current_value whatever the current active status is
1003
+	 * @return string
1004
+	 */
1005
+	public function active_status_dropdown($current_value = '')
1006
+	{
1007
+		$select_name = 'active_status';
1008
+		$values = array(
1009
+			'none'     => esc_html__('Show Active/Inactive', 'event_espresso'),
1010
+			'active'   => esc_html__('Active', 'event_espresso'),
1011
+			'upcoming' => esc_html__('Upcoming', 'event_espresso'),
1012
+			'expired'  => esc_html__('Expired', 'event_espresso'),
1013
+			'inactive' => esc_html__('Inactive', 'event_espresso'),
1014
+		);
1015
+		$id = 'id="espresso-active-status-dropdown-filter"';
1016
+		$class = 'wide';
1017
+		return EEH_Form_Fields::select_input($select_name, $values, $current_value, $id, $class);
1018
+	}
1019
+
1020
+
1021
+	/**
1022
+	 * output a dropdown of the categories for the category filter on the event admin list table
1023
+	 *
1024
+	 * @access  public
1025
+	 * @return string html
1026
+	 */
1027
+	public function category_dropdown()
1028
+	{
1029
+		$cur_cat = isset($this->_req_data['EVT_CAT']) ? $this->_req_data['EVT_CAT'] : -1;
1030
+		return EEH_Form_Fields::generate_event_category_dropdown($cur_cat);
1031
+	}
1032
+
1033
+
1034
+	/**
1035
+	 * get total number of events today
1036
+	 *
1037
+	 * @access public
1038
+	 * @return int
1039
+	 * @throws EE_Error
1040
+	 */
1041
+	public function total_events_today()
1042
+	{
1043
+		$start = EEM_Datetime::instance()->convert_datetime_for_query(
1044
+			'DTT_EVT_start',
1045
+			date('Y-m-d') . ' 00:00:00',
1046
+			'Y-m-d H:i:s',
1047
+			'UTC'
1048
+		);
1049
+		$end = EEM_Datetime::instance()->convert_datetime_for_query(
1050
+			'DTT_EVT_start',
1051
+			date('Y-m-d') . ' 23:59:59',
1052
+			'Y-m-d H:i:s',
1053
+			'UTC'
1054
+		);
1055
+		$where = array(
1056
+			'Datetime.DTT_EVT_start' => array('BETWEEN', array($start, $end)),
1057
+		);
1058
+		$count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
1059
+		return $count;
1060
+	}
1061
+
1062
+
1063
+	/**
1064
+	 * get total number of events this month
1065
+	 *
1066
+	 * @access public
1067
+	 * @return int
1068
+	 * @throws EE_Error
1069
+	 */
1070
+	public function total_events_this_month()
1071
+	{
1072
+		// Dates
1073
+		$this_year_r = date('Y');
1074
+		$this_month_r = date('m');
1075
+		$days_this_month = date('t');
1076
+		$start = EEM_Datetime::instance()->convert_datetime_for_query(
1077
+			'DTT_EVT_start',
1078
+			$this_year_r . '-' . $this_month_r . '-01 00:00:00',
1079
+			'Y-m-d H:i:s',
1080
+			'UTC'
1081
+		);
1082
+		$end = EEM_Datetime::instance()->convert_datetime_for_query(
1083
+			'DTT_EVT_start',
1084
+			$this_year_r . '-' . $this_month_r . '-' . $days_this_month . ' 23:59:59',
1085
+			'Y-m-d H:i:s',
1086
+			'UTC'
1087
+		);
1088
+		$where = array(
1089
+			'Datetime.DTT_EVT_start' => array('BETWEEN', array($start, $end)),
1090
+		);
1091
+		$count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
1092
+		return $count;
1093
+	}
1094
+
1095
+
1096
+	/** DEFAULT TICKETS STUFF **/
1097
+
1098
+	/**
1099
+	 * Output default tickets list table view.
1100
+	 */
1101
+	public function _tickets_overview_list_table()
1102
+	{
1103
+		$this->_search_btn_label = esc_html__('Tickets', 'event_espresso');
1104
+		$this->display_admin_list_table_page_with_no_sidebar();
1105
+	}
1106
+
1107
+
1108
+	/**
1109
+	 * @param int  $per_page
1110
+	 * @param bool $count
1111
+	 * @param bool $trashed
1112
+	 * @return \EE_Soft_Delete_Base_Class[]|int
1113
+	 */
1114
+	public function get_default_tickets($per_page = 10, $count = false, $trashed = false)
1115
+	{
1116
+		$orderby = empty($this->_req_data['orderby']) ? 'TKT_name' : $this->_req_data['orderby'];
1117
+		$order = empty($this->_req_data['order']) ? 'ASC' : $this->_req_data['order'];
1118
+		switch ($orderby) {
1119
+			case 'TKT_name':
1120
+				$orderby = array('TKT_name' => $order);
1121
+				break;
1122
+			case 'TKT_price':
1123
+				$orderby = array('TKT_price' => $order);
1124
+				break;
1125
+			case 'TKT_uses':
1126
+				$orderby = array('TKT_uses' => $order);
1127
+				break;
1128
+			case 'TKT_min':
1129
+				$orderby = array('TKT_min' => $order);
1130
+				break;
1131
+			case 'TKT_max':
1132
+				$orderby = array('TKT_max' => $order);
1133
+				break;
1134
+			case 'TKT_qty':
1135
+				$orderby = array('TKT_qty' => $order);
1136
+				break;
1137
+		}
1138
+		$current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
1139
+			? $this->_req_data['paged']
1140
+			: 1;
1141
+		$per_page = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
1142
+			? $this->_req_data['perpage']
1143
+			: $per_page;
1144
+		$_where = array(
1145
+			'TKT_is_default' => 1,
1146
+			'TKT_deleted'    => $trashed,
1147
+		);
1148
+		$offset = ($current_page - 1) * $per_page;
1149
+		$limit = array($offset, $per_page);
1150
+		if (isset($this->_req_data['s'])) {
1151
+			$sstr = '%' . $this->_req_data['s'] . '%';
1152
+			$_where['OR'] = array(
1153
+				'TKT_name'        => array('LIKE', $sstr),
1154
+				'TKT_description' => array('LIKE', $sstr),
1155
+			);
1156
+		}
1157
+		$query_params = array(
1158
+			$_where,
1159
+			'order_by' => $orderby,
1160
+			'limit'    => $limit,
1161
+			'group_by' => 'TKT_ID',
1162
+		);
1163
+		if ($count) {
1164
+			return EEM_Ticket::instance()->count_deleted_and_undeleted(array($_where));
1165
+		} else {
1166
+			return EEM_Ticket::instance()->get_all_deleted_and_undeleted($query_params);
1167
+		}
1168
+	}
1169
+
1170
+
1171
+	/**
1172
+	 * @param bool $trash
1173
+	 * @throws EE_Error
1174
+	 */
1175
+	protected function _trash_or_restore_ticket($trash = false)
1176
+	{
1177
+		$success = 1;
1178
+		$TKT = EEM_Ticket::instance();
1179
+		// checkboxes?
1180
+		if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1181
+			// if array has more than one element then success message should be plural
1182
+			$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1183
+			// cycle thru the boxes
1184
+			while (list($TKT_ID, $value) = each($this->_req_data['checkbox'])) {
1185
+				if ($trash) {
1186
+					if (! $TKT->delete_by_ID($TKT_ID)) {
1187
+						$success = 0;
1188
+					}
1189
+				} else {
1190
+					if (! $TKT->restore_by_ID($TKT_ID)) {
1191
+						$success = 0;
1192
+					}
1193
+				}
1194
+			}
1195
+		} else {
1196
+			// grab single id and trash
1197
+			$TKT_ID = absint($this->_req_data['TKT_ID']);
1198
+			if ($trash) {
1199
+				if (! $TKT->delete_by_ID($TKT_ID)) {
1200
+					$success = 0;
1201
+				}
1202
+			} else {
1203
+				if (! $TKT->restore_by_ID($TKT_ID)) {
1204
+					$success = 0;
1205
+				}
1206
+			}
1207
+		}
1208
+		$action_desc = $trash ? 'moved to the trash' : 'restored';
1209
+		$query_args = array(
1210
+			'action' => 'ticket_list_table',
1211
+			'status' => $trash ? '' : 'trashed',
1212
+		);
1213
+		$this->_redirect_after_action($success, 'Tickets', $action_desc, $query_args);
1214
+	}
1215
+
1216
+
1217
+	/**
1218
+	 * Handles trashing default ticket.
1219
+	 */
1220
+	protected function _delete_ticket()
1221
+	{
1222
+		$success = 1;
1223
+		// checkboxes?
1224
+		if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1225
+			// if array has more than one element then success message should be plural
1226
+			$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1227
+			// cycle thru the boxes
1228
+			while (list($TKT_ID, $value) = each($this->_req_data['checkbox'])) {
1229
+				// delete
1230
+				if (! $this->_delete_the_ticket($TKT_ID)) {
1231
+					$success = 0;
1232
+				}
1233
+			}
1234
+		} else {
1235
+			// grab single id and trash
1236
+			$TKT_ID = absint($this->_req_data['TKT_ID']);
1237
+			if (! $this->_delete_the_ticket($TKT_ID)) {
1238
+				$success = 0;
1239
+			}
1240
+		}
1241
+		$action_desc = 'deleted';
1242
+		$query_args = array(
1243
+			'action' => 'ticket_list_table',
1244
+			'status' => 'trashed',
1245
+		);
1246
+		// fail safe.  If the default ticket count === 1 then we need to redirect to event overview.
1247
+		if (EEM_Ticket::instance()->count_deleted_and_undeleted(
1248
+			array(array('TKT_is_default' => 1)),
1249
+			'TKT_ID',
1250
+			true
1251
+		)
1252
+		) {
1253
+			$query_args = array();
1254
+		}
1255
+		$this->_redirect_after_action($success, 'Tickets', $action_desc, $query_args);
1256
+	}
1257
+
1258
+
1259
+	/**
1260
+	 * @param int $TKT_ID
1261
+	 * @return bool|int
1262
+	 * @throws EE_Error
1263
+	 */
1264
+	protected function _delete_the_ticket($TKT_ID)
1265
+	{
1266
+		$tkt = EEM_Ticket::instance()->get_one_by_ID($TKT_ID);
1267
+		$tkt->_remove_relations('Datetime');
1268
+		// delete all related prices first
1269
+		$tkt->delete_related_permanently('Price');
1270
+		return $tkt->delete_permanently();
1271
+	}
1272 1272
 }
Please login to merge, or discard this patch.
Spacing   +41 added lines, -41 removed lines patch added patch discarded remove patch
@@ -24,10 +24,10 @@  discard block
 block discarded – undo
24 24
     public function __construct($routing = true)
25 25
     {
26 26
         parent::__construct($routing);
27
-        if (! defined('EVENTS_CAF_TEMPLATE_PATH')) {
28
-            define('EVENTS_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'events/templates/');
29
-            define('EVENTS_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'events/assets/');
30
-            define('EVENTS_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'events/assets/');
27
+        if ( ! defined('EVENTS_CAF_TEMPLATE_PATH')) {
28
+            define('EVENTS_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND.'events/templates/');
29
+            define('EVENTS_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND.'events/assets/');
30
+            define('EVENTS_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL.'events/assets/');
31 31
         }
32 32
     }
33 33
 
@@ -37,7 +37,7 @@  discard block
 block discarded – undo
37 37
      */
38 38
     protected function _extend_page_config()
39 39
     {
40
-        $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'events';
40
+        $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND.'events';
41 41
         // is there a evt_id in the request?
42 42
         $evt_id = ! empty($this->_req_data['EVT_ID']) && ! is_array($this->_req_data['EVT_ID'])
43 43
             ? $this->_req_data['EVT_ID']
@@ -247,7 +247,7 @@  discard block
 block discarded – undo
247 247
     {
248 248
         $return = parent::extra_permalink_field_buttons($return, $id, $new_title, $new_slug);
249 249
         // make sure this is only when editing
250
-        if (! empty($id)) {
250
+        if ( ! empty($id)) {
251 251
             $href = EE_Admin_Page::add_query_args_and_nonce(
252 252
                 array('action' => 'duplicate_event', 'EVT_ID' => $id),
253 253
                 $this->_admin_base_url
@@ -299,7 +299,7 @@  discard block
 block discarded – undo
299 299
     {
300 300
         wp_register_script(
301 301
             'ee-event-editor-heartbeat',
302
-            EVENTS_CAF_ASSETS_URL . 'event-editor-heartbeat.js',
302
+            EVENTS_CAF_ASSETS_URL.'event-editor-heartbeat.js',
303 303
             array('ee_admin_js', 'heartbeat'),
304 304
             EVENT_ESPRESSO_VERSION,
305 305
             true
@@ -323,7 +323,7 @@  discard block
 block discarded – undo
323 323
     public function add_additional_datetime_button($template, $template_args)
324 324
     {
325 325
         return EEH_Template::display_template(
326
-            EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_add_additional_time.template.php',
326
+            EVENTS_CAF_TEMPLATE_PATH.'event_datetime_add_additional_time.template.php',
327 327
             $template_args,
328 328
             true
329 329
         );
@@ -341,7 +341,7 @@  discard block
 block discarded – undo
341 341
     public function add_datetime_clone_button($template, $template_args)
342 342
     {
343 343
         return EEH_Template::display_template(
344
-            EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_metabox_clone_button.template.php',
344
+            EVENTS_CAF_TEMPLATE_PATH.'event_datetime_metabox_clone_button.template.php',
345 345
             $template_args,
346 346
             true
347 347
         );
@@ -359,7 +359,7 @@  discard block
 block discarded – undo
359 359
     public function datetime_timezones_template($template, $template_args)
360 360
     {
361 361
         return EEH_Template::display_template(
362
-            EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_timezones.template.php',
362
+            EVENTS_CAF_TEMPLATE_PATH.'event_datetime_timezones.template.php',
363 363
             $template_args,
364 364
             true
365 365
         );
@@ -478,7 +478,7 @@  discard block
 block discarded – undo
478 478
     {
479 479
         // first make sure the ID for the event is in the request.
480 480
         //  If it isn't then we need to bail and redirect back to overview list table (cause how did we get here?)
481
-        if (! isset($this->_req_data['EVT_ID'])) {
481
+        if ( ! isset($this->_req_data['EVT_ID'])) {
482 482
             EE_Error::add_error(
483 483
                 esc_html__(
484 484
                     'In order to duplicate an event an Event ID is required.  None was given.',
@@ -493,7 +493,7 @@  discard block
 block discarded – undo
493 493
         }
494 494
         // k we've got EVT_ID so let's use that to get the event we'll duplicate
495 495
         $orig_event = EEM_Event::instance()->get_one_by_ID($this->_req_data['EVT_ID']);
496
-        if (! $orig_event instanceof EE_Event) {
496
+        if ( ! $orig_event instanceof EE_Event) {
497 497
             throw new EE_Error(
498 498
                 sprintf(
499 499
                     esc_html__('An EE_Event object could not be retrieved for the given ID (%s)', 'event_espresso'),
@@ -509,7 +509,7 @@  discard block
 block discarded – undo
509 509
         $orig_ven = $orig_event->get_many_related('Venue');
510 510
         // reset the ID and modify other details to make it clear this is a dupe
511 511
         $new_event->set('EVT_ID', 0);
512
-        $new_name = $new_event->name() . ' ' . esc_html__('**DUPLICATE**', 'event_espresso');
512
+        $new_name = $new_event->name().' '.esc_html__('**DUPLICATE**', 'event_espresso');
513 513
         $new_event->set('EVT_name', $new_name);
514 514
         $new_event->set(
515 515
             'EVT_slug',
@@ -538,7 +538,7 @@  discard block
 block discarded – undo
538 538
             'Question_Group',
539 539
             array(array('Event_Question_Group.EQG_primary' => 1))
540 540
         );
541
-        if (! empty($orig_primary_qgs)) {
541
+        if ( ! empty($orig_primary_qgs)) {
542 542
             foreach ($orig_primary_qgs as $id => $obj) {
543 543
                 if ($obj instanceof EE_Question_Group) {
544 544
                     $new_event->_add_relation_to($obj, 'Question_Group', array('EQG_primary' => 1));
@@ -550,7 +550,7 @@  discard block
 block discarded – undo
550 550
             'Question_Group',
551 551
             array(array('Event_Question_Group.EQG_primary' => 0))
552 552
         );
553
-        if (! empty($orig_additional_qgs)) {
553
+        if ( ! empty($orig_additional_qgs)) {
554 554
             foreach ($orig_additional_qgs as $id => $obj) {
555 555
                 if ($obj instanceof EE_Question_Group) {
556 556
                     $new_event->_add_relation_to($obj, 'Question_Group', array('EQG_primary' => 0));
@@ -563,7 +563,7 @@  discard block
 block discarded – undo
563 563
         // k now that we have the new event saved we can loop through the datetimes and start adding relations.
564 564
         $cloned_tickets = array();
565 565
         foreach ($orig_datetimes as $orig_dtt) {
566
-            if (! $orig_dtt instanceof EE_Datetime) {
566
+            if ( ! $orig_dtt instanceof EE_Datetime) {
567 567
                 continue;
568 568
             }
569 569
             $new_dtt = clone $orig_dtt;
@@ -578,7 +578,7 @@  discard block
 block discarded – undo
578 578
             // now let's get the ticket relations setup.
579 579
             foreach ((array) $orig_tkts as $orig_tkt) {
580 580
                 // it's possible a datetime will have no tickets so let's verify we HAVE a ticket first.
581
-                if (! $orig_tkt instanceof EE_Ticket) {
581
+                if ( ! $orig_tkt instanceof EE_Ticket) {
582 582
                     continue;
583 583
                 }
584 584
                 // is this ticket archived?  If it is then let's skip
@@ -587,8 +587,8 @@  discard block
 block discarded – undo
587 587
                 }
588 588
                 // does this original ticket already exist in the clone_tickets cache?
589 589
                 //  If so we'll just use the new ticket from it.
590
-                if (isset($cloned_tickets[ $orig_tkt->ID() ])) {
591
-                    $new_tkt = $cloned_tickets[ $orig_tkt->ID() ];
590
+                if (isset($cloned_tickets[$orig_tkt->ID()])) {
591
+                    $new_tkt = $cloned_tickets[$orig_tkt->ID()];
592 592
                 } else {
593 593
                     $new_tkt = clone $orig_tkt;
594 594
                     // get relations on the $orig_tkt that we need to setup.
@@ -621,7 +621,7 @@  discard block
 block discarded – undo
621 621
                 // for use with later datetimes that have the same ticket.
622 622
                 $new_dtt->_add_relation_to($new_tkt, 'Ticket');
623 623
                 $new_dtt->save();
624
-                $cloned_tickets[ $orig_tkt->ID() ] = $new_tkt;
624
+                $cloned_tickets[$orig_tkt->ID()] = $new_tkt;
625 625
             }
626 626
         }
627 627
         // clone taxonomy information
@@ -704,7 +704,7 @@  discard block
 block discarded – undo
704 704
             $this->_admin_base_url
705 705
         );
706 706
         $content = EEH_Template::display_template(
707
-            EVENTS_CAF_TEMPLATE_PATH . 'import_page.template.php',
707
+            EVENTS_CAF_TEMPLATE_PATH.'import_page.template.php',
708 708
             $this->_template_args,
709 709
             true
710 710
         );
@@ -721,7 +721,7 @@  discard block
 block discarded – undo
721 721
      */
722 722
     protected function _import_events()
723 723
     {
724
-        require_once(EE_CLASSES . 'EE_Import.class.php');
724
+        require_once(EE_CLASSES.'EE_Import.class.php');
725 725
         $success = EE_Import::instance()->import();
726 726
         $this->_redirect_after_action($success, 'Import File', 'ran', array('action' => 'import_page'), true);
727 727
     }
@@ -750,8 +750,8 @@  discard block
 block discarded – undo
750 750
             'EVT_ID' => $event_ids,
751 751
         );
752 752
         $this->_req_data = array_merge($this->_req_data, $new_request_args);
753
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
754
-            require_once(EE_CLASSES . 'EE_Export.class.php');
753
+        if (is_readable(EE_CLASSES.'EE_Export.class.php')) {
754
+            require_once(EE_CLASSES.'EE_Export.class.php');
755 755
             $EE_Export = EE_Export::instance($this->_req_data);
756 756
             $EE_Export->export();
757 757
         }
@@ -772,8 +772,8 @@  discard block
 block discarded – undo
772 772
             'category_ids' => $this->_req_data['EVT_CAT_ID'],
773 773
         );
774 774
         $this->_req_data = array_merge($this->_req_data, $new_request_args);
775
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
776
-            require_once(EE_CLASSES . 'EE_Export.class.php');
775
+        if (is_readable(EE_CLASSES.'EE_Export.class.php')) {
776
+            require_once(EE_CLASSES.'EE_Export.class.php');
777 777
             $EE_Export = EE_Export::instance($this->_req_data);
778 778
             $EE_Export->export();
779 779
         }
@@ -811,7 +811,7 @@  discard block
 block discarded – undo
811 811
         $this->_set_add_edit_form_tags('update_template_settings');
812 812
         $this->_set_publish_post_box_vars(null, false, false, null, false);
813 813
         $this->_template_args['admin_page_content'] = EEH_Template::display_template(
814
-            EVENTS_CAF_TEMPLATE_PATH . 'template_settings.template.php',
814
+            EVENTS_CAF_TEMPLATE_PATH.'template_settings.template.php',
815 815
             $this->_template_args,
816 816
             true
817 817
         );
@@ -938,7 +938,7 @@  discard block
 block discarded – undo
938 938
             $default_reg_status_values
939 939
         );
940 940
         EEH_Template::display_template(
941
-            EVENTS_CAF_TEMPLATE_PATH . 'event_registration_options.template.php',
941
+            EVENTS_CAF_TEMPLATE_PATH.'event_registration_options.template.php',
942 942
             $template_args
943 943
         );
944 944
     }
@@ -1042,13 +1042,13 @@  discard block
 block discarded – undo
1042 1042
     {
1043 1043
         $start = EEM_Datetime::instance()->convert_datetime_for_query(
1044 1044
             'DTT_EVT_start',
1045
-            date('Y-m-d') . ' 00:00:00',
1045
+            date('Y-m-d').' 00:00:00',
1046 1046
             'Y-m-d H:i:s',
1047 1047
             'UTC'
1048 1048
         );
1049 1049
         $end = EEM_Datetime::instance()->convert_datetime_for_query(
1050 1050
             'DTT_EVT_start',
1051
-            date('Y-m-d') . ' 23:59:59',
1051
+            date('Y-m-d').' 23:59:59',
1052 1052
             'Y-m-d H:i:s',
1053 1053
             'UTC'
1054 1054
         );
@@ -1075,13 +1075,13 @@  discard block
 block discarded – undo
1075 1075
         $days_this_month = date('t');
1076 1076
         $start = EEM_Datetime::instance()->convert_datetime_for_query(
1077 1077
             'DTT_EVT_start',
1078
-            $this_year_r . '-' . $this_month_r . '-01 00:00:00',
1078
+            $this_year_r.'-'.$this_month_r.'-01 00:00:00',
1079 1079
             'Y-m-d H:i:s',
1080 1080
             'UTC'
1081 1081
         );
1082 1082
         $end = EEM_Datetime::instance()->convert_datetime_for_query(
1083 1083
             'DTT_EVT_start',
1084
-            $this_year_r . '-' . $this_month_r . '-' . $days_this_month . ' 23:59:59',
1084
+            $this_year_r.'-'.$this_month_r.'-'.$days_this_month.' 23:59:59',
1085 1085
             'Y-m-d H:i:s',
1086 1086
             'UTC'
1087 1087
         );
@@ -1148,7 +1148,7 @@  discard block
 block discarded – undo
1148 1148
         $offset = ($current_page - 1) * $per_page;
1149 1149
         $limit = array($offset, $per_page);
1150 1150
         if (isset($this->_req_data['s'])) {
1151
-            $sstr = '%' . $this->_req_data['s'] . '%';
1151
+            $sstr = '%'.$this->_req_data['s'].'%';
1152 1152
             $_where['OR'] = array(
1153 1153
                 'TKT_name'        => array('LIKE', $sstr),
1154 1154
                 'TKT_description' => array('LIKE', $sstr),
@@ -1177,17 +1177,17 @@  discard block
 block discarded – undo
1177 1177
         $success = 1;
1178 1178
         $TKT = EEM_Ticket::instance();
1179 1179
         // checkboxes?
1180
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1180
+        if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1181 1181
             // if array has more than one element then success message should be plural
1182 1182
             $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1183 1183
             // cycle thru the boxes
1184 1184
             while (list($TKT_ID, $value) = each($this->_req_data['checkbox'])) {
1185 1185
                 if ($trash) {
1186
-                    if (! $TKT->delete_by_ID($TKT_ID)) {
1186
+                    if ( ! $TKT->delete_by_ID($TKT_ID)) {
1187 1187
                         $success = 0;
1188 1188
                     }
1189 1189
                 } else {
1190
-                    if (! $TKT->restore_by_ID($TKT_ID)) {
1190
+                    if ( ! $TKT->restore_by_ID($TKT_ID)) {
1191 1191
                         $success = 0;
1192 1192
                     }
1193 1193
                 }
@@ -1196,11 +1196,11 @@  discard block
 block discarded – undo
1196 1196
             // grab single id and trash
1197 1197
             $TKT_ID = absint($this->_req_data['TKT_ID']);
1198 1198
             if ($trash) {
1199
-                if (! $TKT->delete_by_ID($TKT_ID)) {
1199
+                if ( ! $TKT->delete_by_ID($TKT_ID)) {
1200 1200
                     $success = 0;
1201 1201
                 }
1202 1202
             } else {
1203
-                if (! $TKT->restore_by_ID($TKT_ID)) {
1203
+                if ( ! $TKT->restore_by_ID($TKT_ID)) {
1204 1204
                     $success = 0;
1205 1205
                 }
1206 1206
             }
@@ -1221,20 +1221,20 @@  discard block
 block discarded – undo
1221 1221
     {
1222 1222
         $success = 1;
1223 1223
         // checkboxes?
1224
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1224
+        if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1225 1225
             // if array has more than one element then success message should be plural
1226 1226
             $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1227 1227
             // cycle thru the boxes
1228 1228
             while (list($TKT_ID, $value) = each($this->_req_data['checkbox'])) {
1229 1229
                 // delete
1230
-                if (! $this->_delete_the_ticket($TKT_ID)) {
1230
+                if ( ! $this->_delete_the_ticket($TKT_ID)) {
1231 1231
                     $success = 0;
1232 1232
                 }
1233 1233
             }
1234 1234
         } else {
1235 1235
             // grab single id and trash
1236 1236
             $TKT_ID = absint($this->_req_data['TKT_ID']);
1237
-            if (! $this->_delete_the_ticket($TKT_ID)) {
1237
+            if ( ! $this->_delete_the_ticket($TKT_ID)) {
1238 1238
                 $success = 0;
1239 1239
             }
1240 1240
         }
Please login to merge, or discard this patch.
core/EE_System.core.php 1 patch
Indentation   +1308 added lines, -1308 removed lines patch added patch discarded remove patch
@@ -27,1312 +27,1312 @@
 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
-    /**
130
-     * @singleton method used to instantiate class object
131
-     * @param EE_Registry|null         $registry
132
-     * @param LoaderInterface|null     $loader
133
-     * @param RequestInterface|null    $request
134
-     * @param EE_Maintenance_Mode|null $maintenance_mode
135
-     * @return EE_System
136
-     */
137
-    public static function instance(
138
-        EE_Registry $registry = null,
139
-        LoaderInterface $loader = null,
140
-        RequestInterface $request = null,
141
-        EE_Maintenance_Mode $maintenance_mode = null
142
-    ) {
143
-        // check if class object is instantiated
144
-        if (! self::$_instance instanceof EE_System) {
145
-            self::$_instance = new self($registry, $loader, $request, $maintenance_mode);
146
-        }
147
-        return self::$_instance;
148
-    }
149
-
150
-
151
-    /**
152
-     * resets the instance and returns it
153
-     *
154
-     * @return EE_System
155
-     */
156
-    public static function reset()
157
-    {
158
-        self::$_instance->_req_type = null;
159
-        // make sure none of the old hooks are left hanging around
160
-        remove_all_actions('AHEE__EE_System__perform_activations_upgrades_and_migrations');
161
-        // we need to reset the migration manager in order for it to detect DMSs properly
162
-        EE_Data_Migration_Manager::reset();
163
-        self::instance()->detect_activations_or_upgrades();
164
-        self::instance()->perform_activations_upgrades_and_migrations();
165
-        return self::instance();
166
-    }
167
-
168
-
169
-    /**
170
-     * sets hooks for running rest of system
171
-     * provides "AHEE__EE_System__construct__complete" hook for EE Addons to use as their starting point
172
-     * starting EE Addons from any other point may lead to problems
173
-     *
174
-     * @param EE_Registry         $registry
175
-     * @param LoaderInterface     $loader
176
-     * @param RequestInterface    $request
177
-     * @param EE_Maintenance_Mode $maintenance_mode
178
-     */
179
-    private function __construct(
180
-        EE_Registry $registry,
181
-        LoaderInterface $loader,
182
-        RequestInterface $request,
183
-        EE_Maintenance_Mode $maintenance_mode
184
-    ) {
185
-        $this->registry = $registry;
186
-        $this->loader = $loader;
187
-        $this->request = $request;
188
-        $this->maintenance_mode = $maintenance_mode;
189
-        do_action('AHEE__EE_System__construct__begin', $this);
190
-        add_action(
191
-            'AHEE__EE_Bootstrap__load_espresso_addons',
192
-            array($this, 'loadCapabilities'),
193
-            5
194
-        );
195
-        add_action(
196
-            'AHEE__EE_Bootstrap__load_espresso_addons',
197
-            array($this, 'loadCommandBus'),
198
-            7
199
-        );
200
-        add_action(
201
-            'AHEE__EE_Bootstrap__load_espresso_addons',
202
-            array($this, 'loadPluginApi'),
203
-            9
204
-        );
205
-        // allow addons to load first so that they can register autoloaders, set hooks for running DMS's, etc
206
-        add_action(
207
-            'AHEE__EE_Bootstrap__load_espresso_addons',
208
-            array($this, 'load_espresso_addons')
209
-        );
210
-        // when an ee addon is activated, we want to call the core hook(s) again
211
-        // because the newly-activated addon didn't get a chance to run at all
212
-        add_action('activate_plugin', array($this, 'load_espresso_addons'), 1);
213
-        // detect whether install or upgrade
214
-        add_action(
215
-            'AHEE__EE_Bootstrap__detect_activations_or_upgrades',
216
-            array($this, 'detect_activations_or_upgrades'),
217
-            3
218
-        );
219
-        // load EE_Config, EE_Textdomain, etc
220
-        add_action(
221
-            'AHEE__EE_Bootstrap__load_core_configuration',
222
-            array($this, 'load_core_configuration'),
223
-            5
224
-        );
225
-        // load specifications for matching routes to current request
226
-        add_action(
227
-            'AHEE__EE_Bootstrap__load_core_configuration',
228
-            array($this, 'loadRouteMatchSpecifications')
229
-        );
230
-        // load EE_Config, EE_Textdomain, etc
231
-        add_action(
232
-            'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets',
233
-            array($this, 'register_shortcodes_modules_and_widgets'),
234
-            7
235
-        );
236
-        // you wanna get going? I wanna get going... let's get going!
237
-        add_action(
238
-            'AHEE__EE_Bootstrap__brew_espresso',
239
-            array($this, 'brew_espresso'),
240
-            9
241
-        );
242
-        // other housekeeping
243
-        // exclude EE critical pages from wp_list_pages
244
-        add_filter(
245
-            'wp_list_pages_excludes',
246
-            array($this, 'remove_pages_from_wp_list_pages'),
247
-            10
248
-        );
249
-        // ALL EE Addons should use the following hook point to attach their initial setup too
250
-        // it's extremely important for EE Addons to register any class autoloaders so that they can be available when the EE_Config loads
251
-        do_action('AHEE__EE_System__construct__complete', $this);
252
-    }
253
-
254
-
255
-    /**
256
-     * load and setup EE_Capabilities
257
-     *
258
-     * @return void
259
-     * @throws EE_Error
260
-     */
261
-    public function loadCapabilities()
262
-    {
263
-        $this->capabilities = $this->loader->getShared('EE_Capabilities');
264
-        add_action(
265
-            'AHEE__EE_Capabilities__init_caps__before_initialization',
266
-            function () {
267
-                LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
268
-            }
269
-        );
270
-    }
271
-
272
-
273
-    /**
274
-     * create and cache the CommandBus, and also add middleware
275
-     * The CapChecker middleware requires the use of EE_Capabilities
276
-     * which is why we need to load the CommandBus after Caps are set up
277
-     *
278
-     * @return void
279
-     * @throws EE_Error
280
-     */
281
-    public function loadCommandBus()
282
-    {
283
-        $this->loader->getShared(
284
-            'CommandBusInterface',
285
-            array(
286
-                null,
287
-                apply_filters(
288
-                    'FHEE__EE_Load_Espresso_Core__handle_request__CommandBus_middleware',
289
-                    array(
290
-                        $this->loader->getShared('EventEspresso\core\services\commands\middleware\CapChecker'),
291
-                        $this->loader->getShared('EventEspresso\core\services\commands\middleware\AddActionHook'),
292
-                    )
293
-                ),
294
-            )
295
-        );
296
-    }
297
-
298
-
299
-    /**
300
-     * @return void
301
-     * @throws EE_Error
302
-     */
303
-    public function loadPluginApi()
304
-    {
305
-        // set autoloaders for all of the classes implementing EEI_Plugin_API
306
-        // which provide helpers for EE plugin authors to more easily register certain components with EE.
307
-        EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'plugin_api');
308
-        $this->loader->getShared('EE_Request_Handler');
309
-    }
310
-
311
-
312
-    /**
313
-     * @param string $addon_name
314
-     * @param string $version_constant
315
-     * @param string $min_version_required
316
-     * @param string $load_callback
317
-     * @param string $plugin_file_constant
318
-     * @return void
319
-     */
320
-    private function deactivateIncompatibleAddon(
321
-        $addon_name,
322
-        $version_constant,
323
-        $min_version_required,
324
-        $load_callback,
325
-        $plugin_file_constant
326
-    ) {
327
-        if (! defined($version_constant)) {
328
-            return;
329
-        }
330
-        $addon_version = constant($version_constant);
331
-        if ($addon_version && version_compare($addon_version, $min_version_required, '<')) {
332
-            remove_action('AHEE__EE_System__load_espresso_addons', $load_callback);
333
-            if (! function_exists('deactivate_plugins')) {
334
-                require_once ABSPATH . 'wp-admin/includes/plugin.php';
335
-            }
336
-            deactivate_plugins(plugin_basename(constant($plugin_file_constant)));
337
-            unset($_GET['activate'], $_REQUEST['activate'], $_GET['activate-multi'], $_REQUEST['activate-multi']);
338
-            EE_Error::add_error(
339
-                sprintf(
340
-                    esc_html__(
341
-                        '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.',
342
-                        'event_espresso'
343
-                    ),
344
-                    $addon_name,
345
-                    $min_version_required
346
-                ),
347
-                __FILE__,
348
-                __FUNCTION__ . "({$addon_name})",
349
-                __LINE__
350
-            );
351
-            EE_Error::get_notices(false, true);
352
-        }
353
-    }
354
-
355
-
356
-    /**
357
-     * load_espresso_addons
358
-     * allow addons to load first so that they can set hooks for running DMS's, etc
359
-     * this is hooked into both:
360
-     *    'AHEE__EE_Bootstrap__load_core_configuration'
361
-     *        which runs during the WP 'plugins_loaded' action at priority 5
362
-     *    and the WP 'activate_plugin' hook point
363
-     *
364
-     * @access public
365
-     * @return void
366
-     */
367
-    public function load_espresso_addons()
368
-    {
369
-        $this->deactivateIncompatibleAddon(
370
-            'Wait Lists',
371
-            'EE_WAIT_LISTS_VERSION',
372
-            '1.0.0.beta.074',
373
-            'load_espresso_wait_lists',
374
-            'EE_WAIT_LISTS_PLUGIN_FILE'
375
-        );
376
-        $this->deactivateIncompatibleAddon(
377
-            'Automated Upcoming Event Notifications',
378
-            'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_VERSION',
379
-            '1.0.0.beta.091',
380
-            'load_espresso_automated_upcoming_event_notification',
381
-            'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_PLUGIN_FILE'
382
-        );
383
-        do_action('AHEE__EE_System__load_espresso_addons');
384
-        // if the WP API basic auth plugin isn't already loaded, load it now.
385
-        // We want it for mobile apps. Just include the entire plugin
386
-        // also, don't load the basic auth when a plugin is getting activated, because
387
-        // it could be the basic auth plugin, and it doesn't check if its methods are already defined
388
-        // and causes a fatal error
389
-        if ($this->request->getRequestParam('activate') !== 'true'
390
-            && ! function_exists('json_basic_auth_handler')
391
-            && ! function_exists('json_basic_auth_error')
392
-            && ! in_array(
393
-                $this->request->getRequestParam('action'),
394
-                array('activate', 'activate-selected'),
395
-                true
396
-            )
397
-        ) {
398
-            include_once EE_THIRD_PARTY . 'wp-api-basic-auth' . DS . 'basic-auth.php';
399
-        }
400
-        do_action('AHEE__EE_System__load_espresso_addons__complete');
401
-    }
402
-
403
-
404
-    /**
405
-     * detect_activations_or_upgrades
406
-     * Checks for activation or upgrade of core first;
407
-     * then also checks if any registered addons have been activated or upgraded
408
-     * This is hooked into 'AHEE__EE_Bootstrap__detect_activations_or_upgrades'
409
-     * which runs during the WP 'plugins_loaded' action at priority 3
410
-     *
411
-     * @access public
412
-     * @return void
413
-     */
414
-    public function detect_activations_or_upgrades()
415
-    {
416
-        // first off: let's make sure to handle core
417
-        $this->detect_if_activation_or_upgrade();
418
-        foreach ($this->registry->addons as $addon) {
419
-            if ($addon instanceof EE_Addon) {
420
-                // detect teh request type for that addon
421
-                $addon->detect_activation_or_upgrade();
422
-            }
423
-        }
424
-    }
425
-
426
-
427
-    /**
428
-     * detect_if_activation_or_upgrade
429
-     * Takes care of detecting whether this is a brand new install or code upgrade,
430
-     * and either setting up the DB or setting up maintenance mode etc.
431
-     *
432
-     * @access public
433
-     * @return void
434
-     */
435
-    public function detect_if_activation_or_upgrade()
436
-    {
437
-        do_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin');
438
-        // check if db has been updated, or if its a brand-new installation
439
-        $espresso_db_update = $this->fix_espresso_db_upgrade_option();
440
-        $request_type = $this->detect_req_type($espresso_db_update);
441
-        // EEH_Debug_Tools::printr( $request_type, '$request_type', __FILE__, __LINE__ );
442
-        switch ($request_type) {
443
-            case EE_System::req_type_new_activation:
444
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__new_activation');
445
-                $this->_handle_core_version_change($espresso_db_update);
446
-                break;
447
-            case EE_System::req_type_reactivation:
448
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__reactivation');
449
-                $this->_handle_core_version_change($espresso_db_update);
450
-                break;
451
-            case EE_System::req_type_upgrade:
452
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__upgrade');
453
-                // migrations may be required now that we've upgraded
454
-                $this->maintenance_mode->set_maintenance_mode_if_db_old();
455
-                $this->_handle_core_version_change($espresso_db_update);
456
-                break;
457
-            case EE_System::req_type_downgrade:
458
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__downgrade');
459
-                // its possible migrations are no longer required
460
-                $this->maintenance_mode->set_maintenance_mode_if_db_old();
461
-                $this->_handle_core_version_change($espresso_db_update);
462
-                break;
463
-            case EE_System::req_type_normal:
464
-            default:
465
-                break;
466
-        }
467
-        do_action('AHEE__EE_System__detect_if_activation_or_upgrade__complete');
468
-    }
469
-
470
-
471
-    /**
472
-     * Updates the list of installed versions and sets hooks for
473
-     * initializing the database later during the request
474
-     *
475
-     * @param array $espresso_db_update
476
-     */
477
-    private function _handle_core_version_change($espresso_db_update)
478
-    {
479
-        $this->update_list_of_installed_versions($espresso_db_update);
480
-        // get ready to verify the DB is ok (provided we aren't in maintenance mode, of course)
481
-        add_action(
482
-            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
483
-            array($this, 'initialize_db_if_no_migrations_required')
484
-        );
485
-    }
486
-
487
-
488
-    /**
489
-     * standardizes the wp option 'espresso_db_upgrade' which actually stores
490
-     * information about what versions of EE have been installed and activated,
491
-     * NOT necessarily the state of the database
492
-     *
493
-     * @param mixed $espresso_db_update           the value of the WordPress option.
494
-     *                                            If not supplied, fetches it from the options table
495
-     * @return array the correct value of 'espresso_db_upgrade', after saving it, if it needed correction
496
-     */
497
-    private function fix_espresso_db_upgrade_option($espresso_db_update = null)
498
-    {
499
-        do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
500
-        if (! $espresso_db_update) {
501
-            $espresso_db_update = get_option('espresso_db_update');
502
-        }
503
-        // check that option is an array
504
-        if (! is_array($espresso_db_update)) {
505
-            // if option is FALSE, then it never existed
506
-            if ($espresso_db_update === false) {
507
-                // make $espresso_db_update an array and save option with autoload OFF
508
-                $espresso_db_update = array();
509
-                add_option('espresso_db_update', $espresso_db_update, '', 'no');
510
-            } else {
511
-                // option is NOT FALSE but also is NOT an array, so make it an array and save it
512
-                $espresso_db_update = array($espresso_db_update => array());
513
-                update_option('espresso_db_update', $espresso_db_update);
514
-            }
515
-        } else {
516
-            $corrected_db_update = array();
517
-            // if IS an array, but is it an array where KEYS are version numbers, and values are arrays?
518
-            foreach ($espresso_db_update as $should_be_version_string => $should_be_array) {
519
-                if (is_int($should_be_version_string) && ! is_array($should_be_array)) {
520
-                    // the key is an int, and the value IS NOT an array
521
-                    // so it must be numerically-indexed, where values are versions installed...
522
-                    // fix it!
523
-                    $version_string = $should_be_array;
524
-                    $corrected_db_update[ $version_string ] = array('unknown-date');
525
-                } else {
526
-                    // ok it checks out
527
-                    $corrected_db_update[ $should_be_version_string ] = $should_be_array;
528
-                }
529
-            }
530
-            $espresso_db_update = $corrected_db_update;
531
-            update_option('espresso_db_update', $espresso_db_update);
532
-        }
533
-        do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__complete', $espresso_db_update);
534
-        return $espresso_db_update;
535
-    }
536
-
537
-
538
-    /**
539
-     * Does the traditional work of setting up the plugin's database and adding default data.
540
-     * If migration script/process did not exist, this is what would happen on every activation/reactivation/upgrade.
541
-     * NOTE: if we're in maintenance mode (which would be the case if we detect there are data
542
-     * migration scripts that need to be run and a version change happens), enqueues core for database initialization,
543
-     * so that it will be done when migrations are finished
544
-     *
545
-     * @param boolean $initialize_addons_too if true, we double-check addons' database tables etc too;
546
-     * @param boolean $verify_schema         if true will re-check the database tables have the correct schema.
547
-     *                                       This is a resource-intensive job
548
-     *                                       so we prefer to only do it when necessary
549
-     * @return void
550
-     * @throws EE_Error
551
-     */
552
-    public function initialize_db_if_no_migrations_required($initialize_addons_too = false, $verify_schema = true)
553
-    {
554
-        $request_type = $this->detect_req_type();
555
-        // only initialize system if we're not in maintenance mode.
556
-        if ($this->maintenance_mode->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
557
-            /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
558
-            $rewrite_rules = $this->loader->getShared(
559
-                'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
560
-            );
561
-            $rewrite_rules->flush();
562
-            if ($verify_schema) {
563
-                EEH_Activation::initialize_db_and_folders();
564
-            }
565
-            EEH_Activation::initialize_db_content();
566
-            EEH_Activation::system_initialization();
567
-            if ($initialize_addons_too) {
568
-                $this->initialize_addons();
569
-            }
570
-        } else {
571
-            EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for('Core');
572
-        }
573
-        if ($request_type === EE_System::req_type_new_activation
574
-            || $request_type === EE_System::req_type_reactivation
575
-            || (
576
-                $request_type === EE_System::req_type_upgrade
577
-                && $this->is_major_version_change()
578
-            )
579
-        ) {
580
-            add_action('AHEE__EE_System__initialize_last', array($this, 'redirect_to_about_ee'), 9);
581
-        }
582
-    }
583
-
584
-
585
-    /**
586
-     * Initializes the db for all registered addons
587
-     *
588
-     * @throws EE_Error
589
-     */
590
-    public function initialize_addons()
591
-    {
592
-        // foreach registered addon, make sure its db is up-to-date too
593
-        foreach ($this->registry->addons as $addon) {
594
-            if ($addon instanceof EE_Addon) {
595
-                $addon->initialize_db_if_no_migrations_required();
596
-            }
597
-        }
598
-    }
599
-
600
-
601
-    /**
602
-     * Adds the current code version to the saved wp option which stores a list of all ee versions ever installed.
603
-     *
604
-     * @param    array  $version_history
605
-     * @param    string $current_version_to_add version to be added to the version history
606
-     * @return    boolean success as to whether or not this option was changed
607
-     */
608
-    public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
609
-    {
610
-        if (! $version_history) {
611
-            $version_history = $this->fix_espresso_db_upgrade_option($version_history);
612
-        }
613
-        if ($current_version_to_add === null) {
614
-            $current_version_to_add = espresso_version();
615
-        }
616
-        $version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
617
-        // re-save
618
-        return update_option('espresso_db_update', $version_history);
619
-    }
620
-
621
-
622
-    /**
623
-     * Detects if the current version indicated in the has existed in the list of
624
-     * previously-installed versions of EE (espresso_db_update). Does NOT modify it (ie, no side-effect)
625
-     *
626
-     * @param array $espresso_db_update array from the wp option stored under the name 'espresso_db_update'.
627
-     *                                  If not supplied, fetches it from the options table.
628
-     *                                  Also, caches its result so later parts of the code can also know whether
629
-     *                                  there's been an update or not. This way we can add the current version to
630
-     *                                  espresso_db_update, but still know if this is a new install or not
631
-     * @return int one of the constants on EE_System::req_type_
632
-     */
633
-    public function detect_req_type($espresso_db_update = null)
634
-    {
635
-        if ($this->_req_type === null) {
636
-            $espresso_db_update = ! empty($espresso_db_update)
637
-                ? $espresso_db_update
638
-                : $this->fix_espresso_db_upgrade_option();
639
-            $this->_req_type = EE_System::detect_req_type_given_activation_history(
640
-                $espresso_db_update,
641
-                'ee_espresso_activation',
642
-                espresso_version()
643
-            );
644
-            $this->_major_version_change = $this->_detect_major_version_change($espresso_db_update);
645
-            $this->request->setIsActivation($this->_req_type !== EE_System::req_type_normal);
646
-        }
647
-        return $this->_req_type;
648
-    }
649
-
650
-
651
-    /**
652
-     * Returns whether or not there was a non-micro version change (ie, change in either
653
-     * the first or second number in the version. Eg 4.9.0.rc.001 to 4.10.0.rc.000,
654
-     * but not 4.9.0.rc.0001 to 4.9.1.rc.0001
655
-     *
656
-     * @param $activation_history
657
-     * @return bool
658
-     */
659
-    private function _detect_major_version_change($activation_history)
660
-    {
661
-        $previous_version = EE_System::_get_most_recently_active_version_from_activation_history($activation_history);
662
-        $previous_version_parts = explode('.', $previous_version);
663
-        $current_version_parts = explode('.', espresso_version());
664
-        return isset($previous_version_parts[0], $previous_version_parts[1], $current_version_parts[0], $current_version_parts[1])
665
-               && ($previous_version_parts[0] !== $current_version_parts[0]
666
-                   || $previous_version_parts[1] !== $current_version_parts[1]
667
-               );
668
-    }
669
-
670
-
671
-    /**
672
-     * Returns true if either the major or minor version of EE changed during this request.
673
-     * 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
674
-     *
675
-     * @return bool
676
-     */
677
-    public function is_major_version_change()
678
-    {
679
-        return $this->_major_version_change;
680
-    }
681
-
682
-
683
-    /**
684
-     * Determines the request type for any ee addon, given three piece of info: the current array of activation
685
-     * histories (for core that' 'espresso_db_update' wp option); the name of the WordPress option which is temporarily
686
-     * set upon activation of the plugin (for core it's 'ee_espresso_activation'); and the version that this plugin was
687
-     * just activated to (for core that will always be espresso_version())
688
-     *
689
-     * @param array  $activation_history_for_addon     the option's value which stores the activation history for this
690
-     *                                                 ee plugin. for core that's 'espresso_db_update'
691
-     * @param string $activation_indicator_option_name the name of the WordPress option that is temporarily set to
692
-     *                                                 indicate that this plugin was just activated
693
-     * @param string $version_to_upgrade_to            the version that was just upgraded to (for core that will be
694
-     *                                                 espresso_version())
695
-     * @return int one of the constants on EE_System::req_type_*
696
-     */
697
-    public static function detect_req_type_given_activation_history(
698
-        $activation_history_for_addon,
699
-        $activation_indicator_option_name,
700
-        $version_to_upgrade_to
701
-    ) {
702
-        $version_is_higher = self::_new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to);
703
-        if ($activation_history_for_addon) {
704
-            // it exists, so this isn't a completely new install
705
-            // check if this version already in that list of previously installed versions
706
-            if (! isset($activation_history_for_addon[ $version_to_upgrade_to ])) {
707
-                // it a version we haven't seen before
708
-                if ($version_is_higher === 1) {
709
-                    $req_type = EE_System::req_type_upgrade;
710
-                } else {
711
-                    $req_type = EE_System::req_type_downgrade;
712
-                }
713
-                delete_option($activation_indicator_option_name);
714
-            } else {
715
-                // its not an update. maybe a reactivation?
716
-                if (get_option($activation_indicator_option_name, false)) {
717
-                    if ($version_is_higher === -1) {
718
-                        $req_type = EE_System::req_type_downgrade;
719
-                    } elseif ($version_is_higher === 0) {
720
-                        // we've seen this version before, but it's an activation. must be a reactivation
721
-                        $req_type = EE_System::req_type_reactivation;
722
-                    } else {// $version_is_higher === 1
723
-                        $req_type = EE_System::req_type_upgrade;
724
-                    }
725
-                    delete_option($activation_indicator_option_name);
726
-                } else {
727
-                    // we've seen this version before and the activation indicate doesn't show it was just activated
728
-                    if ($version_is_higher === -1) {
729
-                        $req_type = EE_System::req_type_downgrade;
730
-                    } elseif ($version_is_higher === 0) {
731
-                        // we've seen this version before and it's not an activation. its normal request
732
-                        $req_type = EE_System::req_type_normal;
733
-                    } else {// $version_is_higher === 1
734
-                        $req_type = EE_System::req_type_upgrade;
735
-                    }
736
-                }
737
-            }
738
-        } else {
739
-            // brand new install
740
-            $req_type = EE_System::req_type_new_activation;
741
-            delete_option($activation_indicator_option_name);
742
-        }
743
-        return $req_type;
744
-    }
745
-
746
-
747
-    /**
748
-     * Detects if the $version_to_upgrade_to is higher than the most recent version in
749
-     * the $activation_history_for_addon
750
-     *
751
-     * @param array  $activation_history_for_addon (keys are versions, values are arrays of times activated,
752
-     *                                             sometimes containing 'unknown-date'
753
-     * @param string $version_to_upgrade_to        (current version)
754
-     * @return int results of version_compare( $version_to_upgrade_to, $most_recently_active_version ).
755
-     *                                             ie, -1 if $version_to_upgrade_to is LOWER (downgrade);
756
-     *                                             0 if $version_to_upgrade_to MATCHES (reactivation or normal request);
757
-     *                                             1 if $version_to_upgrade_to is HIGHER (upgrade) ;
758
-     */
759
-    private static function _new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to)
760
-    {
761
-        // find the most recently-activated version
762
-        $most_recently_active_version =
763
-            EE_System::_get_most_recently_active_version_from_activation_history($activation_history_for_addon);
764
-        return version_compare($version_to_upgrade_to, $most_recently_active_version);
765
-    }
766
-
767
-
768
-    /**
769
-     * Gets the most recently active version listed in the activation history,
770
-     * and if none are found (ie, it's a brand new install) returns '0.0.0.dev.000'.
771
-     *
772
-     * @param array $activation_history  (keys are versions, values are arrays of times activated,
773
-     *                                   sometimes containing 'unknown-date'
774
-     * @return string
775
-     */
776
-    private static function _get_most_recently_active_version_from_activation_history($activation_history)
777
-    {
778
-        $most_recently_active_version_activation = '1970-01-01 00:00:00';
779
-        $most_recently_active_version = '0.0.0.dev.000';
780
-        if (is_array($activation_history)) {
781
-            foreach ($activation_history as $version => $times_activated) {
782
-                // check there is a record of when this version was activated. Otherwise,
783
-                // mark it as unknown
784
-                if (! $times_activated) {
785
-                    $times_activated = array('unknown-date');
786
-                }
787
-                if (is_string($times_activated)) {
788
-                    $times_activated = array($times_activated);
789
-                }
790
-                foreach ($times_activated as $an_activation) {
791
-                    if ($an_activation !== 'unknown-date'
792
-                        && $an_activation
793
-                           > $most_recently_active_version_activation) {
794
-                        $most_recently_active_version = $version;
795
-                        $most_recently_active_version_activation = $an_activation === 'unknown-date'
796
-                            ? '1970-01-01 00:00:00'
797
-                            : $an_activation;
798
-                    }
799
-                }
800
-            }
801
-        }
802
-        return $most_recently_active_version;
803
-    }
804
-
805
-
806
-    /**
807
-     * This redirects to the about EE page after activation
808
-     *
809
-     * @return void
810
-     */
811
-    public function redirect_to_about_ee()
812
-    {
813
-        $notices = EE_Error::get_notices(false);
814
-        // if current user is an admin and it's not an ajax or rest request
815
-        if (! isset($notices['errors'])
816
-            && $this->request->isAdmin()
817
-            && apply_filters(
818
-                'FHEE__EE_System__redirect_to_about_ee__do_redirect',
819
-                $this->capabilities->current_user_can('manage_options', 'espresso_about_default')
820
-            )
821
-        ) {
822
-            $query_params = array('page' => 'espresso_about');
823
-            if (EE_System::instance()->detect_req_type() === EE_System::req_type_new_activation) {
824
-                $query_params['new_activation'] = true;
825
-            }
826
-            if (EE_System::instance()->detect_req_type() === EE_System::req_type_reactivation) {
827
-                $query_params['reactivation'] = true;
828
-            }
829
-            $url = add_query_arg($query_params, admin_url('admin.php'));
830
-            wp_safe_redirect($url);
831
-            exit();
832
-        }
833
-    }
834
-
835
-
836
-    /**
837
-     * load_core_configuration
838
-     * this is hooked into 'AHEE__EE_Bootstrap__load_core_configuration'
839
-     * which runs during the WP 'plugins_loaded' action at priority 5
840
-     *
841
-     * @return void
842
-     * @throws ReflectionException
843
-     * @throws Exception
844
-     */
845
-    public function load_core_configuration()
846
-    {
847
-        do_action('AHEE__EE_System__load_core_configuration__begin', $this);
848
-        $this->loader->getShared('EE_Load_Textdomain');
849
-        // load textdomain
850
-        EE_Load_Textdomain::load_textdomain();
851
-        // load and setup EE_Config and EE_Network_Config
852
-        $config = $this->loader->getShared('EE_Config');
853
-        $this->loader->getShared('EE_Network_Config');
854
-        // setup autoloaders
855
-        // enable logging?
856
-        if ($config->admin->use_full_logging) {
857
-            $this->loader->getShared('EE_Log');
858
-        }
859
-        // check for activation errors
860
-        $activation_errors = get_option('ee_plugin_activation_errors', false);
861
-        if ($activation_errors) {
862
-            EE_Error::add_error($activation_errors, __FILE__, __FUNCTION__, __LINE__);
863
-            update_option('ee_plugin_activation_errors', false);
864
-        }
865
-        // get model names
866
-        $this->_parse_model_names();
867
-        // load caf stuff a chance to play during the activation process too.
868
-        $this->_maybe_brew_regular();
869
-        // configure custom post type definitions
870
-        $this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions');
871
-        $this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions');
872
-        do_action('AHEE__EE_System__load_core_configuration__complete', $this);
873
-    }
874
-
875
-
876
-    /**
877
-     * cycles through all of the models/*.model.php files, and assembles an array of model names
878
-     *
879
-     * @return void
880
-     * @throws ReflectionException
881
-     */
882
-    private function _parse_model_names()
883
-    {
884
-        // get all the files in the EE_MODELS folder that end in .model.php
885
-        $models = glob(EE_MODELS . '*.model.php');
886
-        $model_names = array();
887
-        $non_abstract_db_models = array();
888
-        foreach ($models as $model) {
889
-            // get model classname
890
-            $classname = EEH_File::get_classname_from_filepath_with_standard_filename($model);
891
-            $short_name = str_replace('EEM_', '', $classname);
892
-            $reflectionClass = new ReflectionClass($classname);
893
-            if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
894
-                $non_abstract_db_models[ $short_name ] = $classname;
895
-            }
896
-            $model_names[ $short_name ] = $classname;
897
-        }
898
-        $this->registry->models = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
899
-        $this->registry->non_abstract_db_models = apply_filters(
900
-            'FHEE__EE_System__parse_implemented_model_names',
901
-            $non_abstract_db_models
902
-        );
903
-    }
904
-
905
-
906
-    /**
907
-     * The purpose of this method is to simply check for a file named "caffeinated/brewing_regular.php" for any hooks
908
-     * that need to be setup before our EE_System launches.
909
-     *
910
-     * @return void
911
-     * @throws DomainException
912
-     * @throws InvalidArgumentException
913
-     * @throws InvalidDataTypeException
914
-     * @throws InvalidInterfaceException
915
-     * @throws InvalidClassException
916
-     * @throws InvalidFilePathException
917
-     */
918
-    private function _maybe_brew_regular()
919
-    {
920
-        /** @var Domain $domain */
921
-        $domain = DomainFactory::getShared(
922
-            new FullyQualifiedName(
923
-                'EventEspresso\core\domain\Domain'
924
-            ),
925
-            array(
926
-                new FilePath(EVENT_ESPRESSO_MAIN_FILE),
927
-                Version::fromString(espresso_version()),
928
-            )
929
-        );
930
-        if ($domain->isCaffeinated()) {
931
-            require_once EE_CAFF_PATH . 'brewing_regular.php';
932
-        }
933
-    }
934
-
935
-
936
-    /**
937
-     * @since 4.9.71.p
938
-     * @throws Exception
939
-     */
940
-    public function loadRouteMatchSpecifications()
941
-    {
942
-        try {
943
-            $this->loader->getShared(
944
-                'EventEspresso\core\services\route_match\RouteMatchSpecificationManager'
945
-            );
946
-        } catch (Exception $exception) {
947
-            new ExceptionStackTraceDisplay($exception);
948
-        }
949
-        do_action('AHEE__EE_System__loadRouteMatchSpecifications');
950
-    }
951
-
952
-
953
-    /**
954
-     * register_shortcodes_modules_and_widgets
955
-     * generate lists of shortcodes and modules, then verify paths and classes
956
-     * This is hooked into 'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets'
957
-     * which runs during the WP 'plugins_loaded' action at priority 7
958
-     *
959
-     * @access public
960
-     * @return void
961
-     * @throws Exception
962
-     */
963
-    public function register_shortcodes_modules_and_widgets()
964
-    {
965
-        if ($this->request->isFrontend() || $this->request->isIframe() || $this->request->isAjax()) {
966
-            try {
967
-                // load, register, and add shortcodes the new way
968
-                $this->loader->getShared(
969
-                    'EventEspresso\core\services\shortcodes\ShortcodesManager',
970
-                    array(
971
-                        // and the old way, but we'll put it under control of the new system
972
-                        EE_Config::getLegacyShortcodesManager(),
973
-                    )
974
-                );
975
-            } catch (Exception $exception) {
976
-                new ExceptionStackTraceDisplay($exception);
977
-            }
978
-        }
979
-        do_action('AHEE__EE_System__register_shortcodes_modules_and_widgets');
980
-        // check for addons using old hook point
981
-        if (has_action('AHEE__EE_System__register_shortcodes_modules_and_addons')) {
982
-            $this->_incompatible_addon_error();
983
-        }
984
-    }
985
-
986
-
987
-    /**
988
-     * _incompatible_addon_error
989
-     *
990
-     * @access public
991
-     * @return void
992
-     */
993
-    private function _incompatible_addon_error()
994
-    {
995
-        // get array of classes hooking into here
996
-        $class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook(
997
-            'AHEE__EE_System__register_shortcodes_modules_and_addons'
998
-        );
999
-        if (! empty($class_names)) {
1000
-            $msg = __(
1001
-                'The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
1002
-                'event_espresso'
1003
-            );
1004
-            $msg .= '<ul>';
1005
-            foreach ($class_names as $class_name) {
1006
-                $msg .= '<li><b>Event Espresso - '
1007
-                        . str_replace(
1008
-                            array('EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'),
1009
-                            '',
1010
-                            $class_name
1011
-                        ) . '</b></li>';
1012
-            }
1013
-            $msg .= '</ul>';
1014
-            $msg .= __(
1015
-                'Compatibility issues can be avoided and/or resolved by keeping addons and plugins updated to the latest version.',
1016
-                'event_espresso'
1017
-            );
1018
-            // save list of incompatible addons to wp-options for later use
1019
-            add_option('ee_incompatible_addons', $class_names, '', 'no');
1020
-            if (is_admin()) {
1021
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1022
-            }
1023
-        }
1024
-    }
1025
-
1026
-
1027
-    /**
1028
-     * brew_espresso
1029
-     * begins the process of setting hooks for initializing EE in the correct order
1030
-     * This is happening on the 'AHEE__EE_Bootstrap__brew_espresso' hook point
1031
-     * which runs during the WP 'plugins_loaded' action at priority 9
1032
-     *
1033
-     * @return void
1034
-     */
1035
-    public function brew_espresso()
1036
-    {
1037
-        do_action('AHEE__EE_System__brew_espresso__begin', $this);
1038
-        // load some final core systems
1039
-        add_action('init', array($this, 'set_hooks_for_core'), 1);
1040
-        add_action('init', array($this, 'perform_activations_upgrades_and_migrations'), 3);
1041
-        add_action('init', array($this, 'load_CPTs_and_session'), 5);
1042
-        add_action('init', array($this, 'load_controllers'), 7);
1043
-        add_action('init', array($this, 'core_loaded_and_ready'), 9);
1044
-        add_action('init', array($this, 'initialize'), 10);
1045
-        add_action('init', array($this, 'initialize_last'), 100);
1046
-        if (is_admin() && apply_filters('FHEE__EE_System__brew_espresso__load_pue', true)) {
1047
-            // pew pew pew
1048
-            $this->loader->getShared('EventEspresso\core\services\licensing\LicenseService');
1049
-            do_action('AHEE__EE_System__brew_espresso__after_pue_init');
1050
-        }
1051
-        do_action('AHEE__EE_System__brew_espresso__complete', $this);
1052
-    }
1053
-
1054
-
1055
-    /**
1056
-     *    set_hooks_for_core
1057
-     *
1058
-     * @access public
1059
-     * @return    void
1060
-     * @throws EE_Error
1061
-     */
1062
-    public function set_hooks_for_core()
1063
-    {
1064
-        $this->_deactivate_incompatible_addons();
1065
-        do_action('AHEE__EE_System__set_hooks_for_core');
1066
-        $this->loader->getShared('EventEspresso\core\domain\values\session\SessionLifespan');
1067
-        // caps need to be initialized on every request so that capability maps are set.
1068
-        // @see https://events.codebasehq.com/projects/event-espresso/tickets/8674
1069
-        $this->registry->CAP->init_caps();
1070
-    }
1071
-
1072
-
1073
-    /**
1074
-     * Using the information gathered in EE_System::_incompatible_addon_error,
1075
-     * deactivates any addons considered incompatible with the current version of EE
1076
-     */
1077
-    private function _deactivate_incompatible_addons()
1078
-    {
1079
-        $incompatible_addons = get_option('ee_incompatible_addons', array());
1080
-        if (! empty($incompatible_addons)) {
1081
-            $active_plugins = get_option('active_plugins', array());
1082
-            foreach ($active_plugins as $active_plugin) {
1083
-                foreach ($incompatible_addons as $incompatible_addon) {
1084
-                    if (strpos($active_plugin, $incompatible_addon) !== false) {
1085
-                        unset($_GET['activate']);
1086
-                        espresso_deactivate_plugin($active_plugin);
1087
-                    }
1088
-                }
1089
-            }
1090
-        }
1091
-    }
1092
-
1093
-
1094
-    /**
1095
-     *    perform_activations_upgrades_and_migrations
1096
-     *
1097
-     * @access public
1098
-     * @return    void
1099
-     */
1100
-    public function perform_activations_upgrades_and_migrations()
1101
-    {
1102
-        do_action('AHEE__EE_System__perform_activations_upgrades_and_migrations');
1103
-    }
1104
-
1105
-
1106
-    /**
1107
-     * @return void
1108
-     * @throws DomainException
1109
-     */
1110
-    public function load_CPTs_and_session()
1111
-    {
1112
-        do_action('AHEE__EE_System__load_CPTs_and_session__start');
1113
-        /** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies $register_custom_taxonomies */
1114
-        $register_custom_taxonomies = $this->loader->getShared(
1115
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies'
1116
-        );
1117
-        $register_custom_taxonomies->registerCustomTaxonomies();
1118
-        /** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes $register_custom_post_types */
1119
-        $register_custom_post_types = $this->loader->getShared(
1120
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes'
1121
-        );
1122
-        $register_custom_post_types->registerCustomPostTypes();
1123
-        /** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms $register_custom_taxonomy_terms */
1124
-        $register_custom_taxonomy_terms = $this->loader->getShared(
1125
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms'
1126
-        );
1127
-        $register_custom_taxonomy_terms->registerCustomTaxonomyTerms();
1128
-        // load legacy Custom Post Types and Taxonomies
1129
-        $this->loader->getShared('EE_Register_CPTs');
1130
-        do_action('AHEE__EE_System__load_CPTs_and_session__complete');
1131
-    }
1132
-
1133
-
1134
-    /**
1135
-     * load_controllers
1136
-     * this is the best place to load any additional controllers that needs access to EE core.
1137
-     * it is expected that all basic core EE systems, that are not dependant on the current request are loaded at this
1138
-     * time
1139
-     *
1140
-     * @access public
1141
-     * @return void
1142
-     */
1143
-    public function load_controllers()
1144
-    {
1145
-        do_action('AHEE__EE_System__load_controllers__start');
1146
-        // let's get it started
1147
-        if (! $this->maintenance_mode->level()
1148
-            && ($this->request->isFrontend() || $this->request->isFrontAjax())
1149
-        ) {
1150
-            do_action('AHEE__EE_System__load_controllers__load_front_controllers');
1151
-            $this->loader->getShared('EE_Front_Controller');
1152
-        } elseif ($this->request->isAdmin() || $this->request->isAdminAjax()) {
1153
-            do_action('AHEE__EE_System__load_controllers__load_admin_controllers');
1154
-            $this->loader->getShared('EE_Admin');
1155
-        } elseif ($this->request->isWordPressHeartbeat()) {
1156
-            $this->loader->getShared('EventEspresso\core\domain\services\admin\ajax\WordpressHeartbeat');
1157
-        }
1158
-        do_action('AHEE__EE_System__load_controllers__complete');
1159
-    }
1160
-
1161
-
1162
-    /**
1163
-     * core_loaded_and_ready
1164
-     * all of the basic EE core should be loaded at this point and available regardless of M-Mode
1165
-     *
1166
-     * @access public
1167
-     * @return void
1168
-     * @throws Exception
1169
-     */
1170
-    public function core_loaded_and_ready()
1171
-    {
1172
-        if ($this->request->isAdmin()
1173
-            || $this->request->isFrontend()
1174
-            || $this->request->isIframe()
1175
-            || $this->request->isWordPressApi()
1176
-        ) {
1177
-            try {
1178
-                $this->loader->getShared('EventEspresso\core\services\assets\Registry');
1179
-                $this->loader->getShared('EventEspresso\core\domain\services\assets\CoreAssetManager');
1180
-                if ($this->canLoadBlocks()) {
1181
-                    $this->loader->getShared(
1182
-                        'EventEspresso\core\services\editor\BlockRegistrationManager'
1183
-                    );
1184
-                }
1185
-            } catch (Exception $exception) {
1186
-                new ExceptionStackTraceDisplay($exception);
1187
-            }
1188
-        }
1189
-        if ($this->request->isAdmin()
1190
-            || $this->request->isEeAjax()
1191
-            || $this->request->isFrontend()
1192
-        ) {
1193
-            $this->loader->getShared('EE_Session');
1194
-        }
1195
-        // integrate WP_Query with the EE models
1196
-        $this->loader->getShared('EE_CPT_Strategy');
1197
-        do_action('AHEE__EE_System__core_loaded_and_ready');
1198
-        // always load template tags, because it's faster than checking if it's a front-end request, and many page
1199
-        // builders require these even on the front-end
1200
-        require_once EE_PUBLIC . 'template_tags.php';
1201
-        do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1202
-    }
1203
-
1204
-
1205
-    /**
1206
-     * initialize
1207
-     * this is the best place to begin initializing client code
1208
-     *
1209
-     * @access public
1210
-     * @return void
1211
-     */
1212
-    public function initialize()
1213
-    {
1214
-        do_action('AHEE__EE_System__initialize');
1215
-    }
1216
-
1217
-
1218
-    /**
1219
-     * initialize_last
1220
-     * this is run really late during the WP init hook point, and ensures that mostly everything else that needs to
1221
-     * initialize has done so
1222
-     *
1223
-     * @access public
1224
-     * @return void
1225
-     */
1226
-    public function initialize_last()
1227
-    {
1228
-        do_action('AHEE__EE_System__initialize_last');
1229
-        /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
1230
-        $rewrite_rules = $this->loader->getShared(
1231
-            'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
1232
-        );
1233
-        $rewrite_rules->flushRewriteRules();
1234
-        add_action('admin_bar_init', array($this, 'addEspressoToolbar'));
1235
-        if (($this->request->isAjax() || $this->request->isAdmin())
1236
-            && $this->maintenance_mode->models_can_query()) {
1237
-            $this->loader->getShared('EventEspresso\core\services\privacy\export\PersonalDataExporterManager');
1238
-            $this->loader->getShared('EventEspresso\core\services\privacy\erasure\PersonalDataEraserManager');
1239
-        }
1240
-    }
1241
-
1242
-
1243
-    /**
1244
-     * @return void
1245
-     * @throws EE_Error
1246
-     */
1247
-    public function addEspressoToolbar()
1248
-    {
1249
-        $this->loader->getShared(
1250
-            'EventEspresso\core\domain\services\admin\AdminToolBar',
1251
-            array($this->registry->CAP)
1252
-        );
1253
-    }
1254
-
1255
-
1256
-    /**
1257
-     * do_not_cache
1258
-     * sets no cache headers and defines no cache constants for WP plugins
1259
-     *
1260
-     * @access public
1261
-     * @return void
1262
-     */
1263
-    public static function do_not_cache()
1264
-    {
1265
-        // set no cache constants
1266
-        if (! defined('DONOTCACHEPAGE')) {
1267
-            define('DONOTCACHEPAGE', true);
1268
-        }
1269
-        if (! defined('DONOTCACHCEOBJECT')) {
1270
-            define('DONOTCACHCEOBJECT', true);
1271
-        }
1272
-        if (! defined('DONOTCACHEDB')) {
1273
-            define('DONOTCACHEDB', true);
1274
-        }
1275
-        // add no cache headers
1276
-        add_action('send_headers', array('EE_System', 'nocache_headers'), 10);
1277
-        // plus a little extra for nginx and Google Chrome
1278
-        add_filter('nocache_headers', array('EE_System', 'extra_nocache_headers'), 10, 1);
1279
-        // prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes with the registration process
1280
-        remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
1281
-    }
1282
-
1283
-
1284
-    /**
1285
-     *    extra_nocache_headers
1286
-     *
1287
-     * @access    public
1288
-     * @param $headers
1289
-     * @return    array
1290
-     */
1291
-    public static function extra_nocache_headers($headers)
1292
-    {
1293
-        // for NGINX
1294
-        $headers['X-Accel-Expires'] = 0;
1295
-        // plus extra for Google Chrome since it doesn't seem to respect "no-cache", but WILL respect "no-store"
1296
-        $headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0';
1297
-        return $headers;
1298
-    }
1299
-
1300
-
1301
-    /**
1302
-     *    nocache_headers
1303
-     *
1304
-     * @access    public
1305
-     * @return    void
1306
-     */
1307
-    public static function nocache_headers()
1308
-    {
1309
-        nocache_headers();
1310
-    }
1311
-
1312
-
1313
-    /**
1314
-     * simply hooks into "wp_list_pages_exclude" filter (for wp_list_pages method) and makes sure EE critical pages are
1315
-     * never returned with the function.
1316
-     *
1317
-     * @param  array $exclude_array any existing pages being excluded are in this array.
1318
-     * @return array
1319
-     */
1320
-    public function remove_pages_from_wp_list_pages($exclude_array)
1321
-    {
1322
-        return array_merge($exclude_array, $this->registry->CFG->core->get_critical_pages_array());
1323
-    }
1324
-
1325
-
1326
-    /**
1327
-     * Return whether blocks can be registered/loaded or not.
1328
-     * @return bool
1329
-     */
1330
-    private function canLoadBlocks()
1331
-    {
1332
-        return apply_filters('FHEE__EE_System__canLoadBlocks', true)
1333
-               && function_exists('register_block_type')
1334
-               // don't load blocks if in the Divi page builder editor context
1335
-               // @see https://github.com/eventespresso/event-espresso-core/issues/814
1336
-               && ! $this->request->getRequestParam('et_fb', false);
1337
-    }
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
+	/**
130
+	 * @singleton method used to instantiate class object
131
+	 * @param EE_Registry|null         $registry
132
+	 * @param LoaderInterface|null     $loader
133
+	 * @param RequestInterface|null    $request
134
+	 * @param EE_Maintenance_Mode|null $maintenance_mode
135
+	 * @return EE_System
136
+	 */
137
+	public static function instance(
138
+		EE_Registry $registry = null,
139
+		LoaderInterface $loader = null,
140
+		RequestInterface $request = null,
141
+		EE_Maintenance_Mode $maintenance_mode = null
142
+	) {
143
+		// check if class object is instantiated
144
+		if (! self::$_instance instanceof EE_System) {
145
+			self::$_instance = new self($registry, $loader, $request, $maintenance_mode);
146
+		}
147
+		return self::$_instance;
148
+	}
149
+
150
+
151
+	/**
152
+	 * resets the instance and returns it
153
+	 *
154
+	 * @return EE_System
155
+	 */
156
+	public static function reset()
157
+	{
158
+		self::$_instance->_req_type = null;
159
+		// make sure none of the old hooks are left hanging around
160
+		remove_all_actions('AHEE__EE_System__perform_activations_upgrades_and_migrations');
161
+		// we need to reset the migration manager in order for it to detect DMSs properly
162
+		EE_Data_Migration_Manager::reset();
163
+		self::instance()->detect_activations_or_upgrades();
164
+		self::instance()->perform_activations_upgrades_and_migrations();
165
+		return self::instance();
166
+	}
167
+
168
+
169
+	/**
170
+	 * sets hooks for running rest of system
171
+	 * provides "AHEE__EE_System__construct__complete" hook for EE Addons to use as their starting point
172
+	 * starting EE Addons from any other point may lead to problems
173
+	 *
174
+	 * @param EE_Registry         $registry
175
+	 * @param LoaderInterface     $loader
176
+	 * @param RequestInterface    $request
177
+	 * @param EE_Maintenance_Mode $maintenance_mode
178
+	 */
179
+	private function __construct(
180
+		EE_Registry $registry,
181
+		LoaderInterface $loader,
182
+		RequestInterface $request,
183
+		EE_Maintenance_Mode $maintenance_mode
184
+	) {
185
+		$this->registry = $registry;
186
+		$this->loader = $loader;
187
+		$this->request = $request;
188
+		$this->maintenance_mode = $maintenance_mode;
189
+		do_action('AHEE__EE_System__construct__begin', $this);
190
+		add_action(
191
+			'AHEE__EE_Bootstrap__load_espresso_addons',
192
+			array($this, 'loadCapabilities'),
193
+			5
194
+		);
195
+		add_action(
196
+			'AHEE__EE_Bootstrap__load_espresso_addons',
197
+			array($this, 'loadCommandBus'),
198
+			7
199
+		);
200
+		add_action(
201
+			'AHEE__EE_Bootstrap__load_espresso_addons',
202
+			array($this, 'loadPluginApi'),
203
+			9
204
+		);
205
+		// allow addons to load first so that they can register autoloaders, set hooks for running DMS's, etc
206
+		add_action(
207
+			'AHEE__EE_Bootstrap__load_espresso_addons',
208
+			array($this, 'load_espresso_addons')
209
+		);
210
+		// when an ee addon is activated, we want to call the core hook(s) again
211
+		// because the newly-activated addon didn't get a chance to run at all
212
+		add_action('activate_plugin', array($this, 'load_espresso_addons'), 1);
213
+		// detect whether install or upgrade
214
+		add_action(
215
+			'AHEE__EE_Bootstrap__detect_activations_or_upgrades',
216
+			array($this, 'detect_activations_or_upgrades'),
217
+			3
218
+		);
219
+		// load EE_Config, EE_Textdomain, etc
220
+		add_action(
221
+			'AHEE__EE_Bootstrap__load_core_configuration',
222
+			array($this, 'load_core_configuration'),
223
+			5
224
+		);
225
+		// load specifications for matching routes to current request
226
+		add_action(
227
+			'AHEE__EE_Bootstrap__load_core_configuration',
228
+			array($this, 'loadRouteMatchSpecifications')
229
+		);
230
+		// load EE_Config, EE_Textdomain, etc
231
+		add_action(
232
+			'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets',
233
+			array($this, 'register_shortcodes_modules_and_widgets'),
234
+			7
235
+		);
236
+		// you wanna get going? I wanna get going... let's get going!
237
+		add_action(
238
+			'AHEE__EE_Bootstrap__brew_espresso',
239
+			array($this, 'brew_espresso'),
240
+			9
241
+		);
242
+		// other housekeeping
243
+		// exclude EE critical pages from wp_list_pages
244
+		add_filter(
245
+			'wp_list_pages_excludes',
246
+			array($this, 'remove_pages_from_wp_list_pages'),
247
+			10
248
+		);
249
+		// ALL EE Addons should use the following hook point to attach their initial setup too
250
+		// it's extremely important for EE Addons to register any class autoloaders so that they can be available when the EE_Config loads
251
+		do_action('AHEE__EE_System__construct__complete', $this);
252
+	}
253
+
254
+
255
+	/**
256
+	 * load and setup EE_Capabilities
257
+	 *
258
+	 * @return void
259
+	 * @throws EE_Error
260
+	 */
261
+	public function loadCapabilities()
262
+	{
263
+		$this->capabilities = $this->loader->getShared('EE_Capabilities');
264
+		add_action(
265
+			'AHEE__EE_Capabilities__init_caps__before_initialization',
266
+			function () {
267
+				LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
268
+			}
269
+		);
270
+	}
271
+
272
+
273
+	/**
274
+	 * create and cache the CommandBus, and also add middleware
275
+	 * The CapChecker middleware requires the use of EE_Capabilities
276
+	 * which is why we need to load the CommandBus after Caps are set up
277
+	 *
278
+	 * @return void
279
+	 * @throws EE_Error
280
+	 */
281
+	public function loadCommandBus()
282
+	{
283
+		$this->loader->getShared(
284
+			'CommandBusInterface',
285
+			array(
286
+				null,
287
+				apply_filters(
288
+					'FHEE__EE_Load_Espresso_Core__handle_request__CommandBus_middleware',
289
+					array(
290
+						$this->loader->getShared('EventEspresso\core\services\commands\middleware\CapChecker'),
291
+						$this->loader->getShared('EventEspresso\core\services\commands\middleware\AddActionHook'),
292
+					)
293
+				),
294
+			)
295
+		);
296
+	}
297
+
298
+
299
+	/**
300
+	 * @return void
301
+	 * @throws EE_Error
302
+	 */
303
+	public function loadPluginApi()
304
+	{
305
+		// set autoloaders for all of the classes implementing EEI_Plugin_API
306
+		// which provide helpers for EE plugin authors to more easily register certain components with EE.
307
+		EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'plugin_api');
308
+		$this->loader->getShared('EE_Request_Handler');
309
+	}
310
+
311
+
312
+	/**
313
+	 * @param string $addon_name
314
+	 * @param string $version_constant
315
+	 * @param string $min_version_required
316
+	 * @param string $load_callback
317
+	 * @param string $plugin_file_constant
318
+	 * @return void
319
+	 */
320
+	private function deactivateIncompatibleAddon(
321
+		$addon_name,
322
+		$version_constant,
323
+		$min_version_required,
324
+		$load_callback,
325
+		$plugin_file_constant
326
+	) {
327
+		if (! defined($version_constant)) {
328
+			return;
329
+		}
330
+		$addon_version = constant($version_constant);
331
+		if ($addon_version && version_compare($addon_version, $min_version_required, '<')) {
332
+			remove_action('AHEE__EE_System__load_espresso_addons', $load_callback);
333
+			if (! function_exists('deactivate_plugins')) {
334
+				require_once ABSPATH . 'wp-admin/includes/plugin.php';
335
+			}
336
+			deactivate_plugins(plugin_basename(constant($plugin_file_constant)));
337
+			unset($_GET['activate'], $_REQUEST['activate'], $_GET['activate-multi'], $_REQUEST['activate-multi']);
338
+			EE_Error::add_error(
339
+				sprintf(
340
+					esc_html__(
341
+						'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.',
342
+						'event_espresso'
343
+					),
344
+					$addon_name,
345
+					$min_version_required
346
+				),
347
+				__FILE__,
348
+				__FUNCTION__ . "({$addon_name})",
349
+				__LINE__
350
+			);
351
+			EE_Error::get_notices(false, true);
352
+		}
353
+	}
354
+
355
+
356
+	/**
357
+	 * load_espresso_addons
358
+	 * allow addons to load first so that they can set hooks for running DMS's, etc
359
+	 * this is hooked into both:
360
+	 *    'AHEE__EE_Bootstrap__load_core_configuration'
361
+	 *        which runs during the WP 'plugins_loaded' action at priority 5
362
+	 *    and the WP 'activate_plugin' hook point
363
+	 *
364
+	 * @access public
365
+	 * @return void
366
+	 */
367
+	public function load_espresso_addons()
368
+	{
369
+		$this->deactivateIncompatibleAddon(
370
+			'Wait Lists',
371
+			'EE_WAIT_LISTS_VERSION',
372
+			'1.0.0.beta.074',
373
+			'load_espresso_wait_lists',
374
+			'EE_WAIT_LISTS_PLUGIN_FILE'
375
+		);
376
+		$this->deactivateIncompatibleAddon(
377
+			'Automated Upcoming Event Notifications',
378
+			'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_VERSION',
379
+			'1.0.0.beta.091',
380
+			'load_espresso_automated_upcoming_event_notification',
381
+			'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_PLUGIN_FILE'
382
+		);
383
+		do_action('AHEE__EE_System__load_espresso_addons');
384
+		// if the WP API basic auth plugin isn't already loaded, load it now.
385
+		// We want it for mobile apps. Just include the entire plugin
386
+		// also, don't load the basic auth when a plugin is getting activated, because
387
+		// it could be the basic auth plugin, and it doesn't check if its methods are already defined
388
+		// and causes a fatal error
389
+		if ($this->request->getRequestParam('activate') !== 'true'
390
+			&& ! function_exists('json_basic_auth_handler')
391
+			&& ! function_exists('json_basic_auth_error')
392
+			&& ! in_array(
393
+				$this->request->getRequestParam('action'),
394
+				array('activate', 'activate-selected'),
395
+				true
396
+			)
397
+		) {
398
+			include_once EE_THIRD_PARTY . 'wp-api-basic-auth' . DS . 'basic-auth.php';
399
+		}
400
+		do_action('AHEE__EE_System__load_espresso_addons__complete');
401
+	}
402
+
403
+
404
+	/**
405
+	 * detect_activations_or_upgrades
406
+	 * Checks for activation or upgrade of core first;
407
+	 * then also checks if any registered addons have been activated or upgraded
408
+	 * This is hooked into 'AHEE__EE_Bootstrap__detect_activations_or_upgrades'
409
+	 * which runs during the WP 'plugins_loaded' action at priority 3
410
+	 *
411
+	 * @access public
412
+	 * @return void
413
+	 */
414
+	public function detect_activations_or_upgrades()
415
+	{
416
+		// first off: let's make sure to handle core
417
+		$this->detect_if_activation_or_upgrade();
418
+		foreach ($this->registry->addons as $addon) {
419
+			if ($addon instanceof EE_Addon) {
420
+				// detect teh request type for that addon
421
+				$addon->detect_activation_or_upgrade();
422
+			}
423
+		}
424
+	}
425
+
426
+
427
+	/**
428
+	 * detect_if_activation_or_upgrade
429
+	 * Takes care of detecting whether this is a brand new install or code upgrade,
430
+	 * and either setting up the DB or setting up maintenance mode etc.
431
+	 *
432
+	 * @access public
433
+	 * @return void
434
+	 */
435
+	public function detect_if_activation_or_upgrade()
436
+	{
437
+		do_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin');
438
+		// check if db has been updated, or if its a brand-new installation
439
+		$espresso_db_update = $this->fix_espresso_db_upgrade_option();
440
+		$request_type = $this->detect_req_type($espresso_db_update);
441
+		// EEH_Debug_Tools::printr( $request_type, '$request_type', __FILE__, __LINE__ );
442
+		switch ($request_type) {
443
+			case EE_System::req_type_new_activation:
444
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__new_activation');
445
+				$this->_handle_core_version_change($espresso_db_update);
446
+				break;
447
+			case EE_System::req_type_reactivation:
448
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__reactivation');
449
+				$this->_handle_core_version_change($espresso_db_update);
450
+				break;
451
+			case EE_System::req_type_upgrade:
452
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__upgrade');
453
+				// migrations may be required now that we've upgraded
454
+				$this->maintenance_mode->set_maintenance_mode_if_db_old();
455
+				$this->_handle_core_version_change($espresso_db_update);
456
+				break;
457
+			case EE_System::req_type_downgrade:
458
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__downgrade');
459
+				// its possible migrations are no longer required
460
+				$this->maintenance_mode->set_maintenance_mode_if_db_old();
461
+				$this->_handle_core_version_change($espresso_db_update);
462
+				break;
463
+			case EE_System::req_type_normal:
464
+			default:
465
+				break;
466
+		}
467
+		do_action('AHEE__EE_System__detect_if_activation_or_upgrade__complete');
468
+	}
469
+
470
+
471
+	/**
472
+	 * Updates the list of installed versions and sets hooks for
473
+	 * initializing the database later during the request
474
+	 *
475
+	 * @param array $espresso_db_update
476
+	 */
477
+	private function _handle_core_version_change($espresso_db_update)
478
+	{
479
+		$this->update_list_of_installed_versions($espresso_db_update);
480
+		// get ready to verify the DB is ok (provided we aren't in maintenance mode, of course)
481
+		add_action(
482
+			'AHEE__EE_System__perform_activations_upgrades_and_migrations',
483
+			array($this, 'initialize_db_if_no_migrations_required')
484
+		);
485
+	}
486
+
487
+
488
+	/**
489
+	 * standardizes the wp option 'espresso_db_upgrade' which actually stores
490
+	 * information about what versions of EE have been installed and activated,
491
+	 * NOT necessarily the state of the database
492
+	 *
493
+	 * @param mixed $espresso_db_update           the value of the WordPress option.
494
+	 *                                            If not supplied, fetches it from the options table
495
+	 * @return array the correct value of 'espresso_db_upgrade', after saving it, if it needed correction
496
+	 */
497
+	private function fix_espresso_db_upgrade_option($espresso_db_update = null)
498
+	{
499
+		do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
500
+		if (! $espresso_db_update) {
501
+			$espresso_db_update = get_option('espresso_db_update');
502
+		}
503
+		// check that option is an array
504
+		if (! is_array($espresso_db_update)) {
505
+			// if option is FALSE, then it never existed
506
+			if ($espresso_db_update === false) {
507
+				// make $espresso_db_update an array and save option with autoload OFF
508
+				$espresso_db_update = array();
509
+				add_option('espresso_db_update', $espresso_db_update, '', 'no');
510
+			} else {
511
+				// option is NOT FALSE but also is NOT an array, so make it an array and save it
512
+				$espresso_db_update = array($espresso_db_update => array());
513
+				update_option('espresso_db_update', $espresso_db_update);
514
+			}
515
+		} else {
516
+			$corrected_db_update = array();
517
+			// if IS an array, but is it an array where KEYS are version numbers, and values are arrays?
518
+			foreach ($espresso_db_update as $should_be_version_string => $should_be_array) {
519
+				if (is_int($should_be_version_string) && ! is_array($should_be_array)) {
520
+					// the key is an int, and the value IS NOT an array
521
+					// so it must be numerically-indexed, where values are versions installed...
522
+					// fix it!
523
+					$version_string = $should_be_array;
524
+					$corrected_db_update[ $version_string ] = array('unknown-date');
525
+				} else {
526
+					// ok it checks out
527
+					$corrected_db_update[ $should_be_version_string ] = $should_be_array;
528
+				}
529
+			}
530
+			$espresso_db_update = $corrected_db_update;
531
+			update_option('espresso_db_update', $espresso_db_update);
532
+		}
533
+		do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__complete', $espresso_db_update);
534
+		return $espresso_db_update;
535
+	}
536
+
537
+
538
+	/**
539
+	 * Does the traditional work of setting up the plugin's database and adding default data.
540
+	 * If migration script/process did not exist, this is what would happen on every activation/reactivation/upgrade.
541
+	 * NOTE: if we're in maintenance mode (which would be the case if we detect there are data
542
+	 * migration scripts that need to be run and a version change happens), enqueues core for database initialization,
543
+	 * so that it will be done when migrations are finished
544
+	 *
545
+	 * @param boolean $initialize_addons_too if true, we double-check addons' database tables etc too;
546
+	 * @param boolean $verify_schema         if true will re-check the database tables have the correct schema.
547
+	 *                                       This is a resource-intensive job
548
+	 *                                       so we prefer to only do it when necessary
549
+	 * @return void
550
+	 * @throws EE_Error
551
+	 */
552
+	public function initialize_db_if_no_migrations_required($initialize_addons_too = false, $verify_schema = true)
553
+	{
554
+		$request_type = $this->detect_req_type();
555
+		// only initialize system if we're not in maintenance mode.
556
+		if ($this->maintenance_mode->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
557
+			/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
558
+			$rewrite_rules = $this->loader->getShared(
559
+				'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
560
+			);
561
+			$rewrite_rules->flush();
562
+			if ($verify_schema) {
563
+				EEH_Activation::initialize_db_and_folders();
564
+			}
565
+			EEH_Activation::initialize_db_content();
566
+			EEH_Activation::system_initialization();
567
+			if ($initialize_addons_too) {
568
+				$this->initialize_addons();
569
+			}
570
+		} else {
571
+			EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for('Core');
572
+		}
573
+		if ($request_type === EE_System::req_type_new_activation
574
+			|| $request_type === EE_System::req_type_reactivation
575
+			|| (
576
+				$request_type === EE_System::req_type_upgrade
577
+				&& $this->is_major_version_change()
578
+			)
579
+		) {
580
+			add_action('AHEE__EE_System__initialize_last', array($this, 'redirect_to_about_ee'), 9);
581
+		}
582
+	}
583
+
584
+
585
+	/**
586
+	 * Initializes the db for all registered addons
587
+	 *
588
+	 * @throws EE_Error
589
+	 */
590
+	public function initialize_addons()
591
+	{
592
+		// foreach registered addon, make sure its db is up-to-date too
593
+		foreach ($this->registry->addons as $addon) {
594
+			if ($addon instanceof EE_Addon) {
595
+				$addon->initialize_db_if_no_migrations_required();
596
+			}
597
+		}
598
+	}
599
+
600
+
601
+	/**
602
+	 * Adds the current code version to the saved wp option which stores a list of all ee versions ever installed.
603
+	 *
604
+	 * @param    array  $version_history
605
+	 * @param    string $current_version_to_add version to be added to the version history
606
+	 * @return    boolean success as to whether or not this option was changed
607
+	 */
608
+	public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
609
+	{
610
+		if (! $version_history) {
611
+			$version_history = $this->fix_espresso_db_upgrade_option($version_history);
612
+		}
613
+		if ($current_version_to_add === null) {
614
+			$current_version_to_add = espresso_version();
615
+		}
616
+		$version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
617
+		// re-save
618
+		return update_option('espresso_db_update', $version_history);
619
+	}
620
+
621
+
622
+	/**
623
+	 * Detects if the current version indicated in the has existed in the list of
624
+	 * previously-installed versions of EE (espresso_db_update). Does NOT modify it (ie, no side-effect)
625
+	 *
626
+	 * @param array $espresso_db_update array from the wp option stored under the name 'espresso_db_update'.
627
+	 *                                  If not supplied, fetches it from the options table.
628
+	 *                                  Also, caches its result so later parts of the code can also know whether
629
+	 *                                  there's been an update or not. This way we can add the current version to
630
+	 *                                  espresso_db_update, but still know if this is a new install or not
631
+	 * @return int one of the constants on EE_System::req_type_
632
+	 */
633
+	public function detect_req_type($espresso_db_update = null)
634
+	{
635
+		if ($this->_req_type === null) {
636
+			$espresso_db_update = ! empty($espresso_db_update)
637
+				? $espresso_db_update
638
+				: $this->fix_espresso_db_upgrade_option();
639
+			$this->_req_type = EE_System::detect_req_type_given_activation_history(
640
+				$espresso_db_update,
641
+				'ee_espresso_activation',
642
+				espresso_version()
643
+			);
644
+			$this->_major_version_change = $this->_detect_major_version_change($espresso_db_update);
645
+			$this->request->setIsActivation($this->_req_type !== EE_System::req_type_normal);
646
+		}
647
+		return $this->_req_type;
648
+	}
649
+
650
+
651
+	/**
652
+	 * Returns whether or not there was a non-micro version change (ie, change in either
653
+	 * the first or second number in the version. Eg 4.9.0.rc.001 to 4.10.0.rc.000,
654
+	 * but not 4.9.0.rc.0001 to 4.9.1.rc.0001
655
+	 *
656
+	 * @param $activation_history
657
+	 * @return bool
658
+	 */
659
+	private function _detect_major_version_change($activation_history)
660
+	{
661
+		$previous_version = EE_System::_get_most_recently_active_version_from_activation_history($activation_history);
662
+		$previous_version_parts = explode('.', $previous_version);
663
+		$current_version_parts = explode('.', espresso_version());
664
+		return isset($previous_version_parts[0], $previous_version_parts[1], $current_version_parts[0], $current_version_parts[1])
665
+			   && ($previous_version_parts[0] !== $current_version_parts[0]
666
+				   || $previous_version_parts[1] !== $current_version_parts[1]
667
+			   );
668
+	}
669
+
670
+
671
+	/**
672
+	 * Returns true if either the major or minor version of EE changed during this request.
673
+	 * 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
674
+	 *
675
+	 * @return bool
676
+	 */
677
+	public function is_major_version_change()
678
+	{
679
+		return $this->_major_version_change;
680
+	}
681
+
682
+
683
+	/**
684
+	 * Determines the request type for any ee addon, given three piece of info: the current array of activation
685
+	 * histories (for core that' 'espresso_db_update' wp option); the name of the WordPress option which is temporarily
686
+	 * set upon activation of the plugin (for core it's 'ee_espresso_activation'); and the version that this plugin was
687
+	 * just activated to (for core that will always be espresso_version())
688
+	 *
689
+	 * @param array  $activation_history_for_addon     the option's value which stores the activation history for this
690
+	 *                                                 ee plugin. for core that's 'espresso_db_update'
691
+	 * @param string $activation_indicator_option_name the name of the WordPress option that is temporarily set to
692
+	 *                                                 indicate that this plugin was just activated
693
+	 * @param string $version_to_upgrade_to            the version that was just upgraded to (for core that will be
694
+	 *                                                 espresso_version())
695
+	 * @return int one of the constants on EE_System::req_type_*
696
+	 */
697
+	public static function detect_req_type_given_activation_history(
698
+		$activation_history_for_addon,
699
+		$activation_indicator_option_name,
700
+		$version_to_upgrade_to
701
+	) {
702
+		$version_is_higher = self::_new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to);
703
+		if ($activation_history_for_addon) {
704
+			// it exists, so this isn't a completely new install
705
+			// check if this version already in that list of previously installed versions
706
+			if (! isset($activation_history_for_addon[ $version_to_upgrade_to ])) {
707
+				// it a version we haven't seen before
708
+				if ($version_is_higher === 1) {
709
+					$req_type = EE_System::req_type_upgrade;
710
+				} else {
711
+					$req_type = EE_System::req_type_downgrade;
712
+				}
713
+				delete_option($activation_indicator_option_name);
714
+			} else {
715
+				// its not an update. maybe a reactivation?
716
+				if (get_option($activation_indicator_option_name, false)) {
717
+					if ($version_is_higher === -1) {
718
+						$req_type = EE_System::req_type_downgrade;
719
+					} elseif ($version_is_higher === 0) {
720
+						// we've seen this version before, but it's an activation. must be a reactivation
721
+						$req_type = EE_System::req_type_reactivation;
722
+					} else {// $version_is_higher === 1
723
+						$req_type = EE_System::req_type_upgrade;
724
+					}
725
+					delete_option($activation_indicator_option_name);
726
+				} else {
727
+					// we've seen this version before and the activation indicate doesn't show it was just activated
728
+					if ($version_is_higher === -1) {
729
+						$req_type = EE_System::req_type_downgrade;
730
+					} elseif ($version_is_higher === 0) {
731
+						// we've seen this version before and it's not an activation. its normal request
732
+						$req_type = EE_System::req_type_normal;
733
+					} else {// $version_is_higher === 1
734
+						$req_type = EE_System::req_type_upgrade;
735
+					}
736
+				}
737
+			}
738
+		} else {
739
+			// brand new install
740
+			$req_type = EE_System::req_type_new_activation;
741
+			delete_option($activation_indicator_option_name);
742
+		}
743
+		return $req_type;
744
+	}
745
+
746
+
747
+	/**
748
+	 * Detects if the $version_to_upgrade_to is higher than the most recent version in
749
+	 * the $activation_history_for_addon
750
+	 *
751
+	 * @param array  $activation_history_for_addon (keys are versions, values are arrays of times activated,
752
+	 *                                             sometimes containing 'unknown-date'
753
+	 * @param string $version_to_upgrade_to        (current version)
754
+	 * @return int results of version_compare( $version_to_upgrade_to, $most_recently_active_version ).
755
+	 *                                             ie, -1 if $version_to_upgrade_to is LOWER (downgrade);
756
+	 *                                             0 if $version_to_upgrade_to MATCHES (reactivation or normal request);
757
+	 *                                             1 if $version_to_upgrade_to is HIGHER (upgrade) ;
758
+	 */
759
+	private static function _new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to)
760
+	{
761
+		// find the most recently-activated version
762
+		$most_recently_active_version =
763
+			EE_System::_get_most_recently_active_version_from_activation_history($activation_history_for_addon);
764
+		return version_compare($version_to_upgrade_to, $most_recently_active_version);
765
+	}
766
+
767
+
768
+	/**
769
+	 * Gets the most recently active version listed in the activation history,
770
+	 * and if none are found (ie, it's a brand new install) returns '0.0.0.dev.000'.
771
+	 *
772
+	 * @param array $activation_history  (keys are versions, values are arrays of times activated,
773
+	 *                                   sometimes containing 'unknown-date'
774
+	 * @return string
775
+	 */
776
+	private static function _get_most_recently_active_version_from_activation_history($activation_history)
777
+	{
778
+		$most_recently_active_version_activation = '1970-01-01 00:00:00';
779
+		$most_recently_active_version = '0.0.0.dev.000';
780
+		if (is_array($activation_history)) {
781
+			foreach ($activation_history as $version => $times_activated) {
782
+				// check there is a record of when this version was activated. Otherwise,
783
+				// mark it as unknown
784
+				if (! $times_activated) {
785
+					$times_activated = array('unknown-date');
786
+				}
787
+				if (is_string($times_activated)) {
788
+					$times_activated = array($times_activated);
789
+				}
790
+				foreach ($times_activated as $an_activation) {
791
+					if ($an_activation !== 'unknown-date'
792
+						&& $an_activation
793
+						   > $most_recently_active_version_activation) {
794
+						$most_recently_active_version = $version;
795
+						$most_recently_active_version_activation = $an_activation === 'unknown-date'
796
+							? '1970-01-01 00:00:00'
797
+							: $an_activation;
798
+					}
799
+				}
800
+			}
801
+		}
802
+		return $most_recently_active_version;
803
+	}
804
+
805
+
806
+	/**
807
+	 * This redirects to the about EE page after activation
808
+	 *
809
+	 * @return void
810
+	 */
811
+	public function redirect_to_about_ee()
812
+	{
813
+		$notices = EE_Error::get_notices(false);
814
+		// if current user is an admin and it's not an ajax or rest request
815
+		if (! isset($notices['errors'])
816
+			&& $this->request->isAdmin()
817
+			&& apply_filters(
818
+				'FHEE__EE_System__redirect_to_about_ee__do_redirect',
819
+				$this->capabilities->current_user_can('manage_options', 'espresso_about_default')
820
+			)
821
+		) {
822
+			$query_params = array('page' => 'espresso_about');
823
+			if (EE_System::instance()->detect_req_type() === EE_System::req_type_new_activation) {
824
+				$query_params['new_activation'] = true;
825
+			}
826
+			if (EE_System::instance()->detect_req_type() === EE_System::req_type_reactivation) {
827
+				$query_params['reactivation'] = true;
828
+			}
829
+			$url = add_query_arg($query_params, admin_url('admin.php'));
830
+			wp_safe_redirect($url);
831
+			exit();
832
+		}
833
+	}
834
+
835
+
836
+	/**
837
+	 * load_core_configuration
838
+	 * this is hooked into 'AHEE__EE_Bootstrap__load_core_configuration'
839
+	 * which runs during the WP 'plugins_loaded' action at priority 5
840
+	 *
841
+	 * @return void
842
+	 * @throws ReflectionException
843
+	 * @throws Exception
844
+	 */
845
+	public function load_core_configuration()
846
+	{
847
+		do_action('AHEE__EE_System__load_core_configuration__begin', $this);
848
+		$this->loader->getShared('EE_Load_Textdomain');
849
+		// load textdomain
850
+		EE_Load_Textdomain::load_textdomain();
851
+		// load and setup EE_Config and EE_Network_Config
852
+		$config = $this->loader->getShared('EE_Config');
853
+		$this->loader->getShared('EE_Network_Config');
854
+		// setup autoloaders
855
+		// enable logging?
856
+		if ($config->admin->use_full_logging) {
857
+			$this->loader->getShared('EE_Log');
858
+		}
859
+		// check for activation errors
860
+		$activation_errors = get_option('ee_plugin_activation_errors', false);
861
+		if ($activation_errors) {
862
+			EE_Error::add_error($activation_errors, __FILE__, __FUNCTION__, __LINE__);
863
+			update_option('ee_plugin_activation_errors', false);
864
+		}
865
+		// get model names
866
+		$this->_parse_model_names();
867
+		// load caf stuff a chance to play during the activation process too.
868
+		$this->_maybe_brew_regular();
869
+		// configure custom post type definitions
870
+		$this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions');
871
+		$this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions');
872
+		do_action('AHEE__EE_System__load_core_configuration__complete', $this);
873
+	}
874
+
875
+
876
+	/**
877
+	 * cycles through all of the models/*.model.php files, and assembles an array of model names
878
+	 *
879
+	 * @return void
880
+	 * @throws ReflectionException
881
+	 */
882
+	private function _parse_model_names()
883
+	{
884
+		// get all the files in the EE_MODELS folder that end in .model.php
885
+		$models = glob(EE_MODELS . '*.model.php');
886
+		$model_names = array();
887
+		$non_abstract_db_models = array();
888
+		foreach ($models as $model) {
889
+			// get model classname
890
+			$classname = EEH_File::get_classname_from_filepath_with_standard_filename($model);
891
+			$short_name = str_replace('EEM_', '', $classname);
892
+			$reflectionClass = new ReflectionClass($classname);
893
+			if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
894
+				$non_abstract_db_models[ $short_name ] = $classname;
895
+			}
896
+			$model_names[ $short_name ] = $classname;
897
+		}
898
+		$this->registry->models = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
899
+		$this->registry->non_abstract_db_models = apply_filters(
900
+			'FHEE__EE_System__parse_implemented_model_names',
901
+			$non_abstract_db_models
902
+		);
903
+	}
904
+
905
+
906
+	/**
907
+	 * The purpose of this method is to simply check for a file named "caffeinated/brewing_regular.php" for any hooks
908
+	 * that need to be setup before our EE_System launches.
909
+	 *
910
+	 * @return void
911
+	 * @throws DomainException
912
+	 * @throws InvalidArgumentException
913
+	 * @throws InvalidDataTypeException
914
+	 * @throws InvalidInterfaceException
915
+	 * @throws InvalidClassException
916
+	 * @throws InvalidFilePathException
917
+	 */
918
+	private function _maybe_brew_regular()
919
+	{
920
+		/** @var Domain $domain */
921
+		$domain = DomainFactory::getShared(
922
+			new FullyQualifiedName(
923
+				'EventEspresso\core\domain\Domain'
924
+			),
925
+			array(
926
+				new FilePath(EVENT_ESPRESSO_MAIN_FILE),
927
+				Version::fromString(espresso_version()),
928
+			)
929
+		);
930
+		if ($domain->isCaffeinated()) {
931
+			require_once EE_CAFF_PATH . 'brewing_regular.php';
932
+		}
933
+	}
934
+
935
+
936
+	/**
937
+	 * @since 4.9.71.p
938
+	 * @throws Exception
939
+	 */
940
+	public function loadRouteMatchSpecifications()
941
+	{
942
+		try {
943
+			$this->loader->getShared(
944
+				'EventEspresso\core\services\route_match\RouteMatchSpecificationManager'
945
+			);
946
+		} catch (Exception $exception) {
947
+			new ExceptionStackTraceDisplay($exception);
948
+		}
949
+		do_action('AHEE__EE_System__loadRouteMatchSpecifications');
950
+	}
951
+
952
+
953
+	/**
954
+	 * register_shortcodes_modules_and_widgets
955
+	 * generate lists of shortcodes and modules, then verify paths and classes
956
+	 * This is hooked into 'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets'
957
+	 * which runs during the WP 'plugins_loaded' action at priority 7
958
+	 *
959
+	 * @access public
960
+	 * @return void
961
+	 * @throws Exception
962
+	 */
963
+	public function register_shortcodes_modules_and_widgets()
964
+	{
965
+		if ($this->request->isFrontend() || $this->request->isIframe() || $this->request->isAjax()) {
966
+			try {
967
+				// load, register, and add shortcodes the new way
968
+				$this->loader->getShared(
969
+					'EventEspresso\core\services\shortcodes\ShortcodesManager',
970
+					array(
971
+						// and the old way, but we'll put it under control of the new system
972
+						EE_Config::getLegacyShortcodesManager(),
973
+					)
974
+				);
975
+			} catch (Exception $exception) {
976
+				new ExceptionStackTraceDisplay($exception);
977
+			}
978
+		}
979
+		do_action('AHEE__EE_System__register_shortcodes_modules_and_widgets');
980
+		// check for addons using old hook point
981
+		if (has_action('AHEE__EE_System__register_shortcodes_modules_and_addons')) {
982
+			$this->_incompatible_addon_error();
983
+		}
984
+	}
985
+
986
+
987
+	/**
988
+	 * _incompatible_addon_error
989
+	 *
990
+	 * @access public
991
+	 * @return void
992
+	 */
993
+	private function _incompatible_addon_error()
994
+	{
995
+		// get array of classes hooking into here
996
+		$class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook(
997
+			'AHEE__EE_System__register_shortcodes_modules_and_addons'
998
+		);
999
+		if (! empty($class_names)) {
1000
+			$msg = __(
1001
+				'The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
1002
+				'event_espresso'
1003
+			);
1004
+			$msg .= '<ul>';
1005
+			foreach ($class_names as $class_name) {
1006
+				$msg .= '<li><b>Event Espresso - '
1007
+						. str_replace(
1008
+							array('EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'),
1009
+							'',
1010
+							$class_name
1011
+						) . '</b></li>';
1012
+			}
1013
+			$msg .= '</ul>';
1014
+			$msg .= __(
1015
+				'Compatibility issues can be avoided and/or resolved by keeping addons and plugins updated to the latest version.',
1016
+				'event_espresso'
1017
+			);
1018
+			// save list of incompatible addons to wp-options for later use
1019
+			add_option('ee_incompatible_addons', $class_names, '', 'no');
1020
+			if (is_admin()) {
1021
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1022
+			}
1023
+		}
1024
+	}
1025
+
1026
+
1027
+	/**
1028
+	 * brew_espresso
1029
+	 * begins the process of setting hooks for initializing EE in the correct order
1030
+	 * This is happening on the 'AHEE__EE_Bootstrap__brew_espresso' hook point
1031
+	 * which runs during the WP 'plugins_loaded' action at priority 9
1032
+	 *
1033
+	 * @return void
1034
+	 */
1035
+	public function brew_espresso()
1036
+	{
1037
+		do_action('AHEE__EE_System__brew_espresso__begin', $this);
1038
+		// load some final core systems
1039
+		add_action('init', array($this, 'set_hooks_for_core'), 1);
1040
+		add_action('init', array($this, 'perform_activations_upgrades_and_migrations'), 3);
1041
+		add_action('init', array($this, 'load_CPTs_and_session'), 5);
1042
+		add_action('init', array($this, 'load_controllers'), 7);
1043
+		add_action('init', array($this, 'core_loaded_and_ready'), 9);
1044
+		add_action('init', array($this, 'initialize'), 10);
1045
+		add_action('init', array($this, 'initialize_last'), 100);
1046
+		if (is_admin() && apply_filters('FHEE__EE_System__brew_espresso__load_pue', true)) {
1047
+			// pew pew pew
1048
+			$this->loader->getShared('EventEspresso\core\services\licensing\LicenseService');
1049
+			do_action('AHEE__EE_System__brew_espresso__after_pue_init');
1050
+		}
1051
+		do_action('AHEE__EE_System__brew_espresso__complete', $this);
1052
+	}
1053
+
1054
+
1055
+	/**
1056
+	 *    set_hooks_for_core
1057
+	 *
1058
+	 * @access public
1059
+	 * @return    void
1060
+	 * @throws EE_Error
1061
+	 */
1062
+	public function set_hooks_for_core()
1063
+	{
1064
+		$this->_deactivate_incompatible_addons();
1065
+		do_action('AHEE__EE_System__set_hooks_for_core');
1066
+		$this->loader->getShared('EventEspresso\core\domain\values\session\SessionLifespan');
1067
+		// caps need to be initialized on every request so that capability maps are set.
1068
+		// @see https://events.codebasehq.com/projects/event-espresso/tickets/8674
1069
+		$this->registry->CAP->init_caps();
1070
+	}
1071
+
1072
+
1073
+	/**
1074
+	 * Using the information gathered in EE_System::_incompatible_addon_error,
1075
+	 * deactivates any addons considered incompatible with the current version of EE
1076
+	 */
1077
+	private function _deactivate_incompatible_addons()
1078
+	{
1079
+		$incompatible_addons = get_option('ee_incompatible_addons', array());
1080
+		if (! empty($incompatible_addons)) {
1081
+			$active_plugins = get_option('active_plugins', array());
1082
+			foreach ($active_plugins as $active_plugin) {
1083
+				foreach ($incompatible_addons as $incompatible_addon) {
1084
+					if (strpos($active_plugin, $incompatible_addon) !== false) {
1085
+						unset($_GET['activate']);
1086
+						espresso_deactivate_plugin($active_plugin);
1087
+					}
1088
+				}
1089
+			}
1090
+		}
1091
+	}
1092
+
1093
+
1094
+	/**
1095
+	 *    perform_activations_upgrades_and_migrations
1096
+	 *
1097
+	 * @access public
1098
+	 * @return    void
1099
+	 */
1100
+	public function perform_activations_upgrades_and_migrations()
1101
+	{
1102
+		do_action('AHEE__EE_System__perform_activations_upgrades_and_migrations');
1103
+	}
1104
+
1105
+
1106
+	/**
1107
+	 * @return void
1108
+	 * @throws DomainException
1109
+	 */
1110
+	public function load_CPTs_and_session()
1111
+	{
1112
+		do_action('AHEE__EE_System__load_CPTs_and_session__start');
1113
+		/** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies $register_custom_taxonomies */
1114
+		$register_custom_taxonomies = $this->loader->getShared(
1115
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies'
1116
+		);
1117
+		$register_custom_taxonomies->registerCustomTaxonomies();
1118
+		/** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes $register_custom_post_types */
1119
+		$register_custom_post_types = $this->loader->getShared(
1120
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes'
1121
+		);
1122
+		$register_custom_post_types->registerCustomPostTypes();
1123
+		/** @var EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms $register_custom_taxonomy_terms */
1124
+		$register_custom_taxonomy_terms = $this->loader->getShared(
1125
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms'
1126
+		);
1127
+		$register_custom_taxonomy_terms->registerCustomTaxonomyTerms();
1128
+		// load legacy Custom Post Types and Taxonomies
1129
+		$this->loader->getShared('EE_Register_CPTs');
1130
+		do_action('AHEE__EE_System__load_CPTs_and_session__complete');
1131
+	}
1132
+
1133
+
1134
+	/**
1135
+	 * load_controllers
1136
+	 * this is the best place to load any additional controllers that needs access to EE core.
1137
+	 * it is expected that all basic core EE systems, that are not dependant on the current request are loaded at this
1138
+	 * time
1139
+	 *
1140
+	 * @access public
1141
+	 * @return void
1142
+	 */
1143
+	public function load_controllers()
1144
+	{
1145
+		do_action('AHEE__EE_System__load_controllers__start');
1146
+		// let's get it started
1147
+		if (! $this->maintenance_mode->level()
1148
+			&& ($this->request->isFrontend() || $this->request->isFrontAjax())
1149
+		) {
1150
+			do_action('AHEE__EE_System__load_controllers__load_front_controllers');
1151
+			$this->loader->getShared('EE_Front_Controller');
1152
+		} elseif ($this->request->isAdmin() || $this->request->isAdminAjax()) {
1153
+			do_action('AHEE__EE_System__load_controllers__load_admin_controllers');
1154
+			$this->loader->getShared('EE_Admin');
1155
+		} elseif ($this->request->isWordPressHeartbeat()) {
1156
+			$this->loader->getShared('EventEspresso\core\domain\services\admin\ajax\WordpressHeartbeat');
1157
+		}
1158
+		do_action('AHEE__EE_System__load_controllers__complete');
1159
+	}
1160
+
1161
+
1162
+	/**
1163
+	 * core_loaded_and_ready
1164
+	 * all of the basic EE core should be loaded at this point and available regardless of M-Mode
1165
+	 *
1166
+	 * @access public
1167
+	 * @return void
1168
+	 * @throws Exception
1169
+	 */
1170
+	public function core_loaded_and_ready()
1171
+	{
1172
+		if ($this->request->isAdmin()
1173
+			|| $this->request->isFrontend()
1174
+			|| $this->request->isIframe()
1175
+			|| $this->request->isWordPressApi()
1176
+		) {
1177
+			try {
1178
+				$this->loader->getShared('EventEspresso\core\services\assets\Registry');
1179
+				$this->loader->getShared('EventEspresso\core\domain\services\assets\CoreAssetManager');
1180
+				if ($this->canLoadBlocks()) {
1181
+					$this->loader->getShared(
1182
+						'EventEspresso\core\services\editor\BlockRegistrationManager'
1183
+					);
1184
+				}
1185
+			} catch (Exception $exception) {
1186
+				new ExceptionStackTraceDisplay($exception);
1187
+			}
1188
+		}
1189
+		if ($this->request->isAdmin()
1190
+			|| $this->request->isEeAjax()
1191
+			|| $this->request->isFrontend()
1192
+		) {
1193
+			$this->loader->getShared('EE_Session');
1194
+		}
1195
+		// integrate WP_Query with the EE models
1196
+		$this->loader->getShared('EE_CPT_Strategy');
1197
+		do_action('AHEE__EE_System__core_loaded_and_ready');
1198
+		// always load template tags, because it's faster than checking if it's a front-end request, and many page
1199
+		// builders require these even on the front-end
1200
+		require_once EE_PUBLIC . 'template_tags.php';
1201
+		do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1202
+	}
1203
+
1204
+
1205
+	/**
1206
+	 * initialize
1207
+	 * this is the best place to begin initializing client code
1208
+	 *
1209
+	 * @access public
1210
+	 * @return void
1211
+	 */
1212
+	public function initialize()
1213
+	{
1214
+		do_action('AHEE__EE_System__initialize');
1215
+	}
1216
+
1217
+
1218
+	/**
1219
+	 * initialize_last
1220
+	 * this is run really late during the WP init hook point, and ensures that mostly everything else that needs to
1221
+	 * initialize has done so
1222
+	 *
1223
+	 * @access public
1224
+	 * @return void
1225
+	 */
1226
+	public function initialize_last()
1227
+	{
1228
+		do_action('AHEE__EE_System__initialize_last');
1229
+		/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
1230
+		$rewrite_rules = $this->loader->getShared(
1231
+			'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
1232
+		);
1233
+		$rewrite_rules->flushRewriteRules();
1234
+		add_action('admin_bar_init', array($this, 'addEspressoToolbar'));
1235
+		if (($this->request->isAjax() || $this->request->isAdmin())
1236
+			&& $this->maintenance_mode->models_can_query()) {
1237
+			$this->loader->getShared('EventEspresso\core\services\privacy\export\PersonalDataExporterManager');
1238
+			$this->loader->getShared('EventEspresso\core\services\privacy\erasure\PersonalDataEraserManager');
1239
+		}
1240
+	}
1241
+
1242
+
1243
+	/**
1244
+	 * @return void
1245
+	 * @throws EE_Error
1246
+	 */
1247
+	public function addEspressoToolbar()
1248
+	{
1249
+		$this->loader->getShared(
1250
+			'EventEspresso\core\domain\services\admin\AdminToolBar',
1251
+			array($this->registry->CAP)
1252
+		);
1253
+	}
1254
+
1255
+
1256
+	/**
1257
+	 * do_not_cache
1258
+	 * sets no cache headers and defines no cache constants for WP plugins
1259
+	 *
1260
+	 * @access public
1261
+	 * @return void
1262
+	 */
1263
+	public static function do_not_cache()
1264
+	{
1265
+		// set no cache constants
1266
+		if (! defined('DONOTCACHEPAGE')) {
1267
+			define('DONOTCACHEPAGE', true);
1268
+		}
1269
+		if (! defined('DONOTCACHCEOBJECT')) {
1270
+			define('DONOTCACHCEOBJECT', true);
1271
+		}
1272
+		if (! defined('DONOTCACHEDB')) {
1273
+			define('DONOTCACHEDB', true);
1274
+		}
1275
+		// add no cache headers
1276
+		add_action('send_headers', array('EE_System', 'nocache_headers'), 10);
1277
+		// plus a little extra for nginx and Google Chrome
1278
+		add_filter('nocache_headers', array('EE_System', 'extra_nocache_headers'), 10, 1);
1279
+		// prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes with the registration process
1280
+		remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
1281
+	}
1282
+
1283
+
1284
+	/**
1285
+	 *    extra_nocache_headers
1286
+	 *
1287
+	 * @access    public
1288
+	 * @param $headers
1289
+	 * @return    array
1290
+	 */
1291
+	public static function extra_nocache_headers($headers)
1292
+	{
1293
+		// for NGINX
1294
+		$headers['X-Accel-Expires'] = 0;
1295
+		// plus extra for Google Chrome since it doesn't seem to respect "no-cache", but WILL respect "no-store"
1296
+		$headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0';
1297
+		return $headers;
1298
+	}
1299
+
1300
+
1301
+	/**
1302
+	 *    nocache_headers
1303
+	 *
1304
+	 * @access    public
1305
+	 * @return    void
1306
+	 */
1307
+	public static function nocache_headers()
1308
+	{
1309
+		nocache_headers();
1310
+	}
1311
+
1312
+
1313
+	/**
1314
+	 * simply hooks into "wp_list_pages_exclude" filter (for wp_list_pages method) and makes sure EE critical pages are
1315
+	 * never returned with the function.
1316
+	 *
1317
+	 * @param  array $exclude_array any existing pages being excluded are in this array.
1318
+	 * @return array
1319
+	 */
1320
+	public function remove_pages_from_wp_list_pages($exclude_array)
1321
+	{
1322
+		return array_merge($exclude_array, $this->registry->CFG->core->get_critical_pages_array());
1323
+	}
1324
+
1325
+
1326
+	/**
1327
+	 * Return whether blocks can be registered/loaded or not.
1328
+	 * @return bool
1329
+	 */
1330
+	private function canLoadBlocks()
1331
+	{
1332
+		return apply_filters('FHEE__EE_System__canLoadBlocks', true)
1333
+			   && function_exists('register_block_type')
1334
+			   // don't load blocks if in the Divi page builder editor context
1335
+			   // @see https://github.com/eventespresso/event-espresso-core/issues/814
1336
+			   && ! $this->request->getRequestParam('et_fb', false);
1337
+	}
1338 1338
 }
Please login to merge, or discard this patch.
core/domain/entities/contexts/RequestTypeContext.php 1 patch
Indentation   +151 added lines, -151 removed lines patch added patch discarded remove patch
@@ -16,155 +16,155 @@
 block discarded – undo
16 16
 class RequestTypeContext extends Context
17 17
 {
18 18
 
19
-    /**
20
-     * indicates that the current request involves some form of activation
21
-     */
22
-    const ACTIVATION = 'activation-request';
23
-
24
-    /**
25
-     * indicates that the current request is for the admin but is not being made via AJAX
26
-     */
27
-    const ADMIN = 'non-ajax-admin-request';
28
-
29
-    /**
30
-     * indicates that the current request is for the admin AND is being made via AJAX
31
-     */
32
-    const AJAX_ADMIN = 'admin-ajax-request';
33
-
34
-    /**
35
-     * indicates that the current request is for the frontend AND is being made via AJAX
36
-     */
37
-    const AJAX_FRONT = 'frontend-ajax-request';
38
-
39
-    /**
40
-     * indicates that the current request is for the WP Heartbeat
41
-     */
42
-    const AJAX_HEARTBEAT = 'admin-ajax-heartbeat';
43
-
44
-    /**
45
-     * indicates that the current request is being made via AJAX, but is NOT for EE
46
-     */
47
-    const AJAX_OTHER = 'other-ajax-request';
48
-
49
-    /**
50
-     * indicates that the current request is for the EE REST API
51
-     */
52
-    const API = 'rest-api';
53
-
54
-    /**
55
-     * indicates that the current request is from the command line
56
-     */
57
-    const CLI = 'command-line';
58
-
59
-    /**
60
-     * indicates that the current request is for a WP_Cron
61
-     */
62
-    const CRON = 'wp-cron';
63
-
64
-    /**
65
-     * indicates that the current request is for a feed (ie: RSS)
66
-     */
67
-    const FEED = 'feed-request';
68
-
69
-    /**
70
-     * indicates that the current request is for the frontend but is not being made via AJAX
71
-     */
72
-    const FRONTEND = 'non-ajax-frontend-request';
73
-
74
-    /**
75
-     * indicates that the current request is for content that is to be displayed within an iframe
76
-     */
77
-    const IFRAME = 'iframe-request';
78
-
79
-    /**
80
-     * indicates that the current request is for the WP REST API
81
-     */
82
-    const WP_API = 'wp-rest-api';
83
-
84
-    /**
85
-     * indicates that the current request is a loopback sent from WP core to test for errors
86
-     */
87
-    const WP_SCRAPE = 'wordpress-scrape';
88
-
89
-    /**
90
-     * @var boolean $is_activation
91
-     */
92
-    private $is_activation = false;
93
-
94
-    /**
95
-     * @var array $valid_request_types
96
-     */
97
-    private $valid_request_types = array();
98
-
99
-
100
-    /**
101
-     * RequestTypeContext constructor.
102
-     *
103
-     * @param string $slug
104
-     * @param string $description
105
-     * @throws InvalidArgumentException
106
-     */
107
-    public function __construct($slug, $description)
108
-    {
109
-        parent::__construct($slug, $description);
110
-        if (! in_array($this->slug(), $this->validRequestTypes(), true)) {
111
-            throw new InvalidArgumentException(
112
-                sprintf(
113
-                    esc_html__(
114
-                        'The RequestTypeContext slug must be one of the following values: %1$s %2$s',
115
-                        'event_espresso'
116
-                    ),
117
-                    var_export($this->validRequestTypes(), true)
118
-                )
119
-            );
120
-        }
121
-    }
122
-
123
-
124
-    /**
125
-     * @return array
126
-     */
127
-    public function validRequestTypes()
128
-    {
129
-        if (empty($this->valid_request_types)) {
130
-            $this->valid_request_types = apply_filters(
131
-                'FHEE__EventEspresso_core_domain_entities_contexts_RequestTypeContext__validRequestTypes',
132
-                array(
133
-                    RequestTypeContext::ACTIVATION,
134
-                    RequestTypeContext::ADMIN,
135
-                    RequestTypeContext::AJAX_ADMIN,
136
-                    RequestTypeContext::AJAX_FRONT,
137
-                    RequestTypeContext::AJAX_HEARTBEAT,
138
-                    RequestTypeContext::AJAX_OTHER,
139
-                    RequestTypeContext::API,
140
-                    RequestTypeContext::CLI,
141
-                    RequestTypeContext::CRON,
142
-                    RequestTypeContext::FEED,
143
-                    RequestTypeContext::FRONTEND,
144
-                    RequestTypeContext::IFRAME,
145
-                    RequestTypeContext::WP_API,
146
-                    RequestTypeContext::WP_SCRAPE,
147
-                )
148
-            );
149
-        }
150
-        return $this->valid_request_types;
151
-    }
152
-
153
-
154
-    /**
155
-     * @return bool
156
-     */
157
-    public function isActivation()
158
-    {
159
-        return $this->is_activation;
160
-    }
161
-
162
-
163
-    /**
164
-     * @param bool $is_activation
165
-     */
166
-    public function setIsActivation($is_activation)
167
-    {
168
-        $this->is_activation = filter_var($is_activation, FILTER_VALIDATE_BOOLEAN);
169
-    }
19
+	/**
20
+	 * indicates that the current request involves some form of activation
21
+	 */
22
+	const ACTIVATION = 'activation-request';
23
+
24
+	/**
25
+	 * indicates that the current request is for the admin but is not being made via AJAX
26
+	 */
27
+	const ADMIN = 'non-ajax-admin-request';
28
+
29
+	/**
30
+	 * indicates that the current request is for the admin AND is being made via AJAX
31
+	 */
32
+	const AJAX_ADMIN = 'admin-ajax-request';
33
+
34
+	/**
35
+	 * indicates that the current request is for the frontend AND is being made via AJAX
36
+	 */
37
+	const AJAX_FRONT = 'frontend-ajax-request';
38
+
39
+	/**
40
+	 * indicates that the current request is for the WP Heartbeat
41
+	 */
42
+	const AJAX_HEARTBEAT = 'admin-ajax-heartbeat';
43
+
44
+	/**
45
+	 * indicates that the current request is being made via AJAX, but is NOT for EE
46
+	 */
47
+	const AJAX_OTHER = 'other-ajax-request';
48
+
49
+	/**
50
+	 * indicates that the current request is for the EE REST API
51
+	 */
52
+	const API = 'rest-api';
53
+
54
+	/**
55
+	 * indicates that the current request is from the command line
56
+	 */
57
+	const CLI = 'command-line';
58
+
59
+	/**
60
+	 * indicates that the current request is for a WP_Cron
61
+	 */
62
+	const CRON = 'wp-cron';
63
+
64
+	/**
65
+	 * indicates that the current request is for a feed (ie: RSS)
66
+	 */
67
+	const FEED = 'feed-request';
68
+
69
+	/**
70
+	 * indicates that the current request is for the frontend but is not being made via AJAX
71
+	 */
72
+	const FRONTEND = 'non-ajax-frontend-request';
73
+
74
+	/**
75
+	 * indicates that the current request is for content that is to be displayed within an iframe
76
+	 */
77
+	const IFRAME = 'iframe-request';
78
+
79
+	/**
80
+	 * indicates that the current request is for the WP REST API
81
+	 */
82
+	const WP_API = 'wp-rest-api';
83
+
84
+	/**
85
+	 * indicates that the current request is a loopback sent from WP core to test for errors
86
+	 */
87
+	const WP_SCRAPE = 'wordpress-scrape';
88
+
89
+	/**
90
+	 * @var boolean $is_activation
91
+	 */
92
+	private $is_activation = false;
93
+
94
+	/**
95
+	 * @var array $valid_request_types
96
+	 */
97
+	private $valid_request_types = array();
98
+
99
+
100
+	/**
101
+	 * RequestTypeContext constructor.
102
+	 *
103
+	 * @param string $slug
104
+	 * @param string $description
105
+	 * @throws InvalidArgumentException
106
+	 */
107
+	public function __construct($slug, $description)
108
+	{
109
+		parent::__construct($slug, $description);
110
+		if (! in_array($this->slug(), $this->validRequestTypes(), true)) {
111
+			throw new InvalidArgumentException(
112
+				sprintf(
113
+					esc_html__(
114
+						'The RequestTypeContext slug must be one of the following values: %1$s %2$s',
115
+						'event_espresso'
116
+					),
117
+					var_export($this->validRequestTypes(), true)
118
+				)
119
+			);
120
+		}
121
+	}
122
+
123
+
124
+	/**
125
+	 * @return array
126
+	 */
127
+	public function validRequestTypes()
128
+	{
129
+		if (empty($this->valid_request_types)) {
130
+			$this->valid_request_types = apply_filters(
131
+				'FHEE__EventEspresso_core_domain_entities_contexts_RequestTypeContext__validRequestTypes',
132
+				array(
133
+					RequestTypeContext::ACTIVATION,
134
+					RequestTypeContext::ADMIN,
135
+					RequestTypeContext::AJAX_ADMIN,
136
+					RequestTypeContext::AJAX_FRONT,
137
+					RequestTypeContext::AJAX_HEARTBEAT,
138
+					RequestTypeContext::AJAX_OTHER,
139
+					RequestTypeContext::API,
140
+					RequestTypeContext::CLI,
141
+					RequestTypeContext::CRON,
142
+					RequestTypeContext::FEED,
143
+					RequestTypeContext::FRONTEND,
144
+					RequestTypeContext::IFRAME,
145
+					RequestTypeContext::WP_API,
146
+					RequestTypeContext::WP_SCRAPE,
147
+				)
148
+			);
149
+		}
150
+		return $this->valid_request_types;
151
+	}
152
+
153
+
154
+	/**
155
+	 * @return bool
156
+	 */
157
+	public function isActivation()
158
+	{
159
+		return $this->is_activation;
160
+	}
161
+
162
+
163
+	/**
164
+	 * @param bool $is_activation
165
+	 */
166
+	public function setIsActivation($is_activation)
167
+	{
168
+		$this->is_activation = filter_var($is_activation, FILTER_VALIDATE_BOOLEAN);
169
+	}
170 170
 }
Please login to merge, or discard this patch.
core/domain/services/admin/ajax/EventEditorHeartbeat.php 2 patches
Indentation   +43 added lines, -43 removed lines patch added patch discarded remove patch
@@ -16,52 +16,52 @@
 block discarded – undo
16 16
 class EventEditorHeartbeat
17 17
 {
18 18
 
19
-    /**
20
-     * @var Domain $domain
21
-     */
22
-    protected $domain;
19
+	/**
20
+	 * @var Domain $domain
21
+	 */
22
+	protected $domain;
23 23
 
24
-    /**
25
-     * @var EE_Environment_Config $environment
26
-     */
27
-    protected $environment;
24
+	/**
25
+	 * @var EE_Environment_Config $environment
26
+	 */
27
+	protected $environment;
28 28
 
29 29
 
30
-    /**
31
-     * EventEditorHeartbeat constructor.
32
-     *
33
-     * @param Domain                $domain
34
-     * @param EE_Environment_Config $environment
35
-     */
36
-    public function __construct(Domain $domain, EE_Environment_Config $environment)
37
-    {
38
-        $this->domain = $domain;
39
-        $this->environment = $environment;
40
-        if($this->domain->isCaffeinated()) {
41
-            add_filter('heartbeat_received', array($this, 'heartbeatResponse'), 10, 2);
42
-        }
43
-    }
30
+	/**
31
+	 * EventEditorHeartbeat constructor.
32
+	 *
33
+	 * @param Domain                $domain
34
+	 * @param EE_Environment_Config $environment
35
+	 */
36
+	public function __construct(Domain $domain, EE_Environment_Config $environment)
37
+	{
38
+		$this->domain = $domain;
39
+		$this->environment = $environment;
40
+		if($this->domain->isCaffeinated()) {
41
+			add_filter('heartbeat_received', array($this, 'heartbeatResponse'), 10, 2);
42
+		}
43
+	}
44 44
 
45 45
 
46
-    /**
47
-     * This will be used to listen for any heartbeat data packages coming via the WordPress heartbeat API and handle
48
-     * accordingly.
49
-     *
50
-     * @param array $response The existing heartbeat response array.
51
-     * @param array $data     The incoming data package.
52
-     * @return array  possibly appended response.
53
-     */
54
-    public function heartbeatResponse($response, $data)
55
-    {
56
-        /**
57
-         * check whether count of tickets is approaching the potential
58
-         * limits for the server.
59
-         */
60
-        if (! empty($data['input_count'])) {
61
-            $response['max_input_vars_check'] = $this->environment->max_input_vars_limit_check(
62
-                $data['input_count']
63
-            );
64
-        }
65
-        return $response;
66
-    }
46
+	/**
47
+	 * This will be used to listen for any heartbeat data packages coming via the WordPress heartbeat API and handle
48
+	 * accordingly.
49
+	 *
50
+	 * @param array $response The existing heartbeat response array.
51
+	 * @param array $data     The incoming data package.
52
+	 * @return array  possibly appended response.
53
+	 */
54
+	public function heartbeatResponse($response, $data)
55
+	{
56
+		/**
57
+		 * check whether count of tickets is approaching the potential
58
+		 * limits for the server.
59
+		 */
60
+		if (! empty($data['input_count'])) {
61
+			$response['max_input_vars_check'] = $this->environment->max_input_vars_limit_check(
62
+				$data['input_count']
63
+			);
64
+		}
65
+		return $response;
66
+	}
67 67
 }
68 68
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -37,7 +37,7 @@  discard block
 block discarded – undo
37 37
     {
38 38
         $this->domain = $domain;
39 39
         $this->environment = $environment;
40
-        if($this->domain->isCaffeinated()) {
40
+        if ($this->domain->isCaffeinated()) {
41 41
             add_filter('heartbeat_received', array($this, 'heartbeatResponse'), 10, 2);
42 42
         }
43 43
     }
@@ -57,7 +57,7 @@  discard block
 block discarded – undo
57 57
          * check whether count of tickets is approaching the potential
58 58
          * limits for the server.
59 59
          */
60
-        if (! empty($data['input_count'])) {
60
+        if ( ! empty($data['input_count'])) {
61 61
             $response['max_input_vars_check'] = $this->environment->max_input_vars_limit_check(
62 62
                 $data['input_count']
63 63
             );
Please login to merge, or discard this patch.
core/domain/services/admin/ajax/WordpressHeartbeat.php 2 patches
Indentation   +41 added lines, -41 removed lines patch added patch discarded remove patch
@@ -17,51 +17,51 @@
 block discarded – undo
17 17
 class WordpressHeartbeat
18 18
 {
19 19
 
20
-    /**
21
-     * @var LoaderInterface $loader
22
-     */
23
-    protected $loader;
20
+	/**
21
+	 * @var LoaderInterface $loader
22
+	 */
23
+	protected $loader;
24 24
 
25
-    /**
26
-     * @var RequestInterface $request
27
-     */
28
-    protected $request;
25
+	/**
26
+	 * @var RequestInterface $request
27
+	 */
28
+	protected $request;
29 29
 
30 30
 
31
-    /**
32
-     * WordpressHeartbeat constructor.
33
-     *
34
-     * @param LoaderInterface $loader
35
-     * @param RequestInterface $request
36
-     */
37
-    public function __construct(
38
-        LoaderInterface $loader,
39
-        RequestInterface $request
40
-    ) {
41
-        $this->loader = $loader;
42
-        $this->request = $request;
43
-        do_action('AHEE__EventEspresso_core_domain_services_admin_ajax_WordpressHeartbeat__constructor', $this);
44
-        add_action('AHEE__EE_System__core_loaded_and_ready', array($this, 'resolveRoutes'));
45
-    }
31
+	/**
32
+	 * WordpressHeartbeat constructor.
33
+	 *
34
+	 * @param LoaderInterface $loader
35
+	 * @param RequestInterface $request
36
+	 */
37
+	public function __construct(
38
+		LoaderInterface $loader,
39
+		RequestInterface $request
40
+	) {
41
+		$this->loader = $loader;
42
+		$this->request = $request;
43
+		do_action('AHEE__EventEspresso_core_domain_services_admin_ajax_WordpressHeartbeat__constructor', $this);
44
+		add_action('AHEE__EE_System__core_loaded_and_ready', array($this, 'resolveRoutes'));
45
+	}
46 46
 
47 47
 
48
-    /**
49
-     * @since $VID:$
50
-     * @throws InvalidClassException
51
-     */
52
-    public function resolveRoutes()
53
-    {
54
-        $screenID = $this->request->getRequestParam('screen_id');
55
-        $heartbeat_data = $this->request->getRequestParam('data', array());
56
-        if ($screenID === 'espresso_events') {
57
-            $this->loader->getShared(
58
-                'EventEspresso\core\domain\services\admin\ajax\EventEditorHeartbeat'
59
-            );
60
-        } else if ($screenID === 'front'&& ! empty($heartbeat_data['espresso_thank_you_page'])) {
61
-            $this->loader->getShared(
62
-                'EventEspresso\core\domain\services\admin\ajax\ThankYouPageIpnMonitor'
63
-            );
64
-        }
65
-    }
48
+	/**
49
+	 * @since $VID:$
50
+	 * @throws InvalidClassException
51
+	 */
52
+	public function resolveRoutes()
53
+	{
54
+		$screenID = $this->request->getRequestParam('screen_id');
55
+		$heartbeat_data = $this->request->getRequestParam('data', array());
56
+		if ($screenID === 'espresso_events') {
57
+			$this->loader->getShared(
58
+				'EventEspresso\core\domain\services\admin\ajax\EventEditorHeartbeat'
59
+			);
60
+		} else if ($screenID === 'front'&& ! empty($heartbeat_data['espresso_thank_you_page'])) {
61
+			$this->loader->getShared(
62
+				'EventEspresso\core\domain\services\admin\ajax\ThankYouPageIpnMonitor'
63
+			);
64
+		}
65
+	}
66 66
 
67 67
 }
68 68
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -57,7 +57,7 @@
 block discarded – undo
57 57
             $this->loader->getShared(
58 58
                 'EventEspresso\core\domain\services\admin\ajax\EventEditorHeartbeat'
59 59
             );
60
-        } else if ($screenID === 'front'&& ! empty($heartbeat_data['espresso_thank_you_page'])) {
60
+        } else if ($screenID === 'front' && ! empty($heartbeat_data['espresso_thank_you_page'])) {
61 61
             $this->loader->getShared(
62 62
                 'EventEspresso\core\domain\services\admin\ajax\ThankYouPageIpnMonitor'
63 63
             );
Please login to merge, or discard this patch.
core/domain/services/admin/ajax/ThankYouPageIpnMonitor.php 2 patches
Indentation   +202 added lines, -202 removed lines patch added patch discarded remove patch
@@ -21,206 +21,206 @@
 block discarded – undo
21 21
 class ThankYouPageIpnMonitor
22 22
 {
23 23
 
24
-    /**
25
-     * @var EED_Thank_You_Page $thank_you_page
26
-     */
27
-    private $thank_you_page;
28
-
29
-    /**
30
-     * @var EE_Transaction $transaction
31
-     */
32
-    private $transaction;
33
-
34
-    /**
35
-     * EventEditorHeartbeat constructor.
36
-     *
37
-     */
38
-    public function __construct()
39
-    {
40
-        add_filter('heartbeat_received', array($this, 'heartbeatResponse'), 10, 3);
41
-        add_filter('heartbeat_nopriv_received', array($this, 'heartbeatResponse'), 10, 3);
42
-    }
43
-
44
-
45
-    /**
46
-     * thank_you_page_IPN_monitor
47
-     * this basically just pulls the TXN based on the reg_url_link sent from the server,
48
-     * then checks that the TXN status is not failed, and that no other errors have been generated.
49
-     * it also calculates the IPN wait time since the Thank You page was first loaded
50
-     *
51
-     * @param array $response
52
-     * @param array $data
53
-     * @return array
54
-     * @throws EE_Error
55
-     * @throws InvalidDataTypeException
56
-     * @throws InvalidInterfaceException
57
-     * @throws InvalidArgumentException
58
-     */
59
-    public function heartbeatResponse($response = array(), $data = array())
60
-    {
61
-        // does this heartbeat contain our data ?
62
-        if (! isset($data['espresso_thank_you_page'])) {
63
-            return $response;
64
-        }
65
-        // check for reg_url_link in the incoming heartbeat data
66
-        if (! isset($data['espresso_thank_you_page']['e_reg_url_link'])) {
67
-            $response['espresso_thank_you_page'] = array(
68
-                'errors' => ! empty($notices['errors'])
69
-                    ? $notices['errors']
70
-                    : __(
71
-                        'No transaction information could be retrieved because the registration URL link is missing or invalid.',
72
-                        'event_espresso'
73
-                    ),
74
-            );
75
-            return $response;
76
-        }
77
-        // kk heartbeat has our data
78
-        $response = $this->initializeThankYouPageAndTransaction($response, $data);
79
-        // if something went wrong...
80
-        if (isset($response['espresso_thank_you_page']['errors'])) {
81
-            return $response;
82
-        }
83
-        // grab transient of Transaction's status
84
-        $txn_status = isset($data['espresso_thank_you_page']['txn_status'])
85
-            ? $data['espresso_thank_you_page']['txn_status']
86
-            : null;
87
-        $response = $this->getTransactionDetails($txn_status, $response, $data);
88
-        // no payment data yet?
89
-        if(isset($response['espresso_thank_you_page']['still_waiting'])) {
90
-            return $response;
91
-        }
92
-        // TXN is happening so let's get the payments now
93
-        // if we've already gotten payments then the heartbeat data will contain the timestamp of the last time we checked
94
-        $since = isset($data['espresso_thank_you_page']['get_payments_since'])
95
-            ? $data['espresso_thank_you_page']['get_payments_since']
96
-            : 0;
97
-        return $this->paymentDetails($since);
98
-    }
99
-
100
-
101
-    /**
102
-     * @param array  $response
103
-     * @param array  $data
104
-     * @return array
105
-     * @throws EE_Error
106
-     * @throws InvalidArgumentException
107
-     * @throws InvalidDataTypeException
108
-     * @throws InvalidInterfaceException
109
-     */
110
-    private function initializeThankYouPageAndTransaction($response, $data)
111
-    {
112
-        require_once EE_MODULES . 'thank_you_page/EED_Thank_You_Page.module.php';
113
-        // set_definitions, instantiate the thank you page class, and get the ball rolling
114
-        EED_Thank_You_Page::set_definitions();
115
-        $this->thank_you_page = EED_Thank_You_Page::instance();
116
-        $this->thank_you_page->set_reg_url_link($data['espresso_thank_you_page']['e_reg_url_link']);
117
-        $this->thank_you_page->init();
118
-        $response['espresso_thank_you_page'] = array();
119
-        // get TXN
120
-        $transaction = $this->thank_you_page->get_txn();
121
-        // no TXN? then get out
122
-        if (! $transaction instanceof EE_Transaction) {
123
-            $notices = EE_Error::get_notices();
124
-            $response['espresso_thank_you_page'] = array(
125
-                'errors' => ! empty($notices['errors'])
126
-                    ? $notices['errors']
127
-                    : sprintf(
128
-                        __(
129
-                            'The information for your transaction could not be retrieved from the server or the transaction data received was invalid because of a technical reason. (%s)',
130
-                            'event_espresso'
131
-                        ),
132
-                        __LINE__
133
-                    ),
134
-            );
135
-            return $response;
136
-        }
137
-        $this->transaction = $transaction;
138
-        return $response;
139
-    }
140
-
141
-
142
-    /**
143
-     * @param string $txn_status
144
-     * @param array $response
145
-     * @param array $data
146
-     * @return array
147
-     * @throws EE_Error
148
-     */
149
-    private function getTransactionDetails($txn_status, $response, $data)
150
-    {
151
-        // has the TXN status changed since we last checked (or empty because this is the first time running through this code)?
152
-        if ($txn_status !== $this->transaction->status_ID()) {
153
-            // switch between two possible basic outcomes
154
-            switch ($this->transaction->status_ID()) {
155
-                // TXN has been updated in some way
156
-                case EEM_Transaction::overpaid_status_code:
157
-                case EEM_Transaction::complete_status_code:
158
-                case EEM_Transaction::incomplete_status_code:
159
-                    // send updated TXN results back to client,
160
-                    $response['espresso_thank_you_page'] = array(
161
-                        'transaction_details' => $this->thank_you_page->get_transaction_details(),
162
-                        'txn_status'          => $this->transaction->status_ID(),
163
-                    );
164
-                    return $response;
165
-                // or we have a bad TXN, or really slow IPN, so calculate the wait time and send that back...
166
-                case EEM_Transaction::failed_status_code:
167
-                default:
168
-                    // keep on waiting...
169
-                    return $this->updateServerWaitTime($data['espresso_thank_you_page']);
170
-            }
171
-            // or is the TXN still failed (never been updated) ???
172
-        } elseif ($this->transaction->failed()) {
173
-            // keep on waiting...
174
-            return $this->updateServerWaitTime($data['espresso_thank_you_page']);
175
-        }
176
-    }
177
-
178
-
179
-    /**
180
-     * @param int $since
181
-     * @return array
182
-     * @throws EE_Error
183
-     */
184
-    private function paymentDetails($since)
185
-    {
186
-        // then check for payments
187
-        $payments = $this->thank_you_page->get_txn_payments($since);
188
-        // has a payment been processed ?
189
-        if (! empty($payments) || $this->thank_you_page->isOfflinePaymentMethod()) {
190
-            if ($since) {
191
-                $response['espresso_thank_you_page'] = array(
192
-                    'new_payments'        => $this->thank_you_page->get_new_payments($payments),
193
-                    'transaction_details' => $this->thank_you_page->get_transaction_details(),
194
-                    'txn_status'          => $this->transaction->status_ID(),
195
-                );
196
-            } else {
197
-                $response['espresso_thank_you_page']['payment_details'] = $this->thank_you_page->get_payment_details(
198
-                    $payments
199
-                );
200
-            }
201
-            // reset time to check for payments
202
-            $response['espresso_thank_you_page']['get_payments_since'] = time();
203
-        } else {
204
-            $response['espresso_thank_you_page']['get_payments_since'] = $since;
205
-        }
206
-        return $response;
207
-    }
208
-
209
-
210
-    /**
211
-     * @param array $thank_you_page_data    thank you page portion of the incoming JSON array
212
-     *                                      from the WP heartbeat data
213
-     * @return array
214
-     * @throws EE_Error
215
-     */
216
-    private function updateServerWaitTime($thank_you_page_data)
217
-    {
218
-        $response['espresso_thank_you_page'] = array(
219
-            'still_waiting' => isset($thank_you_page_data['initial_access'])
220
-                ? time() - $thank_you_page_data['initial_access']
221
-                : 0,
222
-            'txn_status'    => $this->transaction->status_ID(),
223
-        );
224
-        return $response;
225
-    }
24
+	/**
25
+	 * @var EED_Thank_You_Page $thank_you_page
26
+	 */
27
+	private $thank_you_page;
28
+
29
+	/**
30
+	 * @var EE_Transaction $transaction
31
+	 */
32
+	private $transaction;
33
+
34
+	/**
35
+	 * EventEditorHeartbeat constructor.
36
+	 *
37
+	 */
38
+	public function __construct()
39
+	{
40
+		add_filter('heartbeat_received', array($this, 'heartbeatResponse'), 10, 3);
41
+		add_filter('heartbeat_nopriv_received', array($this, 'heartbeatResponse'), 10, 3);
42
+	}
43
+
44
+
45
+	/**
46
+	 * thank_you_page_IPN_monitor
47
+	 * this basically just pulls the TXN based on the reg_url_link sent from the server,
48
+	 * then checks that the TXN status is not failed, and that no other errors have been generated.
49
+	 * it also calculates the IPN wait time since the Thank You page was first loaded
50
+	 *
51
+	 * @param array $response
52
+	 * @param array $data
53
+	 * @return array
54
+	 * @throws EE_Error
55
+	 * @throws InvalidDataTypeException
56
+	 * @throws InvalidInterfaceException
57
+	 * @throws InvalidArgumentException
58
+	 */
59
+	public function heartbeatResponse($response = array(), $data = array())
60
+	{
61
+		// does this heartbeat contain our data ?
62
+		if (! isset($data['espresso_thank_you_page'])) {
63
+			return $response;
64
+		}
65
+		// check for reg_url_link in the incoming heartbeat data
66
+		if (! isset($data['espresso_thank_you_page']['e_reg_url_link'])) {
67
+			$response['espresso_thank_you_page'] = array(
68
+				'errors' => ! empty($notices['errors'])
69
+					? $notices['errors']
70
+					: __(
71
+						'No transaction information could be retrieved because the registration URL link is missing or invalid.',
72
+						'event_espresso'
73
+					),
74
+			);
75
+			return $response;
76
+		}
77
+		// kk heartbeat has our data
78
+		$response = $this->initializeThankYouPageAndTransaction($response, $data);
79
+		// if something went wrong...
80
+		if (isset($response['espresso_thank_you_page']['errors'])) {
81
+			return $response;
82
+		}
83
+		// grab transient of Transaction's status
84
+		$txn_status = isset($data['espresso_thank_you_page']['txn_status'])
85
+			? $data['espresso_thank_you_page']['txn_status']
86
+			: null;
87
+		$response = $this->getTransactionDetails($txn_status, $response, $data);
88
+		// no payment data yet?
89
+		if(isset($response['espresso_thank_you_page']['still_waiting'])) {
90
+			return $response;
91
+		}
92
+		// TXN is happening so let's get the payments now
93
+		// if we've already gotten payments then the heartbeat data will contain the timestamp of the last time we checked
94
+		$since = isset($data['espresso_thank_you_page']['get_payments_since'])
95
+			? $data['espresso_thank_you_page']['get_payments_since']
96
+			: 0;
97
+		return $this->paymentDetails($since);
98
+	}
99
+
100
+
101
+	/**
102
+	 * @param array  $response
103
+	 * @param array  $data
104
+	 * @return array
105
+	 * @throws EE_Error
106
+	 * @throws InvalidArgumentException
107
+	 * @throws InvalidDataTypeException
108
+	 * @throws InvalidInterfaceException
109
+	 */
110
+	private function initializeThankYouPageAndTransaction($response, $data)
111
+	{
112
+		require_once EE_MODULES . 'thank_you_page/EED_Thank_You_Page.module.php';
113
+		// set_definitions, instantiate the thank you page class, and get the ball rolling
114
+		EED_Thank_You_Page::set_definitions();
115
+		$this->thank_you_page = EED_Thank_You_Page::instance();
116
+		$this->thank_you_page->set_reg_url_link($data['espresso_thank_you_page']['e_reg_url_link']);
117
+		$this->thank_you_page->init();
118
+		$response['espresso_thank_you_page'] = array();
119
+		// get TXN
120
+		$transaction = $this->thank_you_page->get_txn();
121
+		// no TXN? then get out
122
+		if (! $transaction instanceof EE_Transaction) {
123
+			$notices = EE_Error::get_notices();
124
+			$response['espresso_thank_you_page'] = array(
125
+				'errors' => ! empty($notices['errors'])
126
+					? $notices['errors']
127
+					: sprintf(
128
+						__(
129
+							'The information for your transaction could not be retrieved from the server or the transaction data received was invalid because of a technical reason. (%s)',
130
+							'event_espresso'
131
+						),
132
+						__LINE__
133
+					),
134
+			);
135
+			return $response;
136
+		}
137
+		$this->transaction = $transaction;
138
+		return $response;
139
+	}
140
+
141
+
142
+	/**
143
+	 * @param string $txn_status
144
+	 * @param array $response
145
+	 * @param array $data
146
+	 * @return array
147
+	 * @throws EE_Error
148
+	 */
149
+	private function getTransactionDetails($txn_status, $response, $data)
150
+	{
151
+		// has the TXN status changed since we last checked (or empty because this is the first time running through this code)?
152
+		if ($txn_status !== $this->transaction->status_ID()) {
153
+			// switch between two possible basic outcomes
154
+			switch ($this->transaction->status_ID()) {
155
+				// TXN has been updated in some way
156
+				case EEM_Transaction::overpaid_status_code:
157
+				case EEM_Transaction::complete_status_code:
158
+				case EEM_Transaction::incomplete_status_code:
159
+					// send updated TXN results back to client,
160
+					$response['espresso_thank_you_page'] = array(
161
+						'transaction_details' => $this->thank_you_page->get_transaction_details(),
162
+						'txn_status'          => $this->transaction->status_ID(),
163
+					);
164
+					return $response;
165
+				// or we have a bad TXN, or really slow IPN, so calculate the wait time and send that back...
166
+				case EEM_Transaction::failed_status_code:
167
+				default:
168
+					// keep on waiting...
169
+					return $this->updateServerWaitTime($data['espresso_thank_you_page']);
170
+			}
171
+			// or is the TXN still failed (never been updated) ???
172
+		} elseif ($this->transaction->failed()) {
173
+			// keep on waiting...
174
+			return $this->updateServerWaitTime($data['espresso_thank_you_page']);
175
+		}
176
+	}
177
+
178
+
179
+	/**
180
+	 * @param int $since
181
+	 * @return array
182
+	 * @throws EE_Error
183
+	 */
184
+	private function paymentDetails($since)
185
+	{
186
+		// then check for payments
187
+		$payments = $this->thank_you_page->get_txn_payments($since);
188
+		// has a payment been processed ?
189
+		if (! empty($payments) || $this->thank_you_page->isOfflinePaymentMethod()) {
190
+			if ($since) {
191
+				$response['espresso_thank_you_page'] = array(
192
+					'new_payments'        => $this->thank_you_page->get_new_payments($payments),
193
+					'transaction_details' => $this->thank_you_page->get_transaction_details(),
194
+					'txn_status'          => $this->transaction->status_ID(),
195
+				);
196
+			} else {
197
+				$response['espresso_thank_you_page']['payment_details'] = $this->thank_you_page->get_payment_details(
198
+					$payments
199
+				);
200
+			}
201
+			// reset time to check for payments
202
+			$response['espresso_thank_you_page']['get_payments_since'] = time();
203
+		} else {
204
+			$response['espresso_thank_you_page']['get_payments_since'] = $since;
205
+		}
206
+		return $response;
207
+	}
208
+
209
+
210
+	/**
211
+	 * @param array $thank_you_page_data    thank you page portion of the incoming JSON array
212
+	 *                                      from the WP heartbeat data
213
+	 * @return array
214
+	 * @throws EE_Error
215
+	 */
216
+	private function updateServerWaitTime($thank_you_page_data)
217
+	{
218
+		$response['espresso_thank_you_page'] = array(
219
+			'still_waiting' => isset($thank_you_page_data['initial_access'])
220
+				? time() - $thank_you_page_data['initial_access']
221
+				: 0,
222
+			'txn_status'    => $this->transaction->status_ID(),
223
+		);
224
+		return $response;
225
+	}
226 226
 }
227 227
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -59,11 +59,11 @@  discard block
 block discarded – undo
59 59
     public function heartbeatResponse($response = array(), $data = array())
60 60
     {
61 61
         // does this heartbeat contain our data ?
62
-        if (! isset($data['espresso_thank_you_page'])) {
62
+        if ( ! isset($data['espresso_thank_you_page'])) {
63 63
             return $response;
64 64
         }
65 65
         // check for reg_url_link in the incoming heartbeat data
66
-        if (! isset($data['espresso_thank_you_page']['e_reg_url_link'])) {
66
+        if ( ! isset($data['espresso_thank_you_page']['e_reg_url_link'])) {
67 67
             $response['espresso_thank_you_page'] = array(
68 68
                 'errors' => ! empty($notices['errors'])
69 69
                     ? $notices['errors']
@@ -86,7 +86,7 @@  discard block
 block discarded – undo
86 86
             : null;
87 87
         $response = $this->getTransactionDetails($txn_status, $response, $data);
88 88
         // no payment data yet?
89
-        if(isset($response['espresso_thank_you_page']['still_waiting'])) {
89
+        if (isset($response['espresso_thank_you_page']['still_waiting'])) {
90 90
             return $response;
91 91
         }
92 92
         // TXN is happening so let's get the payments now
@@ -109,7 +109,7 @@  discard block
 block discarded – undo
109 109
      */
110 110
     private function initializeThankYouPageAndTransaction($response, $data)
111 111
     {
112
-        require_once EE_MODULES . 'thank_you_page/EED_Thank_You_Page.module.php';
112
+        require_once EE_MODULES.'thank_you_page/EED_Thank_You_Page.module.php';
113 113
         // set_definitions, instantiate the thank you page class, and get the ball rolling
114 114
         EED_Thank_You_Page::set_definitions();
115 115
         $this->thank_you_page = EED_Thank_You_Page::instance();
@@ -119,7 +119,7 @@  discard block
 block discarded – undo
119 119
         // get TXN
120 120
         $transaction = $this->thank_you_page->get_txn();
121 121
         // no TXN? then get out
122
-        if (! $transaction instanceof EE_Transaction) {
122
+        if ( ! $transaction instanceof EE_Transaction) {
123 123
             $notices = EE_Error::get_notices();
124 124
             $response['espresso_thank_you_page'] = array(
125 125
                 'errors' => ! empty($notices['errors'])
@@ -186,7 +186,7 @@  discard block
 block discarded – undo
186 186
         // then check for payments
187 187
         $payments = $this->thank_you_page->get_txn_payments($since);
188 188
         // has a payment been processed ?
189
-        if (! empty($payments) || $this->thank_you_page->isOfflinePaymentMethod()) {
189
+        if ( ! empty($payments) || $this->thank_you_page->isOfflinePaymentMethod()) {
190 190
             if ($since) {
191 191
                 $response['espresso_thank_you_page'] = array(
192 192
                     'new_payments'        => $this->thank_you_page->get_new_payments($payments),
Please login to merge, or discard this patch.
core/domain/services/contexts/RequestTypeContextChecker.php 1 patch
Indentation   +213 added lines, -213 removed lines patch added patch discarded remove patch
@@ -16,217 +16,217 @@
 block discarded – undo
16 16
 class RequestTypeContextChecker extends ContextChecker implements RequestTypeContextCheckerInterface
17 17
 {
18 18
 
19
-    /**
20
-     * @var RequestTypeContext $request_type
21
-     */
22
-    private $request_type;
23
-
24
-
25
-    /**
26
-     * RequestTypeContextChecker constructor.
27
-     *
28
-     * @param RequestTypeContext $request_type
29
-     */
30
-    public function __construct(RequestTypeContext $request_type)
31
-    {
32
-        $this->request_type = $request_type;
33
-        parent::__construct(
34
-            'RequestTypeContextChecker',
35
-            $this->request_type->validRequestTypes()
36
-        );
37
-    }
38
-
39
-
40
-    /**
41
-     * true if the current request involves some form of activation
42
-     *
43
-     * @return bool
44
-     */
45
-    public function isActivation()
46
-    {
47
-        return $this->request_type->isActivation();
48
-    }
49
-
50
-
51
-    /**
52
-     * @param $is_activation
53
-     * @return bool
54
-     */
55
-    public function setIsActivation($is_activation)
56
-    {
57
-        return $this->request_type->setIsActivation($is_activation);
58
-    }
59
-
60
-
61
-    /**
62
-     * true if the current request is for the admin and is not being made via AJAX
63
-     *
64
-     * @return bool
65
-     */
66
-    public function isAdmin()
67
-    {
68
-        return $this->request_type->slug() === RequestTypeContext::ADMIN;
69
-    }
70
-
71
-
72
-    /**
73
-     * true if the current request is for the admin AND is being made via AJAX
74
-     *
75
-     * @return bool
76
-     */
77
-    public function isAdminAjax()
78
-    {
79
-        return $this->request_type->slug() === RequestTypeContext::AJAX_ADMIN;
80
-    }
81
-
82
-
83
-    /**
84
-     * true if the current request is being made via AJAX... any AJAX
85
-     *
86
-     * @return bool
87
-     */
88
-    public function isAjax()
89
-    {
90
-        return $this->isEeAjax() || $this->isOtherAjax();
91
-    }
92
-
93
-
94
-    /**
95
-     * true if the current request is for either the EE admin or EE frontend AND is being made via AJAX
96
-     *
97
-     * @return bool
98
-     */
99
-    public function isEeAjax()
100
-    {
101
-        return $this->isAdminAjax() || $this->isFrontAjax();
102
-    }
103
-
104
-
105
-    /**
106
-     * true if the current request is being made via AJAX but is NOT for EE related logic
107
-     *
108
-     * @return bool
109
-     */
110
-    public function isOtherAjax()
111
-    {
112
-        return $this->request_type->slug() === RequestTypeContext::AJAX_OTHER;
113
-    }
114
-
115
-    /**
116
-     * true if the current request is for the EE REST API
117
-     *
118
-     * @return bool
119
-     */
120
-    public function isApi()
121
-    {
122
-        return $this->request_type->slug() === RequestTypeContext::API;
123
-    }
124
-
125
-
126
-    /**
127
-     * true if the current request is from the command line
128
-     *
129
-     * @return bool
130
-     */
131
-    public function isCli()
132
-    {
133
-        return $this->request_type->slug() === RequestTypeContext::CLI;
134
-    }
135
-
136
-
137
-    /**
138
-     * true if the current request is for a WP_Cron
139
-     *
140
-     * @return bool
141
-     */
142
-    public function isCron()
143
-    {
144
-        return $this->request_type->slug() === RequestTypeContext::CRON;
145
-    }
146
-
147
-
148
-    /**
149
-     * true if the current request is for a feed (ie: RSS)
150
-     *
151
-     * @return bool
152
-     */
153
-    public function isFeed()
154
-    {
155
-        return $this->request_type->slug() === RequestTypeContext::FEED;
156
-    }
157
-
158
-
159
-    /**
160
-     * true if the current request is for the frontend and is not being made via AJAX
161
-     *
162
-     * @return bool
163
-     */
164
-    public function isFrontend()
165
-    {
166
-        return $this->request_type->slug() === RequestTypeContext::FRONTEND;
167
-    }
168
-
169
-
170
-    /**
171
-     * true if the current request is for the frontend AND is being made via AJAX
172
-     *
173
-     * @return bool
174
-     */
175
-    public function isFrontAjax()
176
-    {
177
-        return $this->request_type->slug() === RequestTypeContext::AJAX_FRONT;
178
-    }
179
-
180
-
181
-    /**
182
-     * true if the current request is for content that is to be displayed within an iframe
183
-     *
184
-     * @return bool
185
-     */
186
-    public function isIframe()
187
-    {
188
-        return $this->request_type->slug() === RequestTypeContext::IFRAME;
189
-    }
190
-
191
-
192
-    /**
193
-     * true if the current request is for the WP REST API
194
-     *
195
-     * @return bool
196
-     */
197
-    public function isWordPressApi()
198
-    {
199
-        return $this->request_type->slug() === RequestTypeContext::WP_API;
200
-    }
201
-
202
-
203
-    /**
204
-     * true if the current request is being made via AJAX for the WP Heartbeat
205
-     *
206
-     * @return bool
207
-     */
208
-    public function isWordPressHeartbeat()
209
-    {
210
-        return $this->request_type->slug() === RequestTypeContext::AJAX_HEARTBEAT;
211
-    }
212
-
213
-
214
-    /**
215
-     * true if the current request is a loopback sent from WP core to test for errors
216
-     *
217
-     * @return bool
218
-     */
219
-    public function isWordPressScrape()
220
-    {
221
-        return $this->request_type->slug() === RequestTypeContext::WP_SCRAPE;
222
-    }
223
-
224
-
225
-    /**
226
-     * @return string
227
-     */
228
-    public function slug()
229
-    {
230
-        return $this->request_type->slug();
231
-    }
19
+	/**
20
+	 * @var RequestTypeContext $request_type
21
+	 */
22
+	private $request_type;
23
+
24
+
25
+	/**
26
+	 * RequestTypeContextChecker constructor.
27
+	 *
28
+	 * @param RequestTypeContext $request_type
29
+	 */
30
+	public function __construct(RequestTypeContext $request_type)
31
+	{
32
+		$this->request_type = $request_type;
33
+		parent::__construct(
34
+			'RequestTypeContextChecker',
35
+			$this->request_type->validRequestTypes()
36
+		);
37
+	}
38
+
39
+
40
+	/**
41
+	 * true if the current request involves some form of activation
42
+	 *
43
+	 * @return bool
44
+	 */
45
+	public function isActivation()
46
+	{
47
+		return $this->request_type->isActivation();
48
+	}
49
+
50
+
51
+	/**
52
+	 * @param $is_activation
53
+	 * @return bool
54
+	 */
55
+	public function setIsActivation($is_activation)
56
+	{
57
+		return $this->request_type->setIsActivation($is_activation);
58
+	}
59
+
60
+
61
+	/**
62
+	 * true if the current request is for the admin and is not being made via AJAX
63
+	 *
64
+	 * @return bool
65
+	 */
66
+	public function isAdmin()
67
+	{
68
+		return $this->request_type->slug() === RequestTypeContext::ADMIN;
69
+	}
70
+
71
+
72
+	/**
73
+	 * true if the current request is for the admin AND is being made via AJAX
74
+	 *
75
+	 * @return bool
76
+	 */
77
+	public function isAdminAjax()
78
+	{
79
+		return $this->request_type->slug() === RequestTypeContext::AJAX_ADMIN;
80
+	}
81
+
82
+
83
+	/**
84
+	 * true if the current request is being made via AJAX... any AJAX
85
+	 *
86
+	 * @return bool
87
+	 */
88
+	public function isAjax()
89
+	{
90
+		return $this->isEeAjax() || $this->isOtherAjax();
91
+	}
92
+
93
+
94
+	/**
95
+	 * true if the current request is for either the EE admin or EE frontend AND is being made via AJAX
96
+	 *
97
+	 * @return bool
98
+	 */
99
+	public function isEeAjax()
100
+	{
101
+		return $this->isAdminAjax() || $this->isFrontAjax();
102
+	}
103
+
104
+
105
+	/**
106
+	 * true if the current request is being made via AJAX but is NOT for EE related logic
107
+	 *
108
+	 * @return bool
109
+	 */
110
+	public function isOtherAjax()
111
+	{
112
+		return $this->request_type->slug() === RequestTypeContext::AJAX_OTHER;
113
+	}
114
+
115
+	/**
116
+	 * true if the current request is for the EE REST API
117
+	 *
118
+	 * @return bool
119
+	 */
120
+	public function isApi()
121
+	{
122
+		return $this->request_type->slug() === RequestTypeContext::API;
123
+	}
124
+
125
+
126
+	/**
127
+	 * true if the current request is from the command line
128
+	 *
129
+	 * @return bool
130
+	 */
131
+	public function isCli()
132
+	{
133
+		return $this->request_type->slug() === RequestTypeContext::CLI;
134
+	}
135
+
136
+
137
+	/**
138
+	 * true if the current request is for a WP_Cron
139
+	 *
140
+	 * @return bool
141
+	 */
142
+	public function isCron()
143
+	{
144
+		return $this->request_type->slug() === RequestTypeContext::CRON;
145
+	}
146
+
147
+
148
+	/**
149
+	 * true if the current request is for a feed (ie: RSS)
150
+	 *
151
+	 * @return bool
152
+	 */
153
+	public function isFeed()
154
+	{
155
+		return $this->request_type->slug() === RequestTypeContext::FEED;
156
+	}
157
+
158
+
159
+	/**
160
+	 * true if the current request is for the frontend and is not being made via AJAX
161
+	 *
162
+	 * @return bool
163
+	 */
164
+	public function isFrontend()
165
+	{
166
+		return $this->request_type->slug() === RequestTypeContext::FRONTEND;
167
+	}
168
+
169
+
170
+	/**
171
+	 * true if the current request is for the frontend AND is being made via AJAX
172
+	 *
173
+	 * @return bool
174
+	 */
175
+	public function isFrontAjax()
176
+	{
177
+		return $this->request_type->slug() === RequestTypeContext::AJAX_FRONT;
178
+	}
179
+
180
+
181
+	/**
182
+	 * true if the current request is for content that is to be displayed within an iframe
183
+	 *
184
+	 * @return bool
185
+	 */
186
+	public function isIframe()
187
+	{
188
+		return $this->request_type->slug() === RequestTypeContext::IFRAME;
189
+	}
190
+
191
+
192
+	/**
193
+	 * true if the current request is for the WP REST API
194
+	 *
195
+	 * @return bool
196
+	 */
197
+	public function isWordPressApi()
198
+	{
199
+		return $this->request_type->slug() === RequestTypeContext::WP_API;
200
+	}
201
+
202
+
203
+	/**
204
+	 * true if the current request is being made via AJAX for the WP Heartbeat
205
+	 *
206
+	 * @return bool
207
+	 */
208
+	public function isWordPressHeartbeat()
209
+	{
210
+		return $this->request_type->slug() === RequestTypeContext::AJAX_HEARTBEAT;
211
+	}
212
+
213
+
214
+	/**
215
+	 * true if the current request is a loopback sent from WP core to test for errors
216
+	 *
217
+	 * @return bool
218
+	 */
219
+	public function isWordPressScrape()
220
+	{
221
+		return $this->request_type->slug() === RequestTypeContext::WP_SCRAPE;
222
+	}
223
+
224
+
225
+	/**
226
+	 * @return string
227
+	 */
228
+	public function slug()
229
+	{
230
+		return $this->request_type->slug();
231
+	}
232 232
 }
Please login to merge, or discard this patch.
core/domain/services/contexts/RequestTypeContextDetector.php 1 patch
Indentation   +170 added lines, -170 removed lines patch added patch discarded remove patch
@@ -18,174 +18,174 @@
 block discarded – undo
18 18
 class RequestTypeContextDetector
19 19
 {
20 20
 
21
-    /**
22
-     * @var RequestTypeContextFactoryInterface $factory
23
-     */
24
-    private $factory;
25
-
26
-    /**
27
-     * @var RequestInterface $request
28
-     */
29
-    private $request;
30
-
31
-    /**
32
-     * @var array $globalRouteConditions
33
-     */
34
-    private $globalRouteConditions;
35
-
36
-
37
-    /**
38
-     * RequestTypeContextDetector constructor.
39
-     *
40
-     * @param RequestInterface                   $request
41
-     * @param RequestTypeContextFactoryInterface $factory
42
-     * @param array                              $globalRouteConditions an array for injecting values that would
43
-     *                                                                  otherwise be defined as global constants
44
-     *                                                                  or other global variables for the current
45
-     *                                                                  request route such as DOING_AJAX
46
-     */
47
-    public function __construct(
48
-        RequestInterface $request,
49
-        RequestTypeContextFactoryInterface $factory,
50
-        array $globalRouteConditions = array()
51
-    ) {
52
-        $this->request = $request;
53
-        $this->factory = $factory;
54
-        $this->globalRouteConditions = $globalRouteConditions;
55
-    }
56
-
57
-
58
-    /**
59
-     * @return mixed
60
-     */
61
-    private function getGlobalRouteCondition($globalRouteCondition, $default)
62
-    {
63
-        return isset($this->globalRouteConditions[ $globalRouteCondition ])
64
-            ? $this->globalRouteConditions[ $globalRouteCondition ]
65
-            : $default;
66
-    }
67
-
68
-
69
-    /**
70
-     * @return RequestTypeContext
71
-     * @throws InvalidArgumentException
72
-     */
73
-    public function detectRequestTypeContext()
74
-    {
75
-        // Detect error scrapes
76
-        if ($this->request->getRequestParam('wp_scrape_key') !== null
77
-            && $this->request->getRequestParam('wp_scrape_nonce') !== null
78
-        ) {
79
-            return $this->factory->create(RequestTypeContext::WP_SCRAPE);
80
-        }
81
-        // Detect EE REST API
82
-        if ($this->isEspressoRestApiRequest()) {
83
-            return $this->factory->create(RequestTypeContext::API);
84
-        }
85
-        // Detect WP REST API
86
-        if ($this->isWordPressRestApiRequest()) {
87
-            return $this->factory->create(RequestTypeContext::WP_API);
88
-        }
89
-        // Detect AJAX
90
-        if ($this->getGlobalRouteCondition('DOING_AJAX', false)) {
91
-            if (filter_var($this->request->getRequestParam('ee_front_ajax'), FILTER_VALIDATE_BOOLEAN)) {
92
-                return $this->factory->create(RequestTypeContext::AJAX_FRONT);
93
-            }
94
-            if (filter_var($this->request->getRequestParam('ee_admin_ajax'), FILTER_VALIDATE_BOOLEAN)) {
95
-                return $this->factory->create(RequestTypeContext::AJAX_ADMIN);
96
-            }
97
-            if ($this->request->getRequestParam('action') === 'heartbeat') {
98
-                return $this->factory->create(RequestTypeContext::AJAX_HEARTBEAT);
99
-            }
100
-            return $this->factory->create(RequestTypeContext::AJAX_OTHER);
101
-        }
102
-        // Detect WP_Cron
103
-        if ($this->isCronRequest()) {
104
-            return $this->factory->create(RequestTypeContext::CRON);
105
-        }
106
-        // Detect command line requests
107
-        if ($this->getGlobalRouteCondition('WP_CLI', false)) {
108
-            return $this->factory->create(RequestTypeContext::CLI);
109
-        }
110
-        // detect WordPress admin (ie: "Dashboard")
111
-        if ($this->getGlobalRouteCondition('is_admin', false)) {
112
-            return $this->factory->create(RequestTypeContext::ADMIN);
113
-        }
114
-        // Detect iFrames
115
-        if ($this->isIframeRoute()) {
116
-            return $this->factory->create(RequestTypeContext::IFRAME);
117
-        }
118
-        // Detect Feeds
119
-        if ($this->isFeedRequest()) {
120
-            return $this->factory->create(RequestTypeContext::FEED);
121
-        }
122
-        // and by process of elimination...
123
-        return $this->factory->create(RequestTypeContext::FRONTEND);
124
-    }
125
-
126
-
127
-    /**
128
-     * @return bool
129
-     */
130
-    private function isEspressoRestApiRequest()
131
-    {
132
-        return $this->uriPathMatches(trim(rest_get_url_prefix(), '/') . '/' . Domain::API_NAMESPACE);
133
-    }
134
-
135
-
136
-
137
-    /**
138
-     * @return bool
139
-     */
140
-    private function isWordPressRestApiRequest()
141
-    {
142
-        return $this->uriPathMatches(trim(rest_get_url_prefix(), '/'));
143
-    }
144
-
145
-
146
-    /**
147
-     * @return bool
148
-     */
149
-    private function isCronRequest()
150
-    {
151
-        return $this->uriPathMatches('wp-cron.php');
152
-    }
153
-
154
-
155
-    /**
156
-     * @return bool
157
-     */
158
-    private function isFeedRequest()
159
-    {
160
-        return $this->uriPathMatches('feed');
161
-    }
162
-
163
-
164
-    /**
165
-     * @param string $component
166
-     * @return bool
167
-     */
168
-    private function uriPathMatches($component)
169
-    {
170
-        $request_uri = $this->request->requestUri();
171
-        $parts = explode('?', $request_uri);
172
-        $path = trim(reset($parts), '/');
173
-        return strpos($path, $component) === 0;
174
-    }
175
-
176
-
177
-    /**
178
-     * @return bool
179
-     */
180
-    private function isIframeRoute()
181
-    {
182
-        $is_iframe_route = apply_filters(
183
-            'FHEE__EventEspresso_core_domain_services_contexts_RequestTypeContextDetector__isIframeRoute',
184
-            $this->request->getRequestParam('event_list', '') === 'iframe'
185
-            || $this->request->getRequestParam('ticket_selector', '') === 'iframe'
186
-            || $this->request->getRequestParam('calendar', '') === 'iframe',
187
-            $this
188
-        );
189
-        return filter_var($is_iframe_route, FILTER_VALIDATE_BOOLEAN);
190
-    }
21
+	/**
22
+	 * @var RequestTypeContextFactoryInterface $factory
23
+	 */
24
+	private $factory;
25
+
26
+	/**
27
+	 * @var RequestInterface $request
28
+	 */
29
+	private $request;
30
+
31
+	/**
32
+	 * @var array $globalRouteConditions
33
+	 */
34
+	private $globalRouteConditions;
35
+
36
+
37
+	/**
38
+	 * RequestTypeContextDetector constructor.
39
+	 *
40
+	 * @param RequestInterface                   $request
41
+	 * @param RequestTypeContextFactoryInterface $factory
42
+	 * @param array                              $globalRouteConditions an array for injecting values that would
43
+	 *                                                                  otherwise be defined as global constants
44
+	 *                                                                  or other global variables for the current
45
+	 *                                                                  request route such as DOING_AJAX
46
+	 */
47
+	public function __construct(
48
+		RequestInterface $request,
49
+		RequestTypeContextFactoryInterface $factory,
50
+		array $globalRouteConditions = array()
51
+	) {
52
+		$this->request = $request;
53
+		$this->factory = $factory;
54
+		$this->globalRouteConditions = $globalRouteConditions;
55
+	}
56
+
57
+
58
+	/**
59
+	 * @return mixed
60
+	 */
61
+	private function getGlobalRouteCondition($globalRouteCondition, $default)
62
+	{
63
+		return isset($this->globalRouteConditions[ $globalRouteCondition ])
64
+			? $this->globalRouteConditions[ $globalRouteCondition ]
65
+			: $default;
66
+	}
67
+
68
+
69
+	/**
70
+	 * @return RequestTypeContext
71
+	 * @throws InvalidArgumentException
72
+	 */
73
+	public function detectRequestTypeContext()
74
+	{
75
+		// Detect error scrapes
76
+		if ($this->request->getRequestParam('wp_scrape_key') !== null
77
+			&& $this->request->getRequestParam('wp_scrape_nonce') !== null
78
+		) {
79
+			return $this->factory->create(RequestTypeContext::WP_SCRAPE);
80
+		}
81
+		// Detect EE REST API
82
+		if ($this->isEspressoRestApiRequest()) {
83
+			return $this->factory->create(RequestTypeContext::API);
84
+		}
85
+		// Detect WP REST API
86
+		if ($this->isWordPressRestApiRequest()) {
87
+			return $this->factory->create(RequestTypeContext::WP_API);
88
+		}
89
+		// Detect AJAX
90
+		if ($this->getGlobalRouteCondition('DOING_AJAX', false)) {
91
+			if (filter_var($this->request->getRequestParam('ee_front_ajax'), FILTER_VALIDATE_BOOLEAN)) {
92
+				return $this->factory->create(RequestTypeContext::AJAX_FRONT);
93
+			}
94
+			if (filter_var($this->request->getRequestParam('ee_admin_ajax'), FILTER_VALIDATE_BOOLEAN)) {
95
+				return $this->factory->create(RequestTypeContext::AJAX_ADMIN);
96
+			}
97
+			if ($this->request->getRequestParam('action') === 'heartbeat') {
98
+				return $this->factory->create(RequestTypeContext::AJAX_HEARTBEAT);
99
+			}
100
+			return $this->factory->create(RequestTypeContext::AJAX_OTHER);
101
+		}
102
+		// Detect WP_Cron
103
+		if ($this->isCronRequest()) {
104
+			return $this->factory->create(RequestTypeContext::CRON);
105
+		}
106
+		// Detect command line requests
107
+		if ($this->getGlobalRouteCondition('WP_CLI', false)) {
108
+			return $this->factory->create(RequestTypeContext::CLI);
109
+		}
110
+		// detect WordPress admin (ie: "Dashboard")
111
+		if ($this->getGlobalRouteCondition('is_admin', false)) {
112
+			return $this->factory->create(RequestTypeContext::ADMIN);
113
+		}
114
+		// Detect iFrames
115
+		if ($this->isIframeRoute()) {
116
+			return $this->factory->create(RequestTypeContext::IFRAME);
117
+		}
118
+		// Detect Feeds
119
+		if ($this->isFeedRequest()) {
120
+			return $this->factory->create(RequestTypeContext::FEED);
121
+		}
122
+		// and by process of elimination...
123
+		return $this->factory->create(RequestTypeContext::FRONTEND);
124
+	}
125
+
126
+
127
+	/**
128
+	 * @return bool
129
+	 */
130
+	private function isEspressoRestApiRequest()
131
+	{
132
+		return $this->uriPathMatches(trim(rest_get_url_prefix(), '/') . '/' . Domain::API_NAMESPACE);
133
+	}
134
+
135
+
136
+
137
+	/**
138
+	 * @return bool
139
+	 */
140
+	private function isWordPressRestApiRequest()
141
+	{
142
+		return $this->uriPathMatches(trim(rest_get_url_prefix(), '/'));
143
+	}
144
+
145
+
146
+	/**
147
+	 * @return bool
148
+	 */
149
+	private function isCronRequest()
150
+	{
151
+		return $this->uriPathMatches('wp-cron.php');
152
+	}
153
+
154
+
155
+	/**
156
+	 * @return bool
157
+	 */
158
+	private function isFeedRequest()
159
+	{
160
+		return $this->uriPathMatches('feed');
161
+	}
162
+
163
+
164
+	/**
165
+	 * @param string $component
166
+	 * @return bool
167
+	 */
168
+	private function uriPathMatches($component)
169
+	{
170
+		$request_uri = $this->request->requestUri();
171
+		$parts = explode('?', $request_uri);
172
+		$path = trim(reset($parts), '/');
173
+		return strpos($path, $component) === 0;
174
+	}
175
+
176
+
177
+	/**
178
+	 * @return bool
179
+	 */
180
+	private function isIframeRoute()
181
+	{
182
+		$is_iframe_route = apply_filters(
183
+			'FHEE__EventEspresso_core_domain_services_contexts_RequestTypeContextDetector__isIframeRoute',
184
+			$this->request->getRequestParam('event_list', '') === 'iframe'
185
+			|| $this->request->getRequestParam('ticket_selector', '') === 'iframe'
186
+			|| $this->request->getRequestParam('calendar', '') === 'iframe',
187
+			$this
188
+		);
189
+		return filter_var($is_iframe_route, FILTER_VALIDATE_BOOLEAN);
190
+	}
191 191
 }
Please login to merge, or discard this patch.