Skip to content

Commit 85ceb55

Browse files
committed
Merge branch '8.x'
2 parents f15b9ae + 80f0112 commit 85ceb55

File tree

6 files changed

+164
-96
lines changed

6 files changed

+164
-96
lines changed

src/Illuminate/Database/Concerns/BuildsQueries.php

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -282,14 +282,49 @@ public function sole($columns = ['*'])
282282
}
283283

284284
/**
285-
* Pass the query to a given callback.
285+
* Paginate the given query using a cursor paginator.
286286
*
287-
* @param callable $callback
288-
* @return $this
287+
* @param int $perPage
288+
* @param array $columns
289+
* @param string $cursorName
290+
* @param string|null $cursor
291+
* @return \Illuminate\Contracts\Pagination\CursorPaginator
289292
*/
290-
public function tap($callback)
293+
protected function paginateUsingCursor($perPage, $columns = ['*'], $cursorName = 'cursor', $cursor = null)
291294
{
292-
return $this->when(true, $callback);
295+
$cursor = $cursor ?: CursorPaginator::resolveCurrentCursor($cursorName);
296+
297+
$orders = $this->ensureOrderForCursorPagination(! is_null($cursor) && $cursor->pointsToPreviousItems());
298+
299+
if (! is_null($cursor)) {
300+
$addCursorConditions = function (self $builder, $previousColumn, $i) use (&$addCursorConditions, $cursor, $orders) {
301+
if (! is_null($previousColumn)) {
302+
$builder->where($previousColumn, '=', $cursor->parameter($previousColumn));
303+
}
304+
305+
$builder->where(function (self $builder) use ($addCursorConditions, $cursor, $orders, $i) {
306+
['column' => $column, 'direction' => $direction] = $orders[$i];
307+
308+
$builder->where($column, $direction === 'asc' ? '>' : '<', $cursor->parameter($column));
309+
310+
if ($i < $orders->count() - 1) {
311+
$builder->orWhere(function (self $builder) use ($addCursorConditions, $column, $i) {
312+
$addCursorConditions($builder, $column, $i + 1);
313+
});
314+
}
315+
});
316+
};
317+
318+
$addCursorConditions($this, null, 0);
319+
}
320+
321+
$this->limit($perPage + 1);
322+
323+
return $this->cursorPaginator($this->get($columns), $perPage, $cursor, [
324+
'path' => Paginator::resolveCurrentPath(),
325+
'cursorName' => $cursorName,
326+
'parameters' => $orders->pluck('column')->toArray(),
327+
]);
293328
}
294329

295330
/**
@@ -340,4 +375,15 @@ protected function cursorPaginator($items, $perPage, $cursor, $options)
340375
'items', 'perPage', 'cursor', 'options'
341376
));
342377
}
378+
379+
/**
380+
* Pass the query to a given callback.
381+
*
382+
* @param callable $callback
383+
* @return $this
384+
*/
385+
public function tap($callback)
386+
{
387+
return $this->when(true, $callback);
388+
}
343389
}

src/Illuminate/Database/Eloquent/Builder.php

