Completed
Branch BUG-11108-ticket-reserved-coun... (144d27)
by
unknown
14:21 queued 17s
created

getTimezoneStringFromAbbreviationsList()   D

Complexity

Conditions 9
Paths 19

Size

Total Lines 42
Code Lines 27

Duplication

Lines 15
Ratio 35.71 %

Importance

Changes 0
Metric Value
cc 9
eloc 27
nc 19
nop 2
dl 15
loc 42
rs 4.909
c 0
b 0
f 0
1
<?php
2
namespace EventEspresso\core\services\helpers\datetime;
3
4
use DateTimeZone;
5
use DomainException;
6
use EE_Error;
7
use Exception;
8
9
/**
10
 * PhpCompatLessFiveSixHelper
11
 * This class is an implementation of DatetimeHelper methods for php versions < 5.6
12
 * This class will throw an exception if the php version is greater than 5.6 when it is constructed.
13
 *
14
 * @package EventEspresso\core\domain\datetime
15
 * @author  Darren Ethier
16
 * @since   4.9.54.rc
17
 */
18
class PhpCompatLessFiveSixHelper extends AbstractHelper
19
{
20
21
    /**
22
     * PhpCompatLessFiveSixHelper constructor.
23
     *
24
     * @throws DomainException
25
     */
26 View Code Duplication
    public function __construct()
27
    {
28
        if (PHP_VERSION_ID >= 50600) {
29
            throw new DomainException(
30
                sprintf(
31
                    esc_html__(
32
                        'The %1$s is only usable on php versions less than 5.6.  You\'ll want to use %2$s instead.',
33
                        'event_espresso'
34
                    ),
35
                    __CLASS__,
36
                    'EventEspresso\core\services\helpers\datetime\PhpCompatGreaterFiveSixHelper'
37
                )
38
            );
39
        }
40
    }
41
42
    /**
43
     * Returns a timezone string for the provided gmt_offset.
44
     *
45
     * @param float|string $gmt_offset
46
     * @return string
47
     * @throws EE_Error
48
     */
49
    public function getTimezoneStringFromGmtOffset($gmt_offset = '')
50
    {
51
        $gmt_offset_or_timezone_string = $this->sanitizeInitialIncomingGmtOffsetForGettingTimezoneString($gmt_offset);
52
        if (is_string($gmt_offset_or_timezone_string)) {
53
            return $gmt_offset_or_timezone_string;
54
        }
55
        //well we know its a float, so let's roll with it.
56
        $gmt_offset = $gmt_offset_or_timezone_string;
57
        // convert GMT offset to seconds
58
        $gmt_offset *= HOUR_IN_SECONDS;
59
        // although we don't know the TZ abbreviation, we know the UTC offset
60
        $timezone_string = timezone_name_from_abbr(null, $gmt_offset);
61
        //only use this timezone_string IF it's current offset matches the given offset
62
        if (! empty($timezone_string)) {
63
            $offset = null;
64
            try {
65
                $offset = $this->getTimezoneOffset(new DateTimeZone($timezone_string));
66
                if ($offset !== $gmt_offset) {
67
                    $timezone_string = false;
68
                }
69
            } catch (Exception $e) {
70
                $timezone_string = false;
71
            }
72
        }
73
        // better have a valid timezone string by now, but if not, sigh... loop thru  the timezone_abbreviations_list()
74
        //...
75
        $timezone_string = $timezone_string !== false
76
            ? $timezone_string
77
            : $this->getTimezoneStringFromAbbreviationsList($gmt_offset);
78
        return $timezone_string;
79
    }
80
81
82
    /**
83
     * @param int  $gmt_offset
84
     * @param bool $coerce If true, we attempt to coerce with our adjustment table
85
     * @see self::adjustInvalidGmtOffset
86
     * @return string
87
     * @throws EE_Error
88
     */
89
    protected function getTimezoneStringFromAbbreviationsList($gmt_offset = 0, $coerce = true)
90
    {
91
        $gmt_offset = (int)$gmt_offset;
92
        /** @var array[] $abbreviations */
93
        $abbreviations = DateTimeZone::listAbbreviations();
94 View Code Duplication
        foreach ($abbreviations as $abbreviation) {
95
            foreach ($abbreviation as $timezone) {
96
                if ((int)$timezone['offset'] === $gmt_offset && (bool)$timezone['dst'] === false) {
97
                    try {
98
                        $offset = $this->getTimezoneOffset(new DateTimeZone($timezone['timezone_id']));
99
                        if ($offset !== $gmt_offset) {
100
                            continue;
101
                        }
102
                        return $timezone['timezone_id'];
103
                    } catch (Exception $e) {
104
                        continue;
105
                    }
106
                }
107
            }
108
        }
109
        //if $coerce is true, let's see if we can get a timezone string after the offset is adjusted
110
        if ($coerce === true) {
111
            $timezone_string = $this->getTimezoneStringFromAbbreviationsList(
112
                $this->adjustInvalidGmtOffsets($gmt_offset),
113
                false
114
            );
115
            if ($timezone_string) {
116
                return $timezone_string;
117
            }
118
        }
119
        throw new EE_Error(
120
            sprintf(
121
                esc_html__(
122
                    'The provided GMT offset (%1$s), is invalid, please check with %2$sthis list%3$s for what valid timezones can be used',
123
                    'event_espresso'
124
                ),
125
                $gmt_offset / HOUR_IN_SECONDS,
126
                '<a href="http://www.php.net/manual/en/timezones.php">',
127
                '</a>'
128
            )
129
        );
130
    }
131
132
133
    /**
134
     * Depending on PHP version,
135
     * there might not be valid current timezone strings to match these gmt_offsets in its timezone tables.
136
     * To get around that, for these fringe timezones we bump them to a known valid offset.
137
     * This method should ONLY be called after first verifying an timezone_string cannot be retrieved for the offset.
138
     *
139
     * @param int $gmt_offset
140
     * @return int
141
     */
142
    public function adjustInvalidGmtOffsets($gmt_offset = 0)
143
    {
144
        //make sure $gmt_offset is int
145
        $gmt_offset = (int) $gmt_offset;
146
        switch ($gmt_offset) {
147
            //-12
148
            case -43200:
149
                $gmt_offset = -39600;
150
                break;
151
            //-11.5
152
            case -41400:
153
                $gmt_offset = -39600;
154
                break;
155
            //-10.5
156
            case -37800:
157
                $gmt_offset = -39600;
158
                break;
159
            //-8.5
160
            case -30600:
161
                $gmt_offset = -28800;
162
                break;
163
            //-7.5
164
            case -27000:
165
                $gmt_offset = -25200;
166
                break;
167
            //-6.5
168
            case -23400:
169
                $gmt_offset = -21600;
170
                break;
171
            //-5.5
172
            case -19800:
173
                $gmt_offset = -18000;
174
                break;
175
            //-4.5
176
            case -16200:
177
                $gmt_offset = -14400;
178
                break;
179
            //-3.5
180
            case -12600:
181
                $gmt_offset = -10800;
182
                break;
183
            //-2.5
184
            case -9000:
185
                $gmt_offset = -7200;
186
                break;
187
            //-1.5
188
            case -5400:
189
                $gmt_offset = -3600;
190
                break;
191
            //-0.5
192
            case -1800:
193
                $gmt_offset = 0;
194
                break;
195
            //.5
196
            case 1800:
197
                $gmt_offset = 3600;
198
                break;
199
            //1.5
200
            case 5400:
201
                $gmt_offset = 7200;
202
                break;
203
            //2.5
204
            case 9000:
205
                $gmt_offset = 10800;
206
                break;
207
            //3.5
208
            case 12600:
209
                $gmt_offset = 14400;
210
                break;
211
            //7.5
212
            case 27000:
213
                $gmt_offset = 28800;
214
                break;
215
            //8.5
216
            case 30600:
217
                $gmt_offset = 31500;
218
                break;
219
            //10.5
220
            case 37800:
221
                $gmt_offset = 39600;
222
                break;
223
            //11.5
224
            case 41400:
225
                $gmt_offset = 43200;
226
                break;
227
            //12.75
228
            case 45900:
229
                $gmt_offset = 46800;
230
                break;
231
            //13.75
232
            case 49500:
233
                $gmt_offset = 50400;
234
                break;
235
        }
236
        return $gmt_offset;
237
    }
238
}
239