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

serializeMultilingualText()   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\MultilingualTextValue;
7
use InvalidArgumentException;
8
use LogicException;
9
use Serializers\Serializer;
10
use Wikibase\DataModel\Entity\EntityId;
11
use WikibaseQuality\ConstraintReport\ConstraintCheck\Context\Context;
12
use WikibaseQuality\ConstraintReport\ConstraintCheck\ItemIdSnakValue;
13
use Wikimedia\Assert\Assert;
14
15
/**
16
 * A serializer for {@link ViolationMessage}s.
17
 *
18
 * @license GPL-2.0-or-later
19
 */
20
class ViolationMessageSerializer implements Serializer {
21
22
	private function abbreviateViolationMessageKey( $fullMessageKey ) {
23
		return substr( $fullMessageKey, strlen( ViolationMessage::MESSAGE_KEY_PREFIX ) );
24
	}
25
26
	/**
27
	 * @param ViolationMessage $object
28
	 * @return array
29
	 */
30
	public function serialize( $object ) {
31
		/** @var ViolationMessage $object */
32
		Assert::parameterType( ViolationMessage::class, $object, '$object' );
33
34
		$arguments = $object->getArguments();
35
		$serializedArguments = [];
36
		foreach ( $arguments as $argument ) {
37
			$serializedArguments[] = $this->serializeArgument( $argument );
38
		}
39
40
		return [
41
			'k' => $this->abbreviateViolationMessageKey( $object->getMessageKey() ),
42
			'a' => $serializedArguments,
43
		];
44
	}
45
46
	/**
47
	 * @param array $argument element of ViolationMessage::getArguments()
48
	 * @return array [ 't' => ViolationMessage::TYPE_*, 'v' => serialized value, 'r' => $role ]
49
	 */
50
	private function serializeArgument( array $argument ) {
51
		$methods = [
52
			ViolationMessage::TYPE_ENTITY_ID => 'serializeEntityId',
53
			ViolationMessage::TYPE_ENTITY_ID_LIST => 'serializeEntityIdList',
54
			ViolationMessage::TYPE_ITEM_ID_SNAK_VALUE => 'serializeItemIdSnakValue',
55
			ViolationMessage::TYPE_ITEM_ID_SNAK_VALUE_LIST => 'serializeItemIdSnakValueList',
56
			ViolationMessage::TYPE_DATA_VALUE => 'serializeDataValue',
57
			ViolationMessage::TYPE_DATA_VALUE_TYPE => 'serializeStringByIdentity',
58
			ViolationMessage::TYPE_INLINE_CODE => 'serializeStringByIdentity',
59
			ViolationMessage::TYPE_CONSTRAINT_SCOPE => 'serializeContextType',
60
			ViolationMessage::TYPE_CONSTRAINT_SCOPE_LIST => 'serializeContextTypeList',
61
			ViolationMessage::TYPE_PROPERTY_SCOPE => 'serializeContextType',
62
			ViolationMessage::TYPE_PROPERTY_SCOPE_LIST => 'serializeContextTypeList',
63
			ViolationMessage::TYPE_LANGUAGE => 'serializeStringByIdentity',
64
			ViolationMessage::TYPE_MULTILINGUAL_TEXT => 'serializeMultilingualText',
65
		];
66
67
		$type = $argument['type'];
68
		$value = $argument['value'];
69
		$role = $argument['role'];
70
71 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...
72
			$method = $methods[$type];
73
			$serializedValue = $this->$method( $value );
74
		} else {
75
			throw new InvalidArgumentException(
76
				'Unknown ViolationMessage argument type ' . $type . '!'
77
			);
78
		}
79
80
		$serialized = [
81
			't' => $type,
82
			'v' => $serializedValue,
83
			'r' => $role,
84
		];
85
86
		return $serialized;
87
	}
88
89
	/**
90
	 * @param string $string any value that shall simply be serialized to itself
91
	 * @return string that same value, unchanged
92
	 */
93
	private function serializeStringByIdentity( $string ) {
94
		Assert::parameterType( 'string', $string, '$string' );
95
		return $string;
96
	}
97
98
	/**
99
	 * @param EntityId $entityId
100
	 * @return string entity ID serialization
101
	 */
102
	private function serializeEntityId( EntityId $entityId ) {
103
		return $entityId->getSerialization();
104
	}
105
106
	/**
107
	 * @param EntityId[] $entityIdList
108
	 * @return string[] entity ID serializations
109
	 */
110
	private function serializeEntityIdList( array $entityIdList ) {
111
		return array_map( [ $this, 'serializeEntityId' ], $entityIdList );
112
	}
113
114
	/**
115
	 * @param ItemIdSnakValue $value
116
	 * @return string entity ID serialization, '::somevalue', or '::novalue'
117
	 * (according to EntityId::PATTERN, entity ID serializations can never begin with two colons)
118
	 */
119
	private function serializeItemIdSnakValue( ItemIdSnakValue $value ) {
120
		switch ( true ) {
121
			case $value->isValue():
122
				return $this->serializeEntityId( $value->getItemId() );
0 ignored issues
show
Bug introduced by
It seems like $value->getItemId() can be null; however, serializeEntityId() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
123
			case $value->isSomeValue():
124
				return '::somevalue';
125
			case $value->isNoValue():
126
				return '::novalue';
127
			default:
128
				// @codeCoverageIgnoreStart
129
				throw new LogicException(
130
					'ItemIdSnakValue should guarantee that one of is{,Some,No}Value() is true'
131
				);
132
				// @codeCoverageIgnoreEnd
133
		}
134
	}
135
136
	/**
137
	 * @param ItemIdSnakValue[] $valueList
138
	 * @return string[] array of entity ID serializations, '::somevalue's or '::novalue's
139
	 */
140
	private function serializeItemIdSnakValueList( array $valueList ) {
141
		return array_map( [ $this, 'serializeItemIdSnakValue' ], $valueList );
142
	}
143
144
	/**
145
	 * @param DataValue $dataValue
146
	 * @return array the data value in array form
147
	 */
148
	private function serializeDataValue( DataValue $dataValue ) {
149
		return $dataValue->toArray();
150
	}
151
152
	/**
153
	 * @param string $contextType one of the Context::TYPE_* constants
154
	 * @return string the abbreviated context type
155
	 */
156 View Code Duplication
	private function serializeContextType( $contextType ) {
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...
157
		switch ( $contextType ) {
158
			case Context::TYPE_STATEMENT:
159
				return 's';
160
			case Context::TYPE_QUALIFIER:
161
				return 'q';
162
			case Context::TYPE_REFERENCE:
163
				return 'r';
164
			default:
165
				// @codeCoverageIgnoreStart
166
				throw new LogicException(
167
					'Unknown context type ' . $contextType
168
				);
169
				// @codeCoverageIgnoreEnd
170
		}
171
	}
172
173
	/**
174
	 * @param string[] $contextTypeList Context::TYPE_* constants
175
	 * @return string[] abbreviated context types
176
	 */
177
	private function serializeContextTypeList( array $contextTypeList ) {
178
		return array_map( [ $this, 'serializeContextType' ], $contextTypeList );
179
	}
180
181
	/**
182
	 * @param MultilingualTextValue $text
183
	 * @return mixed {@see MultilingualTextValue::getArrayValue}
184
	 */
185
	private function serializeMultilingualText( MultilingualTextValue $text ) {
186
		return $text->getArrayValue();
187
	}
188
189
}
190