Skip to content

Instantly share code, notes, and snippets.

@boekkooi
Created February 24, 2015 15:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save boekkooi/4a80283c0582827b9e39 to your computer and use it in GitHub Desktop.
Save boekkooi/4a80283c0582827b9e39 to your computer and use it in GitHub Desktop.
Event sourced form mapping
<?php
use Symfony\Component\Form\Exception\UnexpectedTypeException;
use Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper;
/**
* Custom datamapper
* This uses normal getters to fill the form using PropertyPathMapper.
* But for setters it go's the custom route.
*/
class MyDataMapper extends PropertyPathMapper {
/**
* {@inheritdoc}
*/
public function mapFormsToData($forms, &$data)
{
if (null === $data) {
return;
}
if (!$data instanceof MySource) {
throw new UnexpectedTypeException($data, sprintf('Expected instance of %s', MySource::class));
}
// Get the submitted data
// In some cases you may want to also normalize or do some very funky validation here
// If that fails you can throw a `Symfony\Component\Form\Exception\TransformationFailedException`.
$submittedData = $this->retrieveData($forms);
// Call the actual method that will apply the changes
$data->myChangeMethod(
$submittedData['<element_name_1>'],
$submittedData['<element_name_2>']
);
}
/**
* Get the data form the given forms/elements and puts it into a array.
*
* @param \Symfony\Component\Form\Form[] $forms
* @return array
*/
private function retrieveData($forms)
{
$data = [];
/** @var \Symfony\Component\Form\Form[] $forms */
foreach ($forms as $form) {
$propertyPath = $form->getPropertyPath();
$config = $form->getConfig();
// Write-back is disabled if the form is not synchronized (transformation failed),
// if the form was not submitted and if the form is disabled (modification not allowed)
if (null === $propertyPath || !$config->getMapped() || !$form->isSubmitted() || !$form->isSynchronized() || $form->isDisabled()) {
continue;
}
$data[(string)$propertyPath] = $form->getData();
}
return $data;
}
}
<?php
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
class MySexyFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
// ...
$builder->setDataMapper(new MyDataMapper());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment