Symfony2 bindRequset displaying property doesn't exist - php

I am new to Symfony and learning Symfony2 by creating a small project.
/** UserType buildform function */
$age_choices = array('18'=>'18+','25'=>'25+','30'=>'30+','40'=>'40+','50'=>'50+');
$complextion_choices = array('Moderate'=>'Moderate','Fair'=>'Fair');
$builder
->add('first_name', 'text')
->add('last_name', 'text')
->add('email', 'text')
->add('phone', 'text', array('required' => false))
->add('age', 'choice', array('choices' => $age_choices) )
->add('complextion', 'choice', array('choices' => $complextion_choices) );
/** Creating user form ***/**
$user = new Users();
$form = $this->createForm(new UsersType());
return $this->render('TrytillUserBundle:User:signup.html.twig', array('form' =>
$form->createView()));
Now When I submit this form.. getting it using following way.
$user = new Users();
$form = $this->createForm(new UsersType(), $user);
$form->bindRequest($request);
if ($form->isValid()) {
/// some task here.
}
return $this->render('TrytillUserBundle:User:signup.html.twig', array('form' => $form->createView()));
The problem is that on bindRequest line it saying me that property first_name doesn't exist in Entity Users.
I have created Users Entity using doctrine and it's private $firstName in Entity/Users.php
Thanks for any help.

Try ->add('firstName', 'text') instead of ->add('first_name', 'text') in your UserType::buildForm function, same goes for last_name.

Related

Passing data to buildForm() in Symfony 3.3

i'm trying to pass current authenticated user to buildForm for the pass couple of hours, i searched google ... nothing worked
the error i'm getting is
The form's view data is expected to be an instance of class AppBundle\Entity\AdsList, but is a(n) array. You can avoid this error by setting the "data_class" option to null or by adding a view transformer that transforms a(n) array to an instance of AppBundle\Entity\AdsList.
on ->getForm();
i have to ideea what to do ... a view transformer ... ( https://symfony.com/doc/current/form/data_transformers.html )
but i only have an integer ...
i also want to generate unique slugs from the content ( final version wont have a title field ) if you have a good example :)
thanks in advance :)
AgencyController.php
/**
* #Route("/agency/post", name="agency_post")
*/
public function agencyNewAd(Request $request)
{
// $agency = $this->get('security.token_storage')->getToken()->getUser(); ( this didn't worked .. )
$form = $this->createForm(AgencyNewAdType::class, array(
'postedBy' => $this->getUser(),
));
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$ad = $form->getData();
// save the task to the database
$em = $this->getDoctrine()->getManager();
$em->persist($ad);
$em->flush();
// return new Response('Saved new Post with id ' . $ad->getId());
return $this->redirectToRoute('agency_admin');
}
return $this->render('agency/new_ad.html.twig', [
'adForm' => $form->createView()
]);
}
AgencyNewAdType.php
class AgencyNewAdType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
// https://stackoverflow.com/questions/36905490/how-to-pass-parameter-to-formtype-constructor-from-controller
$builder
->add('title', TextType::class)
->add('content', TextareaType::class)
->add('category', EntityType::class, array(
// query choices from Category.Name
'class' => 'AppBundle:CategoryAd',
'choice_label' => 'name',
))
->add('postedAt', DateType::class)
->add('postedBy',HiddenType::class, array(
'data' => $options['postedBy']
))
->add('save', SubmitType::class, array('label' => 'Create Post'))
->getForm();
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'postedBy' => null,
'data_class' => 'AppBundle\Entity\AdsList',
));
}
}
i needed to pass the argument to the form so it would look like
public function agencyNewAd(Request $request): Response
{
$pass = new AdsList();
$pass->setPostedBy($this->getUser());
$form = $this->createForm(AgencyNewAdType::class, $pass);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// $form->getData() holds the submitted values iN MeM
$ad = $form->getData();
// save the ad to the database
$em = $this->getDoctrine()->getManager();
$em->persist($ad);
$em->flush();
// return new Response('Saved new Post with id ' . $ad->getId());
return $this->redirectToRoute('agency_admin');
}
return $this->render('agency/new_ad.html.twig', [
'adForm' => $form->createView()
]);
}
and in the form i need to remove postedBy ...
public function buildForm(FormBuilderInterface $builder, array $options)
{
// https://stackoverflow.com/questions/36905490/how-to-pass-parameter-to-formtype-constructor-from-controller
$builder
->add('title', TextType::class)
->add('content', TextareaType::class)
->add('category', EntityType::class, array(
// query choices from Category.Name
'class' => 'AppBundle:CategoryAd',
'choice_label' => 'name',
))
->add('postedAt', DateType::class)
->add('save', SubmitType::class, array('label' => 'Create Post'))
->getForm();
}
You missed a parameter when creating you from in a controller, 2nd parameter should be your object connected to the form and 3rd is the options array, so it would look like:
public function agencyNewAd(Request $request)
{
$ad = new AdsList();
$form = $this->createForm(AgencyNewAdType::class, $ad, array(
'postedBy' => $this->getUser(),
));
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($ad);
$em->flush();
return $this->redirectToRoute('agency_admin');
}
return $this->render('agency/new_ad.html.twig', [
'adForm' => $form->createView()
]);
}
The alternative way is to pass your option to the construct of your form like this:
public function agencyNewAd(Request $request)
{
$ad = new AdsList();
$form = $this->createForm(new AgencyNewAdType($this->getUser()), $ad);
and then in your constructor of AgencyNewAdType you would accept your parameter, in this case currently logged in user.

Username in current session

I want to add hidden field with username in current session. Username is in another entity called User. How to solve it?
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title', TextType::class, array('required' => false))
->add('description', TextareaType::class, array(
'required' => false,
'attr' => array('style' => 'resize: none')))
->add('imageFile', FileType::class);
}
public function addPhotoAction(Request $request)
{
$photo = new Photo();
$user = $this->getUser()->getId();
$form = $this->createForm(PhotoFormType::class, $photo);
$form->handleRequest($request);
if($form->isSubmitted() && $form->isValid()){
$em = $this->getDoctrine()->getManager();
$em->persist($photo);
$em->flush();
$this->addFlash('success', 'You\'ve shared a photo!');
return $this->redirectToRoute('homepage');
}
return $this->render('pages/addPhoto.html.twig', [
'photoForm' => $form->createView(),
'user' => $user
]);
}
How can I add userId to $builder? id(user table) must be in addedBy(photo table). I have to do a relation?
You can push the data to the form field. If you add a hidden field to form object it looks like these rows.
$form = $this->createForm(PhotoFormType::class, $photo);
$form->get('usernameField')->setData($this->getUser()->getUsername());

