symfony2: fill request data into form - symfony

I've tried to pass GET parameter to fill default values of form fields:
Form Fields: field1, field2
URL: http://localhost:8000/some_entity/new?field1=default
In the controller if tried to bind the parameters to the form:
public function newAction(Request $request) {
$entity = new Entity();
$form = $this->createCreateForm($entity);
// first try
$request->request->set('field1', $_GET['field1']);
$form->handleRequest($request);
// second try
$form->setData(array('field1' => $_GET['field1']));
// this works, but it's useless in my case
$entity->setField1($_GET['field1']);
$form->setData($entity);
[...]
}
Can you tell me how I can do this?
EDIT:
I need this because this controller is not used for this entity exclusively. In a second step, I want to provide a button to add "child values" of joining entities. E.g. add a comment to a post providing the dedicated post id through $_GET vars to be selected automatically.

The easiest way is to pass these values to the entity. And you can get the _GET values from the request object like below.
$entity = new Entity();
$entity->setField1($request->query->get('field1'));
//...
$form = $this->createCreateForm($entity);

Related

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)

Cloning object after getting data from a form in Symfony2

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.

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();

symfony2 render part of form

First of all, thanks for all of you who take a look of this problem.
I got a FormType like userFormType.
class UserFormType extends AbstractType{
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('address','collection', ....)
->add('group','entity',....)
->add('companies','collection',....);
...
}
}
So you see i got two collection in the user form. I create the form and i set the companies. When i wanna to modify ONLY the information of companies and the address, but not in touch with group. So i have to render a user form, but not some company forms or address forms. so i write a controller like this:
$user= $this->get('security.context')->getToken()->getUser();
$form =$this->createForm(new UserForm(),$user);
$request = $this->get('request');
if ('POST' == $request->getMethod()) {
$form->bindRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getEntityManager();
$em->persist($user);
$em->flush();
....
}
}
Of course, i do not wanna to modify the group so in the twig template, i dot not render the group. the form is rendered correctly, but every time i try to submit it, it tell me:
Argument 1 passed to ... User->setGroup() must be an instance of Group ... null given
So I'm asking, what should i do?
The error specifically is because your method definition in User is probably:
public function setGroup(Group $group);
but in order to set it null it would need to be:
public function setGroup(Group $group = null);
That will fix the error but it still might not be what you want functionality wise. My question is, why have the group field on the form if you are not using it? You may need another form type or pass an option to the form to not include the group field during edits.

How to update a Doctrine Entity from a serialized JSON?

We are using Symfony2 to create an API. When updating a record, we expect the JSON input to represent a serialized updated entity. The JSON data will not contain some fields (for instance, CreatedAt should be set only once when the entity is created - and never updated). For instance, here is an example JSON PUT request:
{"id":"1","name":"anyname","description":"anydescription"}
Here is the PHP code on the Controller that should update the entity according to the JSON above (we are using JMS serializer Bundle):
$supplier = $serializer->deserialize(
$this->get('request')->getContent(),
'WhateverEntity',
'json'
);
The EntityManger understands (correctly) that this is an update request (in fact, a SELECT query is implicitly triggered). The EntityManager also guess (not correctly) that CreatedAt property should be NULLified - it should instead keep the previous one.
How to fix this issue?
It's possible as well to do it with Symfony Serializer using object_to_populate option.
Example: I receive JSON request. If record exists in database I want to update fields received in body, if it does not exist I want to create new one.
/**
* #Route("/{id}", methods={"PUT"})
*/
public function upsert(string $id, Request $request, SerializerInterface $serializer)
{
$content = $request->getContent(); // Get json from request
$product = $this->getDoctrine()->getRepository(Product::class)->findOne($id); // Try to find product in database with provided id
if (!$product) { // If product does not exist, create fresh entity
$product = new Product();
}
$product = $serializer->deserialize(
$content,
Product::class,
'json',
['object_to_populate' => $product] // Populate deserialized JSON content into existing/new entity
);
// validation, etc...
$this->getDoctrine()->getManager()->persist($product); // Will produce update/instert statement
$this->getDoctrine()->getManager()->flush($product);
// (...)
using the JMSSerializerBundle follow the install instructions at
http://jmsyst.com/bundles/JMSSerializerBundle
either create your own serializer service or alter the JMSSerializerBundle to use the doctrine object constructor instead of the simple object constructor.
<service id="jms_serializer.object_constructor" alias="jms_serializer.doctrine_object_constructor" public="false"/>
This basically handles exactly what Ocramius solution does but using the JMSSerializerBundles deserialize.
I would use the Doctrine\ORM\Mapping\ClassMetadata API to discover existing fields in your entity.
You can do following (I don't know how JMSSerializerBundle works):
//Unserialize data into $data
$metadata = $em->getMetadataFactory()->getMetadataFor($FQCN);
$id = array();
foreach ($metadata->getIdentifierFieldNames() as $identifier) {
if (!isset($data[$identifier])) {
throw new InvalidArgumentException('Missing identifier');
}
$id[$identifier] = $data[$identifier];
unset($data[$identifier]);
}
$entity = $em->find($metadata->getName(), $id);
foreach ($metadata->getFieldNames() as $field) {
//add necessary checks about field read/write operation feasibility here
if (isset($data[$field])) {
//careful! setters are not being called! Inflection is up to you if you need it!
$metadata->setFieldValue($entity, $field, $data[$field]);
}
}
$em->flush();

Resources