Reputation: 348
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
Solution I have tried so far :
Do I have any solution ? I was thinking maybe to use an event listener
Upvotes: 0
Views: 4689
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