From 1ee9a4d7560e67735da73bf36243f74ca2473009 Mon Sep 17 00:00:00 2001 From: Erik Gaal Date: Wed, 14 Sep 2022 23:21:51 +0200 Subject: [PATCH 01/10] Add generic paginators --- stubs/EloquentBuilder.stub | 8 +-- stubs/Pagination.stub | 80 +++++++++++++++++++++---- tests/Features/Methods/Builder.php | 18 ++++++ tests/Features/Models/Relations.php | 5 +- tests/Type/data/paginator-extension.php | 13 +++- 5 files changed, 103 insertions(+), 21 deletions(-) diff --git a/stubs/EloquentBuilder.stub b/stubs/EloquentBuilder.stub index 9046d52fb..17939589e 100644 --- a/stubs/EloquentBuilder.stub +++ b/stubs/EloquentBuilder.stub @@ -440,7 +440,7 @@ class Builder * @param array $columns * @param string $pageName * @param int|null $page - * @return \Illuminate\Pagination\LengthAwarePaginator + * @return \Illuminate\Pagination\LengthAwarePaginator * * @throws \InvalidArgumentException */ @@ -453,7 +453,7 @@ class Builder * @param array $columns * @param string $pageName * @param int|null $page - * @return \Illuminate\Pagination\Paginator + * @return \Illuminate\Pagination\Paginator */ public function simplePaginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null); @@ -463,8 +463,8 @@ class Builder * @param int|null $perPage * @param array $columns * @param string $cursorName - * @param \Illuminate\Pagination\Cursor|string|null $cursor - * @return \Illuminate\Pagination\CursorPaginator + * @param \Illuminate\Pagination\Cursor|string|null $cursor + * @return \Illuminate\Pagination\CursorPaginator */ public function cursorPaginate($perPage = null, $columns = ['*'], $cursorName = 'cursor', $cursor = null); diff --git a/stubs/Pagination.stub b/stubs/Pagination.stub index 5a0cd1002..6e98cc15e 100644 --- a/stubs/Pagination.stub +++ b/stubs/Pagination.stub @@ -3,37 +3,91 @@ namespace Illuminate\Pagination; /** - * @mixin \Illuminate\Support\Collection + * @template TValue + * + * @mixin \Illuminate\Support\Collection */ abstract class AbstractPaginator implements \Illuminate\Contracts\Support\Htmlable -{} +{ + /** + * @return array + */ + public function items(): array; + + /** + * @return \Illuminate\Support\Collection + */ + public function getCollection(): \Illuminate\Support\Collection; + + /** + * @return \ArrayIterator + */ + public function getIterator(): \Traversable; +} /** - * @implements \ArrayAccess - * @implements \IteratorAggregate - * @implements \Illuminate\Contracts\Support\Arrayable + * @template TValue + * + * @implements \ArrayAccess + * @implements \IteratorAggregate + * @implements \Illuminate\Contracts\Support\Arrayable + * + * @extends AbstractPaginator */ class Paginator extends AbstractPaginator implements \Illuminate\Contracts\Support\Arrayable, \ArrayAccess, \Countable, \IteratorAggregate, \Illuminate\Contracts\Support\Jsonable, \JsonSerializable, \Illuminate\Contracts\Pagination\Paginator {} /** - * @implements \ArrayAccess - * @implements \IteratorAggregate - * @implements \Illuminate\Contracts\Support\Arrayable + * @template TValue + * + * @implements \ArrayAccess + * @implements \IteratorAggregate + * @implements \Illuminate\Contracts\Support\Arrayable + * + * @extends AbstractPaginator */ class LengthAwarePaginator extends AbstractPaginator implements \Illuminate\Contracts\Support\Arrayable, \ArrayAccess, \Countable, \IteratorAggregate, \Illuminate\Contracts\Support\Jsonable, \JsonSerializable, \Illuminate\Contracts\Pagination\LengthAwarePaginator {} /** - * @implements \ArrayAccess - * @implements \IteratorAggregate - * @implements \Illuminate\Contracts\Support\Arrayable + * @template TValue + * + * @mixin \Illuminate\Support\Collection + */ +abstract class AbstractCursorPaginator implements \Illuminate\Contracts\Support\Htmlable +{ + /** + * @return array + */ + public function items(): array; + + /** + * @return \Illuminate\Support\Collection + */ + public function getCollection(): \Illuminate\Support\Collection; + + /** + * @return \ArrayIterator + */ + public function getIterator(): \Traversable; +} + +/** + * @template TValue + * + * @implements \ArrayAccess + * @implements \IteratorAggregate + * @implements \Illuminate\Contracts\Support\Arrayable + * + * @extends AbstractCursorPaginator */ -class CursorPaginator extends AbstractPaginator implements \Illuminate\Contracts\Support\Arrayable, \ArrayAccess, \Countable, \IteratorAggregate, \Illuminate\Contracts\Support\Jsonable, \JsonSerializable, \Illuminate\Contracts\Pagination\CursorPaginator +class CursorPaginator extends AbstractCursorPaginator implements \Illuminate\Contracts\Support\Arrayable, \ArrayAccess, \Countable, \IteratorAggregate, \Illuminate\Contracts\Support\Jsonable, \JsonSerializable, \Illuminate\Contracts\Pagination\CursorPaginator {} /** - * @implements \Illuminate\Contracts\Support\Arrayable + * @template TValue + * + * @implements \Illuminate\Contracts\Support\Arrayable */ class Cursor implements \Illuminate\Contracts\Support\Arrayable {} diff --git a/tests/Features/Methods/Builder.php b/tests/Features/Methods/Builder.php index 004e69fd2..58bd11d8e 100644 --- a/tests/Features/Methods/Builder.php +++ b/tests/Features/Methods/Builder.php @@ -4,11 +4,13 @@ namespace Tests\Features\Methods; +use App\Account; use App\Post; use App\PostBuilder; use App\User; use Illuminate\Database\Eloquent\Builder as EloquentBuilder; use Illuminate\Database\Query\Builder as QueryBuilder; +use Illuminate\Pagination\LengthAwarePaginator; use Illuminate\Support\Collection; use function PHPStan\Testing\assertType; @@ -345,4 +347,20 @@ public function testQueryBuilderOnEloquentBuilderWithBaseModel(EloquentBuilder $ { assertType('Illuminate\Database\Eloquent\Builder', $query->select()); } + + /** + * @phpstan-return LengthAwarePaginator + */ + public function testPaginate() + { + return User::query()->paginate(); + } + + /** + * @phpstan-return array + */ + public function testPaginateItems() + { + return User::query()->paginate()->items(); + } } diff --git a/tests/Features/Models/Relations.php b/tests/Features/Models/Relations.php index ceea00d9b..b5c63cae6 100644 --- a/tests/Features/Models/Relations.php +++ b/tests/Features/Models/Relations.php @@ -9,7 +9,6 @@ use App\Post; use App\Role; use App\User; -use Illuminate\Contracts\Pagination\LengthAwarePaginator; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Model; @@ -19,6 +18,7 @@ use Illuminate\Database\Eloquent\Relations\MorphMany; use Illuminate\Database\Eloquent\Relations\MorphTo; use Illuminate\Database\Eloquent\Relations\MorphToMany; +use Illuminate\Pagination\LengthAwarePaginator; use function PHPStan\Testing\assertType; class Relations @@ -86,6 +86,9 @@ public function testDecrementWithAmountOnRelation(User $user): int return $user->accounts()->decrement('id', 5); } + /** + * @return LengthAwarePaginator + */ public function testPaginate(User $user): LengthAwarePaginator { return $user->accounts()->paginate(5); diff --git a/tests/Type/data/paginator-extension.php b/tests/Type/data/paginator-extension.php index 86e45a776..585cceed2 100644 --- a/tests/Type/data/paginator-extension.php +++ b/tests/Type/data/paginator-extension.php @@ -7,6 +7,13 @@ use App\User; use function PHPStan\Testing\assertType; -assertType('array', User::paginate()->all()); -assertType('array', User::simplePaginate()->all()); -assertType('array', User::cursorPaginate()->all()); +assertType('Illuminate\Pagination\LengthAwarePaginator', User::paginate()); +assertType('array', User::paginate()->items()); + +assertType('Illuminate\Pagination\Paginator', User::simplePaginate()); +assertType('array', User::simplePaginate()->items()); + +assertType('Illuminate\Pagination\CursorPaginator', User::cursorPaginate()); +assertType('array', User::cursorPaginate()->items()); + +assertType('ArrayIterator', User::query()->paginate()->getIterator()); From ba389a1d84859050407a41386447fe6ff4dac92e Mon Sep 17 00:00:00 2001 From: Erik Gaal Date: Wed, 14 Sep 2022 23:32:38 +0200 Subject: [PATCH 02/10] Upgrade CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 82b01a5f0..c31efa082 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - fix: Eloquent builder `whereRelation()` losing the TModelClass generic type by @mad-briller. - feat: updated return type of the Validator::safe and FormRequest::safe method by @jdjfisher - feat: Added stub for the DB::transaction method by @jdjfisher +- feat: add support for generic paginators by @erikgaal ## [2.2.0] - 2022-08-31 From da0d62c5ff9b63c08f9df96d4436c606c024b207 Mon Sep 17 00:00:00 2001 From: Erik Gaal Date: Wed, 14 Sep 2022 23:36:34 +0200 Subject: [PATCH 03/10] Apply fixes from StyleCI --- tests/Features/Methods/Builder.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Features/Methods/Builder.php b/tests/Features/Methods/Builder.php index 58bd11d8e..5eece37f4 100644 --- a/tests/Features/Methods/Builder.php +++ b/tests/Features/Methods/Builder.php @@ -4,7 +4,6 @@ namespace Tests\Features\Methods; -use App\Account; use App\Post; use App\PostBuilder; use App\User; From a322e4e4745db66cf95aef01c181ff470e93e8f5 Mon Sep 17 00:00:00 2001 From: Erik Gaal Date: Wed, 14 Sep 2022 23:56:25 +0200 Subject: [PATCH 04/10] Revert Cursor generic --- stubs/EloquentBuilder.stub | 2 +- stubs/Pagination.stub | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/stubs/EloquentBuilder.stub b/stubs/EloquentBuilder.stub index 17939589e..e3890e58c 100644 --- a/stubs/EloquentBuilder.stub +++ b/stubs/EloquentBuilder.stub @@ -463,7 +463,7 @@ class Builder * @param int|null $perPage * @param array $columns * @param string $cursorName - * @param \Illuminate\Pagination\Cursor|string|null $cursor + * @param \Illuminate\Pagination\Cursor|string|null $cursor * @return \Illuminate\Pagination\CursorPaginator */ public function cursorPaginate($perPage = null, $columns = ['*'], $cursorName = 'cursor', $cursor = null); diff --git a/stubs/Pagination.stub b/stubs/Pagination.stub index 6e98cc15e..d15cb645e 100644 --- a/stubs/Pagination.stub +++ b/stubs/Pagination.stub @@ -85,9 +85,7 @@ class CursorPaginator extends AbstractCursorPaginator implements \Illuminate\Con {} /** - * @template TValue - * - * @implements \Illuminate\Contracts\Support\Arrayable + * @implements \Illuminate\Contracts\Support\Arrayable */ class Cursor implements \Illuminate\Contracts\Support\Arrayable {} From 1377cce6feb657943bd69fd9201dcddfb8d39083 Mon Sep 17 00:00:00 2001 From: Erik Gaal Date: Wed, 14 Sep 2022 23:59:49 +0200 Subject: [PATCH 05/10] Fix ArrayIterator key type --- stubs/Pagination.stub | 12 ++++++------ tests/Type/data/paginator-extension.php | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/stubs/Pagination.stub b/stubs/Pagination.stub index d15cb645e..f7f83b504 100644 --- a/stubs/Pagination.stub +++ b/stubs/Pagination.stub @@ -28,8 +28,8 @@ abstract class AbstractPaginator implements \Illuminate\Contracts\Support\Htmlab /** * @template TValue * - * @implements \ArrayAccess - * @implements \IteratorAggregate + * @implements \ArrayAccess + * @implements \IteratorAggregate * @implements \Illuminate\Contracts\Support\Arrayable * * @extends AbstractPaginator @@ -40,8 +40,8 @@ class Paginator extends AbstractPaginator implements \Illuminate\Contracts\Suppo /** * @template TValue * - * @implements \ArrayAccess - * @implements \IteratorAggregate + * @implements \ArrayAccess + * @implements \IteratorAggregate * @implements \Illuminate\Contracts\Support\Arrayable * * @extends AbstractPaginator @@ -75,8 +75,8 @@ abstract class AbstractCursorPaginator implements \Illuminate\Contracts\Support\ /** * @template TValue * - * @implements \ArrayAccess - * @implements \IteratorAggregate + * @implements \ArrayAccess + * @implements \IteratorAggregate * @implements \Illuminate\Contracts\Support\Arrayable * * @extends AbstractCursorPaginator diff --git a/tests/Type/data/paginator-extension.php b/tests/Type/data/paginator-extension.php index 585cceed2..b256d771c 100644 --- a/tests/Type/data/paginator-extension.php +++ b/tests/Type/data/paginator-extension.php @@ -16,4 +16,4 @@ assertType('Illuminate\Pagination\CursorPaginator', User::cursorPaginate()); assertType('array', User::cursorPaginate()->items()); -assertType('ArrayIterator', User::query()->paginate()->getIterator()); +assertType('ArrayIterator<(int|string), App\User>', User::query()->paginate()->getIterator()); From db02ba91c5fe30f00cb29c53cb219c777a1c1332 Mon Sep 17 00:00:00 2001 From: Erik Gaal Date: Fri, 16 Sep 2022 15:03:40 +0200 Subject: [PATCH 06/10] Test and fix pagination types on relations --- stubs/BelongsToMany.stub | 33 +++++++++++++++++++++++ stubs/Contracts/Pagination.stub | 35 ++++++++++++++++++------- stubs/HasManyThrough.stub | 33 +++++++++++++++++++++++ stubs/Pagination.stub | 3 +++ tests/Type/data/paginator-extension.php | 6 +++++ 5 files changed, 101 insertions(+), 9 deletions(-) diff --git a/stubs/BelongsToMany.stub b/stubs/BelongsToMany.stub index c79d7831f..105dd8c0e 100644 --- a/stubs/BelongsToMany.stub +++ b/stubs/BelongsToMany.stub @@ -109,4 +109,37 @@ class BelongsToMany extends Relation * @phpstan-return \Traversable */ public function getResults(); + + /** + * Get a paginator for the "select" statement. + * + * @param int|null $perPage + * @param array $columns + * @param string $pageName + * @param int|null $page + * @return \Illuminate\Pagination\LengthAwarePaginator + */ + public function paginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null); + + /** + * Paginate the given query into a simple paginator. + * + * @param int|null $perPage + * @param array $columns + * @param string $pageName + * @param int|null $page + * @return \Illuminate\Pagination\Paginator + */ + public function simplePaginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null); + + /** + * Paginate the given query into a cursor paginator. + * + * @param int|null $perPage + * @param array $columns + * @param string $cursorName + * @param string|null $cursor + * @return \Illuminate\Pagination\CursorPaginator + */ + public function cursorPaginate($perPage = null, $columns = ['*'], $cursorName = 'cursor', $cursor = null); } diff --git a/stubs/Contracts/Pagination.stub b/stubs/Contracts/Pagination.stub index 674838285..c22073d83 100644 --- a/stubs/Contracts/Pagination.stub +++ b/stubs/Contracts/Pagination.stub @@ -3,22 +3,39 @@ namespace Illuminate\Contracts\Pagination; /** - * @mixin \Illuminate\Support\Collection - * @mixin \Illuminate\Pagination\Paginator + * @template TItem + * + * @mixin \Illuminate\Support\Collection + * @mixin \Illuminate\Pagination\Paginator */ interface Paginator -{} +{ + /** + * @return array + */ + public function items(): array; +} /** - * @mixin \Illuminate\Support\Collection - * @mixin \Illuminate\Pagination\LengthAwarePaginator + * @template TItem + * + * @mixin \Illuminate\Support\Collection + * @mixin \Illuminate\Pagination\LengthAwarePaginator + * @extends Paginator */ interface LengthAwarePaginator extends Paginator {} /** - * @mixin \Illuminate\Support\Collection - * @mixin \Illuminate\Pagination\CursorPaginator + * @template TItem + * + * @mixin \Illuminate\Support\Collection + * @mixin \Illuminate\Pagination\CursorPaginator */ -interface CursorPaginator extends Paginator -{} +interface CursorPaginator +{ + /** + * @return array + */ + public function items(): array; +} diff --git a/stubs/HasManyThrough.stub b/stubs/HasManyThrough.stub index db0323e8a..c37805d44 100644 --- a/stubs/HasManyThrough.stub +++ b/stubs/HasManyThrough.stub @@ -14,4 +14,37 @@ class HasManyThrough extends Relation * @phpstan-return \Traversable */ public function getResults(); + + /** + * Get a paginator for the "select" statement. + * + * @param int|null $perPage + * @param array $columns + * @param string $pageName + * @param int|null $page + * @return \Illuminate\Pagination\LengthAwarePaginator + */ + public function paginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null); + + /** + * Paginate the given query into a simple paginator. + * + * @param int|null $perPage + * @param array $columns + * @param string $pageName + * @param int|null $page + * @return \Illuminate\Pagination\Paginator + */ + public function simplePaginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null); + + /** + * Paginate the given query into a cursor paginator. + * + * @param int|null $perPage + * @param array $columns + * @param string $cursorName + * @param string|null $cursor + * @return \Illuminate\Pagination\CursorPaginator + */ + public function cursorPaginate($perPage = null, $columns = ['*'], $cursorName = 'cursor', $cursor = null); } diff --git a/stubs/Pagination.stub b/stubs/Pagination.stub index f7f83b504..efe0741a4 100644 --- a/stubs/Pagination.stub +++ b/stubs/Pagination.stub @@ -31,6 +31,7 @@ abstract class AbstractPaginator implements \Illuminate\Contracts\Support\Htmlab * @implements \ArrayAccess * @implements \IteratorAggregate * @implements \Illuminate\Contracts\Support\Arrayable + * @implements \Illuminate\Contracts\Pagination\Paginator * * @extends AbstractPaginator */ @@ -43,6 +44,7 @@ class Paginator extends AbstractPaginator implements \Illuminate\Contracts\Suppo * @implements \ArrayAccess * @implements \IteratorAggregate * @implements \Illuminate\Contracts\Support\Arrayable + * @implements \Illuminate\Contracts\Pagination\LengthAwarePaginator * * @extends AbstractPaginator */ @@ -78,6 +80,7 @@ abstract class AbstractCursorPaginator implements \Illuminate\Contracts\Support\ * @implements \ArrayAccess * @implements \IteratorAggregate * @implements \Illuminate\Contracts\Support\Arrayable + * @implements \Illuminate\Contracts\Pagination\CursorPaginator * * @extends AbstractCursorPaginator */ diff --git a/tests/Type/data/paginator-extension.php b/tests/Type/data/paginator-extension.php index b256d771c..79abaefb1 100644 --- a/tests/Type/data/paginator-extension.php +++ b/tests/Type/data/paginator-extension.php @@ -17,3 +17,9 @@ assertType('array', User::cursorPaginate()->items()); assertType('ArrayIterator<(int|string), App\User>', User::query()->paginate()->getIterator()); + +// HasMany +assertType('Illuminate\Pagination\LengthAwarePaginator', (new User())->accounts()->paginate()); + +// BelongsToMany +assertType('Illuminate\Pagination\LengthAwarePaginator', (new User())->posts()->paginate()); From 638c840e2235a29a34bb5646088dda2664f13d67 Mon Sep 17 00:00:00 2001 From: Erik Gaal Date: Tue, 18 Oct 2022 16:21:14 +0200 Subject: [PATCH 07/10] Support $paginator->all() and other Collection methods Thanks to fix in https://github.com/phpstan/phpstan/releases/tag/1.8.7 --- tests/Type/data/paginator-extension.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/Type/data/paginator-extension.php b/tests/Type/data/paginator-extension.php index 79abaefb1..7b97ed831 100644 --- a/tests/Type/data/paginator-extension.php +++ b/tests/Type/data/paginator-extension.php @@ -8,12 +8,15 @@ use function PHPStan\Testing\assertType; assertType('Illuminate\Pagination\LengthAwarePaginator', User::paginate()); +assertType('array', User::paginate()->all()); assertType('array', User::paginate()->items()); assertType('Illuminate\Pagination\Paginator', User::simplePaginate()); +assertType('array', User::simplePaginate()->all()); assertType('array', User::simplePaginate()->items()); assertType('Illuminate\Pagination\CursorPaginator', User::cursorPaginate()); +assertType('array', User::cursorPaginate()->all()); assertType('array', User::cursorPaginate()->items()); assertType('ArrayIterator<(int|string), App\User>', User::query()->paginate()->getIterator()); From 13172d7f43822a6f6218c6951c98748e8d05a5a1 Mon Sep 17 00:00:00 2001 From: Erik Gaal Date: Tue, 18 Oct 2022 17:05:20 +0200 Subject: [PATCH 08/10] Remove @mixin from interfaces --- stubs/Contracts/Pagination.stub | 8 -------- 1 file changed, 8 deletions(-) diff --git a/stubs/Contracts/Pagination.stub b/stubs/Contracts/Pagination.stub index c22073d83..b37af9925 100644 --- a/stubs/Contracts/Pagination.stub +++ b/stubs/Contracts/Pagination.stub @@ -4,9 +4,6 @@ namespace Illuminate\Contracts\Pagination; /** * @template TItem - * - * @mixin \Illuminate\Support\Collection - * @mixin \Illuminate\Pagination\Paginator */ interface Paginator { @@ -19,8 +16,6 @@ interface Paginator /** * @template TItem * - * @mixin \Illuminate\Support\Collection - * @mixin \Illuminate\Pagination\LengthAwarePaginator * @extends Paginator */ interface LengthAwarePaginator extends Paginator @@ -28,9 +23,6 @@ interface LengthAwarePaginator extends Paginator /** * @template TItem - * - * @mixin \Illuminate\Support\Collection - * @mixin \Illuminate\Pagination\CursorPaginator */ interface CursorPaginator { From 65f0dea3599d0623bac3617d8fc4e5c1a0ace681 Mon Sep 17 00:00:00 2001 From: Erik Gaal Date: Fri, 28 Oct 2022 12:27:54 +0100 Subject: [PATCH 09/10] Add test for ArrayAccess types --- tests/Type/data/paginator-extension.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/Type/data/paginator-extension.php b/tests/Type/data/paginator-extension.php index 7b97ed831..d396972e7 100644 --- a/tests/Type/data/paginator-extension.php +++ b/tests/Type/data/paginator-extension.php @@ -10,14 +10,17 @@ assertType('Illuminate\Pagination\LengthAwarePaginator', User::paginate()); assertType('array', User::paginate()->all()); assertType('array', User::paginate()->items()); +assertType('App\User', User::paginate()[0]); assertType('Illuminate\Pagination\Paginator', User::simplePaginate()); assertType('array', User::simplePaginate()->all()); assertType('array', User::simplePaginate()->items()); +assertType('App\User', User::simplePaginate()[0]); assertType('Illuminate\Pagination\CursorPaginator', User::cursorPaginate()); assertType('array', User::cursorPaginate()->all()); assertType('array', User::cursorPaginate()->items()); +assertType('App\User', User::cursorPaginate()[0]); assertType('ArrayIterator<(int|string), App\User>', User::query()->paginate()->getIterator()); From c1dc9d4fd7170179330d20b59bc35793c56b25da Mon Sep 17 00:00:00 2001 From: Erik Gaal Date: Fri, 28 Oct 2022 14:05:26 +0100 Subject: [PATCH 10/10] Implement offset* method types --- stubs/Pagination.stub | 28 +++++++++++++++++++++++++ tests/Type/data/paginator-extension.php | 6 +++--- 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/stubs/Pagination.stub b/stubs/Pagination.stub index efe0741a4..4b92dcfe7 100644 --- a/stubs/Pagination.stub +++ b/stubs/Pagination.stub @@ -23,6 +23,20 @@ abstract class AbstractPaginator implements \Illuminate\Contracts\Support\Htmlab * @return \ArrayIterator */ public function getIterator(): \Traversable; + + public function offsetExists(mixed $offset): bool; + + /** + * @return TValue|null + */ + public function offsetGet(mixed $offset): mixed; + + /** + * @param TValue $value + */ + public function offsetSet(mixed $offset, $value): void; + + public function offsetUnset(mixed $offset): void; } /** @@ -72,6 +86,20 @@ abstract class AbstractCursorPaginator implements \Illuminate\Contracts\Support\ * @return \ArrayIterator */ public function getIterator(): \Traversable; + + public function offsetExists(mixed $offset): bool; + + /** + * @return TValue|null + */ + public function offsetGet(mixed $offset): mixed; + + /** + * @param TValue $value + */ + public function offsetSet(mixed $offset, $value): void; + + public function offsetUnset(mixed $offset): void; } /** diff --git a/tests/Type/data/paginator-extension.php b/tests/Type/data/paginator-extension.php index d396972e7..56f6f31af 100644 --- a/tests/Type/data/paginator-extension.php +++ b/tests/Type/data/paginator-extension.php @@ -10,17 +10,17 @@ assertType('Illuminate\Pagination\LengthAwarePaginator', User::paginate()); assertType('array', User::paginate()->all()); assertType('array', User::paginate()->items()); -assertType('App\User', User::paginate()[0]); +assertType('App\User|null', User::paginate()[0]); assertType('Illuminate\Pagination\Paginator', User::simplePaginate()); assertType('array', User::simplePaginate()->all()); assertType('array', User::simplePaginate()->items()); -assertType('App\User', User::simplePaginate()[0]); +assertType('App\User|null', User::simplePaginate()[0]); assertType('Illuminate\Pagination\CursorPaginator', User::cursorPaginate()); assertType('array', User::cursorPaginate()->all()); assertType('array', User::cursorPaginate()->items()); -assertType('App\User', User::cursorPaginate()[0]); +assertType('App\User|null', User::cursorPaginate()[0]); assertType('ArrayIterator<(int|string), App\User>', User::query()->paginate()->getIterator());