ParamValidator: Flag as unstable for 1.34
[lhc/web/wiklou.git] / includes / libs / ParamValidator / TypeDef / TimestampDef.php
1 <?php
2
3 namespace Wikimedia\ParamValidator\TypeDef;
4
5 use Wikimedia\ParamValidator\Callbacks;
6 use Wikimedia\ParamValidator\TypeDef;
7 use Wikimedia\ParamValidator\ValidationException;
8 use Wikimedia\Timestamp\ConvertibleTimestamp;
9 use Wikimedia\Timestamp\TimestampException;
10
11 /**
12 * Type definition for timestamp types
13 *
14 * This uses the wikimedia/timestamp library for parsing and formatting the
15 * timestamps.
16 *
17 * The result from validate() is a ConvertibleTimestamp by default, but this
18 * may be changed by both a constructor option and a PARAM constant.
19 *
20 * ValidationException codes:
21 * - 'badtimestamp': The timestamp is not valid. No data, but the
22 * TimestampException is available via Exception::getPrevious().
23 * - 'unclearnowtimestamp': Non-fatal. The value is the empty string or "0".
24 * Use 'now' instead if you really want the current timestamp. No data.
25 *
26 * @since 1.34
27 * @unstable
28 */
29 class TimestampDef extends TypeDef {
30
31 /**
32 * (string|int) Timestamp format to return from validate()
33 *
34 * Values include:
35 * - 'ConvertibleTimestamp': A ConvertibleTimestamp object.
36 * - 'DateTime': A PHP DateTime object
37 * - One of ConvertibleTimestamp's TS_* constants.
38 *
39 * This does not affect the format returned by stringifyValue().
40 */
41 const PARAM_TIMESTAMP_FORMAT = 'param-timestamp-format';
42
43 /** @var string|int */
44 protected $defaultFormat;
45
46 /** @var int */
47 protected $stringifyFormat;
48
49 /**
50 * @param Callbacks $callbacks
51 * @param array $options Options:
52 * - defaultFormat: (string|int) Default for PARAM_TIMESTAMP_FORMAT.
53 * Default if not specified is 'ConvertibleTimestamp'.
54 * - stringifyFormat: (int) Format to use for stringifyValue().
55 * Default is TS_ISO_8601.
56 */
57 public function __construct( Callbacks $callbacks, array $options = [] ) {
58 parent::__construct( $callbacks );
59
60 $this->defaultFormat = $options['defaultFormat'] ?? 'ConvertibleTimestamp';
61 $this->stringifyFormat = $options['stringifyFormat'] ?? TS_ISO_8601;
62 }
63
64 public function validate( $name, $value, array $settings, array $options ) {
65 // Confusing synonyms for the current time accepted by ConvertibleTimestamp
66 if ( !$value ) {
67 $this->callbacks->recordCondition(
68 new ValidationException( $name, $value, $settings, 'unclearnowtimestamp', [] ),
69 $options
70 );
71 $value = 'now';
72 }
73
74 try {
75 $timestamp = new ConvertibleTimestamp( $value === 'now' ? false : $value );
76 } catch ( TimestampException $ex ) {
77 throw new ValidationException( $name, $value, $settings, 'badtimestamp', [], $ex );
78 }
79
80 $format = $settings[self::PARAM_TIMESTAMP_FORMAT] ?? $this->defaultFormat;
81 switch ( $format ) {
82 case 'ConvertibleTimestamp':
83 return $timestamp;
84
85 case 'DateTime':
86 // Eew, no getter.
87 return $timestamp->timestamp;
88
89 default:
90 return $timestamp->getTimestamp( $format );
91 }
92 }
93
94 public function stringifyValue( $name, $value, array $settings, array $options ) {
95 if ( !$value instanceof ConvertibleTimestamp ) {
96 $value = new ConvertibleTimestamp( $value );
97 }
98 return $value->getTimestamp( $this->stringifyFormat );
99 }
100
101 }