aboutsummaryrefslogtreecommitdiffhomepage
path: root/Digitigrade/Pagination.php
diff options
context:
space:
mode:
authorwinter2025-03-31 21:29:22 +0100
committerwinter2025-03-31 21:29:22 +0100
commita9f0003e809d46093e783d2079be7a952b5f5e0d (patch)
tree154cb0ad413756a265baebeee45a868d3ed79879 /Digitigrade/Pagination.php
parent8c3f045ed44bcb27189a605a4b86e5db22fee4d6 (diff)
implement backfilling for newly discovered actors
Diffstat (limited to 'Digitigrade/Pagination.php')
-rw-r--r--Digitigrade/Pagination.php60
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