Completed
Push — master ( 31dda1...f33739 )
by
unknown
03:00
created

FingerprintPatcher   B

Complexity

Total Complexity 38

Size/Duplication

Total Lines 176
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 11

Test Coverage

Coverage 100%

Importance

Changes 3
Bugs 0 Features 1
Metric Value
wmc 38
c 3
b 0
f 1
lcom 1
cbo 11
dl 0
loc 176
ccs 40
cts 40
cp 1
rs 8.3999

9 Methods

Rating   Name   Duplication   Size   Complexity  
A patchFingerprint() 0 6 1
A patchTermList() 0 5 2
C patchTerm() 0 23 9
A patchAliasGroupList() 0 5 2
B patchAliasGroup() 0 21 8
A applyAliasGroupChange() 0 7 3
A applyAliasGroupDiff() 0 9 4
A containsOperationsOnOldValues() 0 4 2
C getPatchedAliases() 0 24 7
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
		if ( $diffOp instanceof DiffOpAdd ) {
65 4
			if ( !$hasLang ) {
66
				$terms->setTextForLanguage( $lang, $diffOp->getNewValue() );
67 4
			}
68
		} elseif ( $diffOp instanceof DiffOpChange ) {
69
			if ( $hasLang
70 4
				&& $terms->getByLanguage( $lang )->getText() === $diffOp->getOldValue()
71 4
			) {
72 4
				$terms->setTextForLanguage( $lang, $diffOp->getNewValue() );
73
			}
74 4
		} elseif ( $diffOp instanceof DiffOpRemove ) {
75
			if ( $hasLang
76 4
				&& $terms->getByLanguage( $lang )->getText() === $diffOp->getOldValue()
77 4
			) {
78
				$terms->removeByLanguage( $lang );
79 4
			}
80 4
		} else {
81
			throw new PatcherException( 'Invalid terms diff' );
82
		}
83
	}
84
85 4
	/**
86 4
	 * @param AliasGroupList $groups
87 4
	 * @param Diff $patch
88
	 *
89 4
	 * @throws PatcherException
90
	 */
91
	private function patchAliasGroupList( AliasGroupList $groups, Diff $patch ) {
92
		foreach ( $patch as $lang => $diffOp ) {
93
			$this->patchAliasGroup( $groups, $lang, $diffOp );
94
		}
95
	}
96
97 4
	/**
98 4
	 * @see MapPatcher
99
	 *
100 4
	 * @param AliasGroupList $groups
101 4
	 * @param string $lang
102 4
	 * @param DiffOp $diffOp
103
	 *
104 4
	 * @throws PatcherException
105
	 */
106
	private function patchAliasGroup( AliasGroupList $groups, $lang, DiffOp $diffOp ) {
107
		$hasLang = $groups->hasGroupForLanguage( $lang );
108
109
		if ( $diffOp instanceof DiffOpAdd ) {
110
			if ( !$hasLang ) {
111
				$groups->setAliasesForLanguage( $lang, $diffOp->getNewValue() );
112
			}
113
		} elseif ( $diffOp instanceof DiffOpChange ) {
114
			$this->applyAliasGroupChange( $groups, $lang, $diffOp );
115
		} elseif ( $diffOp instanceof DiffOpRemove ) {
116
			if ( $hasLang
117
				&& $groups->getByLanguage( $lang )->getAliases() === $diffOp->getOldValue()
118
			) {
119
				$groups->removeByLanguage( $lang );
120
			}
121
		} elseif ( $diffOp instanceof Diff ) {
122
			$this->applyAliasGroupDiff( $groups, $lang, $diffOp );
123
		} else {
124
			throw new PatcherException( 'Invalid aliases diff' );
125
		}
126
	}
127
128
	/**
129
	 * @param AliasGroupList $groups
130
	 * @param string $lang
131
	 * @param DiffOpChange $patch
132
	 */
133
	private function applyAliasGroupChange( AliasGroupList $groups, $lang, DiffOpChange $patch ) {
134
		if ( $groups->hasGroupForLanguage( $lang )
135
			&& $groups->getByLanguage( $lang )->getAliases() === $patch->getOldValue()
136
		) {
137
			$groups->setAliasesForLanguage( $lang, $patch->getNewValue() );
138
		}
139
	}
140
141
	/**
142
	 * @param AliasGroupList $groups
143
	 * @param string $lang
144
	 * @param Diff $patch
145
	 */
146
	private function applyAliasGroupDiff( AliasGroupList $groups, $lang, Diff $patch ) {
147
		$hasLang = $groups->hasGroupForLanguage( $lang );
148
149
		if ( $hasLang || !$this->containsOperationsOnOldValues( $patch ) ) {
150
			$aliases = $hasLang ? $groups->getByLanguage( $lang )->getAliases() : array();
151
			$aliases = $this->getPatchedAliases( $aliases, $patch );
152
			$groups->setAliasesForLanguage( $lang, $aliases );
153
		}
154
	}
155
156
	/**
157
	 * @param Diff $diff
158
	 *
159
	 * @return bool
160
	 */
161
	private function containsOperationsOnOldValues( Diff $diff ) {
162
		return $diff->getChanges() !== array()
163
			|| $diff->getRemovals() !== array();
164
	}
165
166
	/**
167
	 * @see ListPatcher
168
	 *
169
	 * @param string[] $aliases
170
	 * @param Diff $patch
171
	 *
172
	 * @throws PatcherException
173
	 * @return string[]
174
	 */
175
	private function getPatchedAliases( array $aliases, Diff $patch ) {
176
		foreach ( $patch as $diffOp ) {
177
			if ( $diffOp instanceof DiffOpAdd ) {
178
				$aliases[] = $diffOp->getNewValue();
179
			} elseif ( $diffOp instanceof DiffOpChange ) {
180
				$key = array_search( $diffOp->getOldValue(), $aliases, true );
181
182
				if ( $key !== false ) {
183
					unset( $aliases[$key] );
184
					$aliases[] = $diffOp->getNewValue();
185
				}
186
			} elseif ( $diffOp instanceof DiffOpRemove ) {
187
				$key = array_search( $diffOp->getOldValue(), $aliases, true );
188
189
				if ( $key !== false ) {
190
					unset( $aliases[$key] );
191
				}
192
			} else {
193
				throw new PatcherException( 'Invalid aliases diff' );
194
			}
195
		}
196
197
		return $aliases;
198
	}
199
200
}
201