summaryrefslogtreecommitdiff
path: root/classes
diff options
context:
space:
mode:
Diffstat (limited to 'classes')
-rw-r--r--classes/config.php6
-rwxr-xr-xclasses/handler/public.php10
-rw-r--r--classes/pref/prefs.php2
-rw-r--r--classes/prefs.php279
-rw-r--r--classes/userhelper.php4
5 files changed, 293 insertions, 8 deletions
diff --git a/classes/config.php b/classes/config.php
index effbb78ad..95bf3bf71 100644
--- a/classes/config.php
+++ b/classes/config.php
@@ -124,12 +124,12 @@ class Config {
list ($defval, $deftype) = $this::_DEFAULTS[$const];
- $this->params[$cvalue] = [ $this->cast_to(!empty($override) ? $override : $defval, $deftype), $deftype ];
+ $this->params[$cvalue] = [ self::cast_to(!empty($override) ? $override : $defval, $deftype), $deftype ];
}
}
}
- private function cast_to(string $value, int $type_hint) {
+ static function cast_to(string $value, int $type_hint) {
switch ($type_hint) {
case self::T_BOOL:
return sql_bool_to_bool($value);
@@ -149,7 +149,7 @@ class Config {
private function _add(string $param, string $default, int $type_hint) {
$override = getenv($this::_ENVVAR_PREFIX . $param);
- $this->params[$param] = [ $this->cast_to(!empty($override) ? $override : $default, $type_hint), $type_hint ];
+ $this->params[$param] = [ self::cast_to(!empty($override) ? $override : $default, $type_hint), $type_hint ];
}
static function add(string $param, string $default, int $type_hint = Config::T_STRING) {
diff --git a/classes/handler/public.php b/classes/handler/public.php
index 42be6f713..58e467a4f 100755
--- a/classes/handler/public.php
+++ b/classes/handler/public.php
@@ -354,10 +354,12 @@ class Handler_Public extends Handler {
$remember_me = clean($_POST["remember_me"] ?? false);
$safe_mode = checkbox_to_sql_bool(clean($_POST["safe_mode"] ?? false));
- if ($remember_me) {
- @session_set_cookie_params(Config::get(Config::SESSION_COOKIE_LIFETIME));
- } else {
- @session_set_cookie_params(0);
+ if (session_status() != PHP_SESSION_ACTIVE) {
+ if ($remember_me) {
+ session_set_cookie_params(Config::get(Config::SESSION_COOKIE_LIFETIME));
+ } else {
+ session_set_cookie_params(0);
+ }
}
if (UserHelper::authenticate($login, $password)) {
diff --git a/classes/pref/prefs.php b/classes/pref/prefs.php
index 0d0dcadbc..ffee57ed5 100644
--- a/classes/pref/prefs.php
+++ b/classes/pref/prefs.php
@@ -1370,6 +1370,8 @@ class Pref_Prefs extends Handler_Protected {
static function _init_user_prefs($uid, $profile = false) {
+ Prefs::initialize($uid, $profile);
+
if (get_schema_version() < 63) $profile_qpart = "";
$pdo = Db::pdo();
diff --git a/classes/prefs.php b/classes/prefs.php
new file mode 100644
index 000000000..21006e34a
--- /dev/null
+++ b/classes/prefs.php
@@ -0,0 +1,279 @@
+<?php
+class Prefs {
+ // (this is the database-backed version of Config.php)
+
+ const PURGE_OLD_DAYS = "PURGE_OLD_DAYS";
+ const DEFAULT_UPDATE_INTERVAL = "DEFAULT_UPDATE_INTERVAL";
+ const DEFAULT_ARTICLE_LIMIT = "DEFAULT_ARTICLE_LIMIT";
+ const ALLOW_DUPLICATE_POSTS = "ALLOW_DUPLICATE_POSTS";
+ const ENABLE_FEED_CATS = "ENABLE_FEED_CATS";
+ const SHOW_CONTENT_PREVIEW = "SHOW_CONTENT_PREVIEW";
+ const SHORT_DATE_FORMAT = "SHORT_DATE_FORMAT";
+ const LONG_DATE_FORMAT = "LONG_DATE_FORMAT";
+ const COMBINED_DISPLAY_MODE = "COMBINED_DISPLAY_MODE";
+ const HIDE_READ_FEEDS = "HIDE_READ_FEEDS";
+ const ON_CATCHUP_SHOW_NEXT_FEED = "ON_CATCHUP_SHOW_NEXT_FEED";
+ const FEEDS_SORT_BY_UNREAD = "FEEDS_SORT_BY_UNREAD";
+ const REVERSE_HEADLINES = "REVERSE_HEADLINES";
+ const DIGEST_ENABLE = "DIGEST_ENABLE";
+ const CONFIRM_FEED_CATCHUP = "CONFIRM_FEED_CATCHUP";
+ const CDM_AUTO_CATCHUP = "CDM_AUTO_CATCHUP";
+ const _DEFAULT_VIEW_MODE = "_DEFAULT_VIEW_MODE";
+ const _DEFAULT_VIEW_LIMIT = "_DEFAULT_VIEW_LIMIT";
+ //const _PREFS_ACTIVE_TAB = "_PREFS_ACTIVE_TAB";
+ const STRIP_UNSAFE_TAGS = "STRIP_UNSAFE_TAGS";
+ const BLACKLISTED_TAGS = "BLACKLISTED_TAGS";
+ const FRESH_ARTICLE_MAX_AGE = "FRESH_ARTICLE_MAX_AGE";
+ const DIGEST_CATCHUP = "DIGEST_CATCHUP";
+ const CDM_EXPANDED = "CDM_EXPANDED";
+ const PURGE_UNREAD_ARTICLES = "PURGE_UNREAD_ARTICLES";
+ const HIDE_READ_SHOWS_SPECIAL = "HIDE_READ_SHOWS_SPECIAL";
+ const VFEED_GROUP_BY_FEED = "VFEED_GROUP_BY_FEED";
+ const STRIP_IMAGES = "STRIP_IMAGES";
+ const _DEFAULT_VIEW_ORDER_BY = "_DEFAULT_VIEW_ORDER_BY";
+ const ENABLE_API_ACCESS = "ENABLE_API_ACCESS";
+ //const _COLLAPSED_SPECIAL = "_COLLAPSED_SPECIAL";
+ //const _COLLAPSED_LABELS = "_COLLAPSED_LABELS";
+ //const _COLLAPSED_UNCAT = "_COLLAPSED_UNCAT";
+ //const _COLLAPSED_FEEDLIST = "_COLLAPSED_FEEDLIST";
+ //const _MOBILE_ENABLE_CATS = "_MOBILE_ENABLE_CATS";
+ //const _MOBILE_SHOW_IMAGES = "_MOBILE_SHOW_IMAGES";
+ //const _MOBILE_HIDE_READ = "_MOBILE_HIDE_READ";
+ //const _MOBILE_SORT_FEEDS_UNREAD = "_MOBILE_SORT_FEEDS_UNREAD";
+ //const _MOBILE_BROWSE_CATS = "_MOBILE_BROWSE_CATS";
+ //const _THEME_ID = "_THEME_ID";
+ const USER_TIMEZONE = "USER_TIMEZONE";
+ const USER_STYLESHEET = "USER_STYLESHEET";
+ const SORT_HEADLINES_BY_FEED_DATE = "SORT_HEADLINES_BY_FEED_DATE";
+ const SSL_CERT_SERIAL = "SSL_CERT_SERIAL";
+ const DIGEST_PREFERRED_TIME = "DIGEST_PREFERRED_TIME";
+ //const _PREFS_SHOW_EMPTY_CATS = "_PREFS_SHOW_EMPTY_CATS";
+ const _DEFAULT_INCLUDE_CHILDREN = "_DEFAULT_INCLUDE_CHILDREN";
+ //const AUTO_ASSIGN_LABELS = "AUTO_ASSIGN_LABELS";
+ const _ENABLED_PLUGINS = "_ENABLED_PLUGINS";
+ const _MOBILE_REVERSE_HEADLINES = "_MOBILE_REVERSE_HEADLINES";
+ const USER_CSS_THEME = "USER_CSS_THEME";
+ const USER_LANGUAGE = "USER_LANGUAGE";
+ const DEFAULT_SEARCH_LANGUAGE = "DEFAULT_SEARCH_LANGUAGE";
+ const _PREFS_MIGRATED = "_PREFS_MIGRATED";
+
+ private const _DEFAULTS = [
+ Prefs::PURGE_OLD_DAYS => [ 60, Config::T_INT ],
+ Prefs::DEFAULT_UPDATE_INTERVAL => [ 30, Config::T_INT ],
+ Prefs::DEFAULT_ARTICLE_LIMIT => [ 30, Config::T_INT ],
+ Prefs::ALLOW_DUPLICATE_POSTS => [ false, Config::T_BOOL ],
+ Prefs::ENABLE_FEED_CATS => [ true, Config::T_BOOL ],
+ Prefs::SHOW_CONTENT_PREVIEW => [ true, Config::T_BOOL ],
+ Prefs::SHORT_DATE_FORMAT => [ "M d, G:i", Config::T_STRING ],
+ Prefs::LONG_DATE_FORMAT => [ "D, M d Y - G:i", Config::T_STRING ],
+ Prefs::COMBINED_DISPLAY_MODE => [ true, Config::T_BOOL ],
+ Prefs::HIDE_READ_FEEDS => [ false, Config::T_BOOL ],
+ Prefs::ON_CATCHUP_SHOW_NEXT_FEED => [ false, Config::T_BOOL ],
+ Prefs::FEEDS_SORT_BY_UNREAD => [ false, Config::T_BOOL ],
+ Prefs::REVERSE_HEADLINES => [ false, Config::T_BOOL ],
+ Prefs::DIGEST_ENABLE => [ false, Config::T_BOOL ],
+ Prefs::CONFIRM_FEED_CATCHUP => [ true, Config::T_BOOL ],
+ Prefs::CDM_AUTO_CATCHUP => [ false, Config::T_BOOL ],
+ Prefs::_DEFAULT_VIEW_MODE => [ "adaptive", Config::T_BOOL ],
+ Prefs::_DEFAULT_VIEW_LIMIT => [ 30, Config::T_INT ],
+ //Prefs::_PREFS_ACTIVE_TAB => [ "", Config::T_STRING ],
+ Prefs::STRIP_UNSAFE_TAGS => [ true, Config::T_BOOL ],
+ Prefs::BLACKLISTED_TAGS => [ 'main, generic, misc, uncategorized, blog, blogroll, general, news', Config::T_STRING ],
+ Prefs::FRESH_ARTICLE_MAX_AGE => [ 24, Config::T_INT ],
+ Prefs::DIGEST_CATCHUP => [ false, Config::T_BOOL ],
+ Prefs::CDM_EXPANDED => [ true, Config::T_BOOL ],
+ Prefs::PURGE_UNREAD_ARTICLES => [ true, Config::T_BOOL ],
+ Prefs::HIDE_READ_SHOWS_SPECIAL => [ true, Config::T_BOOL ],
+ Prefs::VFEED_GROUP_BY_FEED => [ false, Config::T_BOOL ],
+ Prefs::STRIP_IMAGES => [ false, Config::T_BOOL ],
+ Prefs::_DEFAULT_VIEW_ORDER_BY => [ "default", Config::T_STRING ],
+ Prefs::ENABLE_API_ACCESS => [ false, Config::T_BOOL ],
+ //Prefs::_COLLAPSED_SPECIAL => [ false, Config::T_BOOL ],
+ //Prefs::_COLLAPSED_LABELS => [ false, Config::T_BOOL ],
+ //Prefs::_COLLAPSED_UNCAT => [ false, Config::T_BOOL ],
+ //Prefs::_COLLAPSED_FEEDLIST => [ false, Config::T_BOOL ],
+ //Prefs::_MOBILE_ENABLE_CATS => [ false, Config::T_BOOL ],
+ //Prefs::_MOBILE_SHOW_IMAGES => [ false, Config::T_BOOL ],
+ //Prefs::_MOBILE_HIDE_READ => [ false, Config::T_BOOL ],
+ //Prefs::_MOBILE_SORT_FEEDS_UNREAD => [ false, Config::T_BOOL ],
+ //Prefs::_MOBILE_BROWSE_CATS => [ true, Config::T_BOOL ],
+ //Prefs::_THEME_ID => [ 0, Config::T_BOOL ],
+ Prefs::USER_TIMEZONE => [ "Automatic", Config::T_STRING ],
+ Prefs::USER_STYLESHEET => [ "", Config::T_STRING ],
+ Prefs::SORT_HEADLINES_BY_FEED_DATE => [ false, Config::T_BOOL ],
+ Prefs::SSL_CERT_SERIAL => [ "", Config::T_STRING ],
+ Prefs::DIGEST_PREFERRED_TIME => [ "00:00", Config::T_STRING ],
+ //Prefs::_PREFS_SHOW_EMPTY_CATS => [ false, Config::T_BOOL ],
+ Prefs::_DEFAULT_INCLUDE_CHILDREN => [ false, Config::T_BOOL ],
+ //Prefs::AUTO_ASSIGN_LABELS => [ false, Config::T_BOOL ],
+ Prefs::_ENABLED_PLUGINS => [ "", Config::T_STRING ],
+ Prefs::_MOBILE_REVERSE_HEADLINES => [ false, Config::T_BOOL ],
+ Prefs::USER_CSS_THEME => [ "" , Config::T_STRING ],
+ Prefs::USER_LANGUAGE => [ "" , Config::T_STRING ],
+ Prefs::DEFAULT_SEARCH_LANGUAGE => [ "" , Config::T_STRING ],
+ Prefs::_PREFS_MIGRATED => [ false, Config::T_BOOL ],
+ ];
+
+ private const _PROFILE_BLACKLIST = [
+ Prefs::ALLOW_DUPLICATE_POSTS,
+ Prefs::PURGE_OLD_DAYS,
+ Prefs::PURGE_UNREAD_ARTICLES,
+ Prefs::DIGEST_ENABLE,
+ Prefs::DIGEST_CATCHUP,
+ Prefs::BLACKLISTED_TAGS,
+ Prefs::ENABLE_API_ACCESS,
+ //Prefs::UPDATE_POST_ON_CHECKSUM_CHANGE,
+ Prefs::DEFAULT_UPDATE_INTERVAL,
+ Prefs::USER_TIMEZONE,
+ Prefs::SORT_HEADLINES_BY_FEED_DATE,
+ Prefs::SSL_CERT_SERIAL,
+ Prefs::DIGEST_PREFERRED_TIME
+ ];
+
+ private static $instance;
+ private $cache = [];
+
+ /** @var PDO */
+ private $pdo;
+
+ public static function get_instance() {
+ if (self::$instance == null)
+ self::$instance = new self();
+
+ return self::$instance;
+ }
+
+ function __construct() {
+ $this->pdo = Db::pdo();
+
+ /*$ref = new ReflectionClass(get_class($this));
+
+ foreach ($ref->getConstants() as $const => $cvalue) {
+ if (isset($this::_DEFAULTS[$const])) {
+ list ($defval, $deftype) = $this::_DEFAULTS[$const];
+
+ $this->cache[$cvalue] = [ Config::cast_to($defval, $deftype), $deftype ];
+ }
+ }*/
+ }
+
+ private function _get(string $pref_name, int $owner_uid, int $profile_id = null) {
+ if (isset(self::_DEFAULTS[$pref_name])) {
+ if (!$profile_id || in_array($pref_name, self::_PROFILE_BLACKLIST)) $profile_id = null;
+
+ list ($def_val, $type_hint) = self::_DEFAULTS[$pref_name];
+
+ $cached_value = $this->_get_cache($pref_name, $owner_uid, $profile_id);
+
+ if (!empty($cached_value)) {
+ return Config::cast_to($cached_value, $type_hint);
+ } else {
+ $sth = $this->pdo->prepare("SELECT value FROM ttrss_user_prefs2
+ WHERE pref_name = :name AND owner_uid = :uid AND
+ (profile = :profile OR (:profile IS NULL AND profile IS NULL))");
+
+ $sth->execute(["uid" => $owner_uid, "profile" => $profile_id, "name" => $pref_name ]);
+
+ if ($row = $sth->fetch(PDO::FETCH_ASSOC)) {
+ $this->_set_cache($pref_name, $row["value"], $owner_uid, $profile_id);
+
+ return Config::cast_to($row["value"], $type_hint);
+ } else {
+ $this->_set_cache($pref_name, $def_val, $owner_uid, $profile_id);
+
+ return $def_val;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ private function _get_cache(string $pref_name, int $owner_uid, int $profile_id = null) {
+ $cache_key = sprintf("%d/%d/%s", $owner_uid, $profile_id, $pref_name);
+
+ if (isset($this->cache[$cache_key]))
+ return $this->cache[$cache_key];
+
+ return null;
+ }
+
+ private function _set_cache(string $pref_name, $value, int $owner_uid, int $profile_id = null) {
+ $cache_key = sprintf("%d/%d/%s", $owner_uid, $profile_id, $pref_name);
+
+ $this->cache[$cache_key] = $value;
+ }
+
+ private function _set(string $pref_name, $value, int $owner_uid, int $profile_id = null) {
+ if (!$profile_id) $profile_id = null;
+
+ if ($profile_id && in_array($pref_name, self::_PROFILE_BLACKLIST))
+ return false;
+
+ if (isset(self::_DEFAULTS[$pref_name])) {
+
+ $this->_set_cache($pref_name, $value, $owner_uid, $profile_id);
+
+ $sth = $this->pdo->prepare("SELECT COUNT(pref_name) AS count FROM ttrss_user_prefs2
+ WHERE pref_name = :name AND owner_uid = :uid AND
+ (profile = :profile OR (:profile IS NULL AND profile IS NULL))");
+ $sth->execute(["uid" => $owner_uid, "profile" => $profile_id, "name" => $pref_name ]);
+
+ if ($row = $sth->fetch()) {
+ if ($row["count"] == 0) {
+ $sth = $this->pdo->prepare("INSERT INTO ttrss_user_prefs2
+ (pref_name, value, owner_uid, profile)
+ VALUES
+ (:name, :value, :uid, :profile)");
+
+ return $sth->execute(["uid" => $owner_uid, "profile" => $profile_id, "name" => $pref_name, "value" => $value ]);
+
+ } else {
+ $sth = $this->pdo->prepare("UPDATE ttrss_user_prefs2
+ SET value = :value
+ WHERE pref_name = :name AND owner_uid = :uid AND
+ (profile = :profile OR (:profile IS NULL AND profile IS NULL))");
+
+ return $sth->execute(["uid" => $owner_uid, "profile" => $profile_id, "name" => $pref_name, "value" => $value ]);
+ }
+ }
+ }
+
+ return false;
+ }
+
+ function migrate(int $owner_uid, int $profile_id = null) {
+ if (get_schema_version(true) < 141)
+ return;
+
+ if (!$profile_id) $profile_id = null;
+
+ if (!$this->_get(Prefs::_PREFS_MIGRATED, $owner_uid, $profile_id)) {
+
+ $sth = $this->pdo->prepare("SELECT pref_name, value FROM ttrss_user_prefs
+ WHERE owner_uid = :uid AND
+ (profile = :profile OR (:profile IS NULL AND profile IS NULL))");
+ $sth->execute(["uid" => $owner_uid, "profile" => $profile_id]);
+
+ while ($row = $sth->fetch(PDO::FETCH_ASSOC)) {
+ if (isset(self::_DEFAULTS[$row["pref_name"]])) {
+ list ($def_val, $type_hint) = self::_DEFAULTS[$row["pref_name"]];
+
+ $user_val = Config::cast_to($row["value"], $type_hint);
+
+ if ($user_val != $def_val) {
+ $this->_set($row["pref_name"], $user_val, $owner_uid, $profile_id);
+ }
+ }
+ }
+
+ $this->_set(Prefs::_PREFS_MIGRATED, "1", $owner_uid, $profile_id);
+ }
+ }
+
+ static function initialize(int $owner_uid, int $profile_id = null) {
+ $instance = self::get_instance();
+
+ $instance->migrate($owner_uid, $profile_id);
+ }
+}
diff --git a/classes/userhelper.php b/classes/userhelper.php
index 82a2fe05f..949c8a5cf 100644
--- a/classes/userhelper.php
+++ b/classes/userhelper.php
@@ -18,7 +18,9 @@ class UserHelper {
if ($user_id && !$check_only) {
- session_start();
+ if (session_status() != PHP_SESSION_ACTIVE)
+ session_start();
+
session_regenerate_id(true);
$_SESSION["uid"] = $user_id;