symfony: forms with some fields related each other - symfony1

I've got this schema.yml
Region:
columns:
name: { type: string(255), notnull: true, unique: true }
options:
symfony: { form: false, filter: false }
Province:
columns:
id: { type: string(2), notnull: true, primary: true }
name: { type: string(255), notnull: true, unique: true }
region_id: { type: integer, notnull: true }
relations:
Region: { local: region_id, foreign: id, onDelete: CASCADE, foreignAlias: Provinces }
options:
symfony: { form: false, filter: false }
City:
columns:
id: { type: string(4), notnull: true, primary: true }
name: { type: string(255), notnull: true, unique: true }
province_id: { type: string(2), notnull: true }
latitude: { type: decimal, scale: 6, size: 8, notnull: true }
longitude: { type: decimal, scale: 6, size: 8, notnull: true }
relations:
Province: { local: province_id, foreign: id, onDelete: CASCADE, foreignAlias: Cities }
options:
symfony: { form: false, filter: false }
I would like to make a form that has got these fields related each other: I choose the region in a dropdown menu, then in the next dropdown menu I can choose between provinces of selected region, then in the last dropdown menu I can see only cities of the province previously selected.
I've no idea on how to do this... could you please help me?

you can use this plugin its so helpful
http://www.symfony-project.org/plugins/sfDependentSelectPlugin

Related

Symfony get records from category and subcategory

I use symfony 1.4.15 with doctrine. And I have category and subcategory:
Category:
actAs:
Timestampable: ~
Sluggable:
unique: true
canUpdate: true
fields: [name]
builder: [myTools, StripText]
I18n:
fields: [name]
columns:
name: { type: string(255), notnull: true }
Subcategory:
actAs:
Timestampable: ~
Sluggable:
unique: true
canUpdate: true
fields: [name]
builder: [myTools, StripText]
I18n:
fields: [name]
columns:
category_id: { type: integer() }
name: { type: string(255), notnull: true }
relations:
Category: { onDelete: CASCADE,local: category_id , foreign: id }
And I have product. Product has relations with category and subcategory.
Product:
actAs:
Timestampable: ~
Sluggable:
unique: true
canUpdate: true
fields: [name]
builder: [myTools, StripText]
I18n:
fields: [name,description,shortbody,meta_keywords,meta_description]
columns:
partner_id: { type: integer() }
active: { type: boolean, default: 0, notnull: false }
name: { type: string(255), notnull: true }
shortbody: { type: string(500), notnull: true }
description: { type: string(), notnull: true }
reference: { type: string(100), notnull: true }
code: { type: string(100), notnull: true }
delivery_period: { type: string(100), notnull: true }
shipping_volume: { type: string(100), notnull: true }
weight: { type: string(100), notnull: true }
packing: { type: string(100), notnull: true }
package_dimensions: { type: string(100), notnull: true }
type_of_packaging: { type: string(100), notnull: true }
video_url: { type: string(100), notnull: false }
meta_keywords: { type: string(255) }
meta_description: { type: string(255) }
relations:
Subcategory: { local: product_id , foreign: subcategory_id, refClass: ProductSubcategory }
Category: { local: product_id , foreign: category_id, refClass: ProductCategory }
Partner: { local: partner_id , foreign: id, onDelete: CASCADE }
ProductSubcategory:
connection: doctrine
columns:
subcategory_id: { type: integer(), primary: true}
product_id: { type: integer(), primary: true }
relations:
Product: { onDelete: CASCADE,local: product_id, foreign: id }
Subcategory: { onDelete: CASCADE,local: subcategory_id, foreign: id }
ProductCategory:
connection: doctrine
columns:
category_id: { type: integer(), primary: true}
product_id: { type: integer(), primary: true }
relations:
Product: { onDelete: CASCADE,local: product_id, foreign: id }
Category: { onDelete: CASCADE,local: category_id, foreign: id }
So I need to get all products from subcategory and category(one query for it)
I can get all product that belongs to category:
$q = $this->createQuery('a')
->andWhere('a.active=1')
->leftJoin('a.ProductCategory o')
->andWhere('o.Category_id=?',$category_id)
->addORDERBY ('created_at DESC');
But I do not now how to get all product from all subcategories of category....Thank you!
1) are you aware of the NestedSet behaviour in Doctrine? This should solve the need for your Subcategory table. And it also allows for "deeper categories"
2) In your current model, why does Product have a relation to both Subcategory and Category? The Category can be determined by the Subcategory.
If you fix one of these, it will be a lot easier to implement your query.

