Completed
Branch FET-10768-extract-admin-bar (46d5db)
by
unknown
119:49 queued 108:29
created

Collection::has()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 8

Duplication

Lines 11
Ratio 100 %

Importance

Changes 0
Metric Value
cc 3
eloc 8
nc 3
nop 1
dl 11
loc 11
rs 9.4285
c 0
b 0
f 0
1
<?php
2
namespace EventEspresso\core\services\collections;
3
4
use  EventEspresso\core\exceptions\InvalidEntityException;
5
use  EventEspresso\core\exceptions\InvalidInterfaceException;
6
use LimitIterator;
7
8
if ( ! defined( 'EVENT_ESPRESSO_VERSION' ) ) {
9
	exit( 'No direct script access allowed' );
10
}
11
/**
12
 * Class Collection
13
 * class for managing a set of entities that all adhere to the same interface
14
 * unofficially follows Interop\Container\ContainerInterface
15
 *
16
 * @package       Event Espresso
17
 * @author        Brent Christensen
18
 * @since         4.9.0
19
 */
20
 class Collection extends \SplObjectStorage implements CollectionInterface {
21
22
23
	 /**
24
	  * an interface (or class) name to be used for restricting the type of objects added to the storage
25
	  * this should be set from within the child class constructor
26
	  *
27
	  * @type string $interface
28
	  */
29
	 protected $collection_interface;
30
31
32
33
	 /**
34
	  * Collection constructor
35
	  *
36
	  * @param string $collection_interface
37
	  * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
38
	  */
39
	 public function __construct( $collection_interface ) {
40
		 $this->setCollectionInterface( $collection_interface );
41
	 }
42
43
44
45
	 /**
46
	  * setCollectionInterface
47
	  *
48
	  * @access protected
49
	  * @param  string $collection_interface
50
	  * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
51
	  */
52
	 protected function setCollectionInterface( $collection_interface ) {
53
		 if ( ! ( interface_exists( $collection_interface ) || class_exists( $collection_interface ) ) ) {
54
			 throw new InvalidInterfaceException( $collection_interface );
55
		 }
56
		 $this->collection_interface = $collection_interface;
57
	 }
58
59
60
61
	 /**
62
	  * add
63
	  * attaches an object to the Collection
64
	  * and sets any supplied data associated with the current iterator entry
65
	  * by calling EE_Object_Collection::set_identifier()
66
	  *
67
	  * @access public
68
	  * @param        $object
69
	  * @param  mixed $identifier
70
	  * @return bool
71
	  * @throws \EventEspresso\core\exceptions\InvalidEntityException
72
	  */
73
	 public function add( $object, $identifier = null ) {
74
		 if ( ! $object instanceof $this->collection_interface ) {
75
			 throw new InvalidEntityException( $object, $this->collection_interface );
76
		 }
77
		 $this->attach( $object );
78
		 $this->setIdentifier( $object, $identifier );
79
		 return $this->contains( $object );
80
	 }
81
82
83
84
	 /**
85
	  * setIdentifier
86
87
	  * Sets the data associated with an object in the Collection
88
	  * if no $identifier is supplied, then the spl_object_hash() is used
89
	  *
90
	  * @access public
91
	  * @param  $object
92
	  * @param  mixed $identifier
93
	  * @return bool
94
	  */
95 View Code Duplication
	 public function setIdentifier( $object, $identifier = null ) {
96
		 $identifier = ! empty( $identifier ) ? $identifier : spl_object_hash( $object );
97
		 $this->rewind();
98
		 while ( $this->valid() ) {
99
			 if ( $object === $this->current() ) {
100
				 $this->setInfo( $identifier );
101
				 $this->rewind();
102
				 return true;
103
			 }
104
			 $this->next();
105
		 }
106
		 return false;
107
	 }
108
109
110
111
	 /**
112
	  * get
113
	  * finds and returns an object in the Collection based on the identifier that was set using addObject()
114
	  * PLZ NOTE: the pointer is reset to the beginning of the collection before returning
115
	  *
116
	  * @access public
117
	  * @param mixed $identifier
118
	  * @return mixed
119
	  */
120 View Code Duplication
	 public function get( $identifier ) {
121
		 $this->rewind();
122
		 while ( $this->valid() ) {
123
			 if ( $identifier === $this->getInfo() ) {
124
				 $object = $this->current();
125
				 $this->rewind();
126
				 return $object;
127
			 }
128
			 $this->next();
129
		 }
130
		 return null;
131
	 }
132
133
134
135
	 /**
136
	  * has
137
	  * returns TRUE or FALSE
138
	  * depending on whether the object is within the Collection
139
	  * based on the supplied $identifier
140
	  *
141
	  * @access public
142
	  * @param  mixed $identifier
143
	  * @return bool
144
	  */
145 View Code Duplication
	 public function has( $identifier ) {
146
		 $this->rewind();
147
		 while ( $this->valid() ) {
148
			 if ( $identifier === $this->getInfo() ) {
149
				 $this->rewind();
150
				 return true;
151
			 }
152
			 $this->next();
153
		 }
154
		 return false;
155
	 }
156
157
158
159
	 /**
160
	  * hasObject
161
	  * returns TRUE or FALSE depending on whether the supplied object is within the Collection
162
	  *
163
	  * @access public
164
	  * @param $object
165
	  * @return bool
166
	  */
167
	 public function hasObject( $object ) {
168
		 return $this->contains( $object );
169
	 }
170
171
172
173
	 /**
174
	  * remove
175
	  * detaches an object from the Collection
176
	  *
177
	  * @access public
178
	  * @param $object
179
	  * @return bool
180
	  */
181
	 public function remove( $object ) {
182
		 $this->detach( $object );
183
		 return true;
184
	 }
185
186
187
188
	 /**
189
	  * setCurrent
190
	  * advances pointer to the object whose identifier matches that which was provided
191
	  *
192
	  * @access public
193
	  * @param mixed $identifier
194
	  * @return boolean
195
	  */
196 View Code Duplication
	 public function setCurrent( $identifier ) {
197
		 $this->rewind();
198
		 while ( $this->valid() ) {
199
			 if ( $identifier === $this->getInfo() ) {
200
				 return true;
201
			 }
202
			 $this->next();
203
		 }
204
		 return false;
205
	 }
206
207
208
209
	 /**
210
	  * setCurrentUsingObject
211
	  * advances pointer to the provided object
212
	  *
213
	  * @access public
214
	  * @param $object
215
	  * @return boolean
216
	  */
217
	 public function setCurrentUsingObject( $object ) {
218
		 $this->rewind();
219
		 while ( $this->valid() ) {
220
			 if ( $this->current() === $object ) {
221
				 return true;
222
			 }
223
			 $this->next();
224
		 }
225
		 return false;
226
	 }
227
228
229
230
	 /**
231
	  * Returns the object occupying the index before the current object,
232
	  * unless this is already the first object, in which case it just returns the first object
233
	  *
234
	  * @return mixed
235
	  */
236
	 public function previous() {
237
		 $index = $this->indexOf( $this->current() );
238
		 if ( $index === 0 ) {
239
			 return $this->current();
240
		 }
241
		 $index--;
242
		 return $this->objectAtIndex( $index );
243
	 }
244
245
246
247
	 /**
248
	  * Returns the index of a given object, or false if not found
249
	  *
250
	  * @see http://stackoverflow.com/a/8736013
251
	  * @param $object
252
	  * @return boolean|int|string
253
	  */
254
	 public function indexOf( $object ) {
255
		 if ( ! $this->contains( $object ) ) {
256
			 return false;
257
		 }
258
		 foreach ( $this as $index => $obj ) {
259
			 if ( $obj === $object ) {
260
				 return $index;
261
			 }
262
		 }
263
		 return false;
264
	 }
265
266
267
268
	 /**
269
	  * Returns the object at the given index
270
	  *
271
	  * @see http://stackoverflow.com/a/8736013
272
	  * @param int $index
273
	  * @return mixed
274
	  */
275
	 public function objectAtIndex( $index ) {
276
		 $iterator = new LimitIterator( $this, $index, 1 );
277
		 $iterator->rewind();
278
		 return $iterator->current();
279
	 }
280
281
282
283
	 /**
284
	  * Returns the sequence of objects as specified by the offset and length
285
	  *
286
	  * @see http://stackoverflow.com/a/8736013
287
	  * @param int $offset
288
	  * @param int $length
289
	  * @return array
290
	  */
291
	 public function slice( $offset, $length ) {
292
		 $slice = array();
293
		 $iterator = new LimitIterator( $this, $offset, $length );
294
		 foreach ( $iterator as $object ) {
295
			 $slice[] = $object;
296
		 }
297
		 return $slice;
298
	 }
299
300
301
302
	 /**
303
	  * Inserts an object (or an array of objects) at a certain point
304
	  *
305
	  * @see http://stackoverflow.com/a/8736013
306
	  * @param mixed $objects A single object or an array of objects
307
	  * @param int $index
308
	  */
309
	 public function insertAt( $objects, $index ) {
310
		 if ( ! is_array( $objects ) ) {
311
			 $objects = array( $objects );
312
		 }
313
		 // check to ensure that objects don't already exist in the collection
314
		 foreach ( $objects as $key => $object ) {
315
			 if ( $this->contains( $object ) ) {
316
				 unset( $objects[ $key ] );
317
			 }
318
		 }
319
		 // do we have any objects left?
320
		 if ( ! $objects ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $objects of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
321
			 return;
322
		 }
323
		 // detach any objects at or past this index
324
		 $remaining = array();
325
		 if ( $index < $this->count() ) {
326
			 $remaining = $this->slice( $index, $this->count() - $index );
327
			 foreach ( $remaining as $object ) {
328
				 $this->detach( $object );
329
			 }
330
		 }
331
		 // add the new objects we're splicing in
332
		 foreach ( $objects as $object ) {
333
			 $this->attach( $object );
334
		 }
335
		 // attach the objects we previously detached
336
		 foreach ( $remaining as $object ) {
337
			 $this->attach( $object );
338
		 }
339
	 }
340
341
342
343
	 /**
344
	  * Removes the object at the given index
345
	  *
346
	  * @see http://stackoverflow.com/a/8736013
347
	  * @param int $index
348
	  */
349
	 public function removeAt( $index ) {
350
		 $this->detach( $this->objectAtIndex( $index ) );
351
	 }
352
353
354
355
     /**
356
      * detaches ALL objects from the Collection
357
      */
358
     public function detachAll()
359
     {
360
         $this->rewind();
361
         while ($this->valid()) {
362
             $object = $this->current();
363
             $this->next();
364
             $this->detach($object);
365
         }
366
     }
367
368
369
370
     /**
371
      * unsets and detaches ALL objects from the Collection
372
      */
373
     public function trashAndDetachAll()
374
     {
375
         $this->rewind();
376
         while ($this->valid()) {
377
             $object = $this->current();
378
             $this->next();
379
             $this->detach($object);
380
             unset($object);
381
         }
382
     }
383
384
385
386
 }
387
// End of file Collection.php
388
// Location: /Collection.php
389