Symfony2 How to process dynamic embed forms collection? - php

I try this cookbook about embed form:
http://symfony.com/doc/current/cookbook/form/form_collections.html
But the embed foreign key (task_id field in Tag table) is not save, always NULL
Here the complete code: https://gist.github.com/1755140
Do you know why?
Thank
Edit::
My trouble was in process form action. Like the tag form is embed dynamically, so i don't know how many tag(s) i will have. If i add in createAction
$tag1 = new Tag();
$task->addTags($tag1);
only the first embed form was correctly save! How to save the other tags?
public function createAction(Request $request)
{
$task = new Task();
$tag1 = new Tag();
$task->addTags($tag1);
$form = $this->createForm(new TaskType(), $task);
$form->bindRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getEntityManager();
$em->persist($task);
$em->flush();
return $this->redirect($this->generateUrl('new_task', array('id' => $task->getId())));
}
return array(
'form' => $form->createView()
);
}
Edit2:
My solution which resolve the trouble, what do you think about it? Better?
public function createAction(Request $request)
{
$task = new Task();
$tasks = $request->request->get('task', array());
if (isset($tasks['tags'])) {
$tags = $tasks['tags'];
foreach($tags as $tag) {
$tag = new Tag();
$task->addTags($tag);
}
}
$form = $this->createForm(new TaskType(), $task);
$form->bindRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getEntityManager();
$em->persist($task);
$em->flush();
return $this->redirect($this->generateUrl('new_task', array('id' => $task->getId())));
}
return array(
'form' => $form->createView()
);
}
Edit3:
A much better alternative (not tested again)
http://www.siteduzero.com/tutoriel-3-523899-creer-des-formulaires-avec-symfony2.html#ss_part_2
public function createAction(Request $request)
{
$task = new Task();
$form = $this->createForm(new TaskType(), $task);
$form->bindRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getEntityManager();
$em->persist($task);
foreach($task->getTags() as $tag) {
$em->persist($tag);
}
$em->flush();
return $this->redirect($this->generateUrl('new_task', array('id' => $task->getId())));
}
return array(
'form' => $form->createView()
);
}

In TaskController on line 29 try to use $task->addTags($tag1); instead of $task->getTags()->add($tag1);

I don't understand. Is this solution wrong?
if ($form->isValid()) {
$em = $this->getDoctrine()->getEntityManager();
foreach($task->getTags() as $tag) {
$tag->setTask($task);
}
$em->persist($task);
$em->flush();
return $this->redirect($this->generateUrl('new_task', array('id' => $task->getId())));
}
It works and it seems simpler.

Related

How Can I specified the object of my precedent form?

In my project I want to use the object created by my precedent form:
Here is the schema of my database:
My QuizController
public function creation(Request $request){
$quiz = new Quiz();
$user = $this->getUser();
$formQuiz = $this->createForm(QuizType::class, $quiz);
$formQuiz->handleRequest($request);
if ($formQuiz->isSubmitted() && $formQuiz->isValid() ) {
$quiz->setCreatedAt(new DateTimeImmutable());
$quiz->setCreatedBy($user);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($quiz);
$entityManager->flush();
return $this->redirectToRoute('creation_questions');
}
return $this->render('quiz/creation.html.twig', [
'formQuiz' => $formQuiz->createView(),
]);
}
And my QuestionController that must be connected with the quiz form
public function creation_questions(Request $request){
$quiz = ?
$question = new Questions();
$formQuestions = $this->createForm(QuestionType::class, $question);
$formQuestions->handleRequest($request);
if ($formQuestions->isSubmitted() && $formQuestions->isValid() ) {
$question->setCreatedAt(new DateTimeImmutable());
$question->setQuiz($quiz);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($question);
$entityManager->flush();
return $this->redirectToRoute('home');
}
return $this->render('questions/questions.html.twig', [
'formQuestion' => $formQuestions->createView()
]);
}
What do I have to write in place of the '?'?
You don't show your routing but you could use paramConverte "magic" from SensioFrameworkExtraBundle and do something like this.
/**
* #Route("/some-route/{id}", name="some_route_name")
*/
public function creation_questions(Request $request, Quiz $quiz)
{
$question = new Questions();
$formQuestions = $this->createForm(QuestionType::class, $question);
$formQuestions->handleRequest($request);
if ($formQuestions->isSubmitted() && $formQuestions->isValid()) {
$question->setCreatedAt(new DateTimeImmutable());
$question->setQuiz($quiz);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($question);
$entityManager->flush();
return $this->redirectToRoute('home');
}
return $this->render('questions/questions.html.twig', [
'formQuestion' => $formQuestions->createView()
]);
}
Where the {id} part of /someRoute/{id} is the Quiz Id. Symfony should automagically fetch the Quiz matching that id. Or you can be more explicit about how the param converter should interpret such a value. More info here https://symfony.com/bundles/SensioFrameworkExtraBundle/current/annotations/converters.html
Alternatively, you could pass the quiz id and fetch the quiz manually (less magic but totally legit).
/**
* #Route("/some-route/{id}", name="some_route_name")
*/
public function creation_questions(Request $request, int $id)
{
$entityManager = $this->getDoctrine()->getManager();
$quiz = $entityManager->getRepository(Quiz::class)->find($id);
$question = new Questions();
$formQuestions = $this->createForm(QuestionType::class, $question);
$formQuestions->handleRequest($request);
if ($formQuestions->isSubmitted() && $formQuestions->isValid()) {
$question->setCreatedAt(new DateTimeImmutable());
$question->setQuiz($quiz);
$entityManager->persist($question);
$entityManager->flush();
return $this->redirectToRoute('home');
}
return $this->render('questions/questions.html.twig', [
'formQuestion' => $formQuestions->createView()
]);
}

