How do I retain the Original Filename After upload in Symfony

markb picture markb · Jan 25, 2010 · Viewed 12.6k times · Source

Users from the backend application can upload files and publish them to the frontend. Using sfWidgetFormInputFile and sfValidatorFile, I would like to keep the original filename instead of the default functionality of a random string (i.e. Meaningful_filename.docx instead of a4b25e9f48cfb6268f34b691fc18cd76fefe96b5.docx - numbers can be appended onto duplicate names). This can be useful in scenarios where the user downloads several files and would not be able to tell them apart from the file name.

$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.'
));

Is there native functionality in the sfWidgetFormInputFile widget or is there another solution to this?

Answer

Felix Kling picture Felix Kling · Jan 26, 2010

You get the file by calling $form["file_name"]->getValue(). This gives you an object of class sfValidatedFile where you can call the method getOriginalName().


To define how the file should be save you can do this: The sfValidatorFile class accepts an option which sfValidatedFile class to use:

validated_file_class: Name of the class that manages the cleaned uploaded file (optional)

The sfValidatedFile class has a method save that calls a method generateFileName. Subclass this class and overwrite this method:

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;
    }
}

Here is the function from the original class:

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

Then you set up the validator this way:

$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.')
);

Hope that helps!