From 2c4f2ba4e8611d0ac0237563d9b5a568d7cc0429 Mon Sep 17 00:00:00 2001 From: BASAK Semih Date: Tue, 20 Jun 2023 18:25:07 +0200 Subject: [PATCH 1/2] feat: add option "format" to MoneyType [Form] --- .../MoneyToLocalizedStringTransformer.php | 7 +++++- .../Form/Extension/Core/Type/MoneyType.php | 22 +++++++++++-------- .../Extension/Core/Type/MoneyTypeTest.php | 13 +++++++++++ 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformer.php index fd943cc820f49..ada54b0344dea 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 $format; - 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 $format = 'float') { parent::__construct($scale ?? 2, $grouping ?? true, $roundingMode, $locale); $this->divisor = $divisor ?? 1; + $this->format = $format; } /** @@ -61,6 +63,9 @@ public function transform(mixed $value): string public function reverseTransform(mixed $value): int|float|null { $value = parent::reverseTransform($value); + if ($this->format === 'integer') { + return (int) $value * $this->divisor; + } 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..037bb6b454a00 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['format'] + )) ; } @@ -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['format'] === '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.', + 'format' => 'float' ]); $resolver->setAllowedValues('rounding_mode', [ @@ -80,6 +83,7 @@ public function configureOptions(OptionsResolver $resolver) \NumberFormatter::ROUND_CEILING, ]); + $resolver->setAllowedValues('format', ['float', 'integer']); $resolver->setAllowedTypes('scale', 'int'); $resolver->setAllowedTypes('html5', 'bool'); 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..da125636a8b8d 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,17 @@ 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, 'format' => 'integer']); + $this->assertSame('integer', $form->createView()->vars['type']); + } + + public function testValueToIntegerWithSpecificOptionFormatToInteger() + { + $form = $this->factory->create(static::TESTED_TYPE, null, ['format' => 'integer']); + $form->submit('12345.6'); + $this->assertSame(12345, $form->getData()); + } } From e59dcbf557f5532ee9add8a7227dfa6b812cd08e Mon Sep 17 00:00:00 2001 From: BASAK Semih Date: Thu, 22 Jun 2023 20:11:50 +0200 Subject: [PATCH 2/2] feat: rename "format" to "input", add condition resolver --- .../MoneyToLocalizedStringTransformer.php | 10 +++++----- .../Form/Extension/Core/Type/MoneyType.php | 16 ++++++++++++---- .../Tests/Extension/Core/Type/MoneyTypeTest.php | 12 +++++++++--- 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/Symfony/Component/Form/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformer.php b/src/Symfony/Component/Form/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformer.php index ada54b0344dea..6f1d8f6ec9ed8 100644 --- a/src/Symfony/Component/Form/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformer.php +++ b/src/Symfony/Component/Form/Extension/Core/DataTransformer/MoneyToLocalizedStringTransformer.php @@ -22,14 +22,14 @@ class MoneyToLocalizedStringTransformer extends NumberToLocalizedStringTransformer { private int $divisor; - private string $format; + private string $input; - public function __construct(?int $scale = 2, ?bool $grouping = true, ?int $roundingMode = \NumberFormatter::ROUND_HALFUP, ?int $divisor = 1, string $locale = null, string $format = 'float') + 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->format = $format; + $this->input = $input; } /** @@ -63,8 +63,8 @@ public function transform(mixed $value): string public function reverseTransform(mixed $value): int|float|null { $value = parent::reverseTransform($value); - if ($this->format === 'integer') { - return (int) $value * $this->divisor; + 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 037bb6b454a00..53ee1dfb1a87e 100644 --- a/src/Symfony/Component/Form/Extension/Core/Type/MoneyType.php +++ b/src/Symfony/Component/Form/Extension/Core/Type/MoneyType.php @@ -38,7 +38,7 @@ public function buildForm(FormBuilderInterface $builder, array $options) $options['rounding_mode'], $options['divisor'], $options['html5'] ? 'en' : null, - $options['format'] + $options['input'] )) ; @@ -52,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'] = $options['format'] === 'integer' ? 'integer' : 'number'; + $view->vars['type'] = $options['input'] === 'integer' ? 'integer' : 'number'; } } @@ -70,7 +70,7 @@ public function configureOptions(OptionsResolver $resolver) 'compound' => false, 'html5' => false, 'invalid_message' => 'Please enter a valid money amount.', - 'format' => 'float' + 'input' => 'float' ]); $resolver->setAllowedValues('rounding_mode', [ @@ -83,7 +83,7 @@ public function configureOptions(OptionsResolver $resolver) \NumberFormatter::ROUND_CEILING, ]); - $resolver->setAllowedValues('format', ['float', 'integer']); + $resolver->setAllowedValues('input', ['float', 'integer']); $resolver->setAllowedTypes('scale', 'int'); $resolver->setAllowedTypes('html5', 'bool'); @@ -95,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 da125636a8b8d..6707d9995113d 100644 --- a/src/Symfony/Component/Form/Tests/Extension/Core/Type/MoneyTypeTest.php +++ b/src/Symfony/Component/Form/Tests/Extension/Core/Type/MoneyTypeTest.php @@ -126,14 +126,20 @@ public function testHtml5EnablesSpecificFormatting() public function testHtml5EnablesSpecificFormattingWithIntegerFormat() { - $form = $this->factory->create(static::TESTED_TYPE, null, ['html5' => true, 'scale' => 2, 'format' => 'integer']); + $form = $this->factory->create(static::TESTED_TYPE, null, ['html5' => true, 'scale' => 2, 'input' => 'integer']); $this->assertSame('integer', $form->createView()->vars['type']); } - public function testValueToIntegerWithSpecificOptionFormatToInteger() + public function testValueToIntegerWithSpecificOptionInputToInteger() { - $form = $this->factory->create(static::TESTED_TYPE, null, ['format' => 'integer']); + $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']); + } }