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