Completed
Push — develop ( 85c3bd...3560f1 )
by Adrien
21:11
created

StringHelper::setThousandsSeparator()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
ccs 3
cts 3
cp 1
crap 1
1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Shared;
4
5
/**
6
 * Copyright (c) 2006 - 2016 PhpSpreadsheet.
7
 *
8
 * This library is free software; you can redistribute it and/or
9
 * modify it under the terms of the GNU Lesser General Public
10
 * License as published by the Free Software Foundation; either
11
 * version 2.1 of the License, or (at your option) any later version.
12
 *
13
 * This library is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
 * Lesser General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Lesser General Public
19
 * License along with this library; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21
 *
22
 * @category   PhpSpreadsheet
23
 *
24
 * @copyright  Copyright (c) 2006 - 2016 PhpSpreadsheet (https://github.com/PHPOffice/PhpSpreadsheet)
25
 * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
26
 */
27
class StringHelper
28
{
29
    /**    Constants                */
30
    /**    Regular Expressions        */
31
    //    Fraction
32
    const STRING_REGEXP_FRACTION = '(-?)(\d+)\s+(\d+\/\d+)';
33
34
    /**
35
     * Control characters array.
36
     *
37
     * @var string[]
38
     */
39
    private static $controlCharacters = [];
40
41
    /**
42
     * SYLK Characters array.
43
     *
44
     * @var array
45
     */
46
    private static $SYLKCharacters = [];
47
48
    /**
49
     * Decimal separator.
50
     *
51
     * @var string
52
     */
53
    private static $decimalSeparator;
54
55
    /**
56
     * Thousands separator.
57
     *
58
     * @var string
59
     */
60
    private static $thousandsSeparator;
61
62
    /**
63
     * Currency code.
64
     *
65
     * @var string
66
     */
67
    private static $currencyCode;
68
69
    /**
70
     * Is iconv extension avalable?
71
     *
72
     * @var bool
73
     */
74
    private static $isIconvEnabled;
75
76
    /**
77
     * Build control characters array.
78
     */
79
    private static function buildControlCharacters()
80
    {
81
        for ($i = 0; $i <= 31; ++$i) {
82
            if ($i != 9 && $i != 10 && $i != 13) {
83
                $find = '_x' . sprintf('%04s', strtoupper(dechex($i))) . '_';
84
                $replace = chr($i);
85
                self::$controlCharacters[$find] = $replace;
86
            }
87
        }
88
    }
89
90
    /**
91
     * Build SYLK characters array.
92
     */
93
    private static function buildSYLKCharacters()
94
    {
95
        self::$SYLKCharacters = [
96
            "\x1B 0" => chr(0),
97
            "\x1B 1" => chr(1),
98
            "\x1B 2" => chr(2),
99
            "\x1B 3" => chr(3),
100
            "\x1B 4" => chr(4),
101
            "\x1B 5" => chr(5),
102
            "\x1B 6" => chr(6),
103
            "\x1B 7" => chr(7),
104
            "\x1B 8" => chr(8),
105
            "\x1B 9" => chr(9),
106
            "\x1B :" => chr(10),
107
            "\x1B ;" => chr(11),
108
            "\x1B <" => chr(12),
109
            "\x1B =" => chr(13),
110
            "\x1B >" => chr(14),
111
            "\x1B ?" => chr(15),
112
            "\x1B!0" => chr(16),
113
            "\x1B!1" => chr(17),
114
            "\x1B!2" => chr(18),
115
            "\x1B!3" => chr(19),
116
            "\x1B!4" => chr(20),
117
            "\x1B!5" => chr(21),
118
            "\x1B!6" => chr(22),
119
            "\x1B!7" => chr(23),
120
            "\x1B!8" => chr(24),
121
            "\x1B!9" => chr(25),
122
            "\x1B!:" => chr(26),
123
            "\x1B!;" => chr(27),
124
            "\x1B!<" => chr(28),
125
            "\x1B!=" => chr(29),
126
            "\x1B!>" => chr(30),
127
            "\x1B!?" => chr(31),
128
            "\x1B'?" => chr(127),
129
            "\x1B(0" => '€', // 128 in CP1252
130
            "\x1B(2" => '‚', // 130 in CP1252
131
            "\x1B(3" => 'ƒ', // 131 in CP1252
132
            "\x1B(4" => '„', // 132 in CP1252
133
            "\x1B(5" => '…', // 133 in CP1252
134
            "\x1B(6" => '†', // 134 in CP1252
135
            "\x1B(7" => '‡', // 135 in CP1252
136
            "\x1B(8" => 'ˆ', // 136 in CP1252
137
            "\x1B(9" => '‰', // 137 in CP1252
138
            "\x1B(:" => 'Š', // 138 in CP1252
139
            "\x1B(;" => '‹', // 139 in CP1252
140
            "\x1BNj" => 'Œ', // 140 in CP1252
141
            "\x1B(>" => 'Ž', // 142 in CP1252
142
            "\x1B)1" => '‘', // 145 in CP1252
143
            "\x1B)2" => '’', // 146 in CP1252
144
            "\x1B)3" => '“', // 147 in CP1252
145
            "\x1B)4" => '”', // 148 in CP1252
146
            "\x1B)5" => '•', // 149 in CP1252
147
            "\x1B)6" => '–', // 150 in CP1252
148
            "\x1B)7" => '—', // 151 in CP1252
149
            "\x1B)8" => '˜', // 152 in CP1252
150
            "\x1B)9" => '™', // 153 in CP1252
151
            "\x1B):" => 'š', // 154 in CP1252
152
            "\x1B);" => '›', // 155 in CP1252
153
            "\x1BNz" => 'œ', // 156 in CP1252
154
            "\x1B)>" => 'ž', // 158 in CP1252
155
            "\x1B)?" => 'Ÿ', // 159 in CP1252
156
            "\x1B*0" => ' ', // 160 in CP1252
157
            "\x1BN!" => '¡', // 161 in CP1252
158
            "\x1BN\"" => '¢', // 162 in CP1252
159
            "\x1BN#" => '£', // 163 in CP1252
160
            "\x1BN(" => '¤', // 164 in CP1252
161
            "\x1BN%" => '¥', // 165 in CP1252
162
            "\x1B*6" => '¦', // 166 in CP1252
163
            "\x1BN'" => '§', // 167 in CP1252
164
            "\x1BNH " => '¨', // 168 in CP1252
165
            "\x1BNS" => '©', // 169 in CP1252
166
            "\x1BNc" => 'ª', // 170 in CP1252
167
            "\x1BN+" => '«', // 171 in CP1252
168
            "\x1B*<" => '¬', // 172 in CP1252
169
            "\x1B*=" => '­', // 173 in CP1252
170
            "\x1BNR" => '®', // 174 in CP1252
171
            "\x1B*?" => '¯', // 175 in CP1252
172
            "\x1BN0" => '°', // 176 in CP1252
173
            "\x1BN1" => '±', // 177 in CP1252
174
            "\x1BN2" => '²', // 178 in CP1252
175
            "\x1BN3" => '³', // 179 in CP1252
176
            "\x1BNB " => '´', // 180 in CP1252
177
            "\x1BN5" => 'µ', // 181 in CP1252
178
            "\x1BN6" => '¶', // 182 in CP1252
179
            "\x1BN7" => '·', // 183 in CP1252
180
            "\x1B+8" => '¸', // 184 in CP1252
181
            "\x1BNQ" => '¹', // 185 in CP1252
182
            "\x1BNk" => 'º', // 186 in CP1252
183
            "\x1BN;" => '»', // 187 in CP1252
184
            "\x1BN<" => '¼', // 188 in CP1252
185
            "\x1BN=" => '½', // 189 in CP1252
186
            "\x1BN>" => '¾', // 190 in CP1252
187
            "\x1BN?" => '¿', // 191 in CP1252
188
            "\x1BNAA" => 'À', // 192 in CP1252
189
            "\x1BNBA" => 'Á', // 193 in CP1252
190
            "\x1BNCA" => 'Â', // 194 in CP1252
191
            "\x1BNDA" => 'Ã', // 195 in CP1252
192
            "\x1BNHA" => 'Ä', // 196 in CP1252
193
            "\x1BNJA" => 'Å', // 197 in CP1252
194
            "\x1BNa" => 'Æ', // 198 in CP1252
195
            "\x1BNKC" => 'Ç', // 199 in CP1252
196
            "\x1BNAE" => 'È', // 200 in CP1252
197
            "\x1BNBE" => 'É', // 201 in CP1252
198
            "\x1BNCE" => 'Ê', // 202 in CP1252
199
            "\x1BNHE" => 'Ë', // 203 in CP1252
200
            "\x1BNAI" => 'Ì', // 204 in CP1252
201
            "\x1BNBI" => 'Í', // 205 in CP1252
202
            "\x1BNCI" => 'Î', // 206 in CP1252
203
            "\x1BNHI" => 'Ï', // 207 in CP1252
204
            "\x1BNb" => 'Ð', // 208 in CP1252
205
            "\x1BNDN" => 'Ñ', // 209 in CP1252
206
            "\x1BNAO" => 'Ò', // 210 in CP1252
207
            "\x1BNBO" => 'Ó', // 211 in CP1252
208
            "\x1BNCO" => 'Ô', // 212 in CP1252
209
            "\x1BNDO" => 'Õ', // 213 in CP1252
210
            "\x1BNHO" => 'Ö', // 214 in CP1252
211
            "\x1B-7" => '×', // 215 in CP1252
212
            "\x1BNi" => 'Ø', // 216 in CP1252
213
            "\x1BNAU" => 'Ù', // 217 in CP1252
214
            "\x1BNBU" => 'Ú', // 218 in CP1252
215
            "\x1BNCU" => 'Û', // 219 in CP1252
216
            "\x1BNHU" => 'Ü', // 220 in CP1252
217
            "\x1B-=" => 'Ý', // 221 in CP1252
218
            "\x1BNl" => 'Þ', // 222 in CP1252
219
            "\x1BN{" => 'ß', // 223 in CP1252
220
            "\x1BNAa" => 'à', // 224 in CP1252
221
            "\x1BNBa" => 'á', // 225 in CP1252
222
            "\x1BNCa" => 'â', // 226 in CP1252
223
            "\x1BNDa" => 'ã', // 227 in CP1252
224
            "\x1BNHa" => 'ä', // 228 in CP1252
225
            "\x1BNJa" => 'å', // 229 in CP1252
226
            "\x1BNq" => 'æ', // 230 in CP1252
227
            "\x1BNKc" => 'ç', // 231 in CP1252
228
            "\x1BNAe" => 'è', // 232 in CP1252
229
            "\x1BNBe" => 'é', // 233 in CP1252
230
            "\x1BNCe" => 'ê', // 234 in CP1252
231
            "\x1BNHe" => 'ë', // 235 in CP1252
232
            "\x1BNAi" => 'ì', // 236 in CP1252
233
            "\x1BNBi" => 'í', // 237 in CP1252
234
            "\x1BNCi" => 'î', // 238 in CP1252
235
            "\x1BNHi" => 'ï', // 239 in CP1252
236
            "\x1BNs" => 'ð', // 240 in CP1252
237
            "\x1BNDn" => 'ñ', // 241 in CP1252
238
            "\x1BNAo" => 'ò', // 242 in CP1252
239
            "\x1BNBo" => 'ó', // 243 in CP1252
240
            "\x1BNCo" => 'ô', // 244 in CP1252
241
            "\x1BNDo" => 'õ', // 245 in CP1252
242
            "\x1BNHo" => 'ö', // 246 in CP1252
243
            "\x1B/7" => '÷', // 247 in CP1252
244
            "\x1BNy" => 'ø', // 248 in CP1252
245
            "\x1BNAu" => 'ù', // 249 in CP1252
246
            "\x1BNBu" => 'ú', // 250 in CP1252
247
            "\x1BNCu" => 'û', // 251 in CP1252
248
            "\x1BNHu" => 'ü', // 252 in CP1252
249
            "\x1B/=" => 'ý', // 253 in CP1252
250
            "\x1BN|" => 'þ', // 254 in CP1252
251
            "\x1BNHy" => 'ÿ', // 255 in CP1252
252
        ];
253
    }
254
255
    /**
256
     * Get whether iconv extension is available.
257
     *
258
     * @return bool
259
     */
260 76
    public static function getIsIconvEnabled()
261
    {
262 76
        if (isset(self::$isIconvEnabled)) {
263 75
            return self::$isIconvEnabled;
264
        }
265
266
        // Fail if iconv doesn't exist
267 62
        if (!function_exists('iconv')) {
268
            self::$isIconvEnabled = false;
269
270
            return false;
271
        }
272
273
        // Sometimes iconv is not working, and e.g. iconv('UTF-8', 'UTF-16LE', 'x') just returns false,
274 62
        if (!@iconv('UTF-8', 'UTF-16LE', 'x')) {
275
            self::$isIconvEnabled = false;
276
277
            return false;
278
        }
279
280
        // 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...
281
        // we cannot use iconv in that case either (http://bugs.php.net/bug.php?id=37773)
282 62
        if (!@iconv_substr('A', 0, 1, 'UTF-8')) {
283
            self::$isIconvEnabled = false;
284
285
            return false;
286
        }
287
288
        // CUSTOM: IBM AIX iconv() does not work
289 62
        if (defined('PHP_OS') && @stristr(PHP_OS, 'AIX') && defined('ICONV_IMPL') && (@strcasecmp(ICONV_IMPL, 'unknown') == 0) && defined('ICONV_VERSION') && (@strcasecmp(ICONV_VERSION, 'unknown') == 0)) {
290
            self::$isIconvEnabled = false;
291
292
            return false;
293
        }
294
295
        // If we reach here no problems were detected with iconv
296 62
        self::$isIconvEnabled = true;
297
298 62
        return true;
299
    }
300
301
    public static function buildCharacterSets()
302
    {
303
        if (empty(self::$controlCharacters)) {
304
            self::buildControlCharacters();
305
        }
306
        if (empty(self::$SYLKCharacters)) {
307
            self::buildSYLKCharacters();
308
        }
309
    }
310
311
    /**
312
     * Convert from OpenXML escaped control character to PHP control character.
313
     *
314
     * Excel 2007 team:
315
     * ----------------
316
     * That's correct, control characters are stored directly in the shared-strings table.
317
     * We do encode characters that cannot be represented in XML using the following escape sequence:
318
     * _xHHHH_ where H represents a hexadecimal character in the character's value...
319
     * So you could end up with something like _x0008_ in a string (either in a cell value (<v>)
320
     * element or in the shared string <t> element.
321
     *
322
     * @param string $value Value to unescape
323
     *
324
     * @return string
325
     */
326 8
    public static function controlCharacterOOXML2PHP($value = '')
327
    {
328 8
        return str_replace(array_keys(self::$controlCharacters), array_values(self::$controlCharacters), $value);
329
    }
330
331
    /**
332
     * Convert from PHP control character to OpenXML escaped control character.
333
     *
334
     * Excel 2007 team:
335
     * ----------------
336
     * That's correct, control characters are stored directly in the shared-strings table.
337
     * We do encode characters that cannot be represented in XML using the following escape sequence:
338
     * _xHHHH_ where H represents a hexadecimal character in the character's value...
339
     * So you could end up with something like _x0008_ in a string (either in a cell value (<v>)
340
     * element or in the shared string <t> element.
341
     *
342
     * @param string $value Value to escape
343
     *
344
     * @return string
345
     */
346 51
    public static function controlCharacterPHP2OOXML($value = '')
347
    {
348 51
        return str_replace(array_values(self::$controlCharacters), array_keys(self::$controlCharacters), $value);
349
    }
350
351
    /**
352
     * Try to sanitize UTF8, stripping invalid byte sequences. Not perfect. Does not surrogate characters.
353
     *
354
     * @param string $value
355
     *
356
     * @return string
357
     */
358 65
    public static function sanitizeUTF8($value)
359
    {
360 65
        if (self::getIsIconvEnabled()) {
361 65
            $value = @iconv('UTF-8', 'UTF-8', $value);
362
363 65
            return $value;
364
        }
365
366
        $value = mb_convert_encoding($value, 'UTF-8', 'UTF-8');
367
368
        return $value;
369
    }
370
371
    /**
372
     * Check if a string contains UTF8 data.
373
     *
374
     * @param string $value
375
     *
376
     * @return bool
377
     */
378
    public static function isUTF8($value = '')
379
    {
380
        return $value === '' || preg_match('/^./su', $value) === 1;
381
    }
382
383
    /**
384
     * Formats a numeric value as a string for output in various output writers forcing
385
     * point as decimal separator in case locale is other than English.
386
     *
387
     * @param mixed $value
388
     *
389
     * @return string
390
     */
391 60
    public static function formatNumber($value)
392
    {
393 60
        if (is_float($value)) {
394 60
            return str_replace(',', '.', $value);
395
        }
396
397 56
        return (string) $value;
398
    }
399
400
    /**
401
     * Converts a UTF-8 string into BIFF8 Unicode string data (8-bit string length)
402
     * Writes the string using uncompressed notation, no rich text, no Asian phonetics
403
     * If mbstring extension is not available, ASCII is assumed, and compressed notation is used
404
     * although this will give wrong results for non-ASCII strings
405
     * see OpenOffice.org's Documentation of the Microsoft Excel File Format, sect. 2.5.3.
406
     *
407
     * @param string $value UTF-8 encoded string
408
     * @param mixed[] $arrcRuns Details of rich text runs in $value
409
     *
410
     * @return string
411
     */
412 38
    public static function UTF8toBIFF8UnicodeShort($value, $arrcRuns = [])
413
    {
414
        // character count
415 38
        $ln = self::countCharacters($value, 'UTF-8');
416
        // option flags
417 38
        if (empty($arrcRuns)) {
418 38
            $data = pack('CC', $ln, 0x0001);
419
            // characters
420 38
            $data .= self::convertEncoding($value, 'UTF-16LE', 'UTF-8');
421
        } else {
422 9
            $data = pack('vC', $ln, 0x09);
423 9
            $data .= pack('v', count($arrcRuns));
424
            // characters
425 9
            $data .= self::convertEncoding($value, 'UTF-16LE', 'UTF-8');
426 9
            foreach ($arrcRuns as $cRun) {
427 9
                $data .= pack('v', $cRun['strlen']);
428 9
                $data .= pack('v', $cRun['fontidx']);
429
            }
430
        }
431
432 38
        return $data;
433
    }
434
435
    /**
436
     * Converts a UTF-8 string into BIFF8 Unicode string data (16-bit string length)
437
     * Writes the string using uncompressed notation, no rich text, no Asian phonetics
438
     * If mbstring extension is not available, ASCII is assumed, and compressed notation is used
439
     * although this will give wrong results for non-ASCII strings
440
     * see OpenOffice.org's Documentation of the Microsoft Excel File Format, sect. 2.5.3.
441
     *
442
     * @param string $value UTF-8 encoded string
443
     *
444
     * @return string
445
     */
446 38
    public static function UTF8toBIFF8UnicodeLong($value)
447
    {
448
        // character count
449 38
        $ln = self::countCharacters($value, 'UTF-8');
450
451
        // characters
452 38
        $chars = self::convertEncoding($value, 'UTF-16LE', 'UTF-8');
453
454 38
        $data = pack('vC', $ln, 0x0001) . $chars;
455
456 38
        return $data;
457
    }
458
459
    /**
460
     * Convert string from one encoding to another.
461
     *
462
     * @param string $value
463
     * @param string $to Encoding to convert to, e.g. 'UTF-8'
464
     * @param string $from Encoding to convert from, e.g. 'UTF-16LE'
465
     *
466
     * @return string
467
     */
468 38
    public static function convertEncoding($value, $to, $from)
469
    {
470 38
        if (self::getIsIconvEnabled()) {
471 38
            return iconv($from, $to . '//IGNORE//TRANSLIT', $value);
472
        }
473
474
        return mb_convert_encoding($value, $to, $from);
475
    }
476
477
    /**
478
     * Get character count.
479
     *
480
     * @param string $value
481
     * @param string $enc Encoding
482
     *
483
     * @return int Character count
484
     */
485 103
    public static function countCharacters($value, $enc = 'UTF-8')
486
    {
487 103
        return mb_strlen($value, $enc);
488
    }
489
490
    /**
491
     * Get a substring of a UTF-8 encoded string.
492
     *
493
     * @param string $pValue UTF-8 encoded string
494
     * @param int $pStart Start offset
495
     * @param int $pLength Maximum number of characters in substring
496
     *
497
     * @return string
498
     */
499 79
    public static function substring($pValue = '', $pStart = 0, $pLength = 0)
500
    {
501 79
        return mb_substr($pValue, $pStart, $pLength, 'UTF-8');
502
    }
503
504
    /**
505
     * Convert a UTF-8 encoded string to upper case.
506
     *
507
     * @param string $pValue UTF-8 encoded string
508
     *
509
     * @return string
510
     */
511 4
    public static function strToUpper($pValue = '')
512
    {
513 4
        return mb_convert_case($pValue, MB_CASE_UPPER, 'UTF-8');
514
    }
515
516
    /**
517
     * Convert a UTF-8 encoded string to lower case.
518
     *
519
     * @param string $pValue UTF-8 encoded string
520
     *
521
     * @return string
522
     */
523 4
    public static function strToLower($pValue = '')
524
    {
525 4
        return mb_convert_case($pValue, MB_CASE_LOWER, 'UTF-8');
526
    }
527
528
    /**
529
     * Convert a UTF-8 encoded string to title/proper case
530
     * (uppercase every first character in each word, lower case all other characters).
531
     *
532
     * @param string $pValue UTF-8 encoded string
533
     *
534
     * @return string
535
     */
536 3
    public static function strToTitle($pValue = '')
537
    {
538 3
        return mb_convert_case($pValue, MB_CASE_TITLE, 'UTF-8');
539
    }
540
541 21
    public static function mbIsUpper($char)
542
    {
543 21
        return mb_strtolower($char, 'UTF-8') != $char;
544
    }
545
546 21
    public static function mbStrSplit($string)
547
    {
548
        // Split at all position not after the start: ^
549
        // and not before the end: $
550 21
        return preg_split('/(?<!^)(?!$)/u', $string);
551
    }
552
553
    /**
554
     * Reverse the case of a string, so that all uppercase characters become lowercase
555
     * and all lowercase characters become uppercase.
556
     *
557
     * @param string $pValue UTF-8 encoded string
558
     *
559
     * @return string
560
     */
561 21
    public static function strCaseReverse($pValue = '')
562
    {
563 21
        $characters = self::mbStrSplit($pValue);
564 21
        foreach ($characters as &$character) {
565 21
            if (self::mbIsUpper($character)) {
566 14
                $character = mb_strtolower($character, 'UTF-8');
567
            } else {
568 21
                $character = mb_strtoupper($character, 'UTF-8');
569
            }
570
        }
571
572 21
        return implode('', $characters);
573
    }
574
575
    /**
576
     * Identify whether a string contains a fractional numeric value,
577
     * and convert it to a numeric if it is.
578
     *
579
     * @param string &$operand string value to test
580
     *
581
     * @return bool
582
     */
583 1
    public static function convertToNumberIfFraction(&$operand)
584
    {
585 1
        if (preg_match('/^' . self::STRING_REGEXP_FRACTION . '$/i', $operand, $match)) {
586
            $sign = ($match[1] == '-') ? '-' : '+';
587
            $fractionFormula = '=' . $sign . $match[2] . $sign . $match[3];
588
            $operand = \PhpOffice\PhpSpreadsheet\Calculation::getInstance()->_calculateFormulaValue($fractionFormula);
589
590
            return true;
591
        }
592
593 1
        return false;
594
    }
595
596
    //    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...
597
598
    /**
599
     * Get the decimal separator. If it has not yet been set explicitly, try to obtain number
600
     * formatting information from locale.
601
     *
602
     * @return string
603
     */
604 31
    public static function getDecimalSeparator()
605
    {
606 31
        if (!isset(self::$decimalSeparator)) {
607 7
            $localeconv = localeconv();
608 7
            self::$decimalSeparator = ($localeconv['decimal_point'] != '')
609 7
                ? $localeconv['decimal_point'] : $localeconv['mon_decimal_point'];
610
611 7
            if (self::$decimalSeparator == '') {
612
                // Default to .
613
                self::$decimalSeparator = '.';
614
            }
615
        }
616
617 31
        return self::$decimalSeparator;
618
    }
619
620
    /**
621
     * Set the decimal separator. Only used by \PhpOffice\PhpSpreadsheet\Style\NumberFormat::toFormattedString()
622
     * to format output by \PhpOffice\PhpSpreadsheet\Writer\Html and \PhpOffice\PhpSpreadsheet\Writer\Pdf.
623
     *
624
     * @param string $pValue Character for decimal separator
625
     */
626 77
    public static function setDecimalSeparator($pValue = '.')
627
    {
628 77
        self::$decimalSeparator = $pValue;
629 77
    }
630
631
    /**
632
     * Get the thousands separator. If it has not yet been set explicitly, try to obtain number
633
     * formatting information from locale.
634
     *
635
     * @return string
636
     */
637 39
    public static function getThousandsSeparator()
638
    {
639 39
        if (!isset(self::$thousandsSeparator)) {
640 7
            $localeconv = localeconv();
641 7
            self::$thousandsSeparator = ($localeconv['thousands_sep'] != '')
642 7
                ? $localeconv['thousands_sep'] : $localeconv['mon_thousands_sep'];
643
644 7
            if (self::$thousandsSeparator == '') {
645
                // Default to .
646
                self::$thousandsSeparator = ',';
647
            }
648
        }
649
650 39
        return self::$thousandsSeparator;
651
    }
652
653
    /**
654
     * Set the thousands separator. Only used by \PhpOffice\PhpSpreadsheet\Style\NumberFormat::toFormattedString()
655
     * to format output by \PhpOffice\PhpSpreadsheet\Writer\Html and \PhpOffice\PhpSpreadsheet\Writer\Pdf.
656
     *
657
     * @param string $pValue Character for thousands separator
658
     */
659 77
    public static function setThousandsSeparator($pValue = ',')
660
    {
661 77
        self::$thousandsSeparator = $pValue;
662 77
    }
663
664
    /**
665
     *    Get the currency code. If it has not yet been set explicitly, try to obtain the
666
     *        symbol information from locale.
667
     *
668
     * @return string
669
     */
670 18
    public static function getCurrencyCode()
671
    {
672 18
        if (!empty(self::$currencyCode)) {
673 17
            return self::$currencyCode;
674
        }
675 2
        self::$currencyCode = '$';
676 2
        $localeconv = localeconv();
677 2
        if (!empty($localeconv['currency_symbol'])) {
678 2
            self::$currencyCode = $localeconv['currency_symbol'];
679
680 2
            return self::$currencyCode;
681
        }
682
        if (!empty($localeconv['int_curr_symbol'])) {
683
            self::$currencyCode = $localeconv['int_curr_symbol'];
684
685
            return self::$currencyCode;
686
        }
687
688
        return self::$currencyCode;
689
    }
690
691
    /**
692
     * Set the currency code. Only used by \PhpOffice\PhpSpreadsheet\Style\NumberFormat::toFormattedString()
693
     *        to format output by \PhpOffice\PhpSpreadsheet\Writer\Html and \PhpOffice\PhpSpreadsheet\Writer\Pdf.
694
     *
695
     * @param string $pValue Character for currency code
696
     */
697 38
    public static function setCurrencyCode($pValue = '$')
698
    {
699 38
        self::$currencyCode = $pValue;
700 38
    }
701
702
    /**
703
     * Convert SYLK encoded string to UTF-8.
704
     *
705
     * @param string $pValue
706
     *
707
     * @return string UTF-8 encoded string
708
     */
709 1
    public static function SYLKtoUTF8($pValue = '')
710
    {
711
        // If there is no escape character in the string there is nothing to do
712 1
        if (strpos($pValue, '') === false) {
713 1
            return $pValue;
714
        }
715
716
        foreach (self::$SYLKCharacters as $k => $v) {
717
            $pValue = str_replace($k, $v, $pValue);
718
        }
719
720
        return $pValue;
721
    }
722
723
    /**
724
     * Retrieve any leading numeric part of a string, or return the full string if no leading numeric
725
     * (handles basic integer or float, but not exponent or non decimal).
726
     *
727
     * @param string $value
728
     *
729
     * @return mixed string or only the leading numeric part of the string
730
     */
731 83
    public static function testStringAsNumeric($value)
732
    {
733 83
        if (is_numeric($value)) {
734 83
            return $value;
735
        }
736 3
        $v = (float) $value;
737
738 3
        return (is_numeric(substr($value, 0, strlen($v)))) ? $v : $value;
739
    }
740
}
741