asdsad
This commit is contained in:
@@ -135,12 +135,88 @@ final class Search
|
||||
return false;
|
||||
}));
|
||||
}
|
||||
// Fallback: wenn keine Treffer, erneut ohne Token-Filter laden und nur fuzzy filtern
|
||||
if (!$rows && $tokens) {
|
||||
$wherePartsFallback = [
|
||||
"starts_at >= NOW()",
|
||||
"status != 'cancelled'",
|
||||
];
|
||||
$bindFb = [];
|
||||
$sqlFb = '';
|
||||
if ($hasGeo) {
|
||||
$sqlFb = "SELECT id, title, teaser_public, description, city, region, zip, starts_at, visibility, allow_kids, location_label, lat, lng,
|
||||
(6371 * ACOS(LEAST(1,
|
||||
COS(RADIANS(?)) * COS(RADIANS(lat)) * COS(RADIANS(lng) - RADIANS(?)) +
|
||||
SIN(RADIANS(?)) * SIN(RADIANS(lat))
|
||||
))) AS distance_km";
|
||||
$lat = (float)$geo['lat'];
|
||||
$lng = (float)$geo['lng'];
|
||||
$radius = isset($geo['radius']) && is_numeric($geo['radius']) ? max(0.1, (float)$geo['radius']) : 5.0;
|
||||
$latRange = $radius / 111.0;
|
||||
$lngRange = $radius / (111.0 * max(0.1, cos($lat * M_PI / 180)));
|
||||
$wherePartsFallback[] = "(lat IS NOT NULL AND lng IS NOT NULL)";
|
||||
$wherePartsFallback[] = "(lat BETWEEN ? AND ?)";
|
||||
$wherePartsFallback[] = "(lng BETWEEN ? AND ?)";
|
||||
$bindFb[] = $lat;
|
||||
$bindFb[] = $lng;
|
||||
$bindFb[] = $lat;
|
||||
$bindFb[] = $lat - $latRange;
|
||||
$bindFb[] = $lat + $latRange;
|
||||
$bindFb[] = $lng - $lngRange;
|
||||
$bindFb[] = $lng + $lngRange;
|
||||
$bindFb[] = $radius;
|
||||
$havingFb = true;
|
||||
} else {
|
||||
$sqlFb = "SELECT id, title, teaser_public, description, city, region, zip, starts_at, visibility, allow_kids, location_label, lat, lng, 1 AS distance_km";
|
||||
$havingFb = false;
|
||||
}
|
||||
$whereFb = $wherePartsFallback ? ('WHERE ' . implode(' AND ', $wherePartsFallback)) : '';
|
||||
$sqlFb .= " FROM events $whereFb";
|
||||
if ($havingFb) {
|
||||
$sqlFb .= " HAVING distance_km <= ?";
|
||||
$sqlFb .= " ORDER BY distance_km ASC, starts_at ASC";
|
||||
} else {
|
||||
$sqlFb .= " ORDER BY starts_at ASC";
|
||||
}
|
||||
$sqlFb .= " LIMIT {$limit}";
|
||||
$stmtFb = $this->pdo->prepare($sqlFb);
|
||||
$stmtFb->execute($bindFb);
|
||||
$rowsFb = $stmtFb->fetchAll(\PDO::FETCH_ASSOC) ?: [];
|
||||
if ($rowsFb) {
|
||||
$rows = array_values(array_filter($rowsFb, function ($row) use ($tokens) {
|
||||
$haystack = strtolower(
|
||||
($row['title'] ?? '') . ' ' .
|
||||
($row['teaser_public'] ?? '') . ' ' .
|
||||
($row['description'] ?? '') . ' ' .
|
||||
($row['city'] ?? '') . ' ' .
|
||||
($row['region'] ?? '')
|
||||
);
|
||||
$words = preg_split('/[^a-z0-9äöüß]+/i', $haystack) ?: [];
|
||||
foreach ($tokens as $tok) {
|
||||
$t = strtolower($tok);
|
||||
if ($t === '') continue;
|
||||
if (str_contains($haystack, $t)) {
|
||||
return true;
|
||||
}
|
||||
foreach ($words as $w) {
|
||||
if ($w === '') continue;
|
||||
$dist = levenshtein($t, $w);
|
||||
if ($dist <= 1 || ($dist <= 2 && max(strlen($t), strlen($w)) > 4)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}));
|
||||
}
|
||||
}
|
||||
if (defined('APP_ENV') && APP_ENV === 'staging') {
|
||||
$logOk = [
|
||||
'status' => 'ok',
|
||||
'sql' => $sql,
|
||||
'bind' => $bind,
|
||||
'count' => count($rows),
|
||||
'fallback' => ($rows ? 'primary' : 'fallback'),
|
||||
];
|
||||
@file_put_contents(__DIR__ . '/../../debug/search_debug.log', print_r($logOk, true));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user