Merge "Selenium: replace UserLoginPage with BlankPage where possible"
[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 */
28 class TimestampDef extends TypeDef {
29
30 /**
31 * (string|int) Timestamp format to return from validate()
32 *
33 * Values include:
34 * - 'ConvertibleTimestamp': A ConvertibleTimestamp object.
35 * - 'DateTime': A PHP DateTime object
36 * - One of ConvertibleTimestamp's TS_* constants.
37 *
38 * This does not affect the format returned by stringifyValue().
39 */
40 const PARAM_TIMESTAMP_FORMAT = 'param-timestamp-format';
41
42 /** @var string|int */
43 protected $defaultFormat;
44
45 /** @var int */
46 protected $stringifyFormat;
47
48 /**
49 * @param Callbacks $callbacks
50 * @param array $options Options:
51 * - defaultFormat: (string|int) Default for PARAM_TIMESTAMP_FORMAT.
52 * Default if not specified is 'ConvertibleTimestamp'.
53 * - stringifyFormat: (int) Format to use for stringifyValue().
54 * Default is TS_ISO_8601.
55 */
56 public function __construct( Callbacks $callbacks, array $options = [] ) {
57 parent::__construct( $callbacks );
58
59 $this->defaultFormat = $options['defaultFormat'] ?? 'ConvertibleTimestamp';
60 $this->stringifyFormat = $options['stringifyFormat'] ?? TS_ISO_8601;
61 }
62
63 public function validate( $name, $value, array $settings, array $options ) {
64 // Confusing synonyms for the current time accepted by ConvertibleTimestamp
65 if ( !$value ) {
66 $this->callbacks->recordCondition(
67 new ValidationException( $name, $value, $settings, 'unclearnowtimestamp', [] ),
68 $options
69 );
70 $value = 'now';
71 }
72
73 try {
74 $timestamp = new ConvertibleTimestamp( $value === 'now' ? false : $value );
75 } catch ( TimestampException $ex ) {
76 throw new ValidationException( $name, $value, $settings, 'badtimestamp', [], $ex );
77 }
78
79 $format = $settings[self::PARAM_TIMESTAMP_FORMAT] ?? $this->defaultFormat;
80 switch ( $format ) {
81 case 'ConvertibleTimestamp':
82 return $timestamp;
83
84 case 'DateTime':
85 // Eew, no getter.
86 return $timestamp->timestamp;
87
88 default:
89 return $timestamp->getTimestamp( $format );
90 }
91 }
92
93 public function stringifyValue( $name, $value, array $settings, array $options ) {
94 if ( !$value instanceof ConvertibleTimestamp ) {
95 $value = new ConvertibleTimestamp( $value );
96 }
97 return $value->getTimestamp( $this->stringifyFormat );
98 }
99
100 }