在VichUploaderBundle

时间:2017-09-05 06:21:16

标签: 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\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()

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

1 个答案:

答案 0 :(得分:1)

解决方案非常简单且如此接近。我只需要在我的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();
        }
    }
}

感谢这一点,必须为实体上传文件,并且在更新期间无法将其删除。