Completed
Branch FET/event-question-group-refac... (8c9768)
by
unknown
27:04 queued 17:53
created
core/EE_Data_Migration_Manager.core.php 2 patches
Indentation   +1234 added lines, -1234 removed lines patch added patch discarded remove patch
@@ -33,1238 +33,1238 @@
 block discarded – undo
33 33
 class EE_Data_Migration_Manager implements ResettableInterface
34 34
 {
35 35
 
36
-    /**
37
-     *
38
-     * @var EE_Registry
39
-     */
40
-    // protected $EE;
41
-    /**
42
-     * name of the wordpress option which stores an array of data about
43
-     */
44
-    const data_migrations_option_name = 'ee_data_migration';
45
-
46
-
47
-    const data_migration_script_option_prefix = 'ee_data_migration_script_';
48
-
49
-    const data_migration_script_mapping_option_prefix = 'ee_dms_map_';
50
-
51
-    /**
52
-     * name of the wordpress option which stores the database' current version. IE, the code may be at version 4.2.0,
53
-     * but as migrations are performed the database will progress from 3.1.35 to 4.1.0 etc.
54
-     */
55
-    const current_database_state = 'ee_data_migration_current_db_state';
56
-
57
-    /**
58
-     * Special status string returned when we're positive there are no more data migration
59
-     * scripts that can be run.
60
-     */
61
-    const status_no_more_migration_scripts = 'no_more_migration_scripts';
62
-    /**
63
-     * string indicating the migration should continue
64
-     */
65
-    const status_continue = 'status_continue';
66
-    /**
67
-     * string indicating the migration has completed and should be ended
68
-     */
69
-    const status_completed = 'status_completed';
70
-    /**
71
-     * string indicating a fatal error occurred and the data migration should be completely aborted
72
-     */
73
-    const status_fatal_error = 'status_fatal_error';
74
-
75
-    /**
76
-     * the number of 'items' (usually DB rows) to migrate on each 'step' (ajax request sent
77
-     * during migration)
78
-     */
79
-    const step_size = 50;
80
-
81
-    /**
82
-     * option name that stores the queue of ee plugins needing to have
83
-     * their data initialized (or re-initialized) once we are done migrations
84
-     */
85
-    const db_init_queue_option_name = 'ee_db_init_queue';
86
-    /**
87
-     * Array of information concerning data migrations that have ran in the history
88
-     * of this EE installation. Keys should be the name of the version the script upgraded to
89
-     *
90
-     * @var EE_Data_Migration_Script_Base[]
91
-     */
92
-    private $_data_migrations_ran = null;
93
-    /**
94
-     * The last ran script. It's nice to store this somewhere accessible, as its easiest
95
-     * to know which was the last run by which is the newest wp option; but in most of the code
96
-     * we just use the local $_data_migration_ran array, which organized the scripts differently
97
-     *
98
-     * @var EE_Data_Migration_Script_Base
99
-     */
100
-    private $_last_ran_script = null;
101
-
102
-    /**
103
-     * Similarly to _last_ran_script, but this is the last INCOMPLETE migration script.
104
-     *
105
-     * @var EE_Data_Migration_Script_Base
106
-     */
107
-    private $_last_ran_incomplete_script = null;
108
-    /**
109
-     * array where keys are classnames, and values are filepaths of all the known migration scripts
110
-     *
111
-     * @var array
112
-     */
113
-    private $_data_migration_class_to_filepath_map;
114
-
115
-    /**
116
-     * the following 4 properties are fully set on construction.
117
-     * Note: the first two apply to whether to continue running ALL migration scripts (ie, even though we're finished
118
-     * one, we may want to start the next one); whereas the last two indicate whether to continue running a single
119
-     * data migration script
120
-     *
121
-     * @var array
122
-     */
123
-    public $stati_that_indicate_to_continue_migrations = array();
124
-
125
-    public $stati_that_indicate_to_stop_migrations = array();
126
-
127
-    public $stati_that_indicate_to_continue_single_migration_script = array();
128
-
129
-    public $stati_that_indicate_to_stop_single_migration_script = array();
130
-
131
-    /**
132
-     * @var \EventEspresso\core\services\database\TableManager $table_manager
133
-     */
134
-    protected $_table_manager;
135
-
136
-    /**
137
-     * @var \EventEspresso\core\services\database\TableAnalysis $table_analysis
138
-     */
139
-    protected $_table_analysis;
140
-
141
-    /**
142
-     * @var array $script_migration_versions
143
-     */
144
-    protected $script_migration_versions;
145
-
146
-    /**
147
-     * @var EE_Data_Migration_Manager $_instance
148
-     * @access    private
149
-     */
150
-    private static $_instance = null;
151
-
152
-
153
-    /**
154
-     * @singleton method used to instantiate class object
155
-     * @access    public
156
-     * @return EE_Data_Migration_Manager instance
157
-     */
158
-    public static function instance()
159
-    {
160
-        // check if class object is instantiated
161
-        if (! self::$_instance instanceof EE_Data_Migration_Manager) {
162
-            self::$_instance = new self();
163
-        }
164
-        return self::$_instance;
165
-    }
166
-
167
-    /**
168
-     * resets the singleton to its brand-new state (but does NOT delete old references to the old singleton. Meaning,
169
-     * all new usages of the singleton should be made with Classname::instance()) and returns it
170
-     *
171
-     * @return EE_Data_Migration_Manager
172
-     */
173
-    public static function reset()
174
-    {
175
-        self::$_instance = null;
176
-        return self::instance();
177
-    }
178
-
179
-
180
-    /**
181
-     * constructor
182
-     */
183
-    private function __construct()
184
-    {
185
-        $this->stati_that_indicate_to_continue_migrations = array(
186
-            self::status_continue,
187
-            self::status_completed,
188
-        );
189
-        $this->stati_that_indicate_to_stop_migrations = array(
190
-            self::status_fatal_error,
191
-            self::status_no_more_migration_scripts,
192
-        );
193
-        $this->stati_that_indicate_to_continue_single_migration_script = array(
194
-            self::status_continue,
195
-        );
196
-        $this->stati_that_indicate_to_stop_single_migration_script = array(
197
-            self::status_completed,
198
-            self::status_fatal_error
199
-            // note: status_no_more_migration_scripts doesn't apply
200
-        );
201
-        // make sure we've included the base migration script, because we may need the EE_DMS_Unknown_1_0_0 class
202
-        // to be defined, because right now it doesn't get autoloaded on its own
203
-        EE_Registry::instance()->load_core('Data_Migration_Class_Base', array(), true);
204
-        EE_Registry::instance()->load_core('Data_Migration_Script_Base', array(), true);
205
-        EE_Registry::instance()->load_core('DMS_Unknown_1_0_0', array(), true);
206
-        EE_Registry::instance()->load_core('Data_Migration_Script_Stage', array(), true);
207
-        EE_Registry::instance()->load_core('Data_Migration_Script_Stage_Table', array(), true);
208
-        $this->_table_manager = EE_Registry::instance()->create('TableManager', array(), true);
209
-        $this->_table_analysis = EE_Registry::instance()->create('TableAnalysis', array(), true);
210
-    }
211
-
212
-
213
-    /**
214
-     * Deciphers, from an option's name, what plugin and version it relates to (see _save_migrations_ran to see what
215
-     * the option names are like, but generally they're like
216
-     * 'ee_data_migration_script_Core.4.1.0' in 4.2 or 'ee_data_migration_script_4.1.0' before that).
217
-     * The option name shouldn't ever be like 'ee_data_migration_script_Core.4.1.0.reg' because it's derived,
218
-     * indirectly, from the data migration's classname, which should always be like EE_DMS_%s_%d_%d_%d.dms.php (eg
219
-     * EE_DMS_Core_4_1_0.dms.php)
220
-     *
221
-     * @param string $option_name (see EE_Data_Migration_Manage::_save_migrations_ran() where the option name is set)
222
-     * @return array where the first item is the plugin slug (eg 'Core','Calendar',etc) and the 2nd is the version of
223
-     *               that plugin (eg '4.1.0')
224
-     */
225
-    private function _get_plugin_slug_and_version_string_from_dms_option_name($option_name)
226
-    {
227
-        $plugin_slug_and_version_string = str_replace(
228
-            EE_Data_Migration_Manager::data_migration_script_option_prefix,
229
-            "",
230
-            $option_name
231
-        );
232
-        // check if $plugin_slug_and_version_string is like '4.1.0' (4.1-style) or 'Core.4.1.0' (4.2-style)
233
-        $parts = explode(".", $plugin_slug_and_version_string);
234
-
235
-        if (count($parts) == 4) {
236
-            // it's 4.2-style.eg Core.4.1.0
237
-            $plugin_slug = $parts[0];// eg Core
238
-            $version_string = $parts[1] . "." . $parts[2] . "." . $parts[3]; // eg 4.1.0
239
-        } else {
240
-            // it's 4.1-style: eg 4.1.0
241
-            $plugin_slug = 'Core';
242
-            $version_string = $plugin_slug_and_version_string;// eg 4.1.0
243
-        }
244
-        return array($plugin_slug, $version_string);
245
-    }
246
-
247
-    /**
248
-     * Gets the DMS class from the wordpress option, otherwise throws an EE_Error if it's not
249
-     * for a known DMS class.
250
-     *
251
-     * @param string $dms_option_name
252
-     * @param string $dms_option_value (serialized)
253
-     * @return EE_Data_Migration_Script_Base
254
-     * @throws EE_Error
255
-     */
256
-    private function _get_dms_class_from_wp_option($dms_option_name, $dms_option_value)
257
-    {
258
-        $data_migration_data = maybe_unserialize($dms_option_value);
259
-        if (isset($data_migration_data['class']) && class_exists($data_migration_data['class'])) {
260
-            $class = LoaderFactory::getLoader()->getShared($data_migration_data['class']);
261
-            if ($class instanceof EE_Data_Migration_Script_Base) {
262
-                $class->instantiate_from_array_of_properties($data_migration_data);
263
-                return $class;
264
-            } else {
265
-                // huh, so its an object but not a data migration script?? that shouldn't happen
266
-                // just leave it as an array (which will probably just get ignored)
267
-                throw new EE_Error(
268
-                    sprintf(
269
-                        __(
270
-                            "Trying to retrieve DMS class from wp option. No DMS by the name '%s' exists",
271
-                            'event_espresso'
272
-                        ),
273
-                        $data_migration_data['class']
274
-                    )
275
-                );
276
-            }
277
-        } else {
278
-            // so the data doesn't specify a class. So it must either be a legacy array of info or some array (which we'll probably just ignore), or a class that no longer exists
279
-            throw new EE_Error(
280
-                sprintf(__("The wp option  with key '%s' does not represent a DMS", 'event_espresso'), $dms_option_name)
281
-            );
282
-        }
283
-    }
284
-
285
-    /**
286
-     * Gets the array describing what data migrations have run. Also has a side-effect of recording which was the last
287
-     * ran, and which was the last ran which hasn't finished yet
288
-     *
289
-     * @return array where each element should be an array of EE_Data_Migration_Script_Base (but also has a few legacy
290
-     *               arrays in there - which should probably be ignored)
291
-     */
292
-    public function get_data_migrations_ran()
293
-    {
294
-        if (! $this->_data_migrations_ran) {
295
-            // setup autoloaders for each of the scripts in there
296
-            $this->get_all_data_migration_scripts_available();
297
-            $data_migrations_options = $this->get_all_migration_script_options(
298
-            );// get_option(EE_Data_Migration_Manager::data_migrations_option_name,get_option('espresso_data_migrations',array()));
299
-
300
-            $data_migrations_ran = array();
301
-            // convert into data migration script classes where possible
302
-            foreach ($data_migrations_options as $data_migration_option) {
303
-                list($plugin_slug, $version_string) = $this->_get_plugin_slug_and_version_string_from_dms_option_name(
304
-                    $data_migration_option['option_name']
305
-                );
306
-
307
-                try {
308
-                    $class = $this->_get_dms_class_from_wp_option(
309
-                        $data_migration_option['option_name'],
310
-                        $data_migration_option['option_value']
311
-                    );
312
-                    $data_migrations_ran[ $plugin_slug ][ $version_string ] = $class;
313
-                    // ok so far THIS is the 'last-ran-script'... unless we find another on next iteration
314
-                    $this->_last_ran_script = $class;
315
-                    if (! $class->is_completed()) {
316
-                        // sometimes we also like to know which was the last incomplete script (or if there are any at all)
317
-                        $this->_last_ran_incomplete_script = $class;
318
-                    }
319
-                } catch (EE_Error $e) {
320
-                    // ok so its not a DMS. We'll just keep it, although other code will need to expect non-DMSs
321
-                    $data_migrations_ran[ $plugin_slug ][ $version_string ] = maybe_unserialize(
322
-                        $data_migration_option['option_value']
323
-                    );
324
-                }
325
-            }
326
-            // so here the array of $data_migrations_ran is actually a mix of classes and a few legacy arrays
327
-            $this->_data_migrations_ran = $data_migrations_ran;
328
-            if (! $this->_data_migrations_ran || ! is_array($this->_data_migrations_ran)) {
329
-                $this->_data_migrations_ran = array();
330
-            }
331
-        }
332
-        return $this->_data_migrations_ran;
333
-    }
334
-
335
-
336
-    /**
337
-     *
338
-     * @param string $script_name eg 'DMS_Core_4_1_0'
339
-     * @param string $old_table   eg 'wp_events_detail'
340
-     * @param string $old_pk      eg 'wp_esp_posts'
341
-     * @param        $new_table
342
-     * @return mixed string or int
343
-     */
344
-    public function get_mapping_new_pk($script_name, $old_table, $old_pk, $new_table)
345
-    {
346
-        $script = EE_Registry::instance()->load_dms($script_name);
347
-        $mapping = $script->get_mapping_new_pk($old_table, $old_pk, $new_table);
348
-        return $mapping;
349
-    }
350
-
351
-    /**
352
-     * Gets all the options containing migration scripts that have been run. Ordering is important: it's assumed that
353
-     * the last option returned in this array is the most-recently ran DMS option
354
-     *
355
-     * @return array
356
-     */
357
-    public function get_all_migration_script_options()
358
-    {
359
-        global $wpdb;
360
-        return $wpdb->get_results(
361
-            "SELECT * FROM {$wpdb->options} WHERE option_name like '" . EE_Data_Migration_Manager::data_migration_script_option_prefix . "%' ORDER BY option_id ASC",
362
-            ARRAY_A
363
-        );
364
-    }
365
-
366
-    /**
367
-     * Gets the array of folders which contain data migration scripts. Also adds them to be auto-loaded
368
-     *
369
-     * @return array where each value is the full folder path of a folder containing data migration scripts, WITH
370
-     *               slashes at the end of the folder name.
371
-     */
372
-    public function get_data_migration_script_folders()
373
-    {
374
-        return apply_filters(
375
-            'FHEE__EE_Data_Migration_Manager__get_data_migration_script_folders',
376
-            array('Core' => EE_CORE . 'data_migration_scripts')
377
-        );
378
-    }
379
-
380
-    /**
381
-     * Gets the version the migration script upgrades to
382
-     *
383
-     * @param string $migration_script_name eg 'EE_DMS_Core_4_1_0'
384
-     * @return array {
385
-     * @type string  $slug                  like 'Core','Calendar',etc
386
-     * @type string  $version               like 4.3.0
387
-     *                                      }
388
-     * @throws EE_Error
389
-     */
390
-    public function script_migrates_to_version($migration_script_name, $eeAddonClass = '')
391
-    {
392
-        if (isset($this->script_migration_versions[ $migration_script_name ])) {
393
-            return $this->script_migration_versions[ $migration_script_name ];
394
-        }
395
-        $dms_info = $this->parse_dms_classname($migration_script_name);
396
-        $this->script_migration_versions[ $migration_script_name ] = array(
397
-            'slug'    => $eeAddonClass !== '' ? $eeAddonClass : $dms_info['slug'],
398
-            'version' => $dms_info['major_version'] . "." . $dms_info['minor_version'] . "." . $dms_info['micro_version'],
399
-        );
400
-        return $this->script_migration_versions[ $migration_script_name ];
401
-    }
402
-
403
-    /**
404
-     * Gets the juicy details out of a dms filename like 'EE_DMS_Core_4_1_0'
405
-     *
406
-     * @param string $classname
407
-     * @return array with keys 'slug','major_version','minor_version', and 'micro_version' (the last 3 are ints)
408
-     * @throws EE_Error
409
-     */
410
-    public function parse_dms_classname($classname)
411
-    {
412
-        $matches = array();
413
-        preg_match('~EE_DMS_(.*)_([0-9]*)_([0-9]*)_([0-9]*)~', $classname, $matches);
414
-        if (! $matches || ! (isset($matches[1]) && isset($matches[2]) && isset($matches[3]))) {
415
-            throw new EE_Error(
416
-                sprintf(
417
-                    __(
418
-                        "%s is not a valid Data Migration Script. The classname should be like EE_DMS_w_x_y_z, where w is either 'Core' or the slug of an addon and x, y and z are numbers, ",
419
-                        "event_espresso"
420
-                    ),
421
-                    $classname
422
-                )
423
-            );
424
-        }
425
-        return array(
426
-            'slug'          => $matches[1],
427
-            'major_version' => intval($matches[2]),
428
-            'minor_version' => intval($matches[3]),
429
-            'micro_version' => intval($matches[4]),
430
-        );
431
-    }
432
-
433
-    /**
434
-     * Ensures that the option indicating the current DB version is set. This should only be
435
-     * a concern when activating EE for the first time, THEORETICALLY.
436
-     * If we detect that we're activating EE4 over top of EE3.1, then we set the current db state to 3.1.x, otherwise
437
-     * to 4.1.x.
438
-     *
439
-     * @return string of current db state
440
-     */
441
-    public function ensure_current_database_state_is_set()
442
-    {
443
-        $espresso_db_core_updates = get_option('espresso_db_update', array());
444
-        $db_state = get_option(EE_Data_Migration_Manager::current_database_state);
445
-        if (! $db_state) {
446
-            // mark the DB as being in the state as the last version in there.
447
-            // this is done to trigger maintenance mode and do data migration scripts
448
-            // if the admin installed this version of EE over 3.1.x or 4.0.x
449
-            // otherwise, the normal maintenance mode code is fine
450
-            $previous_versions_installed = array_keys($espresso_db_core_updates);
451
-            $previous_version_installed = end($previous_versions_installed);
452
-            if (version_compare('4.1.0', $previous_version_installed)) {
453
-                // last installed version was less than 4.1
454
-                // so we want the data migrations to happen. SO, we're going to say the DB is at that state
455
-                $db_state = array('Core' => $previous_version_installed);
456
-            } else {
457
-                $db_state = array('Core' => EVENT_ESPRESSO_VERSION);
458
-            }
459
-            update_option(EE_Data_Migration_Manager::current_database_state, $db_state);
460
-        }
461
-        // in 4.1, $db_state would have only been a simple string like '4.1.0',
462
-        // but in 4.2+ it should be an array with at least key 'Core' and the value of that plugin's
463
-        // db, and possibly other keys for other addons like 'Calendar','Permissions',etc
464
-        if (! is_array($db_state)) {
465
-            $db_state = array('Core' => $db_state);
466
-            update_option(EE_Data_Migration_Manager::current_database_state, $db_state);
467
-        }
468
-        return $db_state;
469
-    }
470
-
471
-    /**
472
-     * Checks if there are any data migration scripts that ought to be run. If found,
473
-     * returns the instantiated classes. If none are found (ie, they've all already been run
474
-     * or they don't apply), returns an empty array
475
-     *
476
-     * @return EE_Data_Migration_Script_Base[]
477
-     */
478
-    public function check_for_applicable_data_migration_scripts()
479
-    {
480
-        // get the option describing what options have already run
481
-        $scripts_ran = $this->get_data_migrations_ran();
482
-        // $scripts_ran = array('4.1.0.core'=>array('monkey'=>null));
483
-        $script_class_and_filepaths_available = $this->get_all_data_migration_scripts_available();
484
-
485
-
486
-        $current_database_state = $this->ensure_current_database_state_is_set();
487
-        // determine which have already been run
488
-        $script_classes_that_should_run_per_iteration = array();
489
-        $iteration = 0;
490
-        $next_database_state_to_consider = $current_database_state;
491
-        $theoretical_database_state = null;
492
-        do {
493
-            // the next state after the currently-considered one will start off looking the same as the current, but we may make additions...
494
-            $theoretical_database_state = $next_database_state_to_consider;
495
-            // the next db state to consider is "what would the DB be like had we run all the scripts we found that applied last time?)
496
-            foreach ($script_class_and_filepaths_available as $classname => $filepath) {
497
-                $migrates_to_version = $this->script_migrates_to_version($classname);
498
-                $script_converts_plugin_slug = $migrates_to_version['slug'];
499
-                $script_converts_to_version = $migrates_to_version['version'];
500
-                // check if this version script is DONE or not; or if it's never been ran
501
-                if (! $scripts_ran ||
502
-                    ! isset($scripts_ran[ $script_converts_plugin_slug ]) ||
503
-                    ! isset($scripts_ran[ $script_converts_plugin_slug ][ $script_converts_to_version ])) {
504
-                    // we haven't ran this conversion script before
505
-                    // now check if it applies... note that we've added an autoloader for it on get_all_data_migration_scripts_available
506
-                    $script = LoaderFactory::getLoader()->load($classname);
507
-                    /* @var $script EE_Data_Migration_Script_Base */
508
-                    $can_migrate = $script->can_migrate_from_version($theoretical_database_state);
509
-                    if ($can_migrate) {
510
-                        $script_classes_that_should_run_per_iteration[ $iteration ][ $script->priority() ][] = $script;
511
-                        $migrates_to_version = $script->migrates_to_version();
512
-                        $next_database_state_to_consider[ $migrates_to_version['slug'] ] = $migrates_to_version['version'];
513
-                        unset($script_class_and_filepaths_available[ $classname ]);
514
-                    }
515
-                } elseif ($scripts_ran[ $script_converts_plugin_slug ][ $script_converts_to_version ] instanceof EE_Data_Migration_Script_Base) {
516
-                    // this script has been ran, or at least started
517
-                    $script = $scripts_ran[ $script_converts_plugin_slug ][ $script_converts_to_version ];
518
-                    if ($script->get_status() != self::status_completed) {
519
-                        // this script is already underway... keep going with it
520
-                        $script_classes_that_should_run_per_iteration[ $iteration ][ $script->priority() ][] = $script;
521
-                        $migrates_to_version = $script->migrates_to_version();
522
-                        $next_database_state_to_consider[ $migrates_to_version['slug'] ] = $migrates_to_version['version'];
523
-                        unset($script_class_and_filepaths_available[ $classname ]);
524
-                    } else {
525
-                        // it must have a status that indicates it has finished, so we don't want to try and run it again
526
-                    }
527
-                } else {
528
-                    // it exists but it's not  a proper data migration script
529
-                    // maybe the script got renamed? or was simply removed from EE?
530
-                    // either way, its certainly not runnable!
531
-                }
532
-            }
533
-            $iteration++;
534
-        } while ($next_database_state_to_consider != $theoretical_database_state && $iteration < 6);
535
-        // ok we have all the scripts that should run, now let's make them into flat array
536
-        $scripts_that_should_run = array();
537
-        foreach ($script_classes_that_should_run_per_iteration as $scripts_at_priority) {
538
-            ksort($scripts_at_priority);
539
-            foreach ($scripts_at_priority as $scripts) {
540
-                foreach ($scripts as $script) {
541
-                    $scripts_that_should_run[ get_class($script) ] = $script;
542
-                }
543
-            }
544
-        }
545
-
546
-        do_action(
547
-            'AHEE__EE_Data_Migration_Manager__check_for_applicable_data_migration_scripts__scripts_that_should_run',
548
-            $scripts_that_should_run
549
-        );
550
-        return $scripts_that_should_run;
551
-    }
552
-
553
-
554
-    /**
555
-     * Gets the script which is currently being ran, if there is one. If $include_completed_scripts is set to TRUE
556
-     * it will return the last ran script even if its complete.
557
-     * This means: if you want to find the currently-executing script, leave it as FALSE.
558
-     * If you really just want to find the script which ran most recently, regardless of status, leave it as TRUE.
559
-     *
560
-     * @param bool $include_completed_scripts
561
-     * @return EE_Data_Migration_Script_Base
562
-     */
563
-    public function get_last_ran_script($include_completed_scripts = false)
564
-    {
565
-        // make sure we've setup the class properties _last_ran_script and _last_ran_incomplete_script
566
-        if (! $this->_data_migrations_ran) {
567
-            $this->get_data_migrations_ran();
568
-        }
569
-        if ($include_completed_scripts) {
570
-            return $this->_last_ran_script;
571
-        } else {
572
-            return $this->_last_ran_incomplete_script;
573
-        }
574
-    }
575
-
576
-
577
-    /**
578
-     * Runs the data migration scripts (well, each request to this method calls one of the
579
-     * data migration scripts' migration_step() functions).
580
-     *
581
-     * @param int   $step_size
582
-     * @throws EE_Error
583
-     * @return array {
584
-     *                                  // where the first item is one EE_Data_Migration_Script_Base's stati,
585
-     *                                  //and the second item is a string describing what was done
586
-     * @type int    $records_to_migrate from the current migration script
587
-     * @type int    $records_migrated
588
-     * @type string $status             one of EE_Data_Migration_Manager::status_*
589
-     * @type string $script             verbose name of the current DMS
590
-     * @type string $message            string describing what was done during this step
591
-     *                                  }
592
-     */
593
-    public function migration_step($step_size = 0)
594
-    {
595
-
596
-        // bandaid fix for issue https://events.codebasehq.com/projects/event-espresso/tickets/7535
597
-        if (class_exists('EE_CPT_Strategy')) {
598
-            remove_action('pre_get_posts', array(EE_CPT_Strategy::instance(), 'pre_get_posts'), 5);
599
-        }
600
-
601
-        try {
602
-            $currently_executing_script = $this->get_last_ran_script();
603
-            if (! $currently_executing_script) {
604
-                // Find the next script that needs to execute
605
-                $scripts = $this->check_for_applicable_data_migration_scripts();
606
-                if (! $scripts) {
607
-                    // huh, no more scripts to run... apparently we're done!
608
-                    // but dont forget to make sure initial data is there
609
-                    // we should be good to allow them to exit maintenance mode now
610
-                    EE_Maintenance_Mode::instance()->set_maintenance_level(
611
-                        intval(EE_Maintenance_Mode::level_0_not_in_maintenance)
612
-                    );
613
-                    // saving migrations ran should actually be unnecessary, but leaving in place just in case
614
-                    // remember this migration was finished (even if we timeout initing db for core and plugins)
615
-                    $this->_save_migrations_ran();
616
-                    // make sure DB was updated AFTER we've recorded the migration was done
617
-                    $this->initialize_db_for_enqueued_ee_plugins();
618
-                    return array(
619
-                        'records_to_migrate' => 1,
620
-                        'records_migrated'   => 1,
621
-                        'status'             => self::status_no_more_migration_scripts,
622
-                        'script'             => __("Data Migration Completed Successfully", "event_espresso"),
623
-                        'message'            => __("All done!", "event_espresso"),
624
-                    );
625
-                }
626
-                $currently_executing_script = array_shift($scripts);
627
-                // and add to the array/wp option showing the scripts ran
628
-
629
-                $migrates_to = $this->script_migrates_to_version(get_class($currently_executing_script));
630
-                $plugin_slug = $migrates_to['slug'];
631
-                $version = $migrates_to['version'];
632
-                $this->_data_migrations_ran[ $plugin_slug ][ $version ] = $currently_executing_script;
633
-            }
634
-            $current_script_name = get_class($currently_executing_script);
635
-        } catch (Exception $e) {
636
-            // an exception occurred while trying to get migration scripts
637
-
638
-            $message = sprintf(
639
-                __("Error Message: %sStack Trace:%s", "event_espresso"),
640
-                $e->getMessage() . '<br>',
641
-                $e->getTraceAsString()
642
-            );
643
-            // record it on the array of data migration scripts ran. This will be overwritten next time we try and try to run data migrations
644
-            // but that's ok-- it's just an FYI to support that we couldn't even run any data migrations
645
-            $this->add_error_to_migrations_ran(
646
-                sprintf(__("Could not run data migrations because: %s", "event_espresso"), $message)
647
-            );
648
-            return array(
649
-                'records_to_migrate' => 1,
650
-                'records_migrated'   => 0,
651
-                'status'             => self::status_fatal_error,
652
-                'script'             => __("Error loading data migration scripts", "event_espresso"),
653
-                'message'            => $message,
654
-            );
655
-        }
656
-        // ok so we definitely have a data migration script
657
-        try {
658
-            // how big of a bite do we want to take? Allow users to easily override via their wp-config
659
-            if (absint($step_size) < 1) {
660
-                $step_size = defined('EE_MIGRATION_STEP_SIZE') && absint(EE_MIGRATION_STEP_SIZE)
661
-                    ? EE_MIGRATION_STEP_SIZE : EE_Data_Migration_Manager::step_size;
662
-            }
663
-            // do what we came to do!
664
-            $currently_executing_script->migration_step($step_size);
665
-            // can we wrap it up and verify default data?
666
-            $init_dbs = false;
667
-            switch ($currently_executing_script->get_status()) {
668
-                case EE_Data_Migration_Manager::status_continue:
669
-                    $response_array = array(
670
-                        'records_to_migrate' => $currently_executing_script->count_records_to_migrate(),
671
-                        'records_migrated'   => $currently_executing_script->count_records_migrated(),
672
-                        'status'             => EE_Data_Migration_Manager::status_continue,
673
-                        'message'            => $currently_executing_script->get_feedback_message(),
674
-                        'script'             => $currently_executing_script->pretty_name(),
675
-                    );
676
-                    break;
677
-                case EE_Data_Migration_Manager::status_completed:
678
-                    // ok so THAT script has completed
679
-                    $this->update_current_database_state_to($this->script_migrates_to_version($current_script_name));
680
-                    $response_array = array(
681
-                        'records_to_migrate' => $currently_executing_script->count_records_to_migrate(),
682
-                        'records_migrated'   => $currently_executing_script->count_records_migrated(),
683
-                        'status'             => EE_Data_Migration_Manager::status_completed,
684
-                        'message'            => $currently_executing_script->get_feedback_message(),
685
-                        'script'             => sprintf(
686
-                            __("%s Completed", 'event_espresso'),
687
-                            $currently_executing_script->pretty_name()
688
-                        ),
689
-                    );
690
-                    // check if there are any more after this one.
691
-                    $scripts_remaining = $this->check_for_applicable_data_migration_scripts();
692
-                    if (! $scripts_remaining) {
693
-                        // we should be good to allow them to exit maintenance mode now
694
-                        EE_Maintenance_Mode::instance()->set_maintenance_level(
695
-                            intval(EE_Maintenance_Mode::level_0_not_in_maintenance)
696
-                        );
697
-                        // huh, no more scripts to run... apparently we're done!
698
-                        // but dont forget to make sure initial data is there
699
-                        $init_dbs = true;
700
-                        $response_array['status'] = self::status_no_more_migration_scripts;
701
-                    }
702
-                    break;
703
-                default:
704
-                    $response_array = array(
705
-                        'records_to_migrate' => $currently_executing_script->count_records_to_migrate(),
706
-                        'records_migrated'   => $currently_executing_script->count_records_migrated(),
707
-                        'status'             => $currently_executing_script->get_status(),
708
-                        'message'            => sprintf(
709
-                            __("Minor errors occurred during %s: %s", "event_espresso"),
710
-                            $currently_executing_script->pretty_name(),
711
-                            implode(", ", $currently_executing_script->get_errors())
712
-                        ),
713
-                        'script'             => $currently_executing_script->pretty_name(),
714
-                    );
715
-                    break;
716
-            }
717
-        } catch (Exception $e) {
718
-            // ok so some exception was thrown which killed the data migration script
719
-            // double-check we have a real script
720
-            if ($currently_executing_script instanceof EE_Data_Migration_Script_Base) {
721
-                $script_name = $currently_executing_script->pretty_name();
722
-                $currently_executing_script->set_broken();
723
-                $currently_executing_script->add_error($e->getMessage());
724
-            } else {
725
-                $script_name = __("Error getting Migration Script", "event_espresso");
726
-            }
727
-            $response_array = array(
728
-                'records_to_migrate' => 1,
729
-                'records_migrated'   => 0,
730
-                'status'             => self::status_fatal_error,
731
-                'message'            => sprintf(
732
-                    __("A fatal error occurred during the migration: %s", "event_espresso"),
733
-                    $e->getMessage()
734
-                ),
735
-                'script'             => $script_name,
736
-            );
737
-        }
738
-        $successful_save = $this->_save_migrations_ran();
739
-        if ($successful_save !== true) {
740
-            // ok so the current wp option didn't save. that's tricky, because we'd like to update it
741
-            // and mark it as having a fatal error, but remember- WE CAN'T SAVE THIS WP OPTION!
742
-            // however, if we throw an exception, and return that, then the next request
743
-            // won't have as much info in it, and it may be able to save
744
-            throw new EE_Error(
745
-                sprintf(
746
-                    __(
747
-                        "The error '%s' occurred updating the status of the migration. This is a FATAL ERROR, but the error is preventing the system from remembering that. Please contact event espresso support.",
748
-                        "event_espresso"
749
-                    ),
750
-                    $successful_save
751
-                )
752
-            );
753
-        }
754
-        // if we're all done, initialize EE plugins' default data etc.
755
-        if ($init_dbs) {
756
-            $this->initialize_db_for_enqueued_ee_plugins();
757
-        }
758
-        return $response_array;
759
-    }
760
-
761
-
762
-    /**
763
-     * Echo out JSON response to migration script AJAX requests. Takes precautions
764
-     * to buffer output so that we don't throw junk into our json.
765
-     *
766
-     * @return array with keys:
767
-     * 'records_to_migrate' which counts ALL the records for the current migration, and should remain constant. (ie,
768
-     * it's NOT the count of hwo many remain)
769
-     * 'records_migrated' which also counts ALL the records which have been migrated (ie, percent_complete =
770
-     * records_migrated/records_to_migrate)
771
-     * 'status'=>a string, one of EE_Data_migration_Manager::status_*
772
-     * 'message'=>a string, containing any message you want to show to the user. We may decide to split this up into
773
-     * errors, notifications, and successes
774
-     * 'script'=>a pretty name of the script currently running
775
-     */
776
-    public function response_to_migration_ajax_request()
777
-    {
778
-        ob_start();
779
-        try {
780
-            $response = $this->migration_step();
781
-        } catch (Exception $e) {
782
-            $response = array(
783
-                'records_to_migrate' => 0,
784
-                'records_migrated'   => 0,
785
-                'status'             => EE_Data_Migration_Manager::status_fatal_error,
786
-                'message'            => sprintf(
787
-                    __("Unknown fatal error occurred: %s", "event_espresso"),
788
-                    $e->getMessage()
789
-                ),
790
-                'script'             => 'Unknown',
791
-            );
792
-            $this->add_error_to_migrations_ran($e->getMessage() . "; Stack trace:" . $e->getTraceAsString());
793
-        }
794
-        $warnings_etc = @ob_get_contents();
795
-        ob_end_clean();
796
-        $response['message'] .= $warnings_etc;
797
-        return $response;
798
-    }
799
-
800
-    /**
801
-     * Updates the wordpress option that keeps track of which which EE version the database
802
-     * is at (ie, the code may be at 4.1.0, but the database is still at 3.1.35)
803
-     *
804
-     * @param array $slug_and_version {
805
-     * @type string $slug             like 'Core' or 'Calendar',
806
-     * @type string $version          like '4.1.0'
807
-     *                                }
808
-     * @return void
809
-     */
810
-    public function update_current_database_state_to($slug_and_version = null)
811
-    {
812
-        if (! $slug_and_version) {
813
-            // no version was provided, assume it should be at the current code version
814
-            $slug_and_version = array('slug' => 'Core', 'version' => espresso_version());
815
-        }
816
-        $current_database_state = get_option(self::current_database_state);
817
-        $current_database_state[ $slug_and_version['slug'] ] = $slug_and_version['version'];
818
-        update_option(self::current_database_state, $current_database_state);
819
-    }
820
-
821
-    /**
822
-     * Determines if the database is currently at a state matching what's indicated in $slug and $version.
823
-     *
824
-     * @param array $slug_and_version {
825
-     * @type string $slug             like 'Core' or 'Calendar',
826
-     * @type string $version          like '4.1.0'
827
-     *                                }
828
-     * @return boolean
829
-     */
830
-    public function database_needs_updating_to($slug_and_version)
831
-    {
832
-
833
-        $slug = $slug_and_version['slug'];
834
-        $version = $slug_and_version['version'];
835
-        $current_database_state = get_option(self::current_database_state);
836
-        if (! isset($current_database_state[ $slug ])) {
837
-            return true;
838
-        } else {
839
-            // just compare the first 3 parts of version string, eg "4.7.1", not "4.7.1.dev.032" because DBs shouldn't change on nano version changes
840
-            $version_parts_current_db_state = array_slice(explode('.', $current_database_state[ $slug ]), 0, 3);
841
-            $version_parts_of_provided_db_state = array_slice(explode('.', $version), 0, 3);
842
-            $needs_updating = false;
843
-            foreach ($version_parts_current_db_state as $offset => $version_part_in_current_db_state) {
844
-                if ($version_part_in_current_db_state < $version_parts_of_provided_db_state[ $offset ]) {
845
-                    $needs_updating = true;
846
-                    break;
847
-                }
848
-            }
849
-            return $needs_updating;
850
-        }
851
-    }
852
-
853
-
854
-    /**
855
-     * Gets all the data migration scripts available in the core folder and folders
856
-     * in addons. Has the side effect of adding them for autoloading
857
-     *
858
-     * @return array keys are expected classnames, values are their filepaths
859
-     * @throws InvalidInterfaceException
860
-     * @throws InvalidDataTypeException
861
-     * @throws EE_Error
862
-     * @throws InvalidArgumentException
863
-     */
864
-    public function get_all_data_migration_scripts_available()
865
-    {
866
-        if (! $this->_data_migration_class_to_filepath_map) {
867
-            $this->_data_migration_class_to_filepath_map = array();
868
-            foreach ($this->get_data_migration_script_folders() as $eeAddonClass => $folder_path) {
869
-                // strip any placeholders added to classname to make it a unique array key
870
-                $eeAddonClass = trim($eeAddonClass, '*');
871
-                $eeAddonClass = $eeAddonClass === 'Core' || class_exists($eeAddonClass)
872
-                    ? $eeAddonClass
873
-                    : '';
874
-                $folder_path = EEH_File::end_with_directory_separator($folder_path);
875
-                $files = glob($folder_path . '*.dms.php');
876
-                if (empty($files)) {
877
-                    continue;
878
-                }
879
-                foreach ($files as $file) {
880
-                    $pos_of_last_slash = strrpos($file, DS);
881
-                    $classname = str_replace('.dms.php', '', substr($file, $pos_of_last_slash + 1));
882
-                    $migrates_to = $this->script_migrates_to_version($classname, $eeAddonClass);
883
-                    $slug = $migrates_to['slug'];
884
-                    // check that the slug as contained in the DMS is associated with
885
-                    // the slug of an addon or core
886
-                    if ($slug !== 'Core' && EE_Registry::instance()->get_addon_by_name($slug) === null) {
887
-                        EE_Error::doing_it_wrong(
888
-                            __FUNCTION__,
889
-                            sprintf(
890
-                                esc_html__(
891
-                                    'The data migration script "%s" migrates the "%s" data, but there is no EE addon with that name. There is only: %s. ',
892
-                                    'event_espresso'
893
-                                ),
894
-                                $classname,
895
-                                $slug,
896
-                                implode(', ', array_keys(EE_Registry::instance()->get_addons_by_name()))
897
-                            ),
898
-                            '4.3.0.alpha.019'
899
-                        );
900
-                    }
901
-                    $this->_data_migration_class_to_filepath_map[ $classname ] = $file;
902
-                }
903
-            }
904
-            EEH_Autoloader::register_autoloader($this->_data_migration_class_to_filepath_map);
905
-        }
906
-        return $this->_data_migration_class_to_filepath_map;
907
-    }
908
-
909
-
910
-    /**
911
-     * Once we have an addon that works with EE4.1, we will actually want to fetch the PUE slugs
912
-     * from each addon, and check if they need updating,
913
-     *
914
-     * @return boolean
915
-     */
916
-    public function addons_need_updating()
917
-    {
918
-        return false;
919
-    }
920
-
921
-    /**
922
-     * Adds this error string to the data_migrations_ran array, but we dont necessarily know
923
-     * where to put it, so we just throw it in there... better than nothing...
924
-     *
925
-     * @param string $error_message
926
-     * @throws EE_Error
927
-     */
928
-    public function add_error_to_migrations_ran($error_message)
929
-    {
930
-        // get last-ran migration script
931
-        global $wpdb;
932
-        $last_migration_script_option = $wpdb->get_row(
933
-            "SELECT * FROM $wpdb->options WHERE option_name like '" . EE_Data_Migration_Manager::data_migration_script_option_prefix . "%' ORDER BY option_id DESC LIMIT 1",
934
-            ARRAY_A
935
-        );
936
-
937
-        $last_ran_migration_script_properties = isset($last_migration_script_option['option_value'])
938
-            ? maybe_unserialize($last_migration_script_option['option_value']) : null;
939
-        // now, tread lightly because we're here because a FATAL non-catchable error
940
-        // was thrown last time when we were trying to run a data migration script
941
-        // so the fatal error could have happened while getting the migration script
942
-        // or doing running it...
943
-        $versions_migrated_to = isset($last_migration_script_option['option_name']) ? str_replace(
944
-            EE_Data_Migration_Manager::data_migration_script_option_prefix,
945
-            "",
946
-            $last_migration_script_option['option_name']
947
-        ) : null;
948
-
949
-        // check if it THINKS its a data migration script and especially if it's one that HASN'T finished yet
950
-        // because if it has finished, then it obviously couldn't be the cause of this error, right? (because its all done)
951
-        if (isset($last_ran_migration_script_properties['class']) && isset($last_ran_migration_script_properties['_status']) && $last_ran_migration_script_properties['_status'] != self::status_completed) {
952
-            // ok then just add this error to its list of errors
953
-            $last_ran_migration_script_properties['_errors'][] = $error_message;
954
-            $last_ran_migration_script_properties['_status'] = self::status_fatal_error;
955
-        } else {
956
-            // so we don't even know which script was last running
957
-            // use the data migration error stub, which is designed specifically for this type of thing
958
-            $general_migration_error = new EE_DMS_Unknown_1_0_0();
959
-            $general_migration_error->add_error($error_message);
960
-            $general_migration_error->set_broken();
961
-            $last_ran_migration_script_properties = $general_migration_error->properties_as_array();
962
-            $versions_migrated_to = 'Unknown.1.0.0';
963
-            // now just to make sure appears as last (in case the were previously a fatal error like this)
964
-            // delete the old one
965
-            delete_option(self::data_migration_script_option_prefix . $versions_migrated_to);
966
-        }
967
-        update_option(
968
-            self::data_migration_script_option_prefix . $versions_migrated_to,
969
-            $last_ran_migration_script_properties
970
-        );
971
-    }
972
-
973
-    /**
974
-     * saves what data migrations have ran to the database
975
-     *
976
-     * @return mixed TRUE if successfully saved migrations ran, string if an error occurred
977
-     */
978
-    protected function _save_migrations_ran()
979
-    {
980
-        if ($this->_data_migrations_ran == null) {
981
-            $this->get_data_migrations_ran();
982
-        }
983
-        // now, we don't want to save actual classes to the DB because that's messy
984
-        $successful_updates = true;
985
-        foreach ($this->_data_migrations_ran as $plugin_slug => $migrations_ran_for_plugin) {
986
-            foreach ($migrations_ran_for_plugin as $version_string => $array_or_migration_obj) {
987
-                $plugin_slug_for_use_in_option_name = $plugin_slug . ".";
988
-                $option_name = self::data_migration_script_option_prefix . $plugin_slug_for_use_in_option_name . $version_string;
989
-                $old_option_value = get_option($option_name);
990
-                if ($array_or_migration_obj instanceof EE_Data_Migration_Script_Base) {
991
-                    $script_array_for_saving = $array_or_migration_obj->properties_as_array();
992
-                    if ($old_option_value != $script_array_for_saving) {
993
-                        $successful_updates = update_option($option_name, $script_array_for_saving);
994
-                    }
995
-                } else {// we don't know what this array-thing is. So just save it as-is
996
-                    if ($old_option_value != $array_or_migration_obj) {
997
-                        $successful_updates = update_option($option_name, $array_or_migration_obj);
998
-                    }
999
-                }
1000
-                if (! $successful_updates) {
1001
-                    global $wpdb;
1002
-                    return $wpdb->last_error;
1003
-                }
1004
-            }
1005
-        }
1006
-        return true;
1007
-        // $updated = update_option(self::data_migrations_option_name, $array_of_migrations);
1008
-        // if ($updated !== true) {
1009
-        //     global $wpdb;
1010
-        //     return $wpdb->last_error;
1011
-        // } else {
1012
-        //     return true;
1013
-        // }
1014
-        // wp_mail(
1015
-        //     "[email protected]",
1016
-        //     time() . " price debug info",
1017
-        //     "updated: $updated, last error: $last_error, byte length of option: " . strlen(
1018
-        //         serialize($array_of_migrations)
1019
-        //     )
1020
-        // );
1021
-    }
1022
-
1023
-    /**
1024
-     * Takes an array of data migration script properties and re-creates the class from
1025
-     * them. The argument $properties_array is assumed to have been made by
1026
-     * EE_Data_Migration_Script_Base::properties_as_array()
1027
-     *
1028
-     * @param array $properties_array
1029
-     * @return EE_Data_Migration_Script_Base
1030
-     * @throws EE_Error
1031
-     */
1032
-    public function _instantiate_script_from_properties_array($properties_array)
1033
-    {
1034
-        if (! isset($properties_array['class'])) {
1035
-            throw new EE_Error(
1036
-                sprintf(
1037
-                    __("Properties array  has no 'class' properties. Here's what it has: %s", "event_espresso"),
1038
-                    implode(",", $properties_array)
1039
-                )
1040
-            );
1041
-        }
1042
-        $class_name = $properties_array['class'];
1043
-        if (! class_exists($class_name)) {
1044
-            throw new EE_Error(sprintf(__("There is no migration script named %s", "event_espresso"), $class_name));
1045
-        }
1046
-        $class = new $class_name;
1047
-        if (! $class instanceof EE_Data_Migration_Script_Base) {
1048
-            throw new EE_Error(
1049
-                sprintf(
1050
-                    __("Class '%s' is supposed to be a migration script. Its not, its a '%s'", "event_espresso"),
1051
-                    $class_name,
1052
-                    get_class($class)
1053
-                )
1054
-            );
1055
-        }
1056
-        $class->instantiate_from_array_of_properties($properties_array);
1057
-        return $class;
1058
-    }
1059
-
1060
-    /**
1061
-     * Gets the classname for the most up-to-date DMS (ie, the one that will finally
1062
-     * leave the DB in a state usable by the current plugin code).
1063
-     *
1064
-     * @param string $plugin_slug the slug for the ee plugin we are searching for. Default is 'Core'
1065
-     * @return string
1066
-     */
1067
-    public function get_most_up_to_date_dms($plugin_slug = 'Core')
1068
-    {
1069
-        $class_to_filepath_map = $this->get_all_data_migration_scripts_available();
1070
-        $most_up_to_date_dms_classname = null;
1071
-        foreach ($class_to_filepath_map as $classname => $filepath) {
1072
-            if ($most_up_to_date_dms_classname === null) {
1073
-                $migrates_to = $this->script_migrates_to_version($classname);
1074
-                $this_plugin_slug = $migrates_to['slug'];
1075
-                if ($this_plugin_slug == $plugin_slug) {
1076
-                    // if it's for core, it wins
1077
-                    $most_up_to_date_dms_classname = $classname;
1078
-                }
1079
-                // if it wasn't for core, we must keep searching for one that is!
1080
-                continue;
1081
-            } else {
1082
-                $champion_migrates_to = $this->script_migrates_to_version($most_up_to_date_dms_classname);
1083
-                $contender_migrates_to = $this->script_migrates_to_version($classname);
1084
-                if ($contender_migrates_to['slug'] == $plugin_slug
1085
-                    && version_compare(
1086
-                        $champion_migrates_to['version'],
1087
-                        $contender_migrates_to['version'],
1088
-                        '<'
1089
-                    )) {
1090
-                    // so the contenders version is higher and its for Core
1091
-                    $most_up_to_date_dms_classname = $classname;
1092
-                }
1093
-            }
1094
-        }
1095
-        return $most_up_to_date_dms_classname;
1096
-    }
1097
-
1098
-    /**
1099
-     * Gets the migration script specified but ONLY if it has already ran.
1100
-     *
1101
-     * Eg, if you wanted to see if 'EE_DMS_Core_4_1_0' has ran, you would run the following code:
1102
-     * <code> $core_4_1_0_dms_ran = EE_Data_Migration_Manager::instance()->get_migration_ran( '4.1.0', 'Core' ) !==
1103
-     * NULL;</code> This is especially useful in addons' data migration scripts, this way they can tell if a core (or
1104
-     * other addon) DMS has ran, in case the current DMS depends on it.
1105
-     *
1106
-     * @param string $version     the version the DMS searched for migrates to. Usually just the content before the 3rd
1107
-     *                            period. Eg '4.1.0'
1108
-     * @param string $plugin_slug like 'Core', 'Mailchimp', 'Calendar', etc
1109
-     * @return EE_Data_Migration_Script_Base
1110
-     */
1111
-    public function get_migration_ran($version, $plugin_slug = 'Core')
1112
-    {
1113
-        $migrations_ran = $this->get_data_migrations_ran();
1114
-        if (isset($migrations_ran[ $plugin_slug ]) && isset($migrations_ran[ $plugin_slug ][ $version ])) {
1115
-            return $migrations_ran[ $plugin_slug ][ $version ];
1116
-        } else {
1117
-            return null;
1118
-        }
1119
-    }
1120
-
1121
-    /**
1122
-     * Resets the borked data migration scripts so they're no longer borked
1123
-     * so we can again attempt to migrate
1124
-     *
1125
-     * @return bool
1126
-     * @throws EE_Error
1127
-     */
1128
-    public function reattempt()
1129
-    {
1130
-        // find if the last-ran script was borked
1131
-        // set it as being non-borked (we shouldn't ever get DMSs that we don't recognize)
1132
-        // add an 'error' saying that we attempted to reset
1133
-        // does it have a stage that was borked too? if so make it no longer borked
1134
-        // add an 'error' saying we attempted to reset
1135
-        $last_ran_script = $this->get_last_ran_script();
1136
-        if ($last_ran_script instanceof EE_DMS_Unknown_1_0_0) {
1137
-            // if it was an error DMS, just mark it as complete (if another error occurs it will overwrite it)
1138
-            $last_ran_script->set_completed();
1139
-        } elseif ($last_ran_script instanceof EE_Data_Migration_Script_Base) {
1140
-            $last_ran_script->reattempt();
1141
-        } else {
1142
-            throw new EE_Error(
1143
-                sprintf(
1144
-                    __(
1145
-                        'Unable to reattempt the last ran migration script because it was not a valid migration script. || It was %s',
1146
-                        'event_espresso'
1147
-                    ),
1148
-                    print_r($last_ran_script, true)
1149
-                )
1150
-            );
1151
-        }
1152
-        return $this->_save_migrations_ran();
1153
-    }
1154
-
1155
-    /**
1156
-     * Gets whether or not this particular migration has run or not
1157
-     *
1158
-     * @param string $version     the version the DMS searched for migrates to. Usually just the content before the 3rd
1159
-     *                            period. Eg '4.1.0'
1160
-     * @param string $plugin_slug like 'Core', 'Mailchimp', 'Calendar', etc
1161
-     * @return boolean
1162
-     */
1163
-    public function migration_has_ran($version, $plugin_slug = 'Core')
1164
-    {
1165
-        return $this->get_migration_ran($version, $plugin_slug) !== null;
1166
-    }
1167
-
1168
-    /**
1169
-     * Enqueues this ee plugin to have its data initialized
1170
-     *
1171
-     * @param string $plugin_slug either 'Core' or EE_Addon::name()'s return value
1172
-     */
1173
-    public function enqueue_db_initialization_for($plugin_slug)
1174
-    {
1175
-        $queue = $this->get_db_initialization_queue();
1176
-        if (! in_array($plugin_slug, $queue)) {
1177
-            $queue[] = $plugin_slug;
1178
-        }
1179
-        update_option(self::db_init_queue_option_name, $queue);
1180
-    }
1181
-
1182
-    /**
1183
-     * Calls EE_Addon::initialize_db_if_no_migrations_required() on each addon
1184
-     * specified in EE_Data_Migration_Manager::get_db_init_queue(), and if 'Core' is
1185
-     * in the queue, calls EE_System::initialize_db_if_no_migrations_required().
1186
-     */
1187
-    public function initialize_db_for_enqueued_ee_plugins()
1188
-    {
1189
-        $queue = $this->get_db_initialization_queue();
1190
-        foreach ($queue as $plugin_slug) {
1191
-            $most_up_to_date_dms = $this->get_most_up_to_date_dms($plugin_slug);
1192
-            if (! $most_up_to_date_dms) {
1193
-                // if there is NO DMS for this plugin, obviously there's no schema to verify anyways
1194
-                $verify_db = false;
1195
-            } else {
1196
-                $most_up_to_date_dms_migrates_to = $this->script_migrates_to_version($most_up_to_date_dms);
1197
-                $verify_db = $this->database_needs_updating_to($most_up_to_date_dms_migrates_to);
1198
-            }
1199
-            if ($plugin_slug == 'Core') {
1200
-                EE_System::instance()->initialize_db_if_no_migrations_required(
1201
-                    false,
1202
-                    $verify_db
1203
-                );
1204
-            } else {
1205
-                // just loop through the addons to make sure their database is setup
1206
-                foreach (EE_Registry::instance()->addons as $addon) {
1207
-                    if ($addon->name() == $plugin_slug) {
1208
-                        $addon->initialize_db_if_no_migrations_required($verify_db);
1209
-                        break;
1210
-                    }
1211
-                }
1212
-            }
1213
-        }
1214
-        // because we just initialized the DBs for the enqueued ee plugins
1215
-        // we don't need to keep remembering which ones needed to be initialized
1216
-        delete_option(self::db_init_queue_option_name);
1217
-    }
1218
-
1219
-    /**
1220
-     * Gets a numerically-indexed array of plugin slugs that need to have their databases
1221
-     * (re-)initialized after migrations are complete. ie, each element should be either
1222
-     * 'Core', or the return value of EE_Addon::name() for an addon
1223
-     *
1224
-     * @return array
1225
-     */
1226
-    public function get_db_initialization_queue()
1227
-    {
1228
-        return get_option(self::db_init_queue_option_name, array());
1229
-    }
1230
-
1231
-    /**
1232
-     * Gets the injected table analyzer, or throws an exception
1233
-     *
1234
-     * @return TableAnalysis
1235
-     * @throws EE_Error
1236
-     */
1237
-    protected function _get_table_analysis()
1238
-    {
1239
-        if ($this->_table_analysis instanceof TableAnalysis) {
1240
-            return $this->_table_analysis;
1241
-        } else {
1242
-            throw new EE_Error(
1243
-                sprintf(
1244
-                    __('Table analysis class on class %1$s is not set properly.', 'event_espresso'),
1245
-                    get_class($this)
1246
-                )
1247
-            );
1248
-        }
1249
-    }
1250
-
1251
-    /**
1252
-     * Gets the injected table manager, or throws an exception
1253
-     *
1254
-     * @return TableManager
1255
-     * @throws EE_Error
1256
-     */
1257
-    protected function _get_table_manager()
1258
-    {
1259
-        if ($this->_table_manager instanceof TableManager) {
1260
-            return $this->_table_manager;
1261
-        } else {
1262
-            throw new EE_Error(
1263
-                sprintf(
1264
-                    __('Table manager class on class %1$s is not set properly.', 'event_espresso'),
1265
-                    get_class($this)
1266
-                )
1267
-            );
1268
-        }
1269
-    }
36
+	/**
37
+	 *
38
+	 * @var EE_Registry
39
+	 */
40
+	// protected $EE;
41
+	/**
42
+	 * name of the wordpress option which stores an array of data about
43
+	 */
44
+	const data_migrations_option_name = 'ee_data_migration';
45
+
46
+
47
+	const data_migration_script_option_prefix = 'ee_data_migration_script_';
48
+
49
+	const data_migration_script_mapping_option_prefix = 'ee_dms_map_';
50
+
51
+	/**
52
+	 * name of the wordpress option which stores the database' current version. IE, the code may be at version 4.2.0,
53
+	 * but as migrations are performed the database will progress from 3.1.35 to 4.1.0 etc.
54
+	 */
55
+	const current_database_state = 'ee_data_migration_current_db_state';
56
+
57
+	/**
58
+	 * Special status string returned when we're positive there are no more data migration
59
+	 * scripts that can be run.
60
+	 */
61
+	const status_no_more_migration_scripts = 'no_more_migration_scripts';
62
+	/**
63
+	 * string indicating the migration should continue
64
+	 */
65
+	const status_continue = 'status_continue';
66
+	/**
67
+	 * string indicating the migration has completed and should be ended
68
+	 */
69
+	const status_completed = 'status_completed';
70
+	/**
71
+	 * string indicating a fatal error occurred and the data migration should be completely aborted
72
+	 */
73
+	const status_fatal_error = 'status_fatal_error';
74
+
75
+	/**
76
+	 * the number of 'items' (usually DB rows) to migrate on each 'step' (ajax request sent
77
+	 * during migration)
78
+	 */
79
+	const step_size = 50;
80
+
81
+	/**
82
+	 * option name that stores the queue of ee plugins needing to have
83
+	 * their data initialized (or re-initialized) once we are done migrations
84
+	 */
85
+	const db_init_queue_option_name = 'ee_db_init_queue';
86
+	/**
87
+	 * Array of information concerning data migrations that have ran in the history
88
+	 * of this EE installation. Keys should be the name of the version the script upgraded to
89
+	 *
90
+	 * @var EE_Data_Migration_Script_Base[]
91
+	 */
92
+	private $_data_migrations_ran = null;
93
+	/**
94
+	 * The last ran script. It's nice to store this somewhere accessible, as its easiest
95
+	 * to know which was the last run by which is the newest wp option; but in most of the code
96
+	 * we just use the local $_data_migration_ran array, which organized the scripts differently
97
+	 *
98
+	 * @var EE_Data_Migration_Script_Base
99
+	 */
100
+	private $_last_ran_script = null;
101
+
102
+	/**
103
+	 * Similarly to _last_ran_script, but this is the last INCOMPLETE migration script.
104
+	 *
105
+	 * @var EE_Data_Migration_Script_Base
106
+	 */
107
+	private $_last_ran_incomplete_script = null;
108
+	/**
109
+	 * array where keys are classnames, and values are filepaths of all the known migration scripts
110
+	 *
111
+	 * @var array
112
+	 */
113
+	private $_data_migration_class_to_filepath_map;
114
+
115
+	/**
116
+	 * the following 4 properties are fully set on construction.
117
+	 * Note: the first two apply to whether to continue running ALL migration scripts (ie, even though we're finished
118
+	 * one, we may want to start the next one); whereas the last two indicate whether to continue running a single
119
+	 * data migration script
120
+	 *
121
+	 * @var array
122
+	 */
123
+	public $stati_that_indicate_to_continue_migrations = array();
124
+
125
+	public $stati_that_indicate_to_stop_migrations = array();
126
+
127
+	public $stati_that_indicate_to_continue_single_migration_script = array();
128
+
129
+	public $stati_that_indicate_to_stop_single_migration_script = array();
130
+
131
+	/**
132
+	 * @var \EventEspresso\core\services\database\TableManager $table_manager
133
+	 */
134
+	protected $_table_manager;
135
+
136
+	/**
137
+	 * @var \EventEspresso\core\services\database\TableAnalysis $table_analysis
138
+	 */
139
+	protected $_table_analysis;
140
+
141
+	/**
142
+	 * @var array $script_migration_versions
143
+	 */
144
+	protected $script_migration_versions;
145
+
146
+	/**
147
+	 * @var EE_Data_Migration_Manager $_instance
148
+	 * @access    private
149
+	 */
150
+	private static $_instance = null;
151
+
152
+
153
+	/**
154
+	 * @singleton method used to instantiate class object
155
+	 * @access    public
156
+	 * @return EE_Data_Migration_Manager instance
157
+	 */
158
+	public static function instance()
159
+	{
160
+		// check if class object is instantiated
161
+		if (! self::$_instance instanceof EE_Data_Migration_Manager) {
162
+			self::$_instance = new self();
163
+		}
164
+		return self::$_instance;
165
+	}
166
+
167
+	/**
168
+	 * resets the singleton to its brand-new state (but does NOT delete old references to the old singleton. Meaning,
169
+	 * all new usages of the singleton should be made with Classname::instance()) and returns it
170
+	 *
171
+	 * @return EE_Data_Migration_Manager
172
+	 */
173
+	public static function reset()
174
+	{
175
+		self::$_instance = null;
176
+		return self::instance();
177
+	}
178
+
179
+
180
+	/**
181
+	 * constructor
182
+	 */
183
+	private function __construct()
184
+	{
185
+		$this->stati_that_indicate_to_continue_migrations = array(
186
+			self::status_continue,
187
+			self::status_completed,
188
+		);
189
+		$this->stati_that_indicate_to_stop_migrations = array(
190
+			self::status_fatal_error,
191
+			self::status_no_more_migration_scripts,
192
+		);
193
+		$this->stati_that_indicate_to_continue_single_migration_script = array(
194
+			self::status_continue,
195
+		);
196
+		$this->stati_that_indicate_to_stop_single_migration_script = array(
197
+			self::status_completed,
198
+			self::status_fatal_error
199
+			// note: status_no_more_migration_scripts doesn't apply
200
+		);
201
+		// make sure we've included the base migration script, because we may need the EE_DMS_Unknown_1_0_0 class
202
+		// to be defined, because right now it doesn't get autoloaded on its own
203
+		EE_Registry::instance()->load_core('Data_Migration_Class_Base', array(), true);
204
+		EE_Registry::instance()->load_core('Data_Migration_Script_Base', array(), true);
205
+		EE_Registry::instance()->load_core('DMS_Unknown_1_0_0', array(), true);
206
+		EE_Registry::instance()->load_core('Data_Migration_Script_Stage', array(), true);
207
+		EE_Registry::instance()->load_core('Data_Migration_Script_Stage_Table', array(), true);
208
+		$this->_table_manager = EE_Registry::instance()->create('TableManager', array(), true);
209
+		$this->_table_analysis = EE_Registry::instance()->create('TableAnalysis', array(), true);
210
+	}
211
+
212
+
213
+	/**
214
+	 * Deciphers, from an option's name, what plugin and version it relates to (see _save_migrations_ran to see what
215
+	 * the option names are like, but generally they're like
216
+	 * 'ee_data_migration_script_Core.4.1.0' in 4.2 or 'ee_data_migration_script_4.1.0' before that).
217
+	 * The option name shouldn't ever be like 'ee_data_migration_script_Core.4.1.0.reg' because it's derived,
218
+	 * indirectly, from the data migration's classname, which should always be like EE_DMS_%s_%d_%d_%d.dms.php (eg
219
+	 * EE_DMS_Core_4_1_0.dms.php)
220
+	 *
221
+	 * @param string $option_name (see EE_Data_Migration_Manage::_save_migrations_ran() where the option name is set)
222
+	 * @return array where the first item is the plugin slug (eg 'Core','Calendar',etc) and the 2nd is the version of
223
+	 *               that plugin (eg '4.1.0')
224
+	 */
225
+	private function _get_plugin_slug_and_version_string_from_dms_option_name($option_name)
226
+	{
227
+		$plugin_slug_and_version_string = str_replace(
228
+			EE_Data_Migration_Manager::data_migration_script_option_prefix,
229
+			"",
230
+			$option_name
231
+		);
232
+		// check if $plugin_slug_and_version_string is like '4.1.0' (4.1-style) or 'Core.4.1.0' (4.2-style)
233
+		$parts = explode(".", $plugin_slug_and_version_string);
234
+
235
+		if (count($parts) == 4) {
236
+			// it's 4.2-style.eg Core.4.1.0
237
+			$plugin_slug = $parts[0];// eg Core
238
+			$version_string = $parts[1] . "." . $parts[2] . "." . $parts[3]; // eg 4.1.0
239
+		} else {
240
+			// it's 4.1-style: eg 4.1.0
241
+			$plugin_slug = 'Core';
242
+			$version_string = $plugin_slug_and_version_string;// eg 4.1.0
243
+		}
244
+		return array($plugin_slug, $version_string);
245
+	}
246
+
247
+	/**
248
+	 * Gets the DMS class from the wordpress option, otherwise throws an EE_Error if it's not
249
+	 * for a known DMS class.
250
+	 *
251
+	 * @param string $dms_option_name
252
+	 * @param string $dms_option_value (serialized)
253
+	 * @return EE_Data_Migration_Script_Base
254
+	 * @throws EE_Error
255
+	 */
256
+	private function _get_dms_class_from_wp_option($dms_option_name, $dms_option_value)
257
+	{
258
+		$data_migration_data = maybe_unserialize($dms_option_value);
259
+		if (isset($data_migration_data['class']) && class_exists($data_migration_data['class'])) {
260
+			$class = LoaderFactory::getLoader()->getShared($data_migration_data['class']);
261
+			if ($class instanceof EE_Data_Migration_Script_Base) {
262
+				$class->instantiate_from_array_of_properties($data_migration_data);
263
+				return $class;
264
+			} else {
265
+				// huh, so its an object but not a data migration script?? that shouldn't happen
266
+				// just leave it as an array (which will probably just get ignored)
267
+				throw new EE_Error(
268
+					sprintf(
269
+						__(
270
+							"Trying to retrieve DMS class from wp option. No DMS by the name '%s' exists",
271
+							'event_espresso'
272
+						),
273
+						$data_migration_data['class']
274
+					)
275
+				);
276
+			}
277
+		} else {
278
+			// so the data doesn't specify a class. So it must either be a legacy array of info or some array (which we'll probably just ignore), or a class that no longer exists
279
+			throw new EE_Error(
280
+				sprintf(__("The wp option  with key '%s' does not represent a DMS", 'event_espresso'), $dms_option_name)
281
+			);
282
+		}
283
+	}
284
+
285
+	/**
286
+	 * Gets the array describing what data migrations have run. Also has a side-effect of recording which was the last
287
+	 * ran, and which was the last ran which hasn't finished yet
288
+	 *
289
+	 * @return array where each element should be an array of EE_Data_Migration_Script_Base (but also has a few legacy
290
+	 *               arrays in there - which should probably be ignored)
291
+	 */
292
+	public function get_data_migrations_ran()
293
+	{
294
+		if (! $this->_data_migrations_ran) {
295
+			// setup autoloaders for each of the scripts in there
296
+			$this->get_all_data_migration_scripts_available();
297
+			$data_migrations_options = $this->get_all_migration_script_options(
298
+			);// get_option(EE_Data_Migration_Manager::data_migrations_option_name,get_option('espresso_data_migrations',array()));
299
+
300
+			$data_migrations_ran = array();
301
+			// convert into data migration script classes where possible
302
+			foreach ($data_migrations_options as $data_migration_option) {
303
+				list($plugin_slug, $version_string) = $this->_get_plugin_slug_and_version_string_from_dms_option_name(
304
+					$data_migration_option['option_name']
305
+				);
306
+
307
+				try {
308
+					$class = $this->_get_dms_class_from_wp_option(
309
+						$data_migration_option['option_name'],
310
+						$data_migration_option['option_value']
311
+					);
312
+					$data_migrations_ran[ $plugin_slug ][ $version_string ] = $class;
313
+					// ok so far THIS is the 'last-ran-script'... unless we find another on next iteration
314
+					$this->_last_ran_script = $class;
315
+					if (! $class->is_completed()) {
316
+						// sometimes we also like to know which was the last incomplete script (or if there are any at all)
317
+						$this->_last_ran_incomplete_script = $class;
318
+					}
319
+				} catch (EE_Error $e) {
320
+					// ok so its not a DMS. We'll just keep it, although other code will need to expect non-DMSs
321
+					$data_migrations_ran[ $plugin_slug ][ $version_string ] = maybe_unserialize(
322
+						$data_migration_option['option_value']
323
+					);
324
+				}
325
+			}
326
+			// so here the array of $data_migrations_ran is actually a mix of classes and a few legacy arrays
327
+			$this->_data_migrations_ran = $data_migrations_ran;
328
+			if (! $this->_data_migrations_ran || ! is_array($this->_data_migrations_ran)) {
329
+				$this->_data_migrations_ran = array();
330
+			}
331
+		}
332
+		return $this->_data_migrations_ran;
333
+	}
334
+
335
+
336
+	/**
337
+	 *
338
+	 * @param string $script_name eg 'DMS_Core_4_1_0'
339
+	 * @param string $old_table   eg 'wp_events_detail'
340
+	 * @param string $old_pk      eg 'wp_esp_posts'
341
+	 * @param        $new_table
342
+	 * @return mixed string or int
343
+	 */
344
+	public function get_mapping_new_pk($script_name, $old_table, $old_pk, $new_table)
345
+	{
346
+		$script = EE_Registry::instance()->load_dms($script_name);
347
+		$mapping = $script->get_mapping_new_pk($old_table, $old_pk, $new_table);
348
+		return $mapping;
349
+	}
350
+
351
+	/**
352
+	 * Gets all the options containing migration scripts that have been run. Ordering is important: it's assumed that
353
+	 * the last option returned in this array is the most-recently ran DMS option
354
+	 *
355
+	 * @return array
356
+	 */
357
+	public function get_all_migration_script_options()
358
+	{
359
+		global $wpdb;
360
+		return $wpdb->get_results(
361
+			"SELECT * FROM {$wpdb->options} WHERE option_name like '" . EE_Data_Migration_Manager::data_migration_script_option_prefix . "%' ORDER BY option_id ASC",
362
+			ARRAY_A
363
+		);
364
+	}
365
+
366
+	/**
367
+	 * Gets the array of folders which contain data migration scripts. Also adds them to be auto-loaded
368
+	 *
369
+	 * @return array where each value is the full folder path of a folder containing data migration scripts, WITH
370
+	 *               slashes at the end of the folder name.
371
+	 */
372
+	public function get_data_migration_script_folders()
373
+	{
374
+		return apply_filters(
375
+			'FHEE__EE_Data_Migration_Manager__get_data_migration_script_folders',
376
+			array('Core' => EE_CORE . 'data_migration_scripts')
377
+		);
378
+	}
379
+
380
+	/**
381
+	 * Gets the version the migration script upgrades to
382
+	 *
383
+	 * @param string $migration_script_name eg 'EE_DMS_Core_4_1_0'
384
+	 * @return array {
385
+	 * @type string  $slug                  like 'Core','Calendar',etc
386
+	 * @type string  $version               like 4.3.0
387
+	 *                                      }
388
+	 * @throws EE_Error
389
+	 */
390
+	public function script_migrates_to_version($migration_script_name, $eeAddonClass = '')
391
+	{
392
+		if (isset($this->script_migration_versions[ $migration_script_name ])) {
393
+			return $this->script_migration_versions[ $migration_script_name ];
394
+		}
395
+		$dms_info = $this->parse_dms_classname($migration_script_name);
396
+		$this->script_migration_versions[ $migration_script_name ] = array(
397
+			'slug'    => $eeAddonClass !== '' ? $eeAddonClass : $dms_info['slug'],
398
+			'version' => $dms_info['major_version'] . "." . $dms_info['minor_version'] . "." . $dms_info['micro_version'],
399
+		);
400
+		return $this->script_migration_versions[ $migration_script_name ];
401
+	}
402
+
403
+	/**
404
+	 * Gets the juicy details out of a dms filename like 'EE_DMS_Core_4_1_0'
405
+	 *
406
+	 * @param string $classname
407
+	 * @return array with keys 'slug','major_version','minor_version', and 'micro_version' (the last 3 are ints)
408
+	 * @throws EE_Error
409
+	 */
410
+	public function parse_dms_classname($classname)
411
+	{
412
+		$matches = array();
413
+		preg_match('~EE_DMS_(.*)_([0-9]*)_([0-9]*)_([0-9]*)~', $classname, $matches);
414
+		if (! $matches || ! (isset($matches[1]) && isset($matches[2]) && isset($matches[3]))) {
415
+			throw new EE_Error(
416
+				sprintf(
417
+					__(
418
+						"%s is not a valid Data Migration Script. The classname should be like EE_DMS_w_x_y_z, where w is either 'Core' or the slug of an addon and x, y and z are numbers, ",
419
+						"event_espresso"
420
+					),
421
+					$classname
422
+				)
423
+			);
424
+		}
425
+		return array(
426
+			'slug'          => $matches[1],
427
+			'major_version' => intval($matches[2]),
428
+			'minor_version' => intval($matches[3]),
429
+			'micro_version' => intval($matches[4]),
430
+		);
431
+	}
432
+
433
+	/**
434
+	 * Ensures that the option indicating the current DB version is set. This should only be
435
+	 * a concern when activating EE for the first time, THEORETICALLY.
436
+	 * If we detect that we're activating EE4 over top of EE3.1, then we set the current db state to 3.1.x, otherwise
437
+	 * to 4.1.x.
438
+	 *
439
+	 * @return string of current db state
440
+	 */
441
+	public function ensure_current_database_state_is_set()
442
+	{
443
+		$espresso_db_core_updates = get_option('espresso_db_update', array());
444
+		$db_state = get_option(EE_Data_Migration_Manager::current_database_state);
445
+		if (! $db_state) {
446
+			// mark the DB as being in the state as the last version in there.
447
+			// this is done to trigger maintenance mode and do data migration scripts
448
+			// if the admin installed this version of EE over 3.1.x or 4.0.x
449
+			// otherwise, the normal maintenance mode code is fine
450
+			$previous_versions_installed = array_keys($espresso_db_core_updates);
451
+			$previous_version_installed = end($previous_versions_installed);
452
+			if (version_compare('4.1.0', $previous_version_installed)) {
453
+				// last installed version was less than 4.1
454
+				// so we want the data migrations to happen. SO, we're going to say the DB is at that state
455
+				$db_state = array('Core' => $previous_version_installed);
456
+			} else {
457
+				$db_state = array('Core' => EVENT_ESPRESSO_VERSION);
458
+			}
459
+			update_option(EE_Data_Migration_Manager::current_database_state, $db_state);
460
+		}
461
+		// in 4.1, $db_state would have only been a simple string like '4.1.0',
462
+		// but in 4.2+ it should be an array with at least key 'Core' and the value of that plugin's
463
+		// db, and possibly other keys for other addons like 'Calendar','Permissions',etc
464
+		if (! is_array($db_state)) {
465
+			$db_state = array('Core' => $db_state);
466
+			update_option(EE_Data_Migration_Manager::current_database_state, $db_state);
467
+		}
468
+		return $db_state;
469
+	}
470
+
471
+	/**
472
+	 * Checks if there are any data migration scripts that ought to be run. If found,
473
+	 * returns the instantiated classes. If none are found (ie, they've all already been run
474
+	 * or they don't apply), returns an empty array
475
+	 *
476
+	 * @return EE_Data_Migration_Script_Base[]
477
+	 */
478
+	public function check_for_applicable_data_migration_scripts()
479
+	{
480
+		// get the option describing what options have already run
481
+		$scripts_ran = $this->get_data_migrations_ran();
482
+		// $scripts_ran = array('4.1.0.core'=>array('monkey'=>null));
483
+		$script_class_and_filepaths_available = $this->get_all_data_migration_scripts_available();
484
+
485
+
486
+		$current_database_state = $this->ensure_current_database_state_is_set();
487
+		// determine which have already been run
488
+		$script_classes_that_should_run_per_iteration = array();
489
+		$iteration = 0;
490
+		$next_database_state_to_consider = $current_database_state;
491
+		$theoretical_database_state = null;
492
+		do {
493
+			// the next state after the currently-considered one will start off looking the same as the current, but we may make additions...
494
+			$theoretical_database_state = $next_database_state_to_consider;
495
+			// the next db state to consider is "what would the DB be like had we run all the scripts we found that applied last time?)
496
+			foreach ($script_class_and_filepaths_available as $classname => $filepath) {
497
+				$migrates_to_version = $this->script_migrates_to_version($classname);
498
+				$script_converts_plugin_slug = $migrates_to_version['slug'];
499
+				$script_converts_to_version = $migrates_to_version['version'];
500
+				// check if this version script is DONE or not; or if it's never been ran
501
+				if (! $scripts_ran ||
502
+					! isset($scripts_ran[ $script_converts_plugin_slug ]) ||
503
+					! isset($scripts_ran[ $script_converts_plugin_slug ][ $script_converts_to_version ])) {
504
+					// we haven't ran this conversion script before
505
+					// now check if it applies... note that we've added an autoloader for it on get_all_data_migration_scripts_available
506
+					$script = LoaderFactory::getLoader()->load($classname);
507
+					/* @var $script EE_Data_Migration_Script_Base */
508
+					$can_migrate = $script->can_migrate_from_version($theoretical_database_state);
509
+					if ($can_migrate) {
510
+						$script_classes_that_should_run_per_iteration[ $iteration ][ $script->priority() ][] = $script;
511
+						$migrates_to_version = $script->migrates_to_version();
512
+						$next_database_state_to_consider[ $migrates_to_version['slug'] ] = $migrates_to_version['version'];
513
+						unset($script_class_and_filepaths_available[ $classname ]);
514
+					}
515
+				} elseif ($scripts_ran[ $script_converts_plugin_slug ][ $script_converts_to_version ] instanceof EE_Data_Migration_Script_Base) {
516
+					// this script has been ran, or at least started
517
+					$script = $scripts_ran[ $script_converts_plugin_slug ][ $script_converts_to_version ];
518
+					if ($script->get_status() != self::status_completed) {
519
+						// this script is already underway... keep going with it
520
+						$script_classes_that_should_run_per_iteration[ $iteration ][ $script->priority() ][] = $script;
521
+						$migrates_to_version = $script->migrates_to_version();
522
+						$next_database_state_to_consider[ $migrates_to_version['slug'] ] = $migrates_to_version['version'];
523
+						unset($script_class_and_filepaths_available[ $classname ]);
524
+					} else {
525
+						// it must have a status that indicates it has finished, so we don't want to try and run it again
526
+					}
527
+				} else {
528
+					// it exists but it's not  a proper data migration script
529
+					// maybe the script got renamed? or was simply removed from EE?
530
+					// either way, its certainly not runnable!
531
+				}
532
+			}
533
+			$iteration++;
534
+		} while ($next_database_state_to_consider != $theoretical_database_state && $iteration < 6);
535
+		// ok we have all the scripts that should run, now let's make them into flat array
536
+		$scripts_that_should_run = array();
537
+		foreach ($script_classes_that_should_run_per_iteration as $scripts_at_priority) {
538
+			ksort($scripts_at_priority);
539
+			foreach ($scripts_at_priority as $scripts) {
540
+				foreach ($scripts as $script) {
541
+					$scripts_that_should_run[ get_class($script) ] = $script;
542
+				}
543
+			}
544
+		}
545
+
546
+		do_action(
547
+			'AHEE__EE_Data_Migration_Manager__check_for_applicable_data_migration_scripts__scripts_that_should_run',
548
+			$scripts_that_should_run
549
+		);
550
+		return $scripts_that_should_run;
551
+	}
552
+
553
+
554
+	/**
555
+	 * Gets the script which is currently being ran, if there is one. If $include_completed_scripts is set to TRUE
556
+	 * it will return the last ran script even if its complete.
557
+	 * This means: if you want to find the currently-executing script, leave it as FALSE.
558
+	 * If you really just want to find the script which ran most recently, regardless of status, leave it as TRUE.
559
+	 *
560
+	 * @param bool $include_completed_scripts
561
+	 * @return EE_Data_Migration_Script_Base
562
+	 */
563
+	public function get_last_ran_script($include_completed_scripts = false)
564
+	{
565
+		// make sure we've setup the class properties _last_ran_script and _last_ran_incomplete_script
566
+		if (! $this->_data_migrations_ran) {
567
+			$this->get_data_migrations_ran();
568
+		}
569
+		if ($include_completed_scripts) {
570
+			return $this->_last_ran_script;
571
+		} else {
572
+			return $this->_last_ran_incomplete_script;
573
+		}
574
+	}
575
+
576
+
577
+	/**
578
+	 * Runs the data migration scripts (well, each request to this method calls one of the
579
+	 * data migration scripts' migration_step() functions).
580
+	 *
581
+	 * @param int   $step_size
582
+	 * @throws EE_Error
583
+	 * @return array {
584
+	 *                                  // where the first item is one EE_Data_Migration_Script_Base's stati,
585
+	 *                                  //and the second item is a string describing what was done
586
+	 * @type int    $records_to_migrate from the current migration script
587
+	 * @type int    $records_migrated
588
+	 * @type string $status             one of EE_Data_Migration_Manager::status_*
589
+	 * @type string $script             verbose name of the current DMS
590
+	 * @type string $message            string describing what was done during this step
591
+	 *                                  }
592
+	 */
593
+	public function migration_step($step_size = 0)
594
+	{
595
+
596
+		// bandaid fix for issue https://events.codebasehq.com/projects/event-espresso/tickets/7535
597
+		if (class_exists('EE_CPT_Strategy')) {
598
+			remove_action('pre_get_posts', array(EE_CPT_Strategy::instance(), 'pre_get_posts'), 5);
599
+		}
600
+
601
+		try {
602
+			$currently_executing_script = $this->get_last_ran_script();
603
+			if (! $currently_executing_script) {
604
+				// Find the next script that needs to execute
605
+				$scripts = $this->check_for_applicable_data_migration_scripts();
606
+				if (! $scripts) {
607
+					// huh, no more scripts to run... apparently we're done!
608
+					// but dont forget to make sure initial data is there
609
+					// we should be good to allow them to exit maintenance mode now
610
+					EE_Maintenance_Mode::instance()->set_maintenance_level(
611
+						intval(EE_Maintenance_Mode::level_0_not_in_maintenance)
612
+					);
613
+					// saving migrations ran should actually be unnecessary, but leaving in place just in case
614
+					// remember this migration was finished (even if we timeout initing db for core and plugins)
615
+					$this->_save_migrations_ran();
616
+					// make sure DB was updated AFTER we've recorded the migration was done
617
+					$this->initialize_db_for_enqueued_ee_plugins();
618
+					return array(
619
+						'records_to_migrate' => 1,
620
+						'records_migrated'   => 1,
621
+						'status'             => self::status_no_more_migration_scripts,
622
+						'script'             => __("Data Migration Completed Successfully", "event_espresso"),
623
+						'message'            => __("All done!", "event_espresso"),
624
+					);
625
+				}
626
+				$currently_executing_script = array_shift($scripts);
627
+				// and add to the array/wp option showing the scripts ran
628
+
629
+				$migrates_to = $this->script_migrates_to_version(get_class($currently_executing_script));
630
+				$plugin_slug = $migrates_to['slug'];
631
+				$version = $migrates_to['version'];
632
+				$this->_data_migrations_ran[ $plugin_slug ][ $version ] = $currently_executing_script;
633
+			}
634
+			$current_script_name = get_class($currently_executing_script);
635
+		} catch (Exception $e) {
636
+			// an exception occurred while trying to get migration scripts
637
+
638
+			$message = sprintf(
639
+				__("Error Message: %sStack Trace:%s", "event_espresso"),
640
+				$e->getMessage() . '<br>',
641
+				$e->getTraceAsString()
642
+			);
643
+			// record it on the array of data migration scripts ran. This will be overwritten next time we try and try to run data migrations
644
+			// but that's ok-- it's just an FYI to support that we couldn't even run any data migrations
645
+			$this->add_error_to_migrations_ran(
646
+				sprintf(__("Could not run data migrations because: %s", "event_espresso"), $message)
647
+			);
648
+			return array(
649
+				'records_to_migrate' => 1,
650
+				'records_migrated'   => 0,
651
+				'status'             => self::status_fatal_error,
652
+				'script'             => __("Error loading data migration scripts", "event_espresso"),
653
+				'message'            => $message,
654
+			);
655
+		}
656
+		// ok so we definitely have a data migration script
657
+		try {
658
+			// how big of a bite do we want to take? Allow users to easily override via their wp-config
659
+			if (absint($step_size) < 1) {
660
+				$step_size = defined('EE_MIGRATION_STEP_SIZE') && absint(EE_MIGRATION_STEP_SIZE)
661
+					? EE_MIGRATION_STEP_SIZE : EE_Data_Migration_Manager::step_size;
662
+			}
663
+			// do what we came to do!
664
+			$currently_executing_script->migration_step($step_size);
665
+			// can we wrap it up and verify default data?
666
+			$init_dbs = false;
667
+			switch ($currently_executing_script->get_status()) {
668
+				case EE_Data_Migration_Manager::status_continue:
669
+					$response_array = array(
670
+						'records_to_migrate' => $currently_executing_script->count_records_to_migrate(),
671
+						'records_migrated'   => $currently_executing_script->count_records_migrated(),
672
+						'status'             => EE_Data_Migration_Manager::status_continue,
673
+						'message'            => $currently_executing_script->get_feedback_message(),
674
+						'script'             => $currently_executing_script->pretty_name(),
675
+					);
676
+					break;
677
+				case EE_Data_Migration_Manager::status_completed:
678
+					// ok so THAT script has completed
679
+					$this->update_current_database_state_to($this->script_migrates_to_version($current_script_name));
680
+					$response_array = array(
681
+						'records_to_migrate' => $currently_executing_script->count_records_to_migrate(),
682
+						'records_migrated'   => $currently_executing_script->count_records_migrated(),
683
+						'status'             => EE_Data_Migration_Manager::status_completed,
684
+						'message'            => $currently_executing_script->get_feedback_message(),
685
+						'script'             => sprintf(
686
+							__("%s Completed", 'event_espresso'),
687
+							$currently_executing_script->pretty_name()
688
+						),
689
+					);
690
+					// check if there are any more after this one.
691
+					$scripts_remaining = $this->check_for_applicable_data_migration_scripts();
692
+					if (! $scripts_remaining) {
693
+						// we should be good to allow them to exit maintenance mode now
694
+						EE_Maintenance_Mode::instance()->set_maintenance_level(
695
+							intval(EE_Maintenance_Mode::level_0_not_in_maintenance)
696
+						);
697
+						// huh, no more scripts to run... apparently we're done!
698
+						// but dont forget to make sure initial data is there
699
+						$init_dbs = true;
700
+						$response_array['status'] = self::status_no_more_migration_scripts;
701
+					}
702
+					break;
703
+				default:
704
+					$response_array = array(
705
+						'records_to_migrate' => $currently_executing_script->count_records_to_migrate(),
706
+						'records_migrated'   => $currently_executing_script->count_records_migrated(),
707
+						'status'             => $currently_executing_script->get_status(),
708
+						'message'            => sprintf(
709
+							__("Minor errors occurred during %s: %s", "event_espresso"),
710
+							$currently_executing_script->pretty_name(),
711
+							implode(", ", $currently_executing_script->get_errors())
712
+						),
713
+						'script'             => $currently_executing_script->pretty_name(),
714
+					);
715
+					break;
716
+			}
717
+		} catch (Exception $e) {
718
+			// ok so some exception was thrown which killed the data migration script
719
+			// double-check we have a real script
720
+			if ($currently_executing_script instanceof EE_Data_Migration_Script_Base) {
721
+				$script_name = $currently_executing_script->pretty_name();
722
+				$currently_executing_script->set_broken();
723
+				$currently_executing_script->add_error($e->getMessage());
724
+			} else {
725
+				$script_name = __("Error getting Migration Script", "event_espresso");
726
+			}
727
+			$response_array = array(
728
+				'records_to_migrate' => 1,
729
+				'records_migrated'   => 0,
730
+				'status'             => self::status_fatal_error,
731
+				'message'            => sprintf(
732
+					__("A fatal error occurred during the migration: %s", "event_espresso"),
733
+					$e->getMessage()
734
+				),
735
+				'script'             => $script_name,
736
+			);
737
+		}
738
+		$successful_save = $this->_save_migrations_ran();
739
+		if ($successful_save !== true) {
740
+			// ok so the current wp option didn't save. that's tricky, because we'd like to update it
741
+			// and mark it as having a fatal error, but remember- WE CAN'T SAVE THIS WP OPTION!
742
+			// however, if we throw an exception, and return that, then the next request
743
+			// won't have as much info in it, and it may be able to save
744
+			throw new EE_Error(
745
+				sprintf(
746
+					__(
747
+						"The error '%s' occurred updating the status of the migration. This is a FATAL ERROR, but the error is preventing the system from remembering that. Please contact event espresso support.",
748
+						"event_espresso"
749
+					),
750
+					$successful_save
751
+				)
752
+			);
753
+		}
754
+		// if we're all done, initialize EE plugins' default data etc.
755
+		if ($init_dbs) {
756
+			$this->initialize_db_for_enqueued_ee_plugins();
757
+		}
758
+		return $response_array;
759
+	}
760
+
761
+
762
+	/**
763
+	 * Echo out JSON response to migration script AJAX requests. Takes precautions
764
+	 * to buffer output so that we don't throw junk into our json.
765
+	 *
766
+	 * @return array with keys:
767
+	 * 'records_to_migrate' which counts ALL the records for the current migration, and should remain constant. (ie,
768
+	 * it's NOT the count of hwo many remain)
769
+	 * 'records_migrated' which also counts ALL the records which have been migrated (ie, percent_complete =
770
+	 * records_migrated/records_to_migrate)
771
+	 * 'status'=>a string, one of EE_Data_migration_Manager::status_*
772
+	 * 'message'=>a string, containing any message you want to show to the user. We may decide to split this up into
773
+	 * errors, notifications, and successes
774
+	 * 'script'=>a pretty name of the script currently running
775
+	 */
776
+	public function response_to_migration_ajax_request()
777
+	{
778
+		ob_start();
779
+		try {
780
+			$response = $this->migration_step();
781
+		} catch (Exception $e) {
782
+			$response = array(
783
+				'records_to_migrate' => 0,
784
+				'records_migrated'   => 0,
785
+				'status'             => EE_Data_Migration_Manager::status_fatal_error,
786
+				'message'            => sprintf(
787
+					__("Unknown fatal error occurred: %s", "event_espresso"),
788
+					$e->getMessage()
789
+				),
790
+				'script'             => 'Unknown',
791
+			);
792
+			$this->add_error_to_migrations_ran($e->getMessage() . "; Stack trace:" . $e->getTraceAsString());
793
+		}
794
+		$warnings_etc = @ob_get_contents();
795
+		ob_end_clean();
796
+		$response['message'] .= $warnings_etc;
797
+		return $response;
798
+	}
799
+
800
+	/**
801
+	 * Updates the wordpress option that keeps track of which which EE version the database
802
+	 * is at (ie, the code may be at 4.1.0, but the database is still at 3.1.35)
803
+	 *
804
+	 * @param array $slug_and_version {
805
+	 * @type string $slug             like 'Core' or 'Calendar',
806
+	 * @type string $version          like '4.1.0'
807
+	 *                                }
808
+	 * @return void
809
+	 */
810
+	public function update_current_database_state_to($slug_and_version = null)
811
+	{
812
+		if (! $slug_and_version) {
813
+			// no version was provided, assume it should be at the current code version
814
+			$slug_and_version = array('slug' => 'Core', 'version' => espresso_version());
815
+		}
816
+		$current_database_state = get_option(self::current_database_state);
817
+		$current_database_state[ $slug_and_version['slug'] ] = $slug_and_version['version'];
818
+		update_option(self::current_database_state, $current_database_state);
819
+	}
820
+
821
+	/**
822
+	 * Determines if the database is currently at a state matching what's indicated in $slug and $version.
823
+	 *
824
+	 * @param array $slug_and_version {
825
+	 * @type string $slug             like 'Core' or 'Calendar',
826
+	 * @type string $version          like '4.1.0'
827
+	 *                                }
828
+	 * @return boolean
829
+	 */
830
+	public function database_needs_updating_to($slug_and_version)
831
+	{
832
+
833
+		$slug = $slug_and_version['slug'];
834
+		$version = $slug_and_version['version'];
835
+		$current_database_state = get_option(self::current_database_state);
836
+		if (! isset($current_database_state[ $slug ])) {
837
+			return true;
838
+		} else {
839
+			// just compare the first 3 parts of version string, eg "4.7.1", not "4.7.1.dev.032" because DBs shouldn't change on nano version changes
840
+			$version_parts_current_db_state = array_slice(explode('.', $current_database_state[ $slug ]), 0, 3);
841
+			$version_parts_of_provided_db_state = array_slice(explode('.', $version), 0, 3);
842
+			$needs_updating = false;
843
+			foreach ($version_parts_current_db_state as $offset => $version_part_in_current_db_state) {
844
+				if ($version_part_in_current_db_state < $version_parts_of_provided_db_state[ $offset ]) {
845
+					$needs_updating = true;
846
+					break;
847
+				}
848
+			}
849
+			return $needs_updating;
850
+		}
851
+	}
852
+
853
+
854
+	/**
855
+	 * Gets all the data migration scripts available in the core folder and folders
856
+	 * in addons. Has the side effect of adding them for autoloading
857
+	 *
858
+	 * @return array keys are expected classnames, values are their filepaths
859
+	 * @throws InvalidInterfaceException
860
+	 * @throws InvalidDataTypeException
861
+	 * @throws EE_Error
862
+	 * @throws InvalidArgumentException
863
+	 */
864
+	public function get_all_data_migration_scripts_available()
865
+	{
866
+		if (! $this->_data_migration_class_to_filepath_map) {
867
+			$this->_data_migration_class_to_filepath_map = array();
868
+			foreach ($this->get_data_migration_script_folders() as $eeAddonClass => $folder_path) {
869
+				// strip any placeholders added to classname to make it a unique array key
870
+				$eeAddonClass = trim($eeAddonClass, '*');
871
+				$eeAddonClass = $eeAddonClass === 'Core' || class_exists($eeAddonClass)
872
+					? $eeAddonClass
873
+					: '';
874
+				$folder_path = EEH_File::end_with_directory_separator($folder_path);
875
+				$files = glob($folder_path . '*.dms.php');
876
+				if (empty($files)) {
877
+					continue;
878
+				}
879
+				foreach ($files as $file) {
880
+					$pos_of_last_slash = strrpos($file, DS);
881
+					$classname = str_replace('.dms.php', '', substr($file, $pos_of_last_slash + 1));
882
+					$migrates_to = $this->script_migrates_to_version($classname, $eeAddonClass);
883
+					$slug = $migrates_to['slug'];
884
+					// check that the slug as contained in the DMS is associated with
885
+					// the slug of an addon or core
886
+					if ($slug !== 'Core' && EE_Registry::instance()->get_addon_by_name($slug) === null) {
887
+						EE_Error::doing_it_wrong(
888
+							__FUNCTION__,
889
+							sprintf(
890
+								esc_html__(
891
+									'The data migration script "%s" migrates the "%s" data, but there is no EE addon with that name. There is only: %s. ',
892
+									'event_espresso'
893
+								),
894
+								$classname,
895
+								$slug,
896
+								implode(', ', array_keys(EE_Registry::instance()->get_addons_by_name()))
897
+							),
898
+							'4.3.0.alpha.019'
899
+						);
900
+					}
901
+					$this->_data_migration_class_to_filepath_map[ $classname ] = $file;
902
+				}
903
+			}
904
+			EEH_Autoloader::register_autoloader($this->_data_migration_class_to_filepath_map);
905
+		}
906
+		return $this->_data_migration_class_to_filepath_map;
907
+	}
908
+
909
+
910
+	/**
911
+	 * Once we have an addon that works with EE4.1, we will actually want to fetch the PUE slugs
912
+	 * from each addon, and check if they need updating,
913
+	 *
914
+	 * @return boolean
915
+	 */
916
+	public function addons_need_updating()
917
+	{
918
+		return false;
919
+	}
920
+
921
+	/**
922
+	 * Adds this error string to the data_migrations_ran array, but we dont necessarily know
923
+	 * where to put it, so we just throw it in there... better than nothing...
924
+	 *
925
+	 * @param string $error_message
926
+	 * @throws EE_Error
927
+	 */
928
+	public function add_error_to_migrations_ran($error_message)
929
+	{
930
+		// get last-ran migration script
931
+		global $wpdb;
932
+		$last_migration_script_option = $wpdb->get_row(
933
+			"SELECT * FROM $wpdb->options WHERE option_name like '" . EE_Data_Migration_Manager::data_migration_script_option_prefix . "%' ORDER BY option_id DESC LIMIT 1",
934
+			ARRAY_A
935
+		);
936
+
937
+		$last_ran_migration_script_properties = isset($last_migration_script_option['option_value'])
938
+			? maybe_unserialize($last_migration_script_option['option_value']) : null;
939
+		// now, tread lightly because we're here because a FATAL non-catchable error
940
+		// was thrown last time when we were trying to run a data migration script
941
+		// so the fatal error could have happened while getting the migration script
942
+		// or doing running it...
943
+		$versions_migrated_to = isset($last_migration_script_option['option_name']) ? str_replace(
944
+			EE_Data_Migration_Manager::data_migration_script_option_prefix,
945
+			"",
946
+			$last_migration_script_option['option_name']
947
+		) : null;
948
+
949
+		// check if it THINKS its a data migration script and especially if it's one that HASN'T finished yet
950
+		// because if it has finished, then it obviously couldn't be the cause of this error, right? (because its all done)
951
+		if (isset($last_ran_migration_script_properties['class']) && isset($last_ran_migration_script_properties['_status']) && $last_ran_migration_script_properties['_status'] != self::status_completed) {
952
+			// ok then just add this error to its list of errors
953
+			$last_ran_migration_script_properties['_errors'][] = $error_message;
954
+			$last_ran_migration_script_properties['_status'] = self::status_fatal_error;
955
+		} else {
956
+			// so we don't even know which script was last running
957
+			// use the data migration error stub, which is designed specifically for this type of thing
958
+			$general_migration_error = new EE_DMS_Unknown_1_0_0();
959
+			$general_migration_error->add_error($error_message);
960
+			$general_migration_error->set_broken();
961
+			$last_ran_migration_script_properties = $general_migration_error->properties_as_array();
962
+			$versions_migrated_to = 'Unknown.1.0.0';
963
+			// now just to make sure appears as last (in case the were previously a fatal error like this)
964
+			// delete the old one
965
+			delete_option(self::data_migration_script_option_prefix . $versions_migrated_to);
966
+		}
967
+		update_option(
968
+			self::data_migration_script_option_prefix . $versions_migrated_to,
969
+			$last_ran_migration_script_properties
970
+		);
971
+	}
972
+
973
+	/**
974
+	 * saves what data migrations have ran to the database
975
+	 *
976
+	 * @return mixed TRUE if successfully saved migrations ran, string if an error occurred
977
+	 */
978
+	protected function _save_migrations_ran()
979
+	{
980
+		if ($this->_data_migrations_ran == null) {
981
+			$this->get_data_migrations_ran();
982
+		}
983
+		// now, we don't want to save actual classes to the DB because that's messy
984
+		$successful_updates = true;
985
+		foreach ($this->_data_migrations_ran as $plugin_slug => $migrations_ran_for_plugin) {
986
+			foreach ($migrations_ran_for_plugin as $version_string => $array_or_migration_obj) {
987
+				$plugin_slug_for_use_in_option_name = $plugin_slug . ".";
988
+				$option_name = self::data_migration_script_option_prefix . $plugin_slug_for_use_in_option_name . $version_string;
989
+				$old_option_value = get_option($option_name);
990
+				if ($array_or_migration_obj instanceof EE_Data_Migration_Script_Base) {
991
+					$script_array_for_saving = $array_or_migration_obj->properties_as_array();
992
+					if ($old_option_value != $script_array_for_saving) {
993
+						$successful_updates = update_option($option_name, $script_array_for_saving);
994
+					}
995
+				} else {// we don't know what this array-thing is. So just save it as-is
996
+					if ($old_option_value != $array_or_migration_obj) {
997
+						$successful_updates = update_option($option_name, $array_or_migration_obj);
998
+					}
999
+				}
1000
+				if (! $successful_updates) {
1001
+					global $wpdb;
1002
+					return $wpdb->last_error;
1003
+				}
1004
+			}
1005
+		}
1006
+		return true;
1007
+		// $updated = update_option(self::data_migrations_option_name, $array_of_migrations);
1008
+		// if ($updated !== true) {
1009
+		//     global $wpdb;
1010
+		//     return $wpdb->last_error;
1011
+		// } else {
1012
+		//     return true;
1013
+		// }
1014
+		// wp_mail(
1015
+		//     "[email protected]",
1016
+		//     time() . " price debug info",
1017
+		//     "updated: $updated, last error: $last_error, byte length of option: " . strlen(
1018
+		//         serialize($array_of_migrations)
1019
+		//     )
1020
+		// );
1021
+	}
1022
+
1023
+	/**
1024
+	 * Takes an array of data migration script properties and re-creates the class from
1025
+	 * them. The argument $properties_array is assumed to have been made by
1026
+	 * EE_Data_Migration_Script_Base::properties_as_array()
1027
+	 *
1028
+	 * @param array $properties_array
1029
+	 * @return EE_Data_Migration_Script_Base
1030
+	 * @throws EE_Error
1031
+	 */
1032
+	public function _instantiate_script_from_properties_array($properties_array)
1033
+	{
1034
+		if (! isset($properties_array['class'])) {
1035
+			throw new EE_Error(
1036
+				sprintf(
1037
+					__("Properties array  has no 'class' properties. Here's what it has: %s", "event_espresso"),
1038
+					implode(",", $properties_array)
1039
+				)
1040
+			);
1041
+		}
1042
+		$class_name = $properties_array['class'];
1043
+		if (! class_exists($class_name)) {
1044
+			throw new EE_Error(sprintf(__("There is no migration script named %s", "event_espresso"), $class_name));
1045
+		}
1046
+		$class = new $class_name;
1047
+		if (! $class instanceof EE_Data_Migration_Script_Base) {
1048
+			throw new EE_Error(
1049
+				sprintf(
1050
+					__("Class '%s' is supposed to be a migration script. Its not, its a '%s'", "event_espresso"),
1051
+					$class_name,
1052
+					get_class($class)
1053
+				)
1054
+			);
1055
+		}
1056
+		$class->instantiate_from_array_of_properties($properties_array);
1057
+		return $class;
1058
+	}
1059
+
1060
+	/**
1061
+	 * Gets the classname for the most up-to-date DMS (ie, the one that will finally
1062
+	 * leave the DB in a state usable by the current plugin code).
1063
+	 *
1064
+	 * @param string $plugin_slug the slug for the ee plugin we are searching for. Default is 'Core'
1065
+	 * @return string
1066
+	 */
1067
+	public function get_most_up_to_date_dms($plugin_slug = 'Core')
1068
+	{
1069
+		$class_to_filepath_map = $this->get_all_data_migration_scripts_available();
1070
+		$most_up_to_date_dms_classname = null;
1071
+		foreach ($class_to_filepath_map as $classname => $filepath) {
1072
+			if ($most_up_to_date_dms_classname === null) {
1073
+				$migrates_to = $this->script_migrates_to_version($classname);
1074
+				$this_plugin_slug = $migrates_to['slug'];
1075
+				if ($this_plugin_slug == $plugin_slug) {
1076
+					// if it's for core, it wins
1077
+					$most_up_to_date_dms_classname = $classname;
1078
+				}
1079
+				// if it wasn't for core, we must keep searching for one that is!
1080
+				continue;
1081
+			} else {
1082
+				$champion_migrates_to = $this->script_migrates_to_version($most_up_to_date_dms_classname);
1083
+				$contender_migrates_to = $this->script_migrates_to_version($classname);
1084
+				if ($contender_migrates_to['slug'] == $plugin_slug
1085
+					&& version_compare(
1086
+						$champion_migrates_to['version'],
1087
+						$contender_migrates_to['version'],
1088
+						'<'
1089
+					)) {
1090
+					// so the contenders version is higher and its for Core
1091
+					$most_up_to_date_dms_classname = $classname;
1092
+				}
1093
+			}
1094
+		}
1095
+		return $most_up_to_date_dms_classname;
1096
+	}
1097
+
1098
+	/**
1099
+	 * Gets the migration script specified but ONLY if it has already ran.
1100
+	 *
1101
+	 * Eg, if you wanted to see if 'EE_DMS_Core_4_1_0' has ran, you would run the following code:
1102
+	 * <code> $core_4_1_0_dms_ran = EE_Data_Migration_Manager::instance()->get_migration_ran( '4.1.0', 'Core' ) !==
1103
+	 * NULL;</code> This is especially useful in addons' data migration scripts, this way they can tell if a core (or
1104
+	 * other addon) DMS has ran, in case the current DMS depends on it.
1105
+	 *
1106
+	 * @param string $version     the version the DMS searched for migrates to. Usually just the content before the 3rd
1107
+	 *                            period. Eg '4.1.0'
1108
+	 * @param string $plugin_slug like 'Core', 'Mailchimp', 'Calendar', etc
1109
+	 * @return EE_Data_Migration_Script_Base
1110
+	 */
1111
+	public function get_migration_ran($version, $plugin_slug = 'Core')
1112
+	{
1113
+		$migrations_ran = $this->get_data_migrations_ran();
1114
+		if (isset($migrations_ran[ $plugin_slug ]) && isset($migrations_ran[ $plugin_slug ][ $version ])) {
1115
+			return $migrations_ran[ $plugin_slug ][ $version ];
1116
+		} else {
1117
+			return null;
1118
+		}
1119
+	}
1120
+
1121
+	/**
1122
+	 * Resets the borked data migration scripts so they're no longer borked
1123
+	 * so we can again attempt to migrate
1124
+	 *
1125
+	 * @return bool
1126
+	 * @throws EE_Error
1127
+	 */
1128
+	public function reattempt()
1129
+	{
1130
+		// find if the last-ran script was borked
1131
+		// set it as being non-borked (we shouldn't ever get DMSs that we don't recognize)
1132
+		// add an 'error' saying that we attempted to reset
1133
+		// does it have a stage that was borked too? if so make it no longer borked
1134
+		// add an 'error' saying we attempted to reset
1135
+		$last_ran_script = $this->get_last_ran_script();
1136
+		if ($last_ran_script instanceof EE_DMS_Unknown_1_0_0) {
1137
+			// if it was an error DMS, just mark it as complete (if another error occurs it will overwrite it)
1138
+			$last_ran_script->set_completed();
1139
+		} elseif ($last_ran_script instanceof EE_Data_Migration_Script_Base) {
1140
+			$last_ran_script->reattempt();
1141
+		} else {
1142
+			throw new EE_Error(
1143
+				sprintf(
1144
+					__(
1145
+						'Unable to reattempt the last ran migration script because it was not a valid migration script. || It was %s',
1146
+						'event_espresso'
1147
+					),
1148
+					print_r($last_ran_script, true)
1149
+				)
1150
+			);
1151
+		}
1152
+		return $this->_save_migrations_ran();
1153
+	}
1154
+
1155
+	/**
1156
+	 * Gets whether or not this particular migration has run or not
1157
+	 *
1158
+	 * @param string $version     the version the DMS searched for migrates to. Usually just the content before the 3rd
1159
+	 *                            period. Eg '4.1.0'
1160
+	 * @param string $plugin_slug like 'Core', 'Mailchimp', 'Calendar', etc
1161
+	 * @return boolean
1162
+	 */
1163
+	public function migration_has_ran($version, $plugin_slug = 'Core')
1164
+	{
1165
+		return $this->get_migration_ran($version, $plugin_slug) !== null;
1166
+	}
1167
+
1168
+	/**
1169
+	 * Enqueues this ee plugin to have its data initialized
1170
+	 *
1171
+	 * @param string $plugin_slug either 'Core' or EE_Addon::name()'s return value
1172
+	 */
1173
+	public function enqueue_db_initialization_for($plugin_slug)
1174
+	{
1175
+		$queue = $this->get_db_initialization_queue();
1176
+		if (! in_array($plugin_slug, $queue)) {
1177
+			$queue[] = $plugin_slug;
1178
+		}
1179
+		update_option(self::db_init_queue_option_name, $queue);
1180
+	}
1181
+
1182
+	/**
1183
+	 * Calls EE_Addon::initialize_db_if_no_migrations_required() on each addon
1184
+	 * specified in EE_Data_Migration_Manager::get_db_init_queue(), and if 'Core' is
1185
+	 * in the queue, calls EE_System::initialize_db_if_no_migrations_required().
1186
+	 */
1187
+	public function initialize_db_for_enqueued_ee_plugins()
1188
+	{
1189
+		$queue = $this->get_db_initialization_queue();
1190
+		foreach ($queue as $plugin_slug) {
1191
+			$most_up_to_date_dms = $this->get_most_up_to_date_dms($plugin_slug);
1192
+			if (! $most_up_to_date_dms) {
1193
+				// if there is NO DMS for this plugin, obviously there's no schema to verify anyways
1194
+				$verify_db = false;
1195
+			} else {
1196
+				$most_up_to_date_dms_migrates_to = $this->script_migrates_to_version($most_up_to_date_dms);
1197
+				$verify_db = $this->database_needs_updating_to($most_up_to_date_dms_migrates_to);
1198
+			}
1199
+			if ($plugin_slug == 'Core') {
1200
+				EE_System::instance()->initialize_db_if_no_migrations_required(
1201
+					false,
1202
+					$verify_db
1203
+				);
1204
+			} else {
1205
+				// just loop through the addons to make sure their database is setup
1206
+				foreach (EE_Registry::instance()->addons as $addon) {
1207
+					if ($addon->name() == $plugin_slug) {
1208
+						$addon->initialize_db_if_no_migrations_required($verify_db);
1209
+						break;
1210
+					}
1211
+				}
1212
+			}
1213
+		}
1214
+		// because we just initialized the DBs for the enqueued ee plugins
1215
+		// we don't need to keep remembering which ones needed to be initialized
1216
+		delete_option(self::db_init_queue_option_name);
1217
+	}
1218
+
1219
+	/**
1220
+	 * Gets a numerically-indexed array of plugin slugs that need to have their databases
1221
+	 * (re-)initialized after migrations are complete. ie, each element should be either
1222
+	 * 'Core', or the return value of EE_Addon::name() for an addon
1223
+	 *
1224
+	 * @return array
1225
+	 */
1226
+	public function get_db_initialization_queue()
1227
+	{
1228
+		return get_option(self::db_init_queue_option_name, array());
1229
+	}
1230
+
1231
+	/**
1232
+	 * Gets the injected table analyzer, or throws an exception
1233
+	 *
1234
+	 * @return TableAnalysis
1235
+	 * @throws EE_Error
1236
+	 */
1237
+	protected function _get_table_analysis()
1238
+	{
1239
+		if ($this->_table_analysis instanceof TableAnalysis) {
1240
+			return $this->_table_analysis;
1241
+		} else {
1242
+			throw new EE_Error(
1243
+				sprintf(
1244
+					__('Table analysis class on class %1$s is not set properly.', 'event_espresso'),
1245
+					get_class($this)
1246
+				)
1247
+			);
1248
+		}
1249
+	}
1250
+
1251
+	/**
1252
+	 * Gets the injected table manager, or throws an exception
1253
+	 *
1254
+	 * @return TableManager
1255
+	 * @throws EE_Error
1256
+	 */
1257
+	protected function _get_table_manager()
1258
+	{
1259
+		if ($this->_table_manager instanceof TableManager) {
1260
+			return $this->_table_manager;
1261
+		} else {
1262
+			throw new EE_Error(
1263
+				sprintf(
1264
+					__('Table manager class on class %1$s is not set properly.', 'event_espresso'),
1265
+					get_class($this)
1266
+				)
1267
+			);
1268
+		}
1269
+	}
1270 1270
 }
