Рецепт только для Symfony 1.2. На других версиях не проверялся.
При работе с формами, если требуется сохранить файлы, то в БД пишется только имя загружаемого файла, например: fa3d2c687c04e411372045106.jpg. Мне удобнее сохранить в БД относительный путь к картинке, так легче работать на выводе, например: /uploads/news/2008/10/16/fa3d2c687c04e411372045106.jpg. Для решения этой задачи требуется указать желаемый путь к директории $this->path в классе NewsForm и переназначить метод saveFile, который используется для записи имени файла в БД. Единственное, что перестанет работать удаление файлов, т.к. путь получается неверный, чтобы это исправить расширяем базовый класс BaseFormPropel и корректируем путь к файлам. Полагаю, что то же самое сработает и для Doctrine.
Листинг 1: Изменяем класс NewsForm.class.php, чтобы переназначить пути к файлам
<?php
/**
* News form.
*/
class NewsForm extends BaseNewsForm
{
public function configure()
{
parent::configure();
$this->path = 'news/' . date('Y/m/d');
$this->setWidget('image', new sfWidgetFormInputFileEditable(array(
'file_src' => '-foo-',
'is_image' => true
)));
$this->validatorSchema['image'] = new myValidatorFile(array(
'required' => false,
'mime_types' => 'web_images',
'path' => sfConfig::get('sf_upload_dir') . $this->path,
));
$this->validatorSchema->setOption('allow_extra_fields', true);
$this->validatorSchema->setOption('filter_extra_fields', false);
}
public function saveFile($field, $filename = null, sfValidatedFile $file = null)
{
return '/uploads/' . $this->path . '/' . parent::saveFile($field, $filename, $file);
}
}
Листинг 2: Изменяем класс BaseFormPropel.class.php, чтобы сработало удаление файлов
<?php
abstract class BaseFormPropel extends sfFormPropel
{
public function setup()
{
}
/**
* Removes the current file for the field.
*
* @param string $field The field name
*/
protected function removeFile($field)
{
if (!$this->validatorSchema[$field] instanceof sfValidatorFile)
{
throw new LogicException(sprintf('You cannot remove the current file for field
"%s" as the field is not a file.', $field));
}
$column = call_user_func(array(constant(get_class($this->object).'::PEER'), 'translateFieldName'),
$field, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_PHPNAME);
$getter = 'get'.$column;
if (($directory = sfConfig::get('sf_web_dir')) && is_file($directory.$this->object->$getter()))
{
unlink($directory.$this->object->$getter());
}
}
}
Другие ссылки:
• The symfony Forms Book: Chapter 4 – Propel Integration
• SYMFONY 1.2: UPLOAD A FILE INSIDE AN EMBEDDED FORM


