Symfony 根据条目修改CollectionType中的条目选项';s数据

Symfony 根据条目修改CollectionType中的条目选项';s数据,symfony,symfony-forms,Symfony,Symfony Forms,我有一张带收藏的Symfony表格。用户可以从组织中添加或删除用户(为了简单起见,仅举一个例子)。但是,我希望防止人们从组织中删除某些用户。比如说:管理员不能被删除,但他们的名字仍然可以更改 以下是我现在得到的: class OrganisationType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder-

我有一张带收藏的Symfony表格。用户可以从组织中添加或删除用户(为了简单起见,仅举一个例子)。但是,我希望防止人们从组织中删除某些用户。比如说:管理员不能被删除,但他们的名字仍然可以更改

以下是我现在得到的:

class OrganisationType extends AbstractType {

    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder->add(
            'users',
            CollectionType::class,
            [
                'required' => FALSE,
                'entry_type' => UserType::class,
                'label' => 'Users',
                'show_legend' => FALSE,
                'entry_options' => [
                    'label_render' => FALSE,
                    'data_class' => User::class,
                ],
                'widget_add_btn' => ['label' => 'Add user'],
                'by_reference' => FALSE,
                'allow_add' => TRUE,
                'allow_delete' => TRUE,
                'prototype' => TRUE,
            ]
        );
    }
}

class UserType extends AbstractType {

    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder
            ->add(
                'name',
                TextType::class,
                ['required' => TRUE]
            )
            ->add(
                'email',
                TextType::class,
                ['required' => TRUE]
            );
    }
}
我已经读过,但是当尝试在我的
UserType
中使用表单事件时,似乎没有办法修改集合中的条目:

$builder->addEventListener(
        FormEvents::POST_SET_DATA,
        function(FormEvent $event) {
            $user = $event->getData();
            $form = $event->getForm();

            if ($user->isAdmin()) {
                //maybe some logic here? But what?
            }
        }
)

我可以根据条目的数据修改条目选项吗?

如果我理解正确,可以通过收听您的
组织类型上的
提交前
提交后
事件来完成

首先,我会在
PRE_SUBMIT
上记住用户ID,然后在
POST_SUBMIT
上对照前一个集合检查现有集合。大概是这样的:

<?php
class OrganisationType extends AbstractType {

    private $preSubmitAdminsIds = [];

    public function buildForm(FormBuilderInterface $builder, array $options) {
        // ....

        $adminIds = $this->preSubmitAdminsIds;

        $builder
        ->addEventListener('PRE_SUBMIT', function(FormEvent $event) use (&$adminIds){ // ! Note the reference pass
            $org = $event->getData();
            $users = $org->getUsers();

            foreach ($users as $u){
                if ($u->isAdmin()){
                    $adminIds[] = $u->getId(); // I guess you do have some sort of id
                }
            }
        })
        ->addEventListener('POST_SUBMIT', function(FormEvent $event) use (&$adminIds) { // ! Note the reference pass
            $org = $event->getData();
            $users = $org->getUsers();
            $newAdminIds = [];

            foreach ($users as $u){
                if ($u->isAdmin()){
                    $newAdminIds[] = $u->getId();
                }
            }

            if (!empty(array_diff($adminIds, $newAdminIds))){
                $event->getForm()->get('users')->addError("You cannot remove admins!");
            }
        });

        // ....
    }
} 

不能在将用户列表绑定到集合字段之前过滤用户列表而不是“防止”?不能,因为应该允许他们更改用户(例如他们的电子邮件地址)。