【问题标题】:How to filter out current user from EntityType? (Symfony Forms)如何从 EntityType 中过滤掉当前用户? (Symfony 表格)
【发布时间】:2020-04-13 15:17:27
【问题描述】:

我创建了一个表单ConversationFormType,我想在其中获得该用户的所有朋友在多项选择中选择(EntityType)。

问题出在生成的选择中,包括当前用户及其朋友。有什么办法可以从输出中过滤掉当前用户?

提前致谢。

Form\ConversationFormType.php

 public function buildForm(FormBuilderInterface $builder, array $options)
        {       
            $builder
                ->add('name', TextType::class,[
                    'label'=>'Conversation title'
                ])
                ->add('Users', EntityType::class, [
                    'label' => 'invite a friend to this conversation',
                    'attr'=>['class'=>'form-control'],
                    'class' => Friendship::class,
                    'choice_label' => 'friend.fullName',
                    'multiple'=>true,
                ]);
        }
public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults([
        'data_class' => Conversation::class,
    ]);
}

实体\友谊.php

/**
 * @ORM\Entity(repositoryClass="App\Repository\FriendshipRepository")
 */
class Friendship
{

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="friendships")
     * @ORM\Id
     */
    private $user;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\User", inversedBy="friendsWithMe")
     * @ORM\Id
     */
    public $friend;

    /**
     * @ORM\Column(type="date")
     */
    private $date;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getUser(): ?User
    {
        return $this->user;
    }

    public function setUser(?User $user): self
    {
        $this->user = $user;

        return $this;
    }

    public function getFriend(): ?User
    {
        return $this->friend;
    }

    public function setFriend(?User $friend): self
    {
        $this->friend = $friend;

        return $this;
    }

    public function getDate(): ?\DateTimeInterface
    {
        return $this->date;
    }

    public function setDate(\DateTimeInterface $date): self
    {
        $this->date = $date;

        return $this;
    }
}

Entity\Conversation.php

/**
 * @ORM\Entity(repositoryClass="App\Repository\ConversationRepository")
 */
class Conversation
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\ManyToMany(targetEntity="App\Entity\User", inversedBy="conversations")
     */
    private $Users;

    /**
     * @ORM\OneToMany(targetEntity="App\Entity\Message", mappedBy="conversation")
     */
    private $Messages;

    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private $name;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private $slug;

    public function __construct()
    {
        $this->Users = new ArrayCollection();
        $this->Messages = new ArrayCollection();
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    /**
     * @return Collection|User[]
     */
    public function getUsers(): Collection
    {
        return $this->Users;
    }

    public function addUser(User $user): self
    {
        if (!$this->Users->contains($user)) {
            $this->Users[] = $user;
        }

        return $this;
    }

    public function removeUser(User $user): self
    {
        if ($this->Users->contains($user)) {
            $this->Users->removeElement($user);
        }

        return $this;
    }

    /**
     * @return Collection|Message[]
     */
    public function getMessages(): Collection
    {
        return $this->Messages;
    }

    public function addMessage(Message $message): self
    {
        if (!$this->Messages->contains($message)) {
            $this->Messages[] = $message;
            $message->setConversation($this);
        }

        return $this;
    }

    public function removeMessage(Message $message): self
    {
        if ($this->Messages->contains($message)) {
            $this->Messages->removeElement($message);
            // set the owning side to null (unless already changed)
            if ($message->getConversation() === $this) {
                $message->setConversation(null);
            }
        }

        return $this;
    }

    public function getName(): ?string
    {
        return $this->name;
    }

    public function setName(?string $name): self
    {
        $this->name = $name;

        return $this;
    }

    public function getSlug(): ?string
    {
        return $this->slug;
    }

    public function setSlug(string $slug): self
    {
        $this->slug = $slug;

        return $this;
    }
}

更新

按照建议添加了一个查询生成器,仍然得到相同的结果:

'query_builder' => function (EntityRepository $er) use ($user) { 
     return $er->createQueryBuilder('none')
     ->from(Friendship::class,'friendship')
     ->where('friendship.user != friendship.friend')
     ->andWhere('friendship.user != :user')
     ->setParameter('user', $user);
},

【问题讨论】:

  • 您应该创建一个验证器,以避免用户将自己添加为朋友。您应该在您的数据库上创建一个完整性约束,当用户具有与朋友相同的 ID 时会引发错误。
  • 使用custom query 并排除当前用户。你可以让它在你的类型中注入Security 服务。
  • @AlexandreTranchant 是的,如果我从好友的输出中删除当前用户 ID,那么用户将无法将自己添加为好友。但我试图理解为什么当前用户被包括在内。
  • 该查询不返回除我之外的所有用户的朋友吗?不应该是'friendship.user' = :user吗?
  • @msg 谢谢,但是会返回朋友和当前用户。

标签: php symfony symfony-forms


【解决方案1】:

对我来说,在 Symfony 5 中最通用的方法是:

在 $options 中为我的自定义键定义默认 current_id

public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults([
        'data_class' => Conversation::class,
        'current_id' => 0
    ]);
}

从创建表单的控制器传递当前用户 ID

$options['current_id'] = $user->getId();
$form = $this->createForm(ConversationFormType::class, $conversation, $options);

使用 query_builder 中的选项

'query_builder' => function (EntityRepository $er) use ($options) { 
     $qb = $er->createQueryBuilder('f')
     ->from(Friendship::class,'friendship')
     ->where('friendship.user != friendship.friend');


    if(isset($options['current_id'])) {
        $qb->andWhere('friendship.user != :current_id')
         ->setParameter('current_id', $options['current_id']);

    }

    return $qb;
},

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-25
    • 2021-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多