[Form] Added tests for the case when "property_path" is null or false. Instead of setting "property_path" to false, you should set "mapped" to false instead.
This commit is contained in:
parent
2301b1559e
commit
5e87dd885c
|
@ -458,6 +458,28 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
* Setting the option "property_path" to `false` was deprecated and will be unsupported
|
||||||
|
as of Symfony 2.3.
|
||||||
|
|
||||||
|
You should use the new option "mapped" instead in order to set that you don't want
|
||||||
|
a field to be mapped to its parent's data.
|
||||||
|
|
||||||
|
Before:
|
||||||
|
|
||||||
|
```
|
||||||
|
$builder->add('termsAccepted', 'checkbox', array(
|
||||||
|
'property_path' => false,
|
||||||
|
));
|
||||||
|
```
|
||||||
|
|
||||||
|
After:
|
||||||
|
|
||||||
|
```
|
||||||
|
$builder->add('termsAccepted', 'checkbox', array(
|
||||||
|
'mapped' => false,
|
||||||
|
));
|
||||||
|
```
|
||||||
|
|
||||||
### Validator
|
### Validator
|
||||||
|
|
||||||
* The methods `setMessage()`, `getMessageTemplate()` and
|
* The methods `setMessage()`, `getMessageTemplate()` and
|
||||||
|
|
|
@ -70,3 +70,4 @@ CHANGELOG
|
||||||
* deprecated method `guessMinLength` in favor of `guessPattern`
|
* deprecated method `guessMinLength` in favor of `guessPattern`
|
||||||
* labels don't display field attributes anymore. Label attributes can be
|
* labels don't display field attributes anymore. Label attributes can be
|
||||||
passed in the "label_attr" option/variable
|
passed in the "label_attr" option/variable
|
||||||
|
* added option "mapped" which should be used instead of setting "property_path" to false
|
||||||
|
|
|
@ -44,8 +44,9 @@ class PropertyPathMapper implements DataMapperInterface
|
||||||
{
|
{
|
||||||
if (!empty($data)) {
|
if (!empty($data)) {
|
||||||
$propertyPath = $form->getPropertyPath();
|
$propertyPath = $form->getPropertyPath();
|
||||||
|
$config = $form->getConfig();
|
||||||
|
|
||||||
if (null !== $propertyPath) {
|
if (null !== $propertyPath && $config->getMapped()) {
|
||||||
$propertyData = $propertyPath->getValue($data);
|
$propertyData = $propertyPath->getValue($data);
|
||||||
|
|
||||||
if (is_object($propertyData) && !$form->getAttribute('by_reference')) {
|
if (is_object($propertyData) && !$form->getAttribute('by_reference')) {
|
||||||
|
@ -76,8 +77,11 @@ class PropertyPathMapper implements DataMapperInterface
|
||||||
public function mapFormToData(FormInterface $form, &$data)
|
public function mapFormToData(FormInterface $form, &$data)
|
||||||
{
|
{
|
||||||
$propertyPath = $form->getPropertyPath();
|
$propertyPath = $form->getPropertyPath();
|
||||||
|
$config = $form->getConfig();
|
||||||
|
|
||||||
if (null !== $propertyPath && $form->isSynchronized() && !$form->isDisabled()) {
|
// Write-back is disabled if the form is not synchronized (transformation failed)
|
||||||
|
// and if the form is disabled (modification not allowed)
|
||||||
|
if (null !== $propertyPath && $config->getMapped() && $form->isSynchronized() && !$form->isDisabled()) {
|
||||||
// If the data is identical to the value in $data, we are
|
// If the data is identical to the value in $data, we are
|
||||||
// dealing with a reference
|
// dealing with a reference
|
||||||
$isReference = $form->getData() === $propertyPath->getValue($data);
|
$isReference = $form->getData() === $propertyPath->getValue($data);
|
||||||
|
|
|
@ -44,7 +44,9 @@ class FormType extends AbstractType
|
||||||
->setDisabled($options['disabled'])
|
->setDisabled($options['disabled'])
|
||||||
->setErrorBubbling($options['error_bubbling'])
|
->setErrorBubbling($options['error_bubbling'])
|
||||||
->setEmptyData($options['empty_data'])
|
->setEmptyData($options['empty_data'])
|
||||||
->setPropertyPath($options['property_path'])
|
// BC compatibility, when "property_path" could be false
|
||||||
|
->setPropertyPath(is_string($options['property_path']) ? $options['property_path'] : null)
|
||||||
|
->setMapped($options['mapped'])
|
||||||
->setAttribute('read_only', $options['read_only'])
|
->setAttribute('read_only', $options['read_only'])
|
||||||
->setAttribute('by_reference', $options['by_reference'])
|
->setAttribute('by_reference', $options['by_reference'])
|
||||||
->setAttribute('error_mapping', $options['error_mapping'])
|
->setAttribute('error_mapping', $options['error_mapping'])
|
||||||
|
@ -189,6 +191,11 @@ class FormType extends AbstractType
|
||||||
return !$options['single_control'];
|
return !$options['single_control'];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// BC clause: former property_path=false now equals mapped=false
|
||||||
|
$mapped = function (Options $options) {
|
||||||
|
return false !== $options['property_path'];
|
||||||
|
};
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
'data' => null,
|
'data' => null,
|
||||||
'data_class' => $dataClass,
|
'data_class' => $dataClass,
|
||||||
|
@ -200,6 +207,7 @@ class FormType extends AbstractType
|
||||||
'max_length' => null,
|
'max_length' => null,
|
||||||
'pattern' => null,
|
'pattern' => null,
|
||||||
'property_path' => null,
|
'property_path' => null,
|
||||||
|
'mapped' => $mapped,
|
||||||
'by_reference' => true,
|
'by_reference' => true,
|
||||||
'error_bubbling' => $errorBubbling,
|
'error_bubbling' => $errorBubbling,
|
||||||
'error_mapping' => array(),
|
'error_mapping' => array(),
|
||||||
|
|
|
@ -168,7 +168,7 @@ class Form implements \IteratorAggregate, FormInterface
|
||||||
*/
|
*/
|
||||||
public function getPropertyPath()
|
public function getPropertyPath()
|
||||||
{
|
{
|
||||||
if (!$this->hasParent() || null !== $this->config->getPropertyPath()) {
|
if (null !== $this->config->getPropertyPath()) {
|
||||||
return $this->config->getPropertyPath();
|
return $this->config->getPropertyPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,7 +176,7 @@ class Form implements \IteratorAggregate, FormInterface
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null === $this->getParent()->getConfig()->getDataClass()) {
|
if ($this->hasParent() && null === $this->getParent()->getConfig()->getDataClass()) {
|
||||||
return new PropertyPath('[' . $this->getName() . ']');
|
return new PropertyPath('[' . $this->getName() . ']');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,8 +64,14 @@ class PropertyPathMapperTest extends \PHPUnit_Framework_TestCase
|
||||||
->getMock();
|
->getMock();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getForm(PropertyPath $propertyPath = null, $byReference, $synchronized = true)
|
private function getForm(PropertyPath $propertyPath = null, $byReference, $synchronized = true, $mapped = true, $disabled = false)
|
||||||
{
|
{
|
||||||
|
$config = $this->getMock('Symfony\Component\Form\FormConfigInterface');
|
||||||
|
|
||||||
|
$config->expects($this->any())
|
||||||
|
->method('getMapped')
|
||||||
|
->will($this->returnValue($mapped));
|
||||||
|
|
||||||
$form = $this->getMockBuilder(__CLASS__ . '_Form')
|
$form = $this->getMockBuilder(__CLASS__ . '_Form')
|
||||||
// PHPUnit's getMockForAbstractClass does not behave like in the docs..
|
// PHPUnit's getMockForAbstractClass does not behave like in the docs..
|
||||||
// If the array is empty, all methods are mocked. If it is not
|
// If the array is empty, all methods are mocked. If it is not
|
||||||
|
@ -76,6 +82,10 @@ class PropertyPathMapperTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
$form->setAttribute('by_reference', $byReference);
|
$form->setAttribute('by_reference', $byReference);
|
||||||
|
|
||||||
|
$form->expects($this->any())
|
||||||
|
->method('getConfig')
|
||||||
|
->will($this->returnValue($config));
|
||||||
|
|
||||||
$form->expects($this->any())
|
$form->expects($this->any())
|
||||||
->method('getPropertyPath')
|
->method('getPropertyPath')
|
||||||
->will($this->returnValue($propertyPath));
|
->will($this->returnValue($propertyPath));
|
||||||
|
@ -84,6 +94,10 @@ class PropertyPathMapperTest extends \PHPUnit_Framework_TestCase
|
||||||
->method('isSynchronized')
|
->method('isSynchronized')
|
||||||
->will($this->returnValue($synchronized));
|
->will($this->returnValue($synchronized));
|
||||||
|
|
||||||
|
$form->expects($this->any())
|
||||||
|
->method('isDisabled')
|
||||||
|
->will($this->returnValue($disabled));
|
||||||
|
|
||||||
return $form;
|
return $form;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,10 +146,24 @@ class PropertyPathMapperTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
$form = $this->getForm(null, true);
|
$form = $this->getForm(null, true);
|
||||||
|
|
||||||
$form->expects($this->never())
|
$this->mapper->mapDataToForm($car, $form);
|
||||||
->method('setData');
|
|
||||||
|
$this->assertNull($form->getData());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMapDataToFormIgnoresUnmapped()
|
||||||
|
{
|
||||||
|
$car = new \stdClass();
|
||||||
|
$propertyPath = $this->getPropertyPath('engine');
|
||||||
|
|
||||||
|
$propertyPath->expects($this->never())
|
||||||
|
->method('getValue');
|
||||||
|
|
||||||
|
$form = $this->getForm($propertyPath, true, true, false);
|
||||||
|
|
||||||
$this->mapper->mapDataToForm($car, $form);
|
$this->mapper->mapDataToForm($car, $form);
|
||||||
|
|
||||||
|
$this->assertNull($form->getData());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testMapDataToFormIgnoresEmptyData()
|
public function testMapDataToFormIgnoresEmptyData()
|
||||||
|
@ -143,10 +171,9 @@ class PropertyPathMapperTest extends \PHPUnit_Framework_TestCase
|
||||||
$propertyPath = $this->getPropertyPath('engine');
|
$propertyPath = $this->getPropertyPath('engine');
|
||||||
$form = $this->getForm($propertyPath, true);
|
$form = $this->getForm($propertyPath, true);
|
||||||
|
|
||||||
$form->expects($this->never())
|
|
||||||
->method('setData');
|
|
||||||
|
|
||||||
$this->mapper->mapDataToForm(null, $form);
|
$this->mapper->mapDataToForm(null, $form);
|
||||||
|
|
||||||
|
$this->assertNull($form->getData());
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testMapFormToDataWritesBackIfNotByReference()
|
public function testMapFormToDataWritesBackIfNotByReference()
|
||||||
|
@ -201,4 +228,63 @@ class PropertyPathMapperTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
$this->mapper->mapFormToData($form, $car);
|
$this->mapper->mapFormToData($form, $car);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testMapFormToDataIgnoresUnmapped()
|
||||||
|
{
|
||||||
|
$car = new \stdClass();
|
||||||
|
$engine = new \stdClass();
|
||||||
|
$propertyPath = $this->getPropertyPath('engine');
|
||||||
|
|
||||||
|
$propertyPath->expects($this->never())
|
||||||
|
->method('setValue');
|
||||||
|
|
||||||
|
$form = $this->getForm($propertyPath, true, true, false);
|
||||||
|
$form->setData($engine);
|
||||||
|
|
||||||
|
$this->mapper->mapFormToData($form, $car);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMapFormToDataIgnoresEmptyData()
|
||||||
|
{
|
||||||
|
$car = new \stdClass();
|
||||||
|
$propertyPath = $this->getPropertyPath('engine');
|
||||||
|
|
||||||
|
$propertyPath->expects($this->never())
|
||||||
|
->method('setValue');
|
||||||
|
|
||||||
|
$form = $this->getForm($propertyPath, true);
|
||||||
|
$form->setData(null);
|
||||||
|
|
||||||
|
$this->mapper->mapFormToData($form, $car);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMapFormToDataIgnoresUnsynchronized()
|
||||||
|
{
|
||||||
|
$car = new \stdClass();
|
||||||
|
$engine = new \stdClass();
|
||||||
|
$propertyPath = $this->getPropertyPath('engine');
|
||||||
|
|
||||||
|
$propertyPath->expects($this->never())
|
||||||
|
->method('setValue');
|
||||||
|
|
||||||
|
$form = $this->getForm($propertyPath, true, false);
|
||||||
|
$form->setData($engine);
|
||||||
|
|
||||||
|
$this->mapper->mapFormToData($form, $car);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testMapFormToDataIgnoresDisabled()
|
||||||
|
{
|
||||||
|
$car = new \stdClass();
|
||||||
|
$engine = new \stdClass();
|
||||||
|
$propertyPath = $this->getPropertyPath('engine');
|
||||||
|
|
||||||
|
$propertyPath->expects($this->never())
|
||||||
|
->method('setValue');
|
||||||
|
|
||||||
|
$form = $this->getForm($propertyPath, true, true, true, true);
|
||||||
|
$form->setData($engine);
|
||||||
|
|
||||||
|
$this->mapper->mapFormToData($form, $car);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -562,4 +562,46 @@ class FormTypeTest extends TypeTestCase
|
||||||
|
|
||||||
$this->assertTrue($form->getErrorBubbling());
|
$this->assertTrue($form->getErrorBubbling());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testPropertyPath()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create('form', null, array(
|
||||||
|
'property_path' => 'foo',
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->assertEquals(new PropertyPath('foo'), $form->getPropertyPath());
|
||||||
|
$this->assertTrue($form->getConfig()->getMapped());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testPropertyPathNullImpliesDefault()
|
||||||
|
{
|
||||||
|
$form = $this->factory->createNamed('form', 'name', null, array(
|
||||||
|
'property_path' => null,
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->assertEquals(new PropertyPath('name'), $form->getPropertyPath());
|
||||||
|
$this->assertTrue($form->getConfig()->getMapped());
|
||||||
|
}
|
||||||
|
|
||||||
|
// BC
|
||||||
|
public function testPropertyPathFalseImpliesDefaultNotMapped()
|
||||||
|
{
|
||||||
|
$form = $this->factory->createNamed('form', 'name', null, array(
|
||||||
|
'property_path' => false,
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->assertEquals(new PropertyPath('name'), $form->getPropertyPath());
|
||||||
|
$this->assertFalse($form->getConfig()->getMapped());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function testNotMapped()
|
||||||
|
{
|
||||||
|
$form = $this->factory->create('form', null, array(
|
||||||
|
'property_path' => 'foo',
|
||||||
|
'mapped' => false,
|
||||||
|
));
|
||||||
|
|
||||||
|
$this->assertEquals(new PropertyPath('foo'), $form->getPropertyPath());
|
||||||
|
$this->assertFalse($form->getConfig()->getMapped());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue