2016-11-16 58 views
1

期間發現我創建了一個實體文檔與屬性,包括文件屬性的列表,同時加入了文件去得非常好,當我更新我得到驗證錯誤:Symfony的 - 文件無法更新

無法找到該文件。

文件屬性必須同時增加,但在編輯可選的需要,因爲我可以只保留舊的文件。

這裏是我的實體文檔的一部分:

/** 
* @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); 
    } 

} 

和控制器我有:

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(); 
    } 
... 
} 

任何幫助嗎?


編輯

行爲IAM而文檔更新納悶:

如果用戶已更新文件,那麼該文件屬性必須與@assert \文件進行驗證,

其他文件屬性將不會被驗證,所以我可以保留原始文件uplo同時創建文檔。

回答

2

使用validation groups。 馬場所需文件只用於創建一個新的文件:

/** 
* ... 
* @Assert\File(maxSize = "5M", mimeTypes = {"application/pdf"}, groups = {"create"}) 
* ... 
*/ 
private $file; 

,並指定相關的組創建和編輯的操作:

public function editAction(Request $request) { 
    // ... 
    $form = $this->createForm('AppBundle\Form\DocumentType', $document, ["create"]); 

// ... 

public function editAction(Request $request, Document $document) { 
    // ... 
    $form = $this->createForm('AppBundle\Form\DocumentType', $document, ["edit"]); 
+0

感謝您的回答,如果我使用了您提到的驗證組,當然我可以更新該字段,但如果用戶更新了該文件,則不會將其驗證爲文件。 –

+0

嗯,你把文件名和上傳的文件實例放在同一個地方($文件屬性)。所以,在文檔編輯時,handleRequest()方法會從表單中用值替換舊文件名。空值不應該導致錯誤(驗證器只是跳過這個約束)。但錯誤消息說,值不爲空:由無效文件名引起的相同錯誤(FileValidator也將字符串作爲文件名處理)。請在編輯時檢查$ file屬性中的有限值(在handleRequest()和isValid()調用之前)。 – Timurib

+0

在Symfony中提交的表單不能被編輯,所以它永遠是無效的。在你的情況下,你總是創建兩個單獨的屬性,一個用於文件字符串,另一個用於上傳的文件實例? –

0

的@Timurib回答讓我在正確的方向,但代碼並沒有完全爲我工作的Symfony的3.2.6 什麼工作對我來說是:

/** 
* ... 
* @Assert\File(maxSize = "5M", mimeTypes = {"application/pdf"}, groups = {"create"}) 
* ... 
*/ 
private $file; 

這是同上面的回答和d ifferent部分在的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"]); 
3

我有同樣的問題,但在文檔中,就有答案了: https://symfony.com/doc/current/controller/upload_file.html

當創建一個表單編輯一個已經持久化項目,文件表單類型仍然需要一個File實例。作爲持久的實體現在只包含相對文件路徑,則首先必須使用存儲的文件名來串聯配置的上傳路徑,並創建一個新的文件類:只是你的CreateForm

use Symfony\Component\HttpFoundation\File\File; 
// ... 

$product->setBrochure(
    new File(_YOUR_UPLOAD_DIRECTORY_.'/'.$product->getBrochure()) 
); 

添加它

$document->setFile(
    new File(_YOUR_UPLOAD_DIRECTORY_.'/'.$document->getFile()) 
); 
$form = $this->createForm('AppBundle\Form\DocumentType', $document); 

希望能夠解決您的問題。

+0

非常感謝分享,我設法通過添加額外屬性$ fileTmp(未映射)來解決問題,它看起來像是在Symfony中處理文件上傳的常見方式。以及你的方法也是一個很好的解決方案 –