Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 122
0.00% covered (danger)
0.00%
0 / 10
CRAP
0.00% covered (danger)
0.00%
0 / 1
PFDatePickerInput
0.00% covered (danger)
0.00%
0 / 122
0.00% covered (danger)
0.00%
0 / 10
3192
0.00% covered (danger)
0.00%
0 / 1
 getName
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 __construct
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
6
 getResourceModuleNames
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getParameters
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
2
 getHtmlText
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
6
 getOptions
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
42
 getConvertedFormat
0.00% covered (danger)
0.00%
0 / 44
0.00% covered (danger)
0.00%
0 / 1
1190
 getOtherPropTypesHandled
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getOtherCargoTypesHandled
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 genericTextHTML
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
56
1<?php
2
3/**
4 * @author Stephan Gambke
5 * @author Sam Wilson
6 * @author Amr El-Absy
7 * @file
8 * @ingroup PF
9 */
10
11/**
12 * @ingroup PF
13 */
14
15use MediaWiki\Widget\DateInputWidget;
16
17class PFDatePickerInput extends PFFormInput {
18
19    public static function getName(): string {
20        return 'datepicker';
21    }
22
23    /**
24     * @param string $input_number The number of the input in the form.
25     * @param string $cur_value The current value of the input field.
26     * @param string $input_name The name of the input.
27     * @param bool $disabled Is this input disabled?
28     * @param array $other_args An associative array of other parameters that were present in the
29     *  input definition.
30     */
31    public function __construct( $input_number, $cur_value, $input_name, $disabled, array $other_args ) {
32        if ( $cur_value != '' ) {
33            list( $year, $month, $day ) = PFDateInput::parseDate( $cur_value );
34            $cur_value = sprintf( '%04d-%02d-%02d', $year, $month, $day );
35        }
36
37        parent::__construct( $input_number, $cur_value, $input_name, $disabled, $other_args );
38    }
39
40    /**
41     * Returns the names of the resource modules this input type uses.
42     *
43     * Returns the names of the modules as an array or - if there is only
44     * one module - as a string.
45     *
46     * @return null|string|array
47     */
48    public function getResourceModuleNames() {
49        return [ 'ext.pageforms.datepicker' ];
50    }
51
52    /**
53     * Returns the set of parameters for this form input.
54     *
55     * TODO: Add missing parameters
56     * @return array[]
57     */
58    public static function getParameters() {
59        $params = parent::getParameters();
60        $params['date format'] = [
61            'name' => 'date format',
62            'type' => 'string',
63            'description' => wfMessage(
64                'pf-datepicker-dateformat',
65                'https://www.mediawiki.org/wiki/Special:MyLanguage/Extension:Page_Forms/Input_types/Datepicker#Parameters'
66            )->text()
67        ];
68        $params['first date'] = [
69            'name' => 'first date',
70            'type' => 'string',
71            'description' => wfMessage( 'pf-datepicker-firstdate' )->text()
72        ];
73        $params['last date'] = [
74            'name' => 'last date',
75            'type' => 'string',
76            'description' => wfMessage( 'pf-datepicker-lastdate' )->text()
77        ];
78
79        return $params;
80    }
81
82    /**
83     * Returns the HTML code to be included in the output page for this input.
84     *
85     * Ideally this HTML code should provide a basic functionality even if
86     * the browser is not JavaScript capable, i.e. even without JavaScript
87     * the user should be able to input values.
88     * @return string
89     */
90    public function getHtmlText(): string {
91        $options = array_merge( $this->getOptions(), [
92            'type' => 'date',
93            'name' => $this->mInputName,
94            'value' => $this->mCurrentValue,
95            'id' => 'input_' . $this->mInputNumber,
96            'classes' => [ 'pfDatePicker', 'pfPicker' ],
97            'infusable' => true
98        ] );
99        $widget = new DateInputWidget( $options );
100        $widget->setDisabled( $this->mIsDisabled );
101        $text = $widget->toString();
102
103        // We need a wrapper div so that OOUI won't override
104        // any classes added by "show on select".
105        $wrapperClass = 'pfPickerWrapper';
106        if ( isset( $this->mOtherArgs[ 'mandatory' ] ) ) {
107            $wrapperClass .= ' mandatory';
108        }
109
110        return Html::rawElement( 'div', [ 'class' => $wrapperClass ], $text );
111    }
112
113    private function getOptions() {
114        $params = $this->mOtherArgs;
115        $options = [];
116        if ( isset( $params[ 'date format' ] ) ) {
117            $options[ 'inputFormat' ] = $this->getConvertedFormat();
118            $options[ 'displayFormat' ] = $this->getConvertedFormat();
119        }
120        if ( isset( $params[ 'first date' ] ) ) {
121            $options[ 'mustBeAfter' ] = str_replace( "/", "-", $params[ 'first date' ] );
122        }
123        if ( isset( $params[ 'last date' ] ) ) {
124            $options[ 'mustBeBefore' ] = str_replace( "/", "-", $params[ 'last date' ] );
125        }
126        if ( isset( $params[ 'hidden' ] ) ) {
127            $options[ 'invisibleLabel' ] = true;
128        }
129        if ( isset( $params[ 'maxlength' ] ) ) {
130            $options[ 'maxLength' ] = $params[ 'maxlength' ];
131        }
132        // It would be nice to set this, since it leads to a useful
133        // display (an asterisk), but unfortunately it also causes a
134        // JS error that prevents saving.
135        //if ( isset( $params[ 'mandatory' ] ) ) {
136        //    $options[ 'required' ] = true;
137        //}
138
139        return $options;
140    }
141
142    private function getConvertedFormat() {
143        $oldFormat = $this->mOtherArgs['date format'];
144        $j = 0;
145        $newFormat = [];
146        for ( $i = 0; $i < strlen( $oldFormat ); $i++ ) {
147            if ( $oldFormat[$i] === "d" && isset( $oldFormat[$i + 1] ) && $oldFormat[$i + 1] !== "d" ) {
148                // If the letter is "d" and next letter is not "d"
149                $newFormat[$j] = "D";
150                $j++;
151            } elseif ( $oldFormat[$i] === "d" && isset( $oldFormat[$i + 1] ) && $oldFormat[$i + 1] === "d" ) {
152                // If the letter is "d" and next letter is "d", which means "dd"
153                $newFormat[$j] = "DD";
154                $j += 2;
155                $i++;
156            } elseif ( $oldFormat[$i] === "d" && !isset( $oldFormat[$i + 1] ) ) {
157                // If the letter is "d" and it is the last letter.
158                $newFormat[$j] = "D";
159            } elseif ( $oldFormat[$i] === "D" && isset( $oldFormat[$i + 1] ) && $oldFormat[$i + 1] !== "D" ) {
160                // If the letter is "D" and next letter is not "D"
161                $newFormat[$j] = "dd";
162                $j += 2;
163            } elseif ( $oldFormat[$i] === "D" && isset( $oldFormat[$i + 1] ) && $oldFormat[$i + 1] === "D" ) {
164                // If the letter is "D" and next letter is "D", which means "DD".
165                // Until now, we don't know a corresponding format, so, let's let at as it is.
166                $newFormat[$j] = "DD";
167                $j += 2;
168                $i++;
169            } elseif ( $oldFormat[$i] === "D" && !isset( $oldFormat[$i + 1] ) ) {
170                // If the letter is "D" and it is the last letter.
171                $newFormat[$j] = "dd";
172            } elseif ( $oldFormat[$i] === "m" && isset( $oldFormat[$i + 1] ) && $oldFormat[$i + 1] !== "m" ) {
173                // If the letter is "m" and next letter is not "m"
174                $newFormat[$j] = "M";
175                $j++;
176            } elseif ( $oldFormat[$i] === "m" && isset( $oldFormat[$i + 1] ) && $oldFormat[$i + 1] === "m" ) {
177                // If the letter is "m" and next letter is "m", which means "mm".
178                $newFormat[$j] = "MM";
179                $j += 2;
180                $i++;
181            } elseif ( $oldFormat[$i] === "m" && !isset( $oldFormat[$i + 1] ) ) {
182                // If the letter is "m" and it is the last letter.
183                $newFormat[$j] = "M";
184            } elseif ( $oldFormat[$i] === "y" && isset( $oldFormat[$i + 1] ) && $oldFormat[$i + 1] !== "y" ) {
185                // If the letter is "y" and next letter is not "y"
186                $newFormat[$j] = "YY";
187                $j += 2;
188            } elseif ( $oldFormat[$i] === "y" && isset( $oldFormat[$i + 1] ) && $oldFormat[$i + 1] === "y" ) {
189                // If the letter is "y" and next letter is "y", which means "yy".
190                $newFormat[$j] = "YYYY";
191                $j += 4;
192                $i++;
193            } elseif ( $oldFormat[$i] === "y" && !isset( $oldFormat[$i + 1] ) ) {
194                // If the letter is "y" and it is the last letter.
195                $newFormat[$j] = "YY";
196            } else {
197                // Any another letters, or special characters.
198                $newFormat[$j] = $oldFormat[$i];
199                $j++;
200            }
201        }
202        $newFormat = implode( $newFormat );
203        return $newFormat;
204    }
205
206    /**
207     * Returns the set of SMW property types which this input can
208     * handle, but for which it isn't the default input.
209     *
210     * @return string[]
211     */
212    public static function getOtherPropTypesHandled() {
213        return [ '_dat' ];
214    }
215
216    /**
217     * Returns the set of Cargo field types which this input can
218     * handle, but for which it isn't the default input.
219     *
220     * @return string[]
221     */
222    public static function getOtherCargoTypesHandled() {
223        return [ 'Date' ];
224    }
225
226    /**
227     * Creates the HTML text for an input.
228     *
229     * Common attributes for input types are set according to the parameters.
230     * The parameters are the standard parameters set by Page Forms'
231     * InputTypeHook plus some optional.
232     *
233     * @param string $currentValue
234     * @param string $inputName
235     * @param bool $isDisabled
236     * @param array $otherArgs
237     * @param string|null $inputId (optional)
238     * @param int|null $tabIndex (optional)
239     * @param string $class
240     * @return string the html text of an input element
241     */
242    static function genericTextHTML( $currentValue, $inputName, $isDisabled, $otherArgs, $inputId = null, $tabIndex = null, $class = '' ) {
243        global $wgPageFormsTabIndex;
244
245        // array of attributes to pass to the input field
246        $attribs = [
247            'name'  => $inputName,
248            'class' => $class,
249            'value' => $currentValue,
250            'type'  => 'text'
251        ];
252
253        // set size attrib
254        if ( array_key_exists( 'size', $otherArgs ) ) {
255            $attribs['size'] = $otherArgs['size'];
256        }
257
258        // set maxlength attrib
259        if ( array_key_exists( 'maxlength', $otherArgs ) ) {
260            $attribs['maxlength'] = $otherArgs['maxlength'];
261        }
262
263        // add user class(es) to class attribute of input field
264        if ( array_key_exists( 'class', $otherArgs ) ) {
265            $attribs['class'] .= ' ' . $otherArgs['class'];
266        }
267
268        // set readonly attrib
269        if ( $isDisabled ) {
270            $attribs['disabled'] = true;
271        }
272
273        // if no special input id is specified set the Page Forms standard
274        if ( $inputId !== null ) {
275            $attribs['id'] = $inputId;
276        }
277
278        if ( $tabIndex == null ) {
279            $attribs['tabindex'] = $wgPageFormsTabIndex;
280        } else {
281            $attribs['tabindex'] = $tabIndex;
282        }
283
284        $html = Html::element( 'input', $attribs );
285
286        return $html;
287    }
288}