diff --git a/psalm.xml b/psalm.xml
index df40fdc3..851497c0 100644
--- a/psalm.xml
+++ b/psalm.xml
@@ -34,6 +34,11 @@
+
+
+
+
+
diff --git a/src/View/Helper/NumberFormat.php b/src/View/Helper/NumberFormat.php
index 4b4c0648..4af2f02b 100644
--- a/src/View/Helper/NumberFormat.php
+++ b/src/View/Helper/NumberFormat.php
@@ -13,18 +13,25 @@
use function serialize;
/**
- * View helper for formatting dates.
+ * View helper for formatting numbers.
*/
class NumberFormat extends AbstractHelper
{
use DeprecatedAbstractHelperHierarchyTrait;
/**
- * number of decimals to use.
+ * The maximum number of decimals to use.
*
* @var int
*/
- protected $decimals;
+ protected $maxDecimals;
+
+ /**
+ * The minimum number of decimals to use.
+ *
+ * @var int
+ */
+ protected $minDecimals;
/**
* NumberFormat style to use
@@ -50,7 +57,7 @@ class NumberFormat extends AbstractHelper
/**
* Text attributes.
*
- * @var array
+ * @var array
*/
protected $textAttributes = [];
@@ -64,12 +71,14 @@ class NumberFormat extends AbstractHelper
/**
* Format a number
*
- * @param int|float $number
- * @param int|null $formatStyle
- * @param int|null $formatType
- * @param string|null $locale
- * @param int|null $decimals
- * @param array|null $textAttributes
+ * @param int|float $number
+ * @param int|null $formatStyle
+ * @param int|null $formatType
+ * @param string|null $locale
+ * @param int|null $maxDecimals
+ * @param array $textAttributes
+ * @param int|float $number
+ * @param int|null $minDecimals
* @return string
*/
public function __invoke(
@@ -77,8 +86,9 @@ public function __invoke(
$formatStyle = null,
$formatType = null,
$locale = null,
- $decimals = null,
- ?array $textAttributes = null
+ $maxDecimals = null,
+ ?array $textAttributes = null,
+ $minDecimals = null
) {
if (null === $locale) {
$locale = $this->getLocale();
@@ -89,15 +99,22 @@ public function __invoke(
if (null === $formatType) {
$formatType = $this->getFormatType();
}
- if (! is_int($decimals) || $decimals < 0) {
- $decimals = $this->getDecimals();
+ if (! is_int($minDecimals) || $minDecimals < 0) {
+ $minDecimals = $this->getMinDecimals();
+ }
+ if (! is_int($maxDecimals) || $maxDecimals < 0) {
+ $maxDecimals = $this->getMaxDecimals();
+ }
+ if (($maxDecimals !== null) && ($minDecimals === null)) {
+ // Fallback to old behavior
+ $minDecimals = $maxDecimals;
}
if (! is_array($textAttributes)) {
$textAttributes = $this->getTextAttributes();
}
$formatterId = md5(
- $formatStyle . "\0" . $locale . "\0" . $decimals . "\0"
+ $formatStyle . "\0" . $locale . "\0" . ($minDecimals ?? '') . "\0" . ($maxDecimals ?? '') . "\0"
. md5(serialize($textAttributes))
);
@@ -106,9 +123,12 @@ public function __invoke(
} else {
$formatter = new NumberFormatter($locale, $formatStyle);
- if ($decimals !== null) {
- $formatter->setAttribute(NumberFormatter::MIN_FRACTION_DIGITS, $decimals);
- $formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, $decimals);
+ if ($minDecimals !== null) {
+ $formatter->setAttribute(NumberFormatter::MIN_FRACTION_DIGITS, $minDecimals);
+ }
+
+ if ($maxDecimals !== null) {
+ $formatter->setAttribute(NumberFormatter::MAX_FRACTION_DIGITS, $maxDecimals);
}
foreach ($textAttributes as $textAttribute => $value) {
@@ -173,14 +193,39 @@ public function getFormatType()
}
/**
- * Set number of decimals to use instead of the default.
+ * Set number of decimals (both min & max) to use instead of the default.
*
* @param int $decimals
* @return $this
*/
public function setDecimals($decimals)
{
- $this->decimals = $decimals;
+ $this->minDecimals = $decimals;
+ $this->maxDecimals = $decimals;
+ return $this;
+ }
+
+ /**
+ * Set the maximum number of decimals to use instead of the default.
+ *
+ * @param int $maxDecimals
+ * @return $this
+ */
+ public function setMaxDecimals($maxDecimals)
+ {
+ $this->maxDecimals = $maxDecimals;
+ return $this;
+ }
+
+ /**
+ * Set the minimum number of decimals to use instead of the default.
+ *
+ * @param int $minDecimals
+ * @return $this
+ */
+ public function setMinDecimals($minDecimals)
+ {
+ $this->minDecimals = $minDecimals;
return $this;
}
@@ -191,7 +236,27 @@ public function setDecimals($decimals)
*/
public function getDecimals()
{
- return $this->decimals;
+ return $this->maxDecimals;
+ }
+
+ /**
+ * Get the maximum number of decimals.
+ *
+ * @return int
+ */
+ public function getMaxDecimals()
+ {
+ return $this->maxDecimals;
+ }
+
+ /**
+ * Get the minimum number of decimals.
+ *
+ * @return int
+ */
+ public function getMinDecimals()
+ {
+ return $this->minDecimals;
}
/**
@@ -221,7 +286,7 @@ public function getLocale()
}
/**
- * @return array
+ * @return array
*/
public function getTextAttributes()
{
@@ -229,7 +294,7 @@ public function getTextAttributes()
}
/**
- * @param array $textAttributes
+ * @param array $textAttributes
* @return $this
*/
public function setTextAttributes(array $textAttributes)
diff --git a/src/View/HelperTrait.php b/src/View/HelperTrait.php
index 7c05fe84..26b68ba8 100644
--- a/src/View/HelperTrait.php
+++ b/src/View/HelperTrait.php
@@ -22,7 +22,7 @@
* @method string countryCodeDataList(?string $locale = null, array $dataListAttributes = [])
* @method string currencyFormat(float $number, string|null $currencyCode = null, bool|null $showDecimals = null, string|null $locale = null, string|null $pattern = null)
* @method string dateFormat(\DateTimeInterface|\IntlCalendar|int|array $date, int $dateType = IntlDateFormatter::NONE, int $timeType = IntlDateFormatter::NONE, string|null $locale = null, string|null $pattern = null)
- * @method string numberFormat(int|float $number, int|null $formatStyle = null, int|null $formatType = null, string|null $locale = null, int|null $decimals = null, array|null $textAttributes = null)
+ * @method string numberFormat(int|float $number, int|null $formatStyle = null, int|null $formatType = null, string|null $locale = null, int|null $maxDecimals = null, array|null $textAttributes = null, int|null $minDecimals = null)
* @method string plural(array|string $strings, int $number)
* @method string translate(string $message, string|null $textDomain = null, string|null $locale = null)
* @method string translatePlural(string $singular, string $plural, int $number, string|null $textDomain = null, string|null $locale = null)
diff --git a/test/View/Helper/NumberFormatTest.php b/test/View/Helper/NumberFormatTest.php
index 8286d1e5..7c49a822 100644
--- a/test/View/Helper/NumberFormatTest.php
+++ b/test/View/Helper/NumberFormatTest.php
@@ -22,8 +22,8 @@ protected function setUp(): void
$this->helper = new NumberFormatHelper();
}
- /** @return array, 5: float, 6: string}> */
- public static function currencyTestsDataProvider(): array
+ /** @return array, 5: int|null, 6: float, 7: string}> */
+ public static function numberTestsDataProvider(): array
{
return [
[
@@ -32,6 +32,7 @@ public static function currencyTestsDataProvider(): array
NumberFormatter::TYPE_DOUBLE,
null,
[],
+ null,
1234567.891234567890000,
'1.234.567,891',
],
@@ -41,6 +42,7 @@ public static function currencyTestsDataProvider(): array
NumberFormatter::TYPE_DOUBLE,
6,
[],
+ null,
1234567.891234567890000,
'1.234.567,891235',
],
@@ -50,6 +52,7 @@ public static function currencyTestsDataProvider(): array
NumberFormatter::TYPE_DOUBLE,
null,
[],
+ null,
1234567.891234567890000,
'123.456.789 %',
],
@@ -59,6 +62,7 @@ public static function currencyTestsDataProvider(): array
NumberFormatter::TYPE_DOUBLE,
1,
[],
+ null,
1234567.891234567890000,
'123.456.789,1 %',
],
@@ -68,6 +72,7 @@ public static function currencyTestsDataProvider(): array
NumberFormatter::TYPE_DOUBLE,
null,
[],
+ null,
1234567.891234560000,
'1,23456789123456E6',
],
@@ -77,6 +82,7 @@ public static function currencyTestsDataProvider(): array
NumberFormatter::TYPE_DOUBLE,
null,
[],
+ null,
1234567.891234567890000,
'1 234 567,891',
],
@@ -86,6 +92,7 @@ public static function currencyTestsDataProvider(): array
NumberFormatter::TYPE_DOUBLE,
null,
[],
+ null,
1234567.891234567890000,
'123 456 789 %',
],
@@ -95,6 +102,7 @@ public static function currencyTestsDataProvider(): array
NumberFormatter::TYPE_DOUBLE,
null,
[],
+ null,
1234567.891234560000,
'1,23456789123456E6',
],
@@ -104,6 +112,7 @@ public static function currencyTestsDataProvider(): array
NumberFormatter::TYPE_DOUBLE,
null,
[],
+ null,
1234567.891234567890000,
'1,234,567.891',
],
@@ -113,6 +122,7 @@ public static function currencyTestsDataProvider(): array
NumberFormatter::TYPE_DOUBLE,
null,
[],
+ null,
1234567.891234567890000,
'123,456,789%',
],
@@ -122,6 +132,7 @@ public static function currencyTestsDataProvider(): array
NumberFormatter::TYPE_DOUBLE,
null,
[],
+ null,
1234567.891234560000,
'1.23456789123456E6',
],
@@ -133,22 +144,44 @@ public static function currencyTestsDataProvider(): array
[
NumberFormatter::NEGATIVE_PREFIX => 'MINUS',
],
+ null,
-1234567.891234567890000,
'MINUS123,456,789%',
],
+ [
+ 'de_DE',
+ NumberFormatter::DECIMAL,
+ NumberFormatter::TYPE_DOUBLE,
+ 5,
+ [],
+ 0,
+ 1234567.891234567890000,
+ '1.234.567,89123',
+ ],
+ [
+ 'de_DE',
+ NumberFormatter::DECIMAL,
+ NumberFormatter::TYPE_DOUBLE,
+ 5,
+ [],
+ 0,
+ 1234567,
+ '1.234.567',
+ ],
];
}
/**
* @param array $textAttributes
*/
- #[DataProvider('currencyTestsDataProvider')]
+ #[DataProvider('numberTestsDataProvider')]
public function testBasic(
string $locale,
int $formatStyle,
int $formatType,
?int $decimals,
array $textAttributes,
+ ?int $minDecimals,
float $number,
string $expected
): void {
@@ -158,29 +191,32 @@ public function testBasic(
$formatType,
$locale,
$decimals,
- $textAttributes
+ $textAttributes,
+ $minDecimals
));
}
/**
* @param array $textAttributes
*/
- #[DataProvider('currencyTestsDataProvider')]
+ #[DataProvider('numberTestsDataProvider')]
public function testSettersProvideDefaults(
string $locale,
int $formatStyle,
int $formatType,
?int $decimals,
array $textAttributes,
+ ?int $minDecimals,
float $number,
string $expected
): void {
$this->helper
->setLocale($locale)
->setFormatStyle($formatStyle)
- ->setDecimals($decimals)
+ ->setMaxDecimals($decimals)
->setFormatType($formatType)
- ->setTextAttributes($textAttributes);
+ ->setTextAttributes($textAttributes)
+ ->setMinDecimals($minDecimals);
self::assertMbStringEquals($expected, $this->helper->__invoke($number));
}