Completed
Push — master ( f552f8...7247aa )
by
unknown
03:16
created

AliasGroupListPatcher::getPatchedAliases()   C

Complexity

Conditions 7
Paths 7

Size

Total Lines 32
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 32
rs 6.7272
cc 7
eloc 20
nc 7
nop 2
1
<?php
2
3
namespace Wikibase\DataModel\Services\Diff\Internal;
4
5
use Diff\DiffOp\Diff\Diff;
6
use Diff\DiffOp\DiffOp;
7
use Diff\DiffOp\DiffOpAdd;
8
use Diff\DiffOp\DiffOpChange;
9
use Diff\DiffOp\DiffOpRemove;
10
use Diff\Patcher\MapPatcher;
11
use Diff\Patcher\PatcherException;
12
use Wikibase\DataModel\Term\AliasGroupList;
13
14
/**
15
 * Package private.
16
 *
17
 * @since 3.6
18
 *
19
 * @license GPL-2.0+
20
 * @author Jeroen De Dauw < [email protected] >
21
 * @author Thiemo Mättig
22
 */
23
class AliasGroupListPatcher {
24
25
	/**
26
	 * @since 3.6
27
	 *
28
	 * @param AliasGroupList $groups
29
	 * @param Diff $patch
30
	 *
31
	 * @throws PatcherException
32
	 */
33
	public function patchAliasGroupList( AliasGroupList $groups, Diff $patch ) {
34
		foreach ( $patch as $lang => $diffOp ) {
35
			$this->patchAliasGroup( $groups, $lang, $diffOp );
36
		}
37
	}
38
39
	/**
40
	 * @see MapPatcher
41
	 *
42
	 * @param AliasGroupList $groups
43
	 * @param string $lang
44
	 * @param DiffOp $diffOp
45
	 *
46
	 * @throws PatcherException
47
	 */
48
	private function patchAliasGroup( AliasGroupList $groups, $lang, DiffOp $diffOp ) {
49
		$hasLang = $groups->hasGroupForLanguage( $lang );
50
51
		switch ( true ) {
52
			case $diffOp instanceof DiffOpAdd:
53
				/** @var $diffOp DiffOpAdd */
54
				if ( !$hasLang ) {
55
					$groups->setAliasesForLanguage( $lang, $diffOp->getNewValue() );
56
				}
57
				break;
58
59
			case $diffOp instanceof DiffOpChange:
60
				/** @var $diffOp DiffOpChange */
61
				$this->applyAliasGroupChange( $groups, $lang, $diffOp );
62
				break;
63
64
			case $diffOp instanceof DiffOpRemove:
65
				/** @var $diffOp DiffOpRemove */
66
				if ( $hasLang
67
					&& $groups->getByLanguage( $lang )->getAliases() === $diffOp->getOldValue()
68
				) {
69
					$groups->removeByLanguage( $lang );
70
				}
71
				break;
72
73
			case $diffOp instanceof Diff:
74
				/** @var $diffOp Diff */
75
				$this->applyAliasGroupDiff( $groups, $lang, $diffOp );
76
				break;
77
78
			default:
79
				throw new PatcherException( 'Invalid aliases diff' );
80
		}
81
	}
82
83
	/**
84
	 * @param AliasGroupList $groups
85
	 * @param string $lang
86
	 * @param DiffOpChange $patch
87
	 */
88
	private function applyAliasGroupChange( AliasGroupList $groups, $lang, DiffOpChange $patch ) {
89
		if ( $groups->hasGroupForLanguage( $lang )
90
			&& $groups->getByLanguage( $lang )->getAliases() === $patch->getOldValue()
91
		) {
92
			$groups->setAliasesForLanguage( $lang, $patch->getNewValue() );
93
		}
94
	}
95
96
	/**
97
	 * @param AliasGroupList $groups
98
	 * @param string $lang
99
	 * @param Diff $patch
100
	 */
101
	private function applyAliasGroupDiff( AliasGroupList $groups, $lang, Diff $patch ) {
102
		$hasLang = $groups->hasGroupForLanguage( $lang );
103
104
		if ( $hasLang || !$this->containsOperationsOnOldValues( $patch ) ) {
105
			$aliases = $hasLang ? $groups->getByLanguage( $lang )->getAliases() : array();
106
			$aliases = $this->getPatchedAliases( $aliases, $patch );
107
			$groups->setAliasesForLanguage( $lang, $aliases );
108
		}
109
	}
110
111
	/**
112
	 * @param Diff $diff
113
	 *
114
	 * @return bool
115
	 */
116
	private function containsOperationsOnOldValues( Diff $diff ) {
117
		return $diff->getChanges() !== array()
118
			|| $diff->getRemovals() !== array();
119
	}
120
121
	/**
122
	 * @see ListPatcher
123
	 *
124
	 * @param string[] $aliases
125
	 * @param Diff $patch
126
	 *
127
	 * @throws PatcherException
128
	 * @return string[]
129
	 */
130
	private function getPatchedAliases( array $aliases, Diff $patch ) {
131
		foreach ( $patch as $diffOp ) {
132
			switch ( true ) {
133
				case $diffOp instanceof DiffOpAdd:
134
					/** @var $diffOp DiffOpAdd */
135
					$aliases[] = $diffOp->getNewValue();
136
					break;
137
138
				case $diffOp instanceof DiffOpChange:
139
					/** @var $diffOp DiffOpChange */
140
					$key = array_search( $diffOp->getOldValue(), $aliases, true );
141
					if ( $key !== false ) {
142
						unset( $aliases[$key] );
143
						$aliases[] = $diffOp->getNewValue();
144
					}
145
					break;
146
147
				case $diffOp instanceof DiffOpRemove:
148
					/** @var $diffOp DiffOpRemove */
149
					$key = array_search( $diffOp->getOldValue(), $aliases, true );
150
					if ( $key !== false ) {
151
						unset( $aliases[$key] );
152
					}
153
					break;
154
155
				default:
156
					throw new PatcherException( 'Invalid aliases diff' );
157
			}
158
		}
159
160
		return $aliases;
161
	}
162
163
}
164