2013-10-17 43 views
6

我正在构建一个复杂的文件上载表单。这种形式存在普通数据和一组4种文件类型,每种类型可能有多个文件上传。Symfony2 Forms:表单无效时显示已上传的文件

  • ReportForm
    • 附件
      • 报告(UploadedFile的实体的集合)
      • 照片(UploadedFile的实体的集合)

UploadedFile的实体有文件名,说明等。

使用案例: 现在,我提交了4张照片和2份报告,所有6个文件都可以。 但在表单中还有一些其他错误。 但是我想再次显示上传的文件,以便用户不必再次上传它们。 这些文件已被保存,所以当我用GET回到同一页面时,文件显示正确。

我已经做了/尝试:

  • 之前,我结合我克隆现有上传的文件
  • 结合的形式,我上传的所有新文件(如有),并坚持他们
  • 后请求之后,我重新添加现有上传的文件(来自克隆的对象)。我创建了具有现有文件ID的表单输入,因此我可以识别现有项目。

这一切都工作正常,但因为我更改我的报告和附件后绑定数据后显示的帖子无法更改。我无法在提交的表单上执行setData($ report)。

因此,现有文件不再显示,因为表单数据仍然是旧的报表对象(来自帖子)。

当我做一个正常的页面的GET,$报告从数据库中检索并显示正确。但是,在已经上传文件的POST后,数据库数据是正确的,但表单视图并不知道更改的数据(绑定后)。

任何想法?或者更好的方法来做到这一点?

回答

3

好的,经过几天的追踪和错误,我找到了一个匹配的解决方案。

这就是我所做的,简而言之。

在UploadedFile的实体,我添加了2个新领域:文件UNIQUEID。 这些字段没有映射到ORM中,因为我只在表单中需要它们。

提交表单时,我将新上传的文件添加到特定的会话变量中,并为其分配一个唯一的ID(因为我需要能够删除它们并需要标识符)。 我也将文件上传到他们的新位置。

如果表单有效,我将保存在会话中的该集合添加到持有此集合的实体。

如果表单无效,则会显示文件,因为我从会话中检索了该特定集合。即使当我使用GET重新访问该页面时,也会显示所有上传的文件。

如果我在视图中删除了一个文件,我在输入字段中放置了一个删除的唯一ID列表。所以提交后,我检查我应该从数组中删除哪些文件。

我想,我的回答是我的问题:)

+1

你能告诉来源吗? –

3

我做了以下解决方案,目前还不清楚。您可以根据自己的需求进行调整。但是您需要额外的命令清理uploads/tmp目录中的旧文件。你需要根据参数部分的两个参数在配置:

parameters: 
    uploads_dir: %kernel.root_dir%/../web/uploads 
    uploads_tmp_dir: %uploads_dir%/tmp 

形式:

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder 
     ->add('file',ImageFileType::TYPE_NAME,array(
      'fileField' => 'file', 
      'pathField' => 'path', 
      'required' => false, 
      'label' => 'makeswapping.form.single_image', 
      'imgclass' => 'tumbnail imgbox full-width', 
      'constraints' => array(
       new Assert\Image(array(
        'minWidth' => '440' 
        )) 
      ) 
     )); 

    $container = $this->container; 

    $builder->addEventListener(
     FormEvents::PRE_SUBMIT, 
     function (FormEvent $event) use ($container) { 

      $form = $event->getForm(); 
      $data = $event->getData(); 

      $uploadsTmpDir = $container->getParameter('uploads_tmp_dir'); 
      if (isset($data['file'])) { 
       $filename = sprintf('%s.%s', uniqid('tmp_'), $data['file']->getClientOriginalExtension()); 
       if (!file_exists($uploadsTmpDir)) { 
        mkdir($uploadsTmpDir, 0755, true); 
       } 
       copy($data['file']->getRealPath(), $uploadsTmpDir . '/' . $filename); 
       $form->add('file_hidden', 'hidden', array(
        'mapped' => false, 
        'required' => false, 
        'empty_data' => $filename, 
       )); 
      } else if (!isset($data['file']) && isset($data['file_hidden'])) { 
       $fileInfo = new \SplFileInfo($uploadsTmpDir . '/' . $data['file_hidden']); 

       $mimeTypeGuesser = MimeTypeGuesser::getInstance(); 
       $uploadedFile = new UploadedFile(
        $fileInfo->getRealPath(), 
        $fileInfo->getBasename(), 
        $mimeTypeGuesser->guess($fileInfo->getRealPath()), 
        $fileInfo->getSize(), 
        null, 
        true 
       ); 

       $form->add('file_hidden', 'hidden', array(
        'mapped' => false, 
        'required' => false, 
        'empty_data' => $data['file_hidden'], 
       )); 

       $form->get('file')->setData($uploadedFile); 
       $data['file'] = $uploadedFile; 
       $event->setData($data); 
      } 
     } 
    ); 
}