Completed
Branch FET/11399/verify-paypal-creden... (c7ad03)
by
unknown
66:22 queued 52:43
created

EE_System   F

Complexity

Total Complexity 140

Size/Duplication

Total Lines 1261
Duplicated Lines 2.3 %

Coupling/Cohesion

Components 1
Dependencies 17

Importance

Changes 0
Metric Value
dl 29
loc 1261
rs 0.6314
c 0
b 0
f 0
wmc 140
lcom 1
cbo 17

41 Methods

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

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
125
126
127
128
    /**
129
     * @singleton method used to instantiate class object
130
     * @param EE_Registry|null         $registry
131
     * @param LoaderInterface|null     $loader
132
     * @param RequestInterface|null          $request
133
     * @param EE_Maintenance_Mode|null $maintenance_mode
134
     * @return EE_System
135
     */
136
    public static function instance(
137
        EE_Registry $registry = null,
138
        LoaderInterface $loader = null,
139
        RequestInterface $request = null,
140
        EE_Maintenance_Mode $maintenance_mode = null
141
    ) {
142
        // check if class object is instantiated
143
        if (! self::$_instance instanceof EE_System) {
144
            self::$_instance = new self($registry, $loader, $request, $maintenance_mode);
0 ignored issues
show
Bug introduced by
It seems like $registry defined by parameter $registry on line 137 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 138 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 139 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 140 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...
145
        }
146
        return self::$_instance;
147
    }
148
149
150
151
    /**
152
     * resets the instance and returns it
153
     *
154
     * @return EE_System
155
     */
156
    public static function reset()
157
    {
158
        self::$_instance->_req_type = null;
159
        //make sure none of the old hooks are left hanging around
160
        remove_all_actions('AHEE__EE_System__perform_activations_upgrades_and_migrations');
161
        //we need to reset the migration manager in order for it to detect DMSs properly
162
        EE_Data_Migration_Manager::reset();
163
        self::instance()->detect_activations_or_upgrades();
164
        self::instance()->perform_activations_upgrades_and_migrations();
165
        return self::instance();
166
    }
167
168
169
170
    /**
171
     * sets hooks for running rest of system
172
     * provides "AHEE__EE_System__construct__complete" hook for EE Addons to use as their starting point
173
     * starting EE Addons from any other point may lead to problems
174
     *
175
     * @param EE_Registry         $registry
176
     * @param LoaderInterface     $loader
177
     * @param RequestInterface          $request
178
     * @param EE_Maintenance_Mode $maintenance_mode
179
     */
180
    private function __construct(
181
        EE_Registry $registry,
182
        LoaderInterface $loader,
183
        RequestInterface $request,
184
        EE_Maintenance_Mode $maintenance_mode
185
    ) {
186
        $this->registry         = $registry;
187
        $this->loader           = $loader;
188
        $this->request          = $request;
189
        $this->maintenance_mode = $maintenance_mode;
190
        do_action('AHEE__EE_System__construct__begin', $this);
191
        add_action(
192
            'AHEE__EE_Bootstrap__load_espresso_addons',
193
            array($this, 'loadCapabilities'),
194
            5
195
        );
196
        add_action(
197
            'AHEE__EE_Bootstrap__load_espresso_addons',
198
            array($this, 'loadCommandBus'),
199
            7
200
        );
201
        add_action(
202
            'AHEE__EE_Bootstrap__load_espresso_addons',
203
            array($this, 'loadPluginApi'),
204
            9
205
        );
206
        // allow addons to load first so that they can register autoloaders, set hooks for running DMS's, etc
207
        add_action(
208
            'AHEE__EE_Bootstrap__load_espresso_addons',
209
            array($this, 'load_espresso_addons')
210
        );
211
        // when an ee addon is activated, we want to call the core hook(s) again
212
        // because the newly-activated addon didn't get a chance to run at all
213
        add_action('activate_plugin', array($this, 'load_espresso_addons'), 1);
214
        // detect whether install or upgrade
215
        add_action(
216
            'AHEE__EE_Bootstrap__detect_activations_or_upgrades',
217
            array($this, 'detect_activations_or_upgrades'),
218
            3
219
        );
220
        // load EE_Config, EE_Textdomain, etc
221
        add_action(
222
            'AHEE__EE_Bootstrap__load_core_configuration',
223
            array($this, 'load_core_configuration'),
224
            5
225
        );
226
        // load EE_Config, EE_Textdomain, etc
227
        add_action(
228
            'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets',
229
            array($this, 'register_shortcodes_modules_and_widgets'),
230
            7
231
        );
232
        // you wanna get going? I wanna get going... let's get going!
233
        add_action(
234
            'AHEE__EE_Bootstrap__brew_espresso',
235
            array($this, 'brew_espresso'),
236
            9
237
        );
238
        //other housekeeping
239
        //exclude EE critical pages from wp_list_pages
240
        add_filter(
241
            'wp_list_pages_excludes',
242
            array($this, 'remove_pages_from_wp_list_pages'),
243
            10
244
        );
245
        // ALL EE Addons should use the following hook point to attach their initial setup too
246
        // it's extremely important for EE Addons to register any class autoloaders so that they can be available when the EE_Config loads
247
        do_action('AHEE__EE_System__construct__complete', $this);
248
    }
249
250
251
    /**
252
     * load and setup EE_Capabilities
253
     *
254
     * @return void
255
     * @throws EE_Error
256
     */
