Completed
Push — master ( db833a...340657 )
by
unknown
04:20
created

ViolationMessage::getMessageKey()   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 0
1
<?php
2
3
namespace WikibaseQuality\ConstraintReport\ConstraintCheck\Message;
4
5
use DataValues\DataValue;
6
use DataValues\MultilingualTextValue;
7
use InvalidArgumentException;
8
use Wikibase\DataModel\Entity\EntityId;
9
use WikibaseQuality\ConstraintReport\ConstraintCheck\ItemIdSnakValue;
10
11
/**
12
 * A violation message of a constraint check.
13
 *
14
 * A ViolationMessage object is immutable:
15
 * operations like {@link withEntityId} return a modified copy.
16
 *
17
 * @license GPL-2.0-or-later
18
 */
19
class ViolationMessage {
20
21
	/**
22
	 * @private
23
	 */
24
	const MESSAGE_KEY_PREFIX = 'wbqc-violation-message-';
25
26
	/**
27
	 * Argument type for a single entity ID.
28
	 * Value type: {@link EntityId}
29
	 */
30
	const TYPE_ENTITY_ID = 'e';
31
32
	/**
33
	 * Argument type for a list of entity IDs.
34
	 * Value type: {@link EntityId}[]
35
	 */
36
	const TYPE_ENTITY_ID_LIST = 'E';
37
38
	/**
39
	 * Argument type for an item ID, “unknown value”, or “no value”.
40
	 * Value type: {@link ItemIdSnakValue}
41
	 */
42
	const TYPE_ITEM_ID_SNAK_VALUE = 'i';
43
44
	/**
45
	 * Argument type for a list of item IDs, “unknown value”s, or “no value”s.
46
	 * Value type: {@link ItemIdSnakValue}[]
47
	 */
48
	const TYPE_ITEM_ID_SNAK_VALUE_LIST = 'I';
49
50
	/**
51
	 * Argument type for a single data value.
52
	 * Value type: {@link DataValue}
53
	 */
54
	const TYPE_DATA_VALUE = 'v';
55
56
	/**
57
	 * Argument type for a data value type, like "time" or "wikibase-entityid".
58
	 * (Not to be confused with a data type, like "time" or "wikibase-item".)
59
	 * Value type: string
60
	 */
61
	const TYPE_DATA_VALUE_TYPE = 't';
62
63
	/**
64
	 * Argument type for a short fragment of inline computer code.
65
	 * Value type: string
66
	 */
67
	const TYPE_INLINE_CODE = 'c';
68
69
	/**
70
	 * Argument type for a single constraint scope.
71
	 * Value type: string (one of the Context::TYPE_* constants)
72
	 */
73
	const TYPE_CONSTRAINT_SCOPE = 's';
74
75
	/**
76
	 * Argument type for a list of constraint scopes.
77
	 * Value type: string[]
78
	 */
79
	const TYPE_CONSTRAINT_SCOPE_LIST = 'S';
80
81
	/**
82
	 * Argument type for a single property scope.
83
	 * Value type: string (one of the Context::TYPE_* constants)
84
	 */
85
	const TYPE_PROPERTY_SCOPE = 'p';
86
87
	/**
88
	 * Argument type for a list of property scopes.
89
	 * Value type: string[]
90
	 */
91
	const TYPE_PROPERTY_SCOPE_LIST = 'P';
92
93
	/**
94
	 * Argument type for a language.
95
	 * Value type: string (language code)
96
	 */
97
	const TYPE_LANGUAGE = 'l';
98
99
	/**
100
	 * Argument type for a multilingual text value.
101
	 * Value type: {@link MultilingualTextValue}
102
	 */
103
	const TYPE_MULTILINGUAL_TEXT = 'm';
104
105
	/**
106
	 * @var string
107
	 */
108
	private $messageKeySuffix;
109
110
	/**
111
	 * @var array[]
112
	 */
113
	private $arguments;
114
115
	/**
116
	 * @param string $messageKey The full message key. Must start with 'wbqc-violation-message-'.
117
	 * (We require callers to specify the full message key
118
	 * so that it’s easy to search for code that produces a given message.)
119
	 *
120
	 * @throws InvalidArgumentException If the message key is invalid.
121
	 */
122
	public function __construct(
123
		$messageKey
124
	) {
125
		if ( strpos( $messageKey, self::MESSAGE_KEY_PREFIX ) !== 0 ) {
126
			throw new InvalidArgumentException(
127
				'ViolationMessage key ⧼' .
128
				$messageKey .
129
				'⧽ should start with "' .
130
				self::MESSAGE_KEY_PREFIX .
131
				'".'
132
			);
133
		}
134
135
		$this->messageKeySuffix = substr( $messageKey, strlen( self::MESSAGE_KEY_PREFIX ) );
136
		$this->arguments = [];
137
	}
138
139
	/**
140
	 * Get the full message key of this message.
141
	 * @return string
142
	 */
143
	public function getMessageKey() {
144
		return self::MESSAGE_KEY_PREFIX . $this->messageKeySuffix;
145
	}
146
147
	/**
148
	 * Get the arguments to this message,
149
	 * a list of [ 'type' => self::TYPE_*, 'role' => Role::*, 'value' => $value ] elements.
150
	 * @return array[]
151
	 */
152
	public function getArguments() {
153
		return $this->arguments;
154
	}
155
156
	/**
157
	 * Note: usually you don’t want to use this function directly.
158
	 *
159
	 * @param string $type one of the self::TYPE_* constants
160
	 * @param string|null $role one of the Role::* constants
161
	 * @param mixed $value the value, which should match the $type
162
	 * @return ViolationMessage
163
	 */
164
	public function withArgument( $type, $role, $value ) {
165
		$ret = clone $this;
166
		$ret->arguments[] = [ 'type' => $type, 'role' => $role, 'value' => $value ];
167
		return $ret;
168
	}
169
170
	/**
171
	 * Append a single entity ID to the message arguments.
172
	 * (This operation returns a modified copy, the original object is unchanged.)
173
	 *
174
	 * @param EntityId $entityId
175
	 * @param string|null $role one of the Role::* constants
176
	 * @return ViolationMessage
177
	 */
178
	public function withEntityId( EntityId $entityId, $role = null ) {
179
		return $this->withArgument( self::TYPE_ENTITY_ID, $role, $entityId );
180
	}
181
182
	/**
183
	 * Append a list of entity IDs to the message arguments.
184
	 * (This operation returns a modified copy, the original object is unchanged.)
185
	 *
186
	 * This is not the same as appending the list elements individually with {@link withEntityId}!
187
	 * In the final message, this corresponds to
188
	 * one parameter for the number of list elements,
189
	 * one parameter with an HTML list of the list elements,
190
	 * and then one parameter per entity ID.
191
	 *
192
	 * @param EntityId[] $entityIdList
193
	 * @param string|null $role one of the Role::* constants
194
	 * @return ViolationMessage
195
	 */
196
	public function withEntityIdList( array $entityIdList, $role = null ) {
197
		return $this->withArgument( self::TYPE_ENTITY_ID_LIST, $role, $entityIdList );
198
	}
199
200
	/**
201
	 * Append a single item ID, “unknown value”, or “no value” to the message arguments.
202
	 * (This operation returns a modified copy, the original object is unchanged.)
203
	 *
204
	 * @param ItemIdSnakValue $value
205
	 * @param string|null $role one of the Role::* constants
206
	 * @return ViolationMessage
207
	 */
208
	public function withItemIdSnakValue( ItemIdSnakValue $value, $role = null ) {
209
		return $this->withArgument( self::TYPE_ITEM_ID_SNAK_VALUE, $role, $value );
210
	}
211
212
	/**
213
	 * Append a list of item IDs, “unknown value”s, or “no value”s to the message arguments.
214
	 * (This operation returns a modified copy, the original object is unchanged.)
215
	 *
216
	 * This is not the same as appending the list elements individually with {@link withItemIdSnakValue}!
217
	 * In the final message, this corresponds to
218
	 * one parameter for the number of list elements,
219
	 * one parameter with an HTML list of the list elements,
220
	 * and then one parameter per value.
221
	 *
222
	 * @param ItemIdSnakValue[] $valueList
223
	 * @param string|null $role one of the Role::* constants
224
	 * @return ViolationMessage
225
	 */
226
	public function withItemIdSnakValueList( array $valueList, $role = null ) {
227
		return $this->withArgument( self::TYPE_ITEM_ID_SNAK_VALUE_LIST, $role, $valueList );
228
	}
229
230
	/**
231
	 * Append a single data value to the message arguments.
232
	 * (This operation returns a modified copy, the original object is unchanged.)
233
	 *
234
	 * @param DataValue $dataValue
235
	 * @param string|null $role one of the Role::* constants
236
	 * @return ViolationMessage
237
	 */
238
	public function withDataValue( DataValue $dataValue, $role = null ) {
239
		return $this->withArgument( self::TYPE_DATA_VALUE, $role, $dataValue );
240
	}
241
242
	/**
243
	 * Append a single data value type, like "time" or "wikibase-entityid".
244
	 * (This operation returns a modified copy, the original object is unchanged.)
245
	 *
246
	 * Data value types should not be confused with data types, like "time" or "wikibase-item".
247
	 * For example, "wikibase-entityid" is the data value type
248
	 * used by the data types "wikibase-item" and "wikibase-property".
249
	 *
250
	 * @param string $dataValueType
251
	 * @param string|null $role one of the Role::* constants
252
	 * @return ViolationMessage
253
	 */
254
	public function withDataValueType( $dataValueType, $role = null ) {
255
		return $this->withArgument( self::TYPE_DATA_VALUE_TYPE, $role, $dataValueType );
256
	}
257
258
	/**
259
	 * Append a single short fragment of inline computer code to the message arguments.
260
	 * (This operation returns a modified copy, the original object is unchanged.)
261
	 *
262
	 * @param string $code
263
	 * @param string|null $role one of the Role::* constants
264
	 * @return ViolationMessage
265
	 */
266
	public function withInlineCode( $code, $role = null ) {
267
		return $this->withArgument( self::TYPE_INLINE_CODE, $role, $code );
268
	}
269
270
	/**
271
	 * Append a single constraint scope to the message arguments.
272
	 * (This operation returns a modified copy, the original object is unchanged.)
273
	 *
274
	 * @param string $scope one of the Context::TYPE_* constants
275
	 * @param string|null $role one of the Role::* constants
276
	 * @return ViolationMessage
277
	 */
278
	public function withConstraintScope( $scope, $role = null ) {
279
		return $this->withArgument( self::TYPE_CONSTRAINT_SCOPE, $role, $scope );
280
	}
281
282
	/**
283
	 * Append a list of constraint scopes to the message arguments.
284
	 * (This operation returns a modified copy, the original object is unchanged.)
285
	 *
286
	 * @param string[] $scopeList Role::* constants
287
	 * @param string|null $role one of the Role::* constants
288
	 * @return ViolationMessage
289
	 */
290
	public function withConstraintScopeList( array $scopeList, $role = null ) {
291
		return $this->withArgument( self::TYPE_CONSTRAINT_SCOPE_LIST, $role, $scopeList );
292
	}
293
294
	/**
295
	 * Append a single property scope to the message arguments.
296
	 * (This operation returns a modified copy, the original object is unchanged.)
297
	 *
298
	 * @param string $scope one of the Context::TYPE_* constants
299
	 * @param string|null $role one of the Role::* constants
300
	 * @return ViolationMessage
301
	 */
302
	public function withPropertyScope( $scope, $role = null ) {
303
		return $this->withArgument( self::TYPE_PROPERTY_SCOPE, $role, $scope );
304
	}
305
306
	/**
307
	 * Append a list of property scopes to the message arguments.
308
	 * (This operation returns a modified copy, the original object is unchanged.)
309
	 *
310
	 * @param string[] $scopeList Role::* constants
311
	 * @param string|null $role one of the Role::* constants
312
	 * @return ViolationMessage
313
	 */
314
	public function withPropertyScopeList( array $scopeList, $role = null ) {
315
		return $this->withArgument( self::TYPE_PROPERTY_SCOPE_LIST, $role, $scopeList );
316
	}
317
318
	/**
319
	 * Append a single language to the message arguments.
320
	 * (This operation returns a modified copy, the original object is unchanged.)
321
	 *
322
	 * One language argument corresponds to two params in the final message,
323
	 * one for the language name (autonym) and one for the language code.
324
	 *
325
	 * (Language arguments do not support roles.)
326
	 *
327
	 * @param string $languageCode
328
	 * @return ViolationMessage
329
	 */
330
	public function withLanguage( $languageCode ) {
331
		return $this->withArgument( self::TYPE_LANGUAGE, null, $languageCode );
332
	}
333
334
	/**
335
	 * Append a multilingual text value to the message arguments.
336
	 * (This operation returns a modified copy, the original object is unchanged.)
337
	 *
338
	 * Note that multilingual text arguments can only be rendered for specific message keys
339
	 * (see {@link MultilingualTextViolationMessageRenderer} for details),
340
	 * but this method does not verify whether you’re using one of those message keys.
341
	 *
342
	 * @param MultilingualTextValue $text
343
	 * @param string|null $role one of the Role::* constants
344
	 * @return ViolationMessage
345
	 */
346
	public function withMultilingualText( MultilingualTextValue $text, $role = null ) {
347
		return $this->withArgument( self::TYPE_MULTILINGUAL_TEXT, $role, $text );
348
	}
349
350
}
351