从 Symfony 中的表单类型访问用户实体

Erv*_*bić 1 php multi-tenant symfony fosuserbundle

我正在尝试在 Symfony 中构建多租户支持,为此我group_id在我的用户中创建了一个列,最重要的是,所有实体也都有这个相同的列。这样用户只能访问其组的数据。

我已经成功地通过数据访问和显示解决了整个问题,但随后出现了EntityTypesSymfony Forms 的挑战。

问题基本上是,如何EntityType仅显示该特定组输入的数据。按group_id用户和联系人所拥有的进行排序。传递此信息以便用户只能访问其数据的最佳方法是什么?

<?php 

namespace ContactBundle\Form; 

use ContactBundle\Entity\Contact; 
use ContactBundle\Entity\Organization;
use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\OptionsResolver\OptionsResolver; 
use Symfony\Component\Form\Extension\Core\Type\TextType; 
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType; 

class ContactType extends AbstractType 
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder 
        ->add('first_name', TextType::Class, [
            'attr' => ['class'=>'u-full-width'],
            'label' => 'First Name',])
        ->add('last_name', TextType::Class, [
            'attr' => ['class'=>'u-full-width'],
            'label'=>'Last Name',
        ])
        ->add('email', TextType::Class, [
            'attr' => ['class'=>'u-full-width'],
            'label'=>'Email Address'
        ])
        ->add('organization_id', EntityType::Class, [
            'attr' => ['class'=>'u-full-width'],
            'required' => false,
            'class'=>'ContactBundle:Organization',
            'choice_label'=>'name',
            'choice_value'=>'id',
            'label'=>'Organization'
        ])
        ->add('phone', TextType::Class, [
            'attr' => ['class'=>'u-full-width'],
            'label'=>'Phone',
        ])
        ->add('role', TextType::Class, [
            'attr' => ['class'=>'u-full-width'],
            'label'=>'Role',
        ])
        ->add('submit', SubmitType::class, [
            'label'=>'Submit', 
            'attr' => [
                'class'=>'button-primary',
                'style'=>'margin-top:30px;',]]);
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(['data_class'=>Contact::class,]);
    }
}
?>
Run Code Online (Sandbox Code Playgroud)

值得注意的是,我正在使用FOSUserBundle.

Jim*_*imL 5

在 Symfony 中,可以很容易地在需要的地方注入任何需要的东西。

// ...
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;

class ContactType extends AbstractType
{
    private $user;

    public function __construct(TokenStorageInterface $tokenStorage)
    {
        $this->user = $tokenStorage->getToken()->getUser();
    }

    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            // ...
            ->add('organization_id', EntityType::Class, [
                'attr' => ['class'=>'u-full-width'],
                'required' => false,
                'class'=>'ContactBundle:Organization',
                'query_builder' => function (EntityRepository $er) {
                    return $er->createQueryBuilder('u')
                        ->where('u.group', '?0')
                        ->setParameters([$this->user->getGroup()]);
                },
                'choice_label'=>'name',
                'choice_value'=>'id',
                'label'=>'Organization'
            ])
            // ...
Run Code Online (Sandbox Code Playgroud)

如果您不使用自动装配和自动配置(Symfony 3.3+),请手动将表单注册为服务并使用 form.type 对其进行标记:

# config/services.yaml
services:
    AppBundle\Form\ContactType:
        arguments: ['@security.token_storage']
        tags: [form.type]
Run Code Online (Sandbox Code Playgroud)

相关阅读

https://symfony.com/doc/current/form/form_dependency.html#define-your-form-as-a-service

https://symfony.com/doc/current/reference/forms/types/entity.html#using-a-custom-query-for-the-entities