there is a simple definition:
notifications:
_attributes: { phpName: Notifications, noXsd: false, defaultIdMethod: none, package: lib.model }
auction_id: { type: integer, size: '10', primarykey: true, required: true, defaultvalue: '0', foreignTable: auctions, foreignReference: id, onDelete: cascade, onUpdate: cascade }
alertwhenitsover: { type: tinyint, size: '1', required: true, defaultvalue: '0' }
but it always adds auto increment field... darn I dont want it! How to tell to symfony not to add it?
Related
I have two issues, need some help with.
I have a table which is referenced by a foreign key to a second table:
member_child:
_attributes: { phpName: MemberChild }
id: { type: INTEGER, size: '11', primaryKey: true, autoIncrement: true, required: true }
member_id: { type: INTEGER, size: '11', required: true, foreignTable: member, foreignReference: id }
child_id: { type: INTEGER, size: '11', required: true, foreignTable: child, foreignReference: id }
and child:
child:
_attributes: { phpName: Child }
id: { type: INTEGER, size: '11', primaryKey: true, autoIncrement: true, required: true, onDelete: cascade }
username: { type: VARCHAR, size: '45', required: true, defaultValue: '' }
display: { type: TINYINT, size: '1', required: true, defaultValue: '1' }
...etc
(obviously this is propel)
Now, when I want to create a child object, using a form, I need to do two things:
On submit, submit a member id
override the doSave function so when the child is created, I can also create the member_child object
How can I accomplish these issues?
I agree, you can use embedForm like pankar said. Also you can override save method of your forms like this:
$this->childForm = new ChildForm();
$this->childMemberForm = new ChildMemberForm();
//binding, checking if form was sent etc.
if ($this->childForm->isValid() && $this->childMemberForm->isValid())
{
//save method should return saved object
$childObject = $this->childForm->save();
//therefore this id could be used by next object
$this->childMemberForm->save(childObject->getId());
}
I hope that will help you!
You can always use the built-in Symfony feature sfForm::embedForm in your parent form in order to save the child one, but I haven't figure out a a way of properly get this working.
One post I came across some time ago actually did provide me with the solution. Have a look and see if it fits your needs. Of course it's in Doctrine but I suppose it can be easily ported in Propel
I've got a little problem with many to many relations on the same table using Symfony 1.4 with the Propel ORM. My schema.yml looks like this:
propel:
item:
_attributes: { phpName: Item }
id: { phpName: Id, type: INTEGER, size: '10', primaryKey: true, autoIncrement: true, required: true }
type_id: { phpName: TypeId, type: INTEGER, size: '11', required: true, foreignTable: type, foreignReference: id, onDelete: RESTRICT, onUpdate: RESTRICT }
owner_id: { phpName: OwnerId, type: INTEGER, size: '11', required: true, foreignTable: owner, foreignReference: id, onDelete: RESTRICT, onUpdate: RESTRICT }
place_id: { phpName: PlaceId, type: INTEGER, size: '11', required: true, foreignTable: place, foreignReference: id, onDelete: RESTRICT, onUpdate: RESTRICT }
picture_id: { phpName: PictureId, type: INTEGER, size: '11', required: false, foreignTable: picture, foreignReference: id, onDelete: RESTRICT, onUpdate: RESTRICT }
supplier_id: { phpName: SupplierId, type: INTEGER, size: '11', required: false, foreignTable: supplier, foreignReference: id, onDelete: RESTRICT, onUpdate: RESTRICT }
name: { phpName: Name, type: VARCHAR, size: '255', required: true }
amount: { phpName: Amount, type: INTEGER, size: '11', required: true }
wished_amount: { phpName: WishedAmount, type: INTEGER, size: '11', required: true }
costs: { phpName: Costs, type: DECIMAL, size: '7', scale: '2', required: true }
description: { phpName: Description, type: LONGVARCHAR, required: false }
use_until: { phpName: UseUntil, type: DATE, required: false }
last_used: { phpName: LastUsed, type: TIMESTAMP, required: false }
last_updated: { phpName: LastUpdated, type: TIMESTAMP, required: false }
_indexes: { item_FI_1: [type_id], item_FI_2: [owner_id], item_FI_3: [place_id], item_FI_4: [picture_id], item_FI_5: [supplier_id] }
item_has_item:
item_id: { type: INTEGER, required: true, foreignTable: item, foreignAlias: item, foreignReference: id, primaryKey: true}
parent_item_id: { type: INTEGER, required: true, foreignTable: item, foreignAlias: parent_item, foreignReference: id, primaryKey: true}
_indexes: { item_has_item_FKIndex1: [item_id], item_has_item_FKIndex2: [parent_item_id] }
However, the needed admin_double_list in the admin generator does not appear automatically. It does, when the second foreignTable is adjusted to another table, for example sf_guard_user. I've read that this could be fixed in Propel 1.3, but I don't know which Propel version is included with Symfony 1.4.
I hope I gave enough information for my problem to be solved by you guys. Otherwise I will have to make another table which holds the items that have child item, like this:
Item <---- Item_has_item <---- Combined_item
EDIT AFTER REACTION FROM j0k
After the reaction from j0k, I did update the sfPropelORMPlugin, and it did recognise the relation. However, I still got an error while saving (only when a relation is made):
Unable to execute INSERT statement [INSERT INTO `item_has_item` (`ITEM_ID`) VALUES (:p0)]
[wrapped: SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a
child row: a foreign key constraint fails (`SI/item_has_item`, CONSTRAINT
`item_has_item_FK_1` FOREIGN KEY (`parent_item_id`) REFERENCES `item` (`id`))]
I have found, after a long extensive search, that the form generator fails to correctly understand the many-to-many relation on the same table. In the function saveItemHasItemList($con = null):
$c = new Criteria();
$c->add(ItemHasItemPeer::ITEM_ID, $this->object->getPrimaryKey());
ItemHasItemPeer::doDelete($c, $con);
$values = $this->getValue('item_has_item_list');
if (is_array($values))
{
foreach ($values as $value)
{
$obj = new ItemHasItem();
$obj->setItemId($this->object->getPrimaryKey());
$obj->setItemId($value);
$obj->save();
}
}
As you can see, the ItemId is twice set, while the ParentItemId is not set, hence the constraint value. It should be generated as:
$c->add(ItemHasItemPeer::ITEM_ID, $this->object->getPrimaryKey());
$c->add(ItemHasItemPeer::PARENT_ITEM_ID, $this->object->getPrimaryKey());
&&
$obj->setParentItemId($this->object->getPrimaryKey());
$obj->setItemId($value);
This solves the saving problem, however, it still does not show the already selected relations. To solve that, you should also change the updateDefaultsFromObject():
foreach ($this->object->getItemHasItemsRelatedByItemId() as $obj)
Should be:
foreach ($this->object->getItemHasItemsRelatedByParentItemId() as $obj)
Remember, these functions are located in form/base/BaseItemForm.class.php, but the functions should be overwritten in /form/ItemForm.class.php.
I believe this is an Propel bug, so I will post it tomorrow on the Propel TRAC.
If you are using the last symfony 1.4, it uses Propel 1.4.2.
You should try to use a new version of the Propel Plugin. It uses Propel 1.6.
Symfony 1.4
Propel (with sfPropel15Plugin)
I have a multilanguage Gallery with the following schema:
# Galleries
pi_gallery:
_attributes:
phpName: Gallery
isI18N: true
i18nTable: pi_gallery_i18n
_propel_behaviors:
sortable: ~
id: ~
active:
type: boolean
default: true
required: true
created_at: ~
updated_at: ~
pi_gallery_i18n:
_attributes:
phpName: GalleryI18n
id:
type: integer
foreignTable: pi_gallery
foreignReference: id
required: true
primaryKey: true
onDelete: cascade
culture:
isCulture: true
type: varchar
size: 7
required: true
primaryKey: true
name:
type: varchar
size: 255
required: false
description:
type: longvarchar
required: false
# Images
pi_gallery_image:
_attributes:
phpName: GalleryImage
isI18N: true
i18nTable: pi_gallery_image_i18n
id: ~
gallery_id:
type: integer
foreignTable: pi_gallery
foreignReference: id
required: true
image:
type: varchar
size: 255
required: true
created_at: ~
updated_at: ~
pi_gallery_image_i18n:
_attributes:
phpName: GalleryImageI18n
id:
type: integer
foreignTable: pi_gallery_image
foreignReference: id
required: true
primaryKey: true
onDelete: cascade
culture:
isCulture: true
type: varchar
size: 7
required: true
primaryKey: true
description:
type: varchar
size: 255
required: false
I'm trying to embed the Image forms in the Gallery using the following:
# GalleryForm.class
public function configure()
{
unset(
$this['alias'],
$this['created_at'],
$this['updated_at']
);
$this->widgetSchema['article_id']->setOption('renderer_class', 'sfWidgetFormPropelJQueryAutocompleter');
$this->widgetSchema['article_id']->setOption('renderer_options', array(
'model' => 'Article',
'url' => '/article/ajax'
));
$this->validatorSchema['article_id'] = new sfValidatorPass();
$this->embedI18n(array('es', 'en', 'de', 'it', 'fr'));
$this->widgetSchema->setLabel('en','English');
$this->widgetSchema->setLabel('es','EspaƱol');
$this->widgetSchema->setLabel('de','Deutsch');
$this->widgetSchema->setLabel('it','Italiano');
$this->widgetSchema->setLabel('fr','Francais');
$this->embedRelation('GalleryImage'); // Embeds the Relation between the GalleryImage model and the Gallery Model
}
# GalleryImageForm.class:
public function configure()
{
unset(
$this['created_at'],
$this['updated_at'],
$this['gallery_id'],
$this['sortable_rank']
);
if ($this->isNew()) unset($this['id']);
$this->embedI18n(array('es', 'en', 'de', 'it', 'fr'));
$image = $this->getObject()->getImage();
$template = (!is_null($image) || $image != "") ? '<div>%file%<br />%input%<br />%delete% %delete_label%</div>' : '';
$this->widgetSchema['image'] = new sfWidgetFormInputFileEditable(array(
'label' => 'Imagen',
'file_src' => '/'.sfConfig::get('sf_upload_dir_name').'/images/galleries/thumbs/'.substr($this->getObject()->getImage(),0,-4) . '.jpg',
'is_image' => true,
'edit_mode' => !$this->isNew() && $image != "",
'with_delete' => true,
'delete_label'=>'Eliminar archivo existente',
'template' => $template
));
$this->validatorSchema['image_delete'] = new sfValidatorPass();
$this->validatorSchema['image'] = new sfValidatorFile(array(
'path' => sfConfig::get('sf_upload_dir').'/images/galleries',
'required' => false,
'mime_types' => 'web_images'
));
}
This appears to embed the forms as expected ... initially. The GalleryForm appears with Multilanguage Descriptions and the ImageForms embed beneath them. So far so good.
Saving the form however shows that all is not good.
Two records are saved initially, one with just the image and the other with just the i18n fields. The i18n fields also have the id of the second record added so there is no way of relating the image to the i18n fields. Maybe the order of saving the forms is wrong?
Has anyone successfully got a form to work that embeds I18n in an embedded Relation? Or does anyone have any idea of a workaround? I've read about something about overriding saveEmbeddedForms but I don't even know where to start with that.
Any help appreciated.
Fixed in the sfPropelORMPlugin:
https://github.com/propelorm/sfPropelORMPlugin/issues/13
https://github.com/propelorm/sfPropelORMPlugin/pull/76
https://github.com/propelorm/sfPropelORMPlugin/issues/38
I have article admin module and a tag module
Tags are simply a single tag per row item
What I'd like to do is to embed the list of all the tags (as checkboxes) into my article module
Could I do this with embedded forms?
EDIT:
This is my schema:
article:
id: ~
title: { type: VARCHAR, size: '255', required: true }
tags: { type: VARCHAR, size: '500' }
created_at: { type: TIMESTAMP, required: true }
updated_at: { type: TIMESTAMP, required: true }
tag:
id: ~
tag: { type: VARCHAR, size: '500', required: true }
ord_id: { type: INTEGER, required: true }
created_at: ~
updated_at: ~
item_tag:
id: ~
item_id: { type: INTEGER, required: true, foreignTable: item, foreignReference: id, onDelete: cascade }
tag_id: { type: INTEGER, required: true, foreignTable: tag, foreignReference: id, onDelete: restrict }
created_at: ~
item:
id: ~
article_id: { type: INTEGER, foreignTable: article, foreignReference: id, onDelete: cascade }
So when I need the tags to be displayed and will update the above tables
If you have defined the relationship between the article and tags correctly in your model, then the generated Forms should contain tag select widgets.
Search "sfWidgetFormChoice" in the Forms documentation for more information:
http://www.symfony-project.org/jobeet/1_4/Doctrine/en/10
Note: The examples are created using the Doctrine ORM but everything should work the same way with Propel as well.
does embedRelation() (sfPropel15Plugin) works for many-to-many
relationships? If not any experience or tutorial to get that (embed
forms for m:m relations)?
Regards
Javi
schema.yml
product:
id: ~
name: {type: varchar(255), required: true}
price: {type: integer, required: true}
order_list:
id: ~
order_id: {type: integer, required: true, foreignTable: order, foreignReference: id, onDelete: cascade, onUpdate: cascade}
product_id: {type: integer, required: true, foreignTable: product, foreignReference: id, onDelete: cascade, onUpdate: cascade}
order:
id: ~
name: {type: varchar(255), required: true}
Class form:
class OrderForm extends BaseOrderForm
{
public function configure()
{
$this->embedRelation('OrderList');
}
}
Add it look like: