Completed
Branch FET-9222-rest-api-writes (6820fb)
by
unknown
124:42 queued 113:43
created

EE_Registry::_create_object()   C

Complexity

Conditions 13
Paths 56

Size

Total Lines 54
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 13
eloc 27
c 0
b 0
f 0
nc 56
nop 4
dl 0
loc 54
rs 6.7593

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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