Modification of Admin Generator's Doctrine Form layout

I need to modify Admin Generator's Doctrine Form which is included by:
$this->embedRelation('MyRelation');
The default layout looks like this:
The goal - every Item of Select should be displayed as text in separate row, plus Price and Quantity:
schema.yml
Game:
actAs:
Timestampable: ~
columns:
id: { type: integer(4), primary: true, autoincrement: true, unsigned: true }
game_name: { type: string(100), notnull: true }
indexes:
it:
fields: game_name
type: unique
Campaign:
actAs:
Timestampable: ~
columns:
id: { type: integer(4), primary: true, autoincrement: true, unsigned: true }
name: { type: string(100), notnull: true }
is_active: { type: boolean, notnull: true, default: 0 }
start: { type: datetime, notnull: true }
end: { type: datetime, notnull: true }
relations:
CampaignMatrix: { onDelete: CASCADE, local: id, foreign: campaign_id, foreignAlias: CampaignMatrixCampaign }
CampaignGames:
actAs:
Timestampable: ~
columns:
id: { type: integer(4), primary: true, autoincrement: true, unsigned: true }
campaign_id: { type: integer(4), notnull: true, unsigned: true }
game_id: { type: integer(4), notnull: true, unsigned: true }
indexes:
tc:
fields: [campaign_id, game_id]
type: unique
relations:
Campaign: { onDelete: CASCADE, local: campaign_id, foreign: id, foreignAlias: CampaignCampaignGames }
Game: { onDelete: CASCADE, local: game_id, foreign: id, foreignAlias: GameCampaignGames }
CampaignMatrix:
actAs:
Timestampable: ~
columns:
id: { type: integer(4), primary: true, autoincrement: true, unsigned: true }
item_id: { type: integer(4), notnull: true, unsigned: true }
campaign_id: { type: integer(4), notnull: true, unsigned: true }
price_id: { type: integer(4), notnull: true, unsigned: true }
quantity: { type: integer(4), notnull: true, unsigned: true }
relations:
Item: { onDelete: CASCADE, local: item_id, foreign: id, foreignAlias: ItemCampaignMatrix }
Campaign: { onDelete: CASCADE, local: campaign_id, foreign: id, foreignAlias: CampaignCampaignMatrix }
Price: { onDelete: CASCADE, local: price_id, foreign: id, foreignAlias: PriceItems }
Price:
columns:
id: { type: integer(4), unsigned: true }
currency_code: { type: string(3), notnull: true }
price: { type: float, notnull: true }
indexes:
tc:
fields: [id, currency_code]
type: unique
Item:
actAs:
Timestampable: ~
I18n:
fields: [name, description, image]
columns:
id: { type: integer(4), primary: true, autoincrement: true, unsigned: true }
game_id: { type: integer(4), notnull: true, unsigned: true }
product_id: { type: string(100), notnull: true }
price_id: { type: integer(4), notnull: true, unsigned: true }
quantity: { type: integer(4), notnull: true, unsigned: true }
name: { type: string(100), notnull: true }
description: { type: string(255), notnull: true }
image: { type: string(255), notnull: true }
indexes:
it:
fields: item_type
relations:
Game: { onDelete: CASCADE, local: game_id, foreign: id, foreignAlias: GameItems }
Price: { onDelete: CASCADE, local: price_id, foreign: id, foreignAlias: PriceItems }
This is how I do it:
$list = MainItemTable::getInstance()->findByGameId($gameId);
$CampaignMatrix = new CampaignMatrix();
foreach($list as $index => $item) {
$itemAssocForm = new CampaignMatrixForm($CampaignMatrix);
$itemAssocForm->item_id = $item->getId(); // Need it in the form as hidden field
$this->embedForm($item->getProductId(), $itemAssocForm);
}
And this is how I'm trying to get the value:
$this->widgetSchema['item_id'] = new sfWidgetFormInputText(array(), array('value' => $this->item_id)); // It doesn't get the Id
But I have an error:
Fatal error: Maximum execution time of 30 seconds exceeded in /vendor/symfony/lib/plugins/sfDoctrinePlugin/lib/vendor/doctrine/Doctrine/Relation/Parser.php on line 237
If I unset price_id in CampaignMatrixForm, no error produced. How to avoid execution of select of the same data for every item row in the loop?
Item id is missing, but I need it as hidden field. How to pass CampaignMatrix ID of current row to CampaignMatrixForm?
You have to iterate on association to emebed the association form to the main form. It mays be simple if you post a part of your schema.yml.
Try to re-use this snippet :
$list = MyRelatedObjectTable::getInstance()->findAll();
foreach($list as $item)
{
$itemAssoc = AssociationTable::getInstance()->findByObjectId($this->object->id, $item->id);
if(!$itemAssoc)
{
$itemAssoc = new Association();
$itemAssoc->value_id = $itemAssoc->id;
$itemAssoc->user_id = $this->object->id;
}
$itemAssocForm = new AssociationForm($itemAssoc);
$this->embedForm('itemAssoc'.$item->code, $itemAssocForm);
}
The best way is to create a partial for that. Be aware that you need to unset the select box for the Item in the Form class or you'll lose your association. I can elaborate on that if you need more help.
you can get code from cache and move to your backend/modules/nameAPP and next edit template

