Passed
Push — clear ( 11b8fa )
by Bene
03:57
created

TermList::getByLanguage()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 9
rs 9.6666
cc 2
eloc 5
nc 2
nop 1
1
<?php
2
3
namespace Wikibase\DataModel\Term;
4
5
use ArrayIterator;
6
use Comparable;
7
use Countable;
8
use InvalidArgumentException;
9
use IteratorAggregate;
10
use OutOfBoundsException;
11
use Traversable;
12
13
/**
14
 * Unordered list of Term objects.
15
 * If multiple terms with the same language code are provided, only the last one will be retained.
16
 * Empty terms are skipped and treated as non-existing.
17
 *
18
 * @since 0.7.3
19
 *
20
 * @licence GNU GPL v2+
21
 * @author Jeroen De Dauw < [email protected] >
22
 */
23
class TermList implements Countable, IteratorAggregate, Comparable {
24
25
	/**
26
	 * @var Term[]
27
	 */
28
	private $terms = array();
29
30
	/**
31
	 * @param Term[] $terms
32
	 * @throws InvalidArgumentException
33
	 */
34
	public function __construct( array $terms = array() ) {
35
		foreach ( $terms as $term ) {
36
			if ( !( $term instanceof Term ) ) {
37
				throw new InvalidArgumentException( 'Every element in $terms must be an instance of Term' );
38
			}
39
40
			$this->setTerm( $term );
41
		}
42
	}
43
44
	/**
45
	 * @see Countable::count
46
	 * @return int
47
	 */
48
	public function count() {
49
		return count( $this->terms );
50
	}
51
52
	/**
53
	 * Returns an array with language codes as keys and the term text as values.
54
	 *
55
	 * @return string[]
56
	 */
57
	public function toTextArray() {
58
		$array = array();
59
60
		foreach ( $this->terms as $term ) {
61
			$array[$term->getLanguageCode()] = $term->getText();
62
		}
63
64
		return $array;
65
	}
66
67
	/**
68
	 * @see IteratorAggregate::getIterator
69
	 * @return Traversable|Term[]
70
	 */
71
	public function getIterator() {
72
		return new ArrayIterator( $this->terms );
73
	}
74
75
	/**
76
	 * @param string $languageCode
77
	 *
78
	 * @return Term
79
	 * @throws InvalidArgumentException
80
	 * @throws OutOfBoundsException
81
	 */
82
	public function getByLanguage( $languageCode ) {
83
		$this->assertIsLanguageCode( $languageCode );
84
85
		if ( !array_key_exists( $languageCode, $this->terms ) ) {
86
			throw new OutOfBoundsException( 'Term with languageCode "' . $languageCode . '" not found' );
87
		}
88
89
		return $this->terms[$languageCode];
90
	}
91
92
	/**
93
	 * @since 2.5
94
	 *
95
	 * @param string[] $languageCodes
96
	 *
97
	 * @return self
98
	 */
99
	public function getWithLanguages( array $languageCodes ) {
100
		return new self( array_intersect_key( $this->terms, array_flip( $languageCodes ) ) );
101
	}
102
103
	public function removeByLanguage( $languageCode ) {
104
		$this->assertIsLanguageCode( $languageCode );
105
		unset( $this->terms[$languageCode] );
106
	}
107
108
	public function hasTermForLanguage( $languageCode ) {
109
		$this->assertIsLanguageCode( $languageCode );
110
		return array_key_exists( $languageCode, $this->terms );
111
	}
112
113
	private function assertIsLanguageCode( $languageCode ) {
114
		if ( !is_string( $languageCode ) || $languageCode === '' ) {
115
			throw new InvalidArgumentException( '$languageCode must be a non-empty string' );
116
		}
117
	}
118
119
	/**
120
	 * Replaces non-empty or removes empty terms.
121
	 *
122
	 * @param Term $term
123
	 */
124
	public function setTerm( Term $term ) {
125
		if ( $term->getText() === '' ) {
126
			unset( $this->terms[$term->getLanguageCode()] );
127
		}
128
		else {
129
			$this->terms[$term->getLanguageCode()] = $term;
130
		}
131
	}
132
133
	/**
134
	 * @since 0.8
135
	 *
136
	 * @param string $languageCode
137
	 * @param string $termText
138
	 */
139
	public function setTextForLanguage( $languageCode, $termText ) {
140
		$this->setTerm( new Term( $languageCode, $termText ) );
141
	}
142
143
	/**
144
	 * @see Comparable::equals
145
	 *
146
	 * @since 0.7.4
147
	 *
148
	 * @param mixed $target
149
	 *
150
	 * @return bool
151
	 */
152
	public function equals( $target ) {
153
		if ( $this === $target ) {
154
			return true;
155
		}
156
157
		if ( !( $target instanceof self )
158
			|| $this->count() !== $target->count()
159
		) {
160
			return false;
161
		}
162
163
		foreach ( $this->terms as $term ) {
164
			if ( !$target->hasTerm( $term ) ) {
165
				return false;
166
			}
167
		}
168
169
		return true;
170
	}
171
172
	/**
173
	 * @since 2.4.0
174
	 *
175
	 * @return bool
176
	 */
177
	public function isEmpty() {
178
		return empty( $this->terms );
179
	}
180
181
	/**
182
	 * @since 0.7.4
183
	 *
184
	 * @param Term $term
185
	 *
186
	 * @return boolean
187
	 */
188
	public function hasTerm( Term $term ) {
189
		return array_key_exists( $term->getLanguageCode(), $this->terms )
190
			&& $this->terms[$term->getLanguageCode()]->equals( $term );
191
	}
192
193
	/**
194
	 * Removes all terms from this list.
195
	 *
196
	 * @since 5.1
197
	 */
198
	public function clear() {
199
		$this->terms = array();
200
	}
201
202
}
203