Completed
Pull Request — master (#416)
by no
07:35 queued 03:51
created

SnakList::removeSnak()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1
Metric Value
dl 0
loc 3
ccs 1
cts 1
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 $index => $snak ) {
38
			$this->setElement( $index, $snak );
39
		}
40 3
	}
41 3
42
	/**
43
	 * @see GenericArrayObject::getObjectType
44
	 *
45
	 * @since 0.1
46
	 *
47
	 * @return string
48
	 */
49
	public function getObjectType() {
50
		return 'Wikibase\DataModel\Snak\Snak';
51 5
	}
52 5
53 5
	/**
54
	 * @see Snaks::hasSnakHash
55
	 *
56
	 * @since 0.1
57
	 *
58
	 * @param string $snakHash
59
	 *
60
	 * @return boolean
61
	 */
62
	public function hasSnakHash( $snakHash ) {
63
		return $this->hasElementHash( $snakHash );
64 10
	}
65 10
66
	/**
67
	 * @see Snaks::removeSnakHash
68
	 *
69
	 * @since 0.1
70
	 *
71
	 * @param string $snakHash
72
	 */
73
	public function removeSnakHash( $snakHash ) {
74
		$this->removeByElementHash( $snakHash );
75
	}
76
77 11
	/**
78 11
	 * @see Snaks::addSnak
79
	 *
80
	 * @since 0.1
81
	 *
82
	 * @param Snak $snak
83
	 *
84
	 * @return boolean Indicates if the snak was added or not.
85
	 */
86
	public function addSnak( Snak $snak ) {
87
		return $this->addElement( $snak );
88 13
	}
89 13
90 13
	/**
91
	 * @see Snaks::hasSnak
92
	 *
93
	 * @since 0.1
94
	 *
95
	 * @param Snak $snak
96
	 *
97
	 * @return boolean
98
	 */
99
	public function hasSnak( Snak $snak ) {
100
		return $this->hasElementHash( $snak->getHash() );
101
	}
102
103
	/**
104
	 * @see Snaks::removeSnak
105
	 *
106
	 * @since 0.1
107
	 *
108
	 * @param Snak $snak
109
	 */
110
	public function removeSnak( Snak $snak ) {
111
		$this->removeByElementHash( $snak->getHash() );
112 7
	}
113 7
114 7
	/**
115
	 * @see Snaks::getSnak
116
	 *
117
	 * @since 0.1
118
	 *
119
	 * @param string $snakHash
120
	 *
121
	 * @return Snak|bool
122
	 */
123
	public function getSnak( $snakHash ) {
124 7
		return $this->getByElementHash( $snakHash );
125 7
	}
126 7
127
	/**
128 7
	 * @see HashArray::getHash
129 6
	 *
130 5
	 * @since 0.5
131 5
	 *
132 5
	 * @return string
133 7
	 */
134 7
	public function getHash() {
135
		$hasher = new MapValueHasher();
136
		return $hasher->hash( $this );
137
	}
138
139 5
	/**
140 5
	 * Orders the snaks in the list grouping them by property.
141 5
	 *
142 5
	 * @param string[] $order List of serliazed property ids to order by.
143 5
	 *
144 5
	 * @since 0.5
145
	 */
146
	public function orderByProperty( $order = array() ) {
147
		$snaksByProperty = $this->getSnaksByProperty();
148
		$orderedProperties = array_unique( array_merge( $order, array_keys( $snaksByProperty ) ) );
149
150
		foreach ( $orderedProperties as $property ) {
151
			if ( array_key_exists( $property, $snaksByProperty ) ) {
152 7
				$snaks = $snaksByProperty[$property];
153 7
				$this->moveSnaksToBottom( $snaks );
154
			}
155 7
		}
156
	}
157 5
158 5
	/**
159 5
	 * @param Snak[] $snaks to remove and re add
160 5
	 */
161 5
	private function moveSnaksToBottom( array $snaks ) {
162 7
		foreach ( $snaks as $snak ) {
163
			$this->removeSnak( $snak );
164 7
			$this->addSnak( $snak );
165
		}
166
	}
167
168
	/**
169
	 * Gets the snaks in the current object in an array
170
	 * grouped by property id
171
	 *
172
	 * @return array[]
173
	 */
174
	private function getSnaksByProperty() {
175
		$snaksByProperty = array();
176
177
		foreach ( $this as $snak ) {
178
			/** @var Snak $snak */
179
			$propertyId = $snak->getPropertyId()->getSerialization();
180
			if ( !isset( $snaksByProperty[$propertyId] ) ) {
181
				$snaksByProperty[$propertyId] = array();
182
			}
183
			$snaksByProperty[$propertyId][] = $snak;
184
		}
185
186
		return $snaksByProperty;
187
	}
188
189
}
190