Loic H
Loic H

Reputation: 348

Filter an array collection relation

I try to filter the collection returned by a parent Entity base on several conditions that refer to another Entity (User).

Basicaly i want API PLATFORM to return the messages from the current connected User only.

Here is my Entity named File (very simplified for global understanding)

<?php
namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Symfony\Component\Serializer\Annotation\Groups;
use ApiPlatform\Core\Annotation\ApiFilter;
use ApiPlatform\Core\Annotation\ApiResource;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\DateFilter;
use App\Controller\FileCreatePdfController;
use Ramsey\Uuid\Uuid;
use Gedmo\Mapping\Annotation as Gedmo;



/**
 * @ApiResource(
*
 *     normalizationContext={"groups"={"file"},"enable_max_depth"=true},
 *     denormalizationContext={"groups"={"file-write"},"enable_max_depth"=true},
 *     attributes={"force_eager"=false},
 * )
 * @ApiFilter(SearchFilter::class, properties={"status": "exact"})
 * @ApiFilter(DateFilter::class, properties={"updatedAt"})
 * @ORM\Entity
 * @ORM\Table(name="cases")
 */
class File
{

    public function __construct()
    {
        $this->id = Uuid::uuid4();
        $this->messages = new ArrayCollection();
    }

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


    /**
     * @ORM\Id
     * @ORM\Column(type="uuid", unique=true)
     */
    private $id;

    /**
     * @var Collection|FileMessage[]
     *
     * @Groups({"file"})
     * @ORM\OneToMany(targetEntity="App\Entity\FileMessage", mappedBy="file")
     */
    private $messages;


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


    /**
     * @param FileMessage $message
     * @return File
     */
    public function addMessage(FileMessage $message): self
    {
        if (false === $this->messages->contains($message)) {
            $this->messages->add($message);
        }
        return $this;
    }




}

My file contains some messages from FileMessage (very simplified for global understanding

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use ApiPlatform\Core\Annotation\ApiResource;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
use Ramsey\Uuid\Uuid;


/**
 * @ApiResource(
 *     normalizationContext={"groups"={"file-message"}, "enable_max_depth"=true},
 *     denormalizationContext={"groups"={"file-message-write"}, "enable_max_depth"=true},
 *     attributes={"force_eager"=false}
 * )
 * @ORM\Entity
 * @ORM\Table(name="`file_messages`")
 */

class FileMessage {

    /**
     *
     * @ORM\Id
     * @ORM\Column(type="uuid", unique=true)
     */
    private $id;

    /**
     * @var File
     *
     * @ORM\ManyToOne(targetEntity="File", cascade={"persist"}, inversedBy="messages")
     * @Assert\Valid
     * @Groups({"file-message", "file-message-write","file"})
     */
    private $file;


    /**
     * @var User
     *
     * @ORM\ManyToOne(targetEntity="User", cascade={"persist"}, inversedBy="messages")
     * @Assert\Valid
     * @Groups({"file-message", "file-message-write","file"})
     */
    private $user;


    public function __construct()
    {
        $this->id = Uuid::uuid4();
    }

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


    public function getFile(): ?File
    {
        return $this->file;
    }

    public function setFile(?File $file): self
    {
        $this->file = $file;

        return $this;
    }

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

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

        return $this;
    }



}

Each message is posted by a specific user (another entity User ) i don't think it is neccesary to post the content of this entity.

When i fetch a specific file , url/files/[file_id]

All the messages for all users are displayed , i want to hide all message that not refer to the connected User

enter image description here

Solution I have tried so far :

Do I have any solution ? I was thinking maybe to use an event listener

Upvotes: 0

Views: 4689

Answers (1)

K&#233;vin Dunglas
K&#233;vin Dunglas

Reputation: 3024

Extensions are the way to go. They give you access to the Doctrine ORM Query Builder, so you can filter both the current resource and its relations by tweaking the WHERE clause of the DQL query. It's always better to filter the data as early as possible (for performance, among other reasons), so here doing it at the DBMS level is the best option.

Upvotes: 2

Related Questions