Passed
Push — inline ( 0524ef )
by no
03:18 queued 20s
created

StatementDeserializer::hasType()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 3
rs 10
cc 2
eloc 2
nc 2
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 is_array( $serialization )
65
			&& array_key_exists( 'type', $serialization )
66
			&& ( $serialization['type'] === 'claim' || $serialization['type'] === 'statement' );
67
	}
68
69
	/**
70
	 * @see Deserializer::deserialize
71
	 *
72
	 * @param array $serialization
73
	 *
74
	 * @throws DeserializationException
75
	 * @return Statement
76
	 */
77
	public function deserialize( $serialization ) {
78
		// Note: The following functions have been inlined on purpose, see T157013.
79
		if ( !is_array( $serialization ) || !array_key_exists( 'type', $serialization ) ) {
80
			throw new MissingTypeException();
81
		}
82
83
		if ( $serialization['type'] !== 'claim' && $serialization['type'] !== 'statement' ) {
84
			throw new UnsupportedTypeException( $serialization['type'] );
85
		}
86
87
		if ( !array_key_exists( 'mainsnak', $serialization ) ) {
88
			throw new MissingAttributeException( 'mainsnak' );
89
		}
90
91
		return $this->getDeserialized( $serialization );
92
	}
93
94
	/**
95
	 * @param array $serialization
96
	 *
97
	 * @return Statement
98
	 */
99
	private function getDeserialized( array $serialization ) {
100
		/** @var Snak $mainSnak */
101
		$mainSnak = $this->snakDeserializer->deserialize( $serialization['mainsnak'] );
102
		$statement = new Statement( $mainSnak );
103
104
		// Note: The following ifs are inlined on purpose, see T157013.
105
		if ( array_key_exists( 'id', $serialization ) ) {
106
			$this->setGuidFromSerialization( $serialization, $statement );
107
		}
108
		if ( array_key_exists( 'qualifiers', $serialization ) ) {
109
			$this->setQualifiersFromSerialization( $serialization, $statement );
110
		}
111
		if ( array_key_exists( 'rank', $serialization ) ) {
112
			$this->setRankFromSerialization( $serialization, $statement );
113
		}
114
		if ( array_key_exists( 'references', $serialization ) ) {
115
			$this->setReferencesFromSerialization( $serialization, $statement );
116
		}
117
118
		return $statement;
119
	}
120
121
	private function setGuidFromSerialization( array $serialization, Statement $statement ) {
122
		if ( !is_string( $serialization['id'] ) ) {
123
			throw new DeserializationException( 'The id ' . $serialization['id'] . ' is not a valid GUID.' );
124
		}
125
126
		$statement->setGuid( $serialization['id'] );
127
	}
128
129
	private function setQualifiersFromSerialization( array $serialization, Statement $statement ) {
130
		/** @var SnakList $qualifiers */
131
		$qualifiers = $this->snaksDeserializer->deserialize( $serialization['qualifiers'] );
132
133
		if ( array_key_exists( 'qualifiers-order', $serialization ) ) {
134
			$this->assertQualifiersOrderIsArray( $serialization );
135
136
			$qualifiers->orderByProperty( $serialization['qualifiers-order'] );
137
		}
138
139
		$statement->setQualifiers( $qualifiers );
140
	}
141
142
	private function setRankFromSerialization( array $serialization, Statement $statement ) {
143
		if ( !array_key_exists( $serialization['rank'], $this->rankIds ) ) {
144
			throw new DeserializationException( 'The rank ' . $serialization['rank'] . ' is not a valid rank.' );
145
		}
146
147
		$statement->setRank( $this->rankIds[$serialization['rank']] );
148
	}
149
150
	private function setReferencesFromSerialization( array $serialization, Statement $statement ) {
151
		/** @var ReferenceList $references */
152
		$references = $this->referencesDeserializer->deserialize( $serialization['references'] );
153
		$statement->setReferences( $references );
154
	}
155
156
	private function assertQualifiersOrderIsArray( array $serialization ) {
157
		if ( !is_array( $serialization['qualifiers-order'] ) ) {
158
			throw new InvalidAttributeException(
159
				'qualifiers-order',
160
				$serialization['qualifiers-order'],
161
				'qualifiers-order attribute is not a valid array'
162
			);
163
		}
164
	}
165
166
}
167