Entity not found on Symfony 2 form - php

I generated with the smyfony2 cli tool a CRUD for a entity. Now i want to use the edit function from the CRUD.
First, the code
/**
* Displays a form to edit an existing Poi entity.
*
* #Route("/poi/{id}/edit", name="poi_edit", requirements={"id" = "\d+"})
* #Method("GET")
* #Template()
*/
public function editAction($id){
$em = $this->getDoctrine()->getManager('default')->getRepository('Project\Bundle\ProjectBundle\Entity\Poi');
$entity = $em->find($id);
if (!$entity) {
throw $this->createNotFoundException('Unable to find Poi entity.');
}
$editForm = $this->createEditForm($entity);
return array(
'entity' => $entity,
'edit_form' => $editForm->createView()
);
}
/**
* Creates a form to edit a Poi entity.
*
* #param Poi $entity The entity
*
* #return \Symfony\Component\Form\Form The form
*/
private function createEditForm(Poi $entity)
{
$form = $this->createForm(new PoiType(), $entity, array(
'action' => $this->generateUrl('poi_update', array('id' => $entity->getId())),
'method' => 'PUT',
));
$form->add('submit', 'submit', array('label' => 'Update'));
return $form;
}
But i receive a "Entity not found" error. Of course i first of all i thought about the throw of the NotFoundException, so i commented it out, but still i get the error.
Then i debugged the code and the entity will be found. It's also existing in the database.
I debugged further and found out that the error is thrown somewhere in the Symfony2 Form stack which generates the form, which is called in the createEditForm action.
Do i clearly miss something? What is my error?
My Symfony2 dev log also just says that a NotFoundException was thrown, no further information there to be found.
I have another entity with a generated CRUD, but there i build the form in the createEditForm by myself because of certain fields that shouldn't be displayed. Do i need to create the form by myself or am i doing something obviously wrong?
Also the PoiType code
class PoiType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name')
->add('date')
->add('situation')
->add('description')
->add('isPrivate')
->add('image')
->add('audio')
->add('country')
->add('category')
;
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Project\Bundle\ProjectBundle\Entity\Poi'
));
}
/**
* #return string
*/
public function getName()
{
return 'project_bundle_projectbundle_poi';
}
}
This is the Error i get:
CRITICAL - Uncaught PHP Exception Doctrine\ORM\EntityNotFoundException: "Entity was not found." at /var/www/project-symfony/vendor/doctrine/orm/lib/Doctrine/ORM/Proxy/ProxyFactory.php line 177

Try adding a backslash prefix to your data_class in your FormType as such:
'data_class' => '\Project\Bundle\ProjectBundle\Entity\Poi',
Thanks for this post.

Related

Symfony: How to upload multiple files

