aboutsummaryrefslogtreecommitdiff
path: root/app/Models
diff options
context:
space:
mode:
Diffstat (limited to 'app/Models')
-rw-r--r--app/Models/CategoryDAO.php2
-rw-r--r--app/Models/Configuration.php4
-rw-r--r--app/Models/Context.php44
-rw-r--r--app/Models/EntryDAO.php77
-rw-r--r--app/Models/EntryDAOSQLite.php45
-rw-r--r--app/Models/Feed.php8
-rw-r--r--app/Models/StatsDAO.php56
-rw-r--r--app/Models/UserDAO.php4
8 files changed, 206 insertions, 34 deletions
diff --git a/app/Models/CategoryDAO.php b/app/Models/CategoryDAO.php
index 2e333d2f1..27a558522 100644
--- a/app/Models/CategoryDAO.php
+++ b/app/Models/CategoryDAO.php
@@ -134,7 +134,7 @@ class FreshRSS_CategoryDAO extends Minz_ModelPdo {
$def_cat = $this->searchById(1);
if ($def_cat == null) {
- $cat = new FreshRSS_Category(_t('default_category'));
+ $cat = new FreshRSS_Category(_t('gen.short.default_category'));
$cat->_id(1);
$values = array(
diff --git a/app/Models/Configuration.php b/app/Models/Configuration.php
index 53f136513..8668470b0 100644
--- a/app/Models/Configuration.php
+++ b/app/Models/Configuration.php
@@ -24,6 +24,7 @@ class FreshRSS_Configuration {
'lazyload' => true,
'sticky_post' => true,
'reading_confirm' => false,
+ 'auto_remove_article' => false,
'sort_order' => 'DESC',
'anon_access' => false,
'mark_when' => array(
@@ -191,6 +192,9 @@ class FreshRSS_Configuration {
public function _reading_confirm($value) {
$this->data['reading_confirm'] = ((bool)$value) && $value !== 'no';
}
+ public function _auto_remove_article($value) {
+ $this->data['auto_remove_article'] = ((bool)$value) && $value !== 'no';
+ }
public function _sort_order($value) {
$this->data['sort_order'] = $value === 'ASC' ? 'ASC' : 'DESC';
}
diff --git a/app/Models/Context.php b/app/Models/Context.php
index 36c4087eb..c8a65063a 100644
--- a/app/Models/Context.php
+++ b/app/Models/Context.php
@@ -138,12 +138,12 @@ class FreshRSS_Context {
switch($type) {
case 'a':
self::$current_get['all'] = true;
- self::$name = _t('your_rss_feeds');
+ self::$name = _t('index.feed.title');
self::$get_unread = self::$total_unread;
break;
case 's':
self::$current_get['starred'] = true;
- self::$name = _t('your_favorites');
+ self::$name = _t('index.feed.title_fav');
self::$get_unread = self::$total_starred['unread'];
// Update state if favorite is not yet enabled.
@@ -265,4 +265,44 @@ class FreshRSS_Context {
}
}
}
+
+ /**
+ * Determine if the auto remove is available in the current context.
+ * This feature is available if:
+ * - it is activated in the configuration
+ * - the "read" state is not enable
+ * - the "unread" state is enable
+ *
+ * @return boolean
+ */
+ public static function isAutoRemoveAvailable() {
+ if (!self::$conf->auto_remove_article) {
+ return false;
+ }
+ if (self::isStateEnabled(FreshRSS_Entry::STATE_READ)) {
+ return false;
+ }
+ if (!self::isStateEnabled(FreshRSS_Entry::STATE_NOT_READ)) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * Determine if the "sticky post" option is enabled. It can be enable
+ * by the user when it is selected in the configuration page or by the
+ * application when the context allows to auto-remove articles when they
+ * are read.
+ *
+ * @return boolean
+ */
+ public static function isStickyPostEnabled() {
+ if (self::$conf->sticky_post) {
+ return true;
+ }
+ if (self::isAutoRemoveAvailable()) {
+ return true;
+ }
+ return false;
+ }
}
diff --git a/app/Models/EntryDAO.php b/app/Models/EntryDAO.php
index 5d2909c62..4d06ac028 100644
--- a/app/Models/EntryDAO.php
+++ b/app/Models/EntryDAO.php
@@ -80,6 +80,16 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo {
return -1;
}
+ /**
+ * Toggle favorite marker on one or more article
+ *
+ * @todo simplify the query by removing the str_repeat. I am pretty sure
+ * there is an other way to do that.
+ *
+ * @param integer|array $ids
+ * @param boolean $is_favorite
+ * @return false|integer
+ */
public function markFavorite($ids, $is_favorite = true) {
if (!is_array($ids)) {
$ids = array($ids);
@@ -99,6 +109,17 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo {
}
}
+ /**
+ * Update the unread article cache held on every feed details.
+ * Depending on the parameters, it updates the cache on one feed, on all
+ * feeds from one category or on all feeds.
+ *
+ * @todo It can use the query builder refactoring to build that query
+ *
+ * @param false|integer $catId category ID
+ * @param false|integer $feedId feed ID
+ * @return boolean
+ */
protected function updateCacheUnreads($catId = false, $feedId = false) {
$sql = 'UPDATE `' . $this->prefix . 'feed` f '
. 'LEFT OUTER JOIN ('
@@ -129,6 +150,19 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo {
}
}
+ /**
+ * Toggle the read marker on one or more article.
+ * Then the cache is updated.
+ *
+ * @todo change the way the query is build because it seems there is
+ * unnecessary code in here. For instance, the part with the str_repeat.
+ * @todo remove code duplication. It seems the code is basically the
+ * same if it is an array or not.
+ *
+ * @param integer|array $ids
+ * @param boolean $is_read
+ * @return integer affected rows
+ */
public function markRead($ids, $is_read = true) {
if (is_array($ids)) { //Many IDs at once (used by API)
if (count($ids) < 6) { //Speed heuristics
@@ -172,6 +206,27 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo {
}
}
+ /**
+ * Mark all entries as read depending on parameters.
+ * If $onlyFavorites is true, it is used when the user mark as read in
+ * the favorite pseudo-category.
+ * If $priorityMin is greater than 0, it is used when the user mark as
+ * read in the main feed pseudo-category.
+ * Then the cache is updated.
+ *
+ * If $idMax equals 0, a deprecated debug message is logged
+ *
+ * @todo refactor this method along with markReadCat and markReadFeed
+ * since they are all doing the same thing. I think we need to build a
+ * tool to generate the query instead of having queries all over the
+ * place. It will be reused also for the filtering making every thing
+ * separated.
+ *
+ * @param integer $idMax fail safe article ID
+ * @param boolean $onlyFavorites
+ * @param integer $priorityMin
+ * @return integer affected rows
+ */
public function markReadEntries($idMax = 0, $onlyFavorites = false, $priorityMin = 0) {
if ($idMax == 0) {
$idMax = time() . '000000';
@@ -200,6 +255,17 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo {
return $affected;
}
+ /**
+ * Mark all the articles in a category as read.
+ * There is a fail safe to prevent to mark as read articles that are
+ * loaded during the mark as read action. Then the cache is updated.
+ *
+ * If $idMax equals 0, a deprecated debug message is logged
+ *
+ * @param integer $id category ID
+ * @param integer $idMax fail safe article ID
+ * @return integer affected rows
+ */
public function markReadCat($id, $idMax = 0) {
if ($idMax == 0) {
$idMax = time() . '000000';
@@ -223,6 +289,17 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo {
return $affected;
}
+ /**
+ * Mark all the articles in a feed as read.
+ * There is a fail safe to prevent to mark as read articles that are
+ * loaded during the mark as read action. Then the cache is updated.
+ *
+ * If $idMax equals 0, a deprecated debug message is logged
+ *
+ * @param integer $id feed ID
+ * @param integer $idMax fail safe article ID
+ * @return integer affected rows
+ */
public function markReadFeed($id, $idMax = 0) {
if ($idMax == 0) {
$idMax = time() . '000000';
diff --git a/app/Models/EntryDAOSQLite.php b/app/Models/EntryDAOSQLite.php
index 4a3fe24a2..bb1539e0c 100644
--- a/app/Models/EntryDAOSQLite.php
+++ b/app/Models/EntryDAOSQLite.php
@@ -31,6 +31,19 @@ class FreshRSS_EntryDAOSQLite extends FreshRSS_EntryDAO {
}
}
+ /**
+ * Toggle the read marker on one or more article.
+ * Then the cache is updated.
+ *
+ * @todo change the way the query is build because it seems there is
+ * unnecessary code in here. For instance, the part with the str_repeat.
+ * @todo remove code duplication. It seems the code is basically the
+ * same if it is an array or not.
+ *
+ * @param integer|array $ids
+ * @param boolean $is_read
+ * @return integer affected rows
+ */
public function markRead($ids, $is_read = true) {
if (is_array($ids)) { //Many IDs at once (used by API)
if (true) { //Speed heuristics //TODO: Not implemented yet for SQLite (so always call IDs one by one)
@@ -69,6 +82,27 @@ class FreshRSS_EntryDAOSQLite extends FreshRSS_EntryDAO {
}
}
+ /**
+ * Mark all entries as read depending on parameters.
+ * If $onlyFavorites is true, it is used when the user mark as read in
+ * the favorite pseudo-category.
+ * If $priorityMin is greater than 0, it is used when the user mark as
+ * read in the main feed pseudo-category.
+ * Then the cache is updated.
+ *
+ * If $idMax equals 0, a deprecated debug message is logged
+ *
+ * @todo refactor this method along with markReadCat and markReadFeed
+ * since they are all doing the same thing. I think we need to build a
+ * tool to generate the query instead of having queries all over the
+ * place. It will be reused also for the filtering making every thing
+ * separated.
+ *
+ * @param integer $idMax fail safe article ID
+ * @param boolean $onlyFavorites
+ * @param integer $priorityMin
+ * @return integer affected rows
+ */
public function markReadEntries($idMax = 0, $onlyFavorites = false, $priorityMin = 0) {
if ($idMax == 0) {
$idMax = time() . '000000';
@@ -95,6 +129,17 @@ class FreshRSS_EntryDAOSQLite extends FreshRSS_EntryDAO {
return $affected;
}
+ /**
+ * Mark all the articles in a category as read.
+ * There is a fail safe to prevent to mark as read articles that are
+ * loaded during the mark as read action. Then the cache is updated.
+ *
+ * If $idMax equals 0, a deprecated debug message is logged
+ *
+ * @param integer $id category ID
+ * @param integer $idMax fail safe article ID
+ * @return integer affected rows
+ */
public function markReadCat($id, $idMax = 0) {
if ($idMax == 0) {
$idMax = time() . '000000';
diff --git a/app/Models/Feed.php b/app/Models/Feed.php
index bd1babeea..8f4b60097 100644
--- a/app/Models/Feed.php
+++ b/app/Models/Feed.php
@@ -210,6 +210,10 @@ class FreshRSS_Feed extends Minz_Model {
$url = preg_replace('#((.+)://)(.+)#', '${1}' . $this->httpAuth . '@${3}', $url);
}
$feed = customSimplePie();
+ if (substr($url, -11) === '#force_feed') {
+ $feed->force_feed(true);
+ $url = substr($url, 0, -11);
+ }
$feed->set_feed_url($url);
if (!$loadDetails) { //Only activates auto-discovery when adding a new feed
$feed->set_autodiscovery_level(SIMPLEPIE_LOCATOR_NONE);
@@ -226,7 +230,7 @@ class FreshRSS_Feed extends Minz_Model {
$subscribe_url = $feed->subscribe_url(false);
$title = strtr(html_only_entity_decode($feed->get_title()), array('<' => '&lt;', '>' => '&gt;', '"' => '&quot;')); //HTML to HTML-PRE //ENT_COMPAT except &
- $this->_name($title == '' ? $this->url : $title);
+ $this->_name($title == '' ? $url : $title);
$this->_website(html_only_entity_decode($feed->get_link()));
$this->_description(html_only_entity_decode($feed->get_description()));
@@ -235,7 +239,7 @@ class FreshRSS_Feed extends Minz_Model {
$subscribe_url = $feed->subscribe_url(true);
}
- if ($subscribe_url !== null && $subscribe_url !== $this->url) {
+ if ($subscribe_url !== null && $subscribe_url !== $url) {
if ($this->httpAuth != '') {
// on enlève les id si authentification HTTP
$subscribe_url = preg_replace('#((.+)://)((.+)@)(.+)#', '${1}${5}', $subscribe_url);
diff --git a/app/Models/StatsDAO.php b/app/Models/StatsDAO.php
index 283d5dcb1..80caccc49 100644
--- a/app/Models/StatsDAO.php
+++ b/app/Models/StatsDAO.php
@@ -6,18 +6,36 @@ class FreshRSS_StatsDAO extends Minz_ModelPdo {
/**
* Calculates entry repartition for all feeds and for main stream.
+ *
+ * @return array
+ */
+ public function calculateEntryRepartition() {
+ return array(
+ 'main_stream' => $this->calculateEntryRepartitionPerFeed(null, true),
+ 'all_feeds' => $this->calculateEntryRepartitionPerFeed(null, false),
+ );
+ }
+
+ /**
+ * Calculates entry repartition for the selection.
* The repartition includes:
* - total entries
* - read entries
* - unread entries
* - favorite entries
*
- * @return type
+ * @param null|integer $feed feed id
+ * @param boolean $only_main
+ * @return array
*/
- public function calculateEntryRepartition() {
- $repartition = array();
-
- // Generates the repartition for the main stream of entry
+ public function calculateEntryRepartitionPerFeed($feed = null, $only_main = false) {
+ $filter = '';
+ if ($only_main) {
+ $filter .= 'AND f.priority = 10';
+ }
+ if (!is_null($feed)) {
+ $filter .= "AND e.id_feed = {$feed}";
+ }
$sql = <<<SQL
SELECT COUNT(1) AS `total`,
COUNT(1) - SUM(e.is_read) AS `unread`,
@@ -26,27 +44,13 @@ SUM(e.is_favorite) AS `favorite`
FROM {$this->prefix}entry AS e
, {$this->prefix}feed AS f
WHERE e.id_feed = f.id
-AND f.priority = 10
-SQL;
- $stm = $this->bd->prepare($sql);
- $stm->execute();
- $res = $stm->fetchAll(PDO::FETCH_ASSOC);
- $repartition['main_stream'] = $res[0];
-
- // Generates the repartition for all entries
- $sql = <<<SQL
-SELECT COUNT(1) AS `total`,
-COUNT(1) - SUM(e.is_read) AS `unread`,
-SUM(e.is_read) AS `read`,
-SUM(e.is_favorite) AS `favorite`
-FROM {$this->prefix}entry AS e
+{$filter}
SQL;
$stm = $this->bd->prepare($sql);
$stm->execute();
$res = $stm->fetchAll(PDO::FETCH_ASSOC);
- $repartition['all_feeds'] = $res[0];
- return $repartition;
+ return $res[0];
}
/**
@@ -147,10 +151,9 @@ SQL;
* @return string
*/
protected function calculateEntryRepartitionPerFeedPerPeriod($period, $feed = null) {
+ $restrict = '';
if ($feed) {
$restrict = "WHERE e.id_feed = {$feed}";
- } else {
- $restrict = '';
}
$sql = <<<SQL
SELECT DATE_FORMAT(FROM_UNIXTIME(e.date), '{$period}') AS period
@@ -179,7 +182,7 @@ SQL;
* @return integer
*/
public function calculateEntryAveragePerFeedPerHour($feed = null) {
- return $this->calculateEntryAveragePerFeedPerPeriod(1/24, $feed);
+ return $this->calculateEntryAveragePerFeedPerPeriod(1 / 24, $feed);
}
/**
@@ -210,10 +213,9 @@ SQL;
* @return integer
*/
protected function calculateEntryAveragePerFeedPerPeriod($period, $feed = null) {
+ $restrict = '';
if ($feed) {
$restrict = "WHERE e.id_feed = {$feed}";
- } else {
- $restrict = '';
}
$sql = <<<SQL
SELECT COUNT(1) AS count
@@ -416,7 +418,7 @@ SQL;
*/
private function convertToTranslatedJson($data = array()) {
$translated = array_map(function($a) {
- return _t($a);
+ return _t('gen.date.' . $a);
}, $data);
return json_encode($translated);
diff --git a/app/Models/UserDAO.php b/app/Models/UserDAO.php
index 60fca71b1..f04ae26bf 100644
--- a/app/Models/UserDAO.php
+++ b/app/Models/UserDAO.php
@@ -9,7 +9,7 @@ class FreshRSS_UserDAO extends Minz_ModelPdo {
$ok = false;
if (defined('SQL_CREATE_TABLES')) { //E.g. MySQL
- $sql = sprintf(SQL_CREATE_TABLES, $db['prefix'] . $username . '_', _t('default_category'));
+ $sql = sprintf(SQL_CREATE_TABLES, $db['prefix'] . $username . '_', _t('gen.short.default_category'));
$stm = $userPDO->bd->prepare($sql);
$ok = $stm && $stm->execute();
} else { //E.g. SQLite
@@ -17,7 +17,7 @@ class FreshRSS_UserDAO extends Minz_ModelPdo {
if (is_array($SQL_CREATE_TABLES)) {
$ok = true;
foreach ($SQL_CREATE_TABLES as $instruction) {
- $sql = sprintf($instruction, '', _t('default_category'));
+ $sql = sprintf($instruction, '', _t('gen.short.default_category'));
$stm = $userPDO->bd->prepare($sql);
$ok &= ($stm && $stm->execute());
}