257
    public function loadCapabilities()
258
    {
259
        $this->capabilities = $this->loader->getShared('EE_Capabilities');
260
        add_action(
261
            'AHEE__EE_Capabilities__init_caps__before_initialization',
262
            function ()
263
            {
264
                LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
265
            }
266
        );
267
    }
268
269
270
271
    /**
272
     * create and cache the CommandBus, and also add middleware
273
     * The CapChecker middleware requires the use of EE_Capabilities
274
     * which is why we need to load the CommandBus after Caps are set up
275
     *
276
     * @return void
277
     * @throws EE_Error
278
     */
279
    public function loadCommandBus()
280
    {
281
        $this->loader->getShared(
282
            'CommandBusInterface',
283
            array(
284
                null,
285
                apply_filters(
286
                    'FHEE__EE_Load_Espresso_Core__handle_request__CommandBus_middleware',
287
                    array(
288
                        $this->loader->getShared('EventEspresso\core\services\commands\middleware\CapChecker'),
289
                        $this->loader->getShared('EventEspresso\core\services\commands\middleware\AddActionHook'),
290
                    )
291
                ),
292
            )
293
        );
294
    }
295
296
297
298
    /**
299
     * @return void
300
     * @throws EE_Error
301
     */
302
    public function loadPluginApi()
303
    {
304
        // set autoloaders for all of the classes implementing EEI_Plugin_API
305
        // which provide helpers for EE plugin authors to more easily register certain components with EE.
306
        EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'plugin_api');
307
        $this->loader->getShared('EE_Request_Handler');
308
    }
309
310
311
    /**
312
     * @param string $addon_name
313
     * @param string $version_constant
314
     * @param string $min_version_required
315
     * @param string $load_callback
316
     * @param string $plugin_file_constant
317
     * @return void
318
     */
319
    private function deactivateIncompatibleAddon(
320
        $addon_name,
321
        $version_constant,
322
        $min_version_required,
323
        $load_callback,
324
        $plugin_file_constant
325
    ) {
326
        if (! defined($version_constant)) {
327
            return;
328
        }
329
        $addon_version = constant($version_constant);
330
        if ($addon_version && version_compare($addon_version, $min_version_required, '<')) {
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';
334
            }
335
            deactivate_plugins(plugin_basename(constant($plugin_file_constant)));
336
            unset($_GET['activate'], $_REQUEST['activate'], $_GET['activate-multi'], $_REQUEST['activate-multi']);
337
            EE_Error::add_error(
338
                sprintf(
339
                    esc_html__(
340
                        '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.',
341
                        'event_espresso'
342
                    ),
343
                    $addon_name,
344
                    $min_version_required
345
                ),
346
                __FILE__, __FUNCTION__ . "({$addon_name})", __LINE__
347
            );
348
            EE_Error::get_notices(false, true);
349
        }
350
    }
351
352
353
    /**
354
     * load_espresso_addons
355
     * allow addons to load first so that they can set hooks for running DMS's, etc
356
     * this is hooked into both:
357
     *    'AHEE__EE_Bootstrap__load_core_configuration'
358
     *        which runs during the WP 'plugins_loaded' action at priority 5
359
     *    and the WP 'activate_plugin' hook point
360
     *
361
     * @access public
362
     * @return void
363
     */
364
    public function load_espresso_addons()
365
    {
366
        $this->deactivateIncompatibleAddon(
367
            'Wait Lists',
368
            'EE_WAIT_LISTS_VERSION',
369
            '1.0.0.beta.074',
370
            'load_espresso_wait_lists',
371
            'EE_WAIT_LISTS_PLUGIN_FILE'
372
        );
373
        $this->deactivateIncompatibleAddon(
374
            'Automated Upcoming Event Notifications',
375
            'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_VERSION',
376
            '1.0.0.beta.091',
377
            'load_espresso_automated_upcoming_event_notification',
378
            'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_PLUGIN_FILE'
379
        );
380
        do_action('AHEE__EE_System__load_espresso_addons');
381
        //if the WP API basic auth plugin isn't already loaded, load it now.
382
        //We want it for mobile apps. Just include the entire plugin
383
        //also, don't load the basic auth when a plugin is getting activated, because
384
        //it could be the basic auth plugin, and it doesn't check if its methods are already defined
385
        //and causes a fatal error
386
        if (
387
            $this->request->getRequestParam('activate') !== 'true'
388
            && ! function_exists('json_basic_auth_handler')
389
            && ! function_exists('json_basic_auth_error')
390
            && ! in_array(
391
                $this->request->getRequestParam('action'),
392
                array('activate', 'activate-selected'),
393
                true
394
            )
395
        ) {
396
            include_once EE_THIRD_PARTY . 'wp-api-basic-auth' . DS . 'basic-auth.php';
397
        }
398
        do_action('AHEE__EE_System__load_espresso_addons__complete');
399
    }
400
401
402
403
    /**
404
     * detect_activations_or_upgrades
405
     * Checks for activation or upgrade of core first;
406
     * then also checks if any registered addons have been activated or upgraded
407
     * This is hooked into 'AHEE__EE_Bootstrap__detect_activations_or_upgrades'
408
     * which runs during the WP 'plugins_loaded' action at priority 3
409
     *
410
     * @access public
411
     * @return void
412
     */
413
    public function detect_activations_or_upgrades()
