2013-07-16 2 views
3

Я создаю систему билетов для практических целей.Как обрабатывать загрузку файлов с помощью нескольких отношений в Symfony2?

Прямо сейчас у меня проблема с загрузкой файлов.

Идея состоит в том, что билет может иметь несколько вложений, поэтому я создал взаимосвязь между билетом и таблицами выгрузки.

class Ticket { 

// snip 

/** 
* @ORM\OneToMany(targetEntity="Ticket", mappedBy="ticket") 
*/ 
protected $uploads; 

// snip 
} 

Класс объект загрузки содержит функциональность загрузки, который я взял из this урока:

<?php 

namespace Sytzeandreae\TicketsBundle\Entity; 

use Doctrine\ORM\Mapping as ORM; 
use Symfony\Component\Validator\Constraints as Assert; 
use Symfony\Component\HttpFoundation\File\UploadedFile; 

/** 
* @ORM\Entity(repositoryClass="Sytzeandreae\TicketsBundle\Repository\UploadRepository") 
* @ORM\Table(name="upload") 
* @ORM\HasLifecycleCallbacks 
*/ 
class Upload 
{ 
    /** 
    * @Assert\File(maxSize="6000000") 
    */ 
    private $file; 

    private $temp; 

    /** 
    * @ORM\Id 
    * @ORM\Column(type="integer") 
    * @ORM\GeneratedValue(strategy="AUTO") 
    */ 
    protected $id; 

    /** 
    * @ORM\ManyToOne(targetEntity="Ticket", inversedBy="upload") 
    * @ORM\JoinColumn(name="ticket_id", referencedColumnName="id") 
    */ 
    protected $ticket; 

    /** 
    * @ORM\Column(type="string") 
    */ 
    protected $title; 

    /** 
    * @ORM\Column(type="string") 
    */ 
    protected $src; 

    public function getAbsolutePath() 
    { 
     return null === $this->src 
      ? null 
      : $this->getUploadRootDir().'/'.$this->src; 
    } 

    public function getWebPath() 
    { 
     return null === $this->src 
      ? null 
      : $this->getUploadDir().'/'.$this->src; 
    } 

    public function getUploadRootDir() 
    { 
     // The absolute directory path where uplaoded documents should be saved 
     return __DIR__.'/../../../../web/'.$this->getUploadDir(); 
    } 

    public function getUploadDir() 
    { 
     // Get rid of the __DIR__ so it doesn/t screw up when displaying uploaded doc/img in the view 
     return 'uploads/documents'; 
    } 

    /** 
    * Sets file 
    * 
    * @param UploadedFile $file 
    */ 
    public function setFile(UploadedFile $file = null) 
    { 
     $this->file = $file; 

     if (isset($this->path)) { 
      // store the old name to delete after the update 
      $this->temp = $this->path; 
      $this->path = null; 
     } else { 
      $this->path = 'initial'; 
     } 
    } 

    /** 
    * Get file 
    * 
    * @return UploadedFile 
    */ 
    public function getFile() 
    { 
     return $this->file; 
    } 

    /** 
    * Get id 
    * 
    * @return integer 
    */ 
    public function getId() 
    { 
     return $this->id; 
    } 

    /** 
    * Set title 
    * 
    * @param string $title 
    */ 
    public function setTitle($title) 
    { 
     $this->title = $title; 
    } 

    /** 
    * Get title 
    * 
    * @return string 
    */ 
    public function getTitle() 
    { 
     return $this->title; 
    } 

    /** 
    * Set src 
    * 
    * @param string $src 
    */ 
    public function setSrc($src) 
    { 
     $this->src = $src; 
    } 

    /** 
    * Get src 
    * 
    * @return string 
    */ 
    public function getSrc() 
    { 
     return $this->src; 
    } 