SQL error foreign key constraint

I'm struggling for four days days now with an sql foreign key constraint fails and I reaaly have no idea why. I've read all I could about that subject and it seems that everything is fine.
Here is my schema.yml
Soiree:
actAs: { Timestampable: ~ }
columns:
titre: { type: string(255), notnull: true }
description: { type: blob(), notnull: true }
adresse: { type: string(255), notnull: true, unique: true }
code_postal: {type: integer, notnull: true }
ville: {type: string(255), notnull:true}
date: {type: timestamp, notnull: true }
type_id: {type: integer, notnull: true }
flyer: {type: string(255), notnull:true }
is_visible: { type: boolean, notnull:true, default:0 }
user_id: {type:integer, notnull: true}
relations:
sfGuardUser: {onDelete: CASCADE, local: user_id, foreign: id, foreignAlias: Users}
Type: {onDelete: CASCADE, local: type_id, foreign: id, alias: Types, class: Type, refClass: Soiree}
Type:
columns:
titre: {type: string(255), notnull: true}
Invitation:
actAs: { Timestampable: ~ }
columns:
titre: { type: string(255), notnull: true }
description: { type: blob(), notnull: true }
image: { type: string(255), notnull: true }
is_sent: {type: boolean, notnull:true, default:0}
adresse: { type: string(255) }
code_postal: { type: string(255) }
code_QR: {type: string(255), notnull: true }
invites_id: {type:integer }
user_id: {type:integer, notnull: true}
groupe_invites_id : {type:integer, notnull: true }
soiree_id: {type:integer, notnull:true}
relations:
Invites: { onDelete: CASCADE, local: invites_id, foreign: id, alias: invite, class: Invites, refClass: Invitation }
Groupe_invites: { onDelete: CASCADE, local: groupe_invites_id, foreign: id, alias: invit_groupes, class: Groupe_invites, refClass: Invitation }
sfGuardUser: {onDelete: CASCADE, local: user_id, foreign: id, foreignAlias: Users}
Soiree: { onDelete: CASCADE, local: soiree_id, foreign: id, alias :Soirees, class: Soiree, refClass: Invitation }
Groupe_invites:
actAs: { Timestampable: ~ }
columns:
titre: { type: string(255), notnull: true }
description: { type: string(255), notnull: true, unique: true }
invites_id: { type: integer, notnull: true }
soiree_id: { type: integer }
user_id: {type:integer, notnull: true}
relations:
Invites:
onDelete: CASCADE
local: invites_id
foreign: id
alias: invites
class: Invites
refClass: Groupe_invites
sfGuardUser: {onDelete: CASCADE, local: user_id, foreign: id, foreignAlias: Users}
Soiree: { onDelete: CASCADE, local: soiree_id, foreign: id, alias: Soiree, class: Soiree, refClass: Groupe_invites }
Invites:
columns:
nom: { type: string(255), notnull: true }
prenom: { type: string(255), notnull: true }
age: {type: integer, notnull : true }
email: {type: string(255), notnull: true, unique: true }
adresse: {type: blob(), notnull: true }
telephone: {type: integer(255), notnull: true }
soiree_id: {type: integer, notnull: true }
user_id: {type:integer, notnull: true}
relations:
sfGuardUser: {onDelete: CASCADE, local: user_id, foreign: id, foreignAlias: Users}
Soiree: { onDelete: CASCADE, local: soiree_id, foreign: id, alias: Soiree_invite, class: Soiree, refClass: Invites }
Organisateur:
actAs: {Timestampable: ~ }
columns:
nom: {type: string(255), notnull: true }
prenom: {type: string(255), notnull: true }
age: {type: integer, notnull: true }
description: {type: blob(), notnull: true }
photo: {type: string(255), notnull: true }
user_id: {type:integer, notnull: true}
relations:
sfGuardUser: {onDelete: CASCADE, local: user_id, foreign: id, foreignAlias: Users}
Image:
columns:
titre: {type: string(255), notnull: true }
description: {type: string(255), notnull: true }
lien: {type: string(255)}
album_id: {type: integer}
user_id: {type: integer}
relations:
Album: {onDelete: CASCADE, local: album_id, foreign: id, alias: Albums, class:Album, refClass:Image}
sfGuardUser: {onDelete: CASCADE, local: user_id, foreign: id}
Album:
columns:
titre: {type: string(255), notnull: true }
description: {type: blob(), notnull: true }
user_id: {type:integer, notnull: true}
relations:
sfGuardUser: {onDelete: CASCADE, local: user_id, foreign: id}
And I have an error of type:
SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (soiree.invitation, CONSTRAINT invitation_ibfk_1 FOREIGN KEY (invites_id) REFERENCES invitation (id) ON DELETE CASCADE)
I really need help on this one, thank you !
I typically add the id column to my tables. Apply this to the tables where it makes sense:
id: { type: integer, primary: true, autoincrement: true }

