236d37976c
DbCompat (app/Support/DbCompat.php) : - like() → ilike (pgsql) ou like (mysql) - jsonRegexRaw() → data::text ~* ? (pgsql) ou CAST(data AS CHAR) REGEXP ? (mysql) - ftsRaw() → to_tsvector/plainto_tsquery (pgsql) ou null/fallback LIKE (mysql) - generatedJsonCol() → syntaxe colonne générée JSON selon le SGBD - generatedJsonNestedCol() → idem pour champs imbriqués Migrations : - create_releves_table : JSON/JSONB selon SGBD, colonnes générées adaptées, index GIN uniquement pour PostgreSQL Controllers : - LieuController (search + index) : ilike → DbCompat::like() - Admin\UserController (index) : ilike → DbCompat::like() - RechercheController : FTS + regex → DbCompat, fallback LIKE MySQL - ExportController : regex → DbCompat::jsonRegexRaw() UpdateService : - backupDatabase() : pg_dump (pgsql) ou mysqldump (mysql) - restoreBackup() : psql (pgsql) ou mysql (mysql) Docker : - docker-compose.yml : suppression Redis (plus requis) - docker-compose.mysql.yml : nouveau fichier pour dev MySQL - docker-compose.prod.yml : suppression Redis, DB_IMAGE configurable, CACHE_STORE/SESSION_DRIVER/QUEUE_CONNECTION → database par défaut .env.example : - DB_PORT commenté avec les deux valeurs (5432/3306) - CACHE_STORE et QUEUE_CONNECTION commentés (database par défaut) - Redis marqué optionnel Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
86 lines
2.7 KiB
PHP
86 lines
2.7 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Admin;
|
|
|
|
use App\Enums\UserRole;
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\User;
|
|
use App\Support\DbCompat;
|
|
use Illuminate\Http\RedirectResponse;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Validation\Rules\Enum;
|
|
use Illuminate\View\View;
|
|
|
|
class UserController extends Controller
|
|
{
|
|
public function index(Request $request): View
|
|
{
|
|
$query = User::withCount('sourcesAssignees')->with('sections')->orderBy('name');
|
|
|
|
if ($request->filled('role')) {
|
|
$query->where('role', $request->input('role'));
|
|
}
|
|
|
|
if ($request->filled('q')) {
|
|
$q = trim($request->get('q'));
|
|
$like = DbCompat::like();
|
|
$query->where(fn ($wq) => $wq
|
|
->where('name', $like, "%{$q}%")
|
|
->orWhere('email', $like, "%{$q}%")
|
|
);
|
|
}
|
|
|
|
$users = $query->paginate(25)->withQueryString();
|
|
|
|
return view('admin.utilisateurs.index', compact('users'));
|
|
}
|
|
|
|
public function edit(User $user): View
|
|
{
|
|
$user->load('sections', 'sourcesAssignees');
|
|
|
|
return view('admin.utilisateurs.edit', compact('user'));
|
|
}
|
|
|
|
public function update(Request $request, User $user): RedirectResponse
|
|
{
|
|
$data = $request->validate([
|
|
'role' => ['required', new Enum(UserRole::class)],
|
|
]);
|
|
|
|
if ($user->id === auth()->id()) {
|
|
return back()->with('error', 'Vous ne pouvez pas modifier votre propre rôle.');
|
|
}
|
|
|
|
if ($user->role === UserRole::Admin && $data['role'] !== UserRole::Admin->value) {
|
|
$adminCount = User::where('role', UserRole::Admin->value)->count();
|
|
if ($adminCount <= 1) {
|
|
return back()->with('error', 'Impossible de retirer le rôle admin au dernier administrateur.');
|
|
}
|
|
}
|
|
|
|
$user->update(['role' => $data['role']]);
|
|
|
|
return back()->with('success', 'Rôle mis à jour.');
|
|
}
|
|
|
|
public function toggleActive(User $user): RedirectResponse
|
|
{
|
|
if ($user->id === auth()->id()) {
|
|
return back()->with('error', 'Vous ne pouvez pas désactiver votre propre compte.');
|
|
}
|
|
|
|
if ($user->is_active && $user->role === UserRole::Admin) {
|
|
$activeAdmins = User::where('role', UserRole::Admin->value)->where('is_active', true)->count();
|
|
if ($activeAdmins <= 1) {
|
|
return back()->with('error', 'Impossible de désactiver le dernier administrateur actif.');
|
|
}
|
|
}
|
|
|
|
$user->update(['is_active' => ! $user->is_active]);
|
|
|
|
$label = $user->is_active ? 'activé' : 'désactivé';
|
|
return back()->with('success', "Compte {$label}.");
|
|
}
|
|
}
|