Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[Form] [MoneyType] Add "input" option #50720

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

/**
Expand Down Expand Up @@ -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);
}
Expand Down
30 changes: 21 additions & 9 deletions src/Symfony/Component/Form/Extension/Core/Type/MoneyType.php
Original file line number Diff line number Diff line change
Expand Up @@ -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']

))
;
}
Expand All @@ -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';
}
}

Expand All @@ -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,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the codestyle changes have to be reverted

'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', [
Expand All @@ -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');
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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']);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure that a scale option with a value other than 0 plays well with how the input option is implemented currently.

But, this makes me wonder if the way this option is currently implemented actually makes sense. So maybe we should indeed allow the division to be greater than 1 and take it into account to decide whether we want to render a number or an integer widget.

$this->assertSame('integer', $form->createView()->vars['type']);
}

public function testValueToIntegerWithSpecificOptionInputToInteger()
{
$form = $this->factory->create(static::TESTED_TYPE, null, ['input' => 'integer']);
$form->submit('12345.6');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO this case should trigger an exception in during reverseTransform()

$this->assertSame(12345, $form->getData());
}

public function testInputTypeIntegerAndDivisorNotEgalToOne()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
public function testInputTypeIntegerAndDivisorNotEgalToOne()
public function testInputTypeIntegerAndDivisorNotEqualToOne()

{
$this->expectException(\LogicException::class);
$this->factory->create(static::TESTED_TYPE, null, ['divisor' => 2, 'input' => 'integer']);
}
}