Lines changed: 3 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
use Illuminate\Database\Eloquent\Relations\Relation;
1313
use Illuminate\Database\Query\Builder as QueryBuilder;
1414
use Illuminate\Database\RecordsNotFoundException;
15-
use Illuminate\Pagination\CursorPaginationException;
16-
use Illuminate\Pagination\CursorPaginator;
1715
use Illuminate\Pagination\Paginator;
1816
use Illuminate\Support\Arr;
1917
use Illuminate\Support\Str;
@@ -833,56 +831,25 @@ public function simplePaginate($perPage = null, $columns = ['*'], $pageName = 'p
833831
* @param string $cursorName
834832
* @param string|null $cursor
835833
* @return \Illuminate\Contracts\Pagination\CursorPaginator
836-
* @throws \Illuminate\Pagination\CursorPaginationException
837834
*/
838835
public function cursorPaginate($perPage = null, $columns = ['*'], $cursorName = 'cursor', $cursor = null)
839836
{
840-
$cursor = $cursor ?: CursorPaginator::resolveCurrentCursor($cursorName);
841-
842837
$perPage = $perPage ?: $this->model->getPerPage();
843838

844-
$orders = $this->ensureOrderForCursorPagination(! is_null($cursor) && $cursor->pointsToPreviousItems());
845-
846-
$orderDirection = $orders->first()['direction'] ?? 'asc';
847-
848-
$comparisonOperator = $orderDirection === 'asc' ? '>' : '<';
849-
850-
$parameters = $orders->pluck('column')->toArray();
851-
852-
if (! is_null($cursor)) {
853-
if (count($parameters) === 1) {
854-
$this->where($column = $parameters[0], $comparisonOperator, $cursor->parameter($column));
855-
} elseif (count($parameters) > 1) {
856-
$this->whereRowValues($parameters, $comparisonOperator, $cursor->parameters($parameters));
857-
}
858-
}
859-
860-
$this->take($perPage + 1);
861-
862-
return $this->cursorPaginator($this->get($columns), $perPage, $cursor, [
863-
'path' => Paginator::resolveCurrentPath(),
864-
'cursorName' => $cursorName,
865-
'parameters' => $parameters,
866-
]);
839+
return $this->paginateUsingCursor($perPage, $columns, $cursorName, $cursor);
867840
}
868841

869842
/**
870843
* Ensure the proper order by required for cursor pagination.
871844
*
872845
* @param bool $shouldReverse
873846
* @return \Illuminate\Support\Collection
874-
*
875-
* @throws \Illuminate\Pagination\CursorPaginationException
876847
*/
877848
protected function ensureOrderForCursorPagination($shouldReverse = false)
878849
{
879-
$orderDirections = collect($this->query->orders)->pluck('direction')->unique();
880-
881-
if ($orderDirections->count() > 1) {
882-
throw new CursorPaginationException('Only a single order by direction is supported when using cursor pagination.');
883-
}
850+
$orders = collect($this->query->orders);
884851

885-
if ($orderDirections->count() === 0) {
852+
if ($orders->count() === 0) {
886853
$this->enforceOrderBy();
887854
}
888855

src/Illuminate/Database/Query/Builder.php

Lines changed: 1 addition & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
use Illuminate\Database\Eloquent\Relations\Relation;
1313
use Illuminate\Database\Query\Grammars\Grammar;
1414
use Illuminate\Database\Query\Processors\Processor;
15-
use Illuminate\Pagination\CursorPaginationException;
16-
use Illuminate\Pagination\CursorPaginator;
1715
use Illuminate\Pagination\Paginator;
1816
use Illuminate\Support\Arr;
1917
use Illuminate\Support\Collection;
@@ -2461,54 +2459,22 @@ public function simplePaginate($perPage = 15, $columns = ['*'], $pageName = 'pag
24612459
* @param string $cursorName
24622460
* @param string|null $cursor
24632461
* @return \Illuminate\Contracts\Pagination\CursorPaginator
2464-
* @throws \Illuminate\Pagination\CursorPaginationException
24652462
*/
24662463
public function cursorPaginate($perPage = 15, $columns = ['*'], $cursorName = 'cursor', $cursor = null)
24672464
{
2468-
$cursor = $cursor ?: CursorPaginator::resolveCurrentCursor($cursorName);
2469-
2470-
$orders = $this->ensureOrderForCursorPagination(! is_null($cursor) && $cursor->pointsToPreviousItems());
2471-
2472-
$orderDirection = $orders->first()['direction'] ?? 'asc';
2473-
2474-
$comparisonOperator = $orderDirection === 'asc' ? '>' : '<';
2475-
2476-
$parameters = $orders->pluck('column')->toArray();
2477-
2478-
if (! is_null($cursor)) {
2479-
if (count($parameters) === 1) {
2480-
$this->where($column = $parameters[0], $comparisonOperator, $cursor->parameter($column));
2481-
} elseif (count($parameters) > 1) {
2482-
$this->whereRowValues($parameters, $comparisonOperator, $cursor->parameters($parameters));
2483-
}
2484-
}
2485-
2486-
$this->limit($perPage + 1);
2487-
2488-
return $this->cursorPaginator($this->get($columns), $perPage, $cursor, [
2489-
'path' => Paginator::resolveCurrentPath(),
2490-
'cursorName' => $cursorName,
2491-
'parameters' => $parameters,
2492-
]);
2465+
return $this->paginateUsingCursor($perPage, $columns, $cursorName, $cursor);
24932466
}
24942467

24952468
/**
24962469
* Ensure the proper order by required for cursor pagination.
24972470
*
24982471
* @param bool $shouldReverse
24992472
* @return \Illuminate\Support\Collection
2500-
* @throws \Illuminate\Pagination\CursorPaginationException
25012473
*/
25022474
protected function ensureOrderForCursorPagination($shouldReverse = false)
25032475
{
25042476
$this->enforceOrderBy();
25052477

2506-
$orderDirections = collect($this->orders)->pluck('direction')->unique();
2507-
2508-
if ($orderDirections->count() > 1) {
2509-
throw new CursorPaginationException('Only a single order by direction is supported when using cursor pagination.');
2510-
}
2511-
25122478
if ($shouldReverse) {
25132479
$this->orders = collect($this->orders)->map(function ($order) {
25142480
$order['direction'] = $order['direction'] === 'asc' ? 'desc' : 'asc';

src/Illuminate/Foundation/Console/stubs/policy.stub

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class {{ class }}
1414
* Determine whether the user can view any models.
1515
*
1616
* @param \{{ namespacedUserModel }} $user
17-
* @return mixed
17+
* @return \Illuminate\Auth\Access\Response|bool
1818
*/
1919
public function viewAny({{ user }} $user)
2020
{
@@ -26,7 +26,7 @@ class {{ class }}
2626
*
2727
* @param \{{ namespacedUserModel }} $user
2828
* @param \{{ namespacedModel }} ${{ modelVariable }}
29-
* @return mixed
29+
* @return \Illuminate\Auth\Access\Response|bool
3030
*/
3131
public function view({{ user }} $user, {{ model }} ${{ modelVariable }})
3232
{
@@ -37,7 +37,7 @@ class {{ class }}
3737
* Determine whether the user can create models.
3838
*
3939
* @param \{{ namespacedUserModel }} $user
40-
* @return mixed
40+
* @return \Illuminate\Auth\Access\Response|bool
4141
*/
4242
public function create({{ user }} $user)
4343
{
@@ -49,7 +49,7 @@ class {{ class }}
4949
*
5050
* @param \{{ namespacedUserModel }} $user
5151
* @param \{{ namespacedModel }} ${{ modelVariable }}
52-
* @return mixed
52+
* @return \Illuminate\Auth\Access\Response|bool
5353
*/
5454
public function update({{ user }} $user, {{ model }} ${{ modelVariable }})
5555
{
@@ -61,7 +61,7 @@ class {{ class }}
6161
*
6262
* @param \{{ namespacedUserModel }} $user
6363
* @param \{{ namespacedModel }} ${{ modelVariable }}
64-
* @return mixed
64+
* @return \Illuminate\Auth\Access\Response|bool
6565
*/
6666
public function delete({{ user }} $user, {{ model }} ${{ modelVariable }})
6767
{
@@ -73,7 +73,7 @@ class {{ class }}
7373
*
7474
* @param \{{ namespacedUserModel }} $user
7575
* @param \{{ namespacedModel }} ${{ modelVariable }}
76-
* @return mixed
76+
* @return \Illuminate\Auth\Access\Response|bool
7777
*/
7878
public function restore({{ user }} $user, {{ model }} ${{ modelVariable }})
7979
{
@@ -85,7 +85,7 @@ class {{ class }}
8585
*
8686
* @param \{{ namespacedUserModel }} $user
8787
* @param \{{ namespacedModel }} ${{ modelVariable }}
88-
* @return mixed
88+
* @return \Illuminate\Auth\Access\Response|bool
8989
*/
9090
public function forceDelete({{ user }} $user, {{ model }} ${{ modelVariable }})
9191
{

src/Illuminate/Pagination/CursorPaginationException.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
use RuntimeException;
66

7+
/**
8+
* @deprecated Will be removed in a future Laravel version.
9+
*/
710
class CursorPaginationException extends RuntimeException
811
{
912
//

0 commit comments

Comments
 (0)