2017-02-20 48 views
0

我得到的實體名爲SupportMessage其中包含來自我的支持(票證)系統的消息。我想實現功能,允許用戶和支持代理附加文件到他們的帖子。Symfony 3:FileType multiple和many-to-many數據庫關係

我還收到了一個名爲的實體文件其中列出了我項目中的所有文件:文件ID,文件名,用戶和上傳日期。

當用戶在我的支持系統中寫入消息時,他可以附加多個文件。我認爲使用multiple=true比創建FileType按鈕的CollectionType更優雅,但我不知道如何實現此功能並使其工作。在官方文檔和Google上找不到有關此案例的任何信息。

當我發送的形式,我得到了UploadedFile的對象的數組,而不是ArrayCollection的,所以一切都失敗:

類型的

期望值「學說\ COMMON \收藏\收藏|陣」爲聯想場「AppBundle \ Entity \ SupportMessage#$附件」,取而代之的是「Symfony \ Component \ HttpFoundation \ File \ UploadedFile」。

控制器:

/** 
* @Security("is_granted('ALLOWED_TO_VIEW_SUPPORT_TICKET', supportTicket)") 
* @Route("/support/ticket-{supportTicket}", name="view_ticket") 
* 
* @param Request  $request 
* @param SupportTicket $supportTicket 
* @return Response 
*/ 
public function viewTicket(Request $request, SupportTicket $supportTicket) 
{ 
    $translator = $this->get('translator'); 
    $breadcrumbs = $this->get('white_october_breadcrumbs'); 

    $breadcrumbs->addRouteItem('app.name', 'homepage'); 
    $breadcrumbs->addRouteItem('page_title.support', 'my_support_tickets'); 
    $breadcrumbs->addItem($supportTicket->getTitle()); 

    $supportMessage = new SupportMessage(); 
    $supportMessage->setSupportTicket($supportTicket); 
    $supportMessage->setUser($this->getUser()); 

    $form = $this->createForm(SupportMessageType::class, $supportMessage); 
    $form->handleRequest($request); 

    if ($form->isSubmitted() && $form->isValid()) { 
     foreach ($supportMessage->getAttachments() as $attachment) { 
      $fileName = $this->get('app.file_uploader')->upload($attachment); 

      $file = new File(); 
      $file->setFilename($fileName); 
      $file->setUser($this->getUser()); 

      //$supportMessage->addAttachment($file); 
     } 

     //dump($supportMessage);die; 

     $em = $this->getDoctrine()->getManager(); 
     $em->persist($supportMessage); 
     $em->flush(); 

     $this->addFlash('notice', $translator->trans('support.flash_message.sent')); 

     return $this->redirect($request->getUri()); 
    } 

    return $this->render('support/view-ticket.html.twig', [ 
     'title'   => $supportTicket->getTitle(), 
     'supportTicket' => $supportTicket, 
     'form'   => $form->createView() 
    ]); 
} 

服務:

namespace AppBundle\Service; 

use Symfony\Component\HttpFoundation\File\UploadedFile; 

class FileUploader 
{ 
    private $targetDir; 

    public function __construct($targetDir) 
    { 
     $this->targetDir = $targetDir; 
    } 

    public function upload(UploadedFile $file) 
    { 
     $fileName = md5(uniqid()).'.'.$file->guessExtension(); 

     $file->move($this->targetDir, $fileName); 

     return $fileName; 
    } 
} 

SupportMessage實體:

namespace AppBundle\Entity; 

use Carbon\Carbon; 
use Doctrine\Common\Collections\ArrayCollection; 
use Doctrine\Common\Collections\Collection; 
use Doctrine\ORM\Mapping as ORM; 
use Symfony\Component\Validator\Constraints as Assert; 

/** 
* @ORM\Entity 
*/ 
class SupportMessage 
{ 
    public function __construct() 
    { 
     $this->postedAt = new \DateTime(); 
     $this->attachments = new ArrayCollection(); 
    } 

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

    /** 
    * @ORM\Column(type="text") 
    * 
    * @Assert\NotBlank 
    * @Assert\Length(max=65535) 
    * 
    * @var string 
    */ 
    private $message; 

    /** 
    * @ORM\Column(type="datetime") 
    * 
    * @var \DateTime 
    */ 
    private $postedAt; 

    /** 
    * @return int 
    */ 
    public function getId(): ?int 
    { 
     return $this->id; 
    } 

    /** 
    * @return string 
    */ 
    public function getMessage(): ?string 
    { 
     return $this->message; 
    } 

    /** 
    * @param string $message 
    */ 
    public function setMessage(?string $message) 
    { 
     $this->message = $message; 
    } 

    /** 
    * @return \DateTime 
    */ 
    public function getPostedAt() 
    { 
     return $this->postedAt; 
    } 

    /** 
    * @return string 
    */ 
    public function getPostedAgo() 
    { 
     Carbon::setLocale('ru'); 

     return Carbon::instance($this->postedAt)->diffForHumans(); 
    } 

    /** 
    * @param \DateTime $postedAt 
    */ 
    public function setPostedAt($postedAt) 
    { 
     $this->postedAt = $postedAt; 
    } 

