Completed
Branch TASK/11208/update-bundled-gate... (60edbd)
by
unknown
12:10
created

EE_System   F

Complexity

Total Complexity 131

Size/Duplication

Total Lines 1244
Duplicated Lines 1.53 %

Coupling/Cohesion

Components 1
Dependencies 16

Importance

Changes 0
Metric Value
dl 19
loc 1244
rs 0.6314
c 0
b 0
f 0
wmc 131
lcom 1
cbo 16

41 Methods

Rating   Name   Duplication   Size   Complexity  
A instance() 0 13 2
A reset() 0 11 1
A __construct() 0 71 1
A loadCapabilities() 0 10 1
A loadCommandBus() 0 16 1
A loadPluginApi() 0 6 1
A initialize() 0 4 1
A initialize_last() 0 5 1
A addEspressoToolbar() 0 7 1
A do_not_cache() 0 19 4
A extra_nocache_headers() 0 8 1
A nocache_headers() 0 4 1
B deactivateIncompatibleAddon() 0 32 5
C load_espresso_addons() 0 38 7
A detect_activations_or_upgrades() 0 11 3
B detect_if_activation_or_upgrade() 0 36 6
A _handle_core_version_change() 0 9 1
C fix_espresso_db_upgrade_option() 0 39 7
C initialize_db_if_no_migrations_required() 0 27 8
A initialize_addons() 0 9 3
A update_list_of_installed_versions() 0 12 3
A detect_req_type() 0 14 3
A _detect_major_version_change() 0 10 3
A is_major_version_change() 0 4 1
C detect_req_type_given_activation_history() 19 48 9
A _new_version_is_higher() 0 7 1
D _get_most_recently_active_version_from_activation_history() 0 26 9
D redirect_to_about_ee() 0 25 9
B load_core_configuration() 0 26 3
B _parse_model_names() 0 22 4
A _maybe_brew_regular() 0 6 4
A register_shortcodes_modules_and_widgets() 0 20 3
B _incompatible_addon_error() 0 30 4
A brew_espresso() 0 18 3
A set_hooks_for_core() 0 8 1
B _deactivate_incompatible_addons() 0 15 5
A perform_activations_upgrades_and_migrations() 0 8 2
A load_CPTs_and_session() 0 7 1
A load_controllers() 0 13 4
A core_loaded_and_ready() 0 11 2
A remove_pages_from_wp_list_pages() 0 4 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like EE_System often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use EE_System, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
use EventEspresso\core\exceptions\ExceptionStackTraceDisplay;
4
use EventEspresso\core\interfaces\ResettableInterface;
5
use EventEspresso\core\services\loaders\LoaderFactory;
6
use EventEspresso\core\services\loaders\LoaderInterface;
7
8
defined('EVENT_ESPRESSO_VERSION') || exit('No direct script access allowed');
9
10
11
12
/**
13
 * EE_System
14
 * The backbone of the core application that the rest of the system builds off of once bootstrapping is complete
15
 *
16
 * @package        Event Espresso
17
 * @subpackage     core/
18
 * @author         Brent Christensen, Michael Nelson
19
 */
