From 4e539a165bcb170f167edb7c4878f95d9a0b7e83 Mon Sep 17 00:00:00 2001 From: Deleu Date: Tue, 3 Dec 2019 10:57:45 -0500 Subject: [PATCH 1/6] Allow developer to preserve query parameters on paginated Api resources --- .../Resources/Json/ResourceCollection.php | 42 ++++++++++++++++-- tests/Integration/Http/ResourceTest.php | 43 +++++++++++++++++++ 2 files changed, 82 insertions(+), 3 deletions(-) diff --git a/src/Illuminate/Http/Resources/Json/ResourceCollection.php b/src/Illuminate/Http/Resources/Json/ResourceCollection.php index 40f685497950..8245184d386a 100644 --- a/src/Illuminate/Http/Resources/Json/ResourceCollection.php +++ b/src/Illuminate/Http/Resources/Json/ResourceCollection.php @@ -25,6 +25,13 @@ class ResourceCollection extends JsonResource implements Countable, IteratorAggr */ public $collection; + /** + * Determines whether to preserve all query parameters when generating the navigation links. + * + * @var bool + */ + private $queryParameters; + /** * Create a new resource instance. * @@ -38,6 +45,18 @@ public function __construct($resource) $this->resource = $this->collectResource($resource); } + /** + * Preserve all query parameters when generating the navigation links. + * + * @return $this + */ + public function preserveQueryParameters() + { + $this->queryParameters = true; + + return $this; + } + /** * Return the count of items in the resource collection. * @@ -67,8 +86,25 @@ public function toArray($request) */ public function toResponse($request) { - return $this->resource instanceof AbstractPaginator - ? (new PaginatedResourceResponse($this))->toResponse($request) - : parent::toResponse($request); + if ($this->resource instanceof AbstractPaginator) { + return $this->preparePaginatedResponse($request); + } + + return parent::toResponse($request); + } + + /** + * Create an paginate-aware HTTP response. + * + * @param \Illuminate\Http\Request $request + * @return \Illuminate\Http\JsonResponse + */ + private function preparePaginatedResponse($request) + { + if ($this->queryParameters) { + $this->resource->appends($request->query()); + } + + return (new PaginatedResourceResponse($this))->toResponse($request); } } diff --git a/tests/Integration/Http/ResourceTest.php b/tests/Integration/Http/ResourceTest.php index 6b01b62729d4..96d4e5839ffa 100644 --- a/tests/Integration/Http/ResourceTest.php +++ b/tests/Integration/Http/ResourceTest.php @@ -486,6 +486,49 @@ public function testPaginatorsReceiveLinks() ]); } + public function testPaginatorResourceCanPreserveQueryParameters() + { + Route::get('/', function () { + $collection = collect([new Post(['id' => 2, 'title' => 'Laravel Nova'])]); + $paginator = new LengthAwarePaginator( + $collection, 3, 1, 2 + ); + + return PostCollectionResource::make($paginator)->preserveQueryParameters(); + }); + + $response = $this->withoutExceptionHandling()->get( + '/?framework=laravel&author=Otwell&page=2', ['Accept' => 'application/json'] + ); + + $response->assertStatus(200); + + $response->assertJson([ + 'data' => [ + [ + 'id' => 2, + 'title' => 'Laravel Nova', + ], + ], + 'links' => [ + 'first' => '/?framework=laravel&author=Otwell&page=1', + 'last' => '/?framework=laravel&author=Otwell&page=3', + 'prev' => '/?framework=laravel&author=Otwell&page=1', + 'next' => '/?framework=laravel&author=Otwell&page=3', + ], + 'meta' => [ + 'current_page' => 2, + 'from' => 2, + 'last_page' => 3, + 'path' => '/', + 'per_page' => 1, + 'to' => 2, + 'total' => 3, + ], + ]); + } + + public function testToJsonMayBeLeftOffOfCollection() { Route::get('/', function () { From 01f0486e5e8cf9d518c76b070a0517a98e079b62 Mon Sep 17 00:00:00 2001 From: Deleu Date: Tue, 3 Dec 2019 11:04:10 -0500 Subject: [PATCH 2/6] StyleCI --- tests/Integration/Http/ResourceTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Integration/Http/ResourceTest.php b/tests/Integration/Http/ResourceTest.php index 96d4e5839ffa..aaf08c4e65d8 100644 --- a/tests/Integration/Http/ResourceTest.php +++ b/tests/Integration/Http/ResourceTest.php @@ -528,7 +528,6 @@ public function testPaginatorResourceCanPreserveQueryParameters() ]); } - public function testToJsonMayBeLeftOffOfCollection() { Route::get('/', function () { From 3673354d70b860078d0c88e1d89439e65db9af70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Aur=C3=A9lio=20Deleu?= Date: Tue, 3 Dec 2019 20:30:15 +0100 Subject: [PATCH 3/6] Change method visibility --- src/Illuminate/Http/Resources/Json/ResourceCollection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/Http/Resources/Json/ResourceCollection.php b/src/Illuminate/Http/Resources/Json/ResourceCollection.php index 8245184d386a..65c94ec62f16 100644 --- a/src/Illuminate/Http/Resources/Json/ResourceCollection.php +++ b/src/Illuminate/Http/Resources/Json/ResourceCollection.php @@ -99,7 +99,7 @@ public function toResponse($request) * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\JsonResponse */ - private function preparePaginatedResponse($request) + protected function preparePaginatedResponse($request) { if ($this->queryParameters) { $this->resource->appends($request->query()); From 3f8a842e0c533ea9f09359a7fae55466b851a52e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Aur=C3=A9lio=20Deleu?= Date: Thu, 5 Dec 2019 12:08:23 +0100 Subject: [PATCH 4/6] Update src/Illuminate/Http/Resources/Json/ResourceCollection.php Co-Authored-By: Dries Vints --- src/Illuminate/Http/Resources/Json/ResourceCollection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/Http/Resources/Json/ResourceCollection.php b/src/Illuminate/Http/Resources/Json/ResourceCollection.php index 65c94ec62f16..d2c1be6ee5ba 100644 --- a/src/Illuminate/Http/Resources/Json/ResourceCollection.php +++ b/src/Illuminate/Http/Resources/Json/ResourceCollection.php @@ -94,7 +94,7 @@ public function toResponse($request) } /** - * Create an paginate-aware HTTP response. + * Create a paginate-aware HTTP response. * * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\JsonResponse From 7f0174c4e51a87072908fff2c1db7647a5295e8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Aur=C3=A9lio=20Deleu?= Date: Thu, 5 Dec 2019 12:08:29 +0100 Subject: [PATCH 5/6] Update src/Illuminate/Http/Resources/Json/ResourceCollection.php Co-Authored-By: Dries Vints --- src/Illuminate/Http/Resources/Json/ResourceCollection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/Http/Resources/Json/ResourceCollection.php b/src/Illuminate/Http/Resources/Json/ResourceCollection.php index d2c1be6ee5ba..8483285d71f7 100644 --- a/src/Illuminate/Http/Resources/Json/ResourceCollection.php +++ b/src/Illuminate/Http/Resources/Json/ResourceCollection.php @@ -96,7 +96,7 @@ public function toResponse($request) /** * Create a paginate-aware HTTP response. * - * @param \Illuminate\Http\Request $request + * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\JsonResponse */ protected function preparePaginatedResponse($request) From 43cf1db50987e4dcac7e2da3a65b860ad2403031 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Aur=C3=A9lio=20Deleu?= Date: Thu, 5 Dec 2019 12:08:36 +0100 Subject: [PATCH 6/6] Update src/Illuminate/Http/Resources/Json/ResourceCollection.php Co-Authored-By: Dries Vints --- src/Illuminate/Http/Resources/Json/ResourceCollection.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/Http/Resources/Json/ResourceCollection.php b/src/Illuminate/Http/Resources/Json/ResourceCollection.php index 8483285d71f7..deab912f16cb 100644 --- a/src/Illuminate/Http/Resources/Json/ResourceCollection.php +++ b/src/Illuminate/Http/Resources/Json/ResourceCollection.php @@ -30,7 +30,7 @@ class ResourceCollection extends JsonResource implements Countable, IteratorAggr * * @var bool */ - private $queryParameters; + protected $queryParameters; /** * Create a new resource instance.