the browser-facing portion of osu!
at master 3.4 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\Http\Controllers; 7 8use App\Jobs\RenumberUserScorePins; 9use App\Models\ScorePin; 10use App\Models\Solo; 11use Exception; 12 13class ScorePinsController extends Controller 14{ 15 public function __construct() 16 { 17 $this->middleware('auth'); 18 19 parent::__construct(); 20 } 21 22 public function destroy() 23 { 24 \Auth::user()->scorePins()->whereKey(get_int(request('score_id')))->delete(); 25 26 return response()->noContent(); 27 } 28 29 public function reorder() 30 { 31 $rawParams = \Request::all(); 32 $targetId = get_int($rawParams['score_id'] ?? null); 33 34 $pinsQuery = \Auth::user()->scorePins(); 35 $target = $pinsQuery->clone()->findOrFail($targetId); 36 $rulesetId = $target->ruleset_id; 37 $pinsQuery->where('ruleset_id', $rulesetId); 38 39 $adjacentScores = []; 40 foreach (['order1', 'order3'] as $position) { 41 $adjacentScoreIds[$position] = get_int($rawParams[$position]['score_id'] ?? null); 42 } 43 44 $order1Item = isset($adjacentScoreIds['order1']) 45 ? $pinsQuery->clone()->find($adjacentScoreIds['order1']) 46 : null; 47 $order3Item = $order1Item === null && isset($adjacentScoreIds['order3']) 48 ? $pinsQuery->clone()->find($adjacentScoreIds['order3']) 49 : null; 50 51 abort_if($order1Item === null && $order3Item === null, 422, 'no valid pinned score reference is specified'); 52 53 if ($order1Item === null) { 54 $order3 = $order3Item->display_order; 55 $order1 = $pinsQuery->clone()->where('display_order', '<', $order3)->max('display_order') 56 ?? $order3 - 200; 57 } else { 58 $order1 = $order1Item->display_order; 59 $order3 = $pinsQuery->clone()->where('display_order', '>', $order1)->min('display_order') 60 ?? $order1 + 200; 61 } 62 63 $order2 = ($order1 + $order3) / 2; 64 65 if ($order3 - $order1 < 0.1) { 66 dispatch(new RenumberUserScorePins($target->user_id, $target->ruleset_id)); 67 } 68 69 $target->update(['display_order' => $order2]); 70 71 return response()->noContent(); 72 } 73 74 public function store() 75 { 76 $id = get_int(request('score_id')); 77 $score = Solo\Score::find($id); 78 79 abort_if($score === null, 422, "specified score couldn't be found"); 80 81 $user = \Auth::user(); 82 83 $pin = $user->scorePins()->find($id); 84 85 if ($pin === null) { 86 priv_check('ScorePin', $score)->ensureCan(); 87 88 $rulesetId = $score->ruleset_id; 89 $currentMinDisplayOrder = $user->scorePins()->where('ruleset_id', $rulesetId)->min('display_order') ?? 2500; 90 91 try { 92 (new ScorePin([ 93 'display_order' => $currentMinDisplayOrder - 100, 94 'ruleset_id' => $rulesetId, 95 ]))->user()->associate($user) 96 ->score()->associate($score) 97 ->saveOrExplode(); 98 } catch (Exception $ex) { 99 if (!is_sql_unique_exception($ex)) { 100 throw $ex; 101 } 102 } 103 104 $score->update(['preserve' => true]); 105 } 106 107 return response()->noContent(); 108 } 109}