20
final class EE_System implements ResettableInterface
21
{
22
23
24
    /**
25
     * indicates this is a 'normal' request. Ie, not activation, nor upgrade, nor activation.
26
     * So examples of this would be a normal GET request on the frontend or backend, or a POST, etc
27
     */
28
    const req_type_normal = 0;
29
30
    /**
31
     * Indicates this is a brand new installation of EE so we should install
32
     * tables and default data etc
33
     */
34
    const req_type_new_activation = 1;
35
36
    /**
37
     * we've detected that EE has been reactivated (or EE was activated during maintenance mode,
38
     * and we just exited maintenance mode). We MUST check the database is setup properly
39
     * and that default data is setup too
40
     */
41
    const req_type_reactivation = 2;
42
43
    /**
44
     * indicates that EE has been upgraded since its previous request.
45
     * We may have data migration scripts to call and will want to trigger maintenance mode
46
     */
47
    const req_type_upgrade = 3;
48
49
    /**
50
     * TODO  will detect that EE has been DOWNGRADED. We probably don't want to run in this case...
51
     */
52
    const req_type_downgrade = 4;
53
54
    /**
55
     * @deprecated since version 4.6.0.dev.006
56
     * Now whenever a new_activation is detected the request type is still just
57
     * new_activation (same for reactivation, upgrade, downgrade etc), but if we'r ein maintenance mode
58
     * EE_System::initialize_db_if_no_migrations_required and EE_Addon::initialize_db_if_no_migrations_required
59
     * will instead enqueue that EE plugin's db initialization for when we're taken out of maintenance mode.
60
     * (Specifically, when the migration manager indicates migrations are finished
61
     * EE_Data_Migration_Manager::initialize_db_for_enqueued_ee_plugins() will be called)
62
     */
63
    const req_type_activation_but_not_installed = 5;
64
65
    /**
66
     * option prefix for recording the activation history (like core's "espresso_db_update") of addons
67
     */
68
    const addon_activation_history_option_prefix = 'ee_addon_activation_history_';
69
70
71
    /**
72
     * @var EE_System $_instance
73
     */
74
    private static $_instance;
75
76
    /**
77
     * @var EE_Registry $registry
78
     */
79
    private $registry;
80
81
    /**
82
     * @var LoaderInterface $loader
83
     */
84
    private $loader;
85
86
    /**
87
     * @var EE_Capabilities $capabilities
88
     */
89
    private $capabilities;
90
91
    /**
92
     * @var EE_Request $request
93
     */
94
    private $request;
95
96
    /**
97
     * @var EE_Maintenance_Mode $maintenance_mode
98
     */
99
    private $maintenance_mode;
100
101
    /**
102
     * Stores which type of request this is, options being one of the constants on EE_System starting with req_type_*.
103
     * It can be a brand-new activation, a reactivation, an upgrade, a downgrade, or a normal request.
104
     *
105
     * @var int $_req_type
106
     */
107
    private $_req_type;
108
109
    /**
110
     * Whether or not there was a non-micro version change in EE core version during this request
111
     *
112
     * @var boolean $_major_version_change
113
     */
114
    private $_major_version_change = false;
115
116
117
118
    /**
119
     * @singleton method used to instantiate class object
120
     * @param EE_Registry|null         $registry
121
     * @param LoaderInterface|null     $loader
122
     * @param EE_Capabilities|null     $capabilities
123
     * @param EE_Request|null          $request
124
     * @param EE_Maintenance_Mode|null $maintenance_mode
125
     * @return EE_System
126
     */
127
    public static function instance(
128
        EE_Registry $registry = null,
129
        LoaderInterface $loader = null,
130
        EE_Capabilities $capabilities = null,
131
        EE_Request $request = null,
132
        EE_Maintenance_Mode $maintenance_mode = null
133
    ) {
134
        // check if class object is instantiated
135
        if (! self::$_instance instanceof EE_System) {
136
            self::$_instance = new self($registry, $loader, $capabilities, $request, $maintenance_mode);
0 ignored issues
show
Bug introduced by
It seems like $registry defined by parameter $registry on line 128 can be null; however, EE_System::__construct() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
Bug introduced by
It seems like $loader defined by parameter $loader on line 129 can be null; however, EE_System::__construct() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
Bug introduced by
It seems like $capabilities defined by parameter $capabilities on line 130 can be null; however, EE_System::__construct() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
Bug introduced by
It seems like $request defined by parameter $request on line 131 can be null; however, EE_System::__construct() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
Bug introduced by
It seems like $maintenance_mode defined by parameter $maintenance_mode on line 132 can be null; however, EE_System::__construct() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
137
        }
138
        return self::$_instance;
139
    }
140
141
142
143
    /**
144
     * resets the instance and returns it
145
     *
146
     * @return EE_System
147
     */
148
    public static function reset()
149
    {
150
        self::$_instance->_req_type = null;
151
        //make sure none of the old hooks are left hanging around
152
        remove_all_actions('AHEE__EE_System__perform_activations_upgrades_and_migrations');
153
        //we need to reset the migration manager in order for it to detect DMSs properly
154
        EE_Data_Migration_Manager::reset();
155
        self::instance()->detect_activations_or_upgrades();
156
        self::instance()->perform_activations_upgrades_and_migrations();
157
        return self::instance();
158
    }
159
160
161
162
    /**
163
     * sets hooks for running rest of system
164
     * provides "AHEE__EE_System__construct__complete" hook for EE Addons to use as their starting point
165
     * starting EE Addons from any other point may lead to problems
166
     *
167
     * @param EE_Registry         $registry
168
     * @param LoaderInterface     $loader
169
     * @param EE_Capabilities     $capabilities
170
     * @param EE_Request          $request
171
     * @param EE_Maintenance_Mode $maintenance_mode
172
     */
173
    private function __construct(
174
        EE_Registry $registry,
175
        LoaderInterface $loader,
176
        EE_Capabilities $capabilities,
177
        EE_Request $request,
178
        EE_Maintenance_Mode $maintenance_mode
179
    ) {
180
        $this->registry = $registry;
181
        $this->loader = $loader;
182
        $this->capabilities = $capabilities;
183
        $this->request = $request;
184
        $this->maintenance_mode = $maintenance_mode;
185
        do_action('AHEE__EE_System__construct__begin', $this);
186
        add_action(
187
            'AHEE__EE_Bootstrap__load_espresso_addons',
188
            array($this, 'loadCapabilities'),
189
            5
190
        );
191
        add_action(
192
            'AHEE__EE_Bootstrap__load_espresso_addons',
193
            array($this, 'loadCommandBus'),
194
            7
195
        );
196
        add_action(
197
            'AHEE__EE_Bootstrap__load_espresso_addons',
198
            array($this, 'loadPluginApi'),
199
            9
200
        );
201
        // allow addons to load first so that they can register autoloaders, set hooks for running DMS's, etc
202
        add_action(
203
            'AHEE__EE_Bootstrap__load_espresso_addons',
204
            array($this, 'load_espresso_addons')
205
        );
206
        // when an ee addon is activated, we want to call the core hook(s) again
207
        // because the newly-activated addon didn't get a chance to run at all
208
        add_action('activate_plugin', array($this, 'load_espresso_addons'), 1);
209
        // detect whether install or upgrade
210
        add_action(
211
            'AHEE__EE_Bootstrap__detect_activations_or_upgrades',
212
            array($this, 'detect_activations_or_upgrades'),
213
            3
214
        );
215
        // load EE_Config, EE_Textdomain, etc
216
        add_action(
217
            'AHEE__EE_Bootstrap__load_core_configuration',
218
            array($this, 'load_core_configuration'),
219
            5
220
        );
221
        // load EE_Config, EE_Textdomain, etc
222
        add_action(
223
            'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets',
224
            array($this, 'register_shortcodes_modules_and_widgets'),
225
            7
226
        );
227
        // you wanna get going? I wanna get going... let's get going!
228
        add_action(
229
            'AHEE__EE_Bootstrap__brew_espresso',
230
            array($this, 'brew_espresso'),
231
            9
232
        );
233
        //other housekeeping
234
        //exclude EE critical pages from wp_list_pages
235
        add_filter(
236
            'wp_list_pages_excludes',
237
            array($this, 'remove_pages_from_wp_list_pages'),
238
            10
239
        );
240
        // ALL EE Addons should use the following hook point to attach their initial setup too
241
        // it's extremely important for EE Addons to register any class autoloaders so that they can be available when the EE_Config loads
242
        do_action('AHEE__EE_System__construct__complete', $this);
243
    }
244
245
246
247
    /**
248
     * load and setup EE_Capabilities
249
     *
250
     * @return void
251
     * @throws EE_Error
252
     */
253
    public function loadCapabilities()
254
    {
255
        $this->loader->getShared('EE_Capabilities');
256
        add_action(
257
            'AHEE__EE_Capabilities__init_caps__before_initialization',
258
            function() {
259
                LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
260
            }
261
        );
262
    }
263
264
265
266
    /**
267
     * create and cache the CommandBus, and also add middleware
268
     * The CapChecker middleware requires the use of EE_Capabilities
269
     * which is why we need to load the CommandBus after Caps are set up
270
     *
271
     * @return void
272
     * @throws EE_Error
273
     */
274
    public function loadCommandBus()
275
    {
276
        $this->loader->getShared(
277
            'CommandBusInterface',
278
            array(
279
                null,
280
                apply_filters(
281
                    'FHEE__EE_Load_Espresso_Core__handle_request__CommandBus_middleware',
282
                    array(
283
                        $this->loader->getShared('EventEspresso\core\services\commands\middleware\CapChecker'),
284
                        $this->loader->getShared('EventEspresso\core\services\commands\middleware\AddActionHook'),
285
                    )
286
                ),
287
            )
288
        );
289
    }
290
291
292
293
    /**
294
     * @return void
295
     * @throws EE_Error
296
     */
297
    public function loadPluginApi()
298
    {
299
        // set autoloaders for all of the classes implementing EEI_Plugin_API
300
        // which provide helpers for EE plugin authors to more easily register certain components with EE.
301
        EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'plugin_api');
302
    }
