the browser-facing portion of osu!
at master 91 lines 2.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 App\Jobs\Notifications\UserAchievementUnlock; 9use Exception; 10use Illuminate\Database\Eloquent\Relations\BelongsTo; 11use Illuminate\Support\Facades\DB; 12 13/** 14 * @property-read Achievement $achievement 15 * @property int $achievement_id 16 * @property-read Beatmap|null $beatmap 17 * @property int|null $beatmap_id 18 * @property \Carbon\Carbon $date 19 * @property-read string $date_json 20 * @property-read User $user 21 * @property int $user_id 22 */ 23class UserAchievement extends Model 24{ 25 public $incrementing = false; 26 public $timestamps = false; 27 28 protected $casts = ['date' => 'datetime']; 29 protected $primaryKey = ':composite'; 30 protected $primaryKeys = ['user_id', 'achievement_id']; 31 protected $table = 'osu_user_achievements'; 32 33 /** 34 * Unlock the medal for the given user. 35 */ 36 public static function unlock(User $user, Achievement $achievement, ?Beatmap $beatmap = null): bool 37 { 38 return DB::transaction(function () use ($achievement, $beatmap, $user) { 39 try { 40 $userAchievement = $user->userAchievements()->create([ 41 'achievement_id' => $achievement->getKey(), 42 'beatmap_id' => $beatmap?->getKey(), 43 ]); 44 } catch (Exception $e) { 45 if (is_sql_unique_exception($e)) { 46 return false; 47 } 48 49 throw $e; 50 } 51 52 Event::generate('achievement', compact('achievement', 'user')); 53 54 (new UserAchievementUnlock($achievement, $user))->dispatch(); 55 56 return true; 57 }); 58 } 59 60 public function achievement(): BelongsTo 61 { 62 return $this->belongsTo(Achievement::class, 'achievement_id'); 63 } 64 65 public function beatmap(): BelongsTo 66 { 67 return $this->belongsTo(Beatmap::class, 'beatmap_id'); 68 } 69 70 public function user(): BelongsTo 71 { 72 return $this->belongsTo(User::class, 'user_id'); 73 } 74 75 public function getAttribute($key) 76 { 77 return match ($key) { 78 'achievement_id', 79 'beatmap_id', 80 'user_id' => $this->getRawAttribute($key), 81 82 'date' => $this->getTimeFast($key), 83 84 'date_json' => $this->getJsonTimeFast($key), 85 86 'achievement', 87 'beatmap', 88 'user' => $this->getRelationValue($key), 89 }; 90 } 91}