How make two form in same controller [Symfony]

I have a probleme, i want two forms in same controller
I have this controller with two forms, but the probleme is the form1 work good ( return new response) but form2 not working ..
what the solution?
public function fCandidat($id, Request $request)
{
$candidat = $this->getDoctrine()
->getRepository(Candidat::class)
->find($id);
$form = $this->createForm(CandidatType::class, $candidat);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
return new Response('form1');
}
$defaultData = ['message' => 'Demandes candidats'];
$form2 = $this->createFormBuilder($defaultData)
->add('demandes', DemandeType::class)
->add('send', SubmitType::class)
->getForm();
$form2->handleRequest($request);
if ($form2->isSubmitted() && $form2->isValid()) {
return new Response('form2');
return $this->render('index.html.twig', ['form' => $form->createView(), 'form2' => $form2->createView()]);
}
}

Symfony2: Inserting a collection of files

While trying to insert a collection of entities which have a file field, i couldn't figure out if there's is a better way to create the UploadedFile Object being cast by the Document::document annotation. Here's my code, any help on improving it is very appreciated :)
public function createAction(Request $request) {
$em = $this->getDoctrine()->getManager();
$user = $this->get('security.context')->getToken()->getUser();
$entity = new Paper();
$form = $this->createCreateForm($entity);
$form->handleRequest($request);
if ($form->isValid()) {
$entity->setAuthor($user);
$em->persist($entity);
// chotest foreach in the universe
if (isset($_FILES) && array_key_exists('arkad1a_cfpbundle_paper', $_FILES)) {
foreach ($_FILES['arkad1a_cfpbundle_paper']['name']['documents'] as $k => $v) {
$document = new UploadedFile(
$_FILES['arkad1a_cfpbundle_paper']['tmp_name']['documents'][$k]['document'],
$_FILES['arkad1a_cfpbundle_paper']['name']['documents'][$k]['document'],
$_FILES['arkad1a_cfpbundle_paper']['type']['documents'][$k]['document'],
$_FILES['arkad1a_cfpbundle_paper']['size']['documents'][$k]['document'],
$_FILES['arkad1a_cfpbundle_paper']['error']['documents'][$k]['document'],
false
);
$Document = new \Arkad1a\CFPBundle\Entity\Document();
$Document->setAuthor($user)
->setDocument($document)
->setPaper($entity)
->upload();
$em->persist($Document);
}
}
$em->flush();
return $this->redirect($this->generateUrl('paper_show', array('id' => $entity->getId())));
} else {
die('invalid');
}
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}

How to do edit function in symfony2

