Completed
Push — master ( 8d5611...640432 )
by
unknown
02:53
created

FingerprintPatcher::patchAliasGroup()   C

Complexity

Conditions 8
Paths 7

Size

Total Lines 33
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 72

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 33
ccs 0
cts 0
cp 0
rs 5.3846
cc 8
eloc 20
nc 7
nop 3
crap 72
1
<?php
2
3
namespace Wikibase\DataModel\Services\Diff\Internal;
4
5
use Diff\DiffOp\AtomicDiffOp;
6
use Diff\DiffOp\Diff\Diff;
7
use Diff\DiffOp\DiffOp;
8
use Diff\DiffOp\DiffOpAdd;
9
use Diff\DiffOp\DiffOpChange;
10
use Diff\DiffOp\DiffOpRemove;
11
use Diff\Patcher\MapPatcher;
12
use Diff\Patcher\PatcherException;
13
use Wikibase\DataModel\Services\Diff\EntityDiff;
14
use Wikibase\DataModel\Term\AliasGroupList;
15
use Wikibase\DataModel\Term\Fingerprint;
16
use Wikibase\DataModel\Term\TermList;
17
18
/**
19
 * Package private.
20
 *
21
 * @license GPL-2.0+
22
 * @author Jeroen De Dauw < [email protected] >
23
 * @author Thiemo Mättig
24
 */
