我在我的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是空的。它是在持久化实体期间生成的。但是如果我省略了这个断言,那么就可以在不上传文件的情况下保留实体。
答案 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();
}
}
}
感谢这一点,必须为实体上传文件,并且在更新期间无法将其删除。