aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Alexandre Alapetite <alexandre@alapetite.fr> 2021-12-31 13:10:41 +0100
committerGravatar GitHub <noreply@github.com> 2021-12-31 13:10:41 +0100
commitfb15a2d8048ff66db5cb73b0dfb3a5b6a052e1db (patch)
treeac778c9e2175c7bb3b6dcf15cbe6af562c7713b8
parentafb3035bc6a50b8f6334f2729e3a7f568b429022 (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.php23
-rw-r--r--app/Models/Search.php49
-rw-r--r--docs/en/users/03_Main_view.md1
-rw-r--r--docs/fr/users/03_Main_view.md1
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('/:&quot;(.*?)&quot;/', ':"\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.