Skip to content

Commit

Permalink
CommentSubresourceDataProvider
Browse files Browse the repository at this point in the history
  • Loading branch information
aratinau committed Jul 24, 2021
1 parent 6addf42 commit 29ac71e
Show file tree
Hide file tree
Showing 8 changed files with 229 additions and 7 deletions.
24 changes: 20 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
# Api Platform Sort, Filter and Pagination on custom data

Inspired from https://github.com/api-platform/demo
Inspired by https://github.com/api-platform/demo

# Summary

- [First Example use raw data from a csv file] https://github.com/aratinau/api-platform-pagination#first-example-use-raw-data-from-a-csv-file
- [Second example use custom controller] https://github.com/aratinau/api-platform-pagination#second-example-use-custom-controller
- [Third example use MovieCollectionDataProvider and repository] https://github.com/aratinau/api-platform-pagination#third-example-use-MovieCollectionDataProvider-and-repository
- [Fourth example use QueryBuilder in CarCollectionDataProvider (collectionExtensions)] https://github.com/aratinau/api-platform-pagination#fourth-example-use-QueryBuilder-in-CarCollectionDataProvider-(collectionExtensions)
- [Fifth example use JobCollectionDataProvider (paginationExtension)] https://github.com/aratinau/api-platform-pagination#fifth-example-use-JobCollectionDataProvider-(paginationExtension)
- [Sixth example use FurnitureDataProvider (collectionDataProvider)] https://github.com/aratinau/api-platform-pagination#sixth-example-use-FurnitureDataProvider-(collectionDataProvider)
- [Seventh example use QueryBuilder in subresource]
- [Eight example use QueryBuilder in subresource] https://github.com/aratinau/api-platform-pagination#eight-example-use-QueryBuilder-in-subresource

There is seven examples in this repo

## First Example use raw data from a csv file

Expand Down Expand Up @@ -86,9 +96,15 @@ Basic example showing how use and configure CollectionDataProvider

`api/furniture?page=2`

## Seventh example use QueryBuilder in subresource
## Seventh example : simple DataProvider using subresourceDataProvider

CommentSubresourceDataProvider show how use the standard behaviour

`api/movies/{id}/comments`

## Eight example use QueryBuilder in subresource

DiscussionDataProvider show how use QueryBuilder and order by DESC the result
DiscussionSubresourceDataProvider show how use QueryBuilder and order by DESC the result

### Usage

Expand Down
4 changes: 4 additions & 0 deletions fixtures/comment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
App\Entity\Comment:
comment_{1..1000}:
author: <name()>
content: <text()>
1 change: 1 addition & 0 deletions fixtures/movie.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ App\Entity\Movie:
movie_{1..1000}:
title: <text(10, 700)>
isPublished: '<numberBetween(0, 1)>'
comments: '<numberBetween(100, 200)>x @comment*'
32 changes: 32 additions & 0 deletions src/DataProvider/CommentSubresourceDataProvider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

namespace App\DataProvider;

use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
use ApiPlatform\Core\DataProvider\SubresourceDataProviderInterface;
use App\Entity\Comment;

final class CommentSubresourceDataProvider implements SubresourceDataProviderInterface, RestrictedDataProviderInterface
{
private $alreadyInvoked = false;
private $subresourceDataProvider;

public function __construct(SubresourceDataProviderInterface $subresourceDataProvider)
{
$this->subresourceDataProvider = $subresourceDataProvider;
}

public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
{
return false === $this->alreadyInvoked && $resourceClass === Comment::class;
}

public function getSubresource(string $resourceClass, array $identifiers, array $context, string $operationName = null)
{
$this->alreadyInvoked = true;

return $this->subresourceDataProvider->getSubresource($resourceClass, $identifiers, $context, $operationName);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
use App\Entity\Message;
use Doctrine\Persistence\ManagerRegistry;

class DiscussionDataProvider implements SubresourceDataProviderInterface, RestrictedDataProviderInterface
class DiscussionSubresourceDataProvider implements SubresourceDataProviderInterface, RestrictedDataProviderInterface
{
private $managerRegistry;

Expand All @@ -29,8 +29,6 @@ public function supports(string $resourceClass, string $operationName = null, ar

public function getSubresource(string $resourceClass, array $identifiers, array $context, string $operationName = null)
{
// $this->subresourceDataProvider->getSubresource($resourceClass, $identifiers, $context, $operationName);

$queryBuilder = $this->managerRegistry
->getManagerForClass($resourceClass)
->getRepository($resourceClass)
Expand Down
77 changes: 77 additions & 0 deletions src/Entity/Comment.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

namespace App\Entity;

use ApiPlatform\Core\Annotation\ApiResource;
use App\Repository\CommentRepository;
use Doctrine\ORM\Mapping as ORM;

/**
* @ApiResource()
* @ORM\Entity(repositoryClass=CommentRepository::class)
*/
class Comment
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;

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

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

/**
* @ORM\ManyToOne(targetEntity=Movie::class, inversedBy="comments")
*/
private $movie;

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

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

public function setAuthor(string $author): self
{
$this->author = $author;

return $this;
}

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

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

return $this;
}

public function getMovie(): ?Movie
{
return $this->movie;
}

public function setMovie(?Movie $movie): self
{
$this->movie = $movie;

return $this;
}
}
44 changes: 44 additions & 0 deletions src/Entity/Movie.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@

use ApiPlatform\Core\Annotation\ApiResource;
use App\Repository\MovieRepository;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use App\Controller\CustomMovieAction;
use Symfony\Component\Serializer\Annotation\Groups;
use ApiPlatform\Core\Annotation\ApiSubresource;

/**
* @ApiResource(
Expand Down Expand Up @@ -49,6 +52,17 @@ class Movie
*/
private $isPublished;

/**
* @ORM\OneToMany(targetEntity=Comment::class, mappedBy="movie")
* @ApiSubresource()
*/
private $comments;

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

public function getId(): ?int
{
return $this->id;
Expand Down Expand Up @@ -77,4 +91,34 @@ public function setIsPublished(bool $isPublished): self

return $this;
}

/**
* @return Collection|Comment[]
*/
public function getComments(): Collection
{
return $this->comments;
}

public function addComment(Comment $comment): self
{
if (!$this->comments->contains($comment)) {
$this->comments[] = $comment;
$comment->setMovie($this);
}

return $this;
}

public function removeComment(Comment $comment): self
{
if ($this->comments->removeElement($comment)) {
// set the owning side to null (unless already changed)
if ($comment->getMovie() === $this) {
$comment->setMovie(null);
}
}

return $this;
}
}
50 changes: 50 additions & 0 deletions src/Repository/CommentRepository.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

namespace App\Repository;

use App\Entity\Comment;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;

/**
* @method Comment|null find($id, $lockMode = null, $lockVersion = null)
* @method Comment|null findOneBy(array $criteria, array $orderBy = null)
* @method Comment[] findAll()
* @method Comment[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
*/
class CommentRepository extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Comment::class);
}

// /**
// * @return Comment[] Returns an array of Comment objects
// */
/*
public function findByExampleField($value)
{
return $this->createQueryBuilder('c')
->andWhere('c.exampleField = :val')
->setParameter('val', $value)
->orderBy('c.id', 'ASC')
->setMaxResults(10)
->getQuery()
->getResult()
;
}
*/

/*
public function findOneBySomeField($value): ?Comment
{
return $this->createQueryBuilder('c')
->andWhere('c.exampleField = :val')
->setParameter('val', $value)
->getQuery()
->getOneOrNullResult()
;
}
*/
}

0 comments on commit 29ac71e

Please sign in to comment.