-
-
Save webmozart/36b1cd8a68a5f7844268 to your computer and use it in GitHub Desktop.
class MoneyType extends AbstractType implements DataMapperInterface | |
{ | |
public function buildForm(FormBuilder $builder, array $options) | |
{ | |
$builder | |
->add('amount', 'integer') | |
->add('currency', 'string') | |
->setDataMapper($this) | |
; | |
} | |
public function mapDataToForms($data, $forms) | |
{ | |
foreach ($forms as $form) { | |
switch ($form->getName()) { | |
case 'amount': | |
$form->setData($data->getAmount()); | |
break; | |
case 'currency': | |
$form->setData($data->getCurrency()); | |
break; | |
} | |
} | |
} | |
public function mapFormsToData($forms, &$data) | |
{ | |
$forms = iterator_to_array($forms); | |
$data = new Money($forms['amount']->getData(), $forms['currency']->getData()); | |
} | |
} |
How does this behave when user input breaks the invariants of Money? Will validation by the form take care of this? Or will Money throw an exception because it is instantiated before form validation is performed?
@jaspernbrouwer You could catch the exceptions thrown by Money and wrap them into a TransformationFailedException.
@gnat42 Exchanging information between the data of a form and its children is the responsibility of the data mapper. You could use a data transformer too and transform Money to/from an array, but then you'd need to set the data mapper to something like a NullDataMapper
because then you do the mapping yourself.
would be nice to gets its usage too like:
$form = $this->createForm(new MoneyType(), $user->getInvestment());
if ($form->handleRequest($request)->isValid()) {
$this->bus->dispatch(new UpdateInvestment($user->getId(), $form->getData()))
and also say that should the type have less fields than the VO you can also copy those over to the VO from the $data coming into the call to mapFormsToData($forms, &$data)
😸
I wrote a more detailed blog post about this now.
So this is nice and an interesting way to solve this problem. I'm just wondering isn't this the purpose of data transformers?