2015-02-24 40 views
4

请帮助我,因为我无法相信我的眼睛。Symfony2简单的文件上传编辑没有实体

我拒绝使用一些第三方插件进行文件上传,并拒绝为文件/文档创建单独的实体。我只想简单的文件上传,我会在Zend/Laravel等等。

我有一张最后一个合并名称“附件”的发票表,我想在这里存储它的消毒名称(例如:123421_filename.jpg),添加表单和上传顺利。

代码在这里:

//AddAction 
    $file=$form['attachment']->getData(); 
     $fileName=$file->getClientOriginalName(); 
     $sanitizedFilename=rand(1, 99999).'_'.$fileName; 
     $dir='files/'.$userId.'/'; 
     $file->move($dir, $sanitizedFilename); 
    ... 
     $invoice->setAttachment($sanitizedFilename); 
     $em = $this->getDoctrine()->getManager(); 
     $em->persist($invoice); 

第一个问题我不知道如何使用编辑形式来解决。我有一个formbuilder

$builder->add('attachment', 'file',array('data_class'=>null)) 

因为我没有一个“对象”为我的文件,因为在我的发票表中我将名称存储为一个字符串,我在这里得到一个错误,我需要强制data_class => null ..这是不好的,因为如果我编辑一个发票在上传字段的前端我得到NULL,而不是链接到发票的当前文件的文件名。

有了:

$builder->add('attachment', 'text') 

我没有得到的文件输入只是一个愚蠢的文本框,但这次在--with了它 - ..名使我该如何解决这个问题?没有Document对象的文件输入小部件和文件名?

第二个问题(我只是在扔掉我所有的应用程序,直到现在开发,并转移到laravel,因为我有很多“这类问题”..在symfony中做简单的事情几乎总是比其他框架更复杂..也许是我的错,我不想遵循指导方针并创建一个文档实体?!如果我想要灵活性并希望以不适合的另一种方式管理我的数据库,该怎么办?所有这些指导原则?)

