动态禁用表单事件符号中的表单


Dynamically disable form in form events symfony

我有很多实体,每个实体都有自己的表单类型。一些实体实现FooBarInterface包含方法FooBarInterface::isEnabled();

我想创建一个表单扩展,在所有表单上检查data_class,并在实体实现FooBarInterface并且entity::isEnabled()返回 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';
    }
}

我必须通过$ builder-> addEventListener,因为$ builder-> getData ()并不总是有时间创建表单。但是创建表单后,我无法禁用她的选项

如何更改表单中禁用的选项?

我用方法创建了表单扩展

    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);
        }
    }

对于提交数据时的禁用更改,我创建了具有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));
        }
    }