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