Warning: Please do not give out any FTP or ssh credentials to anyone, unless you trust them completely. Giving out login details is dangerous.
If the asker does not get an answer then they have 10 days to request a refund.
$4
Simple 1:n embedRelation problem
I am using symfony 1.3 and doctrine 1.2
I have a simple situation where one contact has many phone numbers. Contacts are one object/table, phone numbers are another object/table.
I want to have a form where I create a contact along with a single phone number. However, for some reason the "phone" form never displays.
I must be doing something simple wrong, but I can't figure out out.
Here is the schema snippet:
schema.yml
Contact:
columns:
id: { type: integer(4), primary: true, autoincrement: true }
first_name: { type: string(50)}
last_name: { type: string(50)}
Phone:
columns:
id: { type: integer(5), primary: true, autoincrement: true }
contact_id: { type: integer(4) }
number: { type: string(20) }
type: { type: enum, values: [Home, Work, Cell, Fax] }
relations:
Contact: { foreignAlias: Phone }
What I want is for the form to look like:
First name: (input firstname)
Last name: (input lastname)
Phone number: (input number) (dropdown phone number type)
Code snippets:
lib/form/doctrine/PhoneEmbedForm.class.php
<?php
/**
* Phone Embed Form
*
* @package form
* @subpackage PhoneEmbed
* @version 0.1
*/
class PhoneEmbedForm extends BasePhoneForm
{
public function configure()
{
$this->useFields(array('number', 'type'));
}
}
lib/form/doctrine/Contact.class.php
<?php
/**
* Contact form.
*
* @package form
* @subpackage Contact
* @version SVN: $Id: sfDoctrineFormTemplate.php 6174 2007-11-27 06:22:40Z fabien $
*/
class ContactForm extends BaseContactForm
{
public function configure()
{
$this->embedRelation('Phone', 'PhoneEmbedForm');
$this->useFields(array('first_name', 'last_name', 'Phone'));
}
}
apps/myapp/modules/contact/templates/_form.php
<?php echo $form?>
The contact part of the form displays, and it says "Phone" in text but with no input boxes. How do I get it to show the phone boxes AND associate it with the contact upon save? Thank you.
Answerer must submit actual code for this specific case and not just link to a manual (however links to add clarity are appreciated).
This question has been answered.
webguy | 10/19/10 at 4:55pm
Edit
The experts have suggested, on average, a prize of $5 for this question.
(4) Possible Answers Submitted...
See a chronological view of answers?
Warning: Please do not give out any FTP or ssh credentials to anyone, unless you trust them completely. Giving out login details is dangerous.
-

Last edited:
10/20/10
11:54amJoshua Estes says:http://www.symfony-project.org/more-with-symfony/1_4/en/06-Advanced-Forms
- 10/19/10 5:16pm
webguy says:I specifically asked please don't directly link to docs with no notes. I have read that page and am still having issues.
So, a few things:
1) The phone number is a doctrine object, so according to that page embedRelation should work (am i wrong?)
2) I have tried the embedForm approach, however it doesn't properly associate the phone number and contact (however it creates both in the database
lib/form/doctrine/ContactForm.class.php
<?php
/**
* Contact form.
*/
class ContactForm extends BaseContactForm
{
public function configure()
{
$phoneForm = new PhoneEmbedForm(new Phone());
$this->embedForm('Phone', $phoneForm);
$this->useFields(array('first_name', 'last_name', 'Phone'));
}
}
lib/form/doctrine/PhoneEmbedForm.class.php
<?php
/**
* Phone Embed Form
*
* @package form
* @subpackage PhoneEmbed
* @version 0.1
*/
class PhoneEmbedForm extends PhoneForm
{
public function configure()
{
$this->useFields(array('number', 'type'));
}
}
- 10/19/10 5:20pm
Joshua Estes says:schema.yml
Contact:
columns:
first_name: { type: string(50)}
last_name: { type: string(50)}
relations:
Phone:
foreign: contact_id
local: id
Phone:
columns:
contact_id: { type: integer(4) }
number: { type: string(20) }
type: { type: enum, values: [Home, Work, Cell, Fax] }
ContactForm.class.php
class ContactForm extends BaseContactForm
{
public function configure()
{
$this->embedRelation('Phone');
}
}
PhoneForm.class.php
class PhoneForm extends BasePhoneForm
{
public function configure()
{
unset($this['contact_id']);
}
}
That should get you started
- 10/19/10 5:16pm
-

