PluginProbe
Visualizer – Tables & Charts Manager with Built-in AI Generator / 3.4.8
Visualizer – Tables & Charts Manager with Built-in AI Generator v3.4.8
4.0.7 4.0.6 4.0.5 4.0.4 4.0.3 3.0.5 3.0.6 3.0.7 3.0.8 3.0.9 3.1.0 3.1.1 3.1.2 3.1.3 3.10.0 3.10.1 3.10.10 3.10.11 3.10.12 3.10.13 3.10.14 3.10.15 3.10.2 3.10.3 3.10.4 All 148 releases
visualizer / vendor / phpoffice / phpspreadsheet / src / PhpSpreadsheet / Shared / StringHelper.php

StringHelper.php in Visualizer – Tables & Charts Manager with Built-in AI Generator 3.4.8, at vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/StringHelper.php

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