动态禁用表单事件symfony中的表单

时间:2016-02-25 13:19:32

标签: php symfony symfony-forms

我有很多实体,每个实体都有自己的表单类型。一些实体实现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 ()并不总是有时间创建表单。但是在创建表单后,我无法更改她的选项禁用

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

1 个答案:

答案 0 :(得分:0)

我用方法

创建了表单扩展
    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事件创建Doctrine事件订阅者:

    /**
     * @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));
        }
    }