the browser-facing portion of osu!
at master 75 lines 2.7 kB view raw
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\Models\Traits; 7 8use App\Libraries\DbCursorHelper; 9 10trait WithDbCursorHelper 11{ 12 public static function makeDbCursorHelper(?string $sort = null) 13 { 14 return new DbCursorHelper(static::SORTS, static::DEFAULT_SORT, $sort); 15 } 16 17 private static function cursorSortExecOrder($query, array $sort) 18 { 19 foreach ($sort as $i => $sortItem) { 20 $orderMethod = $i === 0 ? 'reorderBy' : 'orderBy'; 21 $query->$orderMethod($sortItem['column'], $sortItem['order']); 22 } 23 24 return $query; 25 } 26 27 private static function cursorSortExecWhere($query, ?array $preparedCursor) 28 { 29 if (empty($preparedCursor)) { 30 return $query; 31 } 32 33 $current = array_shift($preparedCursor); 34 35 $dir = $current['order'] === 'DESC' ? '<' : '>'; 36 37 if (count($preparedCursor) === 0) { 38 $query->where($current['column'], $dir, $current['value']); 39 } else { 40 $query->where($current['column'], "{$dir}=", $current['value']) 41 ->where(function ($q) use ($current, $dir, $preparedCursor) { 42 return $q->where($current['column'], $dir, $current['value']) 43 ->orWhere(function ($qq) use ($preparedCursor) { 44 return static::cursorSortExecWhere($qq, $preparedCursor); 45 }); 46 }); 47 } 48 49 return $query; 50 } 51 52 /** 53 * Builds a cursor-based sort query. 54 * 55 * @param \Illuminate\Database\Eloquent\Builder $query Input query to be extended. 56 * @param string|DbCursorHelper $sortOrCursorHelper Either sort name to create DbCursorHelper or existing DbCursorHelper. 57 * @param array|static $cursorOrStatic Either an input cursor array or object instance to generate cursor array from. 58 * 59 * @return \Illuminate\Database\Eloquent\Builder 60 */ 61 public function scopeCursorSort($query, $sortOrCursorHelper, $cursorOrStatic) 62 { 63 $cursorHelper = $sortOrCursorHelper instanceof DbCursorHelper 64 ? $sortOrCursorHelper 65 : static::makeDbCursorHelper(get_string($sortOrCursorHelper)); 66 67 $query = static::cursorSortExecOrder($query, $cursorHelper->getSort()); 68 69 $cursor = $cursorOrStatic instanceof static 70 ? $cursorHelper->itemToCursor($cursorOrStatic) 71 : $cursorOrStatic; 72 73 return static::cursorSortExecWhere($query, $cursorHelper->prepare($cursor)); 74 } 75}