Completed
Branch FET-10766-extract-activation-d... (99f7dd)
by
unknown
134:15 queued 121:56
created

EE_Registry::__call()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
use EventEspresso\core\services\assets\Registry;
3
4
defined('EVENT_ESPRESSO_VERSION') || exit;
5
6
7
8
/**
9
 * EE_Registry Class
10
 * Centralized Application Data Storage and Management
11
 *
12
 * @package                   Event Espresso
13
 * @subpackage                core
14
 * @author                    Brent Christensen
15
 */
16
class EE_Registry
17
{
18
19
    /**
20
     *    EE_Registry Object
21
     *
22
     * @var EE_Registry $_instance
23
     * @access    private
24
     */
25
    private static $_instance = null;
26
27
    /**
28
     * @var EE_Dependency_Map $_dependency_map
29
     * @access    protected
30
     */
31
    protected $_dependency_map = null;
32
33
    /**
34
     * @var array $_class_abbreviations
35
     * @access    protected
36
     */
37
    protected $_class_abbreviations = array();
38
39
    /**
40
     * @access public
41
     * @var \EventEspresso\core\services\commands\CommandBusInterface $BUS
42
     */
43
    public $BUS;
44
45
    /**
46
     *    EE_Cart Object
47
     *
48
     * @access    public
49
     * @var    EE_Cart $CART
50
     */
51
    public $CART = null;
52
53
    /**
54
     *    EE_Config Object
55
     *
56
     * @access    public
57
     * @var    EE_Config $CFG
58
     */
59
    public $CFG = null;
60
61
    /**
62
     * EE_Network_Config Object
63
     *
64
     * @access public
65
     * @var EE_Network_Config $NET_CFG
66
     */
67
    public $NET_CFG = null;
68
69
    /**
70
     *    StdClass object for storing library classes in
71
     *
72
     * @public LIB
73
     * @var StdClass $LIB
74
     */
75
    public $LIB = null;
76
77
    /**
78
     *    EE_Request_Handler Object
79
     *
80
     * @access    public
81
     * @var    EE_Request_Handler $REQ
82
     */
83
    public $REQ = null;
84
85
    /**
86
     *    EE_Session Object
87
     *
88
     * @access    public
89
     * @var    EE_Session $SSN
90
     */
91
    public $SSN = null;
92
93
    /**
94
     * holds the ee capabilities object.
95
     *
96
     * @since 4.5.0
97
     * @var EE_Capabilities
98
     */
99
    public $CAP = null;
100
101
    /**
102
     * holds the EE_Message_Resource_Manager object.
103
     *
104
     * @since 4.9.0
105
     * @var EE_Message_Resource_Manager
106
     */
107
    public $MRM = null;
108
109
110
    /**
111
     * Holds the Assets Registry instance
112
     * @var Registry
113
     */
114
    public $AssetsRegistry = null;
115
116
    /**
117
     * StdClass object for holding addons which have registered themselves to work with EE core
118
     *
119
     * @var StdClass
120
     */
121
    public $addons = null;
122
123
    /**
124
     *    $models
125
     * @access    public
126
     * @var    EEM_Base[] $models keys are 'short names' (eg Event), values are class names (eg 'EEM_Event')
127
     */
128
    public $models = array();
129
130
    /**
131
     *    $modules
132
     * @access    public
133
     * @var    EED_Module[] $modules
134
     */
135
    public $modules = null;
136
137
    /**
138
     *    $shortcodes
139
     * @access    public
140
     * @var    EES_Shortcode[] $shortcodes
141
     */
142
    public $shortcodes = null;
143
144
    /**
145
     *    $widgets
146
     * @access    public
147
     * @var    WP_Widget[] $widgets
148
     */
149
    public $widgets = null;
150
151
    /**
152
     * $non_abstract_db_models
153
     * @access public
154
     * @var array this is an array of all implemented model names (i.e. not the parent abstract models, or models
155
     * which don't actually fetch items from the DB in the normal way (ie, are not children of EEM_Base)).
156
     * Keys are model "short names" (eg "Event") as used in model relations, and values are
157
     * classnames (eg "EEM_Event")
158
     */
159
    public $non_abstract_db_models = array();
160
161
162
    /**
163
     *    $i18n_js_strings - internationalization for JS strings
164
     *    usage:   EE_Registry::i18n_js_strings['string_key'] = __( 'string to translate.', 'event_espresso' );
165
     *    in js file:  var translatedString = eei18n.string_key;
166
     *
167
     * @access    public
168
     * @var    array
169
     */
170
    public static $i18n_js_strings = array();
171
172
173
    /**
174
     *    $main_file - path to espresso.php
175
     *
176
     * @access    public
177
     * @var    array
178
     */
179
    public $main_file;
180
181
    /**
182
     * array of ReflectionClass objects where the key is the class name
183
     *
184
     * @access    public
185
     * @var ReflectionClass[]
186
     */
187
    public $_reflectors;
188
189
    /**
190
     * boolean flag to indicate whether or not to load/save dependencies from/to the cache
191
     *
192
     * @access    protected
193
     * @var boolean $_cache_on
194
     */
195
    protected $_cache_on = true;
196
197
198
199
    /**
200
     * @singleton method used to instantiate class object
201
     * @access    public
202
     * @param  \EE_Dependency_Map $dependency_map
203
     * @return \EE_Registry instance
204
     */
205
    public static function instance(\EE_Dependency_Map $dependency_map = null)
206
    {
207
        // check if class object is instantiated
208
        if ( ! self::$_instance instanceof EE_Registry) {
209
            self::$_instance = new EE_Registry($dependency_map);
0 ignored issues
show
Bug introduced by
It seems like $dependency_map defined by parameter $dependency_map on line 205 can be null; however, EE_Registry::__construct() does not accept null, maybe add an additional type check?

It seems like you allow that null is being passed for a parameter, however the function which is called does not seem to accept null.

We recommend to add an additional type check (or disallow null for the parameter):

function notNullable(stdClass $x) { }

// Unsafe
function withoutCheck(stdClass $x = null) {
    notNullable($x);
}

// Safe - Alternative 1: Adding Additional Type-Check
function withCheck(stdClass $x = null) {
    if ($x instanceof stdClass) {
        notNullable($x);
    }
}

// Safe - Alternative 2: Changing Parameter
function withNonNullableParam(stdClass $x) {
    notNullable($x);
}
Loading history...
210
        }
211
        return self::$_instance;
212
    }
213
214
215
216
    /**
217
     *protected constructor to prevent direct creation
218
     *
219
     * @Constructor
220
     * @access protected
221
     * @param  \EE_Dependency_Map $dependency_map
222
     */
223
    protected function __construct(\EE_Dependency_Map $dependency_map)
224
    {
225
        $this->_dependency_map = $dependency_map;
226
        $this->LIB = new stdClass();
227
        $this->addons = new stdClass();
228
        $this->modules = new stdClass();
229
        $this->shortcodes = new stdClass();
230
        $this->widgets = new stdClass();
231
        add_action('EE_Load_Espresso_Core__handle_request__initialize_core_loading', array($this, 'initialize'));
232
    }
233
234
235
236
    /**
237
     * initialize
238
     */
239
    public function initialize()
240
    {
241
        $this->_class_abbreviations = apply_filters(
242
            'FHEE__EE_Registry____construct___class_abbreviations',
243
            array(
244
                'EE_Config'                                       => 'CFG',
245
                'EE_Session'                                      => 'SSN',
246
                'EE_Capabilities'                                 => 'CAP',
247
                'EE_Cart'                                         => 'CART',
248
                'EE_Network_Config'                               => 'NET_CFG',
249
                'EE_Request_Handler'                              => 'REQ',
250
                'EE_Message_Resource_Manager'                     => 'MRM',
251
                'EventEspresso\core\services\commands\CommandBus' => 'BUS',
252
                'EventEspresso\core\services\assets\Registry'     => 'AssetsRegistry',
253
            )
254
        );
255
        $this->load_core('Base', array(), true);
256
        // add our request and response objects to the cache
257
        $request_loader = $this->_dependency_map->class_loader('EE_Request');
258
        $this->_set_cached_class(
259
            $request_loader(),
260
            'EE_Request'
261
        );
262
        $response_loader = $this->_dependency_map->class_loader('EE_Response');
263
        $this->_set_cached_class(
264
            $response_loader(),
265
            'EE_Response'
266
        );
267
        add_action('AHEE__EE_System__set_hooks_for_core', array($this, 'init'));
268
    }
269
270
271
272
    /**
273
     *    init
274
     *
275
     * @access    public
276
     * @return    void
277
     */
278
    public function init()
279
    {
280
        // Get current page protocol
281
        $protocol = isset($_SERVER['HTTPS']) ? 'https://' : 'http://';
282
        // Output admin-ajax.php URL with same protocol as current page
283
        self::$i18n_js_strings['ajax_url'] = admin_url('admin-ajax.php', $protocol);
284
        self::$i18n_js_strings['wp_debug'] = defined('WP_DEBUG') ? WP_DEBUG : false;
285
    }
286
287
288
289
    /**
290
     * localize_i18n_js_strings
291
     *
292
     * @return string
293
     */
294
    public static function localize_i18n_js_strings()
295
    {
296
        $i18n_js_strings = (array)EE_Registry::$i18n_js_strings;
297
        foreach ($i18n_js_strings as $key => $value) {
298
            if (is_scalar($value)) {
299
                $i18n_js_strings[$key] = html_entity_decode((string)$value, ENT_QUOTES, 'UTF-8');
300
            }
301
        }
302
        return "/* <![CDATA[ */ var eei18n = " . wp_json_encode($i18n_js_strings) . '; /* ]]> */';
303
    }
304
305
306
307
    /**
308
     * @param mixed string | EED_Module $module
309
     */
310
    public function add_module($module)
311
    {
312
        if ($module instanceof EED_Module) {
313
            $module_class = get_class($module);
314
            $this->modules->{$module_class} = $module;
315
        } else {
316
            if ( ! class_exists('EE_Module_Request_Router')) {
317
                $this->load_core('Module_Request_Router');
318
            }
319
            $this->modules->{$module} = EE_Module_Request_Router::module_factory($module);
320
        }
321
    }
322
323
324
325
    /**
326
     * @param string $module_name
327
     * @return mixed EED_Module | NULL
328
     */
329
    public function get_module($module_name = '')
330
    {
331
        return isset($this->modules->{$module_name}) ? $this->modules->{$module_name} : null;
332
    }
333
334
335
336
    /**
337
     *    loads core classes - must be singletons
338
     *
339
     * @access    public
340
     * @param string $class_name - simple class name ie: session
341
     * @param mixed  $arguments
342
     * @param bool   $load_only
343
     * @return mixed
344
     */
345
    public function load_core($class_name, $arguments = array(), $load_only = false)
346
    {
347
        $core_paths = apply_filters(
348
            'FHEE__EE_Registry__load_core__core_paths',
349
            array(
350
                EE_CORE,
351
                EE_ADMIN,
352
                EE_CPTS,
353
                EE_CORE . 'data_migration_scripts' . DS,
354
                EE_CORE . 'request_stack' . DS,
355
                EE_CORE . 'middleware' . DS,
356
            )
357
        );
358
        // retrieve instantiated class
359
        return $this->_load($core_paths, 'EE_', $class_name, 'core', $arguments, false, true, $load_only);
360
    }
361
362
363
364
    /**
365
     *    loads service classes
366
     *
367
     * @access    public
368
     * @param string $class_name - simple class name ie: session
369
     * @param mixed  $arguments
370
     * @param bool   $load_only
371
     * @return mixed
372
     */
373
    public function load_service($class_name, $arguments = array(), $load_only = false)
374
    {
375
        $service_paths = apply_filters(
376
            'FHEE__EE_Registry__load_service__service_paths',
377
            array(
378
                EE_CORE . 'services' . DS,
379
            )
380
        );
381
        // retrieve instantiated class
382
        return $this->_load($service_paths, 'EE_', $class_name, 'class', $arguments, false, true, $load_only);
383
    }
384
385
386
387
    /**
388
     *    loads data_migration_scripts
389
     *
390
     * @access    public
391
     * @param string $class_name - class name for the DMS ie: EE_DMS_Core_4_2_0
392
     * @param mixed  $arguments
393
     * @return EE_Data_Migration_Script_Base|mixed
394
     */
395
    public function load_dms($class_name, $arguments = array())
396
    {
397
        // retrieve instantiated class
398
        return $this->_load(EE_Data_Migration_Manager::instance()->get_data_migration_script_folders(), 'EE_DMS_', $class_name, 'dms', $arguments, false, false, false);
399
    }
400
401
402
403
    /**
404
     *    loads object creating classes - must be singletons
405
     *
406
     * @param string $class_name - simple class name ie: attendee
407
     * @param mixed  $arguments  - an array of arguments to pass to the class
408
     * @param bool   $from_db    - some classes are instantiated from the db and thus call a different method to instantiate
409
     * @param bool   $cache      if you don't want the class to be stored in the internal cache (non-persistent) then set this to FALSE (ie. when instantiating model objects from client in a loop)
410
     * @param bool   $load_only  whether or not to just load the file and NOT instantiate, or load AND instantiate (default)
411
     * @return EE_Base_Class | bool
412
     */
413
    public function load_class($class_name, $arguments = array(), $from_db = false, $cache = true, $load_only = false)
414
    {
415
        $paths = apply_filters('FHEE__EE_Registry__load_class__paths', array(
416
            EE_CORE,
417
            EE_CLASSES,
418
            EE_BUSINESS,
419
        ));
420
        // retrieve instantiated class
421
        return $this->_load($paths, 'EE_', $class_name, 'class', $arguments, $from_db, $cache, $load_only);
422
    }
423
424
425
426
    /**
427
     *    loads helper classes - must be singletons
428
     *
429
     * @param string $class_name - simple class name ie: price
430
     * @param mixed  $arguments
431
     * @param bool   $load_only
432
     * @return EEH_Base | bool
433
     */
434
    public function load_helper($class_name, $arguments = array(), $load_only = true)
435
    {
436
        // todo: add doing_it_wrong() in a few versions after all addons have had calls to this method removed
437
        $helper_paths = apply_filters('FHEE__EE_Registry__load_helper__helper_paths', array(EE_HELPERS));
438
        // retrieve instantiated class
439
        return $this->_load($helper_paths, 'EEH_', $class_name, 'helper', $arguments, false, true, $load_only);
440
    }
441
442
443
444
    /**
445
     *    loads core classes - must be singletons
446
     *
447
     * @access    public
448
     * @param string $class_name - simple class name ie: session
449
     * @param mixed  $arguments
450
     * @param bool   $load_only
451
     * @param bool   $cache      whether to cache the object or not.
452
     * @return mixed
453
     */
454
    public function load_lib($class_name, $arguments = array(), $load_only = false, $cache = true)
455
    {
456
        $paths = array(
457
            EE_LIBRARIES,
458
            EE_LIBRARIES . 'messages' . DS,
459
            EE_LIBRARIES . 'shortcodes' . DS,
460
            EE_LIBRARIES . 'qtips' . DS,
461
            EE_LIBRARIES . 'payment_methods' . DS,
462
        );
463
        // retrieve instantiated class
464
        return $this->_load($paths, 'EE_', $class_name, 'lib', $arguments, false, $cache, $load_only);
465
    }
466
467
468
469
    /**
470
     *    loads model classes - must be singletons
471
     *
472
     * @param string $class_name - simple class name ie: price
473
     * @param mixed  $arguments
474
     * @param bool   $load_only
475
     * @return EEM_Base | bool
476
     */
477
    public function load_model($class_name, $arguments = array(), $load_only = false)
478
    {
479
        $paths = apply_filters('FHEE__EE_Registry__load_model__paths', array(
480
            EE_MODELS,
481
            EE_CORE,
482
        ));
483
        // retrieve instantiated class
484
        return $this->_load($paths, 'EEM_', $class_name, 'model', $arguments, false, true, $load_only);
485
    }
486
487
488
489
    /**
490
     *    loads model classes - must be singletons
491
     *
492
     * @param string $class_name - simple class name ie: price
493
     * @param mixed  $arguments
494
     * @param bool   $load_only
495
     * @return mixed | bool
496
     */
497
    public function load_model_class($class_name, $arguments = array(), $load_only = true)
498
    {
499
        $paths = array(
500
            EE_MODELS . 'fields' . DS,
501
            EE_MODELS . 'helpers' . DS,
502
            EE_MODELS . 'relations' . DS,
503
            EE_MODELS . 'strategies' . DS,
504
        );
505
        // retrieve instantiated class
506
        return $this->_load($paths, 'EE_', $class_name, '', $arguments, false, true, $load_only);
507
    }
508
509
510
511
    /**
512
     * Determines if $model_name is the name of an actual EE model.
513
     *
514
     * @param string $model_name like Event, Attendee, Question_Group_Question, etc.
515
     * @return boolean
516
     */
517
    public function is_model_name($model_name)
518
    {
519
        return isset($this->models[$model_name]) ? true : false;
520
    }
521
522
523
524
    /**
525
     *    generic class loader
526
     *
527
     * @param string $path_to_file - directory path to file location, not including filename
528
     * @param string $file_name    - file name  ie:  my_file.php, including extension
529
     * @param string $type         - file type - core? class? helper? model?
530
     * @param mixed  $arguments
531
     * @param bool   $load_only
532
     * @return mixed
533
     */
534
    public function load_file($path_to_file, $file_name, $type = '', $arguments = array(), $load_only = true)
535
    {
536
        // retrieve instantiated class
537
        return $this->_load($path_to_file, '', $file_name, $type, $arguments, false, true, $load_only);
538
    }
539
540
541
542
    /**
543
     *    load_addon
544
     *
545
     * @param string $path_to_file - directory path to file location, not including filename
546
     * @param string $class_name   - full class name  ie:  My_Class
547
     * @param string $type         - file type - core? class? helper? model?
548
     * @param mixed  $arguments
549
     * @param bool   $load_only
550
     * @return EE_Addon
551
     */
552
    public function load_addon($path_to_file, $class_name, $type = 'class', $arguments = array(), $load_only = false)
553
    {
554
        // retrieve instantiated class
555
        return $this->_load($path_to_file, 'addon', $class_name, $type, $arguments, false, true, $load_only);
556
    }
557
558
559
560
    /**
561
     * instantiates, caches, and automatically resolves dependencies
562
     * for classes that use a Fully Qualified Class Name.
563
     * if the class is not capable of being loaded using PSR-4 autoloading,
564
     * then you need to use one of the existing load_*() methods
565
     * which can resolve the classname and filepath from the passed arguments
566
     *
567
     * @param bool|string $class_name   Fully Qualified Class Name
568
     * @param array       $arguments    an argument, or array of arguments to pass to the class upon instantiation
569
     * @param bool        $cache        whether to cache the instantiated object for reuse
570
     * @param bool        $from_db      some classes are instantiated from the db
571
     *                                  and thus call a different method to instantiate
572
     * @param bool        $load_only    if true, will only load the file, but will NOT instantiate an object
573
     * @param bool|string $addon        if true, will cache the object in the EE_Registry->$addons array
574
     * @return mixed null = failure to load or instantiate class object.
575
     *                                  object = class loaded and instantiated successfully.
576
     *                                  bool = fail or success when $load_only is true
577
     * @throws EE_Error
578
     */
579
    public function create(
580
        $class_name = false,
581
        $arguments = array(),
582
        $cache = false,
583
        $from_db = false,
584
        $load_only = false,
585
        $addon = false
586
    ) {
587
        $class_name = ltrim($class_name, '\\');
588
        $class_name = $this->_dependency_map->get_alias($class_name);
589
        $class_exists = $this->loadOrVerifyClassExists($class_name, $arguments);
590
        // if a non-FQCN was passed, then verifyClassExists() might return an object
591
        // or it could return null if the class just could not be found anywhere
592
        if ($class_exists instanceof $class_name || $class_exists === null){
593
            // either way, return the results
594
            return $class_exists;
595
        }
596
        $class_name = $class_exists;
597
        // if we're only loading the class and it already exists, then let's just return true immediately
598
        if ($load_only) {
599
            return true;
600
        }
601
        $addon = $addon ? 'addon' : '';
602
        // $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
603
        // $cache is controlled by individual calls to separate Registry loader methods like load_class()
604
        // $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
605 View Code Duplication
        if ($this->_cache_on && $cache && ! $load_only) {
606
            // return object if it's already cached
607
            $cached_class = $this->_get_cached_class($class_name, $addon);
608
            if ($cached_class !== null) {
609
                return $cached_class;
610
            }
611
        }
612
        // instantiate the requested object
613
        $class_obj = $this->_create_object($class_name, $arguments, $addon, $from_db);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $class_obj is correct as $this->_create_object($c...ents, $addon, $from_db) (which targets EE_Registry::_create_object()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
614
        // if caching is turned on OR this class is cached in a class property
615
        if (($this->_cache_on && $cache) || isset($this->_class_abbreviations[ $class_name ])) {
616
            // save it for later... kinda like gum  { : $
617
            $this->_set_cached_class($class_obj, $class_name, $addon, $from_db);
618
        }
619
        $this->_cache_on = true;
620
        return $class_obj;
621
    }
622
623
624
625
    /**
626
     * Recursively checks that a class exists and potentially attempts to load classes with non-FQCNs
627
     *
628
     * @param string $class_name
629
     * @param array  $arguments
630
     * @param int    $attempt
631
     * @return mixed
632
     */
633
    private function loadOrVerifyClassExists($class_name, array $arguments, $attempt = 1) {
634
        if (is_object($class_name) || class_exists($class_name)) {
635
            return $class_name;
636
        }
637
        switch ($attempt) {
638
            case 1:
639
                // if it's a FQCN then maybe the class is registered with a preceding \
640
                $class_name = strpos($class_name, '\\') !== false
641
                    ? '\\' . ltrim($class_name, '\\')
642
                    : $class_name;
643
                break;
644
            case 2:
645
                //
646
                $loader = $this->_dependency_map->class_loader($class_name);
647
                if ($loader && method_exists($this, $loader)) {
648
                    return $this->{$loader}($class_name, $arguments);
649
                }
650
                break;
651
            case 3:
652
            default;
653
                return null;
654
        }
655
        $attempt++;
656
        return $this->loadOrVerifyClassExists($class_name, $arguments, $attempt);
657
    }
658
659
660
661
    /**
662
     * instantiates, caches, and injects dependencies for classes
663
     *
664
     * @param array       $file_paths   an array of paths to folders to look in
665
     * @param string      $class_prefix EE  or EEM or... ???
666
     * @param bool|string $class_name   $class name
667
     * @param string      $type         file type - core? class? helper? model?
668
     * @param mixed       $arguments    an argument or array of arguments to pass to the class upon instantiation
669
     * @param bool        $from_db      some classes are instantiated from the db
670
     *                                  and thus call a different method to instantiate
671
     * @param bool        $cache        whether to cache the instantiated object for reuse
672
     * @param bool        $load_only    if true, will only load the file, but will NOT instantiate an object
673
     * @return bool|null|object null = failure to load or instantiate class object.
674
     *                                  object = class loaded and instantiated successfully.
675
     *                                  bool = fail or success when $load_only is true
676
     * @throws EE_Error
677
     */
678
    protected function _load(
679
        $file_paths = array(),
680
        $class_prefix = 'EE_',
681
        $class_name = false,
682
        $type = 'class',
683
        $arguments = array(),
684
        $from_db = false,
685
        $cache = true,
686
        $load_only = false
687
    ) {
688
        $class_name = ltrim($class_name, '\\');
689
        // strip php file extension
690
        $class_name = str_replace('.php', '', trim($class_name));
691
        // does the class have a prefix ?
692
        if ( ! empty($class_prefix) && $class_prefix != 'addon') {
693
            // make sure $class_prefix is uppercase
694
            $class_prefix = strtoupper(trim($class_prefix));
695
            // add class prefix ONCE!!!
696
            $class_name = $class_prefix . str_replace($class_prefix, '', $class_name);
697
        }
698
        $class_name = $this->_dependency_map->get_alias($class_name);
699
        $class_exists = class_exists($class_name);
700
        // if we're only loading the class and it already exists, then let's just return true immediately
701
        if ($load_only && $class_exists) {
702
            return true;
703
        }
704
        // $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
705
        // $cache is controlled by individual calls to separate Registry loader methods like load_class()
706
        // $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
707 View Code Duplication
        if ($this->_cache_on && $cache && ! $load_only) {
708
            // return object if it's already cached
709
            $cached_class = $this->_get_cached_class($class_name, $class_prefix);
710
            if ($cached_class !== null) {
711
                return $cached_class;
712
            }
713
        }
714
        // if the class doesn't already exist.. then we need to try and find the file and load it
715
        if ( ! $class_exists) {
716
            // get full path to file
717
            $path = $this->_resolve_path($class_name, $type, $file_paths);
718
            // load the file
719
            $loaded = $this->_require_file($path, $class_name, $type, $file_paths);
720
            // if loading failed, or we are only loading a file but NOT instantiating an object
721
            if ( ! $loaded || $load_only) {
722
                // return boolean if only loading, or null if an object was expected
723
                return $load_only ? $loaded : null;
724
            }
725
        }
726
        // instantiate the requested object
727
        $class_obj = $this->_create_object($class_name, $arguments, $type, $from_db);
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $class_obj is correct as $this->_create_object($c...ments, $type, $from_db) (which targets EE_Registry::_create_object()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
728
        if ($this->_cache_on && $cache) {
729
            // save it for later... kinda like gum  { : $
730
            $this->_set_cached_class($class_obj, $class_name, $class_prefix, $from_db);
731
        }
732
        $this->_cache_on = true;
733
        return $class_obj;
734
    }
735
736
737
738
739
    /**
740
     * _get_cached_class
741
     * attempts to find a cached version of the requested class
742
     * by looking in the following places:
743
     *        $this->{$class_abbreviation}            ie:    $this->CART
744
     *        $this->{$class_name}                        ie:    $this->Some_Class
745
     *        $this->LIB->{$class_name}                ie:    $this->LIB->Some_Class
746
     *        $this->addon->{$class_name}    ie:    $this->addon->Some_Addon_Class
747
     *
748
     * @access protected
749
     * @param string $class_name
750
     * @param string $class_prefix
751
     * @return mixed
752
     */
753
    protected function _get_cached_class($class_name, $class_prefix = '')
754
    {
755
        // have to specify something, but not anything that will conflict
756
        $class_abbreviation = isset($this->_class_abbreviations[ $class_name ])
757
            ? $this->_class_abbreviations[ $class_name ]
758
            : 'FANCY_BATMAN_PANTS';
759
        $class_name = str_replace('\\', '_', $class_name);
760
        // check if class has already been loaded, and return it if it has been
761 View Code Duplication
        if (isset($this->{$class_abbreviation}) && ! is_null($this->{$class_abbreviation})) {
762
            return $this->{$class_abbreviation};
763
        }
764
        if (isset ($this->{$class_name})) {
765
            return $this->{$class_name};
766
        }
767
        if (isset ($this->LIB->{$class_name})) {
768
            return $this->LIB->{$class_name};
769
        }
770
        if ($class_prefix === 'addon' && isset ($this->addons->{$class_name})) {
771
            return $this->addons->{$class_name};
772
        }
773
        return null;
774
    }
775
776
777
778
    /**
779
     * removes a cached version of the requested class
780
     *
781
     * @param string $class_name
782
     * @param boolean $addon
783
     * @return boolean
784
     */
785
    public function clear_cached_class($class_name, $addon = false)
786
    {
787
        // have to specify something, but not anything that will conflict
788
        $class_abbreviation = isset($this->_class_abbreviations[ $class_name ])
789
            ? $this->_class_abbreviations[ $class_name ]
790
            : 'FANCY_BATMAN_PANTS';
791
        $class_name = str_replace('\\', '_', $class_name);
792
        // check if class has already been loaded, and return it if it has been
793 View Code Duplication
        if (isset($this->{$class_abbreviation}) && ! is_null($this->{$class_abbreviation})) {
794
            $this->{$class_abbreviation} = null;
795
            return true;
796
        }
797
        if (isset($this->{$class_name})) {
798
            $this->{$class_name} = null;
799
            return true;
800
        }
801
        if (isset($this->LIB->{$class_name})) {
802
            unset($this->LIB->{$class_name});
803
            return true;
804
        }
805
        if ($addon && isset($this->addons->{$class_name})) {
806
            unset($this->addons->{$class_name});
807
            return true;
808
        }
809
        return false;
810
    }
811
812
813
    /**
814
     * _resolve_path
815
     * attempts to find a full valid filepath for the requested class.
816
     * loops thru each of the base paths in the $file_paths array and appends : "{classname} . {file type} . php"
817
     * then returns that path if the target file has been found and is readable
818
     *
819
     * @access protected
820
     * @param string $class_name
821
     * @param string $type
822
     * @param array  $file_paths
823
     * @return string | bool
824
     */
825
    protected function _resolve_path($class_name, $type = '', $file_paths = array())
826
    {
827
        // make sure $file_paths is an array
828
        $file_paths = is_array($file_paths) ? $file_paths : array($file_paths);
829
        // cycle thru paths
830
        foreach ($file_paths as $key => $file_path) {
831
            // convert all separators to proper DS, if no filepath, then use EE_CLASSES
832
            $file_path = $file_path ? str_replace(array('/', '\\'), DS, $file_path) : EE_CLASSES;
833
            // prep file type
834
            $type = ! empty($type) ? trim($type, '.') . '.' : '';
835
            // build full file path
836
            $file_paths[$key] = rtrim($file_path, DS) . DS . $class_name . '.' . $type . 'php';
837
            //does the file exist and can be read ?
838
            if (is_readable($file_paths[$key])) {
839
                return $file_paths[$key];
840
            }
841
        }
842
        return false;
843
    }
844
845
846
847
    /**
848
     * _require_file
849
     * basically just performs a require_once()
850
     * but with some error handling
851
     *
852
     * @access protected
853
     * @param  string $path
854
     * @param  string $class_name
855
     * @param  string $type
856
     * @param  array  $file_paths
857
     * @return boolean
858
     * @throws \EE_Error
859
     */
860
    protected function _require_file($path, $class_name, $type = '', $file_paths = array())
861
    {
862
        // don't give up! you gotta...
863
        try {
864
            //does the file exist and can it be read ?
865 View Code Duplication
            if ( ! $path) {
866
                // so sorry, can't find the file
867
                throw new EE_Error (
868
                    sprintf(
869
                        __('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', 'event_espresso'),
870
                        trim($type, '.'),
871
                        $class_name,
872
                        '<br />' . implode(',<br />', $file_paths)
873
                    )
874
                );
875
            }
876
            // get the file
877
            require_once($path);
878
            // if the class isn't already declared somewhere
879 View Code Duplication
            if (class_exists($class_name, false) === false) {
880
                // so sorry, not a class
881
                throw new EE_Error(
882
                    sprintf(
883
                        __('The %s file %s does not appear to contain the %s Class.', 'event_espresso'),
884
                        $type,
885
                        $path,
886
                        $class_name
887
                    )
888
                );
889
            }
890
        } catch (EE_Error $e) {
891
            $e->get_error();
892
            return false;
893
        }
894
        return true;
895
    }
896
897
898
899
    /**
900
     * _create_object
901
     * Attempts to instantiate the requested class via any of the
902
     * commonly used instantiation methods employed throughout EE.
903
     * The priority for instantiation is as follows:
904
     *        - abstract classes or any class flagged as "load only" (no instantiation occurs)
905
     *        - model objects via their 'new_instance_from_db' method
906
     *        - model objects via their 'new_instance' method
907
     *        - "singleton" classes" via their 'instance' method
908
     *    - standard instantiable classes via their __constructor
909
     * Prior to instantiation, if the classname exists in the dependency_map,
910
     * then the constructor for the requested class will be examined to determine
911
     * if any dependencies exist, and if they can be injected.
912
     * If so, then those classes will be added to the array of arguments passed to the constructor
913
     *
914
     * @access protected
915
     * @param string $class_name
916
     * @param array  $arguments
917
     * @param string $type
918
     * @param bool   $from_db
919
     * @return null | object
920
     * @throws \EE_Error
921
     */
922
    protected function _create_object($class_name, $arguments = array(), $type = '', $from_db = false)
923
    {
924
        $class_obj = null;
925
        $instantiation_mode = '0) none';
926
        // don't give up! you gotta...
927
        try {
928
            // create reflection
929
            $reflector = $this->get_ReflectionClass($class_name);
930
            // make sure arguments are an array
931
            $arguments = is_array($arguments) ? $arguments : array($arguments);
932
            // and if arguments array is numerically and sequentially indexed, then we want it to remain as is,
933
            // else wrap it in an additional array so that it doesn't get split into multiple parameters
934
            $arguments = $this->_array_is_numerically_and_sequentially_indexed($arguments)
935
                ? $arguments
936
                : array($arguments);
937
            // attempt to inject dependencies ?
938
            if ($this->_dependency_map->has($class_name)) {
939
                $arguments = $this->_resolve_dependencies($reflector, $class_name, $arguments);
940
            }
941
            // instantiate the class if possible
942
            if ($reflector->isAbstract()) {
943
                // nothing to instantiate, loading file was enough
944
                // does not throw an exception so $instantiation_mode is unused
945
                // $instantiation_mode = "1) no constructor abstract class";
946
                $class_obj = true;
947
            } else if ($reflector->getConstructor() === null && $reflector->isInstantiable() && empty($arguments)) {
948
                // no constructor = static methods only... nothing to instantiate, loading file was enough
949
                $instantiation_mode = "2) no constructor but instantiable";
950
                $class_obj = $reflector->newInstance();
951
            } else if ($from_db && method_exists($class_name, 'new_instance_from_db')) {
952
                $instantiation_mode = "3) new_instance_from_db()";
953
                $class_obj = call_user_func_array(array($class_name, 'new_instance_from_db'), $arguments);
954
            } else if (method_exists($class_name, 'new_instance')) {
955
                $instantiation_mode = "4) new_instance()";
956
                $class_obj = call_user_func_array(array($class_name, 'new_instance'), $arguments);
957
            } else if (method_exists($class_name, 'instance')) {
958
                $instantiation_mode = "5) instance()";
959
                $class_obj = call_user_func_array(array($class_name, 'instance'), $arguments);
960
            } else if ($reflector->isInstantiable()) {
961
                $instantiation_mode = "6) constructor";
962
                $class_obj = $reflector->newInstanceArgs($arguments);
963
            } else {
964
                // heh ? something's not right !
965
                throw new EE_Error(
966
                    sprintf(
967
                        __('The %s file %s could not be instantiated.', 'event_espresso'),
968
                        $type,
969
                        $class_name
970
                    )
971
                );
972
            }
973
        } catch (Exception $e) {
974
            if ( ! $e instanceof EE_Error) {
975
                $e = new EE_Error(
976
                    sprintf(
977
                        __('The following error occurred while attempting to instantiate "%1$s": %2$s %3$s %2$s instantiation mode : %4$s', 'event_espresso'),
978
                        $class_name,
979
                        '<br />',
980
                        $e->getMessage(),
981
                        $instantiation_mode
982
                    )
983
                );
984
            }
985
            $e->get_error();
986
        }
987
        return $class_obj;
988
    }
989
990
991
992
    /**
993
     * @see http://stackoverflow.com/questions/173400/how-to-check-if-php-array-is-associative-or-sequential
994
     * @param array $array
995
     * @return bool
996
     */
997
    protected function _array_is_numerically_and_sequentially_indexed(array $array)
998
    {
999
        return ! empty($array) ? array_keys($array) === range(0, count($array) - 1) : true;
1000
    }
1001
1002
1003
1004
    /**
1005
     * getReflectionClass
1006
     * checks if a ReflectionClass object has already been generated for a class
1007
     * and returns that instead of creating a new one
1008
     *
1009
     * @access public
1010
     * @param string $class_name
1011
     * @return ReflectionClass
1012
     */
1013 View Code Duplication
    public function get_ReflectionClass($class_name)
1014
    {
1015
        if (
1016
            ! isset($this->_reflectors[$class_name])
1017
            || ! $this->_reflectors[$class_name] instanceof ReflectionClass
1018
        ) {
1019
            $this->_reflectors[$class_name] = new ReflectionClass($class_name);
1020
        }
1021
        return $this->_reflectors[$class_name];
1022
    }
1023
1024
1025
1026
    /**
1027
     * _resolve_dependencies
1028
     * examines the constructor for the requested class to determine
1029
     * if any dependencies exist, and if they can be injected.
1030
     * If so, then those classes will be added to the array of arguments passed to the constructor
1031
     * PLZ NOTE: this is achieved by type hinting the constructor params
1032
     * For example:
1033
     *        if attempting to load a class "Foo" with the following constructor:
1034
     *        __construct( Bar $bar_class, Fighter $grohl_class )
1035
     *        then $bar_class and $grohl_class will be added to the $arguments array,
1036
     *        but only IF they are NOT already present in the incoming arguments array,
1037
     *        and the correct classes can be loaded
1038
     *
1039
     * @access protected
1040
     * @param ReflectionClass $reflector
1041
     * @param string          $class_name
1042
     * @param array           $arguments
1043
     * @return array
1044
     * @throws \ReflectionException
1045
     */
1046
    protected function _resolve_dependencies(ReflectionClass $reflector, $class_name, $arguments = array())
1047
    {
1048
        // let's examine the constructor
1049
        $constructor = $reflector->getConstructor();
1050
        // whu? huh? nothing?
1051
        if ( ! $constructor) {
1052
            return $arguments;
1053
        }
1054
        // get constructor parameters
1055
        $params = $constructor->getParameters();
1056
        // and the keys for the incoming arguments array so that we can compare existing arguments with what is expected
1057
        $argument_keys = array_keys($arguments);
1058
        // now loop thru all of the constructors expected parameters
1059
        foreach ($params as $index => $param) {
1060
            // is this a dependency for a specific class ?
1061
            $param_class = $param->getClass() ? $param->getClass()->name : null;
1062
            // BUT WAIT !!! This class may be an alias for something else (or getting replaced at runtime)
1063
            $param_class = $this->_dependency_map->has_alias($param_class, $class_name)
1064
                ? $this->_dependency_map->get_alias($param_class, $class_name)
1065
                : $param_class;
1066
            if (
1067
                // param is not even a class
1068
                empty($param_class)
1069
                // and something already exists in the incoming arguments for this param
1070
                && isset($argument_keys[$index], $arguments[$argument_keys[$index]])
1071
            ) {
1072
                // so let's skip this argument and move on to the next
1073
                continue;
1074
            }
1075
            if (
1076
                // parameter is type hinted as a class, exists as an incoming argument, AND it's the correct class
1077
                ! empty($param_class)
1078
                && isset($argument_keys[$index], $arguments[$argument_keys[$index]])
1079
                && $arguments[$argument_keys[$index]] instanceof $param_class
1080
            ) {
1081
                // skip this argument and move on to the next
1082
                continue;
1083
            }
1084
            if (
1085
                // parameter is type hinted as a class, and should be injected
1086
                ! empty($param_class)
1087
                && $this->_dependency_map->has_dependency_for_class($class_name, $param_class)
1088
            ) {
1089
                $arguments = $this->_resolve_dependency($class_name, $param_class, $arguments, $index);
1090
            } else {
1091
                try {
1092
                    $arguments[$index] = $param->getDefaultValue();
1093
                } catch (ReflectionException $e) {
1094
                    throw new ReflectionException(
1095
                        sprintf(
1096
                            __('%1$s for parameter "$%2$s"', 'event_espresso'),
1097
                            $e->getMessage(),
1098
                            $param->getName()
1099
                        )
1100
                    );
1101
                }
1102
            }
1103
        }
1104
        return $arguments;
1105
    }
1106
1107
1108
1109
    /**
1110
     * @access protected
1111
     * @param string $class_name
1112
     * @param string $param_class
1113
     * @param array  $arguments
1114
     * @param mixed  $index
1115
     * @return array
1116
     */
1117
    protected function _resolve_dependency($class_name, $param_class, $arguments, $index)
1118
    {
1119
        $dependency = null;
1120
        // should dependency be loaded from cache ?
1121
        $cache_on = $this->_dependency_map->loading_strategy_for_class_dependency($class_name, $param_class)
1122
                    !== EE_Dependency_Map::load_new_object
1123
            ? true
1124
            : false;
1125
        // we might have a dependency...
1126
        // let's MAYBE try and find it in our cache if that's what's been requested
1127
        $cached_class = $cache_on ? $this->_get_cached_class($param_class) : null;
1128
        // and grab it if it exists
1129
        if ($cached_class instanceof $param_class) {
1130
            $dependency = $cached_class;
1131
        } else if ($param_class !== $class_name) {
1132
            // obtain the loader method from the dependency map
1133
            $loader = $this->_dependency_map->class_loader($param_class);
1134
            // is loader a custom closure ?
1135
            if ($loader instanceof Closure) {
1136
                $dependency = $loader();
1137
            } else {
1138
                // set the cache on property for the recursive loading call
1139
                $this->_cache_on = $cache_on;
1140
                // if not, then let's try and load it via the registry
1141
                if ($loader && method_exists($this, $loader)) {
1142
                    $dependency = $this->{$loader}($param_class);
1143
                } else {
1144
                    $dependency = $this->create($param_class, array(), $cache_on);
1145
                }
1146
            }
1147
        }
1148
        // did we successfully find the correct dependency ?
1149
        if ($dependency instanceof $param_class) {
1150
            // then let's inject it into the incoming array of arguments at the correct location
1151
            if (isset($argument_keys[$index])) {
0 ignored issues
show
Bug introduced by
The variable $argument_keys seems to never exist, and therefore isset should always return false. Did you maybe rename this variable?

This check looks for calls to isset(...) or empty() on variables that are yet undefined. These calls will always produce the same result and can be removed.

This is most likely caused by the renaming of a variable or the removal of a function/method parameter.

Loading history...
1152
                $arguments[$argument_keys[$index]] = $dependency;
1153
            } else {
1154
                $arguments[$index] = $dependency;
1155
            }
1156
        }
1157
        return $arguments;
1158
    }
1159
1160
1161
1162
    /**
1163
     * _set_cached_class
1164
     * attempts to cache the instantiated class locally
1165
     * in one of the following places, in the following order:
1166
     *        $this->{class_abbreviation}   ie:    $this->CART
1167
     *        $this->{$class_name}          ie:    $this->Some_Class
1168
     *        $this->addon->{$$class_name}    ie:    $this->addon->Some_Addon_Class
1169
     *        $this->LIB->{$class_name}     ie:    $this->LIB->Some_Class
1170
     *
1171
     * @access protected
1172
     * @param object $class_obj
1173
     * @param string $class_name
1174
     * @param string $class_prefix
1175
     * @param bool   $from_db
1176
     * @return void
1177
     */
1178
    protected function _set_cached_class($class_obj, $class_name, $class_prefix = '', $from_db = false)
1179
    {
1180
        if (empty($class_obj)) {
1181
            return;
1182
        }
1183
        // return newly instantiated class
1184
        if (isset($this->_class_abbreviations[$class_name])) {
1185
            $class_abbreviation = $this->_class_abbreviations[$class_name];
1186
            $this->{$class_abbreviation} = $class_obj;
1187
            return;
1188
        }
1189
        $class_name = str_replace('\\', '_', $class_name);
1190
        if (property_exists($this, $class_name)) {
1191
            $this->{$class_name} = $class_obj;
1192
            return;
1193
        }
1194
        if ($class_prefix === 'addon') {
1195
            $this->addons->{$class_name} = $class_obj;
1196
            return;
1197
        }
1198
        if ( ! $from_db) {
1199
            $this->LIB->{$class_name} = $class_obj;
1200
        }
1201
    }
1202
1203
1204
1205
    /**
1206
     * call any loader that's been registered in the EE_Dependency_Map::$_class_loaders array
1207
     *
1208
     * @param string $classname PLEASE NOTE: the class name needs to match what's registered
1209
     *                          in the EE_Dependency_Map::$_class_loaders array,
1210
     *                          including the class prefix, ie: "EE_", "EEM_", "EEH_", etc
1211
     * @param array  $arguments
1212
     * @return object
1213
     */
1214
    public static function factory($classname, $arguments = array())
1215
    {
1216
        $loader = self::instance()->_dependency_map->class_loader($classname);
1217
        if ($loader instanceof Closure) {
1218
            return $loader($arguments);
1219
        }
1220
        if (method_exists(EE_Registry::instance(), $loader)) {
1221
            return EE_Registry::instance()->{$loader}($classname, $arguments);
1222
        }
1223
        return null;
1224
    }
1225
1226
1227
1228
    /**
1229
     * Gets the addon by its name/slug (not classname. For that, just
1230
     * use the classname as the property name on EE_Config::instance()->addons)
1231
     *
1232
     * @param string $name
1233
     * @return EE_Addon
1234
     */
1235
    public function get_addon_by_name($name)
1236
    {
1237
        foreach ($this->addons as $addon) {
1238
            if ($addon->name() == $name) {
1239
                return $addon;
1240
            }
1241
        }
1242
        return null;
1243
    }
1244
1245
1246
1247
    /**
1248
     * Gets an array of all the registered addons, where the keys are their names. (ie, what each returns for their name() function) They're already available on EE_Config::instance()->addons as properties, where each property's name is
1249
     * the addon's classname. So if you just want to get the addon by classname, use EE_Config::instance()->addons->{classname}
1250
     *
1251
     * @return EE_Addon[] where the KEYS are the addon's name()
1252
     */
1253
    public function get_addons_by_name()
1254
    {
1255
        $addons = array();
1256
        foreach ($this->addons as $addon) {
1257
            $addons[$addon->name()] = $addon;
1258
        }
1259
        return $addons;
1260
    }
1261
1262
1263
1264
    /**
1265
     * Resets the specified model's instance AND makes sure EE_Registry doesn't keep
1266
     * a stale copy of it around
1267
     *
1268
     * @param string $model_name
1269
     * @return \EEM_Base
1270
     * @throws \EE_Error
1271
     */
1272
    public function reset_model($model_name)
1273
    {
1274
        $model_class_name = strpos($model_name, 'EEM_') !== 0 ? "EEM_{$model_name}" : $model_name;
1275
        if ( ! isset($this->LIB->{$model_class_name}) || ! $this->LIB->{$model_class_name} instanceof EEM_Base) {
1276
            return null;
1277
        }
1278
        //get that model reset it and make sure we nuke the old reference to it
1279
        if ($this->LIB->{$model_class_name} instanceof $model_class_name && is_callable(array($model_class_name, 'reset'))) {
1280
            $this->LIB->{$model_class_name} = $this->LIB->{$model_class_name}->reset();
1281
        } else {
1282
            throw new EE_Error(sprintf(__('Model %s does not have a method "reset"', 'event_espresso'), $model_name));
1283
        }
1284
        return $this->LIB->{$model_class_name};
1285
    }
1286
1287
1288
1289
    /**
1290
     * Resets the registry.
1291
     * The criteria for what gets reset is based on what can be shared between sites on the same request when switch_to_blog
1292
     * is used in a multisite install.  Here is a list of things that are NOT reset.
1293
     * - $_dependency_map
1294
     * - $_class_abbreviations
1295
     * - $NET_CFG (EE_Network_Config): The config is shared network wide so no need to reset.
1296
     * - $REQ:  Still on the same request so no need to change.
1297
     * - $CAP: There is no site specific state in the EE_Capability class.
1298
     * - $SSN: Although ideally, the session should not be shared between site switches, we can't reset it because only one Session
1299
     *         can be active in a single request.  Resetting could resolve in "headers already sent" errors.
1300
     * - $addons:  In multisite, the state of the addons is something controlled via hooks etc in a normal request.  So
1301
     *             for now, we won't reset the addons because it could break calls to an add-ons class/methods in the
1302
     *             switch or on the restore.
1303
     * - $modules
1304
     * - $shortcodes
1305
     * - $widgets
1306
     *
1307
     * @param boolean $hard             whether to reset data in the database too, or just refresh
1308
     *                                  the Registry to its state at the beginning of the request
1309
     * @param boolean $reinstantiate    whether to create new instances of EE_Registry's singletons too,
1310
     *                                  or just reset without re-instantiating (handy to set to FALSE if you're not sure if you CAN
1311
     *                                  currently reinstantiate the singletons at the moment)
1312
     * @param   bool  $reset_models     Defaults to true.  When false, then the models are not reset.  This is so client
1313
     *                                  code instead can just change the model context to a different blog id if necessary
1314
     * @return EE_Registry
1315
     */
1316
    public static function reset($hard = false, $reinstantiate = true, $reset_models = true)
1317
    {
1318
        $instance = self::instance();
1319
        EEH_Activation::reset();
1320
        //properties that get reset
1321
        $instance->_cache_on = true;
1322
        $instance->CFG = EE_Config::reset($hard, $reinstantiate);
1323
        $instance->CART = null;
1324
        $instance->MRM = null;
1325
        $instance->AssetsRegistry = null;
1326
        $instance->AssetsRegistry = $instance->create('EventEspresso\core\services\assets\Registry');
1327
        //messages reset
1328
        EED_Messages::reset();
1329
        if ($reset_models) {
1330
            foreach (array_keys($instance->non_abstract_db_models) as $model_name) {
1331
                $instance->reset_model($model_name);
1332
            }
1333
        }
1334
        $instance->LIB = new stdClass();
1335
        return $instance;
1336
    }
1337
1338
1339
1340
    /**
1341
     * @override magic methods
1342
     * @return void
1343
     */
1344
    public final function __destruct()
1345
    {
1346
    }
1347
1348
1349
1350
    /**
1351
     * @param $a
1352
     * @param $b
1353
     */
1354
    public final function __call($a, $b)
1355
    {
1356
    }
1357
1358
1359
1360
    /**
1361
     * @param $a
1362
     */
1363
    public final function __get($a)
1364
    {
1365
    }
1366
1367
1368
1369
    /**
1370
     * @param $a
1371
     * @param $b
1372
     */
1373
    public final function __set($a, $b)
1374
    {
1375
    }
1376
1377
1378
1379
    /**
1380
     * @param $a
1381
     */
1382
    public final function __isset($a)
1383
    {
1384
    }
1385
1386
1387
1388
    /**
1389
     * @param $a
1390
     */
1391
    public final function __unset($a)
1392
    {
1393
    }
1394
1395
1396
1397
    /**
1398
     * @return array
1399
     */
1400
    public final function __sleep()
1401
    {
1402
        return array();
1403
    }
1404
1405
1406
1407
    public final function __wakeup()
1408
    {
1409
    }
1410
1411
1412
1413
    /**
1414
     * @return string
1415
     */
1416
    public final function __toString()
1417
    {
1418
        return '';
1419
    }
1420
1421
1422
1423
    public final function __invoke()
1424
    {
1425
    }
1426
1427
1428
1429
    public final static function __set_state($array = array())
1430
    {
1431
        return EE_Registry::instance();
1432
    }
1433
1434
1435
1436
    public final function __clone()
1437
    {
1438
    }
1439
1440
1441
1442
    /**
1443
     * @param $a
1444
     * @param $b
1445
     */
1446
    public final static function __callStatic($a, $b)
1447
    {
1448
    }
1449
1450
1451
1452
    /**
1453
     * Gets all the custom post type models defined
1454
     *
1455
     * @return array keys are model "short names" (Eg "Event") and keys are classnames (eg "EEM_Event")
1456
     */
1457
    public function cpt_models()
1458
    {
1459
        $cpt_models = array();
1460
        foreach ($this->non_abstract_db_models as $short_name => $classname) {
1461
            if (is_subclass_of($classname, 'EEM_CPT_Base')) {
1462
                $cpt_models[$short_name] = $classname;
1463
            }
1464
        }
1465
        return $cpt_models;
1466
    }
1467
1468
1469
1470
    /**
1471
     * @return \EE_Config
1472
     */
1473
    public static function CFG()
1474
    {
1475
        return self::instance()->CFG;
1476
    }
1477
1478
1479
}
1480
// End of file EE_Registry.core.php
1481
// Location: ./core/EE_Registry.core.php
1482