Reputation: 4038
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?
Upvotes: 0
Views: 1948
Reputation: 2837
This documentation is for the version of symfony and doctrine you're using. Unfortunately, rather than outlining initial setup for you, they include an installer script. Note that this type of setup is outlined elsewhere in both 'A Gentle Introduction to Symfony' as well as in other parts of 'More with Symfony' for version 1.4. Fortunately there is also a fairly verbose look at refactoring the script's form class in the first link which I think would benefit you quite a bit as well - It explains the model's processing of the form (Where you appear to be having issues) quite well, which may make debugging a little less mystifying for you.
I recommend giving it a good read. I followed this for a project a few months ago and came out of it without any issues.
Upvotes: 1