I currently have a script in Symfony where I generate a form in a controller. This form shows the content of the Entity "Page". If the user edits the form, and submits it, the form adjusts the corresponding data in the database.
/**
* Webpage allowing user to edit a page and her attributes
*
* #Route("/edit")
*/
public function editAction(Request $request)
{
/*
* Get an array of all the current pages stored in the database.
*
* foreach loop through each website and create a seperate form for them
*
*/
$em = $this->getDoctrine()->getManager();
$pages = $em->getRepository(Page::class)->findAll();
foreach ($pages as $page) {
$editform= $this->createFormBuilder($page)
->add('name', 'text')
->add('location', 'url')
->add('displayTime', 'integer')
->add('save', 'submit', array(
'label' => 'Edit page'
))
->getForm();
$editform->handleRequest($request);
if ($editform->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->flush();
return new Response('Page edited successfully - immediately effective');
}
}
return $this->render('WalldisplayBundle:Walldisplay:edit.html.twig',
array(
'editform' => $editform->createView()
));
}
Unfortunately, this only prints a form with the last entry in the database. What I'd like is to have a form created for -every- entry in the database, not just the last one. I've tried iterating through the Doctrine repository, no luck however. How could I solve this problem?
Maybe it will work. I have not tested.
/**
* Webpage allowing user to edit a page and her attributes
*
* #Route("/edit")
*/
public function editAction(Request $request)
{
/*
* Get an array of all the current pages stored in the database.
*
* foreach loop through each website and create a seperate form for them
*
*/
$em = $this->getDoctrine()->getManager();
$pages = $em->getRepository(Page::class)->findAll();
foreach ($pages as $key=>$page) {
$editforms[$key] = $this->createFormBuilder($page)
->add('name', 'text')
->add('location', 'url')
->add('displayTime', 'integer')
->add('save', 'submit', array(
'label' => 'Edit page'
))
->getForm();
foreach($editforms as $editform){
$editform->handleRequest($request);
if ($editform->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->flush();
}
}
return new Response('Page edited successfully - immediately effective');
}
foreach($editforms as $editform){
$editform->handleRequest($request);
if ($editform->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->flush();
}
foreach($editforms as $editform){
$arrayForm[$editform] = $editform->createView();
}
return $this->render('WalldisplayBundle:Walldisplay:edit.html.twig', $arrayForm);
}
Related
Thanks in advance to those who want to help me. I'm learning symfony 4 and I'm testing to see how to update a database by taking data from a form. So I made sure that it looked for a table on the base of the id and that it filled the form with the correct values of the form. But when I submit, the form-> isSubmitted condition is never verified. Do you have any suggestions?
public function updateArticle(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$article = $em->getRepository(Article::class)->find($id);
if (!$article) {
throw $this->createNotFoundException(
'No article found for id '.$id
);
}
$articletext = $article->getArticle();
$title = $article->getTitle();
$image = $article->getFeatureimage();
$category = $article->getCategory();
$author = $article->getAuthor();
$article->setArticle($articletext);
$article->setTitle($title);
$article->setFeatureimage($image);
$article->setCategory($category);
$article->setAuthor($author);
$form = $this->createFormBuilder($article)
->add('article', TextareaType::class)
->add('title', TextType::class)
->add('featureimage', FileType::class, array('data_class' => null,'required' => true))
->add('category', TextType::class)
->add('author', TextType::class)
->add('save', SubmitType::class, array('label' => 'Inserisci articolo'))
->getForm();
if ($form->isSubmitted()) {
$article = $form->getData();
print_r($article);
return $this->redirectToRoute('blog');
}
else
return $this->render('insert.html.twig', array(
'form' => $form->createView(),
));
}
Your forgot a line that handle the data.
Look at the doc
Add this line before the if condition:
//form creation as you did but it's better to construct the form via the FormType
$form->handleRequest($request);
if ($form->isSubmitted()){
//Do some stuff
I have a controller action that returns a form to the view. When the form is submitted, the validation of this form needs to be done in a different action than the action returning the form.
This is a sample of the action that returns the form
/**
* #Route("/AjaxAddQuestionForm/{section}")
* #Template
* #ParamConverter("section", class="AppBundle:Section")
*/
public function ajaxAddQuestionFormAction(Request $request, $section)
{
$question = new Question();
$question->setSection($section);
$addQuestionForm = $this->createForm(new AddQuestionType(), $question);
return array(
'section' => $section,
'addAjaxQuestionForm' => $addQuestionForm->createView(),
);
}
And this is the action in which I am currently trying to get the validation to work.
/**
* #Route("/edit/{form}")
* #Template()
* #ParamConverter("form", class="AppBundle:Form")
*/
public function editAction(Request $request, $form)
{
$em = $this->getDoctrine()->getManager();
(...)
$questionForm = new Question();
$addQuestionForm = $this->createForm(new AddQuestionType(), $questionForm);
$addQuestionForm->handleRequest($request);
if ($addQuestionForm->isValid()) {
$em->persist($questionForm);
$em->flush();
return $this->redirectToRoute('app_form_edit', array('form' => $form_id));
}
(...)
The problem is that the validation in the second action is never called. Any idea on how I can get this working?
You should add form action if you want validate form on other url:
In ajaxAddQuestionFormAction:
$addQuestionForm = $this->createForm(new AddQuestionType(), $question,
array(
'action' => $this->generateUrl('edit_form')
));
edit action route:
*#Route("/edit", name="edit_form")
I have a controller action with a couple of forms. One form is for adding a question entity and the other form is for editing an existing question. This is a part of the action
/**
* #Route("/edit/{form}")
* #Template()
* #ParamConverter("form", class="AppBundle:Form")
*/
public function editAction(Request $request, $form)
{
$questionForm = new Question();
$addQuestionForm = $this->createForm(new AddQuestionType(), $questionForm);
$addQuestionForm->handleRequest($request);
if ($addQuestionForm->isValid()) {
dump('Wrong form');
die();
$em->persist($questionForm);
$em->flush();
return $this->redirectToRoute('app_form_edit', array('form' => $form_id));
}
$editQuestion = new Question();
$editAjaxQuestionForm = $this->createForm(new AddQuestionType(), $editQuestion);
$editAjaxQuestionForm->handleRequest($request);
if ($editAjaxQuestionForm->isValid()) {
dump('Correct form');
die();
$em->persist($editQuestion);
$em->flush();
return $this->redirectToRoute('app_form_edit', array('form' => $form_id));
}
I added the dump() and die() for debugging because the editAjaxQuestionForm was not working properly. Then I noticed that when I submit the editAjaxQuestionForm, the dump('Wrong form') is shown. So the form goes through the wrong validation.
The forms are created after an Ajax call. This is the code
/**
* #Route("/AjaxAddQuestionForm/{section}")
* #Template
* #ParamConverter("section", class="AppBundle:Section")
*/
public function ajaxAddQuestionFormAction(Request $request, $section)
{
$question = new Question();
$question->setSection($section);
$addQuestionForm = $this->createForm(new AddQuestionType(), $question);
return array(
'section' => $section,
'addAjaxQuestionForm' => $addQuestionForm->createView(),
);
}
/**
* #Route("/AjaxEditQuestionForm/{question}")
* #Template
* #ParamConverter("question", class="AppBundle:Question")
*/
public function ajaxEditQuestionFormAction(Request $request, $question)
{
$editQuestionForm = $this->createForm(new AddQuestionType(), $question);
return array(
'question' => $question,
'editAjaxQuestionForm' => $editQuestionForm->createView(),
);
}
I think I've tried everything but I can't figure out what is wrong.
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(),
));
}
I am working on a job portal's site built in Symfony 2.1. I have implemented ewz/EWZSearchBundle for job search process which is as given below:
/**
* Displays a form to create a new Job entity.
*
* #Route("/new", name="job_new")
* #Template("JobBundle:Job:new.html.twig")
*/
public function newAction(Request $request)
{
$entity = new Job();
$form = $this->createForm(new JobType(), $entity);
if('POST'===$request->getMethod()){
$form->bind($request);
if ($form->isValid()) {
$entity->setOwner($this->getEmployer());
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
$location = $entity->getLocation();
$loName = array();
foreach ($location as $key => $loc) {
$loName[] = $loc->getName();
}
$industry = $entity->getIndustry();
$inName = array();
foreach ($industry as $key => $ind) {
$inName[] = $ind->getTitle();
}
$skills = $entity->getSkills();
$skillName = array();
foreach ($skills as $key => $skl) {
$skillName[] = $skl->getTitle();
}
$education = $entity->getEducation();
$educationName = array();
foreach ($education as $key => $edu) {
$educationName[] = $edu->getTitle();
}
$search = $this->get('ewz_search.lucene');
$document = new Document();
$document->addField(Field::keyword('key', $entity->getId()));
$document->addField(Field::text('title', $entity->getTitle()));
$document->addField(Field::text('url', $this->generateUrl('job_show', array('slug' => $entity->getSlug()))));
$document->addField(Field::unstored('body', $entity->getDescription()));
$document->addField(Field::text('location', implode(" ", $loName)));
$document->addField(Field::text('industry', implode(" ", $inName)));
$document->addField(Field::text('skills', implode(" ", $skillName)));
$document->addField(Field::text('education', implode(" ", $educationName)));
$search->addDocument($document);
$search->updateIndex();
return $this->redirect($this->generateUrl('job_show', array('slug' => $entity->getSlug())));
}
}
return array(
'entity' => $entity,
'form' => $form->createView(),
);
}
It is working very fine when a candidate is searching jobs by any of following fields: location, industry, skills or education. But there are two issues of mine:
In this process for every field (locations, skills, industry or education) only one job search is applicable while I want separate search forms, for example in location-wise search, only location field is matched not the other remaining fields.
The second problem is when an employer deletes his job, the indexes of deleted jobs are also shown in the search process while after the job was deleted, the index of the deleted job should also be deleted from search index.
I have tried to delete the search index on the time of job_delete action by following code:
/**
* Deletes a Job entity
* #Route("/{slug}/delete", name="job_delete")
* #Method("POST")
*/
public function deleteAction(Request $request, $slug)
{
$em = $this->getDoctrine()->getManager();
$entity = $em->getRepository('JobBundle:Job')
->findOneBy(array('slug' => $slug));
if (!$entity) {
throw $this->createNotFoundException('Unable to find Job entity.');
}
$form = $this->createDeleteForm($entity->getSlug());
$form->bind($request);
if ($form->isValid()) {
$this->checkOwnerSecurity($entity);
$em->remove($entity);
$em->flush();
$search = $this->get('ewz_search.lucene');
$index = $search->getIndex();
$removePath = 'http://localhost/Jobtook/web/app_dev.php/employer/job/{slug}/delete';
$hits = $index->find('job_delete' . $removePath);
foreach ($hits as $hit) {
$index->delete($hit->id);
}
}
return $this->redirect($this->generateUrl('job'));
}
private function createDeleteForm($slug)
{
return $this->createFormBuilder(array('slug' => $slug))
->add('slug', 'hidden')
->getForm()
;
}
But by this code when I create many jobs and delete only one job, then all jobs are deleted from the search index even remaining jobs, that still exist in database. I don't know what I am doing wrong.