303
304
305
    /**
306
     * @param string $addon_name
307
     * @param string $version_constant
308
     * @param string $min_version_required
309
     * @param string $load_callback
310
     * @param string $plugin_file_constant
311
     * @return void
312
     */
313
    private function deactivateIncompatibleAddon(
314
        $addon_name,
315
        $version_constant,
316
        $min_version_required,
317
        $load_callback,
318
        $plugin_file_constant
319
    ) {
320
        if (! defined($version_constant)) {
321
            return;
322
        }
323
        $addon_version = constant($version_constant);
324
        if ($addon_version && version_compare($addon_version, $min_version_required, '<')) {
325
            remove_action('AHEE__EE_System__load_espresso_addons', $load_callback);
326
            if (! function_exists('deactivate_plugins')) {
327
                require_once ABSPATH . 'wp-admin/includes/plugin.php';
328
            }
329
            deactivate_plugins(plugin_basename(constant($plugin_file_constant)));
330
            unset($_GET['activate'], $_REQUEST['activate'], $_GET['activate-multi'], $_REQUEST['activate-multi']);
331
            EE_Error::add_error(
332
                sprintf(
333
                    esc_html__(
334
                        '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.',
335
                        'event_espresso'
336
                    ),
337
                    $addon_name,
338
                    $min_version_required
339
                ),
340
                __FILE__, __FUNCTION__ . "({$addon_name})", __LINE__
341
            );
342
            EE_Error::get_notices(false, true);
343
        }
344
    }
345
346
347
    /**
348
     * load_espresso_addons
349
     * allow addons to load first so that they can set hooks for running DMS's, etc
350
     * this is hooked into both:
351
     *    'AHEE__EE_Bootstrap__load_core_configuration'
352
     *        which runs during the WP 'plugins_loaded' action at priority 5
353
     *    and the WP 'activate_plugin' hook point
354
     *
355
     * @access public
356
     * @return void
357
     */
358
    public function load_espresso_addons()
359
    {
360
        $this->deactivateIncompatibleAddon(
361
            'Wait Lists',
362
            'EE_WAIT_LISTS_VERSION',
363
            '1.0.0.rc.074',
364
            'load_espresso_wait_lists',
365
            'EE_WAIT_LISTS_PLUGIN_FILE'
366
        );
367
        $this->deactivateIncompatibleAddon(
368
            'Automated Upcoming Event Notifications',
369
            'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_VERSION',
370
            '1.0.0.rc.091',
371
            'load_espresso_automated_upcoming_event_notification',
372
            'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_PLUGIN_FILE'
373
        );
374
        do_action('AHEE__EE_System__load_espresso_addons');
375
        //if the WP API basic auth plugin isn't already loaded, load it now.
376
        //We want it for mobile apps. Just include the entire plugin
377
        //also, don't load the basic auth when a plugin is getting activated, because
378
        //it could be the basic auth plugin, and it doesn't check if its methods are already defined
379
        //and causes a fatal error
380
        if (
381
            ! (
382
                isset($_GET['activate'])
383
                && $_GET['activate'] === 'true'
384
            )
385
            && ! function_exists('json_basic_auth_handler')
386
            && ! function_exists('json_basic_auth_error')
387
            && ! (
388
                isset($_GET['action'])
389
                && in_array($_GET['action'], array('activate', 'activate-selected'), true)
390
            )
391
        ) {
392
            include_once EE_THIRD_PARTY . 'wp-api-basic-auth' . DS . 'basic-auth.php';
393
        }
394
        do_action('AHEE__EE_System__load_espresso_addons__complete');
395
    }
396
397
398
399
    /**
400
     * detect_activations_or_upgrades
401
     * Checks for activation or upgrade of core first;
402
     * then also checks if any registered addons have been activated or upgraded
403
     * This is hooked into 'AHEE__EE_Bootstrap__detect_activations_or_upgrades'
404
     * which runs during the WP 'plugins_loaded' action at priority 3
405
     *
406
     * @access public
407
     * @return void
408
     */
409
    public function detect_activations_or_upgrades()
410
    {
411
        //first off: let's make sure to handle core
412
        $this->detect_if_activation_or_upgrade();
413
        foreach ($this->registry->addons as $addon) {
414
            if ($addon instanceof EE_Addon) {
415
                //detect teh request type for that addon
416
                $addon->detect_activation_or_upgrade();
417
            }
418
        }
419
    }
420
421
422
423
    /**
424
     * detect_if_activation_or_upgrade
425
     * Takes care of detecting whether this is a brand new install or code upgrade,
426
     * and either setting up the DB or setting up maintenance mode etc.
427
     *
428
     * @access public
429
     * @return void
430
     */
431
    public function detect_if_activation_or_upgrade()
