Skip to content

Commit

Permalink
read form values using the chain data accessor
Browse files Browse the repository at this point in the history
  • Loading branch information
xabbuh committed Apr 25, 2024
1 parent cc4ea6d commit 6e732c4
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 2 deletions.
25 changes: 23 additions & 2 deletions Extension/Core/DataAccessor/PropertyPathAccessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
namespace Symfony\Component\Form\Extension\Core\DataAccessor;

use Symfony\Component\Form\DataAccessorInterface;
use Symfony\Component\Form\DataMapperInterface;
use Symfony\Component\Form\Exception\AccessException;
use Symfony\Component\Form\Extension\Core\DataMapper\DataMapper;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\PropertyAccess\Exception\AccessException as PropertyAccessException;
use Symfony\Component\PropertyAccess\Exception\NoSuchIndexException;
Expand Down Expand Up @@ -57,15 +59,25 @@ public function setValue(&$data, $propertyValue, FormInterface $form): void
throw new AccessException('Unable to write the given value as no property path is defined.');
}

$getValue = function () use ($data, $form, $propertyPath) {
$dataMapper = $this->getDataMapper($form);

if ($dataMapper instanceof DataMapper && null !== $dataAccessor = $dataMapper->getDataAccessor()) {
return $dataAccessor->getValue($data, $form);
}

return $this->getPropertyValue($data, $propertyPath);
};

// If the field is of type DateTimeInterface and the data is the same skip the update to
// keep the original object hash
if ($propertyValue instanceof \DateTimeInterface && $propertyValue == $this->getPropertyValue($data, $propertyPath)) {
if ($propertyValue instanceof \DateTimeInterface && $propertyValue == $getValue()) {
return;
}

// If the data is identical to the value in $data, we are
// dealing with a reference
if (!\is_object($data) || !$form->getConfig()->getByReference() || $propertyValue !== $this->getPropertyValue($data, $propertyPath)) {
if (!\is_object($data) || !$form->getConfig()->getByReference() || $propertyValue !== $getValue()) {
$this->propertyAccessor->setValue($data, $propertyPath, $propertyValue);
}
}
Expand Down Expand Up @@ -105,4 +117,13 @@ private function getPropertyValue($data, PropertyPathInterface $propertyPath)
return null;
}
}

private function getDataMapper(FormInterface $form): ?DataMapperInterface
{
do {
$dataMapper = $form->getConfig()->getDataMapper();
} while (null === $dataMapper && null !== $form = $form->getParent());

return $dataMapper;
}
}
8 changes: 8 additions & 0 deletions Extension/Core/DataMapper/DataMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,12 @@ public function mapFormsToData(iterable $forms, &$data): void
}
}
}

/**
* @internal
*/
public function getDataAccessor(): DataAccessorInterface
{
return $this->dataAccessor;
}
}
26 changes: 26 additions & 0 deletions Tests/Extension/Core/DataMapper/DataMapperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
use Symfony\Component\Form\Extension\Core\DataAccessor\PropertyPathAccessor;
use Symfony\Component\Form\Extension\Core\DataMapper\DataMapper;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\FormType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Form;
use Symfony\Component\Form\FormConfigBuilder;
use Symfony\Component\Form\FormFactoryBuilder;
Expand Down Expand Up @@ -419,6 +421,25 @@ public function testMapFormsToDataMapsDateTimeInstanceToArrayIfNotSetBefore()

$this->assertEquals(['date' => new \DateTime('2022-08-04', new \DateTimeZone('UTC'))], $form->getData());
}

public function testMapFormToDataWithOnlyGetterConfigured()
{
$person = new DummyPerson('foo');
$form = (new FormFactoryBuilder())
->getFormFactory()
->createBuilder(FormType::class, $person)
->add('name', TextType::class, [
'getter' => function (DummyPerson $person) {
return $person->myName();
},
])
->getForm();
$form->submit([
'name' => 'bar',
]);

$this->assertSame('bar', $person->myName());
}
}

class SubmittedForm extends Form
Expand Down Expand Up @@ -455,4 +476,9 @@ public function rename($name): void
{
$this->name = $name;
}

public function setName($name): void
{
$this->name = $name;
}
}

0 comments on commit 6e732c4

Please sign in to comment.