Symfony2 - How to use a Data Transformer inside EventListeners

后端 未结 2 1838
无人及你
无人及你 2021-01-28 00:41
  • I need to use an Event Listener since I need different things to be displayed in my form whether it is new or an already existing entity. I can manage that.

相关标签:
2条回答
  • 2021-01-28 01:18

    I have wrote a Form Extension to support this use case without changing type of fields.

    1) Create extension class.

    namespace AppBundle\Form\Extension\ModelTransformerExtension
    
    use Symfony\Component\Form\AbstractTypeExtension;
    use Symfony\Component\Form\Extension\Core\Type\FormType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolver;
    
    class ModelTransformerExtension extends AbstractTypeExtension {
    
        public function getExtendedType() {
            return FormType::class;
        }
    
        public function buildForm(FormBuilderInterface $builder, array $options) {
            parent::buildForm($builder, $options);
    
            if (isset($options['model_transformer'])) {
                $builder->addModelTransformer($options['model_transformer']);
            }
        }
    
        public function configureOptions(OptionsResolver $resolver) {
            parent::configureOptions($resolver);
    
            $resolver->setDefaults(array('model_transformer' => null));
        }
    }
    

    2) Register this extension as an application service.

    services:
        app.form.extension.model_transformer:
            class: AppBundle\Form\Extension\ModelTransformerExtension
            tags:
                - { name: form.type_extension, extended_type: Symfony\Component\Form\Extension\Core\Type\FormType }
    

    3) Define model_transformer option to any DataTransformer implement when building the form.

    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder->addEventListener(FormEvents::PRE_SET_DATA, function ($event) {
            $builder = $event->getForm();
    
            $builder->add('myField', TextType::class, array(
                'model_transformer' => new MyModelTransformer()
            ));
        });
    }
    

    This idea can be extended to support addViewTransformer method as well.

    0 讨论(0)
  • 2021-01-28 01:27

    Short answer: You can´t add the transformer inside the listener because the form is already locked.

    Long answer: There are some solutions. The most common, at least for me, is to a create a Custom form type where you add your transformer. Then you add your custom form how you would normally do in the event listener:

    class ElementCustomType extends AbstractType {
    
        private $em;
    
        public function __construct(EntityManager $entityManager)
        {
            $this->em = $entityManager;
        }
    
        public function buildForm(FormBuilderInterface $builder, array $options) {
    
            $builder
                ->addModelTransformer(new ElementObjToStringTransformer($this->em))
            ;
        }
    
        public function getParent() {
            return 'text';
        }
    
        public function getName() {
            return 'elementCustom';
        }
    }
    

    Define your form as a service:

     app.form.type.custom_element:
        class: AppBundle\Form\Type\ElementCustomType
        arguments: [@doctrine.orm.entity_manager]
        tags:
            - { name: form.type, alias: elementCustom }
    

    Use the form in the listener as your would normally do:

    $builder->addEventListener(FormEvents::PRE_SET_DATA, function(FormEvent $event){
            $element = $event->getData();
            $form = $event->getForm();
            $form->add('element', 'elementCustom')
        });
    
    0 讨论(0)
提交回复
热议问题