Completed
Pull Request — master (#439)
by no
11:30 queued 07:22
created

SnakList::removeSnakHash()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1
Metric Value
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 1
eloc 2
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Wikibase\DataModel\Snak;
4
5
use InvalidArgumentException;
6
use Traversable;
7
use Wikibase\DataModel\HashArray;
8
use Wikibase\DataModel\Internal\MapValueHasher;
9
10
/**
11
 * List of Snak objects.
12
 * Indexes the snaks by hash and ensures no more the one snak with the same hash are in the list.
13
 *
14
 * @since 0.1
15
 *
16
 * @licence GNU GPL v2+
17
 * @author Jeroen De Dauw < [email protected] >
18
 * @author Addshore
19
 */
20
class SnakList extends HashArray {
21
22
	/**
23
	 * @param Snak[]|Traversable|Snak $snaks
24
	 * @param Snak [$snak2,...]
25
	 *
26
	 * @throws InvalidArgumentException
27 7
	 */
28 7
	public function __construct( $snaks = array() /*...*/ ) {
29
		if ( $snaks instanceof Snak ) {
30
			$snaks = func_get_args();
31
		}
32
33
		if ( !is_array( $snaks ) && !( $snaks instanceof Traversable ) ) {
34
			throw new InvalidArgumentException( '$snaks must be an array or an instance of Traversable' );
35
		}
36
37
		foreach ( $snaks as $snak ) {
38
			if ( !( $snak instanceof Snak ) ) {
39
				throw new InvalidArgumentException( 'Every element in $snaks must be an instance of Snak' );
40 3
			}
41 3
42
			$this->addSnak( $snak );
43
		}
44
	}
45
46
	/**
47
	 * @see GenericArrayObject::getObjectType
48
	 *
49
	 * @since 0.1
50
	 *
51 5
	 * @return string
52 5
	 */
53 5
	public function getObjectType() {
54
		return 'Wikibase\DataModel\Snak\Snak';
55
	}
56
57
	/**
58
	 * @see Snaks::hasSnakHash
59
	 *
60
	 * @since 0.1
61
	 *
62
	 * @param string $snakHash
63
	 *
64 10
	 * @return boolean
65 10
	 */
66
	public function hasSnakHash( $snakHash ) {
67
		return $this->hasElementHash( $snakHash );
68
	}
69
70
	/**
71
	 * @see Snaks::removeSnakHash
72
	 *
73
	 * @since 0.1
74
	 *
75
	 * @param string $snakHash
76
	 */
77 11
	public function removeSnakHash( $snakHash ) {
78 11
		$this->removeByElementHash( $snakHash );
79
	}
80
81
	/**
82
	 * @see Snaks::addSnak
83
	 *
84
	 * @since 0.1
85
	 *
86
	 * @param Snak $snak
87
	 *
88 13
	 * @return boolean Indicates if the snak was added or not.
89 13
	 */
90 13
	public function addSnak( Snak $snak ) {
91
		return $this->addElement( $snak );
92
	}
93
94
	/**
95
	 * @see Snaks::hasSnak
96
	 *
97
	 * @since 0.1
98
	 *
99
	 * @param Snak $snak
100
	 *
101
	 * @return boolean
102
	 */
103
	public function hasSnak( Snak $snak ) {
104
		return $this->hasElementHash( $snak->getHash() );
105
	}
106
107
	/**
108
	 * @see Snaks::removeSnak
109
	 *
110
	 * @since 0.1
111
	 *
112 7
	 * @param Snak $snak
113 7
	 */
114 7
	public function removeSnak( Snak $snak ) {
115
		$this->removeByElementHash( $snak->getHash() );
116
	}
117
118
	/**
119
	 * @see Snaks::getSnak
120
	 *
121
	 * @since 0.1
122
	 *
123
	 * @param string $snakHash
124 7
	 *
125 7
	 * @return Snak|bool
126 7
	 */
127
	public function getSnak( $snakHash ) {
128 7
		return $this->getByElementHash( $snakHash );
129 6
	}
130 5
131 5
	/**
132 5
	 * @see HashArray::getHash
133 7
	 *
134 7
	 * @since 0.5
135
	 *
136
	 * @return string
137
	 */
138
	public function getHash() {
139 5
		$hasher = new MapValueHasher();
140 5
		return $hasher->hash( $this );
141 5
	}
142 5
143 5
	/**
144 5
	 * Orders the snaks in the list grouping them by property.
145
	 *
146
	 * @param string[] $order List of serliazed property ids to order by.
147
	 *
148
	 * @since 0.5
149
	 */
150
	public function orderByProperty( $order = array() ) {
151
		$snaksByProperty = $this->getSnaksByProperty();
152 7
		$orderedProperties = array_unique( array_merge( $order, array_keys( $snaksByProperty ) ) );
153 7
154
		foreach ( $orderedProperties as $property ) {
155 7
			if ( array_key_exists( $property, $snaksByProperty ) ) {
156
				$snaks = $snaksByProperty[$property];
157 5
				$this->moveSnaksToBottom( $snaks );
158 5
			}
159 5
		}
160 5
	}
161 5
162 7
	/**
163
	 * @param Snak[] $snaks to remove and re add
164 7
	 */
165
	private function moveSnaksToBottom( array $snaks ) {
166
		foreach ( $snaks as $snak ) {
167
			$this->removeSnak( $snak );
168
			$this->addSnak( $snak );
169
		}
170
	}
171
172
	/**
173
	 * Gets the snaks in the current object in an array
174
	 * grouped by property id
175
	 *
176
	 * @return array[]
177
	 */
178
	private function getSnaksByProperty() {
179
		$snaksByProperty = array();
180
181
		foreach ( $this as $snak ) {
182
			/** @var Snak $snak */
183
			$propertyId = $snak->getPropertyId()->getSerialization();
184
			if ( !isset( $snaksByProperty[$propertyId] ) ) {
185
				$snaksByProperty[$propertyId] = array();
186
			}
187
			$snaksByProperty[$propertyId][] = $snak;
188
		}
189
190
		return $snaksByProperty;
191
	}
192
193
}
194