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>
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
namespace App\Services\Meet;
|
||||
|
||||
use App\Models\ContactGroup;
|
||||
use App\Models\Member;
|
||||
use App\Models\User;
|
||||
use Illuminate\Support\Collection;
|
||||
use Illuminate\Support\Facades\Http;
|
||||
|
||||
class ContactService
|
||||
{
|
||||
/**
|
||||
* @return Collection<int, array<string, mixed>>
|
||||
*/
|
||||
public function searchOrgMembers(int $organizationId, string $ownerRef, string $query = '', int $limit = 20): Collection
|
||||
{
|
||||
$members = Member::owned($ownerRef)
|
||||
->where('organization_id', $organizationId)
|
||||
->when($query !== '', function ($q) use ($query) {
|
||||
$q->whereIn('user_ref', User::query()
|
||||
->where(function ($u) use ($query) {
|
||||
$u->where('name', 'like', "%{$query}%")
|
||||
->orWhere('email', 'like', "%{$query}%");
|
||||
})
|
||||
->pluck('public_id'));
|
||||
})
|
||||
->limit($limit)
|
||||
->get();
|
||||
|
||||
return $members->map(function (Member $member) {
|
||||
$user = User::where('public_id', $member->user_ref)->first();
|
||||
|
||||
return [
|
||||
'user_ref' => $member->user_ref,
|
||||
'email' => $user?->email,
|
||||
'name' => $user?->name ?? $member->user_ref,
|
||||
'role' => $member->role,
|
||||
'source' => 'org',
|
||||
];
|
||||
})->filter(fn ($c) => filled($c['email']));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<int, array<string, mixed>>
|
||||
*/
|
||||
public function search(int $organizationId, string $ownerRef, string $query = '', int $limit = 20): Collection
|
||||
{
|
||||
$org = $this->searchOrgMembers($organizationId, $ownerRef, $query, $limit);
|
||||
|
||||
if ($org->count() >= $limit) {
|
||||
return $org;
|
||||
}
|
||||
|
||||
$platform = $this->searchPlatformContacts($query, $limit - $org->count());
|
||||
$emails = $org->pluck('email')->filter()->all();
|
||||
|
||||
return $org->merge($platform->reject(fn ($c) => in_array($c['email'], $emails, true)))->take($limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<int, array<string, mixed>>
|
||||
*/
|
||||
public function fromGroup(ContactGroup $group): Collection
|
||||
{
|
||||
return $group->members->map(fn ($m) => [
|
||||
'email' => $m->email,
|
||||
'name' => $m->display_name,
|
||||
'user_ref' => $m->user_ref,
|
||||
'source' => 'group',
|
||||
])->filter(fn ($c) => filled($c['email']));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<int, array<string, mixed>>
|
||||
*/
|
||||
protected function searchPlatformContacts(string $query, int $limit): Collection
|
||||
{
|
||||
$url = rtrim((string) config('identity.api_url'), '/');
|
||||
$key = config('identity.api_key');
|
||||
|
||||
if ($url === '' || $key === '' || $query === '') {
|
||||
return collect();
|
||||
}
|
||||
|
||||
try {
|
||||
$response = Http::withToken($key)
|
||||
->timeout(5)
|
||||
->get("{$url}/team/search", ['q' => $query, 'limit' => $limit]);
|
||||
|
||||
if (! $response->successful()) {
|
||||
return collect();
|
||||
}
|
||||
|
||||
return collect($response->json('contacts', []))->map(fn ($c) => [
|
||||
'user_ref' => $c['public_id'] ?? null,
|
||||
'email' => $c['email'] ?? null,
|
||||
'name' => $c['name'] ?? null,
|
||||
'source' => 'platform',
|
||||
])->filter(fn ($c) => filled($c['email']));
|
||||
} catch (\Throwable) {
|
||||
return collect();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user