the browser-facing portion of osu!
at master 5.6 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; 7 8use Carbon\Carbon; 9 10/** 11 * @property BeatmapDiscussion $beatmapDiscussion 12 * @property int $beatmap_discussion_id 13 * @property \Carbon\Carbon|null $created_at 14 * @property int $id 15 * @property int $score 16 * @property \Carbon\Carbon|null $updated_at 17 * @property User $user 18 * @property int|null $user_id 19 */ 20class BeatmapDiscussionVote extends Model 21{ 22 protected $touches = ['beatmapDiscussion']; 23 24 public static function recentlyReceivedByUser($userId, $timeframeMonths = 3) 25 { 26 return static::where('beatmap_discussion_votes.created_at', '>', Carbon::now()->subMonths($timeframeMonths)) 27 ->join('beatmap_discussions', 'beatmap_discussion_votes.beatmap_discussion_id', 'beatmap_discussions.id') 28 ->select('beatmap_discussion_votes.user_id') 29 ->selectRaw('sum(beatmap_discussion_votes.score) as score') 30 ->selectRaw('count(beatmap_discussion_votes.score) as count') 31 ->where('beatmap_discussions.user_id', $userId) 32 ->where('beatmap_discussions.updated_at', '>', Carbon::now()->subMonths($timeframeMonths)) 33 ->whereHas('user', function ($userQuery) { 34 $userQuery->default(); 35 }) 36 ->groupBy('beatmap_discussion_votes.user_id') 37 ->orderByDesc('count') 38 ->get(); 39 } 40 41 public static function recentlyGivenByUser($userId, $timeframeMonths = 3) 42 { 43 return static::where('beatmap_discussion_votes.created_at', '>', Carbon::now()->subMonths($timeframeMonths)) 44 ->join('beatmap_discussions', 'beatmap_discussion_votes.beatmap_discussion_id', 'beatmap_discussions.id') 45 ->select('beatmap_discussions.user_id') 46 ->selectRaw('sum(beatmap_discussion_votes.score) as score') 47 ->selectRaw('count(beatmap_discussion_votes.score) as count') 48 ->where('beatmap_discussion_votes.user_id', $userId) 49 ->where('beatmap_discussions.updated_at', '>', Carbon::now()->subMonths($timeframeMonths)) 50 ->whereHas('beatmapDiscussion.user', function ($userQuery) { 51 $userQuery->default(); 52 }) 53 ->groupBy('beatmap_discussions.user_id') 54 ->orderByDesc('count') 55 ->get(); 56 } 57 58 public static function search($rawParams = []) 59 { 60 [$query, $params] = static::searchQueryAndParams(cursor_from_params($rawParams) ?? $rawParams); 61 62 $isModerator = $rawParams['is_moderator'] ?? false; 63 64 if (isset($rawParams['user'])) { 65 $params['user'] = $rawParams['user']; 66 $findAll = $isModerator || (($rawParams['current_user_id'] ?? null) === $rawParams['user']); 67 $user = User::lookup($params['user'], null, $findAll); 68 69 if ($user === null) { 70 $query->none(); 71 } else { 72 $query->where('user_id', $user->getKey()); 73 } 74 } 75 76 if (isset($rawParams['receiver'])) { 77 $params['receiver'] = $rawParams['receiver']; 78 $user = User::lookup($params['receiver']); 79 80 if ($user === null) { 81 $query->none(); 82 } else { 83 $query->whereIn('beatmap_discussion_id', BeatmapDiscussion::where('user_id', '=', $user->getKey())->select('id')); 84 } 85 } 86 87 if (isset($rawParams['sort'])) { 88 $sort = explode('_', strtolower($rawParams['sort'])); 89 90 if (in_array($sort[0] ?? null, ['id'], true)) { 91 $sortField = $sort[0]; 92 } 93 94 if (in_array($sort[1] ?? null, ['asc', 'desc'], true)) { 95 $sortOrder = $sort[1]; 96 } 97 } 98 99 $sortField ?? ($sortField = 'id'); 100 $sortOrder ?? ($sortOrder = 'desc'); 101 102 $params['sort'] = "{$sortField}_{$sortOrder}"; 103 $query->orderBy($sortField, $sortOrder); 104 105 if (isset($rawParams['score'])) { 106 $params['score'] = get_int($rawParams['score']); 107 if ($params['score'] !== null) { 108 $query->where('score', '=', $params['score']); 109 } 110 } 111 112 $params['beatmapset_discussion_id'] = get_int($rawParams['beatmapset_discussion_id'] ?? null); 113 if ($params['beatmapset_discussion_id'] !== null) { 114 // column name is beatmap_ =) 115 $query->where('beatmap_discussion_id', $params['beatmapset_discussion_id']); 116 } 117 118 // TODO: normalize with main beatmapset discussion behaviour (needs React-side fixing) 119 if (!isset($user) && !$isModerator) { 120 $query->whereHas('user', function ($userQuery) { 121 $userQuery->default(); 122 }); 123 } 124 125 return ['query' => $query, 'params' => $params]; 126 } 127 128 public function beatmapDiscussion() 129 { 130 return $this->belongsTo(BeatmapDiscussion::class); 131 } 132 133 public function user() 134 { 135 return $this->belongsTo(User::class, 'user_id'); 136 } 137 138 public function setScoreAttribute($value) 139 { 140 if ($value > 0) { 141 $value = 1; 142 } elseif ($value < 0) { 143 $value = -1; 144 } else { 145 $value = 0; 146 } 147 148 $this->attributes['score'] = $value; 149 } 150 151 public function forEvent() 152 { 153 return [ 154 'user_id' => $this->user_id, 155 'score' => $this->score, 156 ]; 157 } 158}