2010-01-25 81 views
14

來自後端應用程序的用戶可以上傳文件並將其發佈到前端。使用sfWidgetFormInputFile和sfValidatorFile,我想保留原始文件名而不是隨機字符串的默認功能(即Meaningful_filename.docx而不是a4b25e9f48cfb6268f34b691fc18cd76fefe96b5.docx - 可以將數字附加到重複名稱上)。這在用戶下載多個文件並且無法將它們與文件名分開的情況下很有用。如何在Symfony中上傳後保留原始文件名

$this->widgetSchema['file_name'] = new sfWidgetFormInputFile(array('label' => 'File')); 

$this->validatorSchema['file_name'] = new sfValidatorFile(array(
    'required' => true, 
    'path'  =>  sfConfig::get('sf_upload_dir').DIRECTORY_SEPARATOR.sfConfig::get('app_dir_file_sharing').DIRECTORY_SEPARATOR, 
'mime_types' => array('application/msword', 
        'application/vnd.ms-word', 
        'application/msword', 
        'application/msword; charset=binary') 
), array(
    'invalid' => 'Invalid file.', 
    'required' => 'Select a file to upload.', 
    'mime_types' => 'The file must be a supported type.' 
)); 

有沒有在sfWidgetFormInputFile插件機功能或有另一種解決方案呢?

回答

22

您通過致電$form["file_name"]->getValue()獲取該文件。這會給你一個類sfValidatedFile的對象,你可以在這裏調用方法getOriginalName()


要定義文件應該如何救你可以這樣做: 的sfValidatorFile類接受一個選項,使用哪個sfValidatedFile類:管理清潔上傳類的名稱:

validated_file_class文件(可選)

sfValidatedFile類有一個方法save調用一個方法generateFileName。此類子類,並覆蓋此方法:

class CustomValidatedFile extends sfValidatedFile { 
    /** 
     * Generates a random filename for the current file. 
     * 
     * @return string A random name to represent the current file 
     */ 
    public function generateFilename() 
    { 
     return 'foo bar'// your custom generated file name; 
    } 
} 

下面是從原始類的功能:

public function generateFilename() 
{ 
    return sha1($this->getOriginalName().rand(11111, 99999)).$this->getExtension($this->getOriginalExtension()); 
} 

然後你設置了驗證這種方式:

$this->validatorSchema['file_name'] = new sfValidatorFile(array(
     'required' => true, 
     'path' => 'yourpath', 
     'validated_file_class' => 'CustomValidatedFile', 
     'mime_types' => array('application/msword', 
          'application/vnd.ms-word', 
          'application/msword', 
          'application/msword; charset=binary') 
    ), 
    array('invalid' => 'Invalid file.', 
      'required' => 'Select a file to upload.', 
      'mime_types' => 'The file must be a supported type.') 
); 

希望幫助!

+3

我知道這是非常古老的,大多數人可能會得到它,但對於那些有問題的人,不要忘記你需要擴展sfValidatedFile:「類CustomValidatedFile擴展sfValidatedFile」,而不僅僅是保存它。 – Dandy 2011-01-10 23:09:24

+0

@Dan:我想我會最終修復代碼。以防萬一;)謝謝! – 2011-07-10 18:55:55

1

根據Symfony文檔「sfValidatorFile驗證程序驗證上傳的文件。驗證程序將上傳的文件轉換爲sfValidatedFile類的實例,或者如果設置了validated_file_class選項,則將其轉換爲實例。 (來源:http://www.symfony-project.org/forms/1_4/en/B-Validators#chapter_b_sub_sfvalidatorfile

雖然sfValidatedFile類立即重命名文件,但您可以通過將validated_file_class設置爲自定義類並擴展sfValidatedFile來覆蓋此函數。

在您的自定義驗證文件類中,將您的自定義文件名傳遞給save()方法。 「如果你沒有傳遞文件名,它將由generateFilename方法生成。」 (來源: http://www.symfony-project.org/api/1_4/sfValidatedFile#method_save

這裏有一種方法可以做到這(來源:http://forum.symfony-project.org/index.php/m/90887/#msg_90887)...

自定義驗證文件類:

// lib/validator/myValidatedFile.php 
class myValidatedFile extends sfValidatedFile { 
    private $savedFilename = null; 

    // Override sfValidatedFile's save method 
    public function save($file = null, $fileMode = 0666, $create = true, $dirMode = 0777) { 
    // This makes sure we use only one savedFilename (it will be the first) 
    if ($this->savedFilename === null) $this->savedFilename = $file; 

    // Let the original save method do its magic :) 
    return parent::save($this->savedFilename, $fileMode, $create, $dirMode); 
    } 
} 

確保設置'validated_file_class' => 'myValidatedFile'爲sfWidgetFormInputFile 。並設置文件名將在Form的保存方法中的邏輯。

+0

在這個例子中,你會在哪裏設置私有類var $ savedFilename? – codecowboy 2010-12-21 16:32:22

5

經過一番研究:

雖然可以延長sfValidatedFile並覆蓋generateFilename我發現sfFormPropel檢查基於該模型來命名文件列名的方法的存在。

從symfony中/插件/ sfPropelPlugin/lib中/表格行292:

$method = sprintf('generate%sFilename', $column); 
if (null !== $filename) 
{ 
    return $file->save($filename); 
} 
else if (method_exists($this, $method)) 
{ 
    return $file->save($this->$method($file)); 
} 

因此,如果您的列名爲FILE_NAME,該方法查找generateFileNameFilename在窗體類的存在。這樣你只需要添加一個方法到你的表單類,而不是擴展sfValidatedFile小部件。例如,我的函數使用如果不採取它原來的名稱,否則添加一個序列號(一個方法是遞歸查詢生成的文件名):

public function generateFileNameFilename($file = null) 
{ 
    if (null === $file) { 
    // use a random filename instead 
    return null; 
    } 

    if (file_exists($file->getpath().$file->getOriginalName())) { 
    return $this->appendToName($file); 
    } 

    return $file->getOriginalName(); 
} 

public function appendToName($file, $index = 0) 
{ 
    $newname = pathinfo($file->getOriginalName(), PATHINFO_FILENAME).$index.$file->getExtension(); 

    if (file_exists($file->getpath().$newname)) { 
     return $this->appendToName($file, ++$index); 
    } else { 
     return $newname; 
    } 
} 

我找不到這個文件symfony的API中任何地方,這就是爲什麼它需要一些搜索代碼庫找到。如果你在很多地方使用這個方法,擴展sfValidatedFile也是一個不錯的選擇。

+0

對於Doctrine也是有效的。 – neuromancer 2011-07-13 09:01:18

相關問題