Symfony 4.2 Form ChoiceType Expanded Multiple не может заполнять флажки из базы данных и сохранять изменения - PullRequest
0 голосов
/ 03 января 2019

Введение

Для моего личного проекта я использую

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

У меня есть древовидная структура, которая представляет каталоги и файлы. Я должен ограничить доступ к элементам в дереве файлов папки. Для этой цели существует сущность, которая имеет id, access levels (посмотрите на 1-й блок кода для примера) и ссылается на user и file tree.

Для управления этим я использую AccessSetupType (см. 2-й блок кода, представляющий мою форму).

Объяснение проблемы

В данный момент отображается форма. Отображаются элементы выбора параметров и устанавливаются соответствующие значения параметров от 0 до 4.

После публикации я, кажется, получаю только измененные поля (правильный счет, но всегда со значением false), а не все флажки с соответствующими значениями!

Вопросы

  1. Как передать варианты (как в первом примере) в форму и автоматически заполнить флажки данными из базы данных?

  2. Как передать все элементы, проверенные не только контролеру при отправке формы?

Код

1-й кодовый блок ($ access_info)

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

2-й кодовый блок (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',
            ]
        );
    }
}

3-й кодовый блок (соответствующая часть контроллера)

$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 мне нужно передать в форму только 5 из 8 свойств сущностей (тех, которые представляют разрешения). Как это сделать? Может быть, мне нужен DataTransformer для этой цели?

1 Ответ

0 голосов
/ 03 января 2019

Чтобы предварительно заполнить параметры, необходимо связать форму с объектом.Затем, когда вы отправляете форму, вам не нужно все настраивать, это делается автоматически.

$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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...