Api-platform : filtrer les résultats uniquement sur l’utilisateur connecté

Imaginez avoir dans votre projet plusieurs entités avec la relation author comme par exemple ces deux entités suivantes :

<?php

namespace App\Entity;

use ApiPlatform\Metadata\ApiResource;
use App\Repository\CourierFavoriteRepository;
use Doctri…


This content originally appeared on DEV Community and was authored by Aymeric Ratinaud

Imaginez avoir dans votre projet plusieurs entités avec la relation author comme par exemple ces deux entités suivantes :

<?php

namespace App\Entity;

use ApiPlatform\Metadata\ApiResource;
use App\Repository\CourierFavoriteRepository;
use Doctrine\ORM\Mapping as ORM; 

#[ORM\Entity(repositoryClass: CourierFavoriteRepository::class)]
#[ApiResource()]
class Book
{ 
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\ManyToOne]
    #[ORM\JoinColumn(nullable: false)] 
    private ?User $author = null; 

    #[ORM\Column(length: 255)] 
    private ?string $title = null;

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

    public function getAuthor(): ?User
    {
        return $this->author;
    }

    public function setAuthor(?User $author): static
    {
        $this->author = $author;

        return $this;
    } 

    public function getTitle(): ?string
    {
        return $this->title;
    }

    public function setTitle(string $title): self
    {
        $this->title = $title;

        return $this;
    }
}
<?php

namespace App\Entity;

use ApiPlatform\Metadata\ApiResource;
use App\Repository\TodoRepository; 
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: TodoRepository::class)]
#[ApiResource()]
class Todo
{
    #[ORM\Id]
    #[ORM\GeneratedValue]
    #[ORM\Column]
    private ?int $id = null;

    #[ORM\ManyToOne]
    #[ORM\JoinColumn(nullable: false)]
    private ?User $author = null;

    #[ORM\Column(type: Types::TEXT)]
    private ?string $content = null;

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

    public function getAuthor(): ?User
    {
        return $this->author;
    }

    public function setAuthor(?User $author): static
    {
        $this->author = $author;

        return $this;
    }

    public function getContent(): ?string
    {
        return $this->content;
    }

    public function setContent(string $content): static
    {
        $this->content = $content;

        return $this;
    }
}

Nous voulons verrouiller les résultats des GET item et collection uniquement sur l'user connecté.

Nous allons créer une interface que nous implémenterons sur nos entités

<?php

namespace App\Entity;

interface CurrentUserIsAuthorInterface
{
    public function setAuthor(?User $author): static;
}

Maitenant nous allons faire une DoctrineExtension qui va ajouter la contrainte where dans le QueryBuilder sur l'utilisateur connecté.

<?php

namespace App\DoctrineExtension;

use ApiPlatform\Doctrine\Orm\Extension\QueryCollectionExtensionInterface;
use ApiPlatform\Doctrine\Orm\Extension\QueryItemExtensionInterface;
use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface;
use ApiPlatform\Metadata\Operation;
use App\Entity\CurrentUserIsAuthorInterface;
use Doctrine\ORM\QueryBuilder;
use Symfony\Bundle\SecurityBundle\Security;

class CurrentUserIsAuthorExtension implements QueryCollectionExtensionInterface, QueryItemExtensionInterface
{
    public function __construct(
        private Security $security,
    ) {
    }

    public function applyToCollection(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, ?Operation $operation = null, array $context = []): void
    {
        $this->currentUserIsAuthor($resourceClass, $queryBuilder);
    }

    public function applyToItem(QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, array $identifiers, ?Operation $operation = null, array $context = []): void
    {
        $this->currentUserIsAuthor($resourceClass, $queryBuilder);
    }

    /**
     * @param string $resourceClass
     * @param QueryBuilder $queryBuilder
     * @return void
     * @throws ReflectionException
     */
    public function currentUserIsAuthor(string $resourceClass, QueryBuilder $queryBuilder): void
    {
        $reflectionClass = new \ReflectionClass($resourceClass);
        if ($reflectionClass->implementsInterface(CurrentUserIsAuthorInterface::class)) {
            $alias = $queryBuilder->getRootAliases()[0];
            $queryBuilder->andWhere("$alias.author = :current_author")
                ->setParameter('current_author', $this->security->getUser()->getId());
        }
    }
}

Maintenant il nous reste à implémenter notre interface sur nos entités :

<?php

namespace App\Entity;

use ApiPlatform\Metadata\ApiResource;
use App\Repository\CourierFavoriteRepository;
use Doctrine\ORM\Mapping as ORM; 

#[ORM\Entity(repositoryClass: CourierFavoriteRepository::class)]
#[ApiResource()]
class Book implements CurrentUserIsAuthorInterface
{ 
    // ...
<?php

namespace App\Entity;

use ApiPlatform\Metadata\ApiResource;
use App\Repository\TodoRepository; 
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity(repositoryClass: TodoRepository::class)]
#[ApiResource()]
class Todo implements CurrentUserIsAuthorInterface
{
    // ...

Et c'est tout. Pour chaque GET item ou collection vous aurez uniquement les entrées avec l'utilisateurs qui est connecté 🚀

Lisez aussi "comment enregistrer automatiquement l'utilisateur connecté" : https://dev.to/aratinau/automatisons-lenregistrement-du-user-sur-nimporte-quelle-entite-4f68


This content originally appeared on DEV Community and was authored by Aymeric Ratinaud


Print Share Comment Cite Upload Translate Updates
APA

Aymeric Ratinaud | Sciencx (2024-06-23T09:52:46+00:00) Api-platform : filtrer les résultats uniquement sur l’utilisateur connecté. Retrieved from https://www.scien.cx/2024/06/23/api-platform-filtrer-les-resultats-uniquement-sur-lutilisateur-connecte/

MLA
" » Api-platform : filtrer les résultats uniquement sur l’utilisateur connecté." Aymeric Ratinaud | Sciencx - Sunday June 23, 2024, https://www.scien.cx/2024/06/23/api-platform-filtrer-les-resultats-uniquement-sur-lutilisateur-connecte/
HARVARD
Aymeric Ratinaud | Sciencx Sunday June 23, 2024 » Api-platform : filtrer les résultats uniquement sur l’utilisateur connecté., viewed ,<https://www.scien.cx/2024/06/23/api-platform-filtrer-les-resultats-uniquement-sur-lutilisateur-connecte/>
VANCOUVER
Aymeric Ratinaud | Sciencx - » Api-platform : filtrer les résultats uniquement sur l’utilisateur connecté. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2024/06/23/api-platform-filtrer-les-resultats-uniquement-sur-lutilisateur-connecte/
CHICAGO
" » Api-platform : filtrer les résultats uniquement sur l’utilisateur connecté." Aymeric Ratinaud | Sciencx - Accessed . https://www.scien.cx/2024/06/23/api-platform-filtrer-les-resultats-uniquement-sur-lutilisateur-connecte/
IEEE
" » Api-platform : filtrer les résultats uniquement sur l’utilisateur connecté." Aymeric Ratinaud | Sciencx [Online]. Available: https://www.scien.cx/2024/06/23/api-platform-filtrer-les-resultats-uniquement-sur-lutilisateur-connecte/. [Accessed: ]
rf:citation
» Api-platform : filtrer les résultats uniquement sur l’utilisateur connecté | Aymeric Ratinaud | Sciencx | https://www.scien.cx/2024/06/23/api-platform-filtrer-les-resultats-uniquement-sur-lutilisateur-connecte/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.