Completed
Branch BUG/invalid-field-count (a0252b)
by
unknown
14:53 queued 56s
created

EE_System::initialize_last()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

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