$config = HTMLPurifier_Config::createDefault();
- $allowed = "p,a[href],i,em,b,strong,code,pre,blockquote,br,img[src|alt|title],ul,ol,li,h1,h2,h3,h4,s";
+ $allowed = "p,a[href],i,em,b,strong,code,pre,blockquote,br,img[src|alt|title],ul,ol,li,h1,h2,h3,h4,s,object[classid|type|id|name|width|height|codebase],param[name|value],table,tr,td";
+
+ $config->set('HTML.SafeObject', true);
+ @$config->set('HTML', 'Allowed', $allowed);
+ $config->set('Output.FlashCompat', true);
+ $config->set('Attr.EnableID', true);
+ @$config->set('Cache', 'SerializerPath', CACHE_DIR . "/htmlpurifier");
- $config->set('HTML', 'Allowed', $allowed);
$purifier = new HTMLPurifier($config);
+ $tz_offset = -1;
+ $utc_tz = new DateTimeZone('UTC');
+ $schema_version = false;
+
/**
* Print a timestamped debug message.
*
if (!$purge_unread) $query_limit = " unread = false AND ";
if (DB_TYPE == "pgsql") {
-/* $result = db_query($link, "DELETE FROM ttrss_user_entries WHERE
- marked = false AND feed_id = '$feed_id' AND
- (SELECT date_updated FROM ttrss_entries WHERE
- id = ref_id) < NOW() - INTERVAL '$purge_interval days'"); */
-
$pg_version = get_pgsql_version($link);
if (preg_match("/^7\./", $pg_version) || preg_match("/^8\.0/", $pg_version)) {
}
}
- function fetch_file_contents($url, $type = false, $login = false, $pass = false) {
+ function fetch_file_contents($url, $type = false, $login = false, $pass = false, $post_query = false) {
$login = urlencode($login);
$pass = urlencode($pass);
- if (function_exists('curl_init')) {
+ if (function_exists('curl_init') && !ini_get("open_basedir")) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
+ curl_setopt($ch, CURLOPT_USERAGENT, SELF_USER_AGENT);
+
+ if ($post_query) {
+ curl_setopt($ch, CURLOPT_POST, true);
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $post_query);
+ }
if ($login && $pass)
curl_setopt($ch, CURLOPT_USERPWD, "$login:$pass");
return $contents;
} else {
- if ($login && $pass && $updated != 3) {
+ if ($login && $pass ){
$url_parts = array();
preg_match("/(^[^:]*):\/\/(.*)/", $url, $url_parts);
global $memcache;
+ $debug_enabled = defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug'];
+
if (!$_REQUEST["daemon"] && !$ignore_daemon) {
return false;
}
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("update_rss_feed: start");
}
}
if (db_num_rows($result) == 0) {
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("update_rss_feed: feed $feed NOT FOUND/SKIPPED");
}
return false;
else
$use_simplepie = false;
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("update method: $update_method (feed setting: $update_method) (use simplepie: $use_simplepie)\n");
}
$cache_images = sql_bool_to_bool(db_fetch_result($result, 0, "cache_images"));
$fetch_url = db_fetch_result($result, 0, "feed_url");
- if ($update_interval < 0) { return; }
+ if ($update_interval < 0) { return false; }
$feed = db_escape_string($feed);
- if ($auth_login && $auth_pass && $updated != 3) {
+ if ($auth_login && $auth_pass ){
$url_parts = array();
preg_match("/(^[^:]*):\/\/(.*)/", $fetch_url, $url_parts);
}
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("update_rss_feed: fetching [$fetch_url]...");
}
if ($memcache && $obj = $memcache->get($obj_id)) {
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("update_rss_feed: data found in memcache.");
}
define('MAGPIE_CACHE_AGE', get_feed_update_interval($link, $feed) * 60);
define('MAGPIE_CACHE_ON', !$no_cache);
+ define('MAGPIE_FETCH_TIME_OUT', 60);
+ define('MAGPIE_CACHE_DIR', CACHE_DIR . "/magpie");
$rss = @fetch_rss($fetch_url);
} else {
- if (!is_dir(SIMPLEPIE_CACHE_DIR)) {
- mkdir(SIMPLEPIE_CACHE_DIR);
+ $simplepie_cache_dir = CACHE_DIR . "/simplepie";
+
+ if (!is_dir($simplepie_cache_dir)) {
+ mkdir($simplepie_cache_dir);
}
$rss = new SimplePie();
if (SIMPLEPIE_CACHE_IMAGES && $cache_images) {
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("enabling image cache");
}
$rss->set_image_handler("image.php", 'i');
}
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("feed update interval (sec): " .
get_feed_update_interval($link, $feed)*60);
}
$rss->enable_cache(!$no_cache);
if (!$no_cache) {
- $rss->set_cache_location(SIMPLEPIE_CACHE_DIR);
+ $rss->set_cache_location($simplepie_cache_dir);
$rss->set_cache_duration(get_feed_update_interval($link, $feed) * 60);
}
// print_r($rss);
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("update_rss_feed: fetch done, parsing...");
}
if ($fetch_ok) {
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("update_rss_feed: processing feed data...");
}
$site_url = $rss->channel["link"];
}
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ $site_url = rewrite_relative_url($fetch_url, $site_url);
+
+ if ($debug_enabled) {
_debug("update_rss_feed: checking favicon...");
}
$feed_title = db_escape_string($rss->channel["title"]);
}
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("update_rss_feed: registering title: $feed_title");
}
db_query($link, "UPDATE ttrss_feeds SET icon_url = '$icon_url' WHERE id = '$feed'");
}
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("update_rss_feed: loading filters...");
}
$filters = load_filters($link, $feed, $owner_uid);
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug'] == 2) {
- print_r($filters);
- }
+// if ($debug_enabled) {
+// print_r($filters);
+// }
if ($use_simplepie) {
$iterator = $rss->get_items();
// clear any errors and mark feed as updated if fetched okay
// even if it's blank
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("update_rss_feed: entry iterator is not an array, no articles?");
}
return; // no articles
}
- if ($pubsub_state != 2) {
+ if ($pubsub_state != 2 && PUBSUBHUBBUB_ENABLED) {
+
+ if ($debug_enabled) _debug("update_rss_feed: checking for PUSH hub...");
$feed_hub_url = false;
if ($use_simplepie) {
}
}
- if ($feed_hub_url && function_exists('curl_init')) {
+ if ($debug_enabled) _debug("update_rss_feed: feed hub url: $feed_hub_url");
+
+ if ($feed_hub_url && function_exists('curl_init') &&
+ !ini_get("open_basedir")) {
+
$callback_url = get_self_url_prefix() .
"/backend.php?op=pubsub&id=$feed";
$s = new Subscriber($feed_hub_url, $callback_url);
- $s->subscribe($fetch_url);
+ $rc = $s->subscribe($fetch_url);
+
+ if ($debug_enabled)
+ _debug("update_rss_feed: feed hub url found, subscribe request sent.");
db_query($link, "UPDATE ttrss_feeds SET pubsub_state = 1
WHERE id = '$feed'");
}
}
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("update_rss_feed: processing articles...");
}
if (!$entry_guid) $entry_guid = make_guid_from_title($item["title"]);
}
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("update_rss_feed: guid $entry_guid");
}
$entry_timestamp_fmt = strftime("%Y/%m/%d %H:%M:%S", $entry_timestamp);
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("update_rss_feed: date $entry_timestamp [$entry_timestamp_fmt]");
}
if (!$entry_link) $entry_link = $item["link"];
}
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ $entry_link = rewrite_relative_url($site_url, $entry_link);
+
+ if ($debug_enabled) {
_debug("update_rss_feed: title $entry_title");
+ _debug("update_rss_feed: link $entry_link");
}
if (!$entry_title) $entry_title = date("Y-m-d H:i:s", $entry_timestamp);;
if (!$num_comments) $num_comments = 0;
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("update_rss_feed: looking for tags [1]...");
}
}
}
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("update_rss_feed: category tags:");
print_r($additional_tags);
}
}
}
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("update_rss_feed: looking for tags [2]...");
}
for ($i = 0; $i < count($entry_tags); $i++)
$entry_tags[$i] = mb_strtolower($entry_tags[$i], 'utf-8');
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("update_rss_feed: unfiltered tags found:");
print_r($entry_tags);
}
$entry_content = sanitize_article_content($entry_content);
$entry_title = sanitize_article_content($entry_title);
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("update_rss_feed: done collecting data [TITLE:$entry_title]");
}
if (db_num_rows($result) == 0) {
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("update_rss_feed: base guid not found");
}
if (db_num_rows($result) == 1) {
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("update_rss_feed: base guid found, checking for user record");
}
$entry_content, $entry_link, $entry_timestamp, $entry_author,
$entry_tags);
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("update_rss_feed: article filters: ");
if (count($article_filters) != 0) {
print_r($article_filters);
$score = calculate_article_score($article_filters);
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("update_rss_feed: initial score: $score");
}
// okay it doesn't exist - create user entry
if (db_num_rows($result) == 0) {
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("update_rss_feed: user record not found, creating...");
}
$entry_int_id = db_fetch_result($result, 0, "int_id");
}
} else {
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("update_rss_feed: user record FOUND");
}
$entry_int_id = db_fetch_result($result, 0, "int_id");
}
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("update_rss_feed: RID: $entry_ref_id, IID: $entry_int_id");
}
$post_needs_update = false;
+ $update_insignificant = false;
- if ($update_on_checksum_change && $content_hash != $orig_content_hash) {
-// print "<!-- [$entry_title] $content_hash vs $orig_content_hash -->";
+ if ($orig_num_comments != $num_comments) {
$post_needs_update = true;
+ $update_insignificant = true;
}
- if (db_escape_string($orig_title) != $entry_title) {
+ if ($content_hash != $orig_content_hash) {
$post_needs_update = true;
+ $update_insignificant = false;
}
- if ($orig_num_comments != $num_comments) {
+ if (db_escape_string($orig_title) != $entry_title) {
$post_needs_update = true;
+ $update_insignificant = false;
}
-// this doesn't seem to be very reliable
-//
-// if ($orig_timestamp != $entry_timestamp && !$orig_no_orig_date) {
-// $post_needs_update = true;
-// }
-
// if post needs update, update it and mark all user entries
// linking to this post as updated
if ($post_needs_update) {
db_query($link, "UPDATE ttrss_entries
SET title = '$entry_title', content = '$entry_content',
content_hash = '$content_hash',
+ updated = '$entry_timestamp_fmt',
num_comments = '$num_comments'
WHERE id = '$ref_id'");
- if ($mark_unread_on_update) {
- db_query($link, "UPDATE ttrss_user_entries
- SET last_read = null, unread = true WHERE ref_id = '$ref_id'");
- } else {
- db_query($link, "UPDATE ttrss_user_entries
- SET last_read = null WHERE ref_id = '$ref_id' AND unread = false");
+ if (!$update_insignificant) {
+ if ($mark_unread_on_update) {
+ db_query($link, "UPDATE ttrss_user_entries
+ SET last_read = null, unread = true WHERE ref_id = '$ref_id'");
+ } else if ($update_on_checksum_change) {
+ db_query($link, "UPDATE ttrss_user_entries
+ SET last_read = null WHERE ref_id = '$ref_id'
+ AND unread = false");
+ }
}
-
}
}
db_query($link, "COMMIT");
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("update_rss_feed: assigning labels...");
}
assign_article_to_labels($link, $entry_ref_id, $article_filters,
$owner_uid);
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("update_rss_feed: looking for enclosures...");
}
}
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("update_rss_feed: article enclosures:");
print_r($enclosures);
}
foreach ($article_filters as $f) {
if ($f[0] == "tag") {
- $manual_tags = trim_array(split(",", $f[1]));
+ $manual_tags = trim_array(explode(",", $f[1]));
foreach ($manual_tags as $tag) {
if (tag_is_valid($tag)) {
// Skip boring tags
- $boring_tags = trim_array(split(",", mb_strtolower(get_pref($link,
+ $boring_tags = trim_array(explode(",", mb_strtolower(get_pref($link,
'BLACKLISTED_TAGS', $owner_uid, ''), 'utf-8')));
$filtered_tags = array();
$filtered_tags = array_unique($filtered_tags);
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("update_rss_feed: filtered article tags:");
print_r($filtered_tags);
}
db_query($link, "COMMIT");
}
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("update_rss_feed: article processed");
}
}
if (!$last_updated) {
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("update_rss_feed: new feed, catching it up...");
}
catchup_feed($link, $feed, false, $owner_uid);
}
- purge_feed($link, $feed, 0);
+ if ($debug_enabled) {
+ _debug("purging feed...");
+ }
+
+ purge_feed($link, $feed, 0, $debug_enabled);
db_query($link, "UPDATE ttrss_feeds
SET last_updated = NOW(), last_error = '' WHERE id = '$feed'");
$error_msg = mb_substr(magpie_error(), 0, 250);
}
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("update_rss_feed: error fetching feed: $error_msg");
}
unset($rss);
}
- if (defined('DAEMON_EXTENDED_DEBUG') || $_REQUEST['xdebug']) {
+ if ($debug_enabled) {
_debug("update_rss_feed: done");
}
function lookup_user_id($link, $user) {
- $result = db_query($link, "SELECT id FROM ttrss_users WHERE
- login = '$login'");
+ $result = db_query($link, "SELECT id FROM ttrss_users WHERE login = '$user'");
if (db_num_rows($result) == 1) {
return db_fetch_result($result, 0, "id");
}
}
- function http_authenticate_user($link) {
-
-// error_log("http_authenticate_user: ".$_SERVER["PHP_AUTH_USER"]."\n", 3, '/tmp/tt-rss.log');
-
+/* function http_authenticate_user($link) {
if (!$_SERVER["PHP_AUTH_USER"]) {
header('WWW-Authenticate: Basic realm="Tiny Tiny RSS RSSGen"');
}
return true;
- }
+ } */
function get_ssl_certificate_id() {
if ($_SERVER["REDIRECT_SSL_CLIENT_M_SERIAL"]) {
FROM ttrss_users WHERE
login = '$login'";
+ if (defined('AUTO_CREATE_USER') && AUTO_CREATE_USER
+ && $_SERVER["REMOTE_USER"]) {
+ $result = db_query($link, $query);
+
+ // First login ?
+ if (db_num_rows($result) == 0) {
+ $query2 = "INSERT INTO ttrss_users
+ (login,access_level,last_login,created)
+ VALUES ('$login', 0, null, NOW())";
+ db_query($link, $query2);
+ }
+ }
+
} else {
$query = "SELECT id,login,access_level,pwd_hash
FROM ttrss_users WHERE
db_query($link, "UPDATE ttrss_users SET last_login = NOW() WHERE id = " .
$_SESSION["uid"]);
+
+ // LemonLDAP can send user informations via HTTP HEADER
+ if (defined('AUTO_CREATE_USER') && AUTO_CREATE_USER){
+ // update user name
+ $fullname = $_SERVER['HTTP_USER_NAME'] ? $_SERVER['HTTP_USER_NAME'] : $_SERVER['AUTHENTICATE_CN'];
+ if ($fullname){
+ $fullname = db_escape_string($fullname);
+ db_query($link, "UPDATE ttrss_users SET full_name = '$fullname' WHERE id = " .
+ $_SESSION["uid"]);
+ }
+ // update user mail
+ $email = $_SERVER['HTTP_USER_MAIL'] ? $_SERVER['HTTP_USER_MAIL'] : $_SERVER['AUTHENTICATE_MAIL'];
+ if ($email){
+ $email = db_escape_string($email);
+ db_query($link, "UPDATE ttrss_users SET email = '$email' WHERE id = " .
+ $_SESSION["uid"]);
+ }
+ }
+
$_SESSION["ip_address"] = $_SERVER["REMOTE_ADDR"];
$_SESSION["pwd_hash"] = db_fetch_result($result, 0, "pwd_hash");
setcookie("ttrss_lang", $_SESSION["language"],
time() + SESSION_COOKIE_LIFETIME);
}
+
+ // try to remove possible duplicates from feed counter cache
+// ccache_cleanup($link, $_SESSION["uid"]);
}
} else {
if (!$owner_uid) $owner_uid = $_SESSION['uid'];
if (!$timestamp) $timestamp = '1970-01-01 0:00';
- $user_tz_string = get_pref($link, 'USER_TIMEZONE', $owner_uid);
+ global $utc_tz;
+ global $tz_offset;
- try {
- $user_tz = new DateTimeZone($user_tz_string);
- } catch (Exception $e) {
- $user_tz = new DateTimeZone('UTC');
+ # We store date in UTC internally
+ $dt = new DateTime($timestamp, $utc_tz);
+
+ if ($tz_offset == -1) {
+
+ $user_tz_string = get_pref($link, 'USER_TIMEZONE', $owner_uid);
+
+ try {
+ $user_tz = new DateTimeZone($user_tz_string);
+ } catch (Exception $e) {
+ $user_tz = $utc_tz;
+ }
+
+ $tz_offset = $user_tz->getOffset($dt);
}
- # We store date in UTC internally
- $dt = new DateTime($timestamp, new DateTimeZone('UTC'));
- $user_timestamp = $dt->format('U') + $user_tz->getOffset($dt);
+ $user_timestamp = $dt->format('U') + $tz_offset;
if (!$no_smart_dt) {
return smart_date_time($link, $user_timestamp,
- $user_tz->getOffset($dt), $owner_uid);
+ $tz_offset, $owner_uid);
} else {
if ($long)
$format = get_pref($link, 'LONG_DATE_FORMAT', $owner_uid);
}
function sql_bool_to_bool($s) {
- if ($s == "t" || $s == "1") {
+ if ($s == "t" || $s == "1" || $s == "true") {
return true;
} else {
return false;
return "even";
}
+ // Session caching removed due to causing wrong redirects to upgrade
+ // script when get_schema_version() is called on an obsolete session
+ // created on a previous schema version.
function get_schema_version($link, $nocache = false) {
- if (!$_SESSION["schema_version"] || $nocache) {
+ global $schema_version;
+
+ if (!$schema_version) {
$result = db_query($link, "SELECT schema_version FROM ttrss_version");
$version = db_fetch_result($result, 0, "schema_version");
- $_SESSION["schema_version"] = $version;
+ $schema_version = $version;
return $version;
} else {
- return $_SESSION["schema_version"];
+ return $schema_version;
}
}
global $ERRORS;
$error_code = 0;
- $schema_version = get_schema_version($link);
+ $schema_version = get_schema_version($link, true);
if ($schema_version != SCHEMA_VERSION) {
$error_code = 5;
if (strchr($omode, "l")) $data = array_merge($data, getLabelCounters($link));
if (strchr($omode, "f")) $data = array_merge($data, getFeedCounters($link, $active_feed));
if (strchr($omode, "t")) $data = array_merge($data, getTagCounters($link));
- if (strchr($omode, "c")) {
- if (get_pref($link, 'ENABLE_FEED_CATS')) {
- $data = array_merge($data, getCategoryCounters($link));
- }
- }
+ if (strchr($omode, "c")) $data = array_merge($data, getCategoryCounters($link));
return $data;
}
function get_pgsql_version($link) {
$result = db_query($link, "SELECT version() AS version");
- $version = split(" ", db_fetch_result($result, 0, "version"));
+ $version = explode(" ", db_fetch_result($result, 0, "version"));
return $version[1];
}
return "Unknown label ($label_id)";
}
- } else if ($id > 0) {
+ } else if (is_numeric($id) && $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");
$params["theme"] = get_user_theme($link);
$params["theme_options"] = get_user_theme_options($link);
- $params["daemon_enabled"] = ENABLE_UPDATE_DAEMON;
$params["sign_progress"] = theme_image($link, "images/indicator_white.gif");
$params["sign_progress_tiny"] = theme_image($link, "images/indicator_tiny.gif");
$data['last_article_id'] = getLastArticleId($link);
$data['cdm_expanded'] = get_pref($link, 'CDM_EXPANDED');
- if (ENABLE_UPDATE_DAEMON) {
+ if (file_exists(LOCK_DIRECTORY . "/update_daemon.lock")) {
$data['daemon_is_running'] = (int) file_is_locked("update_daemon.lock");
return $data;
}
- function getSearchSql($link, $search, $match_on) {
+ function search_to_sql($link, $search, $match_on) {
$search_query_part = "";
- $keywords = split(" ", $search);
+ $keywords = explode(" ", $search);
$query_keywords = array();
foreach ($keywords as $k) {
$not = "";
}
- if (strpos($k, "@") === 0) {
+ $commandpair = explode(":", mb_strtolower($k), 2);
+
+ if ($commandpair[0] == "note" && $commandpair[1]) {
+
+ if ($commandpair[1] == "true")
+ array_push($query_keywords, "($not (note IS NOT NULL AND note != ''))");
+ else
+ array_push($query_keywords, "($not (note IS NULL OR note = ''))");
+
+ } else if ($commandpair[0] == "star" && $commandpair[1]) {
+
+ if ($commandpair[1] == "true")
+ array_push($query_keywords, "($not (marked = true))");
+ else
+ array_push($query_keywords, "($not (marked = false))");
+
+ } else if ($commandpair[0] == "pub" && $commandpair[1]) {
+
+ if ($commandpair[1] == "true")
+ array_push($query_keywords, "($not (published = true))");
+ else
+ array_push($query_keywords, "($not (published = false))");
+
+ } else if (strpos($k, "@") === 0) {
$user_tz_string = get_pref($link, 'USER_TIMEZONE', $_SESSION['uid']);
$orig_ts = strtotime(substr($k, 1));
-
$k = date("Y-m-d", convert_timestamp($orig_ts, $user_tz_string, 'UTC'));
+ //$k = date("Y-m-d", strtotime(substr($k, 1)));
+
array_push($query_keywords, "(".SUBSTRING_FOR_DATE."(updated,1,LENGTH('$k')) $not = '$k')");
} else if ($match_on == "both") {
array_push($query_keywords, "(UPPER(ttrss_entries.title) $not LIKE UPPER('%$k%')
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) {
+
+ function queryFeedHeadlines($link, $feed, $limit, $view_mode, $cat_view, $search, $search_mode, $match_on, $override_order = false, $offset = 0, $owner_uid = 0, $filter = false) {
if (!$owner_uid) $owner_uid = $_SESSION["uid"];
$search_query_part = "ref_id = -1 AND ";
} else {
- $search_query_part = getSearchSql($link, $search, $match_on);
+ $search_query_part = search_to_sql($link, $search, $match_on);
$search_query_part .= " AND ";
}
$search_query_part = "";
}
+ if ($filter) {
+ $filter_query_part = filter_to_sql($filter);
+ } else {
+ $filter_query_part = "";
+ }
+
$view_query_part = "";
if ($view_mode == "adaptive" || $view_query_part == "noscores") {
if ($cat_view) {
$feed_title = getCategoryTitle($link, $feed);
} else {
- if ((int)$feed == $feed && $feed > 0) {
+ if (is_numeric($feed) && $feed > 0) {
$result = db_query($link, "SELECT title,site_url,last_error
FROM ttrss_feeds WHERE id = '$feed' AND owner_uid = $owner_uid");
ttrss_user_entries.ref_id = ttrss_entries.id AND
ttrss_user_entries.owner_uid = '$owner_uid' AND
$search_query_part
+ $filter_query_part
$view_query_part
$query_strategy_part ORDER BY $order_by
$limit_query_part $offset_query_part";
} else {
// browsing by tag
+ $select_qpart = "SELECT DISTINCT " .
+ "date_entered," .
+ "guid," .
+ "note," .
+ "ttrss_entries.id as id," .
+ "title," .
+ "updated," .
+ "unread," .
+ "feed_id," .
+ "orig_feed_id," .
+ "marked," .
+ "link," .
+ "last_read," .
+ SUBSTRING_FOR_DATE . "(last_read,1,19) as last_read_noms," .
+ $vfeed_query_part .
+ $content_query_part .
+ SUBSTRING_FOR_DATE . "(updated,1,19) as updated_noms," .
+ "score ";
+
$feed_kind = "Tags";
+ $all_tags = explode(",", $feed);
+ if ($search_mode == 'any') {
+ $tag_sql = "tag_name in (" . implode(", ", array_map("db_quote", $all_tags)) . ")";
+ $from_qpart = " FROM ttrss_entries,ttrss_user_entries,ttrss_tags ";
+ $where_qpart = " WHERE " .
+ "ref_id = ttrss_entries.id AND " .
+ "ttrss_user_entries.owner_uid = $owner_uid AND " .
+ "post_int_id = int_id AND $tag_sql AND " .
+ $view_query_part .
+ $search_query_part .
+ $query_strategy_part . " ORDER BY $order_by " .
+ $limit_query_part;
- $result = db_query($link, "SELECT DISTINCT
- date_entered,
- guid,
- note,
- ttrss_entries.id as id,title,
- updated,
- unread,feed_id,orig_feed_id,
- marked,link,last_read,
- ".SUBSTRING_FOR_DATE."(last_read,1,19) as last_read_noms,
- $vfeed_query_part
- $content_query_part
- ".SUBSTRING_FOR_DATE."(updated,1,19) as updated_noms,
- score
- 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");
+ } else {
+ $i = 1;
+ $sub_selects = array();
+ $sub_ands = array();
+ foreach ($all_tags as $term) {
+ array_push($sub_selects, "(SELECT post_int_id from ttrss_tags WHERE tag_name = " . db_quote($term) . " AND owner_uid = $owner_uid) as A$i");
+ $i++;
+ }
+ if ($i > 2) {
+ $x = 1;
+ $y = 2;
+ do {
+ array_push($sub_ands, "A$x.post_int_id = A$y.post_int_id");
+ $x++;
+ $y++;
+ } while ($y < $i);
+ }
+ array_push($sub_ands, "A1.post_int_id = ttrss_user_entries.int_id and ttrss_user_entries.owner_uid = $owner_uid");
+ array_push($sub_ands, "ttrss_user_entries.ref_id = ttrss_entries.id");
+ $from_qpart = " FROM " . implode(", ", $sub_selects) . ", ttrss_user_entries, ttrss_entries";
+ $where_qpart = " WHERE " . implode(" AND ", $sub_ands);
+ }
+ // error_log("TAG SQL: " . $tag_sql);
+ // $tag_sql = "tag_name = '$feed'"; DEFAULT way
+
+ // error_log("[". $select_qpart . "][" . $from_qpart . "][" .$where_qpart . "]");
+ $result = db_query($link, $select_qpart . $from_qpart . $where_qpart);
}
return array($result, $feed_title, $feed_site_url, $last_error);
require_once "lib/MiniTemplator.class.php";
- $note_style = "float : right; background-color : #fff7d5; border-width : 1px; ".
+ $note_style = "background-color : #fff7d5;
+ border-width : 1px; ".
"padding : 5px; border-style : dashed; border-color : #e7d796;".
"margin-bottom : 1em; color : #9a8c59;";
$content = sanitize_rss($link, $line["content_preview"], false, $owner_uid);
if ($line['note']) {
- $content = "<div style=\"$note_style\">" . $line['note'] . "</div>" .
+ $content = "<div style=\"$note_style\">Article note: " . $line['note'] . "</div>" .
$content;
}
$res = trim($str); if (!$res) return '';
- if (get_pref($link, "STRIP_UNSAFE_TAGS", $owner) || $force_strip_tags) {
- $res = $purifier->purify($res);
- }
+// if (get_pref($link, "STRIP_UNSAFE_TAGS", $owner) || $force_strip_tags) {
+ $res = $purifier->purify($res);
+// }
if (get_pref($link, "STRIP_IMAGES", $owner)) {
$res = preg_replace('/<img[^>]+>/is', '', $res);
if ($is_cat) $cat_q = "&is_cat=$is_cat";
+ if ($search) {
+ $search_q = "&q=$search&m=$match_on&smode=$search_mode";
+ } else {
+ $search_q = "";
+ }
+
$rss_link = htmlspecialchars(get_self_url_prefix() .
"/backend.php?op=rss&id=$feed_id$cat_q$search_q");
$fg_color = db_fetch_result($result, 0, "fg_color");
$bg_color = db_fetch_result($result, 0, "bg_color");
- $reply .= "<span style='background : $bg_color; color : $fg_color'>";
+ $reply .= "<span style=\"background : $bg_color; color : $fg_color\" >";
$reply .= $feed_title;
$reply .= "</span>";
} else {
}
}
- if ($search) {
- $search_q = "&q=$search&m=$match_on&smode=$search_mode";
- } else {
- $search_q = "";
- }
-
$reply .= "
<a href=\"#\"
title=\"".__("View as RSS feed")."\"
} else {
$entry .= "<object type=\"application/x-shockwave-flash\"
- data=\"extras/button/musicplayer.swf?song_url=$url\"
+ data=\"lib/button/musicplayer.swf?song_url=$url\"
width=\"17\" height=\"17\" style='float : left; margin-right : 5px;'>
<param name=\"movie\"
- value=\"extras/button/musicplayer.swf?song_url=$url\" />
+ value=\"lib/button/musicplayer.swf?song_url=$url\" />
</object>";
}
}
return $entry;
}
- function format_article($link, $id, $feed_id, $mark_as_read = true,
- $zoom_mode = false) {
+ function format_article($link, $id, $mark_as_read = true, $zoom_mode = false) {
$rv = array();
$rv['content'] .= "<div clear='both'>" . $line["title"] . "$entry_author</div>";
}
- $tags_str = format_tags_string(get_article_tags($link, $id), $id);
+ $tags = get_article_tags($link, $id);
+ $tags_str = format_tags_string($tags, $id);
+ $tags_str_full = join(", ", $tags);
+
+ if (!$tags_str_full) $tags_str_full = __("no tags");
if (!$entry_comments) $entry_comments = " "; # placeholder
<a title=\"".__('Edit tags for this article')."\"
href=\"#\" onclick=\"editArticleTags($id, $feed_id)\">(+)</a>";
+ $rv['content'] .= "<div dojoType=\"dijit.Tooltip\"
+ id=\"ATSTRTIP-$id\" connectId=\"ATSTR-$id\"
+ position=\"below\">$tags_str_full</div>";
+
$rv['content'] .= "<img src=\"".theme_image($link, 'images/art-zoom.png')."\"
class='tagsPic' style=\"cursor : pointer\"
onclick=\"postOpenInNewTab(event, $id)\"
$rv['content'] .= "</div>";
- $rv['content'] .= "<div class=\"postIcon\">" .
- "<a target=\"_blank\" title=\"".__("Visit the website")."\"$
- href=\"".htmlspecialchars($feed_site_url)."\">".
- $feed_icon . "</a></div>";
-
$rv['content'] .= "<div id=\"POSTNOTE-$id\">";
if ($line['note']) {
$rv['content'] .= format_article_note($id, $line['note']);
}
$rv['content'] .= "</div>";
+ $rv['content'] .= "<div class=\"postIcon\">" .
+ "<a target=\"_blank\" title=\"".__("Visit the website")."\"$
+ href=\"".htmlspecialchars($feed_site_url)."\">".
+ $feed_icon . "</a></div>";
+
$rv['content'] .= "<div class=\"postContent\">";
$article_content = sanitize_rss($link, $line["content"], false, false,
$topmost_article_ids = array();
- if (!$offset) {
- $offset = 0;
- }
-
+ if (!$offset) $offset = 0;
if ($subop == "undefined") $subop = "";
- $subop_split = split(":", $subop);
+ $subop_split = explode(":", $subop);
- if ($subop == "CatchupSelected") {
- $ids = split(",", db_escape_string($_REQUEST["ids"]));
+/* if ($subop == "CatchupSelected") {
+ $ids = explode(",", db_escape_string($_REQUEST["ids"]));
$cmode = sprintf("%d", $_REQUEST["cmode"]);
catchupArticlesById($link, $ids, $cmode);
- }
+ } */
- if ($subop == "ForceUpdate" && sprintf("%d", $feed) > 0) {
+ if ($subop == "ForceUpdate" && $feed && is_numeric($feed) > 0) {
update_rss_feed($link, $feed, true);
}
// FIXME: might break tag display?
- if ($feed > 0 && !$cat_view) {
+ if (is_numeric($feed) && $feed > 0 && !$cat_view) {
$result = db_query($link,
"SELECT id FROM ttrss_feeds WHERE id = '$feed' LIMIT 1");
$rtl_content = false;
}
- /// START /////////////////////////////////////////////////////////////////////////////////
-
@$search = db_escape_string($_REQUEST["query"]);
if ($search) {
$match_on = "both";
}
- $real_offset = $offset * $limit;
-
if ($_REQUEST["debug"]) $timing_info = print_checkpoint("H0", $timing_info);
+// error_log("format_headlines_list: [" . $feed . "] subop [" . $subop . "]");
+ if( $search_mode == '' && $subop != '' ){
+ $search_mode = $subop;
+ }
+// error_log("search_mode: " . $search_mode);
$qfh_ret = queryFeedHeadlines($link, $feed, $limit, $view_mode, $cat_view,
- $search, $search_mode, $match_on, $override_order, $real_offset);
+ $search, $search_mode, $match_on, $override_order, $offset);
if ($_REQUEST["debug"]) $timing_info = print_checkpoint("H1", $timing_info);
$vgroup_last_feed = $vgr_last_feed;
- /// STOP //////////////////////////////////////////////////////////////////////////////////
-
if (!$offset) {
if (db_num_rows($result) > 0) {
- $reply['toolbar'] = format_headline_subtoolbar($link, $feed_site_url, $feed_title,
+ $reply['toolbar'] = format_headline_subtoolbar($link, $feed_site_url,
+ $feed_title,
$feed, $cat_view, $search, $match_on, $search_mode, $view_mode,
$last_error);
}
if (db_num_rows($result) > 0) {
- $lnum = $limit*$offset;
+ $lnum = $offset;
$num_unread = 0;
$cur_feed_title = '';
$fresh_intl = get_pref($link, "FRESH_ARTICLE_MAX_AGE") * 60 * 60;
+ if ($_REQUEST["debug"]) $timing_info = print_checkpoint("PS", $timing_info);
+
while ($line = db_fetch_assoc($result)) {
$class = ($lnum % 2) ? "even" : "odd";
$reply['content'] .= $labels_str;
- /* if (!get_pref($link, 'VFEED_GROUP_BY_FEED')) {
+ if (!get_pref($link, 'VFEED_GROUP_BY_FEED') &&
+ defined('_SHOW_FEED_TITLE_IN_VFEEDS')) {
if (@$line["feed_title"]) {
- print "<span class=\"hlFeed\">
+ $reply['content'] .= "<span class=\"hlFeed\">
(<a href=\"#\" onclick=\"viewfeed($feed_id)\">".
$line["feed_title"]."</a>)
</span>";
}
- } */
+ }
$reply['content'] .= "</div>";
- $reply['content'] .= "<div class=\"hlRight\">";
$reply['content'] .= "<span class=\"hlUpdated\">$updated_fmt</span>";
+ $reply['content'] .= "<div class=\"hlRight\">";
+
$reply['content'] .= $score_pic;
if ($line["feed_title"] && !get_pref($link, 'VFEED_GROUP_BY_FEED')) {
$reply['content'] .= "<span onclick=\"viewfeed($feed_id)\"
+ style=\"cursor : pointer\"
title=\"".htmlspecialchars($line['feed_title'])."\">
$feed_icon_img<span>";
}
$reply['content'] .= $labels_str;
+ if (!get_pref($link, 'VFEED_GROUP_BY_FEED') &&
+ defined('_SHOW_FEED_TITLE_IN_VFEEDS')) {
+ if (@$line["feed_title"]) {
+ $reply['content'] .= "<span class=\"hlFeed\">
+ (<a href=\"#\" onclick=\"viewfeed($feed_id)\">".
+ $line["feed_title"]."</a>)
+ </span>";
+ }
+ }
+
if (!$expand_cdm)
$content_hidden = "style=\"display : none\"";
else
++$lnum;
}
+ if ($_REQUEST["debug"]) $timing_info = print_checkpoint("PE", $timing_info);
+
} else {
$message = "";
}
}
-# if (!$offset) {
-# if ($headlines_count > 0) print "</div>";
-# print "</div>";
-# }
-
- #print "]]></content>";
+ if ($_REQUEST["debug"]) $timing_info = print_checkpoint("H2", $timing_info);
return array($topmost_article_ids, $headlines_count, $feed, $disable_cache,
- $vgroup_last_feed, $reply['content'], $reply['toolbar']);
+ $vgroup_last_feed, $reply);
}
// from here: http://www.roscripts.com/Create_tag_cloud-71.html
$tags[$line["tag_name"]] = $line["count"];
}
+ if( count($tags) == 0 ){ return; }
+
ksort($tags);
$max_size = 32; // max font size in pixels
$tag = mb_strtolower($tag, 'utf-8');
- $tag = preg_replace('/[\"\+\>\<]/', "", $tag);
+ $tag = preg_replace('/[\'\"\+\>\<]/', "", $tag);
// $tag = str_replace('"', "", $tag);
// $tag = str_replace("+", " ", $tag);
}
function get_self_url_prefix() {
-
- /* $url_path = "";
-
- if ($_SERVER['HTTPS'] != "on") {
- $url_path = "http://";
- } else {
- $url_path = "https://";
- }
-
- $url_path .= $_SERVER['HTTP_HOST'].dirname($_SERVER['PHP_SELF']);
-
- return $url_path; */
-
return SELF_URL_PATH;
-
}
+
function opml_publish_url($link){
$url_path = get_self_url_prefix();
function update_feedbrowser_cache($link) {
- $result = db_query($link, "SELECT feed_url,title, COUNT(id) AS subscribers
+ $result = db_query($link, "SELECT feed_url, site_url, title, 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, title ORDER BY subscribers DESC LIMIT 1000");
+ AND (private IS true OR auth_login != '' OR auth_pass != '' OR feed_url LIKE '%:%@%/%'))
+ GROUP BY feed_url, site_url, title ORDER BY subscribers DESC LIMIT 1000");
db_query($link, "BEGIN");
$subscribers = db_escape_string($line["subscribers"]);
$feed_url = db_escape_string($line["feed_url"]);
$title = db_escape_string($line["title"]);
+ $site_url = db_escape_string($line["site_url"]);
$tmp_result = db_query($link, "SELECT subscribers FROM
ttrss_feedbrowser_cache WHERE feed_url = '$feed_url'");
if (db_num_rows($tmp_result) == 0) {
db_query($link, "INSERT INTO ttrss_feedbrowser_cache
- (feed_url, title, subscribers) VALUES ('$feed_url',
- '$title', '$subscribers')");
+ (feed_url, site_url, title, subscribers) VALUES ('$feed_url',
+ '$site_url', '$title', '$subscribers')");
++$count;
return $unread;
}
+ function ccache_cleanup($link, $owner_uid) {
+
+ if (DB_TYPE == "pgsql") {
+ db_query($link, "DELETE FROM ttrss_counters_cache AS c1 WHERE
+ (SELECT count(*) FROM ttrss_counters_cache AS c2
+ WHERE c1.feed_id = c2.feed_id AND c2.owner_uid = c1.owner_uid) > 1
+ AND owner_uid = '$owner_uid'");
+
+ db_query($link, "DELETE FROM ttrss_cat_counters_cache AS c1 WHERE
+ (SELECT count(*) FROM ttrss_cat_counters_cache AS c2
+ WHERE c1.feed_id = c2.feed_id AND c2.owner_uid = c1.owner_uid) > 1
+ AND owner_uid = '$owner_uid'");
+ } else {
+ db_query($link, "DELETE c1 FROM
+ ttrss_counters_cache AS c1,
+ ttrss_counters_cache AS c2
+ WHERE
+ c1.owner_uid = '$owner_uid' AND
+ c1.owner_uid = c2.owner_uid AND
+ c1.feed_id = c2.feed_id");
+
+ db_query($link, "DELETE c1 FROM
+ ttrss_cat_counters_cache AS c1,
+ ttrss_cat_counters_cache AS c2
+ WHERE
+ c1.owner_uid = '$owner_uid' AND
+ c1.owner_uid = c2.owner_uid AND
+ c1.feed_id = c2.feed_id");
+
+ }
+ }
+
function label_find_id($link, $label, $owner_uid) {
$result = db_query($link,
"SELECT id FROM ttrss_labels2 WHERE caption = '$label'
$num_tags = 0;
-/* if (get_user_theme($link) == "3pane") {
- $tag_limit = 3;
- } else {
- $tag_limit = 6;
- } */
-
$tag_limit = 6;
$formatted_tags = array();
function format_article_note($id, $note) {
- $str = "<div class='articleNote' title=\"".__('edit note')."\"
- onclick=\"editArticleNote($id)\">$note</div>";
+ $str = "<div class='articleNote' onclick=\"editArticleNote($id)\">
+ <div class='noteEdit' onclick=\"editArticleNote($id)\">".
+ __('(edit note)')."</div>$note</div>";
return $str;
}
}
function api_get_headlines($link, $feed_id, $limit, $offset,
- $filter, $is_cat, $show_excerpt, $show_content, $view_mode, $order) {
+ $filter, $is_cat, $show_excerpt, $show_content, $view_mode, $order,
+ $include_attachments) {
/* do not rely on params below */
"tags" => get_article_tags($link, $line["id"]),
);
+ if ($include_attachments)
+ $headline_row['attachments'] = get_article_enclosures($link,
+ $line['id']);
+
if ($show_excerpt) {
$excerpt = truncate_string(strip_tags($line["content_preview"]), 100);
$headline_row["excerpt"] = $excerpt;
return $result;
}
+ function filter_to_sql($filter) {
+ $query = "";
+
+ if (DB_TYPE == "pgsql")
+ $reg_qpart = "~";
+ else
+ $reg_qpart = "REGEXP";
+
+ switch ($filter["type"]) {
+ case "title":
+ $query = "LOWER(ttrss_entries.title) $reg_qpart LOWER('".
+ $filter['reg_exp'] . "')";
+ break;
+ case "content":
+ $query = "LOWER(ttrss_entries.content) $reg_qpart LOWER('".
+ $filter['reg_exp'] . "')";
+ break;
+ case "both":
+ $query = "LOWER(ttrss_entries.title) $reg_qpart LOWER('".
+ $filter['reg_exp'] . "') OR LOWER(" .
+ "ttrss_entries.content) $reg_qpart LOWER('" . $filter['reg_exp'] . "')";
+ break;
+ case "tag":
+ $query = "LOWER(ttrss_user_entries.tag_cache) $reg_qpart LOWER('".
+ $filter['reg_exp'] . "')";
+ break;
+ case "link":
+ $query = "LOWER(ttrss_entries.link) $reg_qpart LOWER('".
+ $filter['reg_exp'] . "')";
+ break;
+ case "date":
+
+ if ($filter["filter_param"] == "before")
+ $cmp_qpart = "<";
+ else
+ $cmp_qpart = ">=";
+
+ $timestamp = date("Y-m-d H:N:s", strtotime($filter["reg_exp"]));
+ $query = "ttrss_entries.date_entered $cmp_qpart '$timestamp'";
+ break;
+ case "author":
+ $query = "LOWER(ttrss_entries.author) $reg_qpart LOWER('".
+ $filter['reg_exp'] . "')";
+ break;
+ }
+
+ if ($filter["inverse"])
+ $query = "NOT ($query)";
+
+ if ($query) {
+ if (DB_TYPE == "pgsql") {
+ $query = " ($query) AND ttrss_entries.date_entered > NOW() - INTERVAL '14 days'";
+ } else {
+ $query = " ($query) AND ttrss_entries.date_entered > DATE_SUB(NOW(), INTERVAL 14 DAY)";
+ }
+ $query .= " AND ";
+ }
+
+
+ return $query;
+ }
+
+ // Status codes:
+ // -1 - never connected
+ // 0 - no data received
+ // 1 - data received successfully
+ // 2 - did not receive valid data
+ // >10 - server error, code + 10 (e.g. 16 means server error 6)
+
+ function get_linked_feeds($link, $instance_id = false) {
+ if ($instance_id)
+ $instance_qpart = "id = '$instance_id' AND ";
+ else
+ $instance_qpart = "";
+
+ if (DB_TYPE == "pgsql") {
+ $date_qpart = "last_connected < NOW() - INTERVAL '6 hours'";
+ } else {
+ $date_qpart = "last_connected < DATE_SUB(NOW(), INTERVAL 6 HOUR)";
+ }
+
+ $result = db_query($link, "SELECT id, access_key, access_url FROM ttrss_linked_instances
+ WHERE $instance_qpart $date_qpart ORDER BY last_connected");
+
+ while ($line = db_fetch_assoc($result)) {
+ $id = $line['id'];
+
+ _debug("Updating: " . $line['access_url'] . " ($id)");
+
+ $fetch_url = $line['access_url'] . '/backend.php?op=fbexport';
+ $post_query = 'key=' . $line['access_key'];
+
+ $feeds = fetch_file_contents($fetch_url, false, false, false, $post_query);
+
+ if ($feeds) {
+ $feeds = json_decode($feeds, true);
+
+ if ($feeds) {
+ if ($feeds['error']) {
+ $status = $feeds['error']['code'] + 10;
+ } else {
+ $status = 1;
+
+ if (count($feeds['feeds']) > 0) {
+
+ db_query($link, "DELETE FROM ttrss_linked_feeds
+ WHERE instance_id = '$id'");
+
+ foreach ($feeds['feeds'] as $feed) {
+ $feed_url = db_escape_string($feed['feed_url']);
+ $title = db_escape_string($feed['title']);
+ $subscribers = db_escape_string($feed['subscribers']);
+ $site_url = db_escape_string($feed['site_url']);
+
+ db_query($link, "INSERT INTO ttrss_linked_feeds
+ (feed_url, site_url, title, subscribers, instance_id, created, updated)
+ VALUES
+ ('$feed_url', '$site_url', '$title', '$subscribers', '$id', NOW(), NOW())");
+ }
+ } else {
+ // received 0 feeds, this might indicate that
+ // the instance on the other hand is rebuilding feedbrowser cache
+ // we will try again later
+
+ // TODO: maybe perform expiration based on updated here?
+ }
+
+ _debug("Processed " . count($feeds['feeds']) . " feeds.");
+ }
+ } else {
+ $status = 2;
+ }
+
+ } else {
+ $status = 0;
+ }
+
+ _debug("Status: $status");
+
+ db_query($link, "UPDATE ttrss_linked_instances SET
+ last_status_out = '$status', last_connected = NOW() WHERE id = '$id'");
+
+ }
+
+ }
?>