AliasGroupListPatcher::patchAliasGroup()   B
last analyzed

Complexity

Conditions 8
Paths 7

Size

Total Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

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