Please login to merge, or discard this patch.
Spacing   +61 added lines, -61 removed lines patch added patch discarded remove patch
@@ -158,7 +158,7 @@  discard block
 block discarded – undo
158 158
     public static function instance()
159 159
     {
160 160
         // check if class object is instantiated
161
-        if (! self::$_instance instanceof EE_Data_Migration_Manager) {
161
+        if ( ! self::$_instance instanceof EE_Data_Migration_Manager) {
162 162
             self::$_instance = new self();
163 163
         }
164 164
         return self::$_instance;
@@ -234,12 +234,12 @@  discard block
 block discarded – undo
234 234
 
235 235
         if (count($parts) == 4) {
236 236
             // it's 4.2-style.eg Core.4.1.0
237
-            $plugin_slug = $parts[0];// eg Core
238
-            $version_string = $parts[1] . "." . $parts[2] . "." . $parts[3]; // eg 4.1.0
237
+            $plugin_slug = $parts[0]; // eg Core
238
+            $version_string = $parts[1].".".$parts[2].".".$parts[3]; // eg 4.1.0
239 239
         } else {
240 240
             // it's 4.1-style: eg 4.1.0
241 241
             $plugin_slug = 'Core';
242
-            $version_string = $plugin_slug_and_version_string;// eg 4.1.0
242
+            $version_string = $plugin_slug_and_version_string; // eg 4.1.0
243 243
         }
244 244
         return array($plugin_slug, $version_string);
245 245
     }
@@ -291,11 +291,11 @@  discard block
 block discarded – undo
291 291
      */
292 292
     public function get_data_migrations_ran()
293 293
     {
294
-        if (! $this->_data_migrations_ran) {
294
+        if ( ! $this->_data_migrations_ran) {
295 295
             // setup autoloaders for each of the scripts in there
296 296
             $this->get_all_data_migration_scripts_available();
297 297
             $data_migrations_options = $this->get_all_migration_script_options(
298
-            );// get_option(EE_Data_Migration_Manager::data_migrations_option_name,get_option('espresso_data_migrations',array()));
298
+            ); // get_option(EE_Data_Migration_Manager::data_migrations_option_name,get_option('espresso_data_migrations',array()));
299 299
 
300 300
             $data_migrations_ran = array();
301 301
             // convert into data migration script classes where possible
@@ -309,23 +309,23 @@  discard block
 block discarded – undo
309 309
                         $data_migration_option['option_name'],
310 310
                         $data_migration_option['option_value']
311 311
                     );
312
-                    $data_migrations_ran[ $plugin_slug ][ $version_string ] = $class;
312
+                    $data_migrations_ran[$plugin_slug][$version_string] = $class;
313 313
                     // ok so far THIS is the 'last-ran-script'... unless we find another on next iteration
314 314
                     $this->_last_ran_script = $class;
315
-                    if (! $class->is_completed()) {
315
+                    if ( ! $class->is_completed()) {
316 316
                         // sometimes we also like to know which was the last incomplete script (or if there are any at all)
317 317
                         $this->_last_ran_incomplete_script = $class;
318 318
                     }
319 319
                 } catch (EE_Error $e) {
320 320
                     // ok so its not a DMS. We'll just keep it, although other code will need to expect non-DMSs
321
-                    $data_migrations_ran[ $plugin_slug ][ $version_string ] = maybe_unserialize(
321
+                    $data_migrations_ran[$plugin_slug][$version_string] = maybe_unserialize(
322 322
                         $data_migration_option['option_value']
323 323
                     );
324 324
                 }
325 325
             }
326 326
             // so here the array of $data_migrations_ran is actually a mix of classes and a few legacy arrays
327 327
             $this->_data_migrations_ran = $data_migrations_ran;
328
-            if (! $this->_data_migrations_ran || ! is_array($this->_data_migrations_ran)) {
328
+            if ( ! $this->_data_migrations_ran || ! is_array($this->_data_migrations_ran)) {
329 329
                 $this->_data_migrations_ran = array();
330 330
             }
331 331
         }
@@ -358,7 +358,7 @@  discard block
 block discarded – undo
358 358
     {
359 359
         global $wpdb;
360 360
         return $wpdb->get_results(
361
-            "SELECT * FROM {$wpdb->options} WHERE option_name like '" . EE_Data_Migration_Manager::data_migration_script_option_prefix . "%' ORDER BY option_id ASC",
361
+            "SELECT * FROM {$wpdb->options} WHERE option_name like '".EE_Data_Migration_Manager::data_migration_script_option_prefix."%' ORDER BY option_id ASC",
362 362
             ARRAY_A
363 363
         );
364 364
     }
@@ -373,7 +373,7 @@  discard block
 block discarded – undo
373 373
     {
374 374
         return apply_filters(
375 375
             'FHEE__EE_Data_Migration_Manager__get_data_migration_script_folders',
376
-            array('Core' => EE_CORE . 'data_migration_scripts')
376
+            array('Core' => EE_CORE.'data_migration_scripts')
377 377
         );
378 378
     }
379 379
 
@@ -389,15 +389,15 @@  discard block
 block discarded – undo
389 389
      */
390 390
     public function script_migrates_to_version($migration_script_name, $eeAddonClass = '')
391 391
     {
392
-        if (isset($this->script_migration_versions[ $migration_script_name ])) {
393
-            return $this->script_migration_versions[ $migration_script_name ];
392
+        if (isset($this->script_migration_versions[$migration_script_name])) {
393
+            return $this->script_migration_versions[$migration_script_name];
394 394
         }
395 395
         $dms_info = $this->parse_dms_classname($migration_script_name);
396
-        $this->script_migration_versions[ $migration_script_name ] = array(
396
+        $this->script_migration_versions[$migration_script_name] = array(
397 397
             'slug'    => $eeAddonClass !== '' ? $eeAddonClass : $dms_info['slug'],
398
-            'version' => $dms_info['major_version'] . "." . $dms_info['minor_version'] . "." . $dms_info['micro_version'],
398
+            'version' => $dms_info['major_version'].".".$dms_info['minor_version'].".".$dms_info['micro_version'],
399 399
         );
400
-        return $this->script_migration_versions[ $migration_script_name ];
400
+        return $this->script_migration_versions[$migration_script_name];
401 401
     }
402 402
 
403 403
     /**
@@ -411,7 +411,7 @@  discard block
 block discarded – undo
411 411
     {
412 412
         $matches = array();
413 413
         preg_match('~EE_DMS_(.*)_([0-9]*)_([0-9]*)_([0-9]*)~', $classname, $matches);
414
-        if (! $matches || ! (isset($matches[1]) && isset($matches[2]) && isset($matches[3]))) {
414
+        if ( ! $matches || ! (isset($matches[1]) && isset($matches[2]) && isset($matches[3]))) {
415 415
             throw new EE_Error(
416 416
                 sprintf(
417 417
                     __(
@@ -442,7 +442,7 @@  discard block
 block discarded – undo
442 442
     {
443 443
         $espresso_db_core_updates = get_option('espresso_db_update', array());
444 444
         $db_state = get_option(EE_Data_Migration_Manager::current_database_state);
445
-        if (! $db_state) {
445
+        if ( ! $db_state) {
446 446
             // mark the DB as being in the state as the last version in there.
447 447
             // this is done to trigger maintenance mode and do data migration scripts
448 448
             // if the admin installed this version of EE over 3.1.x or 4.0.x
@@ -461,7 +461,7 @@  discard block
 block discarded – undo
461 461
         // in 4.1, $db_state would have only been a simple string like '4.1.0',
462 462
         // but in 4.2+ it should be an array with at least key 'Core' and the value of that plugin's
463 463
         // db, and possibly other keys for other addons like 'Calendar','Permissions',etc
464
-        if (! is_array($db_state)) {
464
+        if ( ! is_array($db_state)) {
465 465
             $db_state = array('Core' => $db_state);
466 466
             update_option(EE_Data_Migration_Manager::current_database_state, $db_state);
467 467
         }
@@ -498,29 +498,29 @@  discard block
 block discarded – undo
498 498
                 $script_converts_plugin_slug = $migrates_to_version['slug'];
499 499
                 $script_converts_to_version = $migrates_to_version['version'];
500 500
                 // check if this version script is DONE or not; or if it's never been ran
501
-                if (! $scripts_ran ||
502
-                    ! isset($scripts_ran[ $script_converts_plugin_slug ]) ||
503
-                    ! isset($scripts_ran[ $script_converts_plugin_slug ][ $script_converts_to_version ])) {
501
+                if ( ! $scripts_ran ||
502
+                    ! isset($scripts_ran[$script_converts_plugin_slug]) ||
503
+                    ! isset($scripts_ran[$script_converts_plugin_slug][$script_converts_to_version])) {
504 504
                     // we haven't ran this conversion script before
505 505
                     // now check if it applies... note that we've added an autoloader for it on get_all_data_migration_scripts_available
506 506
                     $script = LoaderFactory::getLoader()->load($classname);
507 507
                     /* @var $script EE_Data_Migration_Script_Base */
508 508
                     $can_migrate = $script->can_migrate_from_version($theoretical_database_state);
509 509
                     if ($can_migrate) {
510
-                        $script_classes_that_should_run_per_iteration[ $iteration ][ $script->priority() ][] = $script;
510
+                        $script_classes_that_should_run_per_iteration[$iteration][$script->priority()][] = $script;
511 511
                         $migrates_to_version = $script->migrates_to_version();
512
-                        $next_database_state_to_consider[ $migrates_to_version['slug'] ] = $migrates_to_version['version'];
513
-                        unset($script_class_and_filepaths_available[ $classname ]);
512
+                        $next_database_state_to_consider[$migrates_to_version['slug']] = $migrates_to_version['version'];
513
+                        unset($script_class_and_filepaths_available[$classname]);
514 514
                     }
515
-                } elseif ($scripts_ran[ $script_converts_plugin_slug ][ $script_converts_to_version ] instanceof EE_Data_Migration_Script_Base) {
515
+                } elseif ($scripts_ran[$script_converts_plugin_slug][$script_converts_to_version] instanceof EE_Data_Migration_Script_Base) {
516 516
                     // this script has been ran, or at least started
517
-                    $script = $scripts_ran[ $script_converts_plugin_slug ][ $script_converts_to_version ];
517
+                    $script = $scripts_ran[$script_converts_plugin_slug][$script_converts_to_version];
518 518
                     if ($script->get_status() != self::status_completed) {
519 519
                         // this script is already underway... keep going with it
520
-                        $script_classes_that_should_run_per_iteration[ $iteration ][ $script->priority() ][] = $script;
520
+                        $script_classes_that_should_run_per_iteration[$iteration][$script->priority()][] = $script;
521 521
                         $migrates_to_version = $script->migrates_to_version();
522
-                        $next_database_state_to_consider[ $migrates_to_version['slug'] ] = $migrates_to_version['version'];
523
-                        unset($script_class_and_filepaths_available[ $classname ]);
522
+                        $next_database_state_to_consider[$migrates_to_version['slug']] = $migrates_to_version['version'];
523
+                        unset($script_class_and_filepaths_available[$classname]);
524 524
                     } else {
525 525
                         // it must have a status that indicates it has finished, so we don't want to try and run it again
526 526
                     }
@@ -531,14 +531,14 @@  discard block
 block discarded – undo
531 531
                 }
532 532
             }
533 533
             $iteration++;
534
-        } while ($next_database_state_to_consider != $theoretical_database_state && $iteration < 6);
534
+        }while ($next_database_state_to_consider != $theoretical_database_state && $iteration < 6);
535 535
         // ok we have all the scripts that should run, now let's make them into flat array
