Symfony 2 — VichUploader не может обработать файл

У меня очень странная проблема с VichUploader.

У меня есть 2 объекта, где для одного из них VichUploader работает нормально (Download Entity) — он сохраняет файл в каталоге и добавляет запись в таблицу базы данных. Для второго объекта (Предложение) это не работает — он отображает Column 'file_name' cannot be null ошибка. Если я добавил параметр nullable в свойство fileName, он добавил запись в таблицу базы данных, но с 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

Решение

Возможно, это могло произойти, потому что аннотация UploadableField ссылается на имя базы данных поля, а не на имя модели (например, имя_файла, а не имя_файла), но я протестировал это в рабочем примере, и все прошло нормально. Также VichUploaderBundle прослушивает события Doctrine, это означает, что вам нужно обновить любое другое поле сущности, чтобы инициировать фактическую загрузку файла, самый простой способ «принудительно» загрузить его, установив поле в установщике полей файла. Вот пример:

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

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

return $this;
}

Это очень эффективно, потому что вы гарантируете, что ваш файл загружен и прикреплен при запуске событий PrePersist или PreUpdate. Вы можете прослушать события PreUpload и PostUpload и проверить обработанные данные (это легко сделать, если свалка функция предоставлена ​​Symfony, Symfony> = 2.6). Надеюсь, это поможет вам

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]