From 816ceb78b2c45f414a3f9bf352bab769a2636854 Mon Sep 17 00:00:00 2001 From: Andrew Brown Date: Fri, 3 Mar 2023 00:05:40 -0600 Subject: [PATCH 1/2] allow override of the Builder `paginate()` total this allows the user to set the total number of results a query returns. If the user provides this argument, the `paginate()` method will skip running its query to determine the total row count. --- src/Illuminate/Database/Eloquent/Builder.php | 5 ++-- src/Illuminate/Database/Query/Builder.php | 5 ++-- tests/Database/DatabaseQueryBuilderTest.php | 24 ++++++++++++++++++++ 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/Illuminate/Database/Eloquent/Builder.php b/src/Illuminate/Database/Eloquent/Builder.php index 55223ed9a874..8115825c39d5 100755 --- a/src/Illuminate/Database/Eloquent/Builder.php +++ b/src/Illuminate/Database/Eloquent/Builder.php @@ -880,15 +880,16 @@ public function pluck($column, $key = null) * @param array|string $columns * @param string $pageName * @param int|null $page + * @param int|null $total * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator * * @throws \InvalidArgumentException */ - public function paginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null) + public function paginate($perPage = null, $columns = ['*'], $pageName = 'page', $page = null, $total = null) { $page = $page ?: Paginator::resolveCurrentPage($pageName); - $total = $this->toBase()->getCountForPagination(); + $total = $total ?? $this->toBase()->getCountForPagination(); $perPage = ($perPage instanceof Closure ? $perPage($total) diff --git a/src/Illuminate/Database/Query/Builder.php b/src/Illuminate/Database/Query/Builder.php index d1965d6881c3..af03f453e61f 100755 --- a/src/Illuminate/Database/Query/Builder.php +++ b/src/Illuminate/Database/Query/Builder.php @@ -2727,13 +2727,14 @@ protected function runSelect() * @param array|string $columns * @param string $pageName * @param int|null $page + * @param int|null $total * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator */ - public function paginate($perPage = 15, $columns = ['*'], $pageName = 'page', $page = null) + public function paginate($perPage = 15, $columns = ['*'], $pageName = 'page', $page = null, $total = null) { $page = $page ?: Paginator::resolveCurrentPage($pageName); - $total = $this->getCountForPagination(); + $total = $total ?? $this->getCountForPagination(); $perPage = $perPage instanceof Closure ? $perPage($total) : $perPage; diff --git a/tests/Database/DatabaseQueryBuilderTest.php b/tests/Database/DatabaseQueryBuilderTest.php index 25568d5ec069..f6ceb3cd6fb6 100755 --- a/tests/Database/DatabaseQueryBuilderTest.php +++ b/tests/Database/DatabaseQueryBuilderTest.php @@ -4450,6 +4450,30 @@ public function testPaginateWithSpecificColumns() ]), $result); } + public function testPaginateWithTotalOverride() + { + $perPage = 16; + $columns = ['id', 'name']; + $pageName = 'page-name'; + $page = 1; + $builder = $this->getMockQueryBuilder(); + $path = 'http://foo.bar?page=3'; + + $results = collect([['id' => 3, 'name' => 'Taylor'], ['id' => 5, 'name' => 'Mohamed']]); + + $builder->shouldReceive('getCountForPagination')->never(); + $builder->shouldReceive('forPage')->once()->with($page, $perPage)->andReturnSelf(); + $builder->shouldReceive('get')->once()->andReturn($results); + + Paginator::currentPathResolver(function () use ($path) { + return $path; + }); + + $result = $builder->paginate($perPage, $columns, $pageName, $page, 10); + + $this->assertEquals(10, $result->total()); + } + public function testCursorPaginate() { $perPage = 16; From 62b0bdf3058d930d883693f44ffc6b287f0fd327 Mon Sep 17 00:00:00 2001 From: Taylor Otwell Date: Mon, 6 Mar 2023 13:13:20 -0600 Subject: [PATCH 2/2] use value helper --- src/Illuminate/Database/Eloquent/Builder.php | 4 ++-- src/Illuminate/Database/Query/Builder.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Illuminate/Database/Eloquent/Builder.php b/src/Illuminate/Database/Eloquent/Builder.php index 8115825c39d5..f269c6c88415 100755 --- a/src/Illuminate/Database/Eloquent/Builder.php +++ b/src/Illuminate/Database/Eloquent/Builder.php @@ -880,7 +880,7 @@ public function pluck($column, $key = null) * @param array|string $columns * @param string $pageName * @param int|null $page - * @param int|null $total + * @param \Closure|int|null $total * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator * * @throws \InvalidArgumentException @@ -889,7 +889,7 @@ public function paginate($perPage = null, $columns = ['*'], $pageName = 'page', { $page = $page ?: Paginator::resolveCurrentPage($pageName); - $total = $total ?? $this->toBase()->getCountForPagination(); + $total = value($total) ?? $this->toBase()->getCountForPagination(); $perPage = ($perPage instanceof Closure ? $perPage($total) diff --git a/src/Illuminate/Database/Query/Builder.php b/src/Illuminate/Database/Query/Builder.php index af03f453e61f..ec169507e0fb 100755 --- a/src/Illuminate/Database/Query/Builder.php +++ b/src/Illuminate/Database/Query/Builder.php @@ -2727,14 +2727,14 @@ protected function runSelect() * @param array|string $columns * @param string $pageName * @param int|null $page - * @param int|null $total + * @param \Closure|int|null $total * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator */ public function paginate($perPage = 15, $columns = ['*'], $pageName = 'page', $page = null, $total = null) { $page = $page ?: Paginator::resolveCurrentPage($pageName); - $total = $total ?? $this->getCountForPagination(); + $total = value($total) ?? $this->getCountForPagination(); $perPage = $perPage instanceof Closure ? $perPage($total) : $perPage;