Browse Source

Shared queries: combine user search structurally (#9544)

Follow-up to #9541.

In `p/api/query.php`, the optional `search` parameter of a shared user query was appended as a string to the user query's own search, and the result was parsed again.

This keeps both searches as parsed objects and combines them with a structural AND via `FreshRSS_BooleanSearch::add()`, avoiding the serialise/re-parse round trip. Adds a test for combining Boolean searches with `add()`.
Mehmet 8 giờ trước cách đây
mục cha
commit
931a6b3bbd
2 tập tin đã thay đổi với 22 bổ sung và 9 xóa
  1. 13 9
      p/api/query.php
  2. 9 0
      tests/app/Models/SearchTest.php

+ 13 - 9
p/api/query.php

@@ -101,7 +101,6 @@ foreach (FreshRSS_Context::userConf()->queries as $raw_query) {
 		}
 		Minz_Request::_param('state', (string)$query->getState());
 
-		$search = $query->getSearch()->toString();
 		// Note: we disallow references to user queries in public user search to avoid sniffing internal user queries
 		try {
 			$userSearch = new FreshRSS_BooleanSearch(Minz_Request::paramString('search', plaintext: true), 0, 'AND', allowUserQueries: false);
@@ -110,14 +109,8 @@ foreach (FreshRSS_Context::userConf()->queries as $raw_query) {
 			header('Content-Type: text/plain; charset=UTF-8');
 			die($e->getMessage());
 		}
-		if ($userSearch->toString() !== '') {
-			if ($search === '') {
-				$search = $userSearch->toString();
-			} else {
-				$search .= ' (' . $userSearch->toString() . ')';
-			}
-		}
-		Minz_Request::_param('search', $search);
+		// Only the search of the user query is passed as a string; the user search is combined structurally below
+		Minz_Request::_param('search', $query->getSearch()->toString());
 		break;
 	}
 }
@@ -132,6 +125,17 @@ $view = new FreshRSS_View();
 
 try {
 	FreshRSS_Context::updateUsingRequest(false);
+	if ($userSearch->toString() !== '') {
+		if (FreshRSS_Context::$search->toString() === '') {
+			FreshRSS_Context::$search = $userSearch;
+		} else {
+			// Combine with a structural AND, so that the user search cannot alter the search of the user query
+			$combinedSearch = new FreshRSS_BooleanSearch('');
+			$combinedSearch->add(FreshRSS_Context::$search);
+			$combinedSearch->add($userSearch);
+			FreshRSS_Context::$search = $combinedSearch;
+		}
+	}
 	$view->entries = FreshRSS_index_Controller::listEntriesByContext();
 	if (!$view->entries->valid()) {	// Init the generator to consume the aggregated search and catch potential exceptions
 		$view->entries = new EmptyIterator();

+ 9 - 0
tests/app/Models/SearchTest.php

@@ -757,6 +757,15 @@ final class SearchTest extends \PHPUnit\Framework\TestCase {
 		self::assertSame('(e.id >= ?) OR (e.`lastModified` >= ?)', $filterSearch);
 		self::assertSame([$startTime . '000000', $startTime], $filterValues);
 	}
+	public function test__add_boolean_searches_combines_with_and(): void {
+		$combined = new FreshRSS_BooleanSearch('');
+		$combined->add(new FreshRSS_BooleanSearch('ab'));
+		$combined->add(new FreshRSS_BooleanSearch('cd OR ef', 0, 'AND', allowUserQueries: false));
+		self::assertSame('ab (cd OR ef)', $combined->toString());
+
+		[$filterValues] = FreshRSS_EntryDAOPGSQL::sqlBooleanSearch('e.', $combined);
+		self::assertSame(['%ab%', '%ab%', '%cd%', '%cd%', '%ef%', '%ef%'], $filterValues);
+	}
 
 	/**
 	 * @param array<string> $values