2
votes

Problem

I have a Symfony2 2.3 project that consists of many entities (models). These models range from address, person, application and others amongst this. I needed a form to represent different steps in an online application. The application steps all contained many fields from various entities.

So at first; I created matching FormTypes and Twig templates to match. Everything was fine until I needed to mix the forms up.

For example, for one form, I needed:

  • First name
  • Surname
  • DOB
  • Postcode (from address entity)
  • Application started date (from application entity)

As you can see, the form consists of 2 extra elements from different forms. Thus I had the problem of binding the three layers together with use of Doctrine; entity, from type and twig template. (http://symfony.com/doc/current/book/forms.html#handling-form-submissions)

Current Solution

Thus so far, I have my models setup as they should be. So address details are within the address entity and personal details are stored in the person entity.

I have then created all my FormTypes of how I want them to output to the screen, with the mixed fields in. Therefore, I have for example a Step-1 FormType that has:

  • First name
  • Second name
  • DOB
  • Address house number
  • Address postcode

Then in Twig simply output the fields. I was then going to add custom validation and custom methods to save the data to the DB, to the various tables. I came to the conclusion that I had to do this because none of the forms can map to a single entity.

What I Need

If anyone could shed some light on this and provide me with some examples, it would greatly appreciated!

As you can see below, I have some fields that I have hard-coded that represent different properties from other entities and a FormType.

  • I need a way to have all these entities in normal form.
  • Have various FormType steps that have mixed properties from these various entities
  • Some FormTypes will embed other FormTypes, e.g. address - as the user can add 3.
  • Have Twig tempalte that will simply render each individual widget.
  • A controller that loads the form, checks it is valid and saves values to their own tables.

It may be, that I must create a totally custom method that saves the values individually but I was hoping for a 'Symfony way' of achieving this.

Example code

Assume all getters and setters created with Doctrine. Assume all Doctrine Mapping added with one-to-one relationships to link tables.

Person entity:

private $id
private $first_name
private $last_name
private $dob

Address entity

private $address_number
private $address_postcode
private $address_lived_years
private $address_lived_months

Application entity

private $id
private $plan

AddresType

$builder->add('address_number', 'text')
        ->add('address_postcode', 'text')

Example mixed form: Step1Type

$builder->add('first_name', 'text')
        ->add('last_name', text')
        ->add('dob', 'date')
        ->add('address_1', 'collection', array('type' => new AddressType()));
        ->add('address_lived_years', 'text')
        ->add('address_lived_months', 'text')
        ->add('plan', 'text')

Twig

{{ form_start(step_1_form) }}

    {{ form_label(step_1_form.first_name, 'First Name') }}
    {{ form_errors(step_1_form.first_name) }}
    {{ form_widget(step_1_form.first_name) }}

    ... etc

{{ form_end(step_1_form) }}

Controller to bring it all together

$step_1_form = $this->createForm(new StepOneType())->createView();

return $this->render('MyBundle:Application:apply_step_1.html.twig', array(
                    'step_1_form' => $step_1_form));

// Code needed to load form getForm() and handleRequest()
1
symfony 1.3-1.4 had a way of "merging" forms together - perhaps Symfony2 has something like that?halfer
Cheers halfer. It does needed have one using the getForm() method and assigning it a new instance of the entity. All that you would need to do, is then persist() it to save it to database. The problem is, I can't see to find a standardized way of doing this where my forms don't map 1-1 to my entity; but form mapping to many entities.Amarjit
Yes, I think 1.x merging did that, though I never quite spent the right amount of time to get my head around it. The idea was that a customer form (for a single customer) could be merged with an orders form (for many orders), to create a form in which all the above could be edited. I can't offer much more help than that, other than to suggest that "merge form" might be a good set of search keywords!halfer
Thanks for this halfer. I will look into this.Amarjit
Symfony2 has an inherit_data_option that allows merging/sharing of fields between form entities, but I've only had time to skim your question so I am not sure how applicable it is to your question in its entirety. However it's worth a look: symfony.com/doc/2.3/cookbook/form/inherit_data_option.htmlDarragh Enright

1 Answers

1
votes

I do not see any Doctrine association mappings defined there. Since you are asking the user to enter some data from person entity and some data from the address entity I assume you need to save them and mark them as related (as in, the row saved in the person table should be somehow linked to the row saved in the address table). For your case I think that OneToOne should be the case (one person is linked to one address... and vice-versa). Though, in real life, this is not really the case.

You should than define specific *Type classes (PersonAddresType, for instance) to hold ONLY the wanted fields for that specific situation and use the doctrine relations and embedded forms there. See documentation for this on S2 site. For your case I think that embedding a single object is the right start.

If you need more details (or maybe some example)... let me know. I'll try to write some lines of code, if necessary.