Completed
Push — master ( 340657...ed051f )
by
unknown
06:16
created

deserializeDataValue()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
namespace WikibaseQuality\ConstraintReport\ConstraintCheck\Message;
4
5
use DataValues\DataValue;
6
use DataValues\DataValueFactory;
7
use DataValues\MultilingualTextValue;
8
use Deserializers\Deserializer;
9
use InvalidArgumentException;
10
use LogicException;
11
use Wikibase\DataModel\Entity\EntityId;
12
use Wikibase\DataModel\Entity\EntityIdParser;
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_MULTILINGUAL_TEXT => 'deserializeMultilingualText',
84
		];
85
86
		$type = $serializedArgument['t'];
87
		$serializedValue = $serializedArgument['v'];
88
		$role = $serializedArgument['r'];
89
90 View Code Duplication
		if ( array_key_exists( $type, $methods ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
91
			$method = $methods[$type];
92
			$value = $this->$method( $serializedValue );
93
		} else {
94
			throw new InvalidArgumentException(
95
				'Unknown ViolationMessage argument type ' . $type . '!'
96
			);
97
		}
98
99
		return $message->withArgument( $type, $role, $value );
100
	}
101
102
	/**
103
	 * @param string $string any value that shall simply be deserialized into itself
104
	 * @return string that same value, unchanged
105
	 */
106
	private function deserializeStringByIdentity( $string ) {
107
		return $string;
108
	}
109
110
	/**
111
	 * @param string $entityIdSerialization entity ID serialization
112
	 * @return EntityId
113
	 */
114
	private function deserializeEntityId( $entityIdSerialization ) {
115
		return $this->entityIdParser->parse( $entityIdSerialization );
116
	}
117
118
	/**
119
	 * @param string[] $entityIdSerializations entity ID serializations
120
	 * @return EntityId[]
121
	 */
122
	private function deserializeEntityIdList( array $entityIdSerializations ) {
123
		return array_map( [ $this, 'deserializeEntityId' ], $entityIdSerializations );
124
	}
125
126
	/**
127
	 * @param string $valueSerialization entity ID serialization, '::somevalue' or '::novalue'
128
	 * @return ItemIdSnakValue
129
	 */
130
	private function deserializeItemIdSnakValue( $valueSerialization ) {
131
		switch ( $valueSerialization ) {
132
			case '::somevalue':
133
				return ItemIdSnakValue::someValue();
134
			case '::novalue':
135
				return ItemIdSnakValue::noValue();
136
			default:
137
				return ItemIdSnakValue::fromItemId( $this->deserializeEntityId( $valueSerialization ) );
0 ignored issues
show
Compatibility introduced by
$this->deserializeEntityId($valueSerialization) of type object<Wikibase\DataModel\Entity\EntityId> is not a sub-type of object<Wikibase\DataModel\Entity\ItemId>. It seems like you assume a child class of the class Wikibase\DataModel\Entity\EntityId to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
138
		}
139
	}
140
141
	/**
142
	 * @param string[] $valueSerializations entity ID serializations, '::somevalue's or '::novalue's
143
	 * @return ItemIdSnakValue[]
144
	 */
145
	private function deserializeItemIdSnakValueList( $valueSerializations ) {
146
		return array_map( [ $this, 'deserializeItemIdSnakValue' ], $valueSerializations );
147
	}
148
149
	/**
150
	 * @param array $dataValueSerialization the data value in array form
151
	 * @return DataValue
152
	 */
153
	private function deserializeDataValue( array $dataValueSerialization ) {
154
		return $this->dataValueFactory->newFromArray( $dataValueSerialization );
155
	}
156
157
	/**
158
	 * @param string $contextTypeAbbreviation
159
	 * @return string one of the Context::TYPE_* constants
160
	 */
161 View Code Duplication
	private function deserializeContextType( $contextTypeAbbreviation ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
162
		switch ( $contextTypeAbbreviation ) {
163
			case 's':
164
				return Context::TYPE_STATEMENT;
165
			case 'q':
166
				return Context::TYPE_QUALIFIER;
167
			case 'r':
168
				return Context::TYPE_REFERENCE;
169
			default:
170
				// @codeCoverageIgnoreStart
171
				throw new LogicException(
172
					'Unknown context type abbreviation ' . $contextTypeAbbreviation
173
				);
174
				// @codeCoverageIgnoreEnd
175
		}
176
	}
177
178
	/**
179
	 * @param string[] $contextTypeAbbreviations
180
	 * @return string[] Context::TYPE_* constants
181
	 */
182
	private function deserializeContextTypeList( array $contextTypeAbbreviations ) {
183
		return array_map( [ $this, 'deserializeContextType' ], $contextTypeAbbreviations );
184
	}
185
186
	/**
187
	 * @param mixed $textSerialization {@see MultilingualTextValue::getArrayValue}
188
	 * @return MultilingualTextValue
189
	 */
190
	private function deserializeMultilingualText( $textSerialization ) {
191
		return MultilingualTextValue::newFromArray( $textSerialization );
192
	}
193
194
}
195