Files
ladill-meet/app/Services/Meet/RecurringMeetingService.php
T
isaaccladandCursor aed7094fed
Deploy Ladill Meet / deploy (push) Successful in 42s
Remove meeting templates and show Events programme on Meet rooms.
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>
2026-07-01 22:31:03 +00:00

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),
};
}
}