432
    {
433
        do_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin');
434
        // check if db has been updated, or if its a brand-new installation
435
        $espresso_db_update = $this->fix_espresso_db_upgrade_option();
436
        $request_type = $this->detect_req_type($espresso_db_update);
437
        //EEH_Debug_Tools::printr( $request_type, '$request_type', __FILE__, __LINE__ );
438
        switch ($request_type) {
439
            case EE_System::req_type_new_activation:
440
                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__new_activation');
441
                $this->_handle_core_version_change($espresso_db_update);
442
                break;
443
            case EE_System::req_type_reactivation:
444
                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__reactivation');
445
                $this->_handle_core_version_change($espresso_db_update);
446
                break;
447
            case EE_System::req_type_upgrade:
448
                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__upgrade');
449
                //migrations may be required now that we've upgraded
450
                $this->maintenance_mode->set_maintenance_mode_if_db_old();
451
                $this->_handle_core_version_change($espresso_db_update);
452
                //				echo "done upgrade";die;
453
                break;
454
            case EE_System::req_type_downgrade:
455
                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__downgrade');
456
                //its possible migrations are no longer required
457
                $this->maintenance_mode->set_maintenance_mode_if_db_old();
458
                $this->_handle_core_version_change($espresso_db_update);
459
                break;
460
            case EE_System::req_type_normal:
461
            default:
462
                //				$this->_maybe_redirect_to_ee_about();
463
                break;
464
        }
465
        do_action('AHEE__EE_System__detect_if_activation_or_upgrade__complete');
466
    }
467
468
469
470
    /**
471
     * Updates the list of installed versions and sets hooks for
472
     * initializing the database later during the request
473
     *
474
     * @param array $espresso_db_update
475
     */
476
    private function _handle_core_version_change($espresso_db_update)
477
    {
478
        $this->update_list_of_installed_versions($espresso_db_update);
479
        //get ready to verify the DB is ok (provided we aren't in maintenance mode, of course)
480
        add_action(
481
            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
482
            array($this, 'initialize_db_if_no_migrations_required')
483
        );
484
    }
485
486
487
488
    /**
489
     * standardizes the wp option 'espresso_db_upgrade' which actually stores
490
     * information about what versions of EE have been installed and activated,
491
     * NOT necessarily the state of the database
492
     *
493
     * @param mixed $espresso_db_update the value of the WordPress option.
494
     *                                            If not supplied, fetches it from the options table
495
     * @return array the correct value of 'espresso_db_upgrade', after saving it, if it needed correction
496
     */
497
    private function fix_espresso_db_upgrade_option($espresso_db_update = null)
498
    {
499
        do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
500
        if (! $espresso_db_update) {
501
            $espresso_db_update = get_option('espresso_db_update');
502
        }
503
        // check that option is an array
504
        if (! is_array($espresso_db_update)) {
505
            // if option is FALSE, then it never existed
506
            if ($espresso_db_update === false) {
507
                // make $espresso_db_update an array and save option with autoload OFF
508
                $espresso_db_update = array();
509
                add_option('espresso_db_update', $espresso_db_update, '', 'no');
510
            } else {
511
                // option is NOT FALSE but also is NOT an array, so make it an array and save it
512
                $espresso_db_update = array($espresso_db_update => array());
513
                update_option('espresso_db_update', $espresso_db_update);
514
            }
515
        } else {
516
            $corrected_db_update = array();
517
            //if IS an array, but is it an array where KEYS are version numbers, and values are arrays?
518
            foreach ($espresso_db_update as $should_be_version_string => $should_be_array) {
519
                if (is_int($should_be_version_string) && ! is_array($should_be_array)) {
520
                    //the key is an int, and the value IS NOT an array
521
                    //so it must be numerically-indexed, where values are versions installed...
522
                    //fix it!
523
                    $version_string = $should_be_array;
524
                    $corrected_db_update[$version_string] = array('unknown-date');
525
                } else {
526
                    //ok it checks out
527
                    $corrected_db_update[$should_be_version_string] = $should_be_array;
528
                }
529
            }
530
            $espresso_db_update = $corrected_db_update;
531
            update_option('espresso_db_update', $espresso_db_update);
532
        }
533
        do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__complete', $espresso_db_update);
534
        return $espresso_db_update;
535
    }
536
537
538
539
    /**
540
     * Does the traditional work of setting up the plugin's database and adding default data.
541
     * If migration script/process did not exist, this is what would happen on every activation/reactivation/upgrade.
542
     * NOTE: if we're in maintenance mode (which would be the case if we detect there are data
543
     * migration scripts that need to be run and a version change happens), enqueues core for database initialization,
544
     * so that it will be done when migrations are finished
545
     *
546
     * @param boolean $initialize_addons_too if true, we double-check addons' database tables etc too;
547
     * @param boolean $verify_schema         if true will re-check the database tables have the correct schema.
548
     *                                       This is a resource-intensive job
549
     *                                       so we prefer to only do it when necessary
550
     * @return void
551
     * @throws EE_Error
552
     */
553
    public function initialize_db_if_no_migrations_required($initialize_addons_too = false, $verify_schema = true)
554
    {
555
        $request_type = $this->detect_req_type();
556
        //only initialize system if we're not in maintenance mode.
557
        if ($this->maintenance_mode->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
558
            update_option('ee_flush_rewrite_rules', true);
559
            if ($verify_schema) {
560
                EEH_Activation::initialize_db_and_folders();
561
            }
562
            EEH_Activation::initialize_db_content();
563
            EEH_Activation::system_initialization();
564
            if ($initialize_addons_too) {
565
                $this->initialize_addons();
566
            }
567
        } else {
568
            EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for('Core');
569
        }
570
        if ($request_type === EE_System::req_type_new_activation
571
            || $request_type === EE_System::req_type_reactivation
572
            || (
573
                $request_type === EE_System::req_type_upgrade
574
                && $this->is_major_version_change()
575
            )
576
        ) {
577
            add_action('AHEE__EE_System__initialize_last', array($this, 'redirect_to_about_ee'), 9);
578
        }
579
    }
580
581
582
583
    /**
584
     * Initializes the db for all registered addons
585
     *
586
     * @throws EE_Error
587
     */
588
    public function initialize_addons()
589
    {
590
        //foreach registered addon, make sure its db is up-to-date too
591
        foreach ($this->registry->addons as $addon) {
592
            if ($addon instanceof EE_Addon) {
593
                $addon->initialize_db_if_no_migrations_required();
594
            }
595
        }
596
    }