所以我在编辑表单动作,我上传一个新文件(不要忘记,我有文件设置为$ builder-> add('attachment',file',array( 'data_class'=> null))

我无法从我正在编辑的当前发票中获取附件字符串名称? !

public function editAction($id) 
    .... 
    $invoice = $em->getRepository('AppBundle:Invoice')->find($id); 
    .. 
    if ($form->isValid()) { 

      $oldFileName=$invoice->getAttachment(); //this is null 
      $oldFileName=$invoice->getId(); //this returns the invoice id 
      $oldFileName=$invoice->getValue(); //returns invoice value 

       echo 'old: '.$oldFileName.'<br/>'; 
       exit(); 
    } 

那么有人请告诉我为什么我不能访问我的发票属性?这是一个字符串?

我试图使一个新的实例不过,我觉得,不知怎的,当我创建了$发票对象的形式,它以某种方式联系他从编辑表单

if ($form->isValid()) { 
    $sameInvoice= $em->getRepository('AppBundle:Invoice')->find(20); //hardcoded ID 

        $oldFileName=$sameInvoice->getAttachment(); //still null 
        $oldFileName=$sameInvoice->getId(); //returns 20 
        echo 'old: '.$oldFileName.'<br/>'; 
        exit(); 

我想唯一的办法就是附件,有我的发票表中的一个文件名字符串,如果文件存在于具有该文件名的路径中,并且它存在,然后删除它并上载新的文件等等,那么测试我自己。为什么它必须如此艰难?

为什么我必须创建一个实体?为什么我必须改变我的数据库结构(它不是这里的情况..但如果客户端不希望数据库被改变..所以我不能插入这个“文档”表)..为什么可以'表单构建器显示发票 - >附件中的数据,我知道这是因为他需要一个文件数据并且他不能接受一个字符串,但为什么这些简单任务没有指导原则?

enter image description here

回答

0

好吧,我终于设法得到它的工作:

所以问题为什么它是NULL是因为它做了$发票实例绑定到窗体:

$invoice = $em->getRepository('AppBundle:Invoice')->find($id); 
$form = $this->createForm(new InvoiceType($id), $invoice); 

该块后代码,所有参考如:$ invoice-> getAttachment();

被认为是表单发票对象而不是实际对象,所以基本上在这之后我只能调用诸如“getClientOriginalName()”之类的东西,并且会向我显示我在编辑表单中上传的新文件。

为了解决这个问题我创建了最初存储$发票对象之前那名让绑定到窗体

$invoice = $em->getRepository('AppBundle:Invoice')->find($id); 
    $oldFileName=$invoice->getAttachment(); //this is stil the object here I can see the record from the database 
    $form = $this->createForm(new InvoiceType($id), $invoice); 
    //here the $invoice->getAttachment(); returns null 

所以现在我有旧的名字,我可以测试它像一个变量:

if ($form->isValid()) { 

       $fs=new Filesystem(); 
       $newFile=$form['attachment']->getData(); 
       $newFileName=$newFile->getClientOriginalName(); 

       if($newFileName != $oldFileName) 
       { 
        // if($fs->exists('files/'.$this->getUser()->getId().'/'.$oldFileName)) 
        //  $fs->remove('files/'.$this->getUser()->getId().'/'.$oldFileName); 

        $sanitizedFilename=rand(1, 99999).'_'.$newFileName; 
        $dir='files/'.$this->getUser()->getId().'/'; 
        $newFile->move($dir, $sanitizedFilename); 
        $invoice->setAttachment($sanitizedFilename); 
       } 

       $em->persist($invoice); 
       $em->flush(); 

       return $this->redirect($this->generateUrl('my-invoices')); 
      } 

对于没有出现在编辑发票页我派我的变量视图中的旧文件的文件名的其他问题:

return $this->render('AppBundle:Invoices:edit.html.twig', array(
      'oldFileName' => $oldFileName) 

并将该值添加到使用树枝的输入文件小部件的标签

0

保持冷静。你需要做得更难。

myControllerAction() 
{ 
    // No need for an object, an array works fine 
    $model = array(
     'invoice' => $invoice, 
     'attachment' => null 
    ); 

    $builder = $this->createFormBuilder($model); 

    $builder->setAction($this->generateUrl('cerad_game_schedule_import')); 
    $builder->setMethod('POST'); 

    $builder->add('attachment', 'file'); 
    $builder->add('invoice', new InvoiceType()); 

    $builder->add('import', 'submit', array(
     'label' => 'Import From File', 
     'attr' => array('class' => 'import'), 
    ));   
    $form = $builder->getForm(); 

    $form->handleRequest($request); 

    if ($form->isValid()) 
    { 
     $model = $form->getData(); 
     $file = $model['attachment']; // The file object is built by the form processor 

     if (!$file->isValid()) 
     { 
      $model['results'] = sprintf("Max file size %d %d Valid: %d, Error: %d<br />\n", 
      $file->getMaxFilesize(), // Returns null? 
      $file->getClientSize(), 
      $file->isValid(), 
      $file->getError()); 
      die($model['results']; 
     } 
     $importFilePath = $file->getPathname(); 
     $clientFileName = $file->getClientOriginalName(); 

     // Xfer info to the invoice object and update 

    } 
+0

我不太确定什么$ importFilePath = $ file-> getPathname(); $ clientFileName = $ file-> getClientOriginalName();做..但是,我可以看到这是一个编辑操作或添加操作?我的主要问题是,当我访问编辑发票页面时,我看不到添加发票时所获得的单据的文件名。第二个,我无法从我的数据库中获得当我创建发票时保存的文件名..我的测试类似于“:if($ newFileName!= $ oldFileName)//如果旧文件不是与新的 {删除旧的 } – 2015-02-24 20:37:51

+0

他们都在发票的编辑动作..显示文件名上传从数据库(前端)和..得到$发票 - >附件字段(我已经存储使用发票上传的第一个文件的文件名)..获得该文件名测试,如果它的!=来自编辑表单中的新文件,并且它的!=然后删除旧文件,添加新文件$ file->移动()并使用附件字段中的新文件名更新发票记录 – 2015-02-24 20:49:51

+0

importFilePath是文件上传到服务器的位置,您将打开该路径来读取内容。您的代码使用move()方法importFilePath不是相关的NT。 clientFileName是从客户端上传的任何文件的名称。只是名称,而不是完整的客户端路径。这里全部记录:http://api.symfony.com/2.6/Symfony/Component/HttpFoundation/File/UploadedFile.html。 – Cerad 2015-02-24 21:03:11