Symfony 2 : Access database inside FormBuilder

Yoot picture Yoot · Dec 10, 2011 · Viewed 9.2k times · Source

I'm building a form which contains a field named 'category', I need a choice list to do that, but I don't find out how to fill this choice list with the several categories stored in the database.

public function buildForm(FormBuilder $builder, array $options) {
    $builder -> add('item', 'text', array('label' => 'Item'));
    $builder -> add('category', 'choice', array(
        'choices'   => ???,
        'label' => 'Category'
    ));
}

How can I get the categories from the database here and use them to build my form ? (can't seem to access $this->getDoctrine->... inside this class).

Answer

hacksteak25 picture hacksteak25 · Dec 10, 2011

Use type entity instead of choice

$builder
  ->add('entity_property', 'entity', array(
    'class' => 'Namespace\\To\\Entity',
    'query_builder' => function(EntityRepository $repository) {
       return $repository->createQueryBuilder('q')
          ->where('q.a_field = yourvalue');
     }
));

Edit:

Two ways for using custom parameters in your query. In both situations, the parameters are injected from outside, so your FormType don't need any references to the session or request objects or whatever.

1- Pass required parameters to your constructor

class TaskType extends AbstractType
{
    private $custom_value;

    public function __construct($custom_value) {
        $this->custom_value = $custom_value;
    }

    // ...
}

in your buildForm() you must copy the value to local variable and make it available for the query_builder callback:

public function buildForm(/*...*/) {
   $my_custom_value = $this->custom_value;

   // ...
       'query_builder' => function(EntityRepository $repository) use ($my_custom_value) {
           return $repository->createQueryBuilder('q') 
               ->where('q.a_field = :my_custom_value')
               ->setParameter('my_custom_value', $my_custom_value);
       }

   // ...
}

2- use the $options parameter of the buildForm method.

First you have to define a default value by overriding getDefaultOptions:

public function getDefaultOptions(array $options)
{
    return array(
        'my_custom_value' => 'defaultvalue'
    );
}

Then you can pass it from your controller in the third argument of the createForm method.

$this->createForm(new YourFormType(), $entity, array('my_custom_value' => 'custom_value'));

Now the value should be available through the $options parameter of youru buildForm method. Pass it to the callback as described above.