597
598
599
600
    /**
601
     * Adds the current code version to the saved wp option which stores a list of all ee versions ever installed.
602
     *
603
     * @param    array  $version_history
604
     * @param    string $current_version_to_add version to be added to the version history
605
     * @return    boolean success as to whether or not this option was changed
606
     */
607
    public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
608
    {
609
        if (! $version_history) {
610
            $version_history = $this->fix_espresso_db_upgrade_option($version_history);
611
        }
612
        if ($current_version_to_add === null) {
613
            $current_version_to_add = espresso_version();
614
        }
615
        $version_history[$current_version_to_add][] = date('Y-m-d H:i:s', time());
616
        // re-save
617
        return update_option('espresso_db_update', $version_history);
618
    }
619
620
621
622
    /**
623
     * Detects if the current version indicated in the has existed in the list of
624
     * previously-installed versions of EE (espresso_db_update). Does NOT modify it (ie, no side-effect)
625
     *
626
     * @param array $espresso_db_update array from the wp option stored under the name 'espresso_db_update'.
627
     *                                  If not supplied, fetches it from the options table.
628
     *                                  Also, caches its result so later parts of the code can also know whether
629
     *                                  there's been an update or not. This way we can add the current version to
630
     *                                  espresso_db_update, but still know if this is a new install or not
631
     * @return int one of the constants on EE_System::req_type_
632
     */
633
    public function detect_req_type($espresso_db_update = null)
634
    {
635
        if ($this->_req_type === null) {
636
            $espresso_db_update = ! empty($espresso_db_update)
637
                ? $espresso_db_update
638
                : $this->fix_espresso_db_upgrade_option();
639
            $this->_req_type = EE_System::detect_req_type_given_activation_history(
640
                $espresso_db_update,
641
                'ee_espresso_activation', espresso_version()
642
            );
643
            $this->_major_version_change = $this->_detect_major_version_change($espresso_db_update);
644
        }
645
        return $this->_req_type;
646
    }
647
648
649
650
    /**
651
     * Returns whether or not there was a non-micro version change (ie, change in either
652
     * the first or second number in the version. Eg 4.9.0.rc.001 to 4.10.0.rc.000,
653
     * but not 4.9.0.rc.0001 to 4.9.1.rc.0001
654
     *
655
     * @param $activation_history
656
     * @return bool
657
     */
658
    private function _detect_major_version_change($activation_history)
659
    {
660
        $previous_version = EE_System::_get_most_recently_active_version_from_activation_history($activation_history);
661
        $previous_version_parts = explode('.', $previous_version);
662
        $current_version_parts = explode('.', espresso_version());
663
        return isset($previous_version_parts[0], $previous_version_parts[1], $current_version_parts[0], $current_version_parts[1])
664
               && ($previous_version_parts[0] !== $current_version_parts[0]
665
                   || $previous_version_parts[1] !== $current_version_parts[1]
666
               );
667
    }
668
669
670
671
    /**
672
     * Returns true if either the major or minor version of EE changed during this request.
673
     * Eg 4.9.0.rc.001 to 4.10.0.rc.000, but not 4.9.0.rc.0001 to 4.9.1.rc.0001
674
     *
675
     * @return bool
676
     */
677
    public function is_major_version_change()
678
    {
679
        return $this->_major_version_change;
680
    }
681
682
683
684
    /**
685
     * Determines the request type for any ee addon, given three piece of info: the current array of activation
686
     * histories (for core that' 'espresso_db_update' wp option); the name of the WordPress option which is temporarily
687
     * set upon activation of the plugin (for core it's 'ee_espresso_activation'); and the version that this plugin was
688
     * just activated to (for core that will always be espresso_version())
689
     *
690
     * @param array  $activation_history_for_addon     the option's value which stores the activation history for this
691
     *                                                 ee plugin. for core that's 'espresso_db_update'
692
     * @param string $activation_indicator_option_name the name of the WordPress option that is temporarily set to
693
     *                                                 indicate that this plugin was just activated
694
     * @param string $version_to_upgrade_to            the version that was just upgraded to (for core that will be
695
     *                                                 espresso_version())
696
     * @return int one of the constants on EE_System::req_type_*
697
     */
698
    public static function detect_req_type_given_activation_history(
699
        $activation_history_for_addon,
700
        $activation_indicator_option_name,
701
        $version_to_upgrade_to
702
    ) {
703
        $version_is_higher = self::_new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to);
704
        if ($activation_history_for_addon) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $activation_history_for_addon of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
705
            //it exists, so this isn't a completely new install
706
            //check if this version already in that list of previously installed versions
707
            if (! isset($activation_history_for_addon[$version_to_upgrade_to])) {
708
                //it a version we haven't seen before
709
                if ($version_is_higher === 1) {
710
                    $req_type = EE_System::req_type_upgrade;
711
                } else {
712
                    $req_type = EE_System::req_type_downgrade;
713
                }
714
                delete_option($activation_indicator_option_name);
715
            } else {
716
                // its not an update. maybe a reactivation?
717
                if (get_option($activation_indicator_option_name, false)) {
718 View Code Duplication
                    if ($version_is_higher === -1) {
719
                        $req_type = EE_System::req_type_downgrade;
720
                    } else if ($version_is_higher === 0) {
721
                        //we've seen this version before, but it's an activation. must be a reactivation
722
                        $req_type = EE_System::req_type_reactivation;
723
                    } else {//$version_is_higher === 1
724
                        $req_type = EE_System::req_type_upgrade;
725
                    }
726
                    delete_option($activation_indicator_option_name);
727 View Code Duplication
                } else {
728
                    //we've seen this version before and the activation indicate doesn't show it was just activated
729
                    if ($version_is_higher === -1) {
730
                        $req_type = EE_System::req_type_downgrade;
731
                    } else if ($version_is_higher === 0) {
732
                        //we've seen this version before and it's not an activation. its normal request
733
                        $req_type = EE_System::req_type_normal;
734
                    } else {//$version_is_higher === 1
735
                        $req_type = EE_System::req_type_upgrade;
736
                    }
737
                }
738
            }
739
        } else {
740
            //brand new install
741
            $req_type = EE_System::req_type_new_activation;
742
            delete_option($activation_indicator_option_name);
743
        }
