Skip to content

Commit

Permalink
Improve methods reusability
Browse files Browse the repository at this point in the history
cerbero90 committed Feb 11, 2024

Unverified

This user has not yet uploaded their public signing key.
1 parent ed81c94 commit 45a55b1
Showing 8 changed files with 89 additions and 47 deletions.
Original file line number Diff line number Diff line change
@@ -10,16 +10,21 @@
use Psr\Http\Message\ResponseInterface;

/**
* The trait to yield paginated items.
* The trait to parse pages.
*/
trait YieldsPaginatedItems
trait ParsesPages
{
/**
* The number of items per page.
*/
protected readonly int $itemsPerPage;

/**
* Yield paginated items and the given key from the provided response.
*
* @return Generator<int, mixed>
*/
protected function yieldItemsAndReturnKey(ResponseInterface $response, string $key): Generator
protected function yieldItemsAndGetKey(ResponseInterface $response, string $key): Generator
{
$itemsPerPage = 0;
$pointers = [$this->config->itemsPointer];
36 changes: 36 additions & 0 deletions src/Concerns/YieldsItemsByCursor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?php

declare(strict_types=1);

namespace Cerbero\LazyJsonPages\Concerns;

use Cerbero\LazyJsonPages\Services\Client;
use Closure;
use Generator;
use Psr\Http\Message\ResponseInterface;

/**
* The trait to yield items from cursor-aware paginations.
*/
trait YieldsItemsByCursor
{
/**
* Yield the paginated items by following the cursor of each page.
*
* @param (Closure(ResponseInterface): Generator<int, mixed>) $callback
* @return Generator<int, mixed>
*/
protected function yieldItemsByCursor(Closure $callback): Generator
{
yield from $generator = $callback($this->source->pullResponse());

$request = clone $this->source->request();

while ($cursor = $this->toPage($generator->getReturn(), onlyNumerics: false)) {
$uri = $this->uriForPage($request->getUri(), (string) $cursor);
$response = Client::instance()->send($request->withUri($uri));

yield from $generator = $callback($response);
}
}
}
Original file line number Diff line number Diff line change
@@ -2,51 +2,52 @@

declare(strict_types=1);

namespace Cerbero\LazyJsonPages\Paginations;
namespace Cerbero\LazyJsonPages\Concerns;

use Cerbero\LazyJsonPages\Concerns\SendsAsyncRequests;
use Cerbero\LazyJsonPages\Exceptions\InvalidKeyException;
use Closure;
use Generator;
use Illuminate\Support\LazyCollection;
use Psr\Http\Message\ResponseInterface;

/**
* The abstract implementation of a pagination that is aware of its length.
* The trait to yield items from length-aware paginations.
*/
abstract class LengthAwarePagination extends Pagination
trait YieldsItemsByLength
{
use SendsAsyncRequests;

/**
* Yield paginated items until the page resolved from the given key is reached.
*
* @param (Closure(int): int)|null $callback
* @param (Closure(int): int) $callback
* @return Generator<int, mixed>
*/
protected function yieldItemsUntilKey(string $key, ?Closure $callback = null): Generator
protected function yieldItemsUntilKey(string $key, Closure $callback = null): Generator
{
yield from $generator = $this->yieldItemsAndReturnKey($this->source->response(), $key);
yield from $this->yieldItemsUntilPage(function(ResponseInterface $response) use ($key, $callback) {
yield from $generator = $this->yieldItemsAndGetKey($response, $key);

$page = $this->toPage($generator->getReturn());
if (!is_int($page = $this->toPage($generator->getReturn()))) {
throw new InvalidKeyException($key);
}

if (!is_int($page)) {
throw new InvalidKeyException($key);
}

$page = $callback ? $callback($page) : $page;

yield from $this->yieldItemsUntilPage($page);
return $callback ? $callback($page) : $page;
});
}

/**
* Yield paginated items until the given page is reached.
* Yield paginated items until the resolved page is reached.
*
* @param (Closure(ResponseInterface): Generator<int, mixed>) $callback
* @return Generator<int, mixed>
*/
protected function yieldItemsUntilPage(int $page): Generator
protected function yieldItemsUntilPage(Closure $callback): Generator
{
yield from $generator = $callback($this->source->pullResponse());

$uri = $this->source->request()->getUri();
$chunkedPages = $this->chunkPages($page);
$chunkedPages = $this->chunkPages($generator->getReturn());

foreach ($this->fetchPagesAsynchronously($chunkedPages, $uri) as $page) {
yield from $this->yieldItemsFrom($page);
Original file line number Diff line number Diff line change
@@ -4,14 +4,17 @@

namespace Cerbero\LazyJsonPages\Paginations;

use Cerbero\LazyJsonPages\Services\Client;
use Cerbero\LazyJsonPages\Concerns\YieldsItemsByCursor;
use Psr\Http\Message\ResponseInterface;
use Traversable;

/**
* The pagination aware of the cursor of the next page.
*/
class CursorPagination extends Pagination
class CursorAwarePagination extends Pagination
{
use YieldsItemsByCursor;

/**
* Determine whether the configuration matches this pagination.
*/
@@ -30,15 +33,10 @@ public function matches(): bool
*/
public function getIterator(): Traversable
{
yield from $generator = $this->yieldItemsAndReturnKey($this->source->response(), $this->config->cursorKey);

$request = clone $this->source->request();

while ($cursor = $this->toPage($generator->getReturn(), onlyNumerics: false)) {
$uri = $this->uriForPage($request->getUri(), (string) $cursor);
$response = Client::instance()->send($request->withUri($uri));
yield from $this->yieldItemsByCursor(function(ResponseInterface $response) {
yield from $generator = $this->yieldItemsAndGetKey($response, $this->config->cursorKey);

yield from $generator = $this->yieldItemsAndReturnKey($response, $this->config->cursorKey);
}
return $generator->getReturn();
});
}
}
2 changes: 1 addition & 1 deletion src/Paginations/CustomPagination.php
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@
/**
* The user-defined pagination.
*/
class CustomPagination extends LengthAwarePagination
class CustomPagination extends Pagination
{
/**
* Determine whether the configuration matches this pagination.
7 changes: 5 additions & 2 deletions src/Paginations/LastPageAwarePagination.php
Original file line number Diff line number Diff line change
@@ -4,13 +4,16 @@

namespace Cerbero\LazyJsonPages\Paginations;

use Cerbero\LazyJsonPages\Concerns\YieldsItemsByLength;
use Traversable;

/**
* The pagination aware of the number of the last page.
*/
class LastPageAwarePagination extends LengthAwarePagination
class LastPageAwarePagination extends Pagination
{
use YieldsItemsByLength;

/**
* Determine whether the configuration matches this pagination.
*/
@@ -26,7 +29,7 @@ public function matches(): bool
*/
public function getIterator(): Traversable
{
yield from $this->yieldItemsUntilKey($this->config->lastPageKey, function (int $page) {
yield from $this->yieldItemsUntilKey($this->config->lastPageKey, function(int $page) {
return $this->config->firstPage === 0 ? $page + 1 : $page;
});
}
18 changes: 7 additions & 11 deletions src/Paginations/TotalItemsAwarePagination.php
Original file line number Diff line number Diff line change
@@ -4,14 +4,16 @@

namespace Cerbero\LazyJsonPages\Paginations;

use Cerbero\LazyJsonPages\Exceptions\InvalidKeyException;
use Cerbero\LazyJsonPages\Concerns\YieldsItemsByLength;
use Traversable;

/**
* The pagination aware of the total number of items.
*/
class TotalItemsAwarePagination extends LengthAwarePagination
class TotalItemsAwarePagination extends Pagination
{
use YieldsItemsByLength;

/**
* Determine whether the configuration matches this pagination.
*/
@@ -29,14 +31,8 @@ public function matches(): bool
*/
public function getIterator(): Traversable
{
yield from $generator = $this->yieldItemsAndReturnKey($this->source->response(), $this->config->totalItemsKey);

if (!is_numeric($totalItems = $generator->getReturn())) {
throw new InvalidKeyException($this->config->totalItemsKey);
}

$totalPages = $this->itemsPerPage > 0 ? (int) ceil(intval($totalItems) / $this->itemsPerPage) : 0;

yield from $this->yieldItemsUntilPage($totalPages);
yield from $this->yieldItemsUntilKey($this->config->totalItemsKey, function(int $totalItems) {
return $this->itemsPerPage > 0 ? (int) ceil($totalItems / $this->itemsPerPage) : 0;
});
}
}
5 changes: 4 additions & 1 deletion src/Paginations/TotalPagesAwarePagination.php
Original file line number Diff line number Diff line change
@@ -4,13 +4,16 @@

namespace Cerbero\LazyJsonPages\Paginations;

use Cerbero\LazyJsonPages\Concerns\YieldsItemsByLength;
use Traversable;

/**
* The pagination aware of the total number of pages.
*/
class TotalPagesAwarePagination extends LengthAwarePagination
class TotalPagesAwarePagination extends Pagination
{
use YieldsItemsByLength;

/**
* Determine whether the configuration matches this pagination.
*/

0 comments on commit 45a55b1

Please sign in to comment.