Commits (602)

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.
[*]
end_of_line = lf
insert_final_newline = true
[*.php]
indent_style = tab
phpmd:
image: php:5.6
when: manual
script:
- sh utils/gitlab-ci/php-lint.sh
- curl -o /usr/bin/phpmd -L http://static.phpmd.org/php/2.6.0/phpmd.phar
- chmod +x /usr/bin/phpmd
- sh utils/gitlab-ci/phpmd.sh
schema:
image: fox/selenium-ci
when: manual
script:
- /etc/init.d/postgresql start
- /usr/local/sbin/init-database.sh
- sh ./utils/gitlab-ci/check-schema.sh
phpunit_basic:
image: fox/selenium-ci
when: manual
script:
- /etc/init.d/postgresql start
- /usr/local/sbin/init-database.sh
- sh ./utils/gitlab-ci/check-schema.sh
- cp utils/gitlab-ci/config-template.php config.php
- su -s /bin/bash www-data -c "php ./update.php --debug-feed 1"
- wget -O /usr/bin/phpunit https://phar.phpunit.de/phpunit-5.7.phar
- chmod +x /usr/bin/phpunit
- phpunit tests/*.php
phpunit_functional:
image: fox/selenium-ci
when: manual
script:
- /etc/init.d/postgresql start
- /etc/init.d/nginx start
- /etc/init.d/php5-fpm start
- /usr/local/sbin/init-database.sh
- sh ./utils/gitlab-ci/check-schema.sh
- ln -s `pwd` ../../tt-rss
- cp utils/gitlab-ci/config-template.php config.php
- chmod -R 777 cache lock feed-icons
- /usr/local/sbin/init-selenium.sh
- phpunit tests/functional/*.php
## Contributing code the right way
TLDR: it works pretty much like Github.
1. Make an account on Gogs
2. Fork the repository you're interested in
3. Do the needful
4. File a pull request with your changes against master branch.
This diff is collapsed.
......@@ -87,4 +87,4 @@
header("Api-Content-Length: " . ob_get_length());
ob_end_flush();
?>
......@@ -9,11 +9,11 @@
<html>
<head>
<title><xsl:value-of select="atom:title"/></title>
<link rel="stylesheet" type="text/css" href="css/utility.css"/>
<link rel="stylesheet" type="text/css" href="css/default.css"/>
<script language="javascript" src="lib/xsl_mop-up.js"></script>
</head>
<body onload="go_decoding()">
<body onload="go_decoding()" class="ttrss_utility">
<div id="cometestme" style="display:none;">
<xsl:text disable-output-escaping="yes">&amp;amp;</xsl:text>
......
This diff is collapsed.
This diff is collapsed.
<?php
class Auth_Base {
private $dbh;
private $pdo;
function __construct() {
$this->dbh = Db::get();
$this->pdo = Db::pdo();
}
/**
* @SuppressWarnings(unused)
*/
function check_password($owner_uid, $password) {
return false;
}
/**
* @SuppressWarnings(unused)
*/
function authenticate($login, $password) {
return false;
}
......@@ -27,15 +33,13 @@ class Auth_Base {
if (!$password) $password = make_password();
if (!$user_id) {
$login = $this->dbh->escape_string($login);
$salt = substr(bin2hex(get_random_bytes(125)), 0, 250);
$pwd_hash = encrypt_password($password, $salt, true);
$query = "INSERT INTO ttrss_users
$sth = $this->pdo->prepare("INSERT INTO ttrss_users
(login,access_level,last_login,created,pwd_hash,salt)
VALUES ('$login', 0, null, NOW(), '$pwd_hash','$salt')";
$this->dbh->query($query);
VALUES (?, 0, null, NOW(), ?,?)");
$sth->execute([$login, $pwd_hash, $salt]);
return $this->find_user_by_login($login);
......@@ -48,18 +52,15 @@ class Auth_Base {
}
function find_user_by_login($login) {
$login = $this->dbh->escape_string($login);
$result = $this->dbh->query("SELECT id FROM ttrss_users WHERE
login = '$login'");
$sth = $this->pdo->prepare("SELECT id FROM ttrss_users WHERE
login = ?");
$sth->execute([$login]);
if ($this->dbh->num_rows($result) > 0) {
return $this->dbh->fetch_result($result, 0, "id");
if ($row = $sth->fetch()) {
return $row["id"];
} else {
return false;
}
}
}
?>
......@@ -9,9 +9,7 @@ class Backend extends Handler {
function digestTest() {
header("Content-type: text/html");
require_once "digest.php";
$rv = prepare_headlines_digest($_SESSION['uid'], 1, 1000);
$rv = Digest::prepare_headlines_digest($_SESSION['uid'], 1, 1000);
$rv[3] = "<pre>" . $rv[3] . "</pre>";
......@@ -86,7 +84,7 @@ class Backend extends Handler {
}
function help() {
$topic = basename($_REQUEST["topic"]);
$topic = basename(clean($_REQUEST["topic"]));
switch ($topic) {
case "main":
......@@ -115,5 +113,4 @@ class Backend extends Handler {
__('Close this window')."</button></div>"; */
}
}
?>
}
\ No newline at end of file
<?php
class CCache {
static function zero_all($owner_uid) {
$pdo = Db::pdo();
$sth = $pdo->prepare("UPDATE ttrss_counters_cache SET
value = 0 WHERE owner_uid = ?");
$sth->execute([$owner_uid]);
$sth = $pdo->prepare("UPDATE ttrss_cat_counters_cache SET
value = 0 WHERE owner_uid = ?");
$sth->execute([$owner_uid]);
}
static function remove($feed_id, $owner_uid, $is_cat = false) {
$feed_id = (int) $feed_id;
if (!$is_cat) {
$table = "ttrss_counters_cache";
} else {
$table = "ttrss_cat_counters_cache";
}
$pdo = Db::pdo();
$sth = $pdo->prepare("DELETE FROM $table WHERE
feed_id = ? AND owner_uid = ?");
$sth->execute([$feed_id, $owner_uid]);
}
static function update_all($owner_uid) {
$pdo = Db::pdo();
if (get_pref('ENABLE_FEED_CATS', $owner_uid)) {
$sth = $pdo->prepare("SELECT feed_id FROM ttrss_cat_counters_cache
WHERE feed_id > 0 AND owner_uid = ?");
$sth->execute([$owner_uid]);
while ($line = $sth->fetch()) {
CCache::update($line["feed_id"], $owner_uid, true);
}
/* We have to manually include category 0 */
CCache::update(0, $owner_uid, true);
} else {
$sth = $pdo->prepare("SELECT feed_id FROM ttrss_counters_cache
WHERE feed_id > 0 AND owner_uid = ?");
$sth->execute([$owner_uid]);
while ($line = $sth->fetch()) {
print CCache::update($line["feed_id"], $owner_uid);
}
}
}
static function find($feed_id, $owner_uid, $is_cat = false,
$no_update = false) {
// "" (null) is valid and should be cast to 0 (uncategorized)
// everything else i.e. tags are not
if (!is_numeric($feed_id) && $feed_id)
return;
$feed_id = (int) $feed_id;
if (!$is_cat) {
$table = "ttrss_counters_cache";
} else {
$table = "ttrss_cat_counters_cache";
}
$pdo = Db::pdo();
$sth = $pdo->prepare("SELECT value FROM $table
WHERE owner_uid = ? AND feed_id = ?
LIMIT 1");
$sth->execute([$owner_uid, $feed_id]);
if ($row = $sth->fetch()) {
return $row["value"];
} else {
if ($no_update) {
return -1;
} else {
return CCache::update($feed_id, $owner_uid, $is_cat);
}
}
}
static function update($feed_id, $owner_uid, $is_cat = false,
$update_pcat = true, $pcat_fast = false) {
// "" (null) is valid and should be cast to 0 (uncategorized)
// everything else i.e. tags are not
if (!is_numeric($feed_id) && $feed_id)
return;
$feed_id = (int) $feed_id;
$prev_unread = CCache::find($feed_id, $owner_uid, $is_cat, true);
/* When updating a label, all we need to do is recalculate feed counters
* because labels are not cached */
if ($feed_id < 0) {
CCache::update_all($owner_uid);
return;
}
if (!$is_cat) {
$table = "ttrss_counters_cache";
} else {
$table = "ttrss_cat_counters_cache";
}
$pdo = Db::pdo();
if ($is_cat && $feed_id >= 0) {
/* Recalculate counters for child feeds */
if (!$pcat_fast) {
$sth = $pdo->prepare("SELECT id FROM ttrss_feeds
WHERE owner_uid = :uid AND
(cat_id = :cat OR (:cat = 0 AND cat_id IS NULL))");
$sth->execute([":uid" => $owner_uid, ":cat" => $feed_id]);
while ($line = $sth->fetch()) {
CCache::update((int)$line["id"], $owner_uid, false, false);
}
}
$sth = $pdo->prepare("SELECT SUM(value) AS sv
FROM ttrss_counters_cache, ttrss_feeds
WHERE id = feed_id AND
(cat_id = :cat OR (:cat = 0 AND cat_id IS NULL)) AND
ttrss_counters_cache.owner_uid = :uid AND
ttrss_feeds.owner_uid = :uid");
$sth->execute([":uid" => $owner_uid, ":cat" => $feed_id]);
$row = $sth->fetch();
$unread = (int) $row["sv"];
} else {
$unread = (int) Feeds::getFeedArticles($feed_id, $is_cat, true, $owner_uid);
}
$tr_in_progress = false;
try {
$pdo->beginTransaction();
} catch (Exception $e) {
$tr_in_progress = true;
}
$sth = $pdo->prepare("SELECT feed_id FROM $table
WHERE owner_uid = ? AND feed_id = ? LIMIT 1");
$sth->execute([$owner_uid, $feed_id]);
if ($sth->fetch()) {
$sth = $pdo->prepare("UPDATE $table SET
value = ?, updated = NOW() WHERE
feed_id = ? AND owner_uid = ?");
$sth->execute([$unread, $feed_id, $owner_uid]);
} else {
$sth = $pdo->prepare("INSERT INTO $table
(feed_id, value, owner_uid, updated)
VALUES
(?, ?, ?, NOW())");
$sth->execute([$feed_id, $unread, $owner_uid]);
}
if (!$tr_in_progress) $pdo->commit();
if ($feed_id > 0 && $prev_unread != $unread) {
if (!$is_cat) {
/* Update parent category */
if ($update_pcat) {
$sth = $pdo->prepare("SELECT cat_id FROM ttrss_feeds
WHERE owner_uid = ? AND id = ?");
$sth->execute([$owner_uid, $feed_id]);
if ($row = $sth->fetch()) {
CCache::update((int)$row["cat_id"], $owner_uid, true, true, true);
}
}
}
} else if ($feed_id < 0) {
CCache::update_all($owner_uid);
}
return $unread;
}
}
\ No newline at end of file
<?php
class Counters {
static function getAllCounters() {
$data = Counters::getGlobalCounters();
$data = array_merge($data, Counters::getVirtCounters());
$data = array_merge($data, Counters::getLabelCounters());
$data = array_merge($data, Counters::getFeedCounters());
$data = array_merge($data, Counters::getCategoryCounters());
return $data;
}
static function getCategoryCounters() {
$ret_arr = array();
/* Labels category */
$cv = array("id" => -2, "kind" => "cat",
"counter" => Feeds::getCategoryUnread(-2));
array_push($ret_arr, $cv);
$pdo = DB::pdo();
$sth = $pdo->prepare("SELECT id AS cat_id, value AS unread,
(SELECT COUNT(id) FROM ttrss_feed_categories AS c2
WHERE c2.parent_cat = ttrss_feed_categories.id) AS num_children
FROM ttrss_feed_categories, ttrss_cat_counters_cache
WHERE ttrss_cat_counters_cache.feed_id = id AND
ttrss_cat_counters_cache.owner_uid = ttrss_feed_categories.owner_uid AND
ttrss_feed_categories.owner_uid = ?");
$sth->execute([$_SESSION['uid']]);
while ($line = $sth->fetch()) {
$line["cat_id"] = (int) $line["cat_id"];
if ($line["num_children"] > 0) {
$child_counter = Feeds::getCategoryChildrenUnread($line["cat_id"], $_SESSION["uid"]);
} else {
$child_counter = 0;
}
$cv = array("id" => $line["cat_id"], "kind" => "cat",
"counter" => $line["unread"] + $child_counter);
array_push($ret_arr, $cv);
}
/* Special case: NULL category doesn't actually exist in the DB */
$cv = array("id" => 0, "kind" => "cat",
"counter" => (int) CCache::find(0, $_SESSION["uid"], true));
array_push($ret_arr, $cv);
return $ret_arr;
}
static function getGlobalCounters($global_unread = -1) {
$ret_arr = array();
if ($global_unread == -1) {
$global_unread = Feeds::getGlobalUnread();
}
$cv = array("id" => "global-unread",
"counter" => (int) $global_unread);
array_push($ret_arr, $cv);
$pdo = Db::pdo();
$sth = $pdo->prepare("SELECT COUNT(id) AS fn FROM
ttrss_feeds WHERE owner_uid = ?");
$sth->execute([$_SESSION['uid']]);
$row = $sth->fetch();
$subscribed_feeds = $row["fn"];
$cv = array("id" => "subscribed-feeds",
"counter" => (int) $subscribed_feeds);
array_push($ret_arr, $cv);
return $ret_arr;
}
static function getVirtCounters() {
$ret_arr = array();
for ($i = 0; $i >= -4; $i--) {
$count = getFeedUnread($i);
if ($i == 0 || $i == -1 || $i == -2)
$auxctr = Feeds::getFeedArticles($i, false);
else
$auxctr = 0;
$cv = array("id" => $i,
"counter" => (int) $count,
"auxcounter" => (int) $auxctr);
// if (get_pref('EXTENDED_FEEDLIST'))
// $cv["xmsg"] = getFeedArticles($i)." ".__("total");
array_push($ret_arr, $cv);
}
$feeds = PluginHost::getInstance()->get_feeds(-1);
if (is_array($feeds)) {
foreach ($feeds as $feed) {
$cv = array("id" => PluginHost::pfeed_to_feed_id($feed['id']),
"counter" => $feed['sender']->get_unread($feed['id']));
if (method_exists($feed['sender'], 'get_total'))
$cv["auxcounter"] = $feed['sender']->get_total($feed['id']);
array_push($ret_arr, $cv);
}
}
return $ret_arr;
}
static function getLabelCounters($descriptions = false) {
$ret_arr = array();
$pdo = Db::pdo();
$sth = $pdo->prepare("SELECT id,caption,SUM(CASE WHEN u1.unread = true THEN 1 ELSE 0 END) AS unread, COUNT(u1.unread) AS total
FROM ttrss_labels2 LEFT JOIN ttrss_user_labels2 ON
(ttrss_labels2.id = label_id)
LEFT JOIN ttrss_user_entries AS u1 ON u1.ref_id = article_id
WHERE ttrss_labels2.owner_uid = :uid AND u1.owner_uid = :uid
GROUP BY ttrss_labels2.id,
ttrss_labels2.caption");
$sth->execute([":uid" => $_SESSION['uid']]);
while ($line = $sth->fetch()) {
$id = Labels::label_to_feed_id($line["id"]);
$cv = array("id" => $id,
"counter" => (int) $line["unread"],
"auxcounter" => (int) $line["total"]);
if ($descriptions)
$cv["description"] = $line["caption"];
array_push($ret_arr, $cv);
}
return $ret_arr;
}
static function getFeedCounters($active_feed = false) {
$ret_arr = array();
$pdo = Db::pdo();
$sth = $pdo->prepare("SELECT ttrss_feeds.id,
ttrss_feeds.title,
".SUBSTRING_FOR_DATE."(ttrss_feeds.last_updated,1,19) AS last_updated,
last_error, value AS count
FROM ttrss_feeds, ttrss_counters_cache
WHERE ttrss_feeds.owner_uid = ?
AND ttrss_counters_cache.owner_uid = ttrss_feeds.owner_uid
AND ttrss_counters_cache.feed_id = id");
$sth->execute([$_SESSION['uid']]);
while ($line = $sth->fetch()) {
$id = $line["id"];
$count = $line["count"];
$last_error = htmlspecialchars($line["last_error"]);
$last_updated = make_local_datetime($line['last_updated'], false);
if (Feeds::feedHasIcon($id)) {
$has_img = filemtime(Feeds::getIconFile($id));
} else {
$has_img = false;
}
if (date('Y') - date('Y', strtotime($line['last_updated'])) > 2)
$last_updated = '';
$cv = array("id" => $id,
"updated" => $last_updated,
"counter" => (int) $count,
"has_img" => (int) $has_img);
if ($last_error)
$cv["error"] = $last_error;
// if (get_pref('EXTENDED_FEEDLIST'))
// $cv["xmsg"] = getFeedArticles($id)." ".__("total");
if ($active_feed && $id == $active_feed)
$cv["title"] = truncate_string($line["title"], 30);
array_push($ret_arr, $cv);
}
return $ret_arr;
}
}
\ No newline at end of file
<?php
class Db implements IDb {
class Db
{
/* @var Db $instance */
private static $instance;
/* @var IDb $adapter */
private $adapter;
private $link;
private function __construct() {
/* @var PDO $pdo */
private $pdo;
private function __clone() {
//
}
private function legacy_connect() {
user_error("Legacy connect requested to " . DB_TYPE, E_USER_NOTICE);
$er = error_reporting(E_ALL);
if (defined('_ENABLE_PDO') && _ENABLE_PDO && class_exists("PDO")) {
$this->adapter = new Db_PDO();
} else {
switch (DB_TYPE) {
switch (DB_TYPE) {
case "mysql":
$this->adapter = new Db_Mysqli();
break;
......@@ -20,78 +32,74 @@ class Db implements IDb {
break;
default:
die("Unknown DB_TYPE: " . DB_TYPE);
}
}
if (!$this->adapter) die("Error initializing database adapter for " . DB_TYPE);
if (!$this->adapter) {
print("Error initializing database adapter for " . DB_TYPE);
exit(100);
}
$this->link = $this->adapter->connect(DB_HOST, DB_USER, DB_PASS, DB_NAME, defined('DB_PORT') ? DB_PORT : "");
if (!$this->link) {
die("Error connecting through adapter: " . $this->adapter->last_error());
print("Error connecting through adapter: " . $this->adapter->last_error());
exit(101);
}
error_reporting($er);
}
private function __clone() {
//
}
public static function get() {
if (self::$instance == null)
self::$instance = new self();
private function pdo_connect() {
return self::$instance;
}
$db_port = defined('DB_PORT') && DB_PORT ? ';port=' . DB_PORT : '';
$db_host = defined('DB_HOST') && DB_HOST ? ';host=' . DB_HOST : '';
static function quote($str){
return("'$str'");
}
try {
$this->pdo = new PDO(DB_TYPE . ':dbname=' . DB_NAME . $db_host . $db_port,
DB_USER,
DB_PASS);
} catch (Exception $e) {
print "<pre>Exception while creating PDO object:" . $e->getMessage() . "</pre>";
exit(101);
}
function reconnect() {
$this->link = $this->adapter->connect(DB_HOST, DB_USER, DB_PASS, DB_NAME, defined('DB_PORT') ? DB_PORT : "");
}
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
function connect($host, $user, $pass, $db, $port) {
//return $this->adapter->connect($host, $user, $pass, $db, $port);
return ;
}
if (DB_TYPE == "pgsql") {
function escape_string($s, $strip_tags = true) {
return $this->adapter->escape_string($s, $strip_tags);
}
$this->pdo->query("set client_encoding = 'UTF-8'");
$this->pdo->query("set datestyle = 'ISO, european'");
$this->pdo->query("set TIME ZONE 0");
$this->pdo->query("set cpu_tuple_cost = 0.5");
function query($query, $die_on_error = true) {
return $this->adapter->query($query, $die_on_error);
}
} else if (DB_TYPE == "mysql") {
$this->pdo->query("SET time_zone = '+0:0'");
function fetch_assoc($result) {
return $this->adapter->fetch_assoc($result);
if (defined('MYSQL_CHARSET') && MYSQL_CHARSET) {
$this->pdo->query("SET NAMES " . MYSQL_CHARSET);
}
}
}
function num_rows($result) {
return $this->adapter->num_rows($result);
}
public static function get() {
if (self::$instance == null)
self::$instance = new self();
function fetch_result($result, $row, $param) {
return $this->adapter->fetch_result($result, $row, $param);
}
if (!self::$instance->adapter) {
self::$instance->legacy_connect();
}
function close() {
return $this->adapter->close();
return self::$instance->adapter;
}
function affected_rows($result) {
return $this->adapter->affected_rows($result);
}
public static function pdo() {
if (self::$instance == null)
self::$instance = new self();
function last_error() {
return $this->adapter->last_error();
}
if (!self::$instance->pdo) {
self::$instance->pdo_connect();
}
function last_query_error() {
return $this->adapter->last_query_error();
return self::$instance->pdo;
}
}
?>
}
\ No newline at end of file
......@@ -14,7 +14,8 @@ class Db_Mysqli implements IDb {
return $this->link;
} else {
die("Unable to connect to database (as $user to $host, database $db): " . mysqli_connect_error());
print("Unable to connect to database (as $user to $host, database $db): " . mysqli_connect_error());
exit(102);
}
}
......@@ -64,7 +65,7 @@ class Db_Mysqli implements IDb {
}
function last_error() {
return mysqli_error();
return mysqli_error($this->link);
}
function last_query_error() {
......@@ -75,11 +76,10 @@ class Db_Mysqli implements IDb {
$this->query("SET time_zone = '+0:0'");
if (defined('MYSQL_CHARSET') && MYSQL_CHARSET) {
$this->query("SET NAMES " . MYSQL_CHARSET);
mysqli_set_charset($this->link, MYSQL_CHARSET);
}
return true;
}
}
?>
<?php
class Db_PDO implements IDb {
private $pdo;
function connect($host, $user, $pass, $db, $port) {
$connstr = DB_TYPE . ":host=$host;dbname=$db";
if (DB_TYPE == "mysql") $connstr .= ";charset=utf8";
try {
$this->pdo = new PDO($connstr, $user, $pass);
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->init();
} catch (PDOException $e) {
die($e->getMessage());
}
return $this->pdo;
}
function escape_string($s, $strip_tags = true) {
if ($strip_tags) $s = strip_tags($s);
$qs = $this->pdo->quote($s);
return mb_substr($qs, 1, mb_strlen($qs)-2);
}
function query($query, $die_on_error = true) {
try {
return new Db_Stmt($this->pdo->query($query));
} catch (PDOException $e) {
user_error($e->getMessage(), $die_on_error ? E_USER_ERROR : E_USER_WARNING);
}
}
function fetch_assoc($result) {
try {
if ($result) {
return $result->fetch();
} else {
return null;
}
} catch (PDOException $e) {
user_error($e->getMessage(), E_USER_WARNING);
}
}
function num_rows($result) {
try {
if ($result) {
return $result->rowCount();
} else {
return false;
}
} catch (PDOException $e) {
user_error($e->getMessage(), E_USER_WARNING);
}
}
function fetch_result($result, $row, $param) {
return $result->fetch_result($row, $param);
}
function close() {
$this->pdo = null;
}
function affected_rows($result) {
try {
if ($result) {
return $result->rowCount();
} else {
return null;
}
} catch (PDOException $e) {
user_error($e->getMessage(), E_USER_WARNING);
}
}
function last_error() {
return join(" ", $this->pdo->errorInfo());
}
function init() {
switch (DB_TYPE) {
case "pgsql":
$this->query("set client_encoding = 'UTF-8'");
$this->query("set datestyle = 'ISO, european'");
$this->query("set TIME ZONE 0");
return;
case "mysql":
$this->query("SET time_zone = '+0:0'");
return;
}
return true;
}
}
?>
......@@ -21,7 +21,8 @@ class Db_Pgsql implements IDb {
$this->link = pg_connect($string);
if (!$this->link) {
die("Unable to connect to database (as $user to $host, database $db):" . pg_last_error());
print("Unable to connect to database (as $user to $host, database $db):" . pg_last_error());
exit(102);
}
$this->init();
......@@ -87,5 +88,4 @@ class Db_Pgsql implements IDb {
return true;
}
}
?>
}
\ No newline at end of file
<?php
class Db_Prefs {
private $dbh;
private $pdo;
private static $instance;
private $cache;
function __construct() {
$this->dbh = Db::get();
$this->pdo = Db::pdo();
$this->cache = array();
if ($_SESSION["uid"]) $this->cache();
......@@ -23,31 +23,25 @@ class Db_Prefs {
}
function cache() {
$profile = false;
$user_id = $_SESSION["uid"];
@$profile = $_SESSION["profile"];
if ($profile) {
$profile_qpart = "profile = '$profile' AND";
} else {
$profile_qpart = "profile IS NULL AND";
}
if (get_schema_version() < 63) $profile_qpart = "";
if (!$profile || get_schema_version() < 63) $profile = null;
$result = db_query("SELECT
$sth = $this->pdo->prepare("SELECT
value,ttrss_prefs_types.type_name as type_name,ttrss_prefs.pref_name AS pref_name
FROM
ttrss_user_prefs,ttrss_prefs,ttrss_prefs_types
WHERE
$profile_qpart
(profile = :profile OR (:profile IS NULL AND profile IS NULL)) AND
ttrss_prefs.pref_name NOT LIKE '_MOBILE%' AND
ttrss_prefs_types.id = type_id AND
owner_uid = '$user_id' AND
owner_uid = :uid AND
ttrss_user_prefs.pref_name = ttrss_prefs.pref_name");
while ($line = db_fetch_assoc($result)) {
$sth->execute([":profile" => $profile, ":uid" => $user_id]);
while ($line = $sth->fetch()) {
if ($user_id == $_SESSION["uid"]) {
$pref_name = $line["pref_name"];
......@@ -59,7 +53,6 @@ class Db_Prefs {
function read($pref_name, $user_id = false, $die_on_error = false) {
$pref_name = db_escape_string($pref_name);
$profile = false;
if (!$user_id) {
......@@ -69,33 +62,28 @@ class Db_Prefs {
$user_id = sprintf("%d", $user_id);
}
if (isset($this->cache[$pref_name])) {
if (isset($this->cache[$pref_name]) && !$user_id) {
$tuple = $this->cache[$pref_name];
return $this->convert($tuple["value"], $tuple["type"]);
}
if ($profile) {
$profile_qpart = "profile = '$profile' AND";
} else {
$profile_qpart = "profile IS NULL AND";
}
if (get_schema_version() < 63) $profile_qpart = "";
if (!$profile || get_schema_version() < 63) $profile = null;
$result = db_query("SELECT
$sth = $this->pdo->prepare("SELECT
value,ttrss_prefs_types.type_name as type_name
FROM
ttrss_user_prefs,ttrss_prefs,ttrss_prefs_types
WHERE
$profile_qpart
ttrss_user_prefs.pref_name = '$pref_name' AND
(profile = :profile OR (:profile IS NULL AND profile IS NULL)) AND
ttrss_user_prefs.pref_name = :pref_name AND
ttrss_prefs_types.id = type_id AND
owner_uid = '$user_id' AND
owner_uid = :uid AND
ttrss_user_prefs.pref_name = ttrss_prefs.pref_name");
$sth->execute([":uid" => $user_id, ":profile" => $profile, ":pref_name" => $pref_name]);
if (db_num_rows($result) > 0) {
$value = db_fetch_result($result, 0, "value");
$type_name = db_fetch_result($result, 0, "type_name");
if ($row = $sth->fetch()) {
$value = $row["value"];
$type_name = $row["type_name"];
if ($user_id == $_SESSION["uid"]) {
$this->cache[$pref_name]["type"] = $type_name;
......@@ -121,24 +109,16 @@ class Db_Prefs {
}
function write($pref_name, $value, $user_id = false, $strip_tags = true) {
$pref_name = db_escape_string($pref_name);
$value = db_escape_string($value, $strip_tags);
if ($strip_tags) $value = strip_tags($value);
if (!$user_id) {
$user_id = $_SESSION["uid"];
@$profile = $_SESSION["profile"];
} else {
$user_id = sprintf("%d", $user_id);
$prefs_cache = false;
}
if ($profile) {
$profile_qpart = "AND profile = '$profile'";
} else {
$profile_qpart = "AND profile IS NULL";
}
if (get_schema_version() < 63) $profile_qpart = "";
if (!$profile || get_schema_version() < 63) $profile = null;
$type_name = "";
$current_value = "";
......@@ -149,12 +129,14 @@ class Db_Prefs {
}
if (!$type_name) {
$result = db_query("SELECT type_name
$sth = $this->pdo->prepare("SELECT type_name
FROM ttrss_prefs,ttrss_prefs_types
WHERE pref_name = '$pref_name' AND type_id = ttrss_prefs_types.id");
WHERE pref_name = ? AND type_id = ttrss_prefs_types.id");
$sth->execute([$pref_name]);
if ($row = $sth->fetch())
$type_name = $row["type_name"];
if (db_num_rows($result) > 0)
$type_name = db_fetch_result($result, 0, "type_name");
} else if ($current_value == $value) {
return;
}
......@@ -174,10 +156,12 @@ class Db_Prefs {
$value = 'UTC';
}
db_query("UPDATE ttrss_user_prefs SET
value = '$value' WHERE pref_name = '$pref_name'
$profile_qpart
AND owner_uid = " . $_SESSION["uid"]);
$sth = $this->pdo->prepare("UPDATE ttrss_user_prefs SET
value = :value WHERE pref_name = :pref_name
AND (profile = :profile OR (:profile IS NULL AND profile IS NULL))
AND owner_uid = :uid");
$sth->execute([":pref_name" => $pref_name, ":value" => $value, ":uid" => $user_id, ":profile" => $profile]);
if ($user_id == $_SESSION["uid"]) {
$this->cache[$pref_name]["type"] = $type_name;
......@@ -187,4 +171,3 @@ class Db_Prefs {
}
}
?>
<?php
class Db_Stmt {
private $stmt;
private $cache;
function __construct($stmt) {
$this->stmt = $stmt;
$this->cache = false;
}
function fetch_result($row, $param) {
if (!$this->cache) {
$this->cache = $this->stmt->fetchAll();
}
if (isset($this->cache[$row])) {
return $this->cache[$row][$param];
} else {
user_error("Unable to jump to row $row", E_USER_WARNING);
return false;
}
}
function rowCount() {
return $this->stmt->rowCount();
}
function fetch() {
return $this->stmt->fetch();
}
}
?>
<?php
class DbUpdater {
private $dbh;
private $pdo;
private $db_type;
private $need_version;
function __construct($dbh, $db_type, $need_version) {
$this->dbh = $dbh;
function __construct($pdo, $db_type, $need_version) {
$this->pdo = Db::pdo(); //$pdo;
$this->db_type = $db_type;
$this->need_version = (int) $need_version;
}
function getSchemaVersion() {
$result = db_query("SELECT schema_version FROM ttrss_version");
return (int) db_fetch_result($result, 0, "schema_version");
$row = $this->pdo->query("SELECT schema_version FROM ttrss_version")->fetch();
return (int) $row['schema_version'];
}
function isUpdateRequired() {
......@@ -26,6 +26,7 @@ class DbUpdater {
if (file_exists($filename)) {
return explode(";", preg_replace("/[\r\n]/", "", file_get_contents($filename)));
} else {
user_error("DB Updater: schema file for version $version is not found.");
return false;
}
}
......@@ -37,17 +38,17 @@ class DbUpdater {
if (is_array($lines)) {
db_query("BEGIN");
$this->pdo->beginTransaction();
foreach ($lines as $line) {
if (strpos($line, "--") !== 0 && $line) {
if (!db_query($line, false)) {
if (!$this->pdo->query($line)) {
if ($html_output) {
print_notice("Query: $line");
print_error("Error: " . db_last_query_error());
print_error("Error: " . implode(", ", $this->pdo->errorInfo()));
} else {
_debug("Query: $line");
_debug("Error: " . db_last_query_error());
_debug("Error: " . implode(", ", $this->pdo->errorInfo()));
}
return false;
......@@ -58,18 +59,18 @@ class DbUpdater {
$db_version = $this->getSchemaVersion();
if ($db_version == $version) {
db_query("COMMIT");
$this->pdo->commit();
return true;
} else {
db_query("ROLLBACK");
$this->pdo->rollBack();
return false;
}
} else {
return true;
return false;
}
} else {
return false;
}
}
} ?>
}
\ No newline at end of file