我正在使用我的个人项目
Symfony v4.2.1
PHP v7.2.12
Windows 10
我有代表目录和文件的树形结构。我必须限制对文件夹文件树中项目的访问。为此,存在一个实体,该实体具有id
,access levels
(请看示例中的第一个代码块)并引用了user
和file tree
。
为了解决这个问题,我使用AccessSetupType
(请参阅代表我的表单的第二个代码块)。
此时显示表格。显示选择选项元素,并设置从0到4的相应选项值。
发布后,我似乎仅获得更改的字段(正确的计数,但始终为false),而不是所有复选框均具有各自的值!
如何将选择(如第一个示例中所示)传递给表单,并自动使用数据库中的数据填写复选框?
如何在提交表单时不仅将所有检查过的元素传递给控制器?
第一个代码块($ 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
]
这是我单击选项后呈现表单的方式。
它不显示选择的选项数据库。
我在做什么错?我想念什么?
谢谢你的想法!
我已经将FileTreeAccess记录(请参见第4个代码块)传递给表单。
如果我将第二个参数new FileTreeAccess()
传递给表单构造函数
我有以下错误:
Cannot read index "accessSetup" from object of type "App\Entity\FileTreeAccess" because it doesn't implement \ArrayAccess.
我认为问题源可能是-为了管理对
FileTree
的访问,我只需要将8个实体属性中的5个(代表权限的属性)传递给表单。怎么做?也许为此目的需要DataTransformer吗?
答案 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);