Completed
Branch FET-9795-new-interfaces (d74f38)
by
unknown
135:01 queued 115:59
created

EE_Registry::get_module()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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

Adding a @return annotation to a constructor is not recommended, since a constructor does not have a meaningful return value.

Please refer to the PHP core documentation on constructors.

Loading history...
203
	 */
204
	protected function __construct( \EE_Dependency_Map $dependency_map ) {
205
		$this->_dependency_map = $dependency_map;
206
		add_action( 'EE_Load_Espresso_Core__handle_request__initialize_core_loading', array( $this, 'initialize' ) );
207
	}
208
209
210
211
	/**
212
	 * initialize
213
	 */
214
	public function initialize() {
215
		$this->_class_abbreviations = apply_filters(
216
			'FHEE__EE_Registry____construct___class_abbreviations',
217
			array(
218
				'EE_Config'                   => 'CFG',
219
				'EE_Session'                  => 'SSN',
220
				'EE_Capabilities'             => 'CAP',
221
				'EE_Cart'                     => 'CART',
222
				'EE_Network_Config'           => 'NET_CFG',
223
				'EE_Request_Handler'          => 'REQ',
224
				'EE_Message_Resource_Manager' => 'MRM',
225
			)
226
		);
227
		// class library
228
		$this->LIB = new StdClass();
229
		$this->addons = new StdClass();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \StdClass() of type object<stdClass> is incompatible with the declared type array<integer,object<EE_Addon>> of property $addons.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
230
		$this->modules = new StdClass();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \StdClass() of type object<stdClass> is incompatible with the declared type array<integer,object<EED_Module>> of property $modules.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
231
		$this->shortcodes = new StdClass();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \StdClass() of type object<stdClass> is incompatible with the declared type array<integer,object<EES_Shortcode>> of property $shortcodes.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
232
		$this->widgets = new StdClass();
0 ignored issues
show
Documentation Bug introduced by
It seems like new \StdClass() of type object<stdClass> is incompatible with the declared type array<integer,object<WP_Widget>> of property $widgets.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
233
		$this->load_core( 'Base', array(), true );
234
		// add our request and response objects to the cache
235
		$request_loader = $this->_dependency_map->class_loader( 'EE_Request' );
236
		$this->_set_cached_class(
237
			$request_loader(),
238
			'EE_Request'
239
		);
240
		$response_loader = $this->_dependency_map->class_loader( 'EE_Response' );
241
		$this->_set_cached_class(
242
			$response_loader(),
243
			'EE_Response'
244
		);
245
		add_action( 'AHEE__EE_System__set_hooks_for_core', array( $this, 'init' ) );
246
	}
247
248
249
250
	/**
251
	 *    init
252
	 *
253
	 * @access    public
254
	 * @return    void
255
	 */
256
	public function init() {
257
		// Get current page protocol
258
		$protocol = isset( $_SERVER[ 'HTTPS' ] ) ? 'https://' : 'http://';
259
		// Output admin-ajax.php URL with same protocol as current page
260
		self::$i18n_js_strings[ 'ajax_url' ] = admin_url( 'admin-ajax.php', $protocol );
261
		self::$i18n_js_strings[ 'wp_debug' ] = defined( 'WP_DEBUG' ) ? WP_DEBUG : false;
262
	}
263
264
265
266
	/**
267
	 * localize_i18n_js_strings
268
	 *
269
	 * @return string
270
	 */
271
	public static function localize_i18n_js_strings() {
272
		$i18n_js_strings = (array)EE_Registry::$i18n_js_strings;
273
		foreach ( $i18n_js_strings as $key => $value ) {
274
			if ( is_scalar( $value ) ) {
275
				$i18n_js_strings[ $key ] = html_entity_decode( (string)$value, ENT_QUOTES, 'UTF-8' );
276
			}
277
		}
278
279
		return "/* <![CDATA[ */ var eei18n = " . wp_json_encode( $i18n_js_strings ) . '; /* ]]> */';
280
	}
281
282
283
284
	/**
285
	 * @param mixed string | EED_Module $module
286
	 */
287
	public function add_module( $module ) {
288
		if ( $module instanceof EED_Module ) {
289
			$module_class = get_class( $module );
290
			$this->modules->{$module_class} = $module;
291
		} else {
292
			if ( ! class_exists( 'EE_Module_Request_Router' ) ) {
293
				$this->load_core( 'Module_Request_Router' );
294
			}
295
			$this->modules->{$module} = EE_Module_Request_Router::module_factory( $module );
296
		}
297
	}
298
299
300
301
	/**
302
	 * @param string $module_name
303
	 * @return mixed EED_Module | NULL
304
	 */
305
	public function get_module( $module_name = '' ) {
306
		return isset( $this->modules->{$module_name} ) ? $this->modules->{$module_name} : null;
307
	}
308
309
310
311
	/**
312
	 *    loads core classes - must be singletons
313
	 *
314
	 * @access    public
315
	 * @param string $class_name - simple class name ie: session
316
	 * @param mixed $arguments
317
	 * @param bool $load_only
318
	 * @return mixed
319
	 */
