Completed
Branch BUG-9623-config-log (c144cd)
by
unknown
85:11 queued 66:47
created

EE_Dependency_Map::has()   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' ) ) {
3
	exit( 'No direct script access allowed' );
4
}
5
6
7
8
/**
9
 * Class EE_Dependency_Map
10
 *
11
 * info about how to load classes required by other classes
12
 *
13
 * @package       Event Espresso
14
 * @subpackage    core
15
 * @author        Brent Christensen
16
 * @since         4.9.0
17
 *
18
 */
19
class EE_Dependency_Map {
20
21
22
	/**
23
	 * This means that the requested class dependency is not present in the dependency map
24
	 */
25
	const not_registered = 0;
26
27
28
	/**
29
	 * This instructs class loaders to ALWAYS return a newly instantiated object for the requested class.
30
	 */
31
	const load_new_object = 1;
32
33
	/**
34
	 * This instructs class loaders to return a previously instantiated and cached object for the requested class.
35
	 * IF a previously instantiated object does not exist, a new one will be created and added to the cache.
36
	 */
37
	const load_from_cache = 2;
38
39
	/**
40
	 * @type EE_Dependency_Map $_instance
41
	 */
42
	protected static $_instance = null;
43
44
	/**
45
	 * @type EE_Request $request
46
	 */
47
	protected $_request;
48
49
	/**
50
	 * @type EE_Response $response
51
	 */
52
	protected $_response;
53
54
55
	/**
56
	 * @type array $_dependency_map
57
	 */
58
	protected $_dependency_map = array();
59
60
	/**
61
	 * @type array $_class_loaders
62
	 */
63
	protected $_class_loaders = array();
64
65
66
67
	/**
68
	 * EE_Dependency_Map constructor.
69
	 *
70
	 * @param  \EE_Request  $request
71
	 * @param  \EE_Response $response
72
	 */
73
	protected function __construct( EE_Request $request, EE_Response $response ) {
74
		$this->_request = $request;
75
		$this->_response = $response;
76
		add_action( 'EE_Load_Espresso_Core__handle_request__initialize_core_loading', array( $this, 'initialize' ) );
77
		do_action( 'EE_Dependency_Map____construct' );
78
	}
79
80
81
82
	/**
83
	 */
84
	public function initialize() {
85
		$this->_register_core_dependencies();
86
		$this->_register_core_class_loaders();
87
	}
88
89
90
91
	/**
92
	 * @singleton method used to instantiate class object
93
	 * @access    public
94
	 * @param  \EE_Request  $request
95
	 * @param  \EE_Response $response
96
	 * @return \EE_Dependency_Map instance
97
	 */
98
	public static function instance( EE_Request $request = null, EE_Response $response = null ) {
99
		// check if class object is instantiated, and instantiated properly
100
		if ( ! self::$_instance instanceof EE_Dependency_Map ) {
101
			self::$_instance = new EE_Dependency_Map( $request, $response );
0 ignored issues
show
Bug introduced by
It seems like $request defined by parameter $request on line 98 can be null; however, EE_Dependency_Map::__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...
Bug introduced by
It seems like $response defined by parameter $response on line 98 can be null; however, EE_Dependency_Map::__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...
102
		}
103
		return self::$_instance;
104
	}
105
106
107
108
	/**
109
	 * @param string $class
110
	 * @param array  $dependencies
111
	 * @return boolean
112
	 */
113
	public static function register_dependencies( $class, $dependencies ) {
114
		if ( ! isset( self::$_instance->_dependency_map[ $class ] ) ) {
115
			self::$_instance->_dependency_map[ $class ] = (array)$dependencies;
116
			return true;
117
		}
118
		return false;
119
	}
120
121
122
123
	/**
124
	 * @param string $class_name
125
	 * @param string $loader
126
	 * @return bool
127
	 * @throws \EE_Error
128
	 */
129
	public static function register_class_loader( $class_name, $loader = 'load_core' ) {
130
		// check that loader method starts with "load_" and exists in EE_Registry
131
		if ( strpos( $loader, 'load_' ) !== 0 || ! method_exists( 'EE_Registry', $loader ) ) {
132
			throw new EE_Error(
133
				sprintf(
134
					__( '"%1$s" is not a valid loader method on EE_Registry.', 'event_espresso' ),
135
					$loader
136
				)
137
			);
138
		}
139
		if ( ! isset( self::$_instance->_class_loaders[ $class_name ] ) ) {
140
			self::$_instance->_class_loaders[ $class_name ] = $loader;
141
			return true;
142
		}
143
		return false;
144
	}
145
146
147
148
	/**
149
	 * @return array
150
	 */
151
	public function dependency_map() {
152
		return $this->_dependency_map;
153
	}
154
155
156
157
	/**
158
	 * returns TRUE if dependency map contains a listing for the provided class name
159
	 *
160
	 * @param string $class_name
161
	 * @return boolean
162
	 */
163
	public function has( $class_name = '' ) {
164
		return isset( $this->_dependency_map[ $class_name ] ) ? true : false;
165
	}
166
167
168
169
	/**
170
	 * returns TRUE if dependency map contains a listing for the provided class name AND dependency
171
	 *
172
	 * @param string $class_name
173
	 * @param string $dependency
174
	 * @return bool
175
	 */
176
	public function has_dependency_for_class( $class_name = '', $dependency = '' ) {
177
		return isset( $this->_dependency_map[ $class_name ], $this->_dependency_map[ $class_name ][ $dependency ] )
178
			? true
179
			: false;
180
	}
181
182
183
184
	/**
185
	 * returns loading strategy for whether a previously cached dependency should be loaded or a new instance returned
186
	 *
187
	 * @param string $class_name
188
	 * @param string $dependency
189
	 * @return int
190
	 */
191
	public function loading_strategy_for_class_dependency( $class_name = '', $dependency = '' ) {
192
		return $this->has_dependency_for_class( $class_name, $dependency )
193
			? $this->_dependency_map[ $class_name ][ $dependency ]
194
			: EE_Dependency_Map::not_registered;
195
	}
196
197
198
199
	/**
200
	 * @param string $class_name
201
	 * @return string | Closure
202
	 */
203
	public function class_loader( $class_name ) {
204
		return isset( $this->_class_loaders[ $class_name ] ) ? $this->_class_loaders[ $class_name ] : '';
205
	}
206
207
208
209
	/**
210
	 * @return array
211
	 */
212
	public function class_loaders() {
213
		return $this->_class_loaders;
214
	}
215
216
217
218
	/**
219
	 * Registers the core dependencies and whether a previously instantiated object should be loaded from the cache,
220
	 * if one exists, or whether a new object should be generated every time the requested class is loaded.
221
	 * This is done by using the following class constants:
222
	 *
223
	 * 		EE_Dependency_Map::load_from_cache - loads previously instantiated object
224
	 * 		EE_Dependency_Map::load_new_object - generates a new object every time
225
	 */
226
	protected function _register_core_dependencies() {
227
		$this->_dependency_map = array(
228
			'EE_Request_Handler' => array(
229
				'EE_Request' => EE_Dependency_Map::load_from_cache,
230
			),
231
			'EE_System' => array(
232
				'EE_Registry' => EE_Dependency_Map::load_from_cache,
233
			),
234
			'EE_Session' => array(
235
				'EE_Encryption' => EE_Dependency_Map::load_from_cache
236
			),
237
			'EE_Cart' => array(
238
				'EE_Session' => EE_Dependency_Map::load_from_cache,
239
			),
240
			'EE_Front_Controller' => array(
241
				'EE_Registry'              => EE_Dependency_Map::load_from_cache,
242
				'EE_Request_Handler'       => EE_Dependency_Map::load_from_cache,
243
				'EE_Module_Request_Router' => EE_Dependency_Map::load_from_cache,
244
			),
245
			'EE_Messenger_Collection_Loader' => array(
246
				'EE_Messenger_Collection' => EE_Dependency_Map::load_new_object,
247
			),
248
			'EE_Message_Type_Collection_Loader' => array(
249
				'EE_Message_Type_Collection' => EE_Dependency_Map::load_new_object,
250
			),
251
			'EE_Message_Resource_Manager' => array(
252
				'EE_Messenger_Collection_Loader'    => EE_Dependency_Map::load_new_object,
253
				'EE_Message_Type_Collection_Loader' => EE_Dependency_Map::load_new_object,
254
				'EEM_Message_Template_Group'        => EE_Dependency_Map::load_from_cache,
255
			),
256
			'EE_Message_Factory' => array(
257
				'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
258
			),
259
			'EE_messages' => array(
260
				'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
261
			),
262
			'EE_Messages_Generator' => array(
263
				'EE_Messages_Queue'                    => EE_Dependency_Map::load_new_object,
264
				'EE_Messages_Data_Handler_Collection'  => EE_Dependency_Map::load_new_object,
265
				'EE_Message_Template_Group_Collection' => EE_Dependency_Map::load_new_object,
266
				'EEH_Parse_Shortcodes'                 => EE_Dependency_Map::load_from_cache,
267
			),
268
			'EE_Messages_Processor' => array(
269
				'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
270
			),
271
			'EE_Messages_Queue' => array(
272
				'EE_Message_Repository' => EE_Dependency_Map::load_new_object,
273
			),
274
			'EE_Messages_Template_Defaults' => array(
275
				'EEM_Message_Template_Group' => EE_Dependency_Map::load_from_cache,
276
				'EEM_Message_Template' => EE_Dependency_Map::load_from_cache,
277
			),
278
			'EE_Message_To_Generate_From_Request' => array(
279
				'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
280
				'EE_Request_Handler' => EE_Dependency_Map::load_from_cache
281
			)
282
		);
283
	}
284
285
286
287
	/**
288
	 * Registers how core classes are loaded.
289
	 *
290
	 * This can either be done by simply providing the name of one of the EE_Registry loader methods such as:
291
	 *
292
	 * 		'EE_Request_Handler' => 'load_core'
293
	 * 		'EE_Messages_Queue'  => 'load_lib'
294
	 * 		'EEH_Debug_Tools'    => 'load_helper'
295
	 *
296
	 * or, if greater control is required, by providing a custom closure. For example:
297
	 *
298
	 * 		'Some_Class' => function () {
299
	 * 			return new Some_Class();
300
	 * 		},
301
	 *
302
	 * This is required for instantiating dependencies
303
	 * where an interface has been type hinted in a class constructor. For example:
304
	 *
305
	 *        'Required_Interface' => function () {
306
	 *            return new A_Class_That_Implements_Required_Interface();
307
	 *        },
308
	 *
309
	 */
310
	protected function _register_core_class_loaders() {
311
		//for PHP5.3 compat, we need to register any properties called here in a variable because `$this` cannot
312
		//be used in a closure.
313
		$request = &$this->_request;
314
		$response = &$this->_response;
315
		$this->_class_loaders = array(
316
			//load_core
317
			'EE_Encryption'                        => 'load_core',
318
			'EE_Front_Controller'                  => 'load_core',
319
			'EE_Module_Request_Router'             => 'load_core',
320
			'EE_Registry'                          => 'load_core',
321
			'EE_Request' => function() use(&$request) {
322
				return $request;
323
			},
324
			'EE_Response' => function() use(&$response) {
325
				return $response;
326
			},
327
			'EE_Request_Handler'                   => 'load_core',
328
			'EE_Session'                           => 'load_core',
329
			'EE_System'                            => 'load_core',
330
			//load_lib
331
			'EE_Message_Resource_Manager'          => 'load_lib',
332
			'EE_Message_Type_Collection'           => 'load_lib',
333
			'EE_Message_Type_Collection_Loader'    => 'load_lib',
334
			'EE_Messenger_Collection'              => 'load_lib',
335
			'EE_Messenger_Collection_Loader'       => 'load_lib',
336
			'EE_Messages_Processor'       		   => 'load_lib',
337
			'EE_Message_Repository'       		   => 'load_lib',
338
			'EE_Messages_Queue'                    => 'load_lib',
339
			'EE_Messages_Data_Handler_Collection'  => 'load_lib',
340
			'EE_Message_Template_Group_Collection' => 'load_lib',
341
			'EE_Messages_Generator' => function() {
342
				return EE_Registry::instance()->load_lib( 'Messages_Generator', array(), false, false );
343
			},
344
			'EE_Messages_Template_Defaults' => function( $arguments = array() ) {
345
				return EE_Registry::instance()->load_lib( 'Messages_Template_Defaults', $arguments, false, false );
346
			},
347
			//load_model
348
			'EEM_Message_Template_Group'           => 'load_model',
349
			'EEM_Message_Template'                 => 'load_model',
350
			//load_helper
351
			'EEH_Parse_Shortcodes'                 => function() {
352
				if ( EE_Registry::instance()->load_helper( 'Parse_Shortcodes' ) ) {
353
					return new EEH_Parse_Shortcodes();
354
				}
355
				return null;
356
			},
357
		);
358
	}
359
360
361
	/**
362
	 * This is used to reset the internal map and class_loaders to their original default state at the beginning of the request
363
	 * Primarily used by unit tests.
364
	 */
365
	public function reset() {
366
		$this->_register_core_class_loaders();
367
		$this->_register_core_dependencies();
368
	}
369
370
371
}
372
// End of file EE_Dependency_Map.core.php
373
// Location: /EE_Dependency_Map.core.php