PluginProbe
wpDataTables – WordPress Data Table, Dynamic Tables & Table Charts Plugin / 6.5.1.7
wpDataTables – WordPress Data Table, Dynamic Tables & Table Charts Plugin v6.5.1.7
6.5.1.7 6.5.1.6 6.5.1.5 6.5.1.4 6.5.1.3 6.5.1.2 6.5.1.1 6.5.0.9 6.5.0.8 6.5.0.7 6.5.0.6 trunk 3.4.2.40 3.4.2.41 3.4.2.42 3.4.2.43 3.4.2.44 3.4.2.45 3.4.2.46 3.4.2.47 3.4.2.48 3.4.2.49 3.4.2.50 6.3.2 6.3.3.1 All 47 releases
wpdatatables / lib / phpoffice / phpspreadsheet / src / PhpSpreadsheet / Calculation / Engine / FormattedNumber.php

FormattedNumber.php in wpDataTables – WordPress Data Table, Dynamic Tables & Table Charts Plugin 6.5.1.7, at lib/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engine/FormattedNumber.php

148 lines 5.9 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\Calculation\Engine;
4
5 use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
6 use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
7
8 class FormattedNumber
9 {
10 /** Constants */
11 /** Regular Expressions */
12 private const STRING_REGEXP_FRACTION = '~^\s*(-?)((\d*)\s+)?(\d+\/\d+)\s*$~';
13
14 private const STRING_REGEXP_PERCENT = '~^(?:(?: *(?<PrefixedSign>[-+])? *\% *(?<PrefixedSign2>[-+])? *(?<PrefixedValue>[0-9]+\.?[0-9*]*(?:E[-+]?[0-9]*)?) *)|(?: *(?<PostfixedSign>[-+])? *(?<PostfixedValue>[0-9]+\.?[0-9]*(?:E[-+]?[0-9]*)?) *\% *))$~i';
15
16 // preg_quoted string for major currency symbols, with a %s for locale currency
17 private const CURRENCY_CONVERSION_LIST = '\$€£¥%s';
18
19 private const STRING_CONVERSION_LIST = [
20 [self::class, 'convertToNumberIfNumeric'],
21 [self::class, 'convertToNumberIfFraction'],
22 [self::class, 'convertToNumberIfPercent'],
23 [self::class, 'convertToNumberIfCurrency'],
24 ];
25
26 /**
27 * Identify whether a string contains a formatted numeric value,
28 * and convert it to a numeric if it is.
29 *
30 * @param string $operand string value to test
31 */
32 public static function convertToNumberIfFormatted(string &$operand): bool
33 {
34 foreach (self::STRING_CONVERSION_LIST as $conversionMethod) {
35 if ($conversionMethod($operand) === true) {
36 return true;
37 }
38 }
39
40 return false;
41 }
42
43 /**
44 * Identify whether a string contains a numeric value,
45 * and convert it to a numeric if it is.
46 *
47 * @param string $operand string value to test
48 */
49 public static function convertToNumberIfNumeric(string &$operand): bool
50 {
51 $thousandsSeparator = preg_quote(StringHelper::getThousandsSeparator(), '/');
52 $value = preg_replace(['/(\d)' . $thousandsSeparator . '(\d)/u', '/([+-])\s+(\d)/u'], ['$1$2', '$1$2'], trim($operand));
53 $decimalSeparator = preg_quote(StringHelper::getDecimalSeparator(), '/');
54 $value = preg_replace(['/(\d)' . $decimalSeparator . '(\d)/u', '/([+-])\s+(\d)/u'], ['$1.$2', '$1$2'], $value ?? '');
55
56 if (is_numeric($value)) {
57 $operand = (float) $value;
58
59 return true;
60 }
61
62 return false;
63 }
64
65 /**
66 * Identify whether a string contains a fractional numeric value,
67 * and convert it to a numeric if it is.
68 *
69 * @param string $operand string value to test
70 */
71 public static function convertToNumberIfFraction(string &$operand): bool
72 {
73 if (preg_match(self::STRING_REGEXP_FRACTION, $operand, $match)) {
74 $sign = ($match[1] === '-') ? '-' : '+';
75 $wholePart = ($match[3] === '') ? '' : ($sign . $match[3]);
76 $fractionFormula = '=' . $wholePart . $sign . $match[4];
77 $operand = Calculation::getInstance()->_calculateFormulaValue($fractionFormula);
78
79 return true;
80 }
81
82 return false;
83 }
84
85 /**
86 * Identify whether a string contains a percentage, and if so,
87 * convert it to a numeric.
88 *
89 * @param string $operand string value to test
90 */
91 public static function convertToNumberIfPercent(string &$operand): bool
92 {
93 $thousandsSeparator = preg_quote(StringHelper::getThousandsSeparator(), '/');
94 $value = preg_replace('/(\d)' . $thousandsSeparator . '(\d)/u', '$1$2', trim($operand));
95 $decimalSeparator = preg_quote(StringHelper::getDecimalSeparator(), '/');
96 $value = preg_replace(['/(\d)' . $decimalSeparator . '(\d)/u', '/([+-])\s+(\d)/u'], ['$1.$2', '$1$2'], $value ?? '');
97
98 $match = [];
99 if ($value !== null && preg_match(self::STRING_REGEXP_PERCENT, $value, $match, PREG_UNMATCHED_AS_NULL)) {
100 //Calculate the percentage
101 $sign = ($match['PrefixedSign'] ?? $match['PrefixedSign2'] ?? $match['PostfixedSign']) ?? '';
102 $operand = (float) ($sign . ($match['PostfixedValue'] ?? $match['PrefixedValue'])) / 100;
103
104 return true;
105 }
106
107 return false;
108 }
109
110 /**
111 * Identify whether a string contains a currency value, and if so,
112 * convert it to a numeric.
113 *
114 * @param string $operand string value to test
115 */
116 public static function convertToNumberIfCurrency(string &$operand): bool
117 {
118 $currencyRegexp = self::currencyMatcherRegexp();
119 $thousandsSeparator = preg_quote(StringHelper::getThousandsSeparator(), '/');
120 $value = preg_replace('/(\d)' . $thousandsSeparator . '(\d)/u', '$1$2', $operand);
121
122 $match = [];
123 if ($value !== null && preg_match($currencyRegexp, $value, $match, PREG_UNMATCHED_AS_NULL)) {
124 //Determine the sign
125 $sign = ($match['PrefixedSign'] ?? $match['PrefixedSign2'] ?? $match['PostfixedSign']) ?? '';
126 $decimalSeparator = StringHelper::getDecimalSeparator();
127 //Cast to a float
128 $intermediate = (string) ($match['PostfixedValue'] ?? $match['PrefixedValue']);
129 $intermediate = str_replace($decimalSeparator, '.', $intermediate);
130 if (is_numeric($intermediate)) {
131 $operand = (float) ($sign . str_replace($decimalSeparator, '.', $intermediate));
132
133 return true;
134 }
135 }
136
137 return false;
138 }
139
140 public static function currencyMatcherRegexp(): string
141 {
142 $currencyCodes = sprintf(self::CURRENCY_CONVERSION_LIST, preg_quote(StringHelper::getCurrencyCode(), '/'));
143 $decimalSeparator = preg_quote(StringHelper::getDecimalSeparator(), '/');
144
145 return '~^(?:(?: *(?<PrefixedSign>[-+])? *(?<PrefixedCurrency>[' . $currencyCodes . ']) *(?<PrefixedSign2>[-+])? *(?<PrefixedValue>[0-9]+[' . $decimalSeparator . ']?[0-9*]*(?:E[-+]?[0-9]*)?) *)|(?: *(?<PostfixedSign>[-+])? *(?<PostfixedValue>[0-9]+' . $decimalSeparator . '?[0-9]*(?:E[-+]?[0-9]*)?) *(?<PostfixedCurrency>[' . $currencyCodes . ']) *))$~ui';
146 }
147 }
148