Passed
Push — itemIdParser ( 9ff00f...2c5f7a )
by no
03:11
created

StatementDeserializer::assertCanDeserialize()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 9
rs 9.6666
cc 3
eloc 5
nc 3
nop 1
1
<?php
2
3
namespace Wikibase\DataModel\Deserializers;
4
5
use Deserializers\Deserializer;
6
use Deserializers\DispatchableDeserializer;
7
use Deserializers\Exceptions\DeserializationException;
8
use Deserializers\Exceptions\InvalidAttributeException;
9
use Deserializers\Exceptions\MissingAttributeException;
10
use Deserializers\Exceptions\MissingTypeException;
11
use Deserializers\Exceptions\UnsupportedTypeException;
12
use Wikibase\DataModel\ReferenceList;
13
use Wikibase\DataModel\Snak\Snak;
14
use Wikibase\DataModel\Snak\SnakList;
15
use Wikibase\DataModel\Statement\Statement;
16
17
/**
18
 * Package private
19
 *
20
 * @license GPL-2.0+
21
 * @author Thomas Pellissier Tanon
22
 */
23
class StatementDeserializer implements DispatchableDeserializer {
24
25
	private $rankIds = array(
26
		'deprecated' => Statement::RANK_DEPRECATED,
27
		'normal' => Statement::RANK_NORMAL,
28
		'preferred' => Statement::RANK_PREFERRED
29
	);
30
31
	/**
32
	 * @var Deserializer
33
	 */
34
	private $snakDeserializer;
35
36
	/**
37
	 * @var Deserializer
38
	 */
39
	private $snaksDeserializer;
40
41
	/**
42
	 * @var Deserializer
43
	 */
44
	private $referencesDeserializer;
45
46
	public function __construct(
47
		Deserializer $snakDeserializer,
48
		Deserializer $snaksDeserializer,
49
		Deserializer $referencesDeserializer
50
	) {
51
		$this->snakDeserializer = $snakDeserializer;
52
		$this->snaksDeserializer = $snaksDeserializer;
53
		$this->referencesDeserializer = $referencesDeserializer;
54
	}
55
56
	/**
57
	 * @see DispatchableDeserializer::isDeserializerFor
58
	 *
59
	 * @param mixed $serialization
60
	 *
61
	 * @return bool
62
	 */
63
	public function isDeserializerFor( $serialization ) {
64
		return $this->hasType( $serialization ) && $this->hasCorrectType( $serialization );
65
	}
66
67
	private function hasType( $serialization ) {
68
		return is_array( $serialization ) && array_key_exists( 'type', $serialization );
69
	}
70
71
	private function hasCorrectType( $serialization ) {
72
		return in_array( $serialization['type'], array( 'claim', 'statement' ) );
73
	}
74
75
	/**
76
	 * @see Deserializer::deserialize
77
	 *
78
	 * @param array $serialization
79
	 *
80
	 * @throws DeserializationException
81
	 * @return Statement
82
	 */
83
	public function deserialize( $serialization ) {
84
		// Note: The following functions have been inlined on purpose, see T157013.
85
		if ( !is_array( $serialization ) || !array_key_exists( 'type', $serialization ) ) {
86
			throw new MissingTypeException();
87
		}
88
89
		if ( $serialization['type'] !== 'claim' && $serialization['type'] !== 'statement' ) {
90
			throw new UnsupportedTypeException( $serialization['type'] );
91
		}
92
93
		if ( !array_key_exists( 'mainsnak', $serialization ) ) {
94
			throw new MissingAttributeException(
95
				'mainsnak'
96
			);
97
		}
98
99
		return $this->getDeserialized( $serialization );
100
	}
101
102
	/**
103
	 * @param array $serialization
104
	 *
105
	 * @return Statement
106
	 */
107
	private function getDeserialized( array $serialization ) {
108
		/** @var Snak $mainSnak */
109
		$mainSnak = $this->snakDeserializer->deserialize( $serialization['mainsnak'] );
110
		$statement = new Statement( $mainSnak );
111
112
		// Note: The following ifs are inlined on purpose, see T157013.
113
		if ( array_key_exists( 'id', $serialization ) ) {
114
			$this->setGuidFromSerialization( $serialization, $statement );
115
		}
116
		if ( array_key_exists( 'qualifiers', $serialization ) ) {
117
			$this->setQualifiersFromSerialization( $serialization, $statement );
118
		}
119
		if ( array_key_exists( 'rank', $serialization ) ) {
120
			$this->setRankFromSerialization( $serialization, $statement );
121
		}
122
		if ( array_key_exists( 'references', $serialization ) ) {
123
			$this->setReferencesFromSerialization( $serialization, $statement );
124
		}
125
126
		return $statement;
127
	}
128
129
	private function setGuidFromSerialization( array $serialization, Statement $statement ) {
130
		if ( !is_string( $serialization['id'] ) ) {
131
			throw new DeserializationException( 'The id ' . $serialization['id'] . ' is not a valid GUID.' );
132
		}
133
134
		$statement->setGuid( $serialization['id'] );
135
	}
136
137
	private function setQualifiersFromSerialization( array $serialization, Statement $statement ) {
138
		/** @var SnakList $qualifiers */
139
		$qualifiers = $this->snaksDeserializer->deserialize( $serialization['qualifiers'] );
140
141
		if ( array_key_exists( 'qualifiers-order', $serialization ) ) {
142
			$this->assertQualifiersOrderIsArray( $serialization );
143
144
			$qualifiers->orderByProperty( $serialization['qualifiers-order'] );
145
		}
146
147
		$statement->setQualifiers( $qualifiers );
148
	}
149
150
	private function setRankFromSerialization( array $serialization, Statement $statement ) {
151
		if ( !array_key_exists( $serialization['rank'], $this->rankIds ) ) {
152
			throw new DeserializationException( 'The rank ' . $serialization['rank'] . ' is not a valid rank.' );
153
		}
154
155
		$statement->setRank( $this->rankIds[$serialization['rank']] );
156
	}
157
158
	private function setReferencesFromSerialization( array $serialization, Statement $statement ) {
159
		/** @var ReferenceList $references */
160
		$references = $this->referencesDeserializer->deserialize( $serialization['references'] );
161
		$statement->setReferences( $references );
162
	}
163
164
	private function assertQualifiersOrderIsArray( array $serialization ) {
165
		if ( !is_array( $serialization['qualifiers-order'] ) ) {
166
			throw new InvalidAttributeException(
167
				'qualifiers-order',
168
				$serialization['qualifiers-order'],
169
				'qualifiers-order attribute is not a valid array'
170
			);
171
		}
172
	}
173
174
}
175