414
    {
415
        //first off: let's make sure to handle core
416
        $this->detect_if_activation_or_upgrade();
417
        foreach ($this->registry->addons as $addon) {
418
            if ($addon instanceof EE_Addon) {
419
                //detect teh request type for that addon
420
                $addon->detect_activation_or_upgrade();
421
            }
422
        }
423
    }
424
425
426
427
    /**
428
     * detect_if_activation_or_upgrade
429
     * Takes care of detecting whether this is a brand new install or code upgrade,
430
     * and either setting up the DB or setting up maintenance mode etc.
431
     *
432
     * @access public
433
     * @return void
434
     */
435
    public function detect_if_activation_or_upgrade()
436
    {
437
        do_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin');
438
        // check if db has been updated, or if its a brand-new installation
439
        $espresso_db_update = $this->fix_espresso_db_upgrade_option();
440
        $request_type       = $this->detect_req_type($espresso_db_update);
441
        //EEH_Debug_Tools::printr( $request_type, '$request_type', __FILE__, __LINE__ );
442
        switch ($request_type) {
443
            case EE_System::req_type_new_activation:
444
                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__new_activation');
445
                $this->_handle_core_version_change($espresso_db_update);
446
                break;
447
            case EE_System::req_type_reactivation:
448
                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__reactivation');
449
                $this->_handle_core_version_change($espresso_db_update);
450
                break;
451
            case EE_System::req_type_upgrade:
452
                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__upgrade');
453
                //migrations may be required now that we've upgraded
454
                $this->maintenance_mode->set_maintenance_mode_if_db_old();
455
                $this->_handle_core_version_change($espresso_db_update);
456
                //				echo "done upgrade";die;
457
                break;
458
            case EE_System::req_type_downgrade:
459
                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__downgrade');
460
                //its possible migrations are no longer required
461
                $this->maintenance_mode->set_maintenance_mode_if_db_old();
462
                $this->_handle_core_version_change($espresso_db_update);
463
                break;
464
            case EE_System::req_type_normal:
465
            default:
466
                break;
467
        }
468
        do_action('AHEE__EE_System__detect_if_activation_or_upgrade__complete');
469
    }
470
471
472
473
    /**
474
     * Updates the list of installed versions and sets hooks for
475
     * initializing the database later during the request
476
     *
477
     * @param array $espresso_db_update
478
     */
479
    private function _handle_core_version_change($espresso_db_update)
480
    {
481
        $this->update_list_of_installed_versions($espresso_db_update);
482
        //get ready to verify the DB is ok (provided we aren't in maintenance mode, of course)
483
        add_action(
484
            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
485
            array($this, 'initialize_db_if_no_migrations_required')
486
        );
487
    }
488
489
490
491
    /**
492
     * standardizes the wp option 'espresso_db_upgrade' which actually stores
493
     * information about what versions of EE have been installed and activated,
494
     * NOT necessarily the state of the database
495
     *
496
     * @param mixed $espresso_db_update           the value of the WordPress option.
497
     *                                            If not supplied, fetches it from the options table
498
     * @return array the correct value of 'espresso_db_upgrade', after saving it, if it needed correction
499
     */
500
    private function fix_espresso_db_upgrade_option($espresso_db_update = null)
501
    {
502
        do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
503
        if (! $espresso_db_update) {
504
            $espresso_db_update = get_option('espresso_db_update');
505
        }
506
        // check that option is an array
507
        if (! is_array($espresso_db_update)) {
508
            // if option is FALSE, then it never existed
509
            if ($espresso_db_update === false) {
510
                // make $espresso_db_update an array and save option with autoload OFF
511
                $espresso_db_update = array();
512
                add_option('espresso_db_update', $espresso_db_update, '', 'no');
513
            } else {
514
                // option is NOT FALSE but also is NOT an array, so make it an array and save it
515
                $espresso_db_update = array($espresso_db_update => array());
516
                update_option('espresso_db_update', $espresso_db_update);
517
            }
518
        } else {
519
            $corrected_db_update = array();
520
            //if IS an array, but is it an array where KEYS are version numbers, and values are arrays?
521
            foreach ($espresso_db_update as $should_be_version_string => $should_be_array) {
522
                if (is_int($should_be_version_string) && ! is_array($should_be_array)) {
523
                    //the key is an int, and the value IS NOT an array
524
                    //so it must be numerically-indexed, where values are versions installed...
525
                    //fix it!
526
                    $version_string                         = $should_be_array;
527
                    $corrected_db_update[ $version_string ] = array('unknown-date');
528
                } else {
529
                    //ok it checks out
530
                    $corrected_db_update[ $should_be_version_string ] = $should_be_array;
531
                }
532
            }
533
            $espresso_db_update = $corrected_db_update;
534
            update_option('espresso_db_update', $espresso_db_update);
535
        }
536
        do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__complete', $espresso_db_update);
537
        return $espresso_db_update;
538
    }
539
540
541
542
    /**
543
     * Does the traditional work of setting up the plugin's database and adding default data.
544
     * If migration script/process did not exist, this is what would happen on every activation/reactivation/upgrade.
545
     * NOTE: if we're in maintenance mode (which would be the case if we detect there are data
546
     * migration scripts that need to be run and a version change happens), enqueues core for database initialization,
547
     * so that it will be done when migrations are finished
548
     *
549
     * @param boolean $initialize_addons_too if true, we double-check addons' database tables etc too;
550
     * @param boolean $verify_schema         if true will re-check the database tables have the correct schema.
551
     *                                       This is a resource-intensive job
552
     *                                       so we prefer to only do it when necessary
553
     * @return void
554
     * @throws EE_Error
555
     */
