feat: added settings in room to kick

This commit is contained in:
2026-09-06 16:06:12 +02:00
parent 1e0f5cf143
commit 817b1ce1cb
10 changed files with 439 additions and 107 deletions
@@ -5,7 +5,6 @@ namespace App\Http\Controllers;
use App\Http\Requests\KickRoomPlayerRequest;
use App\Models\Player;
use App\Models\Room;
use App\Models\User;
use App\Services\Rooms\RoomParticipationService;
use Illuminate\Http\RedirectResponse;
use Inertia\Inertia;
@@ -18,11 +17,12 @@ class RoomPlayerKickController extends Controller
public function __invoke(KickRoomPlayerRequest $request, Room $room, Player $player): RedirectResponse
{
$user = $request->user();
abort_unless($user instanceof User, 403);
$this->roomParticipation->kick($room, $player, $user);
$this->roomParticipation->kick(
$room,
$player,
$request->user(),
$request->currentPlayer($room),
);
Inertia::flash('toast', [
'type' => 'success',
+34 -6
View File
@@ -14,13 +14,41 @@ class KickRoomPlayerRequest extends FormRequest
public function authorize(): bool
{
$room = $this->route('room');
$player = $this->route('player');
$targetPlayer = $this->route('player');
return $room instanceof Room
&& $player instanceof Player
&& $this->user()?->id === $room->owner_id
&& $player->room_id === $room->id
&& $player->user_id !== $room->owner_id;
if (
! $room instanceof Room
|| ! $targetPlayer instanceof Player
|| $targetPlayer->room_id !== $room->id
|| $targetPlayer->is_moderator
|| ($room->owner_id !== null && $targetPlayer->user_id === $room->owner_id)
) {
return false;
}
$user = $this->user();
if ($user !== null && $user->id === $room->owner_id) {
return true;
}
$currentPlayer = $this->currentPlayer($room);
return ! $room->isClosed()
&& $currentPlayer !== null
&& $currentPlayer->id !== $targetPlayer->id
&& ($currentPlayer->is_moderator || $room->allow_participants_to_manage_rounds);
}
public function currentPlayer(Room $room): ?Player
{
$playerId = $this->session()->get("room_players.{$room->id}");
if (! is_numeric($playerId)) {
return null;
}
return $room->activePlayers()->find((int) $playerId);
}
/**
@@ -180,20 +180,41 @@ class RoomParticipationService
return $player;
}
public function kick(Room $room, Player $player, User $user): void
{
$stateVersion = DB::transaction(function () use ($room, $player, $user): ?int {
public function kick(
Room $room,
Player $player,
?User $user,
?Player $currentPlayer,
): void {
$stateVersion = DB::transaction(function () use ($room, $player, $user, $currentPlayer): ?int {
$lockedRoom = Room::query()
->lockForUpdate()
->findOrFail($room->id);
abort_unless($lockedRoom->owner_id === $user->id, 403);
$lockedCurrentPlayer = $currentPlayer === null
? null
: $lockedRoom->activePlayers()
->lockForUpdate()
->find($currentPlayer->id);
$isOwner = $user !== null && $lockedRoom->owner_id === $user->id;
$participantCanManage = ! $lockedRoom->isClosed()
&& $lockedCurrentPlayer !== null
&& ($lockedCurrentPlayer->is_moderator
|| $lockedRoom->allow_participants_to_manage_rounds);
abort_unless($isOwner || $participantCanManage, 403);
$lockedPlayer = $lockedRoom->players()
->lockForUpdate()
->findOrFail($player->id);
abort_if($lockedPlayer->user_id === $lockedRoom->owner_id, 403);
abort_if(
$lockedPlayer->is_moderator
|| ($lockedRoom->owner_id !== null
&& $lockedPlayer->user_id === $lockedRoom->owner_id)
|| $lockedCurrentPlayer?->id === $lockedPlayer->id,
403,
);
if ($lockedPlayer->inactive_at !== null) {
return null;