This commit is contained in:
2026-01-03 01:43:51 +01:00
parent a55061bdfa
commit 1171639070

View File

@@ -19,6 +19,9 @@ final class Search
if (!$tokens) { if (!$tokens) {
$tokens = [$q]; $tokens = [$q];
} }
// Nur Tokens ab 3 Zeichen für fuzzy/LIKE berücksichtigen
$tokens = array_values(array_filter($tokens, fn($t) => mb_strlen($t) >= 3));
if (!$tokens && !$hasGeo) return [];
$conditions = []; $conditions = [];
$bindTokens = []; $bindTokens = [];
@@ -104,6 +107,34 @@ final class Search
try { try {
$stmt->execute($bind); $stmt->execute($bind);
$rows = $stmt->fetchAll(\PDO::FETCH_ASSOC) ?: []; $rows = $stmt->fetchAll(\PDO::FETCH_ASSOC) ?: [];
// Fuzzy filter: allow slight typos (Levenshtein <= 1 or 2)
if ($tokens) {
$rows = array_values(array_filter($rows, 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') { if (defined('APP_ENV') && APP_ENV === 'staging') {
$logOk = [ $logOk = [
'status' => 'ok', 'status' => 'ok',