Cloning object after getting data from a form in Symfony2 - symfony

I'm sure I'm missing something very basic here.
I have a form, and when the user updates the fields of the form I don't want to update the underlying entity but want to create a new entity with the new values.
To clone Doctrine entities I followed the indication here.
So my code is (let's say I want to clone the object with id=3:
$id = 3;
$storedBI = $this->getDoctrine()
->getRepository('AppBundle:BenefitItem')
->find($id);
$form = $this->createForm(new BenefitItemFormType(), $storedBI);
$form->handleRequest($request);
if ($form->isValid())
{
$em = $this->getDoctrine()->getManager();
$newBI = clone $form->getData();
$em->persist($newBI);
$em->flush();
}
It simply does not work. It properly creates a new object with the new data passed from the form (which is ok), but also updates the "old" stored object with the same new data.
Any idea?

You have to clone your object during the form creation:
$form = $this->createForm(new BenefitItemFormType(), clone $storedBI);
If this does not work, try to detach your cloned object first.

Related

How to implement a Logical Erase in Symfony 3?

I am implementing a logical erase for my Symfony 3 entities.
On my entities, I added a $deleted field, and I created some delete-controllers with this code:
$entity->setDeleted(true);
$em->persist($entity);
$em->flush();
Then, I modified also my queries to avoid select 'deleted' entities. And works great.
The problem:
I have some entities with Unique Constraint (for example, email field on user table), so when I delete an user, and then try to add the same user with the same email, symfony shows a validation form error due to 'duplicated email'.
I tried to control this on controller in the following way:
$user = new User();
$em = $this->getDoctrine()->getManager();
if ($request->getMethod() == 'POST') {
$form->handleRequest($request);
//Check for deleted duplication:
$duplicatedUser = $em->getRepository('AppBundle:User')
->getDuplicatedAndDeletedUser($user);
if($duplicatedUser != null){
$em->remove($duplicatedUser);
$em->flush();
}
if ($form->isValid()) {
$em->persist($user);
$em->flush();
}
}
But this code doesn't avoid the form validation error. First time when I try to create, Stymfony shows an error, and then, if I resubmit the form, it works because of the duplicated entity was removed from db.
How can I solve this issue?
Note: I know this: http://atlantic18.github.io/DoctrineExtensions/doc/softdeleteable.html but, I have already developed all the logic described, so I prefer go in my way with this.
Finally I find the sollution.
As you can see here http://symfony.com/doc/current/forms.html#handling-form-submissions handleRequest() method validate the form, so delete the entity after that don't solve the problem at all.
I do that to get form data:
$userName = $request->request->get('user')['email'];
And then check if this $userName is already used. If so, I delete the user before handleRequest() call.
Hope this help others.
Something strange in your code, I can see a user getting created but it doesn't get injected in the form so it can be used to store data in it and I also don't see the form anywhere, was it created in the controller or is it pure html, if so, you would need to fill in the user with the data from the form with $formName->getData() function or if you so wish, fill in only individual fields with the $formName['fieldname']->getData(). Try this code:
$user = new User();
$form = $this->createForm(UserType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid())
{
$em = $this->getDoctrine()->getManager();
//Check for deleted duplication:
$duplicatedUser = $em->getRepository('AppBundle:User')
->getDuplicatedAndDeletedUser($user);
if($duplicatedUser != null){
$em->remove($duplicatedUser);
$em->flush();
}
$em->persist($user);
$em->flush();
}

symfony crud simple request

i'm trying to do a simple add without the form generated by doctrine
$mail = new Subscription();
$request = $this->getRequest();
if ($request->getMethod() == "POST") {
$em = $this->getDoctrine()->getManager();
$samplees = $request->get("samplees");
$mail->setEmail($samplees);
$em->persist($mail);
$em->flush();
return $this->redirect($this->generateUrl('user_homepage'));
}
First of all, Doctrine2 will not handle any form facility (nor creation neither data binding process): the whole process is up to symfony and its form bundle.
That said, if you need to retrieve a posted data you need to modify
$samplees = $request->get("samplees");
into
$samplees = $request->request->get("samplees");
This because $request is the whole Request object (so, basically, it will handle also get parameters [$request->query->get(...)] just to say one of the functionalities)

symfony2: saving form data in a single step

my form got 4 fields after validation when i look for the insert procedure if found i have to do the following which works fine too
if($form->isValid()){
$data = $form->getData();
$entity->setName($data->getName());
$entity->setEmail($data->getEmail());
$entity->setStatus($data->getStatus());
$entity->setSubscribedon($data->getSubscribedon());
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
$session->getFlashBag()->add('success', 'Subscriber added successfully');
return $this->redirect($this->generateUrl('admin_subscribers'));
}
but do we got any other way like mass assign data to insert ? like in Yii we can assign entire form fields with out setting individual form data , suppose if my form got 15 fields do i have to call set method for each of them ? is there any other way of doing it ?
thank you
You need to pass entity object when you create form, then after form validation just persist that entity
$entity = new Entity();
$em = $this->getDoctrine()->getManager();
$form = $this->createForm(new FormType(), $entity);
$form->handleRequest($request);
if ($form->isValid()) {
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('admin_subscribers'));
}

Update data without form using Symfony2

I've tried searching about updating data in Symfony2 but look like all tutorials need few normal steps to do this :
Manager initialisation $em = $this->getDoctrine()->getManager();
Make Entity with criteria $entity =
$em->getRepository('bundle')->find($id);
Create Form $form = $this->createForm(new Type(), $entity);
Bind with request $editForm->handleRequest($request);
Flush data $em->flush();
Let say that I have custom form in twig and do manual getRequest in controller $variable = $request->request->get('name');. Is there any way I can do to update this data for specific ID in entity $entity = $em->getRepository('bundle')->find($id); without create a form for flush my data?
Because I need to update this variable for many ID in my database using iteration. Let say that I have thousands data need to updated with this value. I'm worried if creating form will impact to performance and time.
Simply set your data directly in your entity using your setters and then flush:
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('Bundle:Entity')->find($id);
$entity->setSomeProperty($propertyValue);
$em->flush();

Entity previous status in Symfony 2

i have a doubt. Probably it is because I am a newbie in symfony.
I have an entity with a status and I show it in a form that the status can be changed.
In the controller i need the previous status to compare with new status to do some actions.
When I do bind I cannot access to previous status for this $entity,
$editForm = $this->createForm(new StatusType(), $entity);
$editForm->bind($request);
How can I access to these previous data?
Best Regards!
Maybe there is a better way, but you can use:
$editForm = $this->createForm(new StatusType(), $entity);
$entity_before = clone $entity; //you can do it before your createform
$editForm->bind($request);

Resources