aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/Controllers/categoryController.php2
-rw-r--r--app/Controllers/configureController.php4
-rw-r--r--app/Controllers/indexController.php2
-rw-r--r--app/Controllers/subscriptionController.php17
-rw-r--r--app/Models/BooleanSearch.php1
-rw-r--r--app/Models/FilterAction.php4
-rw-r--r--app/Models/FilterActionsTrait.php5
-rw-r--r--app/Models/Search.php1
-rw-r--r--app/Models/UserQuery.php4
-rw-r--r--app/layout/nav_menu.phtml6
-rw-r--r--app/views/configure/queries.phtml4
-rw-r--r--app/views/configure/reading.phtml4
-rw-r--r--app/views/helpers/category/update.phtml2
-rw-r--r--app/views/helpers/configure/query.phtml2
-rw-r--r--app/views/helpers/export/opml.phtml2
-rw-r--r--app/views/helpers/feed/update.phtml2
-rw-r--r--app/views/helpers/stream-footer.phtml2
-rw-r--r--app/views/tag/update.phtml2
-rw-r--r--p/api/query.php2
-rw-r--r--tests/app/Models/SearchTest.php5
20 files changed, 40 insertions, 33 deletions
diff --git a/app/Controllers/categoryController.php b/app/Controllers/categoryController.php
index fd148bf05..9bea88a1f 100644
--- a/app/Controllers/categoryController.php
+++ b/app/Controllers/categoryController.php
@@ -110,7 +110,7 @@ class FreshRSS_category_Controller extends FreshRSS_ActionController {
$category->_attribute('read_when_same_title_in_category', null);
}
- $category->_filtersAction('read', Minz_Request::paramTextToArray('filteractions_read')); // Keep as HTML
+ $category->_filtersAction('read', Minz_Request::paramTextToArray('filteractions_read', plaintext: true));
if (Minz_Request::paramBoolean('use_default_purge_options')) {
$category->_attribute('archiving', null);
diff --git a/app/Controllers/configureController.php b/app/Controllers/configureController.php
index 8bc0d08c4..8b42a1441 100644
--- a/app/Controllers/configureController.php
+++ b/app/Controllers/configureController.php
@@ -164,8 +164,8 @@ class FreshRSS_configure_Controller extends FreshRSS_ActionController {
'site' => Minz_Request::paramBoolean('mark_open_site'),
'focus' => Minz_Request::paramBoolean('mark_focus'),
];
- FreshRSS_Context::userConf()->_filtersAction('read', Minz_Request::paramTextToArray('filteractions_read')); // Keep as HTML
- FreshRSS_Context::userConf()->_filtersAction('star', Minz_Request::paramTextToArray('filteractions_star')); // Keep as HTML
+ FreshRSS_Context::userConf()->_filtersAction('read', Minz_Request::paramTextToArray('filteractions_read', plaintext: true));
+ FreshRSS_Context::userConf()->_filtersAction('star', Minz_Request::paramTextToArray('filteractions_star', plaintext: true));
FreshRSS_Context::userConf()->save();
invalidateHttpCache();
diff --git a/app/Controllers/indexController.php b/app/Controllers/indexController.php
index c51dd6662..7def8e781 100644
--- a/app/Controllers/indexController.php
+++ b/app/Controllers/indexController.php
@@ -94,7 +94,7 @@ class FreshRSS_index_Controller extends FreshRSS_ActionController {
};
$searchString = $operator . ':' . ($offset < 0 ? '/' : '') . date('Y-m-d', $timestamp + ($offset * 86400)) . ($offset > 0 ? '/' : '');
return Minz_Url::display(Minz_Request::modifiedCurrentRequest([
- 'search' => FreshRSS_Context::$search->getRawInput() === '' ? $searchString :
+ 'search' => FreshRSS_Context::$search->__toString() === '' ? $searchString :
FreshRSS_Context::$search->enforce(new FreshRSS_Search($searchString))->__toString(),
]));
}
diff --git a/app/Controllers/subscriptionController.php b/app/Controllers/subscriptionController.php
index ad9b05787..02942583f 100644
--- a/app/Controllers/subscriptionController.php
+++ b/app/Controllers/subscriptionController.php
@@ -247,7 +247,7 @@ class FreshRSS_subscription_Controller extends FreshRSS_ActionController {
]);
}
- $feed->_filtersAction('read', Minz_Request::paramTextToArray('filteractions_read')); // Keep as HTML
+ $feed->_filtersAction('read', Minz_Request::paramTextToArray('filteractions_read', plaintext: true));
$feed->_kind(Minz_Request::paramInt('feed_kind') ?: FreshRSS_Feed::KIND_RSS);
if ($feed->kind() === FreshRSS_Feed::KIND_HTML_XPATH || $feed->kind() === FreshRSS_Feed::KIND_XML_XPATH) {
@@ -418,17 +418,22 @@ class FreshRSS_subscription_Controller extends FreshRSS_ActionController {
$filteractions = Minz_Request::paramTextToArray('filteractions_read', plaintext: true);
$filteractions = array_map(fn(string $action): string => trim($action), $filteractions);
$filteractions = array_filter($filteractions, fn(string $action): bool => $action !== '');
- $search = "f:$id (";
+ $actionsSearch = new FreshRSS_BooleanSearch('', operator: 'AND');
foreach ($filteractions as $action) {
- $search .= "($action) OR ";
+ $actionSearch = new FreshRSS_BooleanSearch($action, operator: 'OR');
+ if ($actionSearch->__toString() === '') {
+ continue;
+ }
+ $actionsSearch->add($actionSearch);
}
- $search = preg_replace('/ OR $/', '', $search);
- $search .= ')';
+ $search = new FreshRSS_BooleanSearch('');
+ $search->add(new FreshRSS_Search("f:$id"));
+ $search->add($actionsSearch);
Minz_Request::forward([
'c' => 'index',
'a' => 'index',
'params' => [
- 'search' => $search,
+ 'search' => $search->__toString(),
],
], redirect: true);
}
diff --git a/app/Models/BooleanSearch.php b/app/Models/BooleanSearch.php
index e959f7af9..6be189cda 100644
--- a/app/Models/BooleanSearch.php
+++ b/app/Models/BooleanSearch.php
@@ -525,6 +525,7 @@ class FreshRSS_BooleanSearch implements \Stringable {
}
/** @return string Plain text search query. Must be XML-encoded or URL-encoded depending on the situation */
+ #[Deprecated('Use __tostring() instead')]
public function getRawInput(): string {
return $this->raw_input;
}
diff --git a/app/Models/FilterAction.php b/app/Models/FilterAction.php
index 56c182904..5d11d26db 100644
--- a/app/Models/FilterAction.php
+++ b/app/Models/FilterAction.php
@@ -29,11 +29,11 @@ class FreshRSS_FilterAction {
}
}
- /** @return array{'search'?:string,'actions'?:array<string>} */
+ /** @return array{search?:string,actions?:array<string>} */
public function toJSON(): array {
if (is_array($this->actions) && $this->booleanSearch != null) {
return [
- 'search' => $this->booleanSearch->getRawInput(),
+ 'search' => $this->booleanSearch->__toString(),
'actions' => $this->actions,
];
}
diff --git a/app/Models/FilterActionsTrait.php b/app/Models/FilterActionsTrait.php
index 3c36343d6..819f2d975 100644
--- a/app/Models/FilterActionsTrait.php
+++ b/app/Models/FilterActionsTrait.php
@@ -71,8 +71,7 @@ trait FreshRSS_FilterActionsTrait {
//Check existing filters
for ($i = count($filterActions) - 1; $i >= 0; $i--) {
$filterAction = $filterActions[$i];
- if ($filterAction == null || !is_array($filterAction->actions()) ||
- $filterAction->booleanSearch() == null || trim($filterAction->booleanSearch()->getRawInput()) == '') {
+ if ($filterAction === null || !is_array($filterAction->actions()) || $filterAction->booleanSearch()->__toString() === '') {
array_splice($filterActions, $i, 1);
continue;
}
@@ -86,7 +85,7 @@ trait FreshRSS_FilterActionsTrait {
//Update existing filter with new action
for ($k = count($filters) - 1; $k >= 0; $k--) {
$filter = $filters[$k];
- if ($filter === $filterAction->booleanSearch()->getRawInput()) {
+ if ($filter === $filterAction->booleanSearch()->__toString()) {
$actions[] = $action;
array_splice($filters, $k, 1);
}
diff --git a/app/Models/Search.php b/app/Models/Search.php
index 201fed9f9..046f61a2b 100644
--- a/app/Models/Search.php
+++ b/app/Models/Search.php
@@ -452,6 +452,7 @@ class FreshRSS_Search implements \Stringable {
return trim($result);
}
+ #[Deprecated('Use __tostring() instead')]
public function getRawInput(): string {
return $this->raw_input;
}
diff --git a/app/Models/UserQuery.php b/app/Models/UserQuery.php
index 6050436f4..154f4d92c 100644
--- a/app/Models/UserQuery.php
+++ b/app/Models/UserQuery.php
@@ -123,7 +123,7 @@ class FreshRSS_UserQuery {
'get' => $this->get,
'name' => $this->name,
'order' => $this->order,
- 'search' => $this->search->getRawInput(),
+ 'search' => $this->search->__toString(),
'state' => $this->state,
'url' => $this->url,
'token' => $this->token,
@@ -221,7 +221,7 @@ class FreshRSS_UserQuery {
* Check if there is a search in the search object
*/
public function hasSearch(): bool {
- return $this->search->getRawInput() !== '';
+ return $this->search->__toString() !== '';
}
public function getGet(): string {
diff --git a/app/layout/nav_menu.phtml b/app/layout/nav_menu.phtml
index 04565c9b9..3c3a34243 100644
--- a/app/layout/nav_menu.phtml
+++ b/app/layout/nav_menu.phtml
@@ -39,7 +39,7 @@
<input type="hidden" name="_csrf" value="<?= FreshRSS_Auth::csrfToken() ?>" />
<div id="dropdown-search" class="dropdown-target"></div>
- <a id="toggle-search" class="dropdown-toggle btn<?= (strlen(FreshRSS_Context::$search->getRawInput()) > 0) ? ' active' : ''; ?>" title="<?= _t('gen.menu.search') ?>"
+ <a id="toggle-search" class="dropdown-toggle btn<?= FreshRSS_Context::$search->__toString() !== '' ? ' active' : ''; ?>" title="<?= _t('gen.menu.search') ?>"
href="#dropdown-search"><?= _i('search') ?></a>
<ul class="dropdown-menu">
<li class="item">
@@ -56,7 +56,7 @@
<?php } ?>
<div class="stick search">
<input type="search" name="search"
- value="<?= htmlspecialchars(htmlspecialchars_decode(FreshRSS_Context::$search->getRawInput(), ENT_QUOTES), ENT_COMPAT, 'UTF-8'); ?>"
+ value="<?= htmlspecialchars(FreshRSS_Context::$search->__toString(), ENT_COMPAT, 'UTF-8') ?>"
placeholder="<?= _t('gen.menu.search') ?>" title="<?= _t('gen.menu.search') ?>" /><button class="btn" type="submit" title="<?= _t('index.menu.search_short') ?>"><?= _i('search') ?></button>
</div>
<p class="help"><?= _i('help') ?> <a href="<?= _url('search', 'index') ?>"><?= _t('gen.menu.advanced_search') ?></a></p>
@@ -121,7 +121,7 @@
'get' => $get,
'nextGet' => FreshRSS_Context::$next_get,
'idMax' => FreshRSS_Context::$id_max,
- 'search' => htmlspecialchars_decode(FreshRSS_Context::$search->getRawInput(), ENT_QUOTES),
+ 'search' => FreshRSS_Context::$search->__toString(),
'state' => FreshRSS_Context::$state,
'sort' => FreshRSS_Context::$sort,
'order' => FreshRSS_Context::$order,
diff --git a/app/views/configure/queries.phtml b/app/views/configure/queries.phtml
index 821d8673f..1b36c88bd 100644
--- a/app/views/configure/queries.phtml
+++ b/app/views/configure/queries.phtml
@@ -24,7 +24,7 @@
<input type="hidden" id="queries_<?= $key ?>_shareRss" name="queries[<?= $key ?>][shareRss]" value="<?= $query->shareRss() ? '1' : '0' ?>"/>
<input type="hidden" id="queries_<?= $key ?>_shareOpml" name="queries[<?= $key ?>][shareOpml]" value="<?= $query->shareOpml() ? '1' : '0' ?>"/>
<input type="hidden" id="queries_<?= $key ?>_url" name="queries[<?= $key ?>][url]" value="<?= $query->getUrl() ?>"/>
- <input type="hidden" id="queries_<?= $key ?>_search" name="queries[<?= $key ?>][search]" value="<?= urlencode($query->getSearch()->getRawInput()) ?>"/>
+ <input type="hidden" id="queries_<?= $key ?>_search" name="queries[<?= $key ?>][search]" value="<?= urlencode($query->getSearch()->__toString()) ?>"/>
<input type="hidden" id="queries_<?= $key ?>_state" name="queries[<?= $key ?>][state]" value="<?= $query->getState() ?>"/>
<input type="hidden" id="queries_<?= $key ?>_order" name="queries[<?= $key ?>][order]" value="<?= $query->getOrder() ?>"/>
<input type="hidden" id="queries_<?= $key ?>_get" name="queries[<?= $key ?>][get]" value="<?= $query->getGet() ?>"/>
@@ -44,7 +44,7 @@
<?php } else { ?>
<ul class="box-content scrollbar-thin">
<?php if ($query->hasSearch()) { ?>
- <li class="item"><?= _t('conf.query.search', htmlspecialchars($query->getSearch()->getRawInput(), ENT_NOQUOTES, 'UTF-8')) ?></li>
+ <li class="item"><?= _t('conf.query.search', htmlspecialchars($query->getSearch()->__toString(), ENT_NOQUOTES, 'UTF-8')) ?></li>
<?php } ?>
<?php if ($query->getState()) { ?>
diff --git a/app/views/configure/reading.phtml b/app/views/configure/reading.phtml
index 3b92a9e4f..f761f7951 100644
--- a/app/views/configure/reading.phtml
+++ b/app/views/configure/reading.phtml
@@ -349,7 +349,7 @@
<div class="group-controls">
<textarea name="filteractions_read" id="filteractions_read" class="w100"><?php
foreach (FreshRSS_Context::userConf()->filtersAction('read') as $filterRead) {
- echo $filterRead->getRawInput(), PHP_EOL;
+ echo htmlspecialchars($filterRead->__toString(), ENT_NOQUOTES, 'UTF-8'), PHP_EOL;
}
?></textarea>
<p class="help"><?= _i('help') ?> <?= _t('sub.feed.filteractions.help') ?></p>
@@ -366,7 +366,7 @@
<div class="group-controls">
<textarea name="filteractions_star" id="filteractions_star" class="w100"><?php
foreach (FreshRSS_Context::userConf()->filtersAction('star') as $filterStar) {
- echo $filterStar->getRawInput(), PHP_EOL;
+ echo htmlspecialchars($filterStar->__toString(), ENT_NOQUOTES, 'UTF-8'), PHP_EOL;
}
?></textarea>
<p class="help"><?= _i('help') ?> <?= _t('sub.feed.filteractions.help') ?></p>
diff --git a/app/views/helpers/category/update.phtml b/app/views/helpers/category/update.phtml
index 231f86ebd..61018a15b 100644
--- a/app/views/helpers/category/update.phtml
+++ b/app/views/helpers/category/update.phtml
@@ -96,7 +96,7 @@
<div class="group-controls">
<textarea name="filteractions_read" id="filteractions_read" class="w100"><?php
foreach ($this->category->filtersAction('read') as $filterRead) {
- echo $filterRead->getRawInput(), PHP_EOL;
+ echo htmlspecialchars($filterRead->__toString(), ENT_NOQUOTES, 'UTF-8'), PHP_EOL;
}
?></textarea>
<p class="help"><?= _i('help') ?> <?= _t('sub.feed.filteractions.help') ?></p>
diff --git a/app/views/helpers/configure/query.phtml b/app/views/helpers/configure/query.phtml
index e97ceeeed..fd3877bb6 100644
--- a/app/views/helpers/configure/query.phtml
+++ b/app/views/helpers/configure/query.phtml
@@ -92,7 +92,7 @@
<div class="form-group">
<label class="group-name" for=""><?= _t('conf.query.filter.search') ?></label>
<div class="group-controls">
- <input type="text" class="w100" id="query_search" name="query[search]" value="<?= htmlspecialchars($this->query->getSearch()->getRawInput(), ENT_COMPAT, 'UTF-8') ?>"/>
+ <input type="text" class="w100" id="query_search" name="query[search]" value="<?= htmlspecialchars($this->query->getSearch()->__toString(), ENT_COMPAT, 'UTF-8') ?>"/>
<p class="help"><?= _i('help') ?> <?= _t('gen.menu.search_help') ?></a></p>
</div>
</div>
diff --git a/app/views/helpers/export/opml.phtml b/app/views/helpers/export/opml.phtml
index feeb409a5..2e67cd043 100644
--- a/app/views/helpers/export/opml.phtml
+++ b/app/views/helpers/export/opml.phtml
@@ -89,7 +89,7 @@ function feedsToOutlines(array $feeds, bool $excludeMutedFeeds = false): array {
if (!empty($feed->filtersAction('read'))) {
$filters = '';
foreach ($feed->filtersAction('read') as $filterRead) {
- $filters .= $filterRead->getRawInput() . "\n";
+ $filters .= $filterRead->__toString() . "\n";
}
$filters = trim($filters);
$outline['frss:filtersActionRead'] = $filters;
diff --git a/app/views/helpers/feed/update.phtml b/app/views/helpers/feed/update.phtml
index 6a7ce83c2..73187cbab 100644
--- a/app/views/helpers/feed/update.phtml
+++ b/app/views/helpers/feed/update.phtml
@@ -304,7 +304,7 @@
<textarea name="filteractions_read" id="filteractions_read" class="w100"
placeholder="<?= _t('gen.short.blank_to_disable') ?>"><?php
foreach ($this->feed->filtersAction('read') as $filterRead) {
- echo $filterRead->getRawInput(), PHP_EOL;
+ echo htmlspecialchars($filterRead->__toString(), ENT_NOQUOTES, 'UTF-8'), PHP_EOL;
}
?></textarea>
<p class="help"><?= _i('help') ?> <?= _t('sub.feed.filteractions.help') ?></p>
diff --git a/app/views/helpers/stream-footer.phtml b/app/views/helpers/stream-footer.phtml
index 5165a115e..4fe93cf7d 100644
--- a/app/views/helpers/stream-footer.phtml
+++ b/app/views/helpers/stream-footer.phtml
@@ -18,7 +18,7 @@
'get' => FreshRSS_Context::currentGet(),
'nextGet' => FreshRSS_Context::$next_get,
'idMax' => FreshRSS_Context::$id_max,
- 'search' => htmlspecialchars_decode(FreshRSS_Context::$search->getRawInput(), ENT_QUOTES),
+ 'search' => FreshRSS_Context::$search->__toString(),
'state' => FreshRSS_Context::$state,
'sort' => FreshRSS_Context::$sort,
'order' => FreshRSS_Context::$order,
diff --git a/app/views/tag/update.phtml b/app/views/tag/update.phtml
index cedb75592..b50d2d743 100644
--- a/app/views/tag/update.phtml
+++ b/app/views/tag/update.phtml
@@ -45,7 +45,7 @@
<div class="group-controls">
<textarea name="filteractions_label" id="filteractions_label" class="w100"><?php
foreach ($this->tag->filtersAction('label') as $filterRead) {
- echo $filterRead->getRawInput(), PHP_EOL;
+ echo htmlspecialchars($filterRead->__toString(), ENT_NOQUOTES, 'UTF-8') . PHP_EOL;
}
?></textarea>
<p class="help"><?= _i('help') ?> <?= _t('sub.feed.filteractions.help') ?></p>
diff --git a/p/api/query.php b/p/api/query.php
index 991a1a7bb..7534a9e85 100644
--- a/p/api/query.php
+++ b/p/api/query.php
@@ -117,7 +117,7 @@ $view = new FreshRSS_View();
try {
FreshRSS_Context::updateUsingRequest(false);
- Minz_Request::_param('search', $userSearch->getRawInput()); // Restore user search
+ Minz_Request::_param('search', $userSearch->__toString()); // Restore user search
$view->entries = FreshRSS_index_Controller::listEntriesByContext();
} catch (Minz_Exception) {
Minz_Error::error(400, 'Bad user query!');
diff --git a/tests/app/Models/SearchTest.php b/tests/app/Models/SearchTest.php
index a543777ef..990598dff 100644
--- a/tests/app/Models/SearchTest.php
+++ b/tests/app/Models/SearchTest.php
@@ -10,7 +10,7 @@ final class SearchTest extends \PHPUnit\Framework\TestCase {
#[DataProvider('provideEmptyInput')]
public static function test__construct_whenInputIsEmpty_getsOnlyNullValues(string $input): void {
$search = new FreshRSS_Search($input);
- self::assertSame('', $search->getRawInput());
+ self::assertSame('', $search->__toString());
self::assertNull($search->getIntitle());
self::assertNull($search->getMinDate());
self::assertNull($search->getMaxDate());
@@ -327,7 +327,6 @@ final class SearchTest extends \PHPUnit\Framework\TestCase {
self::assertSame($max_pubdate_value, $search->getMaxPubdate());
self::assertSame($tags_value, $search->getTags());
self::assertSame($search_value, $search->getSearch());
- self::assertSame($input, $search->getRawInput());
}
/** @return list<list<mixed>> */
@@ -1033,7 +1032,9 @@ final class SearchTest extends \PHPUnit\Framework\TestCase {
*/
public static function provideBooleanSearchEnforce(): array {
return [
+ ['', '', ''],
['', 'intitle:b', 'intitle:b'],
+ ['intitle:a', '', 'intitle:a'],
['intitle:a', 'intitle:b', 'intitle:b'],
['a', 'intitle:b', 'intitle:b a'],
['intitle:a intext:a', 'intitle:b', 'intitle:b intext:a'],