diff --git a/classes/prefs.php b/classes/prefs.php new file mode 100644 index 000000000..9855c67d7 --- /dev/null +++ b/classes/prefs.php @@ -0,0 +1,251 @@ + [ 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($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; + + $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 ]); + + list ($def_val, $type_hint) = self::_DEFAULTS[$pref_name]; + + if ($row = $sth->fetch(PDO::FETCH_ASSOC)) { + return Config::cast_to($row["value"], $type_hint); + } else { + return $def_val; + } + } + + return null; + } + + private function _set($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])) { + $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 (!$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); + } + + die; + } + + static function initialize($owner_uid, int $profile_id = null) { + $instance = self::get_instance(); + + $instance->migrate($owner_uid, $profile_id); + } +}