Completed
Branch BUG-9871-email-validation (e62b1a)
by
unknown
350:41 queued 333:27
created

CollectionDetails::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 17
c 0
b 0
f 0
nc 1
nop 8
dl 0
loc 19
rs 9.4285

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
namespace EventEspresso\core\services\collections;
3
4
use  EventEspresso\core\exceptions\InvalidDataTypeException;
5
use  EventEspresso\core\exceptions\InvalidFilePathException;
6
use  EventEspresso\core\exceptions\InvalidIdentifierException;
7
use  EventEspresso\core\exceptions\InvalidInterfaceException;
8
use EventEspresso\core\services\locators\FqcnLocator;
9
use EventEspresso\core\services\locators\LocatorInterface;
10
11
if ( ! defined( 'EVENT_ESPRESSO_VERSION' ) ) {
12
	exit( 'No direct script access allowed' );
13
}
14
15
16
17
/**
18
 * Class CollectionDetails
19
 *
20
 * Abstract parent class for defining classes for loading into a collection.
21
 * The supplied interface will be used for type hinting the objects being loaded.
22
 * Classes can either be located by supplying an array of FQCNs (Fully Qualified Class Names),
23
 * AND/OR
24
 * an array of full server filepaths to a folder containing a set of files,
25
 * where the classnames match the filenames minus all extensions.
26
 *  for example:
27
 *  $FQCNs = array(
28
 *      '/Fully/Qualified/ClassNameA'
29
 *      '/Fully/Qualified/Other/ClassNameB'
30
 *  );
31
 *  $paths = array(
32
 *      '/full/server/path/to/ClassNameA.ext.php' // for class ClassNameA
33
 *      '/full/server/path/to/other/ClassNameB.php' // for class ClassNameB
34
 *  );
35
 * You do NOT have to provide both! They operate exclusively.
36
 * So you can provide an array of class names (FQCNs),
37
 * OR an array of folder filepaths,
38
 * OR you can provide both, if you happen to have classes of the same type in two locations,
39
 * and want to add both locations, and it turns out to be easier to use one loading method (FQCNs)
40
 * for the one location, and the other method for the other location.
41
 * You can of course use the same loading method for both locations if that worked best.
42
 *
43
 * @package       Event Espresso
44
 * @subpackage    core
45
 * @author        Brent Christensen
46
 * @since         4.9.0
47
 */
