Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
96.00% |
48 / 50 |
|
87.50% |
14 / 16 |
CRAP | |
0.00% |
0 / 1 |
FormSet | |
96.00% |
48 / 50 |
|
87.50% |
14 / 16 |
27 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
3 | |||
toArray | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
toArrayUnordered | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
sortForms | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
2 | |||
count | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
maxFormIdNumber | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
2 | |||
add | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
2 | |||
remove | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
put | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
getById | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
copy | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
__clone | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
2 | |||
isEmpty | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
equals | |
80.00% |
4 / 5 |
|
0.00% |
0 / 1 |
3.07 | |||
hasFormWithId | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
sameForms | |
83.33% |
5 / 6 |
|
0.00% |
0 / 1 |
4.07 |
1 | <?php |
2 | |
3 | namespace Wikibase\Lexeme\Domain\Model; |
4 | |
5 | use Countable; |
6 | use Wikibase\Lexeme\Domain\Model\Exceptions\ConflictException; |
7 | |
8 | /** |
9 | * Set of Forms in which uniqueness of a Form is controlled by it's ID. |
10 | * Supposed to be used only inside the Lexeme class |
11 | * |
12 | * @license GPL-2.0-or-later |
13 | */ |
14 | class FormSet implements Countable { |
15 | |
16 | /** |
17 | * @var Form[] indexed by serialization of FormId |
18 | */ |
19 | private $forms = []; |
20 | |
21 | /** |
22 | * @param Form[] $forms |
23 | */ |
24 | public function __construct( array $forms = [] ) { |
25 | foreach ( $forms as $form ) { |
26 | if ( !$form instanceof Form ) { |
27 | throw new \InvalidArgumentException( '$forms must be an array of Forms' ); |
28 | } |
29 | |
30 | $this->add( $form ); |
31 | } |
32 | } |
33 | |
34 | /** |
35 | * @return Form[] |
36 | */ |
37 | public function toArray() { |
38 | $forms = $this->sortForms( $this->forms ); |
39 | return array_values( $forms ); |
40 | } |
41 | |
42 | /** |
43 | * Return the individual Forms in arbitrary order. |
44 | * |
45 | * Only use this method if the order is certainly insignificant, |
46 | * e.g. because the Forms will be summarized or reduced in some way. |
47 | * Otherwise, use {@link toArray()}. |
48 | * |
49 | * @return Form[] |
50 | */ |
51 | public function toArrayUnordered(): array { |
52 | return array_values( $this->forms ); |
53 | } |
54 | |
55 | /** |
56 | * @param Form[] $forms |
57 | * @return array sorted array mapping numeric id to the form |
58 | */ |
59 | private function sortForms( array $forms ) { |
60 | $sortedForms = []; |
61 | foreach ( $forms as $form ) { |
62 | $formIdPart = explode( '-', $form->getId()->getSerialization(), 2 )[1]; |
63 | $formIdNumber = (int)substr( $formIdPart, 1 ); |
64 | $sortedForms[$formIdNumber] = $form; |
65 | } |
66 | ksort( $sortedForms ); |
67 | |
68 | return $sortedForms; |
69 | } |
70 | |
71 | /** |
72 | * @return int |
73 | */ |
74 | public function count(): int { |
75 | return count( $this->forms ); |
76 | } |
77 | |
78 | /** |
79 | * @return int |
80 | */ |
81 | public function maxFormIdNumber() { |
82 | if ( !$this->forms ) { |
83 | return 0; |
84 | } |
85 | |
86 | $numbers = array_map( static function ( $formId ) { |
87 | [ , $formId ] = explode( '-', $formId, 2 ); |
88 | return (int)substr( $formId, 1 ); |
89 | }, array_keys( $this->forms ) ); |
90 | return max( $numbers ); |
91 | } |
92 | |
93 | public function add( Form $form ) { |
94 | $formId = $form->getId()->getSerialization(); |
95 | if ( isset( $this->forms[$formId] ) ) { |
96 | throw new ConflictException( |
97 | 'At least two forms with the same ID were provided: `' . $formId . '`' |
98 | ); |
99 | } |
100 | |
101 | $this->forms[$formId] = $form; |
102 | } |
103 | |
104 | public function remove( FormId $formId ) { |
105 | unset( $this->forms[$formId->getSerialization()] ); |
106 | } |
107 | |
108 | /** |
109 | * Replace the form identified by $form->getId() with the given one or add it |
110 | * |
111 | * @param Form $form |
112 | */ |
113 | public function put( Form $form ) { |
114 | $this->remove( $form->getId() ); |
115 | $this->add( $form ); |
116 | } |
117 | |
118 | /** |
119 | * @param FormId $formId |
120 | * |
121 | * @return Form|null |
122 | */ |
123 | public function getById( FormId $formId ) { |
124 | return $this->forms[$formId->getSerialization()] ?? null; |
125 | } |
126 | |
127 | /** |
128 | * @return self |
129 | */ |
130 | public function copy() { |
131 | return clone $this; |
132 | } |
133 | |
134 | /** |
135 | * @see http://php.net/manual/en/language.oop5.cloning.php |
136 | */ |
137 | public function __clone() { |
138 | $clonedForms = []; |
139 | foreach ( $this->forms as $key => $form ) { |
140 | $clonedForms[$key] = clone $form; |
141 | } |
142 | $this->forms = $clonedForms; |
143 | } |
144 | |
145 | /** |
146 | * @return bool |
147 | */ |
148 | public function isEmpty() { |
149 | return !$this->forms; |
150 | } |
151 | |
152 | public function equals( $other ) { |
153 | if ( $this === $other ) { |
154 | return true; |
155 | } |
156 | |
157 | if ( !( $other instanceof self ) ) { |
158 | return false; |
159 | } |
160 | |
161 | return $this->sameForms( $other ); |
162 | } |
163 | |
164 | /** |
165 | * @param FormId $formId |
166 | * @return bool |
167 | */ |
168 | public function hasFormWithId( FormId $formId ) { |
169 | return $this->getById( $formId ) !== null; |
170 | } |
171 | |
172 | /** |
173 | * @return bool |
174 | */ |
175 | private function sameForms( FormSet $other ) { |
176 | if ( $this->count() !== $other->count() ) { |
177 | return false; |
178 | } |
179 | |
180 | foreach ( $this->forms as $form ) { |
181 | if ( !$form->equals( $other->getById( $form->getId() ) ) ) { |
182 | return false; |
183 | } |
184 | } |
185 | |
186 | return true; |
187 | } |
188 | |
189 | } |