doctrine:build --model and --sql ok but doctrine:insert-sql is not. Do you know why?

here is my schema.yml files:
issues:
actAs: { Timestampable: ~ }
columns:
issueId: { type: integer(4), notnull: true, primary: true, autoincrement: true }
issueDateForPublish: { type: timestamp, notnull: true }
issueName: { type: string(255), notnull: true }
issueCoverArticleId: { type: integer(4), notnull: true }
relations:
articles:
class: articles
foreignAlias: article
local: articleId
foreign: issueId
type: many
articles:
actAs: { Timestampable: ~ }
columns:
articleId: { type: integer(4), notnull: true, primary: true, autoincrement: true }
articleTitle: { type: string(), notnull: true }
articleText: { type: string(), notnull: true }
articleDataForPublish: { type: timestamp, notnull: true }
articleIsDraft: { type: boolean, notnull: true, default: 1 }
articleIsOnHold: { type: boolean, notnull: true, default: 0 }
articleIsModerate: { type: boolean, notnull: true, default: 0 }
articleIsApprove: { type: boolean, notnull: true, default: 0 }
relations:
articles:
local: issueId
foreign: articleId
onDelete: cascade
comments:
class: comments
foreignAlias: comment
local: commentId
foreign: articleId
type: many
comments:
actAs: { Timestampable: ~ }
columns:
commentId: { type: integer(4), notnull: true, primary: true, autoincrement: true }
commentName: { type: string(255), notnull: true }
commentSurname: { type: string(255), notnull: true }
commentMail: { type: string(255), notnull: true }
commentDataForPublish: { type: timestamp }
commentIsModerated: { type: boolean, notnull: true, default: 0 }
commentIsApprove: { type: boolean, notnull: true, default: 0 }
relations:
articles:
local: articleId
foreign: commentId
onDelete: cascade
Again, when i run php symfony doctrine:build --model and php symfony doctrine:build --sql nothing goes bad. "php symfony doctrine:insert-sql" makes this error:
SQLSTATE[42000]: Syntax error or access violation: 1072 Key column 'issueid' doesn't exist in table. Failing Query: "CREATE TABLE articles (articleid INT AUTO_INCREMENT, articletitle TEXT NOT NULL, articletext TEXT NOT NULL, articledataforpublish DATETIME NOT NULL, articleisdraft TINYINT(1) DEFAULT '1' NOT NULL, articleisonhold TINYINT(1) DEFAULT '0' NOT NULL, articleismoderate TINYINT(1) DEFAULT '0' NOT NULL, articleisapprove TINYINT(1) DEFAULT '0' NOT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, INDEX issueid_idx (issueid), PRIMARY KEY(articleid)) ENGINE = INNODB". Failing Query: CREATE TABLE articles (articleid INT AUTO_INCREMENT, articletitle TEXT NOT NULL, articletext TEXT NOT NULL, articledataforpublish DATETIME NOT NULL, articleisdraft TINYINT(1) DEFAULT '1' NOT NULL, articleisonhold TINYINT(1) DEFAULT '0' NOT NULL, articleismoderate TINYINT(1) DEFAULT '0' NOT NULL, articleisapprove TINYINT(1) DEFAULT '0' NOT NULL, created_at DATETIME NOT NULL, updated_at DATETIME NOT NULL, INDEX issueid_idx (issueid), PRIMARY KEY(articleid)) ENGINE = INNODB
Thanks for your help, erman.
You've got your definition a bit wrong.
Local should be the name of the field in the current table, and foreign the field in the foreign table - you have these the wrong way round.
You normally only define one end of the relationship - doctrine auto adds the inverse to the other table, and gets it right 99% of the time. If you do it manually they have to match. In this case, remove the article relation from issues, and the comments relation from articles.
Comments has no article id field.
Foreign alias isn't needed, but you have it the wrong way round - its what the current table/object will be referred to as in the table/object at the far end of the relation. Defaults to the name of the current object, so can often ignore.
Few other minor niggles too. At a guess, I reckon this schema will do you:
issue:
actAs: { Timestampable: ~ }
columns:
issueId: { type: integer(4), notnull: true, primary: true, autoincrement: true }
issueDateForPublish: { type: timestamp, notnull: true }
issueName: { type: string(255), notnull: true }
issueCoverArticleId: { type: integer(4), notnull: true }
article:
actAs: { Timestampable: ~ }
columns:
articleId: { type: integer(4), notnull: true, primary: true, autoincrement: true }
articleTitle: { type: string(), notnull: true }
articleText: { type: string(), notnull: true }
articleDataForPublish: { type: timestamp, notnull: true }
articleIsDraft: { type: boolean, notnull: true, default: 1 }
articleIsOnHold: { type: boolean, notnull: true, default: 0 }
articleIsModerate: { type: boolean, notnull: true, default: 0 }
articleIsApprove: { type: boolean, notnull: true, default: 0 }
issueId: { type: integer(4) }
relations:
issue:
local: issueId
foreign: issueId
foreignAlias: articles
onDelete: cascade
comment:
actAs: { Timestampable: ~ }
columns:
commentId: { type: integer(4), notnull: true, primary: true, autoincrement: true }
commentName: { type: string(255), notnull: true }
commentSurname: { type: string(255), notnull: true }
commentMail: { type: string(255), notnull: true }
commentDataForPublish: { type: timestamp }
commentIsModerated: { type: boolean, notnull: true, default: 0 }
commentIsApprove: { type: boolean, notnull: true, default: 0 }
articleId: { type: integer(4) }
relations:
article:
local: articleId
foreign: articleId
onDelete: cascade
foreignAlias: comments

