-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Expand file tree
/
Copy pathNumberConfigurator.php
More file actions
105 lines (86 loc) · 4.01 KB
/
NumberConfigurator.php
File metadata and controls
105 lines (86 loc) · 4.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
<?php
namespace EasyCorp\Bundle\EasyAdminBundle\Field\Configurator;
use EasyCorp\Bundle\EasyAdminBundle\Context\AdminContext;
use EasyCorp\Bundle\EasyAdminBundle\Contracts\Field\FieldConfiguratorInterface;
use EasyCorp\Bundle\EasyAdminBundle\Contracts\Intl\IntlFormatterInterface;
use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto;
use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto;
use EasyCorp\Bundle\EasyAdminBundle\Field\NumberField;
/**
* @author Javier Eguiluz <javier.eguiluz@gmail.com>
*/
final readonly class NumberConfigurator implements FieldConfiguratorInterface
{
public function __construct(private IntlFormatterInterface $intlFormatter)
{
}
public function supports(FieldDto $field, EntityDto $entityDto): bool
{
return NumberField::class === $field->getFieldFqcn();
}
public function configure(FieldDto $field, EntityDto $entityDto, AdminContext $context): void
{
$scale = $field->getCustomOption(NumberField::OPTION_NUM_DECIMALS);
$roundingMode = $field->getCustomOption(NumberField::OPTION_ROUNDING_MODE);
$isStoredAsString = true === $field->getCustomOption(NumberField::OPTION_STORED_AS_STRING);
$isStoredAsBcMathNumber = true === $field->getCustomOption(NumberField::OPTION_STORED_AS_BCMATH_NUMBER);
if ($isStoredAsString && $isStoredAsBcMathNumber) {
throw new \InvalidArgumentException(sprintf('The "%s" field cannot use both "setStoredAsString()" and "setStoredAsBcMathNumber()" options at the same time.', $field->getProperty()));
}
if ($isStoredAsBcMathNumber && \PHP_VERSION_ID < 80400) {
throw new \LogicException('The "setStoredAsBcMathNumber()" option requires PHP 8.4 or higher.');
}
$input = match (true) {
$isStoredAsString, $isStoredAsBcMathNumber => 'string',
default => 'number',
};
$field->setFormTypeOptionIfNotSet('input', $input);
$field->setFormTypeOptionIfNotSet('rounding_mode', $roundingMode);
$field->setFormTypeOptionIfNotSet('scale', $scale);
if ($isStoredAsBcMathNumber) {
$field->setFormTypeOption('ea_bcmath_number', true);
}
if (null === $value = $field->getValue()) {
return;
}
if ($isStoredAsBcMathNumber) {
$value = (float) (string) $value;
}
$formatterAttributes = ['rounding_mode' => $this->getRoundingModeAsString($roundingMode)];
if (null !== $scale) {
$formatterAttributes['fraction_digit'] = $scale;
}
$numberFormat = $field->getCustomOption(NumberField::OPTION_NUMBER_FORMAT)
?? $context->getCrud()->getNumberFormat()
?? null;
if (null !== $numberFormat) {
$field->setFormattedValue(sprintf($numberFormat, $value));
return;
}
$thousandsSeparator = $field->getCustomOption(NumberField::OPTION_THOUSANDS_SEPARATOR)
?? $context->getCrud()->getThousandsSeparator()
?? null;
if (null !== $thousandsSeparator) {
$formatterAttributes['grouping_separator'] = $thousandsSeparator;
}
$decimalSeparator = $field->getCustomOption(NumberField::OPTION_DECIMAL_SEPARATOR)
?? $context->getCrud()->getDecimalSeparator()
?? null;
if (null !== $decimalSeparator) {
$formatterAttributes['decimal_separator'] = $decimalSeparator;
}
$field->setFormattedValue($this->intlFormatter->formatNumber($value, $formatterAttributes));
}
private function getRoundingModeAsString(int $mode): string
{
return [
\NumberFormatter::ROUND_DOWN => 'down',
\NumberFormatter::ROUND_FLOOR => 'floor',
\NumberFormatter::ROUND_UP => 'up',
\NumberFormatter::ROUND_CEILING => 'ceiling',
\NumberFormatter::ROUND_HALFDOWN => 'halfdown',
\NumberFormatter::ROUND_HALFEVEN => 'halfeven',
\NumberFormatter::ROUND_HALFUP => 'halfup',
][$mode];
}
}