2013-01-20 9 views
17

Sto usando Symfony2. Ho un'entità Post con un titolo e un campo immagine.Symfony 2 | Form eccezione quando si modifica un oggetto che ha un campo file (immagine)

Il mio problema: tutto va bene quando creo un post, ho la mia immagine ecc Ma quando voglio modificarlo, ho un problema con il campo "immagine", che è un file caricato, Symfony vuole un tipo di file e ha una stringa (il percorso del file caricato):

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. 

sono davvero bloccato con questo problema e davvero non so come risolverlo, tutto l'aiuto sarebbe molto apprezzato! Molte grazie!

Ecco il mio PostType.php (che viene utilizzato in newAction() e modifiyAction()) e che possono causare il problema ( 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'; 
    } 
} 

Ecco il mio Messaggio 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 
    } 

Ecco il mio newAction() ( Controller/PostController.php) Ogni funziona bene con questa funzione:

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

Ecco il mio modifyAction() ( Controller/PostController.php): C'è un problema con questa funzione

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

risposta

42

ho risolto il problema impostando data_class a null come segue:

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

Hai capito perché questo risolve il problema alla fine? – nbro

1

Si prega di effettuare sotto cambiamento nel 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' 
     ) 
    ); 
} 
+0

Hi @Reveclaire per favore fatemelo sapere se questo aiuta. È possibile rimuovere 'property_path' atrribute SE genera qualche errore. altrimenti tienilo. – OMG

+1

Ciao @OMG! Grazie mille per la tua risposta. Ho modificato PostType.php come hai detto (con e senza 'property_path' e sfortunatamente ho ancora lo stesso errore). – Reveclair

+0

Ho risolto il problema impostando data_class su null. Grazie per avermi messo sulla strada giusta. – Reveclair

3

ti consiglierei di leggere la documentazione di upload di file con Symfony e Dottrina How to handle File Uploads with Doctrine e una forte raccomandazione per la parte Lifecycle callbacks

In una breve voi di solito sotto forma di utilizzare il 'file' variabile (vedi documentazione), puoi mettere un'etichetta diversa attraverso le opzioni, poi nel campo 'immagine', ti basta memorizzare il nome del file, perché quando hai bisogno del file src puoi semplicemente chiamare il metodo getWebpath().

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

per chiamare nel vostro template ramoscello

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