diff options
Diffstat (limited to 'Digitigrade/Pagination.php')
| -rw-r--r-- | Digitigrade/Pagination.php | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/Digitigrade/Pagination.php b/Digitigrade/Pagination.php new file mode 100644 index 0000000..75a876f --- /dev/null +++ b/Digitigrade/Pagination.php @@ -0,0 +1,60 @@ +<?php +namespace Digitigrade; + +use JsonMapper; + +class Pagination { + public int $page; + public int $totalPages; + public int $totalItems; + public ?string $nextPage = null; + public ?string $previousPage = null; + public array $items; + + /** + * Fetches a pagination page. + * @param string $uri + * @param class-string $innerType Type of the contained items. + * @return self + */ + public static function fromUri(string $uri): self { + $response = send_request_authenticated($uri); + $data = json_decode($response->body); + if (!isset($data->page)) { + throw new \RuntimeException("doesn't look like a pagination: $uri"); + } + $p = (new JsonMapper())->map($data, self::class); + return $p; + } + + private function become(self $other) { + $this->page = $other->page; + $this->totalPages = $other->totalPages; + $this->totalItems = $other->totalItems; + $this->nextPage = $other->nextPage; + $this->previousPage = $other->previousPage; + $this->items = &$other->items; + } + + /** + * Gets the next item from the pagination, going to the next page if needed. + * + * Careful! This behaves differently from PHP's built in `next`: it returns + * the first item, the first time it's called, rather than the second. + * @return mixed The next item, or `false` if at the end. + */ + public function next(): mixed { + if (current($this->items) === false) { + if (isset($this->nextPage)) { + $this->become(self::fromUri($this->nextPage)); + return $this->next(); + } else { + return false; + } + } else { + $item = current($this->items); + next($this->items); + return $item; + } + } +}
\ No newline at end of file |
