MediaWiki master
ExpiryDef.php
Go to the documentation of this file.
1<?php
2
4
5use InvalidArgumentException;
10use Wikimedia\Timestamp\ConvertibleTimestamp;
11
17class ExpiryDef extends TypeDef {
18
20 public const INFINITY_VALS = [ 'infinite', 'indefinite', 'infinity', 'never' ];
21
28 public const PARAM_USE_MAX = 'param-use-max';
29
33 public const PARAM_MAX = 'param-max';
34
35 public function validate( $name, $value, array $settings, array $options ) {
36 $this->failIfNotString( $name, $value, $settings, $options );
37
38 try {
39 $expiry = self::normalizeExpiry( $value, TS_ISO_8601 );
40 } catch ( InvalidArgumentException $e ) {
41 $this->failure( 'badexpiry', $name, $value, $settings, $options );
42 }
43
44 if ( $expiry !== 'infinity' && $expiry < ConvertibleTimestamp::now( TS_ISO_8601 ) ) {
45 $this->failure( 'badexpiry-past', $name, $value, $settings, $options );
46 }
47
48 $max = $settings[self::PARAM_MAX] ?? null;
49
50 if ( self::expiryExceedsMax( $expiry, $max ) ) {
51 $dontUseMax = empty( $settings[self::PARAM_USE_MAX] );
52 // Show warning that expiry exceeds the max, and that the max is being used instead.
53 $msg = DataMessageValue::new(
54 $dontUseMax
55 ? 'paramvalidator-badexpiry-duration'
56 : 'paramvalidator-badexpiry-duration-max',
57 [ $max ]
58 );
59 $this->failure( $msg, $name, $value, $settings, $options, $dontUseMax );
60
61 return self::normalizeExpiry( $max, TS_ISO_8601 );
62 }
63
64 return $expiry;
65 }
66
67 public function getHelpInfo( $name, array $settings, array $options ) {
68 $info = parent::getHelpInfo( $name, $settings, $options );
69
70 $info[ParamValidator::PARAM_TYPE] = MessageValue::new( 'paramvalidator-help-type-expiry' )
71 ->params( empty( $settings[ParamValidator::PARAM_ISMULTI] ) ? 1 : 2 )
72 ->textListParams(
73 // Should be quoted or monospace for presentation purposes,
74 // but textListParams() doesn't do this.
75 array_map( static function ( $val ) {
76 return "\"$val\"";
77 }, self::INFINITY_VALS )
78 );
79
80 return $info;
81 }
82
94 public static function normalizeExpiry( ?string $expiry = null, ?int $style = null ) {
95 if ( $expiry === null ) {
96 return null;
97 }
98 if ( in_array( $expiry, self::INFINITY_VALS, true ) ) {
99 return 'infinity';
100 }
101
102 // ConvertibleTimestamp::time() used so we can fake the current time in ExpiryDefTest.
103 $unix = strtotime( $expiry, ConvertibleTimestamp::time() );
104 if ( $unix === false ) {
105 // Invalid expiry.
106 throw new InvalidArgumentException( "Invalid expiry value: {$expiry}" );
107 }
108
109 // Don't pass 0, since ConvertibleTimestamp interprets that to mean the current timestamp.
110 // '00' does the right thing. Without this check, calling normalizeExpiry()
111 // with 1970-01-01T00:00:00Z incorrectly returns the current time.
112 $expiryConvertibleTimestamp = new ConvertibleTimestamp( $unix === 0 ? '00' : $unix );
113
114 if ( $style !== null ) {
115 return $expiryConvertibleTimestamp->getTimestamp( $style );
116 }
117
118 return $expiryConvertibleTimestamp;
119 }
120
130 public static function normalizeUsingMaxExpiry( ?string $expiry, ?string $maxExpiryDuration, ?int $style ) {
131 if ( self::expiryExceedsMax( $expiry, $maxExpiryDuration ) ) {
132 return self::normalizeExpiry( $maxExpiryDuration, $style );
133 }
134 return self::normalizeExpiry( $expiry, $style );
135 }
136
137 public function checkSettings( string $name, $settings, array $options, array $ret ): array {
138 $ret = parent::checkSettings( $name, $settings, $options, $ret );
139
140 $ret['allowedKeys'][] = self::PARAM_USE_MAX;
141 $ret['allowedKeys'][] = self::PARAM_MAX;
142
143 return $ret;
144 }
145
153 private static function expiryExceedsMax( ?string $expiry, ?string $max = null ): bool {
154 $expiry = self::normalizeExpiry( $expiry );
155 $max = self::normalizeExpiry( $max );
156
157 if ( !$max || !$expiry || $expiry === 'infinity' ) {
158 // Either there is no max or given expiry was invalid.
159 return false;
160 }
161
162 return $expiry > $max;
163 }
164
165}
Value object representing a message for i18n with alternative machine-readable data.
Value object representing a message for i18n.
Service for formatting and validating API parameters.
const PARAM_ISMULTI
(bool) Indicate that the parameter is multi-valued.
const PARAM_TYPE
(string|array) Type of the parameter.
Type definition for expiry timestamps.
Definition ExpiryDef.php:17
validate( $name, $value, array $settings, array $options)
Validate the value.
Definition ExpiryDef.php:35
static normalizeExpiry(?string $expiry=null, ?int $style=null)
Normalize a user-inputted expiry in ConvertibleTimestamp.
Definition ExpiryDef.php:94
static normalizeUsingMaxExpiry(?string $expiry, ?string $maxExpiryDuration, ?int $style)
Returns a normalized expiry or the max expiry if the given expiry exceeds it.
const PARAM_MAX
(int|float) Maximum non-infinity duration.
Definition ExpiryDef.php:33
checkSettings(string $name, $settings, array $options, array $ret)
Validate a parameter settings array.
const PARAM_USE_MAX
(bool) If truthy, the value given for the PARAM_MAX setting is used if the provided expiry exceeds it...
Definition ExpiryDef.php:28
getHelpInfo( $name, array $settings, array $options)
Describe parameter settings in human-readable format.
Definition ExpiryDef.php:67
Base definition for ParamValidator types.
Definition TypeDef.php:19
failIfNotString(string $name, $value, array $settings, array $options)
Fails if $value is not a string.
Definition TypeDef.php:68
failure( $failure, $name, $value, array $settings, array $options, $fatal=true)
Record a failure message.
Definition TypeDef.php:121