Form sending OneToMany to Database fails (Symfony2 / Doctrine)

I have a form that uploads a file and I am trying to "attach" the correct job id/entity to it, but it seems I don't fully understand the concept of table relations:
My File class
/**
* #ORM\ManyToOne(targetEntity="Job", inversedBy="file")
*/
protected $job;
My Job class:
/**
* #ORM\OneToMany(targetEntity="File", mappedBy="job")
*/
protected $file;
public function __construct()
{
$this->file = new ArrayCollection();
}
I am submitting the form and entering everything into a database:
$em = $this->getDoctrine()->getManager();
$file = new File();
$form = $this->createFormBuilder($file)
->add('file')
->add('job','text')
->add('save', 'submit', array('label' => 'Create Task'))
->getForm();
$form->handleRequest($request);
if ($form->isValid()) {
$job = $em->getRepository("AppBundle:Job")->find($form->getData()->getJob());
$file->setFile($form->getData()->getFile());
$file->setPath($form->getData()->getPath());
$file->setJob($job);
$em->persist($file);
$em->flush();
return $this->redirectToRoute("pendingJobs");
}
Submitting the form ends in a fatal error:
Catchable Fatal Error: Argument 1 passed to AppBundle\Entity\File::setJob() must be an instance of AppBundle\Entity\Job, string given, called in /var/www/html/web2gdv/vendor/symfony/symfony/src/Symfony/Component/PropertyAccess/PropertyAccessor.php on line 410 and defined
I tried debugging what was send with
if ($form->isValid()) {
dump($form->getData());
die();
}
but it does even get to the point?!
What am I doing wrong?
Any hint appreciated!
UPDATE
Thanks to #julien-bourdic I updated my form like this:
/**
* #Route("/job/pending", name="pendingJobs")
*/
public function jobAction(Request $request)
{
$this->denyAccessUnlessGranted('ROLE_ADMIN', null, 'Unable to access this page!');
$em = $this->getDoctrine()->getManager();
$file = new File();
$form = $this->createFormBuilder($file)
->add('file')
->add('job','entity',array(
'class' => 'AppBundle:Job',
'choice_label' => 'id',
))
->add('save', 'submit', array('label' => 'Create Task'))
->getForm();
$form->handleRequest($request);
if ($form->isValid()) {
$job = $em->getRepository("AppBundle:Job")->find($form->getData()->getJob());
$file->setFile($form->getData()->getFile());
$file->setPath($form->getData()->getPath());
$file->setJob($job);
$em->persist($file);
$em->flush();
return $this->redirectToRoute("pendingJobs");
}
$jobs = $em->getRepository("AppBundle:Job")->findBy(array(
'receipt' => true,
'receiptStatus' => true,
));
return $this->render(
'default/pending.html.twig',
array(
'jobs' => $jobs,
'form' => $form->createView(),
)
);
}
The whole purpose of this class is to have a table where the last button each row is an upload form. How can I populate multiple forms from one class, is that even possible? What yould I have to send to the renderfunction?
Try to explicitely define your field job in your form :
->add('job','entity',array(
'class'=>'AppBundle:Job',
'property'=>'id',
)
The problem is that find() returns array, not a Job. Use findOne().
$job = $em->getRepository("AppBundle:Job")->find($form->getData()->getJob());
// $job is and Array
do instead
$job = $em->getRepository("AppBundle:Job")->findOne($form->getData()->getJob());
// $job is Job
You have add('job', 'text') and must have a entity type, not text
First you need have a 'jobs' in the DB. Then you can change to
$form = $this->createFormBuilder($file)
->add('file')
->add('job','entity', array('class' => 'YourBundle:Job'))
->add('save', 'submit', array('label' => 'Create Task'))
->getForm();
or short
$form = $this->createFormBuilder($file)
->add('file')
->add('job')
->add('save', 'submit', array('label' => 'Create Task'))
->getForm();
you will receive select box on the job-field

Symfony 2.3 handleRequest($request) doesn't set entity

I have contact Entity, making post call using:
postContactAction(Request $request)
Generated form using app/console generate:doctrine:form BundleName:Contact
In post function trying to get request and set entity to request parameters like name, email and etc:
$contact = new Contact();
$form = $this->createForm(new ContactType(), $contact, array(
'method' => 'POST'));
$form->handleRequest($request);
And while checking, var_dump($contact); returns fields with null value.
What can be the problem?
Using postman to send post request and it worked without form.
In ContactType:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', 'text')
->add('email', 'text', array('required' => false))
->add('phone', 'integer', array('required' => false))
->add('text', 'textarea')
->add('subject', 'text')
->add('createdAt', 'datetime', array('required' => false))
;
}
In ContactController:
public function postContactAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$this->initErrorContainer();
$validator = $this->get('validator');
$contactDetails = $this->getRequest()->request->all();
// check if email and phone exists or not. One is enough
if (!array_key_exists('email', $contactDetails) && !array_key_exists('phone', $contactDetails)) {
$this->errorContainer->createAndAdd('email', $this->errorContainer->MESSAGE_REQUIRED);
$this->errorContainer->createAndAdd('phone', $this->errorContainer->MESSAGE_REQUIRED);
return $this->getView();
}
$contact = new Contact();
// handle form
$form = $this->createForm(new ContactType(), $contact, array(
'method' => 'POST'));
$form->handleRequest($request);
// set default values
var_dump($contact);
die;
Solved. As Entity uses different types than request, you need to create simply model of this entity, set request fields to that entity type using handleRequest, and then you can use it.
Is weird, but can you try to get the form after call createForm to see if that has something related, namely:
you have:
$form = $this->createForm(new ContactType(), $contact, array('method' => 'POST'));
Then just add:
$form = $this->createForm(new ContactType(), $contact, array('method' => 'POST'))->getForm();

