Symfony 4.2表单ChoiceType扩展为“多个”无法填充数据库中的复选框并保存更改

时间:2019-01-02 21:30:25

标签: php forms symfony select symfony4

简介

我正在使用我的个人项目

  • Symfony v4.2.1
  • PHP v7.2.12
  • Windows 10

我有代表目录和文件的树形结构。我必须限制对文件夹文件树中项目的访问。为此,存在一个实体,该实体具有idaccess levels(请看示例中的第一个代码块)并引用了userfile tree

为了解决这个问题,我使用AccessSetupType(请参阅代表我的表单的第二个代码块)。

问题说明

此时显示表格。显示选择选项元素,并设置从0到4的相应选项值。

发布后,我似乎仅获得更改的字段(正确的计数,但始终为false),而不是所有复选框均具有各自的值!

问题

  1. 如何将选择(如第一个示例中所示)传递给表单,并自动使用数据库中的数据填写复选框?

  2. 如何在提交表单时不仅将所有检查过的元素传递给控制器​​?

代码

  

第一个代码块($ access_info)

$access_info = [
  "can_see" => true
  "can_download" => false
  "can_upload" => false
  "can_delete" => true
  "is_owner" => false
]
  

第二个代码块(AccessSetupType)

namespace App\Form\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class AccessSetupType extends AbstractType
{
    private $access_choices;

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $this->access_choices = $options['access_choices'];

        $builder
            ->add('accessSetup', ChoiceType::class,
                [
                    'label' => 'Access level:',
                    'choices' => $this->access_choices,
                    'mapped' => false,
                    'expanded' => true,
                    'multiple' => true,
                    'label_attr' => ['class' => 'checkbox-custom'],
                    'translation_domain' => 'form_access',
                    'empty_data' => false
                ]
            )
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(
            [
                'access_choices' => null,
                'data_class' => null,
                'csrf_protection' => true,
                'csrf_field_name' => '_token',
            ]
        );
    }
}
  

第三个代码块(控制器的相关部分)

$file_tree_node_id = 17;
$user_id = 5;

$access_choices = $repo_file_tree_access->getFileTreeAccessByNodeAndUser($node_id, $user_id);

$form = $this->createForm(AccessSetupType::class, null, array(
    'action' => $this->generateUrl('admin_access_setup_with_node_id', ['node_id' => $node_id]),
    'method' => 'POST',
    'node_id' => $node_id,
    'access_choices' => $access_choices,
));

$form->handleRequest($request);

if ($form->isSubmitted() && $form->isValid())
{
    $data = $form['accessSetup']->getData();
    dump($data);

    if ($form->get('saveAccess')->isClicked())
    {
        // save clicked
        dump('save clicked');

        $file_tree_access = new FileTreeAccess();
        $file_tree_access->setCanSee($data[0]);
        $file_tree_access->setCanDownload($data[1]);
        $file_tree_access->setCanUpload($data[2]);
        $file_tree_access->setCanDelete($data[3]);
        $file_tree_access->setIsOwner($data[4]);
        $file_tree_access->setUser($repo_user->findOneBy(['id' => $user_id]));
        $file_tree_access->setFileTree($repo_file_tree->getOneFileTreeNode($file_tree_node_id));

        if (($file_tree_access !== null) && ($file_tree_access !== []))
        {
            //$em->persist($file_tree_access);
            //$em->flush();
        }
    }
    else if ($form->get('return')->isClicked())
    {
        // return clicked
        dump('return clicked');
    }
}
  

第4个代码块(FileTreeAccess实例示例)

array:8 [
    "id" => 4
    "can_see" => true
    "can_download" => false
    "can_upload" => false
    "can_delete" => false
    "is_owner" => false
    "file_tree_id" => 16
    "user_id" => 5
]

渲染表格

这是我单击选项后呈现表单的方式。

它不显示选择的选项数据库。

enter image description here

结论

我在做什么错?我想念什么?

谢谢你的想法!

更新1

我已经将FileTreeAccess记录(请参见第4个代码块)传递给表单。

如果我将第二个参数new FileTreeAccess()传递给表单构造函数

我有以下错误:

  • Cannot read index "accessSetup" from object of type "App\Entity\FileTreeAccess" because it doesn't implement \ArrayAccess.

更新2

  

我认为问题源可能是-为了管理对FileTree的访问,我只需要将8个实体属性中的5个(代表权限的属性)传递给表单。怎么做?也许为此目的需要DataTransformer吗?

1 个答案:

答案 0 :(得分:0)

要预先填写选项,必须将表单绑定到对象。然后,当您提交表单时,您无需设置所有内容,它会自动完成。

$file_tree_access = new FileTreeAccess();

// load data from database here then set them in your object before passing it to the form

$form = $this->createForm(AccessSetupType::class, $file_tree_access, array(
    'action' => $this->generateUrl('admin_access_setup_with_node_id', ['node_id' => $node_id]),
    'method' => 'POST',
    'node_id' => $node_id,
    'access_choices' => $access_choices,
));

$form->handleRequest($request);