Reputation:
I am building an API and using forms for data binding, now i want to be able to pass the ID of an entity, get the reference and attach it to the item, here is an example:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('credit');
$builder->add('currency', 'currency');
$builder->add('borrower', BorrowerType::class, [
'required' => true
]);
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
$data = $event->getData();
$borrower = $this->em->getReference(Borrower::class, $data['borrower']);
$data['borrower'] = $borrower;
});
}
This returns "ERROR: This value is not valid.\n"
Here is my test request:
$client->request('POST', $endpoint, [
'loan' => [
'credit' => '1000',
'currency' => 'EUR',
'borrower' => $borrower->getId()
]
]);
Upvotes: 2
Views: 965
Reputation: 29912
One straightforward method to reach this a "symfonic" way is to use a DataTransformer
DataTransformer will take a data format and transform it into another format (type).
What you can use is a ViewTransformer
that, in Transform()
phase, will take the entity and return its id
whereas in ReverseTransform()
it takes the id
and, by using a repository, will retrieve Entity.
Something like
class BorrowerToIdTransform implements DataTransformerInterface
{
private $manager;
public function __construct(ObjectManager $manager)
{
$this->manager = $manager;
}
/**
* Transforms an object (Borrower) to a string (id).
*
* @param Borrower|null $issue
* @return string
*/
public function transform($borrower)
{
if (null === $borrower) {
return '';
}
return $borrower->getId();
}
/**
* Transforms a string (id) to an object (Borrower).
*
* @param string $id
* @return Borrower|null
* @throws TransformationFailedException if object (issue) is not found.
*/
public function reverseTransform($id)
{
if (!$id) {
return;
}
$borrower = $this->manager
->getRepository(Borrower::class)
->find($id)
;
if (null === $borrower) {
throw new TransformationFailedException(sprintf(
'A borrower with "%s" id does not exist!',
$id
));
}
return $issue;
}
}
Upvotes: 1
Reputation: 2629
The "$event->getData()" is your actual entity, if this form uses a default entity in its options resolver or if you pass an entity in through your controller when you make the form.
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('credit');
$builder->add('currency', 'currency');
$builder->add('borrower', BorrowerType::class, [
'required' => true
]);
$builder->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) {
$entity = $event->getData();
//The following doesn't make a lot of sense
//The borrower will already be set
$borrower = $this->em->getReference(Borrower::class, $entity->getBorrower());
$entity->setBorrower($borrower);
});
}
Like in this standard way of checking whether a user has to enter a password (if they're new) or if it's not required if the user already exists.
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$user = $event->getData();
$form = $event->getForm();
$formParams = [
'type' => PasswordType::class,
'first_options' => ['label' => 'Password'],
'second_options' => ['label' => 'Repeat Password'],
];
if ((!$user || null === $user->getId())) {
$formParams['constraints'] = new NotBlank();
} else {
$formParams['required'] = false;
}
$form->add('plainPassword', RepeatedType::class, $formParams);
});
If this form is creating or updating an entity then the borrower information is set to the entity when it's created.
Upvotes: 0