320
	public function load_core( $class_name, $arguments = array(), $load_only = false ) {
321
		$core_paths = apply_filters(
322
			'FHEE__EE_Registry__load_core__core_paths',
323
			array(
324
				EE_CORE,
325
				EE_ADMIN,
326
				EE_CPTS,
327
				EE_CORE . 'data_migration_scripts' . DS,
328
				EE_CORE . 'request_stack' . DS,
329
				EE_CORE . 'middleware' . DS,
330
			)
331
		);
332
		// retrieve instantiated class
333
		return $this->_load( $core_paths, 'EE_', $class_name, 'core', $arguments, false, true, $load_only );
334
	}
335
336
337
338
	/**
339
	 *    loads service classes
340
	 *
341
	 * @access    public
342
	 * @param string $class_name - simple class name ie: session
343
	 * @param mixed $arguments
344
	 * @param bool $load_only
345
	 * @return mixed
346
	 */
347
	public function load_service( $class_name, $arguments = array(), $load_only = false ) {
348
		$service_paths = apply_filters(
349
			'FHEE__EE_Registry__load_service__service_paths',
350
			array(
351
				EE_CORE . 'services' . DS,
352
			)
353
		);
354
		// retrieve instantiated class
355
		return $this->_load( $service_paths, 'EE_', $class_name, 'class', $arguments, false, true, $load_only );
356
	}
357
358
359
360
	/**
361
	 *    loads data_migration_scripts
362
	 *
363
	 * @access    public
364
	 * @param string $class_name - class name for the DMS ie: EE_DMS_Core_4_2_0
365
	 * @param mixed $arguments
366
	 * @return EE_Data_Migration_Script_Base
367
	 */
368
	public function load_dms( $class_name, $arguments = array() ) {
369
		// retrieve instantiated class
370
		return $this->_load( EE_Data_Migration_Manager::instance()->get_data_migration_script_folders(), 'EE_DMS_', $class_name, 'dms', $arguments, false, false, false );
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->_load(\EE_Data_Mi..., false, false, false); of type null|object|boolean adds the type boolean to the return on line 370 which is incompatible with the return type documented by EE_Registry::load_dms of type EE_Data_Migration_Script_Base|null.
Loading history...
371
	}
372
373
374
375
	/**
376
	 *    loads object creating classes - must be singletons
377
	 *
378
	 * @param string $class_name - simple class name ie: attendee
379
	 * @param mixed $arguments - an array of arguments to pass to the class
380
	 * @param bool $from_db - some classes are instantiated from the db and thus call a different method to instantiate
381
	 * @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)
382
	 * @param bool $load_only whether or not to just load the file and NOT instantiate, or load AND instantiate (default)
383
	 * @return EE_Base_Class | bool
384
	 */
385
	public function load_class( $class_name, $arguments = array(), $from_db = false, $cache = true, $load_only = false ) {
386
		$paths = apply_filters( 'FHEE__EE_Registry__load_class__paths', array(
387
			EE_CORE,
388
			EE_CLASSES,
389
			EE_BUSINESS
390
		) );
391
		// retrieve instantiated class
392
		return $this->_load( $paths, 'EE_', $class_name, 'class', $arguments, $from_db, $cache, $load_only );
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->_load($paths, 'EE...b, $cache, $load_only); of type null|object|boolean adds the type boolean to the return on line 392 which is incompatible with the return type documented by EE_Registry::load_class of type EE_Base_Class|null.
Loading history...
393
	}
394
395
396
397
	/**
398
	 *    loads helper classes - must be singletons
399
	 *
400
	 * @param string $class_name - simple class name ie: price
401
	 * @param mixed $arguments
402
	 * @param bool $load_only
403
	 * @return EEH_Base | bool
404
	 */
405
	public function load_helper( $class_name, $arguments = array(), $load_only = true ) {
406
		// todo: add doing_it_wrong() in a few versions after all addons have had calls to this method removed
407
		$helper_paths = apply_filters( 'FHEE__EE_Registry__load_helper__helper_paths', array( EE_HELPERS ) );
408
		// retrieve instantiated class
409
		return $this->_load( $helper_paths, 'EEH_', $class_name, 'helper', $arguments, false, true, $load_only );
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->_load($helper_pat...lse, true, $load_only); of type null|object|boolean adds the type boolean to the return on line 409 which is incompatible with the return type documented by EE_Registry::load_helper of type EEH_Base|null.
Loading history...
410
	}
411
412
413
414
	/**
415
	 *    loads core classes - must be singletons
416
	 *
417
	 * @access    public
418
	 * @param string $class_name - simple class name ie: session
419
	 * @param mixed $arguments
420
	 * @param bool $load_only
421
	 * @param bool $cache  whether to cache the object or not.
422
	 * @return mixed
423
	 */
424
	public function load_lib( $class_name, $arguments = array(), $load_only = false, $cache = true ) {
425
		$paths = array(
426
			EE_LIBRARIES,
427
			EE_LIBRARIES . 'messages' . DS,
428
			EE_LIBRARIES . 'shortcodes' . DS,
429
			EE_LIBRARIES . 'qtips' . DS,
430
			EE_LIBRARIES . 'payment_methods' . DS,
431
		);
432
		// retrieve instantiated class
433
		return $this->_load( $paths, 'EE_', $class_name, 'lib', $arguments, false, $cache, $load_only );
434
	}
435
436
437
438
	/**
439
	 *    loads model classes - must be singletons
440
	 *
441
	 * @param string $class_name - simple class name ie: price
442
	 * @param mixed $arguments
443
	 * @param bool $load_only
444
	 * @return EEM_Base | bool
445
	 */
446
	public function load_model( $class_name, $arguments = array(), $load_only = false ) {
447
		$paths = apply_filters( 'FHEE__EE_Registry__load_model__paths', array(
448
			EE_MODELS,
449
			EE_CORE
450
		) );
451
		// retrieve instantiated class
452
		return $this->_load( $paths, 'EEM_', $class_name, 'model', $arguments, false, true, $load_only );
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->_load($paths, 'EE...lse, true, $load_only); of type null|object|boolean adds the type boolean to the return on line 452 which is incompatible with the return type documented by EE_Registry::load_model of type EEM_Base|null.
Loading history...
453
	}
454
455
456
457
	/**
458
	 *    loads model classes - must be singletons
459
	 *
460
	 * @param string $class_name - simple class name ie: price
461
	 * @param mixed $arguments
462
	 * @param bool $load_only
463
	 * @return mixed | bool
464
	 */
465
	public function load_model_class( $class_name, $arguments = array(), $load_only = true ) {
466
		$paths = array(
467
			EE_MODELS . 'fields' . DS,
468
			EE_MODELS . 'helpers' . DS,
469
			EE_MODELS . 'relations' . DS,
470
			EE_MODELS . 'strategies' . DS
471
		);
472
		// retrieve instantiated class
473
		return $this->_load( $paths, 'EE_', $class_name, '', $arguments, false, true, $load_only );
474
	}
475
476
477
478
	/**
479
	 * Determines if $model_name is the name of an actual EE model.
480
	 * @param string $model_name like Event, Attendee, Question_Group_Question, etc.
481
	 * @return boolean
482
	 */
483
	public function is_model_name( $model_name ) {
484
		return isset( $this->models[ $model_name ] ) ? true : false;
485
	}
486
487
488
489
	/**
490
	 *    generic class loader
491
	 *
492
	 * @param string $path_to_file - directory path to file location, not including filename
493
	 * @param string $file_name - file name  ie:  my_file.php, including extension
494
	 * @param string $type - file type - core? class? helper? model?
495
	 * @param mixed $arguments
496
	 * @param bool $load_only
497
	 * @return mixed
498
	 */
499
	public function load_file( $path_to_file, $file_name, $type = '', $arguments = array(), $load_only = true ) {
500
		// retrieve instantiated class
501
		return $this->_load( $path_to_file, '', $file_name, $type, $arguments, false, true, $load_only );
0 ignored issues
show
Documentation introduced by
$path_to_file is of type string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
502
	}
503
504
505
506
	/**
507
	 *    load_addon
508
	 *
509
	 * @param string $path_to_file - directory path to file location, not including filename
510
	 * @param string $class_name - full class name  ie:  My_Class
511
	 * @param string $type - file type - core? class? helper? model?
512
	 * @param mixed $arguments
513
	 * @param bool $load_only
514
	 * @return EE_Addon
515
	 */
516
	public function load_addon( $path_to_file, $class_name, $type = 'class', $arguments = array(), $load_only = false ) {
517
		// retrieve instantiated class
518
		return $this->_load( $path_to_file, 'addon', $class_name, $type, $arguments, false, true, $load_only );
0 ignored issues
show
Documentation introduced by
$path_to_file is of type string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Bug Compatibility introduced by
The expression $this->_load($path_to_fi...lse, true, $load_only); of type null|object|boolean adds the type boolean to the return on line 518 which is incompatible with the return type documented by EE_Registry::load_addon of type EE_Addon|null.
Loading history...
519
	}
520
521
522
523
	/**
524
	 *    loads and tracks classes
525
	 *
526
	 * @param array $file_paths
527
	 * @param string $class_prefix - EE  or EEM or... ???
528
	 * @param bool|string $class_name - $class name
529
	 * @param string $type - file type - core? class? helper? model?
530
	 * @param mixed $arguments - an argument or array of arguments to pass to the class upon instantiation
531
	 * @param bool $from_db - some classes are instantiated from the db and thus call a different method to instantiate
532
	 * @param bool $cache
533
	 * @param bool $load_only
534
	 * @return null|object|bool  	null = failure to load or instantiate class object.
535
	 *                              object = class loaded and instantiated successfully.
536
	 *                              bool = fail or success when $load_only is true
537
	 */
538
	protected function _load(
539
		$file_paths = array(),
540
		$class_prefix = 'EE_',
541
		$class_name = false,
542
		$type = 'class',
543
		$arguments = array(),
544
		$from_db = false,
545
		$cache = true,
546
		$load_only = false
547
	) {
548
		// strip php file extension
549
		$class_name = str_replace( '.php', '', trim( $class_name ) );
550
		// does the class have a prefix ?
551
		if ( ! empty( $class_prefix ) && $class_prefix != 'addon' ) {
552
			// make sure $class_prefix is uppercase
553
			$class_prefix = strtoupper( trim( $class_prefix ) );
554
			// add class prefix ONCE!!!
555
			$class_name = $class_prefix . str_replace( $class_prefix, '', $class_name );
556
		}
557
		$class_exists = class_exists( $class_name );
558
		// if we're only loading the class and it already exists, then let's just return true immediately
559
		if ( $load_only && $class_exists ) {
560
			return true;
561
		}
562
		// $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
563
		// $cache is controlled by individual calls to separate Registry loader methods like load_class()
564
		// $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
565
		if ( $this->_cache_on && $cache && ! $load_only ) {
566
			// return object if it's already cached
567
			$cached_class = $this->_get_cached_class( $class_name, $class_prefix );
568
			if ( $cached_class !== null ) {
569
				return $cached_class;
570
			}
571
		}
572
		// if the class doesn't already exist.. then we need to try and find the file and load it
573
		if ( ! $class_exists ) {
574
			// get full path to file
575
			$path = $this->_resolve_path( $class_name, $type, $file_paths );
576
			// load the file
577
			$loaded = $this->_require_file( $path, $class_name, $type, $file_paths );
0 ignored issues
show
Security Bug introduced by
It seems like $path defined by $this->_resolve_path($cl...me, $type, $file_paths) on line 575 can also be of type false; however, EE_Registry::_require_file() does only seem to accept string, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
578
			// if loading failed, or we are only loading a file but NOT instantiating an object
579
			if ( ! $loaded || $load_only ) {
580
				// return boolean if only loading, or null if an object was expected
581
				return $load_only ? $loaded : null;
582
			}
583
		}
584
		// instantiate the requested object
585
		$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...
586
		if ( $this->_cache_on && $cache ) {
587
			// save it for later... kinda like gum  { : $
588
			$this->_set_cached_class( $class_obj, $class_name, $class_prefix, $from_db );
0 ignored issues
show
Documentation introduced by
$class_obj is of type null, but the function expects a object.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
589
		}
590
		$this->_cache_on = true;
591
		return $class_obj;
592
	}
593
594
595
596
	/**
597
	 * _get_cached_class
598
	 *
599
	 * attempts to find a cached version of the requested class
600
	 * by looking in the following places:
601
	 * 		$this->{$class_abbreviation} 		 	ie:   	$this->CART
602
	 * 		$this->{$class_name}           		 		ie:    $this->Some_Class
603
	 * 		$this->LIB->{$class_name}				ie: 	$this->LIB->Some_Class
604
	 * 		$this->addon->{$class_name}	ie: 	$this->addon->Some_Addon_Class
605
	 *
606
	 * @access protected
607
	 * @param string $class_name
608
	 * @param string $class_prefix
609
	 * @return null|object
610
	 */
611
	protected function _get_cached_class( $class_name, $class_prefix = '' ) {
612
		if ( $class_name === 'EE_Registry' ) {
613
			return $this;
614
		}
615
		if ( isset( $this->_class_abbreviations[ $class_name ] ) ) {
616
			$class_abbreviation = $this->_class_abbreviations[ $class_name ];
617
		} else {
618
			// have to specify something, but not anything that will conflict
619
			$class_abbreviation = 'FANCY_BATMAN_PANTS';
620
		}
621
		// check if class has already been loaded, and return it if it has been
622
		if ( isset( $this->{$class_abbreviation} ) && ! is_null( $this->{$class_abbreviation} ) ) {
623
			return $this->{$class_abbreviation};
624
		} else if ( isset ( $this->{$class_name} ) ) {
625
			return $this->{$class_name};
626
		} else if ( isset ( $this->LIB->{$class_name} ) ) {
627
			return $this->LIB->{$class_name};
628
		} else if ( $class_prefix == 'addon' && isset ( $this->addons->{$class_name} ) ) {
629
			return $this->addons->{$class_name};
630
		}
631
		return null;
632
	}
633
634
635
636
	/**
637
	 * _resolve_path
638
	 *
639
	 * attempts to find a full valid filepath for the requested class.
640
	 * loops thru each of the base paths in the $file_paths array and appends : "{classname} . {file type} . php"
641
	 * then returns that path if the target file has been found and is readable
642
	 *
643
	 * @access protected
644
	 * @param string $class_name
645
	 * @param string $type
646
	 * @param array $file_paths
647
	 * @return string | bool
648
	 */
649
	protected function _resolve_path( $class_name, $type = '', $file_paths = array() ) {
650
		// make sure $file_paths is an array
651
		$file_paths = is_array( $file_paths ) ? $file_paths : array( $file_paths );
652
		// cycle thru paths
653
		foreach ( $file_paths as $key => $file_path ) {
654
			// convert all separators to proper DS, if no filepath, then use EE_CLASSES
655
			$file_path = $file_path ? str_replace( array( '/', '\\' ), DS, $file_path ) : EE_CLASSES;
656
			// prep file type
657
			$type = ! empty( $type ) ? trim( $type, '.' ) . '.' : '';
658
			// build full file path
659
			$file_paths[ $key ] = rtrim( $file_path, DS ) . DS . $class_name . '.' . $type . 'php';
660
			//does the file exist and can be read ?
661
			if ( is_readable( $file_paths[ $key ] ) ) {
662
				return $file_paths[ $key ];
663
			}
664
		}
665
		return false;
666
	}
667
668
669
670
	/**
671
	 * _require_file
672
	 *
673
	 * basically just performs a require_once()
674
	 * but with some error handling
675
	 *
676
	 * @access protected
677
	 * @param  string $path
678
	 * @param  string $class_name
679
	 * @param  string $type
680
	 * @param  array $file_paths
681
	 * @return boolean
682
	 * @throws \EE_Error
683
	 */
684
	protected function _require_file( $path, $class_name, $type = '', $file_paths = array() ) {
685
		// don't give up! you gotta...
686
		try {
687
			//does the file exist and can it be read ?
688 View Code Duplication
			if ( ! $path ) {
689
				// so sorry, can't find the file
690
				throw new EE_Error (
691
					sprintf(
692
						__( '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' ),
693
						trim( $type, '.' ),
694
						$class_name,
695
						'<br />' . implode( ',<br />', $file_paths )
696
					)
697
				);
698
			}
699
			// get the file
700
			require_once( $path );
701
			// if the class isn't already declared somewhere
702 View Code Duplication
			if ( class_exists( $class_name, false ) === false ) {
703
				// so sorry, not a class
704
				throw new EE_Error(
705
					sprintf(
706
						__( 'The %s file %s does not appear to contain the %s Class.', 'event_espresso' ),
707
						$type,
708
						$path,
709
						$class_name
710
					)
711
				);
712
			}
713
714
		} catch ( EE_Error $e ) {
715
			$e->get_error();
716
			return false;
717
		}
718
		return true;
719
	}
720
721
722
723
	/**
724
	 * _create_object
725
	 * Attempts to instantiate the requested class via any of the
726
	 * commonly used instantiation methods employed throughout EE.
727
	 * The priority for instantiation is as follows:
728
	 * 		- abstract classes or any class flagged as "load only" (no instantiation occurs)
729
	 * 	 	- model objects via their 'new_instance_from_db' method
730
	 * 	 	- model objects via their 'new_instance' method
731
	 * 	 	- "singleton" classes" via their 'instance' method
732
	 *  	- standard instantiable classes via their __constructor
733
	 * Prior to instantiation, if the classname exists in the dependency_map,
734
	 * then the constructor for the requested class will be examined to determine
735
	 * if any dependencies exist, and if they can be injected.
736
	 * If so, then those classes will be added to the array of arguments passed to the constructor
737
	 *
738
	 * @access protected
739
	 * @param string $class_name
740
	 * @param array $arguments
741
	 * @param string $type
742
	 * @param bool $from_db
743
	 * @return null | object
744
	 * @throws \EE_Error
745
	 */
746
	protected function _create_object( $class_name, $arguments = array(), $type = '', $from_db = false ) {
747
		$class_obj = null;
748
		// don't give up! you gotta...
749
		try {
750
			// create reflection
751
			$reflector = $this->get_ReflectionClass( $class_name );
752
			// make sure arguments are an array
753
			$arguments = is_array( $arguments ) ? $arguments : array( $arguments );
754
			// and if arguments array is numerically and sequentially indexed, then we want it to remain as is,
755
			// else wrap it in an additional array so that it doesn't get split into multiple parameters
756
			$arguments = $this->_array_is_numerically_and_sequentially_indexed( $arguments )
757
				? $arguments
758
				: array( $arguments );
759
			// attempt to inject dependencies ?
760
			if ( $this->_dependency_map->has( $class_name ) ) {
761
				$arguments = $this->_resolve_dependencies( $reflector, $class_name, $arguments );
762
			}
763
			// instantiate the class and add to the LIB array for tracking
764
			// EE_Base_Classes are instantiated via new_instance by default (models call them via new_instance_from_db)
765
			if ( $reflector->getConstructor() === null || $reflector->isAbstract() ) {
766
				// no constructor = static methods only... nothing to instantiate, loading file was enough
767
				//$instantiation_mode = "no constructor";
768
				$class_obj = true;
769
			} else if ( $from_db && method_exists( $class_name, 'new_instance_from_db' ) ) {
770
				//$instantiation_mode = "new_instance_from_db";
771
				$class_obj = call_user_func_array( array( $class_name, 'new_instance_from_db' ), $arguments );
772
			} else if ( method_exists( $class_name, 'new_instance' ) ) {
773
				//$instantiation_mode = "new_instance";
774
				$class_obj = call_user_func_array( array( $class_name, 'new_instance' ), $arguments );
775
			} else if ( method_exists( $class_name, 'instance' ) ) {
776
				//$instantiation_mode = "instance";
777
				$class_obj = call_user_func_array( array( $class_name, 'instance' ), $arguments );
778
			} else if ( $reflector->isInstantiable() ) {
779
				//$instantiation_mode = "isInstantiable";
780
				$class_obj = $reflector->newInstanceArgs( $arguments );
781
			} else {
782
				// heh ? something's not right !
783
				//$instantiation_mode = 'none';
784
				throw new EE_Error(
785
					sprintf(
786
						__( 'The %s file %s could not be instantiated.', 'event_espresso' ),
787
						$type,
788
						$class_name
789
					)
790
				);
791
			}
792
		} catch ( Exception $e ) {
793
			if ( ! $e instanceof EE_Error ) {
794
				$e = new EE_Error( $e->getMessage() );
795
			}
796
			$e->get_error();
797
		}
798
		return $class_obj;
799
	}
800
801
802
803
	/**
804
	 * @see http://stackoverflow.com/questions/173400/how-to-check-if-php-array-is-associative-or-sequential
805
	 * @param array $array
806
	 * @return bool
807
	 */
808
	protected function _array_is_numerically_and_sequentially_indexed( array $array ) {
809
		return ! empty( $array ) ? array_keys( $array ) === range( 0, count( $array ) - 1 ) : true;
810
	}
811
812
813
814
	/**
815
	 * getReflectionClass
816
	 *
817
	 * checks if a ReflectionClass object has already been generated for a class
818
	 * and returns that instead of creating a new one
819
	 *
820
	 * @access public
821
	 * @param string $class_name
822
	 * @return ReflectionClass
823
	 */
824
	public function get_ReflectionClass( $class_name ) {
825
		if (
826
			! isset( $this->_reflectors[ $class_name ] )
827
			|| ! $this->_reflectors[ $class_name ] instanceof ReflectionClass
828
		) {
829
			$this->_reflectors[ $class_name ] = new ReflectionClass( $class_name );
830
		}
831
		return $this->_reflectors[ $class_name ];
832
	}
833
834
835
836
	/**
837
	 * _resolve_dependencies
838
	 *
839
	 * examines the constructor for the requested class to determine
840
	 * if any dependencies exist, and if they can be injected.
841
	 * If so, then those classes will be added to the array of arguments passed to the constructor
842
	 * PLZ NOTE: this is achieved by type hinting the constructor params
843
	 * For example:
844
	 * 		if attempting to load a class "Foo" with the following constructor:
845
	 *        __construct( Bar $bar_class, Fighter $grohl_class )
846
	 * 		then $bar_class and $grohl_class will be added to the $arguments array,
847
	 * 		but only IF they are NOT already present in the incoming arguments array,
848
	 * 		and the correct classes can be loaded
849
	 *
850
	 * @access protected
851
	 * @param ReflectionClass $reflector
852
	 * @param string $class_name
853
	 * @param array $arguments
854
	 * @return array
855
	 */
856
	protected function _resolve_dependencies( ReflectionClass $reflector, $class_name, $arguments = array() ) {
857
		// let's examine the constructor
858
		$constructor = $reflector->getConstructor();
859
		// whu? huh? nothing?
860
		if ( ! $constructor ) {
861
			return $arguments;
862
		}
863
		// get constructor parameters
864
		$params = $constructor->getParameters();
865
		// and the keys for the incoming arguments array so that we can compare existing arguments with what is expected
866
		$argument_keys = array_keys( $arguments );
867
		// now loop thru all of the constructors expected parameters
868
		foreach ( $params as $index => $param ) {
869
			// is this a dependency for a specific class ?
870
			$param_class = $param->getClass() ? $param->getClass()->name : null;
871
			if (
872
				// param is not even a class
873
				empty( $param_class )
874
				// and something already exists in the incoming arguments for this param
875
				&& isset( $argument_keys[ $index ], $arguments[ $argument_keys[ $index ] ] )
876
			) {
877
				// so let's skip this argument and move on to the next
878
				continue;
879
			} else if (
880
				// parameter is type hinted as a class, exists as an incoming argument, AND it's the correct class
881
				! empty( $param_class )
882
				&& isset( $argument_keys[ $index ], $arguments[ $argument_keys[ $index ] ] )
883
				&& $arguments[ $argument_keys[ $index ] ] instanceof $param_class
884
			) {
885
				// skip this argument and move on to the next
886
				continue;
887
			} else if (
888
				// parameter is type hinted as a class, and should be injected
889
				! empty( $param_class )
890
				&& $this->_dependency_map->has_dependency_for_class( $class_name, $param_class )
891
			) {
892
				$arguments = $this->_resolve_dependency( $class_name, $param_class, $arguments, $index );
893
			} else {
894
				$arguments[ $index ] = $param->getDefaultValue();
895
			}
896
897
		}
898
		return $arguments;
899
	}
900
901
902
903
	/**
904
	 * @access protected
905
	 * @param string $class_name
906
	 * @param string $param_class
907
	 * @param array $arguments
908
	 * @param mixed $index
909
	 * @return array
910
	 */
911
	protected function _resolve_dependency( $class_name, $param_class , $arguments, $index ) {
912
		$dependency = null;
913
		// should dependency be loaded from cache ?
914
		$cache_on = $this->_dependency_map->loading_strategy_for_class_dependency(
915
			$class_name, $param_class
916
		) !== EE_Dependency_Map::load_new_object
917
			? true
918
			: false;
919
		// we might have a dependency...
920
		// let's MAYBE try and find it in our cache if that's what's been requested
921
		$cached_class = $cache_on ? $this->_get_cached_class( $param_class ) : null;
922
		// and grab it if it exists
923
		if ( $cached_class instanceof $param_class ) {
924
			$dependency = $cached_class;
925
		} else if ( $param_class != $class_name ) {
926
			// obtain the loader method from the dependency map
927
			$loader = $this->_dependency_map->class_loader( $param_class );
928
			// is loader a custom closure ?
929
			if ( $loader instanceof Closure ) {
930
				$dependency = $loader();
931
			} else {
932
				// set the cache on property for the recursive loading call
933
				$this->_cache_on = $cache_on;
934
				// if not, then let's try and load it via the registry
935
				$dependency = $this->{$loader}( $param_class );
936
			}
937
		}
938
		// did we successfully find the correct dependency ?
939
		if ( $dependency instanceof $param_class ) {
940
			// then let's inject it into the incoming array of arguments at the correct location
941
			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...
942
				$arguments[ $argument_keys[ $index ] ] = $dependency;
943
			} else {
944
				$arguments[ $index ] = $dependency;
945
			}
946
		}
947
		return $arguments;
948
	}
949
950
951
952
	/**
953
	 * _set_cached_class
954
	 *
955
	 * attempts to cache the instantiated class locally
956
	 * in one of the following places, in the following order:
957
	 *        $this->{class_abbreviation}   ie:    $this->CART
958
	 *        $this->{$class_name}          ie:    $this->Some_Class
959
	 *        $this->addon->{$$class_name} 	ie:    $this->addon->Some_Addon_Class
960
	 *        $this->LIB->{$class_name}     ie:    $this->LIB->Some_Class
961
	 *
962
	 * @access protected
963
	 * @param object $class_obj
964
	 * @param string $class_name
965
	 * @param string $class_prefix
966
	 * @param bool $from_db
967
	 * @return void
968
	 */
969
	protected function _set_cached_class( $class_obj, $class_name, $class_prefix = '', $from_db = false ) {
970
		if ( $class_name === 'EE_Registry' ) {
971
			return;
972
		}
973
		// return newly instantiated class
974
		if ( isset( $this->_class_abbreviations[ $class_name ] ) ) {
975
			$class_abbreviation = $this->_class_abbreviations[ $class_name ];
976
			$this->{$class_abbreviation} = $class_obj;
977
		} else if ( property_exists( $this, $class_name ) ) {
978
			$this->{$class_name} = $class_obj;
979
		} else if ( $class_prefix == 'addon' ) {
980
			$this->addons->{$class_name} = $class_obj;
981
		} else if ( ! $from_db ) {
982
			$this->LIB->{$class_name} = $class_obj;
983
		}
984
	}
985
986
987
988
	/**
989
	 * call any loader that's been registered in the EE_Dependency_Map::$_class_loaders array
990
	 *
991
	 *
992
	 * @param string $classname PLEASE NOTE: the class name needs to match what's registered
993
	 *                          in the EE_Dependency_Map::$_class_loaders array,
994
	 *                          including the class prefix, ie: "EE_", "EEM_", "EEH_", etc
995
	 * @param array  $arguments
996
	 * @return object
997
	 */
998
	public static function factory( $classname, $arguments = array() ) {
999
		$loader = self::instance()->_dependency_map->class_loader( $classname );
1000
		if ( $loader instanceof Closure ) {
1001
			return $loader( $arguments );
1002
		} else if ( method_exists( EE_Registry::instance(), $loader ) ) {
1003
			return EE_Registry::instance()->{$loader}( $classname, $arguments );
1004
		}
1005
		return null;
1006
	}
1007
1008
1009
1010
	/**
1011
	 * Gets the addon by its name/slug (not classname. For that, just
1012
	 * use the classname as the property name on EE_Config::instance()->addons)
1013
	 * @param string $name
1014
	 * @return EE_Addon
1015
	 */
1016
	public function get_addon_by_name( $name ) {
1017
		foreach ( $this->addons as $addon ) {
1018
			if ( $addon->name() == $name ) {
1019
				return $addon;
1020
			}
1021
		}
1022
		return null;
1023
	}
1024
1025
1026
1027
	/**
1028
	 * 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 the addon's classname. So if you just want to get the addon by classname, use EE_Config::instance()->addons->{classname}
1029
	 *
1030
	 * @return EE_Addon[] where the KEYS are the addon's name()
1031
	 */
1032
	public function get_addons_by_name() {
1033
		$addons = array();
1034
		foreach ( $this->addons as $addon ) {
1035
			$addons[ $addon->name() ] = $addon;
1036
		}
1037
		return $addons;
1038
	}
1039
1040
1041
1042
	/**
1043
	 * Resets the specified model's instance AND makes sure EE_Registry doesn't keep
1044
	 * a stale copy of it around
1045
	 *
1046
	 * @param string $model_name
1047
	 * @return \EEM_Base
1048
	 * @throws \EE_Error
1049
	 */
1050
	public function reset_model( $model_name ) {
1051
		$model = $this->load_model( $model_name );
1052
		$model_class_name = get_class( $model );
1053
		//get that model reset it and make sure we nuke the old reference to it
1054
		if ( $model instanceof $model_class_name && is_callable( array( $model_class_name, 'reset' ))) {
1055
			$this->LIB->{$model_class_name} = $model::reset();
1056
		} else {
1057
			throw new EE_Error( sprintf( __( 'Model %s does not have a method "reset"', 'event_espresso' ), $model_name ) );
1058
		}
1059
		return $this->LIB->{$model_class_name};
1060
	}
1061
1062
1063
1064
	/**
1065
	 * Resets the registry.
1066
	 *
1067
	 * The criteria for what gets reset is based on what can be shared between sites on the same request when switch_to_blog
1068
	 * is used in a multisite install.  Here is a list of things that are NOT reset.
1069
	 *
1070
	 * - $_dependency_map
1071
	 * - $_class_abbreviations
1072
	 * - $NET_CFG (EE_Network_Config): The config is shared network wide so no need to reset.
1073
	 * - $REQ:  Still on the same request so no need to change.
1074
	 * - $CAP: There is no site specific state in the EE_Capability class.
1075
	 * - $SSN: Although ideally, the session should not be shared between site switches, we can't reset it because only one Session
1076
	 *         can be active in a single request.  Resetting could resolve in "headers already sent" errors.
1077
	 * - $addons:  In multisite, the state of the addons is something controlled via hooks etc in a normal request.  So
1078
	 *             for now, we won't reset the addons because it could break calls to an add-ons class/methods in the
1079
	 *             switch or on the restore.
1080
	 * - $modules
1081
	 * - $shortcodes
1082
	 * - $widgets
1083
	 * - $LIB:  Only specific classes get unset from $LIB (current EE_Data_Migration_Manager) that persist state.
1084
	 *
1085
	 * @param boolean $hard whether to reset data in the database too, or just refresh
1086
	 * the Registry to its state at the beginning of the request
1087
	 * @param boolean $reinstantiate whether to create new instances of EE_Registry's singletons too,
1088
	 * or just reset without re-instantiating (handy to set to FALSE if you're not sure if you CAN
1089
	 * currently reinstantiate the singletons at the moment)
1090
	 * @param   bool    $reset_models    Defaults to true.  When false, then the models are not reset.  This is so client
1091
	 *                                  code instead can just change the model context to a different blog id if necessary
1092
	 *
1093
	 * @return EE_Registry
1094
	 */
1095
	public static function reset( $hard = false, $reinstantiate = true, $reset_models = true ) {
1096
		$instance = self::instance();
1097
		$instance->_cache_on = true;
1098
		// reset some "special" classes
1099
		EEH_Activation::reset();
1100
		$instance->CFG = $instance->CFG->reset( $hard, $reinstantiate );
1101
		$instance->CART = null;
1102
		$instance->MRM = null;
1103
		//handle of objects cached on LIB
1104
		foreach ( array( 'LIB', 'modules', 'shortcodes' ) as $cache ) {
1105
			foreach ( $instance->{$cache} as $class_name => $class ) {
1106
				if ( EE_Registry::_reset_and_unset_object( $class, $reset_models )) {
1107
					unset( $instance->{$cache}->{$class_name} );
1108
				}
1109
			}
1110
		}
1111
		return $instance;
1112
	}
1113
1114
1115
1116
	/**
1117
	 * if passed object implements ResettableInterface, then call it's reset() method
1118
	 * if passed object implements InterminableInterface, then return false,
1119
	 * to indicate that it should NOT be cleared from the Registry cache
1120
	 *
1121
	 * @param      $object
1122
	 * @param bool $reset_models
1123
	 * @return bool returns true if cached object should be unset
1124
	 */
1125
	private static function _reset_and_unset_object( $object, $reset_models ) {
1126
		static $count = 0;
1127
		$count++;
1128
		if ( $object instanceof ResettableInterface ) {
1129
			if ( $object instanceof EEM_Base ) {
1130
				if ( $reset_models ) {
1131
					$object->reset();
1132
				}
1133
				return false;
1134
			}
1135
			$object->reset();
1136
			return false;
1137
		}
1138
		if ( ! $object instanceof InterminableInterface ) {
1139
			return true;
1140
		}
1141
		return false;
1142
	}
1143
1144
1145
1146
	/**
1147
	 * @override magic methods
1148
	 * @return void
1149
	 */
1150
	final function __destruct() {
1151
	}
1152
1153
1154
1155
	/**
1156
	 * @param $a
1157
	 * @param $b
1158
	 */
1159
	final function __call( $a, $b ) {
1160
	}
1161
1162
1163
1164
	/**
1165
	 * @param $a
1166
	 */
1167
	final function __get( $a ) {
1168
	}
1169
1170
1171
1172
	/**
1173
	 * @param $a
1174
	 * @param $b
1175
	 */
1176
	final function __set( $a, $b ) {
1177
	}
1178
1179
1180
1181
	/**
1182
	 * @param $a
1183
	 */
1184
	final function __isset( $a ) {
1185
	}
1186
1187
1188
1189
	/**
1190
	 * @param $a
1191
	 */
1192
	final function __unset( $a ) {
1193
	}
1194
1195
1196
1197
	/**
1198
	 * @return array
1199
	 */
1200
	final function __sleep() {
1201
		return array();
1202
	}
1203
1204
1205
1206
	final function __wakeup() {
1207
	}
1208
1209
1210
1211
	/**
1212
	 * @return string
1213
	 */
1214
	final function __toString() {
1215
		return '';
1216
	}
1217
1218
1219
1220
	final function __invoke() {
1221
	}
1222
1223
1224
1225
	final function __set_state() {
1226
	}
1227
1228
1229
1230
	final function __clone() {
1231
	}
1232
1233
1234
1235
	/**
1236
	 * @param $a
1237
	 * @param $b
1238
	 */
1239
	final static function __callStatic( $a, $b ) {
1240
	}
1241
1242
	/**
1243
	 * Gets all the custom post type models defined
1244
	 * @return array keys are model "short names" (Eg "Event") and keys are classnames (eg "EEM_Event")
1245
	 */
1246
	public function cpt_models() {
1247
		$cpt_models = array();
1248
		foreach( $this->non_abstract_db_models as $short_name => $classname ) {
1249
			if( is_subclass_of(  $classname, 'EEM_CPT_Base' ) ) {
1250
				$cpt_models[ $short_name ] = $classname;
1251
			}
1252
		}
1253
		return $cpt_models;
1254
	}
1255
1256
1257
1258
	public static function CFG() {
1259
		return self::instance()->CFG;
1260
	}
1261
1262
1263
}
1264
// End of file EE_Registry.core.php
1265
// Location: ./core/EE_Registry.core.php
1266