Completed
Branch master (8f1189)
by
unknown
07:04 queued 04:48
created
espresso.php 1 patch
Indentation   +80 added lines, -80 removed lines patch added patch discarded remove patch
@@ -38,103 +38,103 @@
 block discarded – undo
38 38
  * @since           4.0
39 39
  */
40 40
 if (function_exists('espresso_version')) {
41
-    if (! function_exists('espresso_duplicate_plugin_error')) {
42
-        /**
43
-         *    espresso_duplicate_plugin_error
44
-         *    displays if more than one version of EE is activated at the same time
45
-         */
46
-        function espresso_duplicate_plugin_error()
47
-        {
48
-            ?>
41
+	if (! function_exists('espresso_duplicate_plugin_error')) {
42
+		/**
43
+		 *    espresso_duplicate_plugin_error
44
+		 *    displays if more than one version of EE is activated at the same time
45
+		 */
46
+		function espresso_duplicate_plugin_error()
47
+		{
48
+			?>
49 49
             <div class="error">
50 50
                 <p>
51 51
                     <?php
52
-                    echo esc_html__(
53
-                        'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
-                        'event_espresso'
55
-                    ); ?>
52
+					echo esc_html__(
53
+						'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
+						'event_espresso'
55
+					); ?>
56 56
                 </p>
57 57
             </div>
58 58
             <?php
59
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
60
-        }
61
-    }
62
-    add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
59
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
60
+		}
61
+	}
62
+	add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
63 63
 } else {
64
-    define('EE_MIN_PHP_VER_REQUIRED', '5.6.2');
65
-    if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
66
-        /**
67
-         * espresso_minimum_php_version_error
68
-         *
69
-         * @return void
70
-         */
71
-        function espresso_minimum_php_version_error()
72
-        {
73
-            ?>
64
+	define('EE_MIN_PHP_VER_REQUIRED', '5.6.2');
65
+	if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
66
+		/**
67
+		 * espresso_minimum_php_version_error
68
+		 *
69
+		 * @return void
70
+		 */
71
+		function espresso_minimum_php_version_error()
72
+		{
73
+			?>
74 74
             <div class="error">
75 75
                 <p>
76 76
                     <?php
77
-                    printf(
78
-                        esc_html__(
79
-                            'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
80
-                            'event_espresso'
81
-                        ),
82
-                        EE_MIN_PHP_VER_REQUIRED,
83
-                        PHP_VERSION,
84
-                        '<br/>',
85
-                        '<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
86
-                    );
87
-                    ?>
77
+					printf(
78
+						esc_html__(
79
+							'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
80
+							'event_espresso'
81
+						),
82
+						EE_MIN_PHP_VER_REQUIRED,
83
+						PHP_VERSION,
84
+						'<br/>',
85
+						'<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
86
+					);
87
+					?>
88 88
                 </p>
89 89
             </div>
90 90
             <?php
91
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
92
-        }
91
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
92
+		}
93 93
 
94
-        add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
95
-    } else {
96
-        define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
97
-        /**
98
-         * espresso_version
99
-         * Returns the plugin version
100
-         *
101
-         * @return string
102
-         */
103
-        function espresso_version()
104
-        {
105
-            return apply_filters('FHEE__espresso__espresso_version', '4.10.30.rc.023');
106
-        }
94
+		add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
95
+	} else {
96
+		define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
97
+		/**
98
+		 * espresso_version
99
+		 * Returns the plugin version
100
+		 *
101
+		 * @return string
102
+		 */
103
+		function espresso_version()
104
+		{
105
+			return apply_filters('FHEE__espresso__espresso_version', '4.10.30.rc.023');
106
+		}
107 107
 
108
-        /**
109
-         * espresso_plugin_activation
110
-         * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
111
-         */
112
-        function espresso_plugin_activation()
113
-        {
114
-            update_option('ee_espresso_activation', true);
115
-        }
108
+		/**
109
+		 * espresso_plugin_activation
110
+		 * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
111
+		 */
112
+		function espresso_plugin_activation()
113
+		{
114
+			update_option('ee_espresso_activation', true);
115
+		}
116 116
 
117
-        register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
117
+		register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
118 118
 
119
-        require_once __DIR__ . '/core/bootstrap_espresso.php';
120
-        bootstrap_espresso();
121
-    }
119
+		require_once __DIR__ . '/core/bootstrap_espresso.php';
120
+		bootstrap_espresso();
121
+	}
122 122
 }
123 123
 if (! function_exists('espresso_deactivate_plugin')) {
124
-    /**
125
-     *    deactivate_plugin
126
-     * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
127
-     *
128
-     * @access public
129
-     * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
130
-     * @return    void
131
-     */
132
-    function espresso_deactivate_plugin($plugin_basename = '')
133
-    {
134
-        if (! function_exists('deactivate_plugins')) {
135
-            require_once ABSPATH . 'wp-admin/includes/plugin.php';
136
-        }
137
-        unset($_GET['activate'], $_REQUEST['activate']);
138
-        deactivate_plugins($plugin_basename);
139
-    }
124
+	/**
125
+	 *    deactivate_plugin
126
+	 * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
127
+	 *
128
+	 * @access public
129
+	 * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
130
+	 * @return    void
131
+	 */
132
+	function espresso_deactivate_plugin($plugin_basename = '')
133
+	{
134
+		if (! function_exists('deactivate_plugins')) {
135
+			require_once ABSPATH . 'wp-admin/includes/plugin.php';
136
+		}
137
+		unset($_GET['activate'], $_REQUEST['activate']);
138
+		deactivate_plugins($plugin_basename);
139
+	}
140 140
 }
141 141
\ No newline at end of file
Please login to merge, or discard this patch.
core/EE_Registry.core.php 1 patch
Indentation   +1698 added lines, -1698 removed lines patch added patch discarded remove patch
@@ -23,1703 +23,1703 @@
 block discarded – undo
23 23
 class EE_Registry implements ResettableInterface
