【问题标题】:How can I filter an EntityType in my form with roles?如何使用角色过滤表单中的 EntityType?
【发布时间】:2019-07-10 16:22:49
【问题描述】:

我想在 Synfomy 表单中显示一个选择输入,它只建议具有特定角色的用户。

我目前正在编写一个应用程序,其中涉及一些基本用户和一些负责基本用户的超级用户。

所以每当我注册一个新用户时,我都希望能够将他分配给一个指定的“超级用户”来管理。

但是当我尝试在我的registrationType中创建一个entityType字段来选择要分配的超级用户时,我不知道如何只显示选择中带有ROLE_MANAGER的用户。我只知道如何显示所有用户。

所有用户都在同一个表中。 我只使用 Symfony 角色系统来区分它们。

我尝试查看 query_builder 解决方案,但我不明白如何使用“where”参数查看数组或在该查询中应用角色层次结构。

我的表单类型如下。 我试图在“经理”实体类型选择输入中仅显示角色具有 ROLE_MANAGER 及更高级别的用户。

角色存储在这样的数组中:["ROLE_USER", "ROLE_MANAGER","ROLE_ADMIN"]... 所以 user.roles 返回这种数组。


class RegistrationType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {

        $builder
            ->add('email')
            ->add('username')
            ->add('manager', EntityType::class,[
                'class' => User::class,
                'choice_label' => 'username',
                'query_builder' => function (EntityRepository $er){
                    return $er->createQueryBuilder('u')
                        ->orderBy('u.username', 'ASC');
                }])
            ->add('password',PasswordType::class)
            ->add('confirm_password',PasswordType::class)
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => User::class,
            'validation_groups' => ['Default', 'registration'],
        ]);
    }
}

谁能指出我正确的方向?

非常感谢!

【问题讨论】:

    标签: symfony4


    【解决方案1】:

    我相信用户角色存储在一个字符串化数组中,这使得使用== 之类的东西更难查询。但是,您可以使用 LIKE 运算符。这将寻找一个模式。在您的情况下,如果您只想向用户显示ROLE_MANAGER,您可以使用:

     ->andWhere('u.roles LIKE \'%ROLE_MANAGER%\' ')
    

    把它放在->orderBy('u.username', 'ASC');上方的行中。

    注意:如果您有其他包含ROLE_MANAGER 的角色,在使用LIKE%...% 时也会返回这些角色。您可以阅读有关 sql LIKE 运算符here 的更多信息。

    ps。您可能想知道为什么我会使用andWhere() 而不是where()。这是习惯性的,因为where() 可以删除实际 SQL 查询中以前的WHERE 语句(如果有的话),所以我尽量避免它。并改用andWhere()

    【讨论】:

    • 您好,非常感谢!它实际上作为一种解决方案效果很好!也感谢您对“andWhere()”的附加解释,它实际上解决了我遇到的另一个问题!这里唯一的缺点是它不应用角色层次结构,但是对于这种特殊用途,事实证明这样更好!再次非常感谢!
    【解决方案2】:

    您应该在查询中简单地精确它(并尽可能避免在代码中使用原始字符串):

    //somewhere in your project
    class User
    {
        const ROLE_MANAGER = 'ROLE_MANAGER'; //or in your config, parameters etc
    }
    
    public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $role = User::ROLE_MANAGER;
            // OR something like this if you think you gonna 
            // need to reuse this formtype with other roles restructions : 
            // $role = $options["role"];
    
            //...
                           ->andWhere(':role IN u.roles')
                           ->setParameter('role', $role)
    

    DQL 中另一个很酷的事情是它为标准 SQL 操作添加了一些糖。 例如,在与此类似的用例中,您可能需要使用“MEMBER OF”关键字来搜索集合中的特定实体:

                          ->andWhere(':manager MEMBER OF u.managedBy')
                           ->setParameter('manager', $user)
    

    希望对您有所帮助!

    【讨论】:

    • 这实际上也很有帮助!一种更微妙的方法,到目前为止我还没有成功地实现它,但最终我会尝试以这种方式实现它。我真的要复习一下 DQL,MEMBER OF 运算符似乎很强大,可以忽略!非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2021-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多