Search code examples
phpformssymfonysymfony-3.1

symfony3 form, can't get options in buildForm method


I don't really know which title to give this thread but, i'm working on a Symfony project in v3.1.6 and using the select2 plugin in field of my form with ajax.

I want to use the event (submit and pre_set_data) of the form component for creation and editing to change the field dynamically like this part of the symfony doc. Everything work fine until when i submit the form and give an error Notice: Undefined variable: options

My form type code here

namespace Xxx\ArticleBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Xxx\ArtistBundle\Repository\ArtistRepository;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Ivory\CKEditorBundle\Form\Type\CKEditorType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Doctrine\ORM\EntityManager;

class ArticleType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
    //$em = $options['em']; //this give me same error


        $builder
        ->add('artist', EntityType::class, array(
            'class' => 'XxxArtistBundle:Artist',
            'choice_label' => 'artist_name',
            'multiple' => false,
            'expanded' => false))
        ->add('title', TextType::class)
        ->add('categories', EntityType::class, array(
            'class' => 'XxxArticleBundle:Category',
            'choice_label' => 'name',
            'multiple' => true,
            'expanded' => true))
        ->add('image', ChoiceType::class, array(
            'expanded' => false,
            'multiple' => false))
        ->add('intro', CKEditorType::class)
        ->add('content', CKEditorType::class);

    $formModifier = function (FormInterface $form, $image) {
        $listImages = $options['em']->getRepository('XxxAppBundle:Image')->find($image)); //this line give me the error
        if (!$listImages) {
            return; //i will add a FormError in the field
        }
        $listImages = array();
        die(var_dump($listImages));

        $form->add('image', EntityType::class, array(
            'class'       => 'XxxAppBundle:Image',
            'choices'     => $listImages,
        ));
    };

    $builder->get('image')->addEventListener(
        FormEvents::POST_SUBMIT,
        function (FormEvent $event) use ($formModifier) {
            $image = $event->getForm()->getData();
            //die(var_dump($image)); //select2 field, returned null (but it's not the question
            //die(var_dump($options)); returned error 500 Notice: Undefined variable: options
            $formModifier($event->getForm()->getParent(), $image);
        }
    );
}

/**
 * {@inheritdoc}
 */
public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults(array(
        'data_class' => 'Xxx\ArticleBundle\Entity\Article',
    ));
    $resolver->setRequired('em');
}

/**
 * {@inheritdoc}
 */
public function getBlockPrefix()
{
    return 'xxx_articlebundle_article';
}
}

And i also want to say the goal is to have a UI similar w/ Wordpress when create a post from the dashboard, for set an image in an article and when image is selected throw it in a tag to the user and without entityType because it will have thousand so i choose an choiceType to use with the select2 plugin but if someone got a better solution i'm on it.

Thx in advance for the help


Solution

  • When you're using a variable from a parent scope inside a closure, you should pass it to 'use' language construct.

    $formModifier = function (FormInterface $form, $image) use ($options) {
        $listImages = $options['em']->getRepository('XxxAppBundle:Image')->find($image)); //this line give me the error
        if (!$listImages) {
            return; //i will add a FormError in the field
        }
        $listImages = array();
        die(var_dump($listImages));
    
        $form->add('image', EntityType::class, array(
            'class'       => 'XxxAppBundle:Image',
            'choices'     => $listImages,
        ));
    };