wishthis/vendor/knplabs/github-api/lib/Github/ResultPager.php
2022-01-24 09:08:35 +01:00

212 lines
4.7 KiB
PHP

<?php
namespace Github;
use Closure;
use Generator;
use Github\Api\AbstractApi;
use Github\HttpClient\Message\ResponseMediator;
use ValueError;
/**
* Pager class for supporting pagination in github classes.
*
* @author Ramon de la Fuente <ramon@future500.nl>
* @author Mitchel Verschoof <mitchel@future500.nl>
* @author Graham Campbell <graham@alt-three.com>
*/
class ResultPager implements ResultPagerInterface
{
/**
* The default number of entries to request per page.
*
* @var int
*/
private const PER_PAGE = 100;
/**
* The client to use for pagination.
*
* @var Client
*/
private $client;
/**
* The number of entries to request per page.
*
* @var int
*/
private $perPage;
/**
* The pagination result from the API.
*
* @var array<string,string>
*/
private $pagination;
/**
* Create a new result pager instance.
*
* Example code:
*
* $client = new \Github\Client();
* $api = $client->api('someApi');
* $pager = new \Github\ResultPager($client);
*
* @param Client $client
* @param int|null $perPage
*
* @return void
*/
public function __construct(Client $client, int $perPage = null)
{
if (null !== $perPage && ($perPage < 1 || $perPage > 100)) {
throw new ValueError(sprintf('%s::__construct(): Argument #2 ($perPage) must be between 1 and 100, or null', self::class));
}
$this->client = $client;
$this->perPage = $perPage ?? self::PER_PAGE;
$this->pagination = [];
}
/**
* {@inheritdoc}
*/
public function fetch(AbstractApi $api, string $method, array $parameters = []): array
{
$paginatorPerPage = $this->perPage;
$closure = Closure::bind(function (AbstractApi $api) use ($paginatorPerPage) {
$clone = clone $api;
$clone->perPage = $paginatorPerPage;
return $clone;
}, null, AbstractApi::class);
$api = $closure($api);
$result = $api->$method(...$parameters);
$this->postFetch(true);
return $result;
}
/**
* {@inheritdoc}
*/
public function fetchAll(AbstractApi $api, string $method, array $parameters = []): array
{
return iterator_to_array($this->fetchAllLazy($api, $method, $parameters));
}
/**
* {@inheritdoc}
*/
public function fetchAllLazy(AbstractApi $api, string $method, array $parameters = []): Generator
{
$result = $this->fetch($api, $method, $parameters);
foreach ($result['items'] ?? $result as $key => $item) {
if (is_string($key)) {
yield $key => $item;
} else {
yield $item;
}
}
while ($this->hasNext()) {
$result = $this->fetchNext();
foreach ($result['items'] ?? $result as $key => $item) {
if (is_string($key)) {
yield $key => $item;
} else {
yield $item;
}
}
}
}
/**
* {@inheritdoc}
*/
public function postFetch(/* $skipDeprecation = false */): void
{
if (func_num_args() === 0 || (func_num_args() > 0 && false === func_get_arg(0))) {
trigger_deprecation('KnpLabs/php-github-api', '3.2', 'The "%s" method is deprecated and will be removed.', __METHOD__);
}
$this->setPagination();
}
/**
* {@inheritdoc}
*/
public function hasNext(): bool
{
return isset($this->pagination['next']);
}
/**
* {@inheritdoc}
*/
public function fetchNext(): array
{
return $this->get('next');
}
/**
* {@inheritdoc}
*/
public function hasPrevious(): bool
{
return isset($this->pagination['prev']);
}
/**
* {@inheritdoc}
*/
public function fetchPrevious(): array
{
return $this->get('prev');
}
/**
* {@inheritdoc}
*/
public function fetchFirst(): array
{
return $this->get('first');
}
/**
* {@inheritdoc}
*/
public function fetchLast(): array
{
return $this->get('last');
}
/**
* @param string $key
*
* @return array
*/
protected function get(string $key): array
{
if (!isset($this->pagination[$key])) {
return [];
}
$result = $this->client->getHttpClient()->get($this->pagination[$key]);
$this->postFetch(true);
return ResponseMediator::getContent($result);
}
private function setPagination(): void
{
$this->pagination = ResponseMediator::getPagination($this->client->getLastResponse());
}
}