Passed
Push — equalHashArrays ( ea52b8 )
by no
02:53
created

SnakList::equals()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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