the browser-facing portion of osu!
at master 80 lines 2.9 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 6declare(strict_types=1); 7 8namespace App\Libraries\Beatmapset; 9 10use App\Exceptions\InvariantException; 11use App\Jobs\Notifications\BeatmapOwnerChange; 12use App\Models\Beatmap; 13use App\Models\BeatmapOwner; 14use App\Models\BeatmapsetEvent; 15use App\Models\User; 16use Ds\Set; 17 18class ChangeBeatmapOwners 19{ 20 private Set $userIds; 21 22 public function __construct(private Beatmap $beatmap, array $newUserIds, private User $source) 23 { 24 priv_check_user($source, 'BeatmapUpdateOwner', $beatmap->beatmapset)->ensureCan(); 25 26 $this->userIds = new Set($newUserIds); 27 28 if ($this->userIds->count() > $GLOBALS['cfg']['osu']['beatmaps']['owners_max']) { 29 throw new InvariantException(osu_trans('beatmaps.change_owner.too_many')); 30 } 31 32 if ($this->userIds->isEmpty()) { 33 throw new InvariantException('user_ids must be specified'); 34 } 35 } 36 37 public function handle(): void 38 { 39 $currentOwners = new Set($this->beatmap->getOwners()->pluck('user_id')); 40 if ($currentOwners->xor($this->userIds)->isEmpty()) { 41 return; 42 } 43 44 $newUserIds = $this->userIds->diff($currentOwners); 45 46 if (User::whereIn('user_id', $newUserIds->toArray())->default()->withoutBots()->withoutNoProfile()->count() !== $newUserIds->count()) { 47 throw new InvariantException('invalid user_id'); 48 } 49 50 $this->beatmap->getConnection()->transaction(function () { 51 $params = array_map( 52 fn ($userId) => ['beatmap_id' => $this->beatmap->getKey(), 'user_id' => $userId], 53 $this->userIds->toArray() 54 ); 55 56 $this->beatmap->fill(['user_id' => $this->userIds->first()])->saveOrExplode(); 57 $this->beatmap->beatmapOwners()->delete(); 58 BeatmapOwner::insert($params); 59 60 $this->beatmap->refresh(); 61 62 $newUsers = $this->beatmap->getOwners()->select('id', 'username')->all(); 63 $beatmapset = $this->beatmap->beatmapset; 64 $firstMapper = $newUsers[0]; 65 66 BeatmapsetEvent::log(BeatmapsetEvent::BEATMAP_OWNER_CHANGE, $this->source, $beatmapset, [ 67 'beatmap_id' => $this->beatmap->getKey(), 68 'beatmap_version' => $this->beatmap->version, 69 // TODO: mainly for compatibility during dev when switching branches, can be removed after deployed. 70 'new_user_id' => $firstMapper['id'], 71 'new_user_username' => $firstMapper['username'], 72 'new_users' => $newUsers, 73 ])->saveOrExplode(); 74 75 $beatmapset->update(['eligible_main_rulesets' => null]); 76 }); 77 78 (new BeatmapOwnerChange($this->beatmap, $this->source))->dispatch(); 79 } 80}