EntityDiff::fixSubstructureDiff()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 7.1753

Importance

Changes 0
Metric Value
dl 0
loc 22
ccs 5
cts 12
cp 0.4167
rs 9.568
c 0
b 0
f 0
cc 4
nc 4
nop 2
crap 7.1753
1
<?php
2
3
namespace Wikibase\DataModel\Services\Diff;
4
5
use Diff\DiffOp\Diff\Diff;
6
use Diff\DiffOp\DiffOp;
7
use Wikibase\DataModel\Entity\Item;
8
9
/**
10
 * Represents a diff between two entities.
11
 *
12
 * @since 1.0
13
 *
14
 * @license GPL-2.0-or-later
15
 * @author Jeroen De Dauw < [email protected] >
16
 */
17
class EntityDiff extends Diff {
18
19
	/**
20
	 * @param string $entityType
21
	 * @param DiffOp[] $operations
22
	 *
23
	 * @return self
24
	 */
25
	public static function newForType( $entityType, array $operations = [] ) {
26
		if ( $entityType === Item::ENTITY_TYPE ) {
27
			return new ItemDiff( $operations );
28
		} else {
29
			return new self( $operations );
30
		}
31
	}
32
33
	/**
34
	 * @param DiffOp[] $operations
35
	 */
36 10
	public function __construct( array $operations = [] ) {
37 10
		$this->fixSubstructureDiff( $operations, 'aliases' );
38 10
		$this->fixSubstructureDiff( $operations, 'label' );
39 10
		$this->fixSubstructureDiff( $operations, 'description' );
40 10
		$this->fixSubstructureDiff( $operations, 'claim' );
41
42 10
		parent::__construct( $operations, true );
43 10
	}
44
45
	/**
46
	 * Checks the type of a substructure diff, and replaces it if needed.
47
	 * This is needed for backwards compatibility with old versions of
48
	 * MapDiffer: As of commit ff65735a125e, MapDiffer may generate atomic diffs for
49
	 * substructures even in recursive mode (bug 51363).
50
	 *
51
	 * @param array &$operations All change ops; This is a reference, so the
52
	 *        substructure diff can be replaced if need be.
53
	 * @param string $key The key of the substructure
54
	 */
55 10
	protected function fixSubstructureDiff( array &$operations, $key ) {
56 10
		if ( !isset( $operations[$key] ) ) {
57 9
			return;
58
		}
59
60 9
		if ( !( $operations[$key] instanceof Diff ) ) {
61
			$warning = "Invalid substructure diff for key $key: " . get_class( $operations[$key] );
62
63
			if ( function_exists( 'wfLogWarning' ) ) {
64
				wfLogWarning( $warning );
65
			} else {
66
				trigger_error( $warning, E_USER_WARNING );
67
			}
68
69
			// We could look into the atomic diff, see if it uses arrays as values,
70
			// and construct a new Diff according to these values. But since the
71
			// actual old behavior of MapDiffer didn't cause that to happen, let's
72
			// just use an empty diff, which is what MapDiffer should have returned
73
			// in the actual broken case mentioned in bug 51363.
74
			$operations[$key] = new Diff( [], true );
75
		}
76 9
	}
77
78
	/**
79
	 * FIXME: Not all entities do have aliases!
80
	 *
81
	 * Returns a Diff object with the aliases differences.
82
	 *
83 12
	 * @return Diff
84 12
	 */
85
	public function getAliasesDiff() {
86
		return isset( $this['aliases'] ) ? $this['aliases'] : new Diff( [], true );
87
	}
88
89
	/**
90
	 * FIXME: Not all entities do have labels!
91
	 *
92 14
	 * Returns a Diff object with the labels differences.
93 14
	 *
94
	 * @return Diff
95
	 */
96
	public function getLabelsDiff() {
97
		return isset( $this['label'] ) ? $this['label'] : new Diff( [], true );
98
	}
99
100
	/**
101 13
	 * FIXME: Not all entities do have descriptions!
102 13
	 *
103
	 * Returns a Diff object with the descriptions differences.
104
	 *
105
	 * @return Diff
106
	 */
107
	public function getDescriptionsDiff() {
108
		return isset( $this['description'] ) ? $this['description'] : new Diff( [], true );
109
	}
110 11
111 11
	/**
112
	 * FIXME: Not all entities do have claims a.k.a. statements!
113
	 *
114
	 * Returns a Diff object with the claim differences.
115
	 *
116
	 * @return Diff
117
	 */
118
	public function getClaimsDiff() {
119 10
		return isset( $this['claim'] ) ? $this['claim'] : new Diff( [], true );
120 10
	}
121 10
122 10
	/**
123 10
	 * Returns if there are any changes (equivalent to: any differences between the entities).
124
	 *
125
	 * @return bool
126
	 */
127
	public function isEmpty(): bool {
128
		return $this->getLabelsDiff()->isEmpty()
129
			&& $this->getDescriptionsDiff()->isEmpty()
130
			&& $this->getAliasesDiff()->isEmpty()
131
			&& $this->getClaimsDiff()->isEmpty();
132
	}
133
134
	/**
135
	 * @see DiffOp::getType
136
	 *
137
	 * @return string
138
	 */
139
	public function getType(): string {
140
		return 'diff/entity';
141
	}
142
143
}
144