diff options
| author | 2021-07-24 19:32:43 +0200 | |
|---|---|---|
| committer | 2021-07-24 19:32:43 +0200 | |
| commit | 705be9a6a1608ff195c0f24004d07cb8823fa6de (patch) | |
| tree | 998bf3c93771e94fe470401d3b7a40a662e4e4d0 /app/Models/Search.php | |
| parent | 247dfa6c1ba0f60b7cca63141c94d5754b2bd7e5 (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.php | 149 |
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('/:"(.*?)"/', ':"\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; |
