Publication initiale de RelaisSMS : documentation et sources nettoyees
This commit is contained in:
@@ -0,0 +1,186 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Contact;
|
||||
use App\Models\ContactGroup;
|
||||
use App\Services\Recipients\RecipientResolutionResult;
|
||||
use App\Services\Recipients\RecipientResolver;
|
||||
use App\Services\Sms\SmsMessageComposer;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\Rule;
|
||||
|
||||
class RecipientSelectionController extends Controller
|
||||
{
|
||||
public function index(Request $request, SmsMessageComposer $messageComposer): View
|
||||
{
|
||||
return $this->view($request, messageComposer: $messageComposer);
|
||||
}
|
||||
|
||||
public function search(Request $request): JsonResponse
|
||||
{
|
||||
$search = trim((string) $request->query('q', ''));
|
||||
$like = '%'.str_replace(['%', '_'], ['\%', '\_'], $search).'%';
|
||||
|
||||
$contacts = Contact::query()
|
||||
->with('phoneNumbers')
|
||||
->search($search)
|
||||
->orderByDesc('is_favorite')
|
||||
->orderBy('last_name')
|
||||
->orderBy('first_name')
|
||||
->limit(10)
|
||||
->get()
|
||||
->map(function (Contact $contact): array {
|
||||
$primaryPhone = $contact->phoneNumbers->firstWhere('is_primary', true)
|
||||
?? $contact->phoneNumbers->first();
|
||||
|
||||
return [
|
||||
'type' => 'contact',
|
||||
'id' => $contact->id,
|
||||
'label' => $contact->displayName(),
|
||||
'meta' => $primaryPhone?->normalized_number
|
||||
?: $primaryPhone?->raw_number
|
||||
?: $contact->email
|
||||
?: ucfirst($contact->source),
|
||||
'source' => $contact->source,
|
||||
'is_favorite' => $contact->is_favorite,
|
||||
];
|
||||
});
|
||||
|
||||
$groups = ContactGroup::query()
|
||||
->withCount('contacts')
|
||||
->when($search !== '', function ($query) use ($like): void {
|
||||
$query->where(function ($query) use ($like): void {
|
||||
$query
|
||||
->where('name', 'like', $like)
|
||||
->orWhere('description', 'like', $like);
|
||||
});
|
||||
})
|
||||
->orderByDesc('is_favorite')
|
||||
->orderBy('name')
|
||||
->limit(10)
|
||||
->get()
|
||||
->map(fn (ContactGroup $group): array => [
|
||||
'type' => 'group',
|
||||
'id' => $group->id,
|
||||
'label' => $group->name,
|
||||
'meta' => $group->contacts_count.' contact(s)',
|
||||
'source' => $group->source,
|
||||
'is_favorite' => $group->is_favorite,
|
||||
]);
|
||||
|
||||
return response()->json([
|
||||
'results' => $groups->concat($contacts)->values(),
|
||||
]);
|
||||
}
|
||||
|
||||
public function preview(Request $request, RecipientResolver $resolver, SmsMessageComposer $messageComposer): View|RedirectResponse
|
||||
{
|
||||
$validated = $request->validate([
|
||||
'q' => ['nullable', 'string', 'max:255'],
|
||||
'message' => ['nullable', 'string', 'max:612'],
|
||||
'include_sms_header' => ['nullable', 'boolean'],
|
||||
'include_sms_footer' => ['nullable', 'boolean'],
|
||||
'contact_ids' => ['array'],
|
||||
'contact_ids.*' => ['integer', Rule::exists('contacts', 'id')->whereNull('deleted_at')],
|
||||
'group_ids' => ['array'],
|
||||
'group_ids.*' => ['integer', Rule::exists('contact_groups', 'id')->whereNull('deleted_at')],
|
||||
]);
|
||||
|
||||
$contactIds = $validated['contact_ids'] ?? [];
|
||||
$groupIds = $validated['group_ids'] ?? [];
|
||||
|
||||
if ($contactIds === [] && $groupIds === []) {
|
||||
return redirect()
|
||||
->route('recipients.index', ['q' => $validated['q'] ?? null])
|
||||
->withErrors(['selection' => 'Selectionnez au moins un contact ou un groupe.'])
|
||||
->withInput();
|
||||
}
|
||||
|
||||
return $this->view(
|
||||
$request,
|
||||
$resolver->resolve($contactIds, $groupIds),
|
||||
$contactIds,
|
||||
$groupIds,
|
||||
$messageComposer,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<int, int|string> $selectedContactIds
|
||||
* @param array<int, int|string> $selectedGroupIds
|
||||
*/
|
||||
private function view(
|
||||
Request $request,
|
||||
?RecipientResolutionResult $resolution = null,
|
||||
array $selectedContactIds = [],
|
||||
array $selectedGroupIds = [],
|
||||
?SmsMessageComposer $messageComposer = null,
|
||||
): View {
|
||||
$messageComposer ??= app(SmsMessageComposer::class);
|
||||
$messageSettings = $messageComposer->settings();
|
||||
$oldHeaderChoice = $request->old('include_sms_header');
|
||||
$oldFooterChoice = $request->old('include_sms_footer');
|
||||
$hasHeaderChoice = $oldHeaderChoice !== null || $request->has('include_sms_header');
|
||||
$hasFooterChoice = $oldFooterChoice !== null || $request->has('include_sms_footer');
|
||||
$includeHeader = $hasHeaderChoice
|
||||
? filter_var($oldHeaderChoice ?? $request->input('include_sms_header'), FILTER_VALIDATE_BOOLEAN)
|
||||
: $messageSettings['header'] !== '';
|
||||
$includeFooter = $hasFooterChoice
|
||||
? filter_var($oldFooterChoice ?? $request->input('include_sms_footer'), FILTER_VALIDATE_BOOLEAN)
|
||||
: $messageSettings['footer'] !== '';
|
||||
$messageBody = (string) $request->old('message', $request->input('message', ''));
|
||||
|
||||
$search = trim((string) $request->input('q', ''));
|
||||
$like = '%'.str_replace(['%', '_'], ['\%', '\_'], $search).'%';
|
||||
|
||||
$contacts = Contact::query()
|
||||
->with(['groups', 'phoneNumbers'])
|
||||
->search($search)
|
||||
->orderByDesc('is_favorite')
|
||||
->orderBy('last_name')
|
||||
->orderBy('first_name')
|
||||
->limit(50)
|
||||
->get();
|
||||
|
||||
$groups = ContactGroup::query()
|
||||
->withCount('contacts')
|
||||
->when($search !== '', function ($query) use ($like): void {
|
||||
$query->where(function ($query) use ($like): void {
|
||||
$query
|
||||
->where('name', 'like', $like)
|
||||
->orWhere('description', 'like', $like);
|
||||
});
|
||||
})
|
||||
->orderByDesc('is_favorite')
|
||||
->orderBy('name')
|
||||
->limit(50)
|
||||
->get();
|
||||
|
||||
return view('recipients.index', [
|
||||
'contacts' => $contacts,
|
||||
'groups' => $groups,
|
||||
'search' => $search,
|
||||
'selectedContactIds' => collect($selectedContactIds)->map(fn (int|string $id): int => (int) $id)->all(),
|
||||
'selectedGroupIds' => collect($selectedGroupIds)->map(fn (int|string $id): int => (int) $id)->all(),
|
||||
'selectedContacts' => Contact::query()
|
||||
->whereKey($selectedContactIds)
|
||||
->orderBy('last_name')
|
||||
->orderBy('first_name')
|
||||
->get(),
|
||||
'selectedGroups' => ContactGroup::query()
|
||||
->whereKey($selectedGroupIds)
|
||||
->orderBy('name')
|
||||
->get(),
|
||||
'resolution' => $resolution,
|
||||
'smsHeader' => $messageSettings['header'],
|
||||
'smsFooter' => $messageSettings['footer'],
|
||||
'includeSmsHeader' => $includeHeader,
|
||||
'includeSmsFooter' => $includeFooter,
|
||||
'composedMessage' => $messageComposer->compose($messageBody, $includeHeader, $includeFooter),
|
||||
]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user