    /** 
    * @ORM\ManyToOne(targetEntity="User") 
    * @ORM\JoinColumn(nullable=false) 
    * 
    * @var User 
    */ 
    private $user; 

    /** 
    * @return User 
    */ 
    public function getUser() 
    { 
     return $this->user; 
    } 

    /** 
    * @param User $user 
    */ 
    public function setUser($user) 
    { 
     $this->user = $user; 
    } 

    /** 
    * @ORM\ManyToOne(targetEntity="SupportTicket", inversedBy="supportMessages") 
    * 
    * @var SupportTicket 
    */ 
    private $supportTicket; 

    /** 
    * @return SupportTicket 
    */ 
    public function getSupportTicket() 
    { 
     return $this->supportTicket; 
    } 

    /** 
    * @param SupportTicket $supportTicket 
    */ 
    public function setSupportTicket($supportTicket) 
    { 
     $this->supportTicket = $supportTicket; 
    } 

    /** 
    * @ORM\ManyToMany(targetEntity="File", inversedBy="supportMessages") 
    * 
    * @var File[] 
    */ 
    private $attachments; 

    /** 
    * @return File[] 
    */ 
    public function getAttachments() 
    { 
     return $this->attachments; 
    } 

    /** 
    * @param File[] $attachments 
    */ 
    public function setAttachments($attachments) 
    { 
     foreach ($attachments as $attachment) { 
      $this->attachments->add($attachment); 
     } 

     //dump($this->attachments);die; 
    } 

    /** 
    * @param File $attachment 
    */ 
    public function addAttachment($attachment) 
    { 
     $this->attachments->add($attachment); 
    } 
} 

文件實體:

namespace AppBundle\Entity; 

use Doctrine\Common\Collections\ArrayCollection; 
use Doctrine\Common\Collections\Collection; 
use Doctrine\ORM\Mapping as ORM; 
use Symfony\Component\Validator\Constraints as Assert; 

/** 
* @ORM\Entity 
*/ 
class File 
{ 
    public function __construct() 
    { 
     $this->uploadedAt = new \DateTime(); 
     $this->supportMessages = new ArrayCollection(); 
    } 

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

    /** 
    * @ORM\Column(type="string") 
    * 
    * @Assert\File 
    * 
    * @var string 
    */ 
    private $filename; 

    /** 
    * @ORM\Column(type="string") 
    * 
    * @var User 
    */ 
    private $user; 

    /** 
    * @ORM\Column(type="datetime") 
    * 
    * @var \DateTime 
    */ 
    private $uploadedAt; 

    /** 
    * @return int 
    */ 
    public function getId(): ?int 
    { 
     return $this->id; 
    } 

    /** 
    * @return string 
    */ 
    public function getFilename(): ?string 
    { 
     return $this->filename; 
    } 

    /** 
    * @param string $filename 
    */ 
    public function setFilename(?string $filename) 
    { 
     $this->filename = $filename; 
    } 

    /** 
    * @return User 
    */ 
    public function getUser() 
    { 
     return $this->user; 
    } 

    /** 
    * @param mixed $user 
    */ 
    public function setUser($user) 
    { 
     $this->user = $user; 
    } 

    /** 
    * @return \DateTime 
    */ 
    public function getUploadedAt() 
    { 
     return $this->uploadedAt; 
    } 

    /** 
    * @param \DateTime $uploadedAt 
    */ 
    public function setUploadedAt($uploadedAt) 
    { 
     $this->uploadedAt = $uploadedAt; 
    } 

    /** 
    * @ORM\ManyToMany(targetEntity="SupportMessage", mappedBy="attachments") 
    * 
    * @var Collection|SupportMessage[] 
    */ 
    private $supportMessages; 

    /** 
    * @return Collection|SupportMessage[] 
    */ 
    public function getSupportMessages() 
    { 
     return $this->supportMessages; 
    } 

    /** 
    * @param Collection|SupportMessage[] $supportMessages 
    */ 
    public function setSupportMessages($supportMessages) 
    { 
     $this->supportMessages = $supportMessages; 
    } 

    /** 
    * @param SupportMessage $supportMessage 
    */ 
    public function addSupportMessage($supportMessage) 
    { 
     $supportMessage->addAttachment($this); 

     $this->supportMessages->add($supportMessage); 
    } 
} 

非常感謝任何幫助提前。

+0

請張貼兩個實體,和窗體類。 –

+0

@michail_w,我已經更新了我的問題。 – terron

回答

0

最後,我的同事發現了這個問題。它在我的控制器中。我附加了UploadedFile對象,但實際上我需要附加我的實體File對象。

固定碼剪斷:

if ($form->isSubmitted() && $form->isValid()) { 
    $attachments = new ArrayCollection(); 

    foreach ($supportMessage->getAttachments() as $attachment) { 
     $fileName = $this->get('app.file_uploader')->upload($attachment); 

     $file = new File(); 
     $file->setFilename($fileName); 
     $file->setUser($this->getUser()); 

     $attachments->add($file); 
     //$supportMessage->addAttachment($file); 
    } 

    $supportMessage->setAttachments($attachments); 

    // ... other code here ... 
}