";
}
}
}
if (!get_pref($link, 'ENABLE_FEED_CATS')) {
print "
";
}
if (get_pref($link, 'ENABLE_FEED_CATS')) {
if (get_pref($link, "FEEDS_SORT_BY_UNREAD")) {
$order_by_qpart = "order_id,category,unread DESC,title";
} else {
$order_by_qpart = "order_id,category,title";
}
} else {
if (get_pref($link, "FEEDS_SORT_BY_UNREAD")) {
$order_by_qpart = "unread DESC,title";
} else {
$order_by_qpart = "title";
}
}
$age_qpart = getMaxAgeSubquery();
$query = "SELECT ttrss_feeds.*,
".SUBSTRING_FOR_DATE."(last_updated,1,19) AS last_updated_noms,
cat_id,last_error,
ttrss_feed_categories.title AS category,
ttrss_feed_categories.collapsed
FROM ttrss_feeds LEFT JOIN ttrss_feed_categories
ON (ttrss_feed_categories.id = cat_id)
WHERE
ttrss_feeds.hidden = false AND
ttrss_feeds.owner_uid = '$owner_uid' AND parent_feed IS NULL
ORDER BY $order_by_qpart";
$result = db_query($link, $query);
$actid = $_GET["actid"];
/* real feeds */
$lnum = 0;
$total_unread = 0;
$category = "";
$short_date = get_pref($link, 'SHORT_DATE_FORMAT');
while ($line = db_fetch_assoc($result)) {
$feed = trim($line["title"]);
if (!$feed) $feed = "[Untitled]";
$feed_id = $line["id"];
$subop = $_GET["subop"];
$unread = ccache_find($link, $feed_id, $_SESSION["uid"]);
if (get_pref($link, 'HEADLINES_SMART_DATE')) {
$last_updated = smart_date_time(strtotime($line["last_updated_noms"]));
} else {
$last_updated = date($short_date, strtotime($line["last_updated_noms"]));
}
$rtl_content = sql_bool_to_bool($line["rtl_content"]);
if ($rtl_content) {
$rtl_tag = "dir=\"RTL\"";
} else {
$rtl_tag = "";
}
$tmp_result = db_query($link,
"SELECT SUM(value) AS unread FROM ttrss_feeds, ttrss_counters_cache
WHERE parent_feed = '$feed_id' AND feed_id = id");
$unread += db_fetch_result($tmp_result, 0, "unread");
$cat_id = $line["cat_id"];
$tmp_category = $line["category"];
if (!$tmp_category) {
$tmp_category = __("Uncategorized");
}
// $class = ($lnum % 2) ? "even" : "odd";
if ($line["last_error"]) {
$class = "error";
} else {
$class = "feed";
}
if ($unread > 0) $class .= "Unread";
if ($actid == $feed_id) {
$class .= "Selected";
}
$total_unread += $unread;
if ($category != $tmp_category && get_pref($link, 'ENABLE_FEED_CATS')) {
if ($category) {
print "";
}
$category = $tmp_category;
$collapsed = sql_bool_to_bool($line["collapsed"]);
// workaround for NULL category
if ($category == __("Uncategorized")) {
if ($_COOKIE["ttrss_vf_uclps"] == 1) {
$collapsed = "t";
}
}
$cat_id = sprintf("%d", $cat_id);
printCategoryHeader($link, $cat_id, $collapsed, true);
}
printFeedEntry($feed_id, $class, $feed, $unread,
ICONS_URL."/$feed_id.ico", $link, $rtl_content,
$last_updated, $line["last_error"]);
++$lnum;
}
if (db_num_rows($result) == 0) {
print "
".__('No feeds to display.')."
";
}
} else {
// tags
/* $result = db_query($link, "SELECT tag_name,count(ttrss_entries.id) AS count
FROM ttrss_tags,ttrss_entries,ttrss_user_entries WHERE
post_int_id = ttrss_user_entries.int_id AND
unread = true AND ref_id = ttrss_entries.id
AND ttrss_tags.owner_uid = '$owner_uid' GROUP BY tag_name
UNION
select tag_name,0 as count FROM ttrss_tags WHERE owner_uid = '$owner_uid'
ORDER BY tag_name"); */
if (get_pref($link, 'ENABLE_FEED_CATS')) {
print "
".__('Tags')."
";
print "
";
}
$age_qpart = getMaxAgeSubquery();
$result = db_query($link, "SELECT tag_name,SUM((SELECT COUNT(int_id)
FROM ttrss_user_entries,ttrss_entries WHERE int_id = post_int_id
AND ref_id = id AND $age_qpart
AND unread = true)) AS count FROM ttrss_tags
WHERE owner_uid = ".$_SESSION['uid']." GROUP BY tag_name
ORDER BY count DESC LIMIT 50");
$tags = array();
while ($line = db_fetch_assoc($result)) {
$tags[$line["tag_name"]] += $line["count"];
}
foreach (array_keys($tags) as $tag) {
$unread = $tags[$tag];
$class = "tag";
if ($unread > 0) {
$class .= "Unread";
}
printFeedEntry($tag, $class, $tag, $unread, "images/tag.png", $link);
}
if (db_num_rows($result) == 0) {
print "
No tags to display.
";
}
if (get_pref($link, 'ENABLE_FEED_CATS')) {
print "
";
}
}
print "";
}
function get_article_tags($link, $id, $owner_uid = 0) {
$a_id = db_escape_string($id);
if (!$owner_uid) $owner_uid = $_SESSION["uid"];
$tmp_result = db_query($link, "SELECT DISTINCT tag_name,
owner_uid as owner FROM
ttrss_tags WHERE post_int_id = (SELECT int_id FROM ttrss_user_entries WHERE
ref_id = '$a_id' AND owner_uid = '$owner_uid' LIMIT 1) ORDER BY tag_name");
$tags = array();
while ($tmp_line = db_fetch_assoc($tmp_result)) {
array_push($tags, $tmp_line["tag_name"]);
}
return $tags;
}
function trim_value(&$value) {
$value = trim($value);
}
function trim_array($array) {
$tmp = $array;
array_walk($tmp, 'trim_value');
return $tmp;
}
function tag_is_valid($tag) {
if ($tag == '') return false;
if (preg_match("/^[0-9]*$/", $tag)) return false;
if (function_exists('iconv')) {
$tag = iconv("utf-8", "utf-8", $tag);
}
if (!$tag) return false;
return true;
}
function render_login_form($link, $mobile = false) {
if (!$mobile) {
require_once "login_form.php";
} else {
require_once "mobile/login_form.php";
}
}
// from http://developer.apple.com/internet/safari/faq.html
function no_cache_incantation() {
header("Expires: Mon, 22 Dec 1980 00:00:00 GMT"); // Happy birthday to me :)
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); // always modified
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0"); // HTTP/1.1
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache"); // HTTP/1.0
}
function format_warning($msg, $id = "") {
return "
$msg
";
}
function format_notice($msg) {
return "
$msg
";
}
function format_error($msg) {
return "
$msg
";
}
function print_notice($msg) {
return print format_notice($msg);
}
function print_warning($msg) {
return print format_warning($msg);
}
function print_error($msg) {
return print format_error($msg);
}
function T_sprintf() {
$args = func_get_args();
return vsprintf(__(array_shift($args)), $args);
}
function outputArticleXML($link, $id, $feed_id, $mark_as_read = true,
$zoom_mode = false) {
/* we can figure out feed_id from article id anyway, why do we
* pass feed_id here? */
$result = db_query($link, "SELECT feed_id FROM ttrss_user_entries
WHERE ref_id = '$id'");
$feed_id = db_fetch_result($result, 0, "feed_id");
if (!$zoom_mode) { print "";
} else {
$feed_icon = " ";
}
/* if ($line["comments"] && $line["link"] != $line["comments"]) {
$entry_comments = "(Comments)";
} else {
$entry_comments = "";
} */
$num_comments = $line["num_comments"];
$entry_comments = "";
if ($num_comments > 0) {
if ($line["comments"]) {
$comments_url = $line["comments"];
} else {
$comments_url = $line["link"];
}
$entry_comments = "$num_comments comments";
} else {
if ($line["comments"] && $line["link"] != $line["comments"]) {
$entry_comments = "comments";
}
}
if ($zoom_mode) {
header("Content-Type: text/html");
print "
Tiny Tiny RSS - ".$line["title"]."
";
}
print "
";
}
// print_headline_subtoolbar($link,
// "javascript:catchupPage()", "Mark page as read", true, $rtl_content);
} else {
$message = "";
switch ($view_mode) {
case "unread":
$message = __("No unread articles found to display.");
break;
case "marked":
$message = __("No starred articles found to display.");
break;
default:
$message = __("No articles found to display.");
}
if (!$offset) print "
$message
";
}
if (!$offset) {
print "
";
print "
";
}
return array($topmost_article_ids, $headlines_count, $feed, $disable_cache, $vgroup_last_feed);
}
// from here: http://www.roscripts.com/Create_tag_cloud-71.html
function printTagCloud($link) {
/* get first ref_id to count from */
/*
$query = "";
if (DB_TYPE == "pgsql") {
$query = "SELECT MIN(id) AS id FROM ttrss_user_entries, ttrss_entries
WHERE int_id = id AND owner_uid = ".$_SESSION["uid"]."
AND date_entered > NOW() - INTERVAL '30 days'";
} else {
$query = "SELECT MIN(id) AS id FROM ttrss_user_entries, ttrss_entries
WHERE int_id = id AND owner_uid = ".$_SESSION["uid"]."
AND date_entered > DATE_SUB(NOW(), INTERVAL 30 DAY)";
}
$result = db_query($link, $query);
$first_id = db_fetch_result($result, 0, "id"); */
//AND post_int_id >= '$first_id'
$query = "SELECT tag_name, COUNT(post_int_id) AS count
FROM ttrss_tags WHERE owner_uid = ".$_SESSION["uid"]."
GROUP BY tag_name ORDER BY count DESC LIMIT 50";
$result = db_query($link, $query);
$tags = array();
while ($line = db_fetch_assoc($result)) {
$tags[$line["tag_name"]] = $line["count"];
}
ksort($tags);
$max_size = 32; // max font size in pixels
$min_size = 11; // min font size in pixels
// largest and smallest array values
$max_qty = max(array_values($tags));
$min_qty = min(array_values($tags));
// find the range of values
$spread = $max_qty - $min_qty;
if ($spread == 0) { // we don't want to divide by zero
$spread = 1;
}
// set the font-size increment
$step = ($max_size - $min_size) / ($spread);
// loop through the tag array
foreach ($tags as $key => $value) {
// calculate font-size
// find the $value in excess of $min_qty
// multiply by the font-size increment ($size)
// and add the $min_size set above
$size = round($min_size + (($value - $min_qty) * $step));
$key_escaped = str_replace("'", "\\'", $key);
echo "' . $key . ' ';
}
}
function print_checkpoint($n, $s) {
$ts = getmicrotime();
echo sprintf("", $ts - $s);
return $ts;
}
function sanitize_tag($tag) {
$tag = trim($tag);
$tag = mb_strtolower($tag, 'utf-8');
$tag = preg_replace('/[\"\+\>\<]/', "", $tag);
// $tag = str_replace('"', "", $tag);
// $tag = str_replace("+", " ", $tag);
$tag = str_replace("technorati tag: ", "", $tag);
return $tag;
}
function generate_publish_key() {
return sha1(uniqid(rand(), true));
}
function article_publish_url($link) {
$url_path = "";
if ($_SERVER['HTTPS'] != "on") {
$url_path = "http://";
} else {
$url_path = "https://";
}
$url_path .= $_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']);
$url_path .= "/backend.php?op=publish&key=" . get_pref($link, "_PREFS_PUBLISH_KEY");
return $url_path;
}
/**
* Purge a feed contents, marked articles excepted.
*
* @param mixed $link The database connection.
* @param integer $id The id of the feed to purge.
* @return void
*/
function clear_feed_articles($link, $id) {
$result = db_query($link, "DELETE FROM ttrss_user_entries
WHERE feed_id = '$id' AND marked = false AND owner_uid = " . $_SESSION["uid"]);
$result = db_query($link, "DELETE FROM ttrss_entries WHERE
(SELECT COUNT(int_id) FROM ttrss_user_entries WHERE ref_id = id) = 0");
ccache_update($link, $id, $_SESSION['uid']);
} // function clear_feed_articles
/**
* Compute the Mozilla Firefox feed adding URL from server HOST and REQUEST_URI.
*
* @return string The Mozilla Firefox feed adding URL.
*/
function add_feed_url() {
$url_path = ($_SERVER['HTTPS'] != "on" ? 'http://' : 'https://') . $_SERVER["HTTP_HOST"] . parse_url($_SERVER["REQUEST_URI"], PHP_URL_PATH);
$url_path .= "?op=pref-feeds&quiet=1&subop=add&feed_url=%s";
return $url_path;
} // function add_feed_url
/**
* Encrypt a password in SHA1.
*
* @param string $pass The password to encrypt.
* @param string $login A optionnal login.
* @return string The encrypted password.
*/
function encrypt_password($pass, $login = '') {
if ($login) {
return "SHA1X:" . sha1("$login:$pass");
} else {
return "SHA1:" . sha1($pass);
}
} // function encrypt_password
/**
* Update a feed batch.
* Used by daemons to update n feeds by run.
* Only update feed needing a update, and not being processed
* by another process.
*
* @param mixed $link Database link
* @param integer $limit Maximum number of feeds in update batch. Default to DAEMON_FEED_LIMIT.
* @param boolean $from_http Set to true if you call this function from http to disable cli specific code.
* @param boolean $debug Set to false to disable debug output. Default to true.
* @return void
*/
function update_daemon_common($link, $limit = DAEMON_FEED_LIMIT, $from_http = false, $debug = true) {
// Process all other feeds using last_updated and interval parameters
// Test if the user has loggued in recently. If not, it does not update its feeds.
if (DAEMON_UPDATE_LOGIN_LIMIT > 0) {
if (DB_TYPE == "pgsql") {
$login_thresh_qpart = "AND ttrss_users.last_login >= NOW() - INTERVAL '".DAEMON_UPDATE_LOGIN_LIMIT." days'";
} else {
$login_thresh_qpart = "AND ttrss_users.last_login >= DATE_SUB(NOW(), INTERVAL ".DAEMON_UPDATE_LOGIN_LIMIT." DAY)";
}
} else {
$login_thresh_qpart = "";
}
// Test if the feed need a update (update interval exceded).
if (DB_TYPE == "pgsql") {
$update_limit_qpart = "AND ((
ttrss_feeds.update_interval = 0
AND ttrss_feeds.last_updated < NOW() - CAST((ttrss_user_prefs.value || ' minutes') AS INTERVAL)
) OR (
ttrss_feeds.update_interval > 0
AND ttrss_feeds.last_updated < NOW() - CAST((ttrss_feeds.update_interval || ' minutes') AS INTERVAL)
) OR ttrss_feeds.last_updated IS NULL)";
} else {
$update_limit_qpart = "AND ((
ttrss_feeds.update_interval = 0
AND ttrss_feeds.last_updated < DATE_SUB(NOW(), INTERVAL CONVERT(ttrss_user_prefs.value, SIGNED INTEGER) MINUTE)
) OR (
ttrss_feeds.update_interval > 0
AND ttrss_feeds.last_updated < DATE_SUB(NOW(), INTERVAL ttrss_feeds.update_interval MINUTE)
) OR ttrss_feeds.last_updated IS NULL)";
}
// Test if feed is currently being updated by another process.
if (DB_TYPE == "pgsql") {
$updstart_thresh_qpart = "AND (ttrss_feeds.last_update_started IS NULL OR ttrss_feeds.last_update_started < NOW() - INTERVAL '120 seconds')";
} else {
$updstart_thresh_qpart = "AND (ttrss_feeds.last_update_started IS NULL OR ttrss_feeds.last_update_started < DATE_SUB(NOW(), INTERVAL 120 SECOND))";
}
// Test if there is a limit to number of updated feeds
$query_limit = "";
if($limit) $query_limit = sprintf("LIMIT %d", $limit);
$random_qpart = sql_random_function();
// We search for feed needing update.
$result = db_query($link, "SELECT ttrss_feeds.feed_url,ttrss_feeds.id, ttrss_feeds.owner_uid,
".SUBSTRING_FOR_DATE."(ttrss_feeds.last_updated,1,19) AS last_updated,
ttrss_feeds.update_interval
FROM
ttrss_feeds, ttrss_users, ttrss_user_prefs
WHERE
ttrss_feeds.owner_uid = ttrss_users.id
AND ttrss_users.id = ttrss_user_prefs.owner_uid
AND ttrss_user_prefs.pref_name = 'DEFAULT_UPDATE_INTERVAL'
$login_thresh_qpart $update_limit_qpart
$updstart_thresh_qpart
ORDER BY $random_qpart $query_limit");
$user_prefs_cache = array();
if($debug) _debug(sprintf("Scheduled %d feeds to update...\n", db_num_rows($result)));
// Here is a little cache magic in order to minimize risk of double feed updates.
$feeds_to_update = array();
while ($line = db_fetch_assoc($result)) {
$feeds_to_update[$line['id']] = $line;
}
// We update the feed last update started date before anything else.
// There is no lag due to feed contents downloads
// It prevent an other process to update the same feed.
$feed_ids = array_keys($feeds_to_update);
if($feed_ids) {
db_query($link, sprintf("UPDATE ttrss_feeds SET last_update_started = NOW()
WHERE id IN (%s)", implode(',', $feed_ids)));
}
// For each feed, we call the feed update function.
while ($line = array_pop($feeds_to_update)) {
if($debug) _debug("Feed: " . $line["feed_url"] . ", " . $line["last_updated"]);
// We setup a alarm to alert if the feed take more than 300s to update.
// => HANG alarm.
if(!$from_http && function_exists('pcntl_alarm')) pcntl_alarm(300);
update_rss_feed($link, $line["feed_url"], $line["id"], true);
// Cancel the alarm (the update went well)
if(!$from_http && function_exists('pcntl_alarm')) pcntl_alarm(0);
sleep(1); // prevent flood (FIXME make this an option?)
}
// Send feed digests by email if needed.
if (DAEMON_SENDS_DIGESTS) send_headlines_digests($link);
} // function update_daemon_common
function sanitize_article_content($text) {
# we don't support CDATA sections in articles, they break our own escaping
$text = preg_replace("/\[\[CDATA/", "", $text);
$text = preg_replace("/\]\]\>/", "", $text);
return $text;
}
function load_filters($link, $feed, $owner_uid, $action_id = false) {
$filters = array();
if ($action_id) $ftype_query_part = "action_id = '$action_id' AND";
$result = db_query($link, "SELECT reg_exp,
ttrss_filter_types.name AS name,
ttrss_filter_actions.name AS action,
inverse,
action_param,
filter_param
FROM ttrss_filters,ttrss_filter_types,ttrss_filter_actions WHERE
enabled = true AND
$ftype_query_part
owner_uid = $owner_uid AND
ttrss_filter_types.id = filter_type AND
ttrss_filter_actions.id = action_id AND
(feed_id IS NULL OR feed_id = '$feed') ORDER BY reg_exp");
while ($line = db_fetch_assoc($result)) {
if (!$filters[$line["name"]]) $filters[$line["name"]] = array();
$filter["reg_exp"] = $line["reg_exp"];
$filter["action"] = $line["action"];
$filter["action_param"] = $line["action_param"];
$filter["filter_param"] = $line["filter_param"];
$filter["inverse"] = sql_bool_to_bool($line["inverse"]);
array_push($filters[$line["name"]], $filter);
}
return $filters;
}
function get_score_pic($score) {
if ($score > 100) {
return "score_high.png";
} else if ($score > 0) {
return "score_half_high.png";
} else if ($score < -100) {
return "score_low.png";
} else if ($score < 0) {
return "score_half_low.png";
} else {
return "score_neutral.png";
}
}
function rounded_table_start($classname, $header = " ") {
print "
";
print "
$header
";
print "
";
}
function rounded_table_end($footer = " ") {
print "
";
print "
$footer
";
print "
";
}
function print_label_dlg_common_examples() {
print __("Match ") . " ";
/* print ""; */
print "";
print "";
print " ";
}
function feed_has_icon($id) {
return is_file(ICONS_DIR . "/$id.ico") && filesize(ICONS_DIR . "/$id.ico") > 0;
}
function init_connection($link) {
if (DB_TYPE == "pgsql") {
pg_query($link, "set client_encoding = 'UTF-8'");
pg_set_client_encoding("UNICODE");
pg_query($link, "set datestyle = 'ISO, european'");
} else {
if (defined('MYSQL_CHARSET') && MYSQL_CHARSET) {
db_query($link, "SET NAMES " . MYSQL_CHARSET);
// db_query($link, "SET CHARACTER SET " . MYSQL_CHARSET);
}
}
}
function update_feedbrowser_cache($link) {
$result = db_query($link, "SELECT feed_url,COUNT(id) AS subscribers
FROM ttrss_feeds WHERE (SELECT COUNT(id) = 0 FROM ttrss_feeds AS tf
WHERE tf.feed_url = ttrss_feeds.feed_url
AND (private IS true OR feed_url LIKE '%:%@%/%'))
GROUP BY feed_url ORDER BY subscribers DESC LIMIT 200");
db_query($link, "BEGIN");
db_query($link, "DELETE FROM ttrss_feedbrowser_cache");
$count = 0;
while ($line = db_fetch_assoc($result)) {
$subscribers = db_escape_string($line["subscribers"]);
$feed_url = db_escape_string($line["feed_url"]);
db_query($link, "INSERT INTO ttrss_feedbrowser_cache
(feed_url, subscribers) VALUES ('$feed_url', '$subscribers')");
++$count;
}
db_query($link, "COMMIT");
return $count;
}
function ccache_zero($link, $feed_id, $owner_uid) {
db_query($link, "UPDATE ttrss_counters_cache SET
value = 0, updated = NOW() WHERE
feed_id = '$feed_id' AND owner_uid = '$owner_uid'");
}
function ccache_zero_all($link, $owner_uid) {
db_query($link, "UPDATE ttrss_counters_cache SET
value = 0 WHERE owner_uid = '$owner_uid'");
db_query($link, "UPDATE ttrss_cat_counters_cache SET
value = 0 WHERE owner_uid = '$owner_uid'");
}
function ccache_update_all($link, $owner_uid) {
if (get_pref($link, 'ENABLE_FEED_CATS', $owner_uid)) {
$result = db_query($link, "SELECT feed_id FROM ttrss_cat_counters_cache
WHERE feed_id > 0 AND owner_uid = '$owner_uid'");
while ($line = db_fetch_assoc($result)) {
ccache_update($link, $line["feed_id"], $owner_uid, true);
}
/* We have to manually include category 0 */
ccache_update($link, 0, $owner_uid, true);
} else {
$result = db_query($link, "SELECT feed_id FROM ttrss_counters_cache
WHERE feed_id > 0 AND owner_uid = '$owner_uid'");
while ($line = db_fetch_assoc($result)) {
print ccache_update($link, $line["feed_id"], $owner_uid);
}
}
}
function ccache_find($link, $feed_id, $owner_uid, $is_cat = false,
$no_update = false) {
if (!$is_cat) {
$table = "ttrss_counters_cache";
} else {
$table = "ttrss_cat_counters_cache";
}
if (DB_TYPE == "pgsql") {
$date_qpart = "updated > NOW() - INTERVAL '15 minutes'";
} else if (DB_TYPE == "mysql") {
$date_qpart = "updated > DATE_SUB(NOW(), INTERVAL 15 MINUTE)";
}
$result = db_query($link, "SELECT value FROM $table
WHERE owner_uid = '$owner_uid' AND feed_id = '$feed_id'
LIMIT 1");
if (db_num_rows($result) == 1) {
return db_fetch_result($result, 0, "value");
} else {
if ($no_update) {
return -1;
} else {
return ccache_update($link, $feed_id, $owner_uid, $is_cat);
}
}
}
function ccache_update($link, $feed_id, $owner_uid, $is_cat = false,
$update_pcat = true) {
$prev_unread = ccache_find($link, $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($link, $owner_uid);
return;
}
if (!$is_cat) {
$table = "ttrss_counters_cache";
} else {
$table = "ttrss_cat_counters_cache";
}
if ($is_cat && $feed_id >= 0) {
if ($feed_id != 0) {
$cat_qpart = "cat_id = '$feed_id'";
} else {
$cat_qpart = "cat_id IS NULL";
}
/* Recalculate counters for child feeds */
$result = db_query($link, "SELECT id FROM ttrss_feeds
WHERE owner_uid = '$owner_uid' AND $cat_qpart");
while ($line = db_fetch_assoc($result)) {
ccache_update($link, $line["id"], $owner_uid, false, false);
}
$result = db_query($link, "SELECT SUM(value) AS sv
FROM ttrss_counters_cache, ttrss_feeds
WHERE id = feed_id AND $cat_qpart AND
ttrss_feeds.owner_uid = '$owner_uid'");
$unread = db_fetch_result($result, 0, "sv");
} else {
$unread = (int) getFeedArticles($link, $feed_id, $is_cat, true, $owner_uid);
}
$result = db_query($link, "SELECT feed_id FROM $table
WHERE owner_uid = '$owner_uid' AND feed_id = '$feed_id' LIMIT 1");
if (db_num_rows($result) == 1) {
db_query($link, "UPDATE $table SET
value = '$unread', updated = NOW() WHERE
feed_id = '$feed_id' AND owner_uid = '$owner_uid'");
} else {
db_query($link, "INSERT INTO $table
(feed_id, value, owner_uid, updated)
VALUES
($feed_id, $unread, $owner_uid, NOW())");
}
if ($feed_id > 0 && $prev_unread != $unread) {
if (!$is_cat) {
/* Update parent category */
if ($update_pcat) {
$result = db_query($link, "SELECT cat_id FROM ttrss_feeds
WHERE owner_uid = '$owner_uid' AND id = '$feed_id'");
$cat_id = (int) db_fetch_result($result, 0, "cat_id");
ccache_update($link, $cat_id, $owner_uid, true);
}
}
} else if ($feed_id < 0) {
ccache_update_all($link, $owner_uid);
}
return $unread;
}
?>