aboutsummaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGravatar Alexandre Alapetite <alexandre@alapetite.fr> 2019-03-23 22:52:47 +0100
committerGravatar GitHub <noreply@github.com> 2019-03-23 22:52:47 +0100
commit1804c0e0bc095487b9a1ad13cbc9f55f6cef2a2a (patch)
tree4a250b570a3d0adbfe5f520533c7719646d97c2c /app
parente7a57915f9c90c144d95918048d2523418866921 (diff)
Filter actions (#2275)
* Draft of filter actions * Travis * Implement UI + finish logic * Travis
Diffstat (limited to 'app')
-rwxr-xr-xapp/Controllers/feedController.php27
-rw-r--r--app/Controllers/subscriptionController.php4
-rw-r--r--app/Models/Entry.php113
-rw-r--r--app/Models/Feed.php104
-rw-r--r--app/Models/FilterAction.php45
-rw-r--r--app/i18n/cz/sub.php4
-rw-r--r--app/i18n/de/sub.php4
-rw-r--r--app/i18n/en/sub.php4
-rwxr-xr-xapp/i18n/es/sub.php4
-rw-r--r--app/i18n/fr/sub.php4
-rw-r--r--app/i18n/he/sub.php4
-rw-r--r--app/i18n/it/sub.php4
-rw-r--r--app/i18n/kr/sub.php4
-rw-r--r--app/i18n/nl/sub.php4
-rw-r--r--app/i18n/oc/sub.php4
-rw-r--r--app/i18n/pt-br/sub.php4
-rw-r--r--app/i18n/ru/sub.php4
-rw-r--r--app/i18n/tr/sub.php4
-rw-r--r--app/i18n/zh-cn/sub.php4
-rw-r--r--app/views/helpers/feed/update.phtml13
20 files changed, 345 insertions, 17 deletions
diff --git a/app/Controllers/feedController.php b/app/Controllers/feedController.php
index 7f36e0388..0aed9b0a1 100755
--- a/app/Controllers/feedController.php
+++ b/app/Controllers/feedController.php
@@ -289,7 +289,8 @@ class FreshRSS_feed_Controller extends Minz_ActionController {
}
$ttl = $feed->ttl();
if ((!$simplePiePush) && (!$feed_id) &&
- ($feed->lastUpdate() + 10 >= time() - ($ttl == FreshRSS_Feed::TTL_DEFAULT ? FreshRSS_Context::$user_conf->ttl_default : $ttl))) {
+ ($feed->lastUpdate() + 10 >= time() - (
+ $ttl == FreshRSS_Feed::TTL_DEFAULT ? FreshRSS_Context::$user_conf->ttl_default : $ttl))) {
//Too early to refresh from source, but check whether the feed was updated by another user
$mtime = $feed->cacheModifiedTime();
if ($feed->lastUpdate() + 10 >= $mtime) {
@@ -347,8 +348,8 @@ class FreshRSS_feed_Controller extends Minz_ActionController {
$entry_date = $entry->date(true);
if (isset($existingHashForGuids[$entry->guid()])) {
$existingHash = $existingHashForGuids[$entry->guid()];
- if (strcasecmp($existingHash, $entry->hash()) === 0 || trim($existingHash, '0') == '') {
- //This entry already exists and is unchanged. TODO: Remove the test with the zero'ed hash in FreshRSS v1.3
+ if (strcasecmp($existingHash, $entry->hash()) === 0) {
+ //This entry already exists and is unchanged.
$oldGuids[] = $entry->guid();
} else { //This entry already exists but has been updated
//Minz_Log::debug('Entry with GUID `' . $entry->guid() . '` updated in feed ' . $feed->url(false) .
@@ -374,17 +375,14 @@ class FreshRSS_feed_Controller extends Minz_ActionController {
// This entry should not be added considering configuration and date.
$oldGuids[] = $entry->guid();
} else {
- $read_upon_reception = $feed->attributes('read_upon_reception') !== null ? (
- $feed->attributes('read_upon_reception')
- ) : FreshRSS_Context::$user_conf->mark_when['reception'];
$id = uTimeString();
$entry->_id($id);
if ($entry_date < $date_min) {
$entry->_isRead(true); //Old article that was not in database. Probably an error, so mark as read
- } else {
- $entry->_isRead($read_upon_reception);
}
+ $entry->applyFilterActions();
+
$entry = Minz_ExtensionManager::callHook('entry_before_insert', $entry);
if ($entry === null) {
// An extension has returned a null value, there is nothing to insert.
@@ -392,7 +390,8 @@ class FreshRSS_feed_Controller extends Minz_ActionController {
}
if ($pubSubHubbubEnabled && !$simplePiePush) { //We use push, but have discovered an article by pull!
- $text = 'An article was discovered by pull although we use PubSubHubbub!: Feed ' . $url . ' GUID ' . $entry->guid();
+ $text = 'An article was discovered by pull although we use PubSubHubbub!: Feed ' . $url .
+ ' GUID ' . $entry->guid();
Minz_Log::warning($text, PSHB_LOG);
Minz_Log::warning($text);
$pubSubHubbubEnabled = false;
@@ -416,9 +415,7 @@ class FreshRSS_feed_Controller extends Minz_ActionController {
$entryDAO->beginTransaction();
}
- $nb = $entryDAO->cleanOldEntries($feed->id(),
- $date_min,
- max($feed_history, count($entries) + 10));
+ $nb = $entryDAO->cleanOldEntries($feed->id(), $date_min, max($feed_history, count($entries) + 10));
if ($nb > 0) {
$needFeedCacheRefresh = true;
Minz_Log::debug($nb . ' old entries cleaned in feed [' . $feed->url(false) . ']');
@@ -598,11 +595,9 @@ class FreshRSS_feed_Controller extends Minz_ActionController {
if (self::moveFeed($feed_id, $cat_id)) {
// TODO: return something useful
// Log a notice to prevent "Empty IF statement" warning in PHP_CodeSniffer
- Minz_Log::notice('Moved feed `' . $feed_id . '` ' .
- 'in the category `' . $cat_id . '`');;
+ Minz_Log::notice('Moved feed `' . $feed_id . '` in the category `' . $cat_id . '`');
} else {
- Minz_Log::warning('Cannot move feed `' . $feed_id . '` ' .
- 'in the category `' . $cat_id . '`');
+ Minz_Log::warning('Cannot move feed `' . $feed_id . '` in the category `' . $cat_id . '`');
Minz_Error::error(404);
}
}
diff --git a/app/Controllers/subscriptionController.php b/app/Controllers/subscriptionController.php
index 62fb3d384..9cf41ed0b 100644
--- a/app/Controllers/subscriptionController.php
+++ b/app/Controllers/subscriptionController.php
@@ -110,6 +110,8 @@ class FreshRSS_subscription_Controller extends Minz_ActionController {
$feed->_attributes('timeout', null);
}
+ $feed->_filtersAction('read', preg_split('/[\n\r]+/', Minz_Request::param('filteractions_read', '')));
+
$values = array(
'name' => Minz_Request::param('name', ''),
'description' => sanitizeHTML(Minz_Request::param('description', '', true)),
@@ -121,7 +123,7 @@ class FreshRSS_subscription_Controller extends Minz_ActionController {
'httpAuth' => $httpAuth,
'keep_history' => intval(Minz_Request::param('keep_history', FreshRSS_Feed::KEEP_HISTORY_DEFAULT)),
'ttl' => $ttl * ($mute ? -1 : 1),
- 'attributes' => $feed->attributes()
+ 'attributes' => $feed->attributes(),
);
invalidateHttpCache();
diff --git a/app/Models/Entry.php b/app/Models/Entry.php
index f2f3d08fe..3bb977283 100644
--- a/app/Models/Entry.php
+++ b/app/Models/Entry.php
@@ -185,6 +185,119 @@ class FreshRSS_Entry extends Minz_Model {
$this->tags = $value;
}
+ public function matches($booleanSearch) {
+ if (!$booleanSearch || count($booleanSearch->searches()) <= 0) {
+ return true;
+ }
+ foreach ($booleanSearch->searches() as $filter) {
+ $ok = true;
+ if ($ok && $filter->getMinPubdate()) {
+ $ok &= $this->date >= $filter->getMinPubdate();
+ }
+ if ($ok && $filter->getMaxPubdate()) {
+ $ok &= $this->date <= $filter->getMaxPubdate();
+ }
+ if ($ok && $filter->getMinDate()) {
+ $ok &= strnatcmp($this->id, $filter->getMinDate() . '000000') >= 0;
+ }
+ if ($ok && $filter->getMaxDate()) {
+ $ok &= strnatcmp($this->id, $filter->getMaxDate() . '000000') <= 0;
+ }
+ if ($ok && $filter->getInurl()) {
+ foreach ($filter->getInurl() as $url) {
+ $ok &= stripos($this->link, $url) !== false;
+ }
+ }
+ if ($ok && $filter->getNotInurl()) {
+ foreach ($filter->getNotInurl() as $url) {
+ $ok &= stripos($this->link, $url) === false;
+ }
+ }
+ if ($ok && $filter->getAuthor()) {
+ foreach ($filter->getAuthor() as $author) {
+ $ok &= stripos($this->authors, $author) !== false;
+ }
+ }
+ if ($ok && $filter->getNotAuthor()) {
+ foreach ($filter->getNotAuthor() as $author) {
+ $ok &= stripos($this->authors, $author) === false;
+ }
+ }
+ if ($ok && $filter->getIntitle()) {
+ foreach ($filter->getIntitle() as $title) {
+ $ok &= stripos($this->title, $title) !== false;
+ }
+ }
+ if ($ok && $filter->getNotIntitle()) {
+ foreach ($filter->getNotIntitle() as $title) {
+ $ok &= stripos($this->title, $title) === false;
+ }
+ }
+ if ($ok && $filter->getTags()) {
+ foreach ($filter->getTags() as $tag2) {
+ $found = false;
+ foreach ($this->tags as $tag1) {
+ if (strcasecmp($tag1, $tag2) === 0) {
+ $found = true;
+ }
+ }
+ $ok &= $found;
+ }
+ }
+ if ($ok && $filter->getNotTags()) {
+ foreach ($filter->getNotTags() as $tag2) {
+ $found = false;
+ foreach ($this->tags as $tag1) {
+ if (strcasecmp($tag1, $tag2) === 0) {
+ $found = true;
+ }
+ }
+ $ok &= !$found;
+ }
+ }
+ if ($ok && $filter->getSearch()) {
+ foreach ($filter->getSearch() as $needle) {
+ $ok &= (stripos($this->title, $needle) !== false || stripos($this->content, $needle) !== false);
+ }
+ }
+ if ($ok && $filter->getNotSearch()) {
+ foreach ($filter->getNotSearch() as $needle) {
+ $ok &= (stripos($this->title, $needle) === false && stripos($this->content, $needle) === false);
+ }
+ }
+ if ($ok) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public function applyFilterActions() {
+ if ($this->feed != null) {
+ if ($this->feed->attributes('read_upon_reception') ||
+ ($this->feed->attributes('read_upon_reception') === null && FreshRSS_Context::$user_conf->mark_when['reception'])) {
+ $this->_isRead(true);
+ }
+ foreach ($this->feed->filterActions() as $filterAction) {
+ if ($this->matches($filterAction->booleanSearch())) {
+ foreach ($filterAction->actions() as $action => $params) {
+ switch ($action) {
+ case 'read':
+ $this->_isRead(true);
+ break;
+ case 'star':
+ $this->_is_favorite(true);
+ break;
+ case 'label':
+ //TODO: Implement more actions
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
public function isDay($day, $today) {
$date = $this->dateAdded(true);
switch ($day) {
diff --git a/app/Models/Feed.php b/app/Models/Feed.php
index b21a8bbbe..89989236c 100644
--- a/app/Models/Feed.php
+++ b/app/Models/Feed.php
@@ -32,6 +32,7 @@ class FreshRSS_Feed extends Minz_Model {
private $lockPath = '';
private $hubUrl = '';
private $selfUrl = '';
+ private $filterActions = null;
public function __construct($url, $validate = true) {
if ($validate) {
@@ -498,6 +499,109 @@ class FreshRSS_Feed extends Minz_Model {
@unlink($this->lockPath);
}
+ public function filterActions() {
+ if ($this->filterActions == null) {
+ $this->filterActions = array();
+ $filters = $this->attributes('filters');
+ if (is_array($filters)) {
+ foreach ($filters as $filter) {
+ $filterAction = FreshRSS_FilterAction::fromJSON($filter);
+ if ($filterAction != null) {
+ $this->filterActions[] = $filterAction;
+ }
+ }
+ }
+ }
+ return $this->filterActions;
+ }
+
+ private function _filterActions($filterActions) {
+ $this->filterActions = $filterActions;
+ if (is_array($this->filterActions) && !empty($this->filterActions)) {
+ $this->_attributes('filters', array_map(function ($af) {
+ return $af == null ? null : $af->toJSON();
+ }, $this->filterActions));
+ } else {
+ $this->_attributes('filters', null);
+ }
+ }
+
+ public function filtersAction($action) {
+ $action = trim($action);
+ if ($action == '') {
+ return array();
+ }
+ $filters = array();
+ $filterActions = $this->filterActions();
+ for ($i = count($filterActions) - 1; $i >= 0; $i--) {
+ $filterAction = $filterActions[$i];
+ if ($filterAction != null && $filterAction->booleanSearch() != null &&
+ $filterAction->actions() != null && in_array($action, $filterAction->actions(), true)) {
+ $filters[] = $filterAction->booleanSearch();
+ }
+ }
+ return $filters;
+ }
+
+ public function _filtersAction($action, $filters) {
+ $action = trim($action);
+ if ($action == '' || !is_array($filters)) {
+ return false;
+ }
+ $filters = array_unique(array_map('trim', $filters));
+ $filterActions = $this->filterActions();
+
+ //Check existing filters
+ for ($i = count($filterActions) - 1; $i >= 0; $i--) {
+ $filterAction = $filterActions[$i];
+ if ($filterAction == null || !is_array($filterAction->actions()) ||
+ $filterAction->booleanSearch() == null || trim($filterAction->booleanSearch()->getRawInput()) == '') {
+ array_splice($filterAction, $i, 1);
+ continue;
+ }
+ $actions = $filterAction->actions();
+ //Remove existing rules with same action
+ for ($j = count($actions) - 1; $j >= 0; $j--) {
+ if ($actions[$j] === $action) {
+ array_splice($actions, $j, 1);
+ }
+ }
+ //Update existing filter with new action
+ for ($k = count($filters) - 1; $k >= 0; $k --) {
+ $filter = $filters[$k];
+ if ($filter === $filterAction->booleanSearch()->getRawInput()) {
+ $actions[] = $action;
+ array_splice($filters, $k, 1);
+ }
+ }
+ //Save result
+ if (empty($actions)) {
+ array_splice($filterActions, $i, 1);
+ } else {
+ $filterAction->_actions($actions);
+ }
+ }
+
+ //Add new filters
+ for ($k = count($filters) - 1; $k >= 0; $k --) {
+ $filter = $filters[$k];
+ if ($filter != '') {
+ $filterAction = FreshRSS_FilterAction::fromJSON(array(
+ 'search' => $filter,
+ 'actions' => array($action),
+ ));
+ if ($filterAction != null) {
+ $filterActions[] = $filterAction;
+ }
+ }
+ }
+
+ if (empty($filterActions)) {
+ $filterActions = null;
+ }
+ $this->_filterActions($filterActions);
+ }
+
//<WebSub>
public function pubSubHubbubEnabled() {
diff --git a/app/Models/FilterAction.php b/app/Models/FilterAction.php
new file mode 100644
index 000000000..23a45d14e
--- /dev/null
+++ b/app/Models/FilterAction.php
@@ -0,0 +1,45 @@
+<?php
+
+class FreshRSS_FilterAction {
+
+ private $booleanSearch = null;
+ private $actions = null;
+
+ private function __construct($booleanSearch, $actions) {
+ $this->booleanSearch = $booleanSearch;
+ $this->_actions($actions);
+ }
+
+ public function booleanSearch() {
+ return $this->booleanSearch;
+ }
+
+ public function actions() {
+ return $this->actions;
+ }
+
+ public function _actions($actions) {
+ if (is_array($actions)) {
+ $this->actions = array_unique($actions);
+ } else {
+ $this->actions = null;
+ }
+ }
+
+ public function toJSON() {
+ if (is_array($this->actions) && $this->booleanSearch != null) {
+ return array(
+ 'search' => $this->booleanSearch->getRawInput(),
+ 'actions' => $this->actions,
+ );
+ }
+ return '';
+ }
+
+ public static function fromJSON($json) {
+ if (!empty($json['search']) && !empty($json['actions']) && is_array($json['actions'])) {
+ return new FreshRSS_FilterAction(new FreshRSS_BooleanSearch($json['search']), $json['actions']);
+ }
+ return null;
+ }
+}
diff --git a/app/i18n/cz/sub.php b/app/i18n/cz/sub.php
index 5b5634fed..2e81c928d 100644
--- a/app/i18n/cz/sub.php
+++ b/app/i18n/cz/sub.php
@@ -33,6 +33,10 @@ return array(
'description' => 'Popis',
'empty' => 'Kanál je prázdný. Ověřte prosím zda je ještě autorem udržován.',
'error' => 'Vyskytl se problém s kanálem. Ověřte že je vždy dostupný, prosím, a poté jej aktualizujte.',
+ 'filteractions' => array(
+ '_' => 'Filter actions', //TODO - Translation
+ 'help' => 'Write one search filter per line.', //TODO - Translation
+ ),
'informations' => 'Informace',
'keep_history' => 'Zachovat tento minimální počet článků',
'moved_category_deleted' => 'Po smazání kategorie budou v ní obsažené kanály automaticky přesunuty do <em>%s</em>.',
diff --git a/app/i18n/de/sub.php b/app/i18n/de/sub.php
index 27e893177..bd050671e 100644
--- a/app/i18n/de/sub.php
+++ b/app/i18n/de/sub.php
@@ -33,6 +33,10 @@ return array(
'description' => 'Beschreibung',
'empty' => 'Dieser Feed ist leer. Bitte stellen Sie sicher, dass er noch gepflegt wird.',
'error' => 'Dieser Feed ist auf ein Problem gestoßen. Bitte stellen Sie sicher, dass er immer lesbar ist und aktualisieren Sie ihn dann.',
+ 'filteractions' => array(
+ '_' => 'Filter actions', //TODO - Translation
+ 'help' => 'Write one search filter per line.', //TODO - Translation
+ ),
'informations' => 'Information',
'keep_history' => 'Minimale Anzahl an Artikeln, die behalten wird',
'moved_category_deleted' => 'Wenn Sie eine Kategorie entfernen, werden deren Feeds automatisch in die Kategorie <em>%s</em> eingefügt.',
diff --git a/app/i18n/en/sub.php b/app/i18n/en/sub.php
index 4efd81ba4..f11eb9b99 100644
--- a/app/i18n/en/sub.php
+++ b/app/i18n/en/sub.php
@@ -33,6 +33,10 @@ return array(
'description' => 'Description',
'empty' => 'This feed is empty. Please verify that it is still maintained.',
'error' => 'This feed has encountered a problem. Please verify that it is always reachable then update it.',
+ 'filteractions' => array(
+ '_' => 'Filter actions',
+ 'help' => 'Write one search filter per line.',
+ ),
'informations' => 'Information',
'keep_history' => 'Minimum number of articles to keep',
'moved_category_deleted' => 'When you delete a category, its feeds are automatically classified under <em>%s</em>.',
diff --git a/app/i18n/es/sub.php b/app/i18n/es/sub.php
index 854984891..c0526106f 100755
--- a/app/i18n/es/sub.php
+++ b/app/i18n/es/sub.php
@@ -33,6 +33,10 @@ return array(
'description' => 'Descripción',
'empty' => 'La fuente está vacía. Por favor, verifica que siga activa.',
'error' => 'Hay un problema con esta fuente. Por favor, veritica que esté disponible y prueba de nuevo.',
+ 'filteractions' => array(
+ '_' => 'Filter actions', //TODO - Translation
+ 'help' => 'Write one search filter per line.', //TODO - Translation
+ ),
'informations' => 'Información',
'keep_history' => 'Número mínimo de artículos a conservar',
'moved_category_deleted' => 'Al borrar una categoría todas sus fuentes pasan automáticamente a la categoría <em>%s</em>.',
diff --git a/app/i18n/fr/sub.php b/app/i18n/fr/sub.php
index d9964ac6e..b71019faa 100644
--- a/app/i18n/fr/sub.php
+++ b/app/i18n/fr/sub.php
@@ -33,6 +33,10 @@ return array(
'description' => 'Description',
'empty' => 'Ce flux est vide. Veuillez vérifier qu’il est toujours maintenu.',
'error' => 'Ce flux a rencontré un problème. Veuillez vérifier qu’il est toujours accessible puis actualisez-le.',
+ 'filteractions' => array(
+ '_' => 'Filtres d’action',
+ 'help' => 'Écrivez une recherche par ligne.',
+ ),
'informations' => 'Informations',
'keep_history' => 'Nombre minimum d’articles à conserver',
'moved_category_deleted' => 'Lors de la suppression d’une catégorie, ses flux seront automatiquement classés dans <em>%s</em>.',
diff --git a/app/i18n/he/sub.php b/app/i18n/he/sub.php
index 6d824e349..bb2025bc3 100644
--- a/app/i18n/he/sub.php
+++ b/app/i18n/he/sub.php
@@ -33,6 +33,10 @@ return array(
'description' => 'תיאור',
'empty' => 'הזנה זו ריקה. אנא ודאו שהיא עדיין מתוחזקת.',
'error' => 'הזנה זו נתקלה בשגיאה, אנא ודאו שהיא תקינה ואז נסו שנית.',
+ 'filteractions' => array(
+ '_' => 'Filter actions', //TODO - Translation
+ 'help' => 'Write one search filter per line.', //TODO - Translation
+ ),
'informations' => 'מידע',
'keep_history' => 'מסםר מינימלי של מאמרים לשמור',
'moved_category_deleted' => 'כאשר הקטגוריה נמחקת ההזנות שבתוכה אוטומטית מקוטלגות תחת <em>%s</em>.',
diff --git a/app/i18n/it/sub.php b/app/i18n/it/sub.php
index ff7fa6f1d..bf279e059 100644
--- a/app/i18n/it/sub.php
+++ b/app/i18n/it/sub.php
@@ -33,6 +33,10 @@ return array(
'description' => 'Descrizione',
'empty' => 'Questo feed non contiene articoli. Per favore verifica il sito direttamente.',
'error' => 'Questo feed ha generato un errore. Per favore verifica se ancora disponibile.',
+ 'filteractions' => array(
+ '_' => 'Filter actions', //TODO - Translation
+ 'help' => 'Write one search filter per line.', //TODO - Translation
+ ),
'informations' => 'Informazioni',
'keep_history' => 'Numero minimo di articoli da mantenere',
'moved_category_deleted' => 'Cancellando una categoria i feed al suo interno verranno classificati automaticamente come <em>%s</em>.',
diff --git a/app/i18n/kr/sub.php b/app/i18n/kr/sub.php
index 9edd85818..151775c1c 100644
--- a/app/i18n/kr/sub.php
+++ b/app/i18n/kr/sub.php
@@ -33,6 +33,10 @@ return array(
'description' => '설명',
'empty' => '이 피드는 비어있습니다. 피드가 계속 운영되고 있는지 확인하세요.',
'error' => '이 피드에 문제가 발생했습니다. 이 피드에 접근 권한이 있는지 확인하세요.',
+ 'filteractions' => array(
+ '_' => 'Filter actions', //TODO - Translation
+ 'help' => 'Write one search filter per line.', //TODO - Translation
+ ),
'informations' => '정보',
'keep_history' => '최소 유지 글 개수',
'moved_category_deleted' => '카테고리를 삭제하면, 해당 카테고리 아래에 있던 피드들은 자동적으로 <em>%s</em> 아래로 분류됩니다.',
diff --git a/app/i18n/nl/sub.php b/app/i18n/nl/sub.php
index 1d6c9f806..8ba9c020d 100644
--- a/app/i18n/nl/sub.php
+++ b/app/i18n/nl/sub.php
@@ -33,6 +33,10 @@ return array(
'description' => 'Omschrijving',
'empty' => 'Deze feed is leeg. Controleer of deze nog actueel is.',
'error' => 'Deze feed heeft problemen. Verifieer a.u.b het doeladres en actualiseer het.',
+ 'filteractions' => array(
+ '_' => 'Filter actions', //TODO - Translation
+ 'help' => 'Write one search filter per line.', //TODO - Translation
+ ),
'informations' => 'Informatie',
'keep_history' => 'Minimum aantal artikelen om te houden',
'moved_category_deleted' => 'Als u een categorie verwijderd, worden de feeds automatisch geclassificeerd onder <em>%s</em>.',
diff --git a/app/i18n/oc/sub.php b/app/i18n/oc/sub.php
index fc5a0cc1f..51ee0d43f 100644
--- a/app/i18n/oc/sub.php
+++ b/app/i18n/oc/sub.php
@@ -32,6 +32,10 @@ return array(
'description' => 'Descripcion',
'empty' => 'Aqueste flux es void. Assegurats-vos qu’es totjorn mantengut.',
'error' => 'Aqueste flux a rescontrat un problèma. Volgatz verificar que siá totjorn accessible puèi actualizatz-lo.',
+ 'filteractions' => array(
+ '_' => 'Filter actions', //TODO - Translation
+ 'help' => 'Write one search filter per line.', //TODO - Translation
+ ),
'informations' => 'Informacions',
'keep_history' => 'Nombre minimum d’articles de servar',
'moved_category_deleted' => 'Quand escafatz una categoria, sos fluxes son automaticament classats dins <em>%s</em>.',
diff --git a/app/i18n/pt-br/sub.php b/app/i18n/pt-br/sub.php
index 58b2fc1f9..fc26e89e7 100644
--- a/app/i18n/pt-br/sub.php
+++ b/app/i18n/pt-br/sub.php
@@ -33,6 +33,10 @@ return array(
'description' => 'Descrição',
'empty' => 'Este feed está vazio. Por favor verifique ele ainda é mantido.',
'error' => 'Este feed encontra-se com problema. Por favor verifique se ele ainda está disponível e atualize-o.',
+ 'filteractions' => array(
+ '_' => 'Filter actions', //TODO - Translation
+ 'help' => 'Write one search filter per line.', //TODO - Translation
+ ),
'informations' => 'Informações',
'keep_history' => 'Número mínimo de artigos para manter',
'moved_category_deleted' => 'Quando você deleta uma categoria, seus feeds são automaticamente classificados como <em>%s</em>.',
diff --git a/app/i18n/ru/sub.php b/app/i18n/ru/sub.php
index 62f8a8e3a..e125d549e 100644
--- a/app/i18n/ru/sub.php
+++ b/app/i18n/ru/sub.php
@@ -33,6 +33,10 @@ return array(
'description' => 'Description', //TODO - Translation
'empty' => 'This feed is empty. Please verify that it is still maintained.', //TODO - Translation
'error' => 'This feed has encountered a problem. Please verify that it is always reachable then actualize it.', //TODO - Translation
+ 'filteractions' => array(
+ '_' => 'Filter actions', //TODO - Translation
+ 'help' => 'Write one search filter per line.', //TODO - Translation
+ ),
'informations' => 'Information', //TODO - Translation
'keep_history' => 'Minimum number of articles to keep', //TODO - Translation
'moved_category_deleted' => 'When you delete a category, its feeds are automatically classified under <em>%s</em>.', //TODO - Translation
diff --git a/app/i18n/tr/sub.php b/app/i18n/tr/sub.php
index 7f29633be..9f4945c0a 100644
--- a/app/i18n/tr/sub.php
+++ b/app/i18n/tr/sub.php
@@ -33,6 +33,10 @@ return array(
'description' => 'Tanım',
'empty' => 'Bu akış boş. Lütfen akışın aktif olduğuna emin olun.',
'error' => 'Bu akışda bir hatayla karşılaşıldı. Lütfen akışın sürekli ulaşılabilir olduğuna emin olun.',
+ 'filteractions' => array(
+ '_' => 'Filter actions', //TODO - Translation
+ 'help' => 'Write one search filter per line.', //TODO - Translation
+ ),
'informations' => 'Bilgi',
'keep_history' => 'En az tutulacak makale sayısı',
'moved_category_deleted' => 'Bir kategoriyi silerseniz, içerisindeki akışlar <em>%s</em> içerisine yerleşir.',
diff --git a/app/i18n/zh-cn/sub.php b/app/i18n/zh-cn/sub.php
index f84d08cdf..90f9fd942 100644
--- a/app/i18n/zh-cn/sub.php
+++ b/app/i18n/zh-cn/sub.php
@@ -33,6 +33,10 @@ return array(
'description' => '描述',
'empty' => '此源为空。请确认它是否正常更新。',
'error' => '此源遇到一些问题。请在确认是否能正常访问后重试。',
+ 'filteractions' => array(
+ '_' => 'Filter actions', //TODO - Translation
+ 'help' => 'Write one search filter per line.', //TODO - Translation
+ ),
'informations' => '信息',
'keep_history' => '至少保存的文章数',
'moved_category_deleted' => '删除分类时,其中的 RSS 源会自动归类到 <em>%s</em>',
diff --git a/app/views/helpers/feed/update.phtml b/app/views/helpers/feed/update.phtml
index bc90ba456..be8034c0d 100644
--- a/app/views/helpers/feed/update.phtml
+++ b/app/views/helpers/feed/update.phtml
@@ -234,6 +234,19 @@
</div>
<?php } ?>
+ <legend><?php echo _t('sub.feed.filteractions'); ?></legend>
+ <div class="form-group">
+ <label class="group-name" for="filteractions_read"><?php echo _t('conf.reading.read.when'); ?></label>
+ <div class="group-controls">
+ <textarea name="filteractions_read" id="filteractions_read"><?php
+ foreach ($this->feed->filtersAction('read') as $filterRead) {
+ echo htmlspecialchars($filterRead->getRawInput(), ENT_NOQUOTES, 'UTF-8'), "\n\n";
+ }
+ ?></textarea>
+ <?php echo _i('help'); ?> <?php echo _t('sub.feed.filteractions.help'); ?>
+ </div>
+ </div>
+
<div class="form-group form-actions">
<div class="group-controls">
<button type="submit" class="btn btn-important"><?php echo _t('gen.action.submit'); ?></button>