744
        return $req_type;
745
    }
746
747
748
749
    /**
750
     * Detects if the $version_to_upgrade_to is higher than the most recent version in
751
     * the $activation_history_for_addon
752
     *
753
     * @param array  $activation_history_for_addon (keys are versions, values are arrays of times activated,
754
     *                                             sometimes containing 'unknown-date'
755
     * @param string $version_to_upgrade_to        (current version)
756
     * @return int results of version_compare( $version_to_upgrade_to, $most_recently_active_version ).
757
     *                                             ie, -1 if $version_to_upgrade_to is LOWER (downgrade);
758
     *                                             0 if $version_to_upgrade_to MATCHES (reactivation or normal request);
759
     *                                             1 if $version_to_upgrade_to is HIGHER (upgrade) ;
760
     */
761
    private static function _new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to)
762
    {
763
        //find the most recently-activated version
764
        $most_recently_active_version =
765
            EE_System::_get_most_recently_active_version_from_activation_history($activation_history_for_addon);
766
        return version_compare($version_to_upgrade_to, $most_recently_active_version);
767
    }
768
769
770
771
    /**
772
     * Gets the most recently active version listed in the activation history,
773
     * and if none are found (ie, it's a brand new install) returns '0.0.0.dev.000'.
774
     *
775
     * @param array $activation_history  (keys are versions, values are arrays of times activated,
776
     *                                   sometimes containing 'unknown-date'
777
     * @return string
778
     */
779
    private static function _get_most_recently_active_version_from_activation_history($activation_history)
780
    {
781
        $most_recently_active_version_activation = '1970-01-01 00:00:00';
782
        $most_recently_active_version = '0.0.0.dev.000';
783
        if (is_array($activation_history)) {
784
            foreach ($activation_history as $version => $times_activated) {
785
                //check there is a record of when this version was activated. Otherwise,
786
                //mark it as unknown
787
                if (! $times_activated) {
788
                    $times_activated = array('unknown-date');
789
                }
790
                if (is_string($times_activated)) {
791
                    $times_activated = array($times_activated);
792
                }
793
                foreach ($times_activated as $an_activation) {
794
                    if ($an_activation !== 'unknown-date' && $an_activation > $most_recently_active_version_activation) {
795
                        $most_recently_active_version = $version;
796
                        $most_recently_active_version_activation = $an_activation === 'unknown-date'
797
                            ? '1970-01-01 00:00:00'
798
                            : $an_activation;
799
                    }
800
                }
801
            }
802
        }
803
        return $most_recently_active_version;
804
    }
805
806
807
808
    /**
809
     * This redirects to the about EE page after activation
810
     *
811
     * @return void
812
     */
813
    public function redirect_to_about_ee()
814
    {
815
        $notices = EE_Error::get_notices(false);
816
        //if current user is an admin and it's not an ajax or rest request
817
        if (
818
            ! (defined('DOING_AJAX') && DOING_AJAX)
819
            && ! (defined('REST_REQUEST') && REST_REQUEST)
820
            && ! isset($notices['errors'])
821
            && apply_filters(
822
                'FHEE__EE_System__redirect_to_about_ee__do_redirect',
823
                $this->capabilities->current_user_can('manage_options', 'espresso_about_default')
824
            )
825
        ) {
826
            $query_params = array('page' => 'espresso_about');
827
            if (EE_System::instance()->detect_req_type() === EE_System::req_type_new_activation) {
828
                $query_params['new_activation'] = true;
829
            }
830
            if (EE_System::instance()->detect_req_type() === EE_System::req_type_reactivation) {
831
                $query_params['reactivation'] = true;
832
            }
833
            $url = add_query_arg($query_params, admin_url('admin.php'));
834
            wp_safe_redirect($url);
835
            exit();
836
        }
837
    }
838
839
840
841
    /**
842
     * load_core_configuration
843
     * this is hooked into 'AHEE__EE_Bootstrap__load_core_configuration'
844
     * which runs during the WP 'plugins_loaded' action at priority 5
845
     *
846
     * @return void
847
     * @throws ReflectionException
848
     */
849
    public function load_core_configuration()
850
    {
851
        do_action('AHEE__EE_System__load_core_configuration__begin', $this);
852
        $this->loader->getShared('EE_Load_Textdomain');
853
        //load textdomain
854
        EE_Load_Textdomain::load_textdomain();
855
        // load and setup EE_Config and EE_Network_Config
856
        $config = $this->loader->getShared('EE_Config');
857
        $this->loader->getShared('EE_Network_Config');
858
        // setup autoloaders
859
        // enable logging?
860
        if ($config->admin->use_full_logging) {
861
            $this->loader->getShared('EE_Log');
862
        }
863
        // check for activation errors
864
        $activation_errors = get_option('ee_plugin_activation_errors', false);
865
        if ($activation_errors) {
866
            EE_Error::add_error($activation_errors, __FILE__, __FUNCTION__, __LINE__);
867
            update_option('ee_plugin_activation_errors', false);
868
        }
869
        // get model names
870
        $this->_parse_model_names();
871
        //load caf stuff a chance to play during the activation process too.
872
        $this->_maybe_brew_regular();
873
        do_action('AHEE__EE_System__load_core_configuration__complete', $this);
874
    }
875
876
877
878
    /**
879
     * cycles through all of the models/*.model.php files, and assembles an array of model names
880
     *
881
     * @return void
882
     * @throws ReflectionException
883
     */
884
    private function _parse_model_names()
885
    {
886
        //get all the files in the EE_MODELS folder that end in .model.php
887
        $models = glob(EE_MODELS . '*.model.php');
888
        $model_names = array();
889
        $non_abstract_db_models = array();
890
        foreach ($models as $model) {
891
            // get model classname
892
            $classname = EEH_File::get_classname_from_filepath_with_standard_filename($model);
893
            $short_name = str_replace('EEM_', '', $classname);
894
            $reflectionClass = new ReflectionClass($classname);
895
            if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
896
                $non_abstract_db_models[$short_name] = $classname;
897
            }
898
            $model_names[$short_name] = $classname;
899
        }
900
        $this->registry->models = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
