From eb354e8db235d7d2093a6c0fbfb3fb456a668b0c Mon Sep 17 00:00:00 2001
From: Beudbeud
Date: Sat, 29 Nov 2014 16:42:53 +0100
Subject: [PATCH] update 1.14
---
source/README.md | 2 +-
source/cache/export/.empty | 0
source/cache/images/.empty | 0
source/cache/js/.empty | 0
source/cache/simplepie/.empty | 0
source/cache/upload/.empty | 0
source/classes/api.php | 50 +-
source/classes/article.php | 3 +-
source/classes/dlg.php | 3 +-
source/classes/feedenclosure.php | 2 +
source/classes/feeditem/atom.php | 54 +-
source/classes/feeditem/common.php | 17 +-
source/classes/feeditem/rss.php | 75 +-
source/classes/feedparser.php | 90 +-
source/classes/feeds.php | 116 +-
source/classes/handler/public.php | 270 +-
source/classes/opml.php | 4 +-
source/classes/pluginhost.php | 16 +-
source/classes/pref/feeds.php | 26 +-
source/classes/pref/filters.php | 63 +-
source/classes/pref/prefs.php | 8 +-
source/classes/pref/users.php | 2 +-
source/classes/rpc.php | 13 +-
source/classes/ttrssmailer.php | 124 +-
source/config.php-dist | 17 +-
source/css/cdm.css | 90 +-
source/css/dijit.css | 409 ++
source/css/prefs.css | 33 +-
source/css/tt-rss.css | 571 +-
source/css/utility.css | 13 +-
source/css/zoom.css | 105 +
source/feed-icons/.empty | 0
source/feed-icons/index.html | 0
source/image.php | 2 -
source/images/mark_unset.png | Bin 610 -> 623 bytes
source/images/pub_unset.png | Bin 718 -> 717 bytes
source/images/tick.png | Bin 0 -> 537 bytes
source/images/treeExpandImages.png | Bin 0 -> 288 bytes
source/images/untick.png | Bin 0 -> 518 bytes
source/include/ccache.php | 12 +-
source/include/digest.php | 2 -
source/include/feedbrowser.php | 5 +-
source/include/functions.php | 2471 +------
source/include/functions2.php | 2403 ++++++
source/include/labels.php | 2 +-
source/include/login_form.php | 21 +-
source/include/rssfuncs.php | 352 +-
source/include/sanity_check.php | 5 -
source/include/sanity_config.php | 4 +-
source/include/version.php | 2 +-
source/index.php | 23 +-
source/install/index.php | 9 +-
source/js/FeedTree.js | 14 +-
source/js/PrefFilterTree.js | 8 +
source/js/functions.js | 96 +-
source/js/tt-rss.js | 63 +-
source/js/viewfeed.js | 140 +-
source/lib/MiniTemplator.class.php | 1844 ++---
source/lib/Mobile_Detect.php | 438 +-
source/lib/button/license.txt | 20 +-
source/lib/phpqrcode/CHANGELOG | 76 +-
source/lib/phpqrcode/INSTALL | 134 +-
source/lib/phpqrcode/LICENSE | 330 +-
source/lib/phpqrcode/README | 88 +-
source/lib/phpqrcode/VERSION | 2 +-
source/lib/phpqrcode/index.php | 156 +-
source/lib/phpqrcode/phpqrcode.php | 6434 ++++++++---------
source/lib/phpqrcode/qrbitstream.php | 360 +-
source/lib/phpqrcode/qrconfig.php | 32 +-
source/lib/phpqrcode/qrconst.php | 106 +-
source/lib/phpqrcode/qrencode.php | 1004 +--
source/lib/phpqrcode/qrimage.php | 188 +-
source/lib/phpqrcode/qrinput.php | 1456 ++--
source/lib/phpqrcode/qrlib.php | 86 +-
source/lib/phpqrcode/qrmask.php | 656 +-
source/lib/phpqrcode/qrrscode.php | 418 +-
source/lib/phpqrcode/qrspec.php | 1182 +--
source/lib/phpqrcode/qrsplit.php | 620 +-
source/lib/phpqrcode/qrtools.php | 342 +-
source/lib/phpqrcode/tools/merge.bat | 2 +-
source/lib/phpqrcode/tools/merge.php | 138 +-
source/lib/phpqrcode/tools/merge.sh | 2 +-
source/lib/phpqrcode/tools/merged_config.php | 32 +-
source/lib/phpqrcode/tools/merged_header.php | 70 +-
source/locale/ar_SA/LC_MESSAGES/messages.mo | Bin 0 -> 71877 bytes
source/locale/ar_SA/LC_MESSAGES/messages.po | 3521 +++++++++
source/locale/ca_CA/LC_MESSAGES/messages.mo | Bin 23604 -> 22230 bytes
source/locale/ca_CA/LC_MESSAGES/messages.po | 2078 +++---
source/locale/cs_CZ/LC_MESSAGES/messages.mo | Bin 61444 -> 61905 bytes
source/locale/cs_CZ/LC_MESSAGES/messages.po | 3115 ++++----
source/locale/da_DA/LC_MESSAGES/messages.mo | Bin 0 -> 27246 bytes
source/locale/da_DA/LC_MESSAGES/messages.po | 3505 +++++++++
source/locale/de_DE/LC_MESSAGES/messages.mo | Bin 65134 -> 61508 bytes
source/locale/de_DE/LC_MESSAGES/messages.po | 2626 +++----
source/locale/el_GR/LC_MESSAGES/messages.mo | Bin 0 -> 37462 bytes
source/locale/el_GR/LC_MESSAGES/messages.po | 3505 +++++++++
source/locale/es_ES/LC_MESSAGES/messages.mo | Bin 67373 -> 62246 bytes
source/locale/es_ES/LC_MESSAGES/messages.po | 2749 ++++---
source/locale/es_LA/LC_MESSAGES/messages.mo | Bin 0 -> 29099 bytes
source/locale/es_LA/LC_MESSAGES/messages.po | 3505 +++++++++
source/locale/fi_FI/LC_MESSAGES/messages.mo | Bin 40850 -> 36020 bytes
source/locale/fi_FI/LC_MESSAGES/messages.po | 2010 +++--
source/locale/fr_FR/LC_MESSAGES/messages.mo | Bin 66939 -> 63282 bytes
source/locale/fr_FR/LC_MESSAGES/messages.po | 2692 +++----
source/locale/hu_HU/LC_MESSAGES/messages.mo | Bin 65959 -> 61551 bytes
source/locale/hu_HU/LC_MESSAGES/messages.po | 2078 +++---
source/locale/it_IT/LC_MESSAGES/messages.mo | Bin 34568 -> 31261 bytes
source/locale/it_IT/LC_MESSAGES/messages.po | 2052 +++---
source/locale/ja_JP/LC_MESSAGES/messages.mo | Bin 71901 -> 64400 bytes
source/locale/ja_JP/LC_MESSAGES/messages.po | 2016 +++---
source/locale/ko_KR/LC_MESSAGES/messages.mo | Bin 45785 -> 41311 bytes
source/locale/ko_KR/LC_MESSAGES/messages.po | 1983 +++--
source/locale/lv_LV/LC_MESSAGES/messages.mo | Bin 42784 -> 39031 bytes
source/locale/lv_LV/LC_MESSAGES/messages.po | 2054 +++---
source/locale/nb_NO/LC_MESSAGES/messages.mo | Bin 22368 -> 21124 bytes
source/locale/nb_NO/LC_MESSAGES/messages.po | 2075 +++---
source/locale/nl_NL/LC_MESSAGES/messages.mo | Bin 62280 -> 56356 bytes
source/locale/nl_NL/LC_MESSAGES/messages.po | 2027 +++---
source/locale/pl_PL/LC_MESSAGES/messages.mo | Bin 66808 -> 60776 bytes
source/locale/pl_PL/LC_MESSAGES/messages.po | 2031 +++---
source/locale/pt_BR/LC_MESSAGES/messages.mo | Bin 60350 -> 54532 bytes
source/locale/pt_BR/LC_MESSAGES/messages.po | 2027 +++---
source/locale/pt_PT/LC_MESSAGES/messages.mo | Bin 0 -> 54825 bytes
source/locale/pt_PT/LC_MESSAGES/messages.po | 4190 +++++++++++
source/locale/ru_RU/LC_MESSAGES/messages.mo | Bin 38704 -> 36091 bytes
source/locale/ru_RU/LC_MESSAGES/messages.po | 2110 +++---
source/locale/sv_SE/LC_MESSAGES/messages.mo | Bin 60532 -> 54959 bytes
source/locale/sv_SE/LC_MESSAGES/messages.po | 2029 +++---
source/locale/tr_TR/LC_MESSAGES/messages.mo | Bin 0 -> 58878 bytes
source/locale/tr_TR/LC_MESSAGES/messages.po | 3520 +++++++++
source/locale/zh_CN/LC_MESSAGES/messages.mo | Bin 32451 -> 40442 bytes
source/locale/zh_CN/LC_MESSAGES/messages.po | 2459 ++++---
source/locale/zh_TW/LC_MESSAGES/messages.mo | Bin 0 -> 38696 bytes
source/locale/zh_TW/LC_MESSAGES/messages.po | 4026 +++++++++++
source/lock/.empty | 0
source/lock/.htaccess | 2 +
source/messages.pot | 1465 ++--
.../plugins/af_comics/af_comics_template.php | 14 +
source/plugins/af_comics/filter_base.php | 6 +
.../af_comics/filters/af_comics_cad.php | 36 +
.../filters/af_comics_comicpress.php | 46 +
.../filters/af_comics_darklegacy.php | 43 +
.../af_comics/filters/af_comics_dilbert.php | 47 +
.../af_comics/filters/af_comics_explosm.php | 44 +
.../af_comics/filters/af_comics_gocomics.php | 53 +
.../af_comics/filters/af_comics_pa.php | 77 +
.../af_comics/filters/af_comics_twp.php | 33 +
source/plugins/af_comics/init.php | 79 +
source/plugins/af_elreg/init.php | 50 +
source/plugins/af_fsckportal/init.php | 52 +
source/plugins/af_habr/init.php | 44 +
source/plugins/af_natgeo/init.php | 5 -
source/plugins/af_redditimgur/init.php | 10 +-
source/plugins/af_sciam/init.php | 5 -
source/plugins/af_unburn/init.php | 11 +-
source/plugins/auth_internal/init.php | 5 +-
source/plugins/auth_remote/init.php | 8 -
source/plugins/cache_starred_images/init.php | 4 +-
source/plugins/instances/init.php | 4 +-
source/plugins/mail/init.php | 81 +-
source/plugins/mail/mail.js | 4 +-
source/plugins/mailto/init.php | 4 +-
source/plugins/no_url_hashes/init.js | 4 +
source/plugins/no_url_hashes/init.php | 25 +
source/plugins/search_sphinx/init.php | 64 +
source/plugins/search_sphinx/sphinxapi.php | 1691 +++++
source/plugins/share/init.php | 4 +-
source/plugins/updater/init.php | 15 +
source/prefs.php | 16 +-
source/register.php | 9 +-
source/schema/ttrss_schema_mysql.sql | 497 ++
source/schema/ttrss_schema_pgsql.sql | 441 ++
source/schema/versions/mysql/124.sql | 8 +
source/schema/versions/mysql/125.sql | 10 +
source/schema/versions/mysql/126.sql | 8 +
source/schema/versions/pgsql/124.sql | 8 +
source/schema/versions/pgsql/125.sql | 5 +
source/schema/versions/pgsql/126.sql | 8 +
source/templates/generated_feed.txt | 4 +-
source/templates/resetpass_link_template.txt | 14 +
source/themes/default.css | 1 +
source/themes/night.css | 187 +
source/update.php | 7 +
source/update_daemon2.php | 13 +-
source/utils/update-translations.sh | 2 +-
185 files changed, 62547 insertions(+), 32735 deletions(-)
create mode 100755 source/cache/export/.empty
create mode 100755 source/cache/images/.empty
create mode 100755 source/cache/js/.empty
create mode 100755 source/cache/simplepie/.empty
create mode 100644 source/cache/upload/.empty
create mode 100644 source/css/dijit.css
create mode 100644 source/css/zoom.css
create mode 100755 source/feed-icons/.empty
create mode 100644 source/feed-icons/index.html
create mode 100644 source/images/tick.png
create mode 100644 source/images/treeExpandImages.png
create mode 100644 source/images/untick.png
create mode 100644 source/include/functions2.php
create mode 100755 source/locale/ar_SA/LC_MESSAGES/messages.mo
create mode 100755 source/locale/ar_SA/LC_MESSAGES/messages.po
create mode 100644 source/locale/da_DA/LC_MESSAGES/messages.mo
create mode 100644 source/locale/da_DA/LC_MESSAGES/messages.po
create mode 100644 source/locale/el_GR/LC_MESSAGES/messages.mo
create mode 100644 source/locale/el_GR/LC_MESSAGES/messages.po
create mode 100644 source/locale/es_LA/LC_MESSAGES/messages.mo
create mode 100644 source/locale/es_LA/LC_MESSAGES/messages.po
create mode 100644 source/locale/pt_PT/LC_MESSAGES/messages.mo
create mode 100644 source/locale/pt_PT/LC_MESSAGES/messages.po
create mode 100644 source/locale/tr_TR/LC_MESSAGES/messages.mo
create mode 100644 source/locale/tr_TR/LC_MESSAGES/messages.po
create mode 100644 source/locale/zh_TW/LC_MESSAGES/messages.mo
create mode 100644 source/locale/zh_TW/LC_MESSAGES/messages.po
create mode 100755 source/lock/.empty
create mode 100755 source/lock/.htaccess
create mode 100644 source/plugins/af_comics/af_comics_template.php
create mode 100644 source/plugins/af_comics/filter_base.php
create mode 100644 source/plugins/af_comics/filters/af_comics_cad.php
create mode 100644 source/plugins/af_comics/filters/af_comics_comicpress.php
create mode 100644 source/plugins/af_comics/filters/af_comics_darklegacy.php
create mode 100644 source/plugins/af_comics/filters/af_comics_dilbert.php
create mode 100644 source/plugins/af_comics/filters/af_comics_explosm.php
create mode 100644 source/plugins/af_comics/filters/af_comics_gocomics.php
create mode 100644 source/plugins/af_comics/filters/af_comics_pa.php
create mode 100644 source/plugins/af_comics/filters/af_comics_twp.php
create mode 100644 source/plugins/af_comics/init.php
create mode 100644 source/plugins/af_elreg/init.php
create mode 100644 source/plugins/af_fsckportal/init.php
create mode 100644 source/plugins/af_habr/init.php
create mode 100644 source/plugins/no_url_hashes/init.js
create mode 100644 source/plugins/no_url_hashes/init.php
create mode 100644 source/plugins/search_sphinx/init.php
create mode 100644 source/plugins/search_sphinx/sphinxapi.php
create mode 100644 source/schema/ttrss_schema_mysql.sql
create mode 100644 source/schema/ttrss_schema_pgsql.sql
create mode 100644 source/schema/versions/mysql/124.sql
create mode 100644 source/schema/versions/mysql/125.sql
create mode 100644 source/schema/versions/mysql/126.sql
create mode 100644 source/schema/versions/pgsql/124.sql
create mode 100644 source/schema/versions/pgsql/125.sql
create mode 100644 source/schema/versions/pgsql/126.sql
create mode 100644 source/templates/resetpass_link_template.txt
create mode 100644 source/themes/night.css
diff --git a/source/README.md b/source/README.md
index 97218cd..0c3176f 100644
--- a/source/README.md
+++ b/source/README.md
@@ -4,7 +4,7 @@ Tiny Tiny RSS
Web-based news feed aggregator, designed to allow you to read news from
any location, while feeling as close to a real desktop application as possible.
-http://tt-rss.org
+http://tt-rss.org (http://mirror.tt-rss.org)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
diff --git a/source/cache/export/.empty b/source/cache/export/.empty
new file mode 100755
index 0000000..e69de29
diff --git a/source/cache/images/.empty b/source/cache/images/.empty
new file mode 100755
index 0000000..e69de29
diff --git a/source/cache/js/.empty b/source/cache/js/.empty
new file mode 100755
index 0000000..e69de29
diff --git a/source/cache/simplepie/.empty b/source/cache/simplepie/.empty
new file mode 100755
index 0000000..e69de29
diff --git a/source/cache/upload/.empty b/source/cache/upload/.empty
new file mode 100644
index 0000000..e69de29
diff --git a/source/classes/api.php b/source/classes/api.php
index bbbcbb5..97f17cc 100644
--- a/source/classes/api.php
+++ b/source/classes/api.php
@@ -2,7 +2,7 @@
class API extends Handler {
- const API_LEVEL = 7;
+ const API_LEVEL = 9;
const STATUS_OK = 0;
const STATUS_ERR = 1;
@@ -77,6 +77,7 @@ class API extends Handler {
$this->wrap(self::STATUS_OK, array("session_id" => session_id(),
"api_level" => self::API_LEVEL));
} else { // else we are not logged in
+ user_error("Failed login attempt for $login from {$_SERVER['REMOTE_ADDR']}", E_USER_WARNING);
$this->wrap(self::STATUS_ERR, array("error" => "LOGIN_ERROR"));
}
} else {
@@ -199,9 +200,13 @@ class API extends Handler {
$include_nested = sql_bool_to_bool($_REQUEST["include_nested"]);
$sanitize_content = !isset($_REQUEST["sanitize"]) ||
sql_bool_to_bool($_REQUEST["sanitize"]);
+ $force_update = sql_bool_to_bool($_REQUEST["force_update"]);
$override_order = false;
switch ($_REQUEST["order_by"]) {
+ case "title":
+ $override_order = "ttrss_entries.title";
+ break;
case "date_reverse":
$override_order = "score DESC, date_entered, updated";
break;
@@ -218,7 +223,7 @@ class API extends Handler {
$headlines = $this->api_get_headlines($feed_id, $limit, $offset,
$filter, $is_cat, $show_excerpt, $show_content, $view_mode, $override_order,
$include_attachments, $since_id, $search, $search_mode,
- $include_nested, $sanitize_content);
+ $include_nested, $sanitize_content, $force_update);
$this->wrap(self::STATUS_OK, $headlines);
} else {
@@ -310,7 +315,7 @@ class API extends Handler {
if ($article_id) {
$query = "SELECT id,title,link,content,feed_id,comments,int_id,
- marked,unread,published,score,
+ marked,unread,published,score,note,lang,
".SUBSTRING_FOR_DATE."(updated,1,16) as updated,
author,(SELECT title FROM ttrss_feeds WHERE id = feed_id) AS feed_title
FROM ttrss_entries,ttrss_user_entries
@@ -342,7 +347,9 @@ class API extends Handler {
"feed_id" => $line["feed_id"],
"attachments" => $attachments,
"score" => (int)$line["score"],
- "feed_title" => $line["feed_title"]
+ "feed_title" => $line["feed_title"],
+ "note" => $line["note"],
+ "lang" => $line["lang"]
);
foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_RENDER_ARTICLE_API) as $p) {
@@ -423,7 +430,7 @@ class API extends Handler {
$checked = false;
foreach ($article_labels as $al) {
- if ($al[0] == $line['id']) {
+ if (feed_to_label_id($al[0]) == $line['id']) {
$checked = true;
break;
}
@@ -447,7 +454,7 @@ class API extends Handler {
$assign = (bool) $this->dbh->escape_string($_REQUEST['assign']) == "true";
$label = $this->dbh->escape_string(label_find_caption(
- $label_id, $_SESSION["uid"]));
+ feed_to_label_id($label_id), $_SESSION["uid"]));
$num_updated = 0;
@@ -511,7 +518,7 @@ class API extends Handler {
if ($unread || !$unread_only) {
$row = array(
- "id" => $cv["id"],
+ "id" => (int) $cv["id"],
"title" => $cv["description"],
"unread" => $cv["counter"],
"cat_id" => -2,
@@ -557,7 +564,7 @@ class API extends Handler {
if ($unread || !$unread_only) {
$row = array(
- "id" => $line["id"],
+ "id" => (int) $line["id"],
"title" => $line["title"],
"unread" => $unread,
"is_cat" => true,
@@ -626,7 +633,28 @@ class API extends Handler {
$filter, $is_cat, $show_excerpt, $show_content, $view_mode, $order,
$include_attachments, $since_id,
$search = "", $search_mode = "",
- $include_nested = false, $sanitize_content = true) {
+ $include_nested = false, $sanitize_content = true, $force_update = false) {
+
+ if ($force_update && $feed_id > 0 && is_numeric($feed_id)) {
+ // Update the feed if required with some basic flood control
+
+ $result = db_query(
+ "SELECT cache_images,".SUBSTRING_FOR_DATE."(last_updated,1,19) AS last_updated
+ FROM ttrss_feeds WHERE id = '$feed_id'");
+
+ if (db_num_rows($result) != 0) {
+ $last_updated = strtotime(db_fetch_result($result, 0, "last_updated"));
+ $cache_images = sql_bool_to_bool(db_fetch_result($result, 0, "cache_images"));
+
+ if (!$cache_images && time() - $last_updated > 120) {
+ include "rssfuncs.php";
+ update_rss_feed($feed_id, true, true);
+ } else {
+ db_query("UPDATE ttrss_feeds SET last_updated = '1970-01-01', last_update_started = '1970-01-01'
+ WHERE id = '$feed_id'");
+ }
+ }
+ }
$qfh_ret = queryFeedHeadlines($feed_id, $limit,
$view_mode, $is_cat, $search, $search_mode,
@@ -638,7 +666,7 @@ class API extends Handler {
$headlines = array();
while ($line = db_fetch_assoc($result)) {
- $line["content_preview"] = truncate_string(strip_tags($line["content_preview"]), 100);
+ $line["content_preview"] = truncate_string(strip_tags($line["content"]), 100);
foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_QUERY_HEADLINES) as $p) {
$line = $p->hook_query_headlines($line, 100, true);
}
@@ -700,6 +728,8 @@ class API extends Handler {
$headline_row["author"] = $line["author"];
$headline_row["score"] = (int)$line["score"];
+ $headline_row["note"] = $line["note"];
+ $headline_row["lang"] = $line["lang"];
foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_RENDER_ARTICLE_API) as $p) {
$headline_row = $p->hook_render_article_api(array("headline" => $headline_row));
diff --git a/source/classes/article.php b/source/classes/article.php
index 398132d..9aef107 100644
--- a/source/classes/article.php
+++ b/source/classes/article.php
@@ -30,7 +30,6 @@ class Article extends Handler_Protected {
$id = $this->dbh->escape_string($_REQUEST["id"]);
$cids = explode(",", $this->dbh->escape_string($_REQUEST["cids"]));
$mode = $this->dbh->escape_string($_REQUEST["mode"]);
- $omode = $this->dbh->escape_string($_REQUEST["omode"]);
// in prefetch mode we only output requested cids, main article
// just gets marked as read (it already exists in client cache)
@@ -108,7 +107,7 @@ class Article extends Handler_Protected {
// only check for our user data here, others might have shared this with different content etc
$result = db_query("SELECT id FROM ttrss_entries, ttrss_user_entries WHERE
- link = '$url' AND ref_id = id AND owner_uid = '$owner_uid' LIMIT 1");
+ guid = '$guid' AND ref_id = id AND owner_uid = '$owner_uid' LIMIT 1");
if (db_num_rows($result) != 0) {
$ref_id = db_fetch_result($result, 0, "id");
diff --git a/source/classes/dlg.php b/source/classes/dlg.php
index cfa960d..25a194b 100644
--- a/source/classes/dlg.php
+++ b/source/classes/dlg.php
@@ -16,7 +16,6 @@ class Dlg extends Handler_Protected {
print __("If you have imported labels and/or filters, you might need to reload preferences to see your new data.") . "
";
print "";
- $owner_uid = $_SESSION["uid"];
$this->dbh->query("BEGIN");
@@ -176,7 +175,7 @@ class Dlg extends Handler_Protected {
while ($row = $this->dbh->fetch_assoc($result)) {
$tmp = htmlspecialchars($row["tag_name"]);
- print "
$tmp ";
+ print "
$tmp ";
}
print "";
diff --git a/source/classes/feedenclosure.php b/source/classes/feedenclosure.php
index b57100b..64f1a06 100644
--- a/source/classes/feedenclosure.php
+++ b/source/classes/feedenclosure.php
@@ -4,5 +4,7 @@ class FeedEnclosure {
public $type;
public $length;
public $title;
+ public $height;
+ public $width;
}
?>
diff --git a/source/classes/feeditem/atom.php b/source/classes/feeditem/atom.php
index b7a228a..dfac714 100644
--- a/source/classes/feeditem/atom.php
+++ b/source/classes/feeditem/atom.php
@@ -43,9 +43,9 @@ class FeedItem_Atom extends FeedItem_Common {
$base = $this->xpath->evaluate("string(ancestor-or-self::*[@xml:base][1]/@xml:base)", $link);
if ($base)
- return rewrite_relative_url($base, $link->getAttribute("href"));
+ return rewrite_relative_url($base, trim($link->getAttribute("href")));
else
- return $link->getAttribute("href");
+ return trim($link->getAttribute("href"));
}
}
@@ -55,7 +55,7 @@ class FeedItem_Atom extends FeedItem_Common {
$title = $this->elem->getElementsByTagName("title")->item(0);
if ($title) {
- return $title->nodeValue;
+ return trim($title->nodeValue);
}
}
@@ -106,13 +106,13 @@ class FeedItem_Atom extends FeedItem_Common {
foreach ($categories as $cat) {
if ($cat->hasAttribute("term"))
- array_push($cats, $cat->getAttribute("term"));
+ array_push($cats, trim($cat->getAttribute("term")));
}
$categories = $this->xpath->query("dc:subject", $this->elem);
foreach ($categories as $cat) {
- array_push($cats, $cat->nodeValue);
+ array_push($cats, trim($cat->nodeValue));
}
return $cats;
@@ -137,7 +137,7 @@ class FeedItem_Atom extends FeedItem_Common {
}
}
- $enclosures = $this->xpath->query("media:content | media:group/media:content", $this->elem);
+ $enclosures = $this->xpath->query("media:content", $this->elem);
foreach ($enclosures as $enclosure) {
$enc = new FeedEnclosure();
@@ -145,6 +145,8 @@ class FeedItem_Atom extends FeedItem_Common {
$enc->type = $enclosure->getAttribute("type");
$enc->link = $enclosure->getAttribute("url");
$enc->length = $enclosure->getAttribute("length");
+ $enc->height = $enclosure->getAttribute("height");
+ $enc->width = $enclosure->getAttribute("width");
$desc = $this->xpath->query("media:description", $enclosure)->item(0);
if ($desc) $enc->title = strip_tags($desc->nodeValue);
@@ -152,6 +154,46 @@ class FeedItem_Atom extends FeedItem_Common {
array_push($encs, $enc);
}
+
+ $enclosures = $this->xpath->query("media:group", $this->elem);
+
+ foreach ($enclosures as $enclosure) {
+ $enc = new FeedEnclosure();
+
+ $content = $this->xpath->query("media:content", $enclosure)->item(0);
+
+ if ($content) {
+ $enc->type = $content->getAttribute("type");
+ $enc->link = $content->getAttribute("url");
+ $enc->length = $content->getAttribute("length");
+ $enc->height = $content->getAttribute("height");
+ $enc->width = $content->getAttribute("width");
+
+ $desc = $this->xpath->query("media:description", $content)->item(0);
+ if ($desc) {
+ $enc->title = strip_tags($desc->nodeValue);
+ } else {
+ $desc = $this->xpath->query("media:description", $enclosure)->item(0);
+ if ($desc) $enc->title = strip_tags($desc->nodeValue);
+ }
+
+ array_push($encs, $enc);
+ }
+ }
+
+ $enclosures = $this->xpath->query("media:thumbnail", $this->elem);
+
+ foreach ($enclosures as $enclosure) {
+ $enc = new FeedEnclosure();
+
+ $enc->type = "image/generic";
+ $enc->link = $enclosure->getAttribute("url");
+ $enc->height = $enclosure->getAttribute("height");
+ $enc->width = $enclosure->getAttribute("width");
+
+ array_push($encs, $enc);
+ }
+
return $encs;
}
diff --git a/source/classes/feeditem/common.php b/source/classes/feeditem/common.php
index 58065b1..80bebf8 100644
--- a/source/classes/feeditem/common.php
+++ b/source/classes/feeditem/common.php
@@ -44,13 +44,26 @@ abstract class FeedItem_Common extends FeedItem {
}
}
- // todo
function get_comments_url() {
+ //RSS only. Use a query here to avoid namespace clashes (e.g. with slash).
+ //might give a wrong result if a default namespace was declared (possible with XPath 2.0)
+ $com_url = $this->xpath->query("comments", $this->elem)->item(0);
+ if($com_url)
+ return $com_url->nodeValue;
+
+ //Atom Threading Extension (RFC 4685) stuff. Could be used in RSS feeds, so it's in common.
+ //'text/html' for type is too restrictive?
+ $com_url = $this->xpath->query("atom:link[@rel='replies' and contains(@type,'text/html')]/@href", $this->elem)->item(0);
+
+ if($com_url)
+ return $com_url->nodeValue;
}
function get_comments_count() {
- $comments = $this->xpath->query("slash:comments", $this->elem)->item(0);
+ //also query for ATE stuff here
+ $query = "slash:comments|thread:total|atom:link[@rel='replies']/@thread:count";
+ $comments = $this->xpath->query($query, $this->elem)->item(0);
if ($comments) {
return $comments->nodeValue;
diff --git a/source/classes/feeditem/rss.php b/source/classes/feeditem/rss.php
index 1f59f06..c9a7467 100644
--- a/source/classes/feeditem/rss.php
+++ b/source/classes/feeditem/rss.php
@@ -33,20 +33,20 @@ class FeedItem_RSS extends FeedItem_Common {
|| $link->getAttribute("rel") == "alternate"
|| $link->getAttribute("rel") == "standout")) {
- return $link->getAttribute("href");
+ return trim($link->getAttribute("href"));
}
}
$link = $this->elem->getElementsByTagName("guid")->item(0);
if ($link && $link->hasAttributes() && $link->getAttribute("isPermaLink") == "true") {
- return $link->nodeValue;
+ return trim($link->nodeValue);
}
$link = $this->elem->getElementsByTagName("link")->item(0);
if ($link) {
- return $link->nodeValue;
+ return trim($link->nodeValue);
}
}
@@ -54,21 +54,26 @@ class FeedItem_RSS extends FeedItem_Common {
$title = $this->elem->getElementsByTagName("title")->item(0);
if ($title) {
- return $title->nodeValue;
+ return trim($title->nodeValue);
}
}
function get_content() {
- $content = $this->xpath->query("content:encoded", $this->elem)->item(0);
+ $contentA = $this->xpath->query("content:encoded", $this->elem)->item(0);
+ $contentB = $this->elem->getElementsByTagName("description")->item(0);
- if ($content) {
- return $content->nodeValue;
+ if ($contentA && !$contentB) {
+ return $contentA->nodeValue;
}
- $content = $this->elem->getElementsByTagName("description")->item(0);
- if ($content) {
- return $content->nodeValue;
+ if ($contentB && !$contentA) {
+ return $contentB->nodeValue;
+ }
+
+ if ($contentA && $contentB) {
+ return mb_strlen($contentA->nodeValue) > mb_strlen($contentB->nodeValue) ?
+ $contentA->nodeValue : $contentB->nodeValue;
}
}
@@ -85,13 +90,13 @@ class FeedItem_RSS extends FeedItem_Common {
$cats = array();
foreach ($categories as $cat) {
- array_push($cats, $cat->nodeValue);
+ array_push($cats, trim($cat->nodeValue));
}
$categories = $this->xpath->query("dc:subject", $this->elem);
foreach ($categories as $cat) {
- array_push($cats, $cat->nodeValue);
+ array_push($cats, trim($cat->nodeValue));
}
return $cats;
@@ -108,11 +113,13 @@ class FeedItem_RSS extends FeedItem_Common {
$enc->type = $enclosure->getAttribute("type");
$enc->link = $enclosure->getAttribute("url");
$enc->length = $enclosure->getAttribute("length");
+ $enc->height = $enclosure->getAttribute("height");
+ $enc->width = $enclosure->getAttribute("width");
array_push($encs, $enc);
}
- $enclosures = $this->xpath->query("media:content | media:group/media:content", $this->elem);
+ $enclosures = $this->xpath->query("media:content", $this->elem);
foreach ($enclosures as $enclosure) {
$enc = new FeedEnclosure();
@@ -120,6 +127,8 @@ class FeedItem_RSS extends FeedItem_Common {
$enc->type = $enclosure->getAttribute("type");
$enc->link = $enclosure->getAttribute("url");
$enc->length = $enclosure->getAttribute("length");
+ $enc->height = $enclosure->getAttribute("height");
+ $enc->width = $enclosure->getAttribute("width");
$desc = $this->xpath->query("media:description", $enclosure)->item(0);
if ($desc) $enc->title = strip_tags($desc->nodeValue);
@@ -127,6 +136,46 @@ class FeedItem_RSS extends FeedItem_Common {
array_push($encs, $enc);
}
+
+ $enclosures = $this->xpath->query("media:group", $this->elem);
+
+ foreach ($enclosures as $enclosure) {
+ $enc = new FeedEnclosure();
+
+ $content = $this->xpath->query("media:content", $enclosure)->item(0);
+
+ if ($content) {
+ $enc->type = $content->getAttribute("type");
+ $enc->link = $content->getAttribute("url");
+ $enc->length = $content->getAttribute("length");
+ $enc->height = $content->getAttribute("height");
+ $enc->width = $content->getAttribute("width");
+
+ $desc = $this->xpath->query("media:description", $content)->item(0);
+ if ($desc) {
+ $enc->title = strip_tags($desc->nodeValue);
+ } else {
+ $desc = $this->xpath->query("media:description", $enclosure)->item(0);
+ if ($desc) $enc->title = strip_tags($desc->nodeValue);
+ }
+
+ array_push($encs, $enc);
+ }
+ }
+
+ $enclosures = $this->xpath->query("media:thumbnail", $this->elem);
+
+ foreach ($enclosures as $enclosure) {
+ $enc = new FeedEnclosure();
+
+ $enc->type = "image/generic";
+ $enc->link = $enclosure->getAttribute("url");
+ $enc->height = $enclosure->getAttribute("height");
+ $enc->width = $enclosure->getAttribute("width");
+
+ array_push($encs, $enc);
+ }
+
return $encs;
}
diff --git a/source/classes/feedparser.php b/source/classes/feedparser.php
index 4a2c6c2..239fdb7 100644
--- a/source/classes/feedparser.php
+++ b/source/classes/feedparser.php
@@ -2,6 +2,7 @@
class FeedParser {
private $doc;
private $error;
+ private $libxml_errors = array();
private $items;
private $link;
private $title;
@@ -12,6 +13,16 @@ class FeedParser {
const FEED_RSS = 1;
const FEED_ATOM = 2;
+ function normalize_encoding($data) {
+ if (preg_match('/^(<\?xml[\t\n\r ].*?encoding[\t\n\r ]*=[\t\n\r ]*["\'])(.+?)(["\'].*?\?>)/s', $data, $matches) === 1) {
+ $data = mb_convert_encoding($data, 'UTF-8', $matches[2]);
+
+ $data = preg_replace('/^<\?xml[\t\n\r ].*?\?>/s', $matches[1] . "UTF-8" . $matches[3] , $data);
+ }
+
+ return $data;
+ }
+
function __construct($data) {
libxml_use_internal_errors(true);
libxml_clear_errors();
@@ -23,32 +34,8 @@ class FeedParser {
$error = libxml_get_last_error();
// libxml compiled without iconv?
- if ($error && ($error->code == 32 || $error->code == 9)) {
- if (preg_match('/^(<\?xml[\t\n\r ].*?encoding=["\'])(.+?)(["\'].*?\?>)/s', $data, $matches) === 1) {
- $enc = $matches[2];
-
- $data = mb_convert_encoding($data, 'UTF-8', $enc);
-
- $data = preg_replace('/^<\?xml[\t\n\r ].*?\?>/s', $matches[1] . "UTF-8" . $matches[3] , $data);
-
-
- // apparently not all UTF-8 characters are valid for XML
- $data = preg_replace('/[^\x{0009}\x{000a}\x{000d}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}]+/u', ' ', $data);
-
- if ($data) {
- libxml_clear_errors();
-
- $this->doc = new DOMDocument();
- $this->doc->loadXML($data);
-
- $error = libxml_get_last_error();
- }
- }
- }
-
- // some terrible invalid unicode entity?
- if ($error && $error->code == 9) {
- $data = mb_convert_encoding($data, 'UTF-8', 'UTF-8');
+ if ($error && $error->code == 32) {
+ $data = $this->normalize_encoding($data);
if ($data) {
libxml_clear_errors();
@@ -60,7 +47,41 @@ class FeedParser {
}
}
- $this->error = $this->format_error($error);
+ // some terrible invalid unicode entity?
+ if ($error) {
+ foreach (libxml_get_errors() as $err) {
+ if ($err->code == 9) {
+ // if the source feed is not in utf8, next conversion will fail
+ $data = $this->normalize_encoding($data);
+
+ // remove dangling bytes
+ $data = mb_convert_encoding($data, 'UTF-8', 'UTF-8');
+
+ // apparently not all UTF-8 characters are valid for XML
+ $data = preg_replace('/[^\x{0009}\x{000a}\x{000d}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}]+/u', ' ', $data);
+
+ if ($data) {
+ libxml_clear_errors();
+
+ $this->doc = new DOMDocument();
+ $this->doc->loadXML($data);
+
+ $error = libxml_get_last_error();
+ }
+ break;
+ }
+ }
+ }
+
+ if ($error) {
+ foreach (libxml_get_errors() as $error) {
+ if ($error->level == LIBXML_ERR_FATAL) {
+ if(!isset($this->error)) //currently only the first error is reported
+ $this->error = $this->format_error($error);
+ $this->libxml_errors [] = $this->format_error($error);
+ }
+ }
+ }
libxml_clear_errors();
$this->items = array();
@@ -76,12 +97,13 @@ class FeedParser {
$xpath->registerNamespace('slash', 'http://purl.org/rss/1.0/modules/slash/');
$xpath->registerNamespace('dc', 'http://purl.org/dc/elements/1.1/');
$xpath->registerNamespace('content', 'http://purl.org/rss/1.0/modules/content/');
+ $xpath->registerNamespace('thread', 'http://purl.org/syndication/thread/1.0');
$this->xpath = $xpath;
$root = $xpath->query("(//atom03:feed|//atom:feed|//channel|//rdf:rdf|//rdf:RDF)");
- if ($root) {
+ if ($root && $root->length > 0) {
$root = $root->item(0);
if ($root) {
@@ -183,6 +205,10 @@ class FeedParser {
break;
}
+
+ if ($this->title) $this->title = trim($this->title);
+ if ($this->link) $this->link = trim($this->link);
+
} else {
if( !isset($this->error) ){
$this->error = "Unknown/unsupported feed type";
@@ -205,6 +231,10 @@ class FeedParser {
return $this->error;
}
+ function errors() {
+ return $this->libxml_errors;
+ }
+
function get_link() {
return $this->link;
}
@@ -226,7 +256,7 @@ class FeedParser {
foreach ($links as $link) {
if (!$rel || $link->hasAttribute('rel') && $link->getAttribute('rel') == $rel) {
- array_push($rv, $link->getAttribute('href'));
+ array_push($rv, trim($link->getAttribute('href')));
}
}
break;
@@ -235,7 +265,7 @@ class FeedParser {
foreach ($links as $link) {
if (!$rel || $link->hasAttribute('rel') && $link->getAttribute('rel') == $rel) {
- array_push($rv, $link->getAttribute('href'));
+ array_push($rv, trim($link->getAttribute('href')));
}
}
break;
diff --git a/source/classes/feeds.php b/source/classes/feeds.php
index 5ee125f..5ec1096 100644
--- a/source/classes/feeds.php
+++ b/source/classes/feeds.php
@@ -13,12 +13,6 @@ class Feeds extends Handler_Protected {
$feed_id, $is_cat, $search,
$search_mode, $view_mode, $error, $feed_last_updated) {
- $page_prev_link = "viewFeedGoPage(-1)";
- $page_next_link = "viewFeedGoPage(1)";
- $page_first_link = "viewFeedGoPage(0)";
-
- $catchup_page_link = "catchupPage()";
- $catchup_feed_link = "catchupCurrentFeed()";
$catchup_sel_link = "catchupSelection()";
$archive_sel_link = "archiveSelection()";
@@ -43,6 +37,8 @@ class Feeds extends Handler_Protected {
$search_q = "";
}
+ $reply .= "
";
+
$rss_link = htmlspecialchars(get_self_url_prefix() .
"/public.php?op=rss&id=$feed_id$cat_q$search_q");
@@ -50,8 +46,14 @@ class Feeds extends Handler_Protected {
$error_class = $error ? "error" : "";
- $reply .= "";
- $reply .= " ";
+ $reply .= "
+
+ ";
+
+
+# $reply .= "";
$reply .= "";
if ($feed_site_url) {
@@ -60,11 +62,11 @@ class Feeds extends Handler_Protected {
$target = "target=\"_blank\"";
$reply .= "".
- truncate_string($feed_title,30)." ";
+ truncate_string($feed_title, 30)."";
if ($error) {
$error = htmlspecialchars($error);
- $reply .= " ";
+ $reply .= " ";
}
} else {
@@ -73,17 +75,16 @@ class Feeds extends Handler_Protected {
$reply .= " ";
- $reply .= "
-
- ";
-
$reply .= " ";
+# $reply .= " ";
+
// left part
- $reply .= __('Select:')."
+ $reply .= "";
+ $reply .= " ";
+
+ $reply .= "
".__('All')." ,
".__('Unread')." ,
".__('Invert')." ,
@@ -132,14 +133,14 @@ class Feeds extends Handler_Protected {
$reply .= "";
- //$reply .= " ";
-
//$reply .= "get_hooks(PluginHost::HOOK_HEADLINE_TOOLBAR_BUTTON) as $p) {
- echo $p->hook_headline_toolbar_button($feed_id, $is_cat);
+ $reply .= $p->hook_headline_toolbar_button($feed_id, $is_cat);
}
+ $reply .= "";
+
return $reply;
}
@@ -148,7 +149,7 @@ class Feeds extends Handler_Protected {
$override_order = false, $include_children = false) {
if (isset($_REQUEST["DevForceUpdate"]))
- header("Content-Type: text/plain");
+ header("Content-Type: text/plain; charset=utf-8");
$disable_cache = false;
@@ -247,6 +248,8 @@ class Feeds extends Handler_Protected {
false, 0, $include_children);
}
+ $vfeed_group_enabled = get_pref("VFEED_GROUP_BY_FEED") && $feed != -6;
+
if ($_REQUEST["debug"]) $timing_info = print_checkpoint("H1", $timing_info);
$result = $qfh_ret[0];
@@ -278,6 +281,12 @@ class Feeds extends Handler_Protected {
}
} */
+ if ($offset == 0) {
+ foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_HEADLINES_BEFORE) as $p) {
+ $reply['content'] .= $p->hook_headlines_before($feed, $cat_view, $qfh_ret);
+ }
+ }
+
if ($this->dbh->num_rows($result) > 0) {
$lnum = $offset;
@@ -285,14 +294,12 @@ class Feeds extends Handler_Protected {
$num_unread = 0;
$cur_feed_title = '';
- $fresh_intl = get_pref("FRESH_ARTICLE_MAX_AGE") * 60 * 60;
-
if ($_REQUEST["debug"]) $timing_info = print_checkpoint("PS", $timing_info);
$expand_cdm = get_pref('CDM_EXPANDED');
while ($line = $this->dbh->fetch_assoc($result)) {
- $line["content_preview"] = "— " . truncate_string(strip_tags($line["content_preview"]), 250);
+ $line["content_preview"] = "— " . truncate_string(strip_tags($line["content"]), 250);
foreach (PluginHost::getInstance()->get_hooks(PluginHost::HOOK_QUERY_HEADLINES) as $p) {
$line = $p->hook_query_headlines($line, 250, false);
@@ -422,7 +429,7 @@ class Feeds extends Handler_Protected {
if (!get_pref('COMBINED_DISPLAY_MODE')) {
- if (get_pref('VFEED_GROUP_BY_FEED')) {
+ if ($vfeed_group_enabled) {
if ($feed_id != $vgroup_last_feed && $line["feed_title"]) {
$cur_feed_title = $line["feed_title"];
@@ -430,12 +437,12 @@ class Feeds extends Handler_Protected {
$cur_feed_title = htmlspecialchars($cur_feed_title);
- $vf_catchup_link = "(".__('Mark as read')." )";
+ $vf_catchup_link = "".__('mark feed as read')." ";
- $reply['content'] .= "";
+ $reply['content'] .= "";
}
}
@@ -443,7 +450,7 @@ class Feeds extends Handler_Protected {
$mouseover_attrs = "onmouseover='postMouseIn(event, $id)'
onmouseout='postMouseOut($id)'";
- $reply['content'] .= "";
+ $reply['content'] .= "
";
$reply['content'] .= "
";
@@ -473,17 +480,18 @@ class Feeds extends Handler_Protected {
$reply['content'] .= "
";
- $reply['content'] .= "
";
-
- if (!get_pref('VFEED_GROUP_BY_FEED')) {
+ if (!$vfeed_group_enabled) {
if (@$line["feed_title"]) {
$rgba = @$rgba_cache[$feed_id];
- $reply['content'] .= "".
- truncate_string($line["feed_title"],30)." ";
+ $reply['content'] .= "".
+ truncate_string($line["feed_title"],30)." ";
}
}
+
+ $reply['content'] .= "";
+
$reply['content'] .= "$updated_fmt
";
@@ -491,12 +499,12 @@ class Feeds extends Handler_Protected {
$reply['content'] .= $score_pic;
- if ($line["feed_title"] && !get_pref('VFEED_GROUP_BY_FEED')) {
+ if ($line["feed_title"] && !$vfeed_group_enabled) {
$reply['content'] .= "
- $feed_icon_img";
+ $feed_icon_img ";
}
$reply['content'] .= " ";
@@ -516,7 +524,7 @@ class Feeds extends Handler_Protected {
$line = $p->hook_render_article_cdm($line);
}
- if (get_pref('VFEED_GROUP_BY_FEED') && $line["feed_title"]) {
+ if ($vfeed_group_enabled && $line["feed_title"]) {
if ($feed_id != $vgroup_last_feed) {
$cur_feed_title = $line["feed_title"];
@@ -524,7 +532,7 @@ class Feeds extends Handler_Protected {
$cur_feed_title = htmlspecialchars($cur_feed_title);
- $vf_catchup_link = "(
".__('mark as read')." )";
+ $vf_catchup_link = "
".__('mark feed as read')." ";
$has_feed_icon = feed_has_icon($feed_id);
@@ -534,7 +542,7 @@ class Feeds extends Handler_Protected {
//$feed_icon_img = "
";
}
- $reply['content'] .= "
".
+ $reply['content'] .= "
";
@@ -547,9 +555,9 @@ class Feeds extends Handler_Protected {
$expanded_class = $expand_cdm ? "expanded" : "expandable";
$reply['content'] .= "
";
+ id=\"RROW-$id\" orig-feed-id='$feed_id' $mouseover_attrs>";
- $reply['content'] .= "