MediaWiki master
ParamValidator.php
Go to the documentation of this file.
1<?php
2
4
5use DomainException;
6use InvalidArgumentException;
7use Wikimedia\Assert\Assert;
12use Wikimedia\ObjectFactory\ObjectFactory;
13
43
44 // region Constants for parameter settings arrays
68 public const PARAM_DEFAULT = 'param-default';
69
76 public const PARAM_TYPE = 'param-type';
77
84 public const PARAM_REQUIRED = 'param-required';
85
112 public const PARAM_ISMULTI = 'param-ismulti';
113
119 public const PARAM_ISMULTI_LIMIT1 = 'param-ismulti-limit1';
120
127 public const PARAM_ISMULTI_LIMIT2 = 'param-ismulti-limit2';
128
137 public const PARAM_ALL = 'param-all';
138
145 public const PARAM_ALLOW_DUPLICATES = 'param-allow-duplicates';
146
153 public const PARAM_SENSITIVE = 'param-sensitive';
154
161 public const PARAM_DEPRECATED = 'param-deprecated';
162
168 public const PARAM_IGNORE_UNRECOGNIZED_VALUES = 'param-ignore-unrecognized-values';
169
171 // endregion -- end of Constants for parameter settings arrays
172
174 public const ALL_DEFAULT_STRING = '*';
175
177 public static $STANDARD_TYPES = [
178 'boolean' => [ 'class' => TypeDef\BooleanDef::class ],
179 'checkbox' => [ 'class' => TypeDef\PresenceBooleanDef::class ],
180 'integer' => [ 'class' => TypeDef\IntegerDef::class ],
181 'limit' => [ 'class' => TypeDef\LimitDef::class ],
182 'float' => [ 'class' => TypeDef\FloatDef::class ],
183 'double' => [ 'class' => TypeDef\FloatDef::class ],
184 'string' => [ 'class' => TypeDef\StringDef::class ],
185 'password' => [ 'class' => TypeDef\PasswordDef::class ],
186 'NULL' => [
187 'class' => TypeDef\StringDef::class,
188 'args' => [ [
189 'allowEmptyWhenRequired' => true,
190 ] ],
191 ],
192 'timestamp' => [ 'class' => TypeDef\TimestampDef::class ],
193 'upload' => [ 'class' => TypeDef\UploadDef::class ],
194 'enum' => [ 'class' => TypeDef\EnumDef::class ],
195 'expiry' => [ 'class' => TypeDef\ExpiryDef::class ],
196 ];
197
199 private $callbacks;
200
202 private $objectFactory;
203
205 private $typeDefs = [];
206
208 private $ismultiLimit1;
209
211 private $ismultiLimit2;
212
222 public function __construct(
223 Callbacks $callbacks,
224 ObjectFactory $objectFactory,
225 array $options = []
226 ) {
227 $this->callbacks = $callbacks;
228 $this->objectFactory = $objectFactory;
229
230 $this->addTypeDefs( $options['typeDefs'] ?? self::$STANDARD_TYPES );
231 $this->ismultiLimit1 = $options['ismultiLimits'][0] ?? 50;
232 $this->ismultiLimit2 = $options['ismultiLimits'][1] ?? 500;
233 }
234
239 public function knownTypes() {
240 return array_keys( $this->typeDefs );
241 }
242
249 public function addTypeDefs( array $typeDefs ) {
250 foreach ( $typeDefs as $name => $def ) {
251 $this->addTypeDef( $name, $def );
252 }
253 }
254
268 public function addTypeDef( $name, $typeDef ) {
269 Assert::parameterType(
270 [ TypeDef::class, 'array' ],
271 $typeDef,
272 '$typeDef'
273 );
274
275 if ( isset( $this->typeDefs[$name] ) ) {
276 throw new InvalidArgumentException( "Type '$name' is already registered" );
277 }
278 $this->typeDefs[$name] = $typeDef;
279 }
280
287 public function overrideTypeDef( $name, $typeDef ) {
288 Assert::parameterType(
289 [ TypeDef::class, 'array', 'null' ],
290 $typeDef,
291 '$typeDef'
292 );
293
294 if ( $typeDef === null ) {
295 unset( $this->typeDefs[$name] );
296 } else {
297 $this->typeDefs[$name] = $typeDef;
298 }
299 }
300
306 public function hasTypeDef( $name ) {
307 return isset( $this->typeDefs[$name] );
308 }
309
315 public function getTypeDef( $type ) {
316 if ( is_array( $type ) ) {
317 $type = 'enum';
318 }
319
320 if ( !isset( $this->typeDefs[$type] ) ) {
321 return null;
322 }
323
324 $def = $this->typeDefs[$type];
325 if ( !$def instanceof TypeDef ) {
326 $def = $this->objectFactory->createObject( $def, [
327 'extraArgs' => [ $this->callbacks ],
328 'assertClass' => TypeDef::class,
329 ] );
330 $this->typeDefs[$type] = $def;
331 }
332
333 return $def;
334 }
335
341 private function normalizeSettingsInternal( $settings ) {
342 // Shorthand
343 if ( !is_array( $settings ) ) {
344 $settings = [
345 self::PARAM_DEFAULT => $settings,
346 ];
347 }
348
349 // When type is not given, determine it from the type of the PARAM_DEFAULT
350 if ( !isset( $settings[self::PARAM_TYPE] ) ) {
351 $settings[self::PARAM_TYPE] = gettype( $settings[self::PARAM_DEFAULT] ?? null );
352 }
353
354 return $settings;
355 }
356
363 public function normalizeSettings( $settings ) {
364 $settings = $this->normalizeSettingsInternal( $settings );
365
366 $typeDef = $this->getTypeDef( $settings[self::PARAM_TYPE] );
367 if ( $typeDef ) {
368 $settings = $typeDef->normalizeSettings( $settings );
369 }
370
371 return $settings;
372 }
373
392 public function checkSettings( string $name, $settings, array $options ): array {
393 $settings = $this->normalizeSettingsInternal( $settings );
394 $issues = [];
395 $allowedKeys = [
398 ];
399 $messages = [];
400
401 $type = $settings[self::PARAM_TYPE];
402 $typeDef = null;
403 if ( !is_string( $type ) && !is_array( $type ) ) {
404 $issues[self::PARAM_TYPE] = 'PARAM_TYPE must be a string or array, got ' . gettype( $type );
405 } else {
406 $typeDef = $this->getTypeDef( $settings[self::PARAM_TYPE] );
407 if ( !$typeDef ) {
408 if ( is_array( $type ) ) {
409 $type = 'enum';
410 }
411 $issues[self::PARAM_TYPE] = "Unknown/unregistered PARAM_TYPE \"$type\"";
412 }
413 }
414
415 if ( isset( $settings[self::PARAM_DEFAULT] ) ) {
416 try {
417 $this->validateValue(
418 $name, $settings[self::PARAM_DEFAULT], $settings, [ 'is-default' => true ] + $options
419 );
420 } catch ( ValidationException $ex ) {
421 $issues[self::PARAM_DEFAULT] = 'Value for PARAM_DEFAULT does not validate (code '
422 . $ex->getFailureMessage()->getCode() . ')';
423 }
424 }
425
426 if ( !is_bool( $settings[self::PARAM_REQUIRED] ?? false ) ) {
427 $issues[self::PARAM_REQUIRED] = 'PARAM_REQUIRED must be boolean, got '
428 . gettype( $settings[self::PARAM_REQUIRED] );
429 }
430
431 if ( !is_bool( $settings[self::PARAM_ISMULTI] ?? false ) ) {
432 $issues[self::PARAM_ISMULTI] = 'PARAM_ISMULTI must be boolean, got '
433 . gettype( $settings[self::PARAM_ISMULTI] );
434 }
435
436 if ( !empty( $settings[self::PARAM_ISMULTI] ) ) {
437 $allowedKeys = array_merge( $allowedKeys, [
438 self::PARAM_ISMULTI_LIMIT1, self::PARAM_ISMULTI_LIMIT2,
439 self::PARAM_ALL, self::PARAM_ALLOW_DUPLICATES
440 ] );
441
442 $limit1 = $settings[self::PARAM_ISMULTI_LIMIT1] ?? $this->ismultiLimit1;
443 $limit2 = $settings[self::PARAM_ISMULTI_LIMIT2] ?? $this->ismultiLimit2;
444 if ( !is_int( $limit1 ) ) {
445 $issues[self::PARAM_ISMULTI_LIMIT1] = 'PARAM_ISMULTI_LIMIT1 must be an integer, got '
446 . gettype( $settings[self::PARAM_ISMULTI_LIMIT1] );
447 } elseif ( $limit1 <= 0 ) {
449 "PARAM_ISMULTI_LIMIT1 must be greater than 0, got $limit1";
450 }
451 if ( !is_int( $limit2 ) ) {
452 $issues[self::PARAM_ISMULTI_LIMIT2] = 'PARAM_ISMULTI_LIMIT2 must be an integer, got '
453 . gettype( $settings[self::PARAM_ISMULTI_LIMIT2] );
454 } elseif ( $limit2 < $limit1 ) {
456 'PARAM_ISMULTI_LIMIT2 must be greater than or equal to PARAM_ISMULTI_LIMIT1, but '
457 . "$limit2 < $limit1";
458 }
459
460 $all = $settings[self::PARAM_ALL] ?? false;
461 if ( !is_string( $all ) && !is_bool( $all ) ) {
462 $issues[self::PARAM_ALL] = 'PARAM_ALL must be a string or boolean, got ' . gettype( $all );
463 } elseif ( $all !== false && $typeDef ) {
464 if ( $all === true ) {
466 }
467 $values = $typeDef->getEnumValues( $name, $settings, $options );
468 if ( !is_array( $values ) ) {
469 $issues[self::PARAM_ALL] = 'PARAM_ALL cannot be used with non-enumerated types';
470 } elseif ( in_array( $all, $values, true ) ) {
471 $issues[self::PARAM_ALL] = 'Value for PARAM_ALL conflicts with an enumerated value';
472 }
473 }
474
475 if ( !is_bool( $settings[self::PARAM_ALLOW_DUPLICATES] ?? false ) ) {
476 $issues[self::PARAM_ALLOW_DUPLICATES] = 'PARAM_ALLOW_DUPLICATES must be boolean, got '
477 . gettype( $settings[self::PARAM_ALLOW_DUPLICATES] );
478 }
479 }
480
481 if ( !is_bool( $settings[self::PARAM_SENSITIVE] ?? false ) ) {
482 $issues[self::PARAM_SENSITIVE] = 'PARAM_SENSITIVE must be boolean, got '
483 . gettype( $settings[self::PARAM_SENSITIVE] );
484 }
485
486 if ( !is_bool( $settings[self::PARAM_DEPRECATED] ?? false ) ) {
487 $issues[self::PARAM_DEPRECATED] = 'PARAM_DEPRECATED must be boolean, got '
488 . gettype( $settings[self::PARAM_DEPRECATED] );
489 }
490
491 if ( !is_bool( $settings[self::PARAM_IGNORE_UNRECOGNIZED_VALUES] ?? false ) ) {
492 $issues[self::PARAM_IGNORE_UNRECOGNIZED_VALUES] = 'PARAM_IGNORE_UNRECOGNIZED_VALUES must be '
493 . 'boolean, got ' . gettype( $settings[self::PARAM_IGNORE_UNRECOGNIZED_VALUES] );
494 }
495
496 $ret = [ 'issues' => $issues, 'allowedKeys' => $allowedKeys, 'messages' => $messages ];
497 if ( $typeDef ) {
498 $ret = $typeDef->checkSettings( $name, $settings, $options, $ret );
499 }
500
501 return $ret;
502 }
503
515 public function getValue( $name, $settings, array $options = [] ) {
516 $settings = $this->normalizeSettings( $settings );
517
518 $typeDef = $this->getTypeDef( $settings[self::PARAM_TYPE] );
519 if ( !$typeDef ) {
520 throw new DomainException(
521 "Param $name's type is unknown - {$settings[self::PARAM_TYPE]}"
522 );
523 }
524
525 $value = $typeDef->getValue( $name, $settings, $options );
526
527 if ( $value !== null ) {
528 if ( !empty( $settings[self::PARAM_SENSITIVE] ) ) {
529 $strValue = $typeDef->stringifyValue( $name, $value, $settings, $options );
530 $this->callbacks->recordCondition(
531 DataMessageValue::new( 'paramvalidator-param-sensitive', [], 'param-sensitive' )
532 ->plaintextParams( $name, $strValue ),
533 $name, $value, $settings, $options
534 );
535 }
536
537 // Set a warning if a deprecated parameter has been passed
538 if ( !empty( $settings[self::PARAM_DEPRECATED] ) ) {
539 $strValue = $typeDef->stringifyValue( $name, $value, $settings, $options );
540 $this->callbacks->recordCondition(
541 DataMessageValue::new( 'paramvalidator-param-deprecated', [], 'param-deprecated' )
542 ->plaintextParams( $name, $strValue ),
543 $name, $value, $settings, $options
544 );
545 }
546 } elseif ( isset( $settings[self::PARAM_DEFAULT] ) ) {
547 $value = $settings[self::PARAM_DEFAULT];
548 $options['is-default'] = true;
549 }
550
551 return $this->validateValue( $name, $value, $settings, $options );
552 }
553
567 public function validateValue( $name, $value, $settings, array $options = [] ) {
568 $settings = $this->normalizeSettings( $settings );
569
570 $typeDef = $this->getTypeDef( $settings[self::PARAM_TYPE] );
571 if ( !$typeDef ) {
572 throw new DomainException(
573 "Param $name's type is unknown - {$settings[self::PARAM_TYPE]}"
574 );
575 }
576
577 if ( $value === null ) {
578 if ( !empty( $settings[self::PARAM_REQUIRED] ) ) {
579 throw new ValidationException(
580 DataMessageValue::new( 'paramvalidator-missingparam', [], 'missingparam' )
581 ->plaintextParams( $name ),
582 $name, $value, $settings
583 );
584 }
585 return null;
586 }
587
588 // Non-multi
589 if ( empty( $settings[self::PARAM_ISMULTI] ) ) {
590 if ( is_string( $value ) && substr( $value, 0, 1 ) === "\x1f" ) {
591 throw new ValidationException(
592 DataMessageValue::new( 'paramvalidator-notmulti', [], 'badvalue' )
593 ->plaintextParams( $name, $value ),
594 $name, $value, $settings
595 );
596 }
597
598 // T326764: If the type of the actual param value is different from
599 // the type that is defined via getParamSettings(), throw an exception
600 // because this is a type to value mismatch.
601 if ( is_array( $value ) && !$typeDef->supportsArrays() ) {
602 throw new ValidationException(
603 DataMessageValue::new( 'paramvalidator-notmulti', [], 'badvalue' )
604 ->plaintextParams( $name, gettype( $value ) ),
605 $name, $value, $settings
606 );
607 }
608
609 return $typeDef->validate( $name, $value, $settings, $options );
610 }
611
612 // Split the multi-value and validate each parameter
613 $limit1 = $settings[self::PARAM_ISMULTI_LIMIT1] ?? $this->ismultiLimit1;
614 $limit2 = max( $limit1, $settings[self::PARAM_ISMULTI_LIMIT2] ?? $this->ismultiLimit2 );
615 $valuesList = is_array( $value ) ? $value : self::explodeMultiValue( $value, $limit2 + 1 );
616
617 // Handle PARAM_ALL
618 $enumValues = $typeDef->getEnumValues( $name, $settings, $options );
619 if ( is_array( $enumValues ) && isset( $settings[self::PARAM_ALL] ) &&
620 count( $valuesList ) === 1
621 ) {
622 $allValue = is_string( $settings[self::PARAM_ALL] )
623 ? $settings[self::PARAM_ALL]
624 : self::ALL_DEFAULT_STRING;
625 if ( $valuesList[0] === $allValue ) {
626 return $enumValues;
627 }
628 }
629
630 // Avoid checking useHighLimits() unless it's actually necessary
631 $sizeLimit = (
632 $limit2 > $limit1 && count( $valuesList ) > $limit1 &&
633 $this->callbacks->useHighLimits( $options )
634 ) ? $limit2 : $limit1;
635 if ( count( $valuesList ) > $sizeLimit ) {
636 throw new ValidationException(
637 DataMessageValue::new( 'paramvalidator-toomanyvalues', [], 'toomanyvalues', [
638 'parameter' => $name,
639 'limit' => $sizeLimit,
640 'lowlimit' => $limit1,
641 'highlimit' => $limit2,
642 ] )->plaintextParams( $name )->numParams( $sizeLimit ),
643 $name, $valuesList, $settings
644 );
645 }
646
647 $options['values-list'] = $valuesList;
648 $validValues = [];
649 $invalidValues = [];
650 foreach ( $valuesList as $v ) {
651 try {
652 $validValues[] = $typeDef->validate( $name, $v, $settings, $options );
653 } catch ( ValidationException $ex ) {
654 if ( $ex->getFailureMessage()->getCode() !== 'badvalue' ||
655 empty( $settings[self::PARAM_IGNORE_UNRECOGNIZED_VALUES] )
656 ) {
657 throw $ex;
658 }
659 $invalidValues[] = $v;
660 }
661 }
662 if ( $invalidValues ) {
663 if ( is_array( $value ) ) {
664 $value = self::implodeMultiValue( $value );
665 }
666 $this->callbacks->recordCondition(
667 DataMessageValue::new( 'paramvalidator-unrecognizedvalues', [], 'unrecognizedvalues', [
668 'values' => $invalidValues,
669 ] )
670 ->plaintextParams( $name, $value )
671 ->commaListParams( array_map( static function ( $v ) {
672 return new ScalarParam( ParamType::PLAINTEXT, $v );
673 }, $invalidValues ) )
674 ->numParams( count( $invalidValues ) ),
675 $name, $value, $settings, $options
676 );
677 }
678
679 // Throw out duplicates if requested
680 if ( empty( $settings[self::PARAM_ALLOW_DUPLICATES] ) ) {
681 $validValues = array_values( array_unique( $validValues ) );
682 }
683
684 return $validValues;
685 }
686
696 public function getParamInfo( $name, $settings, array $options ) {
697 $settings = $this->normalizeSettings( $settings );
698 $typeDef = $this->getTypeDef( $settings[self::PARAM_TYPE] );
699 $info = [];
700
701 $info['type'] = $settings[self::PARAM_TYPE];
702 $info['required'] = !empty( $settings[self::PARAM_REQUIRED] );
703 if ( !empty( $settings[self::PARAM_DEPRECATED] ) ) {
704 $info['deprecated'] = true;
705 }
706 if ( !empty( $settings[self::PARAM_SENSITIVE] ) ) {
707 $info['sensitive'] = true;
708 }
709 if ( isset( $settings[self::PARAM_DEFAULT] ) ) {
710 $info['default'] = $settings[self::PARAM_DEFAULT];
711 }
712 $info['multi'] = !empty( $settings[self::PARAM_ISMULTI] );
713 if ( $info['multi'] ) {
714 $info['lowlimit'] = $settings[self::PARAM_ISMULTI_LIMIT1] ?? $this->ismultiLimit1;
715 $info['highlimit'] = max(
716 $info['lowlimit'], $settings[self::PARAM_ISMULTI_LIMIT2] ?? $this->ismultiLimit2
717 );
718 $info['limit'] =
719 $info['highlimit'] > $info['lowlimit'] && $this->callbacks->useHighLimits( $options )
720 ? $info['highlimit']
721 : $info['lowlimit'];
722
723 if ( !empty( $settings[self::PARAM_ALLOW_DUPLICATES] ) ) {
724 $info['allowsduplicates'] = true;
725 }
726
727 $allSpecifier = $settings[self::PARAM_ALL] ?? false;
728 if ( $allSpecifier !== false ) {
729 if ( !is_string( $allSpecifier ) ) {
730 $allSpecifier = self::ALL_DEFAULT_STRING;
731 }
732 $info['allspecifier'] = $allSpecifier;
733 }
734 }
735
736 if ( $typeDef ) {
737 $info = array_merge( $info, $typeDef->getParamInfo( $name, $settings, $options ) );
738 }
739
740 // Filter out nulls (strictly)
741 return array_filter( $info, static function ( $v ) {
742 return $v !== null;
743 } );
744 }
745
755 public function getHelpInfo( $name, $settings, array $options ) {
756 $settings = $this->normalizeSettings( $settings );
757 $typeDef = $this->getTypeDef( $settings[self::PARAM_TYPE] );
758
759 // Define ordering. Some are overwritten below, some expected from the TypeDef
760 $info = [
761 self::PARAM_DEPRECATED => null,
762 self::PARAM_REQUIRED => null,
763 self::PARAM_SENSITIVE => null,
764 self::PARAM_TYPE => null,
765 self::PARAM_ISMULTI => null,
766 self::PARAM_ISMULTI_LIMIT1 => null,
767 self::PARAM_ALL => null,
768 self::PARAM_DEFAULT => null,
769 ];
770
771 if ( !empty( $settings[self::PARAM_DEPRECATED] ) ) {
772 $info[self::PARAM_DEPRECATED] = MessageValue::new( 'paramvalidator-help-deprecated' );
773 }
774
775 if ( !empty( $settings[self::PARAM_REQUIRED] ) ) {
776 $info[self::PARAM_REQUIRED] = MessageValue::new( 'paramvalidator-help-required' );
777 }
778
779 if ( !empty( $settings[self::PARAM_ISMULTI] ) ) {
780 $info[self::PARAM_ISMULTI] = MessageValue::new( 'paramvalidator-help-multi-separate' );
781
782 $lowcount = $settings[self::PARAM_ISMULTI_LIMIT1] ?? $this->ismultiLimit1;
783 $highcount = max( $lowcount, $settings[self::PARAM_ISMULTI_LIMIT2] ?? $this->ismultiLimit2 );
784 $values = $typeDef ? $typeDef->getEnumValues( $name, $settings, $options ) : null;
785 if (
786 // Only mention the limits if they're likely to matter.
787 $values === null || count( $values ) > $lowcount ||
788 !empty( $settings[self::PARAM_ALLOW_DUPLICATES] )
789 ) {
790 if ( $highcount > $lowcount ) {
791 $info[self::PARAM_ISMULTI_LIMIT1] = MessageValue::new( 'paramvalidator-help-multi-max' )
792 ->numParams( $lowcount, $highcount );
793 } else {
794 $info[self::PARAM_ISMULTI_LIMIT1] = MessageValue::new( 'paramvalidator-help-multi-max-simple' )
795 ->numParams( $lowcount );
796 }
797 }
798
799 $allSpecifier = $settings[self::PARAM_ALL] ?? false;
800 if ( $allSpecifier !== false ) {
801 if ( !is_string( $allSpecifier ) ) {
802 $allSpecifier = self::ALL_DEFAULT_STRING;
803 }
804 $info[self::PARAM_ALL] = MessageValue::new( 'paramvalidator-help-multi-all' )
805 ->plaintextParams( $allSpecifier );
806 }
807 }
808
809 if ( isset( $settings[self::PARAM_DEFAULT] ) && $typeDef ) {
810 $value = $typeDef->stringifyValue( $name, $settings[self::PARAM_DEFAULT], $settings, $options );
811 if ( $value === '' ) {
812 $info[self::PARAM_DEFAULT] = MessageValue::new( 'paramvalidator-help-default-empty' );
813 } elseif ( $value !== null ) {
814 $info[self::PARAM_DEFAULT] = MessageValue::new( 'paramvalidator-help-default' )
815 ->plaintextParams( $value );
816 }
817 }
818
819 if ( $typeDef ) {
820 $info = array_merge( $info, $typeDef->getHelpInfo( $name, $settings, $options ) );
821 }
822
823 // Put the default at the very end (the TypeDef may have added extra messages)
824 $default = $info[self::PARAM_DEFAULT];
825 unset( $info[self::PARAM_DEFAULT] );
826 $info[self::PARAM_DEFAULT] = $default;
827
828 // Filter out nulls
829 return array_filter( $info );
830 }
831
842 public static function explodeMultiValue( $value, $limit ) {
843 if ( $value === '' || $value === "\x1f" ) {
844 return [];
845 }
846
847 if ( substr( $value, 0, 1 ) === "\x1f" ) {
848 $sep = "\x1f";
849 $value = substr( $value, 1 );
850 } else {
851 $sep = '|';
852 }
853
854 return explode( $sep, $value, $limit );
855 }
856
863 public static function implodeMultiValue( array $value ) {
864 if ( $value === [ '' ] ) {
865 // There's no value that actually returns a single empty string.
866 // Best we can do is this that returns two, which will be deduplicated to one.
867 return '|';
868 }
869
870 foreach ( $value as $v ) {
871 if ( strpos( $v, '|' ) !== false ) {
872 return "\x1f" . implode( "\x1f", $value );
873 }
874 }
875 return implode( '|', $value );
876 }
877
878}
Value object representing a message for i18n with alternative machine-readable data.
Value object representing a message for i18n.
The constants used to specify parameter types.
Definition ParamType.php:11
const PLAINTEXT
A text parameter which is substituted after formatter processing.
Definition ParamType.php:97
Value object representing a message parameter holding a single value.
Service for formatting and validating API parameters.
__construct(Callbacks $callbacks, ObjectFactory $objectFactory, array $options=[])
getValue( $name, $settings, array $options=[])
Fetch and validate a parameter value using a settings array.
normalizeSettings( $settings)
Normalize a parameter settings array.
const PARAM_ALLOW_DUPLICATES
(bool) Allow the same value to be set more than once when PARAM_ISMULTI is true?
static $STANDARD_TYPES
A list of standard type names and types that may be passed as $typeDefs to __construct().
getTypeDef( $type)
Get the TypeDef for a type.
const PARAM_ISMULTI
(bool) Indicate that the parameter is multi-valued.
addTypeDefs(array $typeDefs)
Register multiple type handlers.
getParamInfo( $name, $settings, array $options)
Describe parameter settings in a machine-readable format.
hasTypeDef( $name)
Test if a type is registered.
const PARAM_ISMULTI_LIMIT2
(int) Maximum number of multi-valued parameter values allowed for users allowed high limits.
checkSettings(string $name, $settings, array $options)
Validate a parameter settings array.
const ALL_DEFAULT_STRING
Magic "all values" value when PARAM_ALL is true.
static implodeMultiValue(array $value)
Implode an array as a multi-valued parameter string, like implode()
validateValue( $name, $value, $settings, array $options=[])
Validate a parameter value using a settings array.
const PARAM_ISMULTI_LIMIT1
(int) Maximum number of multi-valued parameter values allowed
const PARAM_DEFAULT
(mixed) Default value of the parameter.
const PARAM_DEPRECATED
(bool) Indicate that a deprecated parameter was used.
const PARAM_TYPE
(string|array) Type of the parameter.
const PARAM_SENSITIVE
(bool) Indicate that the parameter's value should not be logged.
const PARAM_REQUIRED
(bool) Indicate that the parameter is required.
getHelpInfo( $name, $settings, array $options)
Describe parameter settings in human-readable format.
addTypeDef( $name, $typeDef)
Register a type handler.
static explodeMultiValue( $value, $limit)
Split a multi-valued parameter string, like explode()
const PARAM_IGNORE_UNRECOGNIZED_VALUES
(bool) Whether to downgrade "badvalue" errors to non-fatal when validating multi-valued parameters.
const PARAM_ALL
(bool|string) Whether a magic "all values" value exists for multi-valued enumerated types,...
overrideTypeDef( $name, $typeDef)
Register a type handler, overriding any existing handler.
Base definition for ParamValidator types.
Definition TypeDef.php:19
getFailureMessage()
Fetch the validation failure message.
Interface defining callbacks needed by ParamValidator.
Definition Callbacks.php:21