901
        $this->registry->non_abstract_db_models = apply_filters(
902
            'FHEE__EE_System__parse_implemented_model_names',
903
            $non_abstract_db_models
904
        );
905
    }
906
907
908
909
    /**
910
     * The purpose of this method is to simply check for a file named "caffeinated/brewing_regular.php" for any hooks
911
     * that need to be setup before our EE_System launches.
912
     *
913
     * @return void
914
     */
915
    private function _maybe_brew_regular()
916
    {
917
        if ((! defined('EE_DECAF') || EE_DECAF !== true) && is_readable(EE_CAFF_PATH . 'brewing_regular.php')) {
918
            require_once EE_CAFF_PATH . 'brewing_regular.php';
919
        }
920
    }
921
922
923
924
    /**
925
     * register_shortcodes_modules_and_widgets
926
     * generate lists of shortcodes and modules, then verify paths and classes
927
     * This is hooked into 'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets'
928
     * which runs during the WP 'plugins_loaded' action at priority 7
929
     *
930
     * @access public
931
     * @return void
932
     * @throws Exception
933
     */
934
    public function register_shortcodes_modules_and_widgets()
935
    {
936
        try {
937
            // load, register, and add shortcodes the new way
938
            $this->loader->getShared(
939
                'EventEspresso\core\services\shortcodes\ShortcodesManager',
940
                array(
941
                    // and the old way, but we'll put it under control of the new system
942
                    EE_Config::getLegacyShortcodesManager()
943
                )
944
            );
945
        } catch (Exception $exception) {
946
            new ExceptionStackTraceDisplay($exception);
947
        }
948
        do_action('AHEE__EE_System__register_shortcodes_modules_and_widgets');
949
        // check for addons using old hook point
950
        if (has_action('AHEE__EE_System__register_shortcodes_modules_and_addons')) {
951
            $this->_incompatible_addon_error();
952
        }
953
    }
954
955
956
957
    /**
958
     * _incompatible_addon_error
959
     *
960
     * @access public
961
     * @return void
962
     */
963
    private function _incompatible_addon_error()
964
    {
965
        // get array of classes hooking into here
966
        $class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook(
967
            'AHEE__EE_System__register_shortcodes_modules_and_addons'
968
        );
969
        if (! empty($class_names)) {
970
            $msg = __(
971
                'The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
972
                'event_espresso'
973
            );
974
            $msg .= '<ul>';
975
            foreach ($class_names as $class_name) {
976
                $msg .= '<li><b>Event Espresso - ' . str_replace(
977
                        array('EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'), '',
978
                        $class_name
979
                    ) . '</b></li>';
980
            }
981
            $msg .= '</ul>';
982
            $msg .= __(
983
                'Compatibility issues can be avoided and/or resolved by keeping addons and plugins updated to the latest version.',
984
                'event_espresso'
985
            );
986
            // save list of incompatible addons to wp-options for later use
987
            add_option('ee_incompatible_addons', $class_names, '', 'no');
988
            if (is_admin()) {
989
                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
990
            }
991
        }
992
    }
993
994
995
996
    /**
997
     * brew_espresso
998
     * begins the process of setting hooks for initializing EE in the correct order
999
     * This is happening on the 'AHEE__EE_Bootstrap__brew_espresso' hook point
1000
     * which runs during the WP 'plugins_loaded' action at priority 9
1001
     *
1002
     * @return void
1003
     */
1004
    public function brew_espresso()
1005
    {
1006
        do_action('AHEE__EE_System__brew_espresso__begin', $this);
1007
        // load some final core systems
1008
        add_action('init', array($this, 'set_hooks_for_core'), 1);
1009
        add_action('init', array($this, 'perform_activations_upgrades_and_migrations'), 3);
1010
        add_action('init', array($this, 'load_CPTs_and_session'), 5);
1011
        add_action('init', array($this, 'load_controllers'), 7);
1012
        add_action('init', array($this, 'core_loaded_and_ready'), 9);
1013
        add_action('init', array($this, 'initialize'), 10);
1014
        add_action('init', array($this, 'initialize_last'), 100);
1015
        if (is_admin() && apply_filters('FHEE__EE_System__brew_espresso__load_pue', true)) {
1016
            // pew pew pew
1017
            $this->loader->getShared('EE_PUE');
1018
            do_action('AHEE__EE_System__brew_espresso__after_pue_init');
1019
        }
1020
        do_action('AHEE__EE_System__brew_espresso__complete', $this);
1021
    }
1022
1023
1024
1025
    /**
1026
     *    set_hooks_for_core
1027
     *
1028
     * @access public
1029
     * @return    void
1030
     * @throws EE_Error
1031
     */
1032
    public function set_hooks_for_core()
1033
    {
1034
        $this->_deactivate_incompatible_addons();
1035
        do_action('AHEE__EE_System__set_hooks_for_core');
1036
        //caps need to be initialized on every request so that capability maps are set.
1037
        //@see https://events.codebasehq.com/projects/event-espresso/tickets/8674
1038
        $this->registry->CAP->init_caps();
1039
    }
1040
1041
1042
1043
    /**
1044
     * Using the information gathered in EE_System::_incompatible_addon_error,
1045
     * deactivates any addons considered incompatible with the current version of EE
1046
     */
1047
    private function _deactivate_incompatible_addons()
1048
    {
1049
        $incompatible_addons = get_option('ee_incompatible_addons', array());
1050
        if (! empty($incompatible_addons)) {
1051
            $active_plugins = get_option('active_plugins', array());
1052
            foreach ($active_plugins as $active_plugin) {
1053
                foreach ($incompatible_addons as $incompatible_addon) {
1054
                    if (strpos($active_plugin, $incompatible_addon) !== false) {
1055
                        unset($_GET['activate']);
1056
                        espresso_deactivate_plugin($active_plugin);
1057
                    }
1058
                }
1059
            }
1060
        }
1061
    }
1062
1063
1064
1065
    /**
1066
     *    perform_activations_upgrades_and_migrations
1067
     *
1068
     * @access public
1069
     * @return    void
1070
     */
1071
    public function perform_activations_upgrades_and_migrations()
