how to update only a some field of an entity in symfony2 - php

I have a user table. In that table I have different fields. I only need to update the image column of the user table.
I have a form for uploading the image only. Even though the image is set but when I submit the form I get validations errors of other fields.
I know that the validation errors are because I passed the user object to the form and issued a isValid().
How do I only update the specific column like the image column?
public function updateImageAction(Request $request){
$form = $this->createForm(new UploadImageType(),new User(),[
'action' => $this->generateUrl('update_image')
]);
$form->handleRequest($request);
$user = $this->getUser();
if ($form->isSubmitted() && $form->isValid())
{
$em = $this->getDoctrine()->getManager();
$data = $form->getData();
dump($data);die;
$em->persist($data);
$em->flush();
}
return $this->render('photo.html.twig', [
'form' => $form->createView()
]);
}

Related

How to explain this issue and what should be the best solution about Symfony serializer/csv decoder

I am trying to make a simple CSV uploader with contacts and make them as array using Symfony serializer/CSV encoder. The problem is that when i get data from csv and i dump it i get everything fine i think. But when i want to loop over the array to echo email field or try to create new Objects and save them to database i get an error that index 'Email Address' is undefined. How that can be possible, if when i var_dump in a loop and die after first array on the list i see that 'Email Address' field exists.
Link to image - https://imgur.com/a/7bSJT0z
/**
* #Route("/upload-csv", name="upload")
*/
public function uploadCsv(Request $request)
{
$form = $this->createForm(ContactType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid())
{
$em = $this->getDoctrine()->getManager();
$data = $form->getData();
$file = $data->getCsv();
//dump($file);
$serializer = $this->container->get('serializer');
$cons = $serializer->decode(file_get_contents($file), 'csv');
foreach ($cons as $con)
{
$contact = new Contact();
$contact->setEmail($con['Email Address']);
$contact->setFirstName($con['First Name']);
$contact->setLastName($con['Last Name']);
$contact->setCountry($data->getCountry());
$em->persist($contact);
}
$em->flush();
}
return $this->render('base.html.twig', [
'form' => $form->createView()
]);
}

Symfony form submit and validate from another method

I have made a form created after an Ajax request (after the first form (Test1Type) is submitted)
public function indexAction(Request $request): Response
{
$form = $this->createForm(Test1Type::class);
$form->handleRequest($request);
if ($request->isXmlHttpRequest()) {
$form = $this->createForm(Test2Type::class);
return new Response($this->renderView('test/_results.html.twig', [
'form' => $form->createView(),
]));
}
return $this->render('test/index.html.twig', [
'form' => $form->createView(),
]);
}
Then I want to submit, validate and get the datas from this Test2Type in another method
public function confirmAction(Request $request): Response
{
dump($form->getData());
return $this->render('test/confirm.html.twig', [
]);
}
But I don't have acces to my form variable and I will not re-use $form = $this->createForm(Test2Type::class);...
I think this is possible but I really don't have any clues to made this work...
Do you have some ideas ?
It's not possible, you must create $form variable before using it for submittion and validation. To avoid duplicate code on create Test2Type form, you should redirect to confirmAction in indexAction after the form submitted and valid.
public function indexAction(Request $request)
{
$form = $this->createForm(Test1Type::class)->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
return $this->redirectToRoute('confirm.action.route_name');
}
return $this->render('test/index.html.twig', [
'form' => $form->createView(),
]);
}
public function confirmAction(Request $request)
{
$form = $this->createForm(Test2Type::class)->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
return $this->render('test/confirm.html.twig', [
'data' => $form->getData()
]);
}
return $this->render('test/_results.html.twig', [
'form' => $form->createView(),
]);
}
You should add another action in your controller for the ajax request with another route!!
This is better readable code and works better with the history button of your browser. (less cache problems) furthermore you can of course simply change the 'action' attribute of the HTML <form> element. Follow this link to read how: http://symfony.com/doc/current/form/action_method.html

Silex second form behind first form

