Php Symfony 3:文件类型多和多对多数据库关系

Php Symfony 3:文件类型多和多对多数据库关系,php,file-upload,doctrine-orm,symfony,symfony-forms,Php,File Upload,Doctrine Orm,Symfony,Symfony Forms,我得到了名为SupportMessage的实体,其中包含来自我的支持(票证)系统的消息。我想实现的功能,允许用户和支持代理附加文件到他们的职位 我还得到了一个名为文件的实体,其中列出了我项目中的所有文件:文件ID、文件名、用户和上载日期 当用户在我的支持系统中写入消息时,他可以附加多个文件。我认为使用multiple=true比创建文件类型按钮的CollectionType更优雅,但我真的不知道如何实现此功能并使其工作。在官方文件和谷歌上都没有找到任何关于此案的信息 当我发送表单时,我得到了Up

我得到了名为SupportMessage的实体,其中包含来自我的支持(票证)系统的消息。我想实现的功能,允许用户和支持代理附加文件到他们的职位

我还得到了一个名为文件的实体,其中列出了我项目中的所有文件:文件ID、文件名、用户和上载日期

当用户在我的支持系统中写入消息时,他可以附加多个文件。我认为使用
multiple=true
比创建文件类型按钮的CollectionType更优雅,但我真的不知道如何实现此功能并使其工作。在官方文件和谷歌上都没有找到任何关于此案的信息

当我发送表单时,我得到了UploadedFile对象的数组,但没有ArrayCollection,所以一切都失败了:

关联字段“AppBundle\Entity\SupportMessage#$attachments”的类型“Doctrine\Common\Collections\Collection | array”的预期值改为“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);
    }
}

非常感谢您事先提供的帮助。

最后,我的同事发现了问题。它在我的控制器里。我在那里附加了
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 ...
}

请发布这两个实体和表单类。@michail\u w,我已经更新了我的问题。