diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon
index e2e5395f78..3519835579 100644
--- a/phpstan-baseline.neon
+++ b/phpstan-baseline.neon
@@ -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
diff --git a/psalm-baseline.xml b/psalm-baseline.xml
index 0758571314..e7c301345b 100644
--- a/psalm-baseline.xml
+++ b/psalm-baseline.xml
@@ -1925,6 +1925,12 @@
+
+ data->status['Aborted_clients']]]>
+ data->status['Aborted_connects']]]>
+ data->status['Connections']]]>
+ data->status['Max_used_connections']]]>
+
data->status['Aborted_clients']]]>
data->status['Aborted_clients']]]>
@@ -9256,6 +9262,10 @@
+
+
+
+
@@ -9275,9 +9285,6 @@
-
-
-
@@ -9296,12 +9303,9 @@
-
-
-
diff --git a/src/Util.php b/src/Util.php
index 01b19a9418..e577cc621a 100644
--- a/src/Util.php
+++ b/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
*
*
- * @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);
}
/**
diff --git a/tests/unit/Engines/InnodbTest.php b/tests/unit/Engines/InnodbTest.php
index b1a66c4bdd..a7a6b927a9 100644
--- a/tests/unit/Engines/InnodbTest.php
+++ b/tests/unit/Engines/InnodbTest.php
@@ -194,7 +194,7 @@ class InnodbTest extends AbstractTestCase
' ' . "\n" .
' ' . "\n" .
' | Read misses in % | ' . "\n" .
- ' 50 %' . "\n" .
+ ' | 50 %' . "\n" .
' | ' . "\n" .
'
' . "\n" .
' ' . "\n" .
diff --git a/tests/unit/UtilTest.php b/tests/unit/UtilTest.php
index ab9f887326..396f75e515 100644
--- a/tests/unit/UtilTest.php
+++ b/tests/unit/UtilTest.php
@@ -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 */
+ /** @psalm-return array */
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]],
];
}