556
    public function initialize_db_if_no_migrations_required($initialize_addons_too = false, $verify_schema = true)
557
    {
558
        $request_type = $this->detect_req_type();
559
        //only initialize system if we're not in maintenance mode.
560
        if ($this->maintenance_mode->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
561
            update_option('ee_flush_rewrite_rules', true);
562
            if ($verify_schema) {
563
                EEH_Activation::initialize_db_and_folders();
564
            }
565
            EEH_Activation::initialize_db_content();
566
            EEH_Activation::system_initialization();
567
            if ($initialize_addons_too) {
568
                $this->initialize_addons();
569
            }
570
        } else {
571
            EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for('Core');
572
        }
573
        if ($request_type === EE_System::req_type_new_activation
574
            || $request_type === EE_System::req_type_reactivation
575
            || (
576
                $request_type === EE_System::req_type_upgrade
577
                && $this->is_major_version_change()
578
            )
579
        ) {
580
            add_action('AHEE__EE_System__initialize_last', array($this, 'redirect_to_about_ee'), 9);
581
        }
582
    }
583
584
585
586
    /**
587
     * Initializes the db for all registered addons
588
     *
589
     * @throws EE_Error
590
     */
591
    public function initialize_addons()
592
    {
593
        //foreach registered addon, make sure its db is up-to-date too
594
        foreach ($this->registry->addons as $addon) {
595
            if ($addon instanceof EE_Addon) {
596
                $addon->initialize_db_if_no_migrations_required();
597
            }
598
        }
599
    }
600
601
602
603
    /**
604
     * Adds the current code version to the saved wp option which stores a list of all ee versions ever installed.
605
     *
606
     * @param    array  $version_history
607
     * @param    string $current_version_to_add version to be added to the version history
608
     * @return    boolean success as to whether or not this option was changed
609
     */
610
    public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
611
    {
612
        if (! $version_history) {
613
            $version_history = $this->fix_espresso_db_upgrade_option($version_history);
614
        }
615
        if ($current_version_to_add === null) {
616
            $current_version_to_add = espresso_version();
617
        }
618
        $version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
619
        // re-save
620
        return update_option('espresso_db_update', $version_history);
621
    }
622
623
624
625
    /**
626
     * Detects if the current version indicated in the has existed in the list of
627
     * previously-installed versions of EE (espresso_db_update). Does NOT modify it (ie, no side-effect)
628
     *
629
     * @param array $espresso_db_update array from the wp option stored under the name 'espresso_db_update'.
630
     *                                  If not supplied, fetches it from the options table.
631
     *                                  Also, caches its result so later parts of the code can also know whether
632
     *                                  there's been an update or not. This way we can add the current version to
633
     *                                  espresso_db_update, but still know if this is a new install or not
634
     * @return int one of the constants on EE_System::req_type_
635
     */
636
    public function detect_req_type($espresso_db_update = null)
637
    {
638
        if ($this->_req_type === null) {
639
            $espresso_db_update          = ! empty($espresso_db_update)
640
                ? $espresso_db_update
641
                : $this->fix_espresso_db_upgrade_option();
642
            $this->_req_type             = EE_System::detect_req_type_given_activation_history(
643
                $espresso_db_update,
644
                'ee_espresso_activation', espresso_version()
645
            );
646
            $this->_major_version_change = $this->_detect_major_version_change($espresso_db_update);
647
            $this->request->setIsActivation($this->_req_type !== EE_System::req_type_normal);
648
        }
649
        return $this->_req_type;
650
    }
651
652
653
654
    /**
655
     * Returns whether or not there was a non-micro version change (ie, change in either
656
     * the first or second number in the version. Eg 4.9.0.rc.001 to 4.10.0.rc.000,
657
     * but not 4.9.0.rc.0001 to 4.9.1.rc.0001
658
     *
659
     * @param $activation_history
660
     * @return bool
661
     */
662
    private function _detect_major_version_change($activation_history)
663
    {
664
        $previous_version       = EE_System::_get_most_recently_active_version_from_activation_history($activation_history);
665
        $previous_version_parts = explode('.', $previous_version);
666
        $current_version_parts  = explode('.', espresso_version());
667
        return isset($previous_version_parts[0], $previous_version_parts[1], $current_version_parts[0], $current_version_parts[1])
668
               && ($previous_version_parts[0] !== $current_version_parts[0]
669
                   || $previous_version_parts[1] !== $current_version_parts[1]
670
               );
671
    }
672
673
674
675
    /**
676
     * Returns true if either the major or minor version of EE changed during this request.
677
     * 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
678
     *
679
     * @return bool
680
     */
681
    public function is_major_version_change()
682
    {
683
        return $this->_major_version_change;
684
    }
685
686
687
688
    /**
689
     * Determines the request type for any ee addon, given three piece of info: the current array of activation
690
     * histories (for core that' 'espresso_db_update' wp option); the name of the WordPress option which is temporarily
691
     * set upon activation of the plugin (for core it's 'ee_espresso_activation'); and the version that this plugin was
692
     * just activated to (for core that will always be espresso_version())
693
     *
694
     * @param array  $activation_history_for_addon     the option's value which stores the activation history for this
695
     *                                                 ee plugin. for core that's 'espresso_db_update'
696
     * @param string $activation_indicator_option_name the name of the WordPress option that is temporarily set to
697
     *                                                 indicate that this plugin was just activated
698
     * @param string $version_to_upgrade_to            the version that was just upgraded to (for core that will be
699
     *                                                 espresso_version())
700
     * @return int one of the constants on EE_System::req_type_*
701
     */
