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\Libraries\Search\ScoreSearch;
9use App\Libraries\Search\ScoreSearchParams;
10use DB;
11
12/**
13 * @property int $id
14 * @property int $ruleset_id
15 * @property int $beatmap_id
16 * @property int $user_id
17 * @property int $score_id
18 */
19class BeatmapLeader extends Model
20{
21 public $timestamps = false;
22
23 protected $primaryKey = 'score_id';
24
25 public static function sync(int $beatmapId, int $rulesetId): void
26 {
27 $searchParams = ScoreSearchParams::fromArray([
28 'beatmap_ids' => [$beatmapId],
29 'is_legacy' => false,
30 'limit' => 1,
31 'ruleset_id' => $rulesetId,
32 'sort' => 'score_desc',
33 ]);
34
35 $score = (new ScoreSearch($searchParams))->records()->first();
36
37 DB::transaction(function () use ($beatmapId, $rulesetId, $score): void {
38 $scoreLeader = static::where([
39 'beatmap_id' => $beatmapId,
40 'ruleset_id' => $rulesetId,
41 ])->lockForUpdate()->first();
42
43 if ($score === null) {
44 $scoreLeader?->delete();
45
46 return;
47 }
48
49 $params = [
50 'beatmap_id' => $beatmapId,
51 'ruleset_id' => $rulesetId,
52 'score_id' => $score->getKey(),
53 'user_id' => $score->user_id,
54 ];
55
56 if ($scoreLeader === null) {
57 static::create($params);
58 } else {
59 $scoreLeader->update($params);
60 }
61 });
62 }
63}