1072
    {
1073
        //first check if we had previously attempted to setup EE's directories but failed
1074
        if (EEH_Activation::upload_directories_incomplete()) {
1075
            EEH_Activation::create_upload_directories();
1076
        }
1077
        do_action('AHEE__EE_System__perform_activations_upgrades_and_migrations');
1078
    }
1079
1080
1081
1082
    /**
1083
     *    load_CPTs_and_session
1084
     *
1085
     * @access public
1086
     * @return    void
1087
     */
1088
    public function load_CPTs_and_session()
1089
    {
1090
        do_action('AHEE__EE_System__load_CPTs_and_session__start');
1091
        // register Custom Post Types
1092
        $this->loader->getShared('EE_Register_CPTs');
1093
        do_action('AHEE__EE_System__load_CPTs_and_session__complete');
1094
    }
1095
1096
1097
1098
    /**
1099
     * load_controllers
1100
     * this is the best place to load any additional controllers that needs access to EE core.
1101
     * it is expected that all basic core EE systems, that are not dependant on the current request are loaded at this
1102
     * time
1103
     *
1104
     * @access public
1105
     * @return void
1106
     */
1107
    public function load_controllers()
1108
    {
1109
        do_action('AHEE__EE_System__load_controllers__start');
1110
        // let's get it started
1111
        if (! is_admin() && ! $this->maintenance_mode->level()) {
1112
            do_action('AHEE__EE_System__load_controllers__load_front_controllers');
1113
            $this->loader->getShared('EE_Front_Controller');
1114
        } else if (! EE_FRONT_AJAX) {
1115
            do_action('AHEE__EE_System__load_controllers__load_admin_controllers');
1116
            $this->loader->getShared('EE_Admin');
1117
        }
1118
        do_action('AHEE__EE_System__load_controllers__complete');
1119
    }
1120
1121
1122
1123
    /**
1124
     * core_loaded_and_ready
1125
     * all of the basic EE core should be loaded at this point and available regardless of M-Mode
1126
     *
1127
     * @access public
1128
     * @return void
1129
     */
1130
    public function core_loaded_and_ready()
1131
    {
1132
        $this->loader->getShared('EE_Session');
1133
        do_action('AHEE__EE_System__core_loaded_and_ready');
1134
        // load_espresso_template_tags
1135
        if (is_readable(EE_PUBLIC . 'template_tags.php')) {
1136
            require_once(EE_PUBLIC . 'template_tags.php');
1137
        }
1138
        do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1139
        $this->loader->getShared('EventEspresso\core\services\assets\Registry');
1140
    }
1141
1142
1143
1144
    /**
1145
     * initialize
1146
     * this is the best place to begin initializing client code
1147
     *
1148
     * @access public
1149
     * @return void
1150
     */
1151
    public function initialize()
1152
    {
1153
        do_action('AHEE__EE_System__initialize');
1154
    }
1155
1156
1157
1158
    /**
1159
     * initialize_last
1160
     * this is run really late during the WP init hook point, and ensures that mostly everything else that needs to
1161
     * initialize has done so
1162
     *
1163
     * @access public
1164
     * @return void
1165
     */
1166
    public function initialize_last()
1167
    {
1168
        do_action('AHEE__EE_System__initialize_last');
1169
        add_action('admin_bar_init', array($this, 'addEspressoToolbar'));
1170
    }
1171
1172
1173
1174
    /**
1175
     * @return void
1176
     * @throws EE_Error
1177
     */
1178
    public function addEspressoToolbar()
1179
    {
1180
        $this->loader->getShared(
1181
            'EventEspresso\core\domain\services\admin\AdminToolBar',
1182
            array($this->registry->CAP)
1183
        );
1184
    }
1185
1186
1187
1188
    /**
1189
     * do_not_cache
1190
     * sets no cache headers and defines no cache constants for WP plugins
1191
     *
1192
     * @access public
1193
     * @return void
1194
     */
1195
    public static function do_not_cache()
1196
    {
1197
        // set no cache constants
1198
        if (! defined('DONOTCACHEPAGE')) {
1199
            define('DONOTCACHEPAGE', true);
1200
        }
1201
        if (! defined('DONOTCACHCEOBJECT')) {
1202
            define('DONOTCACHCEOBJECT', true);
1203
        }
1204
        if (! defined('DONOTCACHEDB')) {
1205
            define('DONOTCACHEDB', true);
1206
        }
1207
        // add no cache headers
1208
        add_action('send_headers', array('EE_System', 'nocache_headers'), 10);
1209
        // plus a little extra for nginx and Google Chrome
1210
        add_filter('nocache_headers', array('EE_System', 'extra_nocache_headers'), 10, 1);
1211
        // prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes with the registration process
1212
        remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
1213
    }
1214
1215
1216
1217
    /**
1218
     *    extra_nocache_headers
1219
     *
1220
     * @access    public
1221
     * @param $headers
1222
     * @return    array
1223
     */
1224
    public static function extra_nocache_headers($headers)
1225
    {
1226
        // for NGINX
1227
        $headers['X-Accel-Expires'] = 0;
1228
        // plus extra for Google Chrome since it doesn't seem to respect "no-cache", but WILL respect "no-store"
1229
        $headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0';
1230
        return $headers;
1231
    }
1232
1233
1234
1235
    /**
1236
     *    nocache_headers
1237
     *
1238
     * @access    public
1239
     * @return    void
1240
     */
1241
    public static function nocache_headers()
1242
    {
1243
        nocache_headers();
1244
    }
1245
1246
1247
1248
1249
    /**
1250
     * simply hooks into "wp_list_pages_exclude" filter (for wp_list_pages method) and makes sure EE critical pages are
1251
     * never returned with the function.
1252
     *
1253
     * @param  array $exclude_array any existing pages being excluded are in this array.
1254
     * @return array
1255
     */
1256
    public function remove_pages_from_wp_list_pages($exclude_array)
1257
    {
1258
        return array_merge($exclude_array, $this->registry->CFG->core->get_critical_pages_array());
1259
    }
1260
1261
1262
1263
}
1264
// End of file EE_System.core.php
1265
// Location: /core/EE_System.core.php
1266