MediaWiki 1.41.2
HTMLTimezoneField.php
Go to the documentation of this file.
1<?php
2
9
16 private const FIELD_CLASS = 'mw-htmlform-timezone-field';
17
19 private $msgFormatter;
20
26 public function __construct( $params ) {
27 if ( isset( $params['options'] ) ) {
28 throw new InvalidArgumentException( "Options should not be provided to " . __CLASS__ );
29 }
30 $params['placeholder-message'] ??= 'timezone-useoffset-placeholder';
31 $params['options'] = [];
32 parent::__construct( $params );
33 $lang = $this->mParent ? $this->mParent->getLanguage() : RequestContext::getMain()->getLanguage();
34 $langCode = $lang->getCode();
35 $this->msgFormatter = MediaWikiServices::getInstance()->getMessageFormatterFactory()
36 ->getTextFormatter( $langCode );
37 $this->mOptions = $this->getTimezoneOptions();
38 }
39
43 private function getTimezoneOptions(): array {
44 $opt = [];
45
46 $localTZoffset = MediaWikiServices::getInstance()->getMainConfig()->get( MainConfigNames::LocalTZoffset );
47 $timeZoneList = $this->getTimeZoneList();
48
49 $timestamp = MWTimestamp::getLocalInstance();
50 // Check that the LocalTZoffset is the same as the local time zone offset
51 if ( $localTZoffset === (int)$timestamp->format( 'Z' ) / 60 ) {
52 $timezoneName = $timestamp->getTimezone()->getName();
53 // Localize timezone
54 if ( isset( $timeZoneList[$timezoneName] ) ) {
55 $timezoneName = $timeZoneList[$timezoneName]['name'];
56 }
57 $server_tz_msg = $this->msgFormatter->format(
58 MessageValue::new( 'timezoneuseserverdefault', [ $timezoneName ] )
59 );
60 } else {
61 $tzstring = UserTimeCorrection::formatTimezoneOffset( $localTZoffset );
62 $server_tz_msg = $this->msgFormatter->format(
63 MessageValue::new( 'timezoneuseserverdefault', [ $tzstring ] )
64 );
65 }
66 $opt[$server_tz_msg] = "System|$localTZoffset";
67 $opt[$this->msgFormatter->format( MessageValue::new( 'timezoneuseoffset' ) )] = 'other';
68 $opt[$this->msgFormatter->format( MessageValue::new( 'guesstimezone' ) )] = 'guess';
69
70 foreach ( $timeZoneList as $timeZoneInfo ) {
71 $region = $timeZoneInfo['region'];
72 if ( !isset( $opt[$region] ) ) {
73 $opt[$region] = [];
74 }
75 $opt[$region][$timeZoneInfo['name']] = $timeZoneInfo['timecorrection'];
76 }
77 return $opt;
78 }
79
86 private function getTimeZoneList(): array {
87 $identifiers = DateTimeZone::listIdentifiers();
88 '@phan-var array|false $identifiers'; // See phan issue #3162
89 if ( $identifiers === false ) {
90 return [];
91 }
92 sort( $identifiers );
93
94 $tzRegions = [
95 'Africa' => $this->msgFormatter->format( MessageValue::new( 'timezoneregion-africa' ) ),
96 'America' => $this->msgFormatter->format( MessageValue::new( 'timezoneregion-america' ) ),
97 'Antarctica' => $this->msgFormatter->format( MessageValue::new( 'timezoneregion-antarctica' ) ),
98 'Arctic' => $this->msgFormatter->format( MessageValue::new( 'timezoneregion-arctic' ) ),
99 'Asia' => $this->msgFormatter->format( MessageValue::new( 'timezoneregion-asia' ) ),
100 'Atlantic' => $this->msgFormatter->format( MessageValue::new( 'timezoneregion-atlantic' ) ),
101 'Australia' => $this->msgFormatter->format( MessageValue::new( 'timezoneregion-australia' ) ),
102 'Europe' => $this->msgFormatter->format( MessageValue::new( 'timezoneregion-europe' ) ),
103 'Indian' => $this->msgFormatter->format( MessageValue::new( 'timezoneregion-indian' ) ),
104 'Pacific' => $this->msgFormatter->format( MessageValue::new( 'timezoneregion-pacific' ) ),
105 ];
106 asort( $tzRegions );
107
108 $timeZoneList = [];
109
110 $now = new DateTime();
111
112 foreach ( $identifiers as $identifier ) {
113 $parts = explode( '/', $identifier, 2 );
114
115 // DateTimeZone::listIdentifiers() returns a number of
116 // backwards-compatibility entries. This filters them out of the
117 // list presented to the user.
118 if ( count( $parts ) !== 2 || !array_key_exists( $parts[0], $tzRegions ) ) {
119 continue;
120 }
121
122 // Localize region
123 $parts[0] = $tzRegions[$parts[0]];
124
125 $dateTimeZone = new DateTimeZone( $identifier );
126 $minDiff = floor( $dateTimeZone->getOffset( $now ) / 60 );
127
128 $display = str_replace( '_', ' ', $parts[0] . '/' . $parts[1] );
129 $value = "ZoneInfo|$minDiff|$identifier";
130
131 $timeZoneList[$identifier] = [
132 'name' => $display,
133 'timecorrection' => $value,
134 'region' => $parts[0],
135 ];
136 }
137
138 return $timeZoneList;
139 }
140
144 public function validate( $value, $alldata ) {
145 $p = parent::validate( $value, $alldata );
146 if ( $p !== true ) {
147 return $p;
148 }
149
150 if ( !( new UserTimeCorrection( $value ) )->isValid() ) {
151 return $this->mParent->msg( 'timezone-invalid' )->escaped();
152 }
153
154 return true;
155 }
156
160 protected function getFieldClasses(): array {
161 $classes = parent::getFieldClasses();
162 $classes[] = self::FIELD_CLASS;
163 return $classes;
164 }
165}
Select dropdown field, with an additional "other" textbox.
Dropdown widget that allows the user to select a timezone, either by choosing a geographic zone,...
getFieldClasses()
Returns a list of classes that should be applied to the widget itself.Unfortunately,...
validate( $value, $alldata)
Override this function to add specific validation checks on the field input.Don't forget to call pare...
A class containing constants representing the names of configuration variables.
Service locator for MediaWiki core services.
Utility class to parse the TimeCorrection string value.
Library for creating and parsing MW-style timestamps.
Value object representing a message for i18n.