702
    public static function detect_req_type_given_activation_history(
703
        $activation_history_for_addon,
704
        $activation_indicator_option_name,
705
        $version_to_upgrade_to
706
    ) {
707
        $version_is_higher = self::_new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to);
708
        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...
709
            //it exists, so this isn't a completely new install
710
            //check if this version already in that list of previously installed versions
711
            if (! isset($activation_history_for_addon[ $version_to_upgrade_to ])) {
712
                //it a version we haven't seen before
713
                if ($version_is_higher === 1) {
714
                    $req_type = EE_System::req_type_upgrade;
715
                } else {
716
                    $req_type = EE_System::req_type_downgrade;
717
                }
718
                delete_option($activation_indicator_option_name);
719
            } else {
720
                // its not an update. maybe a reactivation?
721
                if (get_option($activation_indicator_option_name, false)) {
722 View Code Duplication
                    if ($version_is_higher === -1) {
723
                        $req_type = EE_System::req_type_downgrade;
724
                    } elseif ($version_is_higher === 0) {
725
                        //we've seen this version before, but it's an activation. must be a reactivation
726
                        $req_type = EE_System::req_type_reactivation;
727
                    } else {//$version_is_higher === 1
728
                        $req_type = EE_System::req_type_upgrade;
729
                    }
730
                    delete_option($activation_indicator_option_name);
731 View Code Duplication
                } else {
732
                    //we've seen this version before and the activation indicate doesn't show it was just activated
733
                    if ($version_is_higher === -1) {
734
                        $req_type = EE_System::req_type_downgrade;
735
                    } elseif ($version_is_higher === 0) {
736
                        //we've seen this version before and it's not an activation. its normal request
737
                        $req_type = EE_System::req_type_normal;
738
                    } else {//$version_is_higher === 1
739
                        $req_type = EE_System::req_type_upgrade;
740
                    }
741
                }
742
            }
743
        } else {
744
            //brand new install
745
            $req_type = EE_System::req_type_new_activation;
746
            delete_option($activation_indicator_option_name);
747
        }
748
        return $req_type;
749
    }
750
751
752
753
    /**
754
     * Detects if the $version_to_upgrade_to is higher than the most recent version in
755
     * the $activation_history_for_addon
756
     *
757
     * @param array  $activation_history_for_addon (keys are versions, values are arrays of times activated,
758
     *                                             sometimes containing 'unknown-date'
759
     * @param string $version_to_upgrade_to        (current version)
760
     * @return int results of version_compare( $version_to_upgrade_to, $most_recently_active_version ).
761
     *                                             ie, -1 if $version_to_upgrade_to is LOWER (downgrade);
762
     *                                             0 if $version_to_upgrade_to MATCHES (reactivation or normal request);
763
     *                                             1 if $version_to_upgrade_to is HIGHER (upgrade) ;
764
     */
765
    private static function _new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to)
766
    {
767
        //find the most recently-activated version
768
        $most_recently_active_version =
769
            EE_System::_get_most_recently_active_version_from_activation_history($activation_history_for_addon);
770
        return version_compare($version_to_upgrade_to, $most_recently_active_version);
771
    }
772
773
774
775
    /**
776
     * Gets the most recently active version listed in the activation history,
777
     * and if none are found (ie, it's a brand new install) returns '0.0.0.dev.000'.
778
     *
779
     * @param array $activation_history  (keys are versions, values are arrays of times activated,
780
     *                                   sometimes containing 'unknown-date'
781
     * @return string
782
     */
783
    private static function _get_most_recently_active_version_from_activation_history($activation_history)
784
    {
785
        $most_recently_active_version_activation = '1970-01-01 00:00:00';
786
        $most_recently_active_version            = '0.0.0.dev.000';
787
        if (is_array($activation_history)) {
788
            foreach ($activation_history as $version => $times_activated) {
789
                //check there is a record of when this version was activated. Otherwise,
790
                //mark it as unknown
791
                if (! $times_activated) {
792
                    $times_activated = array('unknown-date');
793
                }
794
                if (is_string($times_activated)) {
795
                    $times_activated = array($times_activated);
796
                }
797
                foreach ($times_activated as $an_activation) {
798
                    if ($an_activation !== 'unknown-date'
799
                        && $an_activation
800
                           > $most_recently_active_version_activation) {
801
                        $most_recently_active_version            = $version;
802
                        $most_recently_active_version_activation = $an_activation === 'unknown-date'
803
                            ? '1970-01-01 00:00:00'
804
                            : $an_activation;
805
                    }
806
                }
807
            }
808
        }
809
        return $most_recently_active_version;
810
    }
811
812
813
814
    /**
815
     * This redirects to the about EE page after activation
816
     *
817
     * @return void
818
     */
819
    public function redirect_to_about_ee()