24 24
 {
25 25
 
26
-    /**
27
-     * @var EE_Registry $_instance
28
-     */
29
-    private static $_instance;
30
-
31
-    /**
32
-     * @var EE_Dependency_Map $_dependency_map
33
-     */
34
-    protected $_dependency_map;
35
-
36
-    /**
37
-     * @var Mirror
38
-     */
39
-    private $mirror;
40
-
41
-    /**
42
-     * @var ClassInterfaceCache $class_cache
43
-     */
44
-    private $class_cache;
45
-
46
-    /**
47
-     * @var array $_class_abbreviations
48
-     */
49
-    protected $_class_abbreviations = array();
50
-
51
-    /**
52
-     * @var CommandBusInterface $BUS
53
-     */
54
-    public $BUS;
55
-
56
-    /**
57
-     * @var EE_Cart $CART
58
-     */
59
-    public $CART;
60
-
61
-    /**
62
-     * @var EE_Config $CFG
63
-     */
64
-    public $CFG;
65
-
66
-    /**
67
-     * @var EE_Network_Config $NET_CFG
68
-     */
69
-    public $NET_CFG;
70
-
71
-    /**
72
-     * RegistryContainer for storing library classes in
73
-     *
74
-     * @var RegistryContainer $LIB
75
-     */
76
-    public $LIB;
77
-
78
-    /**
79
-     * @var EE_Request_Handler $REQ
80
-     * @deprecated 4.10.14.p
81
-     */
82
-    public $REQ;
83
-
84
-    /**
85
-     * @var EE_Session $SSN
86
-     */
87
-    public $SSN;
88
-
89
-    /**
90
-     * @since 4.5.0
91
-     * @var EE_Capabilities $CAP
92
-     */
93
-    public $CAP;
94
-
95
-    /**
96
-     * @since 4.9.0
97
-     * @var EE_Message_Resource_Manager $MRM
98
-     */
99
-    public $MRM;
100
-
101
-    /**
102
-     * @var Registry $AssetsRegistry
103
-     */
104
-    public $AssetsRegistry;
105
-
106
-    /**
107
-     * RegistryContainer for holding addons which have registered themselves to work with EE core
108
-     *
109
-     * @var RegistryContainer|EE_Addon[] $addons
110
-     */
111
-    public $addons;
112
-
113
-    /**
114
-     * keys are 'short names' (eg Event), values are class names (eg 'EEM_Event')
115
-     *
116
-     * @var EEM_Base[] $models
117
-     */
118
-    public $models = array();
119
-
120
-    /**
121
-     * @var RegistryContainer|EED_Module[] $modules
122
-     */
123
-    public $modules;
124
-
125
-    /**
126
-     * @var RegistryContainer|EES_Shortcode[] $shortcodes
127
-     */
128
-    public $shortcodes;
129
-
130
-    /**
131
-     * @var RegistryContainer|WP_Widget[] $widgets
132
-     */
133
-    public $widgets;
134
-
135
-    /**
136
-     * this is an array of all implemented model names (i.e. not the parent abstract models, or models
137
-     * which don't actually fetch items from the DB in the normal way (ie, are not children of EEM_Base)).
138
-     * Keys are model "short names" (eg "Event") as used in model relations, and values are
139
-     * classnames (eg "EEM_Event")
140
-     *
141
-     * @var array $non_abstract_db_models
142
-     */
143
-    public $non_abstract_db_models = array();
144
-
145
-    /**
146
-     * internationalization for JS strings
147
-     *    usage:   EE_Registry::i18n_js_strings['string_key'] = esc_html__( 'string to translate.', 'event_espresso' );
148
-     *    in js file:  var translatedString = eei18n.string_key;
149
-     *
150
-     * @var array $i18n_js_strings
151
-     */
152
-    public static $i18n_js_strings = array();
153
-
154
-    /**
155
-     * $main_file - path to espresso.php
156
-     *
157
-     * @var array $main_file
158
-     */
159
-    public $main_file;
160
-
161
-    /**
162
-     * array of ReflectionClass objects where the key is the class name
163
-     *
164
-     * @deprecated 4.9.62.p
165
-     * @var ReflectionClass[] $_reflectors
166
-     */
167
-    public $_reflectors;
168
-
169
-    /**
170
-     * boolean flag to indicate whether or not to load/save dependencies from/to the cache
171
-     *
172
-     * @var boolean $_cache_on
173
-     */
174
-    protected $_cache_on = true;
175
-
176
-    /**
177
-     * @var ObjectIdentifier
178
-     */
179
-    private $object_identifier;
180
-
181
-
182
-    /**
183
-     * @singleton method used to instantiate class object
184
-     * @param EE_Dependency_Map|null   $dependency_map
185
-     * @param Mirror|null              $mirror
186
-     * @param ClassInterfaceCache|null $class_cache
187
-     * @param ObjectIdentifier|null    $object_identifier
188
-     * @return EE_Registry instance
189
-     */
190
-    public static function instance(
191
-        EE_Dependency_Map $dependency_map = null,
192
-        Mirror $mirror = null,
193
-        ClassInterfaceCache $class_cache = null,
194
-        ObjectIdentifier $object_identifier = null
195
-    ) {
196
-        // check if class object is instantiated
197
-        if (
198
-            ! self::$_instance instanceof EE_Registry
199
-            && $dependency_map instanceof EE_Dependency_Map
200
-            && $mirror instanceof Mirror
201
-            && $class_cache instanceof ClassInterfaceCache
202
-            && $object_identifier instanceof ObjectIdentifier
203
-        ) {
204
-            self::$_instance = new self(
205
-                $dependency_map,
206
-                $mirror,
207
-                $class_cache,
208
-                $object_identifier
209
-            );
210
-        }
211
-        return self::$_instance;
212
-    }
213
-
214
-
215
-    /**
216
-     * protected constructor to prevent direct creation
217
-     *
218
-     * @Constructor
219
-     * @param  EE_Dependency_Map  $dependency_map
220
-     * @param Mirror              $mirror
221
-     * @param ClassInterfaceCache $class_cache
222
-     * @param ObjectIdentifier    $object_identifier
223
-     */
224
-    protected function __construct(
225
-        EE_Dependency_Map $dependency_map,
226
-        Mirror $mirror,
227
-        ClassInterfaceCache $class_cache,
228
-        ObjectIdentifier $object_identifier
229
-    ) {
230
-        $this->_dependency_map = $dependency_map;
231
-        $this->mirror = $mirror;
232
-        $this->class_cache = $class_cache;
233
-        $this->object_identifier = $object_identifier;
234
-        // $registry_container = new RegistryContainer();
235
-        $this->LIB = new RegistryContainer();
236
-        $this->addons = new RegistryContainer();
237
-        $this->modules = new RegistryContainer();
238
-        $this->shortcodes = new RegistryContainer();
239
-        $this->widgets = new RegistryContainer();
240
-        add_action('EE_Load_Espresso_Core__handle_request__initialize_core_loading', array($this, 'initialize'));
241
-    }
242
-
243
-
244
-    /**
245
-     * initialize
246
-     *
247
-     * @throws OutOfBoundsException
248
-     * @throws InvalidArgumentException
249
-     * @throws InvalidInterfaceException
250
-     * @throws InvalidDataTypeException
251
-     * @throws EE_Error
252
-     * @throws ReflectionException
253
-     */
254
-    public function initialize()
255
-    {
256
-        $this->_class_abbreviations = apply_filters(
257
-            'FHEE__EE_Registry____construct___class_abbreviations',
258
-            array(
259
-                'EE_Config'                                       => 'CFG',
260
-                'EE_Session'                                      => 'SSN',
261
-                'EE_Capabilities'                                 => 'CAP',
262
-                'EE_Cart'                                         => 'CART',
263
-                'EE_Network_Config'                               => 'NET_CFG',
264
-                'EE_Request_Handler'                              => 'REQ',
265
-                'EE_Message_Resource_Manager'                     => 'MRM',
266
-                'EventEspresso\core\services\commands\CommandBus' => 'BUS',
267
-                'EventEspresso\core\services\assets\Registry'     => 'AssetsRegistry',
268
-            )
269
-        );
270
-        $this->load_core('Base', array(), true);
271
-        // add our request and response objects to the cache
272
-        $request_loader = $this->_dependency_map->class_loader(
273
-            'EventEspresso\core\services\request\Request'
274
-        );
275
-        $this->_set_cached_class(
276
-            $request_loader(),
277
-            'EventEspresso\core\services\request\Request'
278
-        );
279
-        $response_loader = $this->_dependency_map->class_loader(
280
-            'EventEspresso\core\services\request\Response'
281
-        );
282
-        $this->_set_cached_class(
283
-            $response_loader(),
284
-            'EventEspresso\core\services\request\Response'
285
-        );
286
-        add_action('AHEE__EE_System__set_hooks_for_core', array($this, 'init'));
287
-    }
288
-
289
-
290
-    /**
291
-     * @return void
292
-     */
293
-    public function init()
294
-    {
295
-        // Get current page protocol
296
-        $protocol = is_ssl() ? 'https://' : 'http://';
297
-        // Output admin-ajax.php URL with same protocol as current page
298
-        self::$i18n_js_strings['ajax_url'] = admin_url('admin-ajax.php', $protocol);
299
-        self::$i18n_js_strings['wp_debug'] = defined('WP_DEBUG') && WP_DEBUG;
300
-    }
301
-
302
-
303
-    /**
304
-     * @return array
305
-     */
306
-    public static function sanitize_i18n_js_strings()
307
-    {
308
-        $i18n_js_strings = (array) self::$i18n_js_strings;
309
-        foreach ($i18n_js_strings as $key => $value) {
310
-            if (is_scalar($value)) {
311
-                $decoded_value           = html_entity_decode((string) $value, ENT_QUOTES, 'UTF-8');
312
-                $i18n_js_strings[ $key ] = wp_strip_all_tags($decoded_value);
313
-            }
314
-        }
315
-        return $i18n_js_strings;
316
-    }
317
-
318
-
319
-    /**
320
-     * localize_i18n_js_strings
321
-     *
322
-     * @return string
323
-     */
324
-    public static function localize_i18n_js_strings()
325
-    {
326
-        $i18n_js_strings = EE_Registry::sanitize_i18n_js_strings();
327
-        return '/* <![CDATA[ */ var eei18n = ' . wp_json_encode($i18n_js_strings) . '; /* ]]> */';
328
-    }
329
-
330
-
331
-    /**
332
-     * @param mixed string | EED_Module $module
333
-     * @throws OutOfBoundsException
334
-     * @throws InvalidArgumentException
335
-     * @throws InvalidInterfaceException
336
-     * @throws InvalidDataTypeException
337
-     * @throws EE_Error
338
-     * @throws ReflectionException
339
-     */
340
-    public function add_module($module)
341
-    {
342
-        if ($module instanceof EED_Module) {
343
-            $module_class = get_class($module);
344
-            $this->modules->add($module_class, $module);
345
-        } else {
346
-            if (! class_exists('EE_Module_Request_Router', false)) {
347
-                $this->load_core('Module_Request_Router');
348
-            }
349
-            EE_Module_Request_Router::module_factory($module);
350
-        }
351
-    }
352
-
353
-
354
-    /**
355
-     * @param string $module_name
356
-     * @return mixed EED_Module | NULL
357
-     */
358
-    public function get_module($module_name = '')
359
-    {
360
-        return $this->modules->get($module_name);
361
-    }
362
-
363
-
364
-    /**
365
-     * loads core classes - must be singletons
366
-     *
367
-     * @param string $class_name - simple class name ie: session
368
-     * @param mixed  $arguments
369
-     * @param bool   $load_only
370
-     * @return mixed
371
-     * @throws InvalidInterfaceException
372
-     * @throws InvalidDataTypeException
373
-     * @throws EE_Error
374
-     * @throws ReflectionException
375
-     * @throws InvalidArgumentException
376
-     */
377
-    public function load_core($class_name, $arguments = array(), $load_only = false)
378
-    {
379
-        $core_paths = apply_filters(
380
-            'FHEE__EE_Registry__load_core__core_paths',
381
-            array(
382
-                EE_CORE,
383
-                EE_ADMIN,
384
-                EE_CPTS,
385
-                EE_CORE . 'CPTs/',
386
-                EE_CORE . 'data_migration_scripts/',
387
-                EE_CORE . 'request_stack/',
388
-                EE_CORE . 'middleware/',
389
-            )
390
-        );
391
-        // retrieve instantiated class
392
-        return $this->_load(
393
-            $core_paths,
394
-            'EE_',
395
-            $class_name,
396
-            'core',
397
-            $arguments,
398
-            false,
399
-            true,
400
-            $load_only
401
-        );
402
-    }
403
-
404
-
405
-    /**
406
-     * loads service classes
407
-     *
408
-     * @param string $class_name - simple class name ie: session
409
-     * @param mixed  $arguments
410
-     * @param bool   $load_only
411
-     * @return mixed
412
-     * @throws InvalidInterfaceException
413
-     * @throws InvalidDataTypeException
414
-     * @throws EE_Error
415
-     * @throws ReflectionException
416
-     * @throws InvalidArgumentException
417
-     */
418
-    public function load_service($class_name, $arguments = array(), $load_only = false)
419
-    {
420
-        $service_paths = apply_filters(
421
-            'FHEE__EE_Registry__load_service__service_paths',
422
-            array(
423
-                EE_CORE . 'services/',
424
-            )
425
-        );
426
-        // retrieve instantiated class
427
-        return $this->_load(
428
-            $service_paths,
429
-            'EE_',
430
-            $class_name,
431
-            'class',
432
-            $arguments,
433
-            false,
434
-            true,
435
-            $load_only
436
-        );
437
-    }
438
-
439
-
440
-    /**
441
-     * loads data_migration_scripts
442
-     *
443
-     * @param string $class_name - class name for the DMS ie: EE_DMS_Core_4_2_0
444
-     * @param mixed  $arguments
445
-     * @return EE_Data_Migration_Script_Base|mixed
446
-     * @throws InvalidInterfaceException
447
-     * @throws InvalidDataTypeException
448
-     * @throws EE_Error
449
-     * @throws ReflectionException
450
-     * @throws InvalidArgumentException
451
-     */
452
-    public function load_dms($class_name, $arguments = array())
453
-    {
454
-        // retrieve instantiated class
455
-        return $this->_load(
456
-            EE_Data_Migration_Manager::instance()->get_data_migration_script_folders(),
457
-            'EE_DMS_',
458
-            $class_name,
459
-            'dms',
460
-            $arguments,
461
-            false,
462
-            false
463
-        );
464
-    }
465
-
466
-
467
-    /**
468
-     * loads object creating classes - must be singletons
469
-     *
470
-     * @param string $class_name - simple class name ie: attendee
471
-     * @param mixed  $arguments  - an array of arguments to pass to the class
472
-     * @param bool   $from_db    - some classes are instantiated from the db and thus call a different method to
473
-     *                           instantiate
474
-     * @param bool   $cache      if you don't want the class to be stored in the internal cache (non-persistent) then
475
-     *                           set this to FALSE (ie. when instantiating model objects from client in a loop)
476
-     * @param bool   $load_only  whether or not to just load the file and NOT instantiate, or load AND instantiate
477
-     *                           (default)
478
-     * @return EE_Base_Class | bool
479
-     * @throws InvalidInterfaceException
480
-     * @throws InvalidDataTypeException
481
-     * @throws EE_Error
482
-     * @throws ReflectionException
483
-     * @throws InvalidArgumentException
484
-     */
485
-    public function load_class($class_name, $arguments = array(), $from_db = false, $cache = true, $load_only = false)
486
-    {
487
-        $paths = apply_filters(
488
-            'FHEE__EE_Registry__load_class__paths',
489
-            array(
490
-                EE_CORE,
491
-                EE_CLASSES,
492
-                EE_BUSINESS,
493
-            )
494
-        );
495
-        // retrieve instantiated class
496
-        return $this->_load(
497
-            $paths,
498
-            'EE_',
499
-            $class_name,
500
-            'class',
501
-            $arguments,
502
-            $from_db,
503
-            $cache,
504
-            $load_only
505
-        );
506
-    }
507
-
508
-
509
-    /**
510
-     * loads helper classes - must be singletons
511
-     *
512
-     * @param string $class_name - simple class name ie: price
513
-     * @param mixed  $arguments
514
-     * @param bool   $load_only
515
-     * @return EEH_Base | bool
516
-     * @throws InvalidInterfaceException
517
-     * @throws InvalidDataTypeException
518
-     * @throws EE_Error
519
-     * @throws ReflectionException
520
-     * @throws InvalidArgumentException
521
-     */
522
-    public function load_helper($class_name, $arguments = array(), $load_only = true)
523
-    {
524
-        // todo: add doing_it_wrong() in a few versions after all addons have had calls to this method removed
525
-        $helper_paths = apply_filters('FHEE__EE_Registry__load_helper__helper_paths', array(EE_HELPERS));
526
-        // retrieve instantiated class
527
-        return $this->_load(
528
-            $helper_paths,
529
-            'EEH_',
530
-            $class_name,
531
-            'helper',
532
-            $arguments,
533
-            false,
534
-            true,
535
-            $load_only
536
-        );
537
-    }
538
-
539
-
540
-    /**
541
-     * loads core classes - must be singletons
542
-     *
543
-     * @param string $class_name - simple class name ie: session
544
-     * @param mixed  $arguments
545
-     * @param bool   $load_only
546
-     * @param bool   $cache      whether to cache the object or not.
547
-     * @return mixed
548
-     * @throws InvalidInterfaceException
549
-     * @throws InvalidDataTypeException
550
-     * @throws EE_Error
551
-     * @throws ReflectionException
552
-     * @throws InvalidArgumentException
553
-     */
554
-    public function load_lib($class_name, $arguments = array(), $load_only = false, $cache = true)
555
-    {
556
-        $paths = array(
557
-            EE_LIBRARIES,
558
-            EE_LIBRARIES . 'messages/',
559
-            EE_LIBRARIES . 'shortcodes/',
560
-            EE_LIBRARIES . 'qtips/',
561
-            EE_LIBRARIES . 'payment_methods/',
562
-        );
563
-        // retrieve instantiated class
564
-        return $this->_load(
565
-            $paths,
566
-            'EE_',
567
-            $class_name,
568
-            'lib',
569
-            $arguments,
570
-            false,
571
-            $cache,
572
-            $load_only
573
-        );
574
-    }
575
-
576
-
577
-    /**
578
-     * loads model classes - must be singletons
579
-     *
580
-     * @param string $class_name - simple class name ie: price
581
-     * @param mixed  $arguments
582
-     * @param bool   $load_only
583
-     * @return mixed
584
-     * @throws InvalidInterfaceException
585
-     * @throws InvalidDataTypeException
586
-     * @throws EE_Error
587
-     * @throws ReflectionException
588
-     * @throws InvalidArgumentException
589
-     */
590
-    public function load_model($class_name, $arguments = array(), $load_only = false)
591
-    {
592
-        $paths = apply_filters(
593
-            'FHEE__EE_Registry__load_model__paths',
594
-            array(
595
-                EE_MODELS,
596
-                EE_CORE,
597
-            )
598
-        );
599
-        // retrieve instantiated class
600
-        return $this->_load(
601
-            $paths,
602
-            'EEM_',
603
-            $class_name,
604
-            'model',
605
-            $arguments,
606
-            false,
607
-            true,
608
-            $load_only
609
-        );
610
-    }
611
-
612
-
613
-    /**
614
-     * loads model classes - must be singletons
615
-     *
616
-     * @param string $class_name - simple class name ie: price
617
-     * @param mixed  $arguments
618
-     * @param bool   $load_only
619
-     * @return mixed | bool
620
-     * @throws InvalidInterfaceException
621
-     * @throws InvalidDataTypeException
622
-     * @throws EE_Error
623
-     * @throws ReflectionException
624
-     * @throws InvalidArgumentException
625
-     */
626
-    public function load_model_class($class_name, $arguments = array(), $load_only = true)
627
-    {
628
-        $paths = array(
629
-            EE_MODELS . 'fields/',
630
-            EE_MODELS . 'helpers/',
631
-            EE_MODELS . 'relations/',
632
-            EE_MODELS . 'strategies/',
633
-        );
634
-        // retrieve instantiated class
635
-        return $this->_load(
636
-            $paths,
637
-            'EE_',
638
-            $class_name,
639
-            '',
640
-            $arguments,
641
-            false,
642
-            true,
643
-            $load_only
644
-        );
645
-    }
646
-
647
-
648
-    /**
649
-     * Determines if $model_name is the name of an actual EE model.
650
-     *
651
-     * @param string $model_name like Event, Attendee, Question_Group_Question, etc.
652
-     * @return boolean
653
-     */
654
-    public function is_model_name($model_name)
655
-    {
656
-        return isset($this->models[ $model_name ]);
657
-    }
658
-
659
-
660
-    /**
661
-     * generic class loader
662
-     *
663
-     * @param string $path_to_file - directory path to file location, not including filename
664
-     * @param string $file_name    - file name  ie:  my_file.php, including extension
665
-     * @param string $type         - file type - core? class? helper? model?
666
-     * @param mixed  $arguments
667
-     * @param bool   $load_only
668
-     * @return mixed
669
-     * @throws InvalidInterfaceException
670
-     * @throws InvalidDataTypeException
671
-     * @throws EE_Error
672
-     * @throws ReflectionException
673
-     * @throws InvalidArgumentException
674
-     */
675
-    public function load_file($path_to_file, $file_name, $type = '', $arguments = array(), $load_only = true)
676
-    {
677
-        // retrieve instantiated class
678
-        return $this->_load(
679
-            $path_to_file,
680
-            '',
681
-            $file_name,
682
-            $type,
683
-            $arguments,
684
-            false,
685
-            true,
686
-            $load_only
687
-        );
688
-    }
689
-
690
-
691
-    /**
692
-     * @param string $path_to_file - directory path to file location, not including filename
693
-     * @param string $class_name   - full class name  ie:  My_Class
694
-     * @param string $type         - file type - core? class? helper? model?
695
-     * @param mixed  $arguments
696
-     * @param bool   $load_only
697
-     * @return bool|EE_Addon|object
698
-     * @throws InvalidInterfaceException
699
-     * @throws InvalidDataTypeException
700
-     * @throws EE_Error
701
-     * @throws ReflectionException
702
-     * @throws InvalidArgumentException
703
-     */
704
-    public function load_addon($path_to_file, $class_name, $type = 'class', $arguments = array(), $load_only = false)
705
-    {
706
-        // retrieve instantiated class
707
-        return $this->_load(
708
-            $path_to_file,
709
-            'addon',
710
-            $class_name,
711
-            $type,
712
-            $arguments,
713
-            false,
714
-            true,
715
-            $load_only
716
-        );
717
-    }
718
-
719
-
720
-    /**
721
-     * instantiates, caches, and automatically resolves dependencies
722
-     * for classes that use a Fully Qualified Class Name.
723
-     * if the class is not capable of being loaded using PSR-4 autoloading,
724
-     * then you need to use one of the existing load_*() methods
725
-     * which can resolve the classname and filepath from the passed arguments
726
-     *
727
-     * @param bool|string $class_name   Fully Qualified Class Name
728
-     * @param array       $arguments    an argument, or array of arguments to pass to the class upon instantiation
729
-     * @param bool        $cache        whether to cache the instantiated object for reuse
730
-     * @param bool        $from_db      some classes are instantiated from the db
731
-     *                                  and thus call a different method to instantiate
732
-     * @param bool        $load_only    if true, will only load the file, but will NOT instantiate an object
733
-     * @param bool|string $addon        if true, will cache the object in the EE_Registry->$addons array
734
-     * @return bool|null|mixed          null = failure to load or instantiate class object.
735
-     *                                  object = class loaded and instantiated successfully.
736
-     *                                  bool = fail or success when $load_only is true
737
-     * @throws InvalidInterfaceException
738
-     * @throws InvalidDataTypeException
739
-     * @throws EE_Error
740
-     * @throws ReflectionException
741
-     * @throws InvalidArgumentException
742
-     */
743
-    public function create(
744
-        $class_name = false,
745
-        $arguments = array(),
746
-        $cache = false,
747
-        $from_db = false,
748
-        $load_only = false,
749
-        $addon = false
750
-    ) {
751
-        $class_name = ltrim($class_name, '\\');
752
-        $class_name = $this->class_cache->getFqnForAlias($class_name);
753
-        $class_exists = $this->loadOrVerifyClassExists($class_name, $arguments);
754
-        // if a non-FQCN was passed, then
755
-        // verifyClassExists() might return an object
756
-        // or it could return null if the class just could not be found anywhere
757
-        if ($class_exists instanceof $class_name || $class_exists === null) {
758
-            // either way, return the results
759
-            return $class_exists;
760
-        }
761
-        $class_name = $class_exists;
762
-        // if we're only loading the class and it already exists, then let's just return true immediately
763
-        if ($load_only) {
764
-            return true;
765
-        }
766
-        $addon = $addon ? 'addon' : '';
767
-        // $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
768
-        // $cache is controlled by individual calls to separate Registry loader methods like load_class()
769
-        // $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
770
-        if ($this->_cache_on && $cache && ! $load_only) {
771
-            // return object if it's already cached
772
-            $cached_class = $this->_get_cached_class($class_name, $addon, $arguments);
773
-            if ($cached_class !== null) {
774
-                return $cached_class;
775
-            }
776
-        }// obtain the loader method from the dependency map
777
-        $loader = $this->_dependency_map->class_loader($class_name);// instantiate the requested object
778
-        if ($loader instanceof Closure) {
779
-            $class_obj = $loader($arguments);
780
-        } else {
781
-            if ($loader && method_exists($this, $loader)) {
782
-                $class_obj = $this->{$loader}($class_name, $arguments);
783
-            } else {
784
-                $class_obj = $this->_create_object($class_name, $arguments, $addon, $from_db);
785
-            }
786
-        }
787
-        if (($this->_cache_on && $cache) || $this->get_class_abbreviation($class_name, '')) {
788
-            // save it for later... kinda like gum  { : $
789
-            $this->_set_cached_class(
790
-                $class_obj,
791
-                $class_name,
792
-                $addon,
793
-                $from_db,
794
-                $arguments
795
-            );
796
-        }
797
-        $this->_cache_on = true;
798
-        return $class_obj;
799
-    }
800
-
801
-
802
-    /**
803
-     * Recursively checks that a class exists and potentially attempts to load classes with non-FQCNs
804
-     *
805
-     * @param string|object $class_name
806
-     * @param array         $arguments
807
-     * @param int           $attempt
808
-     * @return mixed
809
-     */
810
-    private function loadOrVerifyClassExists($class_name, array $arguments, $attempt = 1)
811
-    {
812
-        if (is_object($class_name) || class_exists($class_name)) {
813
-            return $class_name;
814
-        }
815
-        switch ($attempt) {
816
-            case 1:
817
-                // if it's a FQCN then maybe the class is registered with a preceding \
818
-                $class_name = strpos($class_name, '\\') !== false
819
-                    ? '\\' . ltrim($class_name, '\\')
820
-                    : $class_name;
821
-                break;
822
-            case 2:
823
-                //
824
-                $loader = $this->_dependency_map->class_loader($class_name);
825
-                if ($loader && method_exists($this, $loader)) {
826
-                    return $this->{$loader}($class_name, $arguments);
827
-                }
828
-                break;
829
-            case 3:
830
-            default:
831
-                return null;
832
-        }
833
-        $attempt++;
834
-        return $this->loadOrVerifyClassExists($class_name, $arguments, $attempt);
835
-    }
836
-
837
-
838
-    /**
839
-     * instantiates, caches, and injects dependencies for classes
840
-     *
841
-     * @param array       $file_paths   an array of paths to folders to look in
842
-     * @param string      $class_prefix EE  or EEM or... ???
843
-     * @param bool|string $class_name   $class name
844
-     * @param string      $type         file type - core? class? helper? model?
845
-     * @param mixed       $arguments    an argument or array of arguments to pass to the class upon instantiation
846
-     * @param bool        $from_db      some classes are instantiated from the db
847
-     *                                  and thus call a different method to instantiate
848
-     * @param bool        $cache        whether to cache the instantiated object for reuse
849
-     * @param bool        $load_only    if true, will only load the file, but will NOT instantiate an object
850
-     * @return bool|null|object null = failure to load or instantiate class object.
851
-     *                                  object = class loaded and instantiated successfully.
852
-     *                                  bool = fail or success when $load_only is true
853
-     * @throws EE_Error
854
-     * @throws ReflectionException
855
-     * @throws InvalidInterfaceException
856
-     * @throws InvalidDataTypeException
857
-     * @throws InvalidArgumentException
858
-     */
859
-    protected function _load(
860
-        $file_paths = array(),
861
-        $class_prefix = 'EE_',
862
-        $class_name = false,
863
-        $type = 'class',
864
-        $arguments = array(),
865
-        $from_db = false,
866
-        $cache = true,
867
-        $load_only = false
868
-    ) {
869
-        $class_name = ltrim($class_name, '\\');
870
-        // strip php file extension
871
-        $class_name = str_replace('.php', '', trim($class_name));
872
-        // does the class have a prefix ?
873
-        if (! empty($class_prefix) && $class_prefix !== 'addon') {
874
-            // make sure $class_prefix is uppercase
875
-            $class_prefix = strtoupper(trim($class_prefix));
876
-            // add class prefix ONCE!!!
877
-            $class_name = $class_prefix . str_replace($class_prefix, '', $class_name);
878
-        }
879
-        $class_name = $this->class_cache->getFqnForAlias($class_name);
880
-        $class_exists = class_exists($class_name, false);
881
-        // if we're only loading the class and it already exists, then let's just return true immediately
882
-        if ($load_only && $class_exists) {
883
-            return true;
884
-        }
885
-        $arguments = is_array($arguments) ? $arguments : array($arguments);
886
-        // $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
887
-        // $cache is controlled by individual calls to separate Registry loader methods like load_class()
888
-        // $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
889
-        if ($this->_cache_on && $cache && ! $load_only) {
890
-            // return object if it's already cached
891
-            $cached_class = $this->_get_cached_class($class_name, $class_prefix, $arguments);
892
-            if ($cached_class !== null) {
893
-                return $cached_class;
894
-            }
895
-        }
896
-        // if the class doesn't already exist.. then we need to try and find the file and load it
897
-        if (! $class_exists) {
898
-            // get full path to file
899
-            $path = $this->_resolve_path($class_name, $type, $file_paths);
900
-            // load the file
901
-            $loaded = $this->_require_file($path, $class_name, $type, $file_paths);
902
-            // if we are only loading a file but NOT instantiating an object
903
-            // then return boolean for whether class was loaded or not
904
-            if ($load_only) {
905
-                return $loaded;
906
-            }
907
-            // if an object was expected but loading failed, then return nothing
908
-            if (! $loaded) {
909
-                return null;
910
-            }
911
-        }
912
-        // instantiate the requested object
913
-        $class_obj = $this->_create_object($class_name, $arguments, $type, $from_db);
914
-        if ($this->_cache_on && $cache) {
915
-            // save it for later... kinda like gum  { : $
916
-            $this->_set_cached_class(
917
-                $class_obj,
918
-                $class_name,
919
-                $class_prefix,
920
-                $from_db,
921
-                $arguments
922
-            );
923
-        }
924
-        $this->_cache_on = true;
925
-        return $class_obj;
926
-    }
927
-
928
-
929
-    /**
930
-     * @param string $class_name
931
-     * @param string $default have to specify something, but not anything that will conflict
932
-     * @return mixed|string
933
-     */
934
-    protected function get_class_abbreviation($class_name, $default = 'FANCY_BATMAN_PANTS')
935
-    {
936
-        return isset($this->_class_abbreviations[ $class_name ])
937
-            ? $this->_class_abbreviations[ $class_name ]
938
-            : $default;
939
-    }
940
-
941
-
942
-    /**
943
-     * attempts to find a cached version of the requested class
944
-     * by looking in the following places:
945
-     *        $this->{$class_abbreviation}            ie:    $this->CART
946
-     *        $this->{$class_name}                        ie:    $this->Some_Class
947
-     *        $this->LIB->{$class_name}                ie:    $this->LIB->Some_Class
948
-     *        $this->addon->{$class_name}    ie:    $this->addon->Some_Addon_Class
949
-     *
950
-     * @param string $class_name
951
-     * @param string $class_prefix
952
-     * @param array  $arguments
953
-     * @return mixed
954
-     */
955
-    protected function _get_cached_class(
956
-        $class_name,
957
-        $class_prefix = '',
958
-        $arguments = array()
959
-    ) {
960
-        if ($class_name === 'EE_Registry') {
961
-            return $this;
962
-        }
963
-        $class_abbreviation = $this->get_class_abbreviation($class_name);
964
-        // check if class has already been loaded, and return it if it has been
965
-        if (isset($this->{$class_abbreviation})) {
966
-            return $this->{$class_abbreviation};
967
-        }
968
-        $class_name = str_replace('\\', '_', $class_name);
969
-        if (isset($this->{$class_name})) {
970
-            return $this->{$class_name};
971
-        }
972
-        if ($class_prefix === 'addon' && $this->addons->has($class_name)) {
973
-            return $this->addons->get($class_name);
974
-        }
975
-        $object_identifier = $this->object_identifier->getIdentifier($class_name, $arguments);
976
-        if ($this->LIB->has($object_identifier)) {
977
-            return $this->LIB->get($object_identifier);
978
-        }
979
-        foreach ($this->LIB as $key => $object) {
980
-            if (
26
+	/**
27
+	 * @var EE_Registry $_instance
28
+	 */
29
+	private static $_instance;
30
+
31
+	/**
32
+	 * @var EE_Dependency_Map $_dependency_map
33
+	 */
34
+	protected $_dependency_map;
35
+
36
+	/**
37
+	 * @var Mirror
38
+	 */
39
+	private $mirror;
40
+
41
+	/**
42
+	 * @var ClassInterfaceCache $class_cache
43
+	 */
44
+	private $class_cache;
45
+
46
+	/**
47
+	 * @var array $_class_abbreviations
48
+	 */
49
+	protected $_class_abbreviations = array();
50
+
51
+	/**
52
+	 * @var CommandBusInterface $BUS
53
+	 */
54
+	public $BUS;
55
+
56
+	/**
57
+	 * @var EE_Cart $CART
58
+	 */
59
+	public $CART;
60
+
61
+	/**
62
+	 * @var EE_Config $CFG
63
+	 */
64
+	public $CFG;
65
+
66
+	/**
67
+	 * @var EE_Network_Config $NET_CFG
68
+	 */
69
+	public $NET_CFG;
70
+
71
+	/**
72
+	 * RegistryContainer for storing library classes in
73
+	 *
74
+	 * @var RegistryContainer $LIB
75
+	 */
76
+	public $LIB;
77
+
78
+	/**
79
+	 * @var EE_Request_Handler $REQ
80
+	 * @deprecated 4.10.14.p
81
+	 */
82
+	public $REQ;
83
+
84
+	/**
85
+	 * @var EE_Session $SSN
86
+	 */
87
+	public $SSN;
88
+
89
+	/**
90
+	 * @since 4.5.0
91
+	 * @var EE_Capabilities $CAP
92
+	 */
93
+	public $CAP;
94
+
95
+	/**
96
+	 * @since 4.9.0
97
+	 * @var EE_Message_Resource_Manager $MRM
98
+	 */
99
+	public $MRM;
100
+
101
+	/**
102
+	 * @var Registry $AssetsRegistry
103
+	 */
104
+	public $AssetsRegistry;
105
+
106
+	/**
107
+	 * RegistryContainer for holding addons which have registered themselves to work with EE core
108
+	 *
109
+	 * @var RegistryContainer|EE_Addon[] $addons
110
+	 */
111
+	public $addons;
112
+
113
+	/**
114
+	 * keys are 'short names' (eg Event), values are class names (eg 'EEM_Event')
115
+	 *
116
+	 * @var EEM_Base[] $models
117
+	 */
118
+	public $models = array();
119
+
120
+	/**
121
+	 * @var RegistryContainer|EED_Module[] $modules
122
+	 */
123
+	public $modules;
124
+
125
+	/**
126
+	 * @var RegistryContainer|EES_Shortcode[] $shortcodes
127
+	 */
128
+	public $shortcodes;
129
+
130
+	/**
131
+	 * @var RegistryContainer|WP_Widget[] $widgets
132
+	 */
133
+	public $widgets;
134
+
135
+	/**
136
+	 * this is an array of all implemented model names (i.e. not the parent abstract models, or models
137
+	 * which don't actually fetch items from the DB in the normal way (ie, are not children of EEM_Base)).
138
+	 * Keys are model "short names" (eg "Event") as used in model relations, and values are
139
+	 * classnames (eg "EEM_Event")
140
+	 *
141
+	 * @var array $non_abstract_db_models
142
+	 */
143
+	public $non_abstract_db_models = array();
144
+
145
+	/**
146
+	 * internationalization for JS strings
147
+	 *    usage:   EE_Registry::i18n_js_strings['string_key'] = esc_html__( 'string to translate.', 'event_espresso' );
148
+	 *    in js file:  var translatedString = eei18n.string_key;
149
+	 *
150
+	 * @var array $i18n_js_strings
151
+	 */
152
+	public static $i18n_js_strings = array();
153
+
154
+	/**
155
+	 * $main_file - path to espresso.php
156
+	 *
157
+	 * @var array $main_file
158
+	 */
159
+	public $main_file;
160
+
161
+	/**
162
+	 * array of ReflectionClass objects where the key is the class name
163
+	 *
164
+	 * @deprecated 4.9.62.p
165
+	 * @var ReflectionClass[] $_reflectors
166
+	 */
167
+	public $_reflectors;
168
+
169
+	/**
170
+	 * boolean flag to indicate whether or not to load/save dependencies from/to the cache
171
+	 *
172
+	 * @var boolean $_cache_on
173
+	 */
174
+	protected $_cache_on = true;
175
+
176
+	/**
177
+	 * @var ObjectIdentifier
178
+	 */
179
+	private $object_identifier;
180
+
181
+
182
+	/**
183
+	 * @singleton method used to instantiate class object
184
+	 * @param EE_Dependency_Map|null   $dependency_map
185
+	 * @param Mirror|null              $mirror
186
+	 * @param ClassInterfaceCache|null $class_cache
187
+	 * @param ObjectIdentifier|null    $object_identifier
188
+	 * @return EE_Registry instance
189
+	 */
190
+	public static function instance(
191
+		EE_Dependency_Map $dependency_map = null,
192
+		Mirror $mirror = null,
193
+		ClassInterfaceCache $class_cache = null,
194
+		ObjectIdentifier $object_identifier = null
195
+	) {
196
+		// check if class object is instantiated
197
+		if (
198
+			! self::$_instance instanceof EE_Registry
199
+			&& $dependency_map instanceof EE_Dependency_Map
200
+			&& $mirror instanceof Mirror
201
+			&& $class_cache instanceof ClassInterfaceCache
202
+			&& $object_identifier instanceof ObjectIdentifier
203
+		) {
204
+			self::$_instance = new self(
205
+				$dependency_map,
206
+				$mirror,
207
+				$class_cache,
208
+				$object_identifier
209
+			);
210
+		}
211
+		return self::$_instance;
212
+	}
213
+
214
+
215
+	/**
216
+	 * protected constructor to prevent direct creation
217
+	 *
218
+	 * @Constructor
219
+	 * @param  EE_Dependency_Map  $dependency_map
220
+	 * @param Mirror              $mirror
221
+	 * @param ClassInterfaceCache $class_cache
222
+	 * @param ObjectIdentifier    $object_identifier
223
+	 */
224
+	protected function __construct(
225
+		EE_Dependency_Map $dependency_map,
226
+		Mirror $mirror,
227
+		ClassInterfaceCache $class_cache,
228
+		ObjectIdentifier $object_identifier
229
+	) {
230
+		$this->_dependency_map = $dependency_map;
231
+		$this->mirror = $mirror;
232
+		$this->class_cache = $class_cache;
233
+		$this->object_identifier = $object_identifier;
234
+		// $registry_container = new RegistryContainer();
235
+		$this->LIB = new RegistryContainer();
236
+		$this->addons = new RegistryContainer();
237
+		$this->modules = new RegistryContainer();
238
+		$this->shortcodes = new RegistryContainer();
239
+		$this->widgets = new RegistryContainer();
240
+		add_action('EE_Load_Espresso_Core__handle_request__initialize_core_loading', array($this, 'initialize'));
241
+	}
242
+
243
+
244
+	/**
245
+	 * initialize
246
+	 *
247
+	 * @throws OutOfBoundsException
248
+	 * @throws InvalidArgumentException
249
+	 * @throws InvalidInterfaceException
250
+	 * @throws InvalidDataTypeException
251
+	 * @throws EE_Error
252
+	 * @throws ReflectionException
253
+	 */
254
+	public function initialize()
255
+	{
256
+		$this->_class_abbreviations = apply_filters(
257
+			'FHEE__EE_Registry____construct___class_abbreviations',
258
+			array(
259
+				'EE_Config'                                       => 'CFG',
260
+				'EE_Session'                                      => 'SSN',
261
+				'EE_Capabilities'                                 => 'CAP',
262
+				'EE_Cart'                                         => 'CART',
263
+				'EE_Network_Config'                               => 'NET_CFG',
264
+				'EE_Request_Handler'                              => 'REQ',
265
+				'EE_Message_Resource_Manager'                     => 'MRM',
266
+				'EventEspresso\core\services\commands\CommandBus' => 'BUS',
267
+				'EventEspresso\core\services\assets\Registry'     => 'AssetsRegistry',
268
+			)
269
+		);
270
+		$this->load_core('Base', array(), true);
271
+		// add our request and response objects to the cache
272
+		$request_loader = $this->_dependency_map->class_loader(
273
+			'EventEspresso\core\services\request\Request'
274
+		);
275
+		$this->_set_cached_class(
276
+			$request_loader(),
277
+			'EventEspresso\core\services\request\Request'
278
+		);
279
+		$response_loader = $this->_dependency_map->class_loader(
280
+			'EventEspresso\core\services\request\Response'
281
+		);
282
+		$this->_set_cached_class(
283
+			$response_loader(),
284
+			'EventEspresso\core\services\request\Response'
285
+		);
286
+		add_action('AHEE__EE_System__set_hooks_for_core', array($this, 'init'));
287
+	}
288
+
289
+
290
+	/**
291
+	 * @return void
292
+	 */
293
+	public function init()
294
+	{
295
+		// Get current page protocol
296
+		$protocol = is_ssl() ? 'https://' : 'http://';
297
+		// Output admin-ajax.php URL with same protocol as current page
298
+		self::$i18n_js_strings['ajax_url'] = admin_url('admin-ajax.php', $protocol);
299
+		self::$i18n_js_strings['wp_debug'] = defined('WP_DEBUG') && WP_DEBUG;
300
+	}
301
+
302
+
303
+	/**
304
+	 * @return array
305
+	 */
306
+	public static function sanitize_i18n_js_strings()
307
+	{
308
+		$i18n_js_strings = (array) self::$i18n_js_strings;
309
+		foreach ($i18n_js_strings as $key => $value) {
310
+			if (is_scalar($value)) {
311
+				$decoded_value           = html_entity_decode((string) $value, ENT_QUOTES, 'UTF-8');
312
+				$i18n_js_strings[ $key ] = wp_strip_all_tags($decoded_value);
313
+			}
314
+		}
315
+		return $i18n_js_strings;
316
+	}
317
+
318
+
319
+	/**
320
+	 * localize_i18n_js_strings
321
+	 *
322
+	 * @return string
323
+	 */
324
+	public static function localize_i18n_js_strings()
325
+	{
326
+		$i18n_js_strings = EE_Registry::sanitize_i18n_js_strings();
327
+		return '/* <![CDATA[ */ var eei18n = ' . wp_json_encode($i18n_js_strings) . '; /* ]]> */';
328
+	}
329
+
330
+
331
+	/**
332
+	 * @param mixed string | EED_Module $module
333
+	 * @throws OutOfBoundsException
334
+	 * @throws InvalidArgumentException
335
+	 * @throws InvalidInterfaceException
336
+	 * @throws InvalidDataTypeException
337
+	 * @throws EE_Error
338
+	 * @throws ReflectionException
339
+	 */
340
+	public function add_module($module)
341
+	{
342
+		if ($module instanceof EED_Module) {
343
+			$module_class = get_class($module);
344
+			$this->modules->add($module_class, $module);
345
+		} else {
346
+			if (! class_exists('EE_Module_Request_Router', false)) {
347
+				$this->load_core('Module_Request_Router');
348
+			}
349
+			EE_Module_Request_Router::module_factory($module);
350
+		}
351
+	}
352
+
353
+
354
+	/**
355
+	 * @param string $module_name
356
+	 * @return mixed EED_Module | NULL
357
+	 */
358
+	public function get_module($module_name = '')
359
+	{
360
+		return $this->modules->get($module_name);
361
+	}
362
+
363
+
364
+	/**
365
+	 * loads core classes - must be singletons
366
+	 *
367
+	 * @param string $class_name - simple class name ie: session
368
+	 * @param mixed  $arguments
369
+	 * @param bool   $load_only
370
+	 * @return mixed
371
+	 * @throws InvalidInterfaceException
372
+	 * @throws InvalidDataTypeException
373
+	 * @throws EE_Error
374
+	 * @throws ReflectionException
375
+	 * @throws InvalidArgumentException
376
+	 */
377
+	public function load_core($class_name, $arguments = array(), $load_only = false)
378
+	{
379
+		$core_paths = apply_filters(
380
+			'FHEE__EE_Registry__load_core__core_paths',
381
+			array(
382
+				EE_CORE,
383
+				EE_ADMIN,
384
+				EE_CPTS,
385
+				EE_CORE . 'CPTs/',
386
+				EE_CORE . 'data_migration_scripts/',
387
+				EE_CORE . 'request_stack/',
388
+				EE_CORE . 'middleware/',
389
+			)
390
+		);
391
+		// retrieve instantiated class
392
+		return $this->_load(
393
+			$core_paths,
394
+			'EE_',
395
+			$class_name,
396
+			'core',
397
+			$arguments,
398
+			false,
399
+			true,
400
+			$load_only
401
+		);
402
+	}
403
+
404
+
405
+	/**
406
+	 * loads service classes
407
+	 *
408
+	 * @param string $class_name - simple class name ie: session
409
+	 * @param mixed  $arguments
410
+	 * @param bool   $load_only
411
+	 * @return mixed
412
+	 * @throws InvalidInterfaceException
413
+	 * @throws InvalidDataTypeException
414
+	 * @throws EE_Error
415
+	 * @throws ReflectionException
416
+	 * @throws InvalidArgumentException
417
+	 */
418
+	public function load_service($class_name, $arguments = array(), $load_only = false)
419
+	{
420
+		$service_paths = apply_filters(
421
+			'FHEE__EE_Registry__load_service__service_paths',
422
+			array(
423
+				EE_CORE . 'services/',
424
+			)
425
+		);
426
+		// retrieve instantiated class
427
+		return $this->_load(
428
+			$service_paths,
429
+			'EE_',
430
+			$class_name,
431
+			'class',
432
+			$arguments,
433
+			false,
434
+			true,
435
+			$load_only
436
+		);
437
+	}
438
+
439
+
440
+	/**
441
+	 * loads data_migration_scripts
442
+	 *
443
+	 * @param string $class_name - class name for the DMS ie: EE_DMS_Core_4_2_0
444
+	 * @param mixed  $arguments
445
+	 * @return EE_Data_Migration_Script_Base|mixed
446
+	 * @throws InvalidInterfaceException
447
+	 * @throws InvalidDataTypeException
448
+	 * @throws EE_Error
449
+	 * @throws ReflectionException
450
+	 * @throws InvalidArgumentException
451
+	 */
452
+	public function load_dms($class_name, $arguments = array())
453
+	{
454
+		// retrieve instantiated class
455
+		return $this->_load(
456
+			EE_Data_Migration_Manager::instance()->get_data_migration_script_folders(),
457
+			'EE_DMS_',
458
+			$class_name,
459
+			'dms',
460
+			$arguments,
461
+			false,
462
+			false
463
+		);
464
+	}
465
+
466
+
467
+	/**
468
+	 * loads object creating classes - must be singletons
469
+	 *
470
+	 * @param string $class_name - simple class name ie: attendee
471
+	 * @param mixed  $arguments  - an array of arguments to pass to the class
472
+	 * @param bool   $from_db    - some classes are instantiated from the db and thus call a different method to
473
+	 *                           instantiate
474
+	 * @param bool   $cache      if you don't want the class to be stored in the internal cache (non-persistent) then
475
+	 *                           set this to FALSE (ie. when instantiating model objects from client in a loop)
476
+	 * @param bool   $load_only  whether or not to just load the file and NOT instantiate, or load AND instantiate
477
+	 *                           (default)
478
+	 * @return EE_Base_Class | bool
479
+	 * @throws InvalidInterfaceException
480
+	 * @throws InvalidDataTypeException
481
+	 * @throws EE_Error
482
+	 * @throws ReflectionException
483
+	 * @throws InvalidArgumentException
484
+	 */
485
+	public function load_class($class_name, $arguments = array(), $from_db = false, $cache = true, $load_only = false)
486
+	{
487
+		$paths = apply_filters(
488
+			'FHEE__EE_Registry__load_class__paths',
489
+			array(
490
+				EE_CORE,
491
+				EE_CLASSES,
492
+				EE_BUSINESS,
493
+			)
494
+		);
495
+		// retrieve instantiated class
496
+		return $this->_load(
497
+			$paths,
498
+			'EE_',
499
+			$class_name,
500
+			'class',
501
+			$arguments,
502
+			$from_db,
503
+			$cache,
504
+			$load_only
505
+		);
506
+	}
507
+
508
+
509
+	/**
510
+	 * loads helper classes - must be singletons
511
+	 *
512
+	 * @param string $class_name - simple class name ie: price
513
+	 * @param mixed  $arguments
514
+	 * @param bool   $load_only
515
+	 * @return EEH_Base | bool
516
+	 * @throws InvalidInterfaceException
517
+	 * @throws InvalidDataTypeException
518
+	 * @throws EE_Error
519
+	 * @throws ReflectionException
520
+	 * @throws InvalidArgumentException
521
+	 */
522
+	public function load_helper($class_name, $arguments = array(), $load_only = true)
523
+	{
524
+		// todo: add doing_it_wrong() in a few versions after all addons have had calls to this method removed
525
+		$helper_paths = apply_filters('FHEE__EE_Registry__load_helper__helper_paths', array(EE_HELPERS));
526
+		// retrieve instantiated class
527
+		return $this->_load(
528
+			$helper_paths,
529
+			'EEH_',
530
+			$class_name,
531
+			'helper',
532
+			$arguments,
533
+			false,
534
+			true,
535
+			$load_only
536
+		);
537
+	}
538
+
539
+
540
+	/**
541
+	 * loads core classes - must be singletons
542
+	 *
543
+	 * @param string $class_name - simple class name ie: session
544
+	 * @param mixed  $arguments
545
+	 * @param bool   $load_only
546
+	 * @param bool   $cache      whether to cache the object or not.
547
+	 * @return mixed
548
+	 * @throws InvalidInterfaceException
549
+	 * @throws InvalidDataTypeException
550
+	 * @throws EE_Error
551
+	 * @throws ReflectionException
552
+	 * @throws InvalidArgumentException
553
+	 */
554
+	public function load_lib($class_name, $arguments = array(), $load_only = false, $cache = true)
555
+	{
556
+		$paths = array(
557
+			EE_LIBRARIES,
558
+			EE_LIBRARIES . 'messages/',
559
+			EE_LIBRARIES . 'shortcodes/',
560
+			EE_LIBRARIES . 'qtips/',
561
+			EE_LIBRARIES . 'payment_methods/',
562
+		);
563
+		// retrieve instantiated class
564
+		return $this->_load(
565
+			$paths,
566
+			'EE_',
567
+			$class_name,
568
+			'lib',
569
+			$arguments,
570
+			false,
571
+			$cache,
572
+			$load_only
573
+		);
574
+	}
575
+
576
+
577
+	/**
578
+	 * loads model classes - must be singletons
579
+	 *
580
+	 * @param string $class_name - simple class name ie: price
581
+	 * @param mixed  $arguments
582
+	 * @param bool   $load_only
583
+	 * @return mixed
584
+	 * @throws InvalidInterfaceException
585
+	 * @throws InvalidDataTypeException
586
+	 * @throws EE_Error
587
+	 * @throws ReflectionException
588
+	 * @throws InvalidArgumentException
589
+	 */
590
+	public function load_model($class_name, $arguments = array(), $load_only = false)
591
+	{
592
+		$paths = apply_filters(
593
+			'FHEE__EE_Registry__load_model__paths',
594
+			array(
595
+				EE_MODELS,
596
+				EE_CORE,
597
+			)
598
+		);
599
+		// retrieve instantiated class
600
+		return $this->_load(
601
+			$paths,
602
+			'EEM_',
603
+			$class_name,
604
+			'model',
605
+			$arguments,
606
+			false,
607
+			true,
608
+			$load_only
609
+		);
610
+	}
611
+
612
+
613
+	/**
614
+	 * loads model classes - must be singletons
615
+	 *
616
+	 * @param string $class_name - simple class name ie: price
617
+	 * @param mixed  $arguments
618
+	 * @param bool   $load_only
619
+	 * @return mixed | bool
620
+	 * @throws InvalidInterfaceException
621
+	 * @throws InvalidDataTypeException
622
+	 * @throws EE_Error
623
+	 * @throws ReflectionException
624
+	 * @throws InvalidArgumentException
625
+	 */
626
+	public function load_model_class($class_name, $arguments = array(), $load_only = true)
627
+	{
628
+		$paths = array(
629
+			EE_MODELS . 'fields/',
630
+			EE_MODELS . 'helpers/',
631
+			EE_MODELS . 'relations/',
632
+			EE_MODELS . 'strategies/',
633
+		);
634
+		// retrieve instantiated class
635
+		return $this->_load(
636
+			$paths,
637
+			'EE_',
638
+			$class_name,
639
+			'',
640
+			$arguments,
641
+			false,
642
+			true,
643
+			$load_only
644
+		);
645
+	}
646
+
647
+
648
+	/**
649
+	 * Determines if $model_name is the name of an actual EE model.
650
+	 *
651
+	 * @param string $model_name like Event, Attendee, Question_Group_Question, etc.
652
+	 * @return boolean
653
+	 */
654
+	public function is_model_name($model_name)
655
+	{
656
+		return isset($this->models[ $model_name ]);
657
+	}
658
+
659
+
660
+	/**
661
+	 * generic class loader
662
+	 *
663
+	 * @param string $path_to_file - directory path to file location, not including filename
664
+	 * @param string $file_name    - file name  ie:  my_file.php, including extension
665
+	 * @param string $type         - file type - core? class? helper? model?
666
+	 * @param mixed  $arguments
667
+	 * @param bool   $load_only
668
+	 * @return mixed
669
+	 * @throws InvalidInterfaceException
670
+	 * @throws InvalidDataTypeException
671
+	 * @throws EE_Error
672
+	 * @throws ReflectionException
673
+	 * @throws InvalidArgumentException
674
+	 */
675
+	public function load_file($path_to_file, $file_name, $type = '', $arguments = array(), $load_only = true)
676
+	{
677
+		// retrieve instantiated class
678
+		return $this->_load(
679
+			$path_to_file,
680
+			'',
681
+			$file_name,
682
+			$type,
683
+			$arguments,
684
+			false,
685
+			true,
686
+			$load_only
687
+		);
688
+	}
689
+
690
+
691
+	/**
692
+	 * @param string $path_to_file - directory path to file location, not including filename
693
+	 * @param string $class_name   - full class name  ie:  My_Class
694
+	 * @param string $type         - file type - core? class? helper? model?
695
+	 * @param mixed  $arguments
696
+	 * @param bool   $load_only
697
+	 * @return bool|EE_Addon|object
698
+	 * @throws InvalidInterfaceException
699
+	 * @throws InvalidDataTypeException
700
+	 * @throws EE_Error
701
+	 * @throws ReflectionException
702
+	 * @throws InvalidArgumentException
703
+	 */
704
+	public function load_addon($path_to_file, $class_name, $type = 'class', $arguments = array(), $load_only = false)
705
+	{
706
+		// retrieve instantiated class
707
+		return $this->_load(
708
+			$path_to_file,
709
+			'addon',
710
+			$class_name,
711
+			$type,
712
+			$arguments,
713
+			false,
714
+			true,
715
+			$load_only
716
+		);
717
+	}
718
+
719
+
720
+	/**
721
+	 * instantiates, caches, and automatically resolves dependencies
722
+	 * for classes that use a Fully Qualified Class Name.
723
+	 * if the class is not capable of being loaded using PSR-4 autoloading,
724
+	 * then you need to use one of the existing load_*() methods
725
+	 * which can resolve the classname and filepath from the passed arguments
726
+	 *
727
+	 * @param bool|string $class_name   Fully Qualified Class Name
728
+	 * @param array       $arguments    an argument, or array of arguments to pass to the class upon instantiation
729
+	 * @param bool        $cache        whether to cache the instantiated object for reuse
730
+	 * @param bool        $from_db      some classes are instantiated from the db
731
+	 *                                  and thus call a different method to instantiate
732
+	 * @param bool        $load_only    if true, will only load the file, but will NOT instantiate an object
733
+	 * @param bool|string $addon        if true, will cache the object in the EE_Registry->$addons array
734
+	 * @return bool|null|mixed          null = failure to load or instantiate class object.
735
+	 *                                  object = class loaded and instantiated successfully.
736
+	 *                                  bool = fail or success when $load_only is true
737
+	 * @throws InvalidInterfaceException
738
+	 * @throws InvalidDataTypeException
739
+	 * @throws EE_Error
740
+	 * @throws ReflectionException
741
+	 * @throws InvalidArgumentException
742
+	 */
743
+	public function create(
744
+		$class_name = false,
745
+		$arguments = array(),
746
+		$cache = false,
747
+		$from_db = false,
748
+		$load_only = false,
749
+		$addon = false
750
+	) {
751
+		$class_name = ltrim($class_name, '\\');
752
+		$class_name = $this->class_cache->getFqnForAlias($class_name);
753
+		$class_exists = $this->loadOrVerifyClassExists($class_name, $arguments);
754
+		// if a non-FQCN was passed, then
755
+		// verifyClassExists() might return an object
756
+		// or it could return null if the class just could not be found anywhere
757
+		if ($class_exists instanceof $class_name || $class_exists === null) {
758
+			// either way, return the results
759
+			return $class_exists;
760
+		}
761
+		$class_name = $class_exists;
762
+		// if we're only loading the class and it already exists, then let's just return true immediately
763
+		if ($load_only) {
764
+			return true;
765
+		}
766
+		$addon = $addon ? 'addon' : '';
767
+		// $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
768
+		// $cache is controlled by individual calls to separate Registry loader methods like load_class()
769
+		// $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
770
+		if ($this->_cache_on && $cache && ! $load_only) {
771
+			// return object if it's already cached
772
+			$cached_class = $this->_get_cached_class($class_name, $addon, $arguments);
773
+			if ($cached_class !== null) {
774
+				return $cached_class;
775
+			}
776
+		}// obtain the loader method from the dependency map
777
+		$loader = $this->_dependency_map->class_loader($class_name);// instantiate the requested object
778
+		if ($loader instanceof Closure) {
779
+			$class_obj = $loader($arguments);
780
+		} else {
781
+			if ($loader && method_exists($this, $loader)) {
782
+				$class_obj = $this->{$loader}($class_name, $arguments);
783
+			} else {
784
+				$class_obj = $this->_create_object($class_name, $arguments, $addon, $from_db);
785
+			}
786
+		}
787
+		if (($this->_cache_on && $cache) || $this->get_class_abbreviation($class_name, '')) {
788
+			// save it for later... kinda like gum  { : $
789
+			$this->_set_cached_class(
790
+				$class_obj,
791
+				$class_name,
792
+				$addon,
793
+				$from_db,
794
+				$arguments
795
+			);
796
+		}
797
+		$this->_cache_on = true;
798
+		return $class_obj;
799
+	}
800
+
801
+
802
+	/**
803
+	 * Recursively checks that a class exists and potentially attempts to load classes with non-FQCNs
804
+	 *
805
+	 * @param string|object $class_name
806
+	 * @param array         $arguments
807
+	 * @param int           $attempt
808
+	 * @return mixed
809
+	 */
810
+	private function loadOrVerifyClassExists($class_name, array $arguments, $attempt = 1)
811
+	{
812
+		if (is_object($class_name) || class_exists($class_name)) {
813
+			return $class_name;
814
+		}
815
+		switch ($attempt) {
816
+			case 1:
817
+				// if it's a FQCN then maybe the class is registered with a preceding \
818
+				$class_name = strpos($class_name, '\\') !== false
819
+					? '\\' . ltrim($class_name, '\\')
820
+					: $class_name;
821
+				break;
822
+			case 2:
823
+				//
824
+				$loader = $this->_dependency_map->class_loader($class_name);
825
+				if ($loader && method_exists($this, $loader)) {
826
+					return $this->{$loader}($class_name, $arguments);
827
+				}
828
+				break;
829
+			case 3:
830
+			default:
831
+				return null;
832
+		}
833
+		$attempt++;
834
+		return $this->loadOrVerifyClassExists($class_name, $arguments, $attempt);
835
+	}
836
+
837
+
838
+	/**
839
+	 * instantiates, caches, and injects dependencies for classes
840
+	 *
841
+	 * @param array       $file_paths   an array of paths to folders to look in
842
+	 * @param string      $class_prefix EE  or EEM or... ???
843
+	 * @param bool|string $class_name   $class name
844
+	 * @param string      $type         file type - core? class? helper? model?
845
+	 * @param mixed       $arguments    an argument or array of arguments to pass to the class upon instantiation
846
+	 * @param bool        $from_db      some classes are instantiated from the db
847
+	 *                                  and thus call a different method to instantiate
848
+	 * @param bool        $cache        whether to cache the instantiated object for reuse
849
+	 * @param bool        $load_only    if true, will only load the file, but will NOT instantiate an object
850
+	 * @return bool|null|object null = failure to load or instantiate class object.
851
+	 *                                  object = class loaded and instantiated successfully.
852
+	 *                                  bool = fail or success when $load_only is true
853
+	 * @throws EE_Error
854
+	 * @throws ReflectionException
855
+	 * @throws InvalidInterfaceException
856
+	 * @throws InvalidDataTypeException
857
+	 * @throws InvalidArgumentException
858
+	 */
859
+	protected function _load(
860
+		$file_paths = array(),
861
+		$class_prefix = 'EE_',
862
+		$class_name = false,
863
+		$type = 'class',
864
+		$arguments = array(),
865
+		$from_db = false,
866
+		$cache = true,
867
+		$load_only = false
868
+	) {
869
+		$class_name = ltrim($class_name, '\\');
870
+		// strip php file extension
871
+		$class_name = str_replace('.php', '', trim($class_name));
872
+		// does the class have a prefix ?
873
+		if (! empty($class_prefix) && $class_prefix !== 'addon') {
874
+			// make sure $class_prefix is uppercase
875
+			$class_prefix = strtoupper(trim($class_prefix));
876
+			// add class prefix ONCE!!!
877
+			$class_name = $class_prefix . str_replace($class_prefix, '', $class_name);
878
+		}
879
+		$class_name = $this->class_cache->getFqnForAlias($class_name);
880
+		$class_exists = class_exists($class_name, false);
881
+		// if we're only loading the class and it already exists, then let's just return true immediately
882
+		if ($load_only && $class_exists) {
883
+			return true;
884
+		}
885
+		$arguments = is_array($arguments) ? $arguments : array($arguments);
886
+		// $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
887
+		// $cache is controlled by individual calls to separate Registry loader methods like load_class()
888
+		// $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
889
+		if ($this->_cache_on && $cache && ! $load_only) {
890
+			// return object if it's already cached
891
+			$cached_class = $this->_get_cached_class($class_name, $class_prefix, $arguments);
892
+			if ($cached_class !== null) {
893
+				return $cached_class;
894
+			}
895
+		}
896
+		// if the class doesn't already exist.. then we need to try and find the file and load it
897
+		if (! $class_exists) {
898
+			// get full path to file
899
+			$path = $this->_resolve_path($class_name, $type, $file_paths);
900
+			// load the file
901
+			$loaded = $this->_require_file($path, $class_name, $type, $file_paths);
902
+			// if we are only loading a file but NOT instantiating an object
903
+			// then return boolean for whether class was loaded or not
904
+			if ($load_only) {
905
+				return $loaded;
906
+			}
907
+			// if an object was expected but loading failed, then return nothing
908
+			if (! $loaded) {
909
+				return null;
910
+			}
911
+		}
912
+		// instantiate the requested object
913
+		$class_obj = $this->_create_object($class_name, $arguments, $type, $from_db);
914
+		if ($this->_cache_on && $cache) {
915
+			// save it for later... kinda like gum  { : $
916
+			$this->_set_cached_class(
917
+				$class_obj,
918
+				$class_name,
919
+				$class_prefix,
920
+				$from_db,
921
+				$arguments
922
+			);
923
+		}
924
+		$this->_cache_on = true;
925
+		return $class_obj;
926
+	}
927
+
928
+
929
+	/**
930
+	 * @param string $class_name
931
+	 * @param string $default have to specify something, but not anything that will conflict
932
+	 * @return mixed|string
933
+	 */
934
+	protected function get_class_abbreviation($class_name, $default = 'FANCY_BATMAN_PANTS')
935
+	{
936
+		return isset($this->_class_abbreviations[ $class_name ])
937
+			? $this->_class_abbreviations[ $class_name ]
938
+			: $default;
939
+	}
940
+
941
+
942
+	/**
943
+	 * attempts to find a cached version of the requested class
944
+	 * by looking in the following places:
945
+	 *        $this->{$class_abbreviation}            ie:    $this->CART
946
+	 *        $this->{$class_name}                        ie:    $this->Some_Class
947
+	 *        $this->LIB->{$class_name}                ie:    $this->LIB->Some_Class
948
+	 *        $this->addon->{$class_name}    ie:    $this->addon->Some_Addon_Class
949
+	 *
950
+	 * @param string $class_name
951
+	 * @param string $class_prefix
952
+	 * @param array  $arguments
953
+	 * @return mixed
954
+	 */
955
+	protected function _get_cached_class(
956
+		$class_name,
957
+		$class_prefix = '',
958
+		$arguments = array()
959
+	) {
960
+		if ($class_name === 'EE_Registry') {
961
+			return $this;
962
+		}
963
+		$class_abbreviation = $this->get_class_abbreviation($class_name);
964
+		// check if class has already been loaded, and return it if it has been
965
+		if (isset($this->{$class_abbreviation})) {
966
+			return $this->{$class_abbreviation};
967
+		}
968
+		$class_name = str_replace('\\', '_', $class_name);
969
+		if (isset($this->{$class_name})) {
970
+			return $this->{$class_name};
971
+		}
972
+		if ($class_prefix === 'addon' && $this->addons->has($class_name)) {
973
+			return $this->addons->get($class_name);
974
+		}
975
+		$object_identifier = $this->object_identifier->getIdentifier($class_name, $arguments);
976
+		if ($this->LIB->has($object_identifier)) {
977
+			return $this->LIB->get($object_identifier);
978
+		}
979
+		foreach ($this->LIB as $key => $object) {
980
+			if (
981 981
 // request does not contain new arguments and therefore no args identifier
982
-                ! $this->object_identifier->hasArguments($object_identifier)
983
-                // but previously cached class with args was found
984
-                && $this->object_identifier->fqcnMatchesObjectIdentifier($class_name, $key)
985
-            ) {
986
-                return $object;
987
-            }
988
-        }
989
-        return null;
990
-    }
991
-
992
-
993
-    /**
994
-     * removes a cached version of the requested class
995
-     *
996
-     * @param string  $class_name
997
-     * @param boolean $addon
998
-     * @param array   $arguments
999
-     * @return boolean
1000
-     */
1001
-    public function clear_cached_class(
1002
-        $class_name,
1003
-        $addon = false,
1004
-        $arguments = array()
1005
-    ) {
1006
-        $class_abbreviation = $this->get_class_abbreviation($class_name);
1007
-        // check if class has already been loaded, and return it if it has been
1008
-        if (isset($this->{$class_abbreviation})) {
1009
-            $this->{$class_abbreviation} = null;
1010
-            return true;
1011
-        }
1012
-        $class_name = str_replace('\\', '_', $class_name);
1013
-        if (isset($this->{$class_name})) {
1014
-            $this->{$class_name} = null;
1015
-            return true;
1016
-        }
1017
-        if ($addon && $this->addons->has($class_name)) {
1018
-            $this->addons->remove($class_name);
1019
-            return true;
1020
-        }
1021
-        $class_name = $this->object_identifier->getIdentifier($class_name, $arguments);
1022
-        if ($this->LIB->has($class_name)) {
1023
-            $this->LIB->remove($class_name);
1024
-            return true;
1025
-        }
1026
-        return false;
1027
-    }
1028
-
1029
-
1030
-    /**
1031
-     * _set_cached_class
1032
-     * attempts to cache the instantiated class locally
1033
-     * in one of the following places, in the following order:
1034
-     *        $this->{class_abbreviation}   ie:    $this->CART
1035
-     *        $this->{$class_name}          ie:    $this->Some_Class
1036
-     *        $this->addon->{$$class_name}    ie:    $this->addon->Some_Addon_Class
1037
-     *        $this->LIB->{$class_name}     ie:    $this->LIB->Some_Class
1038
-     *
1039
-     * @param object $class_obj
1040
-     * @param string $class_name
1041
-     * @param string $class_prefix
1042
-     * @param bool   $from_db
1043
-     * @param array  $arguments
1044
-     * @return void
1045
-     */
1046
-    protected function _set_cached_class(
1047
-        $class_obj,
1048
-        $class_name,
1049
-        $class_prefix = '',
1050
-        $from_db = false,
1051
-        $arguments = array()
1052
-    ) {
1053
-        if ($class_name === 'EE_Registry' || empty($class_obj)) {
1054
-            return;
1055
-        }
1056
-        // return newly instantiated class
1057
-        $class_abbreviation = $this->get_class_abbreviation($class_name, '');
1058
-        if ($class_abbreviation) {
1059
-            $this->{$class_abbreviation} = $class_obj;
1060
-            return;
1061
-        }
1062
-        $class_name = str_replace('\\', '_', $class_name);
1063
-        if (property_exists($this, $class_name)) {
1064
-            $this->{$class_name} = $class_obj;
1065
-            return;
1066
-        }
1067
-        if ($class_prefix === 'addon') {
1068
-            $this->addons->add($class_name, $class_obj);
1069
-            return;
1070
-        }
1071
-        if (! $from_db) {
1072
-            $class_name = $this->object_identifier->getIdentifier($class_name, $arguments);
1073
-            $this->LIB->add($class_name, $class_obj);
1074
-        }
1075
-    }
1076
-
1077
-
1078
-    /**
1079
-     * attempts to find a full valid filepath for the requested class.
1080
-     * loops thru each of the base paths in the $file_paths array and appends : "{classname} . {file type} . php"
1081
-     * then returns that path if the target file has been found and is readable
1082
-     *
1083
-     * @param string $class_name
1084
-     * @param string $type
1085
-     * @param array  $file_paths
1086
-     * @return string | bool
1087
-     */
1088
-    protected function _resolve_path($class_name, $type = '', $file_paths = array())
1089
-    {
1090
-        // make sure $file_paths is an array
1091
-        $file_paths = is_array($file_paths)
1092
-            ? $file_paths
1093
-            : array($file_paths);
1094
-        // cycle thru paths
1095
-        foreach ($file_paths as $key => $file_path) {
1096
-            // convert all separators to proper /, if no filepath, then use EE_CLASSES
1097
-            $file_path = $file_path
1098
-                ? str_replace(array('/', '\\'), '/', $file_path)
1099
-                : EE_CLASSES;
1100
-            // prep file type
1101
-            $type = ! empty($type)
1102
-                ? trim($type, '.') . '.'
1103
-                : '';
1104
-            // build full file path
1105
-            $file_paths[ $key ] = rtrim($file_path, '/') . '/' . $class_name . '.' . $type . 'php';
1106
-            // does the file exist and can be read ?
1107
-            if (is_readable($file_paths[ $key ])) {
1108
-                return $file_paths[ $key ];
1109
-            }
1110
-        }
1111
-        return false;
1112
-    }
1113
-
1114
-
1115
-    /**
1116
-     * basically just performs a require_once()
1117
-     * but with some error handling
1118
-     *
1119
-     * @param  string $path
1120
-     * @param  string $class_name
1121
-     * @param  string $type
1122
-     * @param  array  $file_paths
1123
-     * @return bool
1124
-     * @throws EE_Error
1125
-     * @throws ReflectionException
1126
-     */
1127
-    protected function _require_file($path, $class_name, $type = '', $file_paths = array())
1128
-    {
1129
-        $this->resolve_legacy_class_parent($class_name);
1130
-        // don't give up! you gotta...
1131
-        try {
1132
-            // does the file exist and can it be read ?
1133
-            if (! $path) {
1134
-                // just in case the file has already been autoloaded,
1135
-                // but discrepancies in the naming schema are preventing it from
1136
-                // being loaded via one of the EE_Registry::load_*() methods,
1137
-                // then let's try one last hail mary before throwing an exception
1138
-                // and call class_exists() again, but with autoloading turned ON
1139
-                if (class_exists($class_name)) {
1140
-                    return true;
1141
-                }
1142
-                // so sorry, can't find the file
1143
-                throw new EE_Error(
1144
-                    sprintf(
1145
-                        esc_html__(
1146
-                            'The %1$s file %2$s could not be located or is not readable due to file permissions. Please ensure that the following filepath(s) are correct: %3$s',
1147
-                            'event_espresso'
1148
-                        ),
1149
-                        trim($type, '.'),
1150
-                        $class_name,
1151
-                        '<br />' . implode(',<br />', $file_paths)
1152
-                    )
1153
-                );
1154
-            }
1155
-            // get the file
1156
-            require_once($path);
1157
-            // if the class isn't already declared somewhere
1158
-            if (class_exists($class_name, false) === false) {
1159
-                // so sorry, not a class
1160
-                throw new EE_Error(
1161
-                    sprintf(
1162
-                        esc_html__(
1163
-                            'The %s file %s does not appear to contain the %s Class.',
1164
-                            'event_espresso'
1165
-                        ),
1166
-                        $type,
1167
-                        $path,
1168
-                        $class_name
1169
-                    )
1170
-                );
1171
-            }
1172
-        } catch (EE_Error $e) {
1173
-            $e->get_error();
1174
-            return false;
1175
-        }
1176
-        return true;
1177
-    }
1178
-
1179
-
1180
-    /**
1181
-     * Some of our legacy classes that extended a parent class would simply use a require() statement
1182
-     * before their class declaration in order to ensure that the parent class was loaded.
1183
-     * This is not ideal, but it's nearly impossible to determine the parent class of a non-namespaced class,
1184
-     * without triggering a fatal error because the parent class has yet to be loaded and therefore doesn't exist.
1185
-     *
1186
-     * @param string $class_name
1187
-     */
1188
-    protected function resolve_legacy_class_parent($class_name = '')
1189
-    {
1190
-        try {
1191
-            $legacy_parent_class_map = array(
1192
-                'EE_Payment_Processor' => 'core/business/EE_Processor_Base.class.php',
1193
-            );
1194
-            if (isset($legacy_parent_class_map[ $class_name ])) {
1195
-                require_once EE_PLUGIN_DIR_PATH . $legacy_parent_class_map[ $class_name ];
1196
-            }
1197
-        } catch (Exception $exception) {
1198
-        }
1199
-    }
1200
-
1201
-
1202
-    /**
1203
-     * _create_object
1204
-     * Attempts to instantiate the requested class via any of the
1205
-     * commonly used instantiation methods employed throughout EE.
1206
-     * The priority for instantiation is as follows:
1207
-     *        - abstract classes or any class flagged as "load only" (no instantiation occurs)
1208
-     *        - model objects via their 'new_instance_from_db' method
1209
-     *        - model objects via their 'new_instance' method
1210
-     *        - "singleton" classes" via their 'instance' method
1211
-     *    - standard instantiable classes via their __constructor
1212
-     * Prior to instantiation, if the classname exists in the dependency_map,
1213
-     * then the constructor for the requested class will be examined to determine
1214
-     * if any dependencies exist, and if they can be injected.
1215
-     * If so, then those classes will be added to the array of arguments passed to the constructor
1216
-     *
1217
-     * @param string $class_name
1218
-     * @param array  $arguments
1219
-     * @param string $type
1220
-     * @param bool   $from_db
1221
-     * @return null|object|bool
1222
-     * @throws InvalidArgumentException
1223
-     * @throws InvalidInterfaceException
1224
-     * @throws EE_Error
1225
-     * @throws ReflectionException
1226
-     * @throws InvalidDataTypeException
1227
-     */
1228
-    protected function _create_object($class_name, $arguments = array(), $type = '', $from_db = false)
1229
-    {
1230
-        // create reflection
1231
-        $reflector = $this->mirror->getReflectionClass($class_name);
1232
-        // make sure arguments are an array
1233
-        $arguments = is_array($arguments)
1234
-            ? $arguments
1235
-            : array($arguments);
1236
-        // and if arguments array is numerically and sequentially indexed, then we want it to remain as is,
1237
-        // else wrap it in an additional array so that it doesn't get split into multiple parameters
1238
-        $arguments = $this->_array_is_numerically_and_sequentially_indexed($arguments)
1239
-            ? $arguments
1240
-            : array($arguments);
1241
-        // attempt to inject dependencies ?
1242
-        if ($this->_dependency_map->has($class_name)) {
1243
-            $arguments = $this->_resolve_dependencies($reflector, $class_name, $arguments);
1244
-        }
1245
-        // instantiate the class if possible
1246
-        if ($reflector->isAbstract()) {
1247
-            // nothing to instantiate, loading file was enough
1248
-            // does not throw an exception so $instantiation_mode is unused
1249
-            // $instantiation_mode = "1) no constructor abstract class";
1250
-            return true;
1251
-        }
1252
-        if (
1253
-            empty($arguments)
1254
-            && $this->mirror->getConstructorFromReflection($reflector) === null
1255
-            && $reflector->isInstantiable()
1256
-        ) {
1257
-            // no constructor = static methods only... nothing to instantiate, loading file was enough
1258
-            // $instantiation_mode = "2) no constructor but instantiable";
1259
-            return $reflector->newInstance();
1260
-        }
1261
-        if ($from_db && method_exists($class_name, 'new_instance_from_db')) {
1262
-            // $instantiation_mode = "3) new_instance_from_db()";
1263
-            return call_user_func_array(array($class_name, 'new_instance_from_db'), $arguments);
1264
-        }
1265
-        if (method_exists($class_name, 'new_instance')) {
1266
-            // $instantiation_mode = "4) new_instance()";
1267
-            return call_user_func_array(array($class_name, 'new_instance'), $arguments);
1268
-        }
1269
-        if (method_exists($class_name, 'instance')) {
1270
-            // $instantiation_mode = "5) instance()";
1271
-            return call_user_func_array(array($class_name, 'instance'), $arguments);
1272
-        }
1273
-        if ($reflector->isInstantiable()) {
1274
-            // $instantiation_mode = "6) constructor";
1275
-            return $reflector->newInstanceArgs($arguments);
1276
-        }
1277
-        // heh ? something's not right !
1278
-        throw new EE_Error(
1279
-            sprintf(
1280
-                esc_html__('The %s file %s could not be instantiated.', 'event_espresso'),
1281
-                $type,
1282
-                $class_name
1283
-            )
1284
-        );
1285
-    }
1286
-
1287
-
1288
-    /**
1289
-     * @see http://stackoverflow.com/questions/173400/how-to-check-if-php-array-is-associative-or-sequential
1290
-     * @param array $array
1291
-     * @return bool
1292
-     */
1293
-    protected function _array_is_numerically_and_sequentially_indexed(array $array)
1294
-    {
1295
-        return ! empty($array)
1296
-            ? array_keys($array) === range(0, count($array) - 1)
1297
-            : true;
1298
-    }
1299
-
1300
-
1301
-    /**
1302
-     * _resolve_dependencies
1303
-     * examines the constructor for the requested class to determine
1304
-     * if any dependencies exist, and if they can be injected.
1305
-     * If so, then those classes will be added to the array of arguments passed to the constructor
1306
-     * PLZ NOTE: this is achieved by type hinting the constructor params
1307
-     * For example:
1308
-     *        if attempting to load a class "Foo" with the following constructor:
1309
-     *        __construct( Bar $bar_class, Fighter $grohl_class )
1310
-     *        then $bar_class and $grohl_class will be added to the $arguments array,
1311
-     *        but only IF they are NOT already present in the incoming arguments array,
1312
-     *        and the correct classes can be loaded
1313
-     *
1314
-     * @param ReflectionClass $reflector
1315
-     * @param string          $class_name
1316
-     * @param array           $arguments
1317
-     * @return array
1318
-     * @throws InvalidArgumentException
1319
-     * @throws InvalidDataTypeException
1320
-     * @throws InvalidInterfaceException
1321
-     * @throws ReflectionException
1322
-     */
1323
-    protected function _resolve_dependencies(ReflectionClass $reflector, $class_name, array $arguments = array())
1324
-    {
1325
-        // let's examine the constructor
1326
-        $constructor = $this->mirror->getConstructorFromReflection($reflector);
1327
-        // whu? huh? nothing?
1328
-        if (! $constructor) {
1329
-            return $arguments;
1330
-        }
1331
-        // get constructor parameters
1332
-        $params = $this->mirror->getParametersFromReflection($reflector);
1333
-        // and the keys for the incoming arguments array so that we can compare existing arguments with what is expected
1334
-        $argument_keys = array_keys($arguments);
1335
-        // now loop thru all of the constructors expected parameters
1336
-        foreach ($params as $index => $param) {
1337
-            try {
1338
-                // is this a dependency for a specific class ?
1339
-                $param_class = $this->mirror->getParameterClassName($param, $class_name, $index);
1340
-            } catch (ReflectionException $exception) {
1341
-                // uh-oh... most likely a legacy class that has not been autoloaded
1342
-                // let's try to derive the classname from what we have now
1343
-                // and hope that the property var name is close to the class name
1344
-                $param_class = $param->getName();
1345
-                $param_class = str_replace('_', ' ', $param_class);
1346
-                $param_class = ucwords($param_class);
1347
-                $param_class = str_replace(' ', '_', $param_class);
1348
-            }
1349
-            // BUT WAIT !!! This class may be an alias for something else (or getting replaced at runtime)
1350
-            $param_class = $this->class_cache->isAlias($param_class, $class_name)
1351
-                ? $this->class_cache->getFqnForAlias($param_class, $class_name)
1352
-                : $param_class;
1353
-            if (
1354
-                // param is not even a class
1355
-                $param_class === null
1356
-                // and something already exists in the incoming arguments for this param
1357
-                && array_key_exists($index, $argument_keys)
1358
-                && array_key_exists($argument_keys[ $index ], $arguments)
1359
-            ) {
1360
-                // so let's skip this argument and move on to the next
1361
-                continue;
1362
-            }
1363
-            if (
1364
-                // parameter is type hinted as a class, exists as an incoming argument, AND it's the correct class
1365
-                $param_class !== null
1366
-                && isset($argument_keys[ $index ], $arguments[ $argument_keys[ $index ] ])
1367
-                && $arguments[ $argument_keys[ $index ] ] instanceof $param_class
1368
-            ) {
1369
-                // skip this argument and move on to the next
1370
-                continue;
1371
-            }
1372
-            if (
1373
-                // parameter is type hinted as a class, and should be injected
1374
-                $param_class !== null
1375
-                && $this->_dependency_map->has_dependency_for_class($class_name, $param_class)
1376
-            ) {
1377
-                $arguments = $this->_resolve_dependency(
1378
-                    $class_name,
1379
-                    $param_class,
1380
-                    $arguments,
1381
-                    $index
1382
-                );
1383
-            }
1384
-            if (empty($arguments[ $index ])) {
1385
-                $default_value = $this->mirror->getParameterDefaultValue(
1386
-                    $param,
1387
-                    $class_name,
1388
-                    $index
1389
-                );
1390
-                // if there's no default value, and the incoming argument is an array (albeit empty), then use that
1391
-                $arguments[ $index ] = $default_value === null
1392
-                                 && isset($arguments[ $index ])
1393
-                                 && is_array($arguments[ $index ])
1394
-                    ? $arguments[ $index ]
1395
-                    : $default_value;
1396
-            }
1397
-        }
1398
-        return $arguments;
1399
-    }
1400
-
1401
-
1402
-    /**
1403
-     * @param string $class_name
1404
-     * @param string $param_class
1405
-     * @param array  $arguments
1406
-     * @param mixed  $index
1407
-     * @return array
1408
-     * @throws InvalidArgumentException
1409
-     * @throws InvalidInterfaceException
1410
-     * @throws InvalidDataTypeException
1411
-     */
1412
-    protected function _resolve_dependency($class_name, $param_class, $arguments, $index)
1413
-    {
1414
-        $dependency = null;
1415
-        // should dependency be loaded from cache ?
1416
-        $cache_on = $this->_dependency_map->loading_strategy_for_class_dependency(
1417
-            $class_name,
1418
-            $param_class
1419
-        );
1420
-        $cache_on = $cache_on !== EE_Dependency_Map::load_new_object;
1421
-        // we might have a dependency...
1422
-        // let's MAYBE try and find it in our cache if that's what's been requested
1423
-        $cached_class = $cache_on
1424
-            ? $this->_get_cached_class($param_class)
1425
-            : null;
1426
-        // and grab it if it exists
1427
-        if ($cached_class instanceof $param_class) {
1428
-            $dependency = $cached_class;
1429
-        } elseif ($param_class !== $class_name) {
1430
-            // obtain the loader method from the dependency map
1431
-            $loader = $this->_dependency_map->class_loader($param_class);
1432
-            // is loader a custom closure ?
1433
-            if ($loader instanceof Closure) {
1434
-                $dependency = $loader($arguments);
1435
-            } else {
1436
-                // set the cache on property for the recursive loading call
1437
-                $this->_cache_on = $cache_on;
1438
-                // if not, then let's try and load it via the registry
1439
-                if ($loader && method_exists($this, $loader)) {
1440
-                    $dependency = $this->{$loader}($param_class);
1441
-                } else {
1442
-                    $dependency = LoaderFactory::getLoader()->load(
1443
-                        $param_class,
1444
-                        array(),
1445
-                        $cache_on
1446
-                    );
1447
-                }
1448
-            }
1449
-        }
1450
-        // did we successfully find the correct dependency ?
1451
-        if ($dependency instanceof $param_class) {
1452
-            // then let's inject it into the incoming array of arguments at the correct location
1453
-            $arguments[ $index ] = $dependency;
1454
-        }
1455
-        return $arguments;
1456
-    }
1457
-
1458
-
1459
-    /**
1460
-     * call any loader that's been registered in the EE_Dependency_Map::$_class_loaders array
1461
-     *
1462
-     * @param string $classname PLEASE NOTE: the class name needs to match what's registered
1463
-     *                          in the EE_Dependency_Map::$_class_loaders array,
1464
-     *                          including the class prefix, ie: "EE_", "EEM_", "EEH_", etc
1465
-     * @param array  $arguments
1466
-     * @return object
1467
-     */
1468
-    public static function factory($classname, $arguments = array())
1469
-    {
1470
-        $loader = self::instance()->_dependency_map->class_loader($classname);
1471
-        if ($loader instanceof Closure) {
1472
-            return $loader($arguments);
1473
-        }
1474
-        if (method_exists(self::instance(), $loader)) {
1475
-            return self::instance()->{$loader}($classname, $arguments);
1476
-        }
1477
-        return null;
1478
-    }
1479
-
1480
-
1481
-    /**
1482
-     * Gets the addon by its class name
1483
-     *
1484
-     * @param string $class_name
1485
-     * @return EE_Addon
1486
-     */
1487
-    public function getAddon($class_name)
1488
-    {
1489
-        $class_name = str_replace('\\', '_', $class_name);
1490
-        if (isset($this->addons->{$class_name})) {
1491
-            return $this->addons->{$class_name};
1492
-        } else {
1493
-            return null;
1494
-        }
1495
-    }
1496
-
1497
-
1498
-    /**
1499
-     * removes the addon from the internal cache
1500
-     *
1501
-     * @param string $class_name
1502
-     * @return void
1503
-     */
1504
-    public function removeAddon($class_name)
1505
-    {
1506
-        $class_name = str_replace('\\', '_', $class_name);
1507
-        $this->addons->remove($class_name);
1508
-    }
1509
-
1510
-
1511
-    /**
1512
-     * Gets the addon by its name/slug (not classname. For that, just
1513
-     * use the get_addon() method above
1514
-     *
1515
-     * @param string $name
1516
-     * @return EE_Addon
1517
-     */
1518
-    public function get_addon_by_name($name)
1519
-    {
1520
-        foreach ($this->addons as $addon) {
1521
-            if ($addon->name() === $name) {
1522
-                return $addon;
1523
-            }
1524
-        }
1525
-        return null;
1526
-    }
1527
-
1528
-
1529
-    /**
1530
-     * Gets an array of all the registered addons, where the keys are their names.
1531
-     * (ie, what each returns for their name() function)
1532
-     * They're already available on EE_Registry::instance()->addons as properties,
1533
-     * where each property's name is the addon's classname,
1534
-     * So if you just want to get the addon by classname,
1535
-     * OR use the get_addon() method above.
1536
-     * PLEASE  NOTE:
1537
-     * addons with Fully Qualified Class Names
1538
-     * have had the namespace separators converted to underscores,
1539
-     * so a classname like Fully\Qualified\ClassName
1540
-     * would have been converted to Fully_Qualified_ClassName
1541
-     *
1542
-     * @return EE_Addon[] where the KEYS are the addon's name()
1543
-     */
1544
-    public function get_addons_by_name()
1545
-    {
1546
-        $addons = array();
1547
-        foreach ($this->addons as $addon) {
1548
-            $addons[ $addon->name() ] = $addon;
1549
-        }
1550
-        return $addons;
1551
-    }
1552
-
1553
-
1554
-    /**
1555
-     * Resets the specified model's instance AND makes sure EE_Registry doesn't keep
1556
-     * a stale copy of it around
1557
-     *
1558
-     * @param string $model_name
1559
-     * @return \EEM_Base
1560
-     * @throws \EE_Error
1561
-     */
1562
-    public function reset_model($model_name)
1563
-    {
1564
-        $model_class_name = strpos($model_name, 'EEM_') !== 0
1565
-            ? "EEM_{$model_name}"
1566
-            : $model_name;
1567
-        if (! $this->LIB->has($model_class_name)) {
1568
-            return null;
1569
-        }
1570
-        $model = $this->LIB->get($model_class_name);
1571
-        if (! $model instanceof EEM_Base) {
1572
-            return null;
1573
-        }
1574
-        // get that model reset it and make sure we nuke the old reference to it
1575
-        if ($model instanceof $model_class_name && is_callable([$model_class_name, 'reset'])) {
1576
-            $this->LIB->remove($model_class_name);
1577
-            $this->LIB->add($model_class_name, $model->reset());
1578
-        } else {
1579
-            throw new EE_Error(
1580
-                sprintf(
1581
-                    esc_html__('Model %s does not have a method "reset"', 'event_espresso'),
1582
-                    $model_name
1583
-                )
1584
-            );
1585
-        }
1586
-        return $model;
1587
-    }
1588
-
1589
-
1590
-    /**
1591
-     * Resets the registry.
1592
-     * The criteria for what gets reset is based on what can be shared between sites on the same request when
1593
-     * switch_to_blog is used in a multisite install.  Here is a list of things that are NOT reset.
1594
-     * - $_dependency_map
1595
-     * - $_class_abbreviations
1596
-     * - $NET_CFG (EE_Network_Config): The config is shared network wide so no need to reset.
1597
-     * - $REQ:  Still on the same request so no need to change.
1598
-     * - $CAP: There is no site specific state in the EE_Capability class.
1599
-     * - $SSN: Although ideally, the session should not be shared between site switches, we can't reset it because only
1600
-     * one Session can be active in a single request.  Resetting could resolve in "headers already sent" errors.
1601
-     * - $addons:  In multisite, the state of the addons is something controlled via hooks etc in a normal request.  So
1602
-     *             for now, we won't reset the addons because it could break calls to an add-ons class/methods in the
1603
-     *             switch or on the restore.
1604
-     * - $modules
1605
-     * - $shortcodes
1606
-     * - $widgets
1607
-     *
1608
-     * @param boolean $hard             [deprecated]
1609
-     * @param boolean $reinstantiate    whether to create new instances of EE_Registry's singletons too,
1610
-     *                                  or just reset without re-instantiating (handy to set to FALSE if you're not
1611
-     *                                  sure if you CAN currently reinstantiate the singletons at the moment)
1612
-     * @param   bool  $reset_models     Defaults to true.  When false, then the models are not reset.  This is so
1613
-     *                                  client
1614
-     *                                  code instead can just change the model context to a different blog id if
1615
-     *                                  necessary
1616
-     * @return EE_Registry
1617
-     * @throws InvalidInterfaceException
1618
-     * @throws InvalidDataTypeException
1619
-     * @throws EE_Error
1620
-     * @throws ReflectionException
1621
-     * @throws InvalidArgumentException
1622
-     */
1623
-    public static function reset($hard = false, $reinstantiate = true, $reset_models = true)
1624
-    {
1625
-        $instance = self::instance();
1626
-        $instance->_cache_on = true;
1627
-        // reset some "special" classes
1628
-        EEH_Activation::reset();
1629
-        $hard = apply_filters('FHEE__EE_Registry__reset__hard', $hard);
1630
-        $instance->CFG = EE_Config::reset($hard, $reinstantiate);
1631
-        $instance->CART = null;
1632
-        $instance->MRM = null;
1633
-        $instance->AssetsRegistry = LoaderFactory::getLoader()->getShared(
1634
-            'EventEspresso\core\services\assets\Registry'
1635
-        );
1636
-        // messages reset
1637
-        EED_Messages::reset();
1638
-        // handle of objects cached on LIB
1639
-        foreach (array('LIB', 'modules') as $cache) {
1640
-            foreach ($instance->{$cache} as $class_name => $class) {
1641
-                if (self::_reset_and_unset_object($class, $reset_models)) {
1642
-                    unset($instance->{$cache}->{$class_name});
1643
-                }
1644
-            }
1645
-        }
1646
-        return $instance;
1647
-    }
1648
-
1649
-
1650
-    /**
1651
-     * if passed object implements ResettableInterface, then call it's reset() method
1652
-     * if passed object implements InterminableInterface, then return false,
1653
-     * to indicate that it should NOT be cleared from the Registry cache
1654
-     *
1655
-     * @param      $object
1656
-     * @param bool $reset_models
1657
-     * @return bool returns true if cached object should be unset
1658
-     */
1659
-    private static function _reset_and_unset_object($object, $reset_models)
1660
-    {
1661
-        if (! is_object($object)) {
1662
-            // don't unset anything that's not an object
1663
-            return false;
1664
-        }
1665
-        if ($object instanceof EED_Module) {
1666
-            $object::reset();
1667
-            // don't unset modules
1668
-            return false;
1669
-        }
1670
-        if ($object instanceof ResettableInterface) {
1671
-            if ($object instanceof EEM_Base) {
1672
-                if ($reset_models) {
1673
-                    $object->reset();
1674
-                    return true;
1675
-                }
1676
-                return false;
1677
-            }
1678
-            $object->reset();
1679
-            return true;
1680
-        }
1681
-        if (! $object instanceof InterminableInterface) {
1682
-            return true;
1683
-        }
1684
-        return false;
1685
-    }
1686
-
1687
-
1688
-    /**
1689
-     * Gets all the custom post type models defined
1690
-     *
1691
-     * @return array keys are model "short names" (Eg "Event") and keys are classnames (eg "EEM_Event")
1692
-     */
1693
-    public function cpt_models()
1694
-    {
1695
-        $cpt_models = array();
1696
-        foreach ($this->non_abstract_db_models as $short_name => $classname) {
1697
-            if (is_subclass_of($classname, 'EEM_CPT_Base')) {
1698
-                $cpt_models[ $short_name ] = $classname;
1699
-            }
1700
-        }
1701
-        return $cpt_models;
1702
-    }
1703
-
1704
-
1705
-    /**
1706
-     * @return \EE_Config
1707
-     */
1708
-    public static function CFG()
1709
-    {
1710
-        return self::instance()->CFG;
1711
-    }
1712
-
1713
-
1714
-    /**
1715
-     * @deprecated 4.9.62.p
1716
-     * @param string $class_name
1717
-     * @return ReflectionClass
1718
-     * @throws ReflectionException
1719
-     * @throws InvalidDataTypeException
1720
-     */
1721
-    public function get_ReflectionClass($class_name)
1722
-    {
1723
-        return $this->mirror->getReflectionClass($class_name);
1724
-    }
982
+				! $this->object_identifier->hasArguments($object_identifier)
983
+				// but previously cached class with args was found
984
+				&& $this->object_identifier->fqcnMatchesObjectIdentifier($class_name, $key)
985
+			) {
986
+				return $object;
987
+			}
988
+		}
989
+		return null;
990
+	}
991
+
992
+
993
+	/**
994
+	 * removes a cached version of the requested class
995
+	 *
996
+	 * @param string  $class_name
997
+	 * @param boolean $addon
998
+	 * @param array   $arguments
999
+	 * @return boolean
1000
+	 */
1001
+	public function clear_cached_class(
1002
+		$class_name,
1003
+		$addon = false,
1004
+		$arguments = array()
1005
+	) {
1006
+		$class_abbreviation = $this->get_class_abbreviation($class_name);
1007
+		// check if class has already been loaded, and return it if it has been
1008
+		if (isset($this->{$class_abbreviation})) {
1009
+			$this->{$class_abbreviation} = null;
1010
+			return true;
1011
+		}
1012
+		$class_name = str_replace('\\', '_', $class_name);
1013
+		if (isset($this->{$class_name})) {
1014
+			$this->{$class_name} = null;
1015
+			return true;
1016
+		}
1017
+		if ($addon && $this->addons->has($class_name)) {
1018
+			$this->addons->remove($class_name);
1019
+			return true;
1020
+		}
1021
+		$class_name = $this->object_identifier->getIdentifier($class_name, $arguments);
1022
+		if ($this->LIB->has($class_name)) {
1023
+			$this->LIB->remove($class_name);
1024
+			return true;
1025
+		}
1026
+		return false;
1027
+	}
1028
+
1029
+
1030
+	/**
1031
+	 * _set_cached_class
1032
+	 * attempts to cache the instantiated class locally
1033
+	 * in one of the following places, in the following order:
1034
+	 *        $this->{class_abbreviation}   ie:    $this->CART
1035
+	 *        $this->{$class_name}          ie:    $this->Some_Class
1036
+	 *        $this->addon->{$$class_name}    ie:    $this->addon->Some_Addon_Class
1037
+	 *        $this->LIB->{$class_name}     ie:    $this->LIB->Some_Class
1038
+	 *
1039
+	 * @param object $class_obj
1040
+	 * @param string $class_name
1041
+	 * @param string $class_prefix
1042
+	 * @param bool   $from_db
1043
+	 * @param array  $arguments
1044
+	 * @return void
1045
+	 */
1046
+	protected function _set_cached_class(
1047
+		$class_obj,
1048
+		$class_name,
1049
+		$class_prefix = '',
1050
+		$from_db = false,
1051
+		$arguments = array()
1052
+	) {
1053
+		if ($class_name === 'EE_Registry' || empty($class_obj)) {
1054
+			return;
1055
+		}
1056
+		// return newly instantiated class
1057
+		$class_abbreviation = $this->get_class_abbreviation($class_name, '');
1058
+		if ($class_abbreviation) {
1059
+			$this->{$class_abbreviation} = $class_obj;
1060
+			return;
1061
+		}
1062
+		$class_name = str_replace('\\', '_', $class_name);
1063
+		if (property_exists($this, $class_name)) {
1064
+			$this->{$class_name} = $class_obj;
1065
+			return;
1066
+		}
1067
+		if ($class_prefix === 'addon') {
1068
+			$this->addons->add($class_name, $class_obj);
1069
+			return;
1070
+		}
1071
+		if (! $from_db) {
1072
+			$class_name = $this->object_identifier->getIdentifier($class_name, $arguments);
1073
+			$this->LIB->add($class_name, $class_obj);
1074
+		}
1075
+	}
1076
+
1077
+
1078
+	/**
1079
+	 * attempts to find a full valid filepath for the requested class.
1080
+	 * loops thru each of the base paths in the $file_paths array and appends : "{classname} . {file type} . php"
1081
+	 * then returns that path if the target file has been found and is readable
1082
+	 *
1083
+	 * @param string $class_name
1084
+	 * @param string $type
1085
+	 * @param array  $file_paths
1086
+	 * @return string | bool
1087
+	 */
1088
+	protected function _resolve_path($class_name, $type = '', $file_paths = array())
1089
+	{
1090
+		// make sure $file_paths is an array
1091
+		$file_paths = is_array($file_paths)
1092
+			? $file_paths
1093
+			: array($file_paths);
1094
+		// cycle thru paths
1095
+		foreach ($file_paths as $key => $file_path) {
1096
+			// convert all separators to proper /, if no filepath, then use EE_CLASSES
1097
+			$file_path = $file_path
1098
+				? str_replace(array('/', '\\'), '/', $file_path)
1099
+				: EE_CLASSES;
1100
+			// prep file type
1101
+			$type = ! empty($type)
1102
+				? trim($type, '.') . '.'
1103
+				: '';
1104
+			// build full file path
1105
+			$file_paths[ $key ] = rtrim($file_path, '/') . '/' . $class_name . '.' . $type . 'php';
1106
+			// does the file exist and can be read ?
1107
+			if (is_readable($file_paths[ $key ])) {
1108
+				return $file_paths[ $key ];
1109
+			}
1110
+		}
1111
+		return false;
1112
+	}
1113
+
1114
+
1115
+	/**
1116
+	 * basically just performs a require_once()
1117
+	 * but with some error handling
1118
+	 *
1119
+	 * @param  string $path
1120
+	 * @param  string $class_name
1121
+	 * @param  string $type
1122
+	 * @param  array  $file_paths
1123
+	 * @return bool
1124
+	 * @throws EE_Error
1125
+	 * @throws ReflectionException
1126
+	 */
1127
+	protected function _require_file($path, $class_name, $type = '', $file_paths = array())
1128
+	{
1129
+		$this->resolve_legacy_class_parent($class_name);
1130
+		// don't give up! you gotta...
1131
+		try {
1132
+			// does the file exist and can it be read ?
1133
+			if (! $path) {
1134
+				// just in case the file has already been autoloaded,
1135
+				// but discrepancies in the naming schema are preventing it from
1136
+				// being loaded via one of the EE_Registry::load_*() methods,
1137
+				// then let's try one last hail mary before throwing an exception
1138
+				// and call class_exists() again, but with autoloading turned ON
1139
+				if (class_exists($class_name)) {
1140
+					return true;
1141
+				}
1142
+				// so sorry, can't find the file
1143
+				throw new EE_Error(
1144
+					sprintf(
1145
+						esc_html__(
1146
+							'The %1$s file %2$s could not be located or is not readable due to file permissions. Please ensure that the following filepath(s) are correct: %3$s',
1147
+							'event_espresso'
1148
+						),
1149
+						trim($type, '.'),
1150
+						$class_name,
1151
+						'<br />' . implode(',<br />', $file_paths)
1152
+					)
1153
+				);
1154
+			}
1155
+			// get the file
1156
+			require_once($path);
1157
+			// if the class isn't already declared somewhere
1158
+			if (class_exists($class_name, false) === false) {
1159
+				// so sorry, not a class
1160
+				throw new EE_Error(
1161
+					sprintf(
1162
+						esc_html__(
1163
+							'The %s file %s does not appear to contain the %s Class.',
1164
+							'event_espresso'
1165
+						),
1166
+						$type,
1167
+						$path,
1168
+						$class_name
1169
+					)
1170
+				);
1171
+			}
1172
+		} catch (EE_Error $e) {
1173
+			$e->get_error();
1174
+			return false;
1175
+		}
1176
+		return true;
1177
+	}
1178
+
1179
+
1180
+	/**
1181
+	 * Some of our legacy classes that extended a parent class would simply use a require() statement
1182
+	 * before their class declaration in order to ensure that the parent class was loaded.
1183
+	 * This is not ideal, but it's nearly impossible to determine the parent class of a non-namespaced class,
1184
+	 * without triggering a fatal error because the parent class has yet to be loaded and therefore doesn't exist.
1185
+	 *
1186
+	 * @param string $class_name
1187
+	 */
1188
+	protected function resolve_legacy_class_parent($class_name = '')
1189
+	{
1190
+		try {
1191
+			$legacy_parent_class_map = array(
1192
+				'EE_Payment_Processor' => 'core/business/EE_Processor_Base.class.php',
1193
+			);
1194
+			if (isset($legacy_parent_class_map[ $class_name ])) {
1195
+				require_once EE_PLUGIN_DIR_PATH . $legacy_parent_class_map[ $class_name ];
1196
+			}
1197
+		} catch (Exception $exception) {
1198
+		}
1199
+	}
1200
+
1201
+
1202
+	/**
1203
+	 * _create_object
1204
+	 * Attempts to instantiate the requested class via any of the
1205
+	 * commonly used instantiation methods employed throughout EE.
1206
+	 * The priority for instantiation is as follows:
1207
+	 *        - abstract classes or any class flagged as "load only" (no instantiation occurs)
1208
+	 *        - model objects via their 'new_instance_from_db' method
1209
+	 *        - model objects via their 'new_instance' method
1210
+	 *        - "singleton" classes" via their 'instance' method
1211
+	 *    - standard instantiable classes via their __constructor
1212
+	 * Prior to instantiation, if the classname exists in the dependency_map,
1213
+	 * then the constructor for the requested class will be examined to determine
1214
+	 * if any dependencies exist, and if they can be injected.
1215
+	 * If so, then those classes will be added to the array of arguments passed to the constructor
1216
+	 *
1217
+	 * @param string $class_name
1218
+	 * @param array  $arguments
1219
+	 * @param string $type
1220
+	 * @param bool   $from_db
1221
+	 * @return null|object|bool
1222
+	 * @throws InvalidArgumentException
1223
+	 * @throws InvalidInterfaceException
1224
+	 * @throws EE_Error
1225
+	 * @throws ReflectionException
1226
+	 * @throws InvalidDataTypeException
1227
+	 */
1228
+	protected function _create_object($class_name, $arguments = array(), $type = '', $from_db = false)
1229
+	{
1230
+		// create reflection
1231
+		$reflector = $this->mirror->getReflectionClass($class_name);
1232
+		// make sure arguments are an array
1233
+		$arguments = is_array($arguments)
1234
+			? $arguments
1235
+			: array($arguments);
1236
+		// and if arguments array is numerically and sequentially indexed, then we want it to remain as is,
1237
+		// else wrap it in an additional array so that it doesn't get split into multiple parameters
1238
+		$arguments = $this->_array_is_numerically_and_sequentially_indexed($arguments)
1239
+			? $arguments
1240
+			: array($arguments);
1241
+		// attempt to inject dependencies ?
1242
+		if ($this->_dependency_map->has($class_name)) {
1243
+			$arguments = $this->_resolve_dependencies($reflector, $class_name, $arguments);
1244
+		}
1245
+		// instantiate the class if possible
1246
+		if ($reflector->isAbstract()) {
1247
+			// nothing to instantiate, loading file was enough
1248
+			// does not throw an exception so $instantiation_mode is unused
1249
+			// $instantiation_mode = "1) no constructor abstract class";
1250
+			return true;
1251
+		}
1252
+		if (
1253
+			empty($arguments)
1254
+			&& $this->mirror->getConstructorFromReflection($reflector) === null
1255
+			&& $reflector->isInstantiable()
1256
+		) {
1257
+			// no constructor = static methods only... nothing to instantiate, loading file was enough
1258
+			// $instantiation_mode = "2) no constructor but instantiable";
1259
+			return $reflector->newInstance();
1260
+		}
1261
+		if ($from_db && method_exists($class_name, 'new_instance_from_db')) {
1262
+			// $instantiation_mode = "3) new_instance_from_db()";
1263
+			return call_user_func_array(array($class_name, 'new_instance_from_db'), $arguments);
1264
+		}
1265
+		if (method_exists($class_name, 'new_instance')) {
1266
+			// $instantiation_mode = "4) new_instance()";
1267
+			return call_user_func_array(array($class_name, 'new_instance'), $arguments);
1268
+		}
1269
+		if (method_exists($class_name, 'instance')) {
1270
+			// $instantiation_mode = "5) instance()";
1271
+			return call_user_func_array(array($class_name, 'instance'), $arguments);
1272
+		}
1273
+		if ($reflector->isInstantiable()) {
1274
+			// $instantiation_mode = "6) constructor";
1275
+			return $reflector->newInstanceArgs($arguments);
1276
+		}
1277
+		// heh ? something's not right !
1278
+		throw new EE_Error(
1279
+			sprintf(
1280
+				esc_html__('The %s file %s could not be instantiated.', 'event_espresso'),
1281
+				$type,
1282
+				$class_name
1283
+			)
1284
+		);
1285
+	}
1286
+
1287
+
1288
+	/**
1289
+	 * @see http://stackoverflow.com/questions/173400/how-to-check-if-php-array-is-associative-or-sequential
1290
+	 * @param array $array
1291
+	 * @return bool
1292
+	 */
1293
+	protected function _array_is_numerically_and_sequentially_indexed(array $array)
1294
+	{
1295
+		return ! empty($array)
1296
+			? array_keys($array) === range(0, count($array) - 1)
1297
+			: true;
1298
+	}
1299
+
1300
+
1301
+	/**
1302
+	 * _resolve_dependencies
1303
+	 * examines the constructor for the requested class to determine
1304
+	 * if any dependencies exist, and if they can be injected.
1305
+	 * If so, then those classes will be added to the array of arguments passed to the constructor
1306
+	 * PLZ NOTE: this is achieved by type hinting the constructor params
1307
+	 * For example:
1308
+	 *        if attempting to load a class "Foo" with the following constructor:
1309
+	 *        __construct( Bar $bar_class, Fighter $grohl_class )
1310
+	 *        then $bar_class and $grohl_class will be added to the $arguments array,
1311
+	 *        but only IF they are NOT already present in the incoming arguments array,
1312
+	 *        and the correct classes can be loaded
1313
+	 *
1314
+	 * @param ReflectionClass $reflector
1315
+	 * @param string          $class_name
1316
+	 * @param array           $arguments
1317
+	 * @return array
1318
+	 * @throws InvalidArgumentException
1319
+	 * @throws InvalidDataTypeException
1320
+	 * @throws InvalidInterfaceException
1321
+	 * @throws ReflectionException
1322
+	 */
1323
+	protected function _resolve_dependencies(ReflectionClass $reflector, $class_name, array $arguments = array())
1324
+	{
1325
+		// let's examine the constructor
1326
+		$constructor = $this->mirror->getConstructorFromReflection($reflector);
1327
+		// whu? huh? nothing?
1328
+		if (! $constructor) {
1329
+			return $arguments;
1330
+		}
1331
+		// get constructor parameters
1332
+		$params = $this->mirror->getParametersFromReflection($reflector);
1333
+		// and the keys for the incoming arguments array so that we can compare existing arguments with what is expected
1334
+		$argument_keys = array_keys($arguments);
1335
+		// now loop thru all of the constructors expected parameters
1336
+		foreach ($params as $index => $param) {
1337
+			try {
1338
+				// is this a dependency for a specific class ?
1339
+				$param_class = $this->mirror->getParameterClassName($param, $class_name, $index);
1340
+			} catch (ReflectionException $exception) {
1341
+				// uh-oh... most likely a legacy class that has not been autoloaded
1342
+				// let's try to derive the classname from what we have now
1343
+				// and hope that the property var name is close to the class name
1344
+				$param_class = $param->getName();
1345
+				$param_class = str_replace('_', ' ', $param_class);
1346
+				$param_class = ucwords($param_class);
1347
+				$param_class = str_replace(' ', '_', $param_class);
1348
+			}
1349
+			// BUT WAIT !!! This class may be an alias for something else (or getting replaced at runtime)
1350
+			$param_class = $this->class_cache->isAlias($param_class, $class_name)
1351
+				? $this->class_cache->getFqnForAlias($param_class, $class_name)
1352
+				: $param_class;
1353
+			if (
1354
+				// param is not even a class
1355
+				$param_class === null
1356
+				// and something already exists in the incoming arguments for this param
1357
+				&& array_key_exists($index, $argument_keys)
1358
+				&& array_key_exists($argument_keys[ $index ], $arguments)
1359
+			) {
1360
+				// so let's skip this argument and move on to the next
1361
+				continue;
1362
+			}
1363
+			if (
1364
+				// parameter is type hinted as a class, exists as an incoming argument, AND it's the correct class
1365
+				$param_class !== null
1366
+				&& isset($argument_keys[ $index ], $arguments[ $argument_keys[ $index ] ])
1367
+				&& $arguments[ $argument_keys[ $index ] ] instanceof $param_class
1368
+			) {
1369
+				// skip this argument and move on to the next
1370
+				continue;
1371
+			}
1372
+			if (
1373
+				// parameter is type hinted as a class, and should be injected
1374
+				$param_class !== null
1375
+				&& $this->_dependency_map->has_dependency_for_class($class_name, $param_class)
1376
+			) {
1377
+				$arguments = $this->_resolve_dependency(
1378
+					$class_name,
1379
+					$param_class,
1380
+					$arguments,
1381
+					$index
1382
+				);
1383
+			}
1384
+			if (empty($arguments[ $index ])) {
1385
+				$default_value = $this->mirror->getParameterDefaultValue(
1386
+					$param,
1387
+					$class_name,
1388
+					$index
1389
+				);
1390
+				// if there's no default value, and the incoming argument is an array (albeit empty), then use that
1391
+				$arguments[ $index ] = $default_value === null
1392
+								 && isset($arguments[ $index ])
1393
+								 && is_array($arguments[ $index ])
1394
+					? $arguments[ $index ]
1395
+					: $default_value;
1396
+			}
1397
+		}
1398
+		return $arguments;
1399
+	}
1400
+
1401
+
1402
+	/**
1403
+	 * @param string $class_name
1404
+	 * @param string $param_class
1405
+	 * @param array  $arguments
1406
+	 * @param mixed  $index
1407
+	 * @return array
1408
+	 * @throws InvalidArgumentException
1409
+	 * @throws InvalidInterfaceException
1410
+	 * @throws InvalidDataTypeException
1411
+	 */
1412
+	protected function _resolve_dependency($class_name, $param_class, $arguments, $index)
1413
+	{
1414
+		$dependency = null;
1415
+		// should dependency be loaded from cache ?
1416
+		$cache_on = $this->_dependency_map->loading_strategy_for_class_dependency(
1417
+			$class_name,
1418
+			$param_class
1419
+		);
1420
+		$cache_on = $cache_on !== EE_Dependency_Map::load_new_object;
1421
+		// we might have a dependency...
1422
+		// let's MAYBE try and find it in our cache if that's what's been requested
1423
+		$cached_class = $cache_on
1424
+			? $this->_get_cached_class($param_class)
1425
+			: null;
1426
+		// and grab it if it exists
1427
+		if ($cached_class instanceof $param_class) {
1428
+			$dependency = $cached_class;
1429
+		} elseif ($param_class !== $class_name) {
1430
+			// obtain the loader method from the dependency map
1431
+			$loader = $this->_dependency_map->class_loader($param_class);
1432
+			// is loader a custom closure ?
1433
+			if ($loader instanceof Closure) {
1434
+				$dependency = $loader($arguments);
1435
+			} else {
1436
+				// set the cache on property for the recursive loading call
1437
+				$this->_cache_on = $cache_on;
1438
+				// if not, then let's try and load it via the registry
1439
+				if ($loader && method_exists($this, $loader)) {
1440
+					$dependency = $this->{$loader}($param_class);
1441
+				} else {
1442
+					$dependency = LoaderFactory::getLoader()->load(
1443
+						$param_class,
1444
+						array(),
1445
+						$cache_on
1446
+					);
1447
+				}
1448
+			}
1449
+		}
1450
+		// did we successfully find the correct dependency ?
1451
+		if ($dependency instanceof $param_class) {
1452
+			// then let's inject it into the incoming array of arguments at the correct location
1453
+			$arguments[ $index ] = $dependency;
1454
+		}
1455
+		return $arguments;
1456
+	}
1457
+
1458
+
1459
+	/**
1460
+	 * call any loader that's been registered in the EE_Dependency_Map::$_class_loaders array
1461
+	 *
1462
+	 * @param string $classname PLEASE NOTE: the class name needs to match what's registered
1463
+	 *                          in the EE_Dependency_Map::$_class_loaders array,
1464
+	 *                          including the class prefix, ie: "EE_", "EEM_", "EEH_", etc
1465
+	 * @param array  $arguments
1466
+	 * @return object
1467
+	 */
1468
+	public static function factory($classname, $arguments = array())
1469
+	{
1470
+		$loader = self::instance()->_dependency_map->class_loader($classname);
1471
+		if ($loader instanceof Closure) {
1472
+			return $loader($arguments);
1473
+		}
1474
+		if (method_exists(self::instance(), $loader)) {
1475
+			return self::instance()->{$loader}($classname, $arguments);
1476
+		}
1477
+		return null;
1478
+	}
1479
+
1480
+
1481
+	/**
1482
+	 * Gets the addon by its class name
1483
+	 *
1484
+	 * @param string $class_name
1485
+	 * @return EE_Addon
1486
+	 */
1487
+	public function getAddon($class_name)
1488
+	{
1489
+		$class_name = str_replace('\\', '_', $class_name);
1490
+		if (isset($this->addons->{$class_name})) {
1491
+			return $this->addons->{$class_name};
1492
+		} else {
1493
+			return null;
1494
+		}
1495
+	}
1496
+
1497
+
1498
+	/**
1499
+	 * removes the addon from the internal cache
1500
+	 *
1501
+	 * @param string $class_name
1502
+	 * @return void
1503
+	 */
1504
+	public function removeAddon($class_name)
1505
+	{
1506
+		$class_name = str_replace('\\', '_', $class_name);
1507
+		$this->addons->remove($class_name);
1508
+	}
1509
+
1510
+
1511
+	/**
1512
+	 * Gets the addon by its name/slug (not classname. For that, just
1513
+	 * use the get_addon() method above
1514
+	 *
1515
+	 * @param string $name
1516
+	 * @return EE_Addon
1517
+	 */
1518
+	public function get_addon_by_name($name)
1519
+	{
1520
+		foreach ($this->addons as $addon) {
1521
+			if ($addon->name() === $name) {
1522
+				return $addon;
1523
+			}
1524
+		}
1525
+		return null;
1526
+	}
1527
+
1528
+
1529
+	/**
1530
+	 * Gets an array of all the registered addons, where the keys are their names.
1531
+	 * (ie, what each returns for their name() function)
1532
+	 * They're already available on EE_Registry::instance()->addons as properties,
1533
+	 * where each property's name is the addon's classname,
1534
+	 * So if you just want to get the addon by classname,
1535
+	 * OR use the get_addon() method above.
1536
+	 * PLEASE  NOTE:
1537
+	 * addons with Fully Qualified Class Names
1538
+	 * have had the namespace separators converted to underscores,
1539
+	 * so a classname like Fully\Qualified\ClassName
1540
+	 * would have been converted to Fully_Qualified_ClassName
1541
+	 *
1542
+	 * @return EE_Addon[] where the KEYS are the addon's name()
1543
+	 */
1544
+	public function get_addons_by_name()
1545
+	{
1546
+		$addons = array();
1547
+		foreach ($this->addons as $addon) {
1548
+			$addons[ $addon->name() ] = $addon;
1549
+		}
1550
+		return $addons;
1551
+	}
1552
+
1553
+
1554
+	/**
1555
+	 * Resets the specified model's instance AND makes sure EE_Registry doesn't keep
1556
+	 * a stale copy of it around
1557
+	 *
1558
+	 * @param string $model_name
1559
+	 * @return \EEM_Base
1560
+	 * @throws \EE_Error
1561
+	 */
1562
+	public function reset_model($model_name)
1563
+	{
1564
+		$model_class_name = strpos($model_name, 'EEM_') !== 0
1565
+			? "EEM_{$model_name}"
1566
+			: $model_name;
1567
+		if (! $this->LIB->has($model_class_name)) {
1568
+			return null;
1569
+		}
1570
+		$model = $this->LIB->get($model_class_name);
1571
+		if (! $model instanceof EEM_Base) {
1572
+			return null;
1573
+		}
1574
+		// get that model reset it and make sure we nuke the old reference to it
1575
+		if ($model instanceof $model_class_name && is_callable([$model_class_name, 'reset'])) {
1576
+			$this->LIB->remove($model_class_name);
1577
+			$this->LIB->add($model_class_name, $model->reset());
1578
+		} else {
1579
+			throw new EE_Error(
1580
+				sprintf(
1581
+					esc_html__('Model %s does not have a method "reset"', 'event_espresso'),
1582
+					$model_name
1583
+				)
1584
+			);
1585
+		}
1586
+		return $model;
1587
+	}
1588
+
1589
+
1590
+	/**
1591
+	 * Resets the registry.
1592
+	 * The criteria for what gets reset is based on what can be shared between sites on the same request when
1593
+	 * switch_to_blog is used in a multisite install.  Here is a list of things that are NOT reset.
1594
+	 * - $_dependency_map
1595
+	 * - $_class_abbreviations
1596
+	 * - $NET_CFG (EE_Network_Config): The config is shared network wide so no need to reset.
1597
+	 * - $REQ:  Still on the same request so no need to change.
1598
+	 * - $CAP: There is no site specific state in the EE_Capability class.
1599
+	 * - $SSN: Although ideally, the session should not be shared between site switches, we can't reset it because only
1600
+	 * one Session can be active in a single request.  Resetting could resolve in "headers already sent" errors.
1601
+	 * - $addons:  In multisite, the state of the addons is something controlled via hooks etc in a normal request.  So
1602
+	 *             for now, we won't reset the addons because it could break calls to an add-ons class/methods in the
1603
+	 *             switch or on the restore.
1604
+	 * - $modules
1605
+	 * - $shortcodes
1606
+	 * - $widgets
1607
+	 *
1608
+	 * @param boolean $hard             [deprecated]
1609
+	 * @param boolean $reinstantiate    whether to create new instances of EE_Registry's singletons too,
1610
+	 *                                  or just reset without re-instantiating (handy to set to FALSE if you're not
1611
+	 *                                  sure if you CAN currently reinstantiate the singletons at the moment)
1612
+	 * @param   bool  $reset_models     Defaults to true.  When false, then the models are not reset.  This is so
1613
+	 *                                  client
1614
+	 *                                  code instead can just change the model context to a different blog id if
1615
+	 *                                  necessary
1616
+	 * @return EE_Registry
1617
+	 * @throws InvalidInterfaceException
1618
+	 * @throws InvalidDataTypeException
1619
+	 * @throws EE_Error
1620
+	 * @throws ReflectionException
1621
+	 * @throws InvalidArgumentException
1622
+	 */
1623
+	public static function reset($hard = false, $reinstantiate = true, $reset_models = true)
1624
+	{
1625
+		$instance = self::instance();
1626
+		$instance->_cache_on = true;
1627
+		// reset some "special" classes
1628
+		EEH_Activation::reset();
1629
+		$hard = apply_filters('FHEE__EE_Registry__reset__hard', $hard);
1630
+		$instance->CFG = EE_Config::reset($hard, $reinstantiate);
1631
+		$instance->CART = null;
1632
+		$instance->MRM = null;
1633
+		$instance->AssetsRegistry = LoaderFactory::getLoader()->getShared(
1634
+			'EventEspresso\core\services\assets\Registry'
1635
+		);
1636
+		// messages reset
1637
+		EED_Messages::reset();
1638
+		// handle of objects cached on LIB
1639
+		foreach (array('LIB', 'modules') as $cache) {
1640
+			foreach ($instance->{$cache} as $class_name => $class) {
1641
+				if (self::_reset_and_unset_object($class, $reset_models)) {
1642
+					unset($instance->{$cache}->{$class_name});
1643
+				}
1644
+			}
1645
+		}
1646
+		return $instance;
1647
+	}
1648
+
1649
+
1650
+	/**
1651
+	 * if passed object implements ResettableInterface, then call it's reset() method
1652
+	 * if passed object implements InterminableInterface, then return false,
1653
+	 * to indicate that it should NOT be cleared from the Registry cache
1654
+	 *
1655
+	 * @param      $object
1656
+	 * @param bool $reset_models
1657
+	 * @return bool returns true if cached object should be unset
1658
+	 */
1659
+	private static function _reset_and_unset_object($object, $reset_models)
1660
+	{
1661
+		if (! is_object($object)) {
1662
+			// don't unset anything that's not an object
1663
+			return false;
1664
+		}
1665
+		if ($object instanceof EED_Module) {
1666
+			$object::reset();
1667
+			// don't unset modules
1668
+			return false;
1669
+		}
1670
+		if ($object instanceof ResettableInterface) {
1671
+			if ($object instanceof EEM_Base) {
1672
+				if ($reset_models) {
1673
+					$object->reset();
1674
+					return true;
1675
+				}
1676
+				return false;
1677
+			}
1678
+			$object->reset();
1679
+			return true;
1680
+		}
1681
+		if (! $object instanceof InterminableInterface) {
1682
+			return true;
1683
+		}
1684
+		return false;
1685
+	}
1686
+
1687
+
1688
+	/**
1689
+	 * Gets all the custom post type models defined
1690
+	 *
1691
+	 * @return array keys are model "short names" (Eg "Event") and keys are classnames (eg "EEM_Event")
1692
+	 */
1693
+	public function cpt_models()
1694
+	{
1695
+		$cpt_models = array();
1696
+		foreach ($this->non_abstract_db_models as $short_name => $classname) {
1697
+			if (is_subclass_of($classname, 'EEM_CPT_Base')) {
1698
+				$cpt_models[ $short_name ] = $classname;
1699
+			}
1700
+		}
1701
+		return $cpt_models;
1702
+	}
1703
+
1704
+
1705
+	/**
1706
+	 * @return \EE_Config
1707
+	 */
1708
+	public static function CFG()
1709
+	{
1710
+		return self::instance()->CFG;
1711
+	}
1712
+
1713
+
1714
+	/**
1715
+	 * @deprecated 4.9.62.p
1716
+	 * @param string $class_name
1717
+	 * @return ReflectionClass
1718
+	 * @throws ReflectionException
1719
+	 * @throws InvalidDataTypeException
1720
+	 */
1721
+	public function get_ReflectionClass($class_name)
1722
+	{
1723
+		return $this->mirror->getReflectionClass($class_name);
1724
+	}
1725 1725
 }
Please login to merge, or discard this patch.