What I want to do is quite simple. I have a first form. When this form is submitted, I have another form. When this second form is submitted, I want execute somes actions.
So here is my controller simplified:
$app->post('/path', function(Request $request) use ($app) {
$app['request'] = $request;
$token = $app['security.token_storage']->getToken();
if (null !== $token) {
$user = $token->getUser();
// First form
$form = $app['form.factory']->createBuilder(FormType::class)
->add('field_form1', TextType::class, [
'required' => true,
])
->getForm();
// Second form
$formcb = $app['form.factory']->createBuilder(FormType::class)
->add('field_form2', TextType::class, [
'required' => true,
])
->getForm();
// When second form is submitted
$formcb->handleRequest($request);
if($formcb->isSubmitted() && $formcb->isValid()) {
// isValid is never true
$data = $formcb->getData();
}
// When first form is submitted
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
switch ($data["paiementType"]) {
[...]
case 'mycase':
// Render of the second form
return $app['twig']->render('page2.twig', [
'form' => $formcb->createView(),
]);
default: break;
}
}
// Render of the first form
return $app['twig']->render('page1.twig', [
'form' => $form->createView(),
]);
}
})->bind('path');
But,
No problems for the first form, it works well.
The second form seems to have already been validated when it is render, because the fields errors message are display on the form.
When I submit the second form, I never enter in the if($formcb->isSubmitted() && $formcb->isValid()) { clause, because isValid is never true... However, the form is submitted...
So I don't know what is wrong, maybe it is not the good way to render a form behind another form...

Populating form data from entity in Symfony2

I have an action that basically renders a form and I want it to be a new form if the ID is null and an edit form if the ID matches with the PK in the DB. Obviously my logic is wrong because a new form is rendering every single time. .
public function editGlobalFirewallFilter(Request $request, Entities\GlobalFirewallFilter $firewall_rule = null) {
n
// Check if we have a valid rule. If not create a new blank one and associate our account id
// if( ! $firewall_rule ) {
// $results = $this->getDoctrine()->getRepository('bundle:GlobalFirewallFilter');
// $rules = $results->findAll();
// $firewall_rule = new Entities\GlobalFirewallFilter();
// }
$firewall_rule = new Entities\GlobalFirewallFilter();
// Generate our form
$form = $this->createForm(new SAForms\GlobalFirewallRuleType(), $firewall_rule);
$form->handleRequest($request);
if($form->isValid()) {
// Save our firewall rule
$em = $this->getDoctrine()->getManager();
$em->persist($firewall_rule);
$em->flush();
return $this->redirect($this->generateUrl('_dashboard__global_firewall'));
}
return array(
'title' => $firewall_rule->getFirewallFilterId() ? 'Edit Rule' : 'New Rule',
'form' => $form->createView(),
);
}
You should use the form generator command to be oriented in the right way :
Generating a CRUD Controller Based on a Doctrine Entity
http://symfony.com/doc/current/bundles/SensioGeneratorBundle/commands/generate_doctrine_crud.html
use this command :
php app/console generate:doctrine:crud
I will generate the skeleton of you controller with all the standard actions as wanted, in your specifica case, updateAction, newAction, and editAction.
I am not quite sure why are there results and rules - you don't use them. I think this code should do the trick.
public function editGlobalFirewallFilter(Request $request, Entities\GlobalFirewallFilter $firewall_rule = null) {
// Check if we have a valid rule. If not create a new blank one and associate our account id
$firewall_rule = $firewall_rule ?: new Entities\GlobalFirewallFilter();
// Generate our form
$form = $this->createForm(new SAForms\GlobalFirewallRuleType(), $firewall_rule);
$form->handleRequest($request);
if($form->isValid()) {
// Save our firewall rule
$em = $this->getDoctrine()->getManager();
$em->persist($firewall_rule);
$em->flush();
return $this->redirect($this->generateUrl('_dashboard__global_firewall'));
}
return array(
'title' => $firewall_rule->getFirewallFilterId() ? 'Edit Rule' : 'New Rule',
'form' => $form->createView(),
);
}
P.S. Sadly I can't comment yet.. Can you provide controller actions where you use this function?

I want to upload a profile picture with symfony2 and doctrine

In User.php (Entity name is User), I have a field in User entity named userPic , type String
In file UserType.php I mention userPic as shown below :
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('userFullname')
->add('userName')
->add('userEmail')
->add('userPassword')
->add('userPic', 'file', array ('label'=>'profile Picture'))
->add('gender','choice',array('choices' => array('m' => 'Male', 'f' => 'Female')))
->add('isActive')
;
}
Now in the controller I'm getting the form fields as shown below
/**
* Creates a new User entity.
*
*/
public function createAction(Request $request)
{
$entity = new User();
$form = $this->createCreateForm($entity);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('user_show', array('id' => $entity->getId())));
}
return $this->render('MWANRegisterBundle:User:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
Where do I have to give the path in which I want to save the picture? How can I save the uploaded file in my desired directory and save directory path in database?
Christian's answer is valid, however I'd just like to point out more specificaly how to do what is asked. Simply do :
if ($form->isValid()) {
$file = $form->getData()['file'];
$file->move('/your/path/to/your/file', 'yourFileName');
// Do the rest
...
}
Hope this helps.
You need to create an upload method in your entity. Check this link for more details http://symfony.com/doc/current/cookbook/doctrine/file_uploads.html
public function uploadFile()
{
// the file property can be empty if the field is not required
if (null === $this->getFile()) {
return;
}
// use the original file name here but you should
// sanitize it at least to avoid any security issues
// move takes the target directory and then the
// target filename to move to
$this->getFile()->move($this->getUploadDir(), $this->getFile()->getClientOriginalName());
// set the path property to the filename where you've saved the file
$this->path = $this->getFile()->getClientOriginalName();
// clean up the file property as you won't need it anymore
$this->file = null;
}
/**
* Creates a new User entity.
*
*/
public function createAction(Request $request)
{
$entity = new User();
$form = $this->createCreateForm($entity);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
// Upload file
$entity->uploadFile();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('user_show', array('id' => $entity->getId())));
}
return $this->render('MWANRegisterBundle:User:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}

Categories