bug #25741 [Form] issue-13589: adding custom false-values to BooleanToString 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 | https://github.com/symfony/symfony-docs/pull/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"..?)
https://github.com/symfony/symfony/pull/15054
https://github.com/symfony/symfony/pull/18005
Commits
-------
a3e5ac496f
[Form] issue-13589: adding custom false-values to BooleanToString transformer
This commit is contained in:
commit
26e21d1dbb
@ -19,6 +19,7 @@ CHANGELOG
|
|||||||
* removed passing guesser services ids as the fourth argument of `DependencyInjectionExtension::__construct()`
|
* removed passing guesser services ids as the fourth argument of `DependencyInjectionExtension::__construct()`
|
||||||
* removed the ability to validate an unsubmitted form.
|
* removed the ability to validate an unsubmitted form.
|
||||||
* removed `ChoiceLoaderInterface` implementation in `TimezoneType`
|
* 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
|
3.4.0
|
||||||
-----
|
-----
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
namespace Symfony\Component\Form\Extension\Core\DataTransformer;
|
namespace Symfony\Component\Form\Extension\Core\DataTransformer;
|
||||||
|
|
||||||
use Symfony\Component\Form\DataTransformerInterface;
|
use Symfony\Component\Form\DataTransformerInterface;
|
||||||
|
use Symfony\Component\Form\Exception\InvalidArgumentException;
|
||||||
use Symfony\Component\Form\Exception\TransformationFailedException;
|
use Symfony\Component\Form\Exception\TransformationFailedException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -24,12 +25,19 @@ class BooleanToStringTransformer implements DataTransformerInterface
|
|||||||
{
|
{
|
||||||
private $trueValue;
|
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->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');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -65,7 +73,7 @@ class BooleanToStringTransformer implements DataTransformerInterface
|
|||||||
*/
|
*/
|
||||||
public function reverseTransform($value)
|
public function reverseTransform($value)
|
||||||
{
|
{
|
||||||
if (null === $value) {
|
if (in_array($value, $this->falseValues, true)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ class CheckboxType extends AbstractType
|
|||||||
// We cannot solve this case via overriding the "data" option, because
|
// We cannot solve this case via overriding the "data" option, because
|
||||||
// doing so also calls setDataLocked(true).
|
// doing so also calls setDataLocked(true).
|
||||||
$builder->setData(isset($options['data']) ? $options['data'] : false);
|
$builder->setData(isset($options['data']) ? $options['data'] : false);
|
||||||
$builder->addViewTransformer(new BooleanToStringTransformer($options['value']));
|
$builder->addViewTransformer(new BooleanToStringTransformer($options['value'], $options['false_values']));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -59,7 +59,10 @@ class CheckboxType extends AbstractType
|
|||||||
'value' => '1',
|
'value' => '1',
|
||||||
'empty_data' => $emptyData,
|
'empty_data' => $emptyData,
|
||||||
'compound' => false,
|
'compound' => false,
|
||||||
|
'false_values' => array(null),
|
||||||
));
|
));
|
||||||
|
|
||||||
|
$resolver->setAllowedTypes('false_values', 'array');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -68,4 +68,26 @@ class BooleanToStringTransformerTest extends TestCase
|
|||||||
$this->assertTrue($this->transformer->reverseTransform(''));
|
$this->assertTrue($this->transformer->reverseTransform(''));
|
||||||
$this->assertFalse($this->transformer->reverseTransform(null));
|
$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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -173,6 +173,38 @@ class CheckboxTypeTest extends BaseTypeTest
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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)
|
public function testSubmitNull($expected = null, $norm = null, $view = null)
|
||||||
{
|
{
|
||||||
parent::testSubmitNull(false, false, null);
|
parent::testSubmitNull(false, false, null);
|
||||||
|
Reference in New Issue
Block a user