mirror of
https://github.com/ericasch6/scrum-poker-internal.git
synced 2026-10-13 14:52:09 +00:00
84 lines
2.6 KiB
PHP
84 lines
2.6 KiB
PHP
<?php
|
|
|
|
namespace App\Actions\Rooms;
|
|
|
|
use App\Models\Player;
|
|
use App\Models\Room;
|
|
use App\Models\User;
|
|
use App\Models\Vote;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class ClaimGuestRooms
|
|
{
|
|
/**
|
|
* @param array<array-key, mixed> $roomPlayers
|
|
*/
|
|
public function handle(User $user, array $roomPlayers): void
|
|
{
|
|
foreach ($roomPlayers as $roomId => $playerId) {
|
|
if (! is_string($roomId) || ! is_numeric($playerId)) {
|
|
continue;
|
|
}
|
|
|
|
DB::transaction(function () use ($user, $roomId, $playerId): void {
|
|
$room = Room::query()->lockForUpdate()->find($roomId);
|
|
|
|
if ($room === null || $room->owner_id !== null) {
|
|
return;
|
|
}
|
|
|
|
$moderator = $room->players()
|
|
->whereKey((int) $playerId)
|
|
->where('is_moderator', true)
|
|
->where(function ($query) use ($user): void {
|
|
$query->whereNull('user_id')->orWhere('user_id', $user->id);
|
|
})
|
|
->lockForUpdate()
|
|
->first();
|
|
|
|
if ($moderator === null) {
|
|
return;
|
|
}
|
|
|
|
$existingPlayer = $room->players()
|
|
->where('user_id', $user->id)
|
|
->whereKeyNot($moderator->id)
|
|
->lockForUpdate()
|
|
->first();
|
|
|
|
if ($existingPlayer !== null) {
|
|
$this->mergePlayerIntoModerator($existingPlayer, $moderator);
|
|
}
|
|
|
|
$moderator->update(['user_id' => $user->id]);
|
|
$room->update(['owner_id' => $user->id]);
|
|
});
|
|
}
|
|
}
|
|
|
|
private function mergePlayerIntoModerator(Player $source, Player $moderator): void
|
|
{
|
|
$source->votes()
|
|
->orderBy('updated_at')
|
|
->each(function (Vote $vote) use ($moderator): void {
|
|
$targetVote = $moderator->votes()
|
|
->where('room_id', $vote->room_id)
|
|
->where('round', $vote->round)
|
|
->first();
|
|
|
|
if ($targetVote === null || $vote->updated_at->greaterThanOrEqualTo($targetVote->updated_at)) {
|
|
Vote::updateOrCreate(
|
|
[
|
|
'player_id' => $moderator->id,
|
|
'room_id' => $vote->room_id,
|
|
'round' => $vote->round,
|
|
],
|
|
['value' => $vote->value],
|
|
);
|
|
}
|
|
});
|
|
|
|
$source->delete();
|
|
}
|
|
}
|