symfony 1.4: question about accessing a child class from a parent class

i have this schema:
shop_products:
_attributes: { phpName: ShopProduct }
products_id: { phpName: Id, type: INTEGER, size: '11', primaryKey: true, autoIncrement: true, required: true }
products_quantity: { phpName: Quantity, type: INTEGER, size: '4', required: true }
products_model: { phpName: Model, type: VARCHAR, size: '12', required: false }
products_image: { phpName: Image, type: VARCHAR, size: '64', required: false }
products_price: { phpName: Price, type: DECIMAL, size: '15', scale: '4', required: false, defaultValue: '0.0000' }
products_date_added: { phpName: DateAdded, type: TIMESTAMP, required: true }
products_last_modified: { phpName: LastModified, type: TIMESTAMP, required: false }
products_date_available: { phpName: DateAvailable, type: TIMESTAMP, required: false }
products_weight: { phpName: Weight, type: DECIMAL, size: '5', scale: '2', required: true }
products_carati: { phpName: Carati, type: FLOAT, required: false, defaultValue: '1' }
products_status: { phpName: Status, type: TINYINT, size: '1', required: true }
manufacturers_id: { phpName: ManufacturerId, type: INTEGER, size: '11', required: false, foreignTable: shop_manufacturers, foreignReference: manufacturers_id, onDelete: SETNULL }
products_ordered: { phpName: Ordered, type: INTEGER, size: '11', required: true, defaultValue: '0' }
shop_categories:
_attributes: { phpName: ShopCategory }
categories_id: { phpName: Id, type: INTEGER, size: '11', primaryKey: true, autoIncrement: true, required: true }
categories_image: { phpName: Image, type: VARCHAR, size: '64', required: false }
parent_id: { phpName: ParentId, type: INTEGER, size: '11', required: true, defaultValue: '0', foreignTable: shop_categories, foreignReference: categories_id, onDelete: CASCADE, onUpdate: CASCADE }
sort_order: { phpName: SortOrder, type: INTEGER, size: '3', required: false }
date_added: { phpName: DateAdded, type: TIMESTAMP, required: false }
last_modified: { phpName: LastModified, type: TIMESTAMP, required: false }
shop_categories_description:
_attributes: { phpName: ShopCategoryDescription }
categories_id: { phpName: CategoryId, type: INTEGER, size: '11', primaryKey: true, required: true, defaultValue: '0', foreignTable: shop_categories, foreignReference: categories_id, onDelete: CASCADE, onUpdate: CASCADE }
language_id: { phpName: LanguageId, type: INTEGER, size: '11', primaryKey: true, required: true, defaultValue: '1', foreignTable: culture, foreignReference: id, onDelete: CASCADE, onUpdate: CASCADE }
categories_name: { phpName: Name, type: VARCHAR, size: '32', required: true }
Then, I have created an admin module from the ShopProducts model, but when i try to go to it it says:
Class "ShopCategory" must implement a
"__toString" method to be rendered in
a "sfWidgetFormPropelChoice" widget
As you can see, the model where the names of the categories are, is ShopCategoriesDescription. So, how could i get the name of the categories from the ShopCategory model class?
Javier
sf 1.4/propel
That's a standard error that has nothing to do with parent/child relationships. You normally just need to add to the ShopCategory.php file in the lib/model folder a __toString() method
public function __toString()
{
return $this->getCategoryName();
}
Now since you've pulled out the category name from the shop_category table you need to create a function that gets the shop_categories_description that is a child of the shop_category and is the correct culture so that you have a category name to return.

Resources