aboutsummaryrefslogtreecommitdiff
path: root/app/Models
diff options
context:
space:
mode:
Diffstat (limited to 'app/Models')
-rw-r--r--app/Models/Auth.php6
-rw-r--r--app/Models/CategoryDAO.php5
-rw-r--r--app/Models/ConfigurationSetter.php8
-rw-r--r--app/Models/EntryDAO.php63
-rw-r--r--app/Models/Feed.php30
-rw-r--r--app/Models/FeedDAO.php36
-rw-r--r--app/Models/ReadingMode.php148
7 files changed, 258 insertions, 38 deletions
diff --git a/app/Models/Auth.php b/app/Models/Auth.php
index 4de058999..32b673b6d 100644
--- a/app/Models/Auth.php
+++ b/app/Models/Auth.php
@@ -13,6 +13,11 @@ class FreshRSS_Auth {
* This method initializes authentication system.
*/
public static function init() {
+ if (Minz_Session::param('REMOTE_USER', '') !== httpAuthUser()) {
+ //HTTP REMOTE_USER has changed
+ self::removeAccess();
+ }
+
self::$login_ok = Minz_Session::param('loginOk', false);
$current_user = Minz_Session::param('currentUser', '');
if ($current_user === '') {
@@ -58,6 +63,7 @@ class FreshRSS_Auth {
$login_ok = $current_user != '';
if ($login_ok) {
Minz_Session::_param('currentUser', $current_user);
+ Minz_Session::_param('REMOTE_USER', $current_user);
}
return $login_ok;
case 'none':
diff --git a/app/Models/CategoryDAO.php b/app/Models/CategoryDAO.php
index f219c275f..68db17db3 100644
--- a/app/Models/CategoryDAO.php
+++ b/app/Models/CategoryDAO.php
@@ -106,13 +106,14 @@ class FreshRSS_CategoryDAO extends Minz_ModelPdo implements FreshRSS_Searchable
public function listCategories($prePopulateFeeds = true, $details = false) {
if ($prePopulateFeeds) {
$sql = 'SELECT c.id AS c_id, c.name AS c_name, '
- . ($details ? 'f.* ' : 'f.id, f.name, f.url, f.website, f.priority, f.error, f.`cache_nbEntries`, f.`cache_nbUnreads` ')
+ . ($details ? 'f.* ' : 'f.id, f.name, f.url, f.website, f.priority, f.error, f.`cache_nbEntries`, f.`cache_nbUnreads`, f.ttl ')
. 'FROM `' . $this->prefix . 'category` c '
. 'LEFT OUTER JOIN `' . $this->prefix . 'feed` f ON f.category=c.id '
+ . 'WHERE f.priority >= :priority_normal '
. 'GROUP BY f.id, c_id '
. 'ORDER BY c.name, f.name';
$stm = $this->bd->prepare($sql);
- $stm->execute();
+ $stm->execute(array(':priority_normal' => FreshRSS_Feed::PRIORITY_NORMAL));
return self::daoToCategoryPrepopulated($stm->fetchAll(PDO::FETCH_ASSOC));
} else {
$sql = 'SELECT * FROM `' . $this->prefix . 'category` ORDER BY name';
diff --git a/app/Models/ConfigurationSetter.php b/app/Models/ConfigurationSetter.php
index ca4709903..ad703dfc5 100644
--- a/app/Models/ConfigurationSetter.php
+++ b/app/Models/ConfigurationSetter.php
@@ -81,7 +81,7 @@ class FreshRSS_ConfigurationSetter {
private function _keep_history_default(&$data, $value) {
$value = intval($value);
- $data['keep_history_default'] = $value >= -1 ? $value : 0;
+ $data['keep_history_default'] = $value >= FreshRSS_Feed::KEEP_HISTORY_INFINITE ? $value : 0;
}
// It works for system config too!
@@ -154,7 +154,7 @@ class FreshRSS_ConfigurationSetter {
private function _ttl_default(&$data, $value) {
$value = intval($value);
- $data['ttl_default'] = $value >= -1 ? $value : 3600;
+ $data['ttl_default'] = $value > FreshRSS_Feed::TTL_DEFAULT ? $value : 3600;
}
private function _view_mode(&$data, $value) {
@@ -184,6 +184,10 @@ class FreshRSS_ConfigurationSetter {
$data['mark_updated_article_unread'] = $this->handleBool($value);
}
+ private function _show_nav_buttons(&$data, $value) {
+ $data['show_nav_buttons'] = $this->handleBool($value);
+ }
+
private function _display_categories(&$data, $value) {
$data['display_categories'] = $this->handleBool($value);
}
diff --git a/app/Models/EntryDAO.php b/app/Models/EntryDAO.php
index e8b6dcdae..70135e7a0 100644
--- a/app/Models/EntryDAO.php
+++ b/app/Models/EntryDAO.php
@@ -628,10 +628,12 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
$firstId = $order === 'DESC' ? '9000000000'. '000000' : '0';
}*/
if ($firstId !== '') {
- $search .= 'AND ' . $alias . 'id ' . ($order === 'DESC' ? '<=' : '>=') . $firstId . ' ';
+ $search .= 'AND ' . $alias . 'id ' . ($order === 'DESC' ? '<=' : '>=') . ' ? ';
+ $values[] = $firstId;
}
if ($date_min > 0) {
- $search .= 'AND ' . $alias . 'id >= ' . $date_min . '000000 ';
+ $search .= 'AND ' . $alias . 'id >= ? ';
+ $values[] = $date_min . '000000';
}
if ($filter) {
if ($filter->getMinDate()) {
@@ -726,23 +728,23 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
$values = array();
switch ($type) {
case 'a':
- $where .= 'f.priority > 0 ';
- $joinFeed = true;
+ $where .= 'f.priority > ' . FreshRSS_Feed::PRIORITY_NORMAL . ' ';
break;
case 's': //Deprecated: use $state instead
- $where .= 'e.is_favorite=1 ';
+ $where .= 'f.priority >= ' . FreshRSS_Feed::PRIORITY_NORMAL . ' ';
+ $where .= 'AND e.is_favorite=1 ';
break;
case 'c':
- $where .= 'f.category=? ';
+ $where .= 'f.priority >= ' . FreshRSS_Feed::PRIORITY_NORMAL . ' ';
+ $where .= 'AND f.category=? ';
$values[] = intval($id);
- $joinFeed = true;
break;
case 'f':
$where .= 'e.id_feed=? ';
$values[] = intval($id);
break;
case 'A':
- $where .= '1=1 ';
+ $where .= 'f.priority >= ' . FreshRSS_Feed::PRIORITY_NORMAL . ' ';
break;
default:
throw new FreshRSS_EntriesGetter_Exception('Bad type in Entry->listByType: [' . $type . ']!');
@@ -752,7 +754,7 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
return array(array_merge($values, $searchValues),
'SELECT e.id FROM `' . $this->prefix . 'entry` e '
- . ($joinFeed ? 'INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed=f.id ' : '')
+ . 'INNER JOIN `' . $this->prefix . 'feed` f ON e.id_feed = f.id '
. 'WHERE ' . $where
. $search
. 'ORDER BY e.id ' . $order
@@ -781,6 +783,23 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
return self::daoToEntries($stm->fetchAll(PDO::FETCH_ASSOC));
}
+ public function listByIds($ids, $order = 'DESC') {
+ if (count($ids) < 1) {
+ return array();
+ }
+
+ $sql = 'SELECT id, guid, title, author, '
+ . ($this->isCompressed() ? 'UNCOMPRESS(content_bin) AS content' : 'content')
+ . ', link, date, is_read, is_favorite, id_feed, tags '
+ . 'FROM `' . $this->prefix . 'entry` '
+ . 'WHERE id IN (' . str_repeat('?,', count($ids) - 1). '?) '
+ . 'ORDER BY id ' . $order;
+
+ $stm = $this->bd->prepare($sql);
+ $stm->execute($ids);
+ return self::daoToEntries($stm->fetchAll(PDO::FETCH_ASSOC));
+ }
+
public function listIdsWhere($type = 'a', $id = '', $state = FreshRSS_Entry::STATE_ALL, $order = 'DESC', $limit = 1, $firstId = '', $filter = '', $date_min = 0) { //For API
list($values, $sql) = $this->sqlListWhere($type, $id, $state, $order, $limit, $firstId, $filter, $date_min);
@@ -873,12 +892,28 @@ class FreshRSS_EntryDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
}
public function countUnreadReadFavorites() {
- $sql = 'SELECT c FROM ('
- . 'SELECT COUNT(id) AS c, 1 as o FROM `' . $this->prefix . 'entry` WHERE is_favorite=1 '
- . 'UNION SELECT COUNT(id) AS c, 2 AS o FROM `' . $this->prefix . 'entry` WHERE is_favorite=1 AND is_read=0'
- . ') u ORDER BY o';
+ $sql = <<<SQL
+ SELECT c
+ FROM (
+ SELECT COUNT(e1.id) AS c
+ , 1 AS o
+ FROM `{$this->prefix}entry` AS e1
+ JOIN `{$this->prefix}feed` AS f1 ON e1.id_feed = f1.id
+ WHERE e1.is_favorite = 1
+ AND f1.priority >= :priority_normal
+ UNION
+ SELECT COUNT(e2.id) AS c
+ , 2 AS o
+ FROM `{$this->prefix}entry` AS e2
+ JOIN `{$this->prefix}feed` AS f2 ON e2.id_feed = f2.id
+ WHERE e2.is_favorite = 1
+ AND e2.is_read = 0
+ AND f2.priority >= :priority_normal
+ ) u
+ORDER BY o
+SQL;
$stm = $this->bd->prepare($sql);
- $stm->execute();
+ $stm->execute(array(':priority_normal' => FreshRSS_Feed::PRIORITY_NORMAL));
$res = $stm->fetchAll(PDO::FETCH_COLUMN, 0);
$all = empty($res[0]) ? 0 : $res[0];
$unread = empty($res[1]) ? 0 : $res[1];
diff --git a/app/Models/Feed.php b/app/Models/Feed.php
index 560f7415d..13ab13df9 100644
--- a/app/Models/Feed.php
+++ b/app/Models/Feed.php
@@ -1,6 +1,15 @@
<?php
class FreshRSS_Feed extends Minz_Model {
+ const PRIORITY_MAIN_STREAM = 10;
+ const PRIORITY_NORMAL = 0;
+ const PRIORITY_ARCHIVED = -10;
+
+ const TTL_DEFAULT = 0;
+
+ const KEEP_HISTORY_DEFAULT = -2;
+ const KEEP_HISTORY_INFINITE = -1;
+
private $id = 0;
private $url;
private $category = 1;
@@ -11,12 +20,13 @@ class FreshRSS_Feed extends Minz_Model {
private $website = '';
private $description = '';
private $lastUpdate = 0;
- private $priority = 10;
+ private $priority = self::PRIORITY_MAIN_STREAM;
private $pathEntries = '';
private $httpAuth = '';
private $error = false;
- private $keep_history = -2;
- private $ttl = -2;
+ private $keep_history = self::KEEP_HISTORY_DEFAULT;
+ private $ttl = self::TTL_DEFAULT;
+ private $mute = false;
private $hash = null;
private $lockPath = '';
private $hubUrl = '';
@@ -104,9 +114,12 @@ class FreshRSS_Feed extends Minz_Model {
public function ttl() {
return $this->ttl;
}
+ public function mute() {
+ return $this->mute;
+ }
// public function ttlExpire() {
// $ttl = $this->ttl;
- // if ($ttl == -2) { //Default
+ // if ($ttl == self::TTL_DEFAULT) { //Default
// $ttl = FreshRSS_Context::$user_conf->ttl_default;
// }
// if ($ttl == -1) { //Never
@@ -198,8 +211,7 @@ class FreshRSS_Feed extends Minz_Model {
$this->lastUpdate = $value;
}
public function _priority($value) {
- $value = intval($value);
- $this->priority = $value >= 0 ? $value : 10;
+ $this->priority = intval($value);
}
public function _pathEntries($value) {
$this->pathEntries = $value;
@@ -213,14 +225,14 @@ class FreshRSS_Feed extends Minz_Model {
public function _keepHistory($value) {
$value = intval($value);
$value = min($value, 1000000);
- $value = max($value, -2);
+ $value = max($value, self::KEEP_HISTORY_DEFAULT);
$this->keep_history = $value;
}
public function _ttl($value) {
$value = intval($value);
$value = min($value, 100000000);
- $value = max($value, -2);
- $this->ttl = $value;
+ $this->ttl = abs($value);
+ $this->mute = $value < self::TTL_DEFAULT;
}
public function _nbNotRead($value) {
$this->nbNotRead = intval($value);
diff --git a/app/Models/FeedDAO.php b/app/Models/FeedDAO.php
index 0de6d98be..011b3d112 100644
--- a/app/Models/FeedDAO.php
+++ b/app/Models/FeedDAO.php
@@ -18,7 +18,7 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
ttl
)
VALUES
- (?, ?, ?, ?, ?, ?, 10, ?, 0, -2, -2)';
+ (?, ?, ?, ?, ?, ?, 10, ?, 0, ?, ?)';
$stm = $this->bd->prepare($sql);
$valuesTmp['url'] = safe_ascii($valuesTmp['url']);
@@ -32,6 +32,8 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
substr($valuesTmp['description'], 0, 1023),
$valuesTmp['lastUpdate'],
base64_encode($valuesTmp['httpAuth']),
+ FreshRSS_Feed::KEEP_HISTORY_DEFAULT,
+ FreshRSS_Feed::TTL_DEFAULT,
);
if ($stm && $stm->execute($values)) {
@@ -249,18 +251,14 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
* Use $defaultCacheDuration == -1 to return all feeds, without filtering them by TTL.
*/
public function listFeedsOrderUpdate($defaultCacheDuration = 3600) {
+ $this->updateTTL();
$sql = 'SELECT id, url, name, website, `lastUpdate`, `pathEntries`, `httpAuth`, keep_history, ttl '
. 'FROM `' . $this->prefix . 'feed` '
- . ($defaultCacheDuration < 0 ? '' : 'WHERE ttl <> -1 AND `lastUpdate` < (' . (time() + 60) . '-(CASE WHEN ttl=-2 THEN ' . intval($defaultCacheDuration) . ' ELSE ttl END)) ')
+ . ($defaultCacheDuration < 0 ? '' : 'WHERE ttl >= ' . FreshRSS_Feed::TTL_DEFAULT
+ . ' AND `lastUpdate` < (' . (time() + 60) . '-(CASE WHEN ttl=' . FreshRSS_Feed::TTL_DEFAULT . ' THEN ' . intval($defaultCacheDuration) . ' ELSE ttl END)) ')
. 'ORDER BY `lastUpdate`';
$stm = $this->bd->prepare($sql);
- if (!($stm && $stm->execute())) {
- $sql2 = 'ALTER TABLE `' . $this->prefix . 'feed` ADD COLUMN ttl INT NOT NULL DEFAULT -2'; //v0.7.3
- $stm = $this->bd->prepare($sql2);
- $stm->execute();
- $stm = $this->bd->prepare($sql);
- $stm->execute();
- }
+ $stm->execute();
return self::daoToFeed($stm->fetchAll(PDO::FETCH_ASSOC));
}
@@ -409,8 +407,8 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
$myFeed->_pathEntries(isset($dao['pathEntries']) ? $dao['pathEntries'] : '');
$myFeed->_httpAuth(isset($dao['httpAuth']) ? base64_decode($dao['httpAuth']) : '');
$myFeed->_error(isset($dao['error']) ? $dao['error'] : 0);
- $myFeed->_keepHistory(isset($dao['keep_history']) ? $dao['keep_history'] : -2);
- $myFeed->_ttl(isset($dao['ttl']) ? $dao['ttl'] : -2);
+ $myFeed->_keepHistory(isset($dao['keep_history']) ? $dao['keep_history'] : FreshRSS_Feed::KEEP_HISTORY_DEFAULT);
+ $myFeed->_ttl(isset($dao['ttl']) ? $dao['ttl'] : FreshRSS_Feed::TTL_DEFAULT);
$myFeed->_nbNotRead(isset($dao['cache_nbUnreads']) ? $dao['cache_nbUnreads'] : 0);
$myFeed->_nbEntries(isset($dao['cache_nbEntries']) ? $dao['cache_nbEntries'] : 0);
if (isset($dao['id'])) {
@@ -421,4 +419,20 @@ class FreshRSS_FeedDAO extends Minz_ModelPdo implements FreshRSS_Searchable {
return $list;
}
+
+ public function updateTTL() {
+ $sql = <<<SQL
+UPDATE `{$this->prefix}feed`
+ SET ttl = :new_value
+ WHERE ttl = :old_value
+SQL;
+ $stm = $this->bd->prepare($sql);
+ if (!($stm && $stm->execute(array(':new_value' => FreshRSS_Feed::TTL_DEFAULT, ':old_value' => -2)))) {
+ $sql2 = 'ALTER TABLE `' . $this->prefix . 'feed` ADD COLUMN ttl INT NOT NULL DEFAULT ' . FreshRSS_Feed::TTL_DEFAULT; //v0.7.3
+ $stm = $this->bd->prepare($sql2);
+ $stm->execute();
+ } else {
+ $stm->execute(array(':new_value' => -3600, ':old_value' => -1));
+ }
+ }
}
diff --git a/app/Models/ReadingMode.php b/app/Models/ReadingMode.php
new file mode 100644
index 000000000..06af1704c
--- /dev/null
+++ b/app/Models/ReadingMode.php
@@ -0,0 +1,148 @@
+<?php
+
+/**
+ * Manage the reading modes in FreshRSS.
+ */
+class FreshRSS_ReadingMode {
+
+ /**
+ * @var string
+ */
+ protected $id;
+ /**
+ * @var string
+ */
+ protected $name;
+ /**
+ * @var string
+ */
+ protected $title;
+ /**
+ * @var string[]
+ */
+ protected $urlParams;
+ /**
+ * @var bool
+ */
+ protected $isActive = false;
+
+ /**
+ * ReadingMode constructor.
+ * @param string $id
+ * @param string $title
+ * @param string[] $urlParams
+ * @param bool $active
+ */
+ public function __construct($id, $title, $urlParams, $active) {
+ $this->id = $id;
+ $this->name = _i($id);
+ $this->title = $title;
+ $this->urlParams = $urlParams;
+ $this->isActive = $active;
+ }
+
+ /**
+ * @return string
+ */
+ public function getId() {
+ return $this->id;
+ }
+
+ /**
+ * @return string
+ */
+ public function getName() {
+ return $this->name;
+ }
+
+ /**
+ * @param string $name
+ * @return FreshRSS_ReadingMode
+ */
+ public function setName($name) {
+ $this->name = $name;
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getTitle() {
+ return $this->title;
+ }
+
+ /**
+ * @param string $title
+ * @return FreshRSS_ReadingMode
+ */
+ public function setTitle($title) {
+ $this->title = $title;
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getUrlParams() {
+ return $this->urlParams;
+ }
+
+ /**
+ * @param string $urlParams
+ * @return FreshRSS_ReadingMode
+ */
+ public function setUrlParams($urlParams) {
+ $this->urlParams = $urlParams;
+ return $this;
+ }
+
+ /**
+ * @return bool
+ */
+ public function isActive() {
+ return $this->isActive;
+ }
+
+ /**
+ * @param bool $isActive
+ * @return FreshRSS_ReadingMode
+ */
+ public function setIsActive($isActive) {
+ $this->isActive = $isActive;
+ return $this;
+ }
+
+ /**
+ * Returns the built-in reading modes.
+ * return ReadingMode[]
+ */
+ public static function getReadingModes() {
+ $actualView = Minz_Request::actionName();
+ $defaultCtrl = Minz_Request::defaultControllerName();
+ $isDefaultCtrl = Minz_Request::controllerName() === $defaultCtrl;
+ $urlOutput = Minz_Request::currentRequest();
+
+ $readingModes = array(
+ new FreshRSS_ReadingMode(
+ "view-normal",
+ _t('index.menu.normal_view'),
+ array_merge($urlOutput, array('c' => $defaultCtrl, 'a' => 'normal')),
+ ($isDefaultCtrl && $actualView === 'normal')
+ ),
+ new FreshRSS_ReadingMode(
+ "view-global",
+ _t('index.menu.global_view'),
+ array_merge($urlOutput, array('c' => $defaultCtrl, 'a' => 'global')),
+ ($isDefaultCtrl && $actualView === 'global')
+ ),
+ new FreshRSS_ReadingMode(
+ "view-reader",
+ _t('index.menu.reader_view'),
+ array_merge($urlOutput, array('c' => $defaultCtrl, 'a' => 'reader')),
+ ($isDefaultCtrl && $actualView === 'reader')
+ ),
+ );
+
+ return $readingModes;
+ }
+}