Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
59.17% covered (warning)
59.17%
71 / 120
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
timezone
59.17% covered (warning)
59.17%
71 / 120
0.00% covered (danger)
0.00%
0 / 6
236.10
0.00% covered (danger)
0.00%
0 / 1
 effectively_installed
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 depends_on
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 update_schema
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
 update_data
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 update_timezones
96.15% covered (success)
96.15%
25 / 26
0.00% covered (danger)
0.00%
0 / 1
5
 convert_phpbb30_timezone
56.10% covered (warning)
56.10%
46 / 82
0.00% covered (danger)
0.00%
0 / 1
199.46
1<?php
2/**
3*
4* This file is part of the phpBB Forum Software package.
5*
6* @copyright (c) phpBB Limited <https://www.phpbb.com>
7* @license GNU General Public License, version 2 (GPL-2.0)
8*
9* For full copyright and license information, please see
10* the docs/CREDITS.txt file.
11*
12*/
13
14namespace phpbb\db\migration\data\v310;
15
16class timezone extends \phpbb\db\migration\migration
17{
18    public function effectively_installed()
19    {
20        return !$this->db_tools->sql_column_exists($this->table_prefix . 'users', 'user_dst');
21    }
22
23    public static function depends_on()
24    {
25        return array('\phpbb\db\migration\data\v30x\release_3_0_11');
26    }
27
28    public function update_schema()
29    {
30        return array(
31            'change_columns'    => array(
32                $this->table_prefix . 'users'            => array(
33                    'user_timezone'        => array('VCHAR:100', ''),
34                ),
35            ),
36        );
37    }
38
39    public function update_data()
40    {
41        return array(
42            array('custom', array(array($this, 'update_timezones'))),
43        );
44    }
45
46    public function update_timezones($start)
47    {
48        $start = (int) $start;
49        $limit = 500;
50        $converted = 0;
51
52        $update_blocks = array();
53
54        $sql = 'SELECT user_id, user_timezone, user_dst
55            FROM ' . $this->table_prefix . 'users
56            ORDER BY user_id ASC';
57        $result = $this->db->sql_query_limit($sql, $limit, $start);
58        while ($row = $this->db->sql_fetchrow($result))
59        {
60            $converted++;
61
62            // In case this is somehow run twice on a row.
63            // Otherwise it would just end up as UTC on the second run
64            if (is_numeric($row['user_timezone']))
65            {
66                $update_blocks[$row['user_timezone'] . ':' . $row['user_dst']][] = (int) $row['user_id'];
67            }
68        }
69        $this->db->sql_freeresult($result);
70
71        // Update blocks of users who share the same timezone/dst
72        foreach ($update_blocks as $timezone => $user_ids)
73        {
74            $timezone = explode(':', $timezone);
75            $converted_timezone = static::convert_phpbb30_timezone($timezone[0], $timezone[1]);
76
77            $sql = 'UPDATE ' . $this->table_prefix . "users
78                SET user_timezone = '" . $this->db->sql_escape($converted_timezone) . "'
79                WHERE " . $this->db->sql_in_set('user_id', $user_ids);
80            $this->sql_query($sql);
81        }
82
83        if ($converted == $limit)
84        {
85            // There are still more to convert
86            return $start + $limit;
87        }
88
89        // Update board default timezone
90        $sql = 'UPDATE ' . $this->table_prefix . "config
91            SET config_value = '" . static::convert_phpbb30_timezone($this->config['board_timezone'], $this->config['board_dst']) . "'
92            WHERE config_name = 'board_timezone'";
93        $this->sql_query($sql);
94    }
95
96    /**
97    * Determine the new timezone for a given phpBB 3.0 timezone and
98    * "Daylight Saving Time" option
99    *
100    *    @param    $timezone    float    Users timezone in 3.0
101    *    @param    $dst        int        Users daylight saving time
102    *    @return        string        Users new php Timezone which is used since 3.1
103    */
104    public static function convert_phpbb30_timezone($timezone, $dst)
105    {
106        $offset = (float) $timezone + (int) $dst;
107
108        switch ($timezone)
109        {
110            case '-12':
111                return 'Etc/GMT+' . abs($offset);    //'[UTC - 12] Baker Island Time'
112            case '-11':
113                return 'Etc/GMT+' . abs($offset);    //'[UTC - 11] Niue Time, Samoa Standard Time'
114            case '-10':
115                return 'Etc/GMT+' . abs($offset);    //'[UTC - 10] Hawaii-Aleutian Standard Time, Cook Island Time'
116            case '-9.5':
117                return 'Pacific/Marquesas';            //'[UTC - 9:30] Marquesas Islands Time'
118            case '-9':
119                return 'Etc/GMT+' . abs($offset);    //'[UTC - 9] Alaska Standard Time, Gambier Island Time'
120            case '-8':
121                return 'Etc/GMT+' . abs($offset);    //'[UTC - 8] Pacific Standard Time'
122            case '-7':
123                return 'Etc/GMT+' . abs($offset);    //'[UTC - 7] Mountain Standard Time'
124            case '-6':
125                return 'Etc/GMT+' . abs($offset);    //'[UTC - 6] Central Standard Time'
126            case '-5':
127                return 'Etc/GMT+' . abs($offset);    //'[UTC - 5] Eastern Standard Time'
128            case '-4.5':
129                return 'America/Caracas';            //'[UTC - 4:30] Venezuelan Standard Time'
130            case '-4':
131                return 'Etc/GMT+' . abs($offset);    //'[UTC - 4] Atlantic Standard Time'
132            case '-3.5':
133                return 'America/St_Johns';            //'[UTC - 3:30] Newfoundland Standard Time'
134            case '-3':
135                return 'Etc/GMT+' . abs($offset);    //'[UTC - 3] Amazon Standard Time, Central Greenland Time'
136            case '-2':
137                return 'Etc/GMT+' . abs($offset);    //'[UTC - 2] Fernando de Noronha Time, South Georgia &amp; the South Sandwich Islands Time'
138            case '-1':
139                return 'Etc/GMT+' . abs($offset);    //'[UTC - 1] Azores Standard Time, Cape Verde Time, Eastern Greenland Time'
140            case '0':
141                return (!$dst) ? 'UTC' : 'Etc/GMT-1';    //'[UTC] Western European Time, Greenwich Mean Time'
142            case '1':
143                return 'Etc/GMT-' . $offset;        //'[UTC + 1] Central European Time, West African Time'
144            case '2':
145                return 'Etc/GMT-' . $offset;        //'[UTC + 2] Eastern European Time, Central African Time'
146            case '3':
147                return 'Etc/GMT-' . $offset;        //'[UTC + 3] Moscow Standard Time, Eastern African Time'
148            case '3.5':
149                return 'Asia/Tehran';                //'[UTC + 3:30] Iran Standard Time'
150            case '4':
151                return 'Etc/GMT-' . $offset;        //'[UTC + 4] Gulf Standard Time, Samara Standard Time'
152            case '4.5':
153                return 'Asia/Kabul';                //'[UTC + 4:30] Afghanistan Time'
154            case '5':
155                return 'Etc/GMT-' . $offset;        //'[UTC + 5] Pakistan Standard Time, Yekaterinburg Standard Time'
156            case '5.5':
157                return 'Asia/Kolkata';                //'[UTC + 5:30] Indian Standard Time, Sri Lanka Time'
158            case '5.75':
159                return 'Asia/Kathmandu';            //'[UTC + 5:45] Nepal Time'
160            case '6':
161                return 'Etc/GMT-' . $offset;        //'[UTC + 6] Bangladesh Time, Bhutan Time, Novosibirsk Standard Time'
162            case '6.5':
163                return 'Indian/Cocos';                //'[UTC + 6:30] Cocos Islands Time, Myanmar Time'
164            case '7':
165                return 'Etc/GMT-' . $offset;        //'[UTC + 7] Indochina Time, Krasnoyarsk Standard Time'
166            case '8':
167                return 'Etc/GMT-' . $offset;        //'[UTC + 8] Chinese Standard Time, Australian Western Standard Time, Irkutsk Standard Time'
168            case '8.75':
169                return 'Australia/Eucla';            //'[UTC + 8:45] Southeastern Western Australia Standard Time'
170            case '9':
171                return 'Etc/GMT-' . $offset;        //'[UTC + 9] Japan Standard Time, Korea Standard Time, Chita Standard Time'
172            case '9.5':
173                return 'Australia/ACT';                //'[UTC + 9:30] Australian Central Standard Time'
174            case '10':
175                return 'Etc/GMT-' . $offset;        //'[UTC + 10] Australian Eastern Standard Time, Vladivostok Standard Time'
176            case '10.5':
177                return 'Australia/Lord_Howe';        //'[UTC + 10:30] Lord Howe Standard Time'
178            case '11':
179                return 'Etc/GMT-' . $offset;        //'[UTC + 11] Solomon Island Time, Magadan Standard Time'
180            case '11.5':
181                return 'Pacific/Norfolk';            //'[UTC + 11:30] Norfolk Island Time'
182            case '12':
183                return 'Etc/GMT-12';                //'[UTC + 12] New Zealand Time, Fiji Time, Kamchatka Standard Time'
184            case '12.75':
185                return 'Pacific/Chatham';            //'[UTC + 12:45] Chatham Islands Time'
186            case '13':
187                return 'Pacific/Tongatapu';            //'[UTC + 13] Tonga Time, Phoenix Islands Time'
188            case '14':
189                return 'Pacific/Kiritimati';        //'[UTC + 14] Line Island Time'
190            default:
191                return 'UTC';
192        }
193    }
194}