使文件在VichUploaderBundle中不可为空

问题描述:

我在我的Symfony2.8应用程序中使用VichUploaderBundle将文件属性添加到我的实体。请参阅下面的实体代码。使文件在VichUploaderBundle中不可为空

namespace WebsiteBundle\Entity; 

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

/** 
* @ORM\Table(name="website_file") 
* @ORM\Entity(repositoryClass="WebsiteBundle\Repository\FileRepository") 
* @Vich\Uploadable 
*/ 
class File 
{ 
    /** 
    * @var int 
    * 
    * @ORM\Id 
    * @ORM\Column(type="integer") 
    * @ORM\GeneratedValue(strategy="AUTO") 
    * @Assert\Type(type="integer") 
    * @Assert\GreaterThan(value="0") 
    */ 
    private $id; 

    /** 
    * @var string 
    * 
    * @ORM\Column(type="string", length=255) 
    * @Assert\NotBlank() 
    * @Assert\Type(type="string") 
    * @Assert\Length(max="255") 
    */ 
    private $title; 

    /** 
    * @var string 
    * 
    * @ORM\Column(type="text") 
    * @Assert\NotBlank() 
    * @Assert\Type(type="string") 
    */ 
    private $description; 

    /** 
    * @var UploadedFile 
    * 
    * @Vich\UploadableField(mapping="file", fileNameProperty="filename") 
    */ 
    private $file; 

    /** 
    * @var string 
    * 
    * @ORM\Column(type="string", length=255) 
    * @Assert\Type(type="string") 
    * @Assert\Length(max="255") 
    */ 
    private $filename; 

    /** 
    * @var int 
    * 
    * @ORM\Column(type="integer") 
    * @Assert\NotNull() 
    * @Assert\Type(type="integer") 
    * @Assert\GreaterThanOrEqual(value="0") 
    */ 
    private $dummy = 0; 

    /** 
    * @var boolean 
    * 
    * @ORM\Column(type="boolean") 
    * @Assert\NotNull() 
    * @Assert\Type(type="boolean") 
    */ 
    private $published; 

    /** 
    * @var User 
    * 
    * @Gedmo\Blameable(on="create") 
    * @ORM\ManyToOne(targetEntity="WebsiteBundle\Entity\User") 
    * @ORM\JoinColumn(onDelete="CASCADE") 
    * @Assert\Type(type="WebsiteBundle\Entity\User") 
    * @Assert\Valid() 
    */ 
    private $createdBy; 

    /** 
    * @var \DateTime 
    * 
    * @Gedmo\Timestampable(on="create") 
    * @ORM\Column(type="datetime") 
    * @Assert\DateTime() 
    */ 
    private $createdAt; 

    /** 
    * @var User 
    * 
    * @Gedmo\Blameable(on="update") 
    * @ORM\ManyToOne(targetEntity="WebsiteBundle\Entity\User") 
    * @ORM\JoinColumn(onDelete="CASCADE") 
    * @Assert\Type(type="WebsiteBundle\Entity\User") 
    * @Assert\Valid() 
    */ 
    private $updatedBy; 

    /** 
    * @var \DateTime 
    * 
    * @Gedmo\Timestampable(on="update") 
    * @ORM\Column(type="datetime") 
    * @Assert\DateTime() 
    */ 
    private $updatedAt; 

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

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

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

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

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

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

    /** 
    * @param UploadedFile $file 
    */ 
    public function setFile($file) 
    { 
     $this->file = $file; 
     $this->dummy++; 
    } 

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

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

    /** 
    * @return boolean 
    */ 
    public function getPublished() 
    { 
     return $this->published; 
    } 

    /** 
    * @param boolean $published 
    */ 
    public function setPublished($published) 
    { 
     $this->published = $published; 
    } 

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

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

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

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

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

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

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

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

一切正常,只有一个例外。我想让文件名不能为空。文件必须上传到创建实体,并且在更新期间不能删除。它只能被改变。一些文件总是必须上传到实体。如何实现这一目标?如果我添加断言像文件名:

* @Assert\NotNull() 

然后,它不工作,因为在验证表单,文件名是空的。它在持久实体中生成。但是,如果我省略了这个断言,那么可以在没有上传文件的情况下坚持实体。

+0

我从来没有使用过这个包, – sh4

解决方案非常简单而又紧密。我只需要将自定义验证器添加到我的File实体。我是如何做到的?

首先,我将注释添加到文件实体。请参阅下面的代码

/** 
* @ORM\Table(name="website_file") 
* @ORM\Entity(repositoryClass="WebsiteBundle\Repository\FileRepository") 
* @Vich\Uploadable 
* @Assert\Callback({"WebsiteBundle\Validator\Entities\FileValidator", "validate"}) 
*/ 
class File 

属性的注释保持不变。

/** 
* @var UploadedFile 
* 
* @Vich\UploadableField(mapping="file", fileNameProperty="filename") 
* @Assert\Type(type="Symfony\Component\HttpFoundation\File\UploadedFile") 
*/ 
private $file; 

/** 
* @var string 
* 
* @ORM\Column(type="string", length=255) 
* @Assert\Type(type="string") 
* @Assert\Length(max="255") 
*/ 
private $filename; 

最后一步 - 验证器,它非常简单。

class FileValidator 
{ 
    /** 
    * @param File $file 
    * @param ExecutionContextInterface $context 
    */ 
    public static function validate(File $file, ExecutionContextInterface $context) 
    { 
     if ($file->getFilename() === null && $file->getFile() === null) { 
      $context->buildViolation('File cannot be empty.') 
       ->atPath('file') 
       ->addViolation(); 
     } 
    } 
} 

感谢这个文件必须上传实体,它不能被删除在更新过程中。