Symfony 使文件在VichUploaderBundle中不可为空

Symfony 使文件在VichUploaderBundle中不可为空,symfony,doctrine-orm,symfony-2.8,vichuploaderbundle,Symfony,Doctrine Orm,Symfony 2.8,Vichuploaderbundle,我在Symfony2.8应用程序中使用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\V

我在Symfony2.8应用程序中使用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()

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

解决方案非常简单,而且非常接近。我只需要将自定义验证器添加到我的文件实体中。我是怎么做到的

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

/**
 * @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();
        }
    }
}
由于此原因,必须上载实体的文件,并且在更新期间无法删除该文件