我使用包含 file 属性的属性列表创建了一个实体 Document ,而添加文档非常顺利,当我更新时我得到验证错误:
添加时需要找不到该文件。
文件属性,但编辑时可选,因为我可以保留旧文件。
以下是我的实体文档的一部分:
/**
* @ORM\Entity
* @ORM\Table(name="document")
*/
class Document
{
...
/**
* @var string
* @Assert\NotBlank()
* @Assert\File(maxSize = "5M", mimeTypes = {"application/pdf"})
* @ORM\Column(name="file", type="string", length=255, nullable=true)
*/
private $file;
/**
* @var string
* @ORM\Column(name="name", type="string", length=50)
*/
private $name;
/**
* @ORM\ManyToOne(targetEntity="Dtype", inversedBy="documents")
*/
private $dtype;
...
public function uploadFile($path, $type='', $oldFile=null)
{
$file = $this->getFile();
if ($file instanceof UploadedFile) {
if(!empty($type)){
$path = $path. '/' . $type;
}
$fileName = md5(uniqid()).'.'.$file->guessExtension();
$file->move($path, $fileName);
$this->setFile($type. '/' .$fileName);
if($oldFile !== null){
$oldFilePath = $path .'/'. $oldFile;
if(file_exists($oldFilePath))
unlink($oldFilePath);
}
}else{
$this->setFile($oldFile);
}
}
并且在Controller中我有:
public function editAction(Request $request, Document $document) {
$oldFile = $document->getFile();
$form = $this->createForm('AppBundle\Form\DocumentType', $document);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$document->uploadFile($this->getParameter('documents_file_dir'), $document->getDtype()->getChemin(), $oldFile);
$em = $this->getDoctrine()->getManager();
$em->persist($document);
$em->flush();
}
...
}
请帮忙吗?
修改
文档更新时我想知道的行为:
如果用户已更新文件,则必须使用@Assert \ File验证文件属性,
其他不会验证文件属性,因此我可以在创建文档时保留原始文件。
答案 0 :(得分:3)
使用validation groups。 将字段标记为必填文件仅用于创建新文档:
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="height=device-height, width=device-width, initial-scale=1">
<title>The Steve Barrett Collection</title>
<link href="style.css" rel="stylesheet" type="text/css">
</head>
<body>
<div id="container">
<div class="containermenu"><img src="http://oi67.tinypic.com/vgmv80.jpg"></div>
<div class="containermenu"><img src="http://oi67.tinypic.com/vgmv80.jpg"></div>
<div class="containermenu"><img src="http://oi67.tinypic.com/vgmv80.jpg"></div>
<div class="containermenu"><img src="http://oi67.tinypic.com/vgmv80.jpg"></div>
</div>
</body>
</html>
并指定相关组以创建和编辑操作:
/**
* ...
* @Assert\File(maxSize = "5M", mimeTypes = {"application/pdf"}, groups = {"create"})
* ...
*/
private $file;
答案 1 :(得分:3)
我有同样的问题,但在文档中,有答案: https://symfony.com/doc/current/controller/upload_file.html
创建表单以编辑已经存在的项目时,文件表单类型仍然需要File实例。由于持久化实体现在只包含相对文件路径,因此首先必须将已配置的上载路径与存储的文件名连接起来,然后创建一个新的File类:
use Symfony\Component\HttpFoundation\File\File;
// ...
$product->setBrochure(
new File(_YOUR_UPLOAD_DIRECTORY_.'/'.$product->getBrochure())
);
在你的createForm
之前添加它$document->setFile(
new File(_YOUR_UPLOAD_DIRECTORY_.'/'.$document->getFile())
);
$form = $this->createForm('AppBundle\Form\DocumentType', $document);
希望解决您的问题。
答案 2 :(得分:0)
@Timurib的回答让我朝着正确的方向前进,但代码对我来说并不适用于Symfony 3.2.6 对我有用的是:
/**
* ...
* @Assert\File(maxSize = "5M", mimeTypes = {"application/pdf"}, groups = {"create"})
* ...
*/
private $file;
与上面的答案相同,不同的部分是在createForm中指定组:
public function editAction(Request $request) {
// ...
$form = $this->createForm('AppBundle\Form\DocumentType', $document, ["validation_groups" => "create"]);
// ...
public function editAction(Request $request, Document $document) {
// ...
$form = $this->createForm('AppBundle\Form\DocumentType', $document, ["validation_groups" => "edit"]);