aboutsummaryrefslogtreecommitdiff
path: root/app/Models/Search.php
diff options
context:
space:
mode:
authorGravatar Alexandre Alapetite <alexandre@alapetite.fr> 2021-07-24 19:32:43 +0200
committerGravatar GitHub <noreply@github.com> 2021-07-24 19:32:43 +0200
commit705be9a6a1608ff195c0f24004d07cb8823fa6de (patch)
tree998bf3c93771e94fe470401d3b7a40a662e4e4d0 /app/Models/Search.php
parent247dfa6c1ba0f60b7cca63141c94d5754b2bd7e5 (diff)
Search labels (#3709)
* Search labels #fix https://github.com/FreshRSS/FreshRSS/issues/3704 * Documentation * Allow list without quotes * Allow boolean AND searches * Allow searching any label * fix labels alias
Diffstat (limited to 'app/Models/Search.php')
-rw-r--r--app/Models/Search.php149
1 files changed, 140 insertions, 9 deletions
diff --git a/app/Models/Search.php b/app/Models/Search.php
index 23d1024aa..20c4f540a 100644
--- a/app/Models/Search.php
+++ b/app/Models/Search.php
@@ -15,6 +15,8 @@ class FreshRSS_Search {
// The following properties are extracted from the raw input
private $feed_ids;
+ private $label_ids;
+ private $label_names;
private $intitle;
private $min_date;
private $max_date;
@@ -26,6 +28,8 @@ class FreshRSS_Search {
private $search;
private $not_feed_ids;
+ private $not_label_ids;
+ private $not_label_names;
private $not_intitle;
private $not_min_date;
private $not_max_date;
@@ -45,6 +49,8 @@ class FreshRSS_Search {
$input = preg_replace('/:&quot;(.*?)&quot;/', ':"\1"', $input);
$input = $this->parseNotFeedIds($input);
+ $input = $this->parseNotLabelIds($input);
+ $input = $this->parseNotLabelNames($input);
$input = $this->parseNotPubdateSearch($input);
$input = $this->parseNotDateSearch($input);
@@ -55,6 +61,8 @@ class FreshRSS_Search {
$input = $this->parseNotTagsSearch($input);
$input = $this->parseFeedIds($input);
+ $input = $this->parseLabelIds($input);
+ $input = $this->parseLabelNames($input);
$input = $this->parsePubdateSearch($input);
$input = $this->parseDateSearch($input);
@@ -83,6 +91,19 @@ class FreshRSS_Search {
return $this->not_feed_ids;
}
+ public function getLabelIds() {
+ return $this->label_ids;
+ }
+ public function getNotlabelIds() {
+ return $this->not_label_ids;
+ }
+ public function getLabelNames() {
+ return $this->label_names;
+ }
+ public function getNotlabelNames() {
+ return $this->not_label_names;
+ }
+
public function getIntitle() {
return $this->intitle;
}
@@ -175,12 +196,15 @@ class FreshRSS_Search {
*/
private function parseFeedIds($input) {
if (preg_match_all('/\bf:(?P<search>[0-9,]*)/', $input, $matches)) {
- $ids_lists = $matches['search'];
$input = str_replace($matches[0], '', $input);
- $ids_lists = self::removeEmptyValues($ids_lists);
- if (!empty($ids_lists[0])) {
- $this->feed_ids = explode(',', $ids_lists[0]);
- array_filter($this->feed_ids, function($v) { $v != ''; });
+ $ids_lists = $matches['search'];
+ $this->feed_ids = [];
+ foreach ($ids_lists as $ids_list) {
+ $feed_ids = explode(',', $ids_list);
+ $feed_ids = self::removeEmptyValues($feed_ids);
+ if (!empty($feed_ids)) {
+ $this->feed_ids[] = $feed_ids;
+ }
}
}
return $input;
@@ -188,12 +212,119 @@ class FreshRSS_Search {
private function parseNotFeedIds($input) {
if (preg_match_all('/[!-]f:(?P<search>[0-9,]*)/', $input, $matches)) {
+ $input = str_replace($matches[0], '', $input);
+ $ids_lists = $matches['search'];
+ $this->not_feed_ids = [];
+ foreach ($ids_lists as $ids_list) {
+ $feed_ids = explode(',', $ids_list);
+ $feed_ids = self::removeEmptyValues($feed_ids);
+ if (!empty($feed_ids)) {
+ $this->not_feed_ids[] = $feed_ids;
+ }
+ }
+ }
+ return $input;
+ }
+
+ /**
+ * Parse the search string to find tags (labels) IDs.
+ *
+ * @param string $input
+ * @return string
+ */
+ private function parseLabelIds($input) {
+ if (preg_match_all('/\b[lL]:(?P<search>[0-9,]+|[*])/', $input, $matches)) {
+ $input = str_replace($matches[0], '', $input);
+ $ids_lists = $matches['search'];
+ $this->label_ids = [];
+ foreach ($ids_lists as $ids_list) {
+ if ($ids_list === '*') {
+ $this->label_ids[] = '*';
+ break;
+ }
+ $label_ids = explode(',', $ids_list);
+ $label_ids = self::removeEmptyValues($label_ids);
+ if (!empty($label_ids)) {
+ $this->label_ids[] = $label_ids;
+ }
+ }
+ }
+ return $input;
+ }
+
+ private function parseNotLabelIds($input) {
+ if (preg_match_all('/[!-][lL]:(?P<search>[0-9,]+|[*])/', $input, $matches)) {
+ $input = str_replace($matches[0], '', $input);
$ids_lists = $matches['search'];
+ $this->not_label_ids = [];
+ foreach ($ids_lists as $ids_list) {
+ if ($ids_list === '*') {
+ $this->not_label_ids[] = '*';
+ break;
+ }
+ $label_ids = explode(',', $ids_list);
+ $label_ids = self::removeEmptyValues($label_ids);
+ if (!empty($label_ids)) {
+ $this->not_label_ids[] = $label_ids;
+ }
+ }
+ }
+ return $input;
+ }
+
+ /**
+ * Parse the search string to find tags (labels) names.
+ *
+ * @param string $input
+ * @return string
+ */
+ private function parseLabelNames($input) {
+ $names_lists = [];
+ if (preg_match_all('/\blabels?:(?P<delim>[\'"])(?P<search>.*)(?P=delim)/U', $input, $matches)) {
+ $names_lists = $matches['search'];
$input = str_replace($matches[0], '', $input);
- $ids_lists = self::removeEmptyValues($ids_lists);
- if (!empty($ids_lists[0])) {
- $this->not_feed_ids = explode(',', $ids_lists[0]);
- array_filter($this->not_feed_ids, function($v) { $v != ''; });
+ }
+ if (preg_match_all('/\blabels?:(?P<search>[^\s"]*)/', $input, $matches)) {
+ $names_lists = array_merge($names_lists, $matches['search']);
+ $input = str_replace($matches[0], '', $input);
+ }
+ if (!empty($names_lists)) {
+ $this->label_names = [];
+ foreach ($names_lists as $names_list) {
+ $names_array = explode(',', $names_list);
+ $names_array = self::removeEmptyValues($names_array);
+ if (!empty($names_array)) {
+ $this->label_names[] = $names_array;
+ }
+ }
+ }
+ return $input;
+ }
+
+ /**
+ * Parse the search string to find tags (labels) names to exclude.
+ *
+ * @param string $input
+ * @return string
+ */
+ private function parseNotLabelNames($input) {
+ $names_lists = [];
+ if (preg_match_all('/[!-]labels?:(?P<delim>[\'"])(?P<search>.*)(?P=delim)/U', $input, $matches)) {
+ $names_lists = $matches['search'];
+ $input = str_replace($matches[0], '', $input);
+ }
+ if (preg_match_all('/[!-]labels?:(?P<search>[^\s"]*)/', $input, $matches)) {
+ $names_lists = array_merge($names_lists, $matches['search']);
+ $input = str_replace($matches[0], '', $input);
+ }
+ if (!empty($names_lists)) {
+ $this->not_label_names = [];
+ foreach ($names_lists as $names_list) {
+ $names_array = explode(',', $names_list);
+ $names_array = self::removeEmptyValues($names_array);
+ if (!empty($names_array)) {
+ $this->not_label_names[] = $names_array;
+ }
}
}
return $input;