the browser-facing portion of osu!
at master 174 lines 4.8 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 App\Exceptions\InvariantException; 9use App\Models\Store\Product; 10use Carbon\Carbon; 11 12/** 13 * @property \Carbon\Carbon|null $created_at 14 * @property string $description 15 * @property \Carbon\Carbon $end_date 16 * @property string|null $header_banner 17 * @property string|null $info_url 18 * @property string $name 19 * @property int $play_mode 20 * @property \Illuminate\Database\Eloquent\Collection $profileBanners ProfileBanner 21 * @property int|null $rank_max 22 * @property int|null $rank_min 23 * @property \Illuminate\Database\Eloquent\Collection $registrations TournamentRegistration 24 * @property \Carbon\Carbon $signup_close 25 * @property \Carbon\Carbon $signup_open 26 * @property \Carbon\Carbon $start_date 27 * @property int|null $tournament_banner_product_id 28 * @property int $tournament_id 29 * @property \Carbon\Carbon|null $updated_at 30 */ 31class Tournament extends Model 32{ 33 protected $primaryKey = 'tournament_id'; 34 35 protected $casts = [ 36 'end_date' => 'datetime', 37 'signup_close' => 'datetime', 38 'signup_open' => 'datetime', 39 'start_date' => 'datetime', 40 ]; 41 42 public static function getGroupedListing() 43 { 44 $tournaments = static::query() 45 ->with('registrations') 46 ->orderBy('tournament_id', 'desc') 47 ->get(); 48 49 $now = Carbon::now(); 50 51 return [ 52 'current' => $tournaments->where('end_date', '>', $now), 53 'previous' => $tournaments->where('end_date', '<=', $now), 54 ]; 55 } 56 57 public function profileBanners() 58 { 59 return $this->hasMany(ProfileBanner::class); 60 } 61 62 public function registrations() 63 { 64 return $this->hasMany(TournamentRegistration::class); 65 } 66 67 public function product() 68 { 69 return $this->belongsTo(Product::class, 'tournament_banner_product_id'); 70 } 71 72 public function isRegistrationOpen() 73 { 74 $now = Carbon::now(); 75 76 return $this->signup_open < $now && $this->signup_close > $now; 77 } 78 79 public function isTournamentRunning() 80 { 81 $now = Carbon::now(); 82 83 return $this->start_date < $now && $this->end_date > $now; 84 } 85 86 public function isStoreBannerAvailable() 87 { 88 return $this->tournament_banner_product_id !== null && $this->product->isAvailable(); 89 } 90 91 public function isSignedUp($user) 92 { 93 if (!$user) { 94 return false; 95 } 96 97 return $this->registrations()->where('user_id', '=', $user->user_id)->exists(); 98 } 99 100 public function isValidRank($user) 101 { 102 if (!$user) { 103 return false; 104 } 105 106 $userRank = UserStatistics\Model 107 ::getClass($this->playModeStr(), $this->play_mode_variant) 108 ::firstOrNew(['user_id' => $user->getKey()]) 109 ->globalRank(); 110 111 if ($this->rank_min !== null && ($userRank === null || $this->rank_min > $userRank)) { 112 return false; 113 } 114 115 if ($this->rank_max !== null && ($userRank === null || $this->rank_max < $userRank)) { 116 return false; 117 } 118 119 return true; 120 } 121 122 public function unregister($user) 123 { 124 //sanity check: we shouldn't be touching users once the tournament is already in action. 125 if ($this->isTournamentRunning()) { 126 throw new InvariantException('tournament is already running'); 127 } 128 129 $this->registrations()->where('user_id', '=', $user->user_id)->delete(); 130 } 131 132 public function register($user) 133 { 134 if ($this->isSignedUp($user)) { 135 return; 136 } 137 138 //sanity check: we shouldn't be touching users once the tournament is already in action. 139 if ($this->isTournamentRunning()) { 140 throw new InvariantException('tournament is already running'); 141 } 142 143 $reg = new TournamentRegistration(); 144 $reg->user()->associate($user); 145 146 $this->registrations()->save($reg); 147 } 148 149 public function playModeStr() 150 { 151 return Beatmap::modeStr($this->play_mode); 152 } 153 154 public function pageLinks() 155 { 156 $links = []; 157 158 if ($this->info_url !== null) { 159 $links[] = [ 160 'url' => $this->info_url, 161 'title' => osu_trans('tournament.show.info_page'), 162 ]; 163 } 164 165 if ($this->isStoreBannerAvailable()) { 166 $links[] = [ 167 'url' => route('store.products.show', $this->tournament_banner_product_id), 168 'title' => osu_trans('tournament.show.banner'), 169 ]; 170 } 171 172 return $links; 173 } 174}