Kerrial Beckett Newham
Kerrial Beckett Newham

Reputation: 360

How to filter out current user from EntityType? (Symfony Forms)

I have created a form ConversationFormType in which I want to get all the friends of that that user in an multiple choice select (EntityType).

The issue is in the select generated including the current user as well as their friends. is there any way I can filter out the current user from the output?

Thanks in advance.

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,
    ]);
}

Entity\Friendship.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;
    }
}

Update

added a query builder as suggested still getting the same results:

'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);
},

Upvotes: 1

Views: 987

Answers (1)

Milan Švehla
Milan Švehla

Reputation: 635

The most generic way how to do it in Symfony 5 for me was:

Define default current_id value for my custom key in $options

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

Pass the current user id from controller, where you create your Form

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

Use the options in 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;
},

Upvotes: 2

Related Questions