diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformer.php index fd943cc820f49..6f1d8f6ec9ed8 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformer.php @@ -22,12 +22,14 @@ class MoneyToLocalizedStringTransformer extends NumberToLocalizedStringTransformer { private int $divisor; + private string $input; - public function __construct(?int $scale = 2, ?bool $grouping = true, ?int $roundingMode = \NumberFormatter::ROUND_HALFUP, ?int $divisor = 1, string $locale = null) + public function __construct(?int $scale = 2, ?bool $grouping = true, ?int $roundingMode = \NumberFormatter::ROUND_HALFUP, ?int $divisor = 1, string $locale = null, string $input = 'float') { parent::__construct($scale ?? 2, $grouping ?? true, $roundingMode, $locale); $this->divisor = $divisor ?? 1; + $this->input = $input; } /** @@ -61,6 +63,9 @@ public function transform(mixed $value): string public function reverseTransform(mixed $value): int|float|null { $value = parent::reverseTransform($value); + if ($this->input === 'integer' && $this->divisor === 1) { + return (int) $value; + } if (null !== $value && 1 !== $this->divisor) { $value = (float) (string) ($value * $this->divisor); } diff --git a/src/Symfony/Component/Form/Extension/Core/Type/MoneyType.php b/src/Symfony/Component/Form/Extension/Core/Type/MoneyType.php index 9c9e5b4d7c30f..53ee1dfb1a87e 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/MoneyType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/MoneyType.php @@ -37,7 +37,9 @@ public function buildForm(FormBuilderInterface $builder, array $options) $options['grouping'], $options['rounding_mode'], $options['divisor'], - $options['html5'] ? 'en' : null + $options['html5'] ? 'en' : null, + $options['input'] + )) ; } @@ -50,7 +52,7 @@ public function buildView(FormView $view, FormInterface $form, array $options) $view->vars['money_pattern'] = self::getPattern($options['currency']); if ($options['html5']) { - $view->vars['type'] = 'number'; + $view->vars['type'] = $options['input'] === 'integer' ? 'integer' : 'number'; } } @@ -60,14 +62,15 @@ public function buildView(FormView $view, FormInterface $form, array $options) public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ - 'scale' => 2, - 'grouping' => false, - 'rounding_mode' => \NumberFormatter::ROUND_HALFUP, - 'divisor' => 1, - 'currency' => 'EUR', - 'compound' => false, - 'html5' => false, + 'scale' => 2, + 'grouping' => false, + 'rounding_mode' => \NumberFormatter::ROUND_HALFUP, + 'divisor' => 1, + 'currency' => 'EUR', + 'compound' => false, + 'html5' => false, 'invalid_message' => 'Please enter a valid money amount.', + 'input' => 'float' ]); $resolver->setAllowedValues('rounding_mode', [ @@ -80,6 +83,7 @@ public function configureOptions(OptionsResolver $resolver) \NumberFormatter::ROUND_CEILING, ]); + $resolver->setAllowedValues('input', ['float', 'integer']); $resolver->setAllowedTypes('scale', 'int'); $resolver->setAllowedTypes('html5', 'bool'); @@ -91,6 +95,14 @@ public function configureOptions(OptionsResolver $resolver) return $value; }); + + $resolver->setNormalizer('input', static function (Options $options, $value) { + if ($value === 'integer' && $options['divisor'] !== 1) { + throw new LogicException('Cannot use the "input" option when the "divisor" option is different from 1.'); + } + + return $value; + }); } public function getBlockPrefix(): string diff --git a/src/Symfony/Component/Form/Tests/Extension/Core/Type/MoneyTypeTest.php b/src/Symfony/Component/Form/Tests/Extension/Core/Type/MoneyTypeTest.php index c65629d946818..6707d9995113d 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/MoneyTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/MoneyTypeTest.php @@ -123,4 +123,23 @@ public function testHtml5EnablesSpecificFormatting() $this->assertSame('12345.60', $form->createView()->vars['value']); $this->assertSame('number', $form->createView()->vars['type']); } + + public function testHtml5EnablesSpecificFormattingWithIntegerFormat() + { + $form = $this->factory->create(static::TESTED_TYPE, null, ['html5' => true, 'scale' => 2, 'input' => 'integer']); + $this->assertSame('integer', $form->createView()->vars['type']); + } + + public function testValueToIntegerWithSpecificOptionInputToInteger() + { + $form = $this->factory->create(static::TESTED_TYPE, null, ['input' => 'integer']); + $form->submit('12345.6'); + $this->assertSame(12345, $form->getData()); + } + + public function testInputTypeIntegerAndDivisorNotEgalToOne() + { + $this->expectException(\LogicException::class); + $this->factory->create(static::TESTED_TYPE, null, ['divisor' => 2, 'input' => 'integer']); + } }