Completed
Pull Request — master (#603)
by no
06:45 queued 03:38
created

ReferenceList::getReference()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 3
Metric Value
dl 0
loc 12
ccs 6
cts 6
cp 1
rs 9.4285
cc 3
eloc 5
nc 3
nop 1
crap 3
1
<?php
2
3
namespace Wikibase\DataModel;
4
5
use Hashable;
6
use InvalidArgumentException;
7
use Traversable;
8
use Wikibase\DataModel\Snak\Snak;
9
10
/**
11
 * List of Reference objects.
12
 *
13
 * Note that this implementation is based on SplObjectStorage and
14
 * is not enforcing the type of objects set via it's native methods.
15
 * Therefore one can add non-Reference-implementing objects when
16
 * not sticking to the methods of the References interface.
17
 *
18
 * @since 0.1
19
 * Does not implement References anymore since 2.0
20
 *
21
 * @licence GNU GPL v2+
22
 * @author Jeroen De Dauw < [email protected] >
23
 * @author H. Snater < [email protected] >
24
 * @author Thiemo Mättig
25
 */
26
class ReferenceList extends HashableObjectStorage {
0 ignored issues
show
Deprecated Code introduced by
The class Wikibase\DataModel\HashableObjectStorage has been deprecated with message: since 4.4, removal in 6.0 as per https://github.com/wmde/WikibaseDataModel/pull/498

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
27
28
	/**
29
	 * @param Reference[]|Traversable $references
30
	 *
31
	 * @throws InvalidArgumentException
32
	 */
33
	public function __construct( $references = array() ) {
34 29
		if ( !is_array( $references ) && !( $references instanceof Traversable ) ) {
35 29
			throw new InvalidArgumentException( '$references must be an array or an instance of Traversable' );
36 8
		}
37
38
		foreach ( $references as $reference ) {
39 21
			if ( !( $reference instanceof Reference ) ) {
40 12
				throw new InvalidArgumentException( 'Every element in $references must be an instance of Reference' );
41 4
			}
42
43
			$this->addReference( $reference );
44 8
		}
45 17
	}
46 17
47
	/**
48
	 * Adds the provided reference to the list.
49
	 *
50
	 * @since 0.1
51
	 *
52
	 * @param Reference $reference
53
	 * @param int|null $index
54
	 *
55
	 * @throws InvalidArgumentException
56
	 */
57
	public function addReference( Reference $reference, $index = null ) {
58 14
		if ( !is_int( $index ) && $index !== null ) {
59 14
			throw new InvalidArgumentException( '$index must be an integer or null' );
60
		}
61
62
		if ( $index === null || $index >= count( $this ) ) {
63 14
			// Append object to the end of the reference list.
64
			$this->attach( $reference );
65 14
		} else {
66 14
			$this->insertReferenceAtIndex( $reference, $index );
67 2
		}
68
	}
69 14
70
	/**
71
	 * @see SplObjectStorage::attach
72
	 *
73
	 * @param Reference $reference
74
	 * @param mixed $data Unused in the ReferenceList class.
75
	 */
76
	public function attach( $reference, $data = null ) {
77 14
		if ( !$reference->isEmpty() ) {
78 14
			parent::attach( $reference, $data );
79 14
		}
80 14
	}
81 14
82
	/**
83
	 * @since 1.1
84
	 *
85
	 * @param Snak[]|Snak $snaks
86
	 * @param Snak [$snak2,...]
87
	 *
88
	 * @throws InvalidArgumentException
89
	 */
90
	public function addNewReference( $snaks = array() /*...*/ ) {
91 6
		if ( $snaks instanceof Snak ) {
92 6
			$snaks = func_get_args();
93 5
		}
94 5
95
		$this->addReference( new Reference( $snaks ) );
96 6
	}
97 5
98
	/**
99
	 * @param Reference $reference
100
	 * @param int $index
101
	 */
102
	private function insertReferenceAtIndex( Reference $reference, $index ) {
103 2
		$referencesToShift = array();
104 2
		$i = 0;
105 2
106
		// Determine the references that need to be shifted and detach them:
107
		foreach ( $this as $object ) {
108 2
			if ( $i++ >= $index ) {
109 2
				$referencesToShift[] = $object;
110 2
			}
111 2
		}
112 2
113
		foreach ( $referencesToShift as $object ) {
114 2
			$this->detach( $object );
115 2
		}
116 2
117
		// Attach the new reference and reattach the previously detached references:
118
		$this->attach( $reference );
119 2
120
		foreach ( $referencesToShift as $object ) {
121 2
			$this->attach( $object );
122 2
		}
123 2
	}
124 2
125
	/**
126
	 * Returns if the list contains a reference with the same hash as the provided reference.
127
	 *
128
	 * @since 0.1
129
	 *
130
	 * @param Reference $reference
131
	 *
132
	 * @return boolean
133
	 */
134
	public function hasReference( Reference $reference ) {
135 6
		return $this->contains( $reference )
136 6
			|| $this->hasReferenceHash( $reference->getHash() );
137 6
	}
138
139
	/**
140
	 * Returns the index of a reference or false if the reference could not be found.
141
	 *
142
	 * @since 0.5
143
	 *
144
	 * @param Reference $reference
145
	 *
146
	 * @return int|boolean
147
	 */
148
	public function indexOf( Reference $reference ) {
149 2
		$index = 0;
150 2
151
		foreach ( $this as $object ) {
152 2
			if ( $object === $reference ) {
153 1
				return $index;
154 1
			}
155
			$index++;
156 1
		}
157 2
158
		return false;
159 2
	}
160
161
	/**
162
	 * Removes the reference with the same hash as the provided reference if such a reference exists in the list.
163
	 *
164
	 * @since 0.1
165
	 *
166
	 * @param Reference $reference
167
	 */
168
	public function removeReference( Reference $reference ) {
169 3
		$this->removeReferenceHash( $reference->getHash() );
170 3
	}
171 3
172
	/**
173
	 * Returns if the list contains a reference with the provided hash.
174
	 *
175
	 * @since 0.3
176
	 *
177
	 * @param string $referenceHash
178
	 *
179
	 * @return boolean
180
	 */
181
	public function hasReferenceHash( $referenceHash ) {
182 8
		return $this->getReference( $referenceHash ) !== null;
183 8
	}
184
185
	/**
186
	 * Removes the reference with the provided hash if it exists in the list.
187
	 *
188
	 * @since 0.3
189
	 *
190
	 * @param string $referenceHash	`
191
	 */
192
	public function removeReferenceHash( $referenceHash ) {
193 5
		$reference = $this->getReference( $referenceHash );
194 5
195
		if ( $reference !== null ) {
196 5
			$this->detach( $reference );
197 3
		}
198 3
	}
199 5
200
	/**
201
	 * Returns the reference with the provided hash, or null if there is no such reference in the list.
202
	 *
203
	 * @since 0.3
204
	 *
205
	 * @param string $referenceHash
206
	 *
207
	 * @return Reference|null
208
	 */
209
	public function getReference( $referenceHash ) {
210 14
		/**
211
		 * @var Hashable $hashable
212
		 */
213
		foreach ( $this as $hashable ) {
214 14
			if ( $hashable->getHash() === $referenceHash ) {
215 10
				return $hashable;
216 10
			}
217
		}
218 9
219
		return null;
220 9
	}
221
222
	/**
223
	 * @see Serializable::serialize
224
	 *
225
	 * @since 2.1
226
	 *
227
	 * @return string
228
	 */
229
	public function serialize() {
230 3
		return serialize( iterator_to_array( $this ) );
231 3
	}
232
233
	/**
234
	 * @see Serializable::unserialize
235
	 *
236
	 * @since 2.1
237
	 *
238
	 * @param string $data
239
	 */
240
	public function unserialize( $data ) {
241 3
		$this->__construct( unserialize( $data ) );
242 3
	}
243 3
244
	/**
245
	 * @since 4.4
246
	 *
247
	 * @return bool
248
	 */
249
	public function isEmpty() {
250 3
		return $this->count() === 0;
251 3
	}
252
253
}
254