authorizeAbility($request, 'meetings.manage'); $this->authorizeOwner($request, $room); if ($room->isWebinar() || $room->isConference()) { $adminUrl = EventsSourceLink::eventCommsUrl($room) ?? EventsSourceLink::eventAdminUrl($room); if ($adminUrl) { return redirect()->away($adminUrl); } $showRoute = $room->isWebinar() ? 'meet.webinars.show' : 'meet.conferences.show'; return redirect() ->route($showRoute, $room) ->withErrors(['invitations' => 'Link this session to Ladill Events to send bulk invitations.']); } $room->load(['invitations' => fn ($q) => $q->orderByDesc('created_at')]); $groups = ContactGroup::owned($this->ownerRef($request)) ->where('organization_id', $room->organization_id) ->withCount('members') ->orderBy('name') ->get(); return view('meet.invitations.index', compact('room', 'groups')); } public function store(Request $request, Room $room): RedirectResponse { $this->authorizeAbility($request, 'meetings.manage'); $this->authorizeOwner($request, $room); $validated = $request->validate([ 'emails' => ['nullable', 'string'], 'member_refs' => ['nullable', 'array'], 'member_refs.*' => ['string'], 'contact_group_id' => ['nullable', 'integer', 'exists:meet_contact_groups,id'], ]); $invites = []; if ($emails = trim((string) ($validated['emails'] ?? ''))) { foreach (preg_split('/[\s,;]+/', $emails) as $email) { if ($email = trim($email)) { $invites[] = ['email' => $email]; } } } foreach ($validated['member_refs'] ?? [] as $userRef) { $user = \App\Models\User::where('public_id', $userRef)->first(); if ($user?->email) { $invites[] = ['email' => $user->email, 'name' => $user->name, 'user_ref' => $userRef]; } } if (! empty($validated['contact_group_id'])) { $group = ContactGroup::owned($this->ownerRef($request))->findOrFail($validated['contact_group_id']); $invites = array_merge($invites, $this->contacts->fromGroup($group)->all()); } $this->invitations->inviteToRoom($room, $invites, $request->user()); return back()->with('success', count($invites).' invitation(s) sent.'); } public function bulkCsv(Request $request, Room $room): RedirectResponse { $this->authorizeAbility($request, 'meetings.manage'); $this->authorizeOwner($request, $room); $request->validate(['csv' => ['required', 'file', 'mimes:csv,txt', 'max:2048']]); $count = $this->invitations->bulkFromCsv($room, $request->file('csv')->getContent(), $request->user()); return back()->with('success', "{$count} invitation(s) imported."); } public function resend(Request $request, Invitation $invitation): RedirectResponse { $this->authorizeAbility($request, 'meetings.manage'); $this->authorizeOwner($request, $invitation); $this->invitations->resend($invitation, $request->user()); return back()->with('success', 'Invitation resent.'); } public function destroy(Request $request, Invitation $invitation): RedirectResponse { $this->authorizeAbility($request, 'meetings.manage'); $this->authorizeOwner($request, $invitation); $room = $invitation->room; $invitation->delete(); return redirect()->route('meet.invitations.index', $room)->with('success', 'Invitation removed.'); } public function rsvp(Request $request, Invitation $invitation): View|RedirectResponse { abort_unless(hash_equals((string) $invitation->rsvp_token, (string) $request->query('token')), 403); if ($request->isMethod('post')) { $validated = $request->validate(['status' => ['required', 'in:accepted,declined']]); $this->invitations->respond($invitation, $validated['status'], $invitation->rsvp_token); return view('meet.invitations.rsvp-done', [ 'invitation' => $invitation->fresh(), 'room' => $invitation->room, ]); } return view('meet.invitations.rsvp', [ 'invitation' => $invitation, 'room' => $invitation->room, ]); } public function searchContacts(Request $request): JsonResponse { $this->authorizeAbility($request, 'meetings.create'); $organization = $this->organization($request); $query = (string) $request->query('q', ''); $results = $this->contacts->search($organization->id, $this->ownerRef($request), $query); return response()->json(['contacts' => $results]); } }