Last edited:
10/20/10
11:54amPawel Dawczak says:Hi,
first thing is a little change in schema:
Contact:
columns:
id: { type: integer(4), primary: true, autoincrement: true }
first_name: { type: string(50)}
last_name: { type: string(50)}
Phone:
columns:
id: { type: integer(5), primary: true, autoincrement: true }
contact_id: { type: integer(4) }
number: { type: string(20) }
type: { type: enum, values: [Home, Work, Cell, Fax] }
relations:
Contact: { foreignAlias: Phone, foreignType: one }
PhoneForm.class.php should be:
class PhoneForm extends BasePhoneForm
{
public function configure()
{
$this->useFields(array('number', 'type'));
}
}
and ContactForm.class.php:
class ContactForm extends BaseContactForm
{
public function configure()
{
$this->useFields(array('first_name', 'last_name'));
// embdding form
$phoneForm = new PhoneForm($this->getObject()->getPhone());
$this->embedForm('Phone', $phoneForm);
}
}
If you use$this->embedRelation('Phone', 'PhoneEmbedForm');
Doctrine fetches Phone objects related with Contact object only for editing, so you can't create new Phone objects.
In case I showed above you are embedding a Phone form initialized with related Phone object$this->getObject()->getPhone()
If there is no related Phone object, then you can see a blank form for creating new object.Previous versions of this answer: 10/19/10 at 6:49pm
- 10/19/10 7:40pm
webguy says:That works, but the schema complicates things a bit now.
I have a page where I list contacts and all of their phone numbers...
For example:
Contact 1:
- Phone1
- Phone2
Contact 2:
- Phone3
Contact3:
- Phone 4
- Phone 5
I used to be able to do a
<?php foreach ($contact->getPhone() as $i => $phone): ?>
<?php echo $phone->getNumber(); ?>
<?php endforeach; ?>
but now because of the schema updates, that doesnt work...
- 10/20/10 9:47am
Pawel Dawczak says:Hi, sorry for my mistake. I gave you solution if you want to have relation 1:1. But this is for relation 1:N.
config/schema.yml
Contact:
columns:
id: { type: integer(4), primary: true, autoincrement: true }
first_name: { type: string(50)}
last_name: { type: string(50)}
Phone:
columns:
id: { type: integer(5), primary: true, autoincrement: true }
contact_id: { type: integer(4) }
number: { type: string(20) }
type: { type: enum, values: [Home, Work, Cell, Fax] }
relations:
Contact: { foreignAlias: PhoneNumbers }
Now you can fetch all related objects with:
foreach ($contact->getPhoneNumbers() as $number)
{
echo $number->getNumber();
}
lib/form/doctrine/PhoneForm.class.php
class PhoneForm extends BasePhoneForm
{
public function configure()
{
$this->useFields(array('contact_id', 'number', 'type'));
$this->widgetSchema['contact_id'] = new sfWidgetFormInputHidden();
}
}
lib/form/doctrine/ContactForm.class.php
class ContactForm extends BaseContactForm
{
public function configure()
{
$this->useFields(array('first_name', 'last_name'));
// if object is new, it has no ID that we need to set in new embedded form
if (!$this->getObject()->isNew())
{
// adds blank form for adding new related values
$newPhoneForm = new PhoneForm();
$newPhoneForm->setDefault('contact_id', $this->getObject()->getId());
$this->embedForm('new', $newPhoneForm);
// adds forms for all related objects
$this->embedRelation('PhoneNumbers');
}
}
protected function doBind(array $values)
{
// you need to check if blank form is filled
if ('' === trim($values['new']['number']))
{
unset($values['new'], $this['new']);
}
parent::doBind($values);
}
}
It is based on . You can find there a solution, how to add a check box, to delete embedded values. - 10/20/10 9:49am
Pawel Dawczak says:Sorry, I missed a link to article: link
- 10/19/10 7:40pm
-

Last edited:
10/20/10
11:54amIvan Rey says:Just do both things in your form. Do a embedForm to allow the user to add new phone numbers, and do embedRelation to allow the user to edit current relations.
In ContactForm.class.php
class ContactForm extends BaseContactForm
{
public function configure()
{
$this->embedRelation('Phone'); //This allows the user to edit current relations
$phone = new Phone();
$phone->setContact($this->getForm()->getObject());
$phonesForm = new PhoneForm($phone);
$this->embedForm($phonesForm); //This allows new phones to be added
}
}
Previous versions of this answer: 10/20/10 at 12:24am
-

Last edited:
10/20/10
4:25amsaki says:Instead of this:
$phone->setContact($this->getForm()->getObject());
Use this:
$phone->Contact = $this->getObject();
I hope this helps...
This question has expired.
Current status of this question: Completed
Warning: Please do not give out any FTP or ssh credentials to anyone, unless you trust them completely. Giving out login details is dangerous.
If the asker does not get an answer then they have 10 days to request a refund.