48
class CollectionDetails implements CollectionDetailsInterface {
49
50
	/**
51
	 * if $identifier_type is set to this,
52
	 * then the collection will use each object's spl_object_hash() as it's identifier
53
	 */
54
	const ID_OBJECT_HASH = 'identifier-uses-spl-object-hash';
55
56
	/**
57
	 * if $identifier_type is set to this,
58
	 * then the collection will use each object's class name as it's identifier
59
	 */
60
	const ID_CLASS_NAME = 'identifier-uses-object-class-name';
61
62
	/**
63
	 * if $identifier_type is set to this,
64
	 * then the collection will use the return value from a specified callback method on each object
65
	 */
66
	const ID_CALLBACK_METHOD = 'identifier-uses-callback-method';
67
68
	/**
69
	 * The interface used for controlling what gets added to the collection
70
	 *
71
	 * @var string $collection_interface
72
	 */
73
	protected $collection_interface = '';
74
75
	/**
76
	 * a unique name used to identify the collection in filter names
77
	 * supplied value is run through sanitize_title_with_dashes(),
78
	 * but then also converts dashes to underscores
79
	 *
80
	 * @var string $collection_name
81
	 */
82
	protected $collection_name = '';
83
84
	/**
85
	 * what the collection uses for the object identifier.
86
	 * corresponds to one of the class constants above.
87
	 * CollectionDetails::ID_OBJECT_HASH will use spl_object_hash( object ) for the identifier
88
	 * CollectionDetails::ID_CLASS_NAME will use get_class( object ) for the identifier
89
	 * CollectionDetails::ID_CALLBACK_METHOD will use a callback for the identifier
90
	 * defaults to using spl_object_hash() so that multiple objects of the same class can be added
91
	 *
92
	 * @var string $identifier_type
93
	 */
94
	protected $identifier_type = CollectionDetails::ID_OBJECT_HASH;
95
96
	/**
97
	 * the pattern applied to paths when searching for class files to add to the collection
98
	 * ie: "My_Awesome_*.class.php"
99
	 * defaults to "*.php"
100
	 *
101
	 * @var string $file_mask
102
	 */
103
	protected $file_mask = '';
104
105
	/**
106
	 * if the $identifier_type above is set to CollectionDetails::ID_CALLBACK_METHOD,
107
	 * then this specifies the method to use on each entity.
108
	 * If the callback method does not exist, then an exception will be thrown
109
	 *
110
	 * @var string $identifier_callback
111
	 */
112
	protected $identifier_callback = '';
113
114
	/**
115
	 * an array of Fully Qualified Class Names
116
	 *  for example:
117
	 *  $FQCNs = array(
118
	 *      '/Fully/Qualified/ClassNameA'
119
	 *      '/Fully/Qualified/Other/ClassNameB'
120
	 *  );
121
	 *
122
	 * @var array $collection_FQCNs
123
	 */
124
	protected $collection_FQCNs = array();
125
126
	/**
127
	 * an array of full server paths to folders containing files to be loaded into collection
128
	 *  for example:
129
	 *  $paths = array(
130
	 *      '/full/server/path/to/ClassNameA.ext.php' // for class ClassNameA
131
	 *      '/full/server/path/to/other/ClassNameB.php' // for class ClassNameB
132
	 *  );
133
	 *
134
	 * @var array $collection_paths
135
	 */
136
	protected $collection_paths = array();
137
138
	/**
139
	 * @var LocatorInterface $file_locator
140
	 */
141
	protected $file_locator;
142
143
144
145
	/**
146
	 * CollectionDetails constructor.
147
	 *
148
	 * @access public
149
	 * @param string           $collection_name
150
	 * @param string           $collection_interface
151
	 * @param array            $collection_FQCNs
152
	 * @param array            $collection_paths
153
	 * @param string           $file_mask
154
	 * @param string           $identifier_type
155
	 * @param string           $identifier_callback
156
	 * @param LocatorInterface $file_locator
157
	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
158
	 * @throws \EventEspresso\core\exceptions\InvalidFilePathException
159
	 * @throws \EventEspresso\core\exceptions\InvalidIdentifierException
160
	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
161
	 * @throws \EventEspresso\core\exceptions\InvalidClassException
162
	 */
163
	public function __construct(
164
		$collection_name,
165
		$collection_interface,
166
		$collection_FQCNs = array(),
167
		$collection_paths = array(),
168
		$file_mask = '',
169
		$identifier_type = CollectionDetails::ID_OBJECT_HASH,
170
		$identifier_callback = '',
171
		LocatorInterface $file_locator = null
172
	) {
173
		$this->setCollectionName( $collection_name );
174
		$this->setCollectionInterface( $collection_interface );
175
		$this->setCollectionFQCNs( $collection_FQCNs );
176
		$this->setCollectionPaths( $collection_paths );
177
		$this->setFileMasks( $file_mask );
178
		$this->setIdentifierType( $identifier_type );
179
		$this->setIdentifierCallback( $identifier_callback );
180
		$this->file_locator = $file_locator;
181
	}
182
183
184
185
	/**
186
	 * @access public
187
	 * @return mixed
188
	 */
189
	public function getCollectionInterface() {
190
		return $this->collection_interface;
191
	}
192
193
194
195
	/**
196
	 * @access protected
197
	 * @param string $collection_interface
198
	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
199
	 */
200
	protected function setCollectionInterface( $collection_interface ) {
201
		if ( ! ( interface_exists( $collection_interface ) || class_exists( $collection_interface ) ) ) {
202
			throw new InvalidInterfaceException( $collection_interface );
203
		}
204
		$this->collection_interface = $collection_interface;
205
	}
206
207
208
209
	/**
210
	 * the collection name will be used for creating dynamic filters
211
	 *
212
	 * @access public
213
	 * @return string
214
	 */
215
	public function collectionName() {
216
		return $this->collection_name;
217
	}
218
219
220
221
	/**
222
	 * sanitizes collection name and converts spaces and dashes to underscores
223
	 *
224
	 * @access protected
225
	 * @param string $collection_name
226
	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
227
	 */
228
	protected function setCollectionName( $collection_name ) {
229
		if ( ! is_string( $collection_name ) ) {
230
			throw new InvalidDataTypeException( '$collection_name', $collection_name, 'string' );
231
		}
232
		$this->collection_name = str_replace(
233
			'-',
234
			'_',
235
			sanitize_title_with_dashes( $collection_name, '', 'save' )
236
		);
237
	}
238
239
240
241
	/**
242
	 * @access public
243
	 * @return string
244
	 */
245
	public function identifierType() {
246
		return $this->identifier_type;
247
	}
248
249
250
251
	/**
252
	 * @access protected
253
	 * @param string $identifier_type
254
	 * @throws \EventEspresso\core\exceptions\InvalidIdentifierException
255
	 */
256
	protected function setIdentifierType( $identifier_type ) {
257
		if (
258
			! (
259
				$identifier_type === CollectionDetails::ID_CLASS_NAME
260
				|| $identifier_type === CollectionDetails::ID_OBJECT_HASH
261
				|| $identifier_type === CollectionDetails::ID_CALLBACK_METHOD
262
			)
263
		) {
264
			throw new InvalidIdentifierException(
265
				$identifier_type,
266
				'CollectionDetails::ID_CLASS_NAME or CollectionDetails::ID_OBJECT_HASH or CollectionDetails::ID_CALLBACK_METHOD'
267
			);
268
		}
269
		$this->identifier_type = $identifier_type;
270
	}
271
272
273
274
	/**
275
	 * @access public
276
	 * @return string
277
	 */
278
	public function identifierCallback() {
279
		return $this->identifier_callback;
280
	}
281
282
283
284
	/**
285
	 * @access protected
286
	 * @param string $identifier_callback
287
	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
288
	 */
289
	protected function setIdentifierCallback( $identifier_callback = 'identifier' ) {
290
		if ( ! is_string( $identifier_callback ) ) {
291
			throw new InvalidDataTypeException( '$identifier_callback', $identifier_callback, 'string' );
292
		}
293
		$this->identifier_callback = $identifier_callback;
294
	}
295
296
297
298
	/**
299
	 * @access public
300
	 * @return array
301
	 */
302
	public function getFileMask() {
303
		return $this->file_mask;
304
	}
305
306
307
308
	/**
309
	 * sets the file mask which is then used to filter what files get loaded
310
	 * when searching for classes to add to the collection. Defaults to '*.php'
311
	 *
312
	 * @access protected
313
	 * @param string $file_mask
314
	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
315
	 */
316
	protected function setFileMasks( $file_mask ) {
317
		$this->file_mask = ! empty( $file_mask ) ? $file_mask : '*.php';
318
		// we know our default is a string, so if it's not a string now,
319
		// then that means the incoming parameter was something else
320
		if ( ! is_string( $this->file_mask ) ) {
321
			throw new InvalidDataTypeException( '$file_mask', $this->file_mask, 'string' );
322
		}
323
	}
324
325
326
327
	/**
328
	 * @access public
329
	 * @return string
330
	 */
331
	public function getCollectionFQCNs() {
332
		return $this->collection_FQCNs;
333
	}
334
335
336
337
	/**
338
	 * @access public
339
	 * @param string|array $collection_FQCNs
340
	 * @throws \EventEspresso\core\exceptions\InvalidClassException
341
	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
342
	 */
343
	public function setCollectionFQCNs( $collection_FQCNs ) {
344
		foreach ( (array) $collection_FQCNs as $collection_FQCN ) {
345
			if ( ! empty( $collection_FQCN ) ) {
346
				if ( class_exists( $collection_FQCN ) ) {
347
					$this->collection_FQCNs[] = $collection_FQCN;
348
				} else {
349
					foreach ( $this->getFQCNsFromPartialNamespace( $collection_FQCN ) as $FQCN ) {
350
						$this->collection_FQCNs[] = $FQCN;
351
					}
352
				}
353
			}
354
		}
355
	}
356
357
358
359
	/**
360
	 * @access protected
361
	 * @param  string $partial_FQCN
362
	 * @return array
363
	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
364
	 * @throws \EventEspresso\core\exceptions\InvalidClassException
365
	 */
366
	protected function getFQCNsFromPartialNamespace( $partial_FQCN ) {
367
		if ( ! $this->file_locator instanceof FqcnLocator ) {
368
			$this->file_locator = new FqcnLocator();
369
		}
370
		$this->file_locator->locate( $partial_FQCN );
371
		return $this->file_locator->getFQCNs();
372
	}
373
374
375
376
	/**
377
	 * @access public
378
	 * @return string
379
	 */
380
	public function getCollectionPaths() {
381
		return $this->collection_paths;
382
	}
383
384
385
386
	/**
387
	 * @access public
388
	 * @param string|array $collection_paths
389
	 * @throws \EventEspresso\core\exceptions\InvalidFilePathException
390
	 */
391
	public function setCollectionPaths( $collection_paths ) {
392
		foreach ( (array) $collection_paths as $collection_path ) {
393
			if ( ! empty( $collection_path ) ) {
394
				if ( ! is_readable( $collection_path ) ) {
395
					throw new InvalidFilePathException( $collection_path );
396
				}
397
				$this->collection_paths[] = $collection_path;
398
			}
399
		}
400
	}
401
402
403
404
}
405
// End of file CollectionDetails.php
406
// Location: /CollectionDetails.php