536 536
         $scripts_that_should_run = array();
537 537
         foreach ($script_classes_that_should_run_per_iteration as $scripts_at_priority) {
538 538
             ksort($scripts_at_priority);
539 539
             foreach ($scripts_at_priority as $scripts) {
540 540
                 foreach ($scripts as $script) {
541
-                    $scripts_that_should_run[ get_class($script) ] = $script;
541
+                    $scripts_that_should_run[get_class($script)] = $script;
542 542
                 }
543 543
             }
544 544
         }
@@ -563,7 +563,7 @@  discard block
 block discarded – undo
563 563
     public function get_last_ran_script($include_completed_scripts = false)
564 564
     {
565 565
         // make sure we've setup the class properties _last_ran_script and _last_ran_incomplete_script
566
-        if (! $this->_data_migrations_ran) {
566
+        if ( ! $this->_data_migrations_ran) {
567 567
             $this->get_data_migrations_ran();
568 568
         }
569 569
         if ($include_completed_scripts) {
@@ -600,10 +600,10 @@  discard block
 block discarded – undo
600 600
 
601 601
         try {
602 602
             $currently_executing_script = $this->get_last_ran_script();
603
-            if (! $currently_executing_script) {
603
+            if ( ! $currently_executing_script) {
604 604
                 // Find the next script that needs to execute
605 605
                 $scripts = $this->check_for_applicable_data_migration_scripts();
606
-                if (! $scripts) {
606
+                if ( ! $scripts) {
607 607
                     // huh, no more scripts to run... apparently we're done!
608 608
                     // but dont forget to make sure initial data is there
609 609
                     // we should be good to allow them to exit maintenance mode now
@@ -629,7 +629,7 @@  discard block
 block discarded – undo
629 629
                 $migrates_to = $this->script_migrates_to_version(get_class($currently_executing_script));
630 630
                 $plugin_slug = $migrates_to['slug'];
631 631
                 $version = $migrates_to['version'];
632
-                $this->_data_migrations_ran[ $plugin_slug ][ $version ] = $currently_executing_script;
632
+                $this->_data_migrations_ran[$plugin_slug][$version] = $currently_executing_script;
633 633
             }
634 634
             $current_script_name = get_class($currently_executing_script);
635 635
         } catch (Exception $e) {
@@ -637,7 +637,7 @@  discard block
 block discarded – undo
637 637
 
638 638
             $message = sprintf(
639 639
                 __("Error Message: %sStack Trace:%s", "event_espresso"),
640
-                $e->getMessage() . '<br>',
640
+                $e->getMessage().'<br>',
641 641
                 $e->getTraceAsString()
642 642
             );
643 643
             // record it on the array of data migration scripts ran. This will be overwritten next time we try and try to run data migrations
@@ -689,7 +689,7 @@  discard block
 block discarded – undo
689 689
                     );
690 690
                     // check if there are any more after this one.
691 691
                     $scripts_remaining = $this->check_for_applicable_data_migration_scripts();
692
-                    if (! $scripts_remaining) {
692
+                    if ( ! $scripts_remaining) {
693 693
                         // we should be good to allow them to exit maintenance mode now
694 694
                         EE_Maintenance_Mode::instance()->set_maintenance_level(
695 695
                             intval(EE_Maintenance_Mode::level_0_not_in_maintenance)
@@ -789,7 +789,7 @@  discard block
 block discarded – undo
789 789
                 ),
790 790
                 'script'             => 'Unknown',
791 791
             );
792
-            $this->add_error_to_migrations_ran($e->getMessage() . "; Stack trace:" . $e->getTraceAsString());
792
+            $this->add_error_to_migrations_ran($e->getMessage()."; Stack trace:".$e->getTraceAsString());
793 793
         }
794 794
         $warnings_etc = @ob_get_contents();
795 795
         ob_end_clean();
@@ -809,12 +809,12 @@  discard block
 block discarded – undo
809 809
      */
810 810
     public function update_current_database_state_to($slug_and_version = null)
811 811
     {
812
-        if (! $slug_and_version) {
812
+        if ( ! $slug_and_version) {
813 813
             // no version was provided, assume it should be at the current code version
814 814
             $slug_and_version = array('slug' => 'Core', 'version' => espresso_version());
815 815
         }
816 816
         $current_database_state = get_option(self::current_database_state);
817
-        $current_database_state[ $slug_and_version['slug'] ] = $slug_and_version['version'];
817
+        $current_database_state[$slug_and_version['slug']] = $slug_and_version['version'];
818 818
         update_option(self::current_database_state, $current_database_state);
819 819
     }
820 820
 
@@ -833,15 +833,15 @@  discard block
 block discarded – undo
833 833
         $slug = $slug_and_version['slug'];
834 834
         $version = $slug_and_version['version'];
835 835
         $current_database_state = get_option(self::current_database_state);
836
-        if (! isset($current_database_state[ $slug ])) {
836
+        if ( ! isset($current_database_state[$slug])) {
837 837
             return true;
838 838
         } else {
839 839
             // just compare the first 3 parts of version string, eg "4.7.1", not "4.7.1.dev.032" because DBs shouldn't change on nano version changes
840
-            $version_parts_current_db_state = array_slice(explode('.', $current_database_state[ $slug ]), 0, 3);
840
+            $version_parts_current_db_state = array_slice(explode('.', $current_database_state[$slug]), 0, 3);
841 841
             $version_parts_of_provided_db_state = array_slice(explode('.', $version), 0, 3);
842 842
             $needs_updating = false;
843 843
             foreach ($version_parts_current_db_state as $offset => $version_part_in_current_db_state) {
844
-                if ($version_part_in_current_db_state < $version_parts_of_provided_db_state[ $offset ]) {
844
+                if ($version_part_in_current_db_state < $version_parts_of_provided_db_state[$offset]) {
845 845
                     $needs_updating = true;
846 846
                     break;
847 847
                 }
@@ -863,7 +863,7 @@  discard block
 block discarded – undo
863 863
      */
864 864
     public function get_all_data_migration_scripts_available()
865 865
     {
866
-        if (! $this->_data_migration_class_to_filepath_map) {
866
+        if ( ! $this->_data_migration_class_to_filepath_map) {
867 867
             $this->_data_migration_class_to_filepath_map = array();
868 868
             foreach ($this->get_data_migration_script_folders() as $eeAddonClass => $folder_path) {
869 869
                 // strip any placeholders added to classname to make it a unique array key
@@ -872,7 +872,7 @@  discard block
 block discarded – undo
872 872
                     ? $eeAddonClass
873 873
                     : '';
874 874
                 $folder_path = EEH_File::end_with_directory_separator($folder_path);
875
-                $files = glob($folder_path . '*.dms.php');
875
+                $files = glob($folder_path.'*.dms.php');
876 876
                 if (empty($files)) {
877 877
                     continue;
878 878
                 }
@@ -898,7 +898,7 @@  discard block
 block discarded – undo
898 898
                             '4.3.0.alpha.019'
899 899
                         );
900 900
                     }
901
-                    $this->_data_migration_class_to_filepath_map[ $classname ] = $file;
901
+                    $this->_data_migration_class_to_filepath_map[$classname] = $file;
902 902
                 }
903 903
             }
904 904
             EEH_Autoloader::register_autoloader($this->_data_migration_class_to_filepath_map);
@@ -930,7 +930,7 @@  discard block
 block discarded – undo
930 930
         // get last-ran migration script
931 931
         global $wpdb;
932 932
         $last_migration_script_option = $wpdb->get_row(
933
-            "SELECT * FROM $wpdb->options WHERE option_name like '" . EE_Data_Migration_Manager::data_migration_script_option_prefix . "%' ORDER BY option_id DESC LIMIT 1",
933
+            "SELECT * FROM $wpdb->options WHERE option_name like '".EE_Data_Migration_Manager::data_migration_script_option_prefix."%' ORDER BY option_id DESC LIMIT 1",
934 934
             ARRAY_A
935 935
         );
936 936
 
@@ -962,10 +962,10 @@  discard block
 block discarded – undo
962 962
             $versions_migrated_to = 'Unknown.1.0.0';
963 963
             // now just to make sure appears as last (in case the were previously a fatal error like this)
964 964
             // delete the old one
965
-            delete_option(self::data_migration_script_option_prefix . $versions_migrated_to);
965
+            delete_option(self::data_migration_script_option_prefix.$versions_migrated_to);
966 966
         }
967 967
         update_option(
968
-            self::data_migration_script_option_prefix . $versions_migrated_to,
968
+            self::data_migration_script_option_prefix.$versions_migrated_to,
969 969
             $last_ran_migration_script_properties
970 970
         );
971 971
     }
@@ -984,8 +984,8 @@  discard block
 block discarded – undo
984 984
         $successful_updates = true;
985 985
         foreach ($this->_data_migrations_ran as $plugin_slug => $migrations_ran_for_plugin) {
986 986
             foreach ($migrations_ran_for_plugin as $version_string => $array_or_migration_obj) {
987
-                $plugin_slug_for_use_in_option_name = $plugin_slug . ".";
988
-                $option_name = self::data_migration_script_option_prefix . $plugin_slug_for_use_in_option_name . $version_string;
987
+                $plugin_slug_for_use_in_option_name = $plugin_slug.".";
988
+                $option_name = self::data_migration_script_option_prefix.$plugin_slug_for_use_in_option_name.$version_string;
989 989
                 $old_option_value = get_option($option_name);
990 990
                 if ($array_or_migration_obj instanceof EE_Data_Migration_Script_Base) {
991 991
                     $script_array_for_saving = $array_or_migration_obj->properties_as_array();
@@ -997,7 +997,7 @@  discard block
 block discarded – undo
997 997
                         $successful_updates = update_option($option_name, $array_or_migration_obj);
998 998
                     }
999 999
                 }
1000
-                if (! $successful_updates) {
1000
+                if ( ! $successful_updates) {
1001 1001
                     global $wpdb;
1002 1002
                     return $wpdb->last_error;
1003 1003
                 }
@@ -1031,7 +1031,7 @@  discard block
 block discarded – undo
1031 1031
      */
1032 1032
     public function _instantiate_script_from_properties_array($properties_array)
1033 1033
     {
1034
-        if (! isset($properties_array['class'])) {
1034
+        if ( ! isset($properties_array['class'])) {
1035 1035
             throw new EE_Error(
1036 1036
                 sprintf(
1037 1037
                     __("Properties array  has no 'class' properties. Here's what it has: %s", "event_espresso"),
@@ -1040,11 +1040,11 @@  discard block
 block discarded – undo
1040 1040
             );
1041 1041
         }
1042 1042
         $class_name = $properties_array['class'];
1043
-        if (! class_exists($class_name)) {
1043
+        if ( ! class_exists($class_name)) {
1044 1044
             throw new EE_Error(sprintf(__("There is no migration script named %s", "event_espresso"), $class_name));
1045 1045
         }
1046 1046
         $class = new $class_name;
1047
-        if (! $class instanceof EE_Data_Migration_Script_Base) {
1047
+        if ( ! $class instanceof EE_Data_Migration_Script_Base) {
1048 1048
             throw new EE_Error(
1049 1049
                 sprintf(
1050 1050
                     __("Class '%s' is supposed to be a migration script. Its not, its a '%s'", "event_espresso"),
@@ -1111,8 +1111,8 @@  discard block
 block discarded – undo
1111 1111
     public function get_migration_ran($version, $plugin_slug = 'Core')
1112 1112
     {
1113 1113
         $migrations_ran = $this->get_data_migrations_ran();
1114
-        if (isset($migrations_ran[ $plugin_slug ]) && isset($migrations_ran[ $plugin_slug ][ $version ])) {
1115
-            return $migrations_ran[ $plugin_slug ][ $version ];
1114
+        if (isset($migrations_ran[$plugin_slug]) && isset($migrations_ran[$plugin_slug][$version])) {
1115
+            return $migrations_ran[$plugin_slug][$version];
1116 1116
         } else {
1117 1117
             return null;
1118 1118
         }
@@ -1173,7 +1173,7 @@  discard block
 block discarded – undo
1173 1173
     public function enqueue_db_initialization_for($plugin_slug)
1174 1174
     {
1175 1175
         $queue = $this->get_db_initialization_queue();
1176
-        if (! in_array($plugin_slug, $queue)) {
1176
+        if ( ! in_array($plugin_slug, $queue)) {
1177 1177
             $queue[] = $plugin_slug;
1178 1178
         }
1179 1179
         update_option(self::db_init_queue_option_name, $queue);
@@ -1189,7 +1189,7 @@  discard block
 block discarded – undo
1189 1189
         $queue = $this->get_db_initialization_queue();
1190 1190
         foreach ($queue as $plugin_slug) {
1191 1191
             $most_up_to_date_dms = $this->get_most_up_to_date_dms($plugin_slug);
1192
-            if (! $most_up_to_date_dms) {
1192
+            if ( ! $most_up_to_date_dms) {
1193 1193
                 // if there is NO DMS for this plugin, obviously there's no schema to verify anyways
1194 1194
                 $verify_db = false;
1195 1195
             } else {
Please login to merge, or discard this patch.
core/EE_Dependency_Map.core.php 1 patch
Indentation   +1103 added lines, -1103 removed lines patch added patch discarded remove patch
@@ -20,1107 +20,1107 @@
 block discarded – undo
20 20
 class EE_Dependency_Map
21 21
 {
22 22
 
23
-    /**
24
-     * This means that the requested class dependency is not present in the dependency map
25
-     */
26
-    const not_registered = 0;
27
-
28
-    /**
29
-     * This instructs class loaders to ALWAYS return a newly instantiated object for the requested class.
30
-     */
31
-    const load_new_object = 1;
32
-
33
-    /**
34
-     * This instructs class loaders to return a previously instantiated and cached object for the requested class.
35
-     * IF a previously instantiated object does not exist, a new one will be created and added to the cache.
36
-     */
37
-    const load_from_cache = 2;
38
-
39
-    /**
40
-     * When registering a dependency,
41
-     * this indicates to keep any existing dependencies that already exist,
42
-     * and simply discard any new dependencies declared in the incoming data
43
-     */
44
-    const KEEP_EXISTING_DEPENDENCIES = 0;
45
-
46
-    /**
47
-     * When registering a dependency,
48
-     * this indicates to overwrite any existing dependencies that already exist using the incoming data
49
-     */
50
-    const OVERWRITE_DEPENDENCIES = 1;
51
-
52
-
53
-    /**
54
-     * @type EE_Dependency_Map $_instance
55
-     */
56
-    protected static $_instance;
57
-
58
-    /**
59
-     * @var ClassInterfaceCache $class_cache
60
-     */
61
-    private $class_cache;
62
-
63
-    /**
64
-     * @type RequestInterface $request
65
-     */
66
-    protected $request;
67
-
68
-    /**
69
-     * @type LegacyRequestInterface $legacy_request
70
-     */
71
-    protected $legacy_request;
72
-
73
-    /**
74
-     * @type ResponseInterface $response
75
-     */
76
-    protected $response;
77
-
78
-    /**
79
-     * @type LoaderInterface $loader
80
-     */
81
-    protected $loader;
82
-
83
-    /**
84
-     * @type array $_dependency_map
85
-     */
86
-    protected $_dependency_map = array();
87
-
88
-    /**
89
-     * @type array $_class_loaders
90
-     */
91
-    protected $_class_loaders = array();
92
-
93
-
94
-    /**
95
-     * EE_Dependency_Map constructor.
96
-     *
97
-     * @param ClassInterfaceCache $class_cache
98
-     */
99
-    protected function __construct(ClassInterfaceCache $class_cache)
100
-    {
101
-        $this->class_cache = $class_cache;
102
-        do_action('EE_Dependency_Map____construct', $this);
103
-    }
104
-
105
-
106
-    /**
107
-     * @return void
108
-     */
109
-    public function initialize()
110
-    {
111
-        $this->_register_core_dependencies();
112
-        $this->_register_core_class_loaders();
113
-        $this->_register_core_aliases();
114
-    }
115
-
116
-
117
-    /**
118
-     * @singleton method used to instantiate class object
119
-     * @param ClassInterfaceCache|null $class_cache
120
-     * @return EE_Dependency_Map
121
-     */
122
-    public static function instance(ClassInterfaceCache $class_cache = null)
123
-    {
124
-        // check if class object is instantiated, and instantiated properly
125
-        if (! self::$_instance instanceof EE_Dependency_Map
126
-            && $class_cache instanceof ClassInterfaceCache
127
-        ) {
128
-            self::$_instance = new EE_Dependency_Map($class_cache);
129
-        }
130
-        return self::$_instance;
131
-    }
132
-
133
-
134
-    /**
135
-     * @param RequestInterface $request
136
-     */
137
-    public function setRequest(RequestInterface $request)
138
-    {
139
-        $this->request = $request;
140
-    }
141
-
142
-
143
-    /**
144
-     * @param LegacyRequestInterface $legacy_request
145
-     */
146
-    public function setLegacyRequest(LegacyRequestInterface $legacy_request)
147
-    {
148
-        $this->legacy_request = $legacy_request;
149
-    }
150
-
151
-
152
-    /**
153
-     * @param ResponseInterface $response
154
-     */
155
-    public function setResponse(ResponseInterface $response)
156
-    {
157
-        $this->response = $response;
158
-    }
159
-
160
-
161
-    /**
162
-     * @param LoaderInterface $loader
163
-     */
164
-    public function setLoader(LoaderInterface $loader)
165
-    {
166
-        $this->loader = $loader;
167
-    }
168
-
169
-
170
-    /**
171
-     * @param string $class
172
-     * @param array  $dependencies
173
-     * @param int    $overwrite
174
-     * @return bool
175
-     */
176
-    public static function register_dependencies(
177
-        $class,
178
-        array $dependencies,
179
-        $overwrite = EE_Dependency_Map::KEEP_EXISTING_DEPENDENCIES
180
-    ) {
181
-        return self::$_instance->registerDependencies($class, $dependencies, $overwrite);
182
-    }
183
-
184
-
185
-    /**
186
-     * Assigns an array of class names and corresponding load sources (new or cached)
187
-     * to the class specified by the first parameter.
188
-     * IMPORTANT !!!
189
-     * The order of elements in the incoming $dependencies array MUST match
190
-     * the order of the constructor parameters for the class in question.
191
-     * This is especially important when overriding any existing dependencies that are registered.
192
-     * the third parameter controls whether any duplicate dependencies are overwritten or not.
193
-     *
194
-     * @param string $class
195
-     * @param array  $dependencies
196
-     * @param int    $overwrite
197
-     * @return bool
198
-     */
199
-    public function registerDependencies(
200
-        $class,
201
-        array $dependencies,
202
-        $overwrite = EE_Dependency_Map::KEEP_EXISTING_DEPENDENCIES
203
-    ) {
204
-        $class = trim($class, '\\');
205
-        $registered = false;
206
-        if (empty(self::$_instance->_dependency_map[ $class ])) {
207
-            self::$_instance->_dependency_map[ $class ] = array();
208
-        }
209
-        // we need to make sure that any aliases used when registering a dependency
210
-        // get resolved to the correct class name
211
-        foreach ($dependencies as $dependency => $load_source) {
212
-            $alias = self::$_instance->getFqnForAlias($dependency);
213
-            if ($overwrite === EE_Dependency_Map::OVERWRITE_DEPENDENCIES
214
-                || ! isset(self::$_instance->_dependency_map[ $class ][ $alias ])
215
-            ) {
216
-                unset($dependencies[ $dependency ]);
217
-                $dependencies[ $alias ] = $load_source;
218
-                $registered = true;
219
-            }
220
-        }
221
-        // now add our two lists of dependencies together.
222
-        // using Union (+=) favours the arrays in precedence from left to right,
223
-        // so $dependencies is NOT overwritten because it is listed first
224
-        // ie: with A = B + C, entries in B take precedence over duplicate entries in C
225
-        // Union is way faster than array_merge() but should be used with caution...
226
-        // especially with numerically indexed arrays
227
-        $dependencies += self::$_instance->_dependency_map[ $class ];
228
-        // now we need to ensure that the resulting dependencies
229
-        // array only has the entries that are required for the class
230
-        // so first count how many dependencies were originally registered for the class
231
-        $dependency_count = count(self::$_instance->_dependency_map[ $class ]);
232
-        // if that count is non-zero (meaning dependencies were already registered)
233
-        self::$_instance->_dependency_map[ $class ] = $dependency_count
234
-            // then truncate the  final array to match that count
235
-            ? array_slice($dependencies, 0, $dependency_count)
236
-            // otherwise just take the incoming array because nothing previously existed
237
-            : $dependencies;
238
-        return $registered;
239
-    }
240
-
241
-
242
-    /**
243
-     * @param string $class_name
244
-     * @param string $loader
245
-     * @return bool
246
-     * @throws DomainException
247
-     */
248
-    public static function register_class_loader($class_name, $loader = 'load_core')
249
-    {
250
-        if (! $loader instanceof Closure && strpos($class_name, '\\') !== false) {
251
-            throw new DomainException(
252
-                esc_html__('Don\'t use class loaders for FQCNs.', 'event_espresso')
253
-            );
254
-        }
255
-        // check that loader is callable or method starts with "load_" and exists in EE_Registry
256
-        if (! is_callable($loader)
257
-            && (
258
-                strpos($loader, 'load_') !== 0
259
-                || ! method_exists('EE_Registry', $loader)
260
-            )
261
-        ) {
262
-            throw new DomainException(
263
-                sprintf(
264
-                    esc_html__(
265
-                        '"%1$s" is not a valid loader method on EE_Registry.',
266
-                        'event_espresso'
267
-                    ),
268
-                    $loader
269
-                )
270
-            );
271
-        }
272
-        $class_name = self::$_instance->getFqnForAlias($class_name);
273
-        if (! isset(self::$_instance->_class_loaders[ $class_name ])) {
274
-            self::$_instance->_class_loaders[ $class_name ] = $loader;
275
-            return true;
276
-        }
277
-        return false;
278
-    }
279
-
280
-
281
-    /**
282
-     * @return array
283
-     */
284
-    public function dependency_map()
285
-    {
286
-        return $this->_dependency_map;
287
-    }
288
-
289
-
290
-    /**
291
-     * returns TRUE if dependency map contains a listing for the provided class name
292
-     *
293
-     * @param string $class_name
294
-     * @return boolean
295
-     */
296
-    public function has($class_name = '')
297
-    {
298
-        // all legacy models have the same dependencies
299
-        if (strpos($class_name, 'EEM_') === 0) {
300
-            $class_name = 'LEGACY_MODELS';
301
-        }
302
-        return isset($this->_dependency_map[ $class_name ]) ? true : false;
303
-    }
304
-
305
-
306
-    /**
307
-     * returns TRUE if dependency map contains a listing for the provided class name AND dependency
308
-     *
309
-     * @param string $class_name
310
-     * @param string $dependency
311
-     * @return bool
312
-     */
313
-    public function has_dependency_for_class($class_name = '', $dependency = '')
314
-    {
315
-        // all legacy models have the same dependencies
316
-        if (strpos($class_name, 'EEM_') === 0) {
317
-            $class_name = 'LEGACY_MODELS';
318
-        }
319
-        $dependency = $this->getFqnForAlias($dependency, $class_name);
320
-        return isset($this->_dependency_map[ $class_name ][ $dependency ])
321
-            ? true
322
-            : false;
323
-    }
324
-
325
-
326
-    /**
327
-     * returns loading strategy for whether a previously cached dependency should be loaded or a new instance returned
328
-     *
329
-     * @param string $class_name
330
-     * @param string $dependency
331
-     * @return int
332
-     */
333
-    public function loading_strategy_for_class_dependency($class_name = '', $dependency = '')
334
-    {
335
-        // all legacy models have the same dependencies
336
-        if (strpos($class_name, 'EEM_') === 0) {
337
-            $class_name = 'LEGACY_MODELS';
338
-        }
339
-        $dependency = $this->getFqnForAlias($dependency);
340
-        return $this->has_dependency_for_class($class_name, $dependency)
341
-            ? $this->_dependency_map[ $class_name ][ $dependency ]
342
-            : EE_Dependency_Map::not_registered;
343
-    }
344
-
345
-
346
-    /**
347
-     * @param string $class_name
348
-     * @return string | Closure
349
-     */
350
-    public function class_loader($class_name)
351
-    {
352
-        // all legacy models use load_model()
353
-        if (strpos($class_name, 'EEM_') === 0) {
354
-            return 'load_model';
355
-        }
356
-        // EE_CPT_*_Strategy classes like EE_CPT_Event_Strategy, EE_CPT_Venue_Strategy, etc
357
-        // perform strpos() first to avoid loading regex every time we load a class
358
-        if (strpos($class_name, 'EE_CPT_') === 0
359
-            && preg_match('/^EE_CPT_([a-zA-Z]+)_Strategy$/', $class_name)
360
-        ) {
361
-            return 'load_core';
362
-        }
363
-        $class_name = $this->getFqnForAlias($class_name);
364
-        return isset($this->_class_loaders[ $class_name ]) ? $this->_class_loaders[ $class_name ] : '';
365
-    }
366
-
367
-
368
-    /**
369
-     * @return array
370
-     */
371
-    public function class_loaders()
372
-    {
373
-        return $this->_class_loaders;
374
-    }
375
-
376
-
377
-    /**
378
-     * adds an alias for a classname
379
-     *
380
-     * @param string $fqcn      the class name that should be used (concrete class to replace interface)
381
-     * @param string $alias     the class name that would be type hinted for (abstract parent or interface)
382
-     * @param string $for_class the class that has the dependency (is type hinting for the interface)
383
-     */
384
-    public function add_alias($fqcn, $alias, $for_class = '')
385
-    {
386
-        $this->class_cache->addAlias($fqcn, $alias, $for_class);
387
-    }
388
-
389
-
390
-    /**
391
-     * Returns TRUE if the provided fully qualified name IS an alias
392
-     * WHY?
393
-     * Because if a class is type hinting for a concretion,
394
-     * then why would we need to find another class to supply it?
395
-     * ie: if a class asks for `Fully/Qualified/Namespace/SpecificClassName`,
396
-     * then give it an instance of `Fully/Qualified/Namespace/SpecificClassName`.
397
-     * Don't go looking for some substitute.
398
-     * Whereas if a class is type hinting for an interface...
399
-     * then we need to find an actual class to use.
400
-     * So the interface IS the alias for some other FQN,
401
-     * and we need to find out if `Fully/Qualified/Namespace/SomeInterface`
402
-     * represents some other class.
403
-     *
404
-     * @param string $fqn
405
-     * @param string $for_class
406
-     * @return bool
407
-     */
408
-    public function isAlias($fqn = '', $for_class = '')
409
-    {
410
-        return $this->class_cache->isAlias($fqn, $for_class);
411
-    }
412
-
413
-
414
-    /**
415
-     * Returns a FQN for provided alias if one exists, otherwise returns the original $alias
416
-     * functions recursively, so that multiple aliases can be used to drill down to a FQN
417
-     *  for example:
418
-     *      if the following two entries were added to the _aliases array:
419
-     *          array(
420
-     *              'interface_alias'           => 'some\namespace\interface'
421
-     *              'some\namespace\interface'  => 'some\namespace\classname'
422
-     *          )
423
-     *      then one could use EE_Registry::instance()->create( 'interface_alias' )
424
-     *      to load an instance of 'some\namespace\classname'
425
-     *
426
-     * @param string $alias
427
-     * @param string $for_class
428
-     * @return string
429
-     */
430
-    public function getFqnForAlias($alias = '', $for_class = '')
431
-    {
432
-        return (string) $this->class_cache->getFqnForAlias($alias, $for_class);
433
-    }
434
-
435
-
436
-    /**
437
-     * Registers the core dependencies and whether a previously instantiated object should be loaded from the cache,
438
-     * if one exists, or whether a new object should be generated every time the requested class is loaded.
439
-     * This is done by using the following class constants:
440
-     *        EE_Dependency_Map::load_from_cache - loads previously instantiated object
441
-     *        EE_Dependency_Map::load_new_object - generates a new object every time
442
-     */
443
-    protected function _register_core_dependencies()
444
-    {
445
-        $this->_dependency_map = array(
446
-            'EE_Request_Handler'                                                                                          => array(
447
-                'EE_Request' => EE_Dependency_Map::load_from_cache,
448
-            ),
449
-            'EE_System'                                                                                                   => array(
450
-                'EE_Registry'                                 => EE_Dependency_Map::load_from_cache,
451
-                'EventEspresso\core\services\loaders\Loader'  => EE_Dependency_Map::load_from_cache,
452
-                'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
453
-                'EE_Maintenance_Mode'                         => EE_Dependency_Map::load_from_cache,
454
-            ),
455
-            'EE_Session'                                                                                                  => array(
456
-                'EventEspresso\core\services\cache\TransientCacheStorage'  => EE_Dependency_Map::load_from_cache,
457
-                'EventEspresso\core\domain\values\session\SessionLifespan' => EE_Dependency_Map::load_from_cache,
458
-                'EventEspresso\core\services\request\Request'              => EE_Dependency_Map::load_from_cache,
459
-                'EventEspresso\core\services\session\SessionStartHandler'  => EE_Dependency_Map::load_from_cache,
460
-                'EE_Encryption'                                            => EE_Dependency_Map::load_from_cache,
461
-            ),
462
-            'EE_Cart'                                                                                                     => array(
463
-                'EE_Session' => EE_Dependency_Map::load_from_cache,
464
-            ),
465
-            'EE_Front_Controller'                                                                                         => array(
466
-                'EE_Registry'              => EE_Dependency_Map::load_from_cache,
467
-                'EE_Request_Handler'       => EE_Dependency_Map::load_from_cache,
468
-                'EE_Module_Request_Router' => EE_Dependency_Map::load_from_cache,
469
-            ),
470
-            'EE_Messenger_Collection_Loader'                                                                              => array(
471
-                'EE_Messenger_Collection' => EE_Dependency_Map::load_new_object,
472
-            ),
473
-            'EE_Message_Type_Collection_Loader'                                                                           => array(
474
-                'EE_Message_Type_Collection' => EE_Dependency_Map::load_new_object,
475
-            ),
476
-            'EE_Message_Resource_Manager'                                                                                 => array(
477
-                'EE_Messenger_Collection_Loader'    => EE_Dependency_Map::load_new_object,
478
-                'EE_Message_Type_Collection_Loader' => EE_Dependency_Map::load_new_object,
479
-                'EEM_Message_Template_Group'        => EE_Dependency_Map::load_from_cache,
480
-            ),
481
-            'EE_Message_Factory'                                                                                          => array(
482
-                'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
483
-            ),
484
-            'EE_messages'                                                                                                 => array(
485
-                'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
486
-            ),
487
-            'EE_Messages_Generator'                                                                                       => array(
488
-                'EE_Messages_Queue'                    => EE_Dependency_Map::load_new_object,
489
-                'EE_Messages_Data_Handler_Collection'  => EE_Dependency_Map::load_new_object,
490
-                'EE_Message_Template_Group_Collection' => EE_Dependency_Map::load_new_object,
491
-                'EEH_Parse_Shortcodes'                 => EE_Dependency_Map::load_from_cache,
492
-            ),
493
-            'EE_Messages_Processor'                                                                                       => array(
494
-                'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
495
-            ),
496
-            'EE_Messages_Queue'                                                                                           => array(
497
-                'EE_Message_Repository' => EE_Dependency_Map::load_new_object,
498
-            ),
499
-            'EE_Messages_Template_Defaults'                                                                               => array(
500
-                'EEM_Message_Template_Group' => EE_Dependency_Map::load_from_cache,
501
-                'EEM_Message_Template'       => EE_Dependency_Map::load_from_cache,
502
-            ),
503
-            'EE_Message_To_Generate_From_Request'                                                                         => array(
504
-                'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
505
-                'EE_Request_Handler'          => EE_Dependency_Map::load_from_cache,
506
-            ),
507
-            'EventEspresso\core\services\commands\CommandBus'                                                             => array(
508
-                'EventEspresso\core\services\commands\CommandHandlerManager' => EE_Dependency_Map::load_from_cache,
509
-            ),
510
-            'EventEspresso\services\commands\CommandHandler'                                                              => array(
511
-                'EE_Registry'         => EE_Dependency_Map::load_from_cache,
512
-                'CommandBusInterface' => EE_Dependency_Map::load_from_cache,
513
-            ),
514
-            'EventEspresso\core\services\commands\CommandHandlerManager'                                                  => array(
515
-                'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
516
-            ),
517
-            'EventEspresso\core\services\commands\CompositeCommandHandler'                                                => array(
518
-                'EventEspresso\core\services\commands\CommandBus'     => EE_Dependency_Map::load_from_cache,
519
-                'EventEspresso\core\services\commands\CommandFactory' => EE_Dependency_Map::load_from_cache,
520
-            ),
521
-            'EventEspresso\core\services\commands\CommandFactory'                                                         => array(
522
-                'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
523
-            ),
524
-            'EventEspresso\core\services\commands\middleware\CapChecker'                                                  => array(
525
-                'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker' => EE_Dependency_Map::load_from_cache,
526
-            ),
527
-            'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker'                                         => array(
528
-                'EE_Capabilities' => EE_Dependency_Map::load_from_cache,
529
-            ),
530
-            'EventEspresso\core\domain\services\capabilities\RegistrationsCapChecker'                                     => array(
531
-                'EE_Capabilities' => EE_Dependency_Map::load_from_cache,
532
-            ),
533
-            'EventEspresso\core\services\commands\registration\CreateRegistrationCommandHandler'                          => array(
534
-                'EventEspresso\core\domain\services\registration\CreateRegistrationService' => EE_Dependency_Map::load_from_cache,
535
-            ),
536
-            'EventEspresso\core\services\commands\registration\CopyRegistrationDetailsCommandHandler'                     => array(
537
-                'EventEspresso\core\domain\services\registration\CopyRegistrationService' => EE_Dependency_Map::load_from_cache,
538
-            ),
539
-            'EventEspresso\core\services\commands\registration\CopyRegistrationPaymentsCommandHandler'                    => array(
540
-                'EventEspresso\core\domain\services\registration\CopyRegistrationService' => EE_Dependency_Map::load_from_cache,
541
-            ),
542
-            'EventEspresso\core\services\commands\registration\CancelRegistrationAndTicketLineItemCommandHandler'         => array(
543
-                'EventEspresso\core\domain\services\registration\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
544
-            ),
545
-            'EventEspresso\core\services\commands\registration\UpdateRegistrationAndTransactionAfterChangeCommandHandler' => array(
546
-                'EventEspresso\core\domain\services\registration\UpdateRegistrationService' => EE_Dependency_Map::load_from_cache,
547
-            ),
548
-            'EventEspresso\core\services\commands\ticket\CreateTicketLineItemCommandHandler'                              => array(
549
-                'EventEspresso\core\domain\services\ticket\CreateTicketLineItemService' => EE_Dependency_Map::load_from_cache,
550
-            ),
551
-            'EventEspresso\core\services\commands\ticket\CancelTicketLineItemCommandHandler'                              => array(
552
-                'EventEspresso\core\domain\services\ticket\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
553
-            ),
554
-            'EventEspresso\core\domain\services\registration\CancelRegistrationService'                                   => array(
555
-                'EventEspresso\core\domain\services\ticket\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
556
-            ),
557
-            'EventEspresso\core\services\commands\attendee\CreateAttendeeCommandHandler'                                  => array(
558
-                'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
559
-            ),
560
-            'EventEspresso\core\services\database\TableManager'                                                           => array(
561
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
562
-            ),
563
-            'EE_Data_Migration_Class_Base'                                                                                => array(
564
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
565
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
566
-            ),
567
-            'EE_DMS_Core_4_1_0'                                                                                           => array(
568
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
569
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
570
-            ),
571
-            'EE_DMS_Core_4_2_0'                                                                                           => array(
572
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
573
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
574
-            ),
575
-            'EE_DMS_Core_4_3_0'                                                                                           => array(
576
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
577
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
578
-            ),
579
-            'EE_DMS_Core_4_4_0'                                                                                           => array(
580
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
581
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
582
-            ),
583
-            'EE_DMS_Core_4_5_0'                                                                                           => array(
584
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
585
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
586
-            ),
587
-            'EE_DMS_Core_4_6_0'                                                                                           => array(
588
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
589
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
590
-            ),
591
-            'EE_DMS_Core_4_7_0'                                                                                           => array(
592
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
593
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
594
-            ),
595
-            'EE_DMS_Core_4_8_0'                                                                                           => array(
596
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
597
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
598
-            ),
599
-            'EE_DMS_Core_4_9_0' => array(
600
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
601
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
602
-            ),
603
-            'EE_DMS_Core_4_10_0' => array(
604
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
605
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
606
-                'EE_DMS_Core_4_9_0'                                  => EE_Dependency_Map::load_from_cache,
607
-            ),
608
-            'EventEspresso\core\services\assets\I18nRegistry'                                                             => array(
609
-                array(),
610
-                'EventEspresso\core\domain\Domain' => EE_Dependency_Map::load_from_cache,
611
-            ),
612
-            'EventEspresso\core\services\assets\Registry'                                                                 => array(
613
-                'EventEspresso\core\services\assets\AssetCollection' => EE_Dependency_Map::load_from_cache,
614
-                'EventEspresso\core\services\assets\I18nRegistry'    => EE_Dependency_Map::load_from_cache,
615
-            ),
616
-            'EventEspresso\core\domain\entities\shortcodes\EspressoCancelled'                                             => array(
617
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
618
-            ),
619
-            'EventEspresso\core\domain\entities\shortcodes\EspressoCheckout'                                              => array(
620
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
621
-            ),
622
-            'EventEspresso\core\domain\entities\shortcodes\EspressoEventAttendees'                                        => array(
623
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
624
-            ),
625
-            'EventEspresso\core\domain\entities\shortcodes\EspressoEvents'                                                => array(
626
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
627
-            ),
628
-            'EventEspresso\core\domain\entities\shortcodes\EspressoThankYou'                                              => array(
629
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
630
-            ),
631
-            'EventEspresso\core\domain\entities\shortcodes\EspressoTicketSelector'                                        => array(
632
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
633
-            ),
634
-            'EventEspresso\core\domain\entities\shortcodes\EspressoTxnPage'                                               => array(
635
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
636
-            ),
637
-            'EventEspresso\core\services\cache\BasicCacheManager'                                                         => array(
638
-                'EventEspresso\core\services\cache\TransientCacheStorage' => EE_Dependency_Map::load_from_cache,
639
-            ),
640
-            'EventEspresso\core\services\cache\PostRelatedCacheManager'                                                   => array(
641
-                'EventEspresso\core\services\cache\TransientCacheStorage' => EE_Dependency_Map::load_from_cache,
642
-            ),
643
-            'EventEspresso\core\domain\services\validation\email\EmailValidationService'                                  => array(
644
-                'EE_Registration_Config'                     => EE_Dependency_Map::load_from_cache,
645
-                'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
646
-            ),
647
-            'EventEspresso\core\domain\values\EmailAddress'                                                               => array(
648
-                null,
649
-                'EventEspresso\core\domain\services\validation\email\EmailValidationService' => EE_Dependency_Map::load_from_cache,
650
-            ),
651
-            'EventEspresso\core\services\orm\ModelFieldFactory'                                                           => array(
652
-                'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
653
-            ),
654
-            'LEGACY_MODELS'                                                                                               => array(
655
-                null,
656
-                'EventEspresso\core\services\database\ModelFieldFactory' => EE_Dependency_Map::load_from_cache,
657
-            ),
658
-            'EE_Module_Request_Router'                                                                                    => array(
659
-                'EE_Request' => EE_Dependency_Map::load_from_cache,
660
-            ),
661
-            'EE_Registration_Processor'                                                                                   => array(
662
-                'EE_Request' => EE_Dependency_Map::load_from_cache,
663
-            ),
664
-            'EventEspresso\core\services\notifications\PersistentAdminNoticeManager'                                      => array(
665
-                null,
666
-                'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker' => EE_Dependency_Map::load_from_cache,
667
-                'EventEspresso\core\services\request\Request'                         => EE_Dependency_Map::load_from_cache,
668
-            ),
669
-            'EventEspresso\core\services\licensing\LicenseService'                                                        => array(
670
-                'EventEspresso\core\domain\services\pue\Stats'  => EE_Dependency_Map::load_from_cache,
671
-                'EventEspresso\core\domain\services\pue\Config' => EE_Dependency_Map::load_from_cache,
672
-            ),
673
-            'EE_Admin_Transactions_List_Table'                                                                            => array(
674
-                null,
675
-                'EventEspresso\core\domain\values\session\SessionLifespan' => EE_Dependency_Map::load_from_cache,
676
-            ),
677
-            'EventEspresso\core\domain\services\pue\Stats'                                                                => array(
678
-                'EventEspresso\core\domain\services\pue\Config'        => EE_Dependency_Map::load_from_cache,
679
-                'EE_Maintenance_Mode'                                  => EE_Dependency_Map::load_from_cache,
680
-                'EventEspresso\core\domain\services\pue\StatsGatherer' => EE_Dependency_Map::load_from_cache,
681
-            ),
682
-            'EventEspresso\core\domain\services\pue\Config'                                                               => array(
683
-                'EE_Network_Config' => EE_Dependency_Map::load_from_cache,
684
-                'EE_Config'         => EE_Dependency_Map::load_from_cache,
685
-            ),
686
-            'EventEspresso\core\domain\services\pue\StatsGatherer'                                                        => array(
687
-                'EEM_Payment_Method' => EE_Dependency_Map::load_from_cache,
688
-                'EEM_Event'          => EE_Dependency_Map::load_from_cache,
689
-                'EEM_Datetime'       => EE_Dependency_Map::load_from_cache,
690
-                'EEM_Ticket'         => EE_Dependency_Map::load_from_cache,
691
-                'EEM_Registration'   => EE_Dependency_Map::load_from_cache,
692
-                'EEM_Transaction'    => EE_Dependency_Map::load_from_cache,
693
-                'EE_Config'          => EE_Dependency_Map::load_from_cache,
694
-            ),
695
-            'EventEspresso\core\domain\services\admin\ExitModal'                                                          => array(
696
-                'EventEspresso\core\services\assets\Registry' => EE_Dependency_Map::load_from_cache,
697
-            ),
698
-            'EventEspresso\core\domain\services\admin\PluginUpsells'                                                      => array(
699
-                'EventEspresso\core\domain\Domain' => EE_Dependency_Map::load_from_cache,
700
-            ),
701
-            'EventEspresso\caffeinated\modules\recaptcha_invisible\InvisibleRecaptcha'                                    => array(
702
-                'EE_Registration_Config' => EE_Dependency_Map::load_from_cache,
703
-                'EE_Session'             => EE_Dependency_Map::load_from_cache,
704
-            ),
705
-            'EventEspresso\caffeinated\modules\recaptcha_invisible\RecaptchaAdminSettings'                                => array(
706
-                'EE_Registration_Config' => EE_Dependency_Map::load_from_cache,
707
-            ),
708
-            'EventEspresso\modules\ticket_selector\ProcessTicketSelector'                                                 => array(
709
-                'EE_Core_Config'                                                          => EE_Dependency_Map::load_from_cache,
710
-                'EventEspresso\core\services\request\Request'                             => EE_Dependency_Map::load_from_cache,
711
-                'EE_Session'                                                              => EE_Dependency_Map::load_from_cache,
712
-                'EEM_Ticket'                                                              => EE_Dependency_Map::load_from_cache,
713
-                'EventEspresso\modules\ticket_selector\TicketDatetimeAvailabilityTracker' => EE_Dependency_Map::load_from_cache,
714
-            ),
715
-            'EventEspresso\modules\ticket_selector\TicketDatetimeAvailabilityTracker'                                     => array(
716
-                'EEM_Datetime' => EE_Dependency_Map::load_from_cache,
717
-            ),
718
-            'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'                              => array(
719
-                'EE_Core_Config'                             => EE_Dependency_Map::load_from_cache,
720
-                'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
721
-            ),
722
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes'                                => array(
723
-                'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions' => EE_Dependency_Map::load_from_cache,
724
-            ),
725
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies'                               => array(
726
-                'EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions' => EE_Dependency_Map::load_from_cache,
727
-            ),
728
-            'EE_CPT_Strategy'                                                                                             => array(
729
-                'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions' => EE_Dependency_Map::load_from_cache,
730
-                'EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions' => EE_Dependency_Map::load_from_cache,
731
-            ),
732
-            'EventEspresso\core\services\loaders\ObjectIdentifier'                                                        => array(
733
-                'EventEspresso\core\services\loaders\ClassInterfaceCache' => EE_Dependency_Map::load_from_cache,
734
-            ),
735
-            'EventEspresso\core\domain\services\assets\CoreAssetManager'                                                  => array(
736
-                'EventEspresso\core\services\assets\AssetCollection' => EE_Dependency_Map::load_from_cache,
737
-                'EE_Currency_Config'                                 => EE_Dependency_Map::load_from_cache,
738
-                'EE_Template_Config'                                 => EE_Dependency_Map::load_from_cache,
739
-                'EventEspresso\core\domain\Domain'                   => EE_Dependency_Map::load_from_cache,
740
-                'EventEspresso\core\services\assets\Registry'        => EE_Dependency_Map::load_from_cache,
741
-            ),
742
-            'EventEspresso\core\domain\services\admin\privacy\policy\PrivacyPolicy' => array(
743
-                'EEM_Payment_Method' => EE_Dependency_Map::load_from_cache,
744
-                'EventEspresso\core\domain\values\session\SessionLifespan' => EE_Dependency_Map::load_from_cache
745
-            ),
746
-            'EventEspresso\core\domain\services\admin\privacy\export\ExportAttendee' => array(
747
-                'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
748
-            ),
749
-            'EventEspresso\core\domain\services\admin\privacy\export\ExportAttendeeBillingData' => array(
750
-                'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
751
-                'EEM_Payment_Method' => EE_Dependency_Map::load_from_cache
752
-            ),
753
-            'EventEspresso\core\domain\services\admin\privacy\export\ExportCheckins' => array(
754
-                'EEM_Checkin' => EE_Dependency_Map::load_from_cache,
755
-            ),
756
-            'EventEspresso\core\domain\services\admin\privacy\export\ExportRegistration' => array(
757
-                'EEM_Registration' => EE_Dependency_Map::load_from_cache,
758
-            ),
759
-            'EventEspresso\core\domain\services\admin\privacy\export\ExportTransaction' => array(
760
-                'EEM_Transaction' => EE_Dependency_Map::load_from_cache,
761
-            ),
762
-            'EventEspresso\core\domain\services\admin\privacy\erasure\EraseAttendeeData' => array(
763
-                'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
764
-            ),
765
-            'EventEspresso\core\domain\services\admin\privacy\erasure\EraseAnswers' => array(
766
-                'EEM_Answer' => EE_Dependency_Map::load_from_cache,
767
-                'EEM_Question' => EE_Dependency_Map::load_from_cache,
768
-            ),
769
-            'EventEspresso\core\CPTs\CptQueryModifier' => array(
770
-                null,
771
-                null,
772
-                null,
773
-                'EE_Request_Handler'                          => EE_Dependency_Map::load_from_cache,
774
-                'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
775
-                'EventEspresso\core\services\loaders\Loader'  => EE_Dependency_Map::load_from_cache,
776
-            ),
777
-            'EventEspresso\core\domain\services\admin\privacy\forms\PrivacySettingsFormHandler' => array(
778
-                'EE_Registry' => EE_Dependency_Map::load_from_cache,
779
-                'EE_Config' => EE_Dependency_Map::load_from_cache
780
-            ),
781
-            'EventEspresso\core\services\editor\BlockRegistrationManager'                                                 => array(
782
-                'EventEspresso\core\services\assets\BlockAssetManagerCollection' => EE_Dependency_Map::load_from_cache,
783
-                'EventEspresso\core\domain\entities\editor\BlockCollection'      => EE_Dependency_Map::load_from_cache,
784
-                'EventEspresso\core\services\route_match\RouteMatchSpecificationManager' => EE_Dependency_Map::load_from_cache,
785
-                'EventEspresso\core\services\request\Request'                    => EE_Dependency_Map::load_from_cache,
786
-            ),
787
-            'EventEspresso\core\domain\entities\editor\CoreBlocksAssetManager' => array(
788
-                'EventEspresso\core\domain\Domain'                   => EE_Dependency_Map::load_from_cache,
789
-                'EventEspresso\core\services\assets\AssetCollection' => EE_Dependency_Map::load_from_cache,
790
-                'EventEspresso\core\services\assets\Registry'        => EE_Dependency_Map::load_from_cache,
791
-            ),
792
-            'EventEspresso\core\domain\services\blocks\EventAttendeesBlockRenderer' => array(
793
-                'EventEspresso\core\domain\Domain' => EE_Dependency_Map::load_from_cache,
794
-                'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
795
-            ),
796
-            'EventEspresso\core\domain\entities\editor\blocks\EventAttendees' => array(
797
-                'EventEspresso\core\domain\entities\editor\CoreBlocksAssetManager' => self::load_from_cache,
798
-                'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
799
-                'EventEspresso\core\domain\services\blocks\EventAttendeesBlockRenderer' => self::load_from_cache,
800
-            ),
801
-            'EventEspresso\core\services\route_match\RouteMatchSpecificationDependencyResolver' => array(
802
-                'EventEspresso\core\services\container\Mirror' => EE_Dependency_Map::load_from_cache,
803
-                'EventEspresso\core\services\loaders\ClassInterfaceCache' => EE_Dependency_Map::load_from_cache,
804
-                'EE_Dependency_Map' => EE_Dependency_Map::load_from_cache,
805
-            ),
806
-            'EventEspresso\core\services\route_match\RouteMatchSpecificationFactory' => array(
807
-                'EventEspresso\core\services\route_match\RouteMatchSpecificationDependencyResolver' => EE_Dependency_Map::load_from_cache,
808
-                'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
809
-            ),
810
-            'EventEspresso\core\services\route_match\RouteMatchSpecificationManager' => array(
811
-                'EventEspresso\core\services\route_match\RouteMatchSpecificationCollection' => EE_Dependency_Map::load_from_cache,
812
-                'EventEspresso\core\services\route_match\RouteMatchSpecificationFactory' => EE_Dependency_Map::load_from_cache,
813
-            ),
814
-            'EventEspresso\core\libraries\rest_api\CalculatedModelFields' => array(
815
-                'EventEspresso\core\libraries\rest_api\calculations\CalculatedModelFieldsFactory' => EE_Dependency_Map::load_from_cache
816
-            ),
817
-            'EventEspresso\core\libraries\rest_api\calculations\CalculatedModelFieldsFactory' => array(
818
-                'EventEspresso\core\services\loaders\Loader'  => EE_Dependency_Map::load_from_cache,
819
-            ),
820
-            'EventEspresso\core\libraries\rest_api\controllers\model\Read' => array(
821
-                'EventEspresso\core\libraries\rest_api\CalculatedModelFields' => EE_Dependency_Map::load_from_cache
822
-            ),
823
-            'EventEspresso\core\libraries\rest_api\calculations\Datetime' => array(
824
-                'EEM_Datetime' => EE_Dependency_Map::load_from_cache,
825
-                'EEM_Registration' => EE_Dependency_Map::load_from_cache
826
-            ),
827
-            'EventEspresso\core\libraries\rest_api\calculations\Event' => array(
828
-                'EEM_Event' => EE_Dependency_Map::load_from_cache,
829
-                'EEM_Registration' => EE_Dependency_Map::load_from_cache
830
-            ),
831
-            'EventEspresso\core\libraries\rest_api\calculations\Registration' => array(
832
-                'EEM_Registration' => EE_Dependency_Map::load_from_cache
833
-            ),
834
-            'EventEspresso\core\services\session\SessionStartHandler' => array(
835
-                'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
836
-            ),
837
-            'EE_URL_Validation_Strategy' => array(
838
-                null,
839
-                null,
840
-                'EventEspresso\core\services\validators\URLValidator' => EE_Dependency_Map::load_from_cache
841
-            ),
842
-            'EventEspresso\admin_pages\general_settings\OrganizationSettings' => array(
843
-                'EE_Registry'                                             => EE_Dependency_Map::load_from_cache,
844
-                'EE_Organization_Config'                                  => EE_Dependency_Map::load_from_cache,
845
-                'EE_Core_Config'                                          => EE_Dependency_Map::load_from_cache,
846
-                'EE_Network_Core_Config'                                  => EE_Dependency_Map::load_from_cache,
847
-                'EventEspresso\core\services\address\CountrySubRegionDao' => EE_Dependency_Map::load_from_cache,
848
-            ),
849
-            'EventEspresso\core\services\address\CountrySubRegionDao' => array(
850
-                'EEM_State'                                            => EE_Dependency_Map::load_from_cache,
851
-                'EventEspresso\core\services\validators\JsonValidator' => EE_Dependency_Map::load_from_cache
852
-            ),
853
-            'EventEspresso\core\domain\services\admin\ajax\WordpressHeartbeat' => array(
854
-                'EventEspresso\core\services\loaders\Loader'  => EE_Dependency_Map::load_from_cache,
855
-                'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
856
-            ),
857
-            'EventEspresso\core\domain\services\admin\ajax\EventEditorHeartbeat' => array(
858
-                'EventEspresso\core\domain\Domain' => EE_Dependency_Map::load_from_cache,
859
-                'EE_Environment_Config'            => EE_Dependency_Map::load_from_cache,
860
-            ),
861
-            'EventEspresso\core\services\request\files\FilesDataHandler' => array(
862
-                'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
863
-            ),
864
-            'EventEspressoBatchRequest\BatchRequestProcessor' => [
865
-                'EventEspresso\core\services\loaders\Loader'  => EE_Dependency_Map::load_from_cache,
866
-            ]
867
-        );
868
-    }
869
-
870
-
871
-    /**
872
-     * Registers how core classes are loaded.
873
-     * This can either be done by simply providing the name of one of the EE_Registry loader methods such as:
874
-     *        'EE_Request_Handler' => 'load_core'
875
-     *        'EE_Messages_Queue'  => 'load_lib'
876
-     *        'EEH_Debug_Tools'    => 'load_helper'
877
-     * or, if greater control is required, by providing a custom closure. For example:
878
-     *        'Some_Class' => function () {
879
-     *            return new Some_Class();
880
-     *        },
881
-     * This is required for instantiating dependencies
882
-     * where an interface has been type hinted in a class constructor. For example:
883
-     *        'Required_Interface' => function () {
884
-     *            return new A_Class_That_Implements_Required_Interface();
885
-     *        },
886
-     */
887
-    protected function _register_core_class_loaders()
888
-    {
889
-        $this->_class_loaders = array(
890
-            // load_core
891
-            'EE_Dependency_Map'                            => function () {
892
-                return $this;
893
-            },
894
-            'EE_Capabilities'                              => 'load_core',
895
-            'EE_Encryption'                                => 'load_core',
896
-            'EE_Front_Controller'                          => 'load_core',
897
-            'EE_Module_Request_Router'                     => 'load_core',
898
-            'EE_Registry'                                  => 'load_core',
899
-            'EE_Request'                                   => function () {
900
-                return $this->legacy_request;
901
-            },
902
-            'EventEspresso\core\services\request\Request'  => function () {
903
-                return $this->request;
904
-            },
905
-            'EventEspresso\core\services\request\Response' => function () {
906
-                return $this->response;
907
-            },
908
-            'EE_Base'                                      => 'load_core',
909
-            'EE_Request_Handler'                           => 'load_core',
910
-            'EE_Session'                                   => 'load_core',
911
-            'EE_Cron_Tasks'                                => 'load_core',
912
-            'EE_System'                                    => 'load_core',
913
-            'EE_Maintenance_Mode'                          => 'load_core',
914
-            'EE_Register_CPTs'                             => 'load_core',
915
-            'EE_Admin'                                     => 'load_core',
916
-            'EE_CPT_Strategy'                              => 'load_core',
917
-            // load_class
918
-            'EE_Registration_Processor'                    => 'load_class',
919
-            // load_lib
920
-            'EE_Message_Resource_Manager'                  => 'load_lib',
921
-            'EE_Message_Type_Collection'                   => 'load_lib',
922
-            'EE_Message_Type_Collection_Loader'            => 'load_lib',
923
-            'EE_Messenger_Collection'                      => 'load_lib',
924
-            'EE_Messenger_Collection_Loader'               => 'load_lib',
925
-            'EE_Messages_Processor'                        => 'load_lib',
926
-            'EE_Message_Repository'                        => 'load_lib',
927
-            'EE_Messages_Queue'                            => 'load_lib',
928
-            'EE_Messages_Data_Handler_Collection'          => 'load_lib',
929
-            'EE_Message_Template_Group_Collection'         => 'load_lib',
930
-            'EE_Payment_Method_Manager'                    => 'load_lib',
931
-            'EE_DMS_Core_4_1_0'                            => 'load_dms',
932
-            'EE_DMS_Core_4_2_0'                            => 'load_dms',
933
-            'EE_DMS_Core_4_3_0'                            => 'load_dms',
934
-            'EE_DMS_Core_4_5_0'                            => 'load_dms',
935
-            'EE_DMS_Core_4_6_0'                            => 'load_dms',
936
-            'EE_DMS_Core_4_7_0'                            => 'load_dms',
937
-            'EE_DMS_Core_4_8_0'                            => 'load_dms',
938
-            'EE_DMS_Core_4_9_0'                            => 'load_dms',
939
-            'EE_DMS_Core_4_10_0'                            => 'load_dms',
940
-            'EE_Messages_Generator'                        => function () {
941
-                return EE_Registry::instance()->load_lib(
942
-                    'Messages_Generator',
943
-                    array(),
944
-                    false,
945
-                    false
946
-                );
947
-            },
948
-            'EE_Messages_Template_Defaults'                => function ($arguments = array()) {
949
-                return EE_Registry::instance()->load_lib(
950
-                    'Messages_Template_Defaults',
951
-                    $arguments,
952
-                    false,
953
-                    false
954
-                );
955
-            },
956
-            // load_helper
957
-            'EEH_Parse_Shortcodes'                         => function () {
958
-                if (EE_Registry::instance()->load_helper('Parse_Shortcodes')) {
959
-                    return new EEH_Parse_Shortcodes();
960
-                }
961
-                return null;
962
-            },
963
-            'EE_Template_Config'                           => function () {
964
-                return EE_Config::instance()->template_settings;
965
-            },
966
-            'EE_Currency_Config'                           => function () {
967
-                return EE_Config::instance()->currency;
968
-            },
969
-            'EE_Registration_Config'                       => function () {
970
-                return EE_Config::instance()->registration;
971
-            },
972
-            'EE_Core_Config'                               => function () {
973
-                return EE_Config::instance()->core;
974
-            },
975
-            'EventEspresso\core\services\loaders\Loader'   => function () {
976
-                return LoaderFactory::getLoader();
977
-            },
978
-            'EE_Network_Config'                            => function () {
979
-                return EE_Network_Config::instance();
980
-            },
981
-            'EE_Config'                                    => function () {
982
-                return EE_Config::instance();
983
-            },
984
-            'EventEspresso\core\domain\Domain'             => function () {
985
-                return DomainFactory::getEventEspressoCoreDomain();
986
-            },
987
-            'EE_Admin_Config'                              => function () {
988
-                return EE_Config::instance()->admin;
989
-            },
990
-            'EE_Organization_Config'                       => function () {
991
-                return EE_Config::instance()->organization;
992
-            },
993
-            'EE_Network_Core_Config'                       => function () {
994
-                return EE_Network_Config::instance()->core;
995
-            },
996
-            'EE_Environment_Config'                        => function () {
997
-                return EE_Config::instance()->environment;
998
-            },
999
-        );
1000
-    }
1001
-
1002
-
1003
-    /**
1004
-     * can be used for supplying alternate names for classes,
1005
-     * or for connecting interface names to instantiable classes
1006
-     */
1007
-    protected function _register_core_aliases()
1008
-    {
1009
-        $aliases = array(
1010
-            'CommandBusInterface'                                                          => 'EventEspresso\core\services\commands\CommandBusInterface',
1011
-            'EventEspresso\core\services\commands\CommandBusInterface'                     => 'EventEspresso\core\services\commands\CommandBus',
1012
-            'CommandHandlerManagerInterface'                                               => 'EventEspresso\core\services\commands\CommandHandlerManagerInterface',
1013
-            'EventEspresso\core\services\commands\CommandHandlerManagerInterface'          => 'EventEspresso\core\services\commands\CommandHandlerManager',
1014
-            'CapChecker'                                                                   => 'EventEspresso\core\services\commands\middleware\CapChecker',
1015
-            'AddActionHook'                                                                => 'EventEspresso\core\services\commands\middleware\AddActionHook',
1016
-            'CapabilitiesChecker'                                                          => 'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker',
1017
-            'CapabilitiesCheckerInterface'                                                 => 'EventEspresso\core\domain\services\capabilities\CapabilitiesCheckerInterface',
1018
-            'EventEspresso\core\domain\services\capabilities\CapabilitiesCheckerInterface' => 'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker',
1019
-            'CreateRegistrationService'                                                    => 'EventEspresso\core\domain\services\registration\CreateRegistrationService',
1020
-            'CreateRegistrationCommandHandler'                                             => 'EventEspresso\core\services\commands\registration\CreateRegistrationCommand',
1021
-            'CopyRegistrationDetailsCommandHandler'                                        => 'EventEspresso\core\services\commands\registration\CopyRegistrationDetailsCommand',
1022
-            'CopyRegistrationPaymentsCommandHandler'                                       => 'EventEspresso\core\services\commands\registration\CopyRegistrationPaymentsCommand',
1023
-            'CancelRegistrationAndTicketLineItemCommandHandler'                            => 'EventEspresso\core\services\commands\registration\CancelRegistrationAndTicketLineItemCommandHandler',
1024
-            'UpdateRegistrationAndTransactionAfterChangeCommandHandler'                    => 'EventEspresso\core\services\commands\registration\UpdateRegistrationAndTransactionAfterChangeCommandHandler',
1025
-            'CreateTicketLineItemCommandHandler'                                           => 'EventEspresso\core\services\commands\ticket\CreateTicketLineItemCommand',
1026
-            'CreateTransactionCommandHandler'                                              => 'EventEspresso\core\services\commands\transaction\CreateTransactionCommandHandler',
1027
-            'CreateAttendeeCommandHandler'                                                 => 'EventEspresso\core\services\commands\attendee\CreateAttendeeCommandHandler',
1028
-            'TableManager'                                                                 => 'EventEspresso\core\services\database\TableManager',
1029
-            'TableAnalysis'                                                                => 'EventEspresso\core\services\database\TableAnalysis',
1030
-            'EspressoShortcode'                                                            => 'EventEspresso\core\services\shortcodes\EspressoShortcode',
1031
-            'ShortcodeInterface'                                                           => 'EventEspresso\core\services\shortcodes\ShortcodeInterface',
1032
-            'EventEspresso\core\services\shortcodes\ShortcodeInterface'                    => 'EventEspresso\core\services\shortcodes\EspressoShortcode',
1033
-            'EventEspresso\core\services\cache\CacheStorageInterface'                      => 'EventEspresso\core\services\cache\TransientCacheStorage',
1034
-            'LoaderInterface'                                                              => 'EventEspresso\core\services\loaders\LoaderInterface',
1035
-            'EventEspresso\core\services\loaders\LoaderInterface'                          => 'EventEspresso\core\services\loaders\Loader',
1036
-            'CommandFactoryInterface'                                                      => 'EventEspresso\core\services\commands\CommandFactoryInterface',
1037
-            'EventEspresso\core\services\commands\CommandFactoryInterface'                 => 'EventEspresso\core\services\commands\CommandFactory',
1038
-            'EmailValidatorInterface'                                                      => 'EventEspresso\core\domain\services\validation\email\EmailValidatorInterface',
1039
-            'EventEspresso\core\domain\services\validation\email\EmailValidatorInterface'  => 'EventEspresso\core\domain\services\validation\email\EmailValidationService',
1040
-            'NoticeConverterInterface'                                                     => 'EventEspresso\core\services\notices\NoticeConverterInterface',
1041
-            'EventEspresso\core\services\notices\NoticeConverterInterface'                 => 'EventEspresso\core\services\notices\ConvertNoticesToEeErrors',
1042
-            'NoticesContainerInterface'                                                    => 'EventEspresso\core\services\notices\NoticesContainerInterface',
1043
-            'EventEspresso\core\services\notices\NoticesContainerInterface'                => 'EventEspresso\core\services\notices\NoticesContainer',
1044
-            'EventEspresso\core\services\request\RequestInterface'                         => 'EventEspresso\core\services\request\Request',
1045
-            'EventEspresso\core\services\request\ResponseInterface'                        => 'EventEspresso\core\services\request\Response',
1046
-            'EventEspresso\core\domain\DomainInterface'                                    => 'EventEspresso\core\domain\Domain',
1047
-            'Registration_Processor'                                                       => 'EE_Registration_Processor',
1048
-        );
1049
-        foreach ($aliases as $alias => $fqn) {
1050
-            if (is_array($fqn)) {
1051
-                foreach ($fqn as $class => $for_class) {
1052
-                    $this->class_cache->addAlias($class, $alias, $for_class);
1053
-                }
1054
-                continue;
1055
-            }
1056
-            $this->class_cache->addAlias($fqn, $alias);
1057
-        }
1058
-        if (! (defined('DOING_AJAX') && DOING_AJAX) && is_admin()) {
1059
-            $this->class_cache->addAlias(
1060
-                'EventEspresso\core\services\notices\ConvertNoticesToAdminNotices',
1061
-                'EventEspresso\core\services\notices\NoticeConverterInterface'
1062
-            );
1063
-        }
1064
-    }
1065
-
1066
-
1067
-    /**
1068
-     * This is used to reset the internal map and class_loaders to their original default state at the beginning of the
1069
-     * request Primarily used by unit tests.
1070
-     */
1071
-    public function reset()
1072
-    {
1073
-        $this->_register_core_class_loaders();
1074
-        $this->_register_core_dependencies();
1075
-    }
1076
-
1077
-
1078
-    /**
1079
-     * PLZ NOTE: a better name for this method would be is_alias()
1080
-     * because it returns TRUE if the provided fully qualified name IS an alias
1081
-     * WHY?
1082
-     * Because if a class is type hinting for a concretion,
1083
-     * then why would we need to find another class to supply it?
1084
-     * ie: if a class asks for `Fully/Qualified/Namespace/SpecificClassName`,
1085
-     * then give it an instance of `Fully/Qualified/Namespace/SpecificClassName`.
1086
-     * Don't go looking for some substitute.
1087
-     * Whereas if a class is type hinting for an interface...
1088
-     * then we need to find an actual class to use.
1089
-     * So the interface IS the alias for some other FQN,
1090
-     * and we need to find out if `Fully/Qualified/Namespace/SomeInterface`
1091
-     * represents some other class.
1092
-     *
1093
-     * @deprecated 4.9.62.p
1094
-     * @param string $fqn
1095
-     * @param string $for_class
1096
-     * @return bool
1097
-     */
1098
-    public function has_alias($fqn = '', $for_class = '')
1099
-    {
1100
-        return $this->isAlias($fqn, $for_class);
1101
-    }
1102
-
1103
-
1104
-    /**
1105
-     * PLZ NOTE: a better name for this method would be get_fqn_for_alias()
1106
-     * because it returns a FQN for provided alias if one exists, otherwise returns the original $alias
1107
-     * functions recursively, so that multiple aliases can be used to drill down to a FQN
1108
-     *  for example:
1109
-     *      if the following two entries were added to the _aliases array:
1110
-     *          array(
1111
-     *              'interface_alias'           => 'some\namespace\interface'
1112
-     *              'some\namespace\interface'  => 'some\namespace\classname'
1113
-     *          )
1114
-     *      then one could use EE_Registry::instance()->create( 'interface_alias' )
1115
-     *      to load an instance of 'some\namespace\classname'
1116
-     *
1117
-     * @deprecated 4.9.62.p
1118
-     * @param string $alias
1119
-     * @param string $for_class
1120
-     * @return string
1121
-     */
1122
-    public function get_alias($alias = '', $for_class = '')
1123
-    {
1124
-        return $this->getFqnForAlias($alias, $for_class);
1125
-    }
23
+	/**
24
+	 * This means that the requested class dependency is not present in the dependency map
25
+	 */
26
+	const not_registered = 0;
27
+
28
+	/**
29
+	 * This instructs class loaders to ALWAYS return a newly instantiated object for the requested class.
30
+	 */
31
+	const load_new_object = 1;
32
+
33
+	/**
34
+	 * This instructs class loaders to return a previously instantiated and cached object for the requested class.
35
+	 * IF a previously instantiated object does not exist, a new one will be created and added to the cache.
36
+	 */
37
+	const load_from_cache = 2;
38
+
39
+	/**
40
+	 * When registering a dependency,
41
+	 * this indicates to keep any existing dependencies that already exist,
42
+	 * and simply discard any new dependencies declared in the incoming data
43
+	 */
44
+	const KEEP_EXISTING_DEPENDENCIES = 0;
45
+
46
+	/**
47
+	 * When registering a dependency,
48
+	 * this indicates to overwrite any existing dependencies that already exist using the incoming data
49
+	 */
50
+	const OVERWRITE_DEPENDENCIES = 1;
51
+
52
+
53
+	/**
54
+	 * @type EE_Dependency_Map $_instance
55
+	 */
56
+	protected static $_instance;
57
+
58
+	/**
59
+	 * @var ClassInterfaceCache $class_cache
60
+	 */
61
+	private $class_cache;
62
+
63
+	/**
64
+	 * @type RequestInterface $request
65
+	 */
66
+	protected $request;
67
+
68
+	/**
69
+	 * @type LegacyRequestInterface $legacy_request
70
+	 */
71
+	protected $legacy_request;
72
+
73
+	/**
74
+	 * @type ResponseInterface $response
75
+	 */
76
+	protected $response;
77
+
78
+	/**
79
+	 * @type LoaderInterface $loader
80
+	 */
81
+	protected $loader;
82
+
83
+	/**
84
+	 * @type array $_dependency_map
85
+	 */
86
+	protected $_dependency_map = array();
87
+
88
+	/**
89
+	 * @type array $_class_loaders
90
+	 */
91
+	protected $_class_loaders = array();
92
+
93
+
94
+	/**
95
+	 * EE_Dependency_Map constructor.
96
+	 *
97
+	 * @param ClassInterfaceCache $class_cache
98
+	 */
99
+	protected function __construct(ClassInterfaceCache $class_cache)
100
+	{
101
+		$this->class_cache = $class_cache;
102
+		do_action('EE_Dependency_Map____construct', $this);
103
+	}
104
+
105
+
106
+	/**
107
+	 * @return void
108
+	 */
109
+	public function initialize()
110
+	{
111
+		$this->_register_core_dependencies();
112
+		$this->_register_core_class_loaders();
113
+		$this->_register_core_aliases();
114
+	}
115
+
116
+
117
+	/**
118
+	 * @singleton method used to instantiate class object
119
+	 * @param ClassInterfaceCache|null $class_cache
120
+	 * @return EE_Dependency_Map
121
+	 */
122
+	public static function instance(ClassInterfaceCache $class_cache = null)
123
+	{
124
+		// check if class object is instantiated, and instantiated properly
125
+		if (! self::$_instance instanceof EE_Dependency_Map
126
+			&& $class_cache instanceof ClassInterfaceCache
127
+		) {
128
+			self::$_instance = new EE_Dependency_Map($class_cache);
129
+		}
130
+		return self::$_instance;
131
+	}
132
+
133
+
134
+	/**
135
+	 * @param RequestInterface $request
136
+	 */
137
+	public function setRequest(RequestInterface $request)
138
+	{
139
+		$this->request = $request;
140
+	}
141
+
142
+
143
+	/**
144
+	 * @param LegacyRequestInterface $legacy_request
145
+	 */
146
+	public function setLegacyRequest(LegacyRequestInterface $legacy_request)
147
+	{
148
+		$this->legacy_request = $legacy_request;
149
+	}
150
+
151
+
152
+	/**
153
+	 * @param ResponseInterface $response
154
+	 */
155
+	public function setResponse(ResponseInterface $response)
156
+	{
157
+		$this->response = $response;
158
+	}
159
+
160
+
161
+	/**
162
+	 * @param LoaderInterface $loader
163
+	 */
164
+	public function setLoader(LoaderInterface $loader)
165
+	{
166
+		$this->loader = $loader;
167
+	}
168
+
169
+
170
+	/**
171
+	 * @param string $class
172
+	 * @param array  $dependencies
173
+	 * @param int    $overwrite
174
+	 * @return bool
175
+	 */
176
+	public static function register_dependencies(
177
+		$class,
178
+		array $dependencies,
179
+		$overwrite = EE_Dependency_Map::KEEP_EXISTING_DEPENDENCIES
180
+	) {
181
+		return self::$_instance->registerDependencies($class, $dependencies, $overwrite);
182
+	}
183
+
184
+
185
+	/**
186
+	 * Assigns an array of class names and corresponding load sources (new or cached)
187
+	 * to the class specified by the first parameter.
188
+	 * IMPORTANT !!!
189
+	 * The order of elements in the incoming $dependencies array MUST match
190
+	 * the order of the constructor parameters for the class in question.
191
+	 * This is especially important when overriding any existing dependencies that are registered.
192
+	 * the third parameter controls whether any duplicate dependencies are overwritten or not.
193
+	 *
194
+	 * @param string $class
195
+	 * @param array  $dependencies
196
+	 * @param int    $overwrite
197
+	 * @return bool
198
+	 */
199
+	public function registerDependencies(
200
+		$class,
201
+		array $dependencies,
202
+		$overwrite = EE_Dependency_Map::KEEP_EXISTING_DEPENDENCIES
203
+	) {
204
+		$class = trim($class, '\\');
205
+		$registered = false;
206
+		if (empty(self::$_instance->_dependency_map[ $class ])) {
207
+			self::$_instance->_dependency_map[ $class ] = array();
208
+		}
209
+		// we need to make sure that any aliases used when registering a dependency
210
+		// get resolved to the correct class name
211
+		foreach ($dependencies as $dependency => $load_source) {
212
+			$alias = self::$_instance->getFqnForAlias($dependency);
213
+			if ($overwrite === EE_Dependency_Map::OVERWRITE_DEPENDENCIES
214
+				|| ! isset(self::$_instance->_dependency_map[ $class ][ $alias ])
215
+			) {
216
+				unset($dependencies[ $dependency ]);
217
+				$dependencies[ $alias ] = $load_source;
218
+				$registered = true;
219
+			}
220
+		}
221
+		// now add our two lists of dependencies together.
222
+		// using Union (+=) favours the arrays in precedence from left to right,
223
+		// so $dependencies is NOT overwritten because it is listed first
224
+		// ie: with A = B + C, entries in B take precedence over duplicate entries in C
225
+		// Union is way faster than array_merge() but should be used with caution...
226
+		// especially with numerically indexed arrays
227
+		$dependencies += self::$_instance->_dependency_map[ $class ];
228
+		// now we need to ensure that the resulting dependencies
229
+		// array only has the entries that are required for the class
230
+		// so first count how many dependencies were originally registered for the class
231
+		$dependency_count = count(self::$_instance->_dependency_map[ $class ]);
232
+		// if that count is non-zero (meaning dependencies were already registered)
233
+		self::$_instance->_dependency_map[ $class ] = $dependency_count
234
+			// then truncate the  final array to match that count
235
+			? array_slice($dependencies, 0, $dependency_count)
236
+			// otherwise just take the incoming array because nothing previously existed
237
+			: $dependencies;
238
+		return $registered;
239
+	}
240
+
241
+
242
+	/**
243
+	 * @param string $class_name
244
+	 * @param string $loader
245
+	 * @return bool
246
+	 * @throws DomainException
247
+	 */
248
+	public static function register_class_loader($class_name, $loader = 'load_core')
249
+	{
250
+		if (! $loader instanceof Closure && strpos($class_name, '\\') !== false) {
251
+			throw new DomainException(
252
+				esc_html__('Don\'t use class loaders for FQCNs.', 'event_espresso')
253
+			);
254
+		}
255
+		// check that loader is callable or method starts with "load_" and exists in EE_Registry
256
+		if (! is_callable($loader)
257
+			&& (
258
+				strpos($loader, 'load_') !== 0
259
+				|| ! method_exists('EE_Registry', $loader)
260
+			)
261
+		) {
262
+			throw new DomainException(
263
+				sprintf(
264
+					esc_html__(
265
+						'"%1$s" is not a valid loader method on EE_Registry.',
266
+						'event_espresso'
267
+					),
268
+					$loader
269
+				)
270
+			);
271
+		}
272
+		$class_name = self::$_instance->getFqnForAlias($class_name);
273
+		if (! isset(self::$_instance->_class_loaders[ $class_name ])) {
274
+			self::$_instance->_class_loaders[ $class_name ] = $loader;
275
+			return true;
276
+		}
277
+		return false;
278
+	}
279
+
280
+
281
+	/**
282
+	 * @return array
283
+	 */
284
+	public function dependency_map()
285
+	{
286
+		return $this->_dependency_map;
287
+	}
288
+
289
+
290
+	/**
291
+	 * returns TRUE if dependency map contains a listing for the provided class name
292
+	 *
293
+	 * @param string $class_name
294
+	 * @return boolean
295
+	 */
296
+	public function has($class_name = '')
297
+	{
298
+		// all legacy models have the same dependencies
299
+		if (strpos($class_name, 'EEM_') === 0) {
300
+			$class_name = 'LEGACY_MODELS';
301
+		}
302
+		return isset($this->_dependency_map[ $class_name ]) ? true : false;
303
+	}
304
+
305
+
306
+	/**
307
+	 * returns TRUE if dependency map contains a listing for the provided class name AND dependency
308
+	 *
309
+	 * @param string $class_name
310
+	 * @param string $dependency
311
+	 * @return bool
312
+	 */
313
+	public function has_dependency_for_class($class_name = '', $dependency = '')
314
+	{
315
+		// all legacy models have the same dependencies
316
+		if (strpos($class_name, 'EEM_') === 0) {
317
+			$class_name = 'LEGACY_MODELS';
318
+		}
319
+		$dependency = $this->getFqnForAlias($dependency, $class_name);
320
+		return isset($this->_dependency_map[ $class_name ][ $dependency ])
321
+			? true
322
+			: false;
323
+	}
324
+
325
+
326
+	/**
327
+	 * returns loading strategy for whether a previously cached dependency should be loaded or a new instance returned
328
+	 *
329
+	 * @param string $class_name
330
+	 * @param string $dependency
331
+	 * @return int
332
+	 */
333
+	public function loading_strategy_for_class_dependency($class_name = '', $dependency = '')
334
+	{
335
+		// all legacy models have the same dependencies
336
+		if (strpos($class_name, 'EEM_') === 0) {
337
+			$class_name = 'LEGACY_MODELS';
338
+		}
339
+		$dependency = $this->getFqnForAlias($dependency);
340
+		return $this->has_dependency_for_class($class_name, $dependency)
341
+			? $this->_dependency_map[ $class_name ][ $dependency ]
342
+			: EE_Dependency_Map::not_registered;
343
+	}
344
+
345
+
346
+	/**
347
+	 * @param string $class_name
348
+	 * @return string | Closure
349
+	 */
350
+	public function class_loader($class_name)
351
+	{
352
+		// all legacy models use load_model()
353
+		if (strpos($class_name, 'EEM_') === 0) {
354
+			return 'load_model';
355
+		}
356
+		// EE_CPT_*_Strategy classes like EE_CPT_Event_Strategy, EE_CPT_Venue_Strategy, etc
357
+		// perform strpos() first to avoid loading regex every time we load a class
358
+		if (strpos($class_name, 'EE_CPT_') === 0
359
+			&& preg_match('/^EE_CPT_([a-zA-Z]+)_Strategy$/', $class_name)
360
+		) {
361
+			return 'load_core';
362
+		}
363
+		$class_name = $this->getFqnForAlias($class_name);
364
+		return isset($this->_class_loaders[ $class_name ]) ? $this->_class_loaders[ $class_name ] : '';
365
+	}
366
+
367
+
368
+	/**
369
+	 * @return array
370
+	 */
371
+	public function class_loaders()
372
+	{
373
+		return $this->_class_loaders;
374
+	}
375
+
376
+
377
+	/**
378
+	 * adds an alias for a classname
379
+	 *
380
+	 * @param string $fqcn      the class name that should be used (concrete class to replace interface)
381
+	 * @param string $alias     the class name that would be type hinted for (abstract parent or interface)
382
+	 * @param string $for_class the class that has the dependency (is type hinting for the interface)
383
+	 */
384
+	public function add_alias($fqcn, $alias, $for_class = '')
385
+	{
386
+		$this->class_cache->addAlias($fqcn, $alias, $for_class);
387
+	}
388
+
389
+
390
+	/**
391
+	 * Returns TRUE if the provided fully qualified name IS an alias
392
+	 * WHY?
393
+	 * Because if a class is type hinting for a concretion,
394
+	 * then why would we need to find another class to supply it?
395
+	 * ie: if a class asks for `Fully/Qualified/Namespace/SpecificClassName`,
396
+	 * then give it an instance of `Fully/Qualified/Namespace/SpecificClassName`.
397
+	 * Don't go looking for some substitute.
398
+	 * Whereas if a class is type hinting for an interface...
399
+	 * then we need to find an actual class to use.
400
+	 * So the interface IS the alias for some other FQN,
401
+	 * and we need to find out if `Fully/Qualified/Namespace/SomeInterface`
402
+	 * represents some other class.
403
+	 *
404
+	 * @param string $fqn
405
+	 * @param string $for_class
406
+	 * @return bool
407
+	 */
408
+	public function isAlias($fqn = '', $for_class = '')
409
+	{
410
+		return $this->class_cache->isAlias($fqn, $for_class);
411
+	}
412
+
413
+
414
+	/**
415
+	 * Returns a FQN for provided alias if one exists, otherwise returns the original $alias
416
+	 * functions recursively, so that multiple aliases can be used to drill down to a FQN
417
+	 *  for example:
418
+	 *      if the following two entries were added to the _aliases array:
419
+	 *          array(
420
+	 *              'interface_alias'           => 'some\namespace\interface'
421
+	 *              'some\namespace\interface'  => 'some\namespace\classname'
422
+	 *          )
423
+	 *      then one could use EE_Registry::instance()->create( 'interface_alias' )
424
+	 *      to load an instance of 'some\namespace\classname'
425
+	 *
426
+	 * @param string $alias
427
+	 * @param string $for_class
428
+	 * @return string
429
+	 */
430
+	public function getFqnForAlias($alias = '', $for_class = '')
431
+	{
432
+		return (string) $this->class_cache->getFqnForAlias($alias, $for_class);
433
+	}
434
+
435
+
436
+	/**
437
+	 * Registers the core dependencies and whether a previously instantiated object should be loaded from the cache,
438
+	 * if one exists, or whether a new object should be generated every time the requested class is loaded.
439
+	 * This is done by using the following class constants:
440
+	 *        EE_Dependency_Map::load_from_cache - loads previously instantiated object
441
+	 *        EE_Dependency_Map::load_new_object - generates a new object every time
442
+	 */
443
+	protected function _register_core_dependencies()
444
+	{
445
+		$this->_dependency_map = array(
446
+			'EE_Request_Handler'                                                                                          => array(
447
+				'EE_Request' => EE_Dependency_Map::load_from_cache,
448
+			),
449
+			'EE_System'                                                                                                   => array(
450
+				'EE_Registry'                                 => EE_Dependency_Map::load_from_cache,
451
+				'EventEspresso\core\services\loaders\Loader'  => EE_Dependency_Map::load_from_cache,
452
+				'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
453
+				'EE_Maintenance_Mode'                         => EE_Dependency_Map::load_from_cache,
454
+			),
455
+			'EE_Session'                                                                                                  => array(
456
+				'EventEspresso\core\services\cache\TransientCacheStorage'  => EE_Dependency_Map::load_from_cache,
457
+				'EventEspresso\core\domain\values\session\SessionLifespan' => EE_Dependency_Map::load_from_cache,
458
+				'EventEspresso\core\services\request\Request'              => EE_Dependency_Map::load_from_cache,
459
+				'EventEspresso\core\services\session\SessionStartHandler'  => EE_Dependency_Map::load_from_cache,
460
+				'EE_Encryption'                                            => EE_Dependency_Map::load_from_cache,
461
+			),
462
+			'EE_Cart'                                                                                                     => array(
463
+				'EE_Session' => EE_Dependency_Map::load_from_cache,
464
+			),
465
+			'EE_Front_Controller'                                                                                         => array(
466
+				'EE_Registry'              => EE_Dependency_Map::load_from_cache,
467
+				'EE_Request_Handler'       => EE_Dependency_Map::load_from_cache,
468
+				'EE_Module_Request_Router' => EE_Dependency_Map::load_from_cache,
469
+			),
470
+			'EE_Messenger_Collection_Loader'                                                                              => array(
471
+				'EE_Messenger_Collection' => EE_Dependency_Map::load_new_object,
472
+			),
473
+			'EE_Message_Type_Collection_Loader'                                                                           => array(
474
+				'EE_Message_Type_Collection' => EE_Dependency_Map::load_new_object,
475
+			),
476
+			'EE_Message_Resource_Manager'                                                                                 => array(
477
+				'EE_Messenger_Collection_Loader'    => EE_Dependency_Map::load_new_object,
478
+				'EE_Message_Type_Collection_Loader' => EE_Dependency_Map::load_new_object,
479
+				'EEM_Message_Template_Group'        => EE_Dependency_Map::load_from_cache,
480
+			),
481
+			'EE_Message_Factory'                                                                                          => array(
482
+				'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
483
+			),
484
+			'EE_messages'                                                                                                 => array(
485
+				'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
486
+			),
487
+			'EE_Messages_Generator'                                                                                       => array(
488
+				'EE_Messages_Queue'                    => EE_Dependency_Map::load_new_object,
489
+				'EE_Messages_Data_Handler_Collection'  => EE_Dependency_Map::load_new_object,
490
+				'EE_Message_Template_Group_Collection' => EE_Dependency_Map::load_new_object,
491
+				'EEH_Parse_Shortcodes'                 => EE_Dependency_Map::load_from_cache,
492
+			),
493
+			'EE_Messages_Processor'                                                                                       => array(
494
+				'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
495
+			),
496
+			'EE_Messages_Queue'                                                                                           => array(
497
+				'EE_Message_Repository' => EE_Dependency_Map::load_new_object,
498
+			),
499
+			'EE_Messages_Template_Defaults'                                                                               => array(
500
+				'EEM_Message_Template_Group' => EE_Dependency_Map::load_from_cache,
501
+				'EEM_Message_Template'       => EE_Dependency_Map::load_from_cache,
502
+			),
503
+			'EE_Message_To_Generate_From_Request'                                                                         => array(
504
+				'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
505
+				'EE_Request_Handler'          => EE_Dependency_Map::load_from_cache,
506
+			),
507
+			'EventEspresso\core\services\commands\CommandBus'                                                             => array(
508
+				'EventEspresso\core\services\commands\CommandHandlerManager' => EE_Dependency_Map::load_from_cache,
509
+			),
510
+			'EventEspresso\services\commands\CommandHandler'                                                              => array(
511
+				'EE_Registry'         => EE_Dependency_Map::load_from_cache,
512
+				'CommandBusInterface' => EE_Dependency_Map::load_from_cache,
513
+			),
514
+			'EventEspresso\core\services\commands\CommandHandlerManager'                                                  => array(
515
+				'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
516
+			),
517
+			'EventEspresso\core\services\commands\CompositeCommandHandler'                                                => array(
518
+				'EventEspresso\core\services\commands\CommandBus'     => EE_Dependency_Map::load_from_cache,
519
+				'EventEspresso\core\services\commands\CommandFactory' => EE_Dependency_Map::load_from_cache,
520
+			),
521
+			'EventEspresso\core\services\commands\CommandFactory'                                                         => array(
522
+				'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
523
+			),
524
+			'EventEspresso\core\services\commands\middleware\CapChecker'                                                  => array(
525
+				'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker' => EE_Dependency_Map::load_from_cache,
526
+			),
527
+			'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker'                                         => array(
528
+				'EE_Capabilities' => EE_Dependency_Map::load_from_cache,
529
+			),
530
+			'EventEspresso\core\domain\services\capabilities\RegistrationsCapChecker'                                     => array(
531
+				'EE_Capabilities' => EE_Dependency_Map::load_from_cache,
532
+			),
533
+			'EventEspresso\core\services\commands\registration\CreateRegistrationCommandHandler'                          => array(
534
+				'EventEspresso\core\domain\services\registration\CreateRegistrationService' => EE_Dependency_Map::load_from_cache,
535
+			),
536
+			'EventEspresso\core\services\commands\registration\CopyRegistrationDetailsCommandHandler'                     => array(
537
+				'EventEspresso\core\domain\services\registration\CopyRegistrationService' => EE_Dependency_Map::load_from_cache,
538
+			),
539
+			'EventEspresso\core\services\commands\registration\CopyRegistrationPaymentsCommandHandler'                    => array(
540
+				'EventEspresso\core\domain\services\registration\CopyRegistrationService' => EE_Dependency_Map::load_from_cache,
541
+			),
542
+			'EventEspresso\core\services\commands\registration\CancelRegistrationAndTicketLineItemCommandHandler'         => array(
543
+				'EventEspresso\core\domain\services\registration\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
544
+			),
545
+			'EventEspresso\core\services\commands\registration\UpdateRegistrationAndTransactionAfterChangeCommandHandler' => array(
546
+				'EventEspresso\core\domain\services\registration\UpdateRegistrationService' => EE_Dependency_Map::load_from_cache,
547
+			),
548
+			'EventEspresso\core\services\commands\ticket\CreateTicketLineItemCommandHandler'                              => array(
549
+				'EventEspresso\core\domain\services\ticket\CreateTicketLineItemService' => EE_Dependency_Map::load_from_cache,
550
+			),
551
+			'EventEspresso\core\services\commands\ticket\CancelTicketLineItemCommandHandler'                              => array(
552
+				'EventEspresso\core\domain\services\ticket\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
553
+			),
554
+			'EventEspresso\core\domain\services\registration\CancelRegistrationService'                                   => array(
555
+				'EventEspresso\core\domain\services\ticket\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
556
+			),
557
+			'EventEspresso\core\services\commands\attendee\CreateAttendeeCommandHandler'                                  => array(
558
+				'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
559
+			),
560
+			'EventEspresso\core\services\database\TableManager'                                                           => array(
561
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
562
+			),
563
+			'EE_Data_Migration_Class_Base'                                                                                => array(
564
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
565
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
566
+			),
567
+			'EE_DMS_Core_4_1_0'                                                                                           => array(
568
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
569
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
570
+			),
571
+			'EE_DMS_Core_4_2_0'                                                                                           => array(
572
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
573
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
574
+			),
575
+			'EE_DMS_Core_4_3_0'                                                                                           => array(
576
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
577
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
578
+			),
579
+			'EE_DMS_Core_4_4_0'                                                                                           => array(
580
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
581
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
582
+			),
583
+			'EE_DMS_Core_4_5_0'                                                                                           => array(
584
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
585
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
586
+			),
587
+			'EE_DMS_Core_4_6_0'                                                                                           => array(
588
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
589
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
590
+			),
591
+			'EE_DMS_Core_4_7_0'                                                                                           => array(
592
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
593
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
594
+			),
595
+			'EE_DMS_Core_4_8_0'                                                                                           => array(
596
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
597
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
598
+			),
599
+			'EE_DMS_Core_4_9_0' => array(
600
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
601
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
602
+			),
603
+			'EE_DMS_Core_4_10_0' => array(
604
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
605
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
606
+				'EE_DMS_Core_4_9_0'                                  => EE_Dependency_Map::load_from_cache,
607
+			),
608
+			'EventEspresso\core\services\assets\I18nRegistry'                                                             => array(
609
+				array(),
610
+				'EventEspresso\core\domain\Domain' => EE_Dependency_Map::load_from_cache,
611
+			),
612
+			'EventEspresso\core\services\assets\Registry'                                                                 => array(
613
+				'EventEspresso\core\services\assets\AssetCollection' => EE_Dependency_Map::load_from_cache,
614
+				'EventEspresso\core\services\assets\I18nRegistry'    => EE_Dependency_Map::load_from_cache,
615
+			),
616
+			'EventEspresso\core\domain\entities\shortcodes\EspressoCancelled'                                             => array(
617
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
618
+			),
619
+			'EventEspresso\core\domain\entities\shortcodes\EspressoCheckout'                                              => array(
620
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
621
+			),
622
+			'EventEspresso\core\domain\entities\shortcodes\EspressoEventAttendees'                                        => array(
623
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
624
+			),
625
+			'EventEspresso\core\domain\entities\shortcodes\EspressoEvents'                                                => array(
626
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
627
+			),
628
+			'EventEspresso\core\domain\entities\shortcodes\EspressoThankYou'                                              => array(
629
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
630
+			),
631
+			'EventEspresso\core\domain\entities\shortcodes\EspressoTicketSelector'                                        => array(
632
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
633
+			),
634
+			'EventEspresso\core\domain\entities\shortcodes\EspressoTxnPage'                                               => array(
635
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
636
+			),
637
+			'EventEspresso\core\services\cache\BasicCacheManager'                                                         => array(
638
+				'EventEspresso\core\services\cache\TransientCacheStorage' => EE_Dependency_Map::load_from_cache,
639
+			),
640
+			'EventEspresso\core\services\cache\PostRelatedCacheManager'                                                   => array(
641
+				'EventEspresso\core\services\cache\TransientCacheStorage' => EE_Dependency_Map::load_from_cache,
642
+			),
643
+			'EventEspresso\core\domain\services\validation\email\EmailValidationService'                                  => array(
644
+				'EE_Registration_Config'                     => EE_Dependency_Map::load_from_cache,
645
+				'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
646
+			),
647
+			'EventEspresso\core\domain\values\EmailAddress'                                                               => array(
648
+				null,
649
+				'EventEspresso\core\domain\services\validation\email\EmailValidationService' => EE_Dependency_Map::load_from_cache,
650
+			),
651
+			'EventEspresso\core\services\orm\ModelFieldFactory'                                                           => array(
652
+				'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
653
+			),
654
+			'LEGACY_MODELS'                                                                                               => array(
655
+				null,
656
+				'EventEspresso\core\services\database\ModelFieldFactory' => EE_Dependency_Map::load_from_cache,
657
+			),
658
+			'EE_Module_Request_Router'                                                                                    => array(
659
+				'EE_Request' => EE_Dependency_Map::load_from_cache,
660
+			),
661
+			'EE_Registration_Processor'                                                                                   => array(
662
+				'EE_Request' => EE_Dependency_Map::load_from_cache,
663
+			),
664
+			'EventEspresso\core\services\notifications\PersistentAdminNoticeManager'                                      => array(
665
+				null,
666
+				'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker' => EE_Dependency_Map::load_from_cache,
667
+				'EventEspresso\core\services\request\Request'                         => EE_Dependency_Map::load_from_cache,
668
+			),
669
+			'EventEspresso\core\services\licensing\LicenseService'                                                        => array(
670
+				'EventEspresso\core\domain\services\pue\Stats'  => EE_Dependency_Map::load_from_cache,
671
+				'EventEspresso\core\domain\services\pue\Config' => EE_Dependency_Map::load_from_cache,
672
+			),
673
+			'EE_Admin_Transactions_List_Table'                                                                            => array(
674
+				null,
675
+				'EventEspresso\core\domain\values\session\SessionLifespan' => EE_Dependency_Map::load_from_cache,
676
+			),
677
+			'EventEspresso\core\domain\services\pue\Stats'                                                                => array(
678
+				'EventEspresso\core\domain\services\pue\Config'        => EE_Dependency_Map::load_from_cache,
679
+				'EE_Maintenance_Mode'                                  => EE_Dependency_Map::load_from_cache,
680
+				'EventEspresso\core\domain\services\pue\StatsGatherer' => EE_Dependency_Map::load_from_cache,
681
+			),
682
+			'EventEspresso\core\domain\services\pue\Config'                                                               => array(
683
+				'EE_Network_Config' => EE_Dependency_Map::load_from_cache,
684
+				'EE_Config'         => EE_Dependency_Map::load_from_cache,
685
+			),
686
+			'EventEspresso\core\domain\services\pue\StatsGatherer'                                                        => array(
687
+				'EEM_Payment_Method' => EE_Dependency_Map::load_from_cache,
688
+				'EEM_Event'          => EE_Dependency_Map::load_from_cache,
689
+				'EEM_Datetime'       => EE_Dependency_Map::load_from_cache,
690
+				'EEM_Ticket'         => EE_Dependency_Map::load_from_cache,
691
+				'EEM_Registration'   => EE_Dependency_Map::load_from_cache,
692
+				'EEM_Transaction'    => EE_Dependency_Map::load_from_cache,
693
+				'EE_Config'          => EE_Dependency_Map::load_from_cache,
694
+			),
695
+			'EventEspresso\core\domain\services\admin\ExitModal'                                                          => array(
696
+				'EventEspresso\core\services\assets\Registry' => EE_Dependency_Map::load_from_cache,
697
+			),
698
+			'EventEspresso\core\domain\services\admin\PluginUpsells'                                                      => array(
699
+				'EventEspresso\core\domain\Domain' => EE_Dependency_Map::load_from_cache,
700
+			),
701
+			'EventEspresso\caffeinated\modules\recaptcha_invisible\InvisibleRecaptcha'                                    => array(
702
+				'EE_Registration_Config' => EE_Dependency_Map::load_from_cache,
703
+				'EE_Session'             => EE_Dependency_Map::load_from_cache,
704
+			),
705
+			'EventEspresso\caffeinated\modules\recaptcha_invisible\RecaptchaAdminSettings'                                => array(
706
+				'EE_Registration_Config' => EE_Dependency_Map::load_from_cache,
707
+			),
708
+			'EventEspresso\modules\ticket_selector\ProcessTicketSelector'                                                 => array(
709
+				'EE_Core_Config'                                                          => EE_Dependency_Map::load_from_cache,
710
+				'EventEspresso\core\services\request\Request'                             => EE_Dependency_Map::load_from_cache,
711
+				'EE_Session'                                                              => EE_Dependency_Map::load_from_cache,
712
+				'EEM_Ticket'                                                              => EE_Dependency_Map::load_from_cache,
713
+				'EventEspresso\modules\ticket_selector\TicketDatetimeAvailabilityTracker' => EE_Dependency_Map::load_from_cache,
714
+			),
715
+			'EventEspresso\modules\ticket_selector\TicketDatetimeAvailabilityTracker'                                     => array(
716
+				'EEM_Datetime' => EE_Dependency_Map::load_from_cache,
717
+			),
718
+			'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'                              => array(
719
+				'EE_Core_Config'                             => EE_Dependency_Map::load_from_cache,
720
+				'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
721
+			),
722
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes'                                => array(
723
+				'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions' => EE_Dependency_Map::load_from_cache,
724
+			),
725
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies'                               => array(
726
+				'EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions' => EE_Dependency_Map::load_from_cache,
727
+			),
728
+			'EE_CPT_Strategy'                                                                                             => array(
729
+				'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions' => EE_Dependency_Map::load_from_cache,
730
+				'EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions' => EE_Dependency_Map::load_from_cache,
731
+			),
732
+			'EventEspresso\core\services\loaders\ObjectIdentifier'                                                        => array(
733
+				'EventEspresso\core\services\loaders\ClassInterfaceCache' => EE_Dependency_Map::load_from_cache,
734
+			),
735
+			'EventEspresso\core\domain\services\assets\CoreAssetManager'                                                  => array(
736
+				'EventEspresso\core\services\assets\AssetCollection' => EE_Dependency_Map::load_from_cache,
737
+				'EE_Currency_Config'                                 => EE_Dependency_Map::load_from_cache,
738
+				'EE_Template_Config'                                 => EE_Dependency_Map::load_from_cache,
739
+				'EventEspresso\core\domain\Domain'                   => EE_Dependency_Map::load_from_cache,
740
+				'EventEspresso\core\services\assets\Registry'        => EE_Dependency_Map::load_from_cache,
741
+			),
742
+			'EventEspresso\core\domain\services\admin\privacy\policy\PrivacyPolicy' => array(
743
+				'EEM_Payment_Method' => EE_Dependency_Map::load_from_cache,
744
+				'EventEspresso\core\domain\values\session\SessionLifespan' => EE_Dependency_Map::load_from_cache
745
+			),
746
+			'EventEspresso\core\domain\services\admin\privacy\export\ExportAttendee' => array(
747
+				'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
748
+			),
749
+			'EventEspresso\core\domain\services\admin\privacy\export\ExportAttendeeBillingData' => array(
750
+				'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
751
+				'EEM_Payment_Method' => EE_Dependency_Map::load_from_cache
752
+			),
753
+			'EventEspresso\core\domain\services\admin\privacy\export\ExportCheckins' => array(
754
+				'EEM_Checkin' => EE_Dependency_Map::load_from_cache,
755
+			),
756
+			'EventEspresso\core\domain\services\admin\privacy\export\ExportRegistration' => array(
757
+				'EEM_Registration' => EE_Dependency_Map::load_from_cache,
758
+			),
759
+			'EventEspresso\core\domain\services\admin\privacy\export\ExportTransaction' => array(
760
+				'EEM_Transaction' => EE_Dependency_Map::load_from_cache,
761
+			),
762
+			'EventEspresso\core\domain\services\admin\privacy\erasure\EraseAttendeeData' => array(
763
+				'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
764
+			),
765
+			'EventEspresso\core\domain\services\admin\privacy\erasure\EraseAnswers' => array(
766
+				'EEM_Answer' => EE_Dependency_Map::load_from_cache,
767
+				'EEM_Question' => EE_Dependency_Map::load_from_cache,
768
+			),
769
+			'EventEspresso\core\CPTs\CptQueryModifier' => array(
770
+				null,
771
+				null,
772
+				null,
773
+				'EE_Request_Handler'                          => EE_Dependency_Map::load_from_cache,
774
+				'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
775
+				'EventEspresso\core\services\loaders\Loader'  => EE_Dependency_Map::load_from_cache,
776
+			),
777
+			'EventEspresso\core\domain\services\admin\privacy\forms\PrivacySettingsFormHandler' => array(
778
+				'EE_Registry' => EE_Dependency_Map::load_from_cache,
779
+				'EE_Config' => EE_Dependency_Map::load_from_cache
780
+			),
781
+			'EventEspresso\core\services\editor\BlockRegistrationManager'                                                 => array(
782
+				'EventEspresso\core\services\assets\BlockAssetManagerCollection' => EE_Dependency_Map::load_from_cache,
783
+				'EventEspresso\core\domain\entities\editor\BlockCollection'      => EE_Dependency_Map::load_from_cache,
784
+				'EventEspresso\core\services\route_match\RouteMatchSpecificationManager' => EE_Dependency_Map::load_from_cache,
785
+				'EventEspresso\core\services\request\Request'                    => EE_Dependency_Map::load_from_cache,
786
+			),
787
+			'EventEspresso\core\domain\entities\editor\CoreBlocksAssetManager' => array(
788
+				'EventEspresso\core\domain\Domain'                   => EE_Dependency_Map::load_from_cache,
789
+				'EventEspresso\core\services\assets\AssetCollection' => EE_Dependency_Map::load_from_cache,
790
+				'EventEspresso\core\services\assets\Registry'        => EE_Dependency_Map::load_from_cache,
791
+			),
792
+			'EventEspresso\core\domain\services\blocks\EventAttendeesBlockRenderer' => array(
793
+				'EventEspresso\core\domain\Domain' => EE_Dependency_Map::load_from_cache,
794
+				'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
795
+			),
796
+			'EventEspresso\core\domain\entities\editor\blocks\EventAttendees' => array(
797
+				'EventEspresso\core\domain\entities\editor\CoreBlocksAssetManager' => self::load_from_cache,
798
+				'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
799
+				'EventEspresso\core\domain\services\blocks\EventAttendeesBlockRenderer' => self::load_from_cache,
800
+			),
801
+			'EventEspresso\core\services\route_match\RouteMatchSpecificationDependencyResolver' => array(
802
+				'EventEspresso\core\services\container\Mirror' => EE_Dependency_Map::load_from_cache,
803
+				'EventEspresso\core\services\loaders\ClassInterfaceCache' => EE_Dependency_Map::load_from_cache,
804
+				'EE_Dependency_Map' => EE_Dependency_Map::load_from_cache,
805
+			),
806
+			'EventEspresso\core\services\route_match\RouteMatchSpecificationFactory' => array(
807
+				'EventEspresso\core\services\route_match\RouteMatchSpecificationDependencyResolver' => EE_Dependency_Map::load_from_cache,
808
+				'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
809
+			),
810
+			'EventEspresso\core\services\route_match\RouteMatchSpecificationManager' => array(
811
+				'EventEspresso\core\services\route_match\RouteMatchSpecificationCollection' => EE_Dependency_Map::load_from_cache,
812
+				'EventEspresso\core\services\route_match\RouteMatchSpecificationFactory' => EE_Dependency_Map::load_from_cache,
813
+			),
814
+			'EventEspresso\core\libraries\rest_api\CalculatedModelFields' => array(
815
+				'EventEspresso\core\libraries\rest_api\calculations\CalculatedModelFieldsFactory' => EE_Dependency_Map::load_from_cache
816
+			),
817
+			'EventEspresso\core\libraries\rest_api\calculations\CalculatedModelFieldsFactory' => array(
818
+				'EventEspresso\core\services\loaders\Loader'  => EE_Dependency_Map::load_from_cache,
819
+			),
820
+			'EventEspresso\core\libraries\rest_api\controllers\model\Read' => array(
821
+				'EventEspresso\core\libraries\rest_api\CalculatedModelFields' => EE_Dependency_Map::load_from_cache
822
+			),
823
+			'EventEspresso\core\libraries\rest_api\calculations\Datetime' => array(
824
+				'EEM_Datetime' => EE_Dependency_Map::load_from_cache,
825
+				'EEM_Registration' => EE_Dependency_Map::load_from_cache
826
+			),
827
+			'EventEspresso\core\libraries\rest_api\calculations\Event' => array(
828
+				'EEM_Event' => EE_Dependency_Map::load_from_cache,
829
+				'EEM_Registration' => EE_Dependency_Map::load_from_cache
830
+			),
831
+			'EventEspresso\core\libraries\rest_api\calculations\Registration' => array(
832
+				'EEM_Registration' => EE_Dependency_Map::load_from_cache
833
+			),
834
+			'EventEspresso\core\services\session\SessionStartHandler' => array(
835
+				'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
836
+			),
837
+			'EE_URL_Validation_Strategy' => array(
838
+				null,
839
+				null,
840
+				'EventEspresso\core\services\validators\URLValidator' => EE_Dependency_Map::load_from_cache
841
+			),
842
+			'EventEspresso\admin_pages\general_settings\OrganizationSettings' => array(
843
+				'EE_Registry'                                             => EE_Dependency_Map::load_from_cache,
844
+				'EE_Organization_Config'                                  => EE_Dependency_Map::load_from_cache,
845
+				'EE_Core_Config'                                          => EE_Dependency_Map::load_from_cache,
846
+				'EE_Network_Core_Config'                                  => EE_Dependency_Map::load_from_cache,
847
+				'EventEspresso\core\services\address\CountrySubRegionDao' => EE_Dependency_Map::load_from_cache,
848
+			),
849
+			'EventEspresso\core\services\address\CountrySubRegionDao' => array(
850
+				'EEM_State'                                            => EE_Dependency_Map::load_from_cache,
851
+				'EventEspresso\core\services\validators\JsonValidator' => EE_Dependency_Map::load_from_cache
852
+			),
853
+			'EventEspresso\core\domain\services\admin\ajax\WordpressHeartbeat' => array(
854
+				'EventEspresso\core\services\loaders\Loader'  => EE_Dependency_Map::load_from_cache,
855
+				'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
856
+			),
857
+			'EventEspresso\core\domain\services\admin\ajax\EventEditorHeartbeat' => array(
858
+				'EventEspresso\core\domain\Domain' => EE_Dependency_Map::load_from_cache,
859
+				'EE_Environment_Config'            => EE_Dependency_Map::load_from_cache,
860
+			),
861
+			'EventEspresso\core\services\request\files\FilesDataHandler' => array(
862
+				'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
863
+			),
864
+			'EventEspressoBatchRequest\BatchRequestProcessor' => [
865
+				'EventEspresso\core\services\loaders\Loader'  => EE_Dependency_Map::load_from_cache,
866
+			]
867
+		);
868
+	}
869
+
870
+
871
+	/**
872
+	 * Registers how core classes are loaded.
873
+	 * This can either be done by simply providing the name of one of the EE_Registry loader methods such as:
874
+	 *        'EE_Request_Handler' => 'load_core'
875
+	 *        'EE_Messages_Queue'  => 'load_lib'
876
+	 *        'EEH_Debug_Tools'    => 'load_helper'
877
+	 * or, if greater control is required, by providing a custom closure. For example:
878
+	 *        'Some_Class' => function () {
879
+	 *            return new Some_Class();
880
+	 *        },
881
+	 * This is required for instantiating dependencies
882
+	 * where an interface has been type hinted in a class constructor. For example:
883
+	 *        'Required_Interface' => function () {
884
+	 *            return new A_Class_That_Implements_Required_Interface();
885
+	 *        },
886
+	 */
887
+	protected function _register_core_class_loaders()
888
+	{
889
+		$this->_class_loaders = array(
890
+			// load_core
891
+			'EE_Dependency_Map'                            => function () {
892
+				return $this;
893
+			},
894
+			'EE_Capabilities'                              => 'load_core',
895
+			'EE_Encryption'                                => 'load_core',
896
+			'EE_Front_Controller'                          => 'load_core',
897
+			'EE_Module_Request_Router'                     => 'load_core',
898
+			'EE_Registry'                                  => 'load_core',
899
+			'EE_Request'                                   => function () {
900
+				return $this->legacy_request;
901
+			},
902
+			'EventEspresso\core\services\request\Request'  => function () {
903
+				return $this->request;
904
+			},
905
+			'EventEspresso\core\services\request\Response' => function () {
906
+				return $this->response;
907
+			},
908
+			'EE_Base'                                      => 'load_core',
909
+			'EE_Request_Handler'                           => 'load_core',
910
+			'EE_Session'                                   => 'load_core',
911
+			'EE_Cron_Tasks'                                => 'load_core',
912
+			'EE_System'                                    => 'load_core',
913
+			'EE_Maintenance_Mode'                          => 'load_core',
914
+			'EE_Register_CPTs'                             => 'load_core',
915
+			'EE_Admin'                                     => 'load_core',
916
+			'EE_CPT_Strategy'                              => 'load_core',
917
+			// load_class
918
+			'EE_Registration_Processor'                    => 'load_class',
919
+			// load_lib
920
+			'EE_Message_Resource_Manager'                  => 'load_lib',
921
+			'EE_Message_Type_Collection'                   => 'load_lib',
922
+			'EE_Message_Type_Collection_Loader'            => 'load_lib',
923
+			'EE_Messenger_Collection'                      => 'load_lib',
924
+			'EE_Messenger_Collection_Loader'               => 'load_lib',
925
+			'EE_Messages_Processor'                        => 'load_lib',
926
+			'EE_Message_Repository'                        => 'load_lib',
927
+			'EE_Messages_Queue'                            => 'load_lib',
928
+			'EE_Messages_Data_Handler_Collection'          => 'load_lib',
929
+			'EE_Message_Template_Group_Collection'         => 'load_lib',
930
+			'EE_Payment_Method_Manager'                    => 'load_lib',
931
+			'EE_DMS_Core_4_1_0'                            => 'load_dms',
932
+			'EE_DMS_Core_4_2_0'                            => 'load_dms',
933
+			'EE_DMS_Core_4_3_0'                            => 'load_dms',
934
+			'EE_DMS_Core_4_5_0'                            => 'load_dms',
935
+			'EE_DMS_Core_4_6_0'                            => 'load_dms',
936
+			'EE_DMS_Core_4_7_0'                            => 'load_dms',
937
+			'EE_DMS_Core_4_8_0'                            => 'load_dms',
938
+			'EE_DMS_Core_4_9_0'                            => 'load_dms',
939
+			'EE_DMS_Core_4_10_0'                            => 'load_dms',
940
+			'EE_Messages_Generator'                        => function () {
941
+				return EE_Registry::instance()->load_lib(
942
+					'Messages_Generator',
943
+					array(),
944
+					false,
945
+					false
946
+				);
947
+			},
948
+			'EE_Messages_Template_Defaults'                => function ($arguments = array()) {
949
+				return EE_Registry::instance()->load_lib(
950
+					'Messages_Template_Defaults',
951
+					$arguments,
952
+					false,
953
+					false
954
+				);
955
+			},
956
+			// load_helper
957
+			'EEH_Parse_Shortcodes'                         => function () {
958
+				if (EE_Registry::instance()->load_helper('Parse_Shortcodes')) {
959
+					return new EEH_Parse_Shortcodes();
960
+				}
961
+				return null;
962
+			},
963
+			'EE_Template_Config'                           => function () {
964
+				return EE_Config::instance()->template_settings;
965
+			},
966
+			'EE_Currency_Config'                           => function () {
967
+				return EE_Config::instance()->currency;
968
+			},
969
+			'EE_Registration_Config'                       => function () {
970
+				return EE_Config::instance()->registration;
971
+			},
972
+			'EE_Core_Config'                               => function () {
973
+				return EE_Config::instance()->core;
974
+			},
975
+			'EventEspresso\core\services\loaders\Loader'   => function () {
976
+				return LoaderFactory::getLoader();
977
+			},
978
+			'EE_Network_Config'                            => function () {
979
+				return EE_Network_Config::instance();
980
+			},
981
+			'EE_Config'                                    => function () {
982
+				return EE_Config::instance();
983
+			},
984
+			'EventEspresso\core\domain\Domain'             => function () {
985
+				return DomainFactory::getEventEspressoCoreDomain();
986
+			},
987
+			'EE_Admin_Config'                              => function () {
988
+				return EE_Config::instance()->admin;
989
+			},
990
+			'EE_Organization_Config'                       => function () {
991
+				return EE_Config::instance()->organization;
992
+			},
993
+			'EE_Network_Core_Config'                       => function () {
994
+				return EE_Network_Config::instance()->core;
995
+			},
996
+			'EE_Environment_Config'                        => function () {
997
+				return EE_Config::instance()->environment;
998
+			},
999
+		);
1000
+	}
1001
+
1002
+
1003
+	/**
1004
+	 * can be used for supplying alternate names for classes,
1005
+	 * or for connecting interface names to instantiable classes
1006
+	 */
1007
+	protected function _register_core_aliases()
1008
+	{
1009
+		$aliases = array(
1010
+			'CommandBusInterface'                                                          => 'EventEspresso\core\services\commands\CommandBusInterface',
1011
+			'EventEspresso\core\services\commands\CommandBusInterface'                     => 'EventEspresso\core\services\commands\CommandBus',
1012
+			'CommandHandlerManagerInterface'                                               => 'EventEspresso\core\services\commands\CommandHandlerManagerInterface',
1013
+			'EventEspresso\core\services\commands\CommandHandlerManagerInterface'          => 'EventEspresso\core\services\commands\CommandHandlerManager',
1014
+			'CapChecker'                                                                   => 'EventEspresso\core\services\commands\middleware\CapChecker',
1015
+			'AddActionHook'                                                                => 'EventEspresso\core\services\commands\middleware\AddActionHook',
1016
+			'CapabilitiesChecker'                                                          => 'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker',
1017
+			'CapabilitiesCheckerInterface'                                                 => 'EventEspresso\core\domain\services\capabilities\CapabilitiesCheckerInterface',
1018
+			'EventEspresso\core\domain\services\capabilities\CapabilitiesCheckerInterface' => 'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker',
1019
+			'CreateRegistrationService'                                                    => 'EventEspresso\core\domain\services\registration\CreateRegistrationService',
1020
+			'CreateRegistrationCommandHandler'                                             => 'EventEspresso\core\services\commands\registration\CreateRegistrationCommand',
1021
+			'CopyRegistrationDetailsCommandHandler'                                        => 'EventEspresso\core\services\commands\registration\CopyRegistrationDetailsCommand',
1022
+			'CopyRegistrationPaymentsCommandHandler'                                       => 'EventEspresso\core\services\commands\registration\CopyRegistrationPaymentsCommand',
1023
+			'CancelRegistrationAndTicketLineItemCommandHandler'                            => 'EventEspresso\core\services\commands\registration\CancelRegistrationAndTicketLineItemCommandHandler',
1024
+			'UpdateRegistrationAndTransactionAfterChangeCommandHandler'                    => 'EventEspresso\core\services\commands\registration\UpdateRegistrationAndTransactionAfterChangeCommandHandler',
1025
+			'CreateTicketLineItemCommandHandler'                                           => 'EventEspresso\core\services\commands\ticket\CreateTicketLineItemCommand',
1026
+			'CreateTransactionCommandHandler'                                              => 'EventEspresso\core\services\commands\transaction\CreateTransactionCommandHandler',
1027
+			'CreateAttendeeCommandHandler'                                                 => 'EventEspresso\core\services\commands\attendee\CreateAttendeeCommandHandler',
1028
+			'TableManager'                                                                 => 'EventEspresso\core\services\database\TableManager',
1029
+			'TableAnalysis'                                                                => 'EventEspresso\core\services\database\TableAnalysis',
1030
+			'EspressoShortcode'                                                            => 'EventEspresso\core\services\shortcodes\EspressoShortcode',
1031
+			'ShortcodeInterface'                                                           => 'EventEspresso\core\services\shortcodes\ShortcodeInterface',
1032
+			'EventEspresso\core\services\shortcodes\ShortcodeInterface'                    => 'EventEspresso\core\services\shortcodes\EspressoShortcode',
1033
+			'EventEspresso\core\services\cache\CacheStorageInterface'                      => 'EventEspresso\core\services\cache\TransientCacheStorage',
1034
+			'LoaderInterface'                                                              => 'EventEspresso\core\services\loaders\LoaderInterface',
1035
+			'EventEspresso\core\services\loaders\LoaderInterface'                          => 'EventEspresso\core\services\loaders\Loader',
1036
+			'CommandFactoryInterface'                                                      => 'EventEspresso\core\services\commands\CommandFactoryInterface',
1037
+			'EventEspresso\core\services\commands\CommandFactoryInterface'                 => 'EventEspresso\core\services\commands\CommandFactory',
1038
+			'EmailValidatorInterface'                                                      => 'EventEspresso\core\domain\services\validation\email\EmailValidatorInterface',
1039
+			'EventEspresso\core\domain\services\validation\email\EmailValidatorInterface'  => 'EventEspresso\core\domain\services\validation\email\EmailValidationService',
1040
+			'NoticeConverterInterface'                                                     => 'EventEspresso\core\services\notices\NoticeConverterInterface',
1041
+			'EventEspresso\core\services\notices\NoticeConverterInterface'                 => 'EventEspresso\core\services\notices\ConvertNoticesToEeErrors',
1042
+			'NoticesContainerInterface'                                                    => 'EventEspresso\core\services\notices\NoticesContainerInterface',
1043
+			'EventEspresso\core\services\notices\NoticesContainerInterface'                => 'EventEspresso\core\services\notices\NoticesContainer',
1044
+			'EventEspresso\core\services\request\RequestInterface'                         => 'EventEspresso\core\services\request\Request',
1045
+			'EventEspresso\core\services\request\ResponseInterface'                        => 'EventEspresso\core\services\request\Response',
1046
+			'EventEspresso\core\domain\DomainInterface'                                    => 'EventEspresso\core\domain\Domain',
1047
+			'Registration_Processor'                                                       => 'EE_Registration_Processor',
1048
+		);
1049
+		foreach ($aliases as $alias => $fqn) {
1050
+			if (is_array($fqn)) {
1051
+				foreach ($fqn as $class => $for_class) {
1052
+					$this->class_cache->addAlias($class, $alias, $for_class);
1053
+				}
1054
+				continue;
1055
+			}
1056
+			$this->class_cache->addAlias($fqn, $alias);
1057
+		}
1058
+		if (! (defined('DOING_AJAX') && DOING_AJAX) && is_admin()) {
1059
+			$this->class_cache->addAlias(
1060
+				'EventEspresso\core\services\notices\ConvertNoticesToAdminNotices',
1061
+				'EventEspresso\core\services\notices\NoticeConverterInterface'
1062
+			);
1063
+		}
1064
+	}
1065
+
1066
+
1067
+	/**
1068
+	 * This is used to reset the internal map and class_loaders to their original default state at the beginning of the
1069
+	 * request Primarily used by unit tests.
1070
+	 */
1071
+	public function reset()
1072
+	{
1073
+		$this->_register_core_class_loaders();
1074
+		$this->_register_core_dependencies();
1075
+	}
1076
+
1077
+
1078
+	/**
1079
+	 * PLZ NOTE: a better name for this method would be is_alias()
1080
+	 * because it returns TRUE if the provided fully qualified name IS an alias
1081
+	 * WHY?
1082
+	 * Because if a class is type hinting for a concretion,
1083
+	 * then why would we need to find another class to supply it?
1084
+	 * ie: if a class asks for `Fully/Qualified/Namespace/SpecificClassName`,
1085
+	 * then give it an instance of `Fully/Qualified/Namespace/SpecificClassName`.
1086
+	 * Don't go looking for some substitute.
1087
+	 * Whereas if a class is type hinting for an interface...
1088
+	 * then we need to find an actual class to use.
1089
+	 * So the interface IS the alias for some other FQN,
1090
+	 * and we need to find out if `Fully/Qualified/Namespace/SomeInterface`
1091
+	 * represents some other class.
1092
+	 *
1093
+	 * @deprecated 4.9.62.p
1094
+	 * @param string $fqn
1095
+	 * @param string $for_class
1096
+	 * @return bool
1097
+	 */
1098
+	public function has_alias($fqn = '', $for_class = '')
1099
+	{
1100
+		return $this->isAlias($fqn, $for_class);
1101
+	}
1102
+
1103
+
1104
+	/**
1105
+	 * PLZ NOTE: a better name for this method would be get_fqn_for_alias()
1106
+	 * because it returns a FQN for provided alias if one exists, otherwise returns the original $alias
1107
+	 * functions recursively, so that multiple aliases can be used to drill down to a FQN
1108
+	 *  for example:
1109
+	 *      if the following two entries were added to the _aliases array:
1110
+	 *          array(
1111
+	 *              'interface_alias'           => 'some\namespace\interface'
1112
+	 *              'some\namespace\interface'  => 'some\namespace\classname'
1113
+	 *          )
1114
+	 *      then one could use EE_Registry::instance()->create( 'interface_alias' )
1115
+	 *      to load an instance of 'some\namespace\classname'
1116
+	 *
1117
+	 * @deprecated 4.9.62.p
1118
+	 * @param string $alias
1119
+	 * @param string $for_class
1120
+	 * @return string
1121
+	 */
1122
+	public function get_alias($alias = '', $for_class = '')
1123
+	{
1124
+		return $this->getFqnForAlias($alias, $for_class);
1125
+	}
1126 1126
 }
Please login to merge, or discard this patch.