localization::formatSimpleDate()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 9
Ratio 100 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 9
loc 9
rs 9.6666
cc 2
eloc 5
nc 2
nop 4
1
<?php
2
/**
3
 * Main class that defines the Localization class
4
 *
5
 * @author unreal4u
6
 * @link https://github.com/unreal4u/localization
7
 * @package localization
8
 * @category mainClass
9
 */
10
11
namespace unreal4u;
12
13
/**
14
 * Class that deals with localization settings
15
 *
16
 * This class will handle everything related to locales for you: from number formatting 'till timezones. One particular
17
 * caveat of this class however is that it doesn't know how to handle with countries that have more than 1 timezone. In
18
 * this case, it will setup a list with candidates for you to choose from
19
 *
20
 * @author "unreal4u / Camilo Sperberg" <[email protected]>
21
 * @copyright 2010 - 2014 Camilo Sperberg
22
 * @version 0.4.1
23
 * @license BSD License
24
 */
25
class localization
26
{
27
28
    /**
29
     * The version of this class
30
     * @var string
31
     */
32
    private $classVersion = '0.4.1';
33
34
    /**
35
     * Saves the current timezone settings
36
     * @var \DateTimeZone
37
     */
38
    public $timezone = null;
39
40
    /**
41
     * The timezoneId we are in
42
     * @var string
43
     */
44
    public $timezoneId = 'UTC';
45
46
    /**
47
     * Indicated whether the timezone is in DST or not
48
     * @var boolean
49
     */
50
    public $timezoneInDST = false;
51
52
    /**
53
     * Contains the most probable language associated with the selected locale (2 letter code)
54
     * @var string
55
     */
56
    public $language = '';
57
58
    /**
59
     * Which are the most probable timezone candidates for the current setted locale
60
     * @var array
61
     */
62
    protected $_timezoneCandidates = array();
63
64
    /**
65
     * Contains the value of the current setted locale
66
     * @var string
67
     */
68
    protected $_currentLocale = '';
69
70
    /**
71
     * Contains a list of valid timezones
72
     * @var array
73
     */
74
    protected $_validTimeZones = array();
75
76
    /**
77
     * Constructor, will call setLocale internally
78
     *
79
     * @param string $setLocale
80
     */
81
    public function __construct($setLocale = '')
82
    {
83
        $this->setDefault($setLocale);
84
    }
85
86
    /**
87
     * Returns a string with basic information of this class
88
     *
89
     * @return string
90
     */
91
    public function __toString()
92
    {
93
        return basename(__FILE__) . ' v' . $this->classVersion . ' by Camilo Sperberg - http://unreal4u.com/';
94
    }
95
96
    /**
97
     * Sets the locale to the given locale
98
     *
99
     * This function will also set the "old" setlocale, mainly timezone support for PHP5.3 - PHP5.5
100
     *
101
     * @param string $locale Locale we want to set in RFC 4646 format
102
     * @return string Returns the setted locale
103
     */
104
    public function setDefault($locale)
105
    {
106
        $result = '';
107
        if (!empty($locale)) {
108
            $locale = \Locale::parseLocale($locale);
109
            $locale = \Locale::composeLocale($locale);
110
            \Locale::setDefault($locale);
111
            $result = $this->getDefault();
112
            $this->_setOptions();
113
        }
114
115
        return $result;
116
    }
117
118
    /**
119
     * Gets the default setted locale
120
     */
121
    public function getDefault()
122
    {
123
        $this->_currentLocale = \Locale::getDefault();
124
        return $this->_currentLocale;
125
    }
126
127
    /**
128
     * Sets some options
129
     *
130
     * @param string $locale
0 ignored issues
show
Bug introduced by
There is no parameter named $locale. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
131
     * @return boolean
132
     */
133
    private function _setOptions()
134
    {
135
        $this->language = \Locale::getPrimaryLanguage($this->_currentLocale);
136
        $this->_setTimezoneCandidates(\Locale::getRegion($this->_currentLocale));
137
        return true;
138
    }
139
140
    /**
141
     * Sends header to browser containing charset and contentType (mandatory)
142
     *
143
     * @param string $charset Charset to send to browser. Defaults to UTF-8
144
     * @param string $contentType ContentType to send to browser. Defaults to text/html
145
     * @return boolean Returns true if headers could be sent, false otherwise
146
     */
147
    public function sendHeaders($charset = 'UTF-8', $contentType = 'text/html')
148
    {
149
        $return = '';
150
151
        if (!headers_sent() && !empty($contentType)) {
152
            $headerString = sprintf('Content-type: %s', $contentType);
153
            if (!empty($charset)) {
154
                $headerString .= sprintf('; charset=' . $charset);
155
            }
156
            header($headerString);
157
            $return = $headerString;
158
        }
159
160
        return $return;
161
    }
162
163
    /**
164
     * Detects on basis of the browser settings which locale we should apply
165
     *
166
     * @return string Returns the setted locale
167
     */
168
    public function autodetectLocale()
169
    {
170
        if (!empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
171
            $this->setDefault(\Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE']));
172
        }
173
174
        return $this->_currentLocale;
175
    }
176
177
    /**
178
     * Applies simple rules to print a number
179
     *
180
     * @link http://www.php.net/manual/en/class.numberformatter.php#intl.numberformatter-constants.unumberformatstyle
181
     *
182
     * @param float $value
183
     * @param constant $type One of the accepted constants for numfmt_create (See link)
184
     * @param int $minimumDigits The minimum significant digits. Defaults to -1, which equals locale default
185
     * @param int $maximumDigits The maximum significant digits. Defaults to -1, which equals locale default
186
     * @return string Returns the given value formatted according to current locale
187
     */
188
    public function formatNumber($value = 0, $type = 0, $minimumDigits = -1, $maximumDigits = -1)
189
    {
190
        if (empty($type)) {
191
            $type = \NumberFormatter::DECIMAL;
192
        }
193
194
        $numberFormatter = new \NumberFormatter($this->_currentLocale, $type);
195
196
        if ($minimumDigits > -1) {
197
            $numberFormatter->setAttribute(\NumberFormatter::MIN_FRACTION_DIGITS, $minimumDigits);
198
        }
199
200
        if ($maximumDigits > -1) {
201
            $numberFormatter->setAttribute(\NumberFormatter::MAX_FRACTION_DIGITS, $maximumDigits);
202
        }
203
        return $numberFormatter->format($value);
204
    }
205
206
    /**
207
     * Returns the 3-letter (ISO 4217) currency code of the current locale
208
     *
209
     * @return string
210
     */
211
    public function getCurrencyISOCode()
212
    {
213
        $numberFormatter = new \NumberFormatter($this->_currentLocale, \NumberFormatter::CURRENCY);
214
        return $numberFormatter->getSymbol(\NumberFormatter::INTL_CURRENCY_SYMBOL);
215
    }
216
217
    /**
218
     * Returns a intlDateFormatter object
219
     *
220
     * @param int $dateConstant
221
     * @param int $timeConstant
222
     * @param string $timezone
223
     * @return \IntlDateFormatter Returns a \IntlDateFormatter object with given options
224
     */
225
    private function _getDateObject(
226
        $dateConstant = \IntlDateFormatter::MEDIUM,
227
        $timeConstant = \IntlDateFormatter::NONE,
228
        $timezone = ''
229
    ) {
230
        if (!empty($timezone) && $this->isValidTimeZone($timezone)) {
231
            $timezoneId = $timezone;
232
        } else {
233
            $timezoneId = $this->timezoneId;
234
        }
235
        $this->setTimezone($timezoneId);
236
237
        return \intlDateFormatter::create($this->_currentLocale, $dateConstant, $timeConstant, $this->getTimezoneOffset('eo'));
238
    }
239
240
    /**
241
     * Returns a formatted medium-typed date
242
     *
243
     * @TODO Implement printing locale in another locale
244
     *
245
     * @param int $value The UNIX timestamp we want to print. Defaults to current time
246
     * @param string $timezone The timezone for which we want the information
247
     * @param int $type The type of date we want to print
248
     * @param string $locale The locale in which we want the date
249
     * @return string The formatted date according to current locale settings
250
     */
251 View Code Duplication
    public function formatSimpleDate($value = 0, $timezone = '', $type = \IntlDateFormatter::MEDIUM, $locale = '')
0 ignored issues
show
Unused Code introduced by
The parameter $locale is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
252
    {
253
        if (empty($value)) {
254
            $value = time();
255
        }
256
257
        $dateObject = $this->_getDateObject($type, \IntlDateFormatter::NONE, $timezone);
258
        return $dateObject->format($value);
259
    }
260
261
    /**
262
     * Returns a formatted medium-typed time
263
     *
264
     * @TODO Implement printing locale in another locale
265
     *
266
     * @param string $timezone The timezone in which we want to print the time
267
     * @param int $value The UNIX timestamp we want to print. Defaults to current time
268
     * @param int $type The type of time we want to print
269
     * @param string $locale The locale in which we want the time
0 ignored issues
show
Bug introduced by
There is no parameter named $locale. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
270
     * @return string The formatted time according to current locale settings
271
     */
272 View Code Duplication
    public function formatSimpleTime($value = 0, $timezone = '', $type = \intlDateFormatter::MEDIUM)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
273
    {
274
        if (empty($value)) {
275
            $value = time();
276
        }
277
278
        $dateObject = $this->_getDateObject(\intlDateFormatter::NONE, $type, $timezone);
279
        return $dateObject->format($value);
280
    }
281
282
    /**
283
     * Gets the possible timezone candidates and if only found one, instantiates a DateTimeZone object
284
     *
285
     * @param string $region
286
     */
287
    private function _setTimezoneCandidates($region = '')
288
    {
289
        if (!empty($region)) {
290
            $this->_timezoneCandidates = \DateTimeZone::listIdentifiers(\DateTimeZone::PER_COUNTRY, $region);
291
            $this->setTimeZone();
292
            if (!empty($this->_timezoneCandidates) && count($this->_timezoneCandidates) == 1) {
293
                $this->setTimezone($this->_timezoneCandidates[0]);
294
            }
295
        }
296
    }
297
298
    /**
299
     * Gets timezone candidates for the current locale
300
     *
301
     * @TODO Improve this
302
     *
303
     * @return array
304
     */
305
    public function getTimeZoneCandidates()
306
    {
307
        return $this->_timezoneCandidates;
308
    }
309
310
    /**
311
     * Verifies that the given timezone exists and sets the timezone to the selected timezone
312
     *
313
     * @TODO Verify that the given timezone exists
314
     *
315
     * @param string $timezoneName
0 ignored issues
show
Documentation introduced by
There is no parameter named $timezoneName. Did you maybe mean $timeZoneName?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
316
     * @return string
317
     */
318
    public function setTimezone($timeZoneName = 'UTC')
319
    {
320
        if (!$this->isValidTimeZone($timeZoneName)) {
321
            $timeZoneName = 'UTC';
322
        }
323
324
        $this->timezone = new \DateTimeZone($timeZoneName);
325
        $this->timezoneId = $this->timezone->getName();
326
        $transitions = $this->timezone->getTransitions();
327
        $this->timezoneInDST = $transitions[0]['isdst'];
328
329
        return $this->timezoneId;
330
    }
331
332
    /**
333
     * Checks whether a timezonename is valid or not
334
     *
335
     * @param string $timeZoneName
336
     * @return boolean Returns true if timezone name is valid, false otherwise
337
     */
338
    public function isValidTimeZone($timeZoneName = '')
339
    {
340
        if (!is_string($timeZoneName)) {
341
            $timeZoneName = '';
342
        }
343
344
        try {
345
            new \DateTimeZone($timeZoneName);
346
            // @TODO Return a timezone instead of true/false?
347
            return true;
348
        } catch (\Exception $e) {
349
            return false;
350
        }
351
    }
352
353
    /**
354
     * Gets the offset for the current timezone
355
     *
356
     * @param string $unit
357
     * @param string $when
358
     * @return string
359
     */
360
    public function getTimezoneOffset($unit = 'seconds', $when = 'now')
361
    {
362
        $dateTimeObject = new \DateTime($when, $this->timezone);
363
        $return = $dateTimeObject->getOffset();
364
365
        switch ($unit) {
366
            case 'minutes':
367
                $return = $return / 60;
368
                break;
369
            case 'hours':
370
                $return = $return / 60 / 60;
371
                break;
372 View Code Duplication
            case 'z':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
373
                $sign = '+';
374
                if ($return < 0) {
375
                    $sign = '-';
376
                }
377
                $return = $sign . str_pad(gmdate("Hi", abs($return)), 4, '0', STR_PAD_LEFT);
378
                break;
379 View Code Duplication
            case 'eo': // Explicit offset, almost the same as the above, but in a slightly different format
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
380
                $sign = '+';
381
                if ($return < 0) {
382
                    $sign = '-';
383
                }
384
                $return = 'GMT'.$sign . str_pad(gmdate("H:i", abs($return)), 4, '0', STR_PAD_LEFT);
385
                break;
386
        }
387
388
        return (string)$return;
389
    }
390
}
391