Search code examples
phpformssymfonyentity

Symfony 3 - Get choices option from entity object passed to the form?


I have a WorkflowType form class which data_class attribute is Workflow::class. When creating the form in a Controller action function I pass it an Workflow object which has a states property:

public function createWorkflowAction(Request $request, Workflow $workflow) {
    $secondFormPart = $this->createForm(WorkflowType::class, $workflow);
    ...
}

To the form I add an EntityType form field which class attribute is State::class. This entity class has more then one property but I am just using one of it and want to render the EntityType field as a select box:

class WorkflowType extends AbstractType {

    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options) {
        //@formatter:off
            $builder
                ->add('initialState', EntityType::class, array(
                    'class'             => State::class,
                    'choice_label'      => 'key',
                    'choice_value'      => 'key',

                    // This combination of 'expanded' and 'multiple' implements a select box
                    'expanded'          => false,
                    'multiple'          => false,
                ))...
                ...
        }
        ...
}

Now the problem:

Symfony tries to get the choices for initialState EntityType field out of the Database: An exception occurred while executing 'SELECT t0_.id AS id_0, t0_.key AS key_1, t0_.order AS order_2, t0_.workflow_id AS workflow_id_3 FROM testpra_State t0_'.

But I want to get the choices from the states property of the Workflow object $workflowI pass to createForm in the controller.

Something like:

->add('initialState', EntityType::class, array(
    'class'             => State::class,
    'choice_label'      => 'key',
    'choice_value'      => 'key',
    'choices'           => $workflow->getStates(),

    // This combination of 'expanded' and 'multiple' implements a select box
    'expanded'          => false,
    'multiple'          => false,
))

I know that I can use the $option array like:

$secondFormPart = $this->createForm(PraWorkflowTransitionsType::class, $workflow, array(
    'states'    => $workflow->getStates()
));

But is there a simpler solution?

And if yes how can I get access to the object I pass to createForm in a subform?


Solution

  • But is there a simpler solution?

    Like kunicmarko20 stated in a comment the object is accessible through $options['data']:

    public function buildForm(FormBuilderInterface $builder, array $options) {
    
        /** @var Workflow $workflow */
        $workflow = $options['data'];
        ...
    }
    

    He also pointed out that I should use ChoiceType which is better because EntityType is designed to load options from a Doctrine entity.

    And if yes how can I get access to the object I pass to createForm in a subform?

    In my case I have a CollectionType field which dynamically adds forms of entry_type TransitionType. In this case you can pass the data via the entry_options attribute:

    ->add('transitions', CollectionType::class, array(
        'entry_type'        => TransitionType::class,
        'entry_options'     => array(
            'states'    => $workflow->getStates(),
        ),
        ...
    ))
    

    and in the TransitionType class:

    public function buildForm(FormBuilderInterface $builder, array $options) {
    
        /** @var ArrayCollection $states */
        $states = $options['states'];
        ...
    }