diff options
Diffstat (limited to 'app/Models/Search.php')
| -rw-r--r-- | app/Models/Search.php | 71 |
1 files changed, 70 insertions, 1 deletions
diff --git a/app/Models/Search.php b/app/Models/Search.php index 5b88b1f3b..d425fcee8 100644 --- a/app/Models/Search.php +++ b/app/Models/Search.php @@ -29,6 +29,10 @@ class FreshRSS_Search implements \Stringable { private ?array $intitle = null; /** @var list<string>|null */ private ?array $intitle_regex = null; + /** @var list<string>|null */ + private ?array $intext = null; + /** @var list<string>|null */ + private ?array $intext_regex = null; /** @var int|false|null */ private $min_date = null; /** @var int|false|null */ @@ -66,6 +70,10 @@ class FreshRSS_Search implements \Stringable { private ?array $not_intitle = null; /** @var list<string>|null */ private ?array $not_intitle_regex = null; + /** @var list<string>|null */ + private ?array $not_intext = null; + /** @var list<string>|null */ + private ?array $not_intext_regex = null; /** @var int|false|null */ private $not_min_date = null; /** @var int|false|null */ @@ -106,6 +114,7 @@ class FreshRSS_Search implements \Stringable { $input = $this->parseNotDateSearch($input); $input = $this->parseNotIntitleSearch($input); + $input = $this->parseNotIntextSearch($input); $input = $this->parseNotAuthorSearch($input); $input = $this->parseNotInurlSearch($input); $input = $this->parseNotTagsSearch($input); @@ -119,6 +128,7 @@ class FreshRSS_Search implements \Stringable { $input = $this->parseDateSearch($input); $input = $this->parseIntitleSearch($input); + $input = $this->parseIntextSearch($input); $input = $this->parseAuthorSearch($input); $input = $this->parseInurlSearch($input); $input = $this->parseTagsSearch($input); @@ -189,6 +199,23 @@ class FreshRSS_Search implements \Stringable { return $this->not_intitle_regex; } + /** @return list<string>|null */ + public function getIntext(): ?array { + return $this->intext; + } + /** @return list<string>|null */ + public function getIntextRegex(): ?array { + return $this->intext_regex; + } + /** @return list<string>|null */ + public function getNotIntext(): ?array { + return $this->not_intext; + } + /** @return list<string>|null */ + public function getNotIntextRegex(): ?array { + return $this->not_intext_regex; + } + public function getMinDate(): ?int { return $this->min_date ?: null; } @@ -494,7 +521,6 @@ class FreshRSS_Search implements \Stringable { /** * Parse the search string to find intitle keyword and the search related to it. - * The search is the first word following the keyword. */ private function parseIntitleSearch(string $input): string { if (preg_match_all('#\\bintitle:(?P<search>/.*?(?<!\\\\)/[im]*)#', $input, $matches)) { @@ -537,6 +563,49 @@ class FreshRSS_Search implements \Stringable { } /** + * Parse the search string to find intext keyword and the search related to it. + */ + private function parseIntextSearch(string $input): string { + if (preg_match_all('#\\bintext:(?P<search>/.*?(?<!\\\\)/[im]*)#', $input, $matches)) { + $this->intext_regex = self::htmlspecialchars_decodes($matches['search']); + $input = str_replace($matches[0], '', $input); + } + if (preg_match_all('/\\bintext:(?P<delim>[\'"])(?P<search>.*)(?P=delim)/U', $input, $matches)) { + $this->intext = $matches['search']; + $input = str_replace($matches[0], '', $input); + } + if (preg_match_all('/\\bintext:(?P<search>[^\s"]*)/', $input, $matches)) { + $this->intext = array_merge($this->intext ?? [], $matches['search']); + $input = str_replace($matches[0], '', $input); + } + $this->intext = self::removeEmptyValues($this->intext); + if (empty($this->intext)) { + $this->intext = null; + } + return $input; + } + + private function parseNotIntextSearch(string $input): string { + if (preg_match_all('#(?<=[\\s(]|^)[!-]intext:(?P<search>/.*?(?<!\\\\)/[im]*)#', $input, $matches)) { + $this->not_intext_regex = self::htmlspecialchars_decodes($matches['search']); + $input = str_replace($matches[0], '', $input); + } + if (preg_match_all('/(?<=[\\s(]|^)[!-]intext:(?P<delim>[\'"])(?P<search>.*)(?P=delim)/U', $input, $matches)) { + $this->not_intext = $matches['search']; + $input = str_replace($matches[0], '', $input); + } + if (preg_match_all('/(?<=[\\s(]|^)[!-]intext:(?P<search>[^\s"]*)/', $input, $matches)) { + $this->not_intext = array_merge($this->not_intext ?? [], $matches['search']); + $input = str_replace($matches[0], '', $input); + } + $this->not_intext = self::removeEmptyValues($this->not_intext); + if (empty($this->not_intext)) { + $this->not_intext = null; + } + return $input; + } + + /** * Parse the search string to find author keyword and the search related to it. * The search is the first word following the keyword except when using * a delimiter. Supported delimiters are single quote (') and double quotes ("). |
