Skip to content

Commit

Permalink
bug #25741 [Form] issue-13589: adding custom false-values to BooleanT…
Browse files Browse the repository at this point in the history
…oString transformer (leberknecht)

This PR was squashed before being merged into the 4.1-dev branch (closes #25741).

Discussion
----------

[Form] issue-13589: adding custom false-values to BooleanToString transformer

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #13589
| License       | MIT
| Doc PR        | symfony/symfony-docs#9031

As suggested in #13589 , this PR adds the option to specify custom false-values, so we can use the CheckBoxType to handle strings '1' / '0' and eval them to true / false. While HTTP defines that checkbox types are either submitted=true or not-submitted=false, no matter of what value was submitted, it would be nice to have this option.
Also refs (which read like "the basic idea of the feature was accepted, PR almost done, then something-happend so PR wasnt merged"..?)

#15054
#18005

Commits
-------

a3e5ac4 [Form] issue-13589: adding custom false-values to BooleanToString transformer
  • Loading branch information
fabpot committed Jan 17, 2018
2 parents 9e73cc7 + a3e5ac4 commit 26e21d1
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 4 deletions.
1 change: 1 addition & 0 deletions src/Symfony/Component/Form/CHANGELOG.md
Expand Up @@ -19,6 +19,7 @@ CHANGELOG
* removed passing guesser services ids as the fourth argument of `DependencyInjectionExtension::__construct()`
* removed the ability to validate an unsubmitted form.
* removed `ChoiceLoaderInterface` implementation in `TimezoneType`
* added the `false_values` option to the `CheckboxType` which allows to configure custom values which will be treated as `false` during submission

3.4.0
-----
Expand Down
Expand Up @@ -12,6 +12,7 @@
namespace Symfony\Component\Form\Extension\Core\DataTransformer;

use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\InvalidArgumentException;
use Symfony\Component\Form\Exception\TransformationFailedException;

/**
Expand All @@ -24,12 +25,19 @@ class BooleanToStringTransformer implements DataTransformerInterface
{
private $trueValue;

private $falseValues;

/**
* @param string $trueValue The value emitted upon transform if the input is true
* @param string $trueValue The value emitted upon transform if the input is true
* @param array $falseValues
*/
public function __construct(string $trueValue)
public function __construct(string $trueValue, array $falseValues = array(null))
{
$this->trueValue = $trueValue;
$this->falseValues = $falseValues;
if (in_array($this->trueValue, $this->falseValues, true)) {
throw new InvalidArgumentException('The specified "true" value is contained in the false-values');
}
}

/**
Expand Down Expand Up @@ -65,7 +73,7 @@ public function transform($value)
*/
public function reverseTransform($value)
{
if (null === $value) {
if (in_array($value, $this->falseValues, true)) {
return false;
}

Expand Down
Expand Up @@ -32,7 +32,7 @@ public function buildForm(FormBuilderInterface $builder, array $options)
// We cannot solve this case via overriding the "data" option, because
// doing so also calls setDataLocked(true).
$builder->setData(isset($options['data']) ? $options['data'] : false);
$builder->addViewTransformer(new BooleanToStringTransformer($options['value']));
$builder->addViewTransformer(new BooleanToStringTransformer($options['value'], $options['false_values']));
}

/**
Expand All @@ -59,7 +59,10 @@ public function configureOptions(OptionsResolver $resolver)
'value' => '1',
'empty_data' => $emptyData,
'compound' => false,
'false_values' => array(null),
));

$resolver->setAllowedTypes('false_values', 'array');
}

/**
Expand Down
Expand Up @@ -68,4 +68,26 @@ public function testReverseTransform()
$this->assertTrue($this->transformer->reverseTransform(''));
$this->assertFalse($this->transformer->reverseTransform(null));
}

public function testCustomFalseValues()
{
$customFalseTransformer = new BooleanToStringTransformer(self::TRUE_VALUE, array('0', 'myFalse', true));
$this->assertFalse($customFalseTransformer->reverseTransform('myFalse'));
$this->assertFalse($customFalseTransformer->reverseTransform('0'));
$this->assertFalse($customFalseTransformer->reverseTransform(true));
}

/**
* @expectedException \Symfony\Component\Form\Exception\InvalidArgumentException
*/
public function testTrueValueContainedInFalseValues()
{
new BooleanToStringTransformer('0', array(null, '0'));
}

public function testBeStrictOnTrueInFalseValueCheck()
{
$transformer = new BooleanToStringTransformer('0', array(null, false));
$this->assertInstanceOf(BooleanToStringTransformer::class, $transformer);
}
}
Expand Up @@ -173,6 +173,38 @@ public function provideCustomModelTransformerData()
);
}

/**
* @dataProvider provideCustomFalseValues
*/
public function testCustomFalseValues($falseValue)
{
$form = $this->factory->create(static::TESTED_TYPE, null, array(
'false_values' => array($falseValue),
));
$form->submit($falseValue);
$this->assertFalse($form->getData());
}

public function provideCustomFalseValues()
{
return array(
array(''),
array('false'),
array('0'),
);
}

/**
* @expectedException \Symfony\Component\OptionsResolver\Exception\InvalidOptionsException
*/
public function testDontAllowNonArrayFalseValues()
{
$this->expectExceptionMessageRegExp('/"false_values" with value "invalid" is expected to be of type "array"/');
$this->factory->create(static::TESTED_TYPE, null, array(
'false_values' => 'invalid',
));
}

public function testSubmitNull($expected = null, $norm = null, $view = null)
{
parent::testSubmitNull(false, false, null);
Expand Down

4 comments on commit 26e21d1

@vasilvestre
Copy link
Contributor

Choose a reason for hiding this comment

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

This fix concern only the 3.4 version ?

@xabbuh
Copy link
Member

@xabbuh xabbuh commented on 26e21d1 Jan 18, 2018

Choose a reason for hiding this comment

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

This is a new feature that will be available in Symfony 4.1.

@vasilvestre
Copy link
Contributor

Choose a reason for hiding this comment

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

There's a reason to don't add it to LTS versions ? The code is compatible no ?

@xabbuh
Copy link
Member

@xabbuh xabbuh commented on 26e21d1 Jan 18, 2018

Choose a reason for hiding this comment

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

We never add new features to stable versions, but only in the next minor version to be released.

Please sign in to comment.