I'm pretty new to Symfony and I'm trying to upload multiple files (images) using Symfony Forms and the Vichuploader-Bundle.
My TestObjectType looks like this, which should hold a collection of Image objects:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('images', CollectionType::class, array(
'entry_type' => new ImageFormType(),
));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => TestObject::class
));
}
ImageFormType:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('imageFile', VichImageType::class, array(
'required' => false,
));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => Image::class
));
}
Part of the controller code:
public function newAction(Request $request)
$form = $this->createForm(TestObjectType::class, $testObject);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($testObject);
$em->flush();
return $this->redirectToRoute("home");
}
}
I get the following error while submitting:
Neither the property "imageFile" nor one of the methods "getImageFile()", "imageFile()", "isImageFile()", "hasImageFile()", "__get()" exist and have public access in class "TestBundle\Entity\TestObject".
My TestObject does not have an imageFile property, however my Image object does. So what is missing here? Why is the imageFile property of the Image object not used? I've already read How to Upload Files and CollectionType Field but it did not helped much.
EDIT
Maybe a snippet of my entities could be useful:
TestObject
/**
* #ORM\OneToMany(targetEntity="TestBundle\Entity\Image", mappedBy="testObject")
*/
private $images;
Image
/**
* NOTE: This is not a mapped field of entity metadata, just a simple property.
*
* #Vich\UploadableField(mapping="product_image", fileNameProperty="imageName")
*
* #var File|\Symfony\Component\HttpFoundation\File\UploadedFile $image
*/
private $imageFile;
/**
* #ORM\Column(type="string", length=255)
*
* #var string
*/
private $imageName;
/**
* #ORM\ManyToOne(targetEntity="TestBundle\Entity\TestObject", inversedBy="images")
* #ORM\JoinColumn(name="test_object_id", referencedColumnName="id")
*/
private $testObject;
I think I found the solution: Symfony`s cache make me angry! A simple
php app/console cache:clear
did the trick! Argh, that took me hours!

Different type expected in Symfony

I am trying to create a form using Symfony and Doctrine.
I created a Job class, and a table in mysql which relates to it, using Doctrine. It also made the JobType and JobController, and Routing facility.
I can access the index page, where the jobs are listed, but can't access the new entry page.
Here are the files used for creating the forms.
JobController.php
<?php
namespace AppBundle\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use AppBundle\Entity\Job;
use AppBundle\Form\JobType;
/**
* Job controller.
*
* #Route("/job")
*/
class JobController extends Controller
{
/**
* Lists all Job entities.
*
* #Route("/", name="job_index")
* #Method("GET")
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$jobs = $em->getRepository('AppBundle:Job')->findAll();
return $this->render('job/index.html.twig', array(
'jobs' => $jobs,
));
}
/**
* Creates a new Job entity.
*
* #Route("/new", name="job_new")
* #Method({"GET", "POST"})
*/
public function newAction(Request $request)
{
$job = new Job();
$jobType = new JobType();
$form = $this->createForm($jobType, $job);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($job);
$em->flush();
return $this->redirectToRoute('job_show', array('id' => $job->getId()));
}
return $this->render('job/new.html.twig', array(
'job' => $job,
'form' => $form->createView(),
));
}
/**
* Finds and displays a Job entity.
*
* #Route("/{id}", name="job_show")
* #Method("GET")
*/
public function showAction(Job $job)
{
$deleteForm = $this->createDeleteForm($job);
return $this->render('job/show.html.twig', array(
'job' => $job,
'delete_form' => $deleteForm->createView(),
));
}
/**
* Displays a form to edit an existing Job entity.
*
* #Route("/{id}/edit", name="job_edit")
* #Method({"GET", "POST"})
*/
public function editAction(Request $request, Job $job)
{
$deleteForm = $this->createDeleteForm($job);
$editForm = $this->createForm(new JobType(), $job);
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($job);
$em->flush();
return $this->redirectToRoute('job_edit', array('id' => $job->getId()));
}
return $this->render('job/edit.html.twig', array(
'job' => $job,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}
/**
* Deletes a Job entity.
*
* #Route("/{id}", name="job_delete")
* #Method("DELETE")
*/
public function deleteAction(Request $request, Job $job)
{
$form = $this->createDeleteForm($job);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->remove($job);
$em->flush();
}
return $this->redirectToRoute('job_index');
}
/**
* Creates a form to delete a Job entity.
*
* #param Job $job The Job entity
*
* #return \Symfony\Component\Form\Form The form
*/
private function createDeleteForm(Job $job)
{
return $this->createFormBuilder()
->setAction($this->generateUrl('job_delete', array('id' => $job->getId())))
->setMethod('DELETE')
->getForm()
;
}
}
JobType.php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class JobType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('category', 'string')
->add('type', 'string')
->add('company', 'string')
->add('logo', 'string')
->add('url', 'string')
->add('position', 'string')
->add('location', 'string')
->add('desciption', 'text')
->add('how_to_apply', 'text')
->add('token', 'string')
->add('is_public', 'boolean')
->add('is_activated', 'boolean')
->add('email', 'string')
->add('expires_at', 'datetime')
->add('created_at', 'datetime')
->add('updated_at', 'datetime')
;
}
/**
* #param OptionsResolver $resolver
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Job'
));
}
/**
* Mandatory in Symfony2
* Gets the unique name of this form.
* #return string
*/
public function getName()
{
return 'add_job';
}
}
This is the error I receive
Thanks!
EDIT:
The content of app/config/services.yml
parameters:
# parameter_name: value
services:
# service_name:
# class: AppBundle\Directory\ClassName
# arguments: ["#another_service_name", "plain_value", "%parameter_name%"]
$editForm = $this->createForm(new JobType(), $job);
This is no longer possible in Symfony 3. In Symfony 3, you always have to pass the fully-qualified class name for form types:
$editForm = $this->createForm(JobType::class, $job);
Also, in your form type you're passing the type name instead of the FQCN of the type classes.
Symfony 3 has just released its first BETA, which means it's very bleeding edge. Also, there are almost zero tutorials for Symfony 3 yet (as it's so extremely bleeding edge). You're reading a Symfony 2 tutorial, so I recommend you to install Symfony 2 instead of 3.

Symfony ManyToMany in Form

I have entity developer and entity skill, skill have ManyToMany with Platforms, Language and Speciality and I need create form for developer, developer can selected skills and when selected some skill developer can selected Platforms, Language and Speciality for this skill. If developer selected two skill or more so have more Platforms, Language and Speciality for selected. And I don't know how this is create in Symfony. Now I create form only selected skills
class DeveloperProfessionalSkillsType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name');
$builder->add('skills','entity',
array(
'class'=>'Artel\ProfileBundle\Entity\Skill',
'property'=>'skill',
'multiple'=>true,
)
);
}
/**
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Artel\ProfileBundle\Entity\Developer',
'validation_groups' => array('professional_skills')
));
}
/**
* #return string
*/
public function getName()
{
return 'developer_professional_skills';
}
but now I have error form is not valid, interesting when I add 'expanded' => true, all work fine, but I don't need expanded I need simple selected field:
this is my entity
class Skill
{
/**
* #ORM\ManyToMany(targetEntity="Artel\ProfileBundle\Entity\Skill", mappedBy="skills", cascade={"persist"})
*/
protected $developers;
/**
* #var \Artel\ProfileBundle\Entity\CodeDirectoryProgramLanguages
*
* #ORM\ManyToMany(targetEntity="CodeDirectoryProgramLanguages", inversedBy="skills", cascade={"persist"})
*/
protected $language;
/**
* #var \Artel\ProfileBundle\Entity\CodeDirectoryPlatforms
*
* #ORM\ManyToMany(targetEntity="CodeDirectoryPlatforms", inversedBy="skills", cascade={"persist"})
*/
protected $platforms;
/**
* #var \Artel\ProfileBundle\Entity\CodeDirectorySpecialities
*
* #ORM\ManyToMany(targetEntity="CodeDirectorySpecialities", inversedBy="skills", cascade={"persist"})
*/
protected $specialities;
and my action
public function submitProfessionalSkillsAction($securitytoken)
{
$em = $this->getDoctrine()->getManager();
$form = $this->createForm(new DeveloperProfessionalSkillsType(), $user->getDeveloper());
$form->handleRequest($request);
if ($form->isValid()) {
$em->flush();
Recommend, please, how best to solve this problem
Instead of
$builder->add('skills','entity',
array(
'class'=>'Artel\ProfileBundle\Entity\Skill',
'property'=>'skill',
'multiple'=>true,
)
);
You can create new form and add it to your current form like this:
$builder->add('skills', new SkillsType()
);
And in new form you can define all your fields like:
$builder->add('language','entity',
array(
'class'=>'Artel\ProfileBundle\Entity\Language',
'property'=>'some_property',
'multiple'=>true,
)
);
if you need many skills you can use collection form type:
->add('skills', 'collection', array('type' => new SkillsType(),
'allow_add' => true,'by_reference' => false))

Symfony 2 Create a Entity in another Entiy Form

Hi I think there would be a very simple solution for this but I got a little bit stuck here.
I have two entities. An Author and a Poem. As expected one author can write a lot of poems but one poem can only have one author.
Now I have my poem form:
class PoemType extends AbstractType
{
/**
*
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm (FormBuilderInterface $builder, array $options)
{
$builder->add('title')
->add('authorId')
->add('text', 'textarea',
array(
'attr' => array(
'class' => 'tinymce'
)
)
);
}
/**
*
* #param OptionsResolverInterface $resolver
*/
public function setDefaultOptions (OptionsResolverInterface $resolver)
{
$resolver->setDefaults(
array(
'data_class' => 'Galerie\PictureBundle\Entity\Poem'
));
}
/**
*
* #return string
*/
public function getName ()
{
return 'galerie_picturebundle_poem';
}
}
So the user can choose an author for the poem. But I want the possibility that the user can add an author from here. So if he enters a new poem and the author doesn't exist he can add it here.
I already found this Allowing new tags with the prototype but in my case there is no collection.
Is this possible ?
thanks for your help in advance ;)
you can embed the author form in your poem form. see the documentation for details
http://symfony.com/doc/master/book/forms.html#embedded-forms

Symfony2 Form FormType Itself collection

I'm trying to create a symfony 2 form 'PersonType', which has a PersonType collection field that should map a given person's children.
And I'm getting this error,
{"message":"unable to save order","code":400,"errors":["This form should not contain extra fields."]}
Here is my Person entity,
class Person
{
private $id;
/**
* #ORM\OneToMany(targetEntity="Person", mappedBy="parent", cascade={"persist"})
*/
private $children;
/**
* #ORM\ManyToOne(targetEntity="Person", inversedBy="children")
* #ORM\JoinColumn(name="orderitem_id", referencedColumnName="id", nullable=true)
*/
private $parent;
}
And my Type,
class PersonType extends AbstractType
{
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('id')
->add('children', 'collection', array(
'type' => new PersonType()
))
;
}
UPDATE :
I've seen that the problem was because the option :
'allow_add' => true,
'by_reference' => false
wasn't in the Type, I've deleted it because when i insert them, the form don't appear and the page crash with no error.
I'm very confused because with this error, people can't have children :/
Does anyone already faced the same problem? (A formType nested over itself)
ACUTALLY :
I've duplicate my personType to PersonchildrenType to insert this last in the first...
I was having the same problem except that the error message was :
FatalErrorException: Error: Maximum function nesting level of 'MAX' reached, aborting!
Which is normal because "PersonType" is trying to build a form with a new "PersonType" field that is also trying to build a form with a new "PersonType" field and so on...
So the only way I managed to solve this problem, for the moment, is to proceed in two different steps :
Create the parent
Create a child and "link" it to the parent
You can simply do this in your controller
public function addAction(Person $parent=null){
$person = new Person();
$person->setParent($parent);
$request = $this->getRequest();
$form = $this->createForm(new PersonType(), $person);
if($this->getRequest()->getMethod() == 'POST'){
$form->bind($request);
if ($form->isValid()) {
// some code here
return $this->redirect($this->generateUrl('path_to_person_add', array(
'id' => $person->getId()
); //this redirect allows you to directly add a child to the new created person
}
}
//some code here
return $this->render('YourBundle::yourform.html.twig', array(
'form' => $form->createView()
));
}
I hope this can help you to solve your problem.
Tell me if you don't understand something or if I'm completly wrong ;)
Try to register your form as a service, like described here: http://symfony.com/doc/current/book/forms.html#defining-your-forms-as-services, and modify your form like this:
class PersonType extends AbstractType
{
public function getName()
{
return 'person_form';
}
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('id')
->add('children', 'collection', array(
'type' => 'person_form',
'allow_add' => true,
'by_reference' => false
))
;
}
}

Categories