Deploy Ladill Meet / deploy (push) Successful in 42s
Templates duplicated create-form settings without edit/delete flows; drop the feature and table. Conference and webinar pages render synced programme snapshots and link back to Ladill Events. Co-authored-by: Cursor <cursoragent@cursor.com>
93 lines
3.1 KiB
PHP
93 lines
3.1 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Meet;
|
|
|
|
use App\Models\Organization;
|
|
use App\Models\Room;
|
|
use App\Models\User;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Support\Str;
|
|
|
|
class RecurringMeetingService
|
|
{
|
|
public function __construct(
|
|
protected RoomService $rooms,
|
|
) {}
|
|
|
|
/**
|
|
* @param array<string, mixed> $data
|
|
*/
|
|
public function createSeries(User $user, Organization $organization, array $data): Room
|
|
{
|
|
$seriesId = (string) Str::uuid();
|
|
|
|
$room = $this->rooms->createScheduled($user, $organization, array_merge($data, [
|
|
'recurring_series_id' => $seriesId,
|
|
'recurrence_rule' => $data['recurrence_rule'],
|
|
'recurrence_interval' => $data['recurrence_interval'] ?? 1,
|
|
'recurrence_until' => $data['recurrence_until'] ?? null,
|
|
]));
|
|
|
|
$this->spawnNextOccurrences($room, 5);
|
|
|
|
return $room;
|
|
}
|
|
|
|
public function spawnNextOccurrences(Room $parent, int $count = 1): void
|
|
{
|
|
if (! $parent->isRecurring()) {
|
|
return;
|
|
}
|
|
|
|
$last = Room::where('recurring_series_id', $parent->recurring_series_id)
|
|
->orderByDesc('scheduled_at')
|
|
->first();
|
|
|
|
$cursor = Carbon::parse($last?->scheduled_at ?? $parent->scheduled_at);
|
|
|
|
for ($i = 0; $i < $count; $i++) {
|
|
$cursor = $this->nextOccurrence($cursor, $parent->recurrence_rule, (int) $parent->recurrence_interval);
|
|
|
|
if ($parent->recurrence_until && $cursor->toDateString() > $parent->recurrence_until) {
|
|
break;
|
|
}
|
|
|
|
if (Room::where('recurring_series_id', $parent->recurring_series_id)
|
|
->whereDate('scheduled_at', $cursor->toDateString())
|
|
->exists()) {
|
|
continue;
|
|
}
|
|
|
|
Room::create([
|
|
'owner_ref' => $parent->owner_ref,
|
|
'organization_id' => $parent->organization_id,
|
|
'branch_id' => $parent->branch_id,
|
|
'host_user_ref' => $parent->host_user_ref,
|
|
'title' => $parent->title,
|
|
'description' => $parent->description,
|
|
'type' => 'scheduled',
|
|
'status' => 'scheduled',
|
|
'scheduled_at' => $cursor,
|
|
'duration_minutes' => $parent->duration_minutes,
|
|
'timezone' => $parent->timezone,
|
|
'passcode' => $parent->passcode,
|
|
'settings' => $parent->settings,
|
|
'recurring_series_id' => $parent->recurring_series_id,
|
|
'recurrence_rule' => $parent->recurrence_rule,
|
|
'recurrence_interval' => $parent->recurrence_interval,
|
|
'recurrence_until' => $parent->recurrence_until,
|
|
]);
|
|
}
|
|
}
|
|
|
|
protected function nextOccurrence(Carbon $from, string $rule, int $interval): Carbon
|
|
{
|
|
return match ($rule) {
|
|
'daily' => $from->copy()->addDays($interval),
|
|
'weekly' => $from->copy()->addWeeks($interval),
|
|
'monthly' => $from->copy()->addMonths($interval),
|
|
default => $from->copy()->addWeeks($interval),
|
|
};
|
|
}
|
|
}
|