Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
55 / 55 |
|
100.00% |
13 / 13 |
CRAP | |
100.00% |
1 / 1 |
ViolationMessageDeserializer | |
100.00% |
55 / 55 |
|
100.00% |
13 / 13 |
22 | |
100.00% |
1 / 1 |
__construct | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
unabbreviateViolationMessageKey | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
deserialize | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
2 | |||
deserializeArgument | |
100.00% |
26 / 26 |
|
100.00% |
1 / 1 |
2 | |||
deserializeStringByIdentity | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
deserializeEntityId | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
deserializeEntityIdList | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
deserializeItemIdSnakValue | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
4 | |||
deserializeItemIdSnakValueList | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
deserializeDataValue | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
deserializeContextType | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
5 | |||
deserializeContextTypeList | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
deserializeMultilingualText | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | |
3 | namespace WikibaseQuality\ConstraintReport\ConstraintCheck\Message; |
4 | |
5 | use DataValues\DataValue; |
6 | use DataValues\MultilingualTextValue; |
7 | use Deserializers\Deserializer; |
8 | use InvalidArgumentException; |
9 | use LogicException; |
10 | use Wikibase\DataModel\Entity\EntityId; |
11 | use Wikibase\DataModel\Entity\EntityIdParser; |
12 | use Wikibase\Lib\DataValueFactory; |
13 | use WikibaseQuality\ConstraintReport\ConstraintCheck\Context\Context; |
14 | use WikibaseQuality\ConstraintReport\ConstraintCheck\ItemIdSnakValue; |
15 | use Wikimedia\Assert\Assert; |
16 | |
17 | /** |
18 | * A deserializer for {@link ViolationMessage}s. |
19 | * |
20 | * @license GPL-2.0-or-later |
21 | */ |
22 | class ViolationMessageDeserializer implements Deserializer { |
23 | |
24 | /** |
25 | * @var EntityIdParser |
26 | */ |
27 | private $entityIdParser; |
28 | |
29 | /** |
30 | * @var DataValueFactory |
31 | */ |
32 | private $dataValueFactory; |
33 | |
34 | public function __construct( |
35 | EntityIdParser $entityIdParser, |
36 | DataValueFactory $dataValueFactory |
37 | ) { |
38 | $this->entityIdParser = $entityIdParser; |
39 | $this->dataValueFactory = $dataValueFactory; |
40 | } |
41 | |
42 | public function unabbreviateViolationMessageKey( $messageKeySuffix ) { |
43 | return ViolationMessage::MESSAGE_KEY_PREFIX . $messageKeySuffix; |
44 | } |
45 | |
46 | /** |
47 | * @param array $serialization |
48 | * @return ViolationMessage |
49 | */ |
50 | public function deserialize( $serialization ) { |
51 | Assert::parameterType( 'array', $serialization, '$serialization' ); |
52 | |
53 | $message = new ViolationMessage( |
54 | $this->unabbreviateViolationMessageKey( $serialization['k'] ) |
55 | ); |
56 | |
57 | foreach ( $serialization['a'] as $serializedArgument ) { |
58 | $message = $this->deserializeArgument( $message, $serializedArgument ); |
59 | } |
60 | |
61 | return $message; |
62 | } |
63 | |
64 | /** |
65 | * @param ViolationMessage $message |
66 | * @param array $serializedArgument [ 't' => ViolationMessage::TYPE_*, 'v' => serialized value, 'r' => $role ] |
67 | * @return ViolationMessage $message with the deserialized argument appended |
68 | */ |
69 | private function deserializeArgument( ViolationMessage $message, array $serializedArgument ) { |
70 | $methods = [ |
71 | ViolationMessage::TYPE_ENTITY_ID => 'deserializeEntityId', |
72 | ViolationMessage::TYPE_ENTITY_ID_LIST => 'deserializeEntityIdList', |
73 | ViolationMessage::TYPE_ITEM_ID_SNAK_VALUE => 'deserializeItemIdSnakValue', |
74 | ViolationMessage::TYPE_ITEM_ID_SNAK_VALUE_LIST => 'deserializeItemIdSnakValueList', |
75 | ViolationMessage::TYPE_DATA_VALUE => 'deserializeDataValue', |
76 | ViolationMessage::TYPE_DATA_VALUE_TYPE => 'deserializeStringByIdentity', |
77 | ViolationMessage::TYPE_INLINE_CODE => 'deserializeStringByIdentity', |
78 | ViolationMessage::TYPE_CONSTRAINT_SCOPE => 'deserializeContextType', |
79 | ViolationMessage::TYPE_CONSTRAINT_SCOPE_LIST => 'deserializeContextTypeList', |
80 | ViolationMessage::TYPE_PROPERTY_SCOPE => 'deserializeContextType', |
81 | ViolationMessage::TYPE_PROPERTY_SCOPE_LIST => 'deserializeContextTypeList', |
82 | ViolationMessage::TYPE_LANGUAGE => 'deserializeStringByIdentity', |
83 | ViolationMessage::TYPE_LANGUAGE_LIST => 'deserializeStringByIdentity', |
84 | ViolationMessage::TYPE_MULTILINGUAL_TEXT => 'deserializeMultilingualText', |
85 | ]; |
86 | |
87 | $type = $serializedArgument['t']; |
88 | $serializedValue = $serializedArgument['v']; |
89 | $role = $serializedArgument['r']; |
90 | |
91 | if ( array_key_exists( $type, $methods ) ) { |
92 | $method = $methods[$type]; |
93 | $value = $this->$method( $serializedValue ); |
94 | } else { |
95 | throw new InvalidArgumentException( |
96 | 'Unknown ViolationMessage argument type ' . $type . '!' |
97 | ); |
98 | } |
99 | |
100 | return $message->withArgument( $type, $role, $value ); |
101 | } |
102 | |
103 | /** |
104 | * @param string $string any value that shall simply be deserialized into itself |
105 | * @return string that same value, unchanged |
106 | */ |
107 | private function deserializeStringByIdentity( $string ) { |
108 | return $string; |
109 | } |
110 | |
111 | /** |
112 | * @param string $entityIdSerialization entity ID serialization |
113 | * @return EntityId |
114 | */ |
115 | private function deserializeEntityId( $entityIdSerialization ) { |
116 | return $this->entityIdParser->parse( $entityIdSerialization ); |
117 | } |
118 | |
119 | /** |
120 | * @param string[] $entityIdSerializations entity ID serializations |
121 | * @return EntityId[] |
122 | */ |
123 | private function deserializeEntityIdList( array $entityIdSerializations ) { |
124 | return array_map( [ $this, 'deserializeEntityId' ], $entityIdSerializations ); |
125 | } |
126 | |
127 | /** |
128 | * @param string $valueSerialization entity ID serialization, '::somevalue' or '::novalue' |
129 | * @return ItemIdSnakValue |
130 | */ |
131 | private function deserializeItemIdSnakValue( $valueSerialization ) { |
132 | switch ( $valueSerialization ) { |
133 | case '::somevalue': |
134 | return ItemIdSnakValue::someValue(); |
135 | case '::novalue': |
136 | return ItemIdSnakValue::noValue(); |
137 | default: |
138 | $itemId = $this->deserializeEntityId( $valueSerialization ); |
139 | '@phan-var \Wikibase\DataModel\Entity\ItemId $itemId'; |
140 | return ItemIdSnakValue::fromItemId( $itemId ); |
141 | } |
142 | } |
143 | |
144 | /** |
145 | * @param string[] $valueSerializations entity ID serializations, '::somevalue's or '::novalue's |
146 | * @return ItemIdSnakValue[] |
147 | */ |
148 | private function deserializeItemIdSnakValueList( $valueSerializations ) { |
149 | return array_map( [ $this, 'deserializeItemIdSnakValue' ], $valueSerializations ); |
150 | } |
151 | |
152 | /** |
153 | * @param array $dataValueSerialization the data value in array form |
154 | * @return DataValue |
155 | */ |
156 | private function deserializeDataValue( array $dataValueSerialization ) { |
157 | return $this->dataValueFactory->newFromArray( $dataValueSerialization ); |
158 | } |
159 | |
160 | /** |
161 | * @param string $contextTypeAbbreviation |
162 | * @return string one of the Context::TYPE_* constants |
163 | */ |
164 | private function deserializeContextType( $contextTypeAbbreviation ) { |
165 | switch ( $contextTypeAbbreviation ) { |
166 | case 's': |
167 | return Context::TYPE_STATEMENT; |
168 | case 'q': |
169 | return Context::TYPE_QUALIFIER; |
170 | case 'r': |
171 | return Context::TYPE_REFERENCE; |
172 | default: |
173 | // @codeCoverageIgnoreStart |
174 | throw new LogicException( |
175 | 'Unknown context type abbreviation ' . $contextTypeAbbreviation |
176 | ); |
177 | // @codeCoverageIgnoreEnd |
178 | } |
179 | } |
180 | |
181 | /** |
182 | * @param string[] $contextTypeAbbreviations |
183 | * @return string[] Context::TYPE_* constants |
184 | */ |
185 | private function deserializeContextTypeList( array $contextTypeAbbreviations ) { |
186 | return array_map( [ $this, 'deserializeContextType' ], $contextTypeAbbreviations ); |
187 | } |
188 | |
189 | /** |
190 | * @param mixed $textSerialization {@see MultilingualTextValue::getArrayValue} |
191 | * @return MultilingualTextValue |
192 | */ |
193 | private function deserializeMultilingualText( $textSerialization ) { |
194 | return MultilingualTextValue::newFromArray( $textSerialization ); |
195 | } |
196 | |
197 | } |