    /** 
    * Set ticket 
    * 
    * @param Sytzeandreae\TicketsBundle\Entity\Ticket $ticket 
    */ 
    public function setTicket(\Sytzeandreae\TicketsBundle\Entity\Ticket $ticket) 
    { 
     $this->ticket = $ticket; 
    } 

    /** 
    * Get ticket 
    * 
    * @return Sytzeandreae\TicketsBundle\Entity\Ticket 
    */ 
    public function getTicket() 
    { 
     return $this->ticket; 
    } 

    /** 
    * @ORM\PrePersist() 
    * @ORM\PreUpdate() 
    */ 
    public function preUpload() 
    { 
     if (null !== $this->getFile()) { 
      // do whatever you want to generate a unique name 
      $filename = sha1(uniqid(mt_rand(), true)); 
      $this->src = $filename.'.'.$this->getFile()->guessExtension(); 
     } 
    } 

    public function upload() 
    { 
     // the file property can be empty if the field is not required 
     if (null === $this->getFile()) { 
      return; 
     } 

     // move takes the target directory and then the target filename to move to 
     $this->getFile()->move(
      $this->getUploadRootDir(), 
      $this->src 
     ); 

     // check if we have an old image 
     if (isset($this->temp)) { 
      // delete the old image 
      unlink($this->getUploadRootDir().'/'.$this->temp); 
      // clear the temp image path 
      $this->temp = null; 
     } 

     // clean up the file property as you won't need it anymore 
     $this->file = null; 
    } 

    /** 
    * @ORM\PostRemove 
    */ 
    public function removeUpload() 
    { 
     if ($file = $this->getAbsolutePath()) { 
      unlink($file); 
     } 
    } 
} 

Форма построить следующим образом:

class TicketType extends AbstractType 
{ 
    public function buildForm(FormBuilder $builder, array $options) 
    { 
     $builder 
      ->add('title') 
      ->add('description') 
      ->add('priority') 
      ->add('uploads', new UploadType()) 
    } 

Где UploadType выглядит следующим образом:

class UploadType extends AbstractType 
{ 
    public function buildForm(FormBuilder $builder, array $options) { 
     $builder->add('file', 'file', array(
      'label' => 'Attachments', 
      'required' => FALSE, 
      'attr' => array (
       'accept' => 'image/*', 
       'multiple' => 'multiple' 
      ) 
     )); 
    } 

Эта часть работает нормально, я получаю представленную форму, содержащую загрузчик файлов.

Как только я поместил эту строку в constuctor объекта Ticket: $ this-> uploads = new \ Doctrine \ Common \ Collections \ ArrayCollection(); Он бросает мне следующую ошибку:

Neither property "file" nor method "getFile()" nor method "isFile()" exists in class "Doctrine\Common\Collections\ArrayCollection"

Если я оставлю эту строку, и загрузить файл, он выдает мне следующую ошибку:

"Sytzeandreae\TicketsBundle\Entity\Ticket". Maybe you should create the method "setUploads()"?

Так следующая вещь, которую я создавал этот метод , попробуйте загрузить еще раз, и теперь он меня бросает:

Class Symfony\Component\HttpFoundation\File\UploadedFile is not a valid entity or mapped super class.

Здесь я действительно застрял. Я не понимаю, на какой стадии я ошибся и надеюсь на помощь :)

Спасибо!

+0

Вы попробовали [это решение] (http://stackoverflow.com/a/6930001/1847340)? – ferdynator

+0

Да, я не знал, правильно ли я сделал это. Он по-прежнему бросает меня UploadedFile не является допустимой ошибкой сущности ... – Njerpie

+0

Как выглядит ваш метод 'setUpload'? – ferdynator

ответ

0

Вы можете либо добавить collection field-type от UploadType() в вашу форму. Обратите внимание, что вы не можете использовать множественную опцию с вашим текущим объектом Upload ... но это самое быстрое решение.

Или адаптируйте объект Ticket, чтобы иметь возможность обрабатывать несколько файлов в ArrayCollection и перебирать их.

Смежные вопросы