820
    {
821
        $notices = EE_Error::get_notices(false);
822
        //if current user is an admin and it's not an ajax or rest request
823
        if (
824
            ! isset($notices['errors'])
825
            && $this->request->isAdmin()
826
            && apply_filters(
827
                'FHEE__EE_System__redirect_to_about_ee__do_redirect',
828
                $this->capabilities->current_user_can('manage_options', 'espresso_about_default')
829
            )
830
        ) {
831
            $query_params = array('page' => 'espresso_about');
832
            if (EE_System::instance()->detect_req_type() === EE_System::req_type_new_activation) {
833
                $query_params['new_activation'] = true;
834
            }
835
            if (EE_System::instance()->detect_req_type() === EE_System::req_type_reactivation) {
836
                $query_params['reactivation'] = true;
837
            }
838
            $url = add_query_arg($query_params, admin_url('admin.php'));
839
            wp_safe_redirect($url);
840
            exit();
841
        }
842
    }
843
844
845
846
    /**
847
     * load_core_configuration
848
     * this is hooked into 'AHEE__EE_Bootstrap__load_core_configuration'
849
     * which runs during the WP 'plugins_loaded' action at priority 5
850
     *
851
     * @return void
852
     * @throws ReflectionException
853
     */
854
    public function load_core_configuration()
855
    {
856
        do_action('AHEE__EE_System__load_core_configuration__begin', $this);
857
        $this->loader->getShared('EE_Load_Textdomain');
858
        //load textdomain
859
        EE_Load_Textdomain::load_textdomain();
860
        // load and setup EE_Config and EE_Network_Config
861
        $config = $this->loader->getShared('EE_Config');
862
        $this->loader->getShared('EE_Network_Config');
863
        // setup autoloaders
864
        // enable logging?
865
        if ($config->admin->use_full_logging) {
866
            $this->loader->getShared('EE_Log');
867
        }
868
        // check for activation errors
869
        $activation_errors = get_option('ee_plugin_activation_errors', false);
870
        if ($activation_errors) {
871
            EE_Error::add_error($activation_errors, __FILE__, __FUNCTION__, __LINE__);
872
            update_option('ee_plugin_activation_errors', false);
873
        }
874
        // get model names
875
        $this->_parse_model_names();
876
        //load caf stuff a chance to play during the activation process too.
877
        $this->_maybe_brew_regular();
878
        do_action('AHEE__EE_System__load_core_configuration__complete', $this);
879
    }
880
881
882
883
    /**
884
     * cycles through all of the models/*.model.php files, and assembles an array of model names
885
     *
886
     * @return void
887
     * @throws ReflectionException
888
     */
889
    private function _parse_model_names()
890
    {
891
        //get all the files in the EE_MODELS folder that end in .model.php
892
        $models                 = glob(EE_MODELS . '*.model.php');
893
        $model_names            = array();
894
        $non_abstract_db_models = array();
895
        foreach ($models as $model) {
896
            // get model classname
897
            $classname       = EEH_File::get_classname_from_filepath_with_standard_filename($model);
898
            $short_name      = str_replace('EEM_', '', $classname);
899
            $reflectionClass = new ReflectionClass($classname);
900
            if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
901
                $non_abstract_db_models[ $short_name ] = $classname;
902
            }
903
            $model_names[ $short_name ] = $classname;
904
        }
905
        $this->registry->models                 = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
906
        $this->registry->non_abstract_db_models = apply_filters(
907
            'FHEE__EE_System__parse_implemented_model_names',
908
            $non_abstract_db_models
909
        );
910
    }
911
912
913
914
    /**
915
     * The purpose of this method is to simply check for a file named "caffeinated/brewing_regular.php" for any hooks
916
     * that need to be setup before our EE_System launches.
917
     *
918
     * @return void
919
     */
920
    private function _maybe_brew_regular()
921
    {
922
        if ((! defined('EE_DECAF') || EE_DECAF !== true) && is_readable(EE_CAFF_PATH . 'brewing_regular.php')) {
923
            require_once EE_CAFF_PATH . 'brewing_regular.php';
924
        }
925
    }
926
927
928
929
    /**
930
     * register_shortcodes_modules_and_widgets
931
     * generate lists of shortcodes and modules, then verify paths and classes
932
     * This is hooked into 'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets'
933
     * which runs during the WP 'plugins_loaded' action at priority 7
934
     *
935
     * @access public
936
     * @return void
937
     * @throws Exception
938
     */
939
    public function register_shortcodes_modules_and_widgets()
940
    {
941
        if ($this->request->isFrontend() || $this->request->isIframe()) {
942
            try {
943
                // load, register, and add shortcodes the new way
944
                $this->loader->getShared(
945
                    'EventEspresso\core\services\shortcodes\ShortcodesManager',
946
                    array(
947
                        // and the old way, but we'll put it under control of the new system
948
                        EE_Config::getLegacyShortcodesManager(),
949
                    )
950
                );
951
            } catch (Exception $exception) {
952
                new ExceptionStackTraceDisplay($exception);
953
            }
954
        }
955
        do_action('AHEE__EE_System__register_shortcodes_modules_and_widgets');
956
        // check for addons using old hook point
957
        if (has_action('AHEE__EE_System__register_shortcodes_modules_and_addons')) {
958
            $this->_incompatible_addon_error();
959
        }
960
    }
961
962
963
964
    /**
965
     * _incompatible_addon_error
966
     *
967
     * @access public
968
     * @return void
969
     */
970
    private function _incompatible_addon_error()
