Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 63 |
|
0.00% |
0 / 5 |
CRAP | |
0.00% |
0 / 1 |
DateInputWidget | |
0.00% |
0 / 63 |
|
0.00% |
0 / 5 |
756 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 37 |
|
0.00% |
0 / 1 |
210 | |||
getJavaScriptClassName | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getConfig | |
0.00% |
0 / 18 |
|
0.00% |
0 / 1 |
90 | |||
getInputElement | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
6 | |||
modifyDate | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Widget; |
4 | |
5 | use DateTime; |
6 | use OOUI\TextInputWidget; |
7 | |
8 | /** |
9 | * Date input widget. |
10 | * |
11 | * @since 1.29 |
12 | * @copyright 2016 MediaWiki Widgets Team and others; see AUTHORS.txt |
13 | * @license MIT |
14 | */ |
15 | class DateInputWidget extends TextInputWidget { |
16 | |
17 | /** @var string|null */ |
18 | protected $inputFormat = null; |
19 | /** @var string|null */ |
20 | protected $displayFormat = null; |
21 | /** @var string|null|false */ |
22 | protected $longDisplayFormat = null; |
23 | /** @var string|null */ |
24 | protected $placeholderLabel = null; |
25 | /** @var string|null */ |
26 | protected $placeholderDateFormat = null; |
27 | /** @var string|null */ |
28 | protected $precision = null; |
29 | /** @var string|null */ |
30 | protected $mustBeAfter = null; |
31 | /** @var string|null */ |
32 | protected $mustBeBefore = null; |
33 | |
34 | /** |
35 | * @param array $config Configuration options |
36 | * - string $config['inputFormat'] Date format string to use for the textual input field. |
37 | * Displayed while the widget is active, and the user can type in a date in this format. |
38 | * Should be short and easy to type. (default: 'YYYY-MM-DD' or 'YYYY-MM', depending on |
39 | * `precision`) |
40 | * - string $config['displayFormat'] Date format string to use for the clickable label. |
41 | * while the widget is inactive. Should be as unambiguous as possible (for example, prefer |
42 | * to spell out the month, rather than rely on the order), even if that makes it longer. |
43 | * Applicable only if the widget is infused. (default: language-specific) |
44 | * - string $config['longDisplayFormat'] If a custom displayFormat is not specified, use |
45 | * unabbreviated day of the week and month names in the default language-specific |
46 | * displayFormat. (default: false) |
47 | * - string $config['placeholderLabel'] Placeholder text shown when the widget is not |
48 | * selected. Applicable only if the widget is infused. (default: taken from message |
49 | * `mw-widgets-dateinput-no-date`) |
50 | * - string $config['placeholderDateFormat'] User-visible date format string displayed |
51 | * in the textual input field when it's empty. Should be the same as `inputFormat`, but |
52 | * translated to the user's language. (default: 'YYYY-MM-DD' or 'YYYY-MM', depending on |
53 | * `precision`) |
54 | * - string $config['precision'] Date precision to use, 'day' or 'month' (default: 'day') |
55 | * - string $config['min'] Validates the date to be no earlier than this. |
56 | * In the 'YYYY-MM-DD' or 'YYYY-MM' format, depending on `precision`. |
57 | * - string $config['mustBeAfter'] Validates the date to be after this. Overrides 'min'. |
58 | * In the 'YYYY-MM-DD' or 'YYYY-MM' format, depending on `precision`. |
59 | * - string $config['max'] Validates the date to be no later than this. |
60 | * In the 'YYYY-MM-DD' or 'YYYY-MM' format, depending on `precision`. |
61 | * - string $config['mustBeBefore'] Validates the date to be before this. Overrides 'max'. |
62 | * In the 'YYYY-MM-DD' or 'YYYY-MM' format, depending on `precision`. |
63 | */ |
64 | public function __construct( array $config = [] ) { |
65 | $config = array_merge( [ |
66 | // Default config values |
67 | 'precision' => 'day', |
68 | 'longDisplayFormat' => false, |
69 | ], $config ); |
70 | |
71 | // Properties |
72 | if ( isset( $config['inputFormat'] ) ) { |
73 | $this->inputFormat = $config['inputFormat']; |
74 | } |
75 | if ( isset( $config['placeholderDateFormat'] ) ) { |
76 | $this->placeholderDateFormat = $config['placeholderDateFormat']; |
77 | } |
78 | $this->precision = $config['precision']; |
79 | if ( isset( $config['mustBeAfter'] ) ) { |
80 | $this->mustBeAfter = $config['mustBeAfter']; |
81 | } elseif ( isset( $config['min'] ) ) { |
82 | $this->mustBeAfter = $this->modifyDate( $config['min'], '-1 day' ); |
83 | } |
84 | if ( isset( $config['mustBeBefore'] ) ) { |
85 | $this->mustBeBefore = $config['mustBeBefore']; |
86 | } elseif ( isset( $config['max'] ) ) { |
87 | $this->mustBeBefore = $this->modifyDate( $config['max'], '+1 day' ); |
88 | } |
89 | |
90 | // Properties stored for the infused JS widget |
91 | if ( isset( $config['displayFormat'] ) ) { |
92 | $this->displayFormat = $config['displayFormat']; |
93 | } |
94 | if ( isset( $config['longDisplayFormat'] ) ) { |
95 | $this->longDisplayFormat = $config['longDisplayFormat']; |
96 | } |
97 | if ( isset( $config['placeholderLabel'] ) ) { |
98 | $this->placeholderLabel = $config['placeholderLabel']; |
99 | } |
100 | |
101 | // Set up placeholder text visible if the browser doesn't override it (logic taken from JS) |
102 | if ( $this->placeholderDateFormat !== null ) { |
103 | $placeholder = $this->placeholderDateFormat; |
104 | } elseif ( $this->inputFormat !== null ) { |
105 | // We have no way to display a translated placeholder for custom formats |
106 | $placeholder = ''; |
107 | } else { |
108 | $placeholder = wfMessage( "mw-widgets-dateinput-placeholder-$this->precision" )->text(); |
109 | } |
110 | |
111 | $config = array_merge( [ |
112 | // Processed config values |
113 | 'placeholder' => $placeholder, |
114 | ], $config ); |
115 | |
116 | parent::__construct( $config ); |
117 | |
118 | // Calculate min/max attributes (which are skipped by TextInputWidget) and add to <input> |
119 | // min/max attributes are inclusive, but mustBeAfter/Before are exclusive |
120 | if ( $this->mustBeAfter !== null ) { |
121 | $this->input->setAttributes( [ 'min' => $this->modifyDate( $this->mustBeAfter, '+1 day' ) ] ); |
122 | } |
123 | if ( $this->mustBeBefore !== null ) { |
124 | $this->input->setAttributes( [ 'max' => $this->modifyDate( $this->mustBeBefore, '-1 day' ) ] ); |
125 | } |
126 | |
127 | // Initialization |
128 | $this->addClasses( [ 'mw-widget-dateInputWidget' ] ); |
129 | } |
130 | |
131 | protected function getJavaScriptClassName() { |
132 | return 'mw.widgets.DateInputWidget'; |
133 | } |
134 | |
135 | public function getConfig( &$config ) { |
136 | if ( $this->inputFormat !== null ) { |
137 | $config['inputFormat'] = $this->inputFormat; |
138 | } |
139 | if ( $this->displayFormat !== null ) { |
140 | $config['displayFormat'] = $this->displayFormat; |
141 | } |
142 | if ( $this->longDisplayFormat !== null ) { |
143 | $config['longDisplayFormat'] = $this->longDisplayFormat; |
144 | } |
145 | if ( $this->placeholderLabel !== null ) { |
146 | $config['placeholderLabel'] = $this->placeholderLabel; |
147 | } |
148 | if ( $this->placeholderDateFormat !== null ) { |
149 | $config['placeholderDateFormat'] = $this->placeholderDateFormat; |
150 | } |
151 | if ( $this->precision !== null ) { |
152 | $config['precision'] = $this->precision; |
153 | } |
154 | if ( $this->mustBeAfter !== null ) { |
155 | $config['mustBeAfter'] = $this->mustBeAfter; |
156 | } |
157 | if ( $this->mustBeBefore !== null ) { |
158 | $config['mustBeBefore'] = $this->mustBeBefore; |
159 | } |
160 | $config['$overlay'] = true; |
161 | return parent::getConfig( $config ); |
162 | } |
163 | |
164 | public function getInputElement( $config ) { |
165 | // Inserts date/month type attribute |
166 | return parent::getInputElement( $config ) |
167 | ->setAttributes( [ |
168 | 'type' => ( $config['precision'] === 'month' ) ? 'month' : 'date' |
169 | ] ); |
170 | } |
171 | |
172 | private function modifyDate( string $date, string $modifier ): string { |
173 | $datetime = new DateTime( $date ); |
174 | $datetime->modify( $modifier ); |
175 | return $datetime->format( 'Y-m-d' ); |
176 | } |
177 | } |