1<?php
2
3// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0.
4// See the LICENCE file in the repository root for full licence text.
5
6namespace App\Libraries;
7
8use App\Models\Model;
9use Illuminate\Support\Collection;
10
11class DbCursorHelper
12{
13 private $sort;
14 private $sortName;
15
16 public function __construct($sorts, $defaultSort, $requestedSort = null)
17 {
18 $this->sortName = $requestedSort;
19 $this->sort = $sorts[$requestedSort] ?? null;
20
21 if ($this->sort === null) {
22 $this->sort = $sorts[$defaultSort];
23 $this->sortName = $defaultSort;
24 }
25 }
26
27 public function itemToCursor($item)
28 {
29 if (!($item instanceof Model)) {
30 return;
31 }
32
33 $ret = [];
34
35 foreach ($this->sort as $sort) {
36 $column = $sort['column'];
37 $columnInput = $sort['columnInput'] ?? $sort['column'];
38 $ret[$columnInput] = $item->$column;
39 }
40
41 return $ret;
42 }
43
44 public function getSort()
45 {
46 return $this->sort;
47 }
48
49 public function getSortName()
50 {
51 return $this->sortName;
52 }
53
54 public function prepare($cursor)
55 {
56 if (!is_array($cursor)) {
57 return;
58 }
59
60 $ret = [];
61
62 foreach ($this->sort as $sortItem) {
63 $columnInput = $sortItem['columnInput'] ?? $sortItem['column'];
64 $column = $sortItem['column'];
65 $order = $sortItem['order'];
66 $value = get_param_value($cursor[$columnInput] ?? null, $sortItem['type'] ?? null);
67
68 if ($value === null) {
69 return;
70 }
71
72 $ret[] = compact('column', 'order', 'value');
73 }
74
75 return $ret;
76 }
77
78 public function next($items, bool $hasMore = true)
79 {
80 if (!$hasMore) {
81 return null;
82 }
83
84 if (is_array($items)) {
85 $lastItem = array_last($items);
86 } elseif ($items instanceof Collection) {
87 $lastItem = $items->last();
88 }
89
90 if (isset($lastItem)) {
91 return $this->itemToCursor($lastItem);
92 }
93 }
94}