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