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