971
    {
972
        // get array of classes hooking into here
973
        $class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook(
974
            'AHEE__EE_System__register_shortcodes_modules_and_addons'
975
        );
976
        if (! empty($class_names)) {
977
            $msg = __(
978
                'The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
979
                'event_espresso'
980
            );
981
            $msg .= '<ul>';
982
            foreach ($class_names as $class_name) {
983
                $msg .= '<li><b>Event Espresso - ' . str_replace(
984
                        array('EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'), '',
985
                        $class_name
986
                    ) . '</b></li>';
987
            }
988
            $msg .= '</ul>';
989
            $msg .= __(
990
                'Compatibility issues can be avoided and/or resolved by keeping addons and plugins updated to the latest version.',
991
                'event_espresso'
992
            );
993
            // save list of incompatible addons to wp-options for later use
994
            add_option('ee_incompatible_addons', $class_names, '', 'no');
995
            if (is_admin()) {
996
                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
997
            }
998
        }
999
    }
1000
1001
1002
1003
    /**
1004
     * brew_espresso
1005
     * begins the process of setting hooks for initializing EE in the correct order
1006
     * This is happening on the 'AHEE__EE_Bootstrap__brew_espresso' hook point
1007
     * which runs during the WP 'plugins_loaded' action at priority 9
1008
     *
1009
     * @return void
1010
     */
1011
    public function brew_espresso()
1012
    {
1013
        do_action('AHEE__EE_System__brew_espresso__begin', $this);
1014
        // load some final core systems
1015
        add_action('init', array($this, 'set_hooks_for_core'), 1);
1016
        add_action('init', array($this, 'perform_activations_upgrades_and_migrations'), 3);
1017
        add_action('init', array($this, 'load_CPTs_and_session'), 5);
1018
        add_action('init', array($this, 'load_controllers'), 7);
1019
        add_action('init', array($this, 'core_loaded_and_ready'), 9);
1020
        add_action('init', array($this, 'initialize'), 10);
1021
        add_action('init', array($this, 'initialize_last'), 100);
1022
        if (is_admin() && apply_filters('FHEE__EE_System__brew_espresso__load_pue', true)) {
1023
            // pew pew pew
1024
            $this->loader->getShared('EE_PUE');
1025
            do_action('AHEE__EE_System__brew_espresso__after_pue_init');
1026
        }
1027
        do_action('AHEE__EE_System__brew_espresso__complete', $this);
1028
    }
1029
1030
1031
1032
    /**
1033
     *    set_hooks_for_core
1034
     *
1035
     * @access public
1036
     * @return    void
1037
     * @throws EE_Error
1038
     */
1039
    public function set_hooks_for_core()
1040
    {
1041
        $this->_deactivate_incompatible_addons();
1042
        do_action('AHEE__EE_System__set_hooks_for_core');
1043
        //caps need to be initialized on every request so that capability maps are set.
1044
        //@see https://events.codebasehq.com/projects/event-espresso/tickets/8674
1045
        $this->registry->CAP->init_caps();
1046
    }
1047
1048
1049
1050
    /**
1051
     * Using the information gathered in EE_System::_incompatible_addon_error,
1052
     * deactivates any addons considered incompatible with the current version of EE
1053
     */
1054
    private function _deactivate_incompatible_addons()
1055
    {
1056
        $incompatible_addons = get_option('ee_incompatible_addons', array());
1057
        if (! empty($incompatible_addons)) {
1058
            $active_plugins = get_option('active_plugins', array());
1059
            foreach ($active_plugins as $active_plugin) {
1060
                foreach ($incompatible_addons as $incompatible_addon) {
1061
                    if (strpos($active_plugin, $incompatible_addon) !== false) {
1062
                        unset($_GET['activate']);
1063
                        espresso_deactivate_plugin($active_plugin);
1064
                    }
1065
                }
1066
            }
1067
        }
1068
    }
1069
1070
1071
1072
    /**
1073
     *    perform_activations_upgrades_and_migrations
1074
     *
1075
     * @access public
1076
     * @return    void
1077
     */
1078
    public function perform_activations_upgrades_and_migrations()
1079
    {
1080
        //first check if we had previously attempted to setup EE's directories but failed
1081
        if ($this->request->isActivation() && EEH_Activation::upload_directories_incomplete()) {
1082
            EEH_Activation::create_upload_directories();
1083
        }
1084
        do_action('AHEE__EE_System__perform_activations_upgrades_and_migrations');
1085
    }
1086
1087
1088
1089
    /**
1090
     *    load_CPTs_and_session
1091
     *
1092
     * @access public
1093
     * @return    void
1094
     */
1095
    public function load_CPTs_and_session()
1096
    {
1097
        do_action('AHEE__EE_System__load_CPTs_and_session__start');
1098
        // register Custom Post Types
1099
        $this->loader->getShared('EE_Register_CPTs');
1100
        do_action('AHEE__EE_System__load_CPTs_and_session__complete');
1101
    }
1102
1103
1104
1105
    /**
1106
     * load_controllers
1107
     * this is the best place to load any additional controllers that needs access to EE core.
1108
     * it is expected that all basic core EE systems, that are not dependant on the current request are loaded at this
1109
     * time
1110
     *
1111
     * @access public
1112
     * @return void
1113
     */
1114
    public function load_controllers()
