Files
ladill-meet/app/Services/Meet/ChannelService.php
T
isaaccladandCursor 965fb992e9
Deploy Ladill Meet / deploy (push) Failing after 7s
Initial Ladill Meet release.
Phases 0–18: core meetings, webinar, breakouts, team chat, live streaming, town hall, billing, and Ladill Mail calendar wiring.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-30 23:35:29 +00:00

101 lines
3.0 KiB
PHP

<?php
namespace App\Services\Meet;
use App\Models\Channel;
use App\Models\ChannelMember;
use App\Models\ChannelMessage;
use App\Models\Organization;
use App\Models\User;
use Illuminate\Support\Str;
class ChannelService
{
/**
* @param array<string, mixed> $data
*/
public function create(User $user, Organization $organization, array $data): Channel
{
$ownerRef = $user->ownerRef();
$slug = Str::slug($data['name']);
$channel = Channel::create([
'owner_ref' => $ownerRef,
'organization_id' => $organization->id,
'branch_id' => $data['branch_id'] ?? null,
'name' => $data['name'],
'slug' => $this->uniqueSlug($organization->id, $slug),
'visibility' => $data['visibility'] ?? 'public',
'description' => $data['description'] ?? null,
]);
$this->addMember($channel, $ownerRef, 'admin');
AuditLogger::record($ownerRef, 'channel.created', $organization->id, $ownerRef, Channel::class, $channel->id);
return $channel;
}
public function addMember(Channel $channel, string $userRef, string $role = 'member'): ChannelMember
{
return ChannelMember::firstOrCreate(
['channel_id' => $channel->id, 'user_ref' => $userRef],
['role' => $role],
);
}
public function canAccess(Channel $channel, string $userRef): bool
{
if ($channel->visibility === 'public') {
return true;
}
return $channel->members()->where('user_ref', $userRef)->exists();
}
public function canPost(Channel $channel, string $userRef): bool
{
if ($channel->visibility === 'public') {
return true;
}
return $channel->members()->where('user_ref', $userRef)->exists();
}
public function postMessage(Channel $channel, User $user, string $body, ?int $parentId = null): ChannelMessage
{
abort_unless($this->canPost($channel, $user->ownerRef()), 403);
return ChannelMessage::create([
'owner_ref' => $channel->owner_ref,
'channel_id' => $channel->id,
'sender_ref' => $user->ownerRef(),
'sender_name' => $user->name,
'body' => trim($body),
'parent_id' => $parentId,
]);
}
public function react(ChannelMessage $message, string $emoji, string $userRef): ChannelMessage
{
$metadata = $message->metadata ?? [];
$reactions = $metadata['reactions'] ?? [];
$reactions[$emoji] = array_values(array_unique(array_merge($reactions[$emoji] ?? [], [$userRef])));
$metadata['reactions'] = $reactions;
$message->update(['metadata' => $metadata]);
return $message->fresh();
}
protected function uniqueSlug(int $organizationId, string $base): string
{
$slug = $base;
$i = 1;
while (Channel::where('organization_id', $organizationId)->where('slug', $slug)->exists()) {
$slug = $base.'-'.$i++;
}
return $slug;
}
}