Is there some magic in Symfony/doctrine with a model called JosVmOrderHistory?
I have this schema.yml excerpt:
JosVmOrder:
tableName: jos_vm_orders
columns:
order_id: { type: integer(4), primary: true, autoincrement: true }
user_id: { type: integer(4), notnull: true }
vendor_id: { type: integer(4), notnull: true }
order_number: { type: string(32), notnull: false }
user_info_id: { type: string(32), notnull: false }
order_total: { type: 'decimal(15, 5)', notnull: true }
order_subtotal: { type: 'decimal(15, 5)', notnull: false }
order_tax: { type: 'decimal(10, 2)', notnull: false }
order_tax_details: { type: string(), notnull: true }
order_shipping: { type: 'decimal(10, 2)', notnull: false }
order_shipping_tax: { type: 'decimal(10, 2)', notnull: false }
coupon_discount: { type: 'decimal(12, 2)', notnull: true }
coupon_code: { type: string(32), notnull: false }
order_discount: { type: 'decimal(12, 2)', notnull: true }
order_currency: { type: string(16), notnull: false }
order_status: { type: string(1), notnull: false }
cdate: { type: integer(4), notnull: false }
mdate: { type: integer(4), notnull: false }
ship_method_id: { type: string(255), notnull: false }
customer_note: { type: string(), notnull: true }
ip_address: { type: string(15), notnull: true }
relations:
User: { class: JosUser, local: user_id, foreignAlias: OrderList }
LatestVmOrderDetail: { class: LatestVmOrderDetail, local: order_id, foreign: order_id }
JosVmOrderHistory:
tableName: jos_vm_order_history
columns:
order_status_history_id: { type: integer(4),primary: true, autoincrement: true }
order_id: { type: integer(4) }
order_status_code: { type: string(1) }
date_added: { type: timestamp(25) }
customer_notified: { type: integer(4), notnull: false }
comments: { type: clob(16777777), notnull: false }
relations:
Order: { class: JosVmOrder, local: order_id, foreign: order_id }
OrderStatus: { class: JosVmOrderStatus, local: order_status_code, foreign: order_status_code }
Firstly, the foreignAlias of JosVmOrderHistory is "JosVmOrderHistory", not "JosVmOrderHistoryList" as I would have assumed.
Secondly, in model/doctrine/Order.class.php, I have the following function:
function getPaymentStatus(){
$historyList = $this->getJosVmOrderHistory();
if (count($historyList)){
return $paymentStatus = $historyList[0];
}else{
return $paymentStatus = null;
}
}
$historyList is always in descending order of order_status_history_id. I even added to model/doctrine/JosVmOrderHistoryTable.class.php:
public function createQuery($alias){
return parent::createQuery($alias)->orderBy('order_status_history_id asc');
}
but it stays in descending order..
Edit: I've updated the subject - this problem seems to come down to how to control the OrderBy of a relation query. createQuery doesn't seem to be called at all.
If you need this for speed reasons you shouldnt load the entire order history from the DB if you are just interested in the first one, instead use a query like:
function getPaymentStatus(){
$historyList = Doctrine::getTable('JosVmOrderHistory')->createQuery()->where('order_id = ?', $this->order_id)->orderBy('order_status_history_id')->limit(1)->execute();
if (count($historyList)){
return $paymentStatus = $historyList[0];
}else{
return $paymentStatus = null;
}
}
That being said, it is possible to automatically affect the sorting more like what you were trying to do by using a listener. In the past, I have created a generic sort behavior that you can use like:
actAs:
DefaultSort: { column: title }
Related
In Symfony 1.4, Doctrine I have this snippet from schema.yml
Attendance:
columns:
id: { type: integer(4), primary: true, autoincrement: true }
user_id: { type: integer(4) }
relations:
JoomlaUser: { class: JosUser, local: user_id, foreignAlias: AttendanceList }
and
JosUser:
tableName: jos_users
columns:
id: { type: integer(4), primary: true, autoincrement: true }
relations:
AttendanceList: { class: Attendance, local: id, foreign: user_id }
What is the most efficient way to determine from JosUser that there are no Attendance records. I tried model/doctrine/JosUser.class.php
count($this->getAttendanceList())
but this returns a Doctrine Record with all fields empty but user_id
Schema :
JosUser:
tableName: jos_users
columns:
id: { type: integer(4), primary: true, autoincrement: true }
relations:
AttendanceList: { type: many, class: Attendance, local: id, foreign: user_id }
With type: many, getAttendanceList() should return a Doctrine_Collection (see the JosUser base class in lib/model/doctrine/base/BaseJosUser.class.php), then you can use
$this->getAttendanceList()->count()
I have two relations in my schema, product with many subcategory and product with many category. So I can make in my productForm.class.php
$this->widgetSchema['subcategory_list'] = new sfWidgetFormDoctrineChoice(array('model' => 'Subcategory', 'add_empty' => false, 'multiple' => true,'expanded' => true));
$this->widgetSchema['category_list'] = new sfWidgetFormDoctrineChoice(array('model' => 'Category', 'add_empty' => false, 'multiple' => true,'expanded' => true));
And it is work. But I need to make for example:
category1
subcategory 1 , subcategory2
category2
category3
subcategory3, subcategory4
And I need to make, that I can check category and subcategory.
Thank you!
Upd
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 }
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 }
ANSWER
I make it manual. I get from cache file _form.php and rewrite it, add category and subcategory checkbox. Than I make some changes in action class(manual set and delete subcategories and categories). I use code from answer, so I check it!
check this: http://www.symfony-project.org/jobeet/1_4/Doctrine/en/06
UPDATED:
you can simply in template:
$categories = CategoryTable::getInstance()->findAll();
foreach ($categories as $category) {
echo $category->getName();
$subcategory = SubcategoryTable::getInstance()->findBy('category_id', $category->getId());
foreach($subcategory as $sub){
echo $sub->getName();
}
}
this should working ok, but this isnt correctly programming
I have a registration form that includes sfRegistration and sfProfile, which after completion, get's redirected to another form - to determine the user's corporation and is a seperate module. The sfProfile includes a field from the corporation module... the corporate_id. But since the corporate_id is not part of the profile, it does not get included at registration time. Here's the question, after completion of the corporation module, what is the best way to update the user's profile with the corporate_id of the newly completed corporation module? I tried this:
public function postSave()
{
$corpId = $this->form->getId();
$logged_user_id = sfContext::getInstance()->getUser()->getId();
Doctrine_Query::create()
->update('sf_guard_user_profile p')
->set('p.corporate_id', $corpId)
->where('p.user_id' == $logged_user_id )
->execute();
}
placed into the action of the company module, but it is not updating the profile with the company_id.
Suggestions?
UPDATE - per request, here is the information requested: (my >>lib>form>>doctrine>>CorporationForm.class.php is empty... I was trying my functions in the actions class... which may be the issue). Just to clarify, I just need to update the user's profile with the newly created corporate_id after the user completes the corporation module.
And my schema:
sfGuardUser:
actAs: [Timestampable]
columns:
first_name: string(255)
last_name: string(255)
email_address:
type: string(255)
notnull: true
unique: true
username:
type: string(128)
notnull: true
unique: true
algorithm:
type: string(128)
default: sha1
notnull: true
salt: string(128)
password: string(128)
is_active:
type: boolean
default: 1
is_super_admin:
type: boolean
default: false
last_login:
type: timestamp
indexes:
is_active_idx:
fields: [is_active]
relations:
Groups:
class: sfGuardGroup
local: user_id
foreign: group_id
refClass: sfGuardUserGroup
foreignAlias: Users
Permissions:
class: sfGuardPermission
local: user_id
foreign: permission_id
refClass: sfGuardUserPermission
foreignAlias: Users
sfGuardUserProfile:
actAs: { Timestampable: ~ }
columns:
id: { type: integer, primary: true, notnull: true, autoincrement: true, unique: true }
user_id: { type: integer }
corporate_id: { type: integer }
type_id: { type: integer, notnull: true }
prefix_id: { type: integer }
middle_name: { type: string(55) }
suffix_id: { type: integer }
phone: { type: string(55), notnull: true }
home_address_line_one: { type: string }
home_address_line_two: { type: string }
home_city: { type: string }
state_id: { type: integer }
home_zip: { type: integer }
relations:
User: { class: sfGuardUser, local: user_id, foreign: id, type: one, foreignType: one, foreignAlias: Profile }
Type: { local: type_id, foreign: id, type: one, foreignAlias: Types }
Prefix: { local: prefix_id, foreign: id, type: one, foreignAlias: Prefixs }
Suffix: { local: suffix_id, foreign: id, type: one, foreignAlias: Suffixs }
State: { local: state_id, foreign: id, foreignAlias: States }
Corporation: { local: corporate_id, foreign: id, foreignAlias: Corporations }
Corporation:
columns:
id: { type: integer, primary: true, notnull: true, autoincrement: true, unique: true }
user_id: { type: integer }
name: { type: string(55), notnull: true }
address_line1: { type: string(255), notnull: true }
address_line2: { type: string(255), notnull: true }
city: { type: string(25), notnull: true }
state_id: { type: integer, notnull: true }
zip: { type: string(25), notnull: true }
phone: { type: string(25), notnull: true }
email: { type: string(100), notnull: true }
website: { type: string(100) }
logo: { type: string(255) }
relations:
User: { class: sfGuardUser, local: user_id, foreign: id, foreignAlias: Users }
In your form:
public function doUpdateObject($values)
{
parent::doUpdateObject($values);
$this->getObject()->setCorporateId(your value);
}
For example
//apps/frontend/yourmodule/action.class.php
protected function processForm(sfWebRequest $request, sfForm $form)
{
$form->bind($request->getParameter($form->getName()), $request->getFiles($form->getName()));
if ($form->isValid())
{
$corporation = $form->save();
$user_id=$this->getUser()->getGuardUser()->getId();
$profile = Doctrine_Core::getTable('sfGuardUserProfile')->findOneByUserId($user_id);
$profile->setCorporateId('your value');
Don't forget the ->save();
public function setId()
{
$user_id = $this->getUser()->getGuardUser()->getId();
$corp_id = 1;
$user_profile = Doctrine_Core::getTable('sfGuardUserProfile')->findOneByUserId($user_id);
$user_profile->setCorporateId($corp_id)->save();
}
protected function processForm(sfWebRequest $request, sfForm $form)
{
$form->bind($request->getParameter($form->getName()), $request->getFiles($form->getName()));
if ($form->isValid())
{
self::setId();
$corporation = $form->save();
$this->redirect('dashboard/index');
}
}
I use symfony 1.4.11 with Doctrine
I have sfGuardUser module in backend. I have sfGuardUserProfile table.
sfGuardUserProfile:
connection: doctrine
tableName: sf_guard_user_profile
columns:
id: { type: integer(4), primary: true, autoincrement: true }
user_id: { type: integer(4), notnull: true }
salutation: { type: string(10), notnull: true }
first_name: { type: string(30), notnull: true }
last_name: { type: string(30), notnull: true }
country: { type: string(255), notnull: true }
postcode: { type: string(10) , notnull: true }
city: { type: string(255), notnull: true }
address: { type: string() , notnull: true }
phone: { type: string(50) }
email: { type: string(255), notnull: true }
validate: { type: string(17) }
banned: { type: boolean, default: 0 }
payed_until: { type: datetime, notnull: true}
relations:
User:
class: sfGuardUser
foreign: id
local: user_id
type: one
onDelete: cascade
onUpdate: cascade
foreignType: one
foreignAlias: Profile
indexes:
user_id_unique:
fields: [user_id]
type: unique
SfGuardUser table:
GuardUser:
actAs: [Timestampable]
columns:
id:
type: integer(4)
primary: true
autoincrement: true
username:
type: string(128)
notnull: true
unique: true
algorithm:
type: string(128)
default: sha1
notnull: true
salt: string(128)
password: string(128)
is_active:
type: boolean
default: 1
is_super_admin:
type: boolean
default: false
last_login:
type: timestamp
indexes:
is_active_idx:
fields: [is_active]
relations:
groups:
class: sfGuardGroup
local: user_id
foreign: group_id
refClass: sfGuardUserGroup
foreignAlias: Users
permissions:
class: sfGuardPermission
local: user_id
foreign: permission_id
refClass: sfGuardUserPermission
foreignAlias: Users
I have next sfGuardUserForm:
public function configure()
{
parent::configure();
$profileForm = new sfGuardUserProfileForm($this->object->Profile);
unset($profileForm['user_id'],$profileForm['banned'],$profileForm['validate'],$profileForm['payed_until']);
$profileForm->widgetSchema['salutation'] = new weWidgetSalutationI18n();
$profileForm->widgetSchema['country'] = new sfWidgetFormI18nChoiceCountry();
$profileForm->setDefault('country', 'DE');
$this->embedForm('Profile', $profileForm);
}
So, when I add new user from backend, in my sfGuardUserProfile table user_id = 0 ...
Try if this works for you:
public function configure()
{
parent::configure();
$profile = new sfGuardUserProfile();
$profile->setUserId($this->getObject()->id);
$profileForm = new sfGuardUserProfileForm($profile);
$this->embedForm('Profile', $profileForm);
}
I'm not really sure, but form the top of my head it's because you unset the user_id value.
Somethings that first came to mind are:
Read this (to define a primary key, the keyword is primaryKey: true not primary: true and they dont need to be defined as autoincremental, ORM can guess it for himself)
Dont unset the user_id or any ids of forms , they are hidden by default so that should not be a problem.
Check those poitns and see if he problem persist, if so i cuold be something not properly updated when changing the schema (remember always clearing cache and building all classes every time you modify your schema)
Hope this helps!
I have the following schema definition:
Usuario:
columns:
empresa_id: { type: BIGINT, notnull: true }
direccion_id: { type: BIGINT, notnull: false }
publicidad_id: { type: BIGINT, notnull: true }
tipo_id: { type: BIGINT, notnull: true }
nombre: { type: string(60), notnull: true }
paterno: { type: string(60), notnull: true }
materno: { type: string(60), notnull: true }
curp: { type: string(20), notnull: false }
rfc: { type: string(13), notnull: false }
correoPrincipal: { type: string(100), notnull: true, unique: true }
correoSecundario: { type: string(100), notnull: false, unique: true }
telefonoFijo: { type: string(12), notnull: true }
telefonoMovil: { type: string(12), notnull: false }
validado: { type: boolean, notnull: false, default: false }
usuario: { type: string(10), notnull: false }
password: { type: string(10), notnull: false }
matricula: { type: string(16), notnull: false }
fechaNacimiento: { type: date, notnull: true }
relations:
Direccion: { onDelete: CASCADE, local: direccion_id, foreign: id }
Empresa: { onDelete: CASCADE, local: empresa_id, foreign: id, class: Empresa }
Publicidad: { onDelete: CASCADE, local: publicidad_id, foreign: id }
Tipo: { onDelete: CASCADE, local: tipo_id, foreign: id, class: conamatTipo }
Bachillerato:
class: Bachillerato
refClass: BachilleratoUsuario
local: usuario_id
foreign: bachillerato_id
foreignAlias: Usuarios
UsuarioSede:
class: Sede
refClass: SedeUsuario
local: usuario_id
foreign: sede_id
foreignAlias: Usuario
SedeUsuario:
columns:
sede_id: { type: bigint, notnull: true }
usuario_id: { type: bigint, notnull: true }
relations:
Usuario: { local: usuario_id, foreign: id }
Sede: { local: sede_id, foreign: id }
How can I make a form that lets me add multiple "sedes" to one "usuario", I've tried the advanced forms chapter in the symfony documentation, but I don't want to embed the form, I want to use it as another form all alone.
Thanks.
If you use Doctrine in a recent version (I don't know since when this exists), you relationships will be saved when a related object is saved, assuming it the relation has changed. This work without embedded forms (even without form), it's a different thing and part of the ORM.
If this behavior does not work, it's an issue with your model declaration in schema.yml