1 | <?php |
||
28 | class SnakDeserializer implements DispatchableDeserializer { |
||
29 | |||
30 | /** |
||
31 | * @var Deserializer |
||
32 | */ |
||
33 | private $dataValueDeserializer; |
||
34 | |||
35 | public function __construct( Deserializer $dataValueDeserializer ) { |
||
36 | $this->dataValueDeserializer = $dataValueDeserializer; |
||
37 | 68 | } |
|
38 | |||
39 | /** |
||
40 | * @see Deserializer::isDeserializerFor |
||
41 | 68 | * |
|
42 | 68 | * @param mixed $serialization |
|
43 | 68 | * |
|
44 | * @return bool |
||
45 | */ |
||
46 | public function isDeserializerFor( $serialization ) { |
||
47 | return is_array( $serialization ) |
||
48 | && $this->hasSnakType( $serialization ) |
||
49 | && $this->hasCorrectSnakType( $serialization ); |
||
50 | } |
||
51 | |||
52 | 7 | private function hasSnakType( $serialization ) { |
|
53 | 7 | return array_key_exists( 'snaktype', $serialization ); |
|
54 | 7 | } |
|
55 | 7 | ||
56 | private function hasCorrectSnakType( $serialization ) { |
||
57 | return in_array( $serialization['snaktype'], [ 'novalue', 'somevalue', 'value' ] ); |
||
58 | 43 | } |
|
59 | 43 | ||
60 | /** |
||
61 | * @see Deserializer::deserialize |
||
62 | 39 | * |
|
63 | 39 | * @param array $serialization |
|
64 | * |
||
65 | * @throws DeserializationException |
||
66 | * @return PropertyNoValueSnak|PropertySomeValueSnak|PropertyValueSnak |
||
67 | */ |
||
68 | public function deserialize( $serialization ) { |
||
69 | $this->assertCanDeserialize( $serialization ); |
||
70 | $this->requireAttribute( $serialization, 'property' ); |
||
71 | |||
72 | return $this->getDeserialized( $serialization ); |
||
73 | } |
||
74 | 38 | ||
75 | 38 | /** |
|
76 | 34 | * @see SnakDeserializer::hasCorrectSnakType |
|
77 | * |
||
78 | 33 | * @param array $serialization |
|
79 | * |
||
80 | * @throws InvalidAttributeException |
||
81 | * @return PropertyNoValueSnak|PropertySomeValueSnak|PropertyValueSnak |
||
82 | */ |
||
83 | private function getDeserialized( array $serialization ) { |
||
84 | switch ( $serialization['snaktype'] ) { |
||
85 | case 'novalue': |
||
86 | return $this->newNoValueSnak( $serialization ); |
||
87 | case 'somevalue': |
||
88 | return $this->newSomeValueSnak( $serialization ); |
||
89 | 33 | default: |
|
90 | 33 | return $this->newValueSnak( $serialization ); |
|
91 | 33 | } |
|
92 | 21 | } |
|
93 | 17 | ||
94 | 7 | private function newNoValueSnak( array $serialization ) { |
|
95 | return new PropertyNoValueSnak( $this->deserializePropertyId( $serialization['property'] ) ); |
||
96 | 10 | } |
|
97 | |||
98 | private function newSomeValueSnak( array $serialization ) { |
||
99 | return new PropertySomeValueSnak( $this->deserializePropertyId( $serialization['property'] ) ); |
||
100 | 21 | } |
|
101 | 21 | ||
102 | private function newValueSnak( array $serialization ) { |
||
103 | $this->requireAttribute( $serialization, 'datavalue' ); |
||
104 | 7 | ||
105 | 7 | return new PropertyValueSnak( |
|
106 | $this->deserializePropertyId( $serialization['property'] ), |
||
107 | $this->deserializeDataValue( $serialization['datavalue'] ) |
||
108 | 10 | ); |
|
109 | 10 | } |
|
110 | |||
111 | 9 | /** |
|
112 | 9 | * @param array $serialization |
|
113 | 9 | * |
|
114 | * @return DataValue |
||
115 | */ |
||
116 | private function deserializeDataValue( $serialization ) { |
||
117 | 9 | try { |
|
118 | return $this->dataValueDeserializer->deserialize( $serialization ); |
||
119 | 9 | } catch ( DeserializationException $ex ) { |
|
120 | 3 | $value = isset( $serialization[DataValueDeserializer::VALUE_KEY] ) |
|
121 | 3 | ? $serialization[DataValueDeserializer::VALUE_KEY] |
|
122 | 3 | : null; |
|
123 | $type = isset( $serialization[DataValueDeserializer::TYPE_KEY] ) |
||
124 | ? $serialization[DataValueDeserializer::TYPE_KEY] |
||
125 | : null; |
||
126 | $error = isset( $serialization['error'] ) ? $serialization['error'] : $ex->getMessage(); |
||
127 | |||
128 | return new UnDeserializableValue( $value, $type, $error ); |
||
129 | } |
||
130 | } |
||
131 | |||
132 | 32 | /** |
|
133 | 32 | * @param string $serialization |
|
134 | * |
||
135 | 32 | * @throws InvalidAttributeException |
|
136 | 1 | * @return PropertyId |
|
137 | 1 | */ |
|
138 | 1 | private function deserializePropertyId( $serialization ) { |
|
139 | 1 | try { |
|
140 | return new PropertyId( $serialization ); |
||
141 | } catch ( InvalidArgumentException $ex ) { |
||
142 | throw new InvalidAttributeException( |
||
143 | 31 | 'property', |
|
144 | $serialization, |
||
145 | "'$serialization' is not a valid property ID" |
||
146 | 38 | ); |
|
147 | 38 | } |
|
148 | 1 | } |
|
149 | |||
150 | private function assertCanDeserialize( $serialization ) { |
||
163 | 2 | ||
164 | private function requireAttribute( array $array, $attributeName ) { |
||
165 | if ( !array_key_exists( $attributeName, $array ) ) { |
||
166 | 33 | throw new MissingAttributeException( |
|
167 | $attributeName |
||
168 | ); |
||
169 | } |
||
170 | } |
||
171 | |||
172 | } |
||
173 |