Form page after Form page

I am having a problem in my symfony 2 project regarding the use of form (forms without classes). The idea is to develop a sequence of forms (each one in an independent page). Similar to multistep form or wizard but exactly not the same. In each form, partial sent results are saved and a new form is called.
Currently I have a controller with a form like this:
public function form1Action(Request $request, $parameter){
//Get relevant data using the $parameter...
$defaultData = array('message' => 'Type your message here');
$formBuilder = $this->createFormBuilder($defaultData);
$formBuilder->add('sendreport', 'choice', array(
'choices' => array('yes' => 'Yes', 'no' => 'No'),
'expanded' => true,
'label' => 'You will receive a full report from administrator',
'multiple' => false,
));
$formBuilder->add('start', 'submit', array('label' => 'form.labels.start'));
$form = $formBuilder->getForm();
$form->handleRequest($request);
if ($request->getMethod() == 'POST') {
if ($form->isSubmitted() && $form->isValid()){
$data = $form->getData();
return $this->redirect($this->generateUrl('task_form2', array('data' => $data)));
}
return $this->render('MyBundle:Default:showform1.html.twig', array('ourform' => $form->createView()));
}
Then, the redirected page contains a new form with similar structure to the previous one:
public function form2Action(Request $request, $data){
$datasource = $data;
$defaultData = array('message' => 'Type your message here');
$formBuilder = $this->createFormBuilder($defaultData)
->add('name', 'text')
->add('email', 'text')
->add('message', 'textarea')
->add('send', 'submit');
$form = $formBuilder->getForm();
$form->handleRequest($request);
//WHY IS NOT SUBMMITED???
if ($request->getMethod() == 'POST') {
if ($form->isSubmitted() /*&& $form2->isValid()*/) {
$data2 = $form->getData();
$data = //$data = $data2 array + $datasource array...
return $this->redirect($this->generateUrl('task_form3'), array('data' => $data));
}
}
return $this->render('MyBundle:Default:showform2.html.twig', array('ourform' => $form->createView()));
}
But here is the problem, the second form called in 'task_form2' path is not submitted!¿?. When you press the send button nothing happens!.
Any idea?
What is the best way to do this? (I think it is simpler and I would not like to use multistep bundle or something like that).
Thank you in advance.

Categories