Completed
Push — develop ( d3e769...440bfe )
by Adrien
22:10
created

StringHelper::isUTF8()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 2
nc 2
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
ccs 0
cts 2
cp 0
crap 6
1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Shared;
4
5
use PhpOffice\PhpSpreadsheet\Calculation;
6
7
class StringHelper
8
{
9
    /**    Constants                */
10
    /**    Regular Expressions        */
11
    //    Fraction
12
    const STRING_REGEXP_FRACTION = '(-?)(\d+)\s+(\d+\/\d+)';
13
14
    /**
15
     * Control characters array.
16
     *
17
     * @var string[]
18
     */
19
    private static $controlCharacters = [];
20
21
    /**
22
     * SYLK Characters array.
23
     *
24
     * @var array
25
     */
26
    private static $SYLKCharacters = [];
27
28
    /**
29
     * Decimal separator.
30
     *
31
     * @var string
32
     */
33
    private static $decimalSeparator;
34
35
    /**
36
     * Thousands separator.
37
     *
38
     * @var string
39
     */
40
    private static $thousandsSeparator;
41
42
    /**
43
     * Currency code.
44
     *
45
     * @var string
46
     */
47
    private static $currencyCode;
48
49
    /**
50
     * Is iconv extension avalable?
51
     *
52
     * @var bool
53
     */
54
    private static $isIconvEnabled;
55
56
    /**
57
     * Build control characters array.
58
     */
59 54
    private static function buildControlCharacters()
60
    {
61 54
        for ($i = 0; $i <= 31; ++$i) {
62 54
            if ($i != 9 && $i != 10 && $i != 13) {
63 54
                $find = '_x' . sprintf('%04s', strtoupper(dechex($i))) . '_';
64 54
                $replace = chr($i);
65 54
                self::$controlCharacters[$find] = $replace;
66
            }
67
        }
68 54
    }
69
70
    /**
71
     * Build SYLK characters array.
72
     */
73 54
    private static function buildSYLKCharacters()
74
    {
75 54
        self::$SYLKCharacters = [
76 54
            "\x1B 0" => chr(0),
77 54
            "\x1B 1" => chr(1),
78 54
            "\x1B 2" => chr(2),
79 54
            "\x1B 3" => chr(3),
80 54
            "\x1B 4" => chr(4),
81 54
            "\x1B 5" => chr(5),
82 54
            "\x1B 6" => chr(6),
83 54
            "\x1B 7" => chr(7),
84 54
            "\x1B 8" => chr(8),
85 54
            "\x1B 9" => chr(9),
86 54
            "\x1B :" => chr(10),
87 54
            "\x1B ;" => chr(11),
88 54
            "\x1B <" => chr(12),
89 54
            "\x1B =" => chr(13),
90 54
            "\x1B >" => chr(14),
91 54
            "\x1B ?" => chr(15),
92 54
            "\x1B!0" => chr(16),
93 54
            "\x1B!1" => chr(17),
94 54
            "\x1B!2" => chr(18),
95 54
            "\x1B!3" => chr(19),
96 54
            "\x1B!4" => chr(20),
97 54
            "\x1B!5" => chr(21),
98 54
            "\x1B!6" => chr(22),
99 54
            "\x1B!7" => chr(23),
100 54
            "\x1B!8" => chr(24),
101 54
            "\x1B!9" => chr(25),
102 54
            "\x1B!:" => chr(26),
103 54
            "\x1B!;" => chr(27),
104 54
            "\x1B!<" => chr(28),
105 54
            "\x1B!=" => chr(29),
106 54
            "\x1B!>" => chr(30),
107 54
            "\x1B!?" => chr(31),
108 54
            "\x1B'?" => chr(127),
109 54
            "\x1B(0" => '€', // 128 in CP1252
110 54
            "\x1B(2" => '‚', // 130 in CP1252
111 54
            "\x1B(3" => 'ƒ', // 131 in CP1252
112 54
            "\x1B(4" => '„', // 132 in CP1252
113 54
            "\x1B(5" => '…', // 133 in CP1252
114 54
            "\x1B(6" => '†', // 134 in CP1252
115 54
            "\x1B(7" => '‡', // 135 in CP1252
116 54
            "\x1B(8" => 'ˆ', // 136 in CP1252
117 54
            "\x1B(9" => '‰', // 137 in CP1252
118 54
            "\x1B(:" => 'Š', // 138 in CP1252
119 54
            "\x1B(;" => '‹', // 139 in CP1252
120 54
            "\x1BNj" => 'Œ', // 140 in CP1252
121 54
            "\x1B(>" => 'Ž', // 142 in CP1252
122 54
            "\x1B)1" => '‘', // 145 in CP1252
123 54
            "\x1B)2" => '’', // 146 in CP1252
124 54
            "\x1B)3" => '“', // 147 in CP1252
125 54
            "\x1B)4" => '”', // 148 in CP1252
126 54
            "\x1B)5" => '•', // 149 in CP1252
127 54
            "\x1B)6" => '–', // 150 in CP1252
128 54
            "\x1B)7" => '—', // 151 in CP1252
129 54
            "\x1B)8" => '˜', // 152 in CP1252
130 54
            "\x1B)9" => '™', // 153 in CP1252
131 54
            "\x1B):" => 'š', // 154 in CP1252
132 54
            "\x1B);" => '›', // 155 in CP1252
133 54
            "\x1BNz" => 'œ', // 156 in CP1252
134 54
            "\x1B)>" => 'ž', // 158 in CP1252
135 54
            "\x1B)?" => 'Ÿ', // 159 in CP1252
136 54
            "\x1B*0" => ' ', // 160 in CP1252
137 54
            "\x1BN!" => '¡', // 161 in CP1252
138 54
            "\x1BN\"" => '¢', // 162 in CP1252
139 54
            "\x1BN#" => '£', // 163 in CP1252
140 54
            "\x1BN(" => '¤', // 164 in CP1252
141 54
            "\x1BN%" => '¥', // 165 in CP1252
142 54
            "\x1B*6" => '¦', // 166 in CP1252
143 54
            "\x1BN'" => '§', // 167 in CP1252
144 54
            "\x1BNH " => '¨', // 168 in CP1252
145 54
            "\x1BNS" => '©', // 169 in CP1252
146 54
            "\x1BNc" => 'ª', // 170 in CP1252
147 54
            "\x1BN+" => '«', // 171 in CP1252
148 54
            "\x1B*<" => '¬', // 172 in CP1252
149 54
            "\x1B*=" => '­', // 173 in CP1252
150 54
            "\x1BNR" => '®', // 174 in CP1252
151 54
            "\x1B*?" => '¯', // 175 in CP1252
152 54
            "\x1BN0" => '°', // 176 in CP1252
153 54
            "\x1BN1" => '±', // 177 in CP1252
154 54
            "\x1BN2" => '²', // 178 in CP1252
155 54
            "\x1BN3" => '³', // 179 in CP1252
156 54
            "\x1BNB " => '´', // 180 in CP1252
157 54
            "\x1BN5" => 'µ', // 181 in CP1252
158 54
            "\x1BN6" => '¶', // 182 in CP1252
159 54
            "\x1BN7" => '·', // 183 in CP1252
160 54
            "\x1B+8" => '¸', // 184 in CP1252
161 54
            "\x1BNQ" => '¹', // 185 in CP1252
162 54
            "\x1BNk" => 'º', // 186 in CP1252
163 54
            "\x1BN;" => '»', // 187 in CP1252
164 54
            "\x1BN<" => '¼', // 188 in CP1252
165 54
            "\x1BN=" => '½', // 189 in CP1252
166 54
            "\x1BN>" => '¾', // 190 in CP1252
167 54
            "\x1BN?" => '¿', // 191 in CP1252
168 54
            "\x1BNAA" => 'À', // 192 in CP1252
169 54
            "\x1BNBA" => 'Á', // 193 in CP1252
170 54
            "\x1BNCA" => 'Â', // 194 in CP1252
171 54
            "\x1BNDA" => 'Ã', // 195 in CP1252
172 54
            "\x1BNHA" => 'Ä', // 196 in CP1252
173 54
            "\x1BNJA" => 'Å', // 197 in CP1252
174 54
            "\x1BNa" => 'Æ', // 198 in CP1252
175 54
            "\x1BNKC" => 'Ç', // 199 in CP1252
176 54
            "\x1BNAE" => 'È', // 200 in CP1252
177 54
            "\x1BNBE" => 'É', // 201 in CP1252
178 54
            "\x1BNCE" => 'Ê', // 202 in CP1252
179 54
            "\x1BNHE" => 'Ë', // 203 in CP1252
180 54
            "\x1BNAI" => 'Ì', // 204 in CP1252
181 54
            "\x1BNBI" => 'Í', // 205 in CP1252
182 54
            "\x1BNCI" => 'Î', // 206 in CP1252
183 54
            "\x1BNHI" => 'Ï', // 207 in CP1252
184 54
            "\x1BNb" => 'Ð', // 208 in CP1252
185 54
            "\x1BNDN" => 'Ñ', // 209 in CP1252
186 54
            "\x1BNAO" => 'Ò', // 210 in CP1252
187 54
            "\x1BNBO" => 'Ó', // 211 in CP1252
188 54
            "\x1BNCO" => 'Ô', // 212 in CP1252
189 54
            "\x1BNDO" => 'Õ', // 213 in CP1252
190 54
            "\x1BNHO" => 'Ö', // 214 in CP1252
191 54
            "\x1B-7" => '×', // 215 in CP1252
192 54
            "\x1BNi" => 'Ø', // 216 in CP1252
193 54
            "\x1BNAU" => 'Ù', // 217 in CP1252
194 54
            "\x1BNBU" => 'Ú', // 218 in CP1252
195 54
            "\x1BNCU" => 'Û', // 219 in CP1252
196 54
            "\x1BNHU" => 'Ü', // 220 in CP1252
197 54
            "\x1B-=" => 'Ý', // 221 in CP1252
198 54
            "\x1BNl" => 'Þ', // 222 in CP1252
199 54
            "\x1BN{" => 'ß', // 223 in CP1252
200 54
            "\x1BNAa" => 'à', // 224 in CP1252
201 54
            "\x1BNBa" => 'á', // 225 in CP1252
202 54
            "\x1BNCa" => 'â', // 226 in CP1252
203 54
            "\x1BNDa" => 'ã', // 227 in CP1252
204 54
            "\x1BNHa" => 'ä', // 228 in CP1252
205 54
            "\x1BNJa" => 'å', // 229 in CP1252
206 54
            "\x1BNq" => 'æ', // 230 in CP1252
207 54
            "\x1BNKc" => 'ç', // 231 in CP1252
208 54
            "\x1BNAe" => 'è', // 232 in CP1252
209 54
            "\x1BNBe" => 'é', // 233 in CP1252
210 54
            "\x1BNCe" => 'ê', // 234 in CP1252
211 54
            "\x1BNHe" => 'ë', // 235 in CP1252
212 54
            "\x1BNAi" => 'ì', // 236 in CP1252
213 54
            "\x1BNBi" => 'í', // 237 in CP1252
214 54
            "\x1BNCi" => 'î', // 238 in CP1252
215 54
            "\x1BNHi" => 'ï', // 239 in CP1252
216 54
            "\x1BNs" => 'ð', // 240 in CP1252
217 54
            "\x1BNDn" => 'ñ', // 241 in CP1252
218 54
            "\x1BNAo" => 'ò', // 242 in CP1252
219 54
            "\x1BNBo" => 'ó', // 243 in CP1252
220 54
            "\x1BNCo" => 'ô', // 244 in CP1252
221 54
            "\x1BNDo" => 'õ', // 245 in CP1252
222 54
            "\x1BNHo" => 'ö', // 246 in CP1252
223 54
            "\x1B/7" => '÷', // 247 in CP1252
224 54
            "\x1BNy" => 'ø', // 248 in CP1252
225 54
            "\x1BNAu" => 'ù', // 249 in CP1252
226 54
            "\x1BNBu" => 'ú', // 250 in CP1252
227 54
            "\x1BNCu" => 'û', // 251 in CP1252
228 54
            "\x1BNHu" => 'ü', // 252 in CP1252
229 54
            "\x1B/=" => 'ý', // 253 in CP1252
230 54
            "\x1BN|" => 'þ', // 254 in CP1252
231 54
            "\x1BNHy" => 'ÿ', // 255 in CP1252
232
        ];
233 54
    }
234
235
    /**
236
     * Get whether iconv extension is available.
237
     *
238
     * @return bool
239
     */
240 113
    public static function getIsIconvEnabled()
241
    {
242 113
        if (isset(self::$isIconvEnabled)) {
243 112
            return self::$isIconvEnabled;
244
        }
245
246
        // Fail if iconv doesn't exist
247 96
        if (!function_exists('iconv')) {
248
            self::$isIconvEnabled = false;
249
250
            return false;
251
        }
252
253
        // Sometimes iconv is not working, and e.g. iconv('UTF-8', 'UTF-16LE', 'x') just returns false,
254 96
        if (!@iconv('UTF-8', 'UTF-16LE', 'x')) {
255
            self::$isIconvEnabled = false;
256
257
            return false;
258
        }
259
260
        // Sometimes iconv_substr('A', 0, 1, 'UTF-8') just returns false in PHP 5.2.0
0 ignored issues
show
Unused Code Comprehensibility introduced by
42% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
261
        // we cannot use iconv in that case either (http://bugs.php.net/bug.php?id=37773)
262 96
        if (!@iconv_substr('A', 0, 1, 'UTF-8')) {
263
            self::$isIconvEnabled = false;
264
265
            return false;
266
        }
267
268
        // CUSTOM: IBM AIX iconv() does not work
269 96
        if (defined('PHP_OS') && @stristr(PHP_OS, 'AIX') && defined('ICONV_IMPL') && (@strcasecmp(ICONV_IMPL, 'unknown') == 0) && defined('ICONV_VERSION') && (@strcasecmp(ICONV_VERSION, 'unknown') == 0)) {
270
            self::$isIconvEnabled = false;
271
272
            return false;
273
        }
274
275
        // If we reach here no problems were detected with iconv
276 96
        self::$isIconvEnabled = true;
277
278 96
        return true;
279
    }
280
281 56
    private static function buildCharacterSets()
282
    {
283 56
        if (empty(self::$controlCharacters)) {
284 54
            self::buildControlCharacters();
285
        }
286
287 56
        if (empty(self::$SYLKCharacters)) {
288 54
            self::buildSYLKCharacters();
289
        }
290 56
    }
291
292
    /**
293
     * Convert from OpenXML escaped control character to PHP control character.
294
     *
295
     * Excel 2007 team:
296
     * ----------------
297
     * That's correct, control characters are stored directly in the shared-strings table.
298
     * We do encode characters that cannot be represented in XML using the following escape sequence:
299
     * _xHHHH_ where H represents a hexadecimal character in the character's value...
300
     * So you could end up with something like _x0008_ in a string (either in a cell value (<v>)
301
     * element or in the shared string <t> element.
302
     *
303
     * @param string $value Value to unescape
304
     *
305
     * @return string
306
     */
307 11
    public static function controlCharacterOOXML2PHP($value)
308
    {
309 11
        self::buildCharacterSets();
310
311 11
        return str_replace(array_keys(self::$controlCharacters), array_values(self::$controlCharacters), $value);
312
    }
313
314
    /**
315
     * Convert from PHP control character to OpenXML escaped control character.
316
     *
317
     * Excel 2007 team:
318
     * ----------------
319
     * That's correct, control characters are stored directly in the shared-strings table.
320
     * We do encode characters that cannot be represented in XML using the following escape sequence:
321
     * _xHHHH_ where H represents a hexadecimal character in the character's value...
322
     * So you could end up with something like _x0008_ in a string (either in a cell value (<v>)
323
     * element or in the shared string <t> element.
324
     *
325
     * @param string $value Value to escape
326
     *
327
     * @return string
328
     */
329 52
    public static function controlCharacterPHP2OOXML($value)
330
    {
331 52
        self::buildCharacterSets();
332
333 52
        return str_replace(array_values(self::$controlCharacters), array_keys(self::$controlCharacters), $value);
334
    }
335
336
    /**
337
     * Try to sanitize UTF8, stripping invalid byte sequences. Not perfect. Does not surrogate characters.
338
     *
339
     * @param string $value
340
     *
341
     * @return string
342
     */
343 85
    public static function sanitizeUTF8($value)
344
    {
345 85
        if (self::getIsIconvEnabled()) {
346 85
            $value = @iconv('UTF-8', 'UTF-8', $value);
347
348 85
            return $value;
349
        }
350
351
        $value = mb_convert_encoding($value, 'UTF-8', 'UTF-8');
352
353
        return $value;
354
    }
355
356
    /**
357
     * Check if a string contains UTF8 data.
358
     *
359
     * @param string $value
360
     *
361
     * @return bool
362
     */
363
    public static function isUTF8($value)
364
    {
365
        return $value === '' || preg_match('/^./su', $value) === 1;
366
    }
367
368
    /**
369
     * Formats a numeric value as a string for output in various output writers forcing
370
     * point as decimal separator in case locale is other than English.
371
     *
372
     * @param mixed $value
373
     *
374
     * @return string
375
     */
376 60
    public static function formatNumber($value)
377
    {
378 60
        if (is_float($value)) {
379 60
            return str_replace(',', '.', $value);
380
        }
381
382 56
        return (string) $value;
383
    }
384
385
    /**
386
     * Converts a UTF-8 string into BIFF8 Unicode string data (8-bit string length)
387
     * Writes the string using uncompressed notation, no rich text, no Asian phonetics
388
     * If mbstring extension is not available, ASCII is assumed, and compressed notation is used
389
     * although this will give wrong results for non-ASCII strings
390
     * see OpenOffice.org's Documentation of the Microsoft Excel File Format, sect. 2.5.3.
391
     *
392
     * @param string $value UTF-8 encoded string
393
     * @param mixed[] $arrcRuns Details of rich text runs in $value
394
     *
395
     * @return string
396
     */
397 39
    public static function UTF8toBIFF8UnicodeShort($value, $arrcRuns = [])
398
    {
399
        // character count
400 39
        $ln = self::countCharacters($value, 'UTF-8');
401
        // option flags
402 39
        if (empty($arrcRuns)) {
403 39
            $data = pack('CC', $ln, 0x0001);
404
            // characters
405 39
            $data .= self::convertEncoding($value, 'UTF-16LE', 'UTF-8');
406
        } else {
407 9
            $data = pack('vC', $ln, 0x09);
408 9
            $data .= pack('v', count($arrcRuns));
409
            // characters
410 9
            $data .= self::convertEncoding($value, 'UTF-16LE', 'UTF-8');
411 9
            foreach ($arrcRuns as $cRun) {
412 9
                $data .= pack('v', $cRun['strlen']);
413 9
                $data .= pack('v', $cRun['fontidx']);
414
            }
415
        }
416
417 39
        return $data;
418
    }
419
420
    /**
421
     * Converts a UTF-8 string into BIFF8 Unicode string data (16-bit string length)
422
     * Writes the string using uncompressed notation, no rich text, no Asian phonetics
423
     * If mbstring extension is not available, ASCII is assumed, and compressed notation is used
424
     * although this will give wrong results for non-ASCII strings
425
     * see OpenOffice.org's Documentation of the Microsoft Excel File Format, sect. 2.5.3.
426
     *
427
     * @param string $value UTF-8 encoded string
428
     *
429
     * @return string
430
     */
431 39
    public static function UTF8toBIFF8UnicodeLong($value)
432
    {
433
        // character count
434 39
        $ln = self::countCharacters($value, 'UTF-8');
435
436
        // characters
437 39
        $chars = self::convertEncoding($value, 'UTF-16LE', 'UTF-8');
438
439 39
        $data = pack('vC', $ln, 0x0001) . $chars;
440
441 39
        return $data;
442
    }
443
444
    /**
445
     * Convert string from one encoding to another.
446
     *
447
     * @param string $value
448
     * @param string $to Encoding to convert to, e.g. 'UTF-8'
449
     * @param string $from Encoding to convert from, e.g. 'UTF-16LE'
450
     *
451
     * @return string
452
     */
453 56
    public static function convertEncoding($value, $to, $from)
454
    {
455 56
        if (self::getIsIconvEnabled()) {
456 56
            $result = iconv($from, $to . '//IGNORE//TRANSLIT', $value);
457 56
            if (false !== $result) {
458 56
                return $result;
459
            }
460
        }
461
462
        return mb_convert_encoding($value, $to, $from);
463
    }
464
465
    /**
466
     * Get character count.
467
     *
468
     * @param string $value
469
     * @param string $enc Encoding
470
     *
471
     * @return int Character count
472
     */
473 164
    public static function countCharacters($value, $enc = 'UTF-8')
474
    {
475 164
        return mb_strlen($value, $enc);
476
    }
477
478
    /**
479
     * Get a substring of a UTF-8 encoded string.
480
     *
481
     * @param string $pValue UTF-8 encoded string
482
     * @param int $pStart Start offset
483
     * @param int $pLength Maximum number of characters in substring
484
     *
485
     * @return string
486
     */
487 140
    public static function substring($pValue, $pStart, $pLength = 0)
488
    {
489 140
        return mb_substr($pValue, $pStart, $pLength, 'UTF-8');
490
    }
491
492
    /**
493
     * Convert a UTF-8 encoded string to upper case.
494
     *
495
     * @param string $pValue UTF-8 encoded string
496
     *
497
     * @return string
498
     */
499 4
    public static function strToUpper($pValue)
500
    {
501 4
        return mb_convert_case($pValue, MB_CASE_UPPER, 'UTF-8');
502
    }
503
504
    /**
505
     * Convert a UTF-8 encoded string to lower case.
506
     *
507
     * @param string $pValue UTF-8 encoded string
508
     *
509
     * @return string
510
     */
511 4
    public static function strToLower($pValue)
512
    {
513 4
        return mb_convert_case($pValue, MB_CASE_LOWER, 'UTF-8');
514
    }
515
516
    /**
517
     * Convert a UTF-8 encoded string to title/proper case
518
     * (uppercase every first character in each word, lower case all other characters).
519
     *
520
     * @param string $pValue UTF-8 encoded string
521
     *
522
     * @return string
523
     */
524 3
    public static function strToTitle($pValue)
525
    {
526 3
        return mb_convert_case($pValue, MB_CASE_TITLE, 'UTF-8');
527
    }
528
529 21
    public static function mbIsUpper($char)
530
    {
531 21
        return mb_strtolower($char, 'UTF-8') != $char;
532
    }
533
534 21
    public static function mbStrSplit($string)
535
    {
536
        // Split at all position not after the start: ^
537
        // and not before the end: $
538 21
        return preg_split('/(?<!^)(?!$)/u', $string);
539
    }
540
541
    /**
542
     * Reverse the case of a string, so that all uppercase characters become lowercase
543
     * and all lowercase characters become uppercase.
544
     *
545
     * @param string $pValue UTF-8 encoded string
546
     *
547
     * @return string
548
     */
549 21
    public static function strCaseReverse($pValue)
550
    {
551 21
        $characters = self::mbStrSplit($pValue);
552 21
        foreach ($characters as &$character) {
553 21
            if (self::mbIsUpper($character)) {
554 14
                $character = mb_strtolower($character, 'UTF-8');
555
            } else {
556 21
                $character = mb_strtoupper($character, 'UTF-8');
557
            }
558
        }
559
560 21
        return implode('', $characters);
561
    }
562
563
    /**
564
     * Identify whether a string contains a fractional numeric value,
565
     * and convert it to a numeric if it is.
566
     *
567
     * @param string &$operand string value to test
568
     *
569
     * @return bool
570
     */
571 2
    public static function convertToNumberIfFraction(&$operand)
572
    {
573 2
        if (preg_match('/^' . self::STRING_REGEXP_FRACTION . '$/i', $operand, $match)) {
574
            $sign = ($match[1] == '-') ? '-' : '+';
575
            $fractionFormula = '=' . $sign . $match[2] . $sign . $match[3];
576
            $operand = Calculation::getInstance()->_calculateFormulaValue($fractionFormula);
577
578
            return true;
579
        }
580
581 2
        return false;
582
    }
583
584
    //    function convertToNumberIfFraction()
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
585
586
    /**
587
     * Get the decimal separator. If it has not yet been set explicitly, try to obtain number
588
     * formatting information from locale.
589
     *
590
     * @return string
591
     */
592 36
    public static function getDecimalSeparator()
593
    {
594 36
        if (!isset(self::$decimalSeparator)) {
595 12
            $localeconv = localeconv();
596 12
            self::$decimalSeparator = ($localeconv['decimal_point'] != '')
597 12
                ? $localeconv['decimal_point'] : $localeconv['mon_decimal_point'];
598
599 12
            if (self::$decimalSeparator == '') {
600
                // Default to .
601
                self::$decimalSeparator = '.';
602
            }
603
        }
604
605 36
        return self::$decimalSeparator;
606
    }
607
608
    /**
609
     * Set the decimal separator. Only used by NumberFormat::toFormattedString()
610
     * to format output by \PhpOffice\PhpSpreadsheet\Writer\Html and \PhpOffice\PhpSpreadsheet\Writer\Pdf.
611
     *
612
     * @param string $pValue Character for decimal separator
613
     */
614 77
    public static function setDecimalSeparator($pValue)
615
    {
616 77
        self::$decimalSeparator = $pValue;
617 77
    }
618
619
    /**
620
     * Get the thousands separator. If it has not yet been set explicitly, try to obtain number
621
     * formatting information from locale.
622
     *
623
     * @return string
624
     */
625 44
    public static function getThousandsSeparator()
626
    {
627 44
        if (!isset(self::$thousandsSeparator)) {
628 12
            $localeconv = localeconv();
629 12
            self::$thousandsSeparator = ($localeconv['thousands_sep'] != '')
630 12
                ? $localeconv['thousands_sep'] : $localeconv['mon_thousands_sep'];
631
632 12
            if (self::$thousandsSeparator == '') {
633
                // Default to .
634
                self::$thousandsSeparator = ',';
635
            }
636
        }
637
638 44
        return self::$thousandsSeparator;
639
    }
640
641
    /**
642
     * Set the thousands separator. Only used by NumberFormat::toFormattedString()
643
     * to format output by \PhpOffice\PhpSpreadsheet\Writer\Html and \PhpOffice\PhpSpreadsheet\Writer\Pdf.
644
     *
645
     * @param string $pValue Character for thousands separator
646
     */
647 77
    public static function setThousandsSeparator($pValue)
648
    {
649 77
        self::$thousandsSeparator = $pValue;
650 77
    }
651
652
    /**
653
     *    Get the currency code. If it has not yet been set explicitly, try to obtain the
654
     *        symbol information from locale.
655
     *
656
     * @return string
657
     */
658 19
    public static function getCurrencyCode()
659
    {
660 19
        if (!empty(self::$currencyCode)) {
661 18
            return self::$currencyCode;
662
        }
663 3
        self::$currencyCode = '$';
664 3
        $localeconv = localeconv();
665 3
        if (!empty($localeconv['currency_symbol'])) {
666 3
            self::$currencyCode = $localeconv['currency_symbol'];
667
668 3
            return self::$currencyCode;
669
        }
670
        if (!empty($localeconv['int_curr_symbol'])) {
671
            self::$currencyCode = $localeconv['int_curr_symbol'];
672
673
            return self::$currencyCode;
674
        }
675
676
        return self::$currencyCode;
677
    }
678
679
    /**
680
     * Set the currency code. Only used by NumberFormat::toFormattedString()
681
     *        to format output by \PhpOffice\PhpSpreadsheet\Writer\Html and \PhpOffice\PhpSpreadsheet\Writer\Pdf.
682
     *
683
     * @param string $pValue Character for currency code
684
     */
685 41
    public static function setCurrencyCode($pValue)
686
    {
687 41
        self::$currencyCode = $pValue;
688 41
    }
689
690
    /**
691
     * Convert SYLK encoded string to UTF-8.
692
     *
693
     * @param string $pValue
694
     *
695
     * @return string UTF-8 encoded string
696
     */
697 2
    public static function SYLKtoUTF8($pValue)
698
    {
699 2
        self::buildCharacterSets();
700
701
        // If there is no escape character in the string there is nothing to do
702 2
        if (strpos($pValue, '') === false) {
703 1
            return $pValue;
704
        }
705
706 1
        foreach (self::$SYLKCharacters as $k => $v) {
707 1
            $pValue = str_replace($k, $v, $pValue);
708
        }
709
710 1
        return $pValue;
711
    }
712
713
    /**
714
     * Retrieve any leading numeric part of a string, or return the full string if no leading numeric
715
     * (handles basic integer or float, but not exponent or non decimal).
716
     *
717
     * @param string $value
718
     *
719
     * @return mixed string or only the leading numeric part of the string
720
     */
721 84
    public static function testStringAsNumeric($value)
722
    {
723 84
        if (is_numeric($value)) {
724 84
            return $value;
725
        }
726 3
        $v = (float) $value;
727
728 3
        return (is_numeric(substr($value, 0, strlen($v)))) ? $v : $value;
729
    }
730
}
731