Skip to content

Commit

Permalink
[Form] Added tests for the case when "property_path" is null or false…
Browse files Browse the repository at this point in the history
…. Instead of setting "property_path" to false, you should set "mapped" to false instead.
  • Loading branch information
webmozart committed May 22, 2012
1 parent 2301b15 commit 5e87dd8
Show file tree
Hide file tree
Showing 7 changed files with 174 additions and 11 deletions.
22 changes: 22 additions & 0 deletions UPGRADE-2.1.md
Expand Up @@ -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

* The methods `setMessage()`, `getMessageTemplate()` and
Expand Down
1 change: 1 addition & 0 deletions src/Symfony/Component/Form/CHANGELOG.md
Expand Up @@ -70,3 +70,4 @@ CHANGELOG
* deprecated method `guessMinLength` in favor of `guessPattern`
* labels don't display field attributes anymore. Label attributes can be
passed in the "label_attr" option/variable
* added option "mapped" which should be used instead of setting "property_path" to false
Expand Up @@ -44,8 +44,9 @@ public function mapDataToForm($data, FormInterface $form)
{
if (!empty($data)) {
$propertyPath = $form->getPropertyPath();
$config = $form->getConfig();

if (null !== $propertyPath) {
if (null !== $propertyPath && $config->getMapped()) {
$propertyData = $propertyPath->getValue($data);

if (is_object($propertyData) && !$form->getAttribute('by_reference')) {
Expand Down Expand Up @@ -76,8 +77,11 @@ public function mapFormsToData(array $forms, &$data)
public function mapFormToData(FormInterface $form, &$data)
{
$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
// dealing with a reference
$isReference = $form->getData() === $propertyPath->getValue($data);
Expand Down
10 changes: 9 additions & 1 deletion src/Symfony/Component/Form/Extension/Core/Type/FormType.php
Expand Up @@ -44,7 +44,9 @@ public function buildForm(FormBuilder $builder, array $options)
->setDisabled($options['disabled'])
->setErrorBubbling($options['error_bubbling'])
->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('by_reference', $options['by_reference'])
->setAttribute('error_mapping', $options['error_mapping'])
Expand Down Expand Up @@ -189,6 +191,11 @@ public function getDefaultOptions()
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(
'data' => null,
'data_class' => $dataClass,
Expand All @@ -200,6 +207,7 @@ public function getDefaultOptions()
'max_length' => null,
'pattern' => null,
'property_path' => null,
'mapped' => $mapped,
'by_reference' => true,
'error_bubbling' => $errorBubbling,
'error_mapping' => array(),
Expand Down
4 changes: 2 additions & 2 deletions src/Symfony/Component/Form/Form.php
Expand Up @@ -168,15 +168,15 @@ public function getName()
*/
public function getPropertyPath()
{
if (!$this->hasParent() || null !== $this->config->getPropertyPath()) {
if (null !== $this->config->getPropertyPath()) {
return $this->config->getPropertyPath();
}

if (null === $this->getName() || '' === $this->getName()) {
return null;
}

if (null === $this->getParent()->getConfig()->getDataClass()) {
if ($this->hasParent() && null === $this->getParent()->getConfig()->getDataClass()) {
return new PropertyPath('[' . $this->getName() . ']');
}

Expand Down
Expand Up @@ -64,8 +64,14 @@ private function getPropertyPath($path)
->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')
// PHPUnit's getMockForAbstractClass does not behave like in the docs..
// If the array is empty, all methods are mocked. If it is not
Expand All @@ -76,6 +82,10 @@ private function getForm(PropertyPath $propertyPath = null, $byReference, $synch

$form->setAttribute('by_reference', $byReference);

$form->expects($this->any())
->method('getConfig')
->will($this->returnValue($config));

$form->expects($this->any())
->method('getPropertyPath')
->will($this->returnValue($propertyPath));
Expand All @@ -84,6 +94,10 @@ private function getForm(PropertyPath $propertyPath = null, $byReference, $synch
->method('isSynchronized')
->will($this->returnValue($synchronized));

$form->expects($this->any())
->method('isDisabled')
->will($this->returnValue($disabled));

return $form;
}

Expand Down Expand Up @@ -132,21 +146,34 @@ public function testMapDataToFormIgnoresEmptyPropertyPath()

$form = $this->getForm(null, true);

$form->expects($this->never())
->method('setData');
$this->mapper->mapDataToForm($car, $form);

$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->assertNull($form->getData());
}

public function testMapDataToFormIgnoresEmptyData()
{
$propertyPath = $this->getPropertyPath('engine');
$form = $this->getForm($propertyPath, true);

$form->expects($this->never())
->method('setData');

$this->mapper->mapDataToForm(null, $form);

$this->assertNull($form->getData());
}

public function testMapFormToDataWritesBackIfNotByReference()
Expand Down Expand Up @@ -201,4 +228,63 @@ public function testMapFormToDataWritesBackIfByReferenceAndReference()

$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);
}
}
Expand Up @@ -562,4 +562,46 @@ public function testOverrideErrorBubbling()

$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());
}
}

0 comments on commit 5e87dd8

Please sign in to comment.