File: TypeDef.php

package info (click to toggle)
mediawiki 1%3A1.43.3%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 417,464 kB
  • sloc: php: 1,062,949; javascript: 664,290; sql: 9,714; python: 5,458; xml: 3,489; sh: 1,131; makefile: 64
file content (330 lines) | stat: -rw-r--r-- 11,295 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
<?php

namespace Wikimedia\ParamValidator;

use Wikimedia\Message\DataMessageValue;
use Wikimedia\Message\MessageValue;

/**
 * Base definition for ParamValidator types.
 *
 * Most methods in this class accept an "options array". This is just the `$options`
 * passed to ParamValidator::getValue(), ParamValidator::validateValue(), and the like
 * and is intended for communication of non-global state to the Callbacks.
 *
 * @since 1.34
 * @unstable for use in extensions. Intended to become stable to extend, at
 *           least for use in MediaWiki, which already defines some subclasses.
 */
abstract class TypeDef {

	/**
	 * @unstable Temporarily log warnings to detect misbehaving clients (T305973)
	 */
	public const OPT_LOG_BAD_TYPES = 'log-bad-types';

	/**
	 * Option that instructs TypeDefs to enforce the native type of parameter
	 * values, instead of allowing string values as input. This is intended for
	 * use with values coming from a JSON request body, and may accommodate for
	 * differences between the type system of PHP and JSON.
	 */
	public const OPT_ENFORCE_JSON_TYPES = 'enforce-json-types';

	/** @var Callbacks */
	protected $callbacks;

	/**
	 * @stable to call
	 *
	 * @param Callbacks $callbacks
	 */
	public function __construct( Callbacks $callbacks ) {
		$this->callbacks = $callbacks;
	}

	/**
	 * Whether the value may be an array.
	 * Note that this is different from multi-value.
	 * This should only return true if each value can be an array.
	 * @since 1.41
	 * @stable to override
	 * @return bool
	 */
	public function supportsArrays() {
		return false;
	}

	/**
	 * Fails if $value is not a string.
	 *
	 * @param string $name Parameter name being validated.
	 * @param mixed $value Value being validated.
	 * @param array $settings Parameter settings array.
	 * @param array $options Options array.
	 *
	 * @return void
	 */
	protected function failIfNotString(
		string $name,
		$value,
		array $settings,
		array $options
	): void {
		if ( !is_string( $value ) ) {
			$this->fatal(
				$this->failureMessage( 'needstring' )
					->params( gettype( $value ) ),
				$name, $value, $settings, $options
			);
		}
	}

	/**
	 * Throw a ValidationException.
	 * This is a wrapper for failure() which explicitly declares that it
	 * never returns, which is useful to static analysis tools like Phan.
	 *
	 * Note that parameters for `$name` and `$value` are always added as `$1`
	 * and `$2`.
	 *
	 * @param DataMessageValue|string $failure Failure code or message.
	 * @param string $name Parameter name being validated.
	 * @param mixed $value Value being validated.
	 * @param array $settings Parameter settings array.
	 * @param array $options Options array.
	 * @return never
	 * @throws ValidationException always
	 */
	protected function fatal(
		$failure, $name, $value, array $settings, array $options
	) {
		$this->failure( $failure, $name, $value, $settings, $options );
	}

	/**
	 * Record a failure message
	 *
	 * Depending on `$fatal`, this will either throw a ValidationException or
	 * call $this->callbacks->recordCondition().
	 *
	 * Note that parameters for `$name` and `$value` are always added as `$1`
	 * and `$2`.
	 *
	 * @param DataMessageValue|string $failure Failure code or message.
	 * @param string $name Parameter name being validated.
	 * @param mixed $value Value being validated.
	 * @param array $settings Parameter settings array.
	 * @param array $options Options array.
	 * @param bool $fatal Whether the failure is fatal
	 */
	protected function failure(
		$failure, $name, $value, array $settings, array $options, $fatal = true
	) {
		if ( !is_string( $value ) ) {
			$value = (string)$this->stringifyValue( $name, $value, $settings, $options );
		}

		if ( is_string( $failure ) ) {
			$mv = $this->failureMessage( $failure )
				->plaintextParams( $name, $value );
		} else {
			$mv = DataMessageValue::new( $failure->getKey(), [], $failure->getCode(), $failure->getData() )
				->plaintextParams( $name, $value )
				->params( ...$failure->getParams() );
		}

		if ( $fatal ) {
			throw new ValidationException( $mv, $name, $value, $settings );
		}
		$this->callbacks->recordCondition( $mv, $name, $value, $settings, $options );
	}

	/**
	 * Create a DataMessageValue representing a failure
	 *
	 * The message key will be "paramvalidator-$code" or "paramvalidator-$code-$suffix".
	 *
	 * Use DataMessageValue's param mutators to add additional MessageParams.
	 * Note that `failure()` will prepend parameters for `$name` and `$value`.
	 *
	 * @param string $code Failure code.
	 * @param array|null $data Failure data.
	 * @param string|null $suffix Suffix to append when producing the message key
	 * @return DataMessageValue
	 */
	protected function failureMessage( $code, ?array $data = null, $suffix = null ): DataMessageValue {
		return DataMessageValue::new(
			"paramvalidator-$code" . ( $suffix !== null ? "-$suffix" : '' ),
			[], $code, $data
		);
	}

	/**
	 * Get the value from the request
	 * @stable to override
	 *
	 * @note Only override this if you need to use something other than
	 *  $this->callbacks->getValue() to fetch the value. Reformatting from a
	 *  string should typically be done by self::validate().
	 * @note Handling of ParamValidator::PARAM_DEFAULT should be left to ParamValidator,
	 *  as should PARAM_REQUIRED and the like.
	 *
	 * @param string $name Parameter name being fetched.
	 * @param array $settings Parameter settings array.
	 * @param array $options Options array.
	 * @return null|mixed Return null if the value wasn't present, otherwise a
	 *  value to be passed to self::validate().
	 */
	public function getValue( $name, array $settings, array $options ) {
		return $this->callbacks->getValue( $name, null, $options );
	}

	/**
	 * Validate the value
	 *
	 * When ParamValidator is processing a multi-valued parameter, this will be
	 * called once for each of the supplied values. Which may mean zero calls.
	 *
	 * When getValue() returned null, this will not be called.
	 *
	 * @param string $name Parameter name being validated.
	 * @param mixed $value Value to validate, from getValue().
	 * @param array $settings Parameter settings array.
	 * @param array $options Options array. Note the following values that may be set
	 *  by ParamValidator:
	 *   - is-default: (bool) If present and true, the value was taken from PARAM_DEFAULT rather
	 *     that being supplied by the client.
	 *   - values-list: (string[]) If defined, values of a multi-valued parameter are being processed
	 *     (and this array holds the full set of values).
	 * @return mixed Validated value
	 * @throws ValidationException if the value is invalid
	 */
	abstract public function validate( $name, $value, array $settings, array $options );

	/**
	 * Normalize a settings array
	 * @stable to override
	 * @param array $settings
	 * @return array
	 */
	public function normalizeSettings( array $settings ) {
		return $settings;
	}

	/**
	 * Validate a parameter settings array
	 *
	 * This is intended for validation of parameter settings during unit or
	 * integration testing, and should implement strict checks.
	 *
	 * The rest of the code should generally be more permissive.
	 *
	 * @see ParamValidator::checkSettings()
	 * @stable to override
	 *
	 * @param string $name Parameter name
	 * @param array|mixed $settings Default value or an array of settings
	 *  using PARAM_* constants.
	 * @param array $options Options array, passed through to the TypeDef and Callbacks.
	 * @param array $ret
	 *  - 'issues': (string[]) Errors detected in $settings, as English text. If the settings
	 *    are valid, this will be the empty array. Keys on input are ParamValidator constants,
	 *    allowing the typedef to easily override core validation; this need not be preserved
	 *    when returned.
	 *  - 'allowedKeys': (string[]) ParamValidator keys that are allowed in `$settings`.
	 *  - 'messages': (MessageValue[]) Messages to be checked for existence.
	 * @return array $ret, with any relevant changes.
	 */
	public function checkSettings( string $name, $settings, array $options, array $ret ): array {
		return $ret;
	}

	/**
	 * Get the values for enum-like parameters
	 *
	 * This is primarily intended for documentation and implementation of
	 * PARAM_ALL; it is the responsibility of the TypeDef to ensure that validate()
	 * accepts the values returned here.
	 * @stable to override
	 *
	 * @param string $name Parameter name being validated.
	 * @param array $settings Parameter settings array.
	 * @param array $options Options array.
	 * @return array|null All possible enumerated values, or null if this is
	 *  not an enumeration.
	 */
	public function getEnumValues( $name, array $settings, array $options ) {
		return null;
	}

	/**
	 * Convert a value to a string representation.
	 *
	 * This is intended as the inverse of getValue() and validate(): this
	 * should accept anything returned by those methods or expected to be used
	 * as PARAM_DEFAULT, and if the string from this method is passed in as client
	 * input or PARAM_DEFAULT it should give equivalent output from validate().
	 *
	 * @param string $name Parameter name being converted.
	 * @param mixed $value Parameter value being converted. Do not pass null.
	 * @param array $settings Parameter settings array.
	 * @param array $options Options array.
	 * @return string|null Return null if there is no representation of $value
	 *  reasonably satisfying the description given.
	 */
	public function stringifyValue( $name, $value, array $settings, array $options ) {
		if ( is_array( $value ) ) {
			return '(array)';
		}

		return (string)$value;
	}

	/**
	 * Describe parameter settings in a machine-readable format.
	 *
	 * Keys should be short strings using lowercase ASCII letters. Values
	 * should generally be values that could be encoded in JSON or the like.
	 *
	 * This is intended to handle PARAM constants specific to this class. It
	 * generally shouldn't handle constants defined on ParamValidator itself.
	 * @stable to override
	 *
	 * @param string $name Parameter name.
	 * @param array $settings Parameter settings array.
	 * @param array $options Options array.
	 * @return array
	 */
	public function getParamInfo( $name, array $settings, array $options ) {
		return [];
	}

	/**
	 * Describe parameter settings in human-readable format
	 *
	 * Keys in the returned array should generally correspond to PARAM
	 * constants.
	 *
	 * If relevant, a MessageValue describing the type itself should be
	 * returned with key ParamValidator::PARAM_TYPE.
	 *
	 * The default messages for other ParamValidator-defined PARAM constants
	 * may be suppressed by returning null as the value for those constants, or
	 * replaced by returning a replacement MessageValue. Normally, however,
	 * the default messages should not be changed.
	 *
	 * MessageValues describing any other constraints applied via PARAM
	 * constants specific to this class should also be returned.
	 * @stable to override
	 *
	 * @param string $name Parameter name being described.
	 * @param array $settings Parameter settings array.
	 * @param array $options Options array.
	 * @return (MessageValue|null)[]
	 */
	public function getHelpInfo( $name, array $settings, array $options ) {
		return [];
	}

}