1115
    {
1116
        do_action('AHEE__EE_System__load_controllers__start');
1117
        // let's get it started
1118
        if (
1119
            ! $this->maintenance_mode->level()
1120
            && ($this->request->isFrontend() || $this->request->isFrontAjax())
1121
        ) {
1122
            do_action('AHEE__EE_System__load_controllers__load_front_controllers');
1123
            $this->loader->getShared('EE_Front_Controller');
1124
        } elseif ($this->request->isAdmin() || $this->request->isAdminAjax()) {
1125
            do_action('AHEE__EE_System__load_controllers__load_admin_controllers');
1126
            $this->loader->getShared('EE_Admin');
1127
        }
1128
        do_action('AHEE__EE_System__load_controllers__complete');
1129
    }
1130
1131
1132
1133
    /**
1134
     * core_loaded_and_ready
1135
     * all of the basic EE core should be loaded at this point and available regardless of M-Mode
1136
     *
1137
     * @access public
1138
     * @return void
1139
     */
1140
    public function core_loaded_and_ready()
1141
    {
1142 View Code Duplication
        if (
1143
            $this->request->isAdmin()
1144
            || $this->request->isEeAjax()
1145
            || $this->request->isFrontend()
1146
        ) {
1147
            $this->loader->getShared('EE_Session');
1148
        }
1149
        do_action('AHEE__EE_System__core_loaded_and_ready');
1150
        // load_espresso_template_tags
1151
        if (
1152
            is_readable(EE_PUBLIC . 'template_tags.php')
1153
            && ($this->request->isFrontend() || $this->request->isIframe() || $this->request->isFeed())
1154
        ) {
1155
            require_once EE_PUBLIC . 'template_tags.php';
1156
        }
1157
        do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1158 View Code Duplication
        if ($this->request->isAdmin() || $this->request->isFrontend() || $this->request->isIframe()) {
1159
            $this->loader->getShared('EventEspresso\core\services\assets\Registry');
1160
        }
1161
    }
1162
1163
1164
1165
    /**
1166
     * initialize
1167
     * this is the best place to begin initializing client code
1168
     *
1169
     * @access public
1170
     * @return void
1171
     */
1172
    public function initialize()
1173
    {
1174
        do_action('AHEE__EE_System__initialize');
1175
    }
1176
1177
1178
1179
    /**
1180
     * initialize_last
1181
     * this is run really late during the WP init hook point, and ensures that mostly everything else that needs to
1182
     * initialize has done so
1183
     *
1184
     * @access public
1185
     * @return void
1186
     */
1187
    public function initialize_last()
1188
    {
1189
        do_action('AHEE__EE_System__initialize_last');
1190
        add_action('admin_bar_init', array($this, 'addEspressoToolbar'));
1191
    }
1192
1193
1194
1195
    /**
1196
     * @return void
1197
     * @throws EE_Error
1198
     */
1199
    public function addEspressoToolbar()
1200
    {
1201
        $this->loader->getShared(
1202
            'EventEspresso\core\domain\services\admin\AdminToolBar',
1203
            array($this->registry->CAP)
1204
        );
1205
    }
1206
1207
1208
1209
    /**
1210
     * do_not_cache
1211
     * sets no cache headers and defines no cache constants for WP plugins
1212
     *
1213
     * @access public
1214
     * @return void
1215
     */
1216
    public static function do_not_cache()
1217
    {
1218
        // set no cache constants
1219
        if (! defined('DONOTCACHEPAGE')) {
1220
            define('DONOTCACHEPAGE', true);
1221
        }
1222
        if (! defined('DONOTCACHCEOBJECT')) {
1223
            define('DONOTCACHCEOBJECT', true);
1224
        }
1225
        if (! defined('DONOTCACHEDB')) {
1226
            define('DONOTCACHEDB', true);
1227
        }
1228
        // add no cache headers
1229
        add_action('send_headers', array('EE_System', 'nocache_headers'), 10);
1230
        // plus a little extra for nginx and Google Chrome
1231
        add_filter('nocache_headers', array('EE_System', 'extra_nocache_headers'), 10, 1);
1232
        // prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes with the registration process
1233
        remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
1234
    }
1235
1236
1237
1238
    /**
1239
     *    extra_nocache_headers
1240
     *
1241
     * @access    public
1242
     * @param $headers
1243
     * @return    array
1244
     */
1245
    public static function extra_nocache_headers($headers)
1246
    {
1247
        // for NGINX
1248
        $headers['X-Accel-Expires'] = 0;
1249
        // plus extra for Google Chrome since it doesn't seem to respect "no-cache", but WILL respect "no-store"
1250
        $headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0';
1251
        return $headers;
1252
    }
1253
1254
1255
1256
    /**
1257
     *    nocache_headers
1258
     *
1259
     * @access    public
1260
     * @return    void
1261
     */
1262
    public static function nocache_headers()
1263
    {
1264
        nocache_headers();
1265
    }
1266
1267
1268
1269
    /**
1270
     * simply hooks into "wp_list_pages_exclude" filter (for wp_list_pages method) and makes sure EE critical pages are
1271
     * never returned with the function.
1272
     *
1273
     * @param  array $exclude_array any existing pages being excluded are in this array.
1274
     * @return array
1275
     */
1276
    public function remove_pages_from_wp_list_pages($exclude_array)
1277
    {
1278
        return array_merge($exclude_array, $this->registry->CFG->core->get_critical_pages_array());
1279
    }
1280
1281
1282
1283
}
1284
// End of file EE_System.core.php
1285
// Location: /core/EE_System.core.php
1286