From 62156ed946286a7c6b39f07d2e745e648e7033d3 Mon Sep 17 00:00:00 2001 From: hbrain Date: Sun, 31 May 2026 18:10:23 +0200 Subject: [PATCH] =?UTF-8?q?Make=20search=20accent-insensitive=20so=20Sonde?= =?UTF-8?q?rvig=20matches=20S=C3=B8ndervig?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.php | 21 +++++++++++++++++++-- new.php | 21 +++++++++++++++++++-- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/index.php b/index.php index 86c82c3..437711e 100644 --- a/index.php +++ b/index.php @@ -7,12 +7,29 @@ if (!is_dir(__DIR__ . "/cache")) mkdir(__DIR__ . "/cache", 0775, true); function h($s){ return htmlspecialchars((string)$s, ENT_QUOTES, "UTF-8"); } function nice_title($s){ return trim(ucwords(str_replace(['_','-'], ' ', (string)$s))); } function lower_text($s){ return function_exists('mb_strtolower') ? mb_strtolower((string)$s, 'UTF-8') : strtolower((string)$s); } +function fold_text($s){ + $s = strtr((string)$s, [ + 'æ'=>'ae','Æ'=>'ae','ø'=>'o','Ø'=>'o','å'=>'aa','Å'=>'aa', + 'ä'=>'ae','Ä'=>'ae','ö'=>'oe','Ö'=>'oe','ü'=>'ue','Ü'=>'ue','ß'=>'ss','ẞ'=>'ss', + 'č'=>'c','Č'=>'c','ć'=>'c','Ć'=>'c','ž'=>'z','Ž'=>'z','š'=>'s','Š'=>'s','đ'=>'d','Đ'=>'d', + ]); + if (function_exists('iconv')) { + $x = @iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $s); + if ($x !== false) $s = $x; + } + $s = lower_text($s); + return preg_replace('/[^a-z0-9]+/', ' ', $s) ?? ''; +} function ci_contains($haystack, $needle){ $haystack = (string)$haystack; $needle = (string)$needle; if ($needle === '') return true; - if (function_exists('mb_stripos')) return mb_stripos($haystack, $needle, 0, 'UTF-8') !== false; - return strpos(lower_text($haystack), lower_text($needle)) !== false; + if (function_exists('mb_stripos') && mb_stripos($haystack, $needle, 0, 'UTF-8') !== false) return true; + if (strpos(lower_text($haystack), lower_text($needle)) !== false) return true; + $foldHay = fold_text($haystack); + $foldNeedle = trim(fold_text($needle)); + if ($foldNeedle === '') return false; + return strpos($foldHay, $foldNeedle) !== false; } function keep_non_empty(array $params): array { return array_filter($params, fn($v)=>$v !== '' && $v !== null); } function query_url(array $params): string { diff --git a/new.php b/new.php index bfbd32c..bc7cedb 100644 --- a/new.php +++ b/new.php @@ -8,12 +8,29 @@ const ARTICLE_ID_FILE = '.mvlog-id'; function h($s){ return htmlspecialchars((string)$s, ENT_QUOTES, "UTF-8"); } function ajax_json($data){ header('Content-Type: application/json; charset=UTF-8'); echo json_encode($data, JSON_UNESCAPED_UNICODE); exit; } function lower_text($s){ return function_exists('mb_strtolower') ? mb_strtolower((string)$s, 'UTF-8') : strtolower((string)$s); } +function fold_text($s){ + $s = strtr((string)$s, [ + 'æ'=>'ae','Æ'=>'ae','ø'=>'o','Ø'=>'o','å'=>'aa','Å'=>'aa', + 'ä'=>'ae','Ä'=>'ae','ö'=>'oe','Ö'=>'oe','ü'=>'ue','Ü'=>'ue','ß'=>'ss','ẞ'=>'ss', + 'č'=>'c','Č'=>'c','ć'=>'c','Ć'=>'c','ž'=>'z','Ž'=>'z','š'=>'s','Š'=>'s','đ'=>'d','Đ'=>'d', + ]); + if (function_exists('iconv')) { + $x = @iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $s); + if ($x !== false) $s = $x; + } + $s = lower_text($s); + return preg_replace('/[^a-z0-9]+/', ' ', $s) ?? ''; +} function ci_contains($haystack, $needle){ $haystack = (string)$haystack; $needle = (string)$needle; if ($needle === '') return true; - if (function_exists('mb_stripos')) return mb_stripos($haystack, $needle, 0, 'UTF-8') !== false; - return strpos(lower_text($haystack), lower_text($needle)) !== false; + if (function_exists('mb_stripos') && mb_stripos($haystack, $needle, 0, 'UTF-8') !== false) return true; + if (strpos(lower_text($haystack), lower_text($needle)) !== false) return true; + $foldHay = fold_text($haystack); + $foldNeedle = trim(fold_text($needle)); + if ($foldNeedle === '') return false; + return strpos($foldHay, $foldNeedle) !== false; } function ascii_safe($s){ $s = strtr((string)$s, [