Passed
Push — master ( 1624f2...3d792a )
by
unknown
01:39
created

SnakDeserializer::deserializePropertyId()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2.0078

Importance

Changes 0
Metric Value
dl 0
loc 13
ccs 7
cts 8
cp 0.875
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 8
nc 2
nop 1
crap 2.0078
1
<?php
2
3
namespace Wikibase\DataModel\Deserializers;
4
5
use DataValues\UnDeserializableValue;
6
use Deserializers\Deserializer;
7
use Deserializers\DispatchableDeserializer;
8
use Deserializers\Exceptions\DeserializationException;
9
use Deserializers\Exceptions\InvalidAttributeException;
10
use Deserializers\Exceptions\MissingAttributeException;
11
use Deserializers\Exceptions\MissingTypeException;
12
use Deserializers\Exceptions\UnsupportedTypeException;
13
use Wikibase\DataModel\Entity\PropertyId;
14
use Wikibase\DataModel\Snak\PropertyNoValueSnak;
15
use Wikibase\DataModel\Snak\PropertySomeValueSnak;
16
use Wikibase\DataModel\Snak\PropertyValueSnak;
17
18
/**
19
 * Package private
20
 *
21
 * @license GPL-2.0+
22
 * @author Jeroen De Dauw < [email protected] >
23
 * @author Thomas Pellissier Tanon
24
 */
25
class SnakDeserializer implements DispatchableDeserializer {
26
27
	/**
28
	 * @var Deserializer
29
	 */
30
	private $dataValueDeserializer;
31
32
	/**
33
	 * @var Deserializer
34
	 */
35
	private $entityIdDeserializer;
36
37
	/**
38
	 * @param Deserializer $dataValueDeserializer
39
	 * @param Deserializer $entityIdDeserializer
40
	 */
41 68
	public function __construct(
42
		Deserializer $dataValueDeserializer,
43
		Deserializer $entityIdDeserializer
44
	) {
45 68
		$this->dataValueDeserializer = $dataValueDeserializer;
46 68
		$this->entityIdDeserializer = $entityIdDeserializer;
47 68
	}
48
49
	/**
50
	 * @see Deserializer::isDeserializerFor
51
	 *
52
	 * @param mixed $serialization
53
	 *
54
	 * @return bool
55
	 */
56 7
	public function isDeserializerFor( $serialization ) {
57 7
		return is_array( $serialization )
58 6
			&& $this->hasSnakType( $serialization )
59 7
			&& $this->hasCorrectSnakType( $serialization );
60
	}
61
62 43
	private function hasSnakType( $serialization ) {
63 43
		return array_key_exists( 'snaktype', $serialization );
64
	}
65
66 39
	private function hasCorrectSnakType( $serialization ) {
67 39
		return in_array( $serialization['snaktype'], array( 'novalue', 'somevalue', 'value' ) );
68
	}
69
70
	/**
71
	 * @see Deserializer::deserialize
72
	 *
73
	 * @param array $serialization
74
	 *
75
	 * @throws DeserializationException
76
	 * @return PropertyNoValueSnak|PropertySomeValueSnak|PropertyValueSnak
77
	 */
78 38
	public function deserialize( $serialization ) {
79 38
		$this->assertCanDeserialize( $serialization );
80 34
		$this->requireAttribute( $serialization, 'property' );
81
82 33
		return $this->getDeserialized( $serialization );
83
	}
84
85
	/**
86
	 * @see SnakDeserializer::hasCorrectSnakType
87
	 *
88
	 * @param array $serialization
89
	 *
90
	 * @return PropertyNoValueSnak|PropertySomeValueSnak|PropertyValueSnak
91
	 */
92 33
	private function getDeserialized( array $serialization ) {
93 33
		switch ( $serialization['snaktype'] ) {
94 33
			case 'novalue':
95 21
				return $this->newNoValueSnak( $serialization );
96 17
			case 'somevalue':
97 7
				return $this->newSomeValueSnak( $serialization );
98
			default:
99 10
				return $this->newValueSnak( $serialization );
100
		}
101
	}
102
103 21
	private function newNoValueSnak( array $serialization ) {
104 21
		return new PropertyNoValueSnak( $this->deserializePropertyId( $serialization['property'] ) );
105
	}
106
107 7
	private function newSomeValueSnak( array $serialization ) {
108 7
		return new PropertySomeValueSnak( $this->deserializePropertyId( $serialization['property'] ) );
109
	}
110
111 10
	private function newValueSnak( array $serialization ) {
112 10
		$this->requireAttribute( $serialization, 'datavalue' );
113
114 9
		return new PropertyValueSnak(
115 9
			$this->deserializePropertyId( $serialization['property'] ),
116 9
			$this->deserializeDataValue( $serialization['datavalue'] )
117
		);
118
	}
119
120 9
	private function deserializeDataValue( $serialization ) {
121
		try {
122 9
			return $this->dataValueDeserializer->deserialize( $serialization );
123
		}
124 3
		catch ( DeserializationException $ex ) {
125 3
			$error = isset( $serialization['error'] ) ? $serialization['error'] : $ex->getMessage();
126 3
			return new UnDeserializableValue( $serialization['value'], $serialization['type'], $error );
127
		}
128
	}
129
130
	/**
131
	 * @param string $serialization
132
	 *
133
	 * @throw InvalidAttributeException
134
	 * @return PropertyId
135
	 */
136 32
	private function deserializePropertyId( $serialization ) {
137 32
		$propertyId = $this->entityIdDeserializer->deserialize( $serialization );
138
139 32
		if ( !( $propertyId instanceof PropertyId ) ) {
140 1
			throw new InvalidAttributeException(
141 1
				'property',
142
				$serialization,
143 1
				"'$serialization' is not a valid property ID"
144
			);
145
		}
146
147 31
		return $propertyId;
148
	}
149
150 38
	private function assertCanDeserialize( $serialization ) {
151 38
		if ( !is_array( $serialization ) ) {
152 1
			throw new DeserializationException( 'The snak serialization should be an array' );
153
		}
154
155 37
		if ( !$this->hasSnakType( $serialization ) ) {
156 2
			throw new MissingTypeException();
157
		}
158
159 35
		if ( !$this->hasCorrectSnakType( $serialization ) ) {
160 1
			throw new UnsupportedTypeException( $serialization['snaktype'] );
161
		}
162 34
	}
163
164 34
	private function requireAttribute( array $array, $attributeName ) {
165 34
		if ( !array_key_exists( $attributeName, $array ) ) {
166 2
			throw new MissingAttributeException(
167 2
				$attributeName
168
			);
169
		}
170 33
	}
171
172
}
173