Files
scrum-poker-internal/app/Models/Room.php
T
2026-08-20 23:00:47 +02:00

114 lines
3.0 KiB
PHP

<?php
namespace App\Models;
use Carbon\CarbonImmutable;
use Illuminate\Database\Eloquent\Concerns\HasUuids;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
/**
* @property string $id
* @property int|null $owner_id
* @property string|null $title
* @property array{name: string, cards: array<int, array{key: string, label: string}>, id?: int} $deck_config
* @property string $join_code
* @property int $current_round
* @property CarbonImmutable|null $revealed_at
* @property int $state_version
* @property CarbonImmutable|null $last_activity_at
* @property CarbonImmutable|null $closed_at
* @property CarbonImmutable|null $deleted_at
* @property int $players_count
*/
class Room extends Model
{
use HasUuids, SoftDeletes;
protected $fillable = [
'owner_id',
'title',
'current_round',
'deck_config',
'revealed_at',
'state_version',
'last_activity_at',
'closed_at',
];
protected function casts(): array
{
return [
'current_round' => 'integer',
'state_version' => 'integer',
'revealed_at' => 'immutable_datetime',
'last_activity_at' => 'immutable_datetime',
'closed_at' => 'immutable_datetime',
'deck_config' => 'array',
];
}
protected static function booted(): void
{
static::creating(function (Room $room) {
$room->join_code ??= static::generateJoinCode();
$room->last_activity_at ??= now();
});
}
protected static function generateJoinCode(): string
{
$alphabet = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
do {
$code = '';
for ($i = 0; $i < 6; $i++) {
$code .= $alphabet[random_int(0, strlen($alphabet) - 1)];
}
} while (static::withTrashed()->where('join_code', $code)->exists());
return $code;
}
/** @return HasMany<Player, $this> */
public function players(): HasMany
{
return $this->hasMany(Player::class);
}
/** @return HasMany<Player, $this> */
public function activePlayers(): HasMany
{
return $this->hasMany(Player::class)->whereNull('inactive_at');
}
/** @return BelongsTo<User, $this> */
public function owner(): BelongsTo
{
return $this->belongsTo(User::class, 'owner_id');
}
/** @return HasMany<Vote, $this> */
public function votes(): HasMany
{
return $this->hasMany(Vote::class);
}
public function isClosed(): bool
{
return $this->closed_at !== null;
}
/** @return BelongsToMany<User, $this> */
public function favoritedBy(): BelongsToMany
{
return $this->belongsToMany(User::class, 'user_room_favorites')->withTimestamps();
}
}