Files
ladill-meet/app/Models/Room.php
T
isaaccladandCursor 34d0a9c504
Deploy Ladill Meet / deploy (push) Successful in 1m26s
Route webinar and conference registration through Ladill Events.
Add Events linking UI and service client, remove Meet-native registration and invitation flows for these room types, and redirect attendees to Events registration when joining.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-02 07:38:50 +00:00

215 lines
5.4 KiB
PHP

<?php
namespace App\Models;
use App\Models\Concerns\BelongsToOwner;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Support\Str;
class Room extends Model
{
use BelongsToOwner, SoftDeletes;
protected $table = 'meet_rooms';
protected $fillable = [
'uuid', 'owner_ref', 'organization_id', 'branch_id', 'host_user_ref',
'title', 'description', 'type', 'status', 'slug', 'scheduled_at',
'duration_minutes', 'timezone', 'passcode', 'settings', 'source', 'calendar_event_id',
'recurring_series_id', 'recurrence_rule', 'recurrence_interval', 'recurrence_until',
];
protected function casts(): array
{
return [
'scheduled_at' => 'datetime',
'recurrence_until' => 'date',
'settings' => 'array',
'source' => 'array',
];
}
protected static function booted(): void
{
static::creating(function (Room $room) {
if (empty($room->uuid)) {
$room->uuid = (string) Str::uuid();
}
});
}
public function getRouteKeyName(): string
{
return 'uuid';
}
public function organization(): BelongsTo
{
return $this->belongsTo(Organization::class, 'organization_id');
}
public function branch(): BelongsTo
{
return $this->belongsTo(Branch::class, 'branch_id');
}
public function sessions(): HasMany
{
return $this->hasMany(Session::class, 'room_id');
}
public function invitations(): HasMany
{
return $this->hasMany(Invitation::class, 'room_id');
}
public function webinarRegistrations(): HasMany
{
return $this->hasMany(WebinarRegistration::class, 'room_id');
}
public function sessionFiles(): HasMany
{
return $this->hasMany(SessionFile::class, 'room_id');
}
/**
* @param \Illuminate\Database\Eloquent\Builder<self> $query
*/
public function scopeForSource($query, string $app, string $entityId, ?string $ownerRef = null): void
{
$query->where('source->app', $app)
->where('source->entity_id', $entityId);
if ($ownerRef !== null) {
$query->where('owner_ref', $ownerRef);
}
}
public function isWebinar(): bool
{
return $this->type === 'webinar';
}
public function isConference(): bool
{
return $this->type === 'town_hall';
}
public function isSpace(): bool
{
return $this->type === 'space';
}
public function isAudioOnly(): bool
{
return $this->isSpace() || (bool) $this->setting('audio_only', false);
}
public function canRestart(): bool
{
if ($this->status === 'cancelled' || $this->activeSession()) {
return false;
}
return $this->status === 'ended'
|| $this->type === 'personal'
|| $this->status === 'scheduled';
}
public function restartLabel(): string
{
$restarting = $this->status === 'ended' || $this->sessions()->exists();
if ($this->isWebinar()) {
return $restarting ? 'Restart webinar' : 'Start webinar';
}
if ($this->isConference()) {
return $restarting ? 'Restart conference' : 'Start conference';
}
if ($this->isSpace()) {
return $restarting ? 'Reopen room' : 'Open room';
}
return $restarting ? 'Restart meeting' : 'Start meeting';
}
public function isTownHall(): bool
{
return $this->type === 'town_hall';
}
public function isRecurring(): bool
{
return filled($this->recurrence_rule);
}
public function activeSession(): ?Session
{
return $this->sessions()->where('status', 'live')->latest()->first();
}
public function setting(string $key, mixed $default = null): mixed
{
return data_get($this->settings, $key, data_get(config('meet.default_settings'), $key, $default));
}
public function safeTimezone(): string
{
$timezone = (string) ($this->timezone ?: 'UTC');
try {
new \DateTimeZone($timezone);
return $timezone;
} catch (\Throwable) {
return 'UTC';
}
}
public function isLive(): bool
{
return $this->status === 'live';
}
public function requiresWaitingRoom(?User $user, string $role): bool
{
if (! $this->setting('waiting_room', true)) {
return false;
}
if ($role === 'host' || ($user && $user->ownerRef() === $this->host_user_ref)) {
return false;
}
return true;
}
public function joinUrl(): string
{
return rtrim((string) config('app.meet_url', 'https://meet.ladill.com'), '/').'/r/'.$this->uuid;
}
public function isEventsLinked(): bool
{
return \App\Support\EventsSourceLink::isLinked($this);
}
public function hasEventsRegistrationInvite(?string $email): bool
{
if ($email === null || trim($email) === '') {
return false;
}
return $this->invitations()
->where('email', $email)
->whereIn('status', ['pending', 'accepted'])
->exists();
}
}