sfValidatedFile related components native behavior [message #90043] |
Tue, 15 December 2009 14:52  |
lightpriest Messages: 6 Registered: January 2009 |
Junior Member |
|
|
In my current project (V:1.4 branch, ORM: Doctrine), I'm using sfValidatorFile which must accept a "path" in its options.
This has an annoying behavior since I can't control the generated filename (supposed I want a constant one).
The object of sfValidatorFile is a field in the database so when the model's save is executed (in-turn) it executes the save method of sfValidatedFile.
Failing to find any doc about the options I could pass to sfValidatorFile, I've followed the code execution to find which options I could pass that would affect the sfValidatedFile behavior.
I then realized that one cannot force a constant filename for the file to be saved.
// ../symfony/lib/plugins/sfDoctrinePlugin/lib/form/sfFormDoctrine.class.php
public function processValues($values) {
..
..
if ($this->validatorSchema[$field] instanceof sfValidatorFile)
{
$values[$field] = $this->processUploadedFile($field, null, $valuesToProcess);
}
..
..
}
..
..
..
protected function processUploadedFile($field, $filename = null, $values = null) { .. }
Looking at sfValidatedFile API I saw that it has a "isSaved" funcion.
Thinking this function is handled and used somehow in the sfFormDoctrine (so that it won't save the file twice) I created my own ModelForm::save function that saves that file before the form's save method is called only to find out that it is ignored completely and I always get a hashed filename.
Eventually I created my own validatedFile class that inherits from sfValidatedFile and had to implement the "isSaved" method myself.
Is it possible to add a 'filename' option to sfValidatorFile options array? Or to implement the isSaved method?
I didn't want to open a ticket in symfony's trac because I could just be looking in the wrong place.
I could submit a patch myself, but I'm not that active in this community (i.e. I'm not familiar with the idioms you guys work with) so I don't want to interfere with the great work 
Thanks, in advance.
[Updated on: Tue, 15 December 2009 14:56]
|
|
|
Re: sfValidatedFile related components native behavior [message #90887 is a reply to message #90043 ] |
Wed, 06 January 2010 10:51   |
lightpriest Messages: 6 Registered: January 2009 |
Junior Member |
|
|
I see people are viewing this thread.
In case you got here from some search engine, here's my way to work around this:
Luckily, sfValidatedFile supports saving a desired filename (rather then a generated one) so we just need to make it work.
First, I've created my own sfValidatedFile to override the save method.
Let's name it myValidatedFile and put it in project/lib/validator.
// 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);
}
}
To our form we add a normal sfWidgetFormInputFile (or some other file upload widget) and a normal sfValidatorFile with the validated_file_class option:
// lib/form/ArticleForm.class.php
public function configure() {
$this->widgetSchema['thumbnail'] = new sfWidgetFormInputFile();
$this->validatorSchema['thumbnail'] = new sfValidatorFile(array(
'path' => 'path/of/your/choice',
'validated_file_class' => 'myValidatedFile'
));
}
What we did now was just overriding sfValidatedFile with our own method.
Now let's make it work.
We'll need to override the ArticleForm save method so that we'd save the file before sfFormDoctrine saves it.
// lib/form/ArticleForm.class.php
public function save($con = null) {
// Get the uploaded file
$thumbnail = $this->getValue('thumbnail');
// The form could be posted without uploading a file
if ($thumbnail) {
$thumbnail->save('article_thumb_'.date('Ymd').'.jpg');
}
return parent::save($con);
}
A small explanation.
First, the user requests the form which is configured to use "myValidatedFile" class.
Then, when the user submits the form with a file, the ArticleForm::save method is called.
The ArticleForm::save method calls the validatedFile::save method (which is our method), and it passes along a filename.
The validated file class saves that file name to itself, and calls the original validatedFile::save method to really save the file.
When the real form save happens (in sfFormDoctrine), it calls our class' save method again. Because it remembers the desired filename we selected earlier, it calls sfValidatedFile::save with the filename we wanted.
EDIT: Ofcourse we could save all this work if there was a filename option
[Updated on: Wed, 06 January 2010 10:57]
|
|
|
|
Re: Use an object property as part of the uploaded filename [message #96356 is a reply to message #93311 ] |
Mon, 29 March 2010 05:45  |
jmiridis Messages: 14 Registered: April 2009 |
Junior Member |
|
|
May be I'm missing something here and my post is obsolete, but please let me know if this is the case and where my thinking is wrong.
The sfFormDoctrine::saveFile() method looks for both a form-method and and object-method with the name: generate<field>Filename() and uses the returned string (of the method it finds first) as the filename to store uploaded file under. So I think the following options should resolve the problem as well.
// ArticleForm.class.php
public function generateThumbnailFilename(sfValidatedFile $file)
{
return 'article_thumb_'.date('Ymd').'.jpg';
}
or
// Article.class.php
public function generateThumbnailFilename(sfValidatedFile $file)
{
return sprintf('article_thumb_%s_id_%d.jpg', date('Ymd'), $this->getId());
}
|
|
|