I have written a function for edit in symfony2, my problem is i can fetch the previous values from the database but after submitting the form the values were notr created instead a new form is creating
Here is the controller
public function editAction($id){
$request = $this->getRequest();
$em = $this->getDoctrine()->getEntityManager();
$profile= $em->getRepository('TcprofileBundle:TcProfiles')
->find($id);
$profile_form = $this->createForm(new ProfileType(), $profile);
$response = new JsonResponse();
$response->setData(array('content' => $this->renderView('TcprofileBundle:Default:create.html.twig',array('form' => $profile_form->createView()))));
return $response;
}
Html.twig file
<div class="edit01"> Edit Profile </div>
I'm fetching the old values, so i put if loop for condition check like this
controller
public function editAction($id){
$request = $this->getRequest();
$em = $this->getDoctrine()->getEntityManager();
$profile= $em->getRepository('TcprofileBundle:TcProfiles')
->find($id);
if(!$id){
$profile_form = $this->createForm(new ProfileType(), $profile);
$response = new JsonResponse();
$response->setData(array('content' => $this->renderView('TcprofileBundle:Default:create.html.twig',array('form' => $profile_form->createView()))));
return $response;
}else{
$profile->upload();
$em->persist($profile);
$em->flush();
$response = new JsonResponse();
$response->setData(array('content' => $this->renderView('TcprofileBundle:Default:create.html.twig',array('form' => $profile_form->createView()))));
return $response;
}
}
Its not getting output Pls help me if i gone wrong somewhere
You can use $em->merge($profile) instead of $em->persist($profile) when updating an entity. Please this stack overflow post

Var filled with object suddenly null, what happened?

I am building this form in symfony 2.0 and for some reason when I retrieve a object from the db and put it into an object it is gone when I want to save it so I get the following error:
Catchable Fatal Error: Argument 1 passed to MelvinLoos\CMS\CoreBundle\Entity\Page::setParent()
must be an instance of MelvinLoos\CMS\CoreBundle\Entity\Page, null given,
called in vendor\symfony\src\Symfony\Component\Form\Util\PropertyPath.php on line 347
and defined in src\MelvinLoos\CMS\CoreBundle\Entity\Page.php line 233
My code:
public function popupChildAction($parentid)
{
$entity = new Page();
$entity->setWebsite($this->getWebsite());
$parent = $this->getDoctrine()
->getRepository('MelvinLoosCMSCoreBundle:Page')
->findOneById($parentid);
if (!$parent)
{
throw $this->createNotFoundException('No parent found with given id: "' . $parentid . '"');
}
$entity->setParent($parent);
$entity->setCreatedBy($this->getUser());
//$entity->setPageType();
$form = $this->createForm(new PageChildType(), $entity);
$request = $this->getRequest();
$form->bindRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getEntityManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('page_show', array('id' => $entity->getId())));
}
return $this->render('MelvinLoosCMSCoreBundle:Page:new_popup.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
'parent' => $parent
));
}
As you can see I put in a if statement to check if $parent is filled and I also tried a var_dump to double check, it is defiantly filled with an object. But for some reason when I call the setParent() function of the entity object it fills it with null.
Melvin you have the check if the form is submitted and to get your entity from the form.
Can you try like this?
$form = $this->createForm(new PageChildType(), $entity);
$request = $this->getRequest();
if ($request->getMethod() == 'POST') {
$form->bindRequest($request);
if ($form->isValid()) {
$entity = $form->getData();
$em = $this->getDoctrine()->getEntityManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('page_show', array('id' => $entity->getId())));
}
}
Totally forgot that I had this question still floating around... Anyway I got around my problem, still don't know why I got the error but I solved it with quite a easy solution.
Instead of setting the parent for the child, I did the reverse and set the child for the parent. My code is the following (There is also new code in there that's irrelevant because I fixed it some time ago).
public function popupChildAction($parentid)
{
$parent = $this->getDoctrine()
->getRepository('MelvinLoosCMSCoreBundle:Page')
->findOneById($parentid);
if (!$parent)
{
throw $this->createNotFoundException('No parent found with given id: "' . $parentid . '"');
}
$entity = new Page();
$entity->setWebsite($this->getWebsite());
$entity->setCreatedBy($this->getUser());
$form = $this->createForm(new PageChildType(), $entity);
$request = $this->getRequest();
$form->bindRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getEntityManager();
$parent->setChildren($entity);
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('page_show', array('id' => $entity->getId())));
}
return $this->render('MelvinLoosCMSCoreBundle:Page:new_popup.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
'parent' => $parent
));
}
Like I said there is newer code that is irrelevant but what it's all about is the part with
$parent->setChildren($entity); and now it works... hope this helps someone!
Thanks for everyone that gave input!

Categories