feat: try fix meilisearch

This commit is contained in:
Leon 2026-01-30 12:08:17 +01:00
parent c241e67c90
commit 30f253b2d6
1 changed files with 27 additions and 36 deletions

View File

@ -15,22 +15,16 @@ class HuntsController extends Controller
{
try {
$searchTerm = $this->resolveSearchTerm($request);
// Construire les filtres Meilisearch
$filters = $this->buildMeilisearchFilters($request);
// Construire la recherche
$search = Hunts::search($searchTerm ?? '')
->query(fn ($query) => $query->with('participants:id,avatar_uri'));
// N'ajouter le filter que s'il n'est pas vide
// ✅ IMPORTANT: nenvoie PAS filter sil est vide
if ($filters !== '') {
$search->options([
'filter' => $filters,
]);
$search->options(['filter' => $filters]);
}
// (utile en prod pour vérifier ce qui est réellement envoyé)
Log::info('HUNTS_SEARCH', [
'q' => $searchTerm ?? '',
'filters' => $filters,
@ -38,9 +32,7 @@ class HuntsController extends Controller
'index' => (new Hunts)->searchableAs(),
]);
$hunts = $search->paginate(10);
return response()->json($hunts);
return response()->json($search->paginate(10));
} catch (\Throwable $e) {
Log::error('Error fetching hunts: '.$e->getMessage());
@ -63,13 +55,16 @@ class HuntsController extends Controller
FILTER_NULL_ON_FAILURE
);
$userId = auth('sanctum')->id();
$userId = auth('sanctum')->id(); // chez toi => UUID string
if ($userId) {
$escapedUserId = $this->escapeMeiliString((string) $userId);
if ($participating === true) {
$filters[] = "participant_ids = {$userId}";
// ✅ UUID => string
$filters[] = "participant_ids = \"{$escapedUserId}\"";
} elseif ($participating === false) {
$filters[] = "participant_ids != {$userId}";
$filters[] = "participant_ids != \"{$escapedUserId}\"";
}
} elseif ($participating === true) {
$filters[] = "id < 0";
@ -78,7 +73,7 @@ class HuntsController extends Controller
// active
if ($request->has('active')) {
$now = Carbon::now('UTC')->timestamp; // ✅ UTC
$now = Carbon::now('UTC')->timestamp;
$active = filter_var($request->query('active'), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
if ($active === true) {
@ -93,8 +88,7 @@ class HuntsController extends Controller
if ($request->filled('city')) {
$city = $request->query('city');
if (is_string($city)) {
// ✅ échapper correctement les quotes
$city = str_replace('"', '\"', $city);
$city = $this->escapeMeiliString($city);
$filters[] = "city = \"{$city}\"";
}
}
@ -114,17 +108,20 @@ class HuntsController extends Controller
));
if (!empty($validDifficulties)) {
$difficultyFilters = array_map(fn ($d) => "difficulty = \"{$d}\"", $validDifficulties);
$difficultyFilters = array_map(
fn ($d) => 'difficulty = "'.$this->escapeMeiliString($d).'"',
$validDifficulties
);
$filters[] = '(' . implode(' OR ', $difficultyFilters) . ')';
}
}
}
// ✅ Dates (UTC + end-of-day si nécessaire)
// dates (UTC)
$startFrom = $this->parseDateFilterUtc($request->query('start_from'));
$startTo = $this->parseDateFilterUtc($request->query('start_to'), true);
$startTo = $this->parseDateFilterUtc($request->query('start_to'));
$endFrom = $this->parseDateFilterUtc($request->query('end_from'));
$endTo = $this->parseDateFilterUtc($request->query('end_to'), true);
$endTo = $this->parseDateFilterUtc($request->query('end_to'));
if ($startFrom) {
$filters[] = "start_at_timestamp >= {$startFrom->timestamp}";
@ -155,29 +152,23 @@ class HuntsController extends Controller
return $searchTerm !== '' ? $searchTerm : null;
}
/**
* Parse une date en UTC.
* Si $endOfDay=true et que l'entrée ressemble à une date "YYYY-MM-DD",
* on la transforme en fin de journée UTC.
*/
private function parseDateFilterUtc(mixed $value, bool $endOfDay = false): ?Carbon
private function parseDateFilterUtc(mixed $value): ?Carbon
{
if (!is_string($value) || trim($value) === '') {
return null;
}
try {
$value = trim($value);
// Si le front envoie une date simple "2026-01-30"
if ($endOfDay && preg_match('/^\d{4}-\d{2}-\d{2}$/', $value)) {
return Carbon::createFromFormat('Y-m-d', $value, 'UTC')->endOfDay();
}
// ISO 8601 type "2026-01-29T23:00:00.000Z" => UTC garanti
return Carbon::parse($value)->utc();
return Carbon::parse(trim($value))->utc();
} catch (\Throwable $e) {
return null;
}
}
private function escapeMeiliString(string $value): string
{
// Échappe les backslashes et les guillemets pour une string Meilisearch
$value = str_replace('\\', '\\\\', $value);
return str_replace('"', '\"', $value);
}
}