I need to upload images using symfony, but ive not been able to do it using my form...
A simplified model is:
Offer:
columns:
id:
name:
pic:
flyer:
description:
.
.
.
relations:
Picture:
local: pic
foreign: id
type: one
Picture_2:
class: Picture
local: flyer
foreign: id
type: one
Picture:
columns:
id:
path:
name:
.
.
.
Now, im using a form that extends OfferForm, since I need my form to have file widgets instead of a choice widget for the fields 'pic' and 'flyer'. In the saving process, then, i need to create two instances of 'Picture' to create the two Picture objects associated to this Offer.
I have not managed to find good and complete documentation on uploading files... or at least not to my case... every tutorial or article magically uses the $form->save() method, and all goes fine!, but i have had multiple errors while doing this...
this is my form class:
class myOfferForm extends OfferForm {
protected $statusChoices = array(
'A' => 'Active',
'E' => 'Expired',
);
protected $validStatus = array('A','E');
public function configure() {
parent::configure();
$this->setWidgets(array(
'id' => new sfWidgetFormInputHidden(),
'name' => new sfWidgetFormInputText(),
'picFile' => new sfWidgetFormInputFileEditable(array(
'file_src' => $this->getObject()->getPicFileSrc(),
'is_image' => true,
'with_delete' => !is_null($this->getObject()->getPicFileSrc())
)),
'flyerFile' => new sfWidgetFormInputFileEditable(array(
'file_src' => $this->getObject()->getFlyerFileSrc(),
'is_image' => true,
'with_delete' => !is_null($this->getObject()->getFlyerFileSrc())
)),
'from' => new sfWidgetFormDate(array(
'format' => '%day%/%month%/%year%',
'can_be_empty' => false,
'default' => date('Y/m/d')
)),
'to' => new sfWidgetFormDate(array(
'format' => '%day%/%month%/%year%',
'can_be_empty' => false,
'default' => date('Y/m/d')
)),
'description' => new sfWidgetFormTextarea(),
'status' => new sfWidgetFormChoice(array(
'choices' => $this->statusChoices)),
'products' => new sfWidgetFormDoctrineChoice(array(
'model' => 'Product',
'table_method' => 'getActivesOrderedByName',
'add_empty' => 'Check associated products',
'multiple' => true,
)
),
));
$this->widgetSchema->setLabels(array(
'id' => '',
'name' => 'Name *:',
'picFile' => 'Picture *:',
'flyerFile' => 'Flyer *:',
'from' => 'Valid From *:',
'to' => 'Valid To *:',
'description' => 'Description :',
'status' => 'Status *:',
'products' => 'Associated Products :',
));
$this->setValidators(array(
'id' => new sfValidatorChoice(array(
'choices' => array($this->getObject()->get('id')),
'empty_value' => $this->getObject()->get('id'),
'required' => false,
)),
'name' => new sfValidatorString(),
'picFile' => new sfValidatorFile(array(
'required' => false,
'mime_types' => 'web_images',
'path' => WebPromocion::getStaticDirPath().'/',
'validated_file_class' => 'OfferValidatedFile',
)),
'flyerFile' => new sfValidatorFile(array(
'required' => false,
'mime_types' => 'web_images',
'path' => WebPromocion::getStaticDirPath().'/',
'validated_file_class' => 'OfferValidatedFile',
)),
'from' => new sfValidatorDate(),
'to' => new sfValidatorDate(),
'description' => new sfValidatorString(),
'status' => new sfValidatorChoice(array(
'choices' => $this->validStatus,
'required' => true,
)),
'products' => new sfValidatorDoctrineChoice(array(
'required' => false,
'model' => 'Product',
'column' => 'id',
'multiple' => true, )),
));
$this->validatorSchema['fotoFile_delete'] = new sfValidatorPass();
$this->validatorSchema['flyerFile_delete'] = new sfValidatorPass();
$this->widgetSchema->setIdFormat('offer_form_%s');
$this->widgetSchema->setNameFormat('offer[%s]');
}
}
The OfferValidatedFile class:
class OfferValidatedFile extends sfValidatedFile {
/**
* Generates a random filename for the current file, in case
* it already exists.
*
* @return string A convenient name to represent the current file
*/
public function generateFilename()
{
$filename = $this->getOriginalName().$this->getExtension($this->getOriginalExtension());
if (file_exits(WebPromocion::getStaticDirSrc().$filename)) {
return sha1($this->getOriginalName().rand(11111, 99999)).$this->getExtension($this->getOriginalExtension());
} else {
return $filename;
}
}
}
And, in my action, I am doing, along with other stuff:
$this->form->save()
There is a problem. The Offer object does not have any existing Picture object to be associated with by the time the form is saved....
I think the main problem is that i want to use one form to handle submition of information related to two different objects.
So, what am I doing wrong? what am I not doing? Does someone knows a complete documentation on this subject that i could use? Is there a clean symfonian way to do this?