aboutsummaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/Models/Entry.php12
-rw-r--r--app/Models/EntryDAO.php23
-rw-r--r--app/Models/Search.php50
3 files changed, 85 insertions, 0 deletions
diff --git a/app/Models/Entry.php b/app/Models/Entry.php
index 1f99a8345..296c3860f 100644
--- a/app/Models/Entry.php
+++ b/app/Models/Entry.php
@@ -654,6 +654,18 @@ HTML;
if ($ok && $filter->getNotMaxPubdate() !== null) {
$ok &= $this->date > $filter->getNotMaxPubdate();
}
+ if ($ok && $filter->getMinUserdate() !== null) {
+ $ok &= $this->lastUserModified >= $filter->getMinUserdate();
+ }
+ if ($ok && $filter->getNotMinUserdate() !== null) {
+ $ok &= $this->lastUserModified < $filter->getNotMinUserdate();
+ }
+ if ($ok && $filter->getMaxUserdate() !== null) {
+ $ok &= $this->lastUserModified <= $filter->getMaxUserdate();
+ }
+ if ($ok && $filter->getNotMaxUserdate() !== null) {
+ $ok &= $this->lastUserModified > $filter->getNotMaxUserdate();
+ }
if ($ok && $filter->getFeedIds() !== null) {
$ok &= in_array($this->feedId, $filter->getFeedIds(), true);
}
diff --git a/app/Models/EntryDAO.php b/app/Models/EntryDAO.php
index 6eefd684c..c9fae7923 100644
--- a/app/Models/EntryDAO.php
+++ b/app/Models/EntryDAO.php
@@ -906,6 +906,14 @@ SQL;
$sub_search .= 'AND ' . $alias . 'date <= ? ';
$values[] = $filter->getMaxPubdate();
}
+ if ($filter->getMinUserdate() !== null) {
+ $sub_search .= 'AND ' . $alias . '`lastUserModified` >= ? ';
+ $values[] = $filter->getMinUserdate();
+ }
+ if ($filter->getMaxUserdate() !== null) {
+ $sub_search .= 'AND ' . $alias . '`lastUserModified` <= ? ';
+ $values[] = $filter->getMaxUserdate();
+ }
//Negation of date intervals must be combined by OR
if ($filter->getNotMinDate() !== null || $filter->getNotMaxDate() !== null) {
@@ -938,6 +946,21 @@ SQL;
}
$sub_search .= ') ';
}
+ if ($filter->getNotMinUserdate() !== null || $filter->getNotMaxUserdate() !== null) {
+ $sub_search .= 'AND (';
+ if ($filter->getNotMinUserdate() !== null) {
+ $sub_search .= $alias . '`lastUserModified` < ?';
+ $values[] = $filter->getNotMinUserdate();
+ if ($filter->getNotMaxUserdate()) {
+ $sub_search .= ' OR ';
+ }
+ }
+ if ($filter->getNotMaxUserdate() !== null) {
+ $sub_search .= $alias . '`lastUserModified` > ?';
+ $values[] = $filter->getNotMaxUserdate();
+ }
+ $sub_search .= ') ';
+ }
if ($filter->getFeedIds() !== null) {
$sub_search .= 'AND ' . $alias . 'id_feed IN (';
diff --git a/app/Models/Search.php b/app/Models/Search.php
index e88f745ce..a14f1bf1a 100644
--- a/app/Models/Search.php
+++ b/app/Models/Search.php
@@ -43,6 +43,10 @@ class FreshRSS_Search implements \Stringable {
private $min_pubdate = null;
/** @var int|false|null */
private $max_pubdate = null;
+ /** @var int|false|null */
+ private $min_userdate = null;
+ /** @var int|false|null */
+ private $max_userdate = null;
/** @var list<string>|null */
private ?array $inurl = null;
/** @var list<string>|null */
@@ -86,6 +90,10 @@ class FreshRSS_Search implements \Stringable {
private $not_min_pubdate = null;
/** @var int|false|null */
private $not_max_pubdate = null;
+ /** @var int|false|null */
+ private $not_min_userdate = null;
+ /** @var int|false|null */
+ private $not_max_userdate = null;
/** @var list<string>|null */
private ?array $not_inurl = null;
/** @var list<string>|null */
@@ -115,6 +123,7 @@ class FreshRSS_Search implements \Stringable {
$input = $this->parseNotLabelIds($input);
$input = $this->parseNotLabelNames($input);
+ $input = $this->parseNotUserdateSearch($input);
$input = $this->parseNotPubdateSearch($input);
$input = $this->parseNotDateSearch($input);
@@ -130,6 +139,7 @@ class FreshRSS_Search implements \Stringable {
$input = $this->parseLabelIds($input);
$input = $this->parseLabelNames($input);
+ $input = $this->parseUserdateSearch($input);
$input = $this->parsePubdateSearch($input);
$input = $this->parseDateSearch($input);
@@ -265,6 +275,20 @@ class FreshRSS_Search implements \Stringable {
return $this->not_max_pubdate ?: null;
}
+ public function getMinUserdate(): ?int {
+ return $this->min_userdate ?: null;
+ }
+ public function getNotMinUserdate(): ?int {
+ return $this->not_min_userdate ?: null;
+ }
+
+ public function getMaxUserdate(): ?int {
+ return $this->max_userdate ?: null;
+ }
+ public function getNotMaxUserdate(): ?int {
+ return $this->not_max_userdate ?: null;
+ }
+
/** @return list<string>|null */
public function getInurl(): ?array {
return $this->inurl;
@@ -799,6 +823,32 @@ class FreshRSS_Search implements \Stringable {
}
/**
+ * Parse the search string to find userdate keyword and the search related to it.
+ * The search is the first word following the keyword.
+ */
+ private function parseUserdateSearch(string $input): string {
+ if (preg_match_all('/\\buserdate:(?P<search>[^\\s]*)/', $input, $matches)) {
+ $input = str_replace($matches[0], '', $input);
+ $dates = self::removeEmptyValues($matches['search']);
+ if (!empty($dates[0])) {
+ [$this->min_userdate, $this->max_userdate] = parseDateInterval($dates[0]);
+ }
+ }
+ return $input;
+ }
+
+ private function parseNotUserdateSearch(string $input): string {
+ if (preg_match_all('/(?<=[\\s(]|^)[!-]userdate:(?P<search>[^\\s]*)/', $input, $matches)) {
+ $input = str_replace($matches[0], '', $input);
+ $dates = self::removeEmptyValues($matches['search']);
+ if (!empty($dates[0])) {
+ [$this->not_min_userdate, $this->not_max_userdate] = parseDateInterval($dates[0]);
+ }
+ }
+ return $input;
+ }
+
+ /**
* Parse the search string to find tags keyword (# followed by a word)
* and the search related to it.
* The search is the first word following the #.