From e6888bbf232de5547560ea3af56ed760cb11c4ae Mon Sep 17 00:00:00 2001 From: hoilc Date: Mon, 18 Mar 2019 17:55:50 +0800 Subject: update zh-cn (i18n) (#2280) --- app/i18n/zh-cn/admin.php | 20 ++++++++++---------- app/i18n/zh-cn/conf.php | 26 +++++++++++++------------- app/i18n/zh-cn/feedback.php | 10 +++++----- app/i18n/zh-cn/gen.php | 2 +- app/i18n/zh-cn/index.php | 6 +++--- app/i18n/zh-cn/install.php | 4 ++-- app/i18n/zh-cn/sub.php | 14 +++++++------- 7 files changed, 41 insertions(+), 41 deletions(-) (limited to 'app/i18n/zh-cn') diff --git a/app/i18n/zh-cn/admin.php b/app/i18n/zh-cn/admin.php index e34070526..74f57b6e8 100644 --- a/app/i18n/zh-cn/admin.php +++ b/app/i18n/zh-cn/admin.php @@ -64,11 +64,11 @@ return array( 'files' => '文件相关', 'json' => array( 'nok' => '找不到 JSON 扩展 (php-json ) 。', - 'ok' => '已找到 JSON 扩展', + 'ok' => '已找到 JSON 扩展。', ), 'mbstring' => array( - 'nok' => 'Cannot find the recommended library mbstring for Unicode.', //TODO - Translation - 'ok' => 'You have the recommended library mbstring for Unicode.', //TODO - Translation + 'nok' => '找不到推荐的 Unicode 解析库 (mbstring)。', + 'ok' => '已找到推荐的 Unicode 解析库 (mbstring)。', ), 'minz' => array( 'nok' => '找不到 Minz 框架。', @@ -163,8 +163,8 @@ return array( 'max-categories' => '每用户分类限制', 'max-feeds' => '每用户 RSS 源限制', 'cookie-duration' => array( - 'help' => 'in seconds', // @todo translate - 'number' => 'Duration to keep logged in', // @todo translate + 'help' => '单位(秒)', + 'number' => '保持登录的时长', ), 'registration' => array( 'help' => '0 表示无账户数限制', @@ -183,15 +183,15 @@ return array( 'user' => array( 'articles_and_size' => '%s 篇文章 (%s)', 'create' => '创建新用户', - 'delete_users' => 'Delete user', //TODO - Translation + 'delete_users' => '删除用户', 'language' => '语言', - 'number' => '已有 %d 个帐户', - 'numbers' => '已有 %d 个帐户', + 'number' => '已有 %d 个用户', + 'numbers' => '已有 %d 个用户', 'password_form' => '密码
(用于 Web-form 登录方式)', 'password_format' => '至少 7 个字符', - 'selected' => 'Selected user', //TODO - Translation + 'selected' => '已选中用户', 'title' => '用户管理', - 'update_users' => 'Update user', //TODO - Translation + 'update_users' => '更新用户', 'user_list' => '用户列表', 'username' => '用户名', 'users' => '用户', diff --git a/app/i18n/zh-cn/conf.php b/app/i18n/zh-cn/conf.php index 1216aaaca..535dfd358 100644 --- a/app/i18n/zh-cn/conf.php +++ b/app/i18n/zh-cn/conf.php @@ -28,7 +28,7 @@ return array( 'seconds' => '秒 (0 表示不超时)', 'timeout' => 'HTML5 通知超时时间', ), - 'show_nav_buttons' => 'Show the navigation buttons', //TODO - Translation + 'show_nav_buttons' => '显示导航按钮', 'theme' => '主题', 'title' => '显示', 'width' => array( @@ -53,7 +53,7 @@ return array( 'query' => array( '_' => '自定义查询', 'deprecated' => '此查询不再有效。相关的分类或 RSS 源已被删除。', - 'display' => 'Display user query results', //TODO - Translation + 'display' => '显示查询结果', 'filter' => '生效的过滤器:', 'get_all' => '显示所有文章', 'get_category' => '显示分类 "%s"', @@ -64,7 +64,7 @@ return array( 'number' => '查询 n°%d', 'order_asc' => '由旧到新显示文章', 'order_desc' => '由新到旧显示文章', - 'remove' => 'Remove user query', //TODO - Translation + 'remove' => '删除查询', 'search' => '搜索 "%s"', 'state_0' => '显示所有文章', 'state_1' => '显示已读文章', @@ -128,7 +128,7 @@ return array( ), 'sharing' => array( '_' => '分享', - 'add' => 'Add a sharing method', //TODO - Translation + 'add' => '添加分享方式', 'blogotext' => 'Blogotext', 'diaspora' => 'Diaspora*', 'email' => 'Email', @@ -136,7 +136,7 @@ return array( 'g+' => 'Google+', 'more_information' => '更多信息', 'print' => '打印', - 'remove' => 'Remove sharing method', //TODO - Translation + 'remove' => '删除分享方式', 'shaarli' => 'Shaarli', 'share_name' => '名称', 'share_url' => '地址', @@ -148,31 +148,31 @@ return array( '_' => '快捷键', 'article_action' => '文章操作', 'auto_share' => '分享', - 'auto_share_help' => '如果有多种分享模式,则会按照它们的编号依次访问。', + 'auto_share_help' => '如果有多种分享方式,则会按照它们的编号依次访问。', 'close_dropdown' => '关闭菜单', 'collapse_article' => '收起文章', - 'first_article' => '跳转到第一篇文章', + 'first_article' => '打开第一篇文章', 'focus_search' => '聚焦到搜索框', 'global_view' => '切换到全屏视图', 'help' => '显示帮助文档', 'javascript' => '若要使用快捷键,必须启用 JavaScript', - 'last_article' => '跳转到最后一篇文章', + 'last_article' => '打开最后一篇文章', 'load_more' => '载入更多文章', 'mark_favorite' => '加入收藏', 'mark_read' => '设为已读', 'navigation' => '浏览', 'navigation_help' => '搭配 "Shift" 键,浏览快捷键将生效于 RSS 源。
搭配 "Alt" 键,浏览快捷键将生效于分类。', - 'navigation_no_mod_help' => 'The following navigation shortcuts do not support modifiers.', //TODO - Translation - 'next_article' => '跳转到下一篇文章', + 'navigation_no_mod_help' => '以下快捷键不支持组合键 (Shift 或 Alt)', + 'next_article' => '打开下一篇文章', 'normal_view' => '切换到普通视图', 'other_action' => '其他操作', - 'previous_article' => '跳转到上一篇文章', + 'previous_article' => '打开上一篇文章', 'reading_view' => '切换到阅读视图', 'rss_view' => '在新标签中打开 RSS 视图', 'see_on_website' => '在原网站上查看', 'shift_for_all_read' => '+ shift 可以将全部文章设为已读', - 'skip_next_article' => 'Focus next without opening', //TODO - Translation - 'skip_previous_article' => 'Focus previous without opening', //TODO - Translation + 'skip_next_article' => '跳转到下一篇文章而不打开', + 'skip_previous_article' => '跳转到上一篇文章而不打开', 'title' => '快捷键', 'user_filter' => '显示自定义查询', 'user_filter_help' => '如果有多个自定义过滤器,则会按照它们的编号依次访问。', diff --git a/app/i18n/zh-cn/feedback.php b/app/i18n/zh-cn/feedback.php index e1778a9f2..e8ee969b0 100644 --- a/app/i18n/zh-cn/feedback.php +++ b/app/i18n/zh-cn/feedback.php @@ -57,8 +57,8 @@ return array( 'sub' => array( 'actualize' => '获取', 'articles' => array( - 'marked_read' => 'The selected articles have been marked as read.', //TODO - Translation - 'marked_unread' => 'The articles have been marked as unread.', //TODO - Translation + 'marked_read' => '选中文章已标记为已读', + 'marked_unread' => '文章已标记为未读', ), 'category' => array( 'created' => '分类 %s 已创建。', @@ -80,7 +80,7 @@ return array( 'already_subscribed' => '你已订阅 %s', 'deleted' => 'RSS 源已删除', 'error' => 'RSS 源更新失败', - 'internal_problem' => 'RSS 源添加失败。检查 FreshRSS 日志 查看详情。', //TODO - Translation + 'internal_problem' => 'RSS 源添加失败。检查 FreshRSS 日志 查看详情。你可以在URL后附加 #force_feed 从而尝试强制添加。', 'invalid_url' => 'URL %s 无效', 'n_actualized' => '%d 个 RSS 源已更新', 'n_entries_deleted' => '%d 篇文章已删除', @@ -109,8 +109,8 @@ return array( 'error' => '用户 %s 删除失败', ), 'updated' => array( - '_' => 'User %s has been updated', //TODO - Translation - 'error' => 'User %s has not been updated', //TODO - Translation + '_' => '用户 %s 已更新', + 'error' => '用户 %s 更新失败', ), ), ); diff --git a/app/i18n/zh-cn/gen.php b/app/i18n/zh-cn/gen.php index 1dcd95233..11d4efdb3 100644 --- a/app/i18n/zh-cn/gen.php +++ b/app/i18n/zh-cn/gen.php @@ -19,7 +19,7 @@ return array( 'see_website' => '查看网站', 'submit' => '提交', 'truncate' => '删除所有文章', - 'update' => 'Update', //TODO - Translation + 'update' => '更新', //TODO - Translation ), 'auth' => array( 'email' => 'Email 地址', diff --git a/app/i18n/zh-cn/index.php b/app/i18n/zh-cn/index.php index 3f6b44701..018813c3e 100644 --- a/app/i18n/zh-cn/index.php +++ b/app/i18n/zh-cn/index.php @@ -40,7 +40,7 @@ return array( 'mark_all_read' => '全部设为已读', 'mark_cat_read' => '此分类设为已读', 'mark_feed_read' => '此源设为已读', - 'mark_selection_unread' => 'Mark selection as unread', //TODO - Translation + 'mark_selection_unread' => '选中设为已读', 'newer_first' => '由新到旧', 'non-starred' => '显示未收藏', 'normal_view' => '普通视图', @@ -53,11 +53,11 @@ return array( 'starred' => '显示收藏', 'stats' => '统计', 'subscription' => '订阅管理', - 'tags' => 'My labels', //TODO - Translation + 'tags' => '我的标签', 'unread' => '显示未读', ), 'share' => '分享', 'tag' => array( - 'related' => '相关标签', //TODO - Translation + 'related' => '文章标签', ), ); diff --git a/app/i18n/zh-cn/install.php b/app/i18n/zh-cn/install.php index 29647932a..da231917b 100644 --- a/app/i18n/zh-cn/install.php +++ b/app/i18n/zh-cn/install.php @@ -69,8 +69,8 @@ return array( 'ok' => '已找到推荐的 JSON 解析库。', ), 'mbstring' => array( - 'nok' => 'Cannot find the recommended library mbstring for Unicode.', //TODO - Translation - 'ok' => 'You have the recommended library mbstring for Unicode.', //TODO - Translation + 'nok' => '找不到推荐的 Unicode 解析库 (mbstring)。', + 'ok' => '已找到推荐的 Unicode 解析库 (mbstring)。', ), 'minz' => array( 'nok' => '找不到 Minz 框架。', diff --git a/app/i18n/zh-cn/sub.php b/app/i18n/zh-cn/sub.php index 3a9623468..f84d08cdf 100644 --- a/app/i18n/zh-cn/sub.php +++ b/app/i18n/zh-cn/sub.php @@ -27,7 +27,7 @@ return array( 'password' => 'HTTP 密码', 'username' => 'HTTP 用户名', ), - 'clear_cache' => 'Always clear cache', //TODO - Translation + 'clear_cache' => '总是清除缓存', 'css_help' => '用于获取全文(注意,这将耗费更多时间!)', 'css_path' => '原文的 CSS 选择器', 'description' => '描述', @@ -47,16 +47,16 @@ return array( ), 'websub' => 'WebSub 即时通知', 'show' => array( - 'all' => 'Show all feeds', //TODO - Translation - 'error' => 'Show only feeds with error', //TODO - Translation + 'all' => '显示所有 RSS 源', + 'error' => '仅显示有错误的 RSS 源', ), 'showing' => array( - 'error' => 'Showing only feeds with error', //TODO - Translation + 'error' => '正在显示有错误的 RSS 源', ), - 'ssl_verify' => 'Verify SSL security', //TODO - Translation + 'ssl_verify' => '验证 SSL 安全', 'stats' => '统计', 'think_to_add' => '你可以添加一些 RSS 源。', - 'timeout' => 'Timeout in seconds', //TODO - Translation + 'timeout' => '超时时间(秒)', 'title' => '标题', 'title_add' => '添加 RSS 源', 'ttl' => '最小自动更新时间', @@ -72,7 +72,7 @@ return array( 'export' => '导出', 'export_opml' => '导出 RSS 源列表 (OPML)', 'export_starred' => '导出你的收藏', - 'export_labelled' => 'Export your labelled articles', //TODO + 'export_labelled' => '导出有标签的文章', 'feed_list' => '%s 文章列表', 'file_to_import' => '需要导入的文件
(OPML, JSON 或 ZIP)', 'file_to_import_no_zip' => '需要导入的文件
(OPML 或 JSON)', -- cgit v1.2.3 From 1804c0e0bc095487b9a1ad13cbc9f55f6cef2a2a Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Sat, 23 Mar 2019 22:52:47 +0100 Subject: Filter actions (#2275) * Draft of filter actions * Travis * Implement UI + finish logic * Travis --- app/Controllers/feedController.php | 27 +++---- app/Controllers/subscriptionController.php | 4 +- app/Models/Entry.php | 113 +++++++++++++++++++++++++++++ app/Models/Feed.php | 104 ++++++++++++++++++++++++++ app/Models/FilterAction.php | 45 ++++++++++++ app/i18n/cz/sub.php | 4 + app/i18n/de/sub.php | 4 + app/i18n/en/sub.php | 4 + app/i18n/es/sub.php | 4 + app/i18n/fr/sub.php | 4 + app/i18n/he/sub.php | 4 + app/i18n/it/sub.php | 4 + app/i18n/kr/sub.php | 4 + app/i18n/nl/sub.php | 4 + app/i18n/oc/sub.php | 4 + app/i18n/pt-br/sub.php | 4 + app/i18n/ru/sub.php | 4 + app/i18n/tr/sub.php | 4 + app/i18n/zh-cn/sub.php | 4 + app/views/helpers/feed/update.phtml | 13 ++++ 20 files changed, 345 insertions(+), 17 deletions(-) create mode 100644 app/Models/FilterAction.php (limited to 'app/i18n/zh-cn') 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); + } + // 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 @@ +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 %s.', 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 %s 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 %s.', 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 %s.', 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 %s.', 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' => 'כאשר הקטגוריה נמחקת ההזנות שבתוכה אוטומטית מקוטלגות תחת %s.', 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 %s.', 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' => '카테고리를 삭제하면, 해당 카테고리 아래에 있던 피드들은 자동적으로 %s 아래로 분류됩니다.', 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 %s.', 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 %s.', 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 %s.', 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 %s.', //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 %s 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 源会自动归类到 %s', 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 @@ + +
+ +
+ + +
+
+
-- cgit v1.2.3