Symfony 2 | Form exception when modifying an object that has a file(picture) field

30,279

Solution 1

I solved the problem setting data_class to null as follows:

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
    ->add('title')
    ->add('picture', 'file', array('data_class' => null)
    );
}

Solution 2

I would recommend you to read the documentation of file upload with Symfony and Doctrine How to handle File Uploads with Doctrine and a strong recommendation to the part Lifecycle callbacks

In a brief you usually in the form use the 'file' variable (see documentation), you can put a different label through the options, then in your 'picture' field, you just store the name of the file, because when you need the src file you can just call getWebpath() method.

->add('file', 'file', array('label' => 'Post Picture' )
);

to call in your twig template

<img src="{{ asset(entity.webPath) }}" />

Solution 3

Please make below change in your PostType.php.

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
    ->add('title')
    ->add('picture', 'file', array(
            'data_class' => 'Symfony\Component\HttpFoundation\File\File',
            'property_path' => 'picture'
        )
    );
}
Share:
30,279

Related videos on Youtube

Reveclair
Author by

Reveclair

Updated on July 15, 2020

Comments

  • Reveclair
    Reveclair almost 4 years

    I'm using Symfony2. I have an entity Post that has a title and a picture field.

    My problem : Everything is fine when I create a post, I have my picture etc. But when I want to modify it, I have a problem with the "picture" field which is an uploaded file, Symfony wants a file type and it has a string (the path of the uploaded file) :

    The form's view data is expected to be an instance of class Symfony\Component\HttpFoundation\File\File, but is a(n) string. You can avoid this error by setting the "data_class" option to null or by adding a view transformer that transforms a(n) string to an instance of Symfony\Component\HttpFoundation\File\File. 
    

    I'm really stuck with this problem and really don't know how to solve it, any help would be greatly appreciated! Thanks a lot!

    Here is my PostType.php (which is used in newAction() and modifiyAction()) and which may cause the problem (Form/PostType.php) :

    <?php
    namespace MyBundle\Form;
    
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\HttpFoundation\File\UploadedFile;
    
    use MyBundle\Entity\Post;
    
    class PostType extends AbstractType
    {
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
            ->add('title')
            ->add('picture', 'file');//there is a problem here when I call the modifyAction() that calls the PostType file.
        }
    
        public function getDefaultOptions(array $options)
        {
            return array(
                'data_class' => 'MyBundle\Entity\Post',
            );
        }
    
        public static function processImage(UploadedFile $uploaded_file, Post $post)
        {
            $path = 'pictures/blog/';
            //getClientOriginalName() => Returns the original file name.
            $uploaded_file_info = pathinfo($uploaded_file->getClientOriginalName());
            $file_name =
                "post_" .
                $post->getTitle() .
                "." .
                $uploaded_file_info['extension']
                ;
    
            $uploaded_file->move($path, $file_name);
    
            return $file_name;
        }
    
        public function getName()
        {
            return 'form_post';
        }
    }
    

    Here is my Post entity (Entity/Post.php) :

    <?php
    
    namespace MyBundle\Entity;
    
    use Doctrine\ORM\Mapping as ORM;
    
    use Symfony\Component\Validator\Constraints as Assert;
    
    /**
     * MyBundle\Entity\Post
     *
     * @ORM\Table()
     * @ORM\Entity
     */
    class Post
    {
        /**
         * @var integer $id
         *
         * @ORM\Column(name="id", type="integer")
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        private $id;
    
        /**
         * @ORM\Column(type="string", length=255, nullable=true)
         * @Assert\Image(
         *      mimeTypesMessage = "Not valid.",
         *      maxSize = "5M",
         *      maxSizeMessage = "Too big."
         *      )
         */
        private $picture;
    
        /**
         * @var string $title
         *
         * @ORM\Column(name="title", type="string", length=255)
         */
        private $title;
    
       //getters and setters
       }
    

    Here is my newAction() (Controller/PostController.php) Every works fine with this function:

    public function newAction()
    {
        $em = $this->getDoctrine()->getEntityManager();
        $post = new Post();
        $form = $this->createForm(new PostType, $post);
        $post->setPicture("");
        $form->setData($post);
        if ($this->getRequest()->getMethod() == 'POST') 
        {
            $form->bindRequest($this->getRequest(), $post);
            if ($form->isValid()) 
            {
                $uploaded_file = $form['picture']->getData();
                if ($uploaded_file) 
                {
                    $picture = PostType::processImage($uploaded_file, $post);
                    $post->setPicture('pictures/blog/' . $picture);
                }
                $em->persist($post);
                $em->flush();
                $this->get('session')->setFlash('succes', 'Post added.');
    
                return $this->redirect($this->generateUrl('MyBundle_post_show', array('id' => $post->getId())));
            }
        }
    
        return $this->render('MyBundle:Post:new.html.twig', array('form' => $form->createView()));
    }
    

    Here is my modifyAction() (Controller/PostController.php) :There is a problem with this function

    public function modifyAction($id)
    {
        $em = $this->getDoctrine()->getEntityManager();
        $post = $em->getRepository('MyBundle:Post')->find($id);
        $form = $this->createForm(new PostType, $post);//THIS LINE CAUSES THE EXCEPTION
        if ($this->getRequest()->getMethod() == 'POST') 
        {
            $form->bindRequest($this->getRequest(), $post);
            if ($form->isValid()) 
            {
                $uploaded_file = $form['picture']->getData();
                if ($uploaded_file) 
                {
                    $picture = PostType::processImage($uploaded_file, $post);
                    $post->setPicture('pictures/blog/' . $picture);
                }
                $em->persist($post);
                $em->flush();
                $this->get('session')->setFlash('succes', 'Modifications saved.');
    
                return $this->redirect($this->generateUrl('MyBundle_post_show', array('id' => $post->getId())));
            }
        }
        return $this->render('MyBundle:Post:modify.html.twig', array('form' => $form->createView(), 'post' => $post));
    }
    
  • Jirilmon
    Jirilmon over 11 years
    Hi @Reveclaire please let me know if this helps. You can remove 'property_path' atrribute IF it gives some error. otherwise keep it.
  • Reveclair
    Reveclair over 11 years
    Hi @OMG ! Thanks a lot for your answer. I modified PostType.php as you said (with and without 'property_path' and unfortunately I still have the same error).
  • Reveclair
    Reveclair over 11 years
    I solved the problem setting data_class to null. Thanks for setting me on the right track.
  • nbro
    nbro almost 8 years
    Did you figure out why this solve the problem at the end?