diff options
| author | 2021-12-31 13:10:41 +0100 | |
|---|---|---|
| committer | 2021-12-31 13:10:41 +0100 | |
| commit | fb15a2d8048ff66db5cb73b0dfb3a5b6a052e1db (patch) | |
| tree | ac778c9e2175c7bb3b6dcf15cbe6af562c7713b8 | |
| parent | afb3035bc6a50b8f6334f2729e3a7f568b429022 (diff) | |
Search on article IDs (#4058)
* Search on article IDs
Partial implementation of https://github.com/FreshRSS/FreshRSS/issues/4053
| -rw-r--r-- | app/Models/EntryDAO.php | 23 | ||||
| -rw-r--r-- | app/Models/Search.php | 49 | ||||
| -rw-r--r-- | docs/en/users/03_Main_view.md | 1 | ||||
| -rw-r--r-- | docs/fr/users/03_Main_view.md | 1 |
4 files changed, 74 insertions, 0 deletions
diff --git a/app/Models/EntryDAO.php b/app/Models/EntryDAO.php index 86f3ac040..7c133a2f4 100644 --- a/app/Models/EntryDAO.php +++ b/app/Models/EntryDAO.php @@ -732,6 +732,29 @@ SQL; } $sub_search = ''; + if ($filter->getEntryIds()) { + foreach ($filter->getEntryIds() as $entry_ids) { + $sub_search .= 'AND ' . $alias . 'id IN ('; + foreach ($entry_ids as $entry_id) { + $sub_search .= '?,'; + $values[] = $entry_id; + } + $sub_search = rtrim($sub_search, ','); + $sub_search .= ') '; + } + } + if ($filter->getNotEntryIds()) { + foreach ($filter->getNotEntryIds() as $entry_ids) { + $sub_search .= 'AND ' . $alias . 'id NOT IN ('; + foreach ($entry_ids as $entry_id) { + $sub_search .= '?,'; + $values[] = $entry_id; + } + $sub_search = rtrim($sub_search, ','); + $sub_search .= ') '; + } + } + if ($filter->getMinDate()) { $sub_search .= 'AND ' . $alias . 'id >= ? '; $values[] = "{$filter->getMinDate()}000000"; diff --git a/app/Models/Search.php b/app/Models/Search.php index 20c4f540a..47aaa6078 100644 --- a/app/Models/Search.php +++ b/app/Models/Search.php @@ -14,6 +14,7 @@ class FreshRSS_Search { private $raw_input = ''; // The following properties are extracted from the raw input + private $entry_ids; private $feed_ids; private $label_ids; private $label_names; @@ -27,6 +28,7 @@ class FreshRSS_Search { private $tags; private $search; + private $not_entry_ids; private $not_feed_ids; private $not_label_ids; private $not_label_names; @@ -48,6 +50,7 @@ class FreshRSS_Search { $input = preg_replace('/:"(.*?)"/', ':"\1"', $input); + $input = $this->parseNotEntryIds($input); $input = $this->parseNotFeedIds($input); $input = $this->parseNotLabelIds($input); $input = $this->parseNotLabelNames($input); @@ -60,6 +63,7 @@ class FreshRSS_Search { $input = $this->parseNotInurlSearch($input); $input = $this->parseNotTagsSearch($input); + $input = $this->parseEntryIds($input); $input = $this->parseFeedIds($input); $input = $this->parseLabelIds($input); $input = $this->parseLabelNames($input); @@ -84,6 +88,13 @@ class FreshRSS_Search { return $this->raw_input; } + public function getEntryIds() { + return $this->entry_ids; + } + public function getNotEntryIds() { + return $this->not_entry_ids; + } + public function getFeedIds() { return $this->feed_ids; } @@ -189,6 +200,44 @@ class FreshRSS_Search { } /** + * Parse the search string to find entry (article) IDs. + * + * @param string $input + * @return string + */ + private function parseEntryIds($input) { + if (preg_match_all('/\be:(?P<search>[0-9,]*)/', $input, $matches)) { + $input = str_replace($matches[0], '', $input); + $ids_lists = $matches['search']; + $this->entry_ids = []; + foreach ($ids_lists as $ids_list) { + $entry_ids = explode(',', $ids_list); + $entry_ids = self::removeEmptyValues($entry_ids); + if (!empty($entry_ids)) { + $this->entry_ids[] = $entry_ids; + } + } + } + return $input; + } + + private function parseNotEntryIds($input) { + if (preg_match_all('/[!-]e:(?P<search>[0-9,]*)/', $input, $matches)) { + $input = str_replace($matches[0], '', $input); + $ids_lists = $matches['search']; + $this->not_entry_ids = []; + foreach ($ids_lists as $ids_list) { + $entry_ids = explode(',', $ids_list); + $entry_ids = self::removeEmptyValues($entry_ids); + if (!empty($entry_ids)) { + $this->not_entry_ids[] = $entry_ids; + } + } + } + return $input; + } + + /** * Parse the search string to find feed IDs. * * @param string $input diff --git a/docs/en/users/03_Main_view.md b/docs/en/users/03_Main_view.md index dcf599878..8e7563200 100644 --- a/docs/en/users/03_Main_view.md +++ b/docs/en/users/03_Main_view.md @@ -227,6 +227,7 @@ You can use the search field to further refine results: * by custom label ID `L:12` or multiple label IDs: `L:12,13,14` or with any label: `L:*` * by custom label name `label:label`, `label:"my label"` or any label name from a list (*or*): `labels:"my label,my other label"` * by several label names (*and*): `label:"my label" label:"my other label"` +* by entry (article) ID: `e:1639310674957894` or multiple entry IDs (*or*): `e:1639310674957894,1639310674957893` Be careful not to enter a space between the operator and the search value. diff --git a/docs/fr/users/03_Main_view.md b/docs/fr/users/03_Main_view.md index 96e82a6b1..4934301af 100644 --- a/docs/fr/users/03_Main_view.md +++ b/docs/fr/users/03_Main_view.md @@ -251,6 +251,7 @@ Il est possible d’utiliser le champ de recherche pour raffiner les résultats * par ID d’étiquette : `L:12` ou de plusieurs étiquettes : `L:12,13,14` ou avec n’importe quelle étiquette : `L:*` * par nom d’étiquette : `label:étiquette`, `label:"mon étiquette"` ou d’une étiquette parmis une liste (*ou*) : `labels:"mon étiquette,mon autre étiquette"` * par plusieurs noms d’étiquettes (*et*) : `label:"mon étiquette" label:"mon autre étiquette"` +* par ID d’article (entrée) : `e:1639310674957894` ou de plusieurs articles (*ou*): `e:1639310674957894,1639310674957893` Attention à ne pas introduire d’espace entre l’opérateur et la valeur recherchée. |
