Add Paginator

This commit is contained in:
philipp lang 2022-10-18 17:55:10 +02:00
parent 5ce86d632d
commit ba7786f111
2 changed files with 59 additions and 11 deletions

View File

@ -13,6 +13,7 @@ use Zoomyboy\LaravelNami\Data\Course;
use Zoomyboy\LaravelNami\Data\Membership;
use Zoomyboy\LaravelNami\Data\MembershipEntry;
use Zoomyboy\LaravelNami\Exceptions\NotAuthenticatedException;
use Zoomyboy\LaravelNami\Support\Paginator;
class Api
{
@ -55,24 +56,20 @@ class Api
{
$this->assertLoggedIn();
return LazyCollection::make(function () use ($payload) {
$page = 1;
while (!isset($totalEntries) || ($page - 1) * 100 + 1 <= $totalEntries) {
$start = ($page - 1) * 100;
$url = $this->url.'/ica/rest/nami/search-multi/result-list?searchedValues='.rawurlencode(json_encode((object) $payload) ?: '{}').'&page='.$page.'&start='.$start.'&limit=100';
$response = $this->http()->get($url);
return app(Paginator::class)->startResult(100,
fn ($page, $start) => $this->http()->get($this->url.'/ica/rest/nami/search-multi/result-list?searchedValues='.rawurlencode(json_encode((object) $payload) ?: '{}').'&page='.$page.'&start='.$start.'&limit=100'),
function ($response) {
if (true !== $response->json()['success']) {
$this->exception('Search failed', $url, $response->json(), ['page' => $page, 'start' => $start]);
$this->exception('Search failed', '', $response->json(), []);
}
$totalEntries = $response->json()['totalEntries'];
foreach ($response->json()['data'] as $member) {
yield Member::fromNami(collect($member)->mapWithKeys(function ($value, $key) {
return [str_replace('entries_', '', (string) $key) => $value];
}));
}
++$page;
}
});
},
fn ($response) => $response->json()['totalEntries'],
);
}
public function deleteMember(int $id): void

51
src/Support/Paginator.php Normal file
View File

@ -0,0 +1,51 @@
<?php
namespace Zoomyboy\LaravelNami\Support;
use Generator;
use Illuminate\Http\Client\Response;
use Illuminate\Support\LazyCollection;
class Paginator
{
/**
* @param callable(int): Response $responseFactory
* @param callable(Response): Generator $generator
* @param callable(Response): int $totalFetcher
*/
public function result(callable $responseFactory, callable $generator, callable $totalFetcher): LazyCollection
{
return $this->startResult(
0,
fn ($page, $start) => $responseFactory($page),
$generator,
$totalFetcher
);
}
/**
* @param callable(int, int): Response $responseFactory
* @param callable(Response): Generator $generator
* @param callable(Response): int $totalFetcher
*/
public function startResult(int $perPage, callable $responseFactory, callable $generator, callable $totalFetcher): LazyCollection
{
return LazyCollection::make(function () use ($perPage, $responseFactory, $generator, $totalFetcher) {
$page = 1;
$start = 0;
$fetchedEntries = 0;
while (!isset($totalEntries) || $fetchedEntries < $totalEntries) {
$response = $responseFactory($page, $start);
foreach ($generator($response) as $entry) {
++$fetchedEntries;
yield $entry;
}
$totalEntries = $totalFetcher($response);
++$page;
$start += $perPage;
}
});
}
}