Completed
Branch master (053ec2)
by
unknown
14:08 queued 11:56
created
modules/events_archive/EED_Events_Archive.module.php 1 patch
Indentation   +1102 added lines, -1102 removed lines patch added patch discarded remove patch
@@ -16,1097 +16,1097 @@  discard block
 block discarded – undo
16 16
 class EED_Events_Archive extends EED_Module
17 17
 {
18 18
 
19
-    const EVENT_DETAILS_PRIORITY = 100;
20
-
21
-    const EVENT_DATETIMES_PRIORITY = 110;
22
-
23
-    const EVENT_TICKETS_PRIORITY = 120;
24
-
25
-    const EVENT_VENUES_PRIORITY = 130;
26
-
27
-
28
-    public static $espresso_event_list_ID = 0;
29
-
30
-    public static $espresso_grid_event_lists = array();
31
-
32
-    /**
33
-     * @type bool $using_get_the_excerpt
34
-     */
35
-    protected static $using_get_the_excerpt = false;
36
-
37
-    /**
38
-     * Used to flag when the event list is being called from an external iframe.
39
-     *
40
-     * @var bool $iframe
41
-     */
42
-    protected static $iframe = false;
43
-
44
-    /**
45
-     * @var EventListIframeEmbedButton $_iframe_embed_button
46
-     */
47
-    private static $_iframe_embed_button;
48
-
49
-    /**
50
-     * @type EE_Template_Part_Manager $template_parts
51
-     */
52
-    protected $template_parts;
53
-
54
-
55
-    /**
56
-     * @return EED_Events_Archive
57
-     */
58
-    public static function instance()
59
-    {
60
-        return parent::get_instance(__CLASS__);
61
-    }
62
-
63
-
64
-    /**
65
-     * set_hooks - for hooking into EE Core, other modules, etc
66
-     *
67
-     * @return void
68
-     * @throws InvalidArgumentException
69
-     * @throws InvalidDataTypeException
70
-     * @throws InvalidInterfaceException
71
-     */
72
-    public static function set_hooks()
73
-    {
74
-        /** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_type_definitions */
75
-        $custom_post_type_definitions = LoaderFactory::getLoader()->getShared(
76
-            'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'
77
-        );
78
-        $custom_post_types = $custom_post_type_definitions->getDefinitions();
79
-        EE_Config::register_route(
80
-            $custom_post_types['espresso_events']['plural_slug'],
81
-            'Events_Archive',
82
-            'run'
83
-        );
84
-        EE_Config::register_route(
85
-            'event_list',
86
-            'Events_Archive',
87
-            'event_list'
88
-        );
89
-        EE_Config::register_route(
90
-            'iframe',
91
-            'Events_Archive',
92
-            'event_list_iframe',
93
-            'event_list'
94
-        );
95
-        add_action('wp_loaded', array('EED_Events_Archive', 'set_definitions'), 2);
96
-    }
97
-
98
-
99
-    /**
100
-     *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
101
-     *
102
-     * @access    public
103
-     * @return    void
104
-     */
105
-    public static function set_hooks_admin()
106
-    {
107
-        add_action('wp_loaded', array('EED_Events_Archive', 'set_definitions'), 2);
108
-        // hook into the end of the \EE_Admin_Page::_load_page_dependencies()
109
-        // to load assets for "espresso_events" page on the "default" route (action)
110
-        add_action(
111
-            'FHEE__EE_Admin_Page___load_page_dependencies__after_load__espresso_events__default',
112
-            array('EED_Events_Archive', 'event_list_iframe_embed_button'),
113
-            10
114
-        );
115
-    }
116
-
117
-
118
-    /**
119
-     *    set_definitions
120
-     *
121
-     * @access    public
122
-     * @return    void
123
-     */
124
-    public static function set_definitions()
125
-    {
126
-        define('EVENTS_ARCHIVE_ASSETS_URL', plugin_dir_url(__FILE__) . 'assets/');
127
-        define('EVENTS_ARCHIVE_TEMPLATES_PATH', str_replace('\\', '/', plugin_dir_path(__FILE__)) . 'templates/');
128
-    }
129
-
130
-
131
-    /**
132
-     * set up EE_Events_Archive_Config
133
-     */
134
-    protected function set_config()
135
-    {
136
-        $this->set_config_section('template_settings');
137
-        $this->set_config_class('EE_Events_Archive_Config');
138
-        $this->set_config_name('EED_Events_Archive');
139
-    }
140
-
141
-
142
-    /**
143
-     * @return EventListIframeEmbedButton
144
-     */
145
-    public static function get_iframe_embed_button()
146
-    {
147
-        if (! self::$_iframe_embed_button instanceof EventListIframeEmbedButton) {
148
-            self::$_iframe_embed_button = new EventListIframeEmbedButton();
149
-        }
150
-        return self::$_iframe_embed_button;
151
-    }
152
-
153
-
154
-    /**
155
-     * event_list_iframe_embed_button
156
-     *
157
-     * @return    void
158
-     * @throws EE_Error
159
-     */
160
-    public static function event_list_iframe_embed_button()
161
-    {
162
-        $iframe_embed_button = EED_Events_Archive::get_iframe_embed_button();
163
-        $iframe_embed_button->addEmbedButton();
164
-    }
165
-
166
-
167
-    /**
168
-     *    initialize_template_parts
169
-     *
170
-     * @access    public
171
-     * @param EE_Events_Archive_Config $config
172
-     * @return EE_Template_Part_Manager
173
-     */
174
-    public function initialize_template_parts(EE_Events_Archive_Config $config = null)
175
-    {
176
-        $config = $config instanceof EE_Events_Archive_Config ? $config : $this->config();
177
-        EEH_Autoloader::instance()->register_template_part_autoloaders();
178
-        $template_parts = new EE_Template_Part_Manager();
179
-        $template_parts->add_template_part(
180
-            'tickets',
181
-            esc_html__('Ticket Selector', 'event_espresso'),
182
-            'content-espresso_events-tickets.php',
183
-            $config->display_order_tickets
184
-        );
185
-        $template_parts->add_template_part(
186
-            'datetimes',
187
-            esc_html__('Dates and Times', 'event_espresso'),
188
-            'content-espresso_events-datetimes.php',
189
-            $config->display_order_datetimes
190
-        );
191
-        $template_parts->add_template_part(
192
-            'event',
193
-            esc_html__('Event Description', 'event_espresso'),
194
-            'content-espresso_events-details.php',
195
-            $config->display_order_event
196
-        );
197
-        $template_parts->add_template_part(
198
-            'venue',
199
-            esc_html__('Venue Information', 'event_espresso'),
200
-            'content-espresso_events-venues.php',
201
-            $config->display_order_venue
202
-        );
203
-        do_action('AHEE__EED_Event_Archive__initialize_template_parts', $template_parts);
204
-        return $template_parts;
205
-    }
206
-
207
-
208
-    /**
209
-     *    run - initial module setup - this gets called by the EE_Front_Controller if the module route is found in the
210
-     *    incoming request
211
-     *
212
-     * @access    public
213
-     * @param WP $WP
214
-     * @return    void
215
-     */
216
-    public function run($WP)
217
-    {
218
-        do_action('AHEE__EED_Events_Archive__before_run');
219
-        // ensure valid EE_Events_Archive_Config() object exists
220
-        $this->set_config();
221
-        /** @type EE_Events_Archive_Config $config */
222
-        $config = $this->config();
223
-        // load other required components
224
-        $this->load_event_list_assets();
225
-        // filter the WP posts_join, posts_where, and posts_orderby SQL clauses
226
-        // add query filters
227
-        EEH_Event_Query::add_query_filters();
228
-        // set params that will get used by the filters
229
-        EEH_Event_Query::set_query_params(
230
-            '',    // month
231
-            '',    // category
232
-            $config->display_expired_events,    // show_expired
233
-            'start_date',    // orderby
234
-            'ASC'    // sort
235
-        );
236
-        // check what template is loaded
237
-        add_filter('template_include', array($this, 'template_include'), 999, 1);
238
-    }
239
-
240
-
241
-    /**
242
-     * most likely called by the ESPRESSO_EVENTS shortcode which uses this module to do some of it's lifting
243
-     *
244
-     * @return    void
245
-     */
246
-    public function event_list()
247
-    {
248
-        // ensure valid EE_Events_Archive_Config() object exists
249
-        $this->set_config();
250
-        // load other required components
251
-        $this->load_event_list_assets();
252
-    }
253
-
254
-
255
-    /**
256
-     * @access    public
257
-     * @return    void
258
-     * @throws EE_Error
259
-     * @throws DomainException
260
-     */
261
-    public function event_list_iframe()
262
-    {
263
-        EED_Events_Archive::$iframe = true;
264
-        $event_list_iframe          = new EventsArchiveIframe($this);
265
-        $event_list_iframe->display();
266
-    }
267
-
268
-
269
-    /**
270
-     * @access public
271
-     * @return string
272
-     */
273
-    public static function is_iframe()
274
-    {
275
-        return EED_Events_Archive::$iframe;
276
-    }
277
-
278
-
279
-    /**
280
-     * @access public
281
-     * @return string
282
-     */
283
-    public static function link_target()
284
-    {
285
-        return EED_Events_Archive::$iframe ? ' target="_blank"' : '';
286
-    }
287
-
288
-
289
-    /**
290
-     *    template_include
291
-     *
292
-     * @access    public
293
-     * @param string $template
294
-     * @return    string
295
-     */
296
-    public function template_include($template = '')
297
-    {
298
-        // don't add content filter for dedicated EE child themes or private posts
299
-        if (! EEH_Template::is_espresso_theme()) {
300
-            /** @type EE_Events_Archive_Config $config */
301
-            $config = $this->config();
302
-            // add status banner ?
303
-            if ($config->display_status_banner) {
304
-                add_filter('the_title', array('EED_Events_Archive', 'the_title'), 100, 2);
305
-            }
306
-            // if NOT a custom template
307
-            if (
308
-                apply_filters('FHEE__EED_Event_Archive__template_include__allow_custom_selected_template', false)
309
-                || EE_Registry::instance()
310
-                              ->load_core('Front_Controller')
311
-                              ->get_selected_template() !== 'archive-espresso_events.php'
312
-            ) {
313
-                // don't display entry meta because the existing theme will take care of that
314
-                add_filter('FHEE__EED_Events_Archive__template_include__events_list_active', '__return_true');
315
-                // load functions.php file for the theme (loaded by WP if using child theme)
316
-                EEH_Template::load_espresso_theme_functions();
317
-                // because we don't know if the theme is using the_excerpt()
318
-                add_filter(
319
-                    'the_excerpt',
320
-                    array('EED_Events_Archive', 'event_details'),
321
-                    EED_Events_Archive::EVENT_DETAILS_PRIORITY
322
-                );
323
-                // or the_content
324
-                add_filter(
325
-                    'the_content',
326
-                    array('EED_Events_Archive', 'event_details'),
327
-                    EED_Events_Archive::EVENT_DETAILS_PRIORITY
328
-                );
329
-                // and just in case they are running get_the_excerpt() which DESTROYS things
330
-                add_filter('get_the_excerpt', array('EED_Events_Archive', 'get_the_excerpt'), 1, 1);
331
-                // don't display entry meta because the existing theme will take care of that
332
-                add_filter('FHEE__content_espresso_events_details_template__display_entry_meta', '__return_false');
333
-            }
334
-        }
335
-        return $template;
336
-    }
337
-
338
-
339
-    /**
340
-     *    get_the_excerpt - kinda hacky, but if a theme is using get_the_excerpt(), then we need to remove our filters
341
-     *    on the_content()
342
-     *
343
-     * @access    public
344
-     * @param        string $excerpt
345
-     * @return        string
346
-     */
347
-    public static function get_the_excerpt($excerpt = '')
348
-    {
349
-        if (post_password_required()) {
350
-            return $excerpt;
351
-        }
352
-        if (apply_filters('FHEE__EED_Events_Archive__get_the_excerpt__theme_uses_get_the_excerpt', false)) {
353
-            remove_filter(
354
-                'the_excerpt',
355
-                array('EED_Events_Archive', 'event_details'),
356
-                EED_Events_Archive::EVENT_DETAILS_PRIORITY
357
-            );
358
-            remove_filter(
359
-                'the_content',
360
-                array('EED_Events_Archive', 'event_details'),
361
-                EED_Events_Archive::EVENT_DETAILS_PRIORITY
362
-            );
363
-            $excerpt = EED_Events_Archive::event_details($excerpt);
364
-        } else {
365
-            EED_Events_Archive::$using_get_the_excerpt = true;
366
-            add_filter('wp_trim_excerpt', array('EED_Events_Archive', 'end_get_the_excerpt'), 999, 1);
367
-        }
368
-        return $excerpt;
369
-    }
370
-
371
-
372
-    /**
373
-     * end_get_the_excerpt
374
-     *
375
-     * @access public
376
-     * @param  string $text
377
-     * @return string
378
-     */
379
-    public static function end_get_the_excerpt($text = '')
380
-    {
381
-        EED_Events_Archive::$using_get_the_excerpt = false;
382
-        return $text;
383
-    }
384
-
385
-
386
-    /**
387
-     *    the_title
388
-     *
389
-     * @access        public
390
-     * @param        string $title
391
-     * @param        string $id
392
-     * @return        string
393
-     */
394
-    public static function the_title($title = '', $id = '')
395
-    {
396
-        global $post;
397
-        if ($post instanceof WP_Post) {
398
-            return in_the_loop() && $post->ID == $id ? espresso_event_status_banner($post->ID) . $title : $title;
399
-        }
400
-        return $title;
401
-    }
402
-
403
-
404
-    /**
405
-     *    event_details
406
-     *
407
-     * @access    public
408
-     * @param        string $content
409
-     * @return        string
410
-     */
411
-    public static function event_details($content)
412
-    {
413
-        global $post;
414
-        static $current_post_ID = 0;
415
-        if (
416
-            $current_post_ID !== $post->ID
417
-            && $post->post_type === 'espresso_events'
418
-            && ! EED_Events_Archive::$using_get_the_excerpt
419
-            && ! post_password_required()
420
-            && (
421
-                apply_filters('FHEE__EES_Espresso_Events__process_shortcode__true', false)
422
-                || ! apply_filters('FHEE__content_espresso_events__template_loaded', false)
423
-            )
424
-        ) {
425
-            // Set current post ID to prevent showing content twice, but only if headers have definitely been sent.
426
-            // Reason being is that some plugins, like Yoast, need to run through a copy of the loop early
427
-            // BEFORE headers are sent in order to examine the post content and generate content for the HTML header.
428
-            // We want to allow those plugins to still do their thing and have access to our content, but depending on
429
-            // how your event content is being displayed (shortcode, CPT route, etc), this filter can get applied twice,
430
-            // so the following allows this filter to be applied multiple times, but only once for real
431
-            $current_post_ID = did_action('loop_start') ? $post->ID : 0;
432
-            if (EE_Registry::instance()->CFG->template_settings->EED_Events_Archive->use_sortable_display_order) {
433
-                $content = EED_Events_Archive::use_sortable_display_order();
434
-            } else {
435
-                $content = EED_Events_Archive::use_filterable_display_order();
436
-            }
437
-        }
438
-        return $content;
439
-    }
440
-
441
-
442
-    /**
443
-     *    use_sortable_display_order
444
-     *
445
-     * @access    protected
446
-     * @return string
447
-     */
448
-    protected static function use_sortable_display_order()
449
-    {
450
-        // no further password checks required atm
451
-        add_filter('FHEE__EED_Events_Archive__event_details__no_post_password_required', '__return_true');
452
-        // we need to first remove this callback from being applied to the_content() or the_excerpt()
453
-        // (otherwise it will recurse and blow up the interweb)
454
-        remove_filter(
455
-            'the_excerpt',
456
-            array('EED_Events_Archive', 'event_details'),
457
-            EED_Events_Archive::EVENT_DETAILS_PRIORITY
458
-        );
459
-        remove_filter(
460
-            'the_content',
461
-            array('EED_Events_Archive', 'event_details'),
462
-            EED_Events_Archive::EVENT_DETAILS_PRIORITY
463
-        );
464
-        remove_filter('get_the_excerpt', array('EED_Events_Archive', 'get_the_excerpt'), 1);
465
-        // now add additional content depending on whether event is using the_excerpt() or the_content()
466
-        EED_Events_Archive::instance()->template_parts = EED_Events_Archive::instance()->initialize_template_parts();
467
-        $content = EEH_Template::locate_template('content-espresso_events-details.php');
468
-        $content = EED_Events_Archive::instance()->template_parts->apply_template_part_filters($content);
469
-        // re-add our main filters (or else the next event won't have them)
470
-        add_filter(
471
-            'the_excerpt',
472
-            array('EED_Events_Archive', 'event_details'),
473
-            EED_Events_Archive::EVENT_DETAILS_PRIORITY
474
-        );
475
-        add_filter(
476
-            'the_content',
477
-            array('EED_Events_Archive', 'event_details'),
478
-            EED_Events_Archive::EVENT_DETAILS_PRIORITY
479
-        );
480
-        add_filter('get_the_excerpt', array('EED_Events_Archive', 'get_the_excerpt'), 1, 1);
481
-        remove_filter(
482
-            'FHEE__EED_Events_Archive__event_details__no_post_password_required',
483
-            '__return_true'
484
-        );
485
-        return $content;
486
-    }
487
-
488
-
489
-    /**
490
-     *    use_filterable_display_order
491
-     *
492
-     * @access    protected
493
-     * @return    string
494
-     */
495
-    protected static function use_filterable_display_order()
496
-    {
497
-        // we need to first remove this callback from being applied to the_content()
498
-        // (otherwise it will recurse and blow up the interweb)
499
-        remove_filter(
500
-            'the_excerpt',
501
-            array('EED_Events_Archive', 'event_details'),
502
-            EED_Events_Archive::EVENT_DETAILS_PRIORITY
503
-        );
504
-        remove_filter(
505
-            'the_content',
506
-            array('EED_Events_Archive', 'event_details'),
507
-            EED_Events_Archive::EVENT_DETAILS_PRIORITY
508
-        );
509
-        remove_filter('get_the_excerpt', array('EED_Events_Archive', 'get_the_excerpt'), 1);
510
-        // now add additional content depending on whether event is using the_excerpt() or the_content()
511
-        EED_Events_Archive::_add_additional_excerpt_filters();
512
-        EED_Events_Archive::_add_additional_content_filters();
513
-        do_action('AHEE__EED_Events_Archive__use_filterable_display_order__after_add_filters');
514
-        // now load our template
515
-        $content = EEH_Template::locate_template('content-espresso_events-details.php');
516
-        // re-add our main filters (or else the next event won't have them)
517
-        add_filter(
518
-            'the_excerpt',
519
-            array('EED_Events_Archive', 'event_details'),
520
-            EED_Events_Archive::EVENT_DETAILS_PRIORITY
521
-        );
522
-        add_filter(
523
-            'the_content',
524
-            array('EED_Events_Archive', 'event_details'),
525
-            EED_Events_Archive::EVENT_DETAILS_PRIORITY
526
-        );
527
-        add_filter('get_the_excerpt', array('EED_Events_Archive', 'get_the_excerpt'), 1, 1);
528
-        // but remove the other filters so that they don't get applied to the next post
529
-        EED_Events_Archive::_remove_additional_events_archive_filters();
530
-        do_action('AHEE__EED_Events_Archive__use_filterable_display_order__after_remove_filters');
531
-        // we're not returning the $content directly because the template we are loading uses the_content (or the_excerpt)
532
-        // return ! empty( $template ) ? $template : $content;
533
-        return $content;
534
-    }
535
-
536
-
537
-    /**
538
-     *    event_datetimes - adds datetimes ABOVE content
539
-     *
540
-     * @access    public
541
-     * @param        string $content
542
-     * @return        string
543
-     */
544
-    public static function event_datetimes($content)
545
-    {
546
-        if (post_password_required()) {
547
-            return $content;
548
-        }
549
-        return EEH_Template::locate_template('content-espresso_events-datetimes.php') . $content;
550
-    }
551
-
552
-
553
-    /**
554
-     *    event_tickets - adds tickets ABOVE content (which includes datetimes)
555
-     *
556
-     * @access    public
557
-     * @param        string $content
558
-     * @return        string
559
-     */
560
-    public static function event_tickets($content)
561
-    {
562
-        if (post_password_required()) {
563
-            return $content;
564
-        }
565
-        return EEH_Template::locate_template('content-espresso_events-tickets.php') . $content;
566
-    }
567
-
568
-
569
-    /**
570
-     *    event_venues - adds venues BELOW content
571
-     *
572
-     * @access    public
573
-     * @param    string $content
574
-     * @return    string
575
-     */
576
-    public static function event_venue($content)
577
-    {
578
-        return EED_Events_Archive::event_venues($content);
579
-    }
580
-
581
-
582
-    /**
583
-     *    event_venues - adds venues BELOW content
584
-     *
585
-     * @access    public
586
-     * @param        string $content
587
-     * @return        string
588
-     */
589
-    public static function event_venues($content)
590
-    {
591
-        if (post_password_required()) {
592
-            return $content;
593
-        }
594
-        return $content . EEH_Template::locate_template('content-espresso_events-venues.php');
595
-    }
596
-
597
-
598
-    /**
599
-     *    _add_additional_content_filters
600
-     *
601
-     * @access    private
602
-     * @return        void
603
-     */
604
-    private static function _add_additional_excerpt_filters()
605
-    {
606
-        add_filter(
607
-            'the_excerpt',
608
-            array('EED_Events_Archive', 'event_datetimes'),
609
-            EED_Events_Archive::EVENT_DATETIMES_PRIORITY
610
-        );
611
-        add_filter(
612
-            'the_excerpt',
613
-            array('EED_Events_Archive', 'event_tickets'),
614
-            EED_Events_Archive::EVENT_TICKETS_PRIORITY
615
-        );
616
-        add_filter(
617
-            'the_excerpt',
618
-            array('EED_Events_Archive', 'event_venues'),
619
-            EED_Events_Archive::EVENT_VENUES_PRIORITY
620
-        );
621
-    }
622
-
623
-
624
-    /**
625
-     *    _add_additional_content_filters
626
-     *
627
-     * @access    private
628
-     * @return        void
629
-     */
630
-    private static function _add_additional_content_filters()
631
-    {
632
-        add_filter(
633
-            'the_content',
634
-            array('EED_Events_Archive', 'event_datetimes'),
635
-            EED_Events_Archive::EVENT_DATETIMES_PRIORITY
636
-        );
637
-        add_filter(
638
-            'the_content',
639
-            array('EED_Events_Archive', 'event_tickets'),
640
-            EED_Events_Archive::EVENT_TICKETS_PRIORITY
641
-        );
642
-        add_filter(
643
-            'the_content',
644
-            array('EED_Events_Archive', 'event_venues'),
645
-            EED_Events_Archive::EVENT_VENUES_PRIORITY
646
-        );
647
-    }
648
-
649
-
650
-    /**
651
-     *    _remove_additional_events_archive_filters
652
-     *
653
-     * @access    private
654
-     * @return        void
655
-     */
656
-    private static function _remove_additional_events_archive_filters()
657
-    {
658
-        remove_filter(
659
-            'the_excerpt',
660
-            array('EED_Events_Archive', 'event_datetimes'),
661
-            EED_Events_Archive::EVENT_DATETIMES_PRIORITY
662
-        );
663
-        remove_filter(
664
-            'the_excerpt',
665
-            array('EED_Events_Archive', 'event_tickets'),
666
-            EED_Events_Archive::EVENT_TICKETS_PRIORITY
667
-        );
668
-        remove_filter(
669
-            'the_excerpt',
670
-            array('EED_Events_Archive', 'event_venues'),
671
-            EED_Events_Archive::EVENT_VENUES_PRIORITY
672
-        );
673
-        remove_filter(
674
-            'the_content',
675
-            array('EED_Events_Archive', 'event_datetimes'),
676
-            EED_Events_Archive::EVENT_DATETIMES_PRIORITY
677
-        );
678
-        remove_filter(
679
-            'the_content',
680
-            array('EED_Events_Archive', 'event_tickets'),
681
-            EED_Events_Archive::EVENT_TICKETS_PRIORITY
682
-        );
683
-        remove_filter(
684
-            'the_content',
685
-            array('EED_Events_Archive', 'event_venues'),
686
-            EED_Events_Archive::EVENT_VENUES_PRIORITY
687
-        );
688
-    }
689
-
690
-
691
-    /**
692
-     *    remove_all_events_archive_filters
693
-     *
694
-     * @access    public
695
-     * @return        void
696
-     */
697
-    public static function remove_all_events_archive_filters()
698
-    {
699
-        // remove_filter( 'get_the_excerpt', array( 'EED_Events_Archive', 'get_the_excerpt' ), 1 );
700
-        remove_filter('the_title', array('EED_Events_Archive', 'the_title'), 1);
701
-        remove_filter(
702
-            'the_excerpt',
703
-            array('EED_Events_Archive', 'event_details'),
704
-            EED_Events_Archive::EVENT_DETAILS_PRIORITY
705
-        );
706
-        remove_filter(
707
-            'the_excerpt',
708
-            array('EED_Events_Archive', 'event_datetimes'),
709
-            EED_Events_Archive::EVENT_DATETIMES_PRIORITY
710
-        );
711
-        remove_filter(
712
-            'the_excerpt',
713
-            array('EED_Events_Archive', 'event_tickets'),
714
-            EED_Events_Archive::EVENT_TICKETS_PRIORITY
715
-        );
716
-        remove_filter(
717
-            'the_excerpt',
718
-            array('EED_Events_Archive', 'event_venues'),
719
-            EED_Events_Archive::EVENT_VENUES_PRIORITY
720
-        );
721
-        remove_filter(
722
-            'the_content',
723
-            array('EED_Events_Archive', 'event_details'),
724
-            EED_Events_Archive::EVENT_DETAILS_PRIORITY
725
-        );
726
-        remove_filter(
727
-            'the_content',
728
-            array('EED_Events_Archive', 'event_datetimes'),
729
-            EED_Events_Archive::EVENT_DATETIMES_PRIORITY
730
-        );
731
-        remove_filter(
732
-            'the_content',
733
-            array('EED_Events_Archive', 'event_tickets'),
734
-            EED_Events_Archive::EVENT_TICKETS_PRIORITY
735
-        );
736
-        remove_filter(
737
-            'the_content',
738
-            array('EED_Events_Archive', 'event_venues'),
739
-            EED_Events_Archive::EVENT_VENUES_PRIORITY
740
-        );
741
-        // don't display entry meta because the existing theme will take care of that
742
-        remove_filter(
743
-            'FHEE__content_espresso_events_details_template__display_entry_meta',
744
-            '__return_false'
745
-        );
746
-    }
747
-
748
-
749
-    /**
750
-     *    load_event_list_assets
751
-     *
752
-     * @access    public
753
-     * @return    void
754
-     */
755
-    public function load_event_list_assets()
756
-    {
757
-        do_action('AHEE__EED_Events_Archive__before_load_assets');
758
-        add_filter('FHEE_load_EE_Session', '__return_true');
759
-        add_filter('FHEE__EED_Ticket_Selector__load_tckt_slctr_assets', '__return_true');
760
-        add_action('wp_enqueue_scripts', array($this, 'wp_enqueue_scripts'), 10);
761
-        if (EE_Registry::instance()->CFG->map_settings->use_google_maps) {
762
-            add_action('wp_enqueue_scripts', array('EEH_Maps', 'espresso_google_map_js'), 11);
763
-        }
764
-    }
765
-
766
-
767
-    /**
768
-     *    wp_enqueue_scripts
769
-     *
770
-     * @access    public
771
-     * @return    void
772
-     */
773
-    public function wp_enqueue_scripts()
774
-    {
775
-        // get some style
776
-        if (apply_filters('FHEE_enable_default_espresso_css', false)) {
777
-            // first check uploads folder
778
-            if (EEH_File::is_readable(get_stylesheet_directory() . $this->theme . '/style.css')) {
779
-                wp_register_style(
780
-                    $this->theme,
781
-                    get_stylesheet_directory_uri() . $this->theme . '/style.css',
782
-                    array('dashicons', 'espresso_default')
783
-                );
784
-            } else {
785
-            }
786
-            wp_enqueue_style($this->theme);
787
-        }
788
-    }
789
-
790
-
791
-    /**
792
-     *    template_settings_form
793
-     *
794
-     * @access    public
795
-     * @static
796
-     * @return    string
797
-     */
798
-    public static function template_settings_form()
799
-    {
800
-        $template_settings = EE_Registry::instance()->CFG->template_settings;
801
-        $template_settings->EED_Events_Archive = isset($template_settings->EED_Events_Archive)
802
-            ? $template_settings->EED_Events_Archive : new EE_Events_Archive_Config();
803
-        $template_settings->EED_Events_Archive = apply_filters(
804
-            'FHEE__EED_Events_Archive__template_settings_form__event_list_config',
805
-            $template_settings->EED_Events_Archive
806
-        );
807
-        $events_archive_settings = array(
808
-            'display_status_banner' => 0,
809
-            'display_description' => 1,
810
-            'display_ticket_selector' => 0,
811
-            'display_datetimes' => 1,
812
-            'display_venue' => 0,
813
-            'display_expired_events' => 0,
814
-        );
815
-        $events_archive_settings = array_merge(
816
-            $events_archive_settings,
817
-            (array) $template_settings->EED_Events_Archive
818
-        );
819
-        EEH_Template::display_template(
820
-            EVENTS_ARCHIVE_TEMPLATES_PATH . 'admin-event-list-settings.template.php',
821
-            $events_archive_settings
822
-        );
823
-    }
824
-
825
-
826
-    /**
827
-     *    update_template_settings
828
-     *
829
-     * @access    public
830
-     * @param    EE_Template_Config $CFG
831
-     * @param    array $REQ
832
-     * @return    EE_Template_Config
833
-     */
834
-    public static function update_template_settings($CFG, $REQ)
835
-    {
836
-        $CFG->EED_Events_Archive = new EE_Events_Archive_Config();
837
-        // unless we are resetting the config...
838
-        if (
839
-            ! isset($REQ['EED_Events_Archive_reset_event_list_settings'])
840
-            || absint($REQ['EED_Events_Archive_reset_event_list_settings']) !== 1
841
-        ) {
842
-            $CFG->EED_Events_Archive->display_status_banner = isset($REQ['EED_Events_Archive_display_status_banner'])
843
-                ? absint($REQ['EED_Events_Archive_display_status_banner']) : 0;
844
-            $CFG->EED_Events_Archive->display_description = isset($REQ['EED_Events_Archive_display_description'])
845
-                ? absint($REQ['EED_Events_Archive_display_description']) : 1;
846
-            $CFG->EED_Events_Archive->display_ticket_selector = isset($REQ['EED_Events_Archive_display_ticket_selector'])
847
-                ? absint($REQ['EED_Events_Archive_display_ticket_selector']) : 0;
848
-            $CFG->EED_Events_Archive->display_datetimes = isset($REQ['EED_Events_Archive_display_datetimes']) ? absint(
849
-                $REQ['EED_Events_Archive_display_datetimes']
850
-            ) : 1;
851
-            $CFG->EED_Events_Archive->display_venue = isset($REQ['EED_Events_Archive_display_venue']) ? absint(
852
-                $REQ['EED_Events_Archive_display_venue']
853
-            ) : 0;
854
-            $CFG->EED_Events_Archive->display_expired_events = isset($REQ['EED_Events_Archive_display_expired_events'])
855
-                ? absint($REQ['EED_Events_Archive_display_expired_events']) : 0;
856
-        }
857
-        return $CFG;
858
-    }
859
-
860
-
861
-    /**
862
-     *    event_list_css
863
-     *
864
-     * @access    public
865
-     * @param string $extra_class
866
-     * @return    string
867
-     */
868
-    public static function event_list_css($extra_class = '')
869
-    {
870
-        $event_list_css = ! empty($extra_class) ? array($extra_class) : array();
871
-        $event_list_css[] = 'espresso-event-list-event';
872
-        return implode(' ', $event_list_css);
873
-    }
874
-
875
-
876
-    /**
877
-     *    event_categories
878
-     *
879
-     * @access    public
880
-     * @return    array
881
-     */
882
-    public static function event_categories()
883
-    {
884
-        return EE_Registry::instance()->load_model('Term')->get_all_ee_categories();
885
-    }
886
-
887
-
888
-    /**
889
-     *    display_description
890
-     *
891
-     * @access    public
892
-     * @param $value
893
-     * @return    bool
894
-     */
895
-    public static function display_description($value)
896
-    {
897
-        $config = EE_Registry::instance()->CFG->template_settings->EED_Events_Archive;
898
-        $display_description = isset($config->display_description) ? $config->display_description : 1;
899
-        return $display_description === $value ? true : false;
900
-    }
901
-
902
-
903
-    /**
904
-     *    display_ticket_selector
905
-     *
906
-     * @access    public
907
-     * @return    bool
908
-     */
909
-    public static function display_ticket_selector()
910
-    {
911
-        $config = EE_Registry::instance()->CFG->template_settings->EED_Events_Archive;
912
-        return isset($config->display_ticket_selector) && $config->display_ticket_selector ? true : false;
913
-    }
914
-
915
-
916
-    /**
917
-     *    display_venue
918
-     *
919
-     * @access    public
920
-     * @return    bool
921
-     */
922
-    public static function display_venue()
923
-    {
924
-        $config = EE_Registry::instance()->CFG->template_settings->EED_Events_Archive;
925
-        return isset($config->display_venue) && $config->display_venue && EEH_Venue_View::venue_name() ? true : false;
926
-    }
927
-
928
-
929
-    /**
930
-     *    display_datetimes
931
-     *
932
-     * @access    public
933
-     * @return    bool
934
-     */
935
-    public static function display_datetimes()
936
-    {
937
-        $config = EE_Registry::instance()->CFG->template_settings->EED_Events_Archive;
938
-        return isset($config->display_datetimes) && $config->display_datetimes ? true : false;
939
-    }
940
-
941
-
942
-    /**
943
-     *    event_list_title
944
-     *
945
-     * @access    public
946
-     * @return    string
947
-     */
948
-    public static function event_list_title()
949
-    {
950
-        return apply_filters(
951
-            'FHEE__archive_espresso_events_template__upcoming_events_h1',
952
-            esc_html__('Upcoming Events', 'event_espresso')
953
-        );
954
-    }
955
-
956
-
957
-    // GRAVEYARD
958
-
959
-
960
-    /**
961
-     * @since 4.4.0
962
-     */
963
-    public static function _doing_it_wrong_notice($function = '')
964
-    {
965
-        EE_Error::doing_it_wrong(
966
-            __FUNCTION__,
967
-            sprintf(
968
-                esc_html__(
969
-                    'EED_Events_Archive::%1$s was moved to EEH_Event_Query::%1$s:%2$sPlease update your existing code because the method it calls will be removed in version %3$s',
970
-                    'event_espresso'
971
-                ),
972
-                $function,
973
-                '<br />',
974
-                '4.6.0'
975
-            ),
976
-            '4.4.0'
977
-        );
978
-    }
979
-
980
-
981
-    /**
982
-     * @deprecated
983
-     * @since 4.4.0
984
-     */
985
-    public function get_post_data()
986
-    {
987
-        EEH_Event_Query::set_query_params();
988
-    }
989
-
990
-
991
-    /**
992
-     * @deprecated
993
-     * @since 4.4.0
994
-     */
995
-    public function posts_fields($SQL, WP_Query $wp_query)
996
-    {
997
-        EED_Events_Archive::_doing_it_wrong_notice(__FUNCTION__);
998
-        return EEH_Event_Query::posts_fields($SQL, $wp_query);
999
-    }
1000
-
1001
-
1002
-    /**
1003
-     * @deprecated
1004
-     * @since 4.4.0
1005
-     */
1006
-    public static function posts_fields_sql_for_orderby($orderby_params = array())
1007
-    {
1008
-        EED_Events_Archive::_doing_it_wrong_notice(__FUNCTION__);
1009
-        return EEH_Event_Query::posts_fields_sql_for_orderby($orderby_params);
1010
-    }
1011
-
1012
-
1013
-    /**
1014
-     * @deprecated
1015
-     * @since 4.4.0
1016
-     */
1017
-    public function posts_join($SQL, WP_Query $wp_query)
1018
-    {
1019
-        EED_Events_Archive::_doing_it_wrong_notice(__FUNCTION__);
1020
-        return EEH_Event_Query::posts_join($SQL, $wp_query);
1021
-    }
1022
-
1023
-
1024
-    /**
1025
-     * @deprecated
1026
-     * @since 4.4.0
1027
-     */
1028
-    public static function posts_join_sql_for_terms($join_terms = null)
1029
-    {
1030
-        EED_Events_Archive::_doing_it_wrong_notice(__FUNCTION__);
1031
-        return EEH_Event_Query::posts_join_sql_for_terms($join_terms);
1032
-    }
1033
-
1034
-
1035
-    /**
1036
-     * @deprecated
1037
-     * @since 4.4.0
1038
-     */
1039
-    public static function posts_join_for_orderby($orderby_params = array())
1040
-    {
1041
-        EED_Events_Archive::_doing_it_wrong_notice(__FUNCTION__);
1042
-        return EEH_Event_Query::posts_join_for_orderby($orderby_params);
1043
-    }
1044
-
1045
-
1046
-    /**
1047
-     * @deprecated
1048
-     * @since 4.4.0
1049
-     */
1050
-    public function posts_where($SQL, WP_Query $wp_query)
1051
-    {
1052
-        EED_Events_Archive::_doing_it_wrong_notice(__FUNCTION__);
1053
-        return EEH_Event_Query::posts_where($SQL, $wp_query);
1054
-    }
1055
-
1056
-
1057
-    /**
1058
-     * @deprecated
1059
-     * @since 4.4.0
1060
-     */
1061
-    public static function posts_where_sql_for_show_expired($show_expired = false)
1062
-    {
1063
-        EED_Events_Archive::_doing_it_wrong_notice(__FUNCTION__);
1064
-        return EEH_Event_Query::posts_where_sql_for_show_expired($show_expired);
1065
-    }
1066
-
1067
-
1068
-    /**
1069
-     * @deprecated
1070
-     * @since 4.4.0
1071
-     */
1072
-    public static function posts_where_sql_for_event_category_slug($event_category_slug = null)
1073
-    {
1074
-        EED_Events_Archive::_doing_it_wrong_notice(__FUNCTION__);
1075
-        return EEH_Event_Query::posts_where_sql_for_event_category_slug($event_category_slug);
1076
-    }
1077
-
1078
-
1079
-    /**
1080
-     * @deprecated
1081
-     * @since 4.4.0
1082
-     */
1083
-    public static function posts_where_sql_for_event_list_month($month = null)
1084
-    {
1085
-        EED_Events_Archive::_doing_it_wrong_notice(__FUNCTION__);
1086
-        return EEH_Event_Query::posts_where_sql_for_event_list_month($month);
1087
-    }
1088
-
1089
-
1090
-    /**
1091
-     * @deprecated
1092
-     * @since 4.4.0
1093
-     */
1094
-    public function posts_orderby($SQL, WP_Query $wp_query)
1095
-    {
1096
-        EED_Events_Archive::_doing_it_wrong_notice(__FUNCTION__);
1097
-        return EEH_Event_Query::posts_orderby($SQL, $wp_query);
1098
-    }
1099
-
1100
-
1101
-    /**
1102
-     * @deprecated
1103
-     * @since 4.4.0
1104
-     */
1105
-    public static function posts_orderby_sql($orderby_params = array(), $sort = 'ASC')
1106
-    {
1107
-        EED_Events_Archive::_doing_it_wrong_notice(__FUNCTION__);
1108
-        return EEH_Event_Query::posts_orderby_sql($orderby_params, $sort);
1109
-    }
19
+	const EVENT_DETAILS_PRIORITY = 100;
20
+
21
+	const EVENT_DATETIMES_PRIORITY = 110;
22
+
23
+	const EVENT_TICKETS_PRIORITY = 120;
24
+
25
+	const EVENT_VENUES_PRIORITY = 130;
26
+
27
+
28
+	public static $espresso_event_list_ID = 0;
29
+
30
+	public static $espresso_grid_event_lists = array();
31
+
32
+	/**
33
+	 * @type bool $using_get_the_excerpt
34
+	 */
35
+	protected static $using_get_the_excerpt = false;
36
+
37
+	/**
38
+	 * Used to flag when the event list is being called from an external iframe.
39
+	 *
40
+	 * @var bool $iframe
41
+	 */
42
+	protected static $iframe = false;
43
+
44
+	/**
45
+	 * @var EventListIframeEmbedButton $_iframe_embed_button
46
+	 */
47
+	private static $_iframe_embed_button;
48
+
49
+	/**
50
+	 * @type EE_Template_Part_Manager $template_parts
51
+	 */
52
+	protected $template_parts;
53
+
54
+
55
+	/**
56
+	 * @return EED_Events_Archive
57
+	 */
58
+	public static function instance()
59
+	{
60
+		return parent::get_instance(__CLASS__);
61
+	}
62
+
63
+
64
+	/**
65
+	 * set_hooks - for hooking into EE Core, other modules, etc
66
+	 *
67
+	 * @return void
68
+	 * @throws InvalidArgumentException
69
+	 * @throws InvalidDataTypeException
70
+	 * @throws InvalidInterfaceException
71
+	 */
72
+	public static function set_hooks()
73
+	{
74
+		/** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_type_definitions */
75
+		$custom_post_type_definitions = LoaderFactory::getLoader()->getShared(
76
+			'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'
77
+		);
78
+		$custom_post_types = $custom_post_type_definitions->getDefinitions();
79
+		EE_Config::register_route(
80
+			$custom_post_types['espresso_events']['plural_slug'],
81
+			'Events_Archive',
82
+			'run'
83
+		);
84
+		EE_Config::register_route(
85
+			'event_list',
86
+			'Events_Archive',
87
+			'event_list'
88
+		);
89
+		EE_Config::register_route(
90
+			'iframe',
91
+			'Events_Archive',
92
+			'event_list_iframe',
93
+			'event_list'
94
+		);
95
+		add_action('wp_loaded', array('EED_Events_Archive', 'set_definitions'), 2);
96
+	}
97
+
98
+
99
+	/**
100
+	 *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
101
+	 *
102
+	 * @access    public
103
+	 * @return    void
104
+	 */
105
+	public static function set_hooks_admin()
106
+	{
107
+		add_action('wp_loaded', array('EED_Events_Archive', 'set_definitions'), 2);
108
+		// hook into the end of the \EE_Admin_Page::_load_page_dependencies()
109
+		// to load assets for "espresso_events" page on the "default" route (action)
110
+		add_action(
111
+			'FHEE__EE_Admin_Page___load_page_dependencies__after_load__espresso_events__default',
112
+			array('EED_Events_Archive', 'event_list_iframe_embed_button'),
113
+			10
114
+		);
115
+	}
116
+
117
+
118
+	/**
119
+	 *    set_definitions
120
+	 *
121
+	 * @access    public
122
+	 * @return    void
123
+	 */
124
+	public static function set_definitions()
125
+	{
126
+		define('EVENTS_ARCHIVE_ASSETS_URL', plugin_dir_url(__FILE__) . 'assets/');
127
+		define('EVENTS_ARCHIVE_TEMPLATES_PATH', str_replace('\\', '/', plugin_dir_path(__FILE__)) . 'templates/');
128
+	}
129
+
130
+
131
+	/**
132
+	 * set up EE_Events_Archive_Config
133
+	 */
134
+	protected function set_config()
135
+	{
136
+		$this->set_config_section('template_settings');
137
+		$this->set_config_class('EE_Events_Archive_Config');
138
+		$this->set_config_name('EED_Events_Archive');
139
+	}
140
+
141
+
142
+	/**
143
+	 * @return EventListIframeEmbedButton
144
+	 */
145
+	public static function get_iframe_embed_button()
146
+	{
147
+		if (! self::$_iframe_embed_button instanceof EventListIframeEmbedButton) {
148
+			self::$_iframe_embed_button = new EventListIframeEmbedButton();
149
+		}
150
+		return self::$_iframe_embed_button;
151
+	}
152
+
153
+
154
+	/**
155
+	 * event_list_iframe_embed_button
156
+	 *
157
+	 * @return    void
158
+	 * @throws EE_Error
159
+	 */
160
+	public static function event_list_iframe_embed_button()
161
+	{
162
+		$iframe_embed_button = EED_Events_Archive::get_iframe_embed_button();
163
+		$iframe_embed_button->addEmbedButton();
164
+	}
165
+
166
+
167
+	/**
168
+	 *    initialize_template_parts
169
+	 *
170
+	 * @access    public
171
+	 * @param EE_Events_Archive_Config $config
172
+	 * @return EE_Template_Part_Manager
173
+	 */
174
+	public function initialize_template_parts(EE_Events_Archive_Config $config = null)
175
+	{
176
+		$config = $config instanceof EE_Events_Archive_Config ? $config : $this->config();
177
+		EEH_Autoloader::instance()->register_template_part_autoloaders();
178
+		$template_parts = new EE_Template_Part_Manager();
179
+		$template_parts->add_template_part(
180
+			'tickets',
181
+			esc_html__('Ticket Selector', 'event_espresso'),
182
+			'content-espresso_events-tickets.php',
183
+			$config->display_order_tickets
184
+		);
185
+		$template_parts->add_template_part(
186
+			'datetimes',
187
+			esc_html__('Dates and Times', 'event_espresso'),
188
+			'content-espresso_events-datetimes.php',
189
+			$config->display_order_datetimes
190
+		);
191
+		$template_parts->add_template_part(
192
+			'event',
193
+			esc_html__('Event Description', 'event_espresso'),
194
+			'content-espresso_events-details.php',
195
+			$config->display_order_event
196
+		);
197
+		$template_parts->add_template_part(
198
+			'venue',
199
+			esc_html__('Venue Information', 'event_espresso'),
200
+			'content-espresso_events-venues.php',
201
+			$config->display_order_venue
202
+		);
203
+		do_action('AHEE__EED_Event_Archive__initialize_template_parts', $template_parts);
204
+		return $template_parts;
205
+	}
206
+
207
+
208
+	/**
209
+	 *    run - initial module setup - this gets called by the EE_Front_Controller if the module route is found in the
210
+	 *    incoming request
211
+	 *
212
+	 * @access    public
213
+	 * @param WP $WP
214
+	 * @return    void
215
+	 */
216
+	public function run($WP)
217
+	{
218
+		do_action('AHEE__EED_Events_Archive__before_run');
219
+		// ensure valid EE_Events_Archive_Config() object exists
220
+		$this->set_config();
221
+		/** @type EE_Events_Archive_Config $config */
222
+		$config = $this->config();
223
+		// load other required components
224
+		$this->load_event_list_assets();
225
+		// filter the WP posts_join, posts_where, and posts_orderby SQL clauses
226
+		// add query filters
227
+		EEH_Event_Query::add_query_filters();
228
+		// set params that will get used by the filters
229
+		EEH_Event_Query::set_query_params(
230
+			'',    // month
231
+			'',    // category
232
+			$config->display_expired_events,    // show_expired
233
+			'start_date',    // orderby
234
+			'ASC'    // sort
235
+		);
236
+		// check what template is loaded
237
+		add_filter('template_include', array($this, 'template_include'), 999, 1);
238
+	}
239
+
240
+
241
+	/**
242
+	 * most likely called by the ESPRESSO_EVENTS shortcode which uses this module to do some of it's lifting
243
+	 *
244
+	 * @return    void
245
+	 */
246
+	public function event_list()
247
+	{
248
+		// ensure valid EE_Events_Archive_Config() object exists
249
+		$this->set_config();
250
+		// load other required components
251
+		$this->load_event_list_assets();
252
+	}
253
+
254
+
255
+	/**
256
+	 * @access    public
257
+	 * @return    void
258
+	 * @throws EE_Error
259
+	 * @throws DomainException
260
+	 */
261
+	public function event_list_iframe()
262
+	{
263
+		EED_Events_Archive::$iframe = true;
264
+		$event_list_iframe          = new EventsArchiveIframe($this);
265
+		$event_list_iframe->display();
266
+	}
267
+
268
+
269
+	/**
270
+	 * @access public
271
+	 * @return string
272
+	 */
273
+	public static function is_iframe()
274
+	{
275
+		return EED_Events_Archive::$iframe;
276
+	}
277
+
278
+
279
+	/**
280
+	 * @access public
281
+	 * @return string
282
+	 */
283
+	public static function link_target()
284
+	{
285
+		return EED_Events_Archive::$iframe ? ' target="_blank"' : '';
286
+	}
287
+
288
+
289
+	/**
290
+	 *    template_include
291
+	 *
292
+	 * @access    public
293
+	 * @param string $template
294
+	 * @return    string
295
+	 */
296
+	public function template_include($template = '')
297
+	{
298
+		// don't add content filter for dedicated EE child themes or private posts
299
+		if (! EEH_Template::is_espresso_theme()) {
300
+			/** @type EE_Events_Archive_Config $config */
301
+			$config = $this->config();
302
+			// add status banner ?
303
+			if ($config->display_status_banner) {
304
+				add_filter('the_title', array('EED_Events_Archive', 'the_title'), 100, 2);
305
+			}
306
+			// if NOT a custom template
307
+			if (
308
+				apply_filters('FHEE__EED_Event_Archive__template_include__allow_custom_selected_template', false)
309
+				|| EE_Registry::instance()
310
+							  ->load_core('Front_Controller')
311
+							  ->get_selected_template() !== 'archive-espresso_events.php'
312
+			) {
313
+				// don't display entry meta because the existing theme will take care of that
314
+				add_filter('FHEE__EED_Events_Archive__template_include__events_list_active', '__return_true');
315
+				// load functions.php file for the theme (loaded by WP if using child theme)
316
+				EEH_Template::load_espresso_theme_functions();
317
+				// because we don't know if the theme is using the_excerpt()
318
+				add_filter(
319
+					'the_excerpt',
320
+					array('EED_Events_Archive', 'event_details'),
321
+					EED_Events_Archive::EVENT_DETAILS_PRIORITY
322
+				);
323
+				// or the_content
324
+				add_filter(
325
+					'the_content',
326
+					array('EED_Events_Archive', 'event_details'),
327
+					EED_Events_Archive::EVENT_DETAILS_PRIORITY
328
+				);
329
+				// and just in case they are running get_the_excerpt() which DESTROYS things
330
+				add_filter('get_the_excerpt', array('EED_Events_Archive', 'get_the_excerpt'), 1, 1);
331
+				// don't display entry meta because the existing theme will take care of that
332
+				add_filter('FHEE__content_espresso_events_details_template__display_entry_meta', '__return_false');
333
+			}
334
+		}
335
+		return $template;
336
+	}
337
+
338
+
339
+	/**
340
+	 *    get_the_excerpt - kinda hacky, but if a theme is using get_the_excerpt(), then we need to remove our filters
341
+	 *    on the_content()
342
+	 *
343
+	 * @access    public
344
+	 * @param        string $excerpt
345
+	 * @return        string
346
+	 */
347
+	public static function get_the_excerpt($excerpt = '')
348
+	{
349
+		if (post_password_required()) {
350
+			return $excerpt;
351
+		}
352
+		if (apply_filters('FHEE__EED_Events_Archive__get_the_excerpt__theme_uses_get_the_excerpt', false)) {
353
+			remove_filter(
354
+				'the_excerpt',
355
+				array('EED_Events_Archive', 'event_details'),
356
+				EED_Events_Archive::EVENT_DETAILS_PRIORITY
357
+			);
358
+			remove_filter(
359
+				'the_content',
360
+				array('EED_Events_Archive', 'event_details'),
361
+				EED_Events_Archive::EVENT_DETAILS_PRIORITY
362
+			);
363
+			$excerpt = EED_Events_Archive::event_details($excerpt);
364
+		} else {
365
+			EED_Events_Archive::$using_get_the_excerpt = true;
366
+			add_filter('wp_trim_excerpt', array('EED_Events_Archive', 'end_get_the_excerpt'), 999, 1);
367
+		}
368
+		return $excerpt;
369
+	}
370
+
371
+
372
+	/**
373
+	 * end_get_the_excerpt
374
+	 *
375
+	 * @access public
376
+	 * @param  string $text
377
+	 * @return string
378
+	 */
379
+	public static function end_get_the_excerpt($text = '')
380
+	{
381
+		EED_Events_Archive::$using_get_the_excerpt = false;
382
+		return $text;
383
+	}
384
+
385
+
386
+	/**
387
+	 *    the_title
388
+	 *
389
+	 * @access        public
390
+	 * @param        string $title
391
+	 * @param        string $id
392
+	 * @return        string
393
+	 */
394
+	public static function the_title($title = '', $id = '')
395
+	{
396
+		global $post;
397
+		if ($post instanceof WP_Post) {
398
+			return in_the_loop() && $post->ID == $id ? espresso_event_status_banner($post->ID) . $title : $title;
399
+		}
400
+		return $title;
401
+	}
402
+
403
+
404
+	/**
405
+	 *    event_details
406
+	 *
407
+	 * @access    public
408
+	 * @param        string $content
409
+	 * @return        string
410
+	 */
411
+	public static function event_details($content)
412
+	{
413
+		global $post;
414
+		static $current_post_ID = 0;
415
+		if (
416
+			$current_post_ID !== $post->ID
417
+			&& $post->post_type === 'espresso_events'
418
+			&& ! EED_Events_Archive::$using_get_the_excerpt
419
+			&& ! post_password_required()
420
+			&& (
421
+				apply_filters('FHEE__EES_Espresso_Events__process_shortcode__true', false)
422
+				|| ! apply_filters('FHEE__content_espresso_events__template_loaded', false)
423
+			)
424
+		) {
425
+			// Set current post ID to prevent showing content twice, but only if headers have definitely been sent.
426
+			// Reason being is that some plugins, like Yoast, need to run through a copy of the loop early
427
+			// BEFORE headers are sent in order to examine the post content and generate content for the HTML header.
428
+			// We want to allow those plugins to still do their thing and have access to our content, but depending on
429
+			// how your event content is being displayed (shortcode, CPT route, etc), this filter can get applied twice,
430
+			// so the following allows this filter to be applied multiple times, but only once for real
431
+			$current_post_ID = did_action('loop_start') ? $post->ID : 0;
432
+			if (EE_Registry::instance()->CFG->template_settings->EED_Events_Archive->use_sortable_display_order) {
433
+				$content = EED_Events_Archive::use_sortable_display_order();
434
+			} else {
435
+				$content = EED_Events_Archive::use_filterable_display_order();
436
+			}
437
+		}
438
+		return $content;
439
+	}
440
+
441
+
442
+	/**
443
+	 *    use_sortable_display_order
444
+	 *
445
+	 * @access    protected
446
+	 * @return string
447
+	 */
448
+	protected static function use_sortable_display_order()
449
+	{
450
+		// no further password checks required atm
451
+		add_filter('FHEE__EED_Events_Archive__event_details__no_post_password_required', '__return_true');
452
+		// we need to first remove this callback from being applied to the_content() or the_excerpt()
453
+		// (otherwise it will recurse and blow up the interweb)
454
+		remove_filter(
455
+			'the_excerpt',
456
+			array('EED_Events_Archive', 'event_details'),
457
+			EED_Events_Archive::EVENT_DETAILS_PRIORITY
458
+		);
459
+		remove_filter(
460
+			'the_content',
461
+			array('EED_Events_Archive', 'event_details'),
462
+			EED_Events_Archive::EVENT_DETAILS_PRIORITY
463
+		);
464
+		remove_filter('get_the_excerpt', array('EED_Events_Archive', 'get_the_excerpt'), 1);
465
+		// now add additional content depending on whether event is using the_excerpt() or the_content()
466
+		EED_Events_Archive::instance()->template_parts = EED_Events_Archive::instance()->initialize_template_parts();
467
+		$content = EEH_Template::locate_template('content-espresso_events-details.php');
468
+		$content = EED_Events_Archive::instance()->template_parts->apply_template_part_filters($content);
469
+		// re-add our main filters (or else the next event won't have them)
470
+		add_filter(
471
+			'the_excerpt',
472
+			array('EED_Events_Archive', 'event_details'),
473
+			EED_Events_Archive::EVENT_DETAILS_PRIORITY
474
+		);
475
+		add_filter(
476
+			'the_content',
477
+			array('EED_Events_Archive', 'event_details'),
478
+			EED_Events_Archive::EVENT_DETAILS_PRIORITY
479
+		);
480
+		add_filter('get_the_excerpt', array('EED_Events_Archive', 'get_the_excerpt'), 1, 1);
481
+		remove_filter(
482
+			'FHEE__EED_Events_Archive__event_details__no_post_password_required',
483
+			'__return_true'
484
+		);
485
+		return $content;
486
+	}
487
+
488
+
489
+	/**
490
+	 *    use_filterable_display_order
491
+	 *
492
+	 * @access    protected
493
+	 * @return    string
494
+	 */
495
+	protected static function use_filterable_display_order()
496
+	{
497
+		// we need to first remove this callback from being applied to the_content()
498
+		// (otherwise it will recurse and blow up the interweb)
499
+		remove_filter(
500
+			'the_excerpt',
501
+			array('EED_Events_Archive', 'event_details'),
502
+			EED_Events_Archive::EVENT_DETAILS_PRIORITY
503
+		);
504
+		remove_filter(
505
+			'the_content',
506
+			array('EED_Events_Archive', 'event_details'),
507
+			EED_Events_Archive::EVENT_DETAILS_PRIORITY
508
+		);
509
+		remove_filter('get_the_excerpt', array('EED_Events_Archive', 'get_the_excerpt'), 1);
510
+		// now add additional content depending on whether event is using the_excerpt() or the_content()
511
+		EED_Events_Archive::_add_additional_excerpt_filters();
512
+		EED_Events_Archive::_add_additional_content_filters();
513
+		do_action('AHEE__EED_Events_Archive__use_filterable_display_order__after_add_filters');
514
+		// now load our template
515
+		$content = EEH_Template::locate_template('content-espresso_events-details.php');
516
+		// re-add our main filters (or else the next event won't have them)
517
+		add_filter(
518
+			'the_excerpt',
519
+			array('EED_Events_Archive', 'event_details'),
520
+			EED_Events_Archive::EVENT_DETAILS_PRIORITY
521
+		);
522
+		add_filter(
523
+			'the_content',
524
+			array('EED_Events_Archive', 'event_details'),
525
+			EED_Events_Archive::EVENT_DETAILS_PRIORITY
526
+		);
527
+		add_filter('get_the_excerpt', array('EED_Events_Archive', 'get_the_excerpt'), 1, 1);
528
+		// but remove the other filters so that they don't get applied to the next post
529
+		EED_Events_Archive::_remove_additional_events_archive_filters();
530
+		do_action('AHEE__EED_Events_Archive__use_filterable_display_order__after_remove_filters');
531
+		// we're not returning the $content directly because the template we are loading uses the_content (or the_excerpt)
532
+		// return ! empty( $template ) ? $template : $content;
533
+		return $content;
534
+	}
535
+
536
+
537
+	/**
538
+	 *    event_datetimes - adds datetimes ABOVE content
539
+	 *
540
+	 * @access    public
541
+	 * @param        string $content
542
+	 * @return        string
543
+	 */
544
+	public static function event_datetimes($content)
545
+	{
546
+		if (post_password_required()) {
547
+			return $content;
548
+		}
549
+		return EEH_Template::locate_template('content-espresso_events-datetimes.php') . $content;
550
+	}
551
+
552
+
553
+	/**
554
+	 *    event_tickets - adds tickets ABOVE content (which includes datetimes)
555
+	 *
556
+	 * @access    public
557
+	 * @param        string $content
558
+	 * @return        string
559
+	 */
560
+	public static function event_tickets($content)
561
+	{
562
+		if (post_password_required()) {
563
+			return $content;
564
+		}
565
+		return EEH_Template::locate_template('content-espresso_events-tickets.php') . $content;
566
+	}
567
+
568
+
569
+	/**
570
+	 *    event_venues - adds venues BELOW content
571
+	 *
572
+	 * @access    public
573
+	 * @param    string $content
574
+	 * @return    string
575
+	 */
576
+	public static function event_venue($content)
577
+	{
578
+		return EED_Events_Archive::event_venues($content);
579
+	}
580
+
581
+
582
+	/**
583
+	 *    event_venues - adds venues BELOW content
584
+	 *
585
+	 * @access    public
586
+	 * @param        string $content
587
+	 * @return        string
588
+	 */
589
+	public static function event_venues($content)
590
+	{
591
+		if (post_password_required()) {
592
+			return $content;
593
+		}
594
+		return $content . EEH_Template::locate_template('content-espresso_events-venues.php');
595
+	}
596
+
597
+
598
+	/**
599
+	 *    _add_additional_content_filters
600
+	 *
601
+	 * @access    private
602
+	 * @return        void
603
+	 */
604
+	private static function _add_additional_excerpt_filters()
605
+	{
606
+		add_filter(
607
+			'the_excerpt',
608
+			array('EED_Events_Archive', 'event_datetimes'),
609
+			EED_Events_Archive::EVENT_DATETIMES_PRIORITY
610
+		);
611
+		add_filter(
612
+			'the_excerpt',
613
+			array('EED_Events_Archive', 'event_tickets'),
614
+			EED_Events_Archive::EVENT_TICKETS_PRIORITY
615
+		);
616
+		add_filter(
617
+			'the_excerpt',
618
+			array('EED_Events_Archive', 'event_venues'),
619
+			EED_Events_Archive::EVENT_VENUES_PRIORITY
620
+		);
621
+	}
622
+
623
+
624
+	/**
625
+	 *    _add_additional_content_filters
626
+	 *
627
+	 * @access    private
628
+	 * @return        void
629
+	 */
630
+	private static function _add_additional_content_filters()
631
+	{
632
+		add_filter(
633
+			'the_content',
634
+			array('EED_Events_Archive', 'event_datetimes'),
635
+			EED_Events_Archive::EVENT_DATETIMES_PRIORITY
636
+		);
637
+		add_filter(
638
+			'the_content',
639
+			array('EED_Events_Archive', 'event_tickets'),
640
+			EED_Events_Archive::EVENT_TICKETS_PRIORITY
641
+		);
642
+		add_filter(
643
+			'the_content',
644
+			array('EED_Events_Archive', 'event_venues'),
645
+			EED_Events_Archive::EVENT_VENUES_PRIORITY
646
+		);
647
+	}
648
+
649
+
650
+	/**
651
+	 *    _remove_additional_events_archive_filters
652
+	 *
653
+	 * @access    private
654
+	 * @return        void
655
+	 */
656
+	private static function _remove_additional_events_archive_filters()
657
+	{
658
+		remove_filter(
659
+			'the_excerpt',
660
+			array('EED_Events_Archive', 'event_datetimes'),
661
+			EED_Events_Archive::EVENT_DATETIMES_PRIORITY
662
+		);
663
+		remove_filter(
664
+			'the_excerpt',
665
+			array('EED_Events_Archive', 'event_tickets'),
666
+			EED_Events_Archive::EVENT_TICKETS_PRIORITY
667
+		);
668
+		remove_filter(
669
+			'the_excerpt',
670
+			array('EED_Events_Archive', 'event_venues'),
671
+			EED_Events_Archive::EVENT_VENUES_PRIORITY
672
+		);
673
+		remove_filter(
674
+			'the_content',
675
+			array('EED_Events_Archive', 'event_datetimes'),
676
+			EED_Events_Archive::EVENT_DATETIMES_PRIORITY
677
+		);
678
+		remove_filter(
679
+			'the_content',
680
+			array('EED_Events_Archive', 'event_tickets'),
681
+			EED_Events_Archive::EVENT_TICKETS_PRIORITY
682
+		);
683
+		remove_filter(
684
+			'the_content',
685
+			array('EED_Events_Archive', 'event_venues'),
686
+			EED_Events_Archive::EVENT_VENUES_PRIORITY
687
+		);
688
+	}
689
+
690
+
691
+	/**
692
+	 *    remove_all_events_archive_filters
693
+	 *
694
+	 * @access    public
695
+	 * @return        void
696
+	 */
697
+	public static function remove_all_events_archive_filters()
698
+	{
699
+		// remove_filter( 'get_the_excerpt', array( 'EED_Events_Archive', 'get_the_excerpt' ), 1 );
700
+		remove_filter('the_title', array('EED_Events_Archive', 'the_title'), 1);
701
+		remove_filter(
702
+			'the_excerpt',
703
+			array('EED_Events_Archive', 'event_details'),
704
+			EED_Events_Archive::EVENT_DETAILS_PRIORITY
705
+		);
706
+		remove_filter(
707
+			'the_excerpt',
708
+			array('EED_Events_Archive', 'event_datetimes'),
709
+			EED_Events_Archive::EVENT_DATETIMES_PRIORITY
710
+		);
711
+		remove_filter(
712
+			'the_excerpt',
713
+			array('EED_Events_Archive', 'event_tickets'),
714
+			EED_Events_Archive::EVENT_TICKETS_PRIORITY
715
+		);
716
+		remove_filter(
717
+			'the_excerpt',
718
+			array('EED_Events_Archive', 'event_venues'),
719
+			EED_Events_Archive::EVENT_VENUES_PRIORITY
720
+		);
721
+		remove_filter(
722
+			'the_content',
723
+			array('EED_Events_Archive', 'event_details'),
724
+			EED_Events_Archive::EVENT_DETAILS_PRIORITY
725
+		);
726
+		remove_filter(
727
+			'the_content',
728
+			array('EED_Events_Archive', 'event_datetimes'),
729
+			EED_Events_Archive::EVENT_DATETIMES_PRIORITY
730
+		);
731
+		remove_filter(
732
+			'the_content',
733
+			array('EED_Events_Archive', 'event_tickets'),
734
+			EED_Events_Archive::EVENT_TICKETS_PRIORITY
735
+		);
736
+		remove_filter(
737
+			'the_content',
738
+			array('EED_Events_Archive', 'event_venues'),
739
+			EED_Events_Archive::EVENT_VENUES_PRIORITY
740
+		);
741
+		// don't display entry meta because the existing theme will take care of that
742
+		remove_filter(
743
+			'FHEE__content_espresso_events_details_template__display_entry_meta',
744
+			'__return_false'
745
+		);
746
+	}
747
+
748
+
749
+	/**
750
+	 *    load_event_list_assets
751
+	 *
752
+	 * @access    public
753
+	 * @return    void
754
+	 */
755
+	public function load_event_list_assets()
756
+	{
757
+		do_action('AHEE__EED_Events_Archive__before_load_assets');
758
+		add_filter('FHEE_load_EE_Session', '__return_true');
759
+		add_filter('FHEE__EED_Ticket_Selector__load_tckt_slctr_assets', '__return_true');
760
+		add_action('wp_enqueue_scripts', array($this, 'wp_enqueue_scripts'), 10);
761
+		if (EE_Registry::instance()->CFG->map_settings->use_google_maps) {
762
+			add_action('wp_enqueue_scripts', array('EEH_Maps', 'espresso_google_map_js'), 11);
763
+		}
764
+	}
765
+
766
+
767
+	/**
768
+	 *    wp_enqueue_scripts
769
+	 *
770
+	 * @access    public
771
+	 * @return    void
772
+	 */
773
+	public function wp_enqueue_scripts()
774
+	{
775
+		// get some style
776
+		if (apply_filters('FHEE_enable_default_espresso_css', false)) {
777
+			// first check uploads folder
778
+			if (EEH_File::is_readable(get_stylesheet_directory() . $this->theme . '/style.css')) {
779
+				wp_register_style(
780
+					$this->theme,
781
+					get_stylesheet_directory_uri() . $this->theme . '/style.css',
782
+					array('dashicons', 'espresso_default')
783
+				);
784
+			} else {
785
+			}
786
+			wp_enqueue_style($this->theme);
787
+		}
788
+	}
789
+
790
+
791
+	/**
792
+	 *    template_settings_form
793
+	 *
794
+	 * @access    public
795
+	 * @static
796
+	 * @return    string
797
+	 */
798
+	public static function template_settings_form()
799
+	{
800
+		$template_settings = EE_Registry::instance()->CFG->template_settings;
801
+		$template_settings->EED_Events_Archive = isset($template_settings->EED_Events_Archive)
802
+			? $template_settings->EED_Events_Archive : new EE_Events_Archive_Config();
803
+		$template_settings->EED_Events_Archive = apply_filters(
804
+			'FHEE__EED_Events_Archive__template_settings_form__event_list_config',
805
+			$template_settings->EED_Events_Archive
806
+		);
807
+		$events_archive_settings = array(
808
+			'display_status_banner' => 0,
809
+			'display_description' => 1,
810
+			'display_ticket_selector' => 0,
811
+			'display_datetimes' => 1,
812
+			'display_venue' => 0,
813
+			'display_expired_events' => 0,
814
+		);
815
+		$events_archive_settings = array_merge(
816
+			$events_archive_settings,
817
+			(array) $template_settings->EED_Events_Archive
818
+		);
819
+		EEH_Template::display_template(
820
+			EVENTS_ARCHIVE_TEMPLATES_PATH . 'admin-event-list-settings.template.php',
821
+			$events_archive_settings
822
+		);
823
+	}
824
+
825
+
826
+	/**
827
+	 *    update_template_settings
828
+	 *
829
+	 * @access    public
830
+	 * @param    EE_Template_Config $CFG
831
+	 * @param    array $REQ
832
+	 * @return    EE_Template_Config
833
+	 */
834
+	public static function update_template_settings($CFG, $REQ)
835
+	{
836
+		$CFG->EED_Events_Archive = new EE_Events_Archive_Config();
837
+		// unless we are resetting the config...
838
+		if (
839
+			! isset($REQ['EED_Events_Archive_reset_event_list_settings'])
840
+			|| absint($REQ['EED_Events_Archive_reset_event_list_settings']) !== 1
841
+		) {
842
+			$CFG->EED_Events_Archive->display_status_banner = isset($REQ['EED_Events_Archive_display_status_banner'])
843
+				? absint($REQ['EED_Events_Archive_display_status_banner']) : 0;
844
+			$CFG->EED_Events_Archive->display_description = isset($REQ['EED_Events_Archive_display_description'])
845
+				? absint($REQ['EED_Events_Archive_display_description']) : 1;
846
+			$CFG->EED_Events_Archive->display_ticket_selector = isset($REQ['EED_Events_Archive_display_ticket_selector'])
847
+				? absint($REQ['EED_Events_Archive_display_ticket_selector']) : 0;
848
+			$CFG->EED_Events_Archive->display_datetimes = isset($REQ['EED_Events_Archive_display_datetimes']) ? absint(
849
+				$REQ['EED_Events_Archive_display_datetimes']
850
+			) : 1;
851
+			$CFG->EED_Events_Archive->display_venue = isset($REQ['EED_Events_Archive_display_venue']) ? absint(
852
+				$REQ['EED_Events_Archive_display_venue']
853
+			) : 0;
854
+			$CFG->EED_Events_Archive->display_expired_events = isset($REQ['EED_Events_Archive_display_expired_events'])
855
+				? absint($REQ['EED_Events_Archive_display_expired_events']) : 0;
856
+		}
857
+		return $CFG;
858
+	}
859
+
860
+
861
+	/**
862
+	 *    event_list_css
863
+	 *
864
+	 * @access    public
865
+	 * @param string $extra_class
866
+	 * @return    string
867
+	 */
868
+	public static function event_list_css($extra_class = '')
869
+	{
870
+		$event_list_css = ! empty($extra_class) ? array($extra_class) : array();
871
+		$event_list_css[] = 'espresso-event-list-event';
872
+		return implode(' ', $event_list_css);
873
+	}
874
+
875
+
876
+	/**
877
+	 *    event_categories
878
+	 *
879
+	 * @access    public
880
+	 * @return    array
881
+	 */
882
+	public static function event_categories()
883
+	{
884
+		return EE_Registry::instance()->load_model('Term')->get_all_ee_categories();
885
+	}
886
+
887
+
888
+	/**
889
+	 *    display_description
890
+	 *
891
+	 * @access    public
892
+	 * @param $value
893
+	 * @return    bool
894
+	 */
895
+	public static function display_description($value)
896
+	{
897
+		$config = EE_Registry::instance()->CFG->template_settings->EED_Events_Archive;
898
+		$display_description = isset($config->display_description) ? $config->display_description : 1;
899
+		return $display_description === $value ? true : false;
900
+	}
901
+
902
+
903
+	/**
904
+	 *    display_ticket_selector
905
+	 *
906
+	 * @access    public
907
+	 * @return    bool
908
+	 */
909
+	public static function display_ticket_selector()
910
+	{
911
+		$config = EE_Registry::instance()->CFG->template_settings->EED_Events_Archive;
912
+		return isset($config->display_ticket_selector) && $config->display_ticket_selector ? true : false;
913
+	}
914
+
915
+
916
+	/**
917
+	 *    display_venue
918
+	 *
919
+	 * @access    public
920
+	 * @return    bool
921
+	 */
922
+	public static function display_venue()
923
+	{
924
+		$config = EE_Registry::instance()->CFG->template_settings->EED_Events_Archive;
925
+		return isset($config->display_venue) && $config->display_venue && EEH_Venue_View::venue_name() ? true : false;
926
+	}
927
+
928
+
929
+	/**
930
+	 *    display_datetimes
931
+	 *
932
+	 * @access    public
933
+	 * @return    bool
934
+	 */
935
+	public static function display_datetimes()
936
+	{
937
+		$config = EE_Registry::instance()->CFG->template_settings->EED_Events_Archive;
938
+		return isset($config->display_datetimes) && $config->display_datetimes ? true : false;
939
+	}
940
+
941
+
942
+	/**
943
+	 *    event_list_title
944
+	 *
945
+	 * @access    public
946
+	 * @return    string
947
+	 */
948
+	public static function event_list_title()
949
+	{
950
+		return apply_filters(
951
+			'FHEE__archive_espresso_events_template__upcoming_events_h1',
952
+			esc_html__('Upcoming Events', 'event_espresso')
953
+		);
954
+	}
955
+
956
+
957
+	// GRAVEYARD
958
+
959
+
960
+	/**
961
+	 * @since 4.4.0
962
+	 */
963
+	public static function _doing_it_wrong_notice($function = '')
964
+	{
965
+		EE_Error::doing_it_wrong(
966
+			__FUNCTION__,
967
+			sprintf(
968
+				esc_html__(
969
+					'EED_Events_Archive::%1$s was moved to EEH_Event_Query::%1$s:%2$sPlease update your existing code because the method it calls will be removed in version %3$s',
970
+					'event_espresso'
971
+				),
972
+				$function,
973
+				'<br />',
974
+				'4.6.0'
975
+			),
976
+			'4.4.0'
977
+		);
978
+	}
979
+
980
+
981
+	/**
982
+	 * @deprecated
983
+	 * @since 4.4.0
984
+	 */
985
+	public function get_post_data()
986
+	{
987
+		EEH_Event_Query::set_query_params();
988
+	}
989
+
990
+
991
+	/**
992
+	 * @deprecated
993
+	 * @since 4.4.0
994
+	 */
995
+	public function posts_fields($SQL, WP_Query $wp_query)
996
+	{
997
+		EED_Events_Archive::_doing_it_wrong_notice(__FUNCTION__);
998
+		return EEH_Event_Query::posts_fields($SQL, $wp_query);
999
+	}
1000
+
1001
+
1002
+	/**
1003
+	 * @deprecated
1004
+	 * @since 4.4.0
1005
+	 */
1006
+	public static function posts_fields_sql_for_orderby($orderby_params = array())
1007
+	{
1008
+		EED_Events_Archive::_doing_it_wrong_notice(__FUNCTION__);
1009
+		return EEH_Event_Query::posts_fields_sql_for_orderby($orderby_params);
1010
+	}
1011
+
1012
+
1013
+	/**
1014
+	 * @deprecated
1015
+	 * @since 4.4.0
1016
+	 */
1017
+	public function posts_join($SQL, WP_Query $wp_query)
1018
+	{
1019
+		EED_Events_Archive::_doing_it_wrong_notice(__FUNCTION__);
1020
+		return EEH_Event_Query::posts_join($SQL, $wp_query);
1021
+	}
1022
+
1023
+
1024
+	/**
1025
+	 * @deprecated
1026
+	 * @since 4.4.0
1027
+	 */
1028
+	public static function posts_join_sql_for_terms($join_terms = null)
1029
+	{
1030
+		EED_Events_Archive::_doing_it_wrong_notice(__FUNCTION__);
1031
+		return EEH_Event_Query::posts_join_sql_for_terms($join_terms);
1032
+	}
1033
+
1034
+
1035
+	/**
1036
+	 * @deprecated
1037
+	 * @since 4.4.0
1038
+	 */
1039
+	public static function posts_join_for_orderby($orderby_params = array())
1040
+	{
1041
+		EED_Events_Archive::_doing_it_wrong_notice(__FUNCTION__);
1042
+		return EEH_Event_Query::posts_join_for_orderby($orderby_params);
1043
+	}
1044
+
1045
+
1046
+	/**
1047
+	 * @deprecated
1048
+	 * @since 4.4.0
1049
+	 */
1050
+	public function posts_where($SQL, WP_Query $wp_query)
1051
+	{
1052
+		EED_Events_Archive::_doing_it_wrong_notice(__FUNCTION__);
1053
+		return EEH_Event_Query::posts_where($SQL, $wp_query);
1054
+	}
1055
+
1056
+
1057
+	/**
1058
+	 * @deprecated
1059
+	 * @since 4.4.0
1060
+	 */
1061
+	public static function posts_where_sql_for_show_expired($show_expired = false)
1062
+	{
1063
+		EED_Events_Archive::_doing_it_wrong_notice(__FUNCTION__);
1064
+		return EEH_Event_Query::posts_where_sql_for_show_expired($show_expired);
1065
+	}
1066
+
1067
+
1068
+	/**
1069
+	 * @deprecated
1070
+	 * @since 4.4.0
1071
+	 */
1072
+	public static function posts_where_sql_for_event_category_slug($event_category_slug = null)
1073
+	{
1074
+		EED_Events_Archive::_doing_it_wrong_notice(__FUNCTION__);
1075
+		return EEH_Event_Query::posts_where_sql_for_event_category_slug($event_category_slug);
1076
+	}
1077
+
1078
+
1079
+	/**
1080
+	 * @deprecated
1081
+	 * @since 4.4.0
1082
+	 */
1083
+	public static function posts_where_sql_for_event_list_month($month = null)
1084
+	{
1085
+		EED_Events_Archive::_doing_it_wrong_notice(__FUNCTION__);
1086
+		return EEH_Event_Query::posts_where_sql_for_event_list_month($month);
1087
+	}
1088
+
1089
+
1090
+	/**
1091
+	 * @deprecated
1092
+	 * @since 4.4.0
1093
+	 */
1094
+	public function posts_orderby($SQL, WP_Query $wp_query)
1095
+	{
1096
+		EED_Events_Archive::_doing_it_wrong_notice(__FUNCTION__);
1097
+		return EEH_Event_Query::posts_orderby($SQL, $wp_query);
1098
+	}
1099
+
1100
+
1101
+	/**
1102
+	 * @deprecated
1103
+	 * @since 4.4.0
1104
+	 */
1105
+	public static function posts_orderby_sql($orderby_params = array(), $sort = 'ASC')
1106
+	{
1107
+		EED_Events_Archive::_doing_it_wrong_notice(__FUNCTION__);
1108
+		return EEH_Event_Query::posts_orderby_sql($orderby_params, $sort);
1109
+	}
1110 1110
 }
1111 1111
 
1112 1112
 
@@ -1115,9 +1115,9 @@  discard block
 block discarded – undo
1115 1115
  */
1116 1116
 function espresso_get_event_list_ID()
1117 1117
 {
1118
-    EED_Events_Archive::$espresso_event_list_ID++;
1119
-    EED_Events_Archive::$espresso_grid_event_lists[] = EED_Events_Archive::$espresso_event_list_ID;
1120
-    return EED_Events_Archive::$espresso_event_list_ID;
1118
+	EED_Events_Archive::$espresso_event_list_ID++;
1119
+	EED_Events_Archive::$espresso_grid_event_lists[] = EED_Events_Archive::$espresso_event_list_ID;
1120
+	return EED_Events_Archive::$espresso_event_list_ID;
1121 1121
 }
1122 1122
 
1123 1123
 /**
@@ -1125,7 +1125,7 @@  discard block
 block discarded – undo
1125 1125
  */
1126 1126
 function espresso_event_list_title()
1127 1127
 {
1128
-    return EED_Events_Archive::event_list_title();
1128
+	return EED_Events_Archive::event_list_title();
1129 1129
 }
1130 1130
 
1131 1131
 /**
@@ -1134,7 +1134,7 @@  discard block
 block discarded – undo
1134 1134
  */
1135 1135
 function espresso_event_list_css($extra_class = '')
1136 1136
 {
1137
-    return EED_Events_Archive::event_list_css($extra_class);
1137
+	return EED_Events_Archive::event_list_css($extra_class);
1138 1138
 }
1139 1139
 
1140 1140
 /**
@@ -1142,7 +1142,7 @@  discard block
 block discarded – undo
1142 1142
  */
1143 1143
 function espresso_get_event_categories()
1144 1144
 {
1145
-    return EED_Events_Archive::event_categories();
1145
+	return EED_Events_Archive::event_categories();
1146 1146
 }
1147 1147
 
1148 1148
 /**
@@ -1150,7 +1150,7 @@  discard block
 block discarded – undo
1150 1150
  */
1151 1151
 function espresso_display_full_description_in_event_list()
1152 1152
 {
1153
-    return EED_Events_Archive::display_description(2);
1153
+	return EED_Events_Archive::display_description(2);
1154 1154
 }
1155 1155
 
1156 1156
 /**
@@ -1158,7 +1158,7 @@  discard block
 block discarded – undo
1158 1158
  */
1159 1159
 function espresso_display_excerpt_in_event_list()
1160 1160
 {
1161
-    return EED_Events_Archive::display_description(1);
1161
+	return EED_Events_Archive::display_description(1);
1162 1162
 }
1163 1163
 
1164 1164
 /**
@@ -1166,7 +1166,7 @@  discard block
 block discarded – undo
1166 1166
  */
1167 1167
 function espresso_display_ticket_selector_in_event_list()
1168 1168
 {
1169
-    return EED_Events_Archive::display_ticket_selector();
1169
+	return EED_Events_Archive::display_ticket_selector();
1170 1170
 }
1171 1171
 
1172 1172
 /**
@@ -1174,7 +1174,7 @@  discard block
 block discarded – undo
1174 1174
  */
1175 1175
 function espresso_display_venue_in_event_list()
1176 1176
 {
1177
-    return EED_Events_Archive::display_venue();
1177
+	return EED_Events_Archive::display_venue();
1178 1178
 }
1179 1179
 
1180 1180
 /**
@@ -1182,5 +1182,5 @@  discard block
 block discarded – undo
1182 1182
  */
1183 1183
 function espresso_display_datetimes_in_event_list()
1184 1184
 {
1185
-    return EED_Events_Archive::display_datetimes();
1185
+	return EED_Events_Archive::display_datetimes();
1186 1186
 }
Please login to merge, or discard this patch.
core/EE_System.core.php 2 patches
Spacing   +27 added lines, -27 removed lines patch added patch discarded remove patch
@@ -141,7 +141,7 @@  discard block
 block discarded – undo
141 141
         EE_Maintenance_Mode $maintenance_mode = null
142 142
     ) {
143 143
         // check if class object is instantiated
144
-        if (! self::$_instance instanceof EE_System) {
144
+        if ( ! self::$_instance instanceof EE_System) {
145 145
             self::$_instance = new self($registry, $loader, $request, $maintenance_mode);
146 146
         }
147 147
         return self::$_instance;
@@ -263,7 +263,7 @@  discard block
 block discarded – undo
263 263
         $this->capabilities = $this->loader->getShared('EE_Capabilities');
264 264
         add_action(
265 265
             'AHEE__EE_Capabilities__init_caps__before_initialization',
266
-            function () {
266
+            function() {
267 267
                 LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
268 268
             }
269 269
         );
@@ -304,7 +304,7 @@  discard block
 block discarded – undo
304 304
     {
305 305
         // set autoloaders for all of the classes implementing EEI_Plugin_API
306 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');
307
+        EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES.'plugin_api');
308 308
     }
309 309
 
310 310
 
@@ -323,14 +323,14 @@  discard block
 block discarded – undo
323 323
         $load_callback,
324 324
         $plugin_file_constant
325 325
     ) {
326
-        if (! defined($version_constant)) {
326
+        if ( ! defined($version_constant)) {
327 327
             return;
328 328
         }
329 329
         $addon_version = constant($version_constant);
330 330
         if ($addon_version && version_compare($addon_version, $min_version_required, '<')) {
331 331
             remove_action('AHEE__EE_System__load_espresso_addons', $load_callback);
332
-            if (! function_exists('deactivate_plugins')) {
333
-                require_once ABSPATH . 'wp-admin/includes/plugin.php';
332
+            if ( ! function_exists('deactivate_plugins')) {
333
+                require_once ABSPATH.'wp-admin/includes/plugin.php';
334 334
             }
335 335
             deactivate_plugins(plugin_basename(constant($plugin_file_constant)));
336 336
             $this->request->unSetRequestParams(['activate', 'activate-multi'], true);
@@ -344,7 +344,7 @@  discard block
 block discarded – undo
344 344
                     $min_version_required
345 345
                 ),
346 346
                 __FILE__,
347
-                __FUNCTION__ . "({$addon_name})",
347
+                __FUNCTION__."({$addon_name})",
348 348
                 __LINE__
349 349
             );
350 350
             EE_Error::get_notices(false, true);
@@ -396,7 +396,7 @@  discard block
 block discarded – undo
396 396
                 true
397 397
             )
398 398
         ) {
399
-            include_once EE_THIRD_PARTY . 'wp-api-basic-auth/basic-auth.php';
399
+            include_once EE_THIRD_PARTY.'wp-api-basic-auth/basic-auth.php';
400 400
         }
401 401
         do_action('AHEE__EE_System__load_espresso_addons__complete');
402 402
     }
@@ -498,11 +498,11 @@  discard block
 block discarded – undo
498 498
     private function fix_espresso_db_upgrade_option($espresso_db_update = null)
499 499
     {
500 500
         do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
501
-        if (! $espresso_db_update) {
501
+        if ( ! $espresso_db_update) {
502 502
             $espresso_db_update = get_option('espresso_db_update');
503 503
         }
504 504
         // check that option is an array
505
-        if (! is_array($espresso_db_update)) {
505
+        if ( ! is_array($espresso_db_update)) {
506 506
             // if option is FALSE, then it never existed
507 507
             if ($espresso_db_update === false) {
508 508
                 // make $espresso_db_update an array and save option with autoload OFF
@@ -522,10 +522,10 @@  discard block
 block discarded – undo
522 522
                     // so it must be numerically-indexed, where values are versions installed...
523 523
                     // fix it!
524 524
                     $version_string = $should_be_array;
525
-                    $corrected_db_update[ $version_string ] = array('unknown-date');
525
+                    $corrected_db_update[$version_string] = array('unknown-date');
526 526
                 } else {
527 527
                     // ok it checks out
528
-                    $corrected_db_update[ $should_be_version_string ] = $should_be_array;
528
+                    $corrected_db_update[$should_be_version_string] = $should_be_array;
529 529
                 }
530 530
             }
531 531
             $espresso_db_update = $corrected_db_update;
@@ -609,13 +609,13 @@  discard block
 block discarded – undo
609 609
      */
610 610
     public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
611 611
     {
612
-        if (! $version_history) {
612
+        if ( ! $version_history) {
613 613
             $version_history = $this->fix_espresso_db_upgrade_option($version_history);
614 614
         }
615 615
         if ($current_version_to_add === null) {
616 616
             $current_version_to_add = espresso_version();
617 617
         }
618
-        $version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
618
+        $version_history[$current_version_to_add][] = date('Y-m-d H:i:s', time());
619 619
         // re-save
620 620
         return update_option('espresso_db_update', $version_history);
621 621
     }
@@ -705,7 +705,7 @@  discard block
 block discarded – undo
705 705
         if ($activation_history_for_addon) {
706 706
             // it exists, so this isn't a completely new install
707 707
             // check if this version already in that list of previously installed versions
708
-            if (! isset($activation_history_for_addon[ $version_to_upgrade_to ])) {
708
+            if ( ! isset($activation_history_for_addon[$version_to_upgrade_to])) {
709 709
                 // it a version we haven't seen before
710 710
                 if ($version_is_higher === 1) {
711 711
                     $req_type = EE_System::req_type_upgrade;
@@ -783,7 +783,7 @@  discard block
 block discarded – undo
783 783
             foreach ($activation_history as $version => $times_activated) {
784 784
                 // check there is a record of when this version was activated. Otherwise,
785 785
                 // mark it as unknown
786
-                if (! $times_activated) {
786
+                if ( ! $times_activated) {
787 787
                     $times_activated = array('unknown-date');
788 788
                 }
789 789
                 if (is_string($times_activated)) {
@@ -887,7 +887,7 @@  discard block
 block discarded – undo
887 887
     private function _parse_model_names()
888 888
     {
889 889
         // get all the files in the EE_MODELS folder that end in .model.php
890
-        $models = glob(EE_MODELS . '*.model.php');
890
+        $models = glob(EE_MODELS.'*.model.php');
891 891
         $model_names = array();
892 892
         $non_abstract_db_models = array();
893 893
         foreach ($models as $model) {
@@ -896,9 +896,9 @@  discard block
 block discarded – undo
896 896
             $short_name = str_replace('EEM_', '', $classname);
897 897
             $reflectionClass = new ReflectionClass($classname);
898 898
             if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
899
-                $non_abstract_db_models[ $short_name ] = $classname;
899
+                $non_abstract_db_models[$short_name] = $classname;
900 900
             }
901
-            $model_names[ $short_name ] = $classname;
901
+            $model_names[$short_name] = $classname;
902 902
         }
903 903
         $this->registry->models = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
904 904
         $this->registry->non_abstract_db_models = apply_filters(
@@ -933,7 +933,7 @@  discard block
 block discarded – undo
933 933
             )
934 934
         );
935 935
         if ($domain->isCaffeinated()) {
936
-            require_once EE_CAFF_PATH . 'brewing_regular.php';
936
+            require_once EE_CAFF_PATH.'brewing_regular.php';
937 937
         }
938 938
     }
939 939
 
@@ -991,7 +991,7 @@  discard block
 block discarded – undo
991 991
         $class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook(
992 992
             'AHEE__EE_System__register_shortcodes_modules_and_addons'
993 993
         );
994
-        if (! empty($class_names)) {
994
+        if ( ! empty($class_names)) {
995 995
             $msg = esc_html__(
996 996
                 'The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
997 997
                 'event_espresso'
@@ -1003,7 +1003,7 @@  discard block
 block discarded – undo
1003 1003
                             array('EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'),
1004 1004
                             '',
1005 1005
                             $class_name
1006
-                        ) . '</b></li>';
1006
+                        ).'</b></li>';
1007 1007
             }
1008 1008
             $msg .= '</ul>';
1009 1009
             $msg .= esc_html__(
@@ -1072,7 +1072,7 @@  discard block
 block discarded – undo
1072 1072
     private function _deactivate_incompatible_addons()
1073 1073
     {
1074 1074
         $incompatible_addons = get_option('ee_incompatible_addons', array());
1075
-        if (! empty($incompatible_addons)) {
1075
+        if ( ! empty($incompatible_addons)) {
1076 1076
             $active_plugins = get_option('active_plugins', array());
1077 1077
             foreach ($active_plugins as $active_plugin) {
1078 1078
                 foreach ($incompatible_addons as $incompatible_addon) {
@@ -1197,7 +1197,7 @@  discard block
 block discarded – undo
1197 1197
         do_action('AHEE__EE_System__core_loaded_and_ready');
1198 1198
         // always load template tags, because it's faster than checking if it's a front-end request, and many page
1199 1199
         // builders require these even on the front-end
1200
-        require_once EE_PUBLIC . 'template_tags.php';
1200
+        require_once EE_PUBLIC.'template_tags.php';
1201 1201
         do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1202 1202
     }
1203 1203
 
@@ -1265,13 +1265,13 @@  discard block
 block discarded – undo
1265 1265
     public static function do_not_cache()
1266 1266
     {
1267 1267
         // set no cache constants
1268
-        if (! defined('DONOTCACHEPAGE')) {
1268
+        if ( ! defined('DONOTCACHEPAGE')) {
1269 1269
             define('DONOTCACHEPAGE', true);
1270 1270
         }
1271
-        if (! defined('DONOTCACHCEOBJECT')) {
1271
+        if ( ! defined('DONOTCACHCEOBJECT')) {
1272 1272
             define('DONOTCACHCEOBJECT', true);
1273 1273
         }
1274
-        if (! defined('DONOTCACHEDB')) {
1274
+        if ( ! defined('DONOTCACHEDB')) {
1275 1275
             define('DONOTCACHEDB', true);
1276 1276
         }
1277 1277
         // add no cache headers
Please login to merge, or discard this patch.
Indentation   +1337 added lines, -1337 removed lines patch added patch discarded remove patch
@@ -27,1341 +27,1341 @@
 block discarded – undo
27 27
 final class EE_System implements ResettableInterface
28 28
 {
29 29
 
30
-    /**
31
-     * indicates this is a 'normal' request. Ie, not activation, nor upgrade, nor activation.
32
-     * So examples of this would be a normal GET request on the frontend or backend, or a POST, etc
33
-     */
34
-    const req_type_normal = 0;
35
-
36
-    /**
37
-     * Indicates this is a brand new installation of EE so we should install
38
-     * tables and default data etc
39
-     */
40
-    const req_type_new_activation = 1;
41
-
42
-    /**
43
-     * we've detected that EE has been reactivated (or EE was activated during maintenance mode,
44
-     * and we just exited maintenance mode). We MUST check the database is setup properly
45
-     * and that default data is setup too
46
-     */
47
-    const req_type_reactivation = 2;
48
-
49
-    /**
50
-     * indicates that EE has been upgraded since its previous request.
51
-     * We may have data migration scripts to call and will want to trigger maintenance mode
52
-     */
53
-    const req_type_upgrade = 3;
54
-
55
-    /**
56
-     * TODO  will detect that EE has been DOWNGRADED. We probably don't want to run in this case...
57
-     */
58
-    const req_type_downgrade = 4;
59
-
60
-    /**
61
-     * @deprecated since version 4.6.0.dev.006
62
-     * Now whenever a new_activation is detected the request type is still just
63
-     * new_activation (same for reactivation, upgrade, downgrade etc), but if we'r ein maintenance mode
64
-     * EE_System::initialize_db_if_no_migrations_required and EE_Addon::initialize_db_if_no_migrations_required
65
-     * will instead enqueue that EE plugin's db initialization for when we're taken out of maintenance mode.
66
-     * (Specifically, when the migration manager indicates migrations are finished
67
-     * EE_Data_Migration_Manager::initialize_db_for_enqueued_ee_plugins() will be called)
68
-     */
69
-    const req_type_activation_but_not_installed = 5;
70
-
71
-    /**
72
-     * option prefix for recording the activation history (like core's "espresso_db_update") of addons
73
-     */
74
-    const addon_activation_history_option_prefix = 'ee_addon_activation_history_';
75
-
76
-    /**
77
-     * @var EE_System $_instance
78
-     */
79
-    private static $_instance;
80
-
81
-    /**
82
-     * @var EE_Registry $registry
83
-     */
84
-    private $registry;
85
-
86
-    /**
87
-     * @var LoaderInterface $loader
88
-     */
89
-    private $loader;
90
-
91
-    /**
92
-     * @var EE_Capabilities $capabilities
93
-     */
94
-    private $capabilities;
95
-
96
-    /**
97
-     * @var RequestInterface $request
98
-     */
99
-    private $request;
100
-
101
-    /**
102
-     * @var EE_Maintenance_Mode $maintenance_mode
103
-     */
104
-    private $maintenance_mode;
105
-
106
-    /**
107
-     * Stores which type of request this is, options being one of the constants on EE_System starting with req_type_*.
108
-     * It can be a brand-new activation, a reactivation, an upgrade, a downgrade, or a normal request.
109
-     *
110
-     * @var int $_req_type
111
-     */
112
-    private $_req_type;
113
-
114
-    /**
115
-     * Whether or not there was a non-micro version change in EE core version during this request
116
-     *
117
-     * @var boolean $_major_version_change
118
-     */
119
-    private $_major_version_change = false;
120
-
121
-    /**
122
-     * A Context DTO dedicated solely to identifying the current request type.
123
-     *
124
-     * @var RequestTypeContextCheckerInterface $request_type
125
-     */
126
-    private $request_type;
127
-
128
-    /**
129
-     * @param EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes
130
-     */
131
-    private $register_custom_post_types;
132
-
133
-    /**
134
-     * @param EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies
135
-     */
136
-    private $register_custom_taxonomies;
137
-
138
-    /**
139
-     * @param EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms
140
-     */
141
-    private $register_custom_taxonomy_terms;
142
-
143
-    /**
144
-     * @singleton method used to instantiate class object
145
-     * @param EE_Registry|null         $registry
146
-     * @param LoaderInterface|null     $loader
147
-     * @param RequestInterface|null    $request
148
-     * @param EE_Maintenance_Mode|null $maintenance_mode
149
-     * @return EE_System
150
-     */
151
-    public static function instance(
152
-        EE_Registry $registry = null,
153
-        LoaderInterface $loader = null,
154
-        RequestInterface $request = null,
155
-        EE_Maintenance_Mode $maintenance_mode = null
156
-    ) {
157
-        // check if class object is instantiated
158
-        if (! self::$_instance instanceof EE_System) {
159
-            self::$_instance = new self($registry, $loader, $request, $maintenance_mode);
160
-        }
161
-        return self::$_instance;
162
-    }
163
-
164
-
165
-    /**
166
-     * resets the instance and returns it
167
-     *
168
-     * @return EE_System
169
-     */
170
-    public static function reset()
171
-    {
172
-        self::$_instance->_req_type = null;
173
-        // make sure none of the old hooks are left hanging around
174
-        remove_all_actions('AHEE__EE_System__perform_activations_upgrades_and_migrations');
175
-        // we need to reset the migration manager in order for it to detect DMSs properly
176
-        EE_Data_Migration_Manager::reset();
177
-        self::instance()->detect_activations_or_upgrades();
178
-        self::instance()->perform_activations_upgrades_and_migrations();
179
-        return self::instance();
180
-    }
181
-
182
-
183
-    /**
184
-     * sets hooks for running rest of system
185
-     * provides "AHEE__EE_System__construct__complete" hook for EE Addons to use as their starting point
186
-     * starting EE Addons from any other point may lead to problems
187
-     *
188
-     * @param EE_Registry         $registry
189
-     * @param LoaderInterface     $loader
190
-     * @param RequestInterface    $request
191
-     * @param EE_Maintenance_Mode $maintenance_mode
192
-     */
193
-    private function __construct(
194
-        EE_Registry $registry,
195
-        LoaderInterface $loader,
196
-        RequestInterface $request,
197
-        EE_Maintenance_Mode $maintenance_mode
198
-    ) {
199
-        $this->registry = $registry;
200
-        $this->loader = $loader;
201
-        $this->request = $request;
202
-        $this->maintenance_mode = $maintenance_mode;
203
-        do_action('AHEE__EE_System__construct__begin', $this);
204
-        add_action(
205
-            'AHEE__EE_Bootstrap__load_espresso_addons',
206
-            array($this, 'loadCapabilities'),
207
-            5
208
-        );
209
-        add_action(
210
-            'AHEE__EE_Bootstrap__load_espresso_addons',
211
-            array($this, 'loadCommandBus'),
212
-            7
213
-        );
214
-        add_action(
215
-            'AHEE__EE_Bootstrap__load_espresso_addons',
216
-            array($this, 'loadPluginApi'),
217
-            9
218
-        );
219
-        // allow addons to load first so that they can register autoloaders, set hooks for running DMS's, etc
220
-        add_action(
221
-            'AHEE__EE_Bootstrap__load_espresso_addons',
222
-            array($this, 'load_espresso_addons')
223
-        );
224
-        // when an ee addon is activated, we want to call the core hook(s) again
225
-        // because the newly-activated addon didn't get a chance to run at all
226
-        add_action('activate_plugin', array($this, 'load_espresso_addons'), 1);
227
-        // detect whether install or upgrade
228
-        add_action(
229
-            'AHEE__EE_Bootstrap__detect_activations_or_upgrades',
230
-            array($this, 'detect_activations_or_upgrades'),
231
-            3
232
-        );
233
-        // load EE_Config, EE_Textdomain, etc
234
-        add_action(
235
-            'AHEE__EE_Bootstrap__load_core_configuration',
236
-            array($this, 'load_core_configuration'),
237
-            5
238
-        );
239
-        // load specifications for matching routes to current request
240
-        add_action(
241
-            'AHEE__EE_Bootstrap__load_core_configuration',
242
-            array($this, 'loadRouteMatchSpecifications')
243
-        );
244
-        // load specifications for custom post types
245
-        add_action(
246
-            'AHEE__EE_Bootstrap__load_core_configuration',
247
-            array($this, 'loadCustomPostTypes')
248
-        );
249
-        // load EE_Config, EE_Textdomain, etc
250
-        add_action(
251
-            'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets',
252
-            array($this, 'register_shortcodes_modules_and_widgets'),
253
-            7
254
-        );
255
-        // you wanna get going? I wanna get going... let's get going!
256
-        add_action(
257
-            'AHEE__EE_Bootstrap__brew_espresso',
258
-            array($this, 'brew_espresso'),
259
-            9
260
-        );
261
-        // other housekeeping
262
-        // exclude EE critical pages from wp_list_pages
263
-        add_filter(
264
-            'wp_list_pages_excludes',
265
-            array($this, 'remove_pages_from_wp_list_pages'),
266
-            10
267
-        );
268
-        // ALL EE Addons should use the following hook point to attach their initial setup too
269
-        // it's extremely important for EE Addons to register any class autoloaders so that they can be available when the EE_Config loads
270
-        do_action('AHEE__EE_System__construct__complete', $this);
271
-    }
272
-
273
-
274
-    /**
275
-     * load and setup EE_Capabilities
276
-     *
277
-     * @return void
278
-     * @throws EE_Error
279
-     */
280
-    public function loadCapabilities()
281
-    {
282
-        $this->capabilities = $this->loader->getShared('EE_Capabilities');
283
-        add_action(
284
-            'AHEE__EE_Capabilities__init_caps__before_initialization',
285
-            function () {
286
-                LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
287
-            }
288
-        );
289
-    }
290
-
291
-
292
-    /**
293
-     * create and cache the CommandBus, and also add middleware
294
-     * The CapChecker middleware requires the use of EE_Capabilities
295
-     * which is why we need to load the CommandBus after Caps are set up
296
-     *
297
-     * @return void
298
-     * @throws EE_Error
299
-     */
300
-    public function loadCommandBus()
301
-    {
302
-        $this->loader->getShared(
303
-            'CommandBusInterface',
304
-            array(
305
-                null,
306
-                apply_filters(
307
-                    'FHEE__EE_Load_Espresso_Core__handle_request__CommandBus_middleware',
308
-                    array(
309
-                        $this->loader->getShared('EventEspresso\core\services\commands\middleware\CapChecker'),
310
-                        $this->loader->getShared('EventEspresso\core\services\commands\middleware\AddActionHook'),
311
-                    )
312
-                ),
313
-            )
314
-        );
315
-    }
316
-
317
-
318
-    /**
319
-     * @return void
320
-     * @throws EE_Error
321
-     */
322
-    public function loadPluginApi()
323
-    {
324
-        // set autoloaders for all of the classes implementing EEI_Plugin_API
325
-        // which provide helpers for EE plugin authors to more easily register certain components with EE.
326
-        EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'plugin_api');
327
-    }
328
-
329
-
330
-    /**
331
-     * @param string $addon_name
332
-     * @param string $version_constant
333
-     * @param string $min_version_required
334
-     * @param string $load_callback
335
-     * @param string $plugin_file_constant
336
-     * @return void
337
-     */
338
-    private function deactivateIncompatibleAddon(
339
-        $addon_name,
340
-        $version_constant,
341
-        $min_version_required,
342
-        $load_callback,
343
-        $plugin_file_constant
344
-    ) {
345
-        if (! defined($version_constant)) {
346
-            return;
347
-        }
348
-        $addon_version = constant($version_constant);
349
-        if ($addon_version && version_compare($addon_version, $min_version_required, '<')) {
350
-            remove_action('AHEE__EE_System__load_espresso_addons', $load_callback);
351
-            if (! function_exists('deactivate_plugins')) {
352
-                require_once ABSPATH . 'wp-admin/includes/plugin.php';
353
-            }
354
-            deactivate_plugins(plugin_basename(constant($plugin_file_constant)));
355
-            $this->request->unSetRequestParams(['activate', 'activate-multi'], true);
356
-            EE_Error::add_error(
357
-                sprintf(
358
-                    esc_html__(
359
-                        'We\'re sorry, but the Event Espresso %1$s addon was deactivated because version %2$s or higher is required with this version of Event Espresso core.',
360
-                        'event_espresso'
361
-                    ),
362
-                    $addon_name,
363
-                    $min_version_required
364
-                ),
365
-                __FILE__,
366
-                __FUNCTION__ . "({$addon_name})",
367
-                __LINE__
368
-            );
369
-            EE_Error::get_notices(false, true);
370
-        }
371
-    }
372
-
373
-
374
-    /**
375
-     * load_espresso_addons
376
-     * allow addons to load first so that they can set hooks for running DMS's, etc
377
-     * this is hooked into both:
378
-     *    'AHEE__EE_Bootstrap__load_core_configuration'
379
-     *        which runs during the WP 'plugins_loaded' action at priority 5
380
-     *    and the WP 'activate_plugin' hook point
381
-     *
382
-     * @access public
383
-     * @return void
384
-     */
385
-    public function load_espresso_addons()
386
-    {
387
-        $this->deactivateIncompatibleAddon(
388
-            'Wait Lists',
389
-            'EE_WAIT_LISTS_VERSION',
390
-            '1.0.0.beta.074',
391
-            'load_espresso_wait_lists',
392
-            'EE_WAIT_LISTS_PLUGIN_FILE'
393
-        );
394
-        $this->deactivateIncompatibleAddon(
395
-            'Automated Upcoming Event Notifications',
396
-            'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_VERSION',
397
-            '1.0.0.beta.091',
398
-            'load_espresso_automated_upcoming_event_notification',
399
-            'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_PLUGIN_FILE'
400
-        );
401
-        do_action('AHEE__EE_System__load_espresso_addons');
402
-        // if the WP API basic auth plugin isn't already loaded, load it now.
403
-        // We want it for mobile apps. Just include the entire plugin
404
-        // also, don't load the basic auth when a plugin is getting activated, because
405
-        // it could be the basic auth plugin, and it doesn't check if its methods are already defined
406
-        // and causes a fatal error
407
-        if (
408
-            ($this->request->isWordPressApi() || $this->request->isApi())
409
-            && $this->request->getRequestParam('activate') !== 'true'
410
-            && ! function_exists('json_basic_auth_handler')
411
-            && ! function_exists('json_basic_auth_error')
412
-            && ! in_array(
413
-                $this->request->getRequestParam('action'),
414
-                array('activate', 'activate-selected'),
415
-                true
416
-            )
417
-        ) {
418
-            include_once EE_THIRD_PARTY . 'wp-api-basic-auth/basic-auth.php';
419
-        }
420
-        do_action('AHEE__EE_System__load_espresso_addons__complete');
421
-    }
422
-
423
-
424
-    /**
425
-     * detect_activations_or_upgrades
426
-     * Checks for activation or upgrade of core first;
427
-     * then also checks if any registered addons have been activated or upgraded
428
-     * This is hooked into 'AHEE__EE_Bootstrap__detect_activations_or_upgrades'
429
-     * which runs during the WP 'plugins_loaded' action at priority 3
430
-     *
431
-     * @access public
432
-     * @return void
433
-     */
434
-    public function detect_activations_or_upgrades()
435
-    {
436
-        // first off: let's make sure to handle core
437
-        $this->detect_if_activation_or_upgrade();
438
-        foreach ($this->registry->addons as $addon) {
439
-            if ($addon instanceof EE_Addon) {
440
-                // detect teh request type for that addon
441
-                $addon->detect_req_type();
442
-            }
443
-        }
444
-    }
445
-
446
-
447
-    /**
448
-     * detect_if_activation_or_upgrade
449
-     * Takes care of detecting whether this is a brand new install or code upgrade,
450
-     * and either setting up the DB or setting up maintenance mode etc.
451
-     *
452
-     * @access public
453
-     * @return void
454
-     */
455
-    public function detect_if_activation_or_upgrade()
456
-    {
457
-        do_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin');
458
-        // check if db has been updated, or if its a brand-new installation
459
-        $espresso_db_update = $this->fix_espresso_db_upgrade_option();
460
-        $request_type = $this->detect_req_type($espresso_db_update);
461
-        // EEH_Debug_Tools::printr( $request_type, '$request_type', __FILE__, __LINE__ );
462
-        switch ($request_type) {
463
-            case EE_System::req_type_new_activation:
464
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__new_activation');
465
-                $this->_handle_core_version_change($espresso_db_update);
466
-                break;
467
-            case EE_System::req_type_reactivation:
468
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__reactivation');
469
-                $this->_handle_core_version_change($espresso_db_update);
470
-                break;
471
-            case EE_System::req_type_upgrade:
472
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__upgrade');
473
-                // migrations may be required now that we've upgraded
474
-                $this->maintenance_mode->set_maintenance_mode_if_db_old();
475
-                $this->_handle_core_version_change($espresso_db_update);
476
-                break;
477
-            case EE_System::req_type_downgrade:
478
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__downgrade');
479
-                // its possible migrations are no longer required
480
-                $this->maintenance_mode->set_maintenance_mode_if_db_old();
481
-                $this->_handle_core_version_change($espresso_db_update);
482
-                break;
483
-            case EE_System::req_type_normal:
484
-            default:
485
-                break;
486
-        }
487
-        do_action('AHEE__EE_System__detect_if_activation_or_upgrade__complete');
488
-    }
489
-
490
-
491
-    /**
492
-     * Updates the list of installed versions and sets hooks for
493
-     * initializing the database later during the request
494
-     *
495
-     * @param array $espresso_db_update
496
-     */
497
-    private function _handle_core_version_change($espresso_db_update)
498
-    {
499
-        $this->update_list_of_installed_versions($espresso_db_update);
500
-        // get ready to verify the DB is ok (provided we aren't in maintenance mode, of course)
501
-        add_action(
502
-            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
503
-            array($this, 'initialize_db_if_no_migrations_required')
504
-        );
505
-    }
506
-
507
-
508
-    /**
509
-     * standardizes the wp option 'espresso_db_upgrade' which actually stores
510
-     * information about what versions of EE have been installed and activated,
511
-     * NOT necessarily the state of the database
512
-     *
513
-     * @param mixed $espresso_db_update           the value of the WordPress option.
514
-     *                                            If not supplied, fetches it from the options table
515
-     * @return array the correct value of 'espresso_db_upgrade', after saving it, if it needed correction
516
-     */
517
-    private function fix_espresso_db_upgrade_option($espresso_db_update = null)
518
-    {
519
-        do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
520
-        if (! $espresso_db_update) {
521
-            $espresso_db_update = get_option('espresso_db_update');
522
-        }
523
-        // check that option is an array
524
-        if (! is_array($espresso_db_update)) {
525
-            // if option is FALSE, then it never existed
526
-            if ($espresso_db_update === false) {
527
-                // make $espresso_db_update an array and save option with autoload OFF
528
-                $espresso_db_update = array();
529
-                add_option('espresso_db_update', $espresso_db_update, '', 'no');
530
-            } else {
531
-                // option is NOT FALSE but also is NOT an array, so make it an array and save it
532
-                $espresso_db_update = array($espresso_db_update => array());
533
-                update_option('espresso_db_update', $espresso_db_update);
534
-            }
535
-        } else {
536
-            $corrected_db_update = array();
537
-            // if IS an array, but is it an array where KEYS are version numbers, and values are arrays?
538
-            foreach ($espresso_db_update as $should_be_version_string => $should_be_array) {
539
-                if (is_int($should_be_version_string) && ! is_array($should_be_array)) {
540
-                    // the key is an int, and the value IS NOT an array
541
-                    // so it must be numerically-indexed, where values are versions installed...
542
-                    // fix it!
543
-                    $version_string = $should_be_array;
544
-                    $corrected_db_update[ $version_string ] = array('unknown-date');
545
-                } else {
546
-                    // ok it checks out
547
-                    $corrected_db_update[ $should_be_version_string ] = $should_be_array;
548
-                }
549
-            }
550
-            $espresso_db_update = $corrected_db_update;
551
-            update_option('espresso_db_update', $espresso_db_update);
552
-        }
553
-        do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__complete', $espresso_db_update);
554
-        return $espresso_db_update;
555
-    }
556
-
557
-
558
-    /**
559
-     * Does the traditional work of setting up the plugin's database and adding default data.
560
-     * If migration script/process did not exist, this is what would happen on every activation/reactivation/upgrade.
561
-     * NOTE: if we're in maintenance mode (which would be the case if we detect there are data
562
-     * migration scripts that need to be run and a version change happens), enqueues core for database initialization,
563
-     * so that it will be done when migrations are finished
564
-     *
565
-     * @param boolean $initialize_addons_too if true, we double-check addons' database tables etc too;
566
-     * @param boolean $verify_schema         if true will re-check the database tables have the correct schema.
567
-     *                                       This is a resource-intensive job
568
-     *                                       so we prefer to only do it when necessary
569
-     * @return void
570
-     * @throws EE_Error
571
-     */
572
-    public function initialize_db_if_no_migrations_required($initialize_addons_too = false, $verify_schema = true)
573
-    {
574
-        $request_type = $this->detect_req_type();
575
-        // only initialize system if we're not in maintenance mode.
576
-        if ($this->maintenance_mode->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
577
-            /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
578
-            $rewrite_rules = $this->loader->getShared(
579
-                'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
580
-            );
581
-            $rewrite_rules->flush();
582
-            if ($verify_schema) {
583
-                EEH_Activation::initialize_db_and_folders();
584
-            }
585
-            EEH_Activation::initialize_db_content();
586
-            EEH_Activation::system_initialization();
587
-            if ($initialize_addons_too) {
588
-                $this->initialize_addons();
589
-            }
590
-        } else {
591
-            EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for('Core');
592
-        }
593
-        if (
594
-            $request_type === EE_System::req_type_new_activation
595
-            || $request_type === EE_System::req_type_reactivation
596
-            || (
597
-                $request_type === EE_System::req_type_upgrade
598
-                && $this->is_major_version_change()
599
-            )
600
-        ) {
601
-            add_action('AHEE__EE_System__initialize_last', array($this, 'redirect_to_about_ee'), 9);
602
-        }
603
-    }
604
-
605
-
606
-    /**
607
-     * Initializes the db for all registered addons
608
-     *
609
-     * @throws EE_Error
610
-     */
611
-    public function initialize_addons()
612
-    {
613
-        // foreach registered addon, make sure its db is up-to-date too
614
-        foreach ($this->registry->addons as $addon) {
615
-            if ($addon instanceof EE_Addon) {
616
-                $addon->initialize_db_if_no_migrations_required();
617
-            }
618
-        }
619
-    }
620
-
621
-
622
-    /**
623
-     * Adds the current code version to the saved wp option which stores a list of all ee versions ever installed.
624
-     *
625
-     * @param    array  $version_history
626
-     * @param    string $current_version_to_add version to be added to the version history
627
-     * @return    boolean success as to whether or not this option was changed
628
-     */
629
-    public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
630
-    {
631
-        if (! $version_history) {
632
-            $version_history = $this->fix_espresso_db_upgrade_option($version_history);
633
-        }
634
-        if ($current_version_to_add === null) {
635
-            $current_version_to_add = espresso_version();
636
-        }
637
-        $version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
638
-        // re-save
639
-        return update_option('espresso_db_update', $version_history);
640
-    }
641
-
642
-
643
-    /**
644
-     * Detects if the current version indicated in the has existed in the list of
645
-     * previously-installed versions of EE (espresso_db_update). Does NOT modify it (ie, no side-effect)
646
-     *
647
-     * @param array $espresso_db_update array from the wp option stored under the name 'espresso_db_update'.
648
-     *                                  If not supplied, fetches it from the options table.
649
-     *                                  Also, caches its result so later parts of the code can also know whether
650
-     *                                  there's been an update or not. This way we can add the current version to
651
-     *                                  espresso_db_update, but still know if this is a new install or not
652
-     * @return int one of the constants on EE_System::req_type_
653
-     */
654
-    public function detect_req_type($espresso_db_update = null)
655
-    {
656
-        if ($this->_req_type === null) {
657
-            $espresso_db_update = ! empty($espresso_db_update)
658
-                ? $espresso_db_update
659
-                : $this->fix_espresso_db_upgrade_option();
660
-            $this->_req_type = EE_System::detect_req_type_given_activation_history(
661
-                $espresso_db_update,
662
-                'ee_espresso_activation',
663
-                espresso_version()
664
-            );
665
-            $this->_major_version_change = $this->_detect_major_version_change($espresso_db_update);
666
-            $this->request->setIsActivation($this->_req_type !== EE_System::req_type_normal);
667
-        }
668
-        return $this->_req_type;
669
-    }
670
-
671
-
672
-    /**
673
-     * Returns whether or not there was a non-micro version change (ie, change in either
674
-     * the first or second number in the version. Eg 4.9.0.rc.001 to 4.10.0.rc.000,
675
-     * but not 4.9.0.rc.0001 to 4.9.1.rc.0001
676
-     *
677
-     * @param $activation_history
678
-     * @return bool
679
-     */
680
-    private function _detect_major_version_change($activation_history)
681
-    {
682
-        $previous_version = EE_System::_get_most_recently_active_version_from_activation_history($activation_history);
683
-        $previous_version_parts = explode('.', $previous_version);
684
-        $current_version_parts = explode('.', espresso_version());
685
-        return isset($previous_version_parts[0], $previous_version_parts[1], $current_version_parts[0], $current_version_parts[1])
686
-               && ($previous_version_parts[0] !== $current_version_parts[0]
687
-                   || $previous_version_parts[1] !== $current_version_parts[1]
688
-               );
689
-    }
690
-
691
-
692
-    /**
693
-     * Returns true if either the major or minor version of EE changed during this request.
694
-     * Eg 4.9.0.rc.001 to 4.10.0.rc.000, but not 4.9.0.rc.0001 to 4.9.1.rc.0001
695
-     *
696
-     * @return bool
697
-     */
698
-    public function is_major_version_change()
699
-    {
700
-        return $this->_major_version_change;
701
-    }
702
-
703
-
704
-    /**
705
-     * Determines the request type for any ee addon, given three piece of info: the current array of activation
706
-     * histories (for core that' 'espresso_db_update' wp option); the name of the WordPress option which is temporarily
707
-     * set upon activation of the plugin (for core it's 'ee_espresso_activation'); and the version that this plugin was
708
-     * just activated to (for core that will always be espresso_version())
709
-     *
710
-     * @param array  $activation_history_for_addon     the option's value which stores the activation history for this
711
-     *                                                 ee plugin. for core that's 'espresso_db_update'
712
-     * @param string $activation_indicator_option_name the name of the WordPress option that is temporarily set to
713
-     *                                                 indicate that this plugin was just activated
714
-     * @param string $version_to_upgrade_to            the version that was just upgraded to (for core that will be
715
-     *                                                 espresso_version())
716
-     * @return int one of the constants on EE_System::req_type_*
717
-     */
718
-    public static function detect_req_type_given_activation_history(
719
-        $activation_history_for_addon,
720
-        $activation_indicator_option_name,
721
-        $version_to_upgrade_to
722
-    ) {
723
-        $version_is_higher = self::_new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to);
724
-        if ($activation_history_for_addon) {
725
-            // it exists, so this isn't a completely new install
726
-            // check if this version already in that list of previously installed versions
727
-            if (! isset($activation_history_for_addon[ $version_to_upgrade_to ])) {
728
-                // it a version we haven't seen before
729
-                if ($version_is_higher === 1) {
730
-                    $req_type = EE_System::req_type_upgrade;
731
-                } else {
732
-                    $req_type = EE_System::req_type_downgrade;
733
-                }
734
-                delete_option($activation_indicator_option_name);
735
-            } else {
736
-                // its not an update. maybe a reactivation?
737
-                if (get_option($activation_indicator_option_name, false)) {
738
-                    if ($version_is_higher === -1) {
739
-                        $req_type = EE_System::req_type_downgrade;
740
-                    } elseif ($version_is_higher === 0) {
741
-                        // we've seen this version before, but it's an activation. must be a reactivation
742
-                        $req_type = EE_System::req_type_reactivation;
743
-                    } else {// $version_is_higher === 1
744
-                        $req_type = EE_System::req_type_upgrade;
745
-                    }
746
-                    delete_option($activation_indicator_option_name);
747
-                } else {
748
-                    // we've seen this version before and the activation indicate doesn't show it was just activated
749
-                    if ($version_is_higher === -1) {
750
-                        $req_type = EE_System::req_type_downgrade;
751
-                    } elseif ($version_is_higher === 0) {
752
-                        // we've seen this version before and it's not an activation. its normal request
753
-                        $req_type = EE_System::req_type_normal;
754
-                    } else {// $version_is_higher === 1
755
-                        $req_type = EE_System::req_type_upgrade;
756
-                    }
757
-                }
758
-            }
759
-        } else {
760
-            // brand new install
761
-            $req_type = EE_System::req_type_new_activation;
762
-            delete_option($activation_indicator_option_name);
763
-        }
764
-        return $req_type;
765
-    }
766
-
767
-
768
-    /**
769
-     * Detects if the $version_to_upgrade_to is higher than the most recent version in
770
-     * the $activation_history_for_addon
771
-     *
772
-     * @param array  $activation_history_for_addon (keys are versions, values are arrays of times activated,
773
-     *                                             sometimes containing 'unknown-date'
774
-     * @param string $version_to_upgrade_to        (current version)
775
-     * @return int results of version_compare( $version_to_upgrade_to, $most_recently_active_version ).
776
-     *                                             ie, -1 if $version_to_upgrade_to is LOWER (downgrade);
777
-     *                                             0 if $version_to_upgrade_to MATCHES (reactivation or normal request);
778
-     *                                             1 if $version_to_upgrade_to is HIGHER (upgrade) ;
779
-     */
780
-    private static function _new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to)
781
-    {
782
-        // find the most recently-activated version
783
-        $most_recently_active_version =
784
-            EE_System::_get_most_recently_active_version_from_activation_history($activation_history_for_addon);
785
-        return version_compare($version_to_upgrade_to, $most_recently_active_version);
786
-    }
787
-
788
-
789
-    /**
790
-     * Gets the most recently active version listed in the activation history,
791
-     * and if none are found (ie, it's a brand new install) returns '0.0.0.dev.000'.
792
-     *
793
-     * @param array $activation_history  (keys are versions, values are arrays of times activated,
794
-     *                                   sometimes containing 'unknown-date'
795
-     * @return string
796
-     */
797
-    private static function _get_most_recently_active_version_from_activation_history($activation_history)
798
-    {
799
-        $most_recently_active_version_activation = '1970-01-01 00:00:00';
800
-        $most_recently_active_version = '0.0.0.dev.000';
801
-        if (is_array($activation_history)) {
802
-            foreach ($activation_history as $version => $times_activated) {
803
-                // check there is a record of when this version was activated. Otherwise,
804
-                // mark it as unknown
805
-                if (! $times_activated) {
806
-                    $times_activated = array('unknown-date');
807
-                }
808
-                if (is_string($times_activated)) {
809
-                    $times_activated = array($times_activated);
810
-                }
811
-                foreach ($times_activated as $an_activation) {
812
-                    if (
813
-                        $an_activation !== 'unknown-date'
814
-                        && $an_activation
815
-                           > $most_recently_active_version_activation
816
-                    ) {
817
-                        $most_recently_active_version = $version;
818
-                        $most_recently_active_version_activation = $an_activation === 'unknown-date'
819
-                            ? '1970-01-01 00:00:00'
820
-                            : $an_activation;
821
-                    }
822
-                }
823
-            }
824
-        }
825
-        return $most_recently_active_version;
826
-    }
827
-
828
-
829
-    /**
830
-     * This redirects to the about EE page after activation
831
-     *
832
-     * @return void
833
-     */
834
-    public function redirect_to_about_ee()
835
-    {
836
-        $notices = EE_Error::get_notices(false);
837
-        // if current user is an admin and it's not an ajax or rest request
838
-        if (
839
-            ! isset($notices['errors'])
840
-            && $this->request->isAdmin()
841
-            && apply_filters(
842
-                'FHEE__EE_System__redirect_to_about_ee__do_redirect',
843
-                $this->capabilities->current_user_can('manage_options', 'espresso_about_default')
844
-            )
845
-        ) {
846
-            $query_params = array('page' => 'espresso_about');
847
-            if (EE_System::instance()->detect_req_type() === EE_System::req_type_new_activation) {
848
-                $query_params['new_activation'] = true;
849
-            }
850
-            if (EE_System::instance()->detect_req_type() === EE_System::req_type_reactivation) {
851
-                $query_params['reactivation'] = true;
852
-            }
853
-            $url = add_query_arg($query_params, admin_url('admin.php'));
854
-            wp_safe_redirect($url);
855
-            exit();
856
-        }
857
-    }
858
-
859
-
860
-    /**
861
-     * load_core_configuration
862
-     * this is hooked into 'AHEE__EE_Bootstrap__load_core_configuration'
863
-     * which runs during the WP 'plugins_loaded' action at priority 5
864
-     *
865
-     * @return void
866
-     * @throws ReflectionException
867
-     * @throws Exception
868
-     */
869
-    public function load_core_configuration()
870
-    {
871
-        do_action('AHEE__EE_System__load_core_configuration__begin', $this);
872
-        $this->loader->getShared('EE_Load_Textdomain');
873
-        // load textdomain
874
-        EE_Load_Textdomain::load_textdomain();
875
-        // load caf stuff a chance to play during the activation process too.
876
-        $this->_maybe_brew_regular();
877
-        // load and setup EE_Config and EE_Network_Config
878
-        $config = $this->loader->getShared('EE_Config');
879
-        $this->loader->getShared('EE_Network_Config');
880
-        // setup autoloaders
881
-        // enable logging?
882
-        if ($config->admin->use_remote_logging) {
883
-            $this->loader->getShared('EE_Log');
884
-        }
885
-        // check for activation errors
886
-        $activation_errors = get_option('ee_plugin_activation_errors', false);
887
-        if ($activation_errors) {
888
-            EE_Error::add_error($activation_errors, __FILE__, __FUNCTION__, __LINE__);
889
-            update_option('ee_plugin_activation_errors', false);
890
-        }
891
-        // get model names
892
-        $this->_parse_model_names();
893
-        // configure custom post type definitions
894
-        $this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions');
895
-        $this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions');
896
-        do_action('AHEE__EE_System__load_core_configuration__complete', $this);
897
-    }
898
-
899
-
900
-    /**
901
-     * cycles through all of the models/*.model.php files, and assembles an array of model names
902
-     *
903
-     * @return void
904
-     * @throws ReflectionException
905
-     */
906
-    private function _parse_model_names()
907
-    {
908
-        // get all the files in the EE_MODELS folder that end in .model.php
909
-        $models = glob(EE_MODELS . '*.model.php');
910
-        $model_names = array();
911
-        $non_abstract_db_models = array();
912
-        foreach ($models as $model) {
913
-            // get model classname
914
-            $classname = EEH_File::get_classname_from_filepath_with_standard_filename($model);
915
-            $short_name = str_replace('EEM_', '', $classname);
916
-            $reflectionClass = new ReflectionClass($classname);
917
-            if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
918
-                $non_abstract_db_models[ $short_name ] = $classname;
919
-            }
920
-            $model_names[ $short_name ] = $classname;
921
-        }
922
-        $this->registry->models = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
923
-        $this->registry->non_abstract_db_models = apply_filters(
924
-            'FHEE__EE_System__parse_implemented_model_names',
925
-            $non_abstract_db_models
926
-        );
927
-    }
928
-
929
-
930
-    /**
931
-     * The purpose of this method is to simply check for a file named "caffeinated/brewing_regular.php" for any hooks
932
-     * that need to be setup before our EE_System launches.
933
-     *
934
-     * @return void
935
-     * @throws DomainException
936
-     * @throws InvalidArgumentException
937
-     * @throws InvalidDataTypeException
938
-     * @throws InvalidInterfaceException
939
-     * @throws InvalidClassException
940
-     * @throws InvalidFilePathException
941
-     */
942
-    private function _maybe_brew_regular()
943
-    {
944
-        /** @var Domain $domain */
945
-        $domain = DomainFactory::getShared(
946
-            new FullyQualifiedName(
947
-                'EventEspresso\core\domain\Domain'
948
-            ),
949
-            array(
950
-                new FilePath(EVENT_ESPRESSO_MAIN_FILE),
951
-                Version::fromString(espresso_version()),
952
-            )
953
-        );
954
-        if ($domain->isCaffeinated()) {
955
-            require_once EE_CAFF_PATH . 'brewing_regular.php';
956
-        }
957
-    }
958
-
959
-
960
-    /**
961
-     * @since 4.9.71.p
962
-     * @throws Exception
963
-     */
964
-    public function loadRouteMatchSpecifications()
965
-    {
966
-        try {
967
-            $this->loader->getShared(
968
-                'EventEspresso\core\services\route_match\RouteMatchSpecificationManager'
969
-            );
970
-        } catch (Exception $exception) {
971
-            new ExceptionStackTraceDisplay($exception);
972
-        }
973
-        do_action('AHEE__EE_System__loadRouteMatchSpecifications');
974
-    }
975
-
976
-
977
-    /**
978
-     * loading CPT related classes earlier so that their definitions are available
979
-     * but not performing any actual registration with WP core until load_CPTs_and_session() is called
980
-     *
981
-     * @since   4.10.21.p
982
-     */
983
-    public function loadCustomPostTypes()
984
-    {
985
-        $this->register_custom_taxonomies = $this->loader->getShared(
986
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies'
987
-        );
988
-        $this->register_custom_post_types = $this->loader->getShared(
989
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes'
990
-        );
991
-        $this->register_custom_taxonomy_terms = $this->loader->getShared(
992
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms'
993
-        );
994
-        // integrate WP_Query with the EE models
995
-        $this->loader->getShared('EE_CPT_Strategy');
996
-        // load legacy EE_Request_Handler in case add-ons still need it
997
-        $this->loader->getShared('EE_Request_Handler');
998
-    }
999
-
1000
-
1001
-    /**
1002
-     * register_shortcodes_modules_and_widgets
1003
-     * generate lists of shortcodes and modules, then verify paths and classes
1004
-     * This is hooked into 'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets'
1005
-     * which runs during the WP 'plugins_loaded' action at priority 7
1006
-     *
1007
-     * @access public
1008
-     * @return void
1009
-     * @throws Exception
1010
-     */
1011
-    public function register_shortcodes_modules_and_widgets()
1012
-    {
1013
-        if ($this->request->isFrontend() || $this->request->isIframe() || $this->request->isAjax()) {
1014
-            // load, register, and add shortcodes the new way
1015
-            $this->loader->getShared('EventEspresso\core\services\shortcodes\ShortcodesManager');
1016
-        }
1017
-        do_action('AHEE__EE_System__register_shortcodes_modules_and_widgets');
1018
-        // check for addons using old hook point
1019
-        if (has_action('AHEE__EE_System__register_shortcodes_modules_and_addons')) {
1020
-            $this->_incompatible_addon_error();
1021
-        }
1022
-    }
1023
-
1024
-
1025
-    /**
1026
-     * _incompatible_addon_error
1027
-     *
1028
-     * @access public
1029
-     * @return void
1030
-     */
1031
-    private function _incompatible_addon_error()
1032
-    {
1033
-        // get array of classes hooking into here
1034
-        $class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook(
1035
-            'AHEE__EE_System__register_shortcodes_modules_and_addons'
1036
-        );
1037
-        if (! empty($class_names)) {
1038
-            $msg = esc_html__(
1039
-                'The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
1040
-                'event_espresso'
1041
-            );
1042
-            $msg .= '<ul>';
1043
-            foreach ($class_names as $class_name) {
1044
-                $msg .= '<li><b>Event Espresso - '
1045
-                        . str_replace(
1046
-                            array('EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'),
1047
-                            '',
1048
-                            $class_name
1049
-                        ) . '</b></li>';
1050
-            }
1051
-            $msg .= '</ul>';
1052
-            $msg .= esc_html__(
1053
-                'Compatibility issues can be avoided and/or resolved by keeping addons and plugins updated to the latest version.',
1054
-                'event_espresso'
1055
-            );
1056
-            // save list of incompatible addons to wp-options for later use
1057
-            add_option('ee_incompatible_addons', $class_names, '', 'no');
1058
-            if (is_admin()) {
1059
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1060
-            }
1061
-        }
1062
-    }
1063
-
1064
-
1065
-    /**
1066
-     * brew_espresso
1067
-     * begins the process of setting hooks for initializing EE in the correct order
1068
-     * This is happening on the 'AHEE__EE_Bootstrap__brew_espresso' hook point
1069
-     * which runs during the WP 'plugins_loaded' action at priority 9
1070
-     *
1071
-     * @return void
1072
-     */
1073
-    public function brew_espresso()
1074
-    {
1075
-        do_action('AHEE__EE_System__brew_espresso__begin', $this);
1076
-        // load some final core systems
1077
-        add_action('init', array($this, 'set_hooks_for_core'), 1);
1078
-        add_action('init', array($this, 'perform_activations_upgrades_and_migrations'), 3);
1079
-        add_action('init', array($this, 'load_CPTs_and_session'), 5);
1080
-        add_action('init', array($this, 'load_controllers'), 7);
1081
-        add_action('init', array($this, 'core_loaded_and_ready'), 9);
1082
-        add_action('init', array($this, 'initialize'), 10);
1083
-        add_action('init', array($this, 'initialize_last'), 100);
1084
-        if (is_admin() && apply_filters('FHEE__EE_System__brew_espresso__load_pue', true)) {
1085
-            // pew pew pew
1086
-            $this->loader->getShared('EventEspresso\core\services\licensing\LicenseService');
1087
-            do_action('AHEE__EE_System__brew_espresso__after_pue_init');
1088
-        }
1089
-        do_action('AHEE__EE_System__brew_espresso__complete', $this);
1090
-    }
1091
-
1092
-
1093
-    /**
1094
-     *    set_hooks_for_core
1095
-     *
1096
-     * @access public
1097
-     * @return    void
1098
-     * @throws EE_Error
1099
-     */
1100
-    public function set_hooks_for_core()
1101
-    {
1102
-        $this->_deactivate_incompatible_addons();
1103
-        do_action('AHEE__EE_System__set_hooks_for_core');
1104
-        $this->loader->getShared('EventEspresso\core\domain\values\session\SessionLifespan');
1105
-        // caps need to be initialized on every request so that capability maps are set.
1106
-        // @see https://events.codebasehq.com/projects/event-espresso/tickets/8674
1107
-        $this->registry->CAP->init_caps();
1108
-    }
1109
-
1110
-
1111
-    /**
1112
-     * Using the information gathered in EE_System::_incompatible_addon_error,
1113
-     * deactivates any addons considered incompatible with the current version of EE
1114
-     */
1115
-    private function _deactivate_incompatible_addons()
1116
-    {
1117
-        $incompatible_addons = get_option('ee_incompatible_addons', array());
1118
-        if (! empty($incompatible_addons)) {
1119
-            $active_plugins = get_option('active_plugins', array());
1120
-            foreach ($active_plugins as $active_plugin) {
1121
-                foreach ($incompatible_addons as $incompatible_addon) {
1122
-                    if (strpos($active_plugin, $incompatible_addon) !== false) {
1123
-                        $this->request->unSetRequestParams(['activate'], true);
1124
-                        espresso_deactivate_plugin($active_plugin);
1125
-                    }
1126
-                }
1127
-            }
1128
-        }
1129
-    }
1130
-
1131
-
1132
-    /**
1133
-     *    perform_activations_upgrades_and_migrations
1134
-     *
1135
-     * @access public
1136
-     * @return    void
1137
-     */
1138
-    public function perform_activations_upgrades_and_migrations()
1139
-    {
1140
-        do_action('AHEE__EE_System__perform_activations_upgrades_and_migrations');
1141
-    }
1142
-
1143
-
1144
-    /**
1145
-     * @return void
1146
-     * @throws DomainException
1147
-     */
1148
-    public function load_CPTs_and_session()
1149
-    {
1150
-        do_action('AHEE__EE_System__load_CPTs_and_session__start');
1151
-        $this->register_custom_taxonomies->registerCustomTaxonomies();
1152
-        $this->register_custom_post_types->registerCustomPostTypes();
1153
-        $this->register_custom_taxonomy_terms->registerCustomTaxonomyTerms();
1154
-        // load legacy Custom Post Types and Taxonomies
1155
-        $this->loader->getShared('EE_Register_CPTs');
1156
-        do_action('AHEE__EE_System__load_CPTs_and_session__complete');
1157
-    }
1158
-
1159
-
1160
-    /**
1161
-     * load_controllers
1162
-     * this is the best place to load any additional controllers that needs access to EE core.
1163
-     * it is expected that all basic core EE systems, that are not dependant on the current request are loaded at this
1164
-     * time
1165
-     *
1166
-     * @access public
1167
-     * @return void
1168
-     */
1169
-    public function load_controllers()
1170
-    {
1171
-        do_action('AHEE__EE_System__load_controllers__start');
1172
-        // let's get it started
1173
-        if (
1174
-            ! $this->maintenance_mode->level()
1175
-            && ($this->request->isFrontend() || $this->request->isFrontAjax())
1176
-        ) {
1177
-            do_action('AHEE__EE_System__load_controllers__load_front_controllers');
1178
-            $this->loader->getShared('EE_Front_Controller');
1179
-        } elseif ($this->request->isAdmin() || $this->request->isAdminAjax()) {
1180
-            do_action('AHEE__EE_System__load_controllers__load_admin_controllers');
1181
-            $this->loader->getShared('EE_Admin');
1182
-        } elseif ($this->request->isWordPressHeartbeat()) {
1183
-            $this->loader->getShared('EventEspresso\core\domain\services\admin\ajax\WordpressHeartbeat');
1184
-        }
1185
-        do_action('AHEE__EE_System__load_controllers__complete');
1186
-    }
1187
-
1188
-
1189
-    /**
1190
-     * core_loaded_and_ready
1191
-     * all of the basic EE core should be loaded at this point and available regardless of M-Mode
1192
-     *
1193
-     * @access public
1194
-     * @return void
1195
-     * @throws Exception
1196
-     */
1197
-    public function core_loaded_and_ready()
1198
-    {
1199
-        if (
1200
-            $this->request->isAdmin()
1201
-            || $this->request->isFrontend()
1202
-            || $this->request->isIframe()
1203
-            || $this->request->isWordPressApi()
1204
-        ) {
1205
-            try {
1206
-                $this->loader->getShared('EventEspresso\core\services\assets\Registry');
1207
-                $this->loader->getShared('EventEspresso\core\domain\services\assets\CoreAssetManager');
1208
-                if ($this->canLoadBlocks()) {
1209
-                    $this->loader->getShared(
1210
-                        'EventEspresso\core\services\editor\BlockRegistrationManager'
1211
-                    );
1212
-                }
1213
-            } catch (Exception $exception) {
1214
-                new ExceptionStackTraceDisplay($exception);
1215
-            }
1216
-        }
1217
-        if (
1218
-            $this->request->isAdmin()
1219
-            || $this->request->isEeAjax()
1220
-            || $this->request->isFrontend()
1221
-        ) {
1222
-            $this->loader->getShared('EE_Session');
1223
-        }
1224
-        do_action('AHEE__EE_System__core_loaded_and_ready');
1225
-        // always load template tags, because it's faster than checking if it's a front-end request, and many page
1226
-        // builders require these even on the front-end
1227
-        require_once EE_PUBLIC . 'template_tags.php';
1228
-        do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1229
-    }
1230
-
1231
-
1232
-    /**
1233
-     * initialize
1234
-     * this is the best place to begin initializing client code
1235
-     *
1236
-     * @access public
1237
-     * @return void
1238
-     */
1239
-    public function initialize()
1240
-    {
1241
-        do_action('AHEE__EE_System__initialize');
1242
-    }
1243
-
1244
-
1245
-    /**
1246
-     * initialize_last
1247
-     * this is run really late during the WP init hook point, and ensures that mostly everything else that needs to
1248
-     * initialize has done so
1249
-     *
1250
-     * @access public
1251
-     * @return void
1252
-     */
1253
-    public function initialize_last()
1254
-    {
1255
-        do_action('AHEE__EE_System__initialize_last');
1256
-        /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
1257
-        $rewrite_rules = $this->loader->getShared(
1258
-            'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
1259
-        );
1260
-        $rewrite_rules->flushRewriteRules();
1261
-        add_action('admin_bar_init', array($this, 'addEspressoToolbar'));
1262
-        if (
1263
-            ($this->request->isAjax() || $this->request->isAdmin())
1264
-            && $this->maintenance_mode->models_can_query()
1265
-        ) {
1266
-            $this->loader->getShared('EventEspresso\core\services\privacy\export\PersonalDataExporterManager');
1267
-            $this->loader->getShared('EventEspresso\core\services\privacy\erasure\PersonalDataEraserManager');
1268
-        }
1269
-    }
1270
-
1271
-
1272
-    /**
1273
-     * @return void
1274
-     * @throws EE_Error
1275
-     */
1276
-    public function addEspressoToolbar()
1277
-    {
1278
-        $this->loader->getShared(
1279
-            'EventEspresso\core\domain\services\admin\AdminToolBar',
1280
-            array($this->registry->CAP)
1281
-        );
1282
-    }
1283
-
1284
-
1285
-    /**
1286
-     * do_not_cache
1287
-     * sets no cache headers and defines no cache constants for WP plugins
1288
-     *
1289
-     * @access public
1290
-     * @return void
1291
-     */
1292
-    public static function do_not_cache()
1293
-    {
1294
-        // set no cache constants
1295
-        if (! defined('DONOTCACHEPAGE')) {
1296
-            define('DONOTCACHEPAGE', true);
1297
-        }
1298
-        if (! defined('DONOTCACHCEOBJECT')) {
1299
-            define('DONOTCACHCEOBJECT', true);
1300
-        }
1301
-        if (! defined('DONOTCACHEDB')) {
1302
-            define('DONOTCACHEDB', true);
1303
-        }
1304
-        // add no cache headers
1305
-        add_action('send_headers', array('EE_System', 'nocache_headers'), 10);
1306
-        // plus a little extra for nginx and Google Chrome
1307
-        add_filter('nocache_headers', array('EE_System', 'extra_nocache_headers'), 10, 1);
1308
-        // prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes with the registration process
1309
-        remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
1310
-    }
1311
-
1312
-
1313
-    /**
1314
-     *    extra_nocache_headers
1315
-     *
1316
-     * @access    public
1317
-     * @param $headers
1318
-     * @return    array
1319
-     */
1320
-    public static function extra_nocache_headers($headers)
1321
-    {
1322
-        // for NGINX
1323
-        $headers['X-Accel-Expires'] = 0;
1324
-        // plus extra for Google Chrome since it doesn't seem to respect "no-cache", but WILL respect "no-store"
1325
-        $headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0';
1326
-        return $headers;
1327
-    }
1328
-
1329
-
1330
-    /**
1331
-     *    nocache_headers
1332
-     *
1333
-     * @access    public
1334
-     * @return    void
1335
-     */
1336
-    public static function nocache_headers()
1337
-    {
1338
-        nocache_headers();
1339
-    }
1340
-
1341
-
1342
-    /**
1343
-     * simply hooks into "wp_list_pages_exclude" filter (for wp_list_pages method) and makes sure EE critical pages are
1344
-     * never returned with the function.
1345
-     *
1346
-     * @param  array $exclude_array any existing pages being excluded are in this array.
1347
-     * @return array
1348
-     */
1349
-    public function remove_pages_from_wp_list_pages($exclude_array)
1350
-    {
1351
-        return array_merge($exclude_array, $this->registry->CFG->core->get_critical_pages_array());
1352
-    }
1353
-
1354
-
1355
-    /**
1356
-     * Return whether blocks can be registered/loaded or not.
1357
-     * @return bool
1358
-     */
1359
-    private function canLoadBlocks()
1360
-    {
1361
-        return apply_filters('FHEE__EE_System__canLoadBlocks', true)
1362
-               && function_exists('register_block_type')
1363
-               // don't load blocks if in the Divi page builder editor context
1364
-               // @see https://github.com/eventespresso/event-espresso-core/issues/814
1365
-               && ! $this->request->getRequestParam('et_fb', false);
1366
-    }
30
+	/**
31
+	 * indicates this is a 'normal' request. Ie, not activation, nor upgrade, nor activation.
32
+	 * So examples of this would be a normal GET request on the frontend or backend, or a POST, etc
33
+	 */
34
+	const req_type_normal = 0;
35
+
36
+	/**
37
+	 * Indicates this is a brand new installation of EE so we should install
38
+	 * tables and default data etc
39
+	 */
40
+	const req_type_new_activation = 1;
41
+
42
+	/**
43
+	 * we've detected that EE has been reactivated (or EE was activated during maintenance mode,
44
+	 * and we just exited maintenance mode). We MUST check the database is setup properly
45
+	 * and that default data is setup too
46
+	 */
47
+	const req_type_reactivation = 2;
48
+
49
+	/**
50
+	 * indicates that EE has been upgraded since its previous request.
51
+	 * We may have data migration scripts to call and will want to trigger maintenance mode
52
+	 */
53
+	const req_type_upgrade = 3;
54
+
55
+	/**
56
+	 * TODO  will detect that EE has been DOWNGRADED. We probably don't want to run in this case...
57
+	 */
58
+	const req_type_downgrade = 4;
59
+
60
+	/**
61
+	 * @deprecated since version 4.6.0.dev.006
62
+	 * Now whenever a new_activation is detected the request type is still just
63
+	 * new_activation (same for reactivation, upgrade, downgrade etc), but if we'r ein maintenance mode
64
+	 * EE_System::initialize_db_if_no_migrations_required and EE_Addon::initialize_db_if_no_migrations_required
65
+	 * will instead enqueue that EE plugin's db initialization for when we're taken out of maintenance mode.
66
+	 * (Specifically, when the migration manager indicates migrations are finished
67
+	 * EE_Data_Migration_Manager::initialize_db_for_enqueued_ee_plugins() will be called)
68
+	 */
69
+	const req_type_activation_but_not_installed = 5;
70
+
71
+	/**
72
+	 * option prefix for recording the activation history (like core's "espresso_db_update") of addons
73
+	 */
74
+	const addon_activation_history_option_prefix = 'ee_addon_activation_history_';
75
+
76
+	/**
77
+	 * @var EE_System $_instance
78
+	 */
79
+	private static $_instance;
80
+
81
+	/**
82
+	 * @var EE_Registry $registry
83
+	 */
84
+	private $registry;
85
+
86
+	/**
87
+	 * @var LoaderInterface $loader
88
+	 */
89
+	private $loader;
90
+
91
+	/**
92
+	 * @var EE_Capabilities $capabilities
93
+	 */
94
+	private $capabilities;
95
+
96
+	/**
97
+	 * @var RequestInterface $request
98
+	 */
99
+	private $request;
100
+
101
+	/**
102
+	 * @var EE_Maintenance_Mode $maintenance_mode
103
+	 */
104
+	private $maintenance_mode;
105
+
106
+	/**
107
+	 * Stores which type of request this is, options being one of the constants on EE_System starting with req_type_*.
108
+	 * It can be a brand-new activation, a reactivation, an upgrade, a downgrade, or a normal request.
109
+	 *
110
+	 * @var int $_req_type
111
+	 */
112
+	private $_req_type;
113
+
114
+	/**
115
+	 * Whether or not there was a non-micro version change in EE core version during this request
116
+	 *
117
+	 * @var boolean $_major_version_change
118
+	 */
119
+	private $_major_version_change = false;
120
+
121
+	/**
122
+	 * A Context DTO dedicated solely to identifying the current request type.
123
+	 *
124
+	 * @var RequestTypeContextCheckerInterface $request_type
125
+	 */
126
+	private $request_type;
127
+
128
+	/**
129
+	 * @param EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes
130
+	 */
131
+	private $register_custom_post_types;
132
+
133
+	/**
134
+	 * @param EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies
135
+	 */
136
+	private $register_custom_taxonomies;
137
+
138
+	/**
139
+	 * @param EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms
140
+	 */
141
+	private $register_custom_taxonomy_terms;
142
+
143
+	/**
144
+	 * @singleton method used to instantiate class object
145
+	 * @param EE_Registry|null         $registry
146
+	 * @param LoaderInterface|null     $loader
147
+	 * @param RequestInterface|null    $request
148
+	 * @param EE_Maintenance_Mode|null $maintenance_mode
149
+	 * @return EE_System
150
+	 */
151
+	public static function instance(
152
+		EE_Registry $registry = null,
153
+		LoaderInterface $loader = null,
154
+		RequestInterface $request = null,
155
+		EE_Maintenance_Mode $maintenance_mode = null
156
+	) {
157
+		// check if class object is instantiated
158
+		if (! self::$_instance instanceof EE_System) {
159
+			self::$_instance = new self($registry, $loader, $request, $maintenance_mode);
160
+		}
161
+		return self::$_instance;
162
+	}
163
+
164
+
165
+	/**
166
+	 * resets the instance and returns it
167
+	 *
168
+	 * @return EE_System
169
+	 */
170
+	public static function reset()
171
+	{
172
+		self::$_instance->_req_type = null;
173
+		// make sure none of the old hooks are left hanging around
174
+		remove_all_actions('AHEE__EE_System__perform_activations_upgrades_and_migrations');
175
+		// we need to reset the migration manager in order for it to detect DMSs properly
176
+		EE_Data_Migration_Manager::reset();
177
+		self::instance()->detect_activations_or_upgrades();
178
+		self::instance()->perform_activations_upgrades_and_migrations();
179
+		return self::instance();
180
+	}
181
+
182
+
183
+	/**
184
+	 * sets hooks for running rest of system
185
+	 * provides "AHEE__EE_System__construct__complete" hook for EE Addons to use as their starting point
186
+	 * starting EE Addons from any other point may lead to problems
187
+	 *
188
+	 * @param EE_Registry         $registry
189
+	 * @param LoaderInterface     $loader
190
+	 * @param RequestInterface    $request
191
+	 * @param EE_Maintenance_Mode $maintenance_mode
192
+	 */
193
+	private function __construct(
194
+		EE_Registry $registry,
195
+		LoaderInterface $loader,
196
+		RequestInterface $request,
197
+		EE_Maintenance_Mode $maintenance_mode
198
+	) {
199
+		$this->registry = $registry;
200
+		$this->loader = $loader;
201
+		$this->request = $request;
202
+		$this->maintenance_mode = $maintenance_mode;
203
+		do_action('AHEE__EE_System__construct__begin', $this);
204
+		add_action(
205
+			'AHEE__EE_Bootstrap__load_espresso_addons',
206
+			array($this, 'loadCapabilities'),
207
+			5
208
+		);
209
+		add_action(
210
+			'AHEE__EE_Bootstrap__load_espresso_addons',
211
+			array($this, 'loadCommandBus'),
212
+			7
213
+		);
214
+		add_action(
215
+			'AHEE__EE_Bootstrap__load_espresso_addons',
216
+			array($this, 'loadPluginApi'),
217
+			9
218
+		);
219
+		// allow addons to load first so that they can register autoloaders, set hooks for running DMS's, etc
220
+		add_action(
221
+			'AHEE__EE_Bootstrap__load_espresso_addons',
222
+			array($this, 'load_espresso_addons')
223
+		);
224
+		// when an ee addon is activated, we want to call the core hook(s) again
225
+		// because the newly-activated addon didn't get a chance to run at all
226
+		add_action('activate_plugin', array($this, 'load_espresso_addons'), 1);
227
+		// detect whether install or upgrade
228
+		add_action(
229
+			'AHEE__EE_Bootstrap__detect_activations_or_upgrades',
230
+			array($this, 'detect_activations_or_upgrades'),
231
+			3
232
+		);
233
+		// load EE_Config, EE_Textdomain, etc
234
+		add_action(
235
+			'AHEE__EE_Bootstrap__load_core_configuration',
236
+			array($this, 'load_core_configuration'),
237
+			5
238
+		);
239
+		// load specifications for matching routes to current request
240
+		add_action(
241
+			'AHEE__EE_Bootstrap__load_core_configuration',
242
+			array($this, 'loadRouteMatchSpecifications')
243
+		);
244
+		// load specifications for custom post types
245
+		add_action(
246
+			'AHEE__EE_Bootstrap__load_core_configuration',
247
+			array($this, 'loadCustomPostTypes')
248
+		);
249
+		// load EE_Config, EE_Textdomain, etc
250
+		add_action(
251
+			'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets',
252
+			array($this, 'register_shortcodes_modules_and_widgets'),
253
+			7
254
+		);
255
+		// you wanna get going? I wanna get going... let's get going!
256
+		add_action(
257
+			'AHEE__EE_Bootstrap__brew_espresso',
258
+			array($this, 'brew_espresso'),
259
+			9
260
+		);
261
+		// other housekeeping
262
+		// exclude EE critical pages from wp_list_pages
263
+		add_filter(
264
+			'wp_list_pages_excludes',
265
+			array($this, 'remove_pages_from_wp_list_pages'),
266
+			10
267
+		);
268
+		// ALL EE Addons should use the following hook point to attach their initial setup too
269
+		// it's extremely important for EE Addons to register any class autoloaders so that they can be available when the EE_Config loads
270
+		do_action('AHEE__EE_System__construct__complete', $this);
271
+	}
272
+
273
+
274
+	/**
275
+	 * load and setup EE_Capabilities
276
+	 *
277
+	 * @return void
278
+	 * @throws EE_Error
279
+	 */
280
+	public function loadCapabilities()
281
+	{
282
+		$this->capabilities = $this->loader->getShared('EE_Capabilities');
283
+		add_action(
284
+			'AHEE__EE_Capabilities__init_caps__before_initialization',
285
+			function () {
286
+				LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
287
+			}
288
+		);
289
+	}
290
+
291
+
292
+	/**
293
+	 * create and cache the CommandBus, and also add middleware
294
+	 * The CapChecker middleware requires the use of EE_Capabilities
295
+	 * which is why we need to load the CommandBus after Caps are set up
296
+	 *
297
+	 * @return void
298
+	 * @throws EE_Error
299
+	 */
300
+	public function loadCommandBus()
301
+	{
302
+		$this->loader->getShared(
303
+			'CommandBusInterface',
304
+			array(
305
+				null,
306
+				apply_filters(
307
+					'FHEE__EE_Load_Espresso_Core__handle_request__CommandBus_middleware',
308
+					array(
309
+						$this->loader->getShared('EventEspresso\core\services\commands\middleware\CapChecker'),
310
+						$this->loader->getShared('EventEspresso\core\services\commands\middleware\AddActionHook'),
311
+					)
312
+				),
313
+			)
314
+		);
315
+	}
316
+
317
+
318
+	/**
319
+	 * @return void
320
+	 * @throws EE_Error
321
+	 */
322
+	public function loadPluginApi()
323
+	{
324
+		// set autoloaders for all of the classes implementing EEI_Plugin_API
325
+		// which provide helpers for EE plugin authors to more easily register certain components with EE.
326
+		EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'plugin_api');
327
+	}
328
+
329
+
330
+	/**
331
+	 * @param string $addon_name
332
+	 * @param string $version_constant
333
+	 * @param string $min_version_required
334
+	 * @param string $load_callback
335
+	 * @param string $plugin_file_constant
336
+	 * @return void
337
+	 */
338
+	private function deactivateIncompatibleAddon(
339
+		$addon_name,
340
+		$version_constant,
341
+		$min_version_required,
342
+		$load_callback,
343
+		$plugin_file_constant
344
+	) {
345
+		if (! defined($version_constant)) {
346
+			return;
347
+		}
348
+		$addon_version = constant($version_constant);
349
+		if ($addon_version && version_compare($addon_version, $min_version_required, '<')) {
350
+			remove_action('AHEE__EE_System__load_espresso_addons', $load_callback);
351
+			if (! function_exists('deactivate_plugins')) {
352
+				require_once ABSPATH . 'wp-admin/includes/plugin.php';
353
+			}
354
+			deactivate_plugins(plugin_basename(constant($plugin_file_constant)));
355
+			$this->request->unSetRequestParams(['activate', 'activate-multi'], true);
356
+			EE_Error::add_error(
357
+				sprintf(
358
+					esc_html__(
359
+						'We\'re sorry, but the Event Espresso %1$s addon was deactivated because version %2$s or higher is required with this version of Event Espresso core.',
360
+						'event_espresso'
361
+					),
362
+					$addon_name,
363
+					$min_version_required
364
+				),
365
+				__FILE__,
366
+				__FUNCTION__ . "({$addon_name})",
367
+				__LINE__
368
+			);
369
+			EE_Error::get_notices(false, true);
370
+		}
371
+	}
372
+
373
+
374
+	/**
375
+	 * load_espresso_addons
376
+	 * allow addons to load first so that they can set hooks for running DMS's, etc
377
+	 * this is hooked into both:
378
+	 *    'AHEE__EE_Bootstrap__load_core_configuration'
379
+	 *        which runs during the WP 'plugins_loaded' action at priority 5
380
+	 *    and the WP 'activate_plugin' hook point
381
+	 *
382
+	 * @access public
383
+	 * @return void
384
+	 */
385
+	public function load_espresso_addons()
386
+	{
387
+		$this->deactivateIncompatibleAddon(
388
+			'Wait Lists',
389
+			'EE_WAIT_LISTS_VERSION',
390
+			'1.0.0.beta.074',
391
+			'load_espresso_wait_lists',
392
+			'EE_WAIT_LISTS_PLUGIN_FILE'
393
+		);
394
+		$this->deactivateIncompatibleAddon(
395
+			'Automated Upcoming Event Notifications',
396
+			'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_VERSION',
397
+			'1.0.0.beta.091',
398
+			'load_espresso_automated_upcoming_event_notification',
399
+			'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_PLUGIN_FILE'
400
+		);
401
+		do_action('AHEE__EE_System__load_espresso_addons');
402
+		// if the WP API basic auth plugin isn't already loaded, load it now.
403
+		// We want it for mobile apps. Just include the entire plugin
404
+		// also, don't load the basic auth when a plugin is getting activated, because
405
+		// it could be the basic auth plugin, and it doesn't check if its methods are already defined
406
+		// and causes a fatal error
407
+		if (
408
+			($this->request->isWordPressApi() || $this->request->isApi())
409
+			&& $this->request->getRequestParam('activate') !== 'true'
410
+			&& ! function_exists('json_basic_auth_handler')
411
+			&& ! function_exists('json_basic_auth_error')
412
+			&& ! in_array(
413
+				$this->request->getRequestParam('action'),
414
+				array('activate', 'activate-selected'),
415
+				true
416
+			)
417
+		) {
418
+			include_once EE_THIRD_PARTY . 'wp-api-basic-auth/basic-auth.php';
419
+		}
420
+		do_action('AHEE__EE_System__load_espresso_addons__complete');
421
+	}
422
+
423
+
424
+	/**
425
+	 * detect_activations_or_upgrades
426
+	 * Checks for activation or upgrade of core first;
427
+	 * then also checks if any registered addons have been activated or upgraded
428
+	 * This is hooked into 'AHEE__EE_Bootstrap__detect_activations_or_upgrades'
429
+	 * which runs during the WP 'plugins_loaded' action at priority 3
430
+	 *
431
+	 * @access public
432
+	 * @return void
433
+	 */
434
+	public function detect_activations_or_upgrades()
435
+	{
436
+		// first off: let's make sure to handle core
437
+		$this->detect_if_activation_or_upgrade();
438
+		foreach ($this->registry->addons as $addon) {
439
+			if ($addon instanceof EE_Addon) {
440
+				// detect teh request type for that addon
441
+				$addon->detect_req_type();
442
+			}
443
+		}
444
+	}
445
+
446
+
447
+	/**
448
+	 * detect_if_activation_or_upgrade
449
+	 * Takes care of detecting whether this is a brand new install or code upgrade,
450
+	 * and either setting up the DB or setting up maintenance mode etc.
451
+	 *
452
+	 * @access public
453
+	 * @return void
454
+	 */
455
+	public function detect_if_activation_or_upgrade()
456
+	{
457
+		do_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin');
458
+		// check if db has been updated, or if its a brand-new installation
459
+		$espresso_db_update = $this->fix_espresso_db_upgrade_option();
460
+		$request_type = $this->detect_req_type($espresso_db_update);
461
+		// EEH_Debug_Tools::printr( $request_type, '$request_type', __FILE__, __LINE__ );
462
+		switch ($request_type) {
463
+			case EE_System::req_type_new_activation:
464
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__new_activation');
465
+				$this->_handle_core_version_change($espresso_db_update);
466
+				break;
467
+			case EE_System::req_type_reactivation:
468
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__reactivation');
469
+				$this->_handle_core_version_change($espresso_db_update);
470
+				break;
471
+			case EE_System::req_type_upgrade:
472
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__upgrade');
473
+				// migrations may be required now that we've upgraded
474
+				$this->maintenance_mode->set_maintenance_mode_if_db_old();
475
+				$this->_handle_core_version_change($espresso_db_update);
476
+				break;
477
+			case EE_System::req_type_downgrade:
478
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__downgrade');
479
+				// its possible migrations are no longer required
480
+				$this->maintenance_mode->set_maintenance_mode_if_db_old();
481
+				$this->_handle_core_version_change($espresso_db_update);
482
+				break;
483
+			case EE_System::req_type_normal:
484
+			default:
485
+				break;
486
+		}
487
+		do_action('AHEE__EE_System__detect_if_activation_or_upgrade__complete');
488
+	}
489
+
490
+
491
+	/**
492
+	 * Updates the list of installed versions and sets hooks for
493
+	 * initializing the database later during the request
494
+	 *
495
+	 * @param array $espresso_db_update
496
+	 */
497
+	private function _handle_core_version_change($espresso_db_update)
498
+	{
499
+		$this->update_list_of_installed_versions($espresso_db_update);
500
+		// get ready to verify the DB is ok (provided we aren't in maintenance mode, of course)
501
+		add_action(
502
+			'AHEE__EE_System__perform_activations_upgrades_and_migrations',
503
+			array($this, 'initialize_db_if_no_migrations_required')
504
+		);
505
+	}
506
+
507
+
508
+	/**
509
+	 * standardizes the wp option 'espresso_db_upgrade' which actually stores
510
+	 * information about what versions of EE have been installed and activated,
511
+	 * NOT necessarily the state of the database
512
+	 *
513
+	 * @param mixed $espresso_db_update           the value of the WordPress option.
514
+	 *                                            If not supplied, fetches it from the options table
515
+	 * @return array the correct value of 'espresso_db_upgrade', after saving it, if it needed correction
516
+	 */
517
+	private function fix_espresso_db_upgrade_option($espresso_db_update = null)
518
+	{
519
+		do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
520
+		if (! $espresso_db_update) {
521
+			$espresso_db_update = get_option('espresso_db_update');
522
+		}
523
+		// check that option is an array
524
+		if (! is_array($espresso_db_update)) {
525
+			// if option is FALSE, then it never existed
526
+			if ($espresso_db_update === false) {
527
+				// make $espresso_db_update an array and save option with autoload OFF
528
+				$espresso_db_update = array();
529
+				add_option('espresso_db_update', $espresso_db_update, '', 'no');
530
+			} else {
531
+				// option is NOT FALSE but also is NOT an array, so make it an array and save it
532
+				$espresso_db_update = array($espresso_db_update => array());
533
+				update_option('espresso_db_update', $espresso_db_update);
534
+			}
535
+		} else {
536
+			$corrected_db_update = array();
537
+			// if IS an array, but is it an array where KEYS are version numbers, and values are arrays?
538
+			foreach ($espresso_db_update as $should_be_version_string => $should_be_array) {
539
+				if (is_int($should_be_version_string) && ! is_array($should_be_array)) {
540
+					// the key is an int, and the value IS NOT an array
541
+					// so it must be numerically-indexed, where values are versions installed...
542
+					// fix it!
543
+					$version_string = $should_be_array;
544
+					$corrected_db_update[ $version_string ] = array('unknown-date');
545
+				} else {
546
+					// ok it checks out
547
+					$corrected_db_update[ $should_be_version_string ] = $should_be_array;
548
+				}
549
+			}
550
+			$espresso_db_update = $corrected_db_update;
551
+			update_option('espresso_db_update', $espresso_db_update);
552
+		}
553
+		do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__complete', $espresso_db_update);
554
+		return $espresso_db_update;
555
+	}
556
+
557
+
558
+	/**
559
+	 * Does the traditional work of setting up the plugin's database and adding default data.
560
+	 * If migration script/process did not exist, this is what would happen on every activation/reactivation/upgrade.
561
+	 * NOTE: if we're in maintenance mode (which would be the case if we detect there are data
562
+	 * migration scripts that need to be run and a version change happens), enqueues core for database initialization,
563
+	 * so that it will be done when migrations are finished
564
+	 *
565
+	 * @param boolean $initialize_addons_too if true, we double-check addons' database tables etc too;
566
+	 * @param boolean $verify_schema         if true will re-check the database tables have the correct schema.
567
+	 *                                       This is a resource-intensive job
568
+	 *                                       so we prefer to only do it when necessary
569
+	 * @return void
570
+	 * @throws EE_Error
571
+	 */
572
+	public function initialize_db_if_no_migrations_required($initialize_addons_too = false, $verify_schema = true)
573
+	{
574
+		$request_type = $this->detect_req_type();
575
+		// only initialize system if we're not in maintenance mode.
576
+		if ($this->maintenance_mode->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
577
+			/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
578
+			$rewrite_rules = $this->loader->getShared(
579
+				'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
580
+			);
581
+			$rewrite_rules->flush();
582
+			if ($verify_schema) {
583
+				EEH_Activation::initialize_db_and_folders();
584
+			}
585
+			EEH_Activation::initialize_db_content();
586
+			EEH_Activation::system_initialization();
587
+			if ($initialize_addons_too) {
588
+				$this->initialize_addons();
589
+			}
590
+		} else {
591
+			EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for('Core');
592
+		}
593
+		if (
594
+			$request_type === EE_System::req_type_new_activation
595
+			|| $request_type === EE_System::req_type_reactivation
596
+			|| (
597
+				$request_type === EE_System::req_type_upgrade
598
+				&& $this->is_major_version_change()
599
+			)
600
+		) {
601
+			add_action('AHEE__EE_System__initialize_last', array($this, 'redirect_to_about_ee'), 9);
602
+		}
603
+	}
604
+
605
+
606
+	/**
607
+	 * Initializes the db for all registered addons
608
+	 *
609
+	 * @throws EE_Error
610
+	 */
611
+	public function initialize_addons()
612
+	{
613
+		// foreach registered addon, make sure its db is up-to-date too
614
+		foreach ($this->registry->addons as $addon) {
615
+			if ($addon instanceof EE_Addon) {
616
+				$addon->initialize_db_if_no_migrations_required();
617
+			}
618
+		}
619
+	}
620
+
621
+
622
+	/**
623
+	 * Adds the current code version to the saved wp option which stores a list of all ee versions ever installed.
624
+	 *
625
+	 * @param    array  $version_history
626
+	 * @param    string $current_version_to_add version to be added to the version history
627
+	 * @return    boolean success as to whether or not this option was changed
628
+	 */
629
+	public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
630
+	{
631
+		if (! $version_history) {
632
+			$version_history = $this->fix_espresso_db_upgrade_option($version_history);
633
+		}
634
+		if ($current_version_to_add === null) {
635
+			$current_version_to_add = espresso_version();
636
+		}
637
+		$version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
638
+		// re-save
639
+		return update_option('espresso_db_update', $version_history);
640
+	}
641
+
642
+
643
+	/**
644
+	 * Detects if the current version indicated in the has existed in the list of
645
+	 * previously-installed versions of EE (espresso_db_update). Does NOT modify it (ie, no side-effect)
646
+	 *
647
+	 * @param array $espresso_db_update array from the wp option stored under the name 'espresso_db_update'.
648
+	 *                                  If not supplied, fetches it from the options table.
649
+	 *                                  Also, caches its result so later parts of the code can also know whether
650
+	 *                                  there's been an update or not. This way we can add the current version to
651
+	 *                                  espresso_db_update, but still know if this is a new install or not
652
+	 * @return int one of the constants on EE_System::req_type_
653
+	 */
654
+	public function detect_req_type($espresso_db_update = null)
655
+	{
656
+		if ($this->_req_type === null) {
657
+			$espresso_db_update = ! empty($espresso_db_update)
658
+				? $espresso_db_update
659
+				: $this->fix_espresso_db_upgrade_option();
660
+			$this->_req_type = EE_System::detect_req_type_given_activation_history(
661
+				$espresso_db_update,
662
+				'ee_espresso_activation',
663
+				espresso_version()
664
+			);
665
+			$this->_major_version_change = $this->_detect_major_version_change($espresso_db_update);
666
+			$this->request->setIsActivation($this->_req_type !== EE_System::req_type_normal);
667
+		}
668
+		return $this->_req_type;
669
+	}
670
+
671
+
672
+	/**
673
+	 * Returns whether or not there was a non-micro version change (ie, change in either
674
+	 * the first or second number in the version. Eg 4.9.0.rc.001 to 4.10.0.rc.000,
675
+	 * but not 4.9.0.rc.0001 to 4.9.1.rc.0001
676
+	 *
677
+	 * @param $activation_history
678
+	 * @return bool
679
+	 */
680
+	private function _detect_major_version_change($activation_history)
681
+	{
682
+		$previous_version = EE_System::_get_most_recently_active_version_from_activation_history($activation_history);
683
+		$previous_version_parts = explode('.', $previous_version);
684
+		$current_version_parts = explode('.', espresso_version());
685
+		return isset($previous_version_parts[0], $previous_version_parts[1], $current_version_parts[0], $current_version_parts[1])
686
+			   && ($previous_version_parts[0] !== $current_version_parts[0]
687
+				   || $previous_version_parts[1] !== $current_version_parts[1]
688
+			   );
689
+	}
690
+
691
+
692
+	/**
693
+	 * Returns true if either the major or minor version of EE changed during this request.
694
+	 * Eg 4.9.0.rc.001 to 4.10.0.rc.000, but not 4.9.0.rc.0001 to 4.9.1.rc.0001
695
+	 *
696
+	 * @return bool
697
+	 */
698
+	public function is_major_version_change()
699
+	{
700
+		return $this->_major_version_change;
701
+	}
702
+
703
+
704
+	/**
705
+	 * Determines the request type for any ee addon, given three piece of info: the current array of activation
706
+	 * histories (for core that' 'espresso_db_update' wp option); the name of the WordPress option which is temporarily
707
+	 * set upon activation of the plugin (for core it's 'ee_espresso_activation'); and the version that this plugin was
708
+	 * just activated to (for core that will always be espresso_version())
709
+	 *
710
+	 * @param array  $activation_history_for_addon     the option's value which stores the activation history for this
711
+	 *                                                 ee plugin. for core that's 'espresso_db_update'
712
+	 * @param string $activation_indicator_option_name the name of the WordPress option that is temporarily set to
713
+	 *                                                 indicate that this plugin was just activated
714
+	 * @param string $version_to_upgrade_to            the version that was just upgraded to (for core that will be
715
+	 *                                                 espresso_version())
716
+	 * @return int one of the constants on EE_System::req_type_*
717
+	 */
718
+	public static function detect_req_type_given_activation_history(
719
+		$activation_history_for_addon,
720
+		$activation_indicator_option_name,
721
+		$version_to_upgrade_to
722
+	) {
723
+		$version_is_higher = self::_new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to);
724
+		if ($activation_history_for_addon) {
725
+			// it exists, so this isn't a completely new install
726
+			// check if this version already in that list of previously installed versions
727
+			if (! isset($activation_history_for_addon[ $version_to_upgrade_to ])) {
728
+				// it a version we haven't seen before
729
+				if ($version_is_higher === 1) {
730
+					$req_type = EE_System::req_type_upgrade;
731
+				} else {
732
+					$req_type = EE_System::req_type_downgrade;
733
+				}
734
+				delete_option($activation_indicator_option_name);
735
+			} else {
736
+				// its not an update. maybe a reactivation?
737
+				if (get_option($activation_indicator_option_name, false)) {
738
+					if ($version_is_higher === -1) {
739
+						$req_type = EE_System::req_type_downgrade;
740
+					} elseif ($version_is_higher === 0) {
741
+						// we've seen this version before, but it's an activation. must be a reactivation
742
+						$req_type = EE_System::req_type_reactivation;
743
+					} else {// $version_is_higher === 1
744
+						$req_type = EE_System::req_type_upgrade;
745
+					}
746
+					delete_option($activation_indicator_option_name);
747
+				} else {
748
+					// we've seen this version before and the activation indicate doesn't show it was just activated
749
+					if ($version_is_higher === -1) {
750
+						$req_type = EE_System::req_type_downgrade;
751
+					} elseif ($version_is_higher === 0) {
752
+						// we've seen this version before and it's not an activation. its normal request
753
+						$req_type = EE_System::req_type_normal;
754
+					} else {// $version_is_higher === 1
755
+						$req_type = EE_System::req_type_upgrade;
756
+					}
757
+				}
758
+			}
759
+		} else {
760
+			// brand new install
761
+			$req_type = EE_System::req_type_new_activation;
762
+			delete_option($activation_indicator_option_name);
763
+		}
764
+		return $req_type;
765
+	}
766
+
767
+
768
+	/**
769
+	 * Detects if the $version_to_upgrade_to is higher than the most recent version in
770
+	 * the $activation_history_for_addon
771
+	 *
772
+	 * @param array  $activation_history_for_addon (keys are versions, values are arrays of times activated,
773
+	 *                                             sometimes containing 'unknown-date'
774
+	 * @param string $version_to_upgrade_to        (current version)
775
+	 * @return int results of version_compare( $version_to_upgrade_to, $most_recently_active_version ).
776
+	 *                                             ie, -1 if $version_to_upgrade_to is LOWER (downgrade);
777
+	 *                                             0 if $version_to_upgrade_to MATCHES (reactivation or normal request);
778
+	 *                                             1 if $version_to_upgrade_to is HIGHER (upgrade) ;
779
+	 */
780
+	private static function _new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to)
781
+	{
782
+		// find the most recently-activated version
783
+		$most_recently_active_version =
784
+			EE_System::_get_most_recently_active_version_from_activation_history($activation_history_for_addon);
785
+		return version_compare($version_to_upgrade_to, $most_recently_active_version);
786
+	}
787
+
788
+
789
+	/**
790
+	 * Gets the most recently active version listed in the activation history,
791
+	 * and if none are found (ie, it's a brand new install) returns '0.0.0.dev.000'.
792
+	 *
793
+	 * @param array $activation_history  (keys are versions, values are arrays of times activated,
794
+	 *                                   sometimes containing 'unknown-date'
795
+	 * @return string
796
+	 */
797
+	private static function _get_most_recently_active_version_from_activation_history($activation_history)
798
+	{
799
+		$most_recently_active_version_activation = '1970-01-01 00:00:00';
800
+		$most_recently_active_version = '0.0.0.dev.000';
801
+		if (is_array($activation_history)) {
802
+			foreach ($activation_history as $version => $times_activated) {
803
+				// check there is a record of when this version was activated. Otherwise,
804
+				// mark it as unknown
805
+				if (! $times_activated) {
806
+					$times_activated = array('unknown-date');
807
+				}
808
+				if (is_string($times_activated)) {
809
+					$times_activated = array($times_activated);
810
+				}
811
+				foreach ($times_activated as $an_activation) {
812
+					if (
813
+						$an_activation !== 'unknown-date'
814
+						&& $an_activation
815
+						   > $most_recently_active_version_activation
816
+					) {
817
+						$most_recently_active_version = $version;
818
+						$most_recently_active_version_activation = $an_activation === 'unknown-date'
819
+							? '1970-01-01 00:00:00'
820
+							: $an_activation;
821
+					}
822
+				}
823
+			}
824
+		}
825
+		return $most_recently_active_version;
826
+	}
827
+
828
+
829
+	/**
830
+	 * This redirects to the about EE page after activation
831
+	 *
832
+	 * @return void
833
+	 */
834
+	public function redirect_to_about_ee()
835
+	{
836
+		$notices = EE_Error::get_notices(false);
837
+		// if current user is an admin and it's not an ajax or rest request
838
+		if (
839
+			! isset($notices['errors'])
840
+			&& $this->request->isAdmin()
841
+			&& apply_filters(
842
+				'FHEE__EE_System__redirect_to_about_ee__do_redirect',
843
+				$this->capabilities->current_user_can('manage_options', 'espresso_about_default')
844
+			)
845
+		) {
846
+			$query_params = array('page' => 'espresso_about');
847
+			if (EE_System::instance()->detect_req_type() === EE_System::req_type_new_activation) {
848
+				$query_params['new_activation'] = true;
849
+			}
850
+			if (EE_System::instance()->detect_req_type() === EE_System::req_type_reactivation) {
851
+				$query_params['reactivation'] = true;
852
+			}
853
+			$url = add_query_arg($query_params, admin_url('admin.php'));
854
+			wp_safe_redirect($url);
855
+			exit();
856
+		}
857
+	}
858
+
859
+
860
+	/**
861
+	 * load_core_configuration
862
+	 * this is hooked into 'AHEE__EE_Bootstrap__load_core_configuration'
863
+	 * which runs during the WP 'plugins_loaded' action at priority 5
864
+	 *
865
+	 * @return void
866
+	 * @throws ReflectionException
867
+	 * @throws Exception
868
+	 */
869
+	public function load_core_configuration()
870
+	{
871
+		do_action('AHEE__EE_System__load_core_configuration__begin', $this);
872
+		$this->loader->getShared('EE_Load_Textdomain');
873
+		// load textdomain
874
+		EE_Load_Textdomain::load_textdomain();
875
+		// load caf stuff a chance to play during the activation process too.
876
+		$this->_maybe_brew_regular();
877
+		// load and setup EE_Config and EE_Network_Config
878
+		$config = $this->loader->getShared('EE_Config');
879
+		$this->loader->getShared('EE_Network_Config');
880
+		// setup autoloaders
881
+		// enable logging?
882
+		if ($config->admin->use_remote_logging) {
883
+			$this->loader->getShared('EE_Log');
884
+		}
885
+		// check for activation errors
886
+		$activation_errors = get_option('ee_plugin_activation_errors', false);
887
+		if ($activation_errors) {
888
+			EE_Error::add_error($activation_errors, __FILE__, __FUNCTION__, __LINE__);
889
+			update_option('ee_plugin_activation_errors', false);
890
+		}
891
+		// get model names
892
+		$this->_parse_model_names();
893
+		// configure custom post type definitions
894
+		$this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions');
895
+		$this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions');
896
+		do_action('AHEE__EE_System__load_core_configuration__complete', $this);
897
+	}
898
+
899
+
900
+	/**
901
+	 * cycles through all of the models/*.model.php files, and assembles an array of model names
902
+	 *
903
+	 * @return void
904
+	 * @throws ReflectionException
905
+	 */
906
+	private function _parse_model_names()
907
+	{
908
+		// get all the files in the EE_MODELS folder that end in .model.php
909
+		$models = glob(EE_MODELS . '*.model.php');
910
+		$model_names = array();
911
+		$non_abstract_db_models = array();
912
+		foreach ($models as $model) {
913
+			// get model classname
914
+			$classname = EEH_File::get_classname_from_filepath_with_standard_filename($model);
915
+			$short_name = str_replace('EEM_', '', $classname);
916
+			$reflectionClass = new ReflectionClass($classname);
917
+			if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
918
+				$non_abstract_db_models[ $short_name ] = $classname;
919
+			}
920
+			$model_names[ $short_name ] = $classname;
921
+		}
922
+		$this->registry->models = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
923
+		$this->registry->non_abstract_db_models = apply_filters(
924
+			'FHEE__EE_System__parse_implemented_model_names',
925
+			$non_abstract_db_models
926
+		);
927
+	}
928
+
929
+
930
+	/**
931
+	 * The purpose of this method is to simply check for a file named "caffeinated/brewing_regular.php" for any hooks
932
+	 * that need to be setup before our EE_System launches.
933
+	 *
934
+	 * @return void
935
+	 * @throws DomainException
936
+	 * @throws InvalidArgumentException
937
+	 * @throws InvalidDataTypeException
938
+	 * @throws InvalidInterfaceException
939
+	 * @throws InvalidClassException
940
+	 * @throws InvalidFilePathException
941
+	 */
942
+	private function _maybe_brew_regular()
943
+	{
944
+		/** @var Domain $domain */
945
+		$domain = DomainFactory::getShared(
946
+			new FullyQualifiedName(
947
+				'EventEspresso\core\domain\Domain'
948
+			),
949
+			array(
950
+				new FilePath(EVENT_ESPRESSO_MAIN_FILE),
951
+				Version::fromString(espresso_version()),
952
+			)
953
+		);
954
+		if ($domain->isCaffeinated()) {
955
+			require_once EE_CAFF_PATH . 'brewing_regular.php';
956
+		}
957
+	}
958
+
959
+
960
+	/**
961
+	 * @since 4.9.71.p
962
+	 * @throws Exception
963
+	 */
964
+	public function loadRouteMatchSpecifications()
965
+	{
966
+		try {
967
+			$this->loader->getShared(
968
+				'EventEspresso\core\services\route_match\RouteMatchSpecificationManager'
969
+			);
970
+		} catch (Exception $exception) {
971
+			new ExceptionStackTraceDisplay($exception);
972
+		}
973
+		do_action('AHEE__EE_System__loadRouteMatchSpecifications');
974
+	}
975
+
976
+
977
+	/**
978
+	 * loading CPT related classes earlier so that their definitions are available
979
+	 * but not performing any actual registration with WP core until load_CPTs_and_session() is called
980
+	 *
981
+	 * @since   4.10.21.p
982
+	 */
983
+	public function loadCustomPostTypes()
984
+	{
985
+		$this->register_custom_taxonomies = $this->loader->getShared(
986
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies'
987
+		);
988
+		$this->register_custom_post_types = $this->loader->getShared(
989
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes'
990
+		);
991
+		$this->register_custom_taxonomy_terms = $this->loader->getShared(
992
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms'
993
+		);
994
+		// integrate WP_Query with the EE models
995
+		$this->loader->getShared('EE_CPT_Strategy');
996
+		// load legacy EE_Request_Handler in case add-ons still need it
997
+		$this->loader->getShared('EE_Request_Handler');
998
+	}
999
+
1000
+
1001
+	/**
1002
+	 * register_shortcodes_modules_and_widgets
1003
+	 * generate lists of shortcodes and modules, then verify paths and classes
1004
+	 * This is hooked into 'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets'
1005
+	 * which runs during the WP 'plugins_loaded' action at priority 7
1006
+	 *
1007
+	 * @access public
1008
+	 * @return void
1009
+	 * @throws Exception
1010
+	 */
1011
+	public function register_shortcodes_modules_and_widgets()
1012
+	{
1013
+		if ($this->request->isFrontend() || $this->request->isIframe() || $this->request->isAjax()) {
1014
+			// load, register, and add shortcodes the new way
1015
+			$this->loader->getShared('EventEspresso\core\services\shortcodes\ShortcodesManager');
1016
+		}
1017
+		do_action('AHEE__EE_System__register_shortcodes_modules_and_widgets');
1018
+		// check for addons using old hook point
1019
+		if (has_action('AHEE__EE_System__register_shortcodes_modules_and_addons')) {
1020
+			$this->_incompatible_addon_error();
1021
+		}
1022
+	}
1023
+
1024
+
1025
+	/**
1026
+	 * _incompatible_addon_error
1027
+	 *
1028
+	 * @access public
1029
+	 * @return void
1030
+	 */
1031
+	private function _incompatible_addon_error()
1032
+	{
1033
+		// get array of classes hooking into here
1034
+		$class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook(
1035
+			'AHEE__EE_System__register_shortcodes_modules_and_addons'
1036
+		);
1037
+		if (! empty($class_names)) {
1038
+			$msg = esc_html__(
1039
+				'The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
1040
+				'event_espresso'
1041
+			);
1042
+			$msg .= '<ul>';
1043
+			foreach ($class_names as $class_name) {
1044
+				$msg .= '<li><b>Event Espresso - '
1045
+						. str_replace(
1046
+							array('EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'),
1047
+							'',
1048
+							$class_name
1049
+						) . '</b></li>';
1050
+			}
1051
+			$msg .= '</ul>';
1052
+			$msg .= esc_html__(
1053
+				'Compatibility issues can be avoided and/or resolved by keeping addons and plugins updated to the latest version.',
1054
+				'event_espresso'
1055
+			);
1056
+			// save list of incompatible addons to wp-options for later use
1057
+			add_option('ee_incompatible_addons', $class_names, '', 'no');
1058
+			if (is_admin()) {
1059
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1060
+			}
1061
+		}
1062
+	}
1063
+
1064
+
1065
+	/**
1066
+	 * brew_espresso
1067
+	 * begins the process of setting hooks for initializing EE in the correct order
1068
+	 * This is happening on the 'AHEE__EE_Bootstrap__brew_espresso' hook point
1069
+	 * which runs during the WP 'plugins_loaded' action at priority 9
1070
+	 *
1071
+	 * @return void
1072
+	 */
1073
+	public function brew_espresso()
1074
+	{
1075
+		do_action('AHEE__EE_System__brew_espresso__begin', $this);
1076
+		// load some final core systems
1077
+		add_action('init', array($this, 'set_hooks_for_core'), 1);
1078
+		add_action('init', array($this, 'perform_activations_upgrades_and_migrations'), 3);
1079
+		add_action('init', array($this, 'load_CPTs_and_session'), 5);
1080
+		add_action('init', array($this, 'load_controllers'), 7);
1081
+		add_action('init', array($this, 'core_loaded_and_ready'), 9);
1082
+		add_action('init', array($this, 'initialize'), 10);
1083
+		add_action('init', array($this, 'initialize_last'), 100);
1084
+		if (is_admin() && apply_filters('FHEE__EE_System__brew_espresso__load_pue', true)) {
1085
+			// pew pew pew
1086
+			$this->loader->getShared('EventEspresso\core\services\licensing\LicenseService');
1087
+			do_action('AHEE__EE_System__brew_espresso__after_pue_init');
1088
+		}
1089
+		do_action('AHEE__EE_System__brew_espresso__complete', $this);
1090
+	}
1091
+
1092
+
1093
+	/**
1094
+	 *    set_hooks_for_core
1095
+	 *
1096
+	 * @access public
1097
+	 * @return    void
1098
+	 * @throws EE_Error
1099
+	 */
1100
+	public function set_hooks_for_core()
1101
+	{
1102
+		$this->_deactivate_incompatible_addons();
1103
+		do_action('AHEE__EE_System__set_hooks_for_core');
1104
+		$this->loader->getShared('EventEspresso\core\domain\values\session\SessionLifespan');
1105
+		// caps need to be initialized on every request so that capability maps are set.
1106
+		// @see https://events.codebasehq.com/projects/event-espresso/tickets/8674
1107
+		$this->registry->CAP->init_caps();
1108
+	}
1109
+
1110
+
1111
+	/**
1112
+	 * Using the information gathered in EE_System::_incompatible_addon_error,
1113
+	 * deactivates any addons considered incompatible with the current version of EE
1114
+	 */
1115
+	private function _deactivate_incompatible_addons()
1116
+	{
1117
+		$incompatible_addons = get_option('ee_incompatible_addons', array());
1118
+		if (! empty($incompatible_addons)) {
1119
+			$active_plugins = get_option('active_plugins', array());
1120
+			foreach ($active_plugins as $active_plugin) {
1121
+				foreach ($incompatible_addons as $incompatible_addon) {
1122
+					if (strpos($active_plugin, $incompatible_addon) !== false) {
1123
+						$this->request->unSetRequestParams(['activate'], true);
1124
+						espresso_deactivate_plugin($active_plugin);
1125
+					}
1126
+				}
1127
+			}
1128
+		}
1129
+	}
1130
+
1131
+
1132
+	/**
1133
+	 *    perform_activations_upgrades_and_migrations
1134
+	 *
1135
+	 * @access public
1136
+	 * @return    void
1137
+	 */
1138
+	public function perform_activations_upgrades_and_migrations()
1139
+	{
1140
+		do_action('AHEE__EE_System__perform_activations_upgrades_and_migrations');
1141
+	}
1142
+
1143
+
1144
+	/**
1145
+	 * @return void
1146
+	 * @throws DomainException
1147
+	 */
1148
+	public function load_CPTs_and_session()
1149
+	{
1150
+		do_action('AHEE__EE_System__load_CPTs_and_session__start');
1151
+		$this->register_custom_taxonomies->registerCustomTaxonomies();
1152
+		$this->register_custom_post_types->registerCustomPostTypes();
1153
+		$this->register_custom_taxonomy_terms->registerCustomTaxonomyTerms();
1154
+		// load legacy Custom Post Types and Taxonomies
1155
+		$this->loader->getShared('EE_Register_CPTs');
1156
+		do_action('AHEE__EE_System__load_CPTs_and_session__complete');
1157
+	}
1158
+
1159
+
1160
+	/**
1161
+	 * load_controllers
1162
+	 * this is the best place to load any additional controllers that needs access to EE core.
1163
+	 * it is expected that all basic core EE systems, that are not dependant on the current request are loaded at this
1164
+	 * time
1165
+	 *
1166
+	 * @access public
1167
+	 * @return void
1168
+	 */
1169
+	public function load_controllers()
1170
+	{
1171
+		do_action('AHEE__EE_System__load_controllers__start');
1172
+		// let's get it started
1173
+		if (
1174
+			! $this->maintenance_mode->level()
1175
+			&& ($this->request->isFrontend() || $this->request->isFrontAjax())
1176
+		) {
1177
+			do_action('AHEE__EE_System__load_controllers__load_front_controllers');
1178
+			$this->loader->getShared('EE_Front_Controller');
1179
+		} elseif ($this->request->isAdmin() || $this->request->isAdminAjax()) {
1180
+			do_action('AHEE__EE_System__load_controllers__load_admin_controllers');
1181
+			$this->loader->getShared('EE_Admin');
1182
+		} elseif ($this->request->isWordPressHeartbeat()) {
1183
+			$this->loader->getShared('EventEspresso\core\domain\services\admin\ajax\WordpressHeartbeat');
1184
+		}
1185
+		do_action('AHEE__EE_System__load_controllers__complete');
1186
+	}
1187
+
1188
+
1189
+	/**
1190
+	 * core_loaded_and_ready
1191
+	 * all of the basic EE core should be loaded at this point and available regardless of M-Mode
1192
+	 *
1193
+	 * @access public
1194
+	 * @return void
1195
+	 * @throws Exception
1196
+	 */
1197
+	public function core_loaded_and_ready()
1198
+	{
1199
+		if (
1200
+			$this->request->isAdmin()
1201
+			|| $this->request->isFrontend()
1202
+			|| $this->request->isIframe()
1203
+			|| $this->request->isWordPressApi()
1204
+		) {
1205
+			try {
1206
+				$this->loader->getShared('EventEspresso\core\services\assets\Registry');
1207
+				$this->loader->getShared('EventEspresso\core\domain\services\assets\CoreAssetManager');
1208
+				if ($this->canLoadBlocks()) {
1209
+					$this->loader->getShared(
1210
+						'EventEspresso\core\services\editor\BlockRegistrationManager'
1211
+					);
1212
+				}
1213
+			} catch (Exception $exception) {
1214
+				new ExceptionStackTraceDisplay($exception);
1215
+			}
1216
+		}
1217
+		if (
1218
+			$this->request->isAdmin()
1219
+			|| $this->request->isEeAjax()
1220
+			|| $this->request->isFrontend()
1221
+		) {
1222
+			$this->loader->getShared('EE_Session');
1223
+		}
1224
+		do_action('AHEE__EE_System__core_loaded_and_ready');
1225
+		// always load template tags, because it's faster than checking if it's a front-end request, and many page
1226
+		// builders require these even on the front-end
1227
+		require_once EE_PUBLIC . 'template_tags.php';
1228
+		do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1229
+	}
1230
+
1231
+
1232
+	/**
1233
+	 * initialize
1234
+	 * this is the best place to begin initializing client code
1235
+	 *
1236
+	 * @access public
1237
+	 * @return void
1238
+	 */
1239
+	public function initialize()
1240
+	{
1241
+		do_action('AHEE__EE_System__initialize');
1242
+	}
1243
+
1244
+
1245
+	/**
1246
+	 * initialize_last
1247
+	 * this is run really late during the WP init hook point, and ensures that mostly everything else that needs to
1248
+	 * initialize has done so
1249
+	 *
1250
+	 * @access public
1251
+	 * @return void
1252
+	 */
1253
+	public function initialize_last()
1254
+	{
1255
+		do_action('AHEE__EE_System__initialize_last');
1256
+		/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
1257
+		$rewrite_rules = $this->loader->getShared(
1258
+			'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
1259
+		);
1260
+		$rewrite_rules->flushRewriteRules();
1261
+		add_action('admin_bar_init', array($this, 'addEspressoToolbar'));
1262
+		if (
1263
+			($this->request->isAjax() || $this->request->isAdmin())
1264
+			&& $this->maintenance_mode->models_can_query()
1265
+		) {
1266
+			$this->loader->getShared('EventEspresso\core\services\privacy\export\PersonalDataExporterManager');
1267
+			$this->loader->getShared('EventEspresso\core\services\privacy\erasure\PersonalDataEraserManager');
1268
+		}
1269
+	}
1270
+
1271
+
1272
+	/**
1273
+	 * @return void
1274
+	 * @throws EE_Error
1275
+	 */
1276
+	public function addEspressoToolbar()
1277
+	{
1278
+		$this->loader->getShared(
1279
+			'EventEspresso\core\domain\services\admin\AdminToolBar',
1280
+			array($this->registry->CAP)
1281
+		);
1282
+	}
1283
+
1284
+
1285
+	/**
1286
+	 * do_not_cache
1287
+	 * sets no cache headers and defines no cache constants for WP plugins
1288
+	 *
1289
+	 * @access public
1290
+	 * @return void
1291
+	 */
1292
+	public static function do_not_cache()
1293
+	{
1294
+		// set no cache constants
1295
+		if (! defined('DONOTCACHEPAGE')) {
1296
+			define('DONOTCACHEPAGE', true);
1297
+		}
1298
+		if (! defined('DONOTCACHCEOBJECT')) {
1299
+			define('DONOTCACHCEOBJECT', true);
1300
+		}
1301
+		if (! defined('DONOTCACHEDB')) {
1302
+			define('DONOTCACHEDB', true);
1303
+		}
1304
+		// add no cache headers
1305
+		add_action('send_headers', array('EE_System', 'nocache_headers'), 10);
1306
+		// plus a little extra for nginx and Google Chrome
1307
+		add_filter('nocache_headers', array('EE_System', 'extra_nocache_headers'), 10, 1);
1308
+		// prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes with the registration process
1309
+		remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
1310
+	}
1311
+
1312
+
1313
+	/**
1314
+	 *    extra_nocache_headers
1315
+	 *
1316
+	 * @access    public
1317
+	 * @param $headers
1318
+	 * @return    array
1319
+	 */
1320
+	public static function extra_nocache_headers($headers)
1321
+	{
1322
+		// for NGINX
1323
+		$headers['X-Accel-Expires'] = 0;
1324
+		// plus extra for Google Chrome since it doesn't seem to respect "no-cache", but WILL respect "no-store"
1325
+		$headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0';
1326
+		return $headers;
1327
+	}
1328
+
1329
+
1330
+	/**
1331
+	 *    nocache_headers
1332
+	 *
1333
+	 * @access    public
1334
+	 * @return    void
1335
+	 */
1336
+	public static function nocache_headers()
1337
+	{
1338
+		nocache_headers();
1339
+	}
1340
+
1341
+
1342
+	/**
1343
+	 * simply hooks into "wp_list_pages_exclude" filter (for wp_list_pages method) and makes sure EE critical pages are
1344
+	 * never returned with the function.
1345
+	 *
1346
+	 * @param  array $exclude_array any existing pages being excluded are in this array.
1347
+	 * @return array
1348
+	 */
1349
+	public function remove_pages_from_wp_list_pages($exclude_array)
1350
+	{
1351
+		return array_merge($exclude_array, $this->registry->CFG->core->get_critical_pages_array());
1352
+	}
1353
+
1354
+
1355
+	/**
1356
+	 * Return whether blocks can be registered/loaded or not.
1357
+	 * @return bool
1358
+	 */
1359
+	private function canLoadBlocks()
1360
+	{
1361
+		return apply_filters('FHEE__EE_System__canLoadBlocks', true)
1362
+			   && function_exists('register_block_type')
1363
+			   // don't load blocks if in the Divi page builder editor context
1364
+			   // @see https://github.com/eventespresso/event-espresso-core/issues/814
1365
+			   && ! $this->request->getRequestParam('et_fb', false);
1366
+	}
1367 1367
 }
Please login to merge, or discard this patch.
core/EE_Registry.core.php 2 patches
Indentation   +1698 added lines, -1698 removed lines patch added patch discarded remove patch
@@ -23,1703 +23,1703 @@
 block discarded – undo
23 23
 class EE_Registry implements ResettableInterface
24 24
 {
25 25
 
26
-    /**
27
-     * @var EE_Registry $_instance
28
-     */
29
-    private static $_instance;
30
-
31
-    /**
32
-     * @var EE_Dependency_Map $_dependency_map
33
-     */
34
-    protected $_dependency_map;
35
-
36
-    /**
37
-     * @var Mirror
38
-     */
39
-    private $mirror;
40
-
41
-    /**
42
-     * @var ClassInterfaceCache $class_cache
43
-     */
44
-    private $class_cache;
45
-
46
-    /**
47
-     * @var array $_class_abbreviations
48
-     */
49
-    protected $_class_abbreviations = array();
50
-
51
-    /**
52
-     * @var CommandBusInterface $BUS
53
-     */
54
-    public $BUS;
55
-
56
-    /**
57
-     * @var EE_Cart $CART
58
-     */
59
-    public $CART;
60
-
61
-    /**
62
-     * @var EE_Config $CFG
63
-     */
64
-    public $CFG;
65
-
66
-    /**
67
-     * @var EE_Network_Config $NET_CFG
68
-     */
69
-    public $NET_CFG;
70
-
71
-    /**
72
-     * RegistryContainer for storing library classes in
73
-     *
74
-     * @var RegistryContainer $LIB
75
-     */
76
-    public $LIB;
77
-
78
-    /**
79
-     * @var EE_Request_Handler $REQ
80
-     * @deprecated 4.10.14.p
81
-     */
82
-    public $REQ;
83
-
84
-    /**
85
-     * @var EE_Session $SSN
86
-     */
87
-    public $SSN;
88
-
89
-    /**
90
-     * @since 4.5.0
91
-     * @var EE_Capabilities $CAP
92
-     */
93
-    public $CAP;
94
-
95
-    /**
96
-     * @since 4.9.0
97
-     * @var EE_Message_Resource_Manager $MRM
98
-     */
99
-    public $MRM;
100
-
101
-    /**
102
-     * @var Registry $AssetsRegistry
103
-     */
104
-    public $AssetsRegistry;
105
-
106
-    /**
107
-     * RegistryContainer for holding addons which have registered themselves to work with EE core
108
-     *
109
-     * @var EE_Addon[] $addons
110
-     */
111
-    public $addons;
112
-
113
-    /**
114
-     * keys are 'short names' (eg Event), values are class names (eg 'EEM_Event')
115
-     *
116
-     * @var EEM_Base[] $models
117
-     */
118
-    public $models = array();
119
-
120
-    /**
121
-     * @var EED_Module[] $modules
122
-     */
123
-    public $modules;
124
-
125
-    /**
126
-     * @var EES_Shortcode[] $shortcodes
127
-     */
128
-    public $shortcodes;
129
-
130
-    /**
131
-     * @var WP_Widget[] $widgets
132
-     */
133
-    public $widgets;
134
-
135
-    /**
136
-     * this is an array of all implemented model names (i.e. not the parent abstract models, or models
137
-     * which don't actually fetch items from the DB in the normal way (ie, are not children of EEM_Base)).
138
-     * Keys are model "short names" (eg "Event") as used in model relations, and values are
139
-     * classnames (eg "EEM_Event")
140
-     *
141
-     * @var array $non_abstract_db_models
142
-     */
143
-    public $non_abstract_db_models = array();
144
-
145
-    /**
146
-     * internationalization for JS strings
147
-     *    usage:   EE_Registry::i18n_js_strings['string_key'] = esc_html__( 'string to translate.', 'event_espresso' );
148
-     *    in js file:  var translatedString = eei18n.string_key;
149
-     *
150
-     * @var array $i18n_js_strings
151
-     */
152
-    public static $i18n_js_strings = array();
153
-
154
-    /**
155
-     * $main_file - path to espresso.php
156
-     *
157
-     * @var array $main_file
158
-     */
159
-    public $main_file;
160
-
161
-    /**
162
-     * array of ReflectionClass objects where the key is the class name
163
-     *
164
-     * @deprecated 4.9.62.p
165
-     * @var ReflectionClass[] $_reflectors
166
-     */
167
-    public $_reflectors;
168
-
169
-    /**
170
-     * boolean flag to indicate whether or not to load/save dependencies from/to the cache
171
-     *
172
-     * @var boolean $_cache_on
173
-     */
174
-    protected $_cache_on = true;
175
-
176
-    /**
177
-     * @var ObjectIdentifier
178
-     */
179
-    private $object_identifier;
180
-
181
-
182
-    /**
183
-     * @singleton method used to instantiate class object
184
-     * @param EE_Dependency_Map|null   $dependency_map
185
-     * @param Mirror|null              $mirror
186
-     * @param ClassInterfaceCache|null $class_cache
187
-     * @param ObjectIdentifier|null    $object_identifier
188
-     * @return EE_Registry instance
189
-     */
190
-    public static function instance(
191
-        EE_Dependency_Map $dependency_map = null,
192
-        Mirror $mirror = null,
193
-        ClassInterfaceCache $class_cache = null,
194
-        ObjectIdentifier $object_identifier = null
195
-    ) {
196
-        // check if class object is instantiated
197
-        if (
198
-            ! self::$_instance instanceof EE_Registry
199
-            && $dependency_map instanceof EE_Dependency_Map
200
-            && $mirror instanceof Mirror
201
-            && $class_cache instanceof ClassInterfaceCache
202
-            && $object_identifier instanceof ObjectIdentifier
203
-        ) {
204
-            self::$_instance = new self(
205
-                $dependency_map,
206
-                $mirror,
207
-                $class_cache,
208
-                $object_identifier
209
-            );
210
-        }
211
-        return self::$_instance;
212
-    }
213
-
214
-
215
-    /**
216
-     * protected constructor to prevent direct creation
217
-     *
218
-     * @Constructor
219
-     * @param  EE_Dependency_Map  $dependency_map
220
-     * @param Mirror              $mirror
221
-     * @param ClassInterfaceCache $class_cache
222
-     * @param ObjectIdentifier    $object_identifier
223
-     */
224
-    protected function __construct(
225
-        EE_Dependency_Map $dependency_map,
226
-        Mirror $mirror,
227
-        ClassInterfaceCache $class_cache,
228
-        ObjectIdentifier $object_identifier
229
-    ) {
230
-        $this->_dependency_map = $dependency_map;
231
-        $this->mirror = $mirror;
232
-        $this->class_cache = $class_cache;
233
-        $this->object_identifier = $object_identifier;
234
-        // $registry_container = new RegistryContainer();
235
-        $this->LIB = new RegistryContainer();
236
-        $this->addons = new RegistryContainer();
237
-        $this->modules = new RegistryContainer();
238
-        $this->shortcodes = new RegistryContainer();
239
-        $this->widgets = new RegistryContainer();
240
-        add_action('EE_Load_Espresso_Core__handle_request__initialize_core_loading', array($this, 'initialize'));
241
-    }
242
-
243
-
244
-    /**
245
-     * initialize
246
-     *
247
-     * @throws OutOfBoundsException
248
-     * @throws InvalidArgumentException
249
-     * @throws InvalidInterfaceException
250
-     * @throws InvalidDataTypeException
251
-     * @throws EE_Error
252
-     * @throws ReflectionException
253
-     */
254
-    public function initialize()
255
-    {
256
-        $this->_class_abbreviations = apply_filters(
257
-            'FHEE__EE_Registry____construct___class_abbreviations',
258
-            array(
259
-                'EE_Config'                                       => 'CFG',
260
-                'EE_Session'                                      => 'SSN',
261
-                'EE_Capabilities'                                 => 'CAP',
262
-                'EE_Cart'                                         => 'CART',
263
-                'EE_Network_Config'                               => 'NET_CFG',
264
-                'EE_Request_Handler'                              => 'REQ',
265
-                'EE_Message_Resource_Manager'                     => 'MRM',
266
-                'EventEspresso\core\services\commands\CommandBus' => 'BUS',
267
-                'EventEspresso\core\services\assets\Registry'     => 'AssetsRegistry',
268
-            )
269
-        );
270
-        $this->load_core('Base', array(), true);
271
-        // add our request and response objects to the cache
272
-        $request_loader = $this->_dependency_map->class_loader(
273
-            'EventEspresso\core\services\request\Request'
274
-        );
275
-        $this->_set_cached_class(
276
-            $request_loader(),
277
-            'EventEspresso\core\services\request\Request'
278
-        );
279
-        $response_loader = $this->_dependency_map->class_loader(
280
-            'EventEspresso\core\services\request\Response'
281
-        );
282
-        $this->_set_cached_class(
283
-            $response_loader(),
284
-            'EventEspresso\core\services\request\Response'
285
-        );
286
-        add_action('AHEE__EE_System__set_hooks_for_core', array($this, 'init'));
287
-    }
288
-
289
-
290
-    /**
291
-     * @return void
292
-     */
293
-    public function init()
294
-    {
295
-        // Get current page protocol
296
-        $protocol = is_ssl() ? 'https://' : 'http://';
297
-        // Output admin-ajax.php URL with same protocol as current page
298
-        self::$i18n_js_strings['ajax_url'] = admin_url('admin-ajax.php', $protocol);
299
-        self::$i18n_js_strings['wp_debug'] = defined('WP_DEBUG') && WP_DEBUG;
300
-    }
301
-
302
-
303
-    /**
304
-     * @return array
305
-     */
306
-    public static function sanitize_i18n_js_strings()
307
-    {
308
-        $i18n_js_strings = (array) self::$i18n_js_strings;
309
-        foreach ($i18n_js_strings as $key => $value) {
310
-            if (is_scalar($value)) {
311
-                $decoded_value           = html_entity_decode((string) $value, ENT_QUOTES, 'UTF-8');
312
-                $i18n_js_strings[ $key ] = wp_strip_all_tags($decoded_value);
313
-            }
314
-        }
315
-        return $i18n_js_strings;
316
-    }
317
-
318
-
319
-    /**
320
-     * localize_i18n_js_strings
321
-     *
322
-     * @return string
323
-     */
324
-    public static function localize_i18n_js_strings()
325
-    {
326
-        $i18n_js_strings = EE_Registry::sanitize_i18n_js_strings();
327
-        return '/* <![CDATA[ */ var eei18n = ' . wp_json_encode($i18n_js_strings) . '; /* ]]> */';
328
-    }
329
-
330
-
331
-    /**
332
-     * @param mixed string | EED_Module $module
333
-     * @throws OutOfBoundsException
334
-     * @throws InvalidArgumentException
335
-     * @throws InvalidInterfaceException
336
-     * @throws InvalidDataTypeException
337
-     * @throws EE_Error
338
-     * @throws ReflectionException
339
-     */
340
-    public function add_module($module)
341
-    {
342
-        if ($module instanceof EED_Module) {
343
-            $module_class = get_class($module);
344
-            $this->modules->add($module_class, $module);
345
-        } else {
346
-            if (! class_exists('EE_Module_Request_Router', false)) {
347
-                $this->load_core('Module_Request_Router');
348
-            }
349
-            EE_Module_Request_Router::module_factory($module);
350
-        }
351
-    }
352
-
353
-
354
-    /**
355
-     * @param string $module_name
356
-     * @return mixed EED_Module | NULL
357
-     */
358
-    public function get_module($module_name = '')
359
-    {
360
-        return $this->modules->get($module_name);
361
-    }
362
-
363
-
364
-    /**
365
-     * loads core classes - must be singletons
366
-     *
367
-     * @param string $class_name - simple class name ie: session
368
-     * @param mixed  $arguments
369
-     * @param bool   $load_only
370
-     * @return mixed
371
-     * @throws InvalidInterfaceException
372
-     * @throws InvalidDataTypeException
373
-     * @throws EE_Error
374
-     * @throws ReflectionException
375
-     * @throws InvalidArgumentException
376
-     */
377
-    public function load_core($class_name, $arguments = array(), $load_only = false)
378
-    {
379
-        $core_paths = apply_filters(
380
-            'FHEE__EE_Registry__load_core__core_paths',
381
-            array(
382
-                EE_CORE,
383
-                EE_ADMIN,
384
-                EE_CPTS,
385
-                EE_CORE . 'CPTs/',
386
-                EE_CORE . 'data_migration_scripts/',
387
-                EE_CORE . 'request_stack/',
388
-                EE_CORE . 'middleware/',
389
-            )
390
-        );
391
-        // retrieve instantiated class
392
-        return $this->_load(
393
-            $core_paths,
394
-            'EE_',
395
-            $class_name,
396
-            'core',
397
-            $arguments,
398
-            false,
399
-            true,
400
-            $load_only
401
-        );
402
-    }
403
-
404
-
405
-    /**
406
-     * loads service classes
407
-     *
408
-     * @param string $class_name - simple class name ie: session
409
-     * @param mixed  $arguments
410
-     * @param bool   $load_only
411
-     * @return mixed
412
-     * @throws InvalidInterfaceException
413
-     * @throws InvalidDataTypeException
414
-     * @throws EE_Error
415
-     * @throws ReflectionException
416
-     * @throws InvalidArgumentException
417
-     */
418
-    public function load_service($class_name, $arguments = array(), $load_only = false)
419
-    {
420
-        $service_paths = apply_filters(
421
-            'FHEE__EE_Registry__load_service__service_paths',
422
-            array(
423
-                EE_CORE . 'services/',
424
-            )
425
-        );
426
-        // retrieve instantiated class
427
-        return $this->_load(
428
-            $service_paths,
429
-            'EE_',
430
-            $class_name,
431
-            'class',
432
-            $arguments,
433
-            false,
434
-            true,
435
-            $load_only
436
-        );
437
-    }
438
-
439
-
440
-    /**
441
-     * loads data_migration_scripts
442
-     *
443
-     * @param string $class_name - class name for the DMS ie: EE_DMS_Core_4_2_0
444
-     * @param mixed  $arguments
445
-     * @return EE_Data_Migration_Script_Base|mixed
446
-     * @throws InvalidInterfaceException
447
-     * @throws InvalidDataTypeException
448
-     * @throws EE_Error
449
-     * @throws ReflectionException
450
-     * @throws InvalidArgumentException
451
-     */
452
-    public function load_dms($class_name, $arguments = array())
453
-    {
454
-        // retrieve instantiated class
455
-        return $this->_load(
456
-            EE_Data_Migration_Manager::instance()->get_data_migration_script_folders(),
457
-            'EE_DMS_',
458
-            $class_name,
459
-            'dms',
460
-            $arguments,
461
-            false,
462
-            false
463
-        );
464
-    }
465
-
466
-
467
-    /**
468
-     * loads object creating classes - must be singletons
469
-     *
470
-     * @param string $class_name - simple class name ie: attendee
471
-     * @param mixed  $arguments  - an array of arguments to pass to the class
472
-     * @param bool   $from_db    - some classes are instantiated from the db and thus call a different method to
473
-     *                           instantiate
474
-     * @param bool   $cache      if you don't want the class to be stored in the internal cache (non-persistent) then
475
-     *                           set this to FALSE (ie. when instantiating model objects from client in a loop)
476
-     * @param bool   $load_only  whether or not to just load the file and NOT instantiate, or load AND instantiate
477
-     *                           (default)
478
-     * @return EE_Base_Class | bool
479
-     * @throws InvalidInterfaceException
480
-     * @throws InvalidDataTypeException
481
-     * @throws EE_Error
482
-     * @throws ReflectionException
483
-     * @throws InvalidArgumentException
484
-     */
485
-    public function load_class($class_name, $arguments = array(), $from_db = false, $cache = true, $load_only = false)
486
-    {
487
-        $paths = apply_filters(
488
-            'FHEE__EE_Registry__load_class__paths',
489
-            array(
490
-                EE_CORE,
491
-                EE_CLASSES,
492
-                EE_BUSINESS,
493
-            )
494
-        );
495
-        // retrieve instantiated class
496
-        return $this->_load(
497
-            $paths,
498
-            'EE_',
499
-            $class_name,
500
-            'class',
501
-            $arguments,
502
-            $from_db,
503
-            $cache,
504
-            $load_only
505
-        );
506
-    }
507
-
508
-
509
-    /**
510
-     * loads helper classes - must be singletons
511
-     *
512
-     * @param string $class_name - simple class name ie: price
513
-     * @param mixed  $arguments
514
-     * @param bool   $load_only
515
-     * @return EEH_Base | bool
516
-     * @throws InvalidInterfaceException
517
-     * @throws InvalidDataTypeException
518
-     * @throws EE_Error
519
-     * @throws ReflectionException
520
-     * @throws InvalidArgumentException
521
-     */
522
-    public function load_helper($class_name, $arguments = array(), $load_only = true)
523
-    {
524
-        // todo: add doing_it_wrong() in a few versions after all addons have had calls to this method removed
525
-        $helper_paths = apply_filters('FHEE__EE_Registry__load_helper__helper_paths', array(EE_HELPERS));
526
-        // retrieve instantiated class
527
-        return $this->_load(
528
-            $helper_paths,
529
-            'EEH_',
530
-            $class_name,
531
-            'helper',
532
-            $arguments,
533
-            false,
534
-            true,
535
-            $load_only
536
-        );
537
-    }
538
-
539
-
540
-    /**
541
-     * loads core classes - must be singletons
542
-     *
543
-     * @param string $class_name - simple class name ie: session
544
-     * @param mixed  $arguments
545
-     * @param bool   $load_only
546
-     * @param bool   $cache      whether to cache the object or not.
547
-     * @return mixed
548
-     * @throws InvalidInterfaceException
549
-     * @throws InvalidDataTypeException
550
-     * @throws EE_Error
551
-     * @throws ReflectionException
552
-     * @throws InvalidArgumentException
553
-     */
554
-    public function load_lib($class_name, $arguments = array(), $load_only = false, $cache = true)
555
-    {
556
-        $paths = array(
557
-            EE_LIBRARIES,
558
-            EE_LIBRARIES . 'messages/',
559
-            EE_LIBRARIES . 'shortcodes/',
560
-            EE_LIBRARIES . 'qtips/',
561
-            EE_LIBRARIES . 'payment_methods/',
562
-        );
563
-        // retrieve instantiated class
564
-        return $this->_load(
565
-            $paths,
566
-            'EE_',
567
-            $class_name,
568
-            'lib',
569
-            $arguments,
570
-            false,
571
-            $cache,
572
-            $load_only
573
-        );
574
-    }
575
-
576
-
577
-    /**
578
-     * loads model classes - must be singletons
579
-     *
580
-     * @param string $class_name - simple class name ie: price
581
-     * @param mixed  $arguments
582
-     * @param bool   $load_only
583
-     * @return EEM_Base | bool
584
-     * @throws InvalidInterfaceException
585
-     * @throws InvalidDataTypeException
586
-     * @throws EE_Error
587
-     * @throws ReflectionException
588
-     * @throws InvalidArgumentException
589
-     */
590
-    public function load_model($class_name, $arguments = array(), $load_only = false)
591
-    {
592
-        $paths = apply_filters(
593
-            'FHEE__EE_Registry__load_model__paths',
594
-            array(
595
-                EE_MODELS,
596
-                EE_CORE,
597
-            )
598
-        );
599
-        // retrieve instantiated class
600
-        return $this->_load(
601
-            $paths,
602
-            'EEM_',
603
-            $class_name,
604
-            'model',
605
-            $arguments,
606
-            false,
607
-            true,
608
-            $load_only
609
-        );
610
-    }
611
-
612
-
613
-    /**
614
-     * loads model classes - must be singletons
615
-     *
616
-     * @param string $class_name - simple class name ie: price
617
-     * @param mixed  $arguments
618
-     * @param bool   $load_only
619
-     * @return mixed | bool
620
-     * @throws InvalidInterfaceException
621
-     * @throws InvalidDataTypeException
622
-     * @throws EE_Error
623
-     * @throws ReflectionException
624
-     * @throws InvalidArgumentException
625
-     */
626
-    public function load_model_class($class_name, $arguments = array(), $load_only = true)
627
-    {
628
-        $paths = array(
629
-            EE_MODELS . 'fields/',
630
-            EE_MODELS . 'helpers/',
631
-            EE_MODELS . 'relations/',
632
-            EE_MODELS . 'strategies/',
633
-        );
634
-        // retrieve instantiated class
635
-        return $this->_load(
636
-            $paths,
637
-            'EE_',
638
-            $class_name,
639
-            '',
640
-            $arguments,
641
-            false,
642
-            true,
643
-            $load_only
644
-        );
645
-    }
646
-
647
-
648
-    /**
649
-     * Determines if $model_name is the name of an actual EE model.
650
-     *
651
-     * @param string $model_name like Event, Attendee, Question_Group_Question, etc.
652
-     * @return boolean
653
-     */
654
-    public function is_model_name($model_name)
655
-    {
656
-        return isset($this->models[ $model_name ]);
657
-    }
658
-
659
-
660
-    /**
661
-     * generic class loader
662
-     *
663
-     * @param string $path_to_file - directory path to file location, not including filename
664
-     * @param string $file_name    - file name  ie:  my_file.php, including extension
665
-     * @param string $type         - file type - core? class? helper? model?
666
-     * @param mixed  $arguments
667
-     * @param bool   $load_only
668
-     * @return mixed
669
-     * @throws InvalidInterfaceException
670
-     * @throws InvalidDataTypeException
671
-     * @throws EE_Error
672
-     * @throws ReflectionException
673
-     * @throws InvalidArgumentException
674
-     */
675
-    public function load_file($path_to_file, $file_name, $type = '', $arguments = array(), $load_only = true)
676
-    {
677
-        // retrieve instantiated class
678
-        return $this->_load(
679
-            $path_to_file,
680
-            '',
681
-            $file_name,
682
-            $type,
683
-            $arguments,
684
-            false,
685
-            true,
686
-            $load_only
687
-        );
688
-    }
689
-
690
-
691
-    /**
692
-     * @param string $path_to_file - directory path to file location, not including filename
693
-     * @param string $class_name   - full class name  ie:  My_Class
694
-     * @param string $type         - file type - core? class? helper? model?
695
-     * @param mixed  $arguments
696
-     * @param bool   $load_only
697
-     * @return bool|EE_Addon|object
698
-     * @throws InvalidInterfaceException
699
-     * @throws InvalidDataTypeException
700
-     * @throws EE_Error
701
-     * @throws ReflectionException
702
-     * @throws InvalidArgumentException
703
-     */
704
-    public function load_addon($path_to_file, $class_name, $type = 'class', $arguments = array(), $load_only = false)
705
-    {
706
-        // retrieve instantiated class
707
-        return $this->_load(
708
-            $path_to_file,
709
-            'addon',
710
-            $class_name,
711
-            $type,
712
-            $arguments,
713
-            false,
714
-            true,
715
-            $load_only
716
-        );
717
-    }
718
-
719
-
720
-    /**
721
-     * instantiates, caches, and automatically resolves dependencies
722
-     * for classes that use a Fully Qualified Class Name.
723
-     * if the class is not capable of being loaded using PSR-4 autoloading,
724
-     * then you need to use one of the existing load_*() methods
725
-     * which can resolve the classname and filepath from the passed arguments
726
-     *
727
-     * @param bool|string $class_name   Fully Qualified Class Name
728
-     * @param array       $arguments    an argument, or array of arguments to pass to the class upon instantiation
729
-     * @param bool        $cache        whether to cache the instantiated object for reuse
730
-     * @param bool        $from_db      some classes are instantiated from the db
731
-     *                                  and thus call a different method to instantiate
732
-     * @param bool        $load_only    if true, will only load the file, but will NOT instantiate an object
733
-     * @param bool|string $addon        if true, will cache the object in the EE_Registry->$addons array
734
-     * @return bool|null|mixed          null = failure to load or instantiate class object.
735
-     *                                  object = class loaded and instantiated successfully.
736
-     *                                  bool = fail or success when $load_only is true
737
-     * @throws InvalidInterfaceException
738
-     * @throws InvalidDataTypeException
739
-     * @throws EE_Error
740
-     * @throws ReflectionException
741
-     * @throws InvalidArgumentException
742
-     */
743
-    public function create(
744
-        $class_name = false,
745
-        $arguments = array(),
746
-        $cache = false,
747
-        $from_db = false,
748
-        $load_only = false,
749
-        $addon = false
750
-    ) {
751
-        $class_name = ltrim($class_name, '\\');
752
-        $class_name = $this->class_cache->getFqnForAlias($class_name);
753
-        $class_exists = $this->loadOrVerifyClassExists($class_name, $arguments);
754
-        // if a non-FQCN was passed, then
755
-        // verifyClassExists() might return an object
756
-        // or it could return null if the class just could not be found anywhere
757
-        if ($class_exists instanceof $class_name || $class_exists === null) {
758
-            // either way, return the results
759
-            return $class_exists;
760
-        }
761
-        $class_name = $class_exists;
762
-        // if we're only loading the class and it already exists, then let's just return true immediately
763
-        if ($load_only) {
764
-            return true;
765
-        }
766
-        $addon = $addon ? 'addon' : '';
767
-        // $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
768
-        // $cache is controlled by individual calls to separate Registry loader methods like load_class()
769
-        // $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
770
-        if ($this->_cache_on && $cache && ! $load_only) {
771
-            // return object if it's already cached
772
-            $cached_class = $this->_get_cached_class($class_name, $addon, $arguments);
773
-            if ($cached_class !== null) {
774
-                return $cached_class;
775
-            }
776
-        }// obtain the loader method from the dependency map
777
-        $loader = $this->_dependency_map->class_loader($class_name);// instantiate the requested object
778
-        if ($loader instanceof Closure) {
779
-            $class_obj = $loader($arguments);
780
-        } else {
781
-            if ($loader && method_exists($this, $loader)) {
782
-                $class_obj = $this->{$loader}($class_name, $arguments);
783
-            } else {
784
-                $class_obj = $this->_create_object($class_name, $arguments, $addon, $from_db);
785
-            }
786
-        }
787
-        if (($this->_cache_on && $cache) || $this->get_class_abbreviation($class_name, '')) {
788
-            // save it for later... kinda like gum  { : $
789
-            $this->_set_cached_class(
790
-                $class_obj,
791
-                $class_name,
792
-                $addon,
793
-                $from_db,
794
-                $arguments
795
-            );
796
-        }
797
-        $this->_cache_on = true;
798
-        return $class_obj;
799
-    }
800
-
801
-
802
-    /**
803
-     * Recursively checks that a class exists and potentially attempts to load classes with non-FQCNs
804
-     *
805
-     * @param string|object $class_name
806
-     * @param array         $arguments
807
-     * @param int           $attempt
808
-     * @return mixed
809
-     */
810
-    private function loadOrVerifyClassExists($class_name, array $arguments, $attempt = 1)
811
-    {
812
-        if (is_object($class_name) || class_exists($class_name)) {
813
-            return $class_name;
814
-        }
815
-        switch ($attempt) {
816
-            case 1:
817
-                // if it's a FQCN then maybe the class is registered with a preceding \
818
-                $class_name = strpos($class_name, '\\') !== false
819
-                    ? '\\' . ltrim($class_name, '\\')
820
-                    : $class_name;
821
-                break;
822
-            case 2:
823
-                //
824
-                $loader = $this->_dependency_map->class_loader($class_name);
825
-                if ($loader && method_exists($this, $loader)) {
826
-                    return $this->{$loader}($class_name, $arguments);
827
-                }
828
-                break;
829
-            case 3:
830
-            default:
831
-                return null;
832
-        }
833
-        $attempt++;
834
-        return $this->loadOrVerifyClassExists($class_name, $arguments, $attempt);
835
-    }
836
-
837
-
838
-    /**
839
-     * instantiates, caches, and injects dependencies for classes
840
-     *
841
-     * @param array       $file_paths   an array of paths to folders to look in
842
-     * @param string      $class_prefix EE  or EEM or... ???
843
-     * @param bool|string $class_name   $class name
844
-     * @param string      $type         file type - core? class? helper? model?
845
-     * @param mixed       $arguments    an argument or array of arguments to pass to the class upon instantiation
846
-     * @param bool        $from_db      some classes are instantiated from the db
847
-     *                                  and thus call a different method to instantiate
848
-     * @param bool        $cache        whether to cache the instantiated object for reuse
849
-     * @param bool        $load_only    if true, will only load the file, but will NOT instantiate an object
850
-     * @return bool|null|object null = failure to load or instantiate class object.
851
-     *                                  object = class loaded and instantiated successfully.
852
-     *                                  bool = fail or success when $load_only is true
853
-     * @throws EE_Error
854
-     * @throws ReflectionException
855
-     * @throws InvalidInterfaceException
856
-     * @throws InvalidDataTypeException
857
-     * @throws InvalidArgumentException
858
-     */
859
-    protected function _load(
860
-        $file_paths = array(),
861
-        $class_prefix = 'EE_',
862
-        $class_name = false,
863
-        $type = 'class',
864
-        $arguments = array(),
865
-        $from_db = false,
866
-        $cache = true,
867
-        $load_only = false
868
-    ) {
869
-        $class_name = ltrim($class_name, '\\');
870
-        // strip php file extension
871
-        $class_name = str_replace('.php', '', trim($class_name));
872
-        // does the class have a prefix ?
873
-        if (! empty($class_prefix) && $class_prefix !== 'addon') {
874
-            // make sure $class_prefix is uppercase
875
-            $class_prefix = strtoupper(trim($class_prefix));
876
-            // add class prefix ONCE!!!
877
-            $class_name = $class_prefix . str_replace($class_prefix, '', $class_name);
878
-        }
879
-        $class_name = $this->class_cache->getFqnForAlias($class_name);
880
-        $class_exists = class_exists($class_name, false);
881
-        // if we're only loading the class and it already exists, then let's just return true immediately
882
-        if ($load_only && $class_exists) {
883
-            return true;
884
-        }
885
-        $arguments = is_array($arguments) ? $arguments : array($arguments);
886
-        // $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
887
-        // $cache is controlled by individual calls to separate Registry loader methods like load_class()
888
-        // $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
889
-        if ($this->_cache_on && $cache && ! $load_only) {
890
-            // return object if it's already cached
891
-            $cached_class = $this->_get_cached_class($class_name, $class_prefix, $arguments);
892
-            if ($cached_class !== null) {
893
-                return $cached_class;
894
-            }
895
-        }
896
-        // if the class doesn't already exist.. then we need to try and find the file and load it
897
-        if (! $class_exists) {
898
-            // get full path to file
899
-            $path = $this->_resolve_path($class_name, $type, $file_paths);
900
-            // load the file
901
-            $loaded = $this->_require_file($path, $class_name, $type, $file_paths);
902
-            // if we are only loading a file but NOT instantiating an object
903
-            // then return boolean for whether class was loaded or not
904
-            if ($load_only) {
905
-                return $loaded;
906
-            }
907
-            // if an object was expected but loading failed, then return nothing
908
-            if (! $loaded) {
909
-                return null;
910
-            }
911
-        }
912
-        // instantiate the requested object
913
-        $class_obj = $this->_create_object($class_name, $arguments, $type, $from_db);
914
-        if ($this->_cache_on && $cache) {
915
-            // save it for later... kinda like gum  { : $
916
-            $this->_set_cached_class(
917
-                $class_obj,
918
-                $class_name,
919
-                $class_prefix,
920
-                $from_db,
921
-                $arguments
922
-            );
923
-        }
924
-        $this->_cache_on = true;
925
-        return $class_obj;
926
-    }
927
-
928
-
929
-    /**
930
-     * @param string $class_name
931
-     * @param string $default have to specify something, but not anything that will conflict
932
-     * @return mixed|string
933
-     */
934
-    protected function get_class_abbreviation($class_name, $default = 'FANCY_BATMAN_PANTS')
935
-    {
936
-        return isset($this->_class_abbreviations[ $class_name ])
937
-            ? $this->_class_abbreviations[ $class_name ]
938
-            : $default;
939
-    }
940
-
941
-
942
-    /**
943
-     * attempts to find a cached version of the requested class
944
-     * by looking in the following places:
945
-     *        $this->{$class_abbreviation}            ie:    $this->CART
946
-     *        $this->{$class_name}                        ie:    $this->Some_Class
947
-     *        $this->LIB->{$class_name}                ie:    $this->LIB->Some_Class
948
-     *        $this->addon->{$class_name}    ie:    $this->addon->Some_Addon_Class
949
-     *
950
-     * @param string $class_name
951
-     * @param string $class_prefix
952
-     * @param array  $arguments
953
-     * @return mixed
954
-     */
955
-    protected function _get_cached_class(
956
-        $class_name,
957
-        $class_prefix = '',
958
-        $arguments = array()
959
-    ) {
960
-        if ($class_name === 'EE_Registry') {
961
-            return $this;
962
-        }
963
-        $class_abbreviation = $this->get_class_abbreviation($class_name);
964
-        // check if class has already been loaded, and return it if it has been
965
-        if (isset($this->{$class_abbreviation})) {
966
-            return $this->{$class_abbreviation};
967
-        }
968
-        $class_name = str_replace('\\', '_', $class_name);
969
-        if (isset($this->{$class_name})) {
970
-            return $this->{$class_name};
971
-        }
972
-        if ($class_prefix === 'addon' && $this->addons->has($class_name)) {
973
-            return $this->addons->get($class_name);
974
-        }
975
-        $object_identifier = $this->object_identifier->getIdentifier($class_name, $arguments);
976
-        if ($this->LIB->has($object_identifier)) {
977
-            return $this->LIB->get($object_identifier);
978
-        }
979
-        foreach ($this->LIB as $key => $object) {
980
-            if (
26
+	/**
27
+	 * @var EE_Registry $_instance
28
+	 */
29
+	private static $_instance;
30
+
31
+	/**
32
+	 * @var EE_Dependency_Map $_dependency_map
33
+	 */
34
+	protected $_dependency_map;
35
+
36
+	/**
37
+	 * @var Mirror
38
+	 */
39
+	private $mirror;
40
+
41
+	/**
42
+	 * @var ClassInterfaceCache $class_cache
43
+	 */
44
+	private $class_cache;
45
+
46
+	/**
47
+	 * @var array $_class_abbreviations
48
+	 */
49
+	protected $_class_abbreviations = array();
50
+
51
+	/**
52
+	 * @var CommandBusInterface $BUS
53
+	 */
54
+	public $BUS;
55
+
56
+	/**
57
+	 * @var EE_Cart $CART
58
+	 */
59
+	public $CART;
60
+
61
+	/**
62
+	 * @var EE_Config $CFG
63
+	 */
64
+	public $CFG;
65
+
66
+	/**
67
+	 * @var EE_Network_Config $NET_CFG
68
+	 */
69
+	public $NET_CFG;
70
+
71
+	/**
72
+	 * RegistryContainer for storing library classes in
73
+	 *
74
+	 * @var RegistryContainer $LIB
75
+	 */
76
+	public $LIB;
77
+
78
+	/**
79
+	 * @var EE_Request_Handler $REQ
80
+	 * @deprecated 4.10.14.p
81
+	 */
82
+	public $REQ;
83
+
84
+	/**
85
+	 * @var EE_Session $SSN
86
+	 */
87
+	public $SSN;
88
+
89
+	/**
90
+	 * @since 4.5.0
91
+	 * @var EE_Capabilities $CAP
92
+	 */
93
+	public $CAP;
94
+
95
+	/**
96
+	 * @since 4.9.0
97
+	 * @var EE_Message_Resource_Manager $MRM
98
+	 */
99
+	public $MRM;
100
+
101
+	/**
102
+	 * @var Registry $AssetsRegistry
103
+	 */
104
+	public $AssetsRegistry;
105
+
106
+	/**
107
+	 * RegistryContainer for holding addons which have registered themselves to work with EE core
108
+	 *
109
+	 * @var EE_Addon[] $addons
110
+	 */
111
+	public $addons;
112
+
113
+	/**
114
+	 * keys are 'short names' (eg Event), values are class names (eg 'EEM_Event')
115
+	 *
116
+	 * @var EEM_Base[] $models
117
+	 */
118
+	public $models = array();
119
+
120
+	/**
121
+	 * @var EED_Module[] $modules
122
+	 */
123
+	public $modules;
124
+
125
+	/**
126
+	 * @var EES_Shortcode[] $shortcodes
127
+	 */
128
+	public $shortcodes;
129
+
130
+	/**
131
+	 * @var WP_Widget[] $widgets
132
+	 */
133
+	public $widgets;
134
+
135
+	/**
136
+	 * this is an array of all implemented model names (i.e. not the parent abstract models, or models
137
+	 * which don't actually fetch items from the DB in the normal way (ie, are not children of EEM_Base)).
138
+	 * Keys are model "short names" (eg "Event") as used in model relations, and values are
139
+	 * classnames (eg "EEM_Event")
140
+	 *
141
+	 * @var array $non_abstract_db_models
142
+	 */
143
+	public $non_abstract_db_models = array();
144
+
145
+	/**
146
+	 * internationalization for JS strings
147
+	 *    usage:   EE_Registry::i18n_js_strings['string_key'] = esc_html__( 'string to translate.', 'event_espresso' );
148
+	 *    in js file:  var translatedString = eei18n.string_key;
149
+	 *
150
+	 * @var array $i18n_js_strings
151
+	 */
152
+	public static $i18n_js_strings = array();
153
+
154
+	/**
155
+	 * $main_file - path to espresso.php
156
+	 *
157
+	 * @var array $main_file
158
+	 */
159
+	public $main_file;
160
+
161
+	/**
162
+	 * array of ReflectionClass objects where the key is the class name
163
+	 *
164
+	 * @deprecated 4.9.62.p
165
+	 * @var ReflectionClass[] $_reflectors
166
+	 */
167
+	public $_reflectors;
168
+
169
+	/**
170
+	 * boolean flag to indicate whether or not to load/save dependencies from/to the cache
171
+	 *
172
+	 * @var boolean $_cache_on
173
+	 */
174
+	protected $_cache_on = true;
175
+
176
+	/**
177
+	 * @var ObjectIdentifier
178
+	 */
179
+	private $object_identifier;
180
+
181
+
182
+	/**
183
+	 * @singleton method used to instantiate class object
184
+	 * @param EE_Dependency_Map|null   $dependency_map
185
+	 * @param Mirror|null              $mirror
186
+	 * @param ClassInterfaceCache|null $class_cache
187
+	 * @param ObjectIdentifier|null    $object_identifier
188
+	 * @return EE_Registry instance
189
+	 */
190
+	public static function instance(
191
+		EE_Dependency_Map $dependency_map = null,
192
+		Mirror $mirror = null,
193
+		ClassInterfaceCache $class_cache = null,
194
+		ObjectIdentifier $object_identifier = null
195
+	) {
196
+		// check if class object is instantiated
197
+		if (
198
+			! self::$_instance instanceof EE_Registry
199
+			&& $dependency_map instanceof EE_Dependency_Map
200
+			&& $mirror instanceof Mirror
201
+			&& $class_cache instanceof ClassInterfaceCache
202
+			&& $object_identifier instanceof ObjectIdentifier
203
+		) {
204
+			self::$_instance = new self(
205
+				$dependency_map,
206
+				$mirror,
207
+				$class_cache,
208
+				$object_identifier
209
+			);
210
+		}
211
+		return self::$_instance;
212
+	}
213
+
214
+
215
+	/**
216
+	 * protected constructor to prevent direct creation
217
+	 *
218
+	 * @Constructor
219
+	 * @param  EE_Dependency_Map  $dependency_map
220
+	 * @param Mirror              $mirror
221
+	 * @param ClassInterfaceCache $class_cache
222
+	 * @param ObjectIdentifier    $object_identifier
223
+	 */
224
+	protected function __construct(
225
+		EE_Dependency_Map $dependency_map,
226
+		Mirror $mirror,
227
+		ClassInterfaceCache $class_cache,
228
+		ObjectIdentifier $object_identifier
229
+	) {
230
+		$this->_dependency_map = $dependency_map;
231
+		$this->mirror = $mirror;
232
+		$this->class_cache = $class_cache;
233
+		$this->object_identifier = $object_identifier;
234
+		// $registry_container = new RegistryContainer();
235
+		$this->LIB = new RegistryContainer();
236
+		$this->addons = new RegistryContainer();
237
+		$this->modules = new RegistryContainer();
238
+		$this->shortcodes = new RegistryContainer();
239
+		$this->widgets = new RegistryContainer();
240
+		add_action('EE_Load_Espresso_Core__handle_request__initialize_core_loading', array($this, 'initialize'));
241
+	}
242
+
243
+
244
+	/**
245
+	 * initialize
246
+	 *
247
+	 * @throws OutOfBoundsException
248
+	 * @throws InvalidArgumentException
249
+	 * @throws InvalidInterfaceException
250
+	 * @throws InvalidDataTypeException
251
+	 * @throws EE_Error
252
+	 * @throws ReflectionException
253
+	 */
254
+	public function initialize()
255
+	{
256
+		$this->_class_abbreviations = apply_filters(
257
+			'FHEE__EE_Registry____construct___class_abbreviations',
258
+			array(
259
+				'EE_Config'                                       => 'CFG',
260
+				'EE_Session'                                      => 'SSN',
261
+				'EE_Capabilities'                                 => 'CAP',
262
+				'EE_Cart'                                         => 'CART',
263
+				'EE_Network_Config'                               => 'NET_CFG',
264
+				'EE_Request_Handler'                              => 'REQ',
265
+				'EE_Message_Resource_Manager'                     => 'MRM',
266
+				'EventEspresso\core\services\commands\CommandBus' => 'BUS',
267
+				'EventEspresso\core\services\assets\Registry'     => 'AssetsRegistry',
268
+			)
269
+		);
270
+		$this->load_core('Base', array(), true);
271
+		// add our request and response objects to the cache
272
+		$request_loader = $this->_dependency_map->class_loader(
273
+			'EventEspresso\core\services\request\Request'
274
+		);
275
+		$this->_set_cached_class(
276
+			$request_loader(),
277
+			'EventEspresso\core\services\request\Request'
278
+		);
279
+		$response_loader = $this->_dependency_map->class_loader(
280
+			'EventEspresso\core\services\request\Response'
281
+		);
282
+		$this->_set_cached_class(
283
+			$response_loader(),
284
+			'EventEspresso\core\services\request\Response'
285
+		);
286
+		add_action('AHEE__EE_System__set_hooks_for_core', array($this, 'init'));
287
+	}
288
+
289
+
290
+	/**
291
+	 * @return void
292
+	 */
293
+	public function init()
294
+	{
295
+		// Get current page protocol
296
+		$protocol = is_ssl() ? 'https://' : 'http://';
297
+		// Output admin-ajax.php URL with same protocol as current page
298
+		self::$i18n_js_strings['ajax_url'] = admin_url('admin-ajax.php', $protocol);
299
+		self::$i18n_js_strings['wp_debug'] = defined('WP_DEBUG') && WP_DEBUG;
300
+	}
301
+
302
+
303
+	/**
304
+	 * @return array
305
+	 */
306
+	public static function sanitize_i18n_js_strings()
307
+	{
308
+		$i18n_js_strings = (array) self::$i18n_js_strings;
309
+		foreach ($i18n_js_strings as $key => $value) {
310
+			if (is_scalar($value)) {
311
+				$decoded_value           = html_entity_decode((string) $value, ENT_QUOTES, 'UTF-8');
312
+				$i18n_js_strings[ $key ] = wp_strip_all_tags($decoded_value);
313
+			}
314
+		}
315
+		return $i18n_js_strings;
316
+	}
317
+
318
+
319
+	/**
320
+	 * localize_i18n_js_strings
321
+	 *
322
+	 * @return string
323
+	 */
324
+	public static function localize_i18n_js_strings()
325
+	{
326
+		$i18n_js_strings = EE_Registry::sanitize_i18n_js_strings();
327
+		return '/* <![CDATA[ */ var eei18n = ' . wp_json_encode($i18n_js_strings) . '; /* ]]> */';
328
+	}
329
+
330
+
331
+	/**
332
+	 * @param mixed string | EED_Module $module
333
+	 * @throws OutOfBoundsException
334
+	 * @throws InvalidArgumentException
335
+	 * @throws InvalidInterfaceException
336
+	 * @throws InvalidDataTypeException
337
+	 * @throws EE_Error
338
+	 * @throws ReflectionException
339
+	 */
340
+	public function add_module($module)
341
+	{
342
+		if ($module instanceof EED_Module) {
343
+			$module_class = get_class($module);
344
+			$this->modules->add($module_class, $module);
345
+		} else {
346
+			if (! class_exists('EE_Module_Request_Router', false)) {
347
+				$this->load_core('Module_Request_Router');
348
+			}
349
+			EE_Module_Request_Router::module_factory($module);
350
+		}
351
+	}
352
+
353
+
354
+	/**
355
+	 * @param string $module_name
356
+	 * @return mixed EED_Module | NULL
357
+	 */
358
+	public function get_module($module_name = '')
359
+	{
360
+		return $this->modules->get($module_name);
361
+	}
362
+
363
+
364
+	/**
365
+	 * loads core classes - must be singletons
366
+	 *
367
+	 * @param string $class_name - simple class name ie: session
368
+	 * @param mixed  $arguments
369
+	 * @param bool   $load_only
370
+	 * @return mixed
371
+	 * @throws InvalidInterfaceException
372
+	 * @throws InvalidDataTypeException
373
+	 * @throws EE_Error
374
+	 * @throws ReflectionException
375
+	 * @throws InvalidArgumentException
376
+	 */
377
+	public function load_core($class_name, $arguments = array(), $load_only = false)
378
+	{
379
+		$core_paths = apply_filters(
380
+			'FHEE__EE_Registry__load_core__core_paths',
381
+			array(
382
+				EE_CORE,
383
+				EE_ADMIN,
384
+				EE_CPTS,
385
+				EE_CORE . 'CPTs/',
386
+				EE_CORE . 'data_migration_scripts/',
387
+				EE_CORE . 'request_stack/',
388
+				EE_CORE . 'middleware/',
389
+			)
390
+		);
391
+		// retrieve instantiated class
392
+		return $this->_load(
393
+			$core_paths,
394
+			'EE_',
395
+			$class_name,
396
+			'core',
397
+			$arguments,
398
+			false,
399
+			true,
400
+			$load_only
401
+		);
402
+	}
403
+
404
+
405
+	/**
406
+	 * loads service classes
407
+	 *
408
+	 * @param string $class_name - simple class name ie: session
409
+	 * @param mixed  $arguments
410
+	 * @param bool   $load_only
411
+	 * @return mixed
412
+	 * @throws InvalidInterfaceException
413
+	 * @throws InvalidDataTypeException
414
+	 * @throws EE_Error
415
+	 * @throws ReflectionException
416
+	 * @throws InvalidArgumentException
417
+	 */
418
+	public function load_service($class_name, $arguments = array(), $load_only = false)
419
+	{
420
+		$service_paths = apply_filters(
421
+			'FHEE__EE_Registry__load_service__service_paths',
422
+			array(
423
+				EE_CORE . 'services/',
424
+			)
425
+		);
426
+		// retrieve instantiated class
427
+		return $this->_load(
428
+			$service_paths,
429
+			'EE_',
430
+			$class_name,
431
+			'class',
432
+			$arguments,
433
+			false,
434
+			true,
435
+			$load_only
436
+		);
437
+	}
438
+
439
+
440
+	/**
441
+	 * loads data_migration_scripts
442
+	 *
443
+	 * @param string $class_name - class name for the DMS ie: EE_DMS_Core_4_2_0
444
+	 * @param mixed  $arguments
445
+	 * @return EE_Data_Migration_Script_Base|mixed
446
+	 * @throws InvalidInterfaceException
447
+	 * @throws InvalidDataTypeException
448
+	 * @throws EE_Error
449
+	 * @throws ReflectionException
450
+	 * @throws InvalidArgumentException
451
+	 */
452
+	public function load_dms($class_name, $arguments = array())
453
+	{
454
+		// retrieve instantiated class
455
+		return $this->_load(
456
+			EE_Data_Migration_Manager::instance()->get_data_migration_script_folders(),
457
+			'EE_DMS_',
458
+			$class_name,
459
+			'dms',
460
+			$arguments,
461
+			false,
462
+			false
463
+		);
464
+	}
465
+
466
+
467
+	/**
468
+	 * loads object creating classes - must be singletons
469
+	 *
470
+	 * @param string $class_name - simple class name ie: attendee
471
+	 * @param mixed  $arguments  - an array of arguments to pass to the class
472
+	 * @param bool   $from_db    - some classes are instantiated from the db and thus call a different method to
473
+	 *                           instantiate
474
+	 * @param bool   $cache      if you don't want the class to be stored in the internal cache (non-persistent) then
475
+	 *                           set this to FALSE (ie. when instantiating model objects from client in a loop)
476
+	 * @param bool   $load_only  whether or not to just load the file and NOT instantiate, or load AND instantiate
477
+	 *                           (default)
478
+	 * @return EE_Base_Class | bool
479
+	 * @throws InvalidInterfaceException
480
+	 * @throws InvalidDataTypeException
481
+	 * @throws EE_Error
482
+	 * @throws ReflectionException
483
+	 * @throws InvalidArgumentException
484
+	 */
485
+	public function load_class($class_name, $arguments = array(), $from_db = false, $cache = true, $load_only = false)
486
+	{
487
+		$paths = apply_filters(
488
+			'FHEE__EE_Registry__load_class__paths',
489
+			array(
490
+				EE_CORE,
491
+				EE_CLASSES,
492
+				EE_BUSINESS,
493
+			)
494
+		);
495
+		// retrieve instantiated class
496
+		return $this->_load(
497
+			$paths,
498
+			'EE_',
499
+			$class_name,
500
+			'class',
501
+			$arguments,
502
+			$from_db,
503
+			$cache,
504
+			$load_only
505
+		);
506
+	}
507
+
508
+
509
+	/**
510
+	 * loads helper classes - must be singletons
511
+	 *
512
+	 * @param string $class_name - simple class name ie: price
513
+	 * @param mixed  $arguments
514
+	 * @param bool   $load_only
515
+	 * @return EEH_Base | bool
516
+	 * @throws InvalidInterfaceException
517
+	 * @throws InvalidDataTypeException
518
+	 * @throws EE_Error
519
+	 * @throws ReflectionException
520
+	 * @throws InvalidArgumentException
521
+	 */
522
+	public function load_helper($class_name, $arguments = array(), $load_only = true)
523
+	{
524
+		// todo: add doing_it_wrong() in a few versions after all addons have had calls to this method removed
525
+		$helper_paths = apply_filters('FHEE__EE_Registry__load_helper__helper_paths', array(EE_HELPERS));
526
+		// retrieve instantiated class
527
+		return $this->_load(
528
+			$helper_paths,
529
+			'EEH_',
530
+			$class_name,
531
+			'helper',
532
+			$arguments,
533
+			false,
534
+			true,
535
+			$load_only
536
+		);
537
+	}
538
+
539
+
540
+	/**
541
+	 * loads core classes - must be singletons
542
+	 *
543
+	 * @param string $class_name - simple class name ie: session
544
+	 * @param mixed  $arguments
545
+	 * @param bool   $load_only
546
+	 * @param bool   $cache      whether to cache the object or not.
547
+	 * @return mixed
548
+	 * @throws InvalidInterfaceException
549
+	 * @throws InvalidDataTypeException
550
+	 * @throws EE_Error
551
+	 * @throws ReflectionException
552
+	 * @throws InvalidArgumentException
553
+	 */
554
+	public function load_lib($class_name, $arguments = array(), $load_only = false, $cache = true)
555
+	{
556
+		$paths = array(
557
+			EE_LIBRARIES,
558
+			EE_LIBRARIES . 'messages/',
559
+			EE_LIBRARIES . 'shortcodes/',
560
+			EE_LIBRARIES . 'qtips/',
561
+			EE_LIBRARIES . 'payment_methods/',
562
+		);
563
+		// retrieve instantiated class
564
+		return $this->_load(
565
+			$paths,
566
+			'EE_',
567
+			$class_name,
568
+			'lib',
569
+			$arguments,
570
+			false,
571
+			$cache,
572
+			$load_only
573
+		);
574
+	}
575
+
576
+
577
+	/**
578
+	 * loads model classes - must be singletons
579
+	 *
580
+	 * @param string $class_name - simple class name ie: price
581
+	 * @param mixed  $arguments
582
+	 * @param bool   $load_only
583
+	 * @return EEM_Base | bool
584
+	 * @throws InvalidInterfaceException
585
+	 * @throws InvalidDataTypeException
586
+	 * @throws EE_Error
587
+	 * @throws ReflectionException
588
+	 * @throws InvalidArgumentException
589
+	 */
590
+	public function load_model($class_name, $arguments = array(), $load_only = false)
591
+	{
592
+		$paths = apply_filters(
593
+			'FHEE__EE_Registry__load_model__paths',
594
+			array(
595
+				EE_MODELS,
596
+				EE_CORE,
597
+			)
598
+		);
599
+		// retrieve instantiated class
600
+		return $this->_load(
601
+			$paths,
602
+			'EEM_',
603
+			$class_name,
604
+			'model',
605
+			$arguments,
606
+			false,
607
+			true,
608
+			$load_only
609
+		);
610
+	}
611
+
612
+
613
+	/**
614
+	 * loads model classes - must be singletons
615
+	 *
616
+	 * @param string $class_name - simple class name ie: price
617
+	 * @param mixed  $arguments
618
+	 * @param bool   $load_only
619
+	 * @return mixed | bool
620
+	 * @throws InvalidInterfaceException
621
+	 * @throws InvalidDataTypeException
622
+	 * @throws EE_Error
623
+	 * @throws ReflectionException
624
+	 * @throws InvalidArgumentException
625
+	 */
626
+	public function load_model_class($class_name, $arguments = array(), $load_only = true)
627
+	{
628
+		$paths = array(
629
+			EE_MODELS . 'fields/',
630
+			EE_MODELS . 'helpers/',
631
+			EE_MODELS . 'relations/',
632
+			EE_MODELS . 'strategies/',
633
+		);
634
+		// retrieve instantiated class
635
+		return $this->_load(
636
+			$paths,
637
+			'EE_',
638
+			$class_name,
639
+			'',
640
+			$arguments,
641
+			false,
642
+			true,
643
+			$load_only
644
+		);
645
+	}
646
+
647
+
648
+	/**
649
+	 * Determines if $model_name is the name of an actual EE model.
650
+	 *
651
+	 * @param string $model_name like Event, Attendee, Question_Group_Question, etc.
652
+	 * @return boolean
653
+	 */
654
+	public function is_model_name($model_name)
655
+	{
656
+		return isset($this->models[ $model_name ]);
657
+	}
658
+
659
+
660
+	/**
661
+	 * generic class loader
662
+	 *
663
+	 * @param string $path_to_file - directory path to file location, not including filename
664
+	 * @param string $file_name    - file name  ie:  my_file.php, including extension
665
+	 * @param string $type         - file type - core? class? helper? model?
666
+	 * @param mixed  $arguments
667
+	 * @param bool   $load_only
668
+	 * @return mixed
669
+	 * @throws InvalidInterfaceException
670
+	 * @throws InvalidDataTypeException
671
+	 * @throws EE_Error
672
+	 * @throws ReflectionException
673
+	 * @throws InvalidArgumentException
674
+	 */
675
+	public function load_file($path_to_file, $file_name, $type = '', $arguments = array(), $load_only = true)
676
+	{
677
+		// retrieve instantiated class
678
+		return $this->_load(
679
+			$path_to_file,
680
+			'',
681
+			$file_name,
682
+			$type,
683
+			$arguments,
684
+			false,
685
+			true,
686
+			$load_only
687
+		);
688
+	}
689
+
690
+
691
+	/**
692
+	 * @param string $path_to_file - directory path to file location, not including filename
693
+	 * @param string $class_name   - full class name  ie:  My_Class
694
+	 * @param string $type         - file type - core? class? helper? model?
695
+	 * @param mixed  $arguments
696
+	 * @param bool   $load_only
697
+	 * @return bool|EE_Addon|object
698
+	 * @throws InvalidInterfaceException
699
+	 * @throws InvalidDataTypeException
700
+	 * @throws EE_Error
701
+	 * @throws ReflectionException
702
+	 * @throws InvalidArgumentException
703
+	 */
704
+	public function load_addon($path_to_file, $class_name, $type = 'class', $arguments = array(), $load_only = false)
705
+	{
706
+		// retrieve instantiated class
707
+		return $this->_load(
708
+			$path_to_file,
709
+			'addon',
710
+			$class_name,
711
+			$type,
712
+			$arguments,
713
+			false,
714
+			true,
715
+			$load_only
716
+		);
717
+	}
718
+
719
+
720
+	/**
721
+	 * instantiates, caches, and automatically resolves dependencies
722
+	 * for classes that use a Fully Qualified Class Name.
723
+	 * if the class is not capable of being loaded using PSR-4 autoloading,
724
+	 * then you need to use one of the existing load_*() methods
725
+	 * which can resolve the classname and filepath from the passed arguments
726
+	 *
727
+	 * @param bool|string $class_name   Fully Qualified Class Name
728
+	 * @param array       $arguments    an argument, or array of arguments to pass to the class upon instantiation
729
+	 * @param bool        $cache        whether to cache the instantiated object for reuse
730
+	 * @param bool        $from_db      some classes are instantiated from the db
731
+	 *                                  and thus call a different method to instantiate
732
+	 * @param bool        $load_only    if true, will only load the file, but will NOT instantiate an object
733
+	 * @param bool|string $addon        if true, will cache the object in the EE_Registry->$addons array
734
+	 * @return bool|null|mixed          null = failure to load or instantiate class object.
735
+	 *                                  object = class loaded and instantiated successfully.
736
+	 *                                  bool = fail or success when $load_only is true
737
+	 * @throws InvalidInterfaceException
738
+	 * @throws InvalidDataTypeException
739
+	 * @throws EE_Error
740
+	 * @throws ReflectionException
741
+	 * @throws InvalidArgumentException
742
+	 */
743
+	public function create(
744
+		$class_name = false,
745
+		$arguments = array(),
746
+		$cache = false,
747
+		$from_db = false,
748
+		$load_only = false,
749
+		$addon = false
750
+	) {
751
+		$class_name = ltrim($class_name, '\\');
752
+		$class_name = $this->class_cache->getFqnForAlias($class_name);
753
+		$class_exists = $this->loadOrVerifyClassExists($class_name, $arguments);
754
+		// if a non-FQCN was passed, then
755
+		// verifyClassExists() might return an object
756
+		// or it could return null if the class just could not be found anywhere
757
+		if ($class_exists instanceof $class_name || $class_exists === null) {
758
+			// either way, return the results
759
+			return $class_exists;
760
+		}
761
+		$class_name = $class_exists;
762
+		// if we're only loading the class and it already exists, then let's just return true immediately
763
+		if ($load_only) {
764
+			return true;
765
+		}
766
+		$addon = $addon ? 'addon' : '';
767
+		// $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
768
+		// $cache is controlled by individual calls to separate Registry loader methods like load_class()
769
+		// $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
770
+		if ($this->_cache_on && $cache && ! $load_only) {
771
+			// return object if it's already cached
772
+			$cached_class = $this->_get_cached_class($class_name, $addon, $arguments);
773
+			if ($cached_class !== null) {
774
+				return $cached_class;
775
+			}
776
+		}// obtain the loader method from the dependency map
777
+		$loader = $this->_dependency_map->class_loader($class_name);// instantiate the requested object
778
+		if ($loader instanceof Closure) {
779
+			$class_obj = $loader($arguments);
780
+		} else {
781
+			if ($loader && method_exists($this, $loader)) {
782
+				$class_obj = $this->{$loader}($class_name, $arguments);
783
+			} else {
784
+				$class_obj = $this->_create_object($class_name, $arguments, $addon, $from_db);
785
+			}
786
+		}
787
+		if (($this->_cache_on && $cache) || $this->get_class_abbreviation($class_name, '')) {
788
+			// save it for later... kinda like gum  { : $
789
+			$this->_set_cached_class(
790
+				$class_obj,
791
+				$class_name,
792
+				$addon,
793
+				$from_db,
794
+				$arguments
795
+			);
796
+		}
797
+		$this->_cache_on = true;
798
+		return $class_obj;
799
+	}
800
+
801
+
802
+	/**
803
+	 * Recursively checks that a class exists and potentially attempts to load classes with non-FQCNs
804
+	 *
805
+	 * @param string|object $class_name
806
+	 * @param array         $arguments
807
+	 * @param int           $attempt
808
+	 * @return mixed
809
+	 */
810
+	private function loadOrVerifyClassExists($class_name, array $arguments, $attempt = 1)
811
+	{
812
+		if (is_object($class_name) || class_exists($class_name)) {
813
+			return $class_name;
814
+		}
815
+		switch ($attempt) {
816
+			case 1:
817
+				// if it's a FQCN then maybe the class is registered with a preceding \
818
+				$class_name = strpos($class_name, '\\') !== false
819
+					? '\\' . ltrim($class_name, '\\')
820
+					: $class_name;
821
+				break;
822
+			case 2:
823
+				//
824
+				$loader = $this->_dependency_map->class_loader($class_name);
825
+				if ($loader && method_exists($this, $loader)) {
826
+					return $this->{$loader}($class_name, $arguments);
827
+				}
828
+				break;
829
+			case 3:
830
+			default:
831
+				return null;
832
+		}
833
+		$attempt++;
834
+		return $this->loadOrVerifyClassExists($class_name, $arguments, $attempt);
835
+	}
836
+
837
+
838
+	/**
839
+	 * instantiates, caches, and injects dependencies for classes
840
+	 *
841
+	 * @param array       $file_paths   an array of paths to folders to look in
842
+	 * @param string      $class_prefix EE  or EEM or... ???
843
+	 * @param bool|string $class_name   $class name
844
+	 * @param string      $type         file type - core? class? helper? model?
845
+	 * @param mixed       $arguments    an argument or array of arguments to pass to the class upon instantiation
846
+	 * @param bool        $from_db      some classes are instantiated from the db
847
+	 *                                  and thus call a different method to instantiate
848
+	 * @param bool        $cache        whether to cache the instantiated object for reuse
849
+	 * @param bool        $load_only    if true, will only load the file, but will NOT instantiate an object
850
+	 * @return bool|null|object null = failure to load or instantiate class object.
851
+	 *                                  object = class loaded and instantiated successfully.
852
+	 *                                  bool = fail or success when $load_only is true
853
+	 * @throws EE_Error
854
+	 * @throws ReflectionException
855
+	 * @throws InvalidInterfaceException
856
+	 * @throws InvalidDataTypeException
857
+	 * @throws InvalidArgumentException
858
+	 */
859
+	protected function _load(
860
+		$file_paths = array(),
861
+		$class_prefix = 'EE_',
862
+		$class_name = false,
863
+		$type = 'class',
864
+		$arguments = array(),
865
+		$from_db = false,
866
+		$cache = true,
867
+		$load_only = false
868
+	) {
869
+		$class_name = ltrim($class_name, '\\');
870
+		// strip php file extension
871
+		$class_name = str_replace('.php', '', trim($class_name));
872
+		// does the class have a prefix ?
873
+		if (! empty($class_prefix) && $class_prefix !== 'addon') {
874
+			// make sure $class_prefix is uppercase
875
+			$class_prefix = strtoupper(trim($class_prefix));
876
+			// add class prefix ONCE!!!
877
+			$class_name = $class_prefix . str_replace($class_prefix, '', $class_name);
878
+		}
879
+		$class_name = $this->class_cache->getFqnForAlias($class_name);
880
+		$class_exists = class_exists($class_name, false);
881
+		// if we're only loading the class and it already exists, then let's just return true immediately
882
+		if ($load_only && $class_exists) {
883
+			return true;
884
+		}
885
+		$arguments = is_array($arguments) ? $arguments : array($arguments);
886
+		// $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
887
+		// $cache is controlled by individual calls to separate Registry loader methods like load_class()
888
+		// $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
889
+		if ($this->_cache_on && $cache && ! $load_only) {
890
+			// return object if it's already cached
891
+			$cached_class = $this->_get_cached_class($class_name, $class_prefix, $arguments);
892
+			if ($cached_class !== null) {
893
+				return $cached_class;
894
+			}
895
+		}
896
+		// if the class doesn't already exist.. then we need to try and find the file and load it
897
+		if (! $class_exists) {
898
+			// get full path to file
899
+			$path = $this->_resolve_path($class_name, $type, $file_paths);
900
+			// load the file
901
+			$loaded = $this->_require_file($path, $class_name, $type, $file_paths);
902
+			// if we are only loading a file but NOT instantiating an object
903
+			// then return boolean for whether class was loaded or not
904
+			if ($load_only) {
905
+				return $loaded;
906
+			}
907
+			// if an object was expected but loading failed, then return nothing
908
+			if (! $loaded) {
909
+				return null;
910
+			}
911
+		}
912
+		// instantiate the requested object
913
+		$class_obj = $this->_create_object($class_name, $arguments, $type, $from_db);
914
+		if ($this->_cache_on && $cache) {
915
+			// save it for later... kinda like gum  { : $
916
+			$this->_set_cached_class(
917
+				$class_obj,
918
+				$class_name,
919
+				$class_prefix,
920
+				$from_db,
921
+				$arguments
922
+			);
923
+		}
924
+		$this->_cache_on = true;
925
+		return $class_obj;
926
+	}
927
+
928
+
929
+	/**
930
+	 * @param string $class_name
931
+	 * @param string $default have to specify something, but not anything that will conflict
932
+	 * @return mixed|string
933
+	 */
934
+	protected function get_class_abbreviation($class_name, $default = 'FANCY_BATMAN_PANTS')
935
+	{
936
+		return isset($this->_class_abbreviations[ $class_name ])
937
+			? $this->_class_abbreviations[ $class_name ]
938
+			: $default;
939
+	}
940
+
941
+
942
+	/**
943
+	 * attempts to find a cached version of the requested class
944
+	 * by looking in the following places:
945
+	 *        $this->{$class_abbreviation}            ie:    $this->CART
946
+	 *        $this->{$class_name}                        ie:    $this->Some_Class
947
+	 *        $this->LIB->{$class_name}                ie:    $this->LIB->Some_Class
948
+	 *        $this->addon->{$class_name}    ie:    $this->addon->Some_Addon_Class
949
+	 *
950
+	 * @param string $class_name
951
+	 * @param string $class_prefix
952
+	 * @param array  $arguments
953
+	 * @return mixed
954
+	 */
955
+	protected function _get_cached_class(
956
+		$class_name,
957
+		$class_prefix = '',
958
+		$arguments = array()
959
+	) {
960
+		if ($class_name === 'EE_Registry') {
961
+			return $this;
962
+		}
963
+		$class_abbreviation = $this->get_class_abbreviation($class_name);
964
+		// check if class has already been loaded, and return it if it has been
965
+		if (isset($this->{$class_abbreviation})) {
966
+			return $this->{$class_abbreviation};
967
+		}
968
+		$class_name = str_replace('\\', '_', $class_name);
969
+		if (isset($this->{$class_name})) {
970
+			return $this->{$class_name};
971
+		}
972
+		if ($class_prefix === 'addon' && $this->addons->has($class_name)) {
973
+			return $this->addons->get($class_name);
974
+		}
975
+		$object_identifier = $this->object_identifier->getIdentifier($class_name, $arguments);
976
+		if ($this->LIB->has($object_identifier)) {
977
+			return $this->LIB->get($object_identifier);
978
+		}
979
+		foreach ($this->LIB as $key => $object) {
980
+			if (
981 981
 // request does not contain new arguments and therefore no args identifier
982
-                ! $this->object_identifier->hasArguments($object_identifier)
983
-                // but previously cached class with args was found
984
-                && $this->object_identifier->fqcnMatchesObjectIdentifier($class_name, $key)
985
-            ) {
986
-                return $object;
987
-            }
988
-        }
989
-        return null;
990
-    }
991
-
992
-
993
-    /**
994
-     * removes a cached version of the requested class
995
-     *
996
-     * @param string  $class_name
997
-     * @param boolean $addon
998
-     * @param array   $arguments
999
-     * @return boolean
1000
-     */
1001
-    public function clear_cached_class(
1002
-        $class_name,
1003
-        $addon = false,
1004
-        $arguments = array()
1005
-    ) {
1006
-        $class_abbreviation = $this->get_class_abbreviation($class_name);
1007
-        // check if class has already been loaded, and return it if it has been
1008
-        if (isset($this->{$class_abbreviation})) {
1009
-            $this->{$class_abbreviation} = null;
1010
-            return true;
1011
-        }
1012
-        $class_name = str_replace('\\', '_', $class_name);
1013
-        if (isset($this->{$class_name})) {
1014
-            $this->{$class_name} = null;
1015
-            return true;
1016
-        }
1017
-        if ($addon && $this->addons->has($class_name)) {
1018
-            $this->addons->remove($class_name);
1019
-            return true;
1020
-        }
1021
-        $class_name = $this->object_identifier->getIdentifier($class_name, $arguments);
1022
-        if ($this->LIB->has($class_name)) {
1023
-            $this->LIB->remove($class_name);
1024
-            return true;
1025
-        }
1026
-        return false;
1027
-    }
1028
-
1029
-
1030
-    /**
1031
-     * _set_cached_class
1032
-     * attempts to cache the instantiated class locally
1033
-     * in one of the following places, in the following order:
1034
-     *        $this->{class_abbreviation}   ie:    $this->CART
1035
-     *        $this->{$class_name}          ie:    $this->Some_Class
1036
-     *        $this->addon->{$$class_name}    ie:    $this->addon->Some_Addon_Class
1037
-     *        $this->LIB->{$class_name}     ie:    $this->LIB->Some_Class
1038
-     *
1039
-     * @param object $class_obj
1040
-     * @param string $class_name
1041
-     * @param string $class_prefix
1042
-     * @param bool   $from_db
1043
-     * @param array  $arguments
1044
-     * @return void
1045
-     */
1046
-    protected function _set_cached_class(
1047
-        $class_obj,
1048
-        $class_name,
1049
-        $class_prefix = '',
1050
-        $from_db = false,
1051
-        $arguments = array()
1052
-    ) {
1053
-        if ($class_name === 'EE_Registry' || empty($class_obj)) {
1054
-            return;
1055
-        }
1056
-        // return newly instantiated class
1057
-        $class_abbreviation = $this->get_class_abbreviation($class_name, '');
1058
-        if ($class_abbreviation) {
1059
-            $this->{$class_abbreviation} = $class_obj;
1060
-            return;
1061
-        }
1062
-        $class_name = str_replace('\\', '_', $class_name);
1063
-        if (property_exists($this, $class_name)) {
1064
-            $this->{$class_name} = $class_obj;
1065
-            return;
1066
-        }
1067
-        if ($class_prefix === 'addon') {
1068
-            $this->addons->add($class_name, $class_obj);
1069
-            return;
1070
-        }
1071
-        if (! $from_db) {
1072
-            $class_name = $this->object_identifier->getIdentifier($class_name, $arguments);
1073
-            $this->LIB->add($class_name, $class_obj);
1074
-        }
1075
-    }
1076
-
1077
-
1078
-    /**
1079
-     * attempts to find a full valid filepath for the requested class.
1080
-     * loops thru each of the base paths in the $file_paths array and appends : "{classname} . {file type} . php"
1081
-     * then returns that path if the target file has been found and is readable
1082
-     *
1083
-     * @param string $class_name
1084
-     * @param string $type
1085
-     * @param array  $file_paths
1086
-     * @return string | bool
1087
-     */
1088
-    protected function _resolve_path($class_name, $type = '', $file_paths = array())
1089
-    {
1090
-        // make sure $file_paths is an array
1091
-        $file_paths = is_array($file_paths)
1092
-            ? $file_paths
1093
-            : array($file_paths);
1094
-        // cycle thru paths
1095
-        foreach ($file_paths as $key => $file_path) {
1096
-            // convert all separators to proper /, if no filepath, then use EE_CLASSES
1097
-            $file_path = $file_path
1098
-                ? str_replace(array('/', '\\'), '/', $file_path)
1099
-                : EE_CLASSES;
1100
-            // prep file type
1101
-            $type = ! empty($type)
1102
-                ? trim($type, '.') . '.'
1103
-                : '';
1104
-            // build full file path
1105
-            $file_paths[ $key ] = rtrim($file_path, '/') . '/' . $class_name . '.' . $type . 'php';
1106
-            // does the file exist and can be read ?
1107
-            if (is_readable($file_paths[ $key ])) {
1108
-                return $file_paths[ $key ];
1109
-            }
1110
-        }
1111
-        return false;
1112
-    }
1113
-
1114
-
1115
-    /**
1116
-     * basically just performs a require_once()
1117
-     * but with some error handling
1118
-     *
1119
-     * @param  string $path
1120
-     * @param  string $class_name
1121
-     * @param  string $type
1122
-     * @param  array  $file_paths
1123
-     * @return bool
1124
-     * @throws EE_Error
1125
-     * @throws ReflectionException
1126
-     */
1127
-    protected function _require_file($path, $class_name, $type = '', $file_paths = array())
1128
-    {
1129
-        $this->resolve_legacy_class_parent($class_name);
1130
-        // don't give up! you gotta...
1131
-        try {
1132
-            // does the file exist and can it be read ?
1133
-            if (! $path) {
1134
-                // just in case the file has already been autoloaded,
1135
-                // but discrepancies in the naming schema are preventing it from
1136
-                // being loaded via one of the EE_Registry::load_*() methods,
1137
-                // then let's try one last hail mary before throwing an exception
1138
-                // and call class_exists() again, but with autoloading turned ON
1139
-                if (class_exists($class_name)) {
1140
-                    return true;
1141
-                }
1142
-                // so sorry, can't find the file
1143
-                throw new EE_Error(
1144
-                    sprintf(
1145
-                        esc_html__(
1146
-                            'The %1$s file %2$s could not be located or is not readable due to file permissions. Please ensure that the following filepath(s) are correct: %3$s',
1147
-                            'event_espresso'
1148
-                        ),
1149
-                        trim($type, '.'),
1150
-                        $class_name,
1151
-                        '<br />' . implode(',<br />', $file_paths)
1152
-                    )
1153
-                );
1154
-            }
1155
-            // get the file
1156
-            require_once($path);
1157
-            // if the class isn't already declared somewhere
1158
-            if (class_exists($class_name, false) === false) {
1159
-                // so sorry, not a class
1160
-                throw new EE_Error(
1161
-                    sprintf(
1162
-                        esc_html__(
1163
-                            'The %s file %s does not appear to contain the %s Class.',
1164
-                            'event_espresso'
1165
-                        ),
1166
-                        $type,
1167
-                        $path,
1168
-                        $class_name
1169
-                    )
1170
-                );
1171
-            }
1172
-        } catch (EE_Error $e) {
1173
-            $e->get_error();
1174
-            return false;
1175
-        }
1176
-        return true;
1177
-    }
1178
-
1179
-
1180
-    /**
1181
-     * Some of our legacy classes that extended a parent class would simply use a require() statement
1182
-     * before their class declaration in order to ensure that the parent class was loaded.
1183
-     * This is not ideal, but it's nearly impossible to determine the parent class of a non-namespaced class,
1184
-     * without triggering a fatal error because the parent class has yet to be loaded and therefore doesn't exist.
1185
-     *
1186
-     * @param string $class_name
1187
-     */
1188
-    protected function resolve_legacy_class_parent($class_name = '')
1189
-    {
1190
-        try {
1191
-            $legacy_parent_class_map = array(
1192
-                'EE_Payment_Processor' => 'core/business/EE_Processor_Base.class.php',
1193
-            );
1194
-            if (isset($legacy_parent_class_map[ $class_name ])) {
1195
-                require_once EE_PLUGIN_DIR_PATH . $legacy_parent_class_map[ $class_name ];
1196
-            }
1197
-        } catch (Exception $exception) {
1198
-        }
1199
-    }
1200
-
1201
-
1202
-    /**
1203
-     * _create_object
1204
-     * Attempts to instantiate the requested class via any of the
1205
-     * commonly used instantiation methods employed throughout EE.
1206
-     * The priority for instantiation is as follows:
1207
-     *        - abstract classes or any class flagged as "load only" (no instantiation occurs)
1208
-     *        - model objects via their 'new_instance_from_db' method
1209
-     *        - model objects via their 'new_instance' method
1210
-     *        - "singleton" classes" via their 'instance' method
1211
-     *    - standard instantiable classes via their __constructor
1212
-     * Prior to instantiation, if the classname exists in the dependency_map,
1213
-     * then the constructor for the requested class will be examined to determine
1214
-     * if any dependencies exist, and if they can be injected.
1215
-     * If so, then those classes will be added to the array of arguments passed to the constructor
1216
-     *
1217
-     * @param string $class_name
1218
-     * @param array  $arguments
1219
-     * @param string $type
1220
-     * @param bool   $from_db
1221
-     * @return null|object|bool
1222
-     * @throws InvalidArgumentException
1223
-     * @throws InvalidInterfaceException
1224
-     * @throws EE_Error
1225
-     * @throws ReflectionException
1226
-     * @throws InvalidDataTypeException
1227
-     */
1228
-    protected function _create_object($class_name, $arguments = array(), $type = '', $from_db = false)
1229
-    {
1230
-        // create reflection
1231
-        $reflector = $this->mirror->getReflectionClass($class_name);
1232
-        // make sure arguments are an array
1233
-        $arguments = is_array($arguments)
1234
-            ? $arguments
1235
-            : array($arguments);
1236
-        // and if arguments array is numerically and sequentially indexed, then we want it to remain as is,
1237
-        // else wrap it in an additional array so that it doesn't get split into multiple parameters
1238
-        $arguments = $this->_array_is_numerically_and_sequentially_indexed($arguments)
1239
-            ? $arguments
1240
-            : array($arguments);
1241
-        // attempt to inject dependencies ?
1242
-        if ($this->_dependency_map->has($class_name)) {
1243
-            $arguments = $this->_resolve_dependencies($reflector, $class_name, $arguments);
1244
-        }
1245
-        // instantiate the class if possible
1246
-        if ($reflector->isAbstract()) {
1247
-            // nothing to instantiate, loading file was enough
1248
-            // does not throw an exception so $instantiation_mode is unused
1249
-            // $instantiation_mode = "1) no constructor abstract class";
1250
-            return true;
1251
-        }
1252
-        if (
1253
-            empty($arguments)
1254
-            && $this->mirror->getConstructorFromReflection($reflector) === null
1255
-            && $reflector->isInstantiable()
1256
-        ) {
1257
-            // no constructor = static methods only... nothing to instantiate, loading file was enough
1258
-            // $instantiation_mode = "2) no constructor but instantiable";
1259
-            return $reflector->newInstance();
1260
-        }
1261
-        if ($from_db && method_exists($class_name, 'new_instance_from_db')) {
1262
-            // $instantiation_mode = "3) new_instance_from_db()";
1263
-            return call_user_func_array(array($class_name, 'new_instance_from_db'), $arguments);
1264
-        }
1265
-        if (method_exists($class_name, 'new_instance')) {
1266
-            // $instantiation_mode = "4) new_instance()";
1267
-            return call_user_func_array(array($class_name, 'new_instance'), $arguments);
1268
-        }
1269
-        if (method_exists($class_name, 'instance')) {
1270
-            // $instantiation_mode = "5) instance()";
1271
-            return call_user_func_array(array($class_name, 'instance'), $arguments);
1272
-        }
1273
-        if ($reflector->isInstantiable()) {
1274
-            // $instantiation_mode = "6) constructor";
1275
-            return $reflector->newInstanceArgs($arguments);
1276
-        }
1277
-        // heh ? something's not right !
1278
-        throw new EE_Error(
1279
-            sprintf(
1280
-                esc_html__('The %s file %s could not be instantiated.', 'event_espresso'),
1281
-                $type,
1282
-                $class_name
1283
-            )
1284
-        );
1285
-    }
1286
-
1287
-
1288
-    /**
1289
-     * @see http://stackoverflow.com/questions/173400/how-to-check-if-php-array-is-associative-or-sequential
1290
-     * @param array $array
1291
-     * @return bool
1292
-     */
1293
-    protected function _array_is_numerically_and_sequentially_indexed(array $array)
1294
-    {
1295
-        return ! empty($array)
1296
-            ? array_keys($array) === range(0, count($array) - 1)
1297
-            : true;
1298
-    }
1299
-
1300
-
1301
-    /**
1302
-     * _resolve_dependencies
1303
-     * examines the constructor for the requested class to determine
1304
-     * if any dependencies exist, and if they can be injected.
1305
-     * If so, then those classes will be added to the array of arguments passed to the constructor
1306
-     * PLZ NOTE: this is achieved by type hinting the constructor params
1307
-     * For example:
1308
-     *        if attempting to load a class "Foo" with the following constructor:
1309
-     *        __construct( Bar $bar_class, Fighter $grohl_class )
1310
-     *        then $bar_class and $grohl_class will be added to the $arguments array,
1311
-     *        but only IF they are NOT already present in the incoming arguments array,
1312
-     *        and the correct classes can be loaded
1313
-     *
1314
-     * @param ReflectionClass $reflector
1315
-     * @param string          $class_name
1316
-     * @param array           $arguments
1317
-     * @return array
1318
-     * @throws InvalidArgumentException
1319
-     * @throws InvalidDataTypeException
1320
-     * @throws InvalidInterfaceException
1321
-     * @throws ReflectionException
1322
-     */
1323
-    protected function _resolve_dependencies(ReflectionClass $reflector, $class_name, array $arguments = array())
1324
-    {
1325
-        // let's examine the constructor
1326
-        $constructor = $this->mirror->getConstructorFromReflection($reflector);
1327
-        // whu? huh? nothing?
1328
-        if (! $constructor) {
1329
-            return $arguments;
1330
-        }
1331
-        // get constructor parameters
1332
-        $params = $this->mirror->getParametersFromReflection($reflector);
1333
-        // and the keys for the incoming arguments array so that we can compare existing arguments with what is expected
1334
-        $argument_keys = array_keys($arguments);
1335
-        // now loop thru all of the constructors expected parameters
1336
-        foreach ($params as $index => $param) {
1337
-            try {
1338
-                // is this a dependency for a specific class ?
1339
-                $param_class = $this->mirror->getParameterClassName($param, $class_name, $index);
1340
-            } catch (ReflectionException $exception) {
1341
-                // uh-oh... most likely a legacy class that has not been autoloaded
1342
-                // let's try to derive the classname from what we have now
1343
-                // and hope that the property var name is close to the class name
1344
-                $param_class = $param->getName();
1345
-                $param_class = str_replace('_', ' ', $param_class);
1346
-                $param_class = ucwords($param_class);
1347
-                $param_class = str_replace(' ', '_', $param_class);
1348
-            }
1349
-            // BUT WAIT !!! This class may be an alias for something else (or getting replaced at runtime)
1350
-            $param_class = $this->class_cache->isAlias($param_class, $class_name)
1351
-                ? $this->class_cache->getFqnForAlias($param_class, $class_name)
1352
-                : $param_class;
1353
-            if (
1354
-                // param is not even a class
1355
-                $param_class === null
1356
-                // and something already exists in the incoming arguments for this param
1357
-                && array_key_exists($index, $argument_keys)
1358
-                && array_key_exists($argument_keys[ $index ], $arguments)
1359
-            ) {
1360
-                // so let's skip this argument and move on to the next
1361
-                continue;
1362
-            }
1363
-            if (
1364
-                // parameter is type hinted as a class, exists as an incoming argument, AND it's the correct class
1365
-                $param_class !== null
1366
-                && isset($argument_keys[ $index ], $arguments[ $argument_keys[ $index ] ])
1367
-                && $arguments[ $argument_keys[ $index ] ] instanceof $param_class
1368
-            ) {
1369
-                // skip this argument and move on to the next
1370
-                continue;
1371
-            }
1372
-            if (
1373
-                // parameter is type hinted as a class, and should be injected
1374
-                $param_class !== null
1375
-                && $this->_dependency_map->has_dependency_for_class($class_name, $param_class)
1376
-            ) {
1377
-                $arguments = $this->_resolve_dependency(
1378
-                    $class_name,
1379
-                    $param_class,
1380
-                    $arguments,
1381
-                    $index
1382
-                );
1383
-            }
1384
-            if (empty($arguments[ $index ])) {
1385
-                $default_value = $this->mirror->getParameterDefaultValue(
1386
-                    $param,
1387
-                    $class_name,
1388
-                    $index
1389
-                );
1390
-                // if there's no default value, and the incoming argument is an array (albeit empty), then use that
1391
-                $arguments[ $index ] = $default_value === null
1392
-                                 && isset($arguments[ $index ])
1393
-                                 && is_array($arguments[ $index ])
1394
-                    ? $arguments[ $index ]
1395
-                    : $default_value;
1396
-            }
1397
-        }
1398
-        return $arguments;
1399
-    }
1400
-
1401
-
1402
-    /**
1403
-     * @param string $class_name
1404
-     * @param string $param_class
1405
-     * @param array  $arguments
1406
-     * @param mixed  $index
1407
-     * @return array
1408
-     * @throws InvalidArgumentException
1409
-     * @throws InvalidInterfaceException
1410
-     * @throws InvalidDataTypeException
1411
-     */
1412
-    protected function _resolve_dependency($class_name, $param_class, $arguments, $index)
1413
-    {
1414
-        $dependency = null;
1415
-        // should dependency be loaded from cache ?
1416
-        $cache_on = $this->_dependency_map->loading_strategy_for_class_dependency(
1417
-            $class_name,
1418
-            $param_class
1419
-        );
1420
-        $cache_on = $cache_on !== EE_Dependency_Map::load_new_object;
1421
-        // we might have a dependency...
1422
-        // let's MAYBE try and find it in our cache if that's what's been requested
1423
-        $cached_class = $cache_on
1424
-            ? $this->_get_cached_class($param_class)
1425
-            : null;
1426
-        // and grab it if it exists
1427
-        if ($cached_class instanceof $param_class) {
1428
-            $dependency = $cached_class;
1429
-        } elseif ($param_class !== $class_name) {
1430
-            // obtain the loader method from the dependency map
1431
-            $loader = $this->_dependency_map->class_loader($param_class);
1432
-            // is loader a custom closure ?
1433
-            if ($loader instanceof Closure) {
1434
-                $dependency = $loader($arguments);
1435
-            } else {
1436
-                // set the cache on property for the recursive loading call
1437
-                $this->_cache_on = $cache_on;
1438
-                // if not, then let's try and load it via the registry
1439
-                if ($loader && method_exists($this, $loader)) {
1440
-                    $dependency = $this->{$loader}($param_class);
1441
-                } else {
1442
-                    $dependency = LoaderFactory::getLoader()->load(
1443
-                        $param_class,
1444
-                        array(),
1445
-                        $cache_on
1446
-                    );
1447
-                }
1448
-            }
1449
-        }
1450
-        // did we successfully find the correct dependency ?
1451
-        if ($dependency instanceof $param_class) {
1452
-            // then let's inject it into the incoming array of arguments at the correct location
1453
-            $arguments[ $index ] = $dependency;
1454
-        }
1455
-        return $arguments;
1456
-    }
1457
-
1458
-
1459
-    /**
1460
-     * call any loader that's been registered in the EE_Dependency_Map::$_class_loaders array
1461
-     *
1462
-     * @param string $classname PLEASE NOTE: the class name needs to match what's registered
1463
-     *                          in the EE_Dependency_Map::$_class_loaders array,
1464
-     *                          including the class prefix, ie: "EE_", "EEM_", "EEH_", etc
1465
-     * @param array  $arguments
1466
-     * @return object
1467
-     */
1468
-    public static function factory($classname, $arguments = array())
1469
-    {
1470
-        $loader = self::instance()->_dependency_map->class_loader($classname);
1471
-        if ($loader instanceof Closure) {
1472
-            return $loader($arguments);
1473
-        }
1474
-        if (method_exists(self::instance(), $loader)) {
1475
-            return self::instance()->{$loader}($classname, $arguments);
1476
-        }
1477
-        return null;
1478
-    }
1479
-
1480
-
1481
-    /**
1482
-     * Gets the addon by its class name
1483
-     *
1484
-     * @param string $class_name
1485
-     * @return EE_Addon
1486
-     */
1487
-    public function getAddon($class_name)
1488
-    {
1489
-        $class_name = str_replace('\\', '_', $class_name);
1490
-        if (isset($this->addons->{$class_name})) {
1491
-            return $this->addons->{$class_name};
1492
-        } else {
1493
-            return null;
1494
-        }
1495
-    }
1496
-
1497
-
1498
-    /**
1499
-     * removes the addon from the internal cache
1500
-     *
1501
-     * @param string $class_name
1502
-     * @return void
1503
-     */
1504
-    public function removeAddon($class_name)
1505
-    {
1506
-        $class_name = str_replace('\\', '_', $class_name);
1507
-        $this->addons->remove($class_name);
1508
-    }
1509
-
1510
-
1511
-    /**
1512
-     * Gets the addon by its name/slug (not classname. For that, just
1513
-     * use the get_addon() method above
1514
-     *
1515
-     * @param string $name
1516
-     * @return EE_Addon
1517
-     */
1518
-    public function get_addon_by_name($name)
1519
-    {
1520
-        foreach ($this->addons as $addon) {
1521
-            if ($addon->name() === $name) {
1522
-                return $addon;
1523
-            }
1524
-        }
1525
-        return null;
1526
-    }
1527
-
1528
-
1529
-    /**
1530
-     * Gets an array of all the registered addons, where the keys are their names.
1531
-     * (ie, what each returns for their name() function)
1532
-     * They're already available on EE_Registry::instance()->addons as properties,
1533
-     * where each property's name is the addon's classname,
1534
-     * So if you just want to get the addon by classname,
1535
-     * OR use the get_addon() method above.
1536
-     * PLEASE  NOTE:
1537
-     * addons with Fully Qualified Class Names
1538
-     * have had the namespace separators converted to underscores,
1539
-     * so a classname like Fully\Qualified\ClassName
1540
-     * would have been converted to Fully_Qualified_ClassName
1541
-     *
1542
-     * @return EE_Addon[] where the KEYS are the addon's name()
1543
-     */
1544
-    public function get_addons_by_name()
1545
-    {
1546
-        $addons = array();
1547
-        foreach ($this->addons as $addon) {
1548
-            $addons[ $addon->name() ] = $addon;
1549
-        }
1550
-        return $addons;
1551
-    }
1552
-
1553
-
1554
-    /**
1555
-     * Resets the specified model's instance AND makes sure EE_Registry doesn't keep
1556
-     * a stale copy of it around
1557
-     *
1558
-     * @param string $model_name
1559
-     * @return \EEM_Base
1560
-     * @throws \EE_Error
1561
-     */
1562
-    public function reset_model($model_name)
1563
-    {
1564
-        $model_class_name = strpos($model_name, 'EEM_') !== 0
1565
-            ? "EEM_{$model_name}"
1566
-            : $model_name;
1567
-        if (! $this->LIB->has($model_class_name)) {
1568
-            return null;
1569
-        }
1570
-        $model = $this->LIB->get($model_class_name);
1571
-        if (! $model instanceof EEM_Base) {
1572
-            return null;
1573
-        }
1574
-        // get that model reset it and make sure we nuke the old reference to it
1575
-        if ($model instanceof $model_class_name && is_callable([$model_class_name, 'reset'])) {
1576
-            $this->LIB->remove($model_class_name);
1577
-            $this->LIB->add($model_class_name, $model->reset());
1578
-        } else {
1579
-            throw new EE_Error(
1580
-                sprintf(
1581
-                    esc_html__('Model %s does not have a method "reset"', 'event_espresso'),
1582
-                    $model_name
1583
-                )
1584
-            );
1585
-        }
1586
-        return $model;
1587
-    }
1588
-
1589
-
1590
-    /**
1591
-     * Resets the registry.
1592
-     * The criteria for what gets reset is based on what can be shared between sites on the same request when
1593
-     * switch_to_blog is used in a multisite install.  Here is a list of things that are NOT reset.
1594
-     * - $_dependency_map
1595
-     * - $_class_abbreviations
1596
-     * - $NET_CFG (EE_Network_Config): The config is shared network wide so no need to reset.
1597
-     * - $REQ:  Still on the same request so no need to change.
1598
-     * - $CAP: There is no site specific state in the EE_Capability class.
1599
-     * - $SSN: Although ideally, the session should not be shared between site switches, we can't reset it because only
1600
-     * one Session can be active in a single request.  Resetting could resolve in "headers already sent" errors.
1601
-     * - $addons:  In multisite, the state of the addons is something controlled via hooks etc in a normal request.  So
1602
-     *             for now, we won't reset the addons because it could break calls to an add-ons class/methods in the
1603
-     *             switch or on the restore.
1604
-     * - $modules
1605
-     * - $shortcodes
1606
-     * - $widgets
1607
-     *
1608
-     * @param boolean $hard             [deprecated]
1609
-     * @param boolean $reinstantiate    whether to create new instances of EE_Registry's singletons too,
1610
-     *                                  or just reset without re-instantiating (handy to set to FALSE if you're not
1611
-     *                                  sure if you CAN currently reinstantiate the singletons at the moment)
1612
-     * @param   bool  $reset_models     Defaults to true.  When false, then the models are not reset.  This is so
1613
-     *                                  client
1614
-     *                                  code instead can just change the model context to a different blog id if
1615
-     *                                  necessary
1616
-     * @return EE_Registry
1617
-     * @throws InvalidInterfaceException
1618
-     * @throws InvalidDataTypeException
1619
-     * @throws EE_Error
1620
-     * @throws ReflectionException
1621
-     * @throws InvalidArgumentException
1622
-     */
1623
-    public static function reset($hard = false, $reinstantiate = true, $reset_models = true)
1624
-    {
1625
-        $instance = self::instance();
1626
-        $instance->_cache_on = true;
1627
-        // reset some "special" classes
1628
-        EEH_Activation::reset();
1629
-        $hard = apply_filters('FHEE__EE_Registry__reset__hard', $hard);
1630
-        $instance->CFG = EE_Config::reset($hard, $reinstantiate);
1631
-        $instance->CART = null;
1632
-        $instance->MRM = null;
1633
-        $instance->AssetsRegistry = LoaderFactory::getLoader()->getShared(
1634
-            'EventEspresso\core\services\assets\Registry'
1635
-        );
1636
-        // messages reset
1637
-        EED_Messages::reset();
1638
-        // handle of objects cached on LIB
1639
-        foreach (array('LIB', 'modules') as $cache) {
1640
-            foreach ($instance->{$cache} as $class_name => $class) {
1641
-                if (self::_reset_and_unset_object($class, $reset_models)) {
1642
-                    unset($instance->{$cache}->{$class_name});
1643
-                }
1644
-            }
1645
-        }
1646
-        return $instance;
1647
-    }
1648
-
1649
-
1650
-    /**
1651
-     * if passed object implements ResettableInterface, then call it's reset() method
1652
-     * if passed object implements InterminableInterface, then return false,
1653
-     * to indicate that it should NOT be cleared from the Registry cache
1654
-     *
1655
-     * @param      $object
1656
-     * @param bool $reset_models
1657
-     * @return bool returns true if cached object should be unset
1658
-     */
1659
-    private static function _reset_and_unset_object($object, $reset_models)
1660
-    {
1661
-        if (! is_object($object)) {
1662
-            // don't unset anything that's not an object
1663
-            return false;
1664
-        }
1665
-        if ($object instanceof EED_Module) {
1666
-            $object::reset();
1667
-            // don't unset modules
1668
-            return false;
1669
-        }
1670
-        if ($object instanceof ResettableInterface) {
1671
-            if ($object instanceof EEM_Base) {
1672
-                if ($reset_models) {
1673
-                    $object->reset();
1674
-                    return true;
1675
-                }
1676
-                return false;
1677
-            }
1678
-            $object->reset();
1679
-            return true;
1680
-        }
1681
-        if (! $object instanceof InterminableInterface) {
1682
-            return true;
1683
-        }
1684
-        return false;
1685
-    }
1686
-
1687
-
1688
-    /**
1689
-     * Gets all the custom post type models defined
1690
-     *
1691
-     * @return array keys are model "short names" (Eg "Event") and keys are classnames (eg "EEM_Event")
1692
-     */
1693
-    public function cpt_models()
1694
-    {
1695
-        $cpt_models = array();
1696
-        foreach ($this->non_abstract_db_models as $short_name => $classname) {
1697
-            if (is_subclass_of($classname, 'EEM_CPT_Base')) {
1698
-                $cpt_models[ $short_name ] = $classname;
1699
-            }
1700
-        }
1701
-        return $cpt_models;
1702
-    }
1703
-
1704
-
1705
-    /**
1706
-     * @return \EE_Config
1707
-     */
1708
-    public static function CFG()
1709
-    {
1710
-        return self::instance()->CFG;
1711
-    }
1712
-
1713
-
1714
-    /**
1715
-     * @deprecated 4.9.62.p
1716
-     * @param string $class_name
1717
-     * @return ReflectionClass
1718
-     * @throws ReflectionException
1719
-     * @throws InvalidDataTypeException
1720
-     */
1721
-    public function get_ReflectionClass($class_name)
1722
-    {
1723
-        return $this->mirror->getReflectionClass($class_name);
1724
-    }
982
+				! $this->object_identifier->hasArguments($object_identifier)
983
+				// but previously cached class with args was found
984
+				&& $this->object_identifier->fqcnMatchesObjectIdentifier($class_name, $key)
985
+			) {
986
+				return $object;
987
+			}
988
+		}
989
+		return null;
990
+	}
991
+
992
+
993
+	/**
994
+	 * removes a cached version of the requested class
995
+	 *
996
+	 * @param string  $class_name
997
+	 * @param boolean $addon
998
+	 * @param array   $arguments
999
+	 * @return boolean
1000
+	 */
1001
+	public function clear_cached_class(
1002
+		$class_name,
1003
+		$addon = false,
1004
+		$arguments = array()
1005
+	) {
1006
+		$class_abbreviation = $this->get_class_abbreviation($class_name);
1007
+		// check if class has already been loaded, and return it if it has been
1008
+		if (isset($this->{$class_abbreviation})) {
1009
+			$this->{$class_abbreviation} = null;
1010
+			return true;
1011
+		}
1012
+		$class_name = str_replace('\\', '_', $class_name);
1013
+		if (isset($this->{$class_name})) {
1014
+			$this->{$class_name} = null;
1015
+			return true;
1016
+		}
1017
+		if ($addon && $this->addons->has($class_name)) {
1018
+			$this->addons->remove($class_name);
1019
+			return true;
1020
+		}
1021
+		$class_name = $this->object_identifier->getIdentifier($class_name, $arguments);
1022
+		if ($this->LIB->has($class_name)) {
1023
+			$this->LIB->remove($class_name);
1024
+			return true;
1025
+		}
1026
+		return false;
1027
+	}
1028
+
1029
+
1030
+	/**
1031
+	 * _set_cached_class
1032
+	 * attempts to cache the instantiated class locally
1033
+	 * in one of the following places, in the following order:
1034
+	 *        $this->{class_abbreviation}   ie:    $this->CART
1035
+	 *        $this->{$class_name}          ie:    $this->Some_Class
1036
+	 *        $this->addon->{$$class_name}    ie:    $this->addon->Some_Addon_Class
1037
+	 *        $this->LIB->{$class_name}     ie:    $this->LIB->Some_Class
1038
+	 *
1039
+	 * @param object $class_obj
1040
+	 * @param string $class_name
1041
+	 * @param string $class_prefix
1042
+	 * @param bool   $from_db
1043
+	 * @param array  $arguments
1044
+	 * @return void
1045
+	 */
1046
+	protected function _set_cached_class(
1047
+		$class_obj,
1048
+		$class_name,
1049
+		$class_prefix = '',
1050
+		$from_db = false,
1051
+		$arguments = array()
1052
+	) {
1053
+		if ($class_name === 'EE_Registry' || empty($class_obj)) {
1054
+			return;
1055
+		}
1056
+		// return newly instantiated class
1057
+		$class_abbreviation = $this->get_class_abbreviation($class_name, '');
1058
+		if ($class_abbreviation) {
1059
+			$this->{$class_abbreviation} = $class_obj;
1060
+			return;
1061
+		}
1062
+		$class_name = str_replace('\\', '_', $class_name);
1063
+		if (property_exists($this, $class_name)) {
1064
+			$this->{$class_name} = $class_obj;
1065
+			return;
1066
+		}
1067
+		if ($class_prefix === 'addon') {
1068
+			$this->addons->add($class_name, $class_obj);
1069
+			return;
1070
+		}
1071
+		if (! $from_db) {
1072
+			$class_name = $this->object_identifier->getIdentifier($class_name, $arguments);
1073
+			$this->LIB->add($class_name, $class_obj);
1074
+		}
1075
+	}
1076
+
1077
+
1078
+	/**
1079
+	 * attempts to find a full valid filepath for the requested class.
1080
+	 * loops thru each of the base paths in the $file_paths array and appends : "{classname} . {file type} . php"
1081
+	 * then returns that path if the target file has been found and is readable
1082
+	 *
1083
+	 * @param string $class_name
1084
+	 * @param string $type
1085
+	 * @param array  $file_paths
1086
+	 * @return string | bool
1087
+	 */
1088
+	protected function _resolve_path($class_name, $type = '', $file_paths = array())
1089
+	{
1090
+		// make sure $file_paths is an array
1091
+		$file_paths = is_array($file_paths)
1092
+			? $file_paths
1093
+			: array($file_paths);
1094
+		// cycle thru paths
1095
+		foreach ($file_paths as $key => $file_path) {
1096
+			// convert all separators to proper /, if no filepath, then use EE_CLASSES
1097
+			$file_path = $file_path
1098
+				? str_replace(array('/', '\\'), '/', $file_path)
1099
+				: EE_CLASSES;
1100
+			// prep file type
1101
+			$type = ! empty($type)
1102
+				? trim($type, '.') . '.'
1103
+				: '';
1104
+			// build full file path
1105
+			$file_paths[ $key ] = rtrim($file_path, '/') . '/' . $class_name . '.' . $type . 'php';
1106
+			// does the file exist and can be read ?
1107
+			if (is_readable($file_paths[ $key ])) {
1108
+				return $file_paths[ $key ];
1109
+			}
1110
+		}
1111
+		return false;
1112
+	}
1113
+
1114
+
1115
+	/**
1116
+	 * basically just performs a require_once()
1117
+	 * but with some error handling
1118
+	 *
1119
+	 * @param  string $path
1120
+	 * @param  string $class_name
1121
+	 * @param  string $type
1122
+	 * @param  array  $file_paths
1123
+	 * @return bool
1124
+	 * @throws EE_Error
1125
+	 * @throws ReflectionException
1126
+	 */
1127
+	protected function _require_file($path, $class_name, $type = '', $file_paths = array())
1128
+	{
1129
+		$this->resolve_legacy_class_parent($class_name);
1130
+		// don't give up! you gotta...
1131
+		try {
1132
+			// does the file exist and can it be read ?
1133
+			if (! $path) {
1134
+				// just in case the file has already been autoloaded,
1135
+				// but discrepancies in the naming schema are preventing it from
1136
+				// being loaded via one of the EE_Registry::load_*() methods,
1137
+				// then let's try one last hail mary before throwing an exception
1138
+				// and call class_exists() again, but with autoloading turned ON
1139
+				if (class_exists($class_name)) {
1140
+					return true;
1141
+				}
1142
+				// so sorry, can't find the file
1143
+				throw new EE_Error(
1144
+					sprintf(
1145
+						esc_html__(
1146
+							'The %1$s file %2$s could not be located or is not readable due to file permissions. Please ensure that the following filepath(s) are correct: %3$s',
1147
+							'event_espresso'
1148
+						),
1149
+						trim($type, '.'),
1150
+						$class_name,
1151
+						'<br />' . implode(',<br />', $file_paths)
1152
+					)
1153
+				);
1154
+			}
1155
+			// get the file
1156
+			require_once($path);
1157
+			// if the class isn't already declared somewhere
1158
+			if (class_exists($class_name, false) === false) {
1159
+				// so sorry, not a class
1160
+				throw new EE_Error(
1161
+					sprintf(
1162
+						esc_html__(
1163
+							'The %s file %s does not appear to contain the %s Class.',
1164
+							'event_espresso'
1165
+						),
1166
+						$type,
1167
+						$path,
1168
+						$class_name
1169
+					)
1170
+				);
1171
+			}
1172
+		} catch (EE_Error $e) {
1173
+			$e->get_error();
1174
+			return false;
1175
+		}
1176
+		return true;
1177
+	}
1178
+
1179
+
1180
+	/**
1181
+	 * Some of our legacy classes that extended a parent class would simply use a require() statement
1182
+	 * before their class declaration in order to ensure that the parent class was loaded.
1183
+	 * This is not ideal, but it's nearly impossible to determine the parent class of a non-namespaced class,
1184
+	 * without triggering a fatal error because the parent class has yet to be loaded and therefore doesn't exist.
1185
+	 *
1186
+	 * @param string $class_name
1187
+	 */
1188
+	protected function resolve_legacy_class_parent($class_name = '')
1189
+	{
1190
+		try {
1191
+			$legacy_parent_class_map = array(
1192
+				'EE_Payment_Processor' => 'core/business/EE_Processor_Base.class.php',
1193
+			);
1194
+			if (isset($legacy_parent_class_map[ $class_name ])) {
1195
+				require_once EE_PLUGIN_DIR_PATH . $legacy_parent_class_map[ $class_name ];
1196
+			}
1197
+		} catch (Exception $exception) {
1198
+		}
1199
+	}
1200
+
1201
+
1202
+	/**
1203
+	 * _create_object
1204
+	 * Attempts to instantiate the requested class via any of the
1205
+	 * commonly used instantiation methods employed throughout EE.
1206
+	 * The priority for instantiation is as follows:
1207
+	 *        - abstract classes or any class flagged as "load only" (no instantiation occurs)
1208
+	 *        - model objects via their 'new_instance_from_db' method
1209
+	 *        - model objects via their 'new_instance' method
1210
+	 *        - "singleton" classes" via their 'instance' method
1211
+	 *    - standard instantiable classes via their __constructor
1212
+	 * Prior to instantiation, if the classname exists in the dependency_map,
1213
+	 * then the constructor for the requested class will be examined to determine
1214
+	 * if any dependencies exist, and if they can be injected.
1215
+	 * If so, then those classes will be added to the array of arguments passed to the constructor
1216
+	 *
1217
+	 * @param string $class_name
1218
+	 * @param array  $arguments
1219
+	 * @param string $type
1220
+	 * @param bool   $from_db
1221
+	 * @return null|object|bool
1222
+	 * @throws InvalidArgumentException
1223
+	 * @throws InvalidInterfaceException
1224
+	 * @throws EE_Error
1225
+	 * @throws ReflectionException
1226
+	 * @throws InvalidDataTypeException
1227
+	 */
1228
+	protected function _create_object($class_name, $arguments = array(), $type = '', $from_db = false)
1229
+	{
1230
+		// create reflection
1231
+		$reflector = $this->mirror->getReflectionClass($class_name);
1232
+		// make sure arguments are an array
1233
+		$arguments = is_array($arguments)
1234
+			? $arguments
1235
+			: array($arguments);
1236
+		// and if arguments array is numerically and sequentially indexed, then we want it to remain as is,
1237
+		// else wrap it in an additional array so that it doesn't get split into multiple parameters
1238
+		$arguments = $this->_array_is_numerically_and_sequentially_indexed($arguments)
1239
+			? $arguments
1240
+			: array($arguments);
1241
+		// attempt to inject dependencies ?
1242
+		if ($this->_dependency_map->has($class_name)) {
1243
+			$arguments = $this->_resolve_dependencies($reflector, $class_name, $arguments);
1244
+		}
1245
+		// instantiate the class if possible
1246
+		if ($reflector->isAbstract()) {
1247
+			// nothing to instantiate, loading file was enough
1248
+			// does not throw an exception so $instantiation_mode is unused
1249
+			// $instantiation_mode = "1) no constructor abstract class";
1250
+			return true;
1251
+		}
1252
+		if (
1253
+			empty($arguments)
1254
+			&& $this->mirror->getConstructorFromReflection($reflector) === null
1255
+			&& $reflector->isInstantiable()
1256
+		) {
1257
+			// no constructor = static methods only... nothing to instantiate, loading file was enough
1258
+			// $instantiation_mode = "2) no constructor but instantiable";
1259
+			return $reflector->newInstance();
1260
+		}
1261
+		if ($from_db && method_exists($class_name, 'new_instance_from_db')) {
1262
+			// $instantiation_mode = "3) new_instance_from_db()";
1263
+			return call_user_func_array(array($class_name, 'new_instance_from_db'), $arguments);
1264
+		}
1265
+		if (method_exists($class_name, 'new_instance')) {
1266
+			// $instantiation_mode = "4) new_instance()";
1267
+			return call_user_func_array(array($class_name, 'new_instance'), $arguments);
1268
+		}
1269
+		if (method_exists($class_name, 'instance')) {
1270
+			// $instantiation_mode = "5) instance()";
1271
+			return call_user_func_array(array($class_name, 'instance'), $arguments);
1272
+		}
1273
+		if ($reflector->isInstantiable()) {
1274
+			// $instantiation_mode = "6) constructor";
1275
+			return $reflector->newInstanceArgs($arguments);
1276
+		}
1277
+		// heh ? something's not right !
1278
+		throw new EE_Error(
1279
+			sprintf(
1280
+				esc_html__('The %s file %s could not be instantiated.', 'event_espresso'),
1281
+				$type,
1282
+				$class_name
1283
+			)
1284
+		);
1285
+	}
1286
+
1287
+
1288
+	/**
1289
+	 * @see http://stackoverflow.com/questions/173400/how-to-check-if-php-array-is-associative-or-sequential
1290
+	 * @param array $array
1291
+	 * @return bool
1292
+	 */
1293
+	protected function _array_is_numerically_and_sequentially_indexed(array $array)
1294
+	{
1295
+		return ! empty($array)
1296
+			? array_keys($array) === range(0, count($array) - 1)
1297
+			: true;
1298
+	}
1299
+
1300
+
1301
+	/**
1302
+	 * _resolve_dependencies
1303
+	 * examines the constructor for the requested class to determine
1304
+	 * if any dependencies exist, and if they can be injected.
1305
+	 * If so, then those classes will be added to the array of arguments passed to the constructor
1306
+	 * PLZ NOTE: this is achieved by type hinting the constructor params
1307
+	 * For example:
1308
+	 *        if attempting to load a class "Foo" with the following constructor:
1309
+	 *        __construct( Bar $bar_class, Fighter $grohl_class )
1310
+	 *        then $bar_class and $grohl_class will be added to the $arguments array,
1311
+	 *        but only IF they are NOT already present in the incoming arguments array,
1312
+	 *        and the correct classes can be loaded
1313
+	 *
1314
+	 * @param ReflectionClass $reflector
1315
+	 * @param string          $class_name
1316
+	 * @param array           $arguments
1317
+	 * @return array
1318
+	 * @throws InvalidArgumentException
1319
+	 * @throws InvalidDataTypeException
1320
+	 * @throws InvalidInterfaceException
1321
+	 * @throws ReflectionException
1322
+	 */
1323
+	protected function _resolve_dependencies(ReflectionClass $reflector, $class_name, array $arguments = array())
1324
+	{
1325
+		// let's examine the constructor
1326
+		$constructor = $this->mirror->getConstructorFromReflection($reflector);
1327
+		// whu? huh? nothing?
1328
+		if (! $constructor) {
1329
+			return $arguments;
1330
+		}
1331
+		// get constructor parameters
1332
+		$params = $this->mirror->getParametersFromReflection($reflector);
1333
+		// and the keys for the incoming arguments array so that we can compare existing arguments with what is expected
1334
+		$argument_keys = array_keys($arguments);
1335
+		// now loop thru all of the constructors expected parameters
1336
+		foreach ($params as $index => $param) {
1337
+			try {
1338
+				// is this a dependency for a specific class ?
1339
+				$param_class = $this->mirror->getParameterClassName($param, $class_name, $index);
1340
+			} catch (ReflectionException $exception) {
1341
+				// uh-oh... most likely a legacy class that has not been autoloaded
1342
+				// let's try to derive the classname from what we have now
1343
+				// and hope that the property var name is close to the class name
1344
+				$param_class = $param->getName();
1345
+				$param_class = str_replace('_', ' ', $param_class);
1346
+				$param_class = ucwords($param_class);
1347
+				$param_class = str_replace(' ', '_', $param_class);
1348
+			}
1349
+			// BUT WAIT !!! This class may be an alias for something else (or getting replaced at runtime)
1350
+			$param_class = $this->class_cache->isAlias($param_class, $class_name)
1351
+				? $this->class_cache->getFqnForAlias($param_class, $class_name)
1352
+				: $param_class;
1353
+			if (
1354
+				// param is not even a class
1355
+				$param_class === null
1356
+				// and something already exists in the incoming arguments for this param
1357
+				&& array_key_exists($index, $argument_keys)
1358
+				&& array_key_exists($argument_keys[ $index ], $arguments)
1359
+			) {
1360
+				// so let's skip this argument and move on to the next
1361
+				continue;
1362
+			}
1363
+			if (
1364
+				// parameter is type hinted as a class, exists as an incoming argument, AND it's the correct class
1365
+				$param_class !== null
1366
+				&& isset($argument_keys[ $index ], $arguments[ $argument_keys[ $index ] ])
1367
+				&& $arguments[ $argument_keys[ $index ] ] instanceof $param_class
1368
+			) {
1369
+				// skip this argument and move on to the next
1370
+				continue;
1371
+			}
1372
+			if (
1373
+				// parameter is type hinted as a class, and should be injected
1374
+				$param_class !== null
1375
+				&& $this->_dependency_map->has_dependency_for_class($class_name, $param_class)
1376
+			) {
1377
+				$arguments = $this->_resolve_dependency(
1378
+					$class_name,
1379
+					$param_class,
1380
+					$arguments,
1381
+					$index
1382
+				);
1383
+			}
1384
+			if (empty($arguments[ $index ])) {
1385
+				$default_value = $this->mirror->getParameterDefaultValue(
1386
+					$param,
1387
+					$class_name,
1388
+					$index
1389
+				);
1390
+				// if there's no default value, and the incoming argument is an array (albeit empty), then use that
1391
+				$arguments[ $index ] = $default_value === null
1392
+								 && isset($arguments[ $index ])
1393
+								 && is_array($arguments[ $index ])
1394
+					? $arguments[ $index ]
1395
+					: $default_value;
1396
+			}
1397
+		}
1398
+		return $arguments;
1399
+	}
1400
+
1401
+
1402
+	/**
1403
+	 * @param string $class_name
1404
+	 * @param string $param_class
1405
+	 * @param array  $arguments
1406
+	 * @param mixed  $index
1407
+	 * @return array
1408
+	 * @throws InvalidArgumentException
1409
+	 * @throws InvalidInterfaceException
1410
+	 * @throws InvalidDataTypeException
1411
+	 */
1412
+	protected function _resolve_dependency($class_name, $param_class, $arguments, $index)
1413
+	{
1414
+		$dependency = null;
1415
+		// should dependency be loaded from cache ?
1416
+		$cache_on = $this->_dependency_map->loading_strategy_for_class_dependency(
1417
+			$class_name,
1418
+			$param_class
1419
+		);
1420
+		$cache_on = $cache_on !== EE_Dependency_Map::load_new_object;
1421
+		// we might have a dependency...
1422
+		// let's MAYBE try and find it in our cache if that's what's been requested
1423
+		$cached_class = $cache_on
1424
+			? $this->_get_cached_class($param_class)
1425
+			: null;
1426
+		// and grab it if it exists
1427
+		if ($cached_class instanceof $param_class) {
1428
+			$dependency = $cached_class;
1429
+		} elseif ($param_class !== $class_name) {
1430
+			// obtain the loader method from the dependency map
1431
+			$loader = $this->_dependency_map->class_loader($param_class);
1432
+			// is loader a custom closure ?
1433
+			if ($loader instanceof Closure) {
1434
+				$dependency = $loader($arguments);
1435
+			} else {
1436
+				// set the cache on property for the recursive loading call
1437
+				$this->_cache_on = $cache_on;
1438
+				// if not, then let's try and load it via the registry
1439
+				if ($loader && method_exists($this, $loader)) {
1440
+					$dependency = $this->{$loader}($param_class);
1441
+				} else {
1442
+					$dependency = LoaderFactory::getLoader()->load(
1443
+						$param_class,
1444
+						array(),
1445
+						$cache_on
1446
+					);
1447
+				}
1448
+			}
1449
+		}
1450
+		// did we successfully find the correct dependency ?
1451
+		if ($dependency instanceof $param_class) {
1452
+			// then let's inject it into the incoming array of arguments at the correct location
1453
+			$arguments[ $index ] = $dependency;
1454
+		}
1455
+		return $arguments;
1456
+	}
1457
+
1458
+
1459
+	/**
1460
+	 * call any loader that's been registered in the EE_Dependency_Map::$_class_loaders array
1461
+	 *
1462
+	 * @param string $classname PLEASE NOTE: the class name needs to match what's registered
1463
+	 *                          in the EE_Dependency_Map::$_class_loaders array,
1464
+	 *                          including the class prefix, ie: "EE_", "EEM_", "EEH_", etc
1465
+	 * @param array  $arguments
1466
+	 * @return object
1467
+	 */
1468
+	public static function factory($classname, $arguments = array())
1469
+	{
1470
+		$loader = self::instance()->_dependency_map->class_loader($classname);
1471
+		if ($loader instanceof Closure) {
1472
+			return $loader($arguments);
1473
+		}
1474
+		if (method_exists(self::instance(), $loader)) {
1475
+			return self::instance()->{$loader}($classname, $arguments);
1476
+		}
1477
+		return null;
1478
+	}
1479
+
1480
+
1481
+	/**
1482
+	 * Gets the addon by its class name
1483
+	 *
1484
+	 * @param string $class_name
1485
+	 * @return EE_Addon
1486
+	 */
1487
+	public function getAddon($class_name)
1488
+	{
1489
+		$class_name = str_replace('\\', '_', $class_name);
1490
+		if (isset($this->addons->{$class_name})) {
1491
+			return $this->addons->{$class_name};
1492
+		} else {
1493
+			return null;
1494
+		}
1495
+	}
1496
+
1497
+
1498
+	/**
1499
+	 * removes the addon from the internal cache
1500
+	 *
1501
+	 * @param string $class_name
1502
+	 * @return void
1503
+	 */
1504
+	public function removeAddon($class_name)
1505
+	{
1506
+		$class_name = str_replace('\\', '_', $class_name);
1507
+		$this->addons->remove($class_name);
1508
+	}
1509
+
1510
+
1511
+	/**
1512
+	 * Gets the addon by its name/slug (not classname. For that, just
1513
+	 * use the get_addon() method above
1514
+	 *
1515
+	 * @param string $name
1516
+	 * @return EE_Addon
1517
+	 */
1518
+	public function get_addon_by_name($name)
1519
+	{
1520
+		foreach ($this->addons as $addon) {
1521
+			if ($addon->name() === $name) {
1522
+				return $addon;
1523
+			}
1524
+		}
1525
+		return null;
1526
+	}
1527
+
1528
+
1529
+	/**
1530
+	 * Gets an array of all the registered addons, where the keys are their names.
1531
+	 * (ie, what each returns for their name() function)
1532
+	 * They're already available on EE_Registry::instance()->addons as properties,
1533
+	 * where each property's name is the addon's classname,
1534
+	 * So if you just want to get the addon by classname,
1535
+	 * OR use the get_addon() method above.
1536
+	 * PLEASE  NOTE:
1537
+	 * addons with Fully Qualified Class Names
1538
+	 * have had the namespace separators converted to underscores,
1539
+	 * so a classname like Fully\Qualified\ClassName
1540
+	 * would have been converted to Fully_Qualified_ClassName
1541
+	 *
1542
+	 * @return EE_Addon[] where the KEYS are the addon's name()
1543
+	 */
1544
+	public function get_addons_by_name()
1545
+	{
1546
+		$addons = array();
1547
+		foreach ($this->addons as $addon) {
1548
+			$addons[ $addon->name() ] = $addon;
1549
+		}
1550
+		return $addons;
1551
+	}
1552
+
1553
+
1554
+	/**
1555
+	 * Resets the specified model's instance AND makes sure EE_Registry doesn't keep
1556
+	 * a stale copy of it around
1557
+	 *
1558
+	 * @param string $model_name
1559
+	 * @return \EEM_Base
1560
+	 * @throws \EE_Error
1561
+	 */
1562
+	public function reset_model($model_name)
1563
+	{
1564
+		$model_class_name = strpos($model_name, 'EEM_') !== 0
1565
+			? "EEM_{$model_name}"
1566
+			: $model_name;
1567
+		if (! $this->LIB->has($model_class_name)) {
1568
+			return null;
1569
+		}
1570
+		$model = $this->LIB->get($model_class_name);
1571
+		if (! $model instanceof EEM_Base) {
1572
+			return null;
1573
+		}
1574
+		// get that model reset it and make sure we nuke the old reference to it
1575
+		if ($model instanceof $model_class_name && is_callable([$model_class_name, 'reset'])) {
1576
+			$this->LIB->remove($model_class_name);
1577
+			$this->LIB->add($model_class_name, $model->reset());
1578
+		} else {
1579
+			throw new EE_Error(
1580
+				sprintf(
1581
+					esc_html__('Model %s does not have a method "reset"', 'event_espresso'),
1582
+					$model_name
1583
+				)
1584
+			);
1585
+		}
1586
+		return $model;
1587
+	}
1588
+
1589
+
1590
+	/**
1591
+	 * Resets the registry.
1592
+	 * The criteria for what gets reset is based on what can be shared between sites on the same request when
1593
+	 * switch_to_blog is used in a multisite install.  Here is a list of things that are NOT reset.
1594
+	 * - $_dependency_map
1595
+	 * - $_class_abbreviations
1596
+	 * - $NET_CFG (EE_Network_Config): The config is shared network wide so no need to reset.
1597
+	 * - $REQ:  Still on the same request so no need to change.
1598
+	 * - $CAP: There is no site specific state in the EE_Capability class.
1599
+	 * - $SSN: Although ideally, the session should not be shared between site switches, we can't reset it because only
1600
+	 * one Session can be active in a single request.  Resetting could resolve in "headers already sent" errors.
1601
+	 * - $addons:  In multisite, the state of the addons is something controlled via hooks etc in a normal request.  So
1602
+	 *             for now, we won't reset the addons because it could break calls to an add-ons class/methods in the
1603
+	 *             switch or on the restore.
1604
+	 * - $modules
1605
+	 * - $shortcodes
1606
+	 * - $widgets
1607
+	 *
1608
+	 * @param boolean $hard             [deprecated]
1609
+	 * @param boolean $reinstantiate    whether to create new instances of EE_Registry's singletons too,
1610
+	 *                                  or just reset without re-instantiating (handy to set to FALSE if you're not
1611
+	 *                                  sure if you CAN currently reinstantiate the singletons at the moment)
1612
+	 * @param   bool  $reset_models     Defaults to true.  When false, then the models are not reset.  This is so
1613
+	 *                                  client
1614
+	 *                                  code instead can just change the model context to a different blog id if
1615
+	 *                                  necessary
1616
+	 * @return EE_Registry
1617
+	 * @throws InvalidInterfaceException
1618
+	 * @throws InvalidDataTypeException
1619
+	 * @throws EE_Error
1620
+	 * @throws ReflectionException
1621
+	 * @throws InvalidArgumentException
1622
+	 */
1623
+	public static function reset($hard = false, $reinstantiate = true, $reset_models = true)
1624
+	{
1625
+		$instance = self::instance();
1626
+		$instance->_cache_on = true;
1627
+		// reset some "special" classes
1628
+		EEH_Activation::reset();
1629
+		$hard = apply_filters('FHEE__EE_Registry__reset__hard', $hard);
1630
+		$instance->CFG = EE_Config::reset($hard, $reinstantiate);
1631
+		$instance->CART = null;
1632
+		$instance->MRM = null;
1633
+		$instance->AssetsRegistry = LoaderFactory::getLoader()->getShared(
1634
+			'EventEspresso\core\services\assets\Registry'
1635
+		);
1636
+		// messages reset
1637
+		EED_Messages::reset();
1638
+		// handle of objects cached on LIB
1639
+		foreach (array('LIB', 'modules') as $cache) {
1640
+			foreach ($instance->{$cache} as $class_name => $class) {
1641
+				if (self::_reset_and_unset_object($class, $reset_models)) {
1642
+					unset($instance->{$cache}->{$class_name});
1643
+				}
1644
+			}
1645
+		}
1646
+		return $instance;
1647
+	}
1648
+
1649
+
1650
+	/**
1651
+	 * if passed object implements ResettableInterface, then call it's reset() method
1652
+	 * if passed object implements InterminableInterface, then return false,
1653
+	 * to indicate that it should NOT be cleared from the Registry cache
1654
+	 *
1655
+	 * @param      $object
1656
+	 * @param bool $reset_models
1657
+	 * @return bool returns true if cached object should be unset
1658
+	 */
1659
+	private static function _reset_and_unset_object($object, $reset_models)
1660
+	{
1661
+		if (! is_object($object)) {
1662
+			// don't unset anything that's not an object
1663
+			return false;
1664
+		}
1665
+		if ($object instanceof EED_Module) {
1666
+			$object::reset();
1667
+			// don't unset modules
1668
+			return false;
1669
+		}
1670
+		if ($object instanceof ResettableInterface) {
1671
+			if ($object instanceof EEM_Base) {
1672
+				if ($reset_models) {
1673
+					$object->reset();
1674
+					return true;
1675
+				}
1676
+				return false;
1677
+			}
1678
+			$object->reset();
1679
+			return true;
1680
+		}
1681
+		if (! $object instanceof InterminableInterface) {
1682
+			return true;
1683
+		}
1684
+		return false;
1685
+	}
1686
+
1687
+
1688
+	/**
1689
+	 * Gets all the custom post type models defined
1690
+	 *
1691
+	 * @return array keys are model "short names" (Eg "Event") and keys are classnames (eg "EEM_Event")
1692
+	 */
1693
+	public function cpt_models()
1694
+	{
1695
+		$cpt_models = array();
1696
+		foreach ($this->non_abstract_db_models as $short_name => $classname) {
1697
+			if (is_subclass_of($classname, 'EEM_CPT_Base')) {
1698
+				$cpt_models[ $short_name ] = $classname;
1699
+			}
1700
+		}
1701
+		return $cpt_models;
1702
+	}
1703
+
1704
+
1705
+	/**
1706
+	 * @return \EE_Config
1707
+	 */
1708
+	public static function CFG()
1709
+	{
1710
+		return self::instance()->CFG;
1711
+	}
1712
+
1713
+
1714
+	/**
1715
+	 * @deprecated 4.9.62.p
1716
+	 * @param string $class_name
1717
+	 * @return ReflectionClass
1718
+	 * @throws ReflectionException
1719
+	 * @throws InvalidDataTypeException
1720
+	 */
1721
+	public function get_ReflectionClass($class_name)
1722
+	{
1723
+		return $this->mirror->getReflectionClass($class_name);
1724
+	}
1725 1725
 }
Please login to merge, or discard this patch.
Spacing   +50 added lines, -50 removed lines patch added patch discarded remove patch
@@ -309,7 +309,7 @@  discard block
 block discarded – undo
309 309
         foreach ($i18n_js_strings as $key => $value) {
310 310
             if (is_scalar($value)) {
311 311
                 $decoded_value           = html_entity_decode((string) $value, ENT_QUOTES, 'UTF-8');
312
-                $i18n_js_strings[ $key ] = wp_strip_all_tags($decoded_value);
312
+                $i18n_js_strings[$key] = wp_strip_all_tags($decoded_value);
313 313
             }
314 314
         }
315 315
         return $i18n_js_strings;
@@ -324,7 +324,7 @@  discard block
 block discarded – undo
324 324
     public static function localize_i18n_js_strings()
325 325
     {
326 326
         $i18n_js_strings = EE_Registry::sanitize_i18n_js_strings();
327
-        return '/* <![CDATA[ */ var eei18n = ' . wp_json_encode($i18n_js_strings) . '; /* ]]> */';
327
+        return '/* <![CDATA[ */ var eei18n = '.wp_json_encode($i18n_js_strings).'; /* ]]> */';
328 328
     }
329 329
 
330 330
 
@@ -343,7 +343,7 @@  discard block
 block discarded – undo
343 343
             $module_class = get_class($module);
344 344
             $this->modules->add($module_class, $module);
345 345
         } else {
346
-            if (! class_exists('EE_Module_Request_Router', false)) {
346
+            if ( ! class_exists('EE_Module_Request_Router', false)) {
347 347
                 $this->load_core('Module_Request_Router');
348 348
             }
349 349
             EE_Module_Request_Router::module_factory($module);
@@ -382,10 +382,10 @@  discard block
 block discarded – undo
382 382
                 EE_CORE,
383 383
                 EE_ADMIN,
384 384
                 EE_CPTS,
385
-                EE_CORE . 'CPTs/',
386
-                EE_CORE . 'data_migration_scripts/',
387
-                EE_CORE . 'request_stack/',
388
-                EE_CORE . 'middleware/',
385
+                EE_CORE.'CPTs/',
386
+                EE_CORE.'data_migration_scripts/',
387
+                EE_CORE.'request_stack/',
388
+                EE_CORE.'middleware/',
389 389
             )
390 390
         );
391 391
         // retrieve instantiated class
@@ -420,7 +420,7 @@  discard block
 block discarded – undo
420 420
         $service_paths = apply_filters(
421 421
             'FHEE__EE_Registry__load_service__service_paths',
422 422
             array(
423
-                EE_CORE . 'services/',
423
+                EE_CORE.'services/',
424 424
             )
425 425
         );
426 426
         // retrieve instantiated class
@@ -555,10 +555,10 @@  discard block
 block discarded – undo
555 555
     {
556 556
         $paths = array(
557 557
             EE_LIBRARIES,
558
-            EE_LIBRARIES . 'messages/',
559
-            EE_LIBRARIES . 'shortcodes/',
560
-            EE_LIBRARIES . 'qtips/',
561
-            EE_LIBRARIES . 'payment_methods/',
558
+            EE_LIBRARIES.'messages/',
559
+            EE_LIBRARIES.'shortcodes/',
560
+            EE_LIBRARIES.'qtips/',
561
+            EE_LIBRARIES.'payment_methods/',
562 562
         );
563 563
         // retrieve instantiated class
564 564
         return $this->_load(
@@ -626,10 +626,10 @@  discard block
 block discarded – undo
626 626
     public function load_model_class($class_name, $arguments = array(), $load_only = true)
627 627
     {
628 628
         $paths = array(
629
-            EE_MODELS . 'fields/',
630
-            EE_MODELS . 'helpers/',
631
-            EE_MODELS . 'relations/',
632
-            EE_MODELS . 'strategies/',
629
+            EE_MODELS.'fields/',
630
+            EE_MODELS.'helpers/',
631
+            EE_MODELS.'relations/',
632
+            EE_MODELS.'strategies/',
633 633
         );
634 634
         // retrieve instantiated class
635 635
         return $this->_load(
@@ -653,7 +653,7 @@  discard block
 block discarded – undo
653 653
      */
654 654
     public function is_model_name($model_name)
655 655
     {
656
-        return isset($this->models[ $model_name ]);
656
+        return isset($this->models[$model_name]);
657 657
     }
658 658
 
659 659
 
@@ -774,7 +774,7 @@  discard block
 block discarded – undo
774 774
                 return $cached_class;
775 775
             }
776 776
         }// obtain the loader method from the dependency map
777
-        $loader = $this->_dependency_map->class_loader($class_name);// instantiate the requested object
777
+        $loader = $this->_dependency_map->class_loader($class_name); // instantiate the requested object
778 778
         if ($loader instanceof Closure) {
779 779
             $class_obj = $loader($arguments);
780 780
         } else {
@@ -816,7 +816,7 @@  discard block
 block discarded – undo
816 816
             case 1:
817 817
                 // if it's a FQCN then maybe the class is registered with a preceding \
818 818
                 $class_name = strpos($class_name, '\\') !== false
819
-                    ? '\\' . ltrim($class_name, '\\')
819
+                    ? '\\'.ltrim($class_name, '\\')
820 820
                     : $class_name;
821 821
                 break;
822 822
             case 2:
@@ -870,11 +870,11 @@  discard block
 block discarded – undo
870 870
         // strip php file extension
871 871
         $class_name = str_replace('.php', '', trim($class_name));
872 872
         // does the class have a prefix ?
873
-        if (! empty($class_prefix) && $class_prefix !== 'addon') {
873
+        if ( ! empty($class_prefix) && $class_prefix !== 'addon') {
874 874
             // make sure $class_prefix is uppercase
875 875
             $class_prefix = strtoupper(trim($class_prefix));
876 876
             // add class prefix ONCE!!!
877
-            $class_name = $class_prefix . str_replace($class_prefix, '', $class_name);
877
+            $class_name = $class_prefix.str_replace($class_prefix, '', $class_name);
878 878
         }
879 879
         $class_name = $this->class_cache->getFqnForAlias($class_name);
880 880
         $class_exists = class_exists($class_name, false);
@@ -894,7 +894,7 @@  discard block
 block discarded – undo
894 894
             }
895 895
         }
896 896
         // if the class doesn't already exist.. then we need to try and find the file and load it
897
-        if (! $class_exists) {
897
+        if ( ! $class_exists) {
898 898
             // get full path to file
899 899
             $path = $this->_resolve_path($class_name, $type, $file_paths);
900 900
             // load the file
@@ -905,7 +905,7 @@  discard block
 block discarded – undo
905 905
                 return $loaded;
906 906
             }
907 907
             // if an object was expected but loading failed, then return nothing
908
-            if (! $loaded) {
908
+            if ( ! $loaded) {
909 909
                 return null;
910 910
             }
911 911
         }
@@ -933,8 +933,8 @@  discard block
 block discarded – undo
933 933
      */
934 934
     protected function get_class_abbreviation($class_name, $default = 'FANCY_BATMAN_PANTS')
935 935
     {
936
-        return isset($this->_class_abbreviations[ $class_name ])
937
-            ? $this->_class_abbreviations[ $class_name ]
936
+        return isset($this->_class_abbreviations[$class_name])
937
+            ? $this->_class_abbreviations[$class_name]
938 938
             : $default;
939 939
     }
940 940
 
@@ -1068,7 +1068,7 @@  discard block
 block discarded – undo
1068 1068
             $this->addons->add($class_name, $class_obj);
1069 1069
             return;
1070 1070
         }
1071
-        if (! $from_db) {
1071
+        if ( ! $from_db) {
1072 1072
             $class_name = $this->object_identifier->getIdentifier($class_name, $arguments);
1073 1073
             $this->LIB->add($class_name, $class_obj);
1074 1074
         }
@@ -1099,13 +1099,13 @@  discard block
 block discarded – undo
1099 1099
                 : EE_CLASSES;
1100 1100
             // prep file type
1101 1101
             $type = ! empty($type)
1102
-                ? trim($type, '.') . '.'
1102
+                ? trim($type, '.').'.'
1103 1103
                 : '';
1104 1104
             // build full file path
1105
-            $file_paths[ $key ] = rtrim($file_path, '/') . '/' . $class_name . '.' . $type . 'php';
1105
+            $file_paths[$key] = rtrim($file_path, '/').'/'.$class_name.'.'.$type.'php';
1106 1106
             // does the file exist and can be read ?
1107
-            if (is_readable($file_paths[ $key ])) {
1108
-                return $file_paths[ $key ];
1107
+            if (is_readable($file_paths[$key])) {
1108
+                return $file_paths[$key];
1109 1109
             }
1110 1110
         }
1111 1111
         return false;
@@ -1130,7 +1130,7 @@  discard block
 block discarded – undo
1130 1130
         // don't give up! you gotta...
1131 1131
         try {
1132 1132
             // does the file exist and can it be read ?
1133
-            if (! $path) {
1133
+            if ( ! $path) {
1134 1134
                 // just in case the file has already been autoloaded,
1135 1135
                 // but discrepancies in the naming schema are preventing it from
1136 1136
                 // being loaded via one of the EE_Registry::load_*() methods,
@@ -1148,7 +1148,7 @@  discard block
 block discarded – undo
1148 1148
                         ),
1149 1149
                         trim($type, '.'),
1150 1150
                         $class_name,
1151
-                        '<br />' . implode(',<br />', $file_paths)
1151
+                        '<br />'.implode(',<br />', $file_paths)
1152 1152
                     )
1153 1153
                 );
1154 1154
             }
@@ -1191,8 +1191,8 @@  discard block
 block discarded – undo
1191 1191
             $legacy_parent_class_map = array(
1192 1192
                 'EE_Payment_Processor' => 'core/business/EE_Processor_Base.class.php',
1193 1193
             );
1194
-            if (isset($legacy_parent_class_map[ $class_name ])) {
1195
-                require_once EE_PLUGIN_DIR_PATH . $legacy_parent_class_map[ $class_name ];
1194
+            if (isset($legacy_parent_class_map[$class_name])) {
1195
+                require_once EE_PLUGIN_DIR_PATH.$legacy_parent_class_map[$class_name];
1196 1196
             }
1197 1197
         } catch (Exception $exception) {
1198 1198
         }
@@ -1325,7 +1325,7 @@  discard block
 block discarded – undo
1325 1325
         // let's examine the constructor
1326 1326
         $constructor = $this->mirror->getConstructorFromReflection($reflector);
1327 1327
         // whu? huh? nothing?
1328
-        if (! $constructor) {
1328
+        if ( ! $constructor) {
1329 1329
             return $arguments;
1330 1330
         }
1331 1331
         // get constructor parameters
@@ -1355,7 +1355,7 @@  discard block
 block discarded – undo
1355 1355
                 $param_class === null
1356 1356
                 // and something already exists in the incoming arguments for this param
1357 1357
                 && array_key_exists($index, $argument_keys)
1358
-                && array_key_exists($argument_keys[ $index ], $arguments)
1358
+                && array_key_exists($argument_keys[$index], $arguments)
1359 1359
             ) {
1360 1360
                 // so let's skip this argument and move on to the next
1361 1361
                 continue;
@@ -1363,8 +1363,8 @@  discard block
 block discarded – undo
1363 1363
             if (
1364 1364
                 // parameter is type hinted as a class, exists as an incoming argument, AND it's the correct class
1365 1365
                 $param_class !== null
1366
-                && isset($argument_keys[ $index ], $arguments[ $argument_keys[ $index ] ])
1367
-                && $arguments[ $argument_keys[ $index ] ] instanceof $param_class
1366
+                && isset($argument_keys[$index], $arguments[$argument_keys[$index]])
1367
+                && $arguments[$argument_keys[$index]] instanceof $param_class
1368 1368
             ) {
1369 1369
                 // skip this argument and move on to the next
1370 1370
                 continue;
@@ -1381,17 +1381,17 @@  discard block
 block discarded – undo
1381 1381
                     $index
1382 1382
                 );
1383 1383
             }
1384
-            if (empty($arguments[ $index ])) {
1384
+            if (empty($arguments[$index])) {
1385 1385
                 $default_value = $this->mirror->getParameterDefaultValue(
1386 1386
                     $param,
1387 1387
                     $class_name,
1388 1388
                     $index
1389 1389
                 );
1390 1390
                 // if there's no default value, and the incoming argument is an array (albeit empty), then use that
1391
-                $arguments[ $index ] = $default_value === null
1392
-                                 && isset($arguments[ $index ])
1393
-                                 && is_array($arguments[ $index ])
1394
-                    ? $arguments[ $index ]
1391
+                $arguments[$index] = $default_value === null
1392
+                                 && isset($arguments[$index])
1393
+                                 && is_array($arguments[$index])
1394
+                    ? $arguments[$index]
1395 1395
                     : $default_value;
1396 1396
             }
1397 1397
         }
@@ -1450,7 +1450,7 @@  discard block
 block discarded – undo
1450 1450
         // did we successfully find the correct dependency ?
1451 1451
         if ($dependency instanceof $param_class) {
1452 1452
             // then let's inject it into the incoming array of arguments at the correct location
1453
-            $arguments[ $index ] = $dependency;
1453
+            $arguments[$index] = $dependency;
1454 1454
         }
1455 1455
         return $arguments;
1456 1456
     }
@@ -1545,7 +1545,7 @@  discard block
 block discarded – undo
1545 1545
     {
1546 1546
         $addons = array();
1547 1547
         foreach ($this->addons as $addon) {
1548
-            $addons[ $addon->name() ] = $addon;
1548
+            $addons[$addon->name()] = $addon;
1549 1549
         }
1550 1550
         return $addons;
1551 1551
     }
@@ -1564,11 +1564,11 @@  discard block
 block discarded – undo
1564 1564
         $model_class_name = strpos($model_name, 'EEM_') !== 0
1565 1565
             ? "EEM_{$model_name}"
1566 1566
             : $model_name;
1567
-        if (! $this->LIB->has($model_class_name)) {
1567
+        if ( ! $this->LIB->has($model_class_name)) {
1568 1568
             return null;
1569 1569
         }
1570 1570
         $model = $this->LIB->get($model_class_name);
1571
-        if (! $model instanceof EEM_Base) {
1571
+        if ( ! $model instanceof EEM_Base) {
1572 1572
             return null;
1573 1573
         }
1574 1574
         // get that model reset it and make sure we nuke the old reference to it
@@ -1658,7 +1658,7 @@  discard block
 block discarded – undo
1658 1658
      */
1659 1659
     private static function _reset_and_unset_object($object, $reset_models)
1660 1660
     {
1661
-        if (! is_object($object)) {
1661
+        if ( ! is_object($object)) {
1662 1662
             // don't unset anything that's not an object
1663 1663
             return false;
1664 1664
         }
@@ -1678,7 +1678,7 @@  discard block
 block discarded – undo
1678 1678
             $object->reset();
1679 1679
             return true;
1680 1680
         }
1681
-        if (! $object instanceof InterminableInterface) {
1681
+        if ( ! $object instanceof InterminableInterface) {
1682 1682
             return true;
1683 1683
         }
1684 1684
         return false;
@@ -1695,7 +1695,7 @@  discard block
 block discarded – undo
1695 1695
         $cpt_models = array();
1696 1696
         foreach ($this->non_abstract_db_models as $short_name => $classname) {
1697 1697
             if (is_subclass_of($classname, 'EEM_CPT_Base')) {
1698
-                $cpt_models[ $short_name ] = $classname;
1698
+                $cpt_models[$short_name] = $classname;
1699 1699
             }
1700 1700
         }
1701 1701
         return $cpt_models;
Please login to merge, or discard this patch.
thank_you_page/templates/thank-you-page-registration-details.template.php 1 patch
Indentation   +62 added lines, -62 removed lines patch added patch discarded remove patch
@@ -14,24 +14,24 @@  discard block
 block discarded – undo
14 14
 
15 15
 <div class="ee-registration-details-dv">
16 16
     <?php
17
-    $registrations = $transaction->registrations();
18
-    $registrations = is_array($registrations) ? $registrations : [];
19
-    $reg_count     = count($registrations);
20
-    $reg_cntr      = 0;
21
-    $event_name    = '';
22
-    $wait_list     = false;
23
-    foreach ($registrations as $registration) {
24
-        if (! $registration instanceof EE_Registration) {
25
-            continue;
26
-        }
27
-        if ($event_name != $registration->event_name() && ! empty($event_name)) { ?>
17
+	$registrations = $transaction->registrations();
18
+	$registrations = is_array($registrations) ? $registrations : [];
19
+	$reg_count     = count($registrations);
20
+	$reg_cntr      = 0;
21
+	$event_name    = '';
22
+	$wait_list     = false;
23
+	foreach ($registrations as $registration) {
24
+		if (! $registration instanceof EE_Registration) {
25
+			continue;
26
+		}
27
+		if ($event_name != $registration->event_name() && ! empty($event_name)) { ?>
28 28
             </tbody>
29 29
             </table>
30 30
             <?php
31
-        }
32
-        $reg_cntr++;
33
-        if ($event_name != $registration->event_name()) {
34
-            ?>
31
+		}
32
+		$reg_cntr++;
33
+		if ($event_name != $registration->event_name()) {
34
+			?>
35 35
             <h5>
36 36
                 <span class="smaller-text grey-text">
37 37
                     <?php esc_html_e('for', 'event_espresso'); ?> :
@@ -54,23 +54,23 @@  discard block
 block discarded – undo
54 54
             </thead>
55 55
             <tbody>
56 56
             <?php
57
-        }
58
-        if ($is_primary || (! $is_primary && $reg_url_link == $registration->reg_url_link())) { ?>
57
+		}
58
+		if ($is_primary || (! $is_primary && $reg_url_link == $registration->reg_url_link())) { ?>
59 59
             <tr>
60 60
                 <td width="40%">
61 61
                     <?php
62
-                    if ($registration->attendee() instanceof EE_Attendee) {
63
-                        echo $registration->attendee()->full_name(true);
64
-                    }
65
-                    ?>
62
+					if ($registration->attendee() instanceof EE_Attendee) {
63
+						echo $registration->attendee()->full_name(true);
64
+					}
65
+					?>
66 66
                     <p class="tiny-text" style="margin: .75em 0 0;">
67 67
                         <?php if ($registration->count_question_groups()) { ?>
68 68
                             <a class="ee-icon-only-lnk"
69 69
                                href="<?php echo esc_url_raw($registration->edit_attendee_information_url()); ?>"
70 70
                                title="<?php esc_attr_e(
71
-                                   'Click here to edit Attendee Information',
72
-                                   'event_espresso'
73
-                               ); ?>"
71
+								   'Click here to edit Attendee Information',
72
+								   'event_espresso'
73
+							   ); ?>"
74 74
                             >
75 75
                                 <span class="ee-icon ee-icon-user-edit"></span>
76 76
                                 <?php esc_html_e('edit info', 'event_espresso'); ?>
@@ -78,15 +78,15 @@  discard block
 block discarded – undo
78 78
                         <?php } ?>
79 79
                         <a class="ee-resend-reg-confirmation-email ee-icon-only-lnk"
80 80
                            href="<?php echo esc_url_raw(
81
-                               add_query_arg(
82
-                                   ['token' => $registration->reg_url_link(), 'resend_reg_confirmation' => 'true'],
83
-                                   EE_Registry::instance()->CFG->core->thank_you_page_url()
84
-                               )
85
-                           ); ?>"
81
+							   add_query_arg(
82
+								   ['token' => $registration->reg_url_link(), 'resend_reg_confirmation' => 'true'],
83
+								   EE_Registry::instance()->CFG->core->thank_you_page_url()
84
+							   )
85
+						   ); ?>"
86 86
                            title="<?php esc_attr_e(
87
-                               'Click here to resend the Registration Confirmation email',
88
-                               'event_espresso'
89
-                           ); ?>"
87
+							   'Click here to resend the Registration Confirmation email',
88
+							   'event_espresso'
89
+						   ); ?>"
90 90
                            rel="<?php echo esc_attr($registration->reg_url_link()); ?>"
91 91
                         >
92 92
                             <span class="dashicons dashicons-email-alt"></span>
@@ -100,27 +100,27 @@  discard block
 block discarded – undo
100 100
                 <td width="35%" class="jst-left">
101 101
                     <?php $registration->e_pretty_status(true) ?>
102 102
                     <?php
103
-                    if ($registration->status_ID() === EEM_Registration::status_id_wait_list) {
104
-                        $wait_list = true;
105
-                    }
106
-                    ?>
103
+					if ($registration->status_ID() === EEM_Registration::status_id_wait_list) {
104
+						$wait_list = true;
105
+					}
106
+					?>
107 107
                 </td>
108 108
             </tr>
109 109
             <?php do_action(
110
-                'AHEE__thank_you_page_registration_details_template__after_registration_table_row',
111
-                $registration
112
-            ); ?>
110
+				'AHEE__thank_you_page_registration_details_template__after_registration_table_row',
111
+				$registration
112
+			); ?>
113 113
             <?php
114
-            $event_name = $registration->event_name();
115
-        }
116
-        if ($reg_cntr >= $reg_count) {
117
-            ?>
114
+			$event_name = $registration->event_name();
115
+		}
116
+		if ($reg_cntr >= $reg_count) {
117
+			?>
118 118
             </tbody>
119 119
             </table>
120 120
             <?php
121
-        }
122
-    }
123
-    ?>
121
+		}
122
+	}
123
+	?>
124 124
     <?php if ($is_primary && $SPCO_attendee_information_url) { ?>
125 125
         <p class="small-text jst-rght">
126 126
             <a href='<?php echo esc_url_raw($SPCO_attendee_information_url) ?>'>
@@ -129,22 +129,22 @@  discard block
 block discarded – undo
129 129
         </p>
130 130
     <?php } ?>
131 131
     <?php
132
-    if ($wait_list) {
133
-        echo apply_filters(
134
-            'AFEE__thank_you_page_registration_details_template__wait_list_notice',
135
-            sprintf(
136
-                esc_html__(
137
-                    '%1$sre: Wait List Registrations%2$sPlease note that the total cost listed below in the Transaction Details is for ALL registrations, including those that are on the wait list, even though they can not be currently paid for. If any spaces become available however, you may be notified by the Event admin and have the opportunity to secure the remaining tickets by making a payment for them.%3$s',
138
-                    'event_espresso'
139
-                ),
140
-                '<h6 class="" style="margin-bottom:.25em;"><span class="dashicons dashicons-clipboard ee-icon-size-16 purple-text"></span>',
141
-                '</h6 ><p class="ee-wait-list-notice">',
142
-                '</p ><br />'
143
-            )
144
-        );
145
-    }
146
-    do_action('AHEE__thank_you_page_registration_details_template__after_registration_details');
147
-    ?>
132
+	if ($wait_list) {
133
+		echo apply_filters(
134
+			'AFEE__thank_you_page_registration_details_template__wait_list_notice',
135
+			sprintf(
136
+				esc_html__(
137
+					'%1$sre: Wait List Registrations%2$sPlease note that the total cost listed below in the Transaction Details is for ALL registrations, including those that are on the wait list, even though they can not be currently paid for. If any spaces become available however, you may be notified by the Event admin and have the opportunity to secure the remaining tickets by making a payment for them.%3$s',
138
+					'event_espresso'
139
+				),
140
+				'<h6 class="" style="margin-bottom:.25em;"><span class="dashicons dashicons-clipboard ee-icon-size-16 purple-text"></span>',
141
+				'</h6 ><p class="ee-wait-list-notice">',
142
+				'</p ><br />'
143
+			)
144
+		);
145
+	}
146
+	do_action('AHEE__thank_you_page_registration_details_template__after_registration_details');
147
+	?>
148 148
 
149 149
 </div>
150 150
 <!-- end of .registration-details -->
Please login to merge, or discard this patch.
espresso.php 1 patch
Indentation   +80 added lines, -80 removed lines patch added patch discarded remove patch
@@ -38,103 +38,103 @@
 block discarded – undo
38 38
  * @since           4.0
39 39
  */
40 40
 if (function_exists('espresso_version')) {
41
-    if (! function_exists('espresso_duplicate_plugin_error')) {
42
-        /**
43
-         *    espresso_duplicate_plugin_error
44
-         *    displays if more than one version of EE is activated at the same time
45
-         */
46
-        function espresso_duplicate_plugin_error()
47
-        {
48
-            ?>
41
+	if (! function_exists('espresso_duplicate_plugin_error')) {
42
+		/**
43
+		 *    espresso_duplicate_plugin_error
44
+		 *    displays if more than one version of EE is activated at the same time
45
+		 */
46
+		function espresso_duplicate_plugin_error()
47
+		{
48
+			?>
49 49
             <div class="error">
50 50
                 <p>
51 51
                     <?php
52
-                    echo esc_html__(
53
-                        'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
-                        'event_espresso'
55
-                    ); ?>
52
+					echo esc_html__(
53
+						'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
+						'event_espresso'
55
+					); ?>
56 56
                 </p>
57 57
             </div>
58 58
             <?php
59
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
60
-        }
61
-    }
62
-    add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
59
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
60
+		}
61
+	}
62
+	add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
63 63
 } else {
64
-    define('EE_MIN_PHP_VER_REQUIRED', '5.6.2');
65
-    if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
66
-        /**
67
-         * espresso_minimum_php_version_error
68
-         *
69
-         * @return void
70
-         */
71
-        function espresso_minimum_php_version_error()
72
-        {
73
-            ?>
64
+	define('EE_MIN_PHP_VER_REQUIRED', '5.6.2');
65
+	if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
66
+		/**
67
+		 * espresso_minimum_php_version_error
68
+		 *
69
+		 * @return void
70
+		 */
71
+		function espresso_minimum_php_version_error()
72
+		{
73
+			?>
74 74
             <div class="error">
75 75
                 <p>
76 76
                     <?php
77
-                    printf(
78
-                        esc_html__(
79
-                            'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
80
-                            'event_espresso'
81
-                        ),
82
-                        EE_MIN_PHP_VER_REQUIRED,
83
-                        PHP_VERSION,
84
-                        '<br/>',
85
-                        '<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
86
-                    );
87
-                    ?>
77
+					printf(
78
+						esc_html__(
79
+							'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
80
+							'event_espresso'
81
+						),
82
+						EE_MIN_PHP_VER_REQUIRED,
83
+						PHP_VERSION,
84
+						'<br/>',
85
+						'<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
86
+					);
87
+					?>
88 88
                 </p>
89 89
             </div>
90 90
             <?php
91
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
92
-        }
91
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
92
+		}
93 93
 
94
-        add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
95
-    } else {
96
-        define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
97
-        /**
98
-         * espresso_version
99
-         * Returns the plugin version
100
-         *
101
-         * @return string
102
-         */
103
-        function espresso_version()
104
-        {
105
-            return apply_filters('FHEE__espresso__espresso_version', '4.10.22.rc.000');
106
-        }
94
+		add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
95
+	} else {
96
+		define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
97
+		/**
98
+		 * espresso_version
99
+		 * Returns the plugin version
100
+		 *
101
+		 * @return string
102
+		 */
103
+		function espresso_version()
104
+		{
105
+			return apply_filters('FHEE__espresso__espresso_version', '4.10.22.rc.000');
106
+		}
107 107
 
108
-        /**
109
-         * espresso_plugin_activation
110
-         * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
111
-         */
112
-        function espresso_plugin_activation()
113
-        {
114
-            update_option('ee_espresso_activation', true);
115
-        }
108
+		/**
109
+		 * espresso_plugin_activation
110
+		 * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
111
+		 */
112
+		function espresso_plugin_activation()
113
+		{
114
+			update_option('ee_espresso_activation', true);
115
+		}
116 116
 
117
-        register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
117
+		register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
118 118
 
119
-        require_once __DIR__ . '/core/bootstrap_espresso.php';
120
-        bootstrap_espresso();
121
-    }
119
+		require_once __DIR__ . '/core/bootstrap_espresso.php';
120
+		bootstrap_espresso();
121
+	}
122 122
 }
123 123
 if (! function_exists('espresso_deactivate_plugin')) {
124
-    /**
125
-     *    deactivate_plugin
126
-     * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
127
-     *
128
-     * @access public
129
-     * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
130
-     * @return    void
131
-     */
132
-    function espresso_deactivate_plugin($plugin_basename = '')
133
-    {
134
-        if (! function_exists('deactivate_plugins')) {
135
-            require_once ABSPATH . 'wp-admin/includes/plugin.php';
136
-        }
137
-        unset($_GET['activate'], $_REQUEST['activate']);
138
-        deactivate_plugins($plugin_basename);
139
-    }
124
+	/**
125
+	 *    deactivate_plugin
126
+	 * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
127
+	 *
128
+	 * @access public
129
+	 * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
130
+	 * @return    void
131
+	 */
132
+	function espresso_deactivate_plugin($plugin_basename = '')
133
+	{
134
+		if (! function_exists('deactivate_plugins')) {
135
+			require_once ABSPATH . 'wp-admin/includes/plugin.php';
136
+		}
137
+		unset($_GET['activate'], $_REQUEST['activate']);
138
+		deactivate_plugins($plugin_basename);
139
+	}
140 140
 }
Please login to merge, or discard this patch.