web-dev-qa-db-fra.com

Symfony 2 | Exception de forme lors de la modification d'un objet comportant un champ de fichier (image)

J'utilise Symfony2. J'ai une entité Poster qui a un titre et un champ d'image.

Mon problème : Tout va bien quand je crée un post, j'ai ma photo, etc. Mais quand je veux le modifier, j'ai un problème avec le champ "Image" qui est un fichier téléchargé, symfony veut un type de fichier et une chaîne ( Le chemin du fichier téléchargé):

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. 

Je suis vraiment bloqué avec ce problème et je ne sais vraiment pas comment résoudre, aucune aide serait grandement appréciée! Merci beaucoup!

Voici mon Postype.php (qui est utilisé dans NEWACACTION () et ModifiyAction ()) et qui peut causer le problème (Forme/postype.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';
    }
}

Voici mon Post-entité (Entité/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
   }

Voici mon newAction () (Contrôleur/postcontroller.phpChaque fonctionne bien avec cette fonction:

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()));
}

Voici mon motifyAction () (Contrôleur/postcontroller.php):Il y a un problème avec cette fonction

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));
}
18
Reveclair

J'ai résolu le problème de problème data_class à null comme suit:

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

Je vous recommanderais de lire la documentation du téléchargement de fichier avec Symfony et Doctrine Comment gérer les téléchargements de fichiers avec la doctrine et une recommandation forte à la partie Lifecycle rappels

Dans un mémoire, vous utilisez généralement la variable "Fichier" (voir la documentation), vous pouvez mettre une étiquette différente via les options, puis dans votre champ "Image", vous stockez simplement le nom du fichier, car lorsque vous avez besoin. Le fichier SRC Vous pouvez simplement appeler la méthode GetWebPath ().

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

appeler dans votre twig Modèle

<img src="{{ asset(entity.webPath) }}" />
3
Richard Pérez

Veuillez faire ci-dessous le changement de votre postytype.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'
        )
    );
}
1
OMG