library->all()->map(fn (array $img) => $img + ['used_in' => $this->usages($img['name'])]); return view('admin.images.index', ['images' => $images, 'maxKb' => config('signature.image_max_kb')]); } public function store(Request $request): RedirectResponse { $request->validate([ 'image' => ['required', ...ImageLibrary::uploadRules()], 'name' => ['nullable', 'string', 'max:80'], ], ImageLibrary::uploadMessages('image')); $name = $this->library->store($request->file('image'), $request->input('name')); AuditLog::record('admin', $this->actor(), 'image.upload', null, ['file' => $name], $this->tenantId()); return back()->with('status', "Image « {$name} » en ligne. Dans un template : {{site_url}}/img/{$name}"); } public function destroy(string $name): RedirectResponse { $name = basename($name); abort_unless($this->library->exists($name), 404); if ($used = $this->usages($name)) { return back()->withErrors(['image' => "« {$name} » est utilisée par : ".implode(', ', $used).'. Retirez-la d\'abord.']); } $this->library->delete($name); AuditLog::record('admin', $this->actor(), 'image.delete', null, ['file' => $name], $this->tenantId()); return back()->with('status', "Image « {$name} » supprimée."); } /** Templates (publiés ou brouillons) et campagnes qui référencent l'image. */ private function usages(string $name): array { $like = '%/img/'.$name.'%'; $templates = Template::where('tenant_id', $this->tenantId()) ->where(fn ($q) => $q->where('html_full', 'like', $like)->orWhere('html_short', 'like', $like) ->orWhere('draft_html_full', 'like', $like)->orWhere('draft_html_short', 'like', $like)) ->pluck('name')->map(fn ($n) => "template {$n}"); $campaigns = Campaign::where('tenant_id', $this->tenantId())->where('image_path', $name) ->pluck('name')->map(fn ($n) => "campagne {$n}"); // La bibliothèque est commune à toutes les collectivités : une image utilisée ailleurs reste protégée. $elsewhere = Template::where('tenant_id', '!=', $this->tenantId()) ->where(fn ($q) => $q->where('html_full', 'like', $like)->orWhere('html_short', 'like', $like) ->orWhere('draft_html_full', 'like', $like)->orWhere('draft_html_short', 'like', $like))->exists() || Campaign::where('tenant_id', '!=', $this->tenantId())->where('image_path', $name)->exists(); return $templates->merge($campaigns)->when($elsewhere, fn ($c) => $c->push('une autre collectivité'))->all(); } }