You must first sign up to be able to contribute.

Version 2 (modified by cocomiel, 8 years ago)
Fixed small typo in the code

How to rename a file after uploading it ?

In this example you will see how to upload a file and rename if afterwards. In the new file name you will optionally be able to include properties of the object you are saving.

Imagine you have a Swimsuit class. This class can hold an image but after you upload it you want the filename to contain the Swimsuit id.

Start by setting up your form and overriding the save() method

// lib/form/doctrine/SwimsuitForm.class.php

class SwimsuitForm extends BaseSwimsuitForm

  public function configure ()
    $this->widgetSchema['image'] = new sfWidgetFormInputFileEditable(
    'label' => 'Foto',
    'file_src' => '/uploads/' . $this->getObject()->getImage(),
    'is_image' => true,
    'edit_mode' => ! $this->isNew(),
    'template' => '<div>%file%<br />%input%<br />%delete_label% %delete%</div>'

    $this->validatorSchema['image'] = new sfValidatorFile(array(
    'required' => false,
    'path' => sfConfig::get('sf_upload_dir'),
    'mime_types' => 'web_images',
    'validated_file_class' => 'SwimsuitValidatedFile'

    $this->validatorSchema['image_delete'] = new sfValidatorPass();

  public function save ($con = null)
    // Get the uploaded image
    $image = $this->getValue('image');
    $swimsuit = $this->getObject();

    if ($image)
      $image->save('swimsuit_' . $swimsuit->getId() . '.jpg');

    return parent::save($con);


First thing to note is that you are passing a validated_file_class option to your sfValidatorFile. This enables you to use your own custom class to validate the file.

The second thing to note is the use of the getObject() method to get a reference to the object about to be inserted in the database.

Next, you need to extend the sfValidatedFile class to match your requirements.

// lib/validator/SwimsuitValidatedFile.php

class SwimsuitValidatedFile 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);

The method SwimsuitValidatedFile::save() actually gets executed twice; once in your overriden SwimsuitForm::save() method and once in the original BaseSwimsuitForm::save() method. That is why you need to store the filename that gets passed to it the first time and the use that.