Refactor Util::formatNumber()
Trim whitespace and add more unit prefixes. Signed-off-by: Maurício Meneghini Fauth <mauricio@mfauth.net>
This commit is contained in:
parent
ba1743bdc0
commit
09e8144e97
@ -2884,7 +2884,13 @@ parameters:
|
||||
path: src/Controllers/Server/Status/StatusController.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$value of static method PhpMyAdmin\\Util\:\:formatNumber\(\) expects float\|int\|string, mixed given\.$#'
|
||||
message: '#^Parameter \#1 \$value of static method PhpMyAdmin\\Util\:\:formatNumber\(\) expects float\|int\|numeric\-string, float\|int\|string given\.$#'
|
||||
identifier: argument.type
|
||||
count: 4
|
||||
path: src/Controllers/Server/Status/StatusController.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$value of static method PhpMyAdmin\\Util\:\:formatNumber\(\) expects float\|int\|numeric\-string, mixed given\.$#'
|
||||
identifier: argument.type
|
||||
count: 5
|
||||
path: src/Controllers/Server/Status/StatusController.php
|
||||
@ -6058,7 +6064,7 @@ parameters:
|
||||
path: src/Engines/Innodb.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$value of static method PhpMyAdmin\\Util\:\:formatNumber\(\) expects float\|int\|string, mixed given\.$#'
|
||||
message: '#^Parameter \#1 \$value of static method PhpMyAdmin\\Util\:\:formatNumber\(\) expects float\|int\|numeric\-string, mixed given\.$#'
|
||||
identifier: argument.type
|
||||
count: 11
|
||||
path: src/Engines/Innodb.php
|
||||
@ -13888,7 +13894,7 @@ parameters:
|
||||
path: src/StorageEngine.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$value of static method PhpMyAdmin\\Util\:\:formatNumber\(\) expects float\|int\|string, mixed given\.$#'
|
||||
message: '#^Parameter \#1 \$value of static method PhpMyAdmin\\Util\:\:formatNumber\(\) expects float\|int\|numeric\-string, mixed given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: src/StorageEngine.php
|
||||
@ -15012,18 +15018,6 @@ parameters:
|
||||
count: 1
|
||||
path: src/Util.php
|
||||
|
||||
-
|
||||
message: '#^Loose comparison via "\!\=" is not allowed\.$#'
|
||||
identifier: notEqual.notAllowed
|
||||
count: 2
|
||||
path: src/Util.php
|
||||
|
||||
-
|
||||
message: '#^Loose comparison via "\=\=" is not allowed\.$#'
|
||||
identifier: equal.notAllowed
|
||||
count: 3
|
||||
path: src/Util.php
|
||||
|
||||
-
|
||||
message: '#^Method PhpMyAdmin\\Util\:\:getDbInfo\(\) return type has no value type specified in iterable type array\.$#'
|
||||
identifier: missingType.iterableValue
|
||||
@ -16888,7 +16882,7 @@ parameters:
|
||||
path: tests/unit/Controllers/Server/Status/QueriesControllerTest.php
|
||||
|
||||
-
|
||||
message: '#^Parameter \#1 \$value of static method PhpMyAdmin\\Util\:\:formatNumber\(\) expects float\|int\|string, mixed given\.$#'
|
||||
message: '#^Parameter \#1 \$value of static method PhpMyAdmin\\Util\:\:formatNumber\(\) expects float\|int\|numeric\-string, mixed given\.$#'
|
||||
identifier: argument.type
|
||||
count: 1
|
||||
path: tests/unit/Controllers/Server/Status/QueriesControllerTest.php
|
||||
|
||||
@ -1925,6 +1925,12 @@
|
||||
</PossiblyUnusedReturnValue>
|
||||
</file>
|
||||
<file src="src/Controllers/Server/Status/StatusController.php">
|
||||
<ArgumentTypeCoercion>
|
||||
<code><![CDATA[$this->data->status['Aborted_clients']]]></code>
|
||||
<code><![CDATA[$this->data->status['Aborted_connects']]]></code>
|
||||
<code><![CDATA[$this->data->status['Connections']]]></code>
|
||||
<code><![CDATA[$this->data->status['Max_used_connections']]]></code>
|
||||
</ArgumentTypeCoercion>
|
||||
<PossiblyInvalidOperand>
|
||||
<code><![CDATA[$this->data->status['Aborted_clients']]]></code>
|
||||
<code><![CDATA[$this->data->status['Aborted_clients']]]></code>
|
||||
@ -9256,6 +9262,10 @@
|
||||
</MixedArgument>
|
||||
</file>
|
||||
<file src="src/Util.php">
|
||||
<ArgumentTypeCoercion>
|
||||
<code><![CDATA[$value]]></code>
|
||||
<code><![CDATA[$value]]></code>
|
||||
</ArgumentTypeCoercion>
|
||||
<DeprecatedMethod>
|
||||
<code><![CDATA[Config::getInstance()]]></code>
|
||||
<code><![CDATA[Config::getInstance()]]></code>
|
||||
@ -9275,9 +9285,6 @@
|
||||
<code><![CDATA[DatabaseInterface::getInstance()]]></code>
|
||||
<code><![CDATA[DatabaseInterface::getInstance()]]></code>
|
||||
</DeprecatedMethod>
|
||||
<InvalidArrayOffset>
|
||||
<code><![CDATA[$units[$d]]]></code>
|
||||
</InvalidArrayOffset>
|
||||
<MixedArgument>
|
||||
<code><![CDATA[$array]]></code>
|
||||
</MixedArgument>
|
||||
@ -9296,12 +9303,9 @@
|
||||
<MixedAssignment>
|
||||
<code><![CDATA[$array]]></code>
|
||||
<code><![CDATA[$columnNames[]]]></code>
|
||||
<code><![CDATA[$unit]]></code>
|
||||
<code><![CDATA[$value]]></code>
|
||||
</MixedAssignment>
|
||||
<MixedOperand>
|
||||
<code><![CDATA[$unit]]></code>
|
||||
<code><![CDATA[$unit]]></code>
|
||||
<code><![CDATA[$value]]></code>
|
||||
</MixedOperand>
|
||||
<MixedReturnStatement>
|
||||
|
||||
84
src/Util.php
84
src/Util.php
@ -47,6 +47,7 @@ use function is_object;
|
||||
use function is_scalar;
|
||||
use function is_string;
|
||||
use function log10;
|
||||
use function max;
|
||||
use function mb_detect_encoding;
|
||||
use function mb_strlen;
|
||||
use function mb_strpos;
|
||||
@ -365,11 +366,11 @@ class Util
|
||||
* echo formatNumber(0, 6); // 0
|
||||
* </code>
|
||||
*
|
||||
* @param float|int|string $value the value to format
|
||||
* @param int $digitsLeft number of digits left of the comma
|
||||
* @param int $digitsRight number of digits right of the comma
|
||||
* @param bool $onlyDown do not reformat numbers below 1
|
||||
* @param bool $noTrailingZero removes trailing zeros right of the comma (default: true)
|
||||
* @param float|int|numeric-string $value the value to format
|
||||
* @param int $digitsLeft number of digits left of the comma
|
||||
* @param int $digitsRight number of digits right of the comma
|
||||
* @param bool $onlyDown do not reformat numbers below 1
|
||||
* @param bool $noTrailingZero removes trailing zeros right of the comma (default: true)
|
||||
*
|
||||
* @return string the formatted value and its unit
|
||||
*/
|
||||
@ -381,51 +382,26 @@ class Util
|
||||
bool $onlyDown = false,
|
||||
bool $noTrailingZero = true,
|
||||
): string {
|
||||
if ($value == 0) {
|
||||
$value = (float) $value;
|
||||
if ($value === 0.0) {
|
||||
return '0';
|
||||
}
|
||||
|
||||
if (is_string($value)) {
|
||||
$value = (float) $value;
|
||||
}
|
||||
|
||||
/* l10n: Decimal separator */
|
||||
$decimalSep = __('.');
|
||||
/* l10n: Thousands separator */
|
||||
$thousandsSep = __(',');
|
||||
|
||||
$originalValue = $value;
|
||||
//number_format is not multibyte safe, str_replace is safe
|
||||
if ($digitsLeft === 0) {
|
||||
$value = number_format((float) $value, $digitsRight, $decimalSep, $thousandsSep);
|
||||
if ($originalValue != 0 && (float) $value == 0) {
|
||||
return ' <' . number_format((1 / 10 ** $digitsRight), $digitsRight, $decimalSep, $thousandsSep);
|
||||
$value = number_format($value, $digitsRight, $decimalSep, $thousandsSep);
|
||||
if ((float) $value === 0.0) {
|
||||
return '<' . number_format((1 / 10 ** $digitsRight), $digitsRight, $decimalSep, $thousandsSep);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
// this units needs no translation, ISO
|
||||
$units = [
|
||||
-8 => 'y',
|
||||
-7 => 'z',
|
||||
-6 => 'a',
|
||||
-5 => 'f',
|
||||
-4 => 'p',
|
||||
-3 => 'n',
|
||||
-2 => 'µ',
|
||||
-1 => 'm',
|
||||
0 => ' ',
|
||||
1 => 'k',
|
||||
2 => 'M',
|
||||
3 => 'G',
|
||||
4 => 'T',
|
||||
5 => 'P',
|
||||
6 => 'E',
|
||||
7 => 'Z',
|
||||
8 => 'Y',
|
||||
];
|
||||
|
||||
// check for negative value to retain sign
|
||||
if ($value < 0) {
|
||||
$sign = '-';
|
||||
@ -437,9 +413,9 @@ class Util
|
||||
$dh = 10 ** $digitsRight;
|
||||
|
||||
// This gives us the right SI prefix already, but $digits_left parameter not incorporated
|
||||
$d = floor(log10((float) $value) / 3);
|
||||
$d = floor(log10($value) / 3);
|
||||
// Lowering the SI prefix by 1 gives us an additional 3 zeros
|
||||
// So if we have 3,6,9,12.. free digits ($digits_left - $cur_digits) to use, then lower the SI prefix
|
||||
// So if we have 3,6,9,12... free digits ($digits_left - $cur_digits) to use, then lower the SI prefix
|
||||
$curDigits = floor(log10($value / 1000 ** $d) + 1);
|
||||
if ($digitsLeft > $curDigits) {
|
||||
$d -= floor(($digitsLeft - $curDigits) / 3);
|
||||
@ -449,6 +425,32 @@ class Util
|
||||
$d = 0;
|
||||
}
|
||||
|
||||
// SI unit prefixes need no translation
|
||||
$units = [
|
||||
-10 => 'q', // quecto
|
||||
-9 => 'r', // ronto
|
||||
-8 => 'y', // yocto
|
||||
-7 => 'z', // zepto
|
||||
-6 => 'a', // atto
|
||||
-5 => 'f', // femto
|
||||
-4 => 'p', // pico
|
||||
-3 => 'n', // nano
|
||||
-2 => 'µ', // micro
|
||||
-1 => 'm', // milli
|
||||
0 => '',
|
||||
1 => 'k', // kilo
|
||||
2 => 'M', // mega
|
||||
3 => 'G', // giga
|
||||
4 => 'T', // tera
|
||||
5 => 'P', // peta
|
||||
6 => 'E', // exa
|
||||
7 => 'Z', // zetta
|
||||
8 => 'Y', // yotta
|
||||
9 => 'R', // ronna
|
||||
10 => 'Q', // quetta
|
||||
];
|
||||
|
||||
$d = min(max((int) $d, -10), 10);
|
||||
$value = round($value / (1000 ** $d / $dh)) / $dh;
|
||||
$unit = $units[$d];
|
||||
|
||||
@ -459,11 +461,13 @@ class Util
|
||||
$formattedValue = preg_replace('/' . preg_quote($decimalSep, '/') . '?0+$/', '', $formattedValue);
|
||||
}
|
||||
|
||||
if ($originalValue != 0 && $value == 0) {
|
||||
return ' <' . number_format(1 / 10 ** $digitsRight, $digitsRight, $decimalSep, $thousandsSep) . ' ' . $unit;
|
||||
if ($value === 0.0) {
|
||||
return '<'
|
||||
. number_format(1 / 10 ** $digitsRight, $digitsRight, $decimalSep, $thousandsSep)
|
||||
. ($unit === '' ? '' : ' ' . $unit);
|
||||
}
|
||||
|
||||
return $sign . $formattedValue . ' ' . $unit;
|
||||
return $sign . $formattedValue . ($unit === '' ? '' : ' ' . $unit);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -194,7 +194,7 @@ class InnodbTest extends AbstractTestCase
|
||||
' </tr>' . "\n" .
|
||||
' <tr>' . "\n" .
|
||||
' <th scope="row">Read misses in %</th>' . "\n" .
|
||||
' <td class="font-monospace text-end">50 %' . "\n" .
|
||||
' <td class="font-monospace text-end">50 %' . "\n" .
|
||||
'</td>' . "\n" .
|
||||
' </tr>' . "\n" .
|
||||
' <tr>' . "\n" .
|
||||
|
||||
@ -538,7 +538,7 @@ class UtilTest extends AbstractTestCase
|
||||
];
|
||||
}
|
||||
|
||||
/** @psalm-param list{0: float|int|string, 1?: int, 2?: int, 3?: bool, 4?: bool} $arguments */
|
||||
/** @psalm-param list{0: float|int|numeric-string, 1?: int, 2?: int, 3?: bool, 4?: bool} $arguments */
|
||||
#[DataProvider('providerFormatNumber')]
|
||||
public function testFormatNumber(string $expected, array $arguments): void
|
||||
{
|
||||
@ -594,16 +594,16 @@ class UtilTest extends AbstractTestCase
|
||||
}
|
||||
}
|
||||
|
||||
/** @psalm-return array<array{string, list{0: float|int|string, 1?: int, 2?: int, 3?: bool, 4?: bool}}> */
|
||||
/** @psalm-return array<array{string, list{0: float|int|numeric-string, 1?: int, 2?: int, 3?: bool, 4?: bool}}> */
|
||||
public static function providerFormatNumber(): array
|
||||
{
|
||||
return [
|
||||
['10 ', [10, 2, 2]],
|
||||
['100 ', [100, 2, 0]],
|
||||
['100 ', [100, 2, 2]],
|
||||
['100 ', ['100', 2, 2]],
|
||||
['-1,000.45 ', [-1000.454, 4, 2]],
|
||||
['-1,000.45 ', ['-1000.454', 4, 2]],
|
||||
['10', [10, 2, 2]],
|
||||
['100', [100, 2, 0]],
|
||||
['100', [100, 2, 2]],
|
||||
['100', ['100', 2, 2]],
|
||||
['-1,000.45', [-1000.454, 4, 2]],
|
||||
['-1,000.45', ['-1000.454', 4, 2]],
|
||||
['30 µ', [0.00003, 3, 2]],
|
||||
['3 m', [0.003, 3, 3]],
|
||||
['-3,000 µ', [-0.003, 6, 0]],
|
||||
@ -619,7 +619,7 @@ class UtilTest extends AbstractTestCase
|
||||
['0', [0.0]],
|
||||
['0', ['0']],
|
||||
['0', ['0.0']],
|
||||
[' <0.001', [0.000001, 0, 3]],
|
||||
['<0.001', [0.000001, 0, 3]],
|
||||
['5 m', [0.005]],
|
||||
['5 µ', [0.000005]],
|
||||
['5 n', [0.000000005]],
|
||||
@ -628,6 +628,9 @@ class UtilTest extends AbstractTestCase
|
||||
['5 a', [0.000000000000000005]],
|
||||
['5 z', [0.000000000000000000005]],
|
||||
['5 y', [0.000000000000000000000005]],
|
||||
['5 r', [0.000000000000000000000000005]],
|
||||
['5 q', [0.000000000000000000000000000005]],
|
||||
['<1 q', [0.000000000000000000000000000000005]],
|
||||
['5 k', [5000]],
|
||||
['5 M', [5000000]],
|
||||
['5 G', [5000000000]],
|
||||
@ -636,8 +639,11 @@ class UtilTest extends AbstractTestCase
|
||||
['5 E', [5000000000000000000]],
|
||||
['5 Z', [5000000000000000000000]],
|
||||
['5 Y', [5000000000000000000000000]],
|
||||
['5 R', [5000000000000000000000000000]],
|
||||
['5 Q', [5000000000000000000000000000000]],
|
||||
['5,000 Q', [5000000000000000000000000000000000]],
|
||||
['100 m', [0.1, 3, 0]],
|
||||
[' <1 ', [0.1, 3, 0, true]],
|
||||
['<1', [0.1, 3, 0, true]],
|
||||
['1.000 k', [1000, 3, 3, false, false]],
|
||||
];
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user