This usually goes in the controller after checking if the form submitted is valid:

// Accessing the request vars works this way:
$formSubmit = $request->request->get(‘parentForm’);
$formEntity1 = $formSubmit['entity1'];

$formEntity2 = $formSubmit['entity2']; // This accesses other sub form object for more unmapped vars

$entity1_property = $formEntity1[0]['property_field_name'];
$entity2_property= $forEntity2[0]['property_field_name'];


Limit your CRUD indexAction so it won’t show 5,000+ records and crash with memory error:

 

public function indexAction()
{
  $em = $this->getDoctrine()->getManager();

  // LIMIT LIST to 10 (whatever you put in the 3rd field below:
  $entities = $em ->getRepository(‘MainFormBundle:SomeEntity’)->findBy(
         array(), // $where
         array(), // $orderBy
         10, // $limit
         0 // $offset
);

return $this->render(‘MainFormBundle:SomeEntity:index.html.twig’, array(
   ‘entities’ => $entities,
));
}

Here are some of the most useful references and snippets for Symfony that I encounter a lot.  I will be sure to add more to the list so I only have one place to look to copy and paste.  For the latest Symfony 2.5 Cheatsheet, click here.

– Aaron Belchamber


Here is the general code pattern to build a form with a choice sub-object and use a custom repository in Symfony.  The data is stored in an “EAV” table (Entity, Attribute, Value) which is a scalable table modeled after Magento that stores different related data.  For instance, a list of all states and their abbreviations.  How about other choices you use throughout your website that you need to build form select lists from?  Use EAV tables.

I like to build different EAV tables that are basically the same except hold different type of values, so “eav_main_vc25” holds values only up to VARCHAR(25).  By separating EAVs into more manageable and like data units, you keep the tables clean and optimized.


//inside your form

$builder->add(‘general_list_of_things’,’choice’,
array(
‘choices’=>$this->em->getRepository(‘MainFormBundle:choiceListTable’)->getChoiceListTableElements($this->em),
‘attr’=>array(‘class’=>’col-xs-6 col-sm-3′),
‘label_attr’=>array(‘class’=>’col-xs-6 col-sm-3′)
));

Then in the custom repository function:


// Example for custom query inside “ChoiceListRepository", a custom function called "getChoiceList()"

This works here in repo, but you need to pass in the Entity Manager through DIC this way:
/*
$dql = “SELECT c.val from \Main\MainBundle\Entity\EavMainVc25 c
WHERE c.attr = ‘choice_list’ AND c.showLive=’1′ ORDER BY c.entityRef ASC”;
$results = $this->em->createQuery($dql)->getArrayResult();
*/

// This is better — no reason to pass the Entity Manager through DIC:

$dql = “SELECT c.val from \Main\MainBundle\Entity\EavMainVc25 c
WHERE c.attr = ‘choice_list’ AND c.showLive=’1′ ORDER BY c.entityRef ASC”;

$results=$this->_em->createQuery($dql)->getArrayResult();
return $results;

This is another pattern that is frequently accessed, so feel free to use this as a template for your own projects inside AND outside of Symfony.

– Aaron Belchamber


Let’s say you are creating a form in Symfony that has some dynamic fields that you need to allow the user to add and remove a subset of options and fields from within the form.  Enabling dynamic forms in Symfony is a bit confusing to those just getting their feet wet.  Here’s a hint:  You have to use data prototypes and a little bit of Javascript.  I prefer JQuery, but it doesn’t matter as long as the behavior ends up with the same result of “cloning” the prototype HTML into the proper place on the form with a serialized incrementation of its field name values.

Symfony relies on Javascript for dynamic forms?!  Say it isn’t so, Fabien!

Well, every framework and those home rolled models all employ the same basic tactic where parts of a form that may “grow” need to first be hidden from the user and serialized as the user adds new fields.  Think of a blogger adding multiple “tags” to a post, or someone needing to leave multiple notes in someone’s medical record.

The fact is that dynamic forms rely on the client side to allow users to add and remove new elements to and from a form so it’s a good initial test to see if they have the capability by initializing a hidden element and taking the “prototype” data out of the “data-prototype” tag that Symfony generates and unescape the embedded HTML and putting it into it’s new visible location within the dynamic form.  By the way, another good practice would be to design the form with “graceful degradation” so those who are blocking Javascript or don’t have it on their browser for some strange reason can still use the forms basically as initially intended, but that choice is up to you — and the people paying the bills.  After all, time is money.

For all those who’ve Googled and been on Stack Overflow and Binged your way onto this god-forsaken page in the middle of the great cyber void, if you need to access prototype information in order to render out certain tags the prototype html generates inside a hidden element with a “data-prototype” tag and you can’t rely on JavaScript and plain CSS to format the label and fields or maybe you just need more control over formatting, this is the general pattern to access such elements inside Twig.  Just replace “blogPost” with the name of the form and “tagName” with the name of the form field.


<div id="clone-tag-form">
<div class="formatting-tag-couldnt-do-before">

{{ form_label(form.blogPost.vars.prototype.tagName)   }}

</div>
{{ form_widget(form.blogPost.vars.prototype.tagName) }}
</div>

Keep in mind that this gives you more granular control over the part of a form that will be cloned so it’s up to you to take the HTML inside “clone-tag-form” and use a placeholder in the field name values such as “__NAME__” and replace these with serialized, incremented numbers so when processed the data won’t confuse the form handler and data won’t get lost.  It’s an all or nothing proposition.  Others suggest making a prototype template and binding the results from the prototype output to the template like so, but it just gets a little more complicated:

Idea adapted from Stack Overflow:

The idea is simply to render the collection items through a Twig template, so you can customize the prototype that will be placed in your

data-prototype="..."

tag as if it was a normal form.

In yourMainForm.html.twig:

<span class="tag">&lt;div</span><span class="atn">id</span><span class="pun">=</span><span class="atv">"collectionCont"</span><span class="atn">data-prototype</span><span class="pun">=</span><span class="atv">"
         {% filter escape %}
             {{ include('MyBundle:MyViewsDir:prototype.html.twig', { 'form': form.myForm.vars.prototype }) }}
         {% endfilter %}}"</span><span class="tag">&gt;</span><span class="tag">&lt;/div&gt;</span>

And in MyBundle:MyViewsDir:prototype.html.twig:

<span class="tag">&lt;div&gt;</span><span class="com">&lt;!-- customize as needed --&gt;</span><span class="pln">
    {{ form_label(form.field1) }}
    {{ form_widget(form.field1) }}
    {{ form_label(form.field2) }}
    {{ form_widget(form.field2) }}
</span><span class="tag">&lt;/div&gt;</span>