Skip to content

Commit eb253e2

Browse files
committed
Check hard limit in paginated responses
1 parent 3e8ccaf commit eb253e2

File tree

5 files changed

+66
-17
lines changed

5 files changed

+66
-17
lines changed

lib/Client/List/PaginatedFilesList.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,11 @@ public function __construct(
2828
}, $filesResponse->getData()));
2929
}
3030

31-
public function getOffset(int $offset): static
31+
public function getOffset(int $offset, int $pageSize): static
3232
{
3333
$options = clone $this->options;
3434
$options->setOffset($offset);
35+
$options->setPageSize($pageSize);
3536
return $this->client->getModFiles($options);
3637
}
3738
}

lib/Client/List/PaginatedGameList.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ public function __construct(
2626
}, $gamesResponse->getData()));
2727
}
2828

29-
public function getOffset(int $offset): static
29+
public function getOffset(int $offset, int $pageSize): static
3030
{
31-
return $this->client->getGames($offset, $this->pagination->getPageSize());
31+
return $this->client->getGames($offset, $pageSize);
3232
}
3333
}

lib/Client/List/PaginatedList.php

+39-13
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@
1818
*/
1919
abstract class PaginatedList implements Iterator, ArrayAccess, Countable
2020
{
21+
/**
22+
* The limit for how many results are allowed to be requested.
23+
* @type int
24+
*/
25+
public const LIMIT = 10_000;
26+
2127
protected int $iterator = 0;
2228

2329
protected function __construct(
@@ -30,6 +36,15 @@ protected function __construct(
3036
{
3137
}
3238

39+
/**
40+
* Get the pagination part of the response
41+
* @return Pagination
42+
*/
43+
public function getPagination(): Pagination
44+
{
45+
return $this->pagination;
46+
}
47+
3348
/**
3449
* @return T[]
3550
*/
@@ -41,18 +56,19 @@ public function getResults(): array
4156
/**
4257
* Get a new page of results starting at the given offset
4358
* @param int $offset
59+
* @param int $pageSize
4460
* @return $this
4561
* @throws ApiException
4662
*/
47-
public abstract function getOffset(int $offset): static;
63+
public abstract function getOffset(int $offset, int $pageSize): static;
4864

4965
/**
5066
* returns true if there is a next page with results on it
5167
* @return bool
5268
*/
5369
public function hasNextPage(): bool
5470
{
55-
return $this->pagination->getTotalCount() > $this->getNextOffset();
71+
return min($this->pagination->getTotalCount(), static::LIMIT) > $this->getNextOffset();
5672
}
5773

5874
/**
@@ -67,16 +83,8 @@ public function getNextPage(): ?static
6783
return null;
6884
}
6985

70-
return $this->getOffset($this->getNextOffset());
71-
}
72-
73-
/**
74-
* get the offset of the next page
75-
* @return int
76-
*/
77-
protected function getNextOffset(): int
78-
{
79-
return $this->pagination->getIndex() + $this->pagination->getPageSize();
86+
$offset = $this->getNextOffset();
87+
return $this->getOffset($offset, $this->getNextPageSize($offset));
8088
}
8189

8290
/**
@@ -110,7 +118,7 @@ public function getPreviousPage(): ?static
110118
return null;
111119
}
112120

113-
return $this->getOffset($this->getPreviousOffset());
121+
return $this->getOffset($this->getPreviousOffset(), $this->pagination->getPageSize());
114122
}
115123

116124
/**
@@ -220,4 +228,22 @@ public function count(): int
220228
{
221229
return count($this->results);
222230
}
231+
232+
/**
233+
* @param int $offset
234+
* @return int
235+
*/
236+
protected function getNextPageSize(int $offset): int
237+
{
238+
return min($this->pagination->getPageSize(), static::LIMIT - $offset);
239+
}
240+
241+
/**
242+
* get the offset of the next page
243+
* @return int
244+
*/
245+
protected function getNextOffset(): int
246+
{
247+
return $this->pagination->getIndex() + $this->pagination->getPageSize();
248+
}
223249
}

lib/Client/List/PaginatedModList.php

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,11 @@ public function __construct(
2828
}, $this->response->getData()));
2929
}
3030

31-
public function getOffset(int $offset): static
31+
public function getOffset(int $offset, int $pageSize): static
3232
{
3333
$options = clone $this->options;
3434
$options->setOffset($offset);
35+
$options->setPageSize($pageSize);
3536
return $this->client->searchMods($options);
3637
}
3738
}

tests/Integration/Client/ClientTest.php

+21
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,27 @@ public function testSearchMods()
210210
}
211211
}
212212

213+
public function testSearchModsLastPage()
214+
{
215+
$options = new ModSearchOptions(static::MINECRAFT_GAME_ID);
216+
$options->setPageSize(50);
217+
$options->setOffset(9_910);
218+
219+
$mods = $this->apiClient->searchMods($options);
220+
$this->assertNotEmpty($mods);
221+
foreach ($mods as $mod) {
222+
$this->assertEquals(static::MINECRAFT_GAME_ID, $mod->getData()->getGameId());
223+
}
224+
225+
$this->assertTrue($mods->hasNextPage());
226+
$mods = $mods->getNextPage();
227+
228+
$this->assertNotEmpty($mods);
229+
$this->assertFalse($mods->hasNextPage());
230+
$this->assertEquals($mods::LIMIT, $mods->getPagination()->getIndex() + $mods->getPagination()->getPageSize());
231+
}
232+
233+
213234
/**
214235
* Test searching mods in a category class
215236
* @return void

0 commit comments

Comments
 (0)