25
class FingerprintPatcher {
26
27 4
	/**
28 4
	 * @param Fingerprint $fingerprint
29 4
	 * @param EntityDiff $patch
30
	 *
31
	 * @throws PatcherException
32
	 */
33
	public function patchFingerprint( Fingerprint $fingerprint, EntityDiff $patch ) {
34
		$this->patchTermList( $fingerprint->getLabels(), $patch->getLabelsDiff() );
35
		$this->patchTermList( $fingerprint->getDescriptions(), $patch->getDescriptionsDiff() );
36
37 4
		$this->patchAliasGroupList( $fingerprint->getAliasGroups(), $patch->getAliasesDiff() );
38 4
	}
39 4
40 4
	/**
41 4
	 * @param TermList $terms
42
	 * @param Diff $patch
43 4
	 *
44
	 * @throws PatcherException
45 4
	 */
46 4
	private function patchTermList( TermList $terms, Diff $patch ) {
47 4
		foreach ( $patch as $lang => $diffOp ) {
48 4
			$this->patchTerm( $terms, $lang, $diffOp );
49
		}
50 4
	}
51
52 4
	/**
53 4
	 * @see MapPatcher
54
	 *
55
	 * @param TermList $terms
56
	 * @param string $lang
57
	 * @param AtomicDiffOp $diffOp
58
	 *
59
	 * @throws PatcherException
60 4
	 */
61 4
	private function patchTerm( TermList $terms, $lang, AtomicDiffOp $diffOp ) {
62
		$hasLang = $terms->hasTermForLanguage( $lang );
63 4
64 4
		switch ( true ) {
65 4
			case $diffOp instanceof DiffOpAdd:
66
				/** @var DiffOpAdd $diffOp */
67 4
				if ( !$hasLang ) {
68
					$terms->setTextForLanguage( $lang, $diffOp->getNewValue() );
69
				}
70 4
				break;
71 4
72 4
			case $diffOp instanceof DiffOpChange:
73
				/** @var DiffOpChange $diffOp */
74 4
				if ( $hasLang
75
					&& $terms->getByLanguage( $lang )->getText() === $diffOp->getOldValue()
76 4
				) {
77 4
					$terms->setTextForLanguage( $lang, $diffOp->getNewValue() );
78
				}
79 4
				break;
80 4
81
			case $diffOp instanceof DiffOpRemove:
82
				/** @var DiffOpRemove $diffOp */
83
				if ( $hasLang
84
					&& $terms->getByLanguage( $lang )->getText() === $diffOp->getOldValue()
85 4
				) {
86 4
					$terms->removeByLanguage( $lang );
87 4
				}
88
				break;
89 4
90
			default:
91
				throw new PatcherException( 'Invalid terms diff' );
92
		}
93
	}
94
95
	/**
96
	 * @param AliasGroupList $groups
97 4
	 * @param Diff $patch
98 4
	 *
99
	 * @throws PatcherException
100 4
	 */
101 4
	private function patchAliasGroupList( AliasGroupList $groups, Diff $patch ) {
102 4
		foreach ( $patch as $lang => $diffOp ) {
103
			$this->patchAliasGroup( $groups, $lang, $diffOp );
104 4
		}
105
	}
106
107
	/**
108
	 * @see MapPatcher
109
	 *
110
	 * @param AliasGroupList $groups
111
	 * @param string $lang
112
	 * @param DiffOp $diffOp
113
	 *
114
	 * @throws PatcherException
115
	 */
116
	private function patchAliasGroup( AliasGroupList $groups, $lang, DiffOp $diffOp ) {
117
		$hasLang = $groups->hasGroupForLanguage( $lang );
118
119
		switch ( true ) {
120
			case $diffOp instanceof DiffOpAdd:
121
				/** @var DiffOpAdd $diffOp */
122
				if ( !$hasLang ) {
123
					$groups->setAliasesForLanguage( $lang, $diffOp->getNewValue() );
124
				}
125
				break;
126
127
			case $diffOp instanceof DiffOpChange:
128
				/** @var DiffOpChange $diffOp */
129
				$this->applyAliasGroupChange( $groups, $lang, $diffOp );
130
				break;
131
132
			case $diffOp instanceof DiffOpRemove:
133
				/** @var DiffOpRemove $diffOp */
134
				if ( $hasLang
135
					&& $groups->getByLanguage( $lang )->getAliases() === $diffOp->getOldValue()
136
				) {
137
					$groups->removeByLanguage( $lang );
138
				}
139
				break;
140
141
			case $diffOp instanceof Diff:
142
				$this->applyAliasGroupDiff( $groups, $lang, $diffOp );
143
				break;
144
145
			default:
146
				throw new PatcherException( 'Invalid aliases diff' );
147
		}
148
	}
149
150
	/**
151
	 * @param AliasGroupList $groups
152
	 * @param string $lang
153
	 * @param DiffOpChange $patch
154
	 */
155
	private function applyAliasGroupChange( AliasGroupList $groups, $lang, DiffOpChange $patch ) {
156
		if ( $groups->hasGroupForLanguage( $lang )
157
			&& $groups->getByLanguage( $lang )->getAliases() === $patch->getOldValue()
158
		) {
159
			$groups->setAliasesForLanguage( $lang, $patch->getNewValue() );
160
		}
161
	}
162
163
	/**
164
	 * @param AliasGroupList $groups
165
	 * @param string $lang
166
	 * @param Diff $patch
167
	 */
168
	private function applyAliasGroupDiff( AliasGroupList $groups, $lang, Diff $patch ) {
169
		$hasLang = $groups->hasGroupForLanguage( $lang );
170
171
		if ( $hasLang || !$this->containsOperationsOnOldValues( $patch ) ) {
172
			$aliases = $hasLang ? $groups->getByLanguage( $lang )->getAliases() : array();
173
			$aliases = $this->getPatchedAliases( $aliases, $patch );
174
			$groups->setAliasesForLanguage( $lang, $aliases );
175
		}
176
	}
177
178
	/**
179
	 * @param Diff $diff
180
	 *
181
	 * @return bool
182
	 */
183
	private function containsOperationsOnOldValues( Diff $diff ) {
184
		return $diff->getChanges() !== array()
185
			|| $diff->getRemovals() !== array();
186
	}
187
188
	/**
189
	 * @see ListPatcher
190
	 *
191
	 * @param string[] $aliases
192
	 * @param Diff $patch
193
	 *
194
	 * @throws PatcherException
195
	 * @return string[]
196
	 */
197
	private function getPatchedAliases( array $aliases, Diff $patch ) {
198
		/** @var DiffOp $diffOp */
199
		foreach ( $patch as $diffOp ) {
200
			switch ( true ) {
201
				case $diffOp instanceof DiffOpAdd:
202
					/** @var DiffOpAdd $diffOp */
203
					$aliases[] = $diffOp->getNewValue();
204
					break;
205
206
				case $diffOp instanceof DiffOpChange:
207
					/** @var DiffOpChange $diffOp */
208
					$key = array_search( $diffOp->getOldValue(), $aliases, true );
209
210
					if ( $key !== false ) {
211
						unset( $aliases[$key] );
212
						$aliases[] = $diffOp->getNewValue();
213
					}
214
					break;
215
216
				case $diffOp instanceof DiffOpRemove:
217
					/** @var DiffOpRemove $diffOp */
218
					$key = array_search( $diffOp->getOldValue(), $aliases, true );
219
220
					if ( $key !== false ) {
221
						unset( $aliases[$key] );
222
					}
223
					break;
224
225
				default:
226
					throw new PatcherException( 'Invalid aliases diff' );
227
			}
228
		}
229
230
		return $aliases;
231
	}
232
233
}
234