Sf2/3 为不同的角色(用户)显示不同的表单
Sf2/3 Displaing different forms for Different roles(users)
我有一个需要复杂访问控制的应用程序。 Voters 是我需要在控制器级别做出决定的东西。
但是,我需要通过不同的方式为不同的用户构建表单。
示例:有 Admin(ROLE_ADMIN) 和 User(ROLE_USER)。有一个 Post 包含字段:
- 发表
- 已审核
- 作者
- 正文
- 时间戳
管理员必须能够编辑任何 Post 的所有字段。
用户 - 仅限特定字段:已发布、正文。 (顺便说一下,只有当他是这个 post 的作者时,但这是由投票者决定的)。
我找到的可能解决方案是 dynamic form modification。但是如果我们需要更复杂一些,比如posts属于Blog,Blog属于author。并且 Post 可以由博客的直接作者和作者编辑。
并且博客的作者也可以编辑 postedAt 字段,但是 post.
的直接作者不能这样做
我需要在 PRE_BIND 侦听器中编写一些登录信息。
也许对于这种情况有某种常见的做法,或者有人可以展示他们自己的例子。
动态表单修改似乎没有必要。用户登录后,角色不应更改。
您可以在您的表单类型中注入 security.authorization_checker
服务,并在 buildForm
方法中使用它来有条件地将字段添加到您的表单中。根据表格的不同程度,如果 if 语句过多,这可能会变得混乱。在那种情况下,我建议完全编写不同的表单类型(可能为重复的事情扩展基本表单类型)。
您可以创建 form type extension
想象一个表单类型,您希望仅在授予 ROLE_ADMIN
时才显示字段。为此,您只需在字段中添加一个新的 属性(本例中为 'author')
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('published', 'text')
->add('moderated', 'text')
->add('author', 'text', [
'is_granted' => 'ROLE_ADMIN',
])
;
}
要解释此参数,您必须通过注入 SecurityContext
Symfony 来创建表单类型扩展,以确保登录用户的权限。
<?php
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Core\SecurityContextInterface;
class SecurityTypeExtension extends AbstractTypeExtension
{
/**
* The security context
* @var SecurityContextInterface
*/
private $securityContext;
/**
* Object constructor
*/
public function __construct(SecurityContextInterface $securityContext)
{
$this->securityContext = $securityContext;
}
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$grant = $options['is_granted'];
if (null === $grant || $this->securityContext->isGranted($grant)) {
return;
}
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$form = $event->getForm();
if ($form->isRoot()) {
return;
}
$form->getParent()->remove($form->getName());
});
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefined(array('is_granted' => null));
}
/**
* {@inheritdoc}
*/
public function getExtendedType()
{
return 'form';
}
}
最后,您只需将扩展程序另存为服务即可:
services:
yourbundle.security_type_extension:
class: YourProject\Bundle\ForumBundle\Form\Extension\SecurityTypeExtension
arguments:
- @security.context
tags:
- { name: form.type_extension, alias: form }
我有一个需要复杂访问控制的应用程序。 Voters 是我需要在控制器级别做出决定的东西。 但是,我需要通过不同的方式为不同的用户构建表单。 示例:有 Admin(ROLE_ADMIN) 和 User(ROLE_USER)。有一个 Post 包含字段:
- 发表
- 已审核
- 作者
- 正文
- 时间戳
管理员必须能够编辑任何 Post 的所有字段。 用户 - 仅限特定字段:已发布、正文。 (顺便说一下,只有当他是这个 post 的作者时,但这是由投票者决定的)。
我找到的可能解决方案是 dynamic form modification。但是如果我们需要更复杂一些,比如posts属于Blog,Blog属于author。并且 Post 可以由博客的直接作者和作者编辑。 并且博客的作者也可以编辑 postedAt 字段,但是 post.
的直接作者不能这样做我需要在 PRE_BIND 侦听器中编写一些登录信息。
也许对于这种情况有某种常见的做法,或者有人可以展示他们自己的例子。
动态表单修改似乎没有必要。用户登录后,角色不应更改。
您可以在您的表单类型中注入 security.authorization_checker
服务,并在 buildForm
方法中使用它来有条件地将字段添加到您的表单中。根据表格的不同程度,如果 if 语句过多,这可能会变得混乱。在那种情况下,我建议完全编写不同的表单类型(可能为重复的事情扩展基本表单类型)。
您可以创建 form type extension
想象一个表单类型,您希望仅在授予 ROLE_ADMIN
时才显示字段。为此,您只需在字段中添加一个新的 属性(本例中为 'author')
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('published', 'text')
->add('moderated', 'text')
->add('author', 'text', [
'is_granted' => 'ROLE_ADMIN',
])
;
}
要解释此参数,您必须通过注入 SecurityContext
Symfony 来创建表单类型扩展,以确保登录用户的权限。
<?php
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Security\Core\SecurityContextInterface;
class SecurityTypeExtension extends AbstractTypeExtension
{
/**
* The security context
* @var SecurityContextInterface
*/
private $securityContext;
/**
* Object constructor
*/
public function __construct(SecurityContextInterface $securityContext)
{
$this->securityContext = $securityContext;
}
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$grant = $options['is_granted'];
if (null === $grant || $this->securityContext->isGranted($grant)) {
return;
}
$builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) {
$form = $event->getForm();
if ($form->isRoot()) {
return;
}
$form->getParent()->remove($form->getName());
});
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefined(array('is_granted' => null));
}
/**
* {@inheritdoc}
*/
public function getExtendedType()
{
return 'form';
}
}
最后,您只需将扩展程序另存为服务即可:
services:
yourbundle.security_type_extension:
class: YourProject\Bundle\ForumBundle\Form\Extension\SecurityTypeExtension
arguments:
- @security.context
tags:
- { name: form.type_extension, alias: form }