validate([ 'name' => ['required', 'string', 'max:255', Rule::unique('contact_groups', 'name')->whereNull('deleted_at')], 'description' => ['nullable', 'string'], ]); ContactGroup::query()->create([ 'source' => 'local', 'name' => $validated['name'], 'slug' => $this->uniqueSlug($validated['name']), 'description' => $validated['description'] ?? null, 'is_favorite' => $request->boolean('is_favorite'), ]); return redirect() ->route('contacts.index') ->with('status', 'Groupe cree.'); } public function edit(ContactGroup $contactGroup): View { $this->ensureLocalGroup($contactGroup); return view('contact-groups.edit', [ 'group' => $contactGroup->load('contacts')->loadCount('contacts'), 'contacts' => Contact::query() ->with('phoneNumbers') ->orderBy('last_name') ->orderBy('first_name') ->get(), 'selectedContactIds' => $contactGroup->contacts->pluck('id')->all(), ]); } public function update(Request $request, ContactGroup $contactGroup): RedirectResponse { $this->ensureLocalGroup($contactGroup); $validated = $request->validate([ 'name' => [ 'required', 'string', 'max:255', Rule::unique('contact_groups', 'name')->ignore($contactGroup)->whereNull('deleted_at'), ], 'description' => ['nullable', 'string'], 'contact_ids' => ['array'], 'contact_ids.*' => [Rule::exists('contacts', 'id')->whereNull('deleted_at')], ]); $contactGroup->update([ 'name' => $validated['name'], 'slug' => $this->uniqueSlug($validated['name'], $contactGroup), 'description' => $validated['description'] ?? null, 'is_favorite' => $request->boolean('is_favorite'), ]); if ($request->has('members_submitted')) { $contactGroup->contacts()->sync($validated['contact_ids'] ?? []); } return redirect() ->route('contacts.index', ['group' => $contactGroup->id]) ->with('status', 'Groupe modifie.'); } public function destroy(ContactGroup $contactGroup): RedirectResponse { $this->ensureLocalGroup($contactGroup); $contactGroup->contacts()->detach(); $contactGroup->delete(); return redirect() ->route('contacts.index') ->with('status', 'Groupe supprime.'); } private function uniqueSlug(string $name, ?ContactGroup $ignore = null): string { $baseSlug = Str::slug($name); $baseSlug = $baseSlug === '' ? 'groupe' : $baseSlug; $slug = $baseSlug; $index = 2; while (ContactGroup::query() ->where('slug', $slug) ->when($ignore, fn ($query) => $query->whereKeyNot($ignore->id)) ->exists() ) { $slug = $baseSlug.'-'.$index; $index++; } return $slug; } private function ensureLocalGroup(ContactGroup $contactGroup): void { abort_if($contactGroup->source !== 'local', 403, 'Les groupes importes ne sont pas modifiables localement.'); } }