Symfony 2 - VichUploader无法处理文件

时间:2015-06-06 22:53:32

标签: php entity-framework symfony vichuploaderbundle

我对VichUploader有一个非常奇怪的问题。

我有2个实体,其中一个VichUploader工作正常(下载实体) - 它将文件保存在目录中并将记录添加到数据库表。对于第二个实体(Offer),它不起作用 - 它显示Column 'file_name' cannot be null错误。如果我在fileName属性中添加了nullable参数,则会将记录添加到数据库表中但是使用NULL file_name(并且它不能将文件保存在目录中)。

我的config.yml

vich_uploader:
    db_driver: orm

    mappings:
        download_file:
            uri_prefix:         /files/download
            upload_destination: %kernel.root_dir%/../web/files/download

        offer_file:
            uri_prefix:         /files/offer
            upload_destination: %kernel.root_dir%/../web/files/offer

            inject_on_load:     false
            delete_on_update:   false
            delete_on_remove:   true

下载实体:

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;

/**
 * Download
 *
 * @ORM\Table(name="izo_download")
 * @ORM\Entity(repositoryClass="AppBundle\Entity\DownloadRepository")
 * @Vich\Uploadable
 */
class Download
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

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

    /**
     * NOTE: This is not a mapped field of entity metadata, just a simple property.
     *
     * @Vich\UploadableField(mapping="download_file", fileNameProperty="name")
     *
     * @var File $file
     */
    private $file;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;


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

    /**
     * Set name
     *
     * @param string $name
     *
     * @return Download
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

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

    /**
     * Set date
     *
     * @param \DateTime $date
     *
     * @return Download
     */
    public function setDate($date)
    {
        $this->date = $date;

        return $this;
    }

    /**
     * Get date
     *
     * @return \DateTime
     */
    public function getDate()
    {
        return $this->date;
    }

    /**
     * If manually uploading a file (i.e. not using Symfony Form) ensure an instance
     * of 'UploadedFile' is injected into this setter to trigger the  update. If this
     * bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
     * must be able to accept an instance of 'File' as the bundle will inject one here
     * during Doctrine hydration.
     *
     * @param File|\Symfony\Component\HttpFoundation\File\UploadedFile $file
     */
    public function setFile(File $file = null)
    {
        $this->file = $file;

        if ($file) {
            // It is required that at least one field changes if you are using doctrine
            // otherwise the event listeners won't be called and the file is lost
            $this->date = new \DateTime('now');
        }
    }

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

提供实体

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * Offer
 *
 * @ORM\Table(name="izo_offer")
 * @ORM\Entity(repositoryClass="AppBundle\Entity\OfferRepository")
 * @Vich\Uploadable
 * @ORM\HasLifecycleCallbacks()
 */
