fix #8131 - chinese translations
[Pman.Core] / TimeZone.php
1 <?php
2 require_once 'Pman.php';
3
4 class Pman_Core_TimeZone extends Pman
5 {
6     function getAuth()
7     {
8         parent::getAuth();
9         
10         if (!$this->getAuthUser()) {  
11             $this->jerr("Not authenticated", array('authFailure' => true));
12         }
13         
14         return true;
15     }
16
17     function get($base, $opts=array())
18     {
19         $this->lang = !empty($_REQUEST['lang']) && in_array($_REQUEST['lang'], array('en', 'zh_CN')) ? $_REQUEST['lang'] : 'en';
20         self::getTimezones($this->lang);
21
22         $data = array();
23
24         foreach(self::$timezones as $tz => $o) {
25             if(!empty($_REQUEST['region']) && $_REQUEST['region'] != $o['region']) {
26                 continue;
27             }
28
29             if(
30                 !empty($_REQUEST['query']['area_start']) 
31                 && 
32                 substr(strtolower($o['area']), 0, strlen($_REQUEST['query']['area_start'])) != strtolower($_REQUEST['query']['area_start'])
33             ){
34                 continue;
35             }
36             $data[] = array(
37                 'region' => $o['region'],
38                 'area' => $o['area'],
39                 'displayRegion' => $o['displayRegion'],
40                 'displayArea' => $o['displayArea']
41             );
42         }
43
44         echo json_encode(array(
45             'data' => $data,
46             'metaData' => array(
47                 'root' => 'data',
48                 'successProperty' => 'success',
49                 'totalProperty' => 'total',
50                 'fields' => array(
51                     'region',
52                     'area',
53                     'displayRegion',
54                     'displayArea'
55                 )
56             ),
57             'success' => true,
58             'total' => count($data),
59             
60         ));
61         exit;
62     }
63
64     function post($base) {
65         die('Invalid post');
66     }
67
68     static $timezones = array();
69
70     static function getTimezones($lang)
71     {
72         if(!empty(self::$timezones)) {
73             return self::$timezones;
74         }
75          $ce = DB_DataObject::factory('core_enum');
76         $ce->query("
77             SELECT
78                 *, TIME_FORMAT(TIMEDIFF(NOW(), CONVERT_TZ(NOW(), Name, 'UTC')), '%H:%i') as timeOffset
79             FROM
80                 mysql.time_zone_name
81             WHERE
82                 Name LIKE '%/%'
83                 AND
84                 Name NOT LIKE '%/%/%'
85                 AND
86                 Name NOT LIKE 'right%'
87                 AND
88                 Name NOT LIKE 'posix%'
89                 AND
90                 Name NOT LIKE 'Etc%'
91             ORDER BY
92                 SUBSTRING_INDEX(Name, '/', 1) ASC,
93                 timeoffset ASC,
94                 Name ASC
95         ");
96
97         $regions = DB_DataObject::factory('core_enum');
98         $regions->setFrom(array(
99             'etype' => 'Timezone.Region',
100             'active' => 1
101         ));
102         $regionIds = $regions->fetchAll('display_name', 'id');
103
104         $areas = DB_DataObject::factory('core_enum');
105         $areas->setFrom(array(
106             'etype' => 'Timezone.Area',
107             'active' => 1
108         ));
109         $areaIds = $areas->fetchAll('display_name', 'id');
110
111
112         $ct = DB_DataObject::factory('core_templatestr');
113         $ct->lang = $lang;
114         $ct->on_table = 'core_enum';
115         $ct->active = 1;
116         $translations = array();
117         foreach($ct->fetchAll() as $t) {
118             if(empty($t->txt)) {
119                 continue;
120             }
121             $translations[$t->on_id][$t->on_col] = $t->txt;
122         }
123
124         while($ce->fetch()) {
125             // ignroe timezone such as 'CET' and 'America/Argentina/Buenos_Aires'
126            
127
128             $ar = explode('/', $ce->Name);
129             // ignore timezone such as 'Etc/GMT+8'
130
131             $region = $displayRegion = $ar[0];
132
133             if(!empty($translations[$regionIds[$region]]['display_name'])) {
134                 $displayRegion = $translations[$regionIds[$region]]['display_name'];
135             }
136
137             $area =  $ar[1];
138             $displayArea = str_replace('_', ' ', $area);
139
140             if(!empty($translations[$areaIds[$displayArea]]['display_name'])) {
141                 $displayArea = $translations[$areaIds[$displayArea]]['display_name'];
142             }
143
144             $timeOffset = ((substr($ce->timeOffset, 0, 1) == '-') ? '' : '+') . $ce->timeOffset;
145             $displayOffset = '(GMT ' . $timeOffset . ')';
146
147             self::$timezones[$ce->Name] = array(
148                 'region' => $region,
149                 'area' => $area,
150                 'displayName' => $ar[0] . '/' . $displayArea . ' ' . $displayOffset,
151                 'displayRegion' => $displayRegion,
152                 'displayArea' => $displayArea . ' ' . $displayOffset
153             );
154         }
155
156         return self::$timezones;
157     }
158
159     static function isValidTimeZone($tz) {
160         try {
161             new DateTimeZone($tz);
162         }
163         catch (Exception $e) {
164             return false;
165         }
166
167         return true;
168     }
169
170     static function toRegion($tz)
171     {
172         if(!self::isValidTimeZone($tz)) {
173             return '';
174         }
175         
176         return explode('/', $tz)[0];
177     }
178
179     static function toArea($tz)
180     {
181         if(!self::isValidTimeZone($tz)) {
182             return '';
183         }
184
185         return explode('/', $tz)[1];
186     }
187     
188     static function toTimeOffset($dt, $tz)
189     {
190         if(!self::isValidTimeZone($tz)) {
191             return '';
192         }
193
194         if($dt == '0000-00-00 00:00:00' || $dt == '') {
195             $dt = 'NOW';
196         }
197
198         $date = new DateTime($dt, new DateTimeZone($tz));
199         return $date->format('P');
200     }
201
202     static function toDisplayRegion($lang, $tz) 
203     {
204         $region = explode('/', $tz)[0];
205
206         $ce = DB_DataObject::factory('core_enum');
207         $ce->setFrom(array(
208             'etype' => 'Timezone.Region',
209             'active' => 1,
210             'name' => $region,
211             'display_name' => $region
212         ));
213         if(!$ce->find(true)) {
214             return $region;
215         }
216
217         $ct = DB_DataObject::factory('core_templatestr');
218         $ct->setFrom(array(
219             'lang' => $lang,
220             'on_table' => 'core_enum',
221             'on_id' => $ce->id,
222             'on_col' => 'display_name',
223             'active' => 1
224         ));
225         if(!$ct->find(true) || empty($ct->txt)) {
226             return $region;
227         }
228         return $ct->txt;
229     }
230
231     static function toDisplayArea($lang, $dt, $tz)
232     {
233         $displayArea = str_replace('_', ' ', self::toArea($tz));
234         $displayOffset = '(GMT ' . self::toTimeOffset($dt,$tz) . ')';
235
236         $ce = DB_DataObject::factory('core_enum');
237         $ce->setFrom(array(
238             'etype' => 'Timezone.Area',
239             'active' => 1,
240             'name' => $displayArea,
241             'display_name' => $displayArea
242         ));
243
244         if(!$ce->find(true)) {
245             return $displayArea . ' ' . $displayOffset;
246         }
247
248         $ct = DB_DataObject::factory('core_templatestr');
249         $ct->setFrom(array(
250             'lang' => $lang,
251             'on_table' => 'core_enum',
252             'on_id' => $ce->id,
253             'on_col' => 'display_name',
254             'active' => 1
255         ));
256         if(!$ct->find(true) || empty($ct->txt)) {
257             return $displayArea . ' ' . $displayOffset;
258         }
259
260         return $ct->txt . ' ' . $displayOffset;
261
262     }
263
264     static function toDisplayName($lang, $dt, $tz)
265     {
266         return self::toDisplayRegion($lang, $tz) . '/' . self::toDisplayArea($lang, $dt, $tz);
267     }
268 }