";
}
}
if ($smart_mode && $fctrs_modified) {
$_SESSION["fctr_last_value"] = $old_counters;
}
}
function get_script_dt_add() {
if (strpos(VERSION, ".99") === false) {
return VERSION;
} else {
return time();
}
}
function get_pgsql_version($link) {
$result = db_query($link, "SELECT version() AS version");
$version = split(" ", db_fetch_result($result, 0, "version"));
return $version[1];
}
function print_error_xml($code, $add_msg = "") {
global $ERRORS;
$error_msg = $ERRORS[$code];
if ($add_msg) {
$error_msg = "$error_msg; $add_msg";
}
print "";
print "";
print " ";
}
function subscribe_to_feed($link, $feed_link, $cat_id = 0,
$auth_login = '', $auth_pass = '') {
# check for feed:http://url
$feed_link = trim(preg_replace("/^feed:/", "", $feed_link));
# check for feed://URL
if (strpos($feed_link, "//") === 0) {
$feed_link = "http:$feed_link";
}
if ($feed_link == "") return;
if ($cat_id == "0" || !$cat_id) {
$cat_qpart = "NULL";
} else {
$cat_qpart = "'$cat_id'";
}
$result = db_query($link,
"SELECT id FROM ttrss_feeds
WHERE feed_url = '$feed_link' AND owner_uid = ".$_SESSION["uid"]);
if (db_num_rows($result) == 0) {
$result = db_query($link,
"INSERT INTO ttrss_feeds
(owner_uid,feed_url,title,cat_id, auth_login,auth_pass)
VALUES ('".$_SESSION["uid"]."', '$feed_link',
'[Unknown]', $cat_qpart, '$auth_login', '$auth_pass')");
$result = db_query($link,
"SELECT id FROM ttrss_feeds WHERE feed_url = '$feed_link'
AND owner_uid = " . $_SESSION["uid"]);
$feed_id = db_fetch_result($result, 0, "id");
if ($feed_id) {
update_rss_feed($link, $feed_link, $feed_id, true);
}
return true;
} else {
return false;
}
}
function print_feed_select($link, $id, $default_id = "",
$attributes = "", $include_all_feeds = true) {
print "";
if ($include_all_feeds) {
print "All feeds ";
}
$result = db_query($link, "SELECT id,title FROM ttrss_feeds
WHERE owner_uid = ".$_SESSION["uid"]." ORDER BY title");
if (db_num_rows($result) > 0 && $include_all_feeds) {
print "-------- ";
}
while ($line = db_fetch_assoc($result)) {
if ($line["id"] == $default_id) {
$is_selected = "selected";
} else {
$is_selected = "";
}
printf("%s ",
$line["id"], htmlspecialchars($line["title"]));
}
print " ";
}
function print_feed_cat_select($link, $id, $default_id = "",
$attributes = "", $include_all_cats = true) {
print "";
if ($include_all_cats) {
print "".__('Uncategorized')." ";
}
$result = db_query($link, "SELECT id,title FROM ttrss_feed_categories
WHERE owner_uid = ".$_SESSION["uid"]." ORDER BY title");
if (db_num_rows($result) > 0 && $include_all_cats) {
print "-------- ";
}
while ($line = db_fetch_assoc($result)) {
if ($line["id"] == $default_id) {
$is_selected = "selected";
} else {
$is_selected = "";
}
printf("%s ",
$line["id"], htmlspecialchars($line["title"]));
}
print " ";
}
function checkbox_to_sql_bool($val) {
return ($val == "on") ? "true" : "false";
}
function getFeedCatTitle($link, $id) {
if ($id == -1) {
return __("Special");
} else if ($id < -10) {
return __("Labels");
} else if ($id > 0) {
$result = db_query($link, "SELECT ttrss_feed_categories.title
FROM ttrss_feeds, ttrss_feed_categories WHERE ttrss_feeds.id = '$id' AND
cat_id = ttrss_feed_categories.id");
if (db_num_rows($result) == 1) {
return db_fetch_result($result, 0, "title");
} else {
return __("Uncategorized");
}
} else {
return "getFeedCatTitle($id) failed";
}
}
function getFeedTitle($link, $id) {
if ($id == -1) {
return __("Starred articles");
} else if ($id == -2) {
return __("Published articles");
} else if ($id < -10) {
$label_id = -10 - $id;
$result = db_query($link, "SELECT description FROM ttrss_labels WHERE id = '$label_id'");
if (db_num_rows($result) == 1) {
return db_fetch_result($result, 0, "description");
} else {
return "Unknown label ($label_id)";
}
} else if ($id > 0) {
$result = db_query($link, "SELECT title FROM ttrss_feeds WHERE id = '$id'");
if (db_num_rows($result) == 1) {
return db_fetch_result($result, 0, "title");
} else {
return "Unknown feed ($id)";
}
} else {
return "getFeedTitle($id) failed";
}
}
function get_session_cookie_name() {
return ((!defined('TTRSS_SESSION_NAME')) ? "ttrss_sid" : TTRSS_SESSION_NAME);
}
function print_init_params($link) {
print "";
if ($_SESSION["stored-params"]) {
foreach (array_keys($_SESSION["stored-params"]) as $key) {
if ($key) {
$value = htmlspecialchars($_SESSION["stored-params"][$key]);
print " ";
}
}
}
print " ";
print " ";
print " ";
print " ";
print " ";
print " ";
print " ";
print " ";
print " ";
print " ";
print " ";
print " ";
print " ";
print " ";
print " ";
}
function print_runtime_info($link) {
print "";
if (ENABLE_UPDATE_DAEMON) {
print " ";
if ($_SESSION["daemon_stamp_check"] + 600 < time()) {
$stamp = (int)read_stampfile("update_daemon.stamp");
if ($stamp) {
if ($stamp + 86400*3 < time()) {
print " ";
} else {
print " ";
}
$stamp_fmt = date("Y.m.d, G:i", $stamp);
print " ";
}
$_SESSION["daemon_stamp_check"] = time();
}
}
if (CHECK_FOR_NEW_VERSION && $_SESSION["access_level"] >= 10) {
if ($_SESSION["last_version_check"] + 600 < time()) {
$new_version_details = check_for_update($link);
print " ";
$_SESSION["last_version_check"] = time();
}
}
print " ";
}
function getSearchSql($search, $match_on) {
$search_query_part = "";
$keywords = split(" ", $search);
$query_keywords = array();
if ($match_on == "both") {
foreach ($keywords as $k) {
array_push($query_keywords, "(UPPER(ttrss_entries.title) LIKE UPPER('%$k%')
OR UPPER(ttrss_entries.content) LIKE UPPER('%$k%'))");
}
$search_query_part = implode("AND", $query_keywords) . " AND ";
} else if ($match_on == "title") {
foreach ($keywords as $k) {
array_push($query_keywords, "(UPPER(ttrss_entries.title) LIKE UPPER('%$k%'))");
}
$search_query_part = implode("AND", $query_keywords) . " AND ";
} else if ($match_on == "content") {
foreach ($keywords as $k) {
array_push($query_keywords, "(UPPER(ttrss_entries.content) LIKE UPPER('%$k%'))");
}
}
$search_query_part = implode("AND", $query_keywords);
return $search_query_part;
}
function queryFeedHeadlines($link, $feed, $limit, $view_mode, $cat_view, $search, $search_mode, $match_on, $override_order = false, $offset = 0, $owner_uid = 0) {
if (!$owner_uid) $owner_uid = $_SESSION["uid"];
if ($search) {
$search_query_part = getSearchSql($search, $match_on);
$search_query_part .= " AND ";
} else {
$search_query_part = "";
}
$view_query_part = "";
if ($view_mode == "adaptive") {
if ($search) {
$view_query_part = " ";
} else if ($feed != -1) {
$unread = getFeedUnread($link, $feed, $cat_view);
if ($unread > 0) {
$view_query_part = " unread = true AND ";
}
}
}
if ($view_mode == "marked") {
$view_query_part = " marked = true AND ";
}
if ($view_mode == "unread") {
$view_query_part = " unread = true AND ";
}
if ($limit > 0) {
$limit_query_part = "LIMIT " . $limit;
}
$vfeed_query_part = "";
// override query strategy and enable feed display when searching globally
if ($search && $search_mode == "all_feeds") {
$query_strategy_part = "ttrss_entries.id > 0";
$vfeed_query_part = "ttrss_feeds.title AS feed_title,";
} else if (preg_match("/^-?[0-9][0-9]*$/", $feed) == false) {
$query_strategy_part = "ttrss_entries.id > 0";
$vfeed_query_part = "(SELECT title FROM ttrss_feeds WHERE
id = feed_id) as feed_title,";
} else if ($feed >= 0 && $search && $search_mode == "this_cat") {
$vfeed_query_part = "ttrss_feeds.title AS feed_title,";
$tmp_result = false;
if ($cat_view) {
$tmp_result = db_query($link, "SELECT id
FROM ttrss_feeds WHERE cat_id = '$feed'");
} else {
$tmp_result = db_query($link, "SELECT id
FROM ttrss_feeds WHERE cat_id = (SELECT cat_id FROM ttrss_feeds
WHERE id = '$feed') AND id != '$feed'");
}
$cat_siblings = array();
if (db_num_rows($tmp_result) > 0) {
while ($p = db_fetch_assoc($tmp_result)) {
array_push($cat_siblings, "feed_id = " . $p["id"]);
}
$query_strategy_part = sprintf("(feed_id = %d OR %s)",
$feed, implode(" OR ", $cat_siblings));
} else {
$query_strategy_part = "ttrss_entries.id > 0";
}
} else if ($feed >= 0) {
if ($cat_view) {
if ($feed > 0) {
$query_strategy_part = "cat_id = '$feed'";
} else {
$query_strategy_part = "cat_id IS NULL";
}
$vfeed_query_part = "ttrss_feeds.title AS feed_title,";
} else {
$tmp_result = db_query($link, "SELECT id
FROM ttrss_feeds WHERE parent_feed = '$feed'
ORDER BY cat_id,title");
$parent_ids = array();
if (db_num_rows($tmp_result) > 0) {
while ($p = db_fetch_assoc($tmp_result)) {
array_push($parent_ids, "feed_id = " . $p["id"]);
}
$query_strategy_part = sprintf("(feed_id = %d OR %s)",
$feed, implode(" OR ", $parent_ids));
$vfeed_query_part = "ttrss_feeds.title AS feed_title,";
} else {
$query_strategy_part = "feed_id = '$feed'";
}
}
} else if ($feed == -1) { // starred virtual feed
$query_strategy_part = "marked = true";
$vfeed_query_part = "ttrss_feeds.title AS feed_title,";
} else if ($feed == -2) { // published virtual feed
$query_strategy_part = "published = true";
$vfeed_query_part = "ttrss_feeds.title AS feed_title,";
} else if ($feed <= -10) { // labels
$label_id = -$feed - 11;
$tmp_result = db_query($link, "SELECT sql_exp FROM ttrss_labels
WHERE id = '$label_id'");
$query_strategy_part = db_fetch_result($tmp_result, 0, "sql_exp");
if (!$query_strategy_part) {
return false;
}
$vfeed_query_part = "ttrss_feeds.title AS feed_title,";
} else {
$query_strategy_part = "id > 0"; // dumb
}
if (get_pref($link, 'REVERSE_HEADLINES')) {
$order_by = "updated";
} else {
$order_by = "updated DESC";
}
if ($override_order) {
$order_by = $override_order;
}
$feed_title = "";
if ($search && $search_mode == "all_feeds") {
$feed_title = __("Search results")." ($search)";
} else if ($search && preg_match('/^-?[0-9][0-9]*$/', $feed) == false) {
$feed_title = __("Search results")." ($search, $feed)";
} else if (preg_match('/^-?[0-9][0-9]*$/', $feed) == false) {
$feed_title = $feed;
} else if (preg_match('/^-?[0-9][0-9]*$/', $feed) != false && $feed >= 0) {
if ($cat_view) {
if ($feed != 0) {
$result = db_query($link, "SELECT title FROM ttrss_feed_categories
WHERE id = '$feed' AND owner_uid = $owner_uid");
$feed_title = db_fetch_result($result, 0, "title");
} else {
$feed_title = __("Uncategorized");
}
if ($search) {
$feed_title = __("Searched for")." $search ($feed_title)";
}
} else {
$result = db_query($link, "SELECT title,site_url,last_error FROM ttrss_feeds
WHERE id = '$feed' AND owner_uid = $owner_uid");
$feed_title = db_fetch_result($result, 0, "title");
$feed_site_url = db_fetch_result($result, 0, "site_url");
$last_error = db_fetch_result($result, 0, "last_error");
if ($search) {
$feed_title = __("Searched for") . " $search ($feed_title)";
}
}
} else if ($feed == -1) {
$feed_title = __("Starred articles");
} else if ($feed == -2) {
$feed_title = __("Published articles");
} else if ($feed < -10) {
$label_id = -$feed - 11;
$result = db_query($link, "SELECT description FROM ttrss_labels
WHERE id = '$label_id'");
$feed_title = db_fetch_result($result, 0, "description");
if ($search) {
$feed_title = __("Searched for") . " $search ($feed_title)";
}
} else {
$feed_title = "?";
}
if ($feed < -10) error_reporting (0);
if (preg_match("/^-?[0-9][0-9]*$/", $feed) != false) {
if ($feed >= 0) {
$feed_kind = "Feeds";
} else {
$feed_kind = "Labels";
}
$content_query_part = "content as content_preview,";
if ($limit_query_part) {
$offset_query_part = "OFFSET $offset";
}
$query = "SELECT
guid,
ttrss_entries.id,ttrss_entries.title,
updated,
unread,feed_id,marked,published,link,last_read,
SUBSTRING(last_read,1,19) as last_read_noms,
$vfeed_query_part
$content_query_part
SUBSTRING(updated,1,19) as updated_noms,
author
FROM
ttrss_entries,ttrss_user_entries,ttrss_feeds
WHERE
ttrss_feeds.hidden = false AND
ttrss_user_entries.feed_id = ttrss_feeds.id AND
ttrss_user_entries.ref_id = ttrss_entries.id AND
ttrss_user_entries.owner_uid = '$owner_uid' AND
$search_query_part
$view_query_part
$query_strategy_part ORDER BY $order_by
$limit_query_part $offset_query_part";
$result = db_query($link, $query);
if ($_GET["debug"]) print $query;
} else {
// browsing by tag
$feed_kind = "Tags";
$result = db_query($link, "SELECT
guid,
ttrss_entries.id as id,title,
updated,
unread,feed_id,
marked,link,last_read,
SUBSTRING(last_read,1,19) as last_read_noms,
$vfeed_query_part
$content_query_part
SUBSTRING(updated,1,19) as updated_noms
FROM
ttrss_entries,ttrss_user_entries,ttrss_tags
WHERE
ref_id = ttrss_entries.id AND
ttrss_user_entries.owner_uid = '$owner_uid' AND
post_int_id = int_id AND tag_name = '$feed' AND
$view_query_part
$search_query_part
$query_strategy_part ORDER BY $order_by
$limit_query_part");
}
return array($result, $feed_title, $feed_site_url, $last_error);
}
function generate_syndicated_feed($link, $owner_uid, $feed, $is_cat,
$search, $search_mode, $match_on) {
$qfh_ret = queryFeedHeadlines($link, $feed,
30, false, $is_cat, $search, $search_mode, $match_on, "updated DESC", 0,
$owner_uid);
$result = $qfh_ret[0];
$feed_title = htmlspecialchars($qfh_ret[1]);
$feed_site_url = $qfh_ret[2];
$last_error = $qfh_ret[3];
# if (!$feed_site_url) $feed_site_url = "http://localhost/";
print "
$feed_title
$feed_site_url
Feed generated by Tiny Tiny RSS ";
while ($line = db_fetch_assoc($result)) {
print "- ";
print "
" . htmlspecialchars($line["guid"]) . " ";
print " " . htmlspecialchars($line["link"]) . "";
$tags = get_article_tags($link, $line["id"], $owner_uid);
foreach ($tags as $tag) {
print "" . htmlspecialchars($tag) . " ";
}
$rfc822_date = date('r', strtotime($line["updated"]));
print "$rfc822_date ";
print "" .
htmlspecialchars($line["title"]) . " ";
print " ";
print " ";
}
print " ";
}
function getCategoryTitle($link, $cat_id) {
$result = db_query($link, "SELECT title FROM ttrss_feed_categories WHERE
id = '$cat_id'");
if (db_num_rows($result) == 1) {
return db_fetch_result($result, 0, "title");
} else {
return "Uncategorized";
}
}
// http://ru2.php.net/strip-tags
function strip_tags_long($textstring, $allowed){
while($textstring != strip_tags($textstring, $allowed))
{
while (strlen($textstring) != 0)
{
if (strlen($textstring) > 1024) {
$otherlen = 1024;
} else {
$otherlen = strlen($textstring);
}
$temptext = strip_tags(substr($textstring,0,$otherlen), $allowed);
$safetext .= $temptext;
$textstring = substr_replace($textstring,'',0,$otherlen);
}
$textstring = $safetext;
}
return $textstring;
}
function sanitize_rss($link, $str, $force_strip_tags = false) {
$res = $str;
if (get_pref($link, "STRIP_UNSAFE_TAGS") || $force_strip_tags) {
global $tw_parser;
global $tw_paranoya_setup;
$res = $tw_parser->strip_tags($res, $tw_paranoya_setup);
// $res = preg_replace("/\r\n|\n|\r/", "", $res);
// $res = strip_tags_long($res, "");
}
return $res;
}
function send_headlines_digests($link, $limit = 100) {
if (!DIGEST_ENABLE) return false;
$user_limit = DIGEST_EMAIL_LIMIT;
$days = 1;
print "Sending digests, batch of max $user_limit users, days = $days, headline limit = $limit\n\n";
if (DB_TYPE == "pgsql") {
$interval_query = "last_digest_sent < NOW() - INTERVAL '$days days'";
} else if (DB_TYPE == "mysql") {
$interval_query = "last_digest_sent < DATE_SUB(NOW(), INTERVAL $days DAY)";
}
$result = db_query($link, "SELECT id,email FROM ttrss_users
WHERE email != '' AND (last_digest_sent IS NULL OR $interval_query)");
while ($line = db_fetch_assoc($result)) {
if (get_pref($link, 'DIGEST_ENABLE', $line['id'], false)) {
print "Sending digest for UID:" . $line['id'] . " - " . $line["email"] . " ... ";
$tuple = prepare_headlines_digest($link, $line["id"], $days, $limit);
$digest = $tuple[0];
$headlines_count = $tuple[1];
if ($headlines_count > 0) {
$rc = mail($line["login"] . " <" . $line["email"] . ">",
"[tt-rss] New headlines for last 24 hours", $digest,
"From: " . MAIL_FROM . "\n".
"Content-Type: text/plain; charset=\"utf-8\"\n".
"Content-Transfer-Encoding: 8bit\n");
print "RC=$rc\n";
db_query($link, "UPDATE ttrss_users SET last_digest_sent = NOW()
WHERE id = " . $line["id"]);
} else {
print "No headlines\n";
}
}
}
// $digest = prepare_headlines_digest($link, $user_id, $days, $limit);
}
function prepare_headlines_digest($link, $user_id, $days = 1, $limit = 100) {
$tmp = __("New headlines for last 24 hours, as of ") . date("Y/m/d H:m") . "\n";
$tmp .= "=======================================================\n\n";
if (DB_TYPE == "pgsql") {
$interval_query = "ttrss_entries.date_entered > NOW() - INTERVAL '$days days'";
} else if (DB_TYPE == "mysql") {
$interval_query = "ttrss_entries.date_entered > DATE_SUB(NOW(), INTERVAL $days DAY)";
}
$result = db_query($link, "SELECT ttrss_entries.title,
ttrss_feeds.title AS feed_title,
date_entered,
link,
SUBSTRING(last_updated,1,19) AS last_updated
FROM
ttrss_user_entries,ttrss_entries,ttrss_feeds
WHERE
ref_id = ttrss_entries.id AND feed_id = ttrss_feeds.id
AND include_in_digest = true
AND $interval_query
AND ttrss_user_entries.owner_uid = $user_id
AND unread = true ORDER BY ttrss_feeds.title, date_entered DESC
LIMIT $limit");
$cur_feed_title = "";
$headlines_count = db_num_rows($result);
while ($line = db_fetch_assoc($result)) {
$updated = smart_date_time(strtotime($line["last_updated"]));
$feed_title = $line["feed_title"];
if ($cur_feed_title != $feed_title) {
$cur_feed_title = $feed_title;
$tmp .= "$feed_title\n\n";
}
$tmp .= " * " . trim($line["title"]) . " - $updated\n";
$tmp .= " " . trim($line["link"]) . "\n";
$tmp .= "\n";
}
$tmp .= "--- \n";
$tmp .= __("You have been sent this email because you have enabled daily digests in Tiny Tiny RSS at ") .
DIGEST_HOSTNAME . "\n".
__("To unsubscribe, visit your configuration options or contact instance owner.\n");
return array($tmp, $headlines_count);
}
function check_for_update($link, $brief_fmt = true) {
$releases_feed = "http://tt-rss.spb.ru/releases.rss";
if (!CHECK_FOR_NEW_VERSION || $_SESSION["access_level"] < 10) {
return;
}
error_reporting(0);
$rss = fetch_rss($releases_feed);
error_reporting (DEFAULT_ERROR_LEVEL);
if ($rss) {
$items = $rss->items;
if (!$items || !is_array($items)) $items = $rss->entries;
if (!$items || !is_array($items)) $items = $rss;
if (!is_array($items) || count($items) == 0) {
return;
}
$latest_item = $items[0];
$latest_version = trim(preg_replace("/(Milestone)|(completed)/", "", $latest_item["title"]));
$release_url = sanitize_rss($link, $latest_item["link"]);
$content = sanitize_rss($link, $latest_item["description"]);
if (version_compare(VERSION, $latest_version) == -1) {
if ($brief_fmt) {
return format_notice("
New version of Tiny-Tiny RSS ($latest_version) is available (click for details)
$content
");
} else {
return "New version of Tiny-Tiny RSS ($latest_version) is available:
$content
Visit official site for
download and update information.";
}
}
}
}
function markArticlesById($link, $ids, $cmode) {
$tmp_ids = array();
foreach ($ids as $id) {
array_push($tmp_ids, "ref_id = '$id'");
}
$ids_qpart = join(" OR ", $tmp_ids);
if ($cmode == 0) {
db_query($link, "UPDATE ttrss_user_entries SET
marked = false,last_read = NOW()
WHERE ($ids_qpart) AND owner_uid = " . $_SESSION["uid"]);
} else if ($cmode == 1) {
db_query($link, "UPDATE ttrss_user_entries SET
marked = true
WHERE ($ids_qpart) AND owner_uid = " . $_SESSION["uid"]);
} else {
db_query($link, "UPDATE ttrss_user_entries SET
marked = NOT marked,last_read = NOW()
WHERE ($ids_qpart) AND owner_uid = " . $_SESSION["uid"]);
}
}
function publishArticlesById($link, $ids, $cmode) {
$tmp_ids = array();
foreach ($ids as $id) {
array_push($tmp_ids, "ref_id = '$id'");
}
$ids_qpart = join(" OR ", $tmp_ids);
if ($cmode == 0) {
db_query($link, "UPDATE ttrss_user_entries SET
published = false,last_read = NOW()
WHERE ($ids_qpart) AND owner_uid = " . $_SESSION["uid"]);
} else if ($cmode == 1) {
db_query($link, "UPDATE ttrss_user_entries SET
published = true
WHERE ($ids_qpart) AND owner_uid = " . $_SESSION["uid"]);
} else {
db_query($link, "UPDATE ttrss_user_entries SET
published = NOT published,last_read = NOW()
WHERE ($ids_qpart) AND owner_uid = " . $_SESSION["uid"]);
}
}
function catchupArticlesById($link, $ids, $cmode) {
$tmp_ids = array();
foreach ($ids as $id) {
array_push($tmp_ids, "ref_id = '$id'");
}
$ids_qpart = join(" OR ", $tmp_ids);
if ($cmode == 0) {
db_query($link, "UPDATE ttrss_user_entries SET
unread = false,last_read = NOW()
WHERE ($ids_qpart) AND owner_uid = " . $_SESSION["uid"]);
} else if ($cmode == 1) {
db_query($link, "UPDATE ttrss_user_entries SET
unread = true
WHERE ($ids_qpart) AND owner_uid = " . $_SESSION["uid"]);
} else {
db_query($link, "UPDATE ttrss_user_entries SET
unread = NOT unread,last_read = NOW()
WHERE ($ids_qpart) AND owner_uid = " . $_SESSION["uid"]);
}
}
function catchupArticleById($link, $id, $cmode) {
if ($cmode == 0) {
db_query($link, "UPDATE ttrss_user_entries SET
unread = false,last_read = NOW()
WHERE ref_id = '$id' AND owner_uid = " . $_SESSION["uid"]);
} else if ($cmode == 1) {
db_query($link, "UPDATE ttrss_user_entries SET
unread = true
WHERE ref_id = '$id' AND owner_uid = " . $_SESSION["uid"]);
} else {
db_query($link, "UPDATE ttrss_user_entries SET
unread = NOT unread,last_read = NOW()
WHERE ref_id = '$id' AND owner_uid = " . $_SESSION["uid"]);
}
}
function make_guid_from_title($title) {
return preg_replace("/[ \"\',.:;]/", "-",
mb_strtolower(strip_tags($title), 'utf-8'));
}
function print_headline_subtoolbar($link, $feed_site_url, $feed_title,
$bottom = false, $rtl_content = false, $feed_id = 0,
$is_cat = false, $search = false, $match_on = false,
$search_mode = false, $offset = 0, $limit = 0) {
$user_page_offset = $offset + 1;
if (!$bottom) {
$class = "headlinesSubToolbar";
$tid = "headlineActionsTop";
} else {
$class = "headlinesSubToolbar";
$tid = "headlineActionsBottom";
}
print "";
if ($rtl_content) {
$rtl_cpart = "RTL";
} else {
$rtl_cpart = "";
}
$page_prev_link = "javascript:viewFeedGoPage(-1)";
$page_next_link = "javascript:viewFeedGoPage(1)";
$page_first_link = "javascript:viewFeedGoPage(0)";
$catchup_page_link = "javascript:catchupPage()";
$catchup_feed_link = "javascript:catchupCurrentFeed()";
if (!get_pref($link, 'COMBINED_DISPLAY_MODE')) {
$sel_all_link = "javascript:selectTableRowsByIdPrefix('headlinesList', 'RROW-', 'RCHK-', true, '', true)";
$sel_unread_link = "javascript:selectTableRowsByIdPrefix('headlinesList', 'RROW-', 'RCHK-', true, 'Unread', true)";
$sel_none_link = "javascript:selectTableRowsByIdPrefix('headlinesList', 'RROW-', 'RCHK-', false)";
$tog_unread_link = "javascript:selectionToggleUnread()";
$tog_marked_link = "javascript:selectionToggleMarked()";
$tog_published_link = "javascript:selectionTogglePublished()";
} else {
$sel_all_link = "javascript:cdmSelectArticles('all')";
$sel_unread_link = "javascript:cdmSelectArticles('unread')";
$sel_none_link = "javascript:cdmSelectArticles('none')";
$tog_unread_link = "javascript:selectionToggleUnread(true)";
$tog_marked_link = "javascript:selectionToggleMarked(true)";
$tog_published_link = "javascript:selectionTogglePublished(true)";
}
if (strpos($_SESSION["client.userAgent"], "MSIE") === false) {
print "
";
}
if ($search && $feed_id >= 0 && get_pref($link, 'ENABLE_LABELS') && GLOBAL_ENABLE_LABELS) {
print "
".__('Convert to label')." ";
}
print "
";
} else {
// old style subtoolbar:
print "".
__('Select:')."
".__('All')." ,
".__('Unread')." ,
".__('None')."
".
__('Toggle:')." ".__('Unread')." ,
".__('Starred')."
".
__('Mark as read:')."
".__('Page')." ,
".__('Feed')." ";
if ($search && $feed_id >= 0 && get_pref($link, 'ENABLE_LABELS') && GLOBAL_ENABLE_LABELS) {
print "
".__('Convert to label')." ";
}
print " ";
}
/* if ($search && $feed_id >= 0 && get_pref($link, 'ENABLE_LABELS') && GLOBAL_ENABLE_LABELS) {
print "
".__('Convert to Label')." ";
} */
print "";
if ($feed_site_url) {
if (!$bottom) {
$target = "target=\"_new\"";
}
print "$feed_title ";
} else {
print $feed_title;
}
if ($search) {
$search_q = "&q=$search&m=$match_on&smode=$search_mode";
}
if ($user_page_offset > 1) {
print " [$user_page_offset] ";
}
if (!$bottom) {
print "
";
}
print " ";
print "
";
}
function outputFeedList($link, $tags = false) {
print "";
$owner_uid = $_SESSION["uid"];
/* virtual feeds */
if (get_pref($link, 'ENABLE_FEED_CATS')) {
print "".__('Special')." ";
print "";
}
$num_starred = getFeedUnread($link, -1);
$num_published = getFeedUnread($link, -2);
$class = "virt";
if ($num_starred > 0) $class .= "Unread";
printFeedEntry(-1, $class, __("Starred articles"), $num_starred,
"images/mark_set.png", $link);
$class = "virt";
if ($num_published > 0) $class .= "Unread";
printFeedEntry(-2, $class, __("Published articles"), $num_published,
"images/pub_set.png", $link);
if (get_pref($link, 'ENABLE_FEED_CATS')) {
print " ";
}
if (!$tags) {
if (GLOBAL_ENABLE_LABELS && get_pref($link, 'ENABLE_LABELS')) {
$result = db_query($link, "SELECT id,sql_exp,description FROM
ttrss_labels WHERE owner_uid = '$owner_uid' ORDER by description");
if (db_num_rows($result) > 0) {
if (get_pref($link, 'ENABLE_FEED_CATS')) {
print "".__('Labels')." ";
print "";
} else {
print " ";
}
}
while ($line = db_fetch_assoc($result)) {
error_reporting (0);
$label_id = -$line['id'] - 11;
$count = getFeedUnread($link, $label_id);
$class = "label";
if ($count > 0) {
$class .= "Unread";
}
error_reporting (DEFAULT_ERROR_LEVEL);
printFeedEntry($label_id,
$class, $line["description"],
$count, "images/label.png", $link);
}
if (db_num_rows($result) > 0) {
if (get_pref($link, 'ENABLE_FEED_CATS')) {
print " ";
}
}
}
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 = "category,unread DESC,title";
} else {
$order_by_qpart = "category,title";
}
} else {
if (get_pref($link, "FEEDS_SORT_BY_UNREAD")) {
$order_by_qpart = "unread DESC,title";
} else {
$order_by_qpart = "title";
}
}
$result = db_query($link, "SELECT ttrss_feeds.*,
SUBSTRING(last_updated,1,19) AS last_updated_noms,
(SELECT COUNT(id) FROM ttrss_entries,ttrss_user_entries
WHERE feed_id = ttrss_feeds.id AND unread = true
AND ttrss_user_entries.ref_id = ttrss_entries.id
AND owner_uid = '$owner_uid') as unread,
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");
$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 = $line["unread"];
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 id,COUNT(unread) AS unread
FROM ttrss_feeds LEFT JOIN ttrss_user_entries
ON (ttrss_feeds.id = ttrss_user_entries.feed_id)
WHERE parent_feed = '$feed_id' AND unread = true
GROUP BY ttrss_feeds.id");
if (db_num_rows($tmp_result) > 0) {
while ($l = db_fetch_assoc($tmp_result)) {
$unread += $l["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 = $line["collapsed"];
// workaround for NULL category
if ($category == __("Uncategorized")) {
if ($_COOKIE["ttrss_vf_uclps"] == 1) {
$collapsed = "t";
}
}
if ($collapsed == "t" || $collapsed == "1") {
$holder_class = "invisible";
$ellipsis = "...";
} else {
$holder_class = "feedCatHolder";
$ellipsis = "";
}
$cat_id = sprintf("%d", $cat_id);
$cat_unread = getCategoryUnread($link, $cat_id);
$catctr_class = ($cat_unread > 0) ? "catCtrHasUnread" : "catCtrNoUnread";
print "
$tmp_category
($cat_unread) $ellipsis
";
// !!! NO SPACE before keyboard navigation, etc.
print "";
}
printFeedEntry($feed_id, $class, $feed, $unread,
ICONS_DIR."/$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 "";
}
$result = db_query($link, "SELECT tag_name,SUM((SELECT COUNT(int_id)
FROM ttrss_user_entries WHERE int_id = post_int_id
AND unread = true)) AS count FROM ttrss_tags
WHERE owner_uid = ".$_SESSION['uid']." GROUP BY tag_name ORDER BY tag_name");
$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;
$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) {
/* 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");
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 ";
}
}
print "";
print "";
print "
" . $feed_icon . "
";
print "
";
print "
".__('Tags:')." $f_tags_str
";
$line["content"] = sanitize_rss($link, $line["content"]);
if (get_pref($link, 'OPEN_LINKS_IN_NEW_WINDOW')) {
$line["content"] = preg_replace("/href=/i", "target=\"_new\" href=", $line["content"]);
}
print $line["content"] . "
";
print "
";
}
print "]]> ";
}
function outputHeadlinesList($link, $feed, $subop, $view_mode, $limit, $cat_view,
$next_unread_feed, $offset) {
$timing_info = getmicrotime();
$topmost_article_ids = array();
if (!$offset) {
$offset = 0;
}
if ($subop == "undefined") $subop = "";
if ($subop == "CatchupSelected") {
$ids = split(",", db_escape_string($_GET["ids"]));
$cmode = sprintf("%d", $_GET["cmode"]);
catchupArticlesById($link, $ids, $cmode);
}
if ($subop == "ForceUpdate" && sprintf("%d", $feed) > 0) {
update_generic_feed($link, $feed, $cat_view);
}
if ($subop == "MarkAllRead") {
catchup_feed($link, $feed, $cat_view);
if (get_pref($link, 'ON_CATCHUP_SHOW_NEXT_FEED')) {
if ($next_unread_feed) {
$feed = $next_unread_feed;
}
}
}
if ($feed_id > 0) {
$result = db_query($link,
"SELECT id FROM ttrss_feeds WHERE id = '$feed' LIMIT 1");
if (db_num_rows($result) == 0) {
print "".__('Feed not found.')."
";
return;
}
}
if (preg_match("/^-?[0-9][0-9]*$/", $feed) != false) {
$result = db_query($link, "SELECT rtl_content FROM ttrss_feeds
WHERE id = '$feed' AND owner_uid = " . $_SESSION["uid"]);
if (db_num_rows($result) == 1) {
$rtl_content = sql_bool_to_bool(db_fetch_result($result, 0, "rtl_content"));
} else {
$rtl_content = false;
}
if ($rtl_content) {
$rtl_tag = "dir=\"RTL\"";
} else {
$rtl_tag = "";
}
} else {
$rtl_tag = "";
$rtl_content = false;
}
$script_dt_add = get_script_dt_add();
/// START /////////////////////////////////////////////////////////////////////////////////
$search = db_escape_string($_GET["query"]);
$search_mode = db_escape_string($_GET["search_mode"]);
$match_on = db_escape_string($_GET["match_on"]);
if (!$match_on) {
$match_on = "both";
}
$real_offset = $offset * $limit;
if ($_GET["debug"]) $timing_info = print_checkpoint("H0", $timing_info);
$qfh_ret = queryFeedHeadlines($link, $feed, $limit, $view_mode, $cat_view,
$search, $search_mode, $match_on, false, $real_offset);
if ($_GET["debug"]) $timing_info = print_checkpoint("H1", $timing_info);
$result = $qfh_ret[0];
$feed_title = $qfh_ret[1];
$feed_site_url = $qfh_ret[2];
$last_error = $qfh_ret[3];
/// STOP //////////////////////////////////////////////////////////////////////////////////
if (!$offset) {
print "";
if (!$result) {
print "
".__("Could not display feed (query failed). Please check label match syntax or local configuration.")."
";
return;
}
print_headline_subtoolbar($link, $feed_site_url, $feed_title, false,
$rtl_content, $feed, $cat_view, $search, $match_on, $search_mode,
$offset, $limit);
print "
";
}
if (db_num_rows($result) > 0) {
# print "\{$offset}";
if (!get_pref($link, 'COMBINED_DISPLAY_MODE') && !$offset) {
print "
";
}
$lnum = 0;
error_reporting (DEFAULT_ERROR_LEVEL);
$num_unread = 0;
while ($line = db_fetch_assoc($result)) {
$class = ($lnum % 2) ? "even" : "odd";
$id = $line["id"];
$feed_id = $line["feed_id"];
if (count($topmost_article_ids) < 5) {
array_push($topmost_article_ids, $id);
}
if ($line["last_read"] == "" &&
($line["unread"] != "t" && $line["unread"] != "1")) {
$update_pic = " ";
} else {
$update_pic = " ";
}
if ($line["unread"] == "t" || $line["unread"] == "1") {
$class .= "Unread";
++$num_unread;
$is_unread = true;
} else {
$is_unread = false;
}
if ($line["marked"] == "t" || $line["marked"] == "1") {
$marked_pic = " ";
} else {
$marked_pic = " ";
}
if ($line["published"] == "t" || $line["published"] == "1") {
$published_pic = " ";
} else {
$published_pic = " ";
}
# $content_link = "" .
# $line["title"] . " ";
$content_link = "" .
$line["title"] . " ";
# $content_link = "" .
# $line["title"] . " ";
if (get_pref($link, 'HEADLINES_SMART_DATE')) {
$updated_fmt = smart_date_time(strtotime($line["updated_noms"]));
} else {
$short_date = get_pref($link, 'SHORT_DATE_FORMAT');
$updated_fmt = date($short_date, strtotime($line["updated_noms"]));
}
if (get_pref($link, 'SHOW_CONTENT_PREVIEW')) {
$content_preview = truncate_string(strip_tags($line["content_preview"]),
100);
}
$entry_author = $line["author"];
if ($entry_author) {
$entry_author = " - by $entry_author";
}
if (!get_pref($link, 'COMBINED_DISPLAY_MODE')) {
print "";
print "$update_pic ";
print "
";
print "$marked_pic ";
print "$published_pic ";
if ($line["feed_title"]) {
print "$content_link ";
print "
".
$line["feed_title"]." ";
} else {
print "";
print "" .
$line["title"];
if (get_pref($link, 'SHOW_CONTENT_PREVIEW')) {
if ($content_preview) {
print " - $content_preview ";
}
}
print " ";
print " ";
}
print "$updated_fmt ";
print " ";
} else {
if ($is_unread) {
$add_class = "Unread";
} else {
$add_class = "";
}
print "";
print "";
if (get_pref($link, 'OPEN_LINKS_IN_NEW_WINDOW')) {
$line["content_preview"] = preg_replace("/href=/i",
"target=\"_new\" href=", $line["content_preview"]);
}
print "
" . $line["content_preview"] . "
";
print "";
print "
";
}
++$lnum;
}
if (!get_pref($link, 'COMBINED_DISPLAY_MODE') && !$offset) {
print "
";
}
// print_headline_subtoolbar($link,
// "javascript:catchupPage()", "Mark page as read", true, $rtl_content);
} else {
if (!$offset) print "
".__('No articles found.')."
";
}
if (!$offset) {
print "
";
print "
";
}
return $topmost_article_ids;
}
// 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));
}
?>