class Offer
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="name", type="string", length=255)
     * @Assert\NotBlank(message="To pole nie może być puste")
     */
    private $name;

    /**
     * @Assert\Type(type="AppBundle\Entity\Client")
     * @Assert\Valid
     * @Assert\NotBlank(message="To pole nie może być puste")
     * @ORM\ManyToOne(targetEntity="Client", inversedBy="offers",cascade={"persist"})
     * @ORM\JoinColumn(name="client_id", referencedColumnName="id")
     */
    private $clientBelongsTo;

    /**
     * @Assert\NotBlank(message="To pole nie może być puste")
     * @ORM\ManyToOne(targetEntity="User", inversedBy="supportOffers")
     * @ORM\JoinColumn(name="contact_person_id", referencedColumnName="id")
     */
    private $contactPerson;

    /**
     * @ORM\ManyToOne(targetEntity="User", inversedBy="createdOffers")
     * @ORM\JoinColumn(name="creator_id", referencedColumnName="id")
     */
    private $createdBy;

    /**
     * @ORM\OneToMany(targetEntity="Measurement", mappedBy="createdBy")
     */
    private $createdMeasurements;

    /**
     * @ORM\OneToMany(targetEntity="Measurement", mappedBy="contactPerson")
     */
    private $supportMeasurements;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="createdAt", type="date")
     */
    private $createdAt;

    /**
     * @var string
     *
     * @ORM\Column(name="note", type="text", nullable=true)
     */
    private $note;

    /**
     * @Assert\NotBlank(message="To pole nie może być puste")
     * @var integer
     *
     * @ORM\Column(name="comesFrom", type="integer")
     */
    private $comesFrom;

    /**
     * @Assert\NotBlank(message="To pole nie może być puste", groups={"creation"})
     * @var \DateTime
     *
     * @ORM\Column(name="notify", type="date")
     */
    private $notify;

    /**
     * @var integer
     *
     * @ORM\Column(name="status", type="integer")
     */
    private $status = 1;

    /**
     * @var integer
     *
     * @ORM\Column(name="whyNotSold", type="integer", nullable=true)
     */
    private $whyNotSold;

    /**
     *
     * NOTE: This is not a mapped field of entity metadata, just a simple property.
     *
     * @Vich\UploadableField(mapping="offer_file", fileNameProperty="fileName")
     *
     * @var File $file
     */
    private $file;

    /**
     * @var string
     *
     * @ORM\Column(name="file_name", type="string", length=255)
     */
    private $fileName;

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

    /**
     * If manually uploading a file (i.e. not using Symfony Form) ensure an instance
     * of 'UploadedFile' is injected into this setter to trigger the  update. If this
     * bundle's configuration parameter 'inject_on_load' is set to 'true' this setter
     * must be able to accept an instance of 'File' as the bundle will inject one here
     * during Doctrine hydration.
     *
     * @param File|\Symfony\Component\HttpFoundation\File\UploadedFile $file
     */
    public function setFile(File $file = null)
    {
        $this->$file = $file;

        if ($file) {
            // It is required that at least one field changes if you are using doctrine
            // otherwise the event listeners won't be called and the file is lost
            $this->updatedAt = new \DateTime('now');
        }
    }

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

    /**
     * @param string $fileName
     */
    public function setFileName($fileName)
    {
        $this->fileName = $fileName;
    }

    /**
     * @return string
     */
    public function getFileName()
    {
        return $this->fileName;
    }


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

    /**
     * Set name
     *
     * @param string $name
     *
     * @return Offer
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

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

    /**
     * Set createdAt
     *
     * @ORM\PrePersist
     *
     * @return Offer
     */
    public function setCreatedAt()
    {
        $this->createdAt = new \DateTime();
    }

    /**
     * Get createdAt
     *
     * @return \DateTime
     */
    public function getCreatedAt()
    {
        return $this->createdAt;
    }

    /**
     * Set note
     *
     * @param string $note
     *
     * @return Offer
     */
    public function setNote($note)
    {
        $this->note = $note;

        return $this;
    }

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


    /**
     * Set notify
     *
     * @param \DateTime $notify
     *
     * @return Offer
     */
    public function setNotify($notify)
    {
        $this->notify = $notify;

        return $this;
    }

    /**
     * Get notify
     *
     * @return \DateTime
     */
    public function getNotify()
    {
        return $this->notify;
    }

    /**
     * Set status
     *
     * @param integer $status
     *
     * @return Offer
     */
    public function setStatus($status)
    {
        $this->status = $status;

        return $this;
    }

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

    /**
     * Set whyNotSold
     *
     * @param integer $whyNotSold
     *
     * @return Offer
     */
    public function setWhyNotSold($whyNotSold)
    {
        $this->whyNotSold = $whyNotSold;

        return $this;
    }

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

    /**
     * Set contactPerson
     *
     * @param \AppBundle\Entity\User $contactPerson
     *
     * @return Offer
     */
    public function setContactPerson(\AppBundle\Entity\User $contactPerson = null)
    {
        $this->contactPerson = $contactPerson;

        return $this;
    }

    /**
     * Get contactPerson
     *
     * @return \AppBundle\Entity\User
     */
    public function getContactPerson()
    {
        return $this->contactPerson;
    }

    /**
     * Set createdBy
     *
     * @param \AppBundle\Entity\User $createdBy
     *
     * @return Offer
     */
    public function setCreatedBy(\AppBundle\Entity\User $createdBy = null)
    {
        $this->createdBy = $createdBy;

        return $this;
    }

    /**
     * Get createdBy
     *
     * @return \AppBundle\Entity\User
     */
    public function getCreatedBy()
    {
        return $this->createdBy;
    }

    /**
     * Set comesFrom
     *
     * @param integer $comesFrom
     *
     * @return Offer
     */
    public function setComesFrom($comesFrom)
    {
        $this->comesFrom = $comesFrom;

        return $this;
    }

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


    /**
     * Set clientBelongsTo
     *
     * @param \AppBundle\Entity\Client $clientBelongsTo
     *
     * @return Offer
     */
    public function setClientBelongsTo(\AppBundle\Entity\Client $clientBelongsTo = null)
    {
        $this->clientBelongsTo = $clientBelongsTo;

        return $this;
    }

    /**
     * Get clientBelongsTo
     *
     * @return \AppBundle\Entity\Client
     */
    public function getClientBelongsTo()
    {
        return $this->clientBelongsTo;
    }
    /**
     * Constructor
     */
    public function __construct()
    {
        $this->createdMeasurements = new \Doctrine\Common\Collections\ArrayCollection();
        $this->supportMeasurements = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Add createdMeasurement
     *
     * @param \AppBundle\Entity\Measurement $createdMeasurement
     *
     * @return Offer
     */
    public function addCreatedMeasurement(\AppBundle\Entity\Measurement $createdMeasurement)
    {
        $this->createdMeasurements[] = $createdMeasurement;

        return $this;
    }

    /**
     * Remove createdMeasurement
     *
     * @param \AppBundle\Entity\Measurement $createdMeasurement
     */
    public function removeCreatedMeasurement(\AppBundle\Entity\Measurement $createdMeasurement)
    {
        $this->createdMeasurements->removeElement($createdMeasurement);
    }

    /**
     * Get createdMeasurements
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getCreatedMeasurements()
    {
        return $this->createdMeasurements;
    }

    /**
     * Add supportMeasurement
     *
     * @param \AppBundle\Entity\Measurement $supportMeasurement
     *
     * @return Offer
     */
    public function addSupportMeasurement(\AppBundle\Entity\Measurement $supportMeasurement)
    {
        $this->supportMeasurements[] = $supportMeasurement;

        return $this;
    }

    /**
     * Remove supportMeasurement
     *
     * @param \AppBundle\Entity\Measurement $supportMeasurement
     */
    public function removeSupportMeasurement(\AppBundle\Entity\Measurement $supportMeasurement)
    {
        $this->supportMeasurements->removeElement($supportMeasurement);
    }

    /**
     * Get supportMeasurements
     *
     * @return \Doctrine\Common\Collections\Collection
     */
    public function getSupportMeasurements()
    {
        return $this->supportMeasurements;
    }
}

1 个答案:

答案 0 :(得分:0)

可能会发生这种情况,因为UploadableField注释引用了字段数据库名称,而不是模型名称(例如:file_name,而不是fileName),但我在一个工作示例中测试了这一点,一切都很顺利。另外VichUploaderBundle监听Doctrine事件,这意味着你需要更新实体的任何其他字段来触发文件的实际上传,最简单的方法是强制&#34;强制&#34;上传其在文件字段设置器上设置字段。这是一个例子:

public function setFile($file)
{
    $this->file= $file;

    if ($this->file) {
        $this->update_date = new \DateTime();
    }

    return $this;
}

这非常有效,因为您可以确保在触发PrePersist或PreUpdate事件时上载并附加文件。您可以收听PreUpload和PostUpload事件并检查已处理的数据(这很容易通过Symfony提供的 dump 功能完成,Symfony&gt; = 2.6)。希望这可以帮助你