From 434da183e7765c7d30a569a60b31af6fe7595b54 Mon Sep 17 00:00:00 2001 From: wn_ Date: Tue, 18 Mar 2025 00:16:09 +0000 Subject: [PATCH] Support using phrases in searches (PostgreSQL only). --- classes/Feeds.php | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/classes/Feeds.php b/classes/Feeds.php index 704249f1e..b336d4df2 100644 --- a/classes/Feeds.php +++ b/classes/Feeds.php @@ -2143,6 +2143,9 @@ class Feeds extends Handler_Protected { // This is needed so potential command pairs are grouped correctly. $search_csv_str = preg_replace('/(-?\w+)\:"(\w+)/', '"$1:$2', trim($search)); + // '-"hello world"' --> '"-hello world"' so negated phrases work + $search_csv_str = preg_replace('/-"([^"]+?")/', '"-$1', $search_csv_str); + // $keywords will be an array like ['"title:hello world"', 'some', 'words'] $keywords = str_getcsv($search_csv_str, ' ', '"', ''); @@ -2161,6 +2164,8 @@ class Feeds extends Handler_Protected { $not = ""; } + $k = trim($k); + $keyword_pair = explode(':', mb_strtolower($k), 2); $keyword_name = $keyword_pair[0]; $keyword_value = empty($keyword_pair[1]) ? '' : trim($keyword_pair[1]); @@ -2265,22 +2270,21 @@ class Feeds extends Handler_Protected { $orig_ts = strtotime(substr($k, 1)); $k = date("Y-m-d", TimeHelper::convert_timestamp($orig_ts, $user_tz_string, 'UTC')); - //$k = date("Y-m-d", strtotime(substr($k, 1))); - array_push($query_keywords, "(".SUBSTRING_FOR_DATE."(updated,1,LENGTH(".$pdo->quote($k).")) $not = ".$pdo->quote($k).")"); } else { // treat as leftover text - // TODO: handle multiword strings in the fulltext search $k = mb_strtolower($k); if (Config::get(Config::DB_TYPE) == "pgsql") { + // A hacky way for phrases (e.g. "hello world") to get through PDO quoting. + // Term '"foo bar baz"' becomes '(foo <-> bar <-> baz)' ("<->" meaning "immediately followed by"). + if (preg_match('/\s+/', $k)) + $k = '(' . preg_replace('/\s+/', ' <-> ', $k) . ')'; + array_push($search_query_leftover, $not ? "!$k" : $k); } else { array_push($search_query_leftover, $not ? "-$k" : $k); - - //array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER(".$pdo->quote("%$k%").") - // OR UPPER(ttrss_entries.content) $not LIKE UPPER(".$pdo->quote("%$k%")."))"); } if (!$not) array_push($search_words, $k);