我对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;
}
}
答案 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)。希望这可以帮助你