-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Custom Paginator in Provider with QueryBuilder
- Loading branch information
Showing
14 changed files
with
600 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
App\Entity\Album: | ||
album_{1..1000}: | ||
title: <word()> | ||
year: '<randomElement( [1999, 2000, 2004, 2011, 2016] )>' | ||
artist: '@artist*' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
App\Entity\Artist: | ||
artist_{1..10}: | ||
author: <name()> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
App\Entity\Post: | ||
post_{1..100}: | ||
title: <word(10, 700)> | ||
slug: <word(10, 700)> | ||
summary: <word(10, 700)> | ||
content: <word(10, 700)> | ||
publishedAt: '<dateTimeBetween("-100 days", "100 days")>' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
<?php | ||
|
||
namespace App\DataProvider\Pagination; | ||
|
||
use ApiPlatform\Core\DataProvider\PaginatorInterface; | ||
use Doctrine\ORM\QueryBuilder as DoctrineQueryBuilder; | ||
|
||
class PostPaginator implements PaginatorInterface, \IteratorAggregate | ||
{ | ||
public const PAGE_SIZE = 3; | ||
|
||
private $postsIterator; | ||
private $currentPage; | ||
private $maxResults; | ||
private $queryBuilder; | ||
private $totalResult; | ||
private $results; | ||
|
||
public function __construct(DoctrineQueryBuilder $queryBuilder, | ||
int $currentPage, | ||
$totalResult, | ||
int $maxResults = self::PAGE_SIZE) | ||
{ | ||
$this->currentPage = $currentPage; | ||
$this->maxResults = $maxResults; | ||
$this->queryBuilder = $queryBuilder; | ||
$this->totalResult = $totalResult; | ||
} | ||
|
||
public function getLastPage(): float | ||
{ | ||
return ceil($this->getTotalItems() / $this->getItemsPerPage()) ?: 1.; | ||
} | ||
|
||
public function getTotalItems(): float | ||
{ | ||
return $this->totalResult; | ||
} | ||
|
||
public function getCurrentPage(): float | ||
{ | ||
return $this->currentPage; | ||
} | ||
|
||
public function getItemsPerPage(): float | ||
{ | ||
return $this->maxResults; | ||
} | ||
|
||
public function count() | ||
{ | ||
return iterator_count($this->getIterator()); | ||
} | ||
|
||
public function getIterator() | ||
{ | ||
if ($this->postsIterator === null) { | ||
$offset = ($this->currentPage - 1) * $this->maxResults; | ||
|
||
$query = $this->queryBuilder | ||
->setFirstResult($offset) | ||
->setMaxResults($this->maxResults) | ||
->getQuery() | ||
; | ||
$this->results = $query->getResult(); | ||
|
||
$this->postsIterator = new \ArrayIterator( | ||
$this->results | ||
); | ||
} | ||
|
||
return $this->postsIterator; | ||
} | ||
|
||
public function getResults(): \Traversable | ||
{ | ||
return $this->results; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
<?php | ||
|
||
namespace App\DataProvider; | ||
|
||
use ApiPlatform\Core\DataProvider\ContextAwareCollectionDataProviderInterface; | ||
use ApiPlatform\Core\DataProvider\Pagination; | ||
use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface; | ||
use App\Entity\Post; | ||
use App\Repository\PostRepository; | ||
|
||
class PostCollectionDataProvider implements ContextAwareCollectionDataProviderInterface, RestrictedDataProviderInterface | ||
{ | ||
private $postRepository; | ||
private $pagination; | ||
|
||
public function __construct(PostRepository $postRepository, | ||
Pagination $pagination) | ||
{ | ||
$this->postRepository = $postRepository; | ||
$this->pagination = $pagination; | ||
} | ||
|
||
public function supports(string $resourceClass, string $operationName = null, array $context = []): bool | ||
{ | ||
return $resourceClass === Post::class; | ||
} | ||
|
||
public function getCollection(string $resourceClass, string $operationName = null, array $context = []) | ||
{ | ||
[$page] = $this->pagination->getPagination($resourceClass, $operationName, $context); | ||
|
||
return $this->postRepository->findLatest($page); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
<?php | ||
|
||
namespace App\Entity; | ||
|
||
use ApiPlatform\Core\Annotation\ApiResource; | ||
use App\Repository\AlbumRepository; | ||
use Doctrine\ORM\Mapping as ORM; | ||
use Symfony\Component\Serializer\Annotation\Groups; | ||
|
||
/** | ||
* @ApiResource() | ||
* @ORM\Entity(repositoryClass=AlbumRepository::class) | ||
*/ | ||
class Album | ||
{ | ||
/** | ||
* @ORM\Id | ||
* @ORM\GeneratedValue | ||
* @ORM\Column(type="integer") | ||
* @Groups({"normalization-albums-by-artist"}) | ||
*/ | ||
private $id; | ||
|
||
/** | ||
* @ORM\Column(type="string", length=255) | ||
* @Groups({"normalization-albums-by-artist"}) | ||
*/ | ||
private $title; | ||
|
||
/** | ||
* @ORM\Column(type="integer") | ||
* @Groups({"normalization-albums-by-artist"}) | ||
*/ | ||
private $year; | ||
|
||
/** | ||
* @ORM\ManyToOne(targetEntity=Artist::class, inversedBy="albums") | ||
*/ | ||
private $artist; | ||
|
||
public function getId(): ?int | ||
{ | ||
return $this->id; | ||
} | ||
|
||
public function getTitle(): ?string | ||
{ | ||
return $this->title; | ||
} | ||
|
||
public function setTitle(string $title): self | ||
{ | ||
$this->title = $title; | ||
|
||
return $this; | ||
} | ||
|
||
public function getYear(): ?int | ||
{ | ||
return $this->year; | ||
} | ||
|
||
public function setYear(int $year): self | ||
{ | ||
$this->year = $year; | ||
|
||
return $this; | ||
} | ||
|
||
public function getArtist(): ?Artist | ||
{ | ||
return $this->artist; | ||
} | ||
|
||
public function setArtist(?Artist $artist): self | ||
{ | ||
$this->artist = $artist; | ||
|
||
return $this; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
<?php | ||
|
||
namespace App\Entity; | ||
|
||
use ApiPlatform\Core\Annotation\ApiResource; | ||
use App\Repository\ArtistRepository; | ||
use Doctrine\Common\Collections\ArrayCollection; | ||
use Doctrine\Common\Collections\Collection; | ||
use Doctrine\ORM\Mapping as ORM; | ||
use Symfony\Component\Serializer\Annotation\Groups; | ||
|
||
/** | ||
* @ApiResource( | ||
* collectionOperations={ | ||
* "get", | ||
* "post", | ||
* "subresource-albums-by-artist"={ | ||
* "method"="GET", | ||
* "deserialize"=false, | ||
* "path"="/artists/{id}/album/{year}", | ||
* "normalization_context"={"groups" = "normalization-albums-by-artist"} | ||
* } | ||
* } | ||
* ) | ||
* @ORM\Entity(repositoryClass=ArtistRepository::class) | ||
*/ | ||
class Artist | ||
{ | ||
/** | ||
* @ORM\Id | ||
* @ORM\GeneratedValue | ||
* @ORM\Column(type="integer") | ||
* @Groups({"normalization-albums-by-artist"}) | ||
*/ | ||
private $id; | ||
|
||
/** | ||
* @ORM\Column(type="string", length=255) | ||
* @Groups({"normalization-albums-by-artist"}) | ||
*/ | ||
private $author; | ||
|
||
/** | ||
* @ORM\OneToMany(targetEntity=Album::class, mappedBy="artist") | ||
*/ | ||
private $albums; | ||
|
||
public function __construct() | ||
{ | ||
$this->albums = new ArrayCollection(); | ||
} | ||
|
||
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; | ||
} | ||
|
||
/** | ||
* @return Collection|Album[] | ||
*/ | ||
public function getAlbums(): Collection | ||
{ | ||
return $this->albums; | ||
} | ||
|
||
public function addAlbum(Album $album): self | ||
{ | ||
if (!$this->albums->contains($album)) { | ||
$this->albums[] = $album; | ||
$album->setArtist($this); | ||
} | ||
|
||
return $this; | ||
} | ||
|
||
public function removeAlbum(Album $album): self | ||
{ | ||
if ($this->albums->removeElement($album)) { | ||
// set the owning side to null (unless already changed) | ||
if ($album->getArtist() === $this) { | ||
$album->setArtist(null); | ||
} | ||
} | ||
|
||
return $this; | ||
} | ||
} |
Oops, something went wrong.