Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 108
0.00% covered (danger)
0.00%
0 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
PFDateInput
0.00% covered (danger)
0.00%
0 / 108
0.00% covered (danger)
0.00%
0 / 9
1332
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
 getDefaultPropTypes
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getDefaultCargoTypes
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 monthDropdownHTML
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
56
 getInputClass
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 parseDate
0.00% covered (danger)
0.00%
0 / 53
0.00% covered (danger)
0.00%
0 / 1
306
 getMainHTML
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
30
 getHTML
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
6
 getHtmlText
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * @file
4 * @ingroup PF
5 */
6
7/**
8 * @ingroup PFFormInput
9 */
10class PFDateInput extends PFFormInput {
11
12    public static function getName(): string {
13        return 'date';
14    }
15
16    public static function getDefaultPropTypes() {
17        return [ '_dat' => [] ];
18    }
19
20    public static function getDefaultCargoTypes() {
21        return [
22            'Date' => []
23        ];
24    }
25
26    public static function monthDropdownHTML( $cur_month, $input_name, $is_disabled ) {
27        global $wgPageFormsTabIndex, $wgAmericanDates;
28
29        $optionsText = '';
30        $month_names = PFFormUtils::getMonthNames();
31        // Add a "null" value at the beginning.
32        array_unshift( $month_names, null );
33        foreach ( $month_names as $i => $name ) {
34            if ( $name === null ) {
35                $month_value = null;
36            } else {
37                // Pad out month to always be two digits.
38                $month_value = ( $wgAmericanDates == true ) ? $name : str_pad( $i, 2, '0', STR_PAD_LEFT );
39            }
40            $optionAttrs = [ 'value' => $month_value ];
41            if ( $name == $cur_month || $i == $cur_month ) {
42                $optionAttrs['selected'] = 'selected';
43            }
44            $optionsText .= Html::element( 'option', $optionAttrs, $name );
45        }
46        $selectAttrs = [
47            'class' => 'monthInput',
48            'name' => $input_name . '[month]',
49            'tabindex' => $wgPageFormsTabIndex
50        ];
51        if ( $is_disabled ) {
52            $selectAttrs['disabled'] = 'disabled';
53        }
54        $text = Html::rawElement( 'select', $selectAttrs, $optionsText );
55        return $text;
56    }
57
58    public function getInputClass() {
59        return 'dateInput';
60    }
61
62    static function parseDate( $date, $includeTime = false ) {
63        global $wgLanguageCode;
64
65        // Special handling for 'default=now'.
66        if ( $date == 'now' ) {
67            global $wgLocaltimezone;
68            if ( isset( $wgLocaltimezone ) ) {
69                $serverTimezone = date_default_timezone_get();
70                date_default_timezone_set( $wgLocaltimezone );
71            }
72            $year = date( 'Y' );
73            $month = date( 'm' );
74            $day = date( 'j' );
75            if ( $includeTime ) {
76                $time = date( 'H:i:s' );
77            }
78
79            if ( isset( $wgLocaltimezone ) ) {
80                date_default_timezone_set( $serverTimezone );
81            }
82            if ( $includeTime ) {
83                return [ $year, $month, $day, $time ];
84            } else {
85                return [ $year, $month, $day ];
86            }
87        }
88
89        // All other dates.
90        if ( ctype_digit( $date ) ) {
91            return [ $date, null, null ];
92        }
93
94        // Convert any date format to ISO standards.
95        $date = str_replace( "/", "-", $date );
96        // Special handling for "MM.YYYY" format.
97        if ( preg_match( '/^(\d\d)\.(\d\d\d\d)$/', $date, $matches ) ) {
98            $date = $matches[2] . '-' . $matches[1];
99        }
100        // Returns an array with detailed information about the date.
101        $date_array = date_parse( $date );
102
103        // If parsing didn't work, it may be because the
104        // date contains a month name in a language other than English.
105        // (Page Forms only puts in a month name if there's no day
106        // value, but the date text could also be coming from an
107        // outside source.)
108        if ( $date_array['error_count'] > 0 && $wgLanguageCode != 'en' ) {
109            $date = strtolower( $date );
110            $monthNames = PFFormUtils::getMonthNames();
111            $englishMonthNames = [ 'January', 'February',
112                'March', 'April', 'May', 'June', 'July',
113                'August', 'September', 'October', 'November',
114                'December' ];
115            foreach ( $monthNames as $i => $monthName ) {
116                $monthName = strtolower( $monthName );
117                if ( strpos( $date, $monthName ) !== false ) {
118                    $englishMonthName = $englishMonthNames[$i];
119                    $date = str_replace( $monthName,
120                        $englishMonthName, $date );
121                    break;
122                }
123            }
124            $date_array = date_parse( $date );
125        }
126
127        if ( $date_array['error_count'] > 0 ) {
128            return null;
129        }
130
131        $year = $date_array['year'];
132        $month = $date_array['month'];
133        $day = $date_array['day'];
134        if ( $includeTime ) {
135            $time = sprintf( '%02d:%02d:%02d', $date_array['hour'],
136                $date_array['minute'], $date_array['second'] );
137        }
138
139        // Determine if there's a month but no day. There's no ideal
140        // way to do this, so: we'll just look for the total
141        // number of spaces and dashes, and if there's
142        // exactly one altogether, we'll guess that it's a month only.
143        $numSpecialChars = substr_count( $date, ' ' ) + substr_count( $date, '-' );
144        if ( $numSpecialChars == 1 ) {
145            // For the case of date format Month YYYY
146            if ( $date_array['error_count'] > 0 ) {
147                // Separating date into its individual components
148                $dateParts = explode( " ", $date );
149                $month = $dateParts[0];
150                $year = $dateParts[1];
151            }
152            return [ $year, $month, null ];
153
154        }
155
156        if ( $includeTime ) {
157            return [ $year, $month, $day, $time ];
158        } else {
159            return [ $year, $month, $day ];
160        }
161    }
162
163    public static function getMainHTML( $date, $input_name, $is_mandatory, $is_disabled, array $other_args ) {
164        global $wgPageFormsTabIndex, $wgAmericanDates;
165
166        $year = $month = $day = null;
167
168        if ( $date ) {
169            // Can show up here either as an array or a string,
170            // depending on whether it came from user input or a
171            // wiki page.
172            if ( is_array( $date ) ) {
173                $year = $date['year'];
174                $month = $date['month'];
175                $day = $date['day'];
176            } else {
177                list( $year, $month, $day ) = self::parseDate( $date );
178            }
179        } else {
180            // Just keep everything at null.
181        }
182        $text = "";
183        $disabled_text = ( $is_disabled ) ? 'disabled' : '';
184        $monthInput = self::monthDropdownHTML( $month, $input_name, $is_disabled );
185        $dayInput = '    <input tabindex="' . $wgPageFormsTabIndex . '" class="dayInput" name="' . $input_name . '[day]" type="text" value="' . $day . '" size="2" ' . $disabled_text . '/>';
186        if ( $wgAmericanDates ) {
187            $text .= "$monthInput\n$dayInput\n";
188        } else {
189            $text .= "$dayInput\n$monthInput\n";
190        }
191        $text .= '    <input tabindex="' . $wgPageFormsTabIndex . '" class="yearInput" name="' . $input_name . '[year]" type="text" value="' . $year . '" size="4" ' . $disabled_text . '/>' . "\n";
192        return $text;
193    }
194
195    public function getHTML( $date, $input_name, $is_mandatory, $is_disabled, array $other_args ) {
196        $text = self::getMainHTML( $date, $input_name, $is_mandatory, $is_disabled, $other_args );
197        $spanClass = $this->getInputClass();
198        if ( $is_mandatory ) {
199            $spanClass .= ' mandatoryFieldSpan';
200        }
201        $text = Html::rawElement( 'span', [ 'class' => $spanClass ], $text );
202        return $text;
203    }
204
205    /**
206     * Returns the HTML code to be included in the output page for this input.
207     * @return string
208     */
209    public function getHtmlText(): string {
210        return $this->getHTML(
211            $this->mCurrentValue,
212            $this->mInputName,
213            $this->mIsMandatory,
214            $this->mIsDisabled,
215            $this->mOtherArgs
216        );
217    }
218}