2016-02-25 9 views
0

J'ai plusieurs entités, chacune ayant son propre type de formulaire. Certaines des entités met en œuvre FooBarInterface comprenant méthode FooBarInterface::isEnabled();Désactiver dynamiquement le formulaire dans les événements de formulaire symfony

Je veux créer une extension formulaire, à vérifier data_class à toutes les formes, et désactiver formulaire si entité implémente FooBarInterface et entity::isEnabled() return false.

<?php 
namespace AppBundle\Form\Extension; 

use Symfony\Component\Form\AbstractTypeExtension; 
use Symfony\Component\Form\FormInterface; 
use Symfony\Component\Form\FormView; 

class MyExtension extends AbstractTypeExtension 
{ 

    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $dataClass = $builder->getDataClass(); 
     if ($dataClass) { 
      $reflection = new \ReflectionClass($dataClass); 

      if ($reflection->implementsInterface(FooBarInterface::class)) { 
       $builder->addEventListener(FormEvents::PRE_SET_DATA, function(FormEvent $formEvent) { 
        $data = $formEvent->getData(); 
        if ($data && !$data->isEnabled()) { 
         // todo this need disable all form with subforms 
        } 
       }); 
      } 
     } 
    } 

    public function getExtendedType() 
    { 
     return 'form'; 
    } 
} 

je dois le faire à travers le $ builder-> addEventListener, parce que $ builder-> getData() n'ont pas toujours le temps de créer une forme. Mais après la création du formulaire, je ne peux pas changer son option désactivée

Comment changer l'option désactivée dans le formulaire?

Répondre

0

I créé le formulaire d'extension avec la méthode

public function finishView(FormView $view, FormInterface $form, array $options) 
    { 
     $dataClass = $form->getConfig()->getDataClass(); 
     if ($dataClass) { 
      $reflection = new \ReflectionClass($dataClass); 

      if ($reflection->implementsInterface(FooBarInterface::class)) { 
       /** @var FooBarInterface$data */ 
       $data = $form->getData(); 

       if ($data && !$data ->isEnabled()) { 
        $this->recursiveDisableForm($view); 
       } 
      } 
     } 
    } 

    private function recursiveDisableForm(FormView $view) 
    { 
     $view->vars['disabled'] = true; 
     foreach ($view->children as $childView) { 
      $this->recursiveDisableForm($childView); 
     } 
    } 

Pour désactiver les modifications si les données sont soumises je crée Doctrine Abonné événement avec l'événement FormEvents::PRE_UPDATE:

/** 
    * @param PreUpdateEventArgs $args 
    */ 
    public function preUpdate(PreUpdateEventArgs $args) 
    { 
     $entity = $args->getEntity(); 

     if (!$entity instanceof DataStateInterface) { 
      return; 
     } 

     if (!$entity->isEnabled()) { 
      $args->getEntityManager()->getUnitOfWork()